@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.
- package/README.md +10 -0
- package/dist/action.d.mts +9 -4
- package/dist/action.mjs +22 -5
- package/dist/action.mjs.map +1 -1
- package/dist/cli.mjs +4 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/{fan-out-BBEATQwc.d.mts → fan-out-C6gq3CFg.d.mts} +87 -3
- package/dist/{github-BZNzmxao.mjs → github-Lfa_ox-u.mjs} +308 -7
- package/dist/github-Lfa_ox-u.mjs.map +1 -0
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +3 -3
- package/dist/{providers-J6BKHyHe.mjs → providers-CaOnz7mK.mjs} +5 -4
- package/dist/{providers-J6BKHyHe.mjs.map → providers-CaOnz7mK.mjs.map} +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.mjs +5 -3
- package/dist/testing.mjs.map +1 -1
- package/package.json +2 -2
- package/src/action.ts +32 -1
- package/src/cli.ts +2 -1
- package/src/index.ts +1 -0
- package/src/internal/action-entry.ts +1 -0
- package/src/internal/fixtures.ts +5 -1
- package/src/internal/github-env.ts +20 -6
- package/src/internal/github.ts +232 -2
- package/src/internal/retirement.ts +332 -0
- package/dist/github-BZNzmxao.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-Lfa_ox-u.mjs","names":[],"sources":["../src/internal/diff.ts","../src/internal/source.ts","../src/internal/review-agent.ts","../src/internal/review-units.ts","../src/internal/fan-out.ts","../src/internal/fingerprint.ts","../src/internal/review-state.ts","../src/internal/retirement.ts","../src/internal/github.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\n// ---------------------------------------------------------------------------\n// Changed-file and unified-diff primitives shared by the tool surface, the\n// publication planner, and the GitHub adapter. The parser is deterministic\n// and bounded; it never throws on malformed hunks — unparseable patch text\n// simply yields no commentable lines, which fails findings closed.\n// ---------------------------------------------------------------------------\n\n/** A repository-relative file path as transported values carry it. */\nexport const ChangedPath = Schema.NonEmptyString.check(Schema.isMaxLength(512));\n\n/** GitHub's changed-file status vocabulary, kept verbatim. */\nexport const ChangedFileStatus = Schema.Literals([\n \"added\",\n \"removed\",\n \"modified\",\n \"renamed\",\n \"copied\",\n \"changed\",\n \"unchanged\",\n]);\n\n/** One file changed by the pull request, with its optional textual patch. */\nexport class ChangedFile extends Schema.Class<ChangedFile>(\"@effect-agent/pr-review/ChangedFile\")({\n path: ChangedPath,\n status: ChangedFileStatus,\n additions: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n deletions: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** Present for renames/copies: the path the file previously had. */\n previousPath: Schema.optionalKey(ChangedPath),\n /** Unified-diff hunks; absent for binary or oversized files. */\n patch: Schema.optionalKey(Schema.String),\n}) {}\n\n/** One parsed line of a unified diff, with both coordinate systems. */\nexport interface PatchLine {\n readonly kind: \"context\" | \"add\" | \"del\";\n readonly oldLine: number | undefined;\n readonly newLine: number | undefined;\n readonly text: string;\n}\n\nconst HUNK_HEADER = /^@@ -(\\d+)(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/;\n\n/**\n * Parse unified-diff hunk text into coordinate-tagged lines. Lines outside a\n * recognized hunk header are ignored rather than guessed at.\n */\nexport const parsePatch = (patch: string): ReadonlyArray<PatchLine> => {\n const lines: Array<PatchLine> = [];\n let oldLine = 0;\n let newLine = 0;\n let inHunk = false;\n for (const raw of patch.split(\"\\n\")) {\n const header = HUNK_HEADER.exec(raw);\n if (header !== null) {\n oldLine = Number(header[1]);\n newLine = Number(header[2]);\n inHunk = true;\n continue;\n }\n if (!inHunk) continue;\n if (raw.startsWith(\"+\")) {\n lines.push({ kind: \"add\", oldLine: undefined, newLine, text: raw.slice(1) });\n newLine += 1;\n } else if (raw.startsWith(\"-\")) {\n lines.push({ kind: \"del\", oldLine, newLine: undefined, text: raw.slice(1) });\n oldLine += 1;\n } else if (raw.startsWith(\" \") || raw === \"\") {\n lines.push({ kind: \"context\", oldLine, newLine, text: raw.slice(1) });\n oldLine += 1;\n newLine += 1;\n } else if (raw.startsWith(\"\\\\\")) {\n // \"\\" — metadata, not a diff line.\n } else {\n // Unrecognized content ends the current hunk conservatively.\n inHunk = false;\n }\n }\n return lines;\n};\n\n/**\n * The new-file line numbers a GitHub review comment may anchor to on the\n * RIGHT side: every added or context line that appears in the diff.\n */\nexport const commentableLines = (patch: string): ReadonlySet<number> => {\n const lines = new Set<number>();\n for (const line of parsePatch(patch)) {\n if (line.newLine !== undefined) lines.add(line.newLine);\n }\n return lines;\n};\n\n/**\n * Render a patch with explicit RIGHT-side line numbers so the model can\n * anchor findings without arithmetic. `R<n>` marks a line that exists in the\n * new version of the file (`+` added, blank context); deleted lines keep a\n * bare `-` marker and no number.\n */\nexport const annotatePatch = (patch: string): string => {\n const output: Array<string> = [];\n let oldLine = 0;\n let newLine = 0;\n let inHunk = false;\n for (const raw of patch.split(\"\\n\")) {\n const header = HUNK_HEADER.exec(raw);\n if (header !== null) {\n oldLine = Number(header[1]);\n newLine = Number(header[2]);\n inHunk = true;\n output.push(raw);\n continue;\n }\n if (!inHunk) continue;\n if (raw.startsWith(\"+\")) {\n output.push(`R${newLine} + ${raw.slice(1)}`);\n newLine += 1;\n } else if (raw.startsWith(\"-\")) {\n output.push(` - ${raw.slice(1)}`);\n oldLine += 1;\n } else if (raw.startsWith(\" \") || raw === \"\") {\n output.push(`R${newLine} ${raw.slice(1)}`);\n oldLine += 1;\n newLine += 1;\n } else if (raw.startsWith(\"\\\\\")) {\n output.push(` ${raw}`);\n } else {\n inHunk = false;\n }\n }\n return output.join(\"\\n\");\n};\n","import { Context, Effect, Schema } from \"effect\";\n\nimport { ChangedFile } from \"./diff.ts\";\n\n// ---------------------------------------------------------------------------\n// The pull-request source port: everything the review tools may observe about\n// one pull request. The live adapter speaks the GitHub REST API; the fixture\n// adapter (testing entry) serves an in-memory pull request so ordinary gates\n// and dry runs need no network or credential.\n// ---------------------------------------------------------------------------\n\n/** Reading a file head version larger than this is refused, never truncated silently. */\nexport const MAX_FILE_CHARS = 200_000;\n\n/** The changeset surface is bounded; larger pull requests fail typed. */\nexport const MAX_CHANGED_FILES = 300;\n\n/** Pull-request identity and framing shown to the agent as its mission. */\nexport class PullRequestMetadata extends Schema.Class<PullRequestMetadata>(\n \"@effect-agent/pr-review/PullRequestMetadata\",\n)({\n /** `owner/name`, exactly as GitHub renders it. */\n repository: Schema.NonEmptyString.check(Schema.isMaxLength(200)),\n number: Schema.Int.check(Schema.isGreaterThan(0)),\n title: Schema.String.check(Schema.isMaxLength(400)),\n /** Author-provided description; empty when the author left none. */\n body: Schema.String.check(Schema.isMaxLength(20_000)),\n baseRef: Schema.NonEmptyString.check(Schema.isMaxLength(300)),\n /** Exact base commit used to validate persisted incremental-review lineage. */\n baseSha: Schema.optionalKey(Schema.NonEmptyString.check(Schema.isMaxLength(64))),\n headRef: Schema.NonEmptyString.check(Schema.isMaxLength(300)),\n headSha: Schema.NonEmptyString.check(Schema.isMaxLength(64)),\n /** GitHub's own changed-file total; may exceed what `changedFiles` returns. */\n totalChangedFiles: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n}) {}\n\n/** The upstream source failed: API error, network fault, or malformed payload. */\nexport class PullRequestSourceFailure extends Schema.TaggedError<PullRequestSourceFailure>()(\n \"PullRequestSourceFailure\",\n {\n operation: Schema.String,\n reason: Schema.String,\n },\n) {\n override get message() {\n return `Pull-request source operation '${this.operation}' failed: ${this.reason}`;\n }\n}\n\n/** A model-supplied path or range was invalid; always fail-closed (SEC-007). */\nexport class ReviewInputViolation extends Schema.TaggedError<ReviewInputViolation>()(\n \"ReviewInputViolation\",\n {\n input: Schema.String,\n reason: Schema.String,\n },\n) {\n override get message() {\n return `Rejected review input '${this.input}': ${this.reason}`;\n }\n}\n\nconst BACKSLASH = String.fromCharCode(92);\n\n/**\n * Normalize and validate one model-supplied repository-relative path.\n * Absolute paths, drive letters, backslashes, empty segments, `.` and `..`\n * segments are all violations — never silently fixed. The changeset list is\n * the real allowlist; this check is defense in depth for URL construction.\n */\nexport const normalizeRepoRelativePath = (\n path: string,\n): Effect.Effect<string, ReviewInputViolation> => {\n const fail = (reason: string) => Effect.fail(ReviewInputViolation.make({ input: path, reason }));\n if (path.length === 0 || path.length > 512) {\n return fail(\"Path length is out of bounds.\");\n }\n if (path.includes(BACKSLASH)) {\n return fail(\"Path contains a forbidden backslash.\");\n }\n if (path.startsWith(\"/\") || /^[A-Za-z]:/.test(path)) {\n return fail(\"Path must be repository-relative, not absolute.\");\n }\n const segments = path.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\" || segment === \".\" || segment === \"..\") {\n return fail(\"Path segments must not be empty, '.', or '..'.\");\n }\n }\n return Effect.succeed(segments.join(\"/\"));\n};\n\n/** Read-only view of one pull request; the only repository access tools get. */\nexport class PullRequestSource extends Context.Service<\n PullRequestSource,\n {\n readonly metadata: Effect.Effect<PullRequestMetadata, PullRequestSourceFailure>;\n /** Files exposed to the model for this run (full PR or selected delta). */\n readonly changedFiles: Effect.Effect<ReadonlyArray<ChangedFile>, PullRequestSourceFailure>;\n /** Full current PR diff used only for host-side anchor/state validation. */\n readonly anchorFiles: Effect.Effect<ReadonlyArray<ChangedFile>, PullRequestSourceFailure>;\n /**\n * The head-version content of one CHANGED file. Paths outside the\n * changeset are violations: the reviewer reads the change, not the tree.\n */\n readonly readFile: (\n path: string,\n ) => Effect.Effect<string, PullRequestSourceFailure | ReviewInputViolation>;\n }\n>()(\"@effect-agent/pr-review/PullRequestSource\") {}\n","import { Effect, Schema } from \"effect\";\nimport { Agent, AgentPolicy, ToolExecutionClass } from \"effect-agent\";\nimport { Tool, Toolkit } from \"effect/unstable/ai\";\n\nimport { annotatePatch, ChangedFileStatus, ChangedPath } from \"./diff.ts\";\nimport {\n normalizeRepoRelativePath,\n PullRequestSource,\n PullRequestSourceFailure,\n ReviewInputViolation,\n} from \"./source.ts\";\n\n// ---------------------------------------------------------------------------\n// The pull-request reviewer: a bounded, read-only agent. Every tool observes\n// the pull request through the PullRequestSource port; nothing the model can\n// call mutates anything. Publishing the review happens OUTSIDE the agent\n// loop, after the finding anchors have been validated against the real diff\n// (model output is untrusted input, AGENTS.md rule 11).\n// ---------------------------------------------------------------------------\n\n/** The hard findings bound carried by the CodeReview schema. */\nexport const MAX_FINDINGS = 20;\n\n/** The hard non-anchored-concerns bound carried by the CodeReview schema. */\nexport const MAX_CONCERNS = 10;\n\n/** Annotated patches larger than this are truncated with an explicit marker. */\nconst MAX_PATCH_CHARS = 60_000;\n\n/** One `read_file` slice never exceeds this many lines. */\nconst MAX_SLICE_LINES = 1_000;\nconst DEFAULT_SLICE_LINES = 400;\n\n// ---------------------------------------------------------------------------\n// Tool surface.\n// ---------------------------------------------------------------------------\n\nexport class ChangedFileSummary extends Schema.Class<ChangedFileSummary>(\n \"@effect-agent/pr-review/ChangedFileSummary\",\n)({\n path: ChangedPath,\n status: ChangedFileStatus,\n additions: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n deletions: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n hasTextualDiff: Schema.Boolean,\n}) {}\n\nexport class ChangedFilesView extends Schema.Class<ChangedFilesView>(\n \"@effect-agent/pr-review/ChangedFilesView\",\n)({\n totalFiles: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** True when the pull request has more changed files than are listed here. */\n truncated: Schema.Boolean,\n files: Schema.Array(ChangedFileSummary).check(Schema.isMaxLength(300)),\n}) {}\n\nexport class ListChangedFilesQuery extends Schema.Class<ListChangedFilesQuery>(\n \"@effect-agent/pr-review/ListChangedFilesQuery\",\n)({\n /** Explicit constant keeps the zero-choice operation compatible with strict provider schemas. */\n scope: Schema.Literal(\"all\"),\n}) {}\n\nexport const ListChangedFiles = Tool.make(\"list_changed_files\", {\n description:\n \"List every file changed by this pull request with its status, line counts, and whether a textual diff is available.\",\n parameters: ListChangedFilesQuery,\n success: ChangedFilesView,\n failure: PullRequestSourceFailure,\n failureMode: \"error\",\n dependencies: [PullRequestSource],\n}).annotate(ToolExecutionClass, \"readonly\");\n\nexport class FileDiffQuery extends Schema.Class<FileDiffQuery>(\n \"@effect-agent/pr-review/FileDiffQuery\",\n)({\n path: ChangedPath,\n}) {}\n\nexport class FileDiffView extends Schema.Class<FileDiffView>(\n \"@effect-agent/pr-review/FileDiffView\",\n)({\n path: ChangedPath,\n status: ChangedFileStatus,\n /**\n * The unified diff with explicit RIGHT-side line numbers: `R<n>` marks a\n * line present in the new file version (only those may anchor findings);\n * `-` marks removed lines. Empty when no textual diff exists.\n */\n annotatedPatch: Schema.String,\n truncated: Schema.Boolean,\n}) {}\n\n// Read failures stay model-visible results (\"return\"), never run-killers:\n// a model asking for an out-of-changeset path is expected untrusted-input\n// behavior, and the fail-closed answer is a typed refusal it can correct —\n// aborting the whole review on one bad path guess would be fragility, not\n// security (the run stays bounded by AgentPolicy regardless).\nexport const ReadFileDiff = Tool.make(\"read_file_diff\", {\n description:\n \"Read the annotated unified diff of one changed file. Lines marked R<number> exist in the new version and are the only valid finding anchors.\",\n parameters: FileDiffQuery,\n success: FileDiffView,\n failure: Schema.Union([PullRequestSourceFailure, ReviewInputViolation]),\n failureMode: \"return\",\n dependencies: [PullRequestSource],\n}).annotate(ToolExecutionClass, \"readonly\");\n\nexport class FileSliceQuery extends Schema.Class<FileSliceQuery>(\n \"@effect-agent/pr-review/FileSliceQuery\",\n)({\n path: ChangedPath,\n /** 1-based first line to read; defaults to 1. */\n startLine: Schema.optionalKey(Schema.Int.check(Schema.isGreaterThan(0))),\n /** Number of lines to read; defaults to 400, capped at 1000. */\n maxLines: Schema.optionalKey(\n Schema.Int.check(Schema.isGreaterThan(0)).check(Schema.isLessThanOrEqualTo(MAX_SLICE_LINES)),\n ),\n}) {}\n\nexport class FileSlice extends Schema.Class<FileSlice>(\"@effect-agent/pr-review/FileSlice\")({\n path: ChangedPath,\n startLine: Schema.Int.check(Schema.isGreaterThan(0)),\n endLine: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n totalLines: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** Slice content with each line prefixed by its 1-based line number. */\n content: Schema.String,\n}) {}\n\nexport const ReadFile = Tool.make(\"read_file\", {\n description:\n \"Read a numbered slice of the NEW (head) version of one changed file, for context around the diff. Only files in the changeset are readable.\",\n parameters: FileSliceQuery,\n success: FileSlice,\n failure: Schema.Union([PullRequestSourceFailure, ReviewInputViolation]),\n failureMode: \"return\",\n dependencies: [PullRequestSource],\n}).annotate(ToolExecutionClass, \"readonly\");\n\nexport const ReviewToolkit = Toolkit.make(ListChangedFiles, ReadFileDiff, ReadFile);\n\n/**\n * The `list_changed_files` handler, shared by the flat reviewer's toolkit and\n * any extended toolkit built by the configuration factory.\n */\nexport const listChangedFilesHandler = (_query: ListChangedFilesQuery) =>\n Effect.gen(function* () {\n const source = yield* PullRequestSource;\n const files = yield* source.changedFiles;\n const metadata = yield* source.metadata;\n return ChangedFilesView.make({\n totalFiles: metadata.totalChangedFiles,\n truncated: files.length < metadata.totalChangedFiles,\n files: files.map((file) =>\n ChangedFileSummary.make({\n path: file.path,\n status: file.status,\n additions: file.additions,\n deletions: file.deletions,\n hasTextualDiff: file.patch !== undefined,\n }),\n ),\n });\n });\n\n/**\n * The `read_file_diff` handler, shared verbatim by the flat reviewer's\n * toolkit and the fan-out child's toolkit (fan-out.ts).\n */\nexport const readFileDiffHandler = (query: FileDiffQuery) =>\n Effect.gen(function* () {\n const source = yield* PullRequestSource;\n const relative = yield* normalizeRepoRelativePath(query.path);\n const files = yield* source.changedFiles;\n const file = files.find((candidate) => candidate.path === relative);\n if (file === undefined) {\n return yield* ReviewInputViolation.make({\n input: relative,\n reason: \"Path is not part of this pull request's changeset.\",\n });\n }\n const annotated = file.patch === undefined ? \"\" : annotatePatch(file.patch);\n const truncated = annotated.length > MAX_PATCH_CHARS;\n return FileDiffView.make({\n path: file.path,\n status: file.status,\n annotatedPatch: truncated\n ? `${annotated.slice(0, MAX_PATCH_CHARS)}\\n[diff truncated]`\n : annotated,\n truncated,\n });\n });\n\n/**\n * The `read_file` handler, shared verbatim by the flat reviewer's toolkit\n * and the fan-out child's toolkit (fan-out.ts).\n */\nexport const readFileHandler = (query: FileSliceQuery) =>\n Effect.gen(function* () {\n const source = yield* PullRequestSource;\n const relative = yield* normalizeRepoRelativePath(query.path);\n const content = yield* source.readFile(relative);\n const lines = content.split(\"\\n\");\n const startLine = query.startLine ?? 1;\n const maxLines = query.maxLines ?? DEFAULT_SLICE_LINES;\n if (startLine > lines.length) {\n return yield* ReviewInputViolation.make({\n input: `${relative}:${startLine}`,\n reason: `startLine is beyond the end of the file (${lines.length} lines).`,\n });\n }\n const slice = lines.slice(startLine - 1, startLine - 1 + maxLines);\n const endLine = startLine + slice.length - 1;\n return FileSlice.make({\n path: relative,\n startLine,\n endLine,\n totalLines: lines.length,\n content: slice\n .map((text, index) => `${String(startLine + index).padStart(5)} ${text}`)\n .join(\"\\n\"),\n });\n });\n\nexport const ReviewToolkitLayer = ReviewToolkit.toLayer({\n list_changed_files: listChangedFilesHandler,\n read_file_diff: readFileDiffHandler,\n read_file: readFileHandler,\n});\n\n// ---------------------------------------------------------------------------\n// Mission input and review output contracts.\n// ---------------------------------------------------------------------------\n\nexport class ReviewMission extends Schema.Class<ReviewMission>(\n \"@effect-agent/pr-review/ReviewMission\",\n)({\n repository: Schema.NonEmptyString.check(Schema.isMaxLength(200)),\n number: Schema.Int.check(Schema.isGreaterThan(0)),\n title: Schema.String.check(Schema.isMaxLength(400)),\n body: Schema.String.check(Schema.isMaxLength(20_000)),\n baseRef: Schema.NonEmptyString.check(Schema.isMaxLength(300)),\n headRef: Schema.NonEmptyString.check(Schema.isMaxLength(300)),\n changedFileCount: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n}) {}\n\nexport const FindingSeverity = Schema.Literals([\"blocking\", \"important\", \"nit\"]);\nexport type FindingSeverity = typeof FindingSeverity.Type;\n\nexport class ReviewFinding extends Schema.Class<ReviewFinding>(\n \"@effect-agent/pr-review/ReviewFinding\",\n)({\n path: ChangedPath,\n /** 1-based line numbers in the NEW file version; must appear in the diff. */\n startLine: Schema.Int.check(Schema.isGreaterThan(0)),\n endLine: Schema.Int.check(Schema.isGreaterThan(0)),\n severity: FindingSeverity,\n title: Schema.NonEmptyString.check(Schema.isMaxLength(120)),\n body: Schema.NonEmptyString.check(Schema.isMaxLength(2_000)),\n /** Replacement for exactly lines startLine..endLine; omit when unsure. */\n suggestion: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(2_000))),\n}) {}\n\nexport const ReviewVerdict = Schema.Literals([\"approve\", \"comment\", \"request-changes\"]);\nexport type ReviewVerdict = typeof ReviewVerdict.Type;\n\n/**\n * A concern with no diff line to anchor to: a missing deletion or cleanup,\n * rollout or migration sequencing, a coverage gap the diff implies but does\n * not add, or a scope question only the author can answer. Rendered as a\n * review-body section — never as an inline comment, so it needs no anchor and\n * is never demoted.\n */\nexport class ReviewConcern extends Schema.Class<ReviewConcern>(\n \"@effect-agent/pr-review/ReviewConcern\",\n)({\n severity: FindingSeverity,\n title: Schema.NonEmptyString.check(Schema.isMaxLength(120)),\n body: Schema.NonEmptyString.check(Schema.isMaxLength(2_000)),\n}) {}\n\nexport class CodeReview extends Schema.Class<CodeReview>(\"@effect-agent/pr-review/CodeReview\")({\n summary: Schema.NonEmptyString.check(Schema.isMaxLength(4_000)),\n verdict: ReviewVerdict,\n findings: Schema.Array(ReviewFinding).check(Schema.isMaxLength(MAX_FINDINGS)),\n /** Non-anchorable concerns; absent when the review raises none. */\n concerns: Schema.optionalKey(Schema.Array(ReviewConcern).check(Schema.isMaxLength(MAX_CONCERNS))),\n}) {}\n\n// ---------------------------------------------------------------------------\n// Instructions. Live models diverge wherever the contract is implicit, so the\n// exact JSON shape, the anchor rule, and the suggestion rule are all spelled\n// out with types. Consumer guidance is injected BETWEEN the mission framing\n// and the procedure — it can widen what the reviewer pays attention to, but\n// the machine contract (anchor rule, JSON shape, bounds) is always appended\n// by this builder and cannot be edited out.\n// ---------------------------------------------------------------------------\n\n/** Consumer-supplied domain guidance: static lines or a function of the mission. */\nexport type ReviewGuidance =\n | string\n | ReadonlyArray<string>\n | ((mission: ReviewMission) => string | ReadonlyArray<string>);\n\nexport const resolveGuidance = (\n guidance: ReviewGuidance | undefined,\n mission: ReviewMission,\n): ReadonlyArray<string> => {\n if (guidance === undefined) return [];\n const value = typeof guidance === \"function\" ? guidance(mission) : guidance;\n const lines = typeof value === \"string\" ? [value] : value;\n return lines.filter((line) => line.length > 0);\n};\n\nexport interface ReviewInstructionOptions {\n readonly guidance?: ReviewGuidance | undefined;\n /** Advertised findings bound; clamped to the CodeReview schema cap. */\n readonly maxFindings?: number | undefined;\n}\n\n/** Clamp a configured findings bound into the schema-supported range. */\nexport const clampMaxFindings = (maxFindings: number | undefined): number =>\n maxFindings === undefined\n ? MAX_FINDINGS\n : Math.min(MAX_FINDINGS, Math.max(1, Math.trunc(maxFindings)));\n\n/** Build the flat reviewer's instructions with optional consumer guidance. */\nexport const makeReviewInstructions =\n (options: ReviewInstructionOptions = {}) =>\n (mission: ReviewMission): string => {\n const maxFindings = clampMaxFindings(options.maxFindings);\n return [\n `You are a senior code reviewer for pull request #${mission.number} (\"${mission.title}\") in ${mission.repository}, merging ${mission.headRef} into ${mission.baseRef}. It changes ${mission.changedFileCount} file(s).`,\n mission.body.length > 0\n ? `Author description:\\n${mission.body}`\n : \"The author provided no description.\",\n ...resolveGuidance(options.guidance, mission),\n \"Work in this order:\",\n \"1. Call list_changed_files once to see the changeset.\",\n \"2. Call read_file_diff for every file you review. In its output, only lines marked R<number> exist in the new version; those numbers are the only valid values for startLine and endLine. Never anchor a finding to a removed (-) line.\",\n \"3. Call read_file when you need surrounding context the diff does not show. ONLY files in the changeset are readable: a request for any other path (an import, a neighbor, a config) returns a failed result — do not retry it; reason from the diff instead and note the gap honestly in your summary when it matters.\",\n \"4. Review for real defects first: correctness, security, concurrency, resource leaks, error handling, API misuse. Style nits are least important. Do not praise; do not restate the diff.\",\n \"When the diff adds or changes a test, check that it can actually fail: a test that would still pass with the bug present is theatre, not coverage. The usual tell is a loose assertion standing where an exact one belongs — >= or a truthiness check over an expected value, or a snapshot that absorbs whatever it is handed.\",\n \"Go shallow only when the diff has no behavioral surface at all: doc typos, formatting, lockfile or generated-code regeneration, a mechanical rename. Line count is not the signal — a one-line change to auth, money, SQL, a comparison operator, or a config default is not trivial.\",\n \"Drop bloat-shaped findings before reporting: defensive checks for cases that cannot happen, abstractions used once, comments restating obvious code, tests asserting tautologies, just-in-case guards. A finding must be sound, correct, and worth acting on; prefer an explicit keep over an invented finding.\",\n '5. After collecting anchored findings, deliberately scan for concerns with NO line to point at: deletion or cleanup plans for code the diff replaces, rollout or migration sequencing, coverage gaps the diff implies but does not add, scope questions only the author can answer. Report each as a \"concern\", never as a finding with an invented anchor; report none when none exist.',\n '6. Then return ONLY a JSON object — no Markdown fences, no prose before or after — exactly this shape: {\"summary\": <string, 1-3 paragraphs of overall assessment>, \"verdict\": <\"approve\" | \"comment\" | \"request-changes\">, \"findings\": [{\"path\": <string, a changed file path>, \"startLine\": <integer, an R-marked new-file line>, \"endLine\": <integer, >= startLine, same file, R-marked>, \"severity\": <\"blocking\" | \"important\" | \"nit\">, \"title\": <string, <= 120 chars>, \"body\": <string, why it matters and what to do>, \"suggestion\": <string, OPTIONAL: replacement text for exactly lines startLine..endLine, ready to commit>}], \"concerns\": <array, OPTIONAL: [{\"severity\": <\"blocking\" | \"important\" | \"nit\">, \"title\": <string, <= 120 chars>, \"body\": <string>}], only for step-5 concerns with no valid anchor — never duplicate a finding here>}.',\n `Report at most ${maxFindings} findings and at most ${MAX_CONCERNS} concerns; prefer the most important ones. An empty findings array with verdict \"approve\" is a valid review. Include \"suggestion\" only when you are confident the replacement compiles and preserves intent; its text must contain the full replacement for every line in the range and nothing else.`,\n 'Use verdict \"request-changes\" only when at least one finding or concern is \"blocking\". Line anchors you invent will be discarded, so copy R-numbers from read_file_diff output.',\n ].join(\"\\n\");\n };\n\n/** The default flat-reviewer instructions: no guidance, schema-cap findings. */\nexport const reviewInstructions = makeReviewInstructions();\n\n/** The default flat-reviewer execution bounds. */\nexport const defaultReviewPolicy = AgentPolicy.make({\n maxTurns: 12,\n maxToolCalls: 24,\n maxDuration: \"8 minutes\",\n toolConcurrency: 2,\n tokenBudget: 300_000,\n // Keep enough output/summary headroom for the 200k-class provider window;\n // tool-heavy histories prune before the engine spends a summarization call.\n contextTokenLimit: 150_000,\n // Budget soft landing (RUN-018): an exhausted reviewer returns its partial\n // review on one final tool-free turn instead of failing the whole run.\n onExhaustion: \"final-answer\",\n});\n\n// ---------------------------------------------------------------------------\n// Agent Definition: model-agnostic (D-027); bindings are created by callers\n// or by the configuration factory.\n// ---------------------------------------------------------------------------\n\nexport const PullRequestReviewer = Agent.define(\"pr-reviewer\", {\n input: ReviewMission,\n output: CodeReview,\n instructions: reviewInstructions,\n toolkit: ReviewToolkit,\n policy: defaultReviewPolicy,\n description:\n \"Review one pull request read-only: list the changeset, read annotated diffs and head-file context, and return a structured, line-anchored code review.\",\n metadata: { deploymentClass: \"E\", surface: \"read-only\" },\n});\n","import { Schema } from \"effect\";\n\nimport type { ChangedFile } from \"./diff.ts\";\nimport { ChangedPath } from \"./diff.ts\";\nimport type { FindingSeverity } from \"./review-agent.ts\";\nimport { ReviewFinding } from \"./review-agent.ts\";\n\n// ---------------------------------------------------------------------------\n// Pure, deterministic planning for the fan-out reviewer: group the changeset\n// into bounded review units (the work one delegated child reviews) and merge\n// the children's findings back into one bounded review. Both operations are\n// plain functions so tests pin them directly and the coordinator's tool\n// surface stays deterministic — grouping is an algorithm, not model prose.\n// ---------------------------------------------------------------------------\n\n/** The delegation fan-out bound: one parent Run spawns at most this many children. */\nexport const MAX_REVIEW_UNITS = 8;\n\n/** A unit never carries more files than this, regardless of their size. */\nexport const MAX_UNIT_FILES = 12;\n\n/** Soft changed-line budget per unit; a single oversized file still gets its own unit. */\nexport const UNIT_CHANGED_LINE_BUDGET = 800;\n\n/** Flat per-file cost so many tiny files still spread across units. */\nconst FILE_OVERHEAD_LINES = 20;\n\n/** The merged review never exceeds the `CodeReview` findings bound. */\nexport const MAX_MERGED_FINDINGS = 20;\n\nexport const ReviewUnitId = Schema.NonEmptyString.check(Schema.isMaxLength(32));\n\n/** One bounded slice of the changeset delegated to one child reviewer. */\nexport class ReviewUnit extends Schema.Class<ReviewUnit>(\"@effect-agent/pr-review/ReviewUnit\")({\n unitId: ReviewUnitId,\n paths: Schema.Array(ChangedPath)\n .check(Schema.isMinLength(1))\n .check(Schema.isMaxLength(MAX_UNIT_FILES)),\n /** additions + deletions across the unit's files, for honest sizing. */\n changedLines: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n}) {}\n\n/** The complete deterministic fan-out plan over one changeset. */\nexport class ReviewUnitPlan extends Schema.Class<ReviewUnitPlan>(\n \"@effect-agent/pr-review/ReviewUnitPlan\",\n)({\n totalFiles: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** True when the source returned fewer files than the pull request has. */\n truncated: Schema.Boolean,\n units: Schema.Array(ReviewUnit).check(Schema.isMaxLength(MAX_REVIEW_UNITS)),\n /** Changed files without a textual diff; no finding can anchor to them. */\n undiffablePaths: Schema.Array(ChangedPath).check(Schema.isMaxLength(300)),\n /**\n * Diffable files beyond the fan-out capacity (MAX_REVIEW_UNITS units of\n * MAX_UNIT_FILES files). Never silently dropped: the coordinator must name\n * them as unreviewed in its summary.\n */\n unassignedPaths: Schema.Array(ChangedPath).check(Schema.isMaxLength(300)),\n}) {}\n\nconst fileCost = (file: ChangedFile): number =>\n file.additions + file.deletions + FILE_OVERHEAD_LINES;\n\nconst unitOf = (index: number, files: ReadonlyArray<ChangedFile>): ReviewUnit =>\n ReviewUnit.make({\n unitId: `unit-${String(index + 1).padStart(3, \"0\")}`,\n paths: files.map((file) => file.path),\n changedLines: files.reduce((total, file) => total + file.additions + file.deletions, 0),\n });\n\n/**\n * Group the changeset into at most `MAX_REVIEW_UNITS` review units.\n *\n * Deterministic by construction: files are ordered by path (so files sharing\n * a directory become neighbors — directory affinity without a heuristic),\n * then packed greedily in that order under the soft changed-line budget and\n * the hard per-unit file bound. Capacity is finite and explicit:\n *\n * - files without a textual diff are not delegated — no finding can anchor\n * to them (anchor validation demands a parsed patch), so they surface in\n * `undiffablePaths` instead of consuming a child's budget;\n * - diffable files beyond `MAX_REVIEW_UNITS` full units surface in\n * `unassignedPaths` so the review can report them as unreviewed, never\n * silently truncated.\n */\nexport const planReviewUnits = (\n files: ReadonlyArray<ChangedFile>,\n options: { readonly totalChangedFiles: number },\n): ReviewUnitPlan => {\n const ordered = [...files].sort((left, right) => (left.path < right.path ? -1 : 1));\n const diffable = ordered.filter((file) => file.patch !== undefined);\n const undiffable = ordered.filter((file) => file.patch === undefined);\n\n const groups: Array<Array<ChangedFile>> = [];\n const unassigned: Array<ChangedFile> = [];\n let current: Array<ChangedFile> = [];\n let currentCost = 0;\n for (const file of diffable) {\n const cost = fileCost(file);\n const wouldOverflow =\n current.length >= MAX_UNIT_FILES ||\n (current.length > 0 && currentCost + cost > UNIT_CHANGED_LINE_BUDGET);\n if (wouldOverflow) {\n groups.push(current);\n current = [];\n currentCost = 0;\n }\n if (groups.length >= MAX_REVIEW_UNITS) {\n unassigned.push(file);\n continue;\n }\n current.push(file);\n currentCost += cost;\n }\n if (current.length > 0 && groups.length < MAX_REVIEW_UNITS) {\n groups.push(current);\n }\n\n return ReviewUnitPlan.make({\n totalFiles: files.length,\n truncated: files.length < options.totalChangedFiles,\n units: groups.map((group, index) => unitOf(index, group)),\n undiffablePaths: undiffable.map((file) => file.path),\n unassignedPaths: unassigned.map((file) => file.path),\n });\n};\n\nconst severityRank: Record<FindingSeverity, number> = {\n blocking: 0,\n important: 1,\n nit: 2,\n};\n\nconst anchorKey = (finding: ReviewFinding): string =>\n `${finding.path} ${finding.startLine} ${finding.endLine}`;\n\n/**\n * Merge the children's findings into one bounded, deterministic list: dedupe\n * findings sharing an anchor (path + line range) keeping the most severe —\n * and, at equal severity, the first in declaration order — then rank by\n * severity, path, and line, and cap at the `CodeReview` findings bound.\n * This is the merge policy the coordinator's instructions state in prose;\n * pinning it here keeps the policy itself deterministic and testable.\n */\nexport const rankAndDedupeFindings = (\n findings: ReadonlyArray<ReviewFinding>,\n): ReadonlyArray<ReviewFinding> => {\n const byAnchor = new Map<string, ReviewFinding>();\n for (const finding of findings) {\n const key = anchorKey(finding);\n const existing = byAnchor.get(key);\n if (\n existing === undefined ||\n severityRank[finding.severity] < severityRank[existing.severity]\n ) {\n byAnchor.set(key, finding);\n }\n }\n return [...byAnchor.values()]\n .sort((left, right) => {\n const bySeverity = severityRank[left.severity] - severityRank[right.severity];\n if (bySeverity !== 0) return bySeverity;\n if (left.path !== right.path) return left.path < right.path ? -1 : 1;\n return left.startLine - right.startLine;\n })\n .slice(0, MAX_MERGED_FINDINGS);\n};\n","import { Effect, Schema } from \"effect\";\nimport {\n Agent,\n AgentPolicy,\n Subagent,\n SubagentPolicy,\n SubagentRuntime,\n ToolExecutionClass,\n type RuntimeBinding,\n} from \"effect-agent\";\nimport { Tool, Toolkit } from \"effect/unstable/ai\";\n\nimport { ChangedPath } from \"./diff.ts\";\nimport {\n clampMaxFindings,\n CodeReview,\n MAX_CONCERNS,\n ReadFile,\n ReadFileDiff,\n readFileDiffHandler,\n readFileHandler,\n ReviewConcern,\n ReviewFinding,\n ReviewMission,\n} from \"./review-agent.ts\";\nimport {\n MAX_REVIEW_UNITS,\n MAX_UNIT_FILES,\n planReviewUnits,\n ReviewUnitId,\n ReviewUnitPlan,\n} from \"./review-units.ts\";\nimport { PullRequestSource, PullRequestSourceFailure } from \"./source.ts\";\n\n// ---------------------------------------------------------------------------\n// The fan-out reviewer: the same review contract as the flat reviewer, but\n// the diff reading happens in bounded delegated children (S1 attached\n// ephemeral delegation) so no single context window has to hold every diff.\n// A coordinator lists the changeset as deterministic review units, delegates\n// one `delegate_file_review` call per unit, then merges the children's\n// bounded findings into one `CodeReview`. Publication and anchor validation\n// are unchanged: child output is untrusted input like everything else and\n// crosses to the host only through the same fail-closed planPublication path.\n// ---------------------------------------------------------------------------\n\n/** One child returns at most this many findings; the merge caps the total. */\nexport const MAX_CHILD_FINDINGS = 8;\n\n/** One child returns at most this many non-anchored concerns. */\nexport const MAX_CHILD_CONCERNS = 3;\n\n/**\n * One mandatory diff read plus one bounded context read for every path in a\n * maximum-size unit. Keep the child and delegation reservation aligned.\n */\nexport const MAX_FILE_REVIEW_TOOL_CALLS = MAX_UNIT_FILES * 2;\n\n// ---------------------------------------------------------------------------\n// The child: a file reviewer over one unit. Its toolkit is intentionally\n// smaller than the flat reviewer's — diff and head-file reads only, no\n// changeset listing — so a child can never roam beyond its briefed unit\n// despite its observation surface being the whole changeset port.\n// ---------------------------------------------------------------------------\n\nexport const FileReviewToolkit = Toolkit.make(ReadFileDiff, ReadFile);\n\nexport const FileReviewToolkitLayer = FileReviewToolkit.toLayer({\n read_file_diff: readFileDiffHandler,\n read_file: readFileHandler,\n});\n\nconst UnitPaths = Schema.Array(ChangedPath)\n .check(Schema.isMinLength(1))\n .check(Schema.isMaxLength(MAX_UNIT_FILES));\n\n/** The child Agent input: one briefed unit of the changeset. */\nexport class FileReviewBrief extends Schema.Class<FileReviewBrief>(\n \"@effect-agent/pr-review/FileReviewBrief\",\n)({\n unitId: ReviewUnitId,\n paths: UnitPaths,\n focus: Schema.NonEmptyString.check(Schema.isMaxLength(200)),\n}) {}\n\n/** The child Agent output: the briefed unit's bounded findings and concerns. */\nexport class FileReviewReport extends Schema.Class<FileReviewReport>(\n \"@effect-agent/pr-review/FileReviewReport\",\n)({\n unitId: ReviewUnitId,\n findings: Schema.Array(ReviewFinding).check(Schema.isMaxLength(MAX_CHILD_FINDINGS)),\n /** Unit-scoped concerns with no diff line to anchor to. */\n concerns: Schema.optionalKey(\n Schema.Array(ReviewConcern).check(Schema.isMaxLength(MAX_CHILD_CONCERNS)),\n ),\n}) {}\n\n/**\n * Guidance for delegated children must be static: child instructions are a\n * pure function of the brief, and the coordinator's mission never crosses the\n * delegation boundary (context isolation), so mission-dependent guidance\n * cannot be resolved for a child.\n */\nexport interface FanOutInstructionOptions {\n readonly guidance?: string | ReadonlyArray<string> | undefined;\n}\n\nconst staticGuidanceLines = (\n guidance: string | ReadonlyArray<string> | undefined,\n): ReadonlyArray<string> => {\n if (guidance === undefined) return [];\n const lines = typeof guidance === \"string\" ? [guidance] : guidance;\n return lines.filter((line) => line.length > 0);\n};\n\n/** Build the child file-reviewer instructions with optional static guidance. */\nexport const makeFileReviewerInstructions =\n (options: FanOutInstructionOptions = {}) =>\n (brief: FileReviewBrief): string =>\n [\n `You are a code reviewer for one unit of a pull request: unit ${brief.unitId}, covering exactly these changed files: ${brief.paths.join(\", \")}. Focus: ${brief.focus}.`,\n ...staticGuidanceLines(options.guidance),\n \"Work in this order:\",\n \"1. Call read_file_diff for every file in your unit. In its output, only lines marked R<number> exist in the new version; those numbers are the only valid values for startLine and endLine. Never anchor a finding to a removed (-) line.\",\n \"2. Call read_file when you need surrounding context the diff does not show. ONLY files in the changeset are readable: a request for any other path (an import, a neighbor, a config) returns a failed result — do not retry it; reason from the diff instead and note the gap in your report when it matters.\",\n \"3. Review for real defects first: correctness, security, concurrency, resource leaks, error handling, API misuse. Style nits are least important. Do not praise; do not restate the diff.\",\n \"When the diff adds or changes a test, check that it can actually fail: a test that would still pass with the bug present is theatre, not coverage. The usual tell is a loose assertion standing where an exact one belongs — >= or a truthiness check over an expected value, or a snapshot that absorbs whatever it is handed.\",\n \"Drop bloat-shaped findings before reporting: defensive checks for cases that cannot happen, abstractions used once, comments restating obvious code, tests asserting tautologies, just-in-case guards. A finding must be sound, correct, and worth acting on; prefer an explicit keep over an invented finding.\",\n `4. Then return ONLY a JSON object — no Markdown fences, no prose before or after — exactly this shape: {\"unitId\": ${JSON.stringify(brief.unitId)}, \"findings\": [{\"path\": <string, a file in your unit>, \"startLine\": <integer, an R-marked new-file line>, \"endLine\": <integer, >= startLine, same file, R-marked>, \"severity\": <\"blocking\" | \"important\" | \"nit\">, \"title\": <string, <= 120 chars>, \"body\": <string, why it matters and what to do>, \"suggestion\": <string, OPTIONAL: replacement text for exactly lines startLine..endLine, ready to commit>}], \"concerns\": <array, OPTIONAL: [{\"severity\": <\"blocking\" | \"important\" | \"nit\">, \"title\": <string, <= 120 chars>, \"body\": <string>}], only for concerns about YOUR unit's files with no valid line anchor (a missing cleanup, a coverage gap the diff implies, sequencing the diff leaves open) — never duplicate a finding here>}.`,\n `Report at most ${MAX_CHILD_FINDINGS} findings and at most ${MAX_CHILD_CONCERNS} concerns; prefer the most important ones. An empty findings array is a valid report. Never report on files outside your unit. Line anchors you invent will be discarded, so copy R-numbers from read_file_diff output.`,\n ].join(\"\\n\");\n\nexport const fileReviewerInstructions = makeFileReviewerInstructions();\n\n/** The default per-unit child execution bounds. */\nexport const defaultFileReviewerPolicy = AgentPolicy.make({\n maxTurns: 8,\n maxToolCalls: MAX_FILE_REVIEW_TOOL_CALLS,\n maxDuration: \"4 minutes\",\n toolConcurrency: 2,\n tokenBudget: 200_000,\n // Bound one live prompt independently from cumulative usage. The engine\n // prunes old diff/file results before paying for a summary.\n contextTokenLimit: 150_000,\n // Typed exhaustion, deliberately NOT the final-answer soft landing: a\n // review is a coverage claim, and a child whose reads were rejected could\n // still emit schema-valid findings — laundering budget exhaustion into\n // \"reviewed\". Until host-owned evidence proves every mandatory\n // read_file_diff completed, an exhausted child fails typed and its unit\n // stays honestly unreviewed (containment turns that into result data\n // without failing the run).\n onExhaustion: \"fail\",\n});\n\n// ---------------------------------------------------------------------------\n// The delegation: one Effect AI Tool per review unit, with explicit\n// projections and finite bounds (SUB-009). `projectResult` is the\n// declassification boundary — the parent sees the child's bounded findings,\n// never its transcript or the diffs it read.\n// ---------------------------------------------------------------------------\n\n/** The model-decoded delegation parameters: which unit to review. */\nexport class FileReviewRequest extends Schema.Class<FileReviewRequest>(\n \"@effect-agent/pr-review/FileReviewRequest\",\n)({\n unitId: ReviewUnitId,\n paths: UnitPaths,\n}) {}\n\n/** The bounded parent-visible result of one delegated unit review. */\nexport class FileReviewUnitResult extends Schema.Class<FileReviewUnitResult>(\n \"@effect-agent/pr-review/FileReviewUnitResult\",\n)({\n unitId: ReviewUnitId,\n findings: Schema.Array(ReviewFinding).check(Schema.isMaxLength(MAX_CHILD_FINDINGS)),\n /** Unit-scoped concerns with no diff line to anchor to. */\n concerns: Schema.optionalKey(\n Schema.Array(ReviewConcern).check(Schema.isMaxLength(MAX_CHILD_CONCERNS)),\n ),\n}) {}\n\n/**\n * One unit's review failed: the child Run ended in a typed failure (policy\n * bound, output violation, model fault). The marker is bounded and carries no\n * child transcript content beyond the failure tag and message.\n */\nexport class FileReviewUnitFailed extends Schema.TaggedError<FileReviewUnitFailed>()(\n \"FileReviewUnitFailed\",\n {\n childErrorTag: Schema.NonEmptyString.check(Schema.isMaxLength(256)),\n message: Schema.String.check(Schema.isMaxLength(400)),\n },\n) {}\n\n/**\n * Finite per-invocation bounds (SUB-009), aligned with the child's own\n * AgentPolicy: the child's policy is the limit that trips typed; the\n * reservation mirrors it so parent-side accounting stays honest.\n */\nexport const fileReviewPolicy = SubagentPolicy.make({\n maxChildren: MAX_REVIEW_UNITS,\n maxConcurrency: 3,\n maxTurns: 8,\n maxToolCalls: MAX_FILE_REVIEW_TOOL_CALLS,\n maxDuration: \"4 minutes\",\n});\n\nconst delegationDescription =\n \"Delegate the review of one planned unit to a bounded file-reviewer child and return its line-anchored findings. Call it exactly once per unit from list_review_units; never retry a failed unit.\";\n\n/**\n * Total mapping from every expected child Run failure to the declared unit\n * failure (SUB-028): the tag plus a bounded message, nothing else crosses.\n */\nexport const mapFileReviewChildFailure = (failure: {\n readonly _tag: string;\n readonly message?: string;\n}): FileReviewUnitFailed =>\n FileReviewUnitFailed.make({\n childErrorTag: failure._tag,\n message: (failure.message ?? \"\").slice(0, 400),\n });\n\n// ---------------------------------------------------------------------------\n// The coordinator's own tool: the deterministic unit plan over the changeset.\n// Grouping is host code (review-units.ts), not model prose, so fan-out shape\n// and budget honesty stay pinnable in tests.\n// ---------------------------------------------------------------------------\n\nexport class ListReviewUnitsQuery extends Schema.Class<ListReviewUnitsQuery>(\n \"@effect-agent/pr-review/ListReviewUnitsQuery\",\n)({\n /** Explicit constant keeps the zero-choice operation compatible with strict provider schemas. */\n scope: Schema.Literal(\"all\"),\n}) {}\n\nexport const ListReviewUnits = Tool.make(\"list_review_units\", {\n description:\n \"List this pull request's changeset grouped into bounded review units (size-budgeted, directory-affine), plus the files no unit can cover.\",\n parameters: ListReviewUnitsQuery,\n success: ReviewUnitPlan,\n failure: PullRequestSourceFailure,\n failureMode: \"error\",\n dependencies: [PullRequestSource],\n}).annotate(ToolExecutionClass, \"readonly\");\n\nexport const FanOutCoordinatorToolkit = Toolkit.make(ListReviewUnits);\n\nexport const FanOutCoordinatorToolkitLayer = FanOutCoordinatorToolkit.toLayer({\n list_review_units: () =>\n Effect.gen(function* () {\n const source = yield* PullRequestSource;\n const files = yield* source.changedFiles;\n const metadata = yield* source.metadata;\n return planReviewUnits(files, { totalChangedFiles: metadata.totalChangedFiles });\n }),\n});\n\n// ---------------------------------------------------------------------------\n// The coordinator Agent Definition: same mission input and CodeReview output\n// contract as the flat reviewer, so planPublication and anchor validation\n// apply unchanged.\n// ---------------------------------------------------------------------------\n\n/**\n * Build the coordinator's instructions. The same consumer guidance the\n * children receive is injected between the mission framing and the procedure\n * so the merged summary and verdict are shaped by the same review profile,\n * and the configured findings bound reaches the merge step instead of only\n * the host-side trim.\n */\nexport const makeFanOutReviewInstructions =\n (options: FanOutInstructionOptions & { readonly maxFindings?: number | undefined } = {}) =>\n (mission: ReviewMission): string => {\n const maxFindings = clampMaxFindings(options.maxFindings);\n return [\n `You coordinate the review of pull request #${mission.number} (\"${mission.title}\") in ${mission.repository}, merging ${mission.headRef} into ${mission.baseRef}. It changes ${mission.changedFileCount} file(s).`,\n mission.body.length > 0\n ? `Author description:\\n${mission.body}`\n : \"The author provided no description.\",\n ...staticGuidanceLines(options.guidance),\n \"Work in this order:\",\n \"1. Call list_review_units once to get the planned review units.\",\n \"2. Call delegate_file_review EXACTLY once per unit, passing each unit's unitId and paths verbatim. Prefer declaring all delegation calls in one batch. Never review files yourself and never invent units.\",\n '3. A delegation result with \"_tag\" is a FAILED unit. Never retry it; instead your summary MUST name it honestly, e.g. \"unit-002 unreviewed: AgentPolicyError\". The plan\\'s undiffablePaths and unassignedPaths must also be named as not reviewed when present.',\n `4. Merge the successful units' findings: drop duplicates sharing the same path and line range keeping the most severe, rank blocking > important > nit, and keep at most ${maxFindings} findings. Drop bloat-shaped findings during the merge — defensive checks for cases that cannot happen, abstractions used once, comments restating obvious code, tests asserting tautologies; children bias toward recommending changes, and a finding must be sound, correct, and worth acting on to survive.`,\n `5. Merge the units' concerns the same way: drop duplicates keeping the most severe, and keep at most ${MAX_CONCERNS}.`,\n '6. Then return ONLY a JSON object — no Markdown fences, no prose before or after — exactly this shape: {\"summary\": <string, 1-3 paragraphs of overall assessment, including every unreviewed unit or file>, \"verdict\": <\"approve\" | \"comment\" | \"request-changes\">, \"findings\": [{\"path\": <string>, \"startLine\": <integer>, \"endLine\": <integer>, \"severity\": <\"blocking\" | \"important\" | \"nit\">, \"title\": <string, <= 120 chars>, \"body\": <string>, \"suggestion\": <string, OPTIONAL>}], \"concerns\": <array, OPTIONAL: [{\"severity\": <\"blocking\" | \"important\" | \"nit\">, \"title\": <string, <= 120 chars>, \"body\": <string>}], the merged unit concerns>}. Copy findings and concerns verbatim from the delegation results; never invent or edit anchors.',\n 'Use verdict \"request-changes\" only when at least one finding or concern is \"blocking\". An empty findings array with verdict \"approve\" is a valid review when every unit succeeded and found nothing.',\n ].join(\"\\n\");\n };\n\nexport const fanOutReviewInstructions = makeFanOutReviewInstructions();\n\n/** The default fan-out coordinator execution bounds. */\nexport const defaultFanOutPolicy = AgentPolicy.make({\n maxTurns: 6,\n maxToolCalls: 1 + MAX_REVIEW_UNITS,\n maxDuration: \"15 minutes\",\n toolConcurrency: 3,\n // Contained unit failures (SUB-033) are ordinary successful Tool results,\n // so they no longer fold into the repeated-failure counter; the default\n // bound suffices.\n repeatedFailureLimit: 3,\n tokenBudget: 300_000,\n // Child reports can amplify the merge prompt; compact before the provider's\n // 200k-class window becomes the failure boundary.\n contextTokenLimit: 150_000,\n // Budget soft landing (RUN-018): an exhausted coordinator merges what it\n // has into one best-effort review instead of discarding every child report.\n onExhaustion: \"final-answer\",\n});\n\n/** Everything one fan-out configuration is made of, built as one unit so the\n * delegation always targets exactly the child definition that will run. */\nexport interface FanOutReviewSuite {\n readonly child: ReturnType<typeof makeFileReviewerDefinition>;\n readonly parent: ReturnType<typeof makeFanOutReviewerDefinition>;\n readonly delegation: ReturnType<typeof makeFileReviewDelegation>;\n}\n\nconst makeFileReviewerDefinition = (options: FanOutInstructionOptions = {}) =>\n Agent.define(\"pr-file-reviewer\", {\n input: FileReviewBrief,\n output: FileReviewReport,\n instructions: makeFileReviewerInstructions(options),\n toolkit: FileReviewToolkit,\n policy: defaultFileReviewerPolicy,\n description:\n \"Review one bounded unit of a pull request's changeset read-only and return line-anchored findings for exactly those files.\",\n metadata: { deploymentClass: \"E\", surface: \"read-only\" },\n });\n\n/** Options for one coherent fan-out suite: shared guidance plus the merge bound. */\nexport interface FanOutSuiteOptions extends FanOutInstructionOptions {\n readonly maxFindings?: number | undefined;\n}\n\nconst makeFileReviewDelegation = (child: ReturnType<typeof makeFileReviewerDefinition>) =>\n Subagent.define(\"delegate_file_review\", {\n description: delegationDescription,\n target: child,\n parameters: FileReviewRequest,\n success: FileReviewUnitResult,\n failure: FileReviewUnitFailed,\n // First-party containment (SUB-033): a failed unit is model-visible\n // result data instead of a parent-Run-fatal error, so the coordinator\n // reports it honestly and keeps reviewing the other units. This retires\n // the former same-name shadow-Tool workaround (FRICTION #7).\n failureMode: \"return\",\n prepareInput: (request) =>\n Effect.succeed(\n FileReviewBrief.make({\n unitId: request.unitId,\n paths: request.paths,\n focus: \"defects-first: correctness, security, concurrency, resources, error handling\",\n }),\n ),\n // The explicit declassification boundary (SUB-015): exactly the bounded\n // findings and concerns cross to the parent. Whether findings may anchor\n // anywhere is decided host-side by planPublication against the real diff.\n projectResult: (report) =>\n Effect.succeed(\n FileReviewUnitResult.make({\n unitId: report.unitId,\n findings: report.findings,\n ...(report.concerns !== undefined ? { concerns: report.concerns } : {}),\n }),\n ),\n policy: fileReviewPolicy,\n });\n\n/**\n * The coordinator-facing delegation Tool: the delegation's own first-party\n * contained Tool plus the read-only execution class (the delegated child's\n * whole tool surface is read-only). Effect AI resolves handlers by Tool name,\n * so `SubagentRuntime.layer`'s handler serves this annotated copy unchanged.\n */\nconst delegationToolFor = (delegation: ReturnType<typeof makeFileReviewDelegation>) =>\n delegation.tool.annotate(ToolExecutionClass, \"readonly\");\n\nconst makeFanOutReviewerDefinition = (\n options: FanOutSuiteOptions,\n delegation: ReturnType<typeof makeFileReviewDelegation>,\n) =>\n Agent.define(\"pr-fanout-reviewer\", {\n input: ReviewMission,\n output: CodeReview,\n instructions: makeFanOutReviewInstructions(options),\n toolkit: Toolkit.make(ListReviewUnits, delegationToolFor(delegation)),\n policy: defaultFanOutPolicy,\n description:\n \"Coordinate one pull-request review by fanning bounded per-unit file reviews out to delegated children and merging their findings into one structured review.\",\n metadata: { deploymentClass: \"E\", surface: \"read-only\", delegation: \"S1-attached\" },\n });\n\n/** Build one coherent fan-out suite: child, coordinator, and delegation. */\nexport const makeFanOutReviewSuite = (options: FanOutSuiteOptions = {}): FanOutReviewSuite => {\n const child = makeFileReviewerDefinition({ guidance: options.guidance });\n const delegation = makeFileReviewDelegation(child);\n return {\n child,\n parent: makeFanOutReviewerDefinition(options, delegation),\n delegation,\n };\n};\n\nconst defaultSuite = makeFanOutReviewSuite();\n\n/** The default child Agent Definition. */\nexport const FileReviewer = defaultSuite.child;\n\n/** The default coordinator Agent Definition. */\nexport const FanOutReviewer = defaultSuite.parent;\n\n/** The default delegation over the default child. */\nexport const fileReviewDelegation = defaultSuite.delegation;\n\n/** The default coordinator-facing delegation Tool (first-party contained mode). */\nexport const DelegateFileReview = delegationToolFor(fileReviewDelegation);\n\n/** The default coordinator Toolkit. */\nexport const FanOutReviewToolkit = FanOutReviewer.toolkit;\n\n/**\n * The contained failure family the delegation can surface as result data\n * (SUB-033), derived from the delegation itself so the coverage decoder can\n * never diverge from what the runtime actually contains.\n */\nexport const FileReviewDelegationFailure = fileReviewDelegation.containedFailure;\n\n/** Runtime wiring: one delegation plus one explicit child Binding. */\nexport const fanOutHandlersLayerFor =\n (delegation: ReturnType<typeof makeFileReviewDelegation>) =>\n <Provider, ModelProvides, ModelRequires>(\n childBinding: RuntimeBinding<\n typeof FileReviewBrief,\n typeof FileReviewReport,\n ReturnType<typeof makeFileReviewerInstructions>,\n Toolkit.Tools<typeof FileReviewToolkit>,\n Provider,\n ModelProvides,\n ModelRequires\n >,\n ) =>\n SubagentRuntime.layer(delegation, childBinding, {\n mapChildFailure: mapFileReviewChildFailure,\n });\n\n/** Runtime wiring over the default delegation, mirroring the leaf example. */\nexport const fanOutHandlersLayer = fanOutHandlersLayerFor(fileReviewDelegation);\n","import { Effect } from \"effect\";\n\nimport type { ChangedFile } from \"./diff.ts\";\n\n// ---------------------------------------------------------------------------\n// Changeset fingerprinting: dedupe re-reviews of an UNCHANGED effective diff.\n// Repositories that auto-merge the base branch into open pull requests fire\n// `synchronize` on every base update; the head SHA moves but the three-dot\n// changeset the reviewer reads is byte-identical. The fingerprint hashes the\n// (ignore-filtered) changeset together with a prompt signature — everything\n// that shapes the review — so a rebase with no content change skips, while a\n// real change, a conflict resolution, or a guidance change reviews again.\n//\n// The reviewer is deployment class E and owns no storage: the fingerprint is\n// embedded in the posted review body as an invisible HTML comment, so the\n// published review itself is the deduplication state.\n// ---------------------------------------------------------------------------\n\nconst MARKER_PREFIX = \"<!-- effect-agent-pr-review fingerprint=sha256:\";\nconst MARKER_SUFFIX = \" -->\";\nconst MARKER_PATTERN = /<!-- effect-agent-pr-review fingerprint=sha256:([0-9a-f]{64}) -->/g;\n\n/** Render the invisible review-body marker for one fingerprint. */\nexport const renderFingerprintMarker = (fingerprint: string): string =>\n `${MARKER_PREFIX}${fingerprint}${MARKER_SUFFIX}`;\n\n/** The rendered marker length is fixed; publication reserves room for it. */\nexport const FINGERPRINT_MARKER_LENGTH = renderFingerprintMarker(\"0\".repeat(64)).length;\n\n/** Extract the last fingerprint marker in one review body, if any. */\nexport const extractFingerprint = (body: string): string | undefined => {\n let last: string | undefined;\n for (const match of body.matchAll(MARKER_PATTERN)) {\n last = match[1];\n }\n return last;\n};\n\n/** WebCrypto SHA-256; unavailable crypto is a defect, not an expected failure. */\nconst sha256Hex = (text: string): Effect.Effect<string> =>\n Effect.promise(async () => {\n const digest = await globalThis.crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return Array.from(new Uint8Array(digest))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n });\n\nconst FIELD = \"\\u0000\";\nconst RECORD = \"\\u0001\";\nconst SECTION = \"\\u0002\";\n\n/**\n * Canonical changeset encoding: sorted by path so provider ordering never\n * matters, with every review-relevant field of every file.\n */\nconst canonicalChangeset = (files: ReadonlyArray<ChangedFile>): string =>\n files\n .map(\n (file) =>\n `${file.path}${FIELD}${file.status}${FIELD}${String(file.additions)}${FIELD}${String(file.deletions)}${FIELD}${file.patch ?? \"\"}`,\n )\n .sort()\n .join(RECORD);\n\n/**\n * Fingerprint one review's complete input surface: the (already\n * ignore-filtered) changeset plus the caller's prompt signature — the\n * rendered instructions and any review-shaping options the instructions do\n * not carry.\n */\nexport const computeChangesetFingerprint = (\n files: ReadonlyArray<ChangedFile>,\n signature: string,\n): Effect.Effect<string> => sha256Hex(`${canonicalChangeset(files)}${SECTION}${signature}`);\n","import { Context, Effect, Encoding, Layer, Option, Redacted, Result, Schema } from \"effect\";\n\nimport { ChangedFile, ChangedPath } from \"./diff.ts\";\nimport { FindingSeverity, ReviewConcern, ReviewFinding, ReviewMission } from \"./review-agent.ts\";\nimport { PullRequestSource, ReviewInputViolation, type PullRequestMetadata } from \"./source.ts\";\n\n// ---------------------------------------------------------------------------\n// Bounded review continuity. The Action is still deployment class E, but every\n// completed review can publish authenticated state inside its GitHub review body.\n// A later Action run validates the state against the live PR/base lineage and\n// uses a head-to-head comparison to select only newly affected scope.\n// ---------------------------------------------------------------------------\n\nexport const ReviewMode = Schema.Literals([\"incremental\", \"final\"]);\nexport type ReviewMode = typeof ReviewMode.Type;\n\nexport const ReviewScopeMode = Schema.Literals([\"incremental\", \"full\"]);\nexport type ReviewScopeMode = typeof ReviewScopeMode.Type;\n\nexport const GitCommitSha = Schema.NonEmptyString.check(\n Schema.isMaxLength(64),\n Schema.isPattern(/^[0-9a-f]{40,64}$/),\n);\n\nconst Fingerprint = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/));\nconst StoredText = Schema.NonEmptyString.check(Schema.isMaxLength(800));\n\n/** A compact unresolved finding suitable for the bounded review-body marker. */\nexport class StoredReviewFinding extends Schema.Class<StoredReviewFinding>(\n \"@effect-agent/pr-review/StoredReviewFinding\",\n)({\n path: ChangedPath,\n startLine: Schema.Int.check(Schema.isGreaterThan(0)),\n endLine: Schema.Int.check(Schema.isGreaterThan(0)),\n severity: FindingSeverity,\n title: Schema.NonEmptyString.check(Schema.isMaxLength(120)),\n body: StoredText,\n}) {}\n\n/** A compact unresolved non-anchored concern carried until a final audit. */\nexport class StoredReviewConcern extends Schema.Class<StoredReviewConcern>(\n \"@effect-agent/pr-review/StoredReviewConcern\",\n)({\n severity: FindingSeverity,\n title: Schema.NonEmptyString.check(Schema.isMaxLength(120)),\n body: StoredText,\n}) {}\n\n/**\n * Versioned state embedded in one successfully covered review. The reviewed\n * head plus the full-scope fingerprint means every path not represented by an\n * unresolved item is accepted at that head; storing hundreds of path strings\n * separately would not fit GitHub's bounded review body in the worst case.\n */\nexport class ReviewState extends Schema.Class<ReviewState>(\"@effect-agent/pr-review/ReviewState\")({\n version: Schema.Literal(1),\n repository: Schema.NonEmptyString.check(Schema.isMaxLength(200)),\n pullRequestNumber: Schema.Int.check(Schema.isGreaterThan(0)),\n baseRef: Schema.NonEmptyString.check(Schema.isMaxLength(300)),\n baseSha: GitCommitSha,\n headRef: Schema.NonEmptyString.check(Schema.isMaxLength(300)),\n reviewedHeadSha: GitCommitSha,\n profileFingerprint: Fingerprint,\n acceptedScopeFingerprint: Fingerprint,\n reviewedPathCount: Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 300 })),\n unresolvedFindings: Schema.Array(StoredReviewFinding).check(Schema.isMaxLength(20)),\n unresolvedConcerns: Schema.Array(StoredReviewConcern).check(Schema.isMaxLength(10)),\n lastReviewMode: ReviewScopeMode,\n}) {}\n\nexport const toStoredFinding = (finding: ReviewFinding): StoredReviewFinding =>\n StoredReviewFinding.make({\n path: finding.path,\n startLine: finding.startLine,\n endLine: finding.endLine,\n severity: finding.severity,\n title: finding.title,\n body: finding.body.slice(0, 800),\n });\n\nexport const fromStoredFinding = (finding: StoredReviewFinding): ReviewFinding =>\n ReviewFinding.make({\n path: finding.path,\n startLine: finding.startLine,\n endLine: finding.endLine,\n severity: finding.severity,\n title: finding.title,\n body: finding.body,\n });\n\nexport const toStoredConcern = (concern: ReviewConcern): StoredReviewConcern =>\n StoredReviewConcern.make({\n severity: concern.severity,\n title: concern.title,\n body: concern.body.slice(0, 800),\n });\n\nexport const fromStoredConcern = (concern: StoredReviewConcern): ReviewConcern =>\n ReviewConcern.make({ severity: concern.severity, title: concern.title, body: concern.body });\n\nconst STATE_MARKER_PREFIX = \"<!-- effect-agent-pr-review state-v1:\";\nconst STATE_MARKER_SUFFIX = \" -->\";\nconst STATE_MARKER_PATTERN =\n /(?:^|\\n)<!-- effect-agent-pr-review state-v1:([A-Za-z0-9+/]+={0,2})\\.([0-9a-f]{64}) -->$/;\nconst STATE_SIGNATURE_DOMAIN = \"effect-agent-pr-review/state-v1\\u0000\";\nexport const MAX_REVIEW_STATE_MARKER_CHARS = 24_000;\nexport const ReviewStateMarker = Schema.NonEmptyString.check(\n Schema.isMaxLength(MAX_REVIEW_STATE_MARKER_CHARS),\n Schema.isPattern(/^<!-- effect-agent-pr-review state-v1:[A-Za-z0-9+/]+={0,2}\\.[0-9a-f]{64} -->$/),\n).pipe(Schema.brand(\"@effect-agent/pr-review/ReviewStateMarker\"));\nexport type ReviewStateMarker = typeof ReviewStateMarker.Type;\n\nexport class ReviewStateAuthenticationFailure extends Schema.TaggedError<ReviewStateAuthenticationFailure>()(\n \"ReviewStateAuthenticationFailure\",\n {\n operation: Schema.Literals([\"sign\", \"verify\"]),\n reason: Schema.NonEmptyString.check(Schema.isMaxLength(2_048)),\n },\n) {}\n\nexport class ReviewStateMarkerTooLarge extends Schema.TaggedError<ReviewStateMarkerTooLarge>()(\n \"ReviewStateMarkerTooLarge\",\n {\n observedChars: Schema.Int.check(Schema.isGreaterThan(0)),\n maximumChars: Schema.Int.check(Schema.isGreaterThan(0)),\n },\n) {}\n\nexport class ReviewStateAuthenticator extends Context.Service<\n ReviewStateAuthenticator,\n {\n readonly status: \"available\" | \"unavailable\";\n readonly unavailableReason: string | undefined;\n readonly render: (\n state: ReviewState,\n ) => Effect.Effect<\n ReviewStateMarker,\n ReviewStateAuthenticationFailure | ReviewStateMarkerTooLarge\n >;\n readonly extract: (\n body: string,\n ) => Effect.Effect<Option.Option<ReviewState>, ReviewStateAuthenticationFailure>;\n }\n>()(\"@effect-agent/pr-review/ReviewStateAuthenticator\") {}\n\nconst authenticationFailure = (\n operation: \"sign\" | \"verify\",\n cause: unknown,\n): ReviewStateAuthenticationFailure =>\n ReviewStateAuthenticationFailure.make({\n operation,\n reason: String(cause).slice(0, 2_048),\n });\n\nconst hmacKey = (secret: Redacted.Redacted<string>, operation: \"sign\" | \"verify\") =>\n Effect.tryPromise({\n try: () =>\n globalThis.crypto.subtle.importKey(\n \"raw\",\n new TextEncoder().encode(Redacted.value(secret)),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\", \"verify\"],\n ),\n catch: (cause) => authenticationFailure(operation, cause),\n });\n\nconst signatureBytes = (signature: string): ArrayBuffer => {\n const pairs = signature.match(/../g) ?? [];\n const buffer = new ArrayBuffer(pairs.length);\n const bytes = new Uint8Array(buffer);\n for (let index = 0; index < pairs.length; index += 1) {\n bytes[index] = Number.parseInt(pairs[index] ?? \"\", 16);\n }\n return buffer;\n};\n\n/** Validated WebCrypto adapter selected at the Action composition root. */\nexport const webCryptoReviewStateAuthenticatorLayer = (\n secret: Redacted.Redacted<string>,\n): Layer.Layer<ReviewStateAuthenticator> =>\n Layer.succeed(ReviewStateAuthenticator)(\n ReviewStateAuthenticator.of({\n status: \"available\",\n unavailableReason: undefined,\n render: (state) =>\n Effect.gen(function* () {\n const json = yield* Schema.encodeUnknownEffect(Schema.fromJsonString(ReviewState))(\n state,\n ).pipe(Effect.mapError((cause) => authenticationFailure(\"sign\", cause)));\n const payload = Encoding.encodeBase64(json);\n const message = new TextEncoder().encode(`${STATE_SIGNATURE_DOMAIN}${payload}`);\n const key = yield* hmacKey(secret, \"sign\");\n const signature = yield* Effect.tryPromise({\n try: () => globalThis.crypto.subtle.sign(\"HMAC\", key, message),\n catch: (cause) => authenticationFailure(\"sign\", cause),\n });\n const hex = Array.from(new Uint8Array(signature))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const marker = `${STATE_MARKER_PREFIX}${payload}.${hex}${STATE_MARKER_SUFFIX}`;\n if (marker.length > MAX_REVIEW_STATE_MARKER_CHARS) {\n return yield* ReviewStateMarkerTooLarge.make({\n observedChars: marker.length,\n maximumChars: MAX_REVIEW_STATE_MARKER_CHARS,\n });\n }\n return yield* Schema.decodeUnknownEffect(ReviewStateMarker)(marker).pipe(\n Effect.mapError((cause) => authenticationFailure(\"sign\", cause)),\n );\n }),\n extract: (body) => {\n if (body.length > 60_000) return Effect.succeed(Option.none());\n const match = STATE_MARKER_PATTERN.exec(body);\n const payload = match?.[1];\n const signature = match?.[2];\n if (payload === undefined || signature === undefined) return Effect.succeed(Option.none());\n const marker = `${STATE_MARKER_PREFIX}${payload}.${signature}${STATE_MARKER_SUFFIX}`;\n if (!Schema.is(ReviewStateMarker)(marker)) return Effect.succeed(Option.none());\n const json = Result.getOrUndefined(Encoding.decodeBase64String(payload));\n if (json === undefined) return Effect.succeed(Option.none());\n const decoded = Schema.decodeUnknownOption(Schema.fromJsonString(ReviewState))(json);\n if (Option.isNone(decoded)) return Effect.succeed(Option.none());\n const message = new TextEncoder().encode(`${STATE_SIGNATURE_DOMAIN}${payload}`);\n return Effect.gen(function* () {\n const key = yield* hmacKey(secret, \"verify\");\n const valid = yield* Effect.tryPromise({\n try: () =>\n globalThis.crypto.subtle.verify(\"HMAC\", key, signatureBytes(signature), message),\n catch: (cause) => authenticationFailure(\"verify\", cause),\n });\n return valid ? Option.some(decoded.value) : Option.none();\n });\n },\n }),\n );\n\n/** Explicit no-state implementation for hosts without a stable authentication secret. */\nexport const unavailableReviewStateAuthenticatorLayer = (\n reason: string,\n): Layer.Layer<ReviewStateAuthenticator> => {\n const safeReason = reason === \"\" ? \"review-state authentication is unavailable\" : reason;\n return Layer.succeed(ReviewStateAuthenticator)(\n ReviewStateAuthenticator.of({\n status: \"unavailable\",\n unavailableReason: safeReason.slice(0, 1_000),\n render: () =>\n Effect.fail(\n ReviewStateAuthenticationFailure.make({\n operation: \"sign\",\n reason: safeReason.slice(0, 2_048),\n }),\n ),\n extract: () => Effect.succeed(Option.none()),\n }),\n );\n};\n\n/** The bounded result of GitHub's previous-head...current-head comparison. */\nexport class ReviewHeadComparison extends Schema.Class<ReviewHeadComparison>(\n \"@effect-agent/pr-review/ReviewHeadComparison\",\n)({\n status: Schema.Literals([\"ahead\", \"behind\", \"diverged\", \"identical\"]),\n baseSha: GitCommitSha,\n headSha: GitCommitSha,\n mergeBaseSha: GitCommitSha,\n files: Schema.Array(ChangedFile).check(Schema.isMaxLength(300)),\n /** GitHub caps compare-file payloads at 300; equality is conservatively truncated. */\n truncated: Schema.Boolean,\n}) {}\n\n/** Internal review selection applied as a decorator over the full PR source. */\nexport interface ReviewSelection {\n readonly mode: ReviewScopeMode;\n readonly reason: string;\n readonly files: ReadonlyArray<ChangedFile>;\n /** Paths whose changes invalidate prior findings, including paths reverted out of the PR. */\n readonly affectedPaths: ReadonlyArray<string>;\n readonly totalFiles: number;\n readonly baselineSha: string | undefined;\n readonly priorState: ReviewState | undefined;\n readonly profileFingerprint: string;\n /** Action-owned authentication capability, constructed at the composition root. */\n readonly stateAuthenticator?: ReviewStateAuthenticator[\"Service\"] | undefined;\n}\n\nconst fullSelection = (input: {\n readonly reason: string;\n readonly files: ReadonlyArray<ChangedFile>;\n readonly totalFiles: number;\n readonly profileFingerprint: string;\n}): ReviewSelection => ({\n mode: \"full\",\n reason: input.reason,\n files: input.files,\n affectedPaths: input.files.flatMap((file) =>\n file.previousPath === undefined ? [file.path] : [file.path, file.previousPath],\n ),\n totalFiles: input.totalFiles,\n baselineSha: undefined,\n priorState: undefined,\n profileFingerprint: input.profileFingerprint,\n});\n\n/**\n * Validate that persisted state belongs to this exact PR/base lineage and the\n * same review profile. A mismatch is a full-review reason, never an error that\n * silently suppresses review work.\n */\nexport const validateReviewState = (\n state: ReviewState,\n current: PullRequestMetadata,\n profileFingerprint: string,\n): string | undefined => {\n if (state.repository !== current.repository || state.pullRequestNumber !== current.number) {\n return \"stored state belongs to a different pull request\";\n }\n if (current.baseSha === undefined) return \"the current base commit is unavailable\";\n if (state.baseRef !== current.baseRef) return \"the pull request base ref changed\";\n if (state.headRef !== current.headRef) return \"the pull request head ref changed\";\n if (state.profileFingerprint !== profileFingerprint) {\n return \"the reviewer profile or model configuration changed\";\n }\n return undefined;\n};\n\n/** Pure, deterministic range selection with conservative full-review fallbacks. */\nexport const selectReviewRange = (input: {\n readonly requestedMode: ReviewMode;\n readonly current: PullRequestMetadata;\n readonly fullFiles: ReadonlyArray<ChangedFile>;\n readonly profileFingerprint: string;\n readonly priorState: ReviewState | undefined;\n readonly comparison: ReviewHeadComparison | undefined;\n readonly baseComparison?: ReviewHeadComparison | undefined;\n readonly lookupFailure?: string | undefined;\n}): ReviewSelection => {\n const full = (reason: string) =>\n fullSelection({\n reason,\n files: input.fullFiles,\n totalFiles: input.current.totalChangedFiles,\n profileFingerprint: input.profileFingerprint,\n });\n if (input.requestedMode === \"final\") return full(\"explicit final full-diff audit requested\");\n if (input.lookupFailure !== undefined) {\n return full(`stored review state could not be recovered: ${input.lookupFailure}`);\n }\n if (input.priorState === undefined) return full(\"no compatible stored review state was found\");\n const invalid = validateReviewState(input.priorState, input.current, input.profileFingerprint);\n if (invalid !== undefined) return full(invalid);\n const comparison = input.comparison;\n if (comparison === undefined) return full(\"the incremental head comparison was unavailable\");\n if (\n comparison.baseSha !== input.priorState.reviewedHeadSha ||\n comparison.headSha !== input.current.headSha ||\n comparison.mergeBaseSha !== input.priorState.reviewedHeadSha ||\n (comparison.status !== \"ahead\" && comparison.status !== \"identical\")\n ) {\n return full(\"the prior reviewed head is not an ancestor of the current head\");\n }\n if (comparison.truncated) return full(\"the incremental comparison exceeded GitHub's file bound\");\n const affectedPaths = new Set(\n comparison.files.flatMap((file) =>\n file.previousPath === undefined ? [file.path] : [file.path, file.previousPath],\n ),\n );\n let baseReason = \"\";\n if (input.priorState.baseSha !== input.current.baseSha) {\n const baseComparison = input.baseComparison;\n if (baseComparison === undefined) {\n return full(\"the pull request base changed and its lineage comparison was unavailable\");\n }\n if (\n baseComparison.baseSha !== input.priorState.baseSha ||\n baseComparison.headSha !== input.current.baseSha ||\n baseComparison.mergeBaseSha !== input.priorState.baseSha ||\n (baseComparison.status !== \"ahead\" && baseComparison.status !== \"identical\") ||\n baseComparison.truncated\n ) {\n return full(\"the pull request base changed materially or exceeded the comparison bound\");\n }\n for (const file of baseComparison.files) {\n affectedPaths.add(file.path);\n if (file.previousPath !== undefined) affectedPaths.add(file.previousPath);\n }\n baseReason = `; base advanced from ${input.priorState.baseSha.slice(0, 7)} and overlapping PR paths were included`;\n }\n const currentPaths = new Set(\n input.fullFiles.flatMap((file) =>\n file.previousPath === undefined ? [file.path] : [file.path, file.previousPath],\n ),\n );\n const selectedByPath = new Map<string, ChangedFile>();\n for (const file of comparison.files) {\n if (\n currentPaths.has(file.path) ||\n (file.previousPath !== undefined && currentPaths.has(file.previousPath))\n ) {\n selectedByPath.set(file.path, file);\n }\n }\n if (input.priorState.baseSha !== input.current.baseSha) {\n for (const file of input.fullFiles) {\n if (\n affectedPaths.has(file.path) ||\n (file.previousPath !== undefined && affectedPaths.has(file.previousPath))\n ) {\n selectedByPath.set(file.path, file);\n }\n }\n }\n const selectedFiles = [...selectedByPath.values()].sort((left, right) =>\n left.path < right.path ? -1 : left.path > right.path ? 1 : 0,\n );\n return {\n mode: \"incremental\",\n reason: `changes since successfully reviewed head ${input.priorState.reviewedHeadSha.slice(0, 7)}${baseReason}`,\n files: selectedFiles,\n affectedPaths: [...affectedPaths].sort(),\n totalFiles: selectedFiles.length,\n baselineSha: input.priorState.reviewedHeadSha,\n priorState: input.priorState,\n profileFingerprint: input.profileFingerprint,\n };\n};\n\n/** Per-run context consumed by orchestration and publication, not by the model. */\nexport class ReviewExecutionContext extends Context.Service<\n ReviewExecutionContext,\n ReviewSelection\n>()(\"@effect-agent/pr-review/ReviewExecutionContext\") {}\n\n/**\n * Decorate the full source with the selected review range. Full anchor files\n * remain available to host-side publication validation; model tools see only\n * the selected delta and may read head context only for that delta's paths.\n */\nexport const selectedPullRequestSourceLayer = (\n selection: ReviewSelection,\n): Layer.Layer<PullRequestSource, never, PullRequestSource> =>\n Layer.effect(PullRequestSource)(\n Effect.gen(function* () {\n const source = yield* PullRequestSource;\n const selectedPaths = new Set(selection.files.map((file) => file.path));\n return PullRequestSource.of({\n metadata: source.metadata,\n changedFiles: Effect.succeed(selection.files),\n anchorFiles: source.anchorFiles,\n readFile: (path) =>\n selectedPaths.has(path)\n ? source.readFile(path)\n : Effect.fail(\n ReviewInputViolation.make({\n input: path,\n reason: \"Path is outside this incremental review range.\",\n }),\n ),\n });\n }),\n );\n\n/** Profile fingerprints are SHA-256 over configuration-only signatures. */\nexport const computeProfileFingerprint = (signature: string): Effect.Effect<string> =>\n Effect.promise(async () => {\n const digest = await globalThis.crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(signature),\n );\n return Array.from(new Uint8Array(digest))\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n });\n\n/** Build the full-surface mission used only to resolve profile guidance. */\nexport const buildProfileMission = (\n metadata: PullRequestMetadata,\n files: ReadonlyArray<ChangedFile>,\n): ReviewMission =>\n ReviewMission.make({\n repository: metadata.repository,\n number: metadata.number,\n title: metadata.title,\n body: metadata.body,\n baseRef: metadata.baseRef,\n headRef: metadata.headRef,\n changedFileCount: files.length,\n });\n","import { Context, DateTime, Effect, Option, Schema } from \"effect\";\n\nimport {\n ReviewStateAuthenticator,\n type ReviewState,\n type StoredReviewFinding,\n} from \"./review-state.ts\";\n\n// ---------------------------------------------------------------------------\n// Review retirement. GitHub mutations stay behind ReviewRetirementHost; this\n// module owns only deterministic identity matching, body rewriting, and the\n// fail-open orchestration that turns stale reviews into quiet history.\n// ---------------------------------------------------------------------------\n\nconst PositiveLine = Schema.Int.check(Schema.isGreaterThan(0));\n\n/** One previously posted review as observed through the retirement host. */\nexport class RetirableReview extends Schema.Class<RetirableReview>(\n \"@effect-agent/pr-review/RetirableReview\",\n)({\n reviewId: Schema.Int.check(Schema.isGreaterThan(0)),\n body: Schema.String.check(Schema.isMaxLength(60_000)),\n commitSha: Schema.NonEmptyString.check(Schema.isMaxLength(64)),\n authorNodeId: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(200))),\n submittedAt: Schema.NullOr(Schema.DateTimeUtc),\n}) {}\n\n/** One inline comment attached to a previously posted review. */\nexport class RetirableReviewComment extends Schema.Class<RetirableReviewComment>(\n \"@effect-agent/pr-review/RetirableReviewComment\",\n)({\n nodeId: Schema.NonEmptyString.check(Schema.isMaxLength(200)),\n path: Schema.NonEmptyString.check(Schema.isMaxLength(500)),\n startLine: Schema.NullOr(PositiveLine),\n endLine: Schema.NullOr(PositiveLine),\n body: Schema.String.check(Schema.isMaxLength(65_536)),\n}) {}\n\n/** A GitHub retirement read or mutation failed. */\nexport class ReviewRetirementFailure extends Schema.TaggedError<ReviewRetirementFailure>()(\n \"ReviewRetirementFailure\",\n {\n operation: Schema.String,\n reason: Schema.String,\n },\n) {\n override get message() {\n return `Review retirement operation '${this.operation}' failed: ${this.reason}`;\n }\n}\n\n/**\n * Host-side GitHub operations used by retirement. Domain code never reaches\n * into REST or GraphQL directly, and deterministic tests substitute this port.\n */\nexport class ReviewRetirementHost extends Context.Service<\n ReviewRetirementHost,\n {\n readonly listReviews: Effect.Effect<ReadonlyArray<RetirableReview>, ReviewRetirementFailure>;\n readonly listComments: (\n reviewId: number,\n ) => Effect.Effect<ReadonlyArray<RetirableReviewComment>, ReviewRetirementFailure>;\n readonly updateBody: (\n reviewId: number,\n body: string,\n ) => Effect.Effect<void, ReviewRetirementFailure>;\n readonly minimizeComment: (nodeId: string) => Effect.Effect<void, ReviewRetirementFailure>;\n }\n>()(\"@effect-agent/pr-review/ReviewRetirementHost\") {}\n\n/** Observable cosmetic work completed by one fail-open retirement pass. */\nexport class ReviewRetirementReport extends Schema.Class<ReviewRetirementReport>(\n \"@effect-agent/pr-review/ReviewRetirementReport\",\n)({\n reviewsRetired: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n findingsResolved: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n commentsMinimized: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n failures: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n}) {}\n\nexport interface ReviewRetirementInput {\n readonly currentReviewId: number;\n readonly currentReviewUrl: string;\n readonly currentAuthorNodeId: string;\n readonly currentSubmittedAt: DateTime.Utc;\n readonly currentState: ReviewState;\n}\n\nexport interface ReviewRetirementDecision {\n readonly body: string;\n readonly resolvedFindings: ReadonlyArray<StoredReviewFinding>;\n readonly priorFindingCount: number;\n}\n\nconst findingIdentity = (finding: {\n readonly path: string;\n readonly startLine: number;\n readonly endLine: number;\n readonly title: string;\n}): string =>\n `${finding.path}\\u0000${finding.startLine}\\u0000${finding.endLine}\\u0000${finding.title}`;\n\nconst REVIEW_METADATA_PATTERN = /<!-- effect-agent-pr-review metadata\\n[\\s\\S]*?\\n-->/g;\nconst FINGERPRINT_PATTERN = /<!-- effect-agent-pr-review fingerprint=sha256:[0-9a-f]{64} -->/g;\nconst STATE_PATTERN =\n /<!-- effect-agent-pr-review state-v1:[A-Za-z0-9+/]+={0,2}\\.[0-9a-f]{64} -->/g;\nconst RETIRED_ORIGINAL_PATTERN =\n /<!-- effect-agent-pr-review retired-original:start -->\\n([\\s\\S]*?)\\n<!-- effect-agent-pr-review retired-original:end -->/;\nconst MACHINE_COMMENT_PATTERN = new RegExp(\n `${REVIEW_METADATA_PATTERN.source}|${FINGERPRINT_PATTERN.source}|${STATE_PATTERN.source}`,\n \"g\",\n);\nconst VERDICT_CALLOUT_PATTERN =\n /^(?:> \\[!(?:CAUTION|IMPORTANT)\\]\\n> [^\\n]*(?:\\n> [^\\n]*)*|> (?:ℹ️|✅)[^\\n]*)\\n*/;\nconst INLINE_FINDING_TITLE_PATTERN = /^\\*\\*\\[(?:🛑 blocking|⚠️ important|💅 nit)\\] ([^\\n]+)\\*\\*$/;\nconst MAX_REVIEW_BODY_CHARS = 60_000;\n\n/** The host-authored metadata marker is the authority gate for any edit. */\nexport const hasReviewMetadataMarker = (body: string): boolean =>\n /<!-- effect-agent-pr-review metadata\\n/.test(body);\n\nconst machineComments = (body: string): ReadonlyArray<string> =>\n Array.from(body.matchAll(MACHINE_COMMENT_PATTERN), (match) => match[0]);\n\nconst originalVisibleBody = (body: string): string => {\n const retired = RETIRED_ORIGINAL_PATTERN.exec(body)?.[1];\n if (retired !== undefined) return retired;\n return body.replace(MACHINE_COMMENT_PATTERN, \"\").trim().replace(VERDICT_CALLOUT_PATTERN, \"\");\n};\n\nconst findingLocation = (finding: StoredReviewFinding): string =>\n `${finding.path}:${finding.startLine}${\n finding.endLine === finding.startLine ? \"\" : `-${finding.endLine}`\n }`;\n\nconst renderRetiredBody = (input: {\n readonly priorBody: string;\n readonly priorState: ReviewState;\n readonly currentState: ReviewState;\n readonly currentReviewUrl: string;\n readonly resolvedFindings: ReadonlyArray<StoredReviewFinding>;\n}): string => {\n const shortSha = input.currentState.reviewedHeadSha.slice(0, 7);\n const comments = machineComments(input.priorBody);\n const original = originalVisibleBody(input.priorBody);\n const resolved =\n input.resolvedFindings.length === 0\n ? []\n : [\n \"### Findings resolved by later review\",\n \"\",\n ...input.resolvedFindings.map(\n (finding) =>\n `- \\`${findingLocation(finding)}\\` ~~${finding.title}~~ · resolved at \\`${shortSha}\\``,\n ),\n \"\",\n ];\n const prefix = [\n `> ℹ️ Superseded — ${input.resolvedFindings.length} of ${input.priorState.unresolvedFindings.length} findings resolved at \\`${shortSha}\\`; see [the latest review](${input.currentReviewUrl}).`,\n \"\",\n \"<details>\",\n \"<summary>Previous review details</summary>\",\n \"\",\n ...resolved,\n \"<!-- effect-agent-pr-review retired-original:start -->\",\n ];\n const suffix = [\n \"<!-- effect-agent-pr-review retired-original:end -->\",\n \"\",\n \"</details>\",\n ...(comments.length === 0 ? [] : [\"\", ...comments]),\n ];\n const render = (visible: string) => [...prefix, visible, ...suffix].join(\"\\n\");\n if (render(original).length <= MAX_REVIEW_BODY_CHARS) return render(original);\n const truncationNotice = \"\\n\\n_Original review content truncated during retirement._\";\n const budget = Math.max(0, MAX_REVIEW_BODY_CHARS - render(truncationNotice).length);\n return render(`${original.slice(0, budget)}${truncationNotice}`);\n};\n\n/** Compute one prior review's resolved subset and deterministic retired body. */\nexport const decideReviewRetirement = (input: {\n readonly priorBody: string;\n readonly priorState: ReviewState;\n readonly currentState: ReviewState;\n readonly currentReviewUrl: string;\n}): ReviewRetirementDecision => {\n const current = new Set(input.currentState.unresolvedFindings.map(findingIdentity));\n const resolvedFindings = input.priorState.unresolvedFindings.filter(\n (finding) => !current.has(findingIdentity(finding)),\n );\n return {\n body: renderRetiredBody({ ...input, resolvedFindings }),\n resolvedFindings,\n priorFindingCount: input.priorState.unresolvedFindings.length,\n };\n};\n\nconst inlineCommentIdentity = (comment: RetirableReviewComment): string | undefined => {\n if (comment.startLine === null || comment.endLine === null) return undefined;\n const firstLine = comment.body.split(\"\\n\", 1)[0] ?? \"\";\n const title = INLINE_FINDING_TITLE_PATTERN.exec(firstLine)?.[1];\n return title === undefined\n ? undefined\n : findingIdentity({\n path: comment.path,\n startLine: comment.startLine,\n endLine: comment.endLine,\n title,\n });\n};\n\nconst failOpen = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n fallback: A,\n message: string,\n): Effect.Effect<A, never, R> =>\n effect.pipe(\n Effect.catch((error) =>\n Effect.logWarning(`${message}: ${String(error)}`).pipe(Effect.as(fallback)),\n ),\n );\n\nconst isStrictlyOlderReview = (review: RetirableReview, input: ReviewRetirementInput): boolean => {\n if (review.submittedAt === null) return false;\n const submittedAt = DateTime.toEpochMillis(review.submittedAt);\n const currentSubmittedAt = DateTime.toEpochMillis(input.currentSubmittedAt);\n return (\n submittedAt < currentSubmittedAt ||\n (submittedAt === currentSubmittedAt && review.reviewId < input.currentReviewId)\n );\n};\n\n/**\n * Retire every marker-bearing prior review against the newest posted state.\n * Every lookup, edit, and minimization is isolated: retirement is cosmetic\n * and can never change the run or check outcome.\n */\nexport const retireStaleReviews = Effect.fn(\"retireStaleReviews\")(function* (\n input: ReviewRetirementInput,\n) {\n const host = yield* ReviewRetirementHost;\n const authenticator = yield* ReviewStateAuthenticator;\n if (authenticator.status !== \"available\") {\n yield* Effect.logWarning(\n \"Skipping stale-review retirement because authenticated review state is unavailable.\",\n );\n return ReviewRetirementReport.make({\n reviewsRetired: 0,\n findingsResolved: 0,\n commentsMinimized: 0,\n failures: 0,\n });\n }\n\n let failures = 0;\n let reviewsRetired = 0;\n let findingsResolved = 0;\n let commentsMinimized = 0;\n const reviews = yield* failOpen(host.listReviews, undefined, \"Could not list prior reviews\");\n if (reviews === undefined) {\n return ReviewRetirementReport.make({\n reviewsRetired,\n findingsResolved,\n commentsMinimized,\n failures: 1,\n });\n }\n\n for (const review of reviews) {\n if (\n review.authorNodeId !== input.currentAuthorNodeId ||\n !isStrictlyOlderReview(review, input) ||\n !hasReviewMetadataMarker(review.body)\n ) {\n continue;\n }\n const priorState = yield* failOpen(\n authenticator.extract(review.body),\n Option.none<ReviewState>(),\n `Could not authenticate prior review ${review.reviewId}`,\n );\n if (Option.isNone(priorState)) continue;\n\n const decision = decideReviewRetirement({\n priorBody: review.body,\n priorState: priorState.value,\n currentState: input.currentState,\n currentReviewUrl: input.currentReviewUrl,\n });\n const updated = yield* failOpen(\n host.updateBody(review.reviewId, decision.body).pipe(Effect.as(true)),\n false,\n `Could not retire prior review ${review.reviewId}`,\n );\n if (updated) {\n reviewsRetired += 1;\n findingsResolved += decision.resolvedFindings.length;\n } else {\n failures += 1;\n }\n\n if (decision.resolvedFindings.length === 0) continue;\n const comments = yield* failOpen(\n host.listComments(review.reviewId),\n undefined,\n `Could not list inline comments for prior review ${review.reviewId}`,\n );\n if (comments === undefined) {\n failures += 1;\n continue;\n }\n const resolved = new Set(decision.resolvedFindings.map(findingIdentity));\n for (const comment of comments) {\n const identity = inlineCommentIdentity(comment);\n if (identity === undefined || !resolved.has(identity)) continue;\n const minimized = yield* failOpen(\n host.minimizeComment(comment.nodeId).pipe(Effect.as(true)),\n false,\n `Could not minimize resolved inline comment ${comment.nodeId}`,\n );\n if (minimized) commentsMinimized += 1;\n else failures += 1;\n }\n }\n\n return ReviewRetirementReport.make({\n reviewsRetired,\n findingsResolved,\n commentsMinimized,\n failures,\n });\n});\n","import type { Redacted } from \"effect\";\nimport { Context, DateTime, Effect, Layer, Option, Schema } from \"effect\";\nimport { HttpClient, HttpClientRequest, HttpClientResponse } from \"effect/unstable/http\";\n\nimport { ChangedFile } from \"./diff.ts\";\nimport { extractFingerprint } from \"./fingerprint.ts\";\nimport type { ReviewPublicationPlan } from \"./render.ts\";\nimport {\n RetirableReview,\n RetirableReviewComment,\n ReviewRetirementFailure,\n ReviewRetirementHost,\n} from \"./retirement.ts\";\nimport {\n ReviewHeadComparison,\n ReviewStateAuthenticator,\n type ReviewState,\n} from \"./review-state.ts\";\nimport {\n MAX_CHANGED_FILES,\n MAX_FILE_CHARS,\n normalizeRepoRelativePath,\n PullRequestMetadata,\n PullRequestSource,\n PullRequestSourceFailure,\n ReviewInputViolation,\n} from \"./source.ts\";\n\n// ---------------------------------------------------------------------------\n// GitHub REST adapters for the PullRequestSource port and the ReviewPublisher.\n// Wire payloads are decoded through minimal Schemas — never asserted — and\n// every upstream fault becomes the typed PullRequestSourceFailure /\n// GitHubApiFailure instead of an untyped defect.\n// ---------------------------------------------------------------------------\n\nconst defaultGraphqlUrl = (apiUrl: string): string =>\n apiUrl === \"https://api.github.com\"\n ? \"https://api.github.com/graphql\"\n : apiUrl.replace(/\\/api\\/v3$/, \"/api/graphql\");\n\n/** Which pull request to review and how to reach the API. */\nexport class GitHubReviewTarget extends Context.Service<\n GitHubReviewTarget,\n {\n /** API root, e.g. `https://api.github.com` (no trailing slash). */\n readonly apiUrl: string;\n /** GraphQL root, e.g. `https://api.github.com/graphql`. */\n readonly graphqlUrl: string;\n /** `owner/name`. */\n readonly repository: string;\n readonly number: number;\n /** Absent token means unauthenticated reads (public repositories only). */\n readonly token: Option.Option<Redacted.Redacted<string>>;\n }\n>()(\"@effect-agent/pr-review/GitHubReviewTarget\") {\n static layer(config: {\n readonly apiUrl: string;\n readonly graphqlUrl?: string | undefined;\n readonly repository: string;\n readonly number: number;\n readonly token: Option.Option<Redacted.Redacted<string>>;\n }): Layer.Layer<GitHubReviewTarget> {\n return Layer.succeed(\n this,\n GitHubReviewTarget.of({\n ...config,\n graphqlUrl: config.graphqlUrl ?? defaultGraphqlUrl(config.apiUrl),\n }),\n );\n }\n}\n\n/** A GitHub API call failed: transport, status, or payload decode. */\nexport class GitHubApiFailure extends Schema.TaggedError<GitHubApiFailure>()(\"GitHubApiFailure\", {\n operation: Schema.String,\n reason: Schema.String,\n}) {\n override get message() {\n return `GitHub API operation '${this.operation}' failed: ${this.reason}`;\n }\n}\n\n// --- Wire schemas (decode-only, minimal fields) ------------------------------\n\nconst GitHubPullRequestWire = Schema.Struct({\n number: Schema.Int,\n title: Schema.String,\n body: Schema.NullOr(Schema.String),\n changed_files: Schema.Int,\n base: Schema.Struct({ ref: Schema.String, sha: Schema.String }),\n head: Schema.Struct({ ref: Schema.String, sha: Schema.String }),\n});\n\nconst GitHubFileWire = Schema.Struct({\n filename: Schema.String,\n status: Schema.String,\n additions: Schema.Int,\n deletions: Schema.Int,\n patch: Schema.optionalKey(Schema.String),\n previous_filename: Schema.optionalKey(Schema.String),\n});\n\nconst GitHubFilesPageWire = Schema.Array(GitHubFileWire);\n\nconst GitHubActorWire = Schema.Struct({ node_id: Schema.String });\n\nconst GitHubReviewWire = Schema.Struct({\n id: Schema.Int,\n html_url: Schema.String,\n user: Schema.NullOr(GitHubActorWire),\n submitted_at: Schema.NullOr(Schema.String),\n});\n\nconst GitHubRetirableReviewWire = Schema.Struct({\n id: Schema.Int,\n body: Schema.NullOr(Schema.String),\n commit_id: Schema.String,\n user: Schema.NullOr(GitHubActorWire),\n submitted_at: Schema.NullOr(Schema.String),\n});\nconst GitHubRetirableReviewsPageWire = Schema.Array(GitHubRetirableReviewWire);\n\nconst GitHubReviewCommentWire = Schema.Struct({\n node_id: Schema.String,\n path: Schema.String,\n body: Schema.String,\n line: Schema.NullOr(Schema.Int),\n original_line: Schema.NullOr(Schema.Int),\n start_line: Schema.optionalKey(Schema.NullOr(Schema.Int)),\n original_start_line: Schema.optionalKey(Schema.NullOr(Schema.Int)),\n});\nconst GitHubReviewCommentsPageWire = Schema.Array(GitHubReviewCommentWire);\n\nconst GitHubMinimizeCommentWire = Schema.Struct({\n data: Schema.optionalKey(\n Schema.NullOr(\n Schema.Struct({\n minimizeComment: Schema.NullOr(\n Schema.Struct({\n minimizedComment: Schema.NullOr(Schema.Struct({ isMinimized: Schema.Boolean })),\n }),\n ),\n }),\n ),\n ),\n errors: Schema.optionalKey(Schema.Array(Schema.Struct({ message: Schema.String }))),\n});\n\n/** Decode GitHub's external timestamp before it participates in mutation ordering. */\nexport const parseGitHubSubmittedAt = (value: string | null): DateTime.Utc | null =>\n value === null ? null : Option.getOrNull(DateTime.make(value));\n\n/** The publication receipt callers report back to the operator. */\nexport class PublishedReview extends Schema.Class<PublishedReview>(\n \"@effect-agent/pr-review/PublishedReview\",\n)({\n reviewId: Schema.Int,\n url: Schema.String,\n event: Schema.String,\n inlineComments: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n /** Actor and ordering boundary returned by the create-review response. */\n authorNodeId: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(200))),\n submittedAt: Schema.NullOr(Schema.DateTimeUtc),\n}) {}\n\n/** Posts one planned review; the ONLY mutating operation in this package. */\nexport class ReviewPublisher extends Context.Service<\n ReviewPublisher,\n {\n readonly publish: (\n plan: ReviewPublicationPlan,\n ) => Effect.Effect<PublishedReview, GitHubApiFailure>;\n }\n>()(\"@effect-agent/pr-review/ReviewPublisher\") {}\n\n// --- Shared request plumbing -------------------------------------------------\n\nconst FILE_STATUSES = new Set([\n \"added\",\n \"removed\",\n \"modified\",\n \"renamed\",\n \"copied\",\n \"changed\",\n \"unchanged\",\n]);\n\nconst withCommonHeaders = (\n request: HttpClientRequest.HttpClientRequest,\n token: Option.Option<Redacted.Redacted<string>>,\n): HttpClientRequest.HttpClientRequest => {\n const base = request.pipe(\n HttpClientRequest.setHeaders({\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": \"effect-agent-pr-review\",\n }),\n );\n return Option.isSome(token) ? base.pipe(HttpClientRequest.bearerToken(token.value)) : base;\n};\n\nconst failWith =\n (operation: string) =>\n (error: { readonly _tag: string; readonly message?: string }): PullRequestSourceFailure =>\n PullRequestSourceFailure.make({\n operation,\n reason: `${error._tag}: ${error.message ?? \"request failed\"}`.slice(0, 2_048),\n });\n\nconst decodeJsonBody = <S extends Schema.Top>(schema: S, operation: string) => {\n const decode = Schema.decodeUnknownEffect(schema);\n return (\n response: HttpClientResponse.HttpClientResponse,\n ): Effect.Effect<S[\"Type\"], PullRequestSourceFailure, S[\"DecodingServices\"]> =>\n response.json.pipe(\n Effect.mapError(failWith(operation)),\n Effect.flatMap((body) => decode(body).pipe(Effect.mapError(failWith(operation)))),\n );\n};\n\nconst executeOk = (\n operation: string,\n request: HttpClientRequest.HttpClientRequest,\n): Effect.Effect<\n HttpClientResponse.HttpClientResponse,\n PullRequestSourceFailure,\n HttpClient.HttpClient\n> =>\n HttpClient.execute(request).pipe(\n Effect.flatMap(HttpClientResponse.filterStatusOk),\n Effect.mapError(failWith(operation)),\n );\n\nconst toChangedFile = (wire: typeof GitHubFileWire.Type): ChangedFile =>\n ChangedFile.make({\n path: wire.filename,\n status: FILE_STATUSES.has(wire.status) ? (wire.status as ChangedFile[\"status\"]) : \"changed\",\n additions: wire.additions,\n deletions: wire.deletions,\n ...(wire.previous_filename !== undefined ? { previousPath: wire.previous_filename } : {}),\n ...(wire.patch !== undefined ? { patch: wire.patch } : {}),\n });\n\n// --- Live PullRequestSource --------------------------------------------------\n\n/**\n * GitHub-backed PullRequestSource. Metadata and the changeset are fetched\n * once per Layer build and cached: the pull request is reviewed as one\n * consistent snapshot even if the branch moves mid-run.\n */\nexport const gitHubPullRequestSourceLayer: Layer.Layer<\n PullRequestSource,\n never,\n GitHubReviewTarget | HttpClient.HttpClient\n> = Layer.effect(PullRequestSource)(\n Effect.gen(function* () {\n const target = yield* GitHubReviewTarget;\n const client = yield* HttpClient.HttpClient;\n const prefix = `${target.apiUrl}/repos/${target.repository}/pulls/${target.number}`;\n\n const fetchMetadata = executeOk(\n \"getPullRequest\",\n withCommonHeaders(\n HttpClientRequest.get(prefix).pipe(HttpClientRequest.acceptJson),\n target.token,\n ),\n ).pipe(\n Effect.flatMap(decodeJsonBody(GitHubPullRequestWire, \"getPullRequest\")),\n Effect.map((wire) =>\n PullRequestMetadata.make({\n repository: target.repository,\n number: wire.number,\n title: wire.title.slice(0, 400),\n body: (wire.body ?? \"\").slice(0, 20_000),\n baseRef: wire.base.ref,\n baseSha: wire.base.sha,\n headRef: wire.head.ref,\n headSha: wire.head.sha,\n totalChangedFiles: wire.changed_files,\n }),\n ),\n );\n\n const fetchFiles = Effect.gen(function* () {\n const perPage = 100;\n const all: Array<ChangedFile> = [];\n for (let page = 1; page <= MAX_CHANGED_FILES / perPage; page += 1) {\n const response = yield* executeOk(\n \"listChangedFiles\",\n withCommonHeaders(\n HttpClientRequest.get(`${prefix}/files`).pipe(\n HttpClientRequest.acceptJson,\n HttpClientRequest.setUrlParams({\n per_page: String(perPage),\n page: String(page),\n }),\n ),\n target.token,\n ),\n );\n const wires = yield* decodeJsonBody(GitHubFilesPageWire, \"listChangedFiles\")(response);\n all.push(...wires.map(toChangedFile));\n if (wires.length < perPage) break;\n }\n return all as ReadonlyArray<ChangedFile>;\n });\n\n const metadata = yield* Effect.cached(\n fetchMetadata.pipe(Effect.provideService(HttpClient.HttpClient, client)),\n );\n const changedFiles = yield* Effect.cached(\n fetchFiles.pipe(Effect.provideService(HttpClient.HttpClient, client)),\n );\n\n const readFile = (path: string) =>\n Effect.gen(function* () {\n const relative = yield* normalizeRepoRelativePath(path);\n const files = yield* changedFiles;\n if (!files.some((file) => file.path === relative)) {\n return yield* ReviewInputViolation.make({\n input: relative,\n reason: \"Path is not part of this pull request's changeset.\",\n });\n }\n const head = yield* metadata;\n const encodedPath = relative.split(\"/\").map(encodeURIComponent).join(\"/\");\n const response = yield* executeOk(\n \"readFile\",\n withCommonHeaders(\n HttpClientRequest.get(\n `${target.apiUrl}/repos/${target.repository}/contents/${encodedPath}`,\n ).pipe(\n HttpClientRequest.accept(\"application/vnd.github.raw+json\"),\n HttpClientRequest.setUrlParams({ ref: head.headSha }),\n ),\n target.token,\n ),\n ).pipe(Effect.provideService(HttpClient.HttpClient, client));\n const text = yield* response.text.pipe(Effect.mapError(failWith(\"readFile\")));\n if (text.length > MAX_FILE_CHARS) {\n return yield* ReviewInputViolation.make({\n input: relative,\n reason: `File is larger than the ${MAX_FILE_CHARS}-character read bound.`,\n });\n }\n return text;\n });\n\n return PullRequestSource.of({ metadata, changedFiles, anchorFiles: changedFiles, readFile });\n }),\n);\n\n// --- Live ReviewPublisher ------------------------------------------------------\n\n/** GitHub-backed publisher: one POST to the pull-request reviews endpoint. */\nexport const gitHubReviewPublisherLayer: Layer.Layer<\n ReviewPublisher,\n never,\n GitHubReviewTarget | HttpClient.HttpClient\n> = Layer.effect(ReviewPublisher)(\n Effect.gen(function* () {\n const target = yield* GitHubReviewTarget;\n const client = yield* HttpClient.HttpClient;\n return ReviewPublisher.of({\n publish: (plan) =>\n Effect.gen(function* () {\n const payload = {\n event: plan.event,\n body: plan.body,\n commit_id: plan.commitSha,\n comments: plan.comments.map((comment) => ({\n path: comment.path,\n line: comment.line,\n side: \"RIGHT\",\n ...(comment.startLine !== undefined\n ? { start_line: comment.startLine, start_side: \"RIGHT\" }\n : {}),\n body: comment.body,\n })),\n };\n const request = withCommonHeaders(\n HttpClientRequest.post(\n `${target.apiUrl}/repos/${target.repository}/pulls/${target.number}/reviews`,\n ).pipe(HttpClientRequest.acceptJson, HttpClientRequest.bodyJsonUnsafe(payload)),\n target.token,\n );\n const wire = yield* HttpClient.execute(request).pipe(\n Effect.flatMap(HttpClientResponse.filterStatusOk),\n Effect.flatMap((response) =>\n response.json.pipe(Effect.flatMap(Schema.decodeUnknownEffect(GitHubReviewWire))),\n ),\n Effect.mapError((error) =>\n GitHubApiFailure.make({\n operation: \"createReview\",\n reason: `${error._tag}: ${error.message ?? \"request failed\"}`.slice(0, 2_048),\n }),\n ),\n Effect.provideService(HttpClient.HttpClient, client),\n );\n return PublishedReview.make({\n reviewId: wire.id,\n url: wire.html_url,\n event: plan.event,\n inlineComments: plan.comments.length,\n authorNodeId: wire.user?.node_id ?? null,\n submittedAt: parseGitHubSubmittedAt(wire.submitted_at),\n });\n }),\n });\n }),\n);\n\n// --- Live ReviewRetirementHost ----------------------------------------------\n\nconst MAX_RETIREMENT_PAGES = 5;\nconst MINIMIZE_REVIEW_COMMENT_MUTATION = `mutation MinimizeReviewComment($subjectId: ID!) {\n minimizeComment(input: { subjectId: $subjectId, classifier: OUTDATED }) {\n minimizedComment { isMinimized }\n }\n}`;\n\n/** GitHub-backed host operations for cosmetic retirement after publication. */\nexport const gitHubReviewRetirementHostLayer: Layer.Layer<\n ReviewRetirementHost,\n never,\n GitHubReviewTarget | HttpClient.HttpClient\n> = Layer.effect(ReviewRetirementHost)(\n Effect.gen(function* () {\n const target = yield* GitHubReviewTarget;\n const client = yield* HttpClient.HttpClient;\n const prefix = `${target.apiUrl}/repos/${target.repository}/pulls/${target.number}`;\n const asRetirementFailure =\n (operation: string) =>\n (error: { readonly _tag: string; readonly message?: string }): ReviewRetirementFailure =>\n ReviewRetirementFailure.make({\n operation,\n reason: `${error._tag}: ${error.message ?? \"request failed\"}`.slice(0, 2_048),\n });\n const executeRetirement = (operation: string, request: HttpClientRequest.HttpClientRequest) =>\n HttpClient.execute(request).pipe(\n Effect.flatMap(HttpClientResponse.filterStatusOk),\n Effect.mapError(asRetirementFailure(operation)),\n Effect.provideService(HttpClient.HttpClient, client),\n );\n const decodeRetirement = <S extends Schema.Top>(schema: S, operation: string) => {\n const decode = Schema.decodeUnknownEffect(schema);\n return (response: HttpClientResponse.HttpClientResponse) =>\n response.json.pipe(\n Effect.mapError(asRetirementFailure(operation)),\n Effect.flatMap((body) =>\n decode(body).pipe(Effect.mapError(asRetirementFailure(operation))),\n ),\n );\n };\n const listPaged = <A>(input: {\n readonly operation: string;\n readonly url: string;\n readonly decode: (\n response: HttpClientResponse.HttpClientResponse,\n ) => Effect.Effect<ReadonlyArray<A>, ReviewRetirementFailure>;\n }) =>\n Effect.gen(function* () {\n const values: Array<A> = [];\n const perPage = 100;\n for (let page = 1; page <= MAX_RETIREMENT_PAGES; page += 1) {\n const response = yield* executeRetirement(\n input.operation,\n withCommonHeaders(\n HttpClientRequest.get(input.url).pipe(\n HttpClientRequest.acceptJson,\n HttpClientRequest.setUrlParams({\n per_page: String(perPage),\n page: String(page),\n }),\n ),\n target.token,\n ),\n );\n const pageValues = yield* input.decode(response);\n values.push(...pageValues);\n if (pageValues.length < perPage) return values;\n }\n return yield* ReviewRetirementFailure.make({\n operation: input.operation,\n reason: `history exceeds the bounded ${MAX_RETIREMENT_PAGES * 100}-item lookup`,\n });\n });\n\n return ReviewRetirementHost.of({\n listReviews: listPaged({\n operation: \"listReviewsForRetirement\",\n url: `${prefix}/reviews`,\n decode: decodeRetirement(GitHubRetirableReviewsPageWire, \"listReviewsForRetirement\"),\n }).pipe(\n Effect.map((reviews) =>\n reviews.map((review) =>\n RetirableReview.make({\n reviewId: review.id,\n body: review.body ?? \"\",\n commitSha: review.commit_id,\n authorNodeId: review.user?.node_id ?? null,\n submittedAt: parseGitHubSubmittedAt(review.submitted_at),\n }),\n ),\n ),\n ),\n listComments: (reviewId) =>\n listPaged({\n operation: \"listReviewCommentsForRetirement\",\n url: `${prefix}/reviews/${reviewId}/comments`,\n decode: decodeRetirement(GitHubReviewCommentsPageWire, \"listReviewCommentsForRetirement\"),\n }).pipe(\n Effect.map((comments) =>\n comments.map((comment) => {\n const endLine = comment.line ?? comment.original_line;\n const startLine = comment.start_line ?? comment.original_start_line ?? endLine;\n return RetirableReviewComment.make({\n nodeId: comment.node_id,\n path: comment.path,\n startLine,\n endLine,\n body: comment.body,\n });\n }),\n ),\n ),\n updateBody: (reviewId, body) =>\n executeRetirement(\n \"updateReview\",\n withCommonHeaders(\n HttpClientRequest.put(`${prefix}/reviews/${reviewId}`).pipe(\n HttpClientRequest.acceptJson,\n HttpClientRequest.bodyJsonUnsafe({ body }),\n ),\n target.token,\n ),\n ).pipe(Effect.asVoid),\n minimizeComment: (nodeId) =>\n Effect.gen(function* () {\n const response = yield* executeRetirement(\n \"minimizeComment\",\n withCommonHeaders(\n HttpClientRequest.post(target.graphqlUrl).pipe(\n HttpClientRequest.acceptJson,\n HttpClientRequest.bodyJsonUnsafe({\n query: MINIMIZE_REVIEW_COMMENT_MUTATION,\n variables: { subjectId: nodeId },\n }),\n ),\n target.token,\n ),\n );\n const wire = yield* decodeRetirement(\n GitHubMinimizeCommentWire,\n \"minimizeComment\",\n )(response);\n if (\n (wire.errors?.length ?? 0) > 0 ||\n wire.data?.minimizeComment?.minimizedComment?.isMinimized !== true\n ) {\n return yield* ReviewRetirementFailure.make({\n operation: \"minimizeComment\",\n reason:\n wire.errors\n ?.map((error) => error.message)\n .join(\"; \")\n .slice(0, 2_048) ?? \"GitHub did not confirm comment minimization\",\n });\n }\n }),\n });\n }),\n);\n\n// --- Prior reviews (fingerprint deduplication) ---------------------------------\n\n/** Reading the pull request's previously posted reviews failed. */\nexport class PriorReviewLookupFailure extends Schema.TaggedError<PriorReviewLookupFailure>()(\n \"PriorReviewLookupFailure\",\n {\n reason: Schema.String,\n },\n) {\n override get message() {\n return `Prior-review lookup failed: ${this.reason}`;\n }\n}\n\n/**\n * Read-only view of this package's previously posted reviews on the target\n * pull request — the deduplication state for unchanged-changeset skipping.\n */\nexport class PriorReviews extends Context.Service<\n PriorReviews,\n {\n /** The fingerprint embedded in the most recent marker-bearing review. */\n readonly latestFingerprint: Effect.Effect<Option.Option<string>, PriorReviewLookupFailure>;\n /** The latest authenticated, successfully covered review state marker. */\n readonly latestState: Effect.Effect<\n Option.Option<ReviewState>,\n PriorReviewLookupFailure,\n ReviewStateAuthenticator\n >;\n /** Compare a previously reviewed head to the live current head. */\n readonly compareHeads: (\n baseSha: string,\n headSha: string,\n ) => Effect.Effect<ReviewHeadComparison, PriorReviewLookupFailure>;\n }\n>()(\"@effect-agent/pr-review/PriorReviews\") {}\n\nconst GitHubPriorReviewWire = Schema.Struct({\n body: Schema.NullOr(Schema.String),\n commit_id: Schema.String,\n user: Schema.optionalKey(\n Schema.NullOr(\n Schema.Struct({\n login: Schema.String,\n type: Schema.String,\n }),\n ),\n ),\n});\nconst GitHubPriorReviewsPageWire = Schema.Array(GitHubPriorReviewWire);\n\nconst GitHubCompareWire = Schema.Struct({\n status: Schema.Literals([\"ahead\", \"behind\", \"diverged\", \"identical\"]),\n base_commit: Schema.Struct({ sha: Schema.String }),\n merge_base_commit: Schema.Struct({ sha: Schema.String }),\n files: GitHubFilesPageWire,\n});\n\n/** Reviews are paged chronologically; scanning stays bounded. */\nconst MAX_PRIOR_REVIEW_PAGES = 5;\n\n/** GitHub-backed PriorReviews over the pull-request reviews endpoint. */\nexport const gitHubPriorReviewsLayer: Layer.Layer<\n PriorReviews,\n never,\n GitHubReviewTarget | HttpClient.HttpClient\n> = Layer.effect(PriorReviews)(\n Effect.gen(function* () {\n const target = yield* GitHubReviewTarget;\n const client = yield* HttpClient.HttpClient;\n const prefix = `${target.apiUrl}/repos/${target.repository}/pulls/${target.number}`;\n const decodePage = Schema.decodeUnknownEffect(GitHubPriorReviewsPageWire);\n const asLookupFailure = (error: { readonly _tag: string; readonly message?: string }) =>\n PriorReviewLookupFailure.make({\n reason: `${error._tag}: ${error.message ?? \"request failed\"}`.slice(0, 2_048),\n });\n const readMarkers = (authenticator: Option.Option<ReviewStateAuthenticator[\"Service\"]>) =>\n Effect.gen(function* () {\n const perPage = 100;\n let latest = Option.none<string>();\n let latestState = Option.none<ReviewState>();\n for (let page = 1; page <= MAX_PRIOR_REVIEW_PAGES; page += 1) {\n const response = yield* HttpClient.execute(\n withCommonHeaders(\n HttpClientRequest.get(`${prefix}/reviews`).pipe(\n HttpClientRequest.acceptJson,\n HttpClientRequest.setUrlParams({\n per_page: String(perPage),\n page: String(page),\n }),\n ),\n target.token,\n ),\n ).pipe(\n Effect.flatMap(HttpClientResponse.filterStatusOk),\n Effect.mapError(asLookupFailure),\n );\n const wires = yield* response.json.pipe(\n Effect.mapError(asLookupFailure),\n Effect.flatMap((body) => decodePage(body).pipe(Effect.mapError(asLookupFailure))),\n );\n for (const wire of wires) {\n // State controls what required scope may be omitted. The author gate\n // rejects user prose; the terminal marker is additionally HMAC\n // authenticated so another bot workflow or model text cannot forge it.\n if (wire.user?.login !== \"github-actions[bot]\" || wire.user.type !== \"Bot\") continue;\n const fingerprint = extractFingerprint(wire.body ?? \"\");\n if (fingerprint !== undefined) latest = Option.some(fingerprint);\n if (Option.isSome(authenticator)) {\n const state = yield* authenticator.value.extract(wire.body ?? \"\").pipe(\n Effect.mapError((error) =>\n PriorReviewLookupFailure.make({\n reason: `${error._tag}: ${error.reason}`.slice(0, 2_048),\n }),\n ),\n );\n if (Option.isSome(state) && state.value.reviewedHeadSha === wire.commit_id) {\n latestState = state;\n }\n }\n }\n if (wires.length < perPage) break;\n if (page === MAX_PRIOR_REVIEW_PAGES) {\n return yield* PriorReviewLookupFailure.make({\n reason: `review history exceeds the bounded ${MAX_PRIOR_REVIEW_PAGES * perPage}-review lookup`,\n });\n }\n }\n return { latestFingerprint: latest, latestState };\n }).pipe(Effect.provideService(HttpClient.HttpClient, client));\n const compareHeads = (baseSha: string, headSha: string) =>\n Effect.gen(function* () {\n const response = yield* HttpClient.execute(\n withCommonHeaders(\n HttpClientRequest.get(\n `${target.apiUrl}/repos/${target.repository}/compare/${encodeURIComponent(baseSha)}...${encodeURIComponent(headSha)}`,\n ).pipe(HttpClientRequest.acceptJson),\n target.token,\n ),\n ).pipe(Effect.flatMap(HttpClientResponse.filterStatusOk), Effect.mapError(asLookupFailure));\n const wire = yield* response.json.pipe(\n Effect.mapError(asLookupFailure),\n Effect.flatMap((body) =>\n Schema.decodeUnknownEffect(GitHubCompareWire)(body).pipe(\n Effect.mapError(asLookupFailure),\n ),\n ),\n );\n const files = wire.files.map(toChangedFile);\n return ReviewHeadComparison.make({\n status: wire.status,\n baseSha: wire.base_commit.sha,\n headSha,\n mergeBaseSha: wire.merge_base_commit.sha,\n files,\n truncated: files.length >= MAX_CHANGED_FILES,\n });\n }).pipe(Effect.provideService(HttpClient.HttpClient, client));\n return PriorReviews.of({\n latestFingerprint: readMarkers(Option.none()).pipe(\n Effect.map((markers) => markers.latestFingerprint),\n ),\n latestState: Effect.gen(function* () {\n const authenticator = yield* ReviewStateAuthenticator;\n return yield* readMarkers(Option.some(authenticator)).pipe(\n Effect.map((markers) => markers.latestState),\n );\n }),\n compareHeads,\n });\n }),\n);\n\n/**\n * Whether the current fingerprint matches the most recent posted review.\n * Fails OPEN: a lookup fault means \"not unchanged\" — the review proceeds,\n * which is the safe direction for a deduplication optimization.\n */\nexport const fingerprintUnchanged = (\n current: string,\n): Effect.Effect<boolean, never, PriorReviews> =>\n Effect.gen(function* () {\n const priorReviews = yield* PriorReviews;\n const latest = yield* priorReviews.latestFingerprint.pipe(\n Effect.orElseSucceed(() => Option.none<string>()),\n );\n return Option.isSome(latest) && latest.value === current;\n });\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { $ as gitHubReviewPublisherLayer, $t as
|
|
1
|
+
import { $ as gitHubReviewPublisherLayer, $t as MAX_FINDINGS, A as fileReviewerInstructions, An as ChangedFile, At as StoredReviewFinding, B as ReviewUnitPlan, Bt as validateReviewState, C as defaultFanOutPolicy, Cn as MAX_CHANGED_FILES, Ct as ReviewSelection, D as fanOutReviewInstructions, Dn as PullRequestSourceFailure, Dt as ReviewStateMarker, E as fanOutHandlersLayerFor, En as PullRequestSource, Et as ReviewStateAuthenticator, F as MAX_MERGED_FINDINGS, Fn as commentableLines, Ft as selectReviewRange, G as GitHubReviewTarget, Gt as FileDiffQuery, H as planReviewUnits, Ht as ChangedFileSummary, I as MAX_REVIEW_UNITS, In as parsePatch, It as selectedPullRequestSourceLayer, J as PublishedReview, Jt as FileSliceQuery, K as PriorReviewLookupFailure, Kt as FileDiffView, L as MAX_UNIT_FILES, Lt as toStoredConcern, M as makeFanOutReviewSuite, Mn as ChangedPath, Mt as computeProfileFingerprint, N as makeFileReviewerInstructions, Nn as PatchLine, Nt as fromStoredConcern, O as fileReviewDelegation, On as ReviewInputViolation, Ot as ReviewStateMarkerTooLarge, P as mapFileReviewChildFailure, Pn as annotatePatch, Pt as fromStoredFinding, Q as gitHubPullRequestSourceLayer, Qt as MAX_CONCERNS, R as ReviewUnit, Rt as toStoredFinding, S as MAX_FILE_REVIEW_TOOL_CALLS, Sn as assessReviewCoverage, St as ReviewScopeMode, T as fanOutHandlersLayer, Tn as PullRequestMetadata, Tt as ReviewStateAuthenticationFailure, U as rankAndDedupeFindings, Ut as ChangedFilesView, V as UNIT_CHANGED_LINE_BUDGET, Vt as webCryptoReviewStateAuthenticatorLayer, W as GitHubApiFailure, Wt as CodeReview, X as fingerprintUnchanged, Xt as ListChangedFiles, Y as ReviewPublisher, Yt as FindingSeverity, Z as gitHubPriorReviewsLayer, Zt as ListChangedFilesQuery, _ as FileReviewer, _n as resolveGuidance, _t as GitCommitSha, a as FanOutReviewSuite, an as ReviewGuidance, at as ReviewRetirementFailure, b as MAX_CHILD_CONCERNS, bn as ReviewCoverage, bt as ReviewHeadComparison, c as FanOutSuiteOptions, cn as ReviewToolkit, ct as ReviewRetirementReport, d as FileReviewReport, dn as clampMaxFindings, dt as retireStaleReviews, en as PullRequestReviewer, et as gitHubReviewRetirementHostLayer, f as FileReviewRequest, fn as defaultReviewPolicy, ft as ReviewCommentDraft, g as FileReviewUnitResult, gn as readFileHandler, gt as planPublication, h as FileReviewUnitFailed, hn as readFileDiffHandler, ht as anchorViolation, i as FanOutInstructionOptions, in as ReviewFinding, it as ReviewRetirementDecision, j as makeFanOutReviewInstructions, jn as ChangedFileStatus, jt as buildProfileMission, k as fileReviewPolicy, kn as normalizeRepoRelativePath, kt as StoredReviewConcern, l as FileReviewBrief, ln as ReviewToolkitLayer, lt as decideReviewRetirement, m as FileReviewToolkitLayer, mn as makeReviewInstructions, mt as ReviewPublicationPlan, n as FanOutCoordinatorToolkit, nn as ReadFileDiff, nt as RetirableReview, o as FanOutReviewToolkit, on as ReviewInstructionOptions, ot as ReviewRetirementHost, p as FileReviewToolkit, pn as listChangedFilesHandler, pt as ReviewEvent, q as PriorReviews, qt as FileSlice, r as FanOutCoordinatorToolkitLayer, rn as ReviewConcern, rt as RetirableReviewComment, s as FanOutReviewer, sn as ReviewMission, st as ReviewRetirementInput, t as DelegateFileReview, tn as ReadFile, tt as parseGitHubSubmittedAt, u as FileReviewDelegationFailure, un as ReviewVerdict, ut as hasReviewMetadataMarker, v as ListReviewUnits, vn as reviewInstructions, vt as MAX_REVIEW_STATE_MARKER_CHARS, w as defaultFileReviewerPolicy, wn as MAX_FILE_CHARS, wt as ReviewState, x as MAX_CHILD_FINDINGS, xn as ReviewShape, xt as ReviewMode, y as ListReviewUnitsQuery, yn as FailedReviewUnit, yt as ReviewExecutionContext, z as ReviewUnitId, zt as unavailableReviewStateAuthenticatorLayer } from "./fan-out-C6gq3CFg.mjs";
|
|
2
2
|
import { Config, Effect, FileSystem, Layer, Option, Schema } from "effect";
|
|
3
3
|
import { AgentPolicyInput, IdGenerator, RuntimeBinding, UsageBudgetLimits, UsageTotals } from "effect-agent";
|
|
4
4
|
import { LanguageModel, Model, Tool, Toolkit } from "effect/unstable/ai";
|
|
5
|
+
import { HttpClient } from "effect/unstable/http";
|
|
5
6
|
import { AnthropicClient } from "@effect/ai-anthropic";
|
|
6
7
|
import { OpenAiClient } from "@effect/ai-openai";
|
|
7
8
|
//#region src/internal/effort.d.ts
|
|
@@ -620,7 +621,7 @@ declare const resolveReviewTarget: (options: {
|
|
|
620
621
|
* reading GITHUB_API_URL and GITHUB_TOKEN from configuration. The returned
|
|
621
622
|
* Layer is the complete GitHub side of a review run.
|
|
622
623
|
*/
|
|
623
|
-
declare const gitHubReviewLayers: (target: ResolvedReviewTarget) => Layer.Layer<PullRequestSource | ReviewPublisher | PriorReviews, Config.ConfigError>;
|
|
624
|
+
declare const gitHubReviewLayers: (target: ResolvedReviewTarget) => Layer.Layer<PullRequestSource | ReviewPublisher | PriorReviews | ReviewRetirementHost, Config.ConfigError, HttpClient.HttpClient>;
|
|
624
625
|
//#endregion
|
|
625
626
|
//#region src/internal/ignore.d.ts
|
|
626
627
|
/** Compile ignore globs into one predicate over repository-relative paths. */
|
|
@@ -712,5 +713,5 @@ declare const openAiClientLayer: Layer.Layer<OpenAiClient.OpenAiClient, Config.C
|
|
|
712
713
|
/** The Anthropic client Layer, credential from `ANTHROPIC_API_KEY`. */
|
|
713
714
|
declare const anthropicClientLayer: Layer.Layer<AnthropicClient.AnthropicClient, Config.ConfigError, never>;
|
|
714
715
|
//#endregion
|
|
715
|
-
export { ChangedFile, ChangedFileStatus, ChangedFileSummary, ChangedFilesView, ChangedPath, CodeReview, DEFAULT_MODEL, DEFAULT_PROVIDER, DelegateFileReview, EFFORT_ALIASES, EffortAliasName, EffortPosition, ExecuteReviewOptions, FINGERPRINT_MARKER_LENGTH, FailedReviewUnit, FanOutCoordinatorToolkit, FanOutCoordinatorToolkitLayer, FanOutInstructionOptions, FanOutReviewSuite, FanOutReviewToolkit, FanOutReviewer, FanOutReviewerProfile, FanOutSuiteOptions, FileDiffQuery, FileDiffView, FileReviewBrief, FileReviewDelegationFailure, FileReviewReport, FileReviewRequest, FileReviewToolkit, FileReviewToolkitLayer, FileReviewUnitFailed, FileReviewUnitResult, FileReviewer, FileSlice, FileSliceQuery, FindingSeverity, GitCommitSha, GitHubApiFailure, GitHubEventWire, GitHubReviewTarget, InvalidEffortInput, LIVE_GATE_ENV, ListChangedFiles, ListChangedFilesQuery, ListReviewUnits, ListReviewUnitsQuery, MAX_CHANGED_FILES, MAX_CHILD_CONCERNS, MAX_CHILD_FINDINGS, MAX_CONCERNS, MAX_FILE_CHARS, MAX_FILE_REVIEW_TOOL_CALLS, MAX_FINDINGS, MAX_MERGED_FINDINGS, MAX_REVIEW_STATE_MARKER_CHARS, MAX_REVIEW_UNITS, MAX_UNIT_FILES, PROVIDER_CREDENTIAL_ENV, PROVIDER_EFFORT_RUNGS, PatchLine, PrReview, PrReviewFanOutOptions, PrReviewOptions, PrReviewSharedOptions, PriorReviewLookupFailure, PriorReviews, PublishedReview, PullRequestMetadata, PullRequestReviewer, PullRequestReviewerProfile, PullRequestSource, PullRequestSourceFailure, ReadFile, ReadFileDiff, ResolvedReviewTarget, ReviewCommentDraft, ReviewConcern, ReviewCoverage, ReviewEvent, ReviewExecutionContext, ReviewFinding, ReviewGuidance, ReviewHeadComparison, ReviewInputViolation, ReviewInstructionOptions, ReviewMission, ReviewMode, ReviewProvider, ReviewPublicationPlan, ReviewPublisher, ReviewRunOutcome, ReviewScopeMode, ReviewSelection, ReviewShape, ReviewState, ReviewStateAuthenticationFailure, ReviewStateAuthenticator, ReviewStateMarker, ReviewStateMarkerTooLarge, ReviewTargetUnresolved, ReviewToolkit, ReviewToolkitLayer, ReviewUnit, ReviewUnitId, ReviewUnitPlan, ReviewVerdict, RunReviewOptions, StoredReviewConcern, StoredReviewFinding, UNIT_CHANGED_LINE_BUDGET, anchorViolation, annotatePatch, anthropicClientLayer, assessReviewCoverage, buildProfileMission, buildReviewMission, clampMaxFindings, commentableLines, compileIgnoreGlobs, computeChangesetFingerprint, computeProfileFingerprint, defaultFanOutPolicy, defaultFileReviewerPolicy, defaultReviewPolicy, describeReviewModel, enforceFindingsBound, executeReview, extractFingerprint, fanOutHandlersLayer, fanOutHandlersLayerFor, fanOutReviewBudgetLimits, fanOutReviewInstructions, fanOutReviewerProfile, fileReviewDelegation, fileReviewPolicy, fileReviewerInstructions, fingerprintUnchanged, fromStoredConcern, fromStoredFinding, gitHubPriorReviewsLayer, gitHubPullRequestSourceLayer, gitHubReviewLayers, gitHubReviewPublisherLayer, ignoringPullRequestSourceLayer, isEffortPosition, listChangedFilesHandler, liveProfileEnabled, makeAnthropicReviewModel, makeFanOutReviewInstructions, makeFanOutReviewSuite, makeFileReviewerInstructions, makeOpenAiReviewModel, makeReviewInstructions, mapFileReviewChildFailure, normalizeRepoRelativePath, openAiClientLayer, parseEffortPosition, parsePatch, planPublication, planReviewUnits, pullRequestReviewerProfile, rankAndDedupeFindings, readFileDiffHandler, readFileHandler, readGitHubEvent, renderFingerprintMarker, resolveEffortRung, resolveGuidance, resolveReviewTarget, reviewBudgetLimits, reviewInstructions, selectReviewRange, selectedPullRequestSourceLayer, toStoredConcern, toStoredFinding, unavailableReviewStateAuthenticatorLayer, validateReviewState, webCryptoReviewStateAuthenticatorLayer };
|
|
716
|
+
export { ChangedFile, ChangedFileStatus, ChangedFileSummary, ChangedFilesView, ChangedPath, CodeReview, DEFAULT_MODEL, DEFAULT_PROVIDER, DelegateFileReview, EFFORT_ALIASES, EffortAliasName, EffortPosition, ExecuteReviewOptions, FINGERPRINT_MARKER_LENGTH, FailedReviewUnit, FanOutCoordinatorToolkit, FanOutCoordinatorToolkitLayer, FanOutInstructionOptions, FanOutReviewSuite, FanOutReviewToolkit, FanOutReviewer, FanOutReviewerProfile, FanOutSuiteOptions, FileDiffQuery, FileDiffView, FileReviewBrief, FileReviewDelegationFailure, FileReviewReport, FileReviewRequest, FileReviewToolkit, FileReviewToolkitLayer, FileReviewUnitFailed, FileReviewUnitResult, FileReviewer, FileSlice, FileSliceQuery, FindingSeverity, GitCommitSha, GitHubApiFailure, GitHubEventWire, GitHubReviewTarget, InvalidEffortInput, LIVE_GATE_ENV, ListChangedFiles, ListChangedFilesQuery, ListReviewUnits, ListReviewUnitsQuery, MAX_CHANGED_FILES, MAX_CHILD_CONCERNS, MAX_CHILD_FINDINGS, MAX_CONCERNS, MAX_FILE_CHARS, MAX_FILE_REVIEW_TOOL_CALLS, MAX_FINDINGS, MAX_MERGED_FINDINGS, MAX_REVIEW_STATE_MARKER_CHARS, MAX_REVIEW_UNITS, MAX_UNIT_FILES, PROVIDER_CREDENTIAL_ENV, PROVIDER_EFFORT_RUNGS, PatchLine, PrReview, PrReviewFanOutOptions, PrReviewOptions, PrReviewSharedOptions, PriorReviewLookupFailure, PriorReviews, PublishedReview, PullRequestMetadata, PullRequestReviewer, PullRequestReviewerProfile, PullRequestSource, PullRequestSourceFailure, ReadFile, ReadFileDiff, ResolvedReviewTarget, RetirableReview, RetirableReviewComment, ReviewCommentDraft, ReviewConcern, ReviewCoverage, ReviewEvent, ReviewExecutionContext, ReviewFinding, ReviewGuidance, ReviewHeadComparison, ReviewInputViolation, ReviewInstructionOptions, ReviewMission, ReviewMode, ReviewProvider, ReviewPublicationPlan, ReviewPublisher, ReviewRetirementDecision, ReviewRetirementFailure, ReviewRetirementHost, ReviewRetirementInput, ReviewRetirementReport, ReviewRunOutcome, ReviewScopeMode, ReviewSelection, ReviewShape, ReviewState, ReviewStateAuthenticationFailure, ReviewStateAuthenticator, ReviewStateMarker, ReviewStateMarkerTooLarge, ReviewTargetUnresolved, ReviewToolkit, ReviewToolkitLayer, ReviewUnit, ReviewUnitId, ReviewUnitPlan, ReviewVerdict, RunReviewOptions, StoredReviewConcern, StoredReviewFinding, UNIT_CHANGED_LINE_BUDGET, anchorViolation, annotatePatch, anthropicClientLayer, assessReviewCoverage, buildProfileMission, buildReviewMission, clampMaxFindings, commentableLines, compileIgnoreGlobs, computeChangesetFingerprint, computeProfileFingerprint, decideReviewRetirement, defaultFanOutPolicy, defaultFileReviewerPolicy, defaultReviewPolicy, describeReviewModel, enforceFindingsBound, executeReview, extractFingerprint, fanOutHandlersLayer, fanOutHandlersLayerFor, fanOutReviewBudgetLimits, fanOutReviewInstructions, fanOutReviewerProfile, fileReviewDelegation, fileReviewPolicy, fileReviewerInstructions, fingerprintUnchanged, fromStoredConcern, fromStoredFinding, gitHubPriorReviewsLayer, gitHubPullRequestSourceLayer, gitHubReviewLayers, gitHubReviewPublisherLayer, gitHubReviewRetirementHostLayer, hasReviewMetadataMarker, ignoringPullRequestSourceLayer, isEffortPosition, listChangedFilesHandler, liveProfileEnabled, makeAnthropicReviewModel, makeFanOutReviewInstructions, makeFanOutReviewSuite, makeFileReviewerInstructions, makeOpenAiReviewModel, makeReviewInstructions, mapFileReviewChildFailure, normalizeRepoRelativePath, openAiClientLayer, parseEffortPosition, parseGitHubSubmittedAt, parsePatch, planPublication, planReviewUnits, pullRequestReviewerProfile, rankAndDedupeFindings, readFileDiffHandler, readFileHandler, readGitHubEvent, renderFingerprintMarker, resolveEffortRung, resolveGuidance, resolveReviewTarget, retireStaleReviews, reviewBudgetLimits, reviewInstructions, selectReviewRange, selectedPullRequestSourceLayer, toStoredConcern, toStoredFinding, unavailableReviewStateAuthenticatorLayer, validateReviewState, webCryptoReviewStateAuthenticatorLayer };
|
|
716
717
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { A as InvalidEffortInput, C as ReviewEvent, D as compileIgnoreGlobs, E as planPublication, F as ReviewCoverage, I as ReviewShape, L as assessReviewCoverage, M as parseEffortPosition, N as resolveEffortRung, O as ignoringPullRequestSourceLayer, P as FailedReviewUnit, S as ReviewCommentDraft, T as anchorViolation, _ as buildReviewMission, a as anthropicClientLayer, b as fanOutReviewBudgetLimits, c as makeOpenAiReviewModel, d as ReviewTargetUnresolved, f as gitHubReviewLayers, g as ReviewRunOutcome, h as PrReview, i as PROVIDER_EFFORT_RUNGS, j as isEffortPosition, k as EFFORT_ALIASES, l as openAiClientLayer, m as resolveReviewTarget, n as DEFAULT_PROVIDER, o as describeReviewModel, p as readGitHubEvent, r as PROVIDER_CREDENTIAL_ENV, s as makeAnthropicReviewModel, t as DEFAULT_MODEL, u as GitHubEventWire, v as enforceFindingsBound, w as ReviewPublicationPlan, x as reviewBudgetLimits, y as executeReview } from "./providers-
|
|
1
|
+
import { $ as FanOutReviewer, $t as ReviewToolkit, A as ReviewStateMarker, At as ReviewUnitId, B as toStoredConcern, Bt as FileSlice, C as ReviewExecutionContext, Ct as makeFanOutReviewSuite, D as ReviewState, Dt as MAX_REVIEW_UNITS, E as ReviewScopeMode, Et as MAX_MERGED_FINDINGS, F as computeProfileFingerprint, Ft as ChangedFileSummary, G as FINGERPRINT_MARKER_LENGTH, Gt as MAX_CONCERNS, H as unavailableReviewStateAuthenticatorLayer, Ht as FindingSeverity, I as fromStoredConcern, It as ChangedFilesView, J as renderFingerprintMarker, Jt as ReadFile, K as computeChangesetFingerprint, Kt as MAX_FINDINGS, L as fromStoredFinding, Lt as CodeReview, M as StoredReviewConcern, Mt as UNIT_CHANGED_LINE_BUDGET, N as StoredReviewFinding, Nt as planReviewUnits, O as ReviewStateAuthenticationFailure, Ot as MAX_UNIT_FILES, P as buildProfileMission, Pt as rankAndDedupeFindings, Q as FanOutReviewToolkit, Qt as ReviewMission, R as selectReviewRange, Rt as FileDiffQuery, S as MAX_REVIEW_STATE_MARKER_CHARS, Sn as parsePatch, St as makeFanOutReviewInstructions, T as ReviewMode, Tt as mapFileReviewChildFailure, U as validateReviewState, Ut as ListChangedFiles, V as toStoredFinding, Vt as FileSliceQuery, W as webCryptoReviewStateAuthenticatorLayer, Wt as ListChangedFilesQuery, X as FanOutCoordinatorToolkit, Xt as ReviewConcern, Y as DelegateFileReview, Yt as ReadFileDiff, Z as FanOutCoordinatorToolkitLayer, Zt as ReviewFinding, _ as ReviewRetirementReport, _n as ChangedFile, _t as fanOutHandlersLayerFor, a as PublishedReview, an as makeReviewInstructions, at as FileReviewToolkitLayer, b as retireStaleReviews, bn as annotatePatch, bt as fileReviewPolicy, c as gitHubPriorReviewsLayer, cn as resolveGuidance, ct as FileReviewer, d as gitHubReviewRetirementHostLayer, dn as MAX_FILE_CHARS, dt as MAX_CHILD_CONCERNS, en as ReviewToolkitLayer, et as FileReviewBrief, f as parseGitHubSubmittedAt, fn as PullRequestMetadata, ft as MAX_CHILD_FINDINGS, g as ReviewRetirementHost, gn as normalizeRepoRelativePath, gt as fanOutHandlersLayer, h as ReviewRetirementFailure, hn as ReviewInputViolation, ht as defaultFileReviewerPolicy, i as PriorReviews, in as listChangedFilesHandler, it as FileReviewToolkit, j as ReviewStateMarkerTooLarge, jt as ReviewUnitPlan, k as ReviewStateAuthenticator, kt as ReviewUnit, l as gitHubPullRequestSourceLayer, ln as reviewInstructions, lt as ListReviewUnits, m as RetirableReviewComment, mn as PullRequestSourceFailure, mt as defaultFanOutPolicy, n as GitHubReviewTarget, nn as clampMaxFindings, nt as FileReviewReport, o as ReviewPublisher, on as readFileDiffHandler, ot as FileReviewUnitFailed, p as RetirableReview, pn as PullRequestSource, pt as MAX_FILE_REVIEW_TOOL_CALLS, q as extractFingerprint, qt as PullRequestReviewer, r as PriorReviewLookupFailure, rn as defaultReviewPolicy, rt as FileReviewRequest, s as fingerprintUnchanged, sn as readFileHandler, st as FileReviewUnitResult, t as GitHubApiFailure, tn as ReviewVerdict, tt as FileReviewDelegationFailure, u as gitHubReviewPublisherLayer, un as MAX_CHANGED_FILES, ut as ListReviewUnitsQuery, v as decideReviewRetirement, vn as ChangedFileStatus, vt as fanOutReviewInstructions, w as ReviewHeadComparison, wt as makeFileReviewerInstructions, x as GitCommitSha, xn as commentableLines, xt as fileReviewerInstructions, y as hasReviewMetadataMarker, yn as ChangedPath, yt as fileReviewDelegation, z as selectedPullRequestSourceLayer, zt as FileDiffView } from "./github-Lfa_ox-u.mjs";
|
|
2
|
+
import { A as InvalidEffortInput, C as ReviewEvent, D as compileIgnoreGlobs, E as planPublication, F as ReviewCoverage, I as ReviewShape, L as assessReviewCoverage, M as parseEffortPosition, N as resolveEffortRung, O as ignoringPullRequestSourceLayer, P as FailedReviewUnit, S as ReviewCommentDraft, T as anchorViolation, _ as buildReviewMission, a as anthropicClientLayer, b as fanOutReviewBudgetLimits, c as makeOpenAiReviewModel, d as ReviewTargetUnresolved, f as gitHubReviewLayers, g as ReviewRunOutcome, h as PrReview, i as PROVIDER_EFFORT_RUNGS, j as isEffortPosition, k as EFFORT_ALIASES, l as openAiClientLayer, m as resolveReviewTarget, n as DEFAULT_PROVIDER, o as describeReviewModel, p as readGitHubEvent, r as PROVIDER_CREDENTIAL_ENV, s as makeAnthropicReviewModel, t as DEFAULT_MODEL, u as GitHubEventWire, v as enforceFindingsBound, w as ReviewPublicationPlan, x as reviewBudgetLimits, y as executeReview } from "./providers-CaOnz7mK.mjs";
|
|
3
3
|
import { Schema } from "effect";
|
|
4
4
|
//#region src/internal/profiles.ts
|
|
5
5
|
/** The flat reviewer's committed capability claim. */
|
|
@@ -61,6 +61,6 @@ const LIVE_GATE_ENV = "EFFECT_AGENT_LIVE";
|
|
|
61
61
|
*/
|
|
62
62
|
const liveProfileEnabled = (env, credentialEnv) => env["EFFECT_AGENT_LIVE"] === "1" && (env[credentialEnv] ?? "") !== "";
|
|
63
63
|
//#endregion
|
|
64
|
-
export { ChangedFile, ChangedFileStatus, ChangedFileSummary, ChangedFilesView, ChangedPath, CodeReview, DEFAULT_MODEL, DEFAULT_PROVIDER, DelegateFileReview, EFFORT_ALIASES, FINGERPRINT_MARKER_LENGTH, FailedReviewUnit, FanOutCoordinatorToolkit, FanOutCoordinatorToolkitLayer, FanOutReviewToolkit, FanOutReviewer, FanOutReviewerProfile, FileDiffQuery, FileDiffView, FileReviewBrief, FileReviewDelegationFailure, FileReviewReport, FileReviewRequest, FileReviewToolkit, FileReviewToolkitLayer, FileReviewUnitFailed, FileReviewUnitResult, FileReviewer, FileSlice, FileSliceQuery, FindingSeverity, GitCommitSha, GitHubApiFailure, GitHubEventWire, GitHubReviewTarget, InvalidEffortInput, LIVE_GATE_ENV, ListChangedFiles, ListChangedFilesQuery, ListReviewUnits, ListReviewUnitsQuery, MAX_CHANGED_FILES, MAX_CHILD_CONCERNS, MAX_CHILD_FINDINGS, MAX_CONCERNS, MAX_FILE_CHARS, MAX_FILE_REVIEW_TOOL_CALLS, MAX_FINDINGS, MAX_MERGED_FINDINGS, MAX_REVIEW_STATE_MARKER_CHARS, MAX_REVIEW_UNITS, MAX_UNIT_FILES, PROVIDER_CREDENTIAL_ENV, PROVIDER_EFFORT_RUNGS, PrReview, PriorReviewLookupFailure, PriorReviews, PublishedReview, PullRequestMetadata, PullRequestReviewer, PullRequestReviewerProfile, PullRequestSource, PullRequestSourceFailure, ReadFile, ReadFileDiff, ReviewCommentDraft, ReviewConcern, ReviewCoverage, ReviewEvent, ReviewExecutionContext, ReviewFinding, ReviewHeadComparison, ReviewInputViolation, ReviewMission, ReviewMode, ReviewPublicationPlan, ReviewPublisher, ReviewRunOutcome, ReviewScopeMode, ReviewShape, ReviewState, ReviewStateAuthenticationFailure, ReviewStateAuthenticator, ReviewStateMarker, ReviewStateMarkerTooLarge, ReviewTargetUnresolved, ReviewToolkit, ReviewToolkitLayer, ReviewUnit, ReviewUnitId, ReviewUnitPlan, ReviewVerdict, StoredReviewConcern, StoredReviewFinding, UNIT_CHANGED_LINE_BUDGET, anchorViolation, annotatePatch, anthropicClientLayer, assessReviewCoverage, buildProfileMission, buildReviewMission, clampMaxFindings, commentableLines, compileIgnoreGlobs, computeChangesetFingerprint, computeProfileFingerprint, defaultFanOutPolicy, defaultFileReviewerPolicy, defaultReviewPolicy, describeReviewModel, enforceFindingsBound, executeReview, extractFingerprint, fanOutHandlersLayer, fanOutHandlersLayerFor, fanOutReviewBudgetLimits, fanOutReviewInstructions, fanOutReviewerProfile, fileReviewDelegation, fileReviewPolicy, fileReviewerInstructions, fingerprintUnchanged, fromStoredConcern, fromStoredFinding, gitHubPriorReviewsLayer, gitHubPullRequestSourceLayer, gitHubReviewLayers, gitHubReviewPublisherLayer, ignoringPullRequestSourceLayer, isEffortPosition, listChangedFilesHandler, liveProfileEnabled, makeAnthropicReviewModel, makeFanOutReviewInstructions, makeFanOutReviewSuite, makeFileReviewerInstructions, makeOpenAiReviewModel, makeReviewInstructions, mapFileReviewChildFailure, normalizeRepoRelativePath, openAiClientLayer, parseEffortPosition, parsePatch, planPublication, planReviewUnits, pullRequestReviewerProfile, rankAndDedupeFindings, readFileDiffHandler, readFileHandler, readGitHubEvent, renderFingerprintMarker, resolveEffortRung, resolveGuidance, resolveReviewTarget, reviewBudgetLimits, reviewInstructions, selectReviewRange, selectedPullRequestSourceLayer, toStoredConcern, toStoredFinding, unavailableReviewStateAuthenticatorLayer, validateReviewState, webCryptoReviewStateAuthenticatorLayer };
|
|
64
|
+
export { ChangedFile, ChangedFileStatus, ChangedFileSummary, ChangedFilesView, ChangedPath, CodeReview, DEFAULT_MODEL, DEFAULT_PROVIDER, DelegateFileReview, EFFORT_ALIASES, FINGERPRINT_MARKER_LENGTH, FailedReviewUnit, FanOutCoordinatorToolkit, FanOutCoordinatorToolkitLayer, FanOutReviewToolkit, FanOutReviewer, FanOutReviewerProfile, FileDiffQuery, FileDiffView, FileReviewBrief, FileReviewDelegationFailure, FileReviewReport, FileReviewRequest, FileReviewToolkit, FileReviewToolkitLayer, FileReviewUnitFailed, FileReviewUnitResult, FileReviewer, FileSlice, FileSliceQuery, FindingSeverity, GitCommitSha, GitHubApiFailure, GitHubEventWire, GitHubReviewTarget, InvalidEffortInput, LIVE_GATE_ENV, ListChangedFiles, ListChangedFilesQuery, ListReviewUnits, ListReviewUnitsQuery, MAX_CHANGED_FILES, MAX_CHILD_CONCERNS, MAX_CHILD_FINDINGS, MAX_CONCERNS, MAX_FILE_CHARS, MAX_FILE_REVIEW_TOOL_CALLS, MAX_FINDINGS, MAX_MERGED_FINDINGS, MAX_REVIEW_STATE_MARKER_CHARS, MAX_REVIEW_UNITS, MAX_UNIT_FILES, PROVIDER_CREDENTIAL_ENV, PROVIDER_EFFORT_RUNGS, PrReview, PriorReviewLookupFailure, PriorReviews, PublishedReview, PullRequestMetadata, PullRequestReviewer, PullRequestReviewerProfile, PullRequestSource, PullRequestSourceFailure, ReadFile, ReadFileDiff, RetirableReview, RetirableReviewComment, ReviewCommentDraft, ReviewConcern, ReviewCoverage, ReviewEvent, ReviewExecutionContext, ReviewFinding, ReviewHeadComparison, ReviewInputViolation, ReviewMission, ReviewMode, ReviewPublicationPlan, ReviewPublisher, ReviewRetirementFailure, ReviewRetirementHost, ReviewRetirementReport, ReviewRunOutcome, ReviewScopeMode, ReviewShape, ReviewState, ReviewStateAuthenticationFailure, ReviewStateAuthenticator, ReviewStateMarker, ReviewStateMarkerTooLarge, ReviewTargetUnresolved, ReviewToolkit, ReviewToolkitLayer, ReviewUnit, ReviewUnitId, ReviewUnitPlan, ReviewVerdict, StoredReviewConcern, StoredReviewFinding, UNIT_CHANGED_LINE_BUDGET, anchorViolation, annotatePatch, anthropicClientLayer, assessReviewCoverage, buildProfileMission, buildReviewMission, clampMaxFindings, commentableLines, compileIgnoreGlobs, computeChangesetFingerprint, computeProfileFingerprint, decideReviewRetirement, defaultFanOutPolicy, defaultFileReviewerPolicy, defaultReviewPolicy, describeReviewModel, enforceFindingsBound, executeReview, extractFingerprint, fanOutHandlersLayer, fanOutHandlersLayerFor, fanOutReviewBudgetLimits, fanOutReviewInstructions, fanOutReviewerProfile, fileReviewDelegation, fileReviewPolicy, fileReviewerInstructions, fingerprintUnchanged, fromStoredConcern, fromStoredFinding, gitHubPriorReviewsLayer, gitHubPullRequestSourceLayer, gitHubReviewLayers, gitHubReviewPublisherLayer, gitHubReviewRetirementHostLayer, hasReviewMetadataMarker, ignoringPullRequestSourceLayer, isEffortPosition, listChangedFilesHandler, liveProfileEnabled, makeAnthropicReviewModel, makeFanOutReviewInstructions, makeFanOutReviewSuite, makeFileReviewerInstructions, makeOpenAiReviewModel, makeReviewInstructions, mapFileReviewChildFailure, normalizeRepoRelativePath, openAiClientLayer, parseEffortPosition, parseGitHubSubmittedAt, parsePatch, planPublication, planReviewUnits, pullRequestReviewerProfile, rankAndDedupeFindings, readFileDiffHandler, readFileHandler, readGitHubEvent, renderFingerprintMarker, resolveEffortRung, resolveGuidance, resolveReviewTarget, retireStaleReviews, reviewBudgetLimits, reviewInstructions, selectReviewRange, selectedPullRequestSourceLayer, toStoredConcern, toStoredFinding, unavailableReviewStateAuthenticatorLayer, validateReviewState, webCryptoReviewStateAuthenticatorLayer };
|
|
65
65
|
|
|
66
66
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as toStoredConcern, C as ReviewExecutionContext, Ct as makeFanOutReviewSuite, D as ReviewState, F as computeProfileFingerprint, I as fromStoredConcern, J as renderFingerprintMarker, Jt as ReadFile, K as computeChangesetFingerprint, L as fromStoredFinding, Lt as CodeReview, Nt as planReviewUnits, P as buildProfileMission, Pt as rankAndDedupeFindings, Qt as ReviewMission, Rt as FileDiffQuery, Ut as ListChangedFiles, V as toStoredFinding, Xt as ReviewConcern, Yt as ReadFileDiff, Z as FanOutCoordinatorToolkitLayer, Zt as ReviewFinding, _t as fanOutHandlersLayerFor, a as PublishedReview, an as makeReviewInstructions, at as FileReviewToolkitLayer, c as gitHubPriorReviewsLayer, cn as resolveGuidance, d as gitHubReviewRetirementHostLayer, en as ReviewToolkitLayer, fn as PullRequestMetadata, hn as ReviewInputViolation, l as gitHubPullRequestSourceLayer, n as GitHubReviewTarget, nn as clampMaxFindings, o as ReviewPublisher, pn as PullRequestSource, rn as defaultReviewPolicy, rt as FileReviewRequest, st as FileReviewUnitResult, tt as FileReviewDelegationFailure, u as gitHubReviewPublisherLayer, xn as commentableLines } from "./github-Lfa_ox-u.mjs";
|
|
2
2
|
import { Config, Effect, FileSystem, Layer, Option, Schema } from "effect";
|
|
3
3
|
import { Agent, AgentPolicy, AgentRuntime, IdGenerator, SubagentReservationsMemoryLive, UsageBudgetLimits, UsageTotals, getToolExecutionClass, makeUsageBudget, toRunBudgetHook } from "effect-agent";
|
|
4
4
|
import { Toolkit } from "effect/unstable/ai";
|
|
@@ -913,15 +913,16 @@ const resolveReviewTarget = Effect.fn("resolveReviewTarget")(function* (options)
|
|
|
913
913
|
*/
|
|
914
914
|
const gitHubReviewLayers = (target) => Layer.unwrap(Effect.gen(function* () {
|
|
915
915
|
const apiUrl = yield* Config.string("GITHUB_API_URL").pipe(Config.withDefault("https://api.github.com"));
|
|
916
|
+
const graphqlUrl = yield* Config.string("GITHUB_GRAPHQL_URL").pipe(Config.withDefault(apiUrl === "https://api.github.com" ? "https://api.github.com/graphql" : apiUrl.replace(/\/api\/v3$/, "/api/graphql")));
|
|
916
917
|
const token = yield* Config.option(Config.redacted("GITHUB_TOKEN"));
|
|
917
918
|
const targetLayer = GitHubReviewTarget.layer({
|
|
918
919
|
apiUrl,
|
|
920
|
+
graphqlUrl,
|
|
919
921
|
repository: target.repository,
|
|
920
922
|
number: target.number,
|
|
921
923
|
token
|
|
922
924
|
});
|
|
923
|
-
|
|
924
|
-
return Layer.mergeAll(gitHubPullRequestSourceLayer.pipe(Layer.provide(deps)), gitHubReviewPublisherLayer.pipe(Layer.provide(deps)), gitHubPriorReviewsLayer.pipe(Layer.provide(deps)));
|
|
925
|
+
return Layer.mergeAll(gitHubPullRequestSourceLayer.pipe(Layer.provide(targetLayer)), gitHubReviewPublisherLayer.pipe(Layer.provide(targetLayer)), gitHubPriorReviewsLayer.pipe(Layer.provide(targetLayer)), gitHubReviewRetirementHostLayer.pipe(Layer.provide(targetLayer)));
|
|
925
926
|
}));
|
|
926
927
|
//#endregion
|
|
927
928
|
//#region src/internal/providers.ts
|
|
@@ -983,4 +984,4 @@ const anthropicClientLayer = AnthropicClient.layerConfig({ apiKey: Config.redact
|
|
|
983
984
|
//#endregion
|
|
984
985
|
export { InvalidEffortInput as A, ReviewEvent as C, compileIgnoreGlobs as D, planPublication as E, ReviewCoverage as F, ReviewShape as I, assessReviewCoverage as L, parseEffortPosition as M, resolveEffortRung as N, ignoringPullRequestSourceLayer as O, FailedReviewUnit as P, ReviewCommentDraft as S, anchorViolation as T, buildReviewMission as _, anthropicClientLayer as a, fanOutReviewBudgetLimits as b, makeOpenAiReviewModel as c, ReviewTargetUnresolved as d, gitHubReviewLayers as f, ReviewRunOutcome as g, PrReview as h, PROVIDER_EFFORT_RUNGS as i, isEffortPosition as j, EFFORT_ALIASES as k, openAiClientLayer as l, resolveReviewTarget as m, DEFAULT_PROVIDER as n, describeReviewModel as o, readGitHubEvent as p, PROVIDER_CREDENTIAL_ENV as r, makeAnthropicReviewModel as s, DEFAULT_MODEL as t, GitHubEventWire as u, enforceFindingsBound as v, ReviewPublicationPlan as w, reviewBudgetLimits as x, executeReview as y };
|
|
985
986
|
|
|
986
|
-
//# sourceMappingURL=providers-
|
|
987
|
+
//# sourceMappingURL=providers-CaOnz7mK.mjs.map
|