@effect-agent/pr-review 0.0.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/dist/action.d.mts +185 -0
  4. package/dist/action.mjs +406 -0
  5. package/dist/action.mjs.map +1 -0
  6. package/dist/cli.d.mts +1 -0
  7. package/dist/cli.mjs +102 -0
  8. package/dist/cli.mjs.map +1 -0
  9. package/dist/fan-out-Dy84-dIs.d.mts +986 -0
  10. package/dist/github-bwQ2V-wb.mjs +1360 -0
  11. package/dist/github-bwQ2V-wb.mjs.map +1 -0
  12. package/dist/index.d.mts +716 -0
  13. package/dist/index.mjs +66 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/dist/providers-DyLJlpJQ.mjs +986 -0
  16. package/dist/providers-DyLJlpJQ.mjs.map +1 -0
  17. package/dist/testing.d.mts +130 -0
  18. package/dist/testing.mjs +228 -0
  19. package/dist/testing.mjs.map +1 -0
  20. package/package.json +54 -0
  21. package/src/action.ts +666 -0
  22. package/src/cli.ts +213 -0
  23. package/src/index.ts +20 -0
  24. package/src/internal/action-entry.ts +41 -0
  25. package/src/internal/coverage.ts +245 -0
  26. package/src/internal/diff.ts +134 -0
  27. package/src/internal/effort.ts +86 -0
  28. package/src/internal/factory.ts +374 -0
  29. package/src/internal/fan-out-scripted.ts +163 -0
  30. package/src/internal/fan-out.ts +447 -0
  31. package/src/internal/fingerprint.ts +74 -0
  32. package/src/internal/fixtures.ts +127 -0
  33. package/src/internal/github-env.ts +128 -0
  34. package/src/internal/github.ts +531 -0
  35. package/src/internal/ignore.ts +88 -0
  36. package/src/internal/profiles.ts +79 -0
  37. package/src/internal/providers.ts +91 -0
  38. package/src/internal/render.ts +428 -0
  39. package/src/internal/review-agent.ts +379 -0
  40. package/src/internal/review-state.ts +488 -0
  41. package/src/internal/review-units.ts +167 -0
  42. package/src/internal/run.ts +397 -0
  43. package/src/internal/scripted.ts +108 -0
  44. package/src/internal/source.ts +110 -0
  45. package/src/testing.ts +8 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel van der Merwe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # @effect-agent/pr-review
2
+
3
+ A bounded, fail-closed GitHub pull-request reviewer built on the effect-agent
4
+ public surface. One read-only Agent reviews a pull request through typed
5
+ ports; the host validates every finding anchor against the real diff and
6
+ posts one review after the run settles.
7
+
8
+ **Deployment class E (ephemeral).** One `AgentRuntime.run` per invocation, no
9
+ durability claim, and review posting is never exactly-once: a failed or
10
+ truncated run posts nothing.
11
+
12
+ ## Use
13
+
14
+ ```ts
15
+ import { Effect, Layer } from "effect";
16
+ import {
17
+ PrReview,
18
+ gitHubReviewLayers,
19
+ resolveReviewTarget,
20
+ makeOpenAiReviewModel,
21
+ openAiClientLayer,
22
+ } from "@effect-agent/pr-review";
23
+
24
+ const reviewer = PrReview.make({ model: makeOpenAiReviewModel() });
25
+
26
+ const program = Effect.gen(function* () {
27
+ const target = yield* resolveReviewTarget({ repository: "acme/api", number: 123 });
28
+ return yield* reviewer
29
+ .run({ post: true })
30
+ .pipe(Effect.provide(Layer.merge(gitHubReviewLayers(target), openAiClientLayer)));
31
+ });
32
+ ```
33
+
34
+ The run's requirement channel keeps every real dependency visible: the
35
+ `PullRequestSource` and `ReviewPublisher` ports, the provider client, and the
36
+ handler Layer of any extra tool you add. Anthropic is equally supported
37
+ (`makeAnthropicReviewModel`, `anthropicClientLayer`), and the factory accepts
38
+ any Effect AI Model.
39
+
40
+ ## Adapt
41
+
42
+ ```ts
43
+ const reviewer = PrReview.make({
44
+ model: makeAnthropicReviewModel("claude-sonnet-5"),
45
+ guidance: (mission) => [
46
+ "This is an Effect codebase. Flag naked Promises in public APIs.",
47
+ mission.changedFileCount > 50 ? "Large PR: prioritize breadth over nit depth." : "",
48
+ ],
49
+ ignore: ["**/*.lock", "dist/**"],
50
+ maxFindings: 10,
51
+ policy: { maxTurns: 20, maxToolCalls: 40, maxDuration: "10 minutes", toolConcurrency: 2 },
52
+ extraTools: [MyReadonlyTool], // must be annotated ToolExecutionClass "readonly"
53
+ });
54
+ ```
55
+
56
+ Every knob widens what goes INTO the review. What leaves it is not
57
+ configurable: model output is untrusted input, so finding anchors are
58
+ re-validated against the parsed unified diff (invalid ones are demoted into
59
+ the review body with the reason named, never trusted), the findings bound is
60
+ enforced host-side, and publication happens only through the
61
+ `ReviewPublisher` port after the run settles. `PrReview.makeFanOut` builds
62
+ the delegating variant — bounded per-unit child reviewers (S1 attached
63
+ ephemeral delegation) merged under the same output contract and the same
64
+ publication path; the shared `guidance` and `maxFindings` shape the
65
+ coordinator's merge as well as the children.
66
+
67
+ ## What a posted review looks like
68
+
69
+ The body opens with a host-derived callout tier — `[!CAUTION]` when any
70
+ finding is blocking, `[!IMPORTANT]` for important findings, an ℹ️ blockquote
71
+ for nits, `✅` for a clean approval — computed from the validated severities,
72
+ never from model prose. Below the summary, non-anchored `concerns` (deletion
73
+ plans, rollout sequencing, coverage gaps, scope questions — things with no
74
+ diff line to point at) render as severity-tagged sections. The footer names
75
+ the model binding, the observed token usage, and links to the workflow run;
76
+ an invisible metadata comment pins the reviewed head commit so later readers
77
+ know when line callouts have gone stale.
78
+
79
+ ## Swap a port
80
+
81
+ Tools observe the pull request only through `PullRequestSource`; publication
82
+ happens only through `ReviewPublisher`. Provide your own Layers to review
83
+ anything diff-shaped or publish anywhere else — the GitHub REST adapters are
84
+ one implementation, not the contract.
85
+
86
+ ## Test what you adapted
87
+
88
+ ```ts
89
+ import {
90
+ fixturePullRequestSourceLayer,
91
+ collectingReviewPublisherLayer,
92
+ makeOfflineReviewerModel,
93
+ makePromptKeyedModel,
94
+ } from "@effect-agent/pr-review/testing";
95
+ ```
96
+
97
+ Deterministic in-memory adapters for both ports plus prompt-keyed scripted
98
+ models that walk the real tool surface — no network, no credentials, every
99
+ ordinary gate.
100
+
101
+ ## Incremental Action reviews
102
+
103
+ A completely covered posted Action review carries bounded, versioned,
104
+ HMAC-authenticated continuity state:
105
+ the exact PR/base/head lineage, profile and accepted-scope fingerprints, and
106
+ the still-unresolved findings and concerns. A later Action run validates the
107
+ state and reviews the GitHub comparison from that reviewed head to the
108
+ current head, not the complete base...HEAD diff. Unchanged accepted scope is
109
+ not sent back to the model; unchanged unresolved findings remain active;
110
+ changed or reverted paths invalidate their prior findings. Non-anchored
111
+ concerns are carried conservatively until a full audit because they cannot be
112
+ mapped safely to one path.
113
+
114
+ The state marker must be terminal, signed with the configured stable
115
+ `PR_REVIEW_STATE_SECRET`, authored by the default GitHub Actions bot, and
116
+ pinned to the reviewed commit. State lookup, authentication, schema, identity,
117
+ ancestry, profile, and comparison checks are
118
+ fail-closed for scope selection: missing, stale, incompatible, or truncated
119
+ state/comparisons produce a visible full-diff fallback. An ancestor base
120
+ advance remains incremental and adds overlapping PR paths as affected
121
+ context; a materially changed base lineage falls back to full. Re-running the
122
+ same covered head skips model execution by default while preserving its
123
+ stored blocking/success conclusion.
124
+
125
+ Authentication is an explicit Effect service supplied by the Action host;
126
+ WebCrypto import/sign/verify failures stay typed. The terminal marker is
127
+ schema-branded and capped at 24,000 characters. If signing fails or state
128
+ exceeds that bound, the completed review is posted without continuity state
129
+ and with a bounded warning, so the next run safely performs a full review.
130
+
131
+ `review-mode: final` is the explicit bounded merge-readiness audit. It reviews
132
+ the full current PR diff and resets the incremental baseline; normal
133
+ `synchronize` events use `incremental` and do not perform this audit.
134
+
135
+ ## Hosts
136
+
137
+ - **GitHub Actions**: the repository ships a prebuilt node-runtime action
138
+ supporting a committed review-profile document via `guidance-file` (this
139
+ repository's own profile lives at `.github/review-guidance.md`)
140
+ (`action/` at the repo root) — `uses` it with an API-key secret and nothing
141
+ else. For custom reviewers in CI, `@effect-agent/pr-review/action` exports
142
+ `runReviewAction` (event resolution, typed draft/non-PR skips, bounded range
143
+ selection, step outputs, and conservative check gate) to harness your own
144
+ `reviewer.run`.
145
+ - **CLI**: `bun src/cli.ts --repo owner/name --pr 123 [--post] [--provider anthropic] [--fan-out]`
146
+ (also exported as the `./cli` entry).
147
+
148
+ Environment: `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` for the model,
149
+ `PR_REVIEW_STATE_SECRET` to authenticate incremental state,
150
+ `GITHUB_TOKEN` to post (optional for public-repository reads), and the
151
+ standard `GITHUB_REPOSITORY` / `GITHUB_EVENT_PATH` / `GITHUB_API_URL`
152
+ variables inside Actions.
153
+
154
+ ## Bounds, spelled out
155
+
156
+ Finite `AgentPolicy` on every definition plus run-level `UsageBudgetLimits`
157
+ (tokens, tool calls, cost, duration). Reading a file head version beyond 200k
158
+ characters is refused typed. The changeset surface is bounded at 300 files:
159
+ files beyond the bound are not fetched, and the review body reports
160
+ `Reviewed N of M changed files` instead of claiming completeness. Fan-out
161
+ capacity overflow is reported in the review summary, never dropped. Any
162
+ blocking active finding fails the Action check. Any required-file coverage
163
+ gap — undiffable/unassigned paths, failed units (including policy exhaustion),
164
+ truncation, or coordinator/run failure — is non-success rather than green.
@@ -0,0 +1,185 @@
1
+ import { J as ReviewPublisher, K as PriorReviews, U as GitHubApiFailure, _n as ChangedFile, ct as ReviewMode, fn as PullRequestMetadata, mn as PullRequestSourceFailure, pn as PullRequestSource, pt as ReviewStateAuthenticator } from "./fan-out-Dy84-dIs.mjs";
2
+ import { EffortPosition, InvalidEffortInput, ReviewProvider, ReviewRunOutcome, ReviewTargetUnresolved, RunReviewOptions } from "./index.mjs";
3
+ import { Config, Effect, FileSystem, Schema } from "effect";
4
+ import { BudgetExceeded } from "effect-agent";
5
+ //#region src/action.d.ts
6
+ /** Deprecated compatibility input; host-derived conclusions are unconditional. */
7
+ declare const FailOnPolicy: Schema.Literals<readonly ["never", "request-changes"]>;
8
+ type FailOnPolicy = typeof FailOnPolicy.Type;
9
+ declare const ReviewCheckConclusion: Schema.Literals<readonly ["success", "blocking", "incomplete"]>;
10
+ type ReviewCheckConclusion = typeof ReviewCheckConclusion.Type;
11
+ declare const ReviewGateFailed_base: Schema.Class<ReviewGateFailed, Schema.TaggedStruct<"ReviewGateFailed", {
12
+ readonly conclusion: Schema.Literals<readonly ["blocking", "incomplete"]>;
13
+ readonly reasons: Schema.$Array<Schema.NonEmptyString>;
14
+ }>, import("effect/Cause").YieldableError>;
15
+ /** The host-derived blocking or incomplete conclusion failed the check. */
16
+ declare class ReviewGateFailed extends ReviewGateFailed_base {
17
+ get message(): string;
18
+ }
19
+ declare const InvalidMaxDurationInput_base: Schema.Class<InvalidMaxDurationInput, Schema.TaggedStruct<"InvalidMaxDurationInput", {
20
+ readonly minutes: Schema.Int;
21
+ }>, import("effect/Cause").YieldableError>;
22
+ /** A configured max-duration that cannot bound a run; configuration faults fail loudly. */
23
+ declare class InvalidMaxDurationInput extends InvalidMaxDurationInput_base {
24
+ get message(): string;
25
+ }
26
+ /** Everything the packaged action reads from its environment. */
27
+ interface ResolvedActionInputs {
28
+ readonly provider: ReviewProvider;
29
+ readonly model: string | undefined;
30
+ readonly effort: EffortPosition | undefined;
31
+ readonly post: boolean;
32
+ readonly applyVerdict: boolean;
33
+ readonly fanOut: boolean;
34
+ readonly guidance: string | undefined;
35
+ readonly guidanceFile: string | undefined;
36
+ readonly ignore: ReadonlyArray<string>;
37
+ readonly maxFindings: number | undefined;
38
+ readonly maxDurationMinutes: number | undefined;
39
+ readonly reviewMode: ReviewMode;
40
+ /** Deprecated compatibility input; conclusions are always conservative. */
41
+ readonly failOn: FailOnPolicy;
42
+ readonly skipUnchanged: boolean;
43
+ }
44
+ /** Read the PR_REVIEW_* input surface (all optional, all defaulted). */
45
+ declare const resolveActionInputs: () => Effect.Effect<{
46
+ provider: ReviewProvider;
47
+ model: string | undefined;
48
+ effort: number | undefined;
49
+ post: boolean;
50
+ applyVerdict: boolean;
51
+ fanOut: boolean;
52
+ guidance: string | undefined;
53
+ guidanceFile: string | undefined;
54
+ ignore: string[];
55
+ maxFindings: number | undefined;
56
+ maxDurationMinutes: number | undefined;
57
+ reviewMode: "final" | "incremental";
58
+ failOn: "never" | "request-changes";
59
+ skipUnchanged: boolean;
60
+ }, Config.ConfigError | InvalidEffortInput | InvalidMaxDurationInput, never>;
61
+ /** A guidance file larger than this is refused, never silently truncated. */
62
+ declare const MAX_GUIDANCE_FILE_CHARS = 20000;
63
+ declare const GuidanceFileUnreadable_base: Schema.Class<GuidanceFileUnreadable, Schema.TaggedStruct<"GuidanceFileUnreadable", {
64
+ readonly path: Schema.String;
65
+ readonly reason: Schema.String;
66
+ }>, import("effect/Cause").YieldableError>;
67
+ /** A configured guidance file could not be used; configuration faults fail loudly. */
68
+ declare class GuidanceFileUnreadable extends GuidanceFileUnreadable_base {
69
+ get message(): string;
70
+ }
71
+ /**
72
+ * Resolve the effective review guidance: the committed guidance file (a
73
+ * repository-owned review profile) first, with any inline guidance appended.
74
+ * A configured-but-unreadable file fails typed — a review silently running
75
+ * without its profile would be worse than a red job.
76
+ */
77
+ declare const resolveGuidance: (inputs: {
78
+ readonly guidance: string | undefined;
79
+ readonly guidanceFile: string | undefined;
80
+ }) => Effect.Effect<string | undefined, GuidanceFileUnreadable, FileSystem.FileSystem>;
81
+ /** Append step outputs to GITHUB_OUTPUT when present (no-op locally). */
82
+ declare const writeActionOutputs: (entries: readonly (readonly [name: string, value: string])[]) => Effect.Effect<void, Config.ConfigError | import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
83
+ /** Append markdown to the GITHUB_STEP_SUMMARY report when present (no-op locally). */
84
+ declare const writeStepSummary: (lines: readonly string[]) => Effect.Effect<void, Config.ConfigError | import("effect/PlatformError").PlatformError, FileSystem.FileSystem>;
85
+ /** The result of one action invocation: a typed skip or a settled review. */
86
+ type ReviewActionResult = {
87
+ readonly _tag: "Skipped";
88
+ readonly reason: string;
89
+ } | {
90
+ readonly _tag: "Completed";
91
+ readonly outcome: ReviewRunOutcome;
92
+ };
93
+ /** The reviewer surface the action harness drives. `PrReview.make` and
94
+ * `PrReview.makeFanOut` provide the state-selection effects; the legacy
95
+ * fingerprint field remains for source compatibility with custom harnesses. */
96
+ interface HarnessedReviewer<E, R, FingerprintE, FingerprintR> {
97
+ readonly run: (runOptions?: RunReviewOptions) => Effect.Effect<ReviewRunOutcome, E, R>;
98
+ readonly fingerprint?: Effect.Effect<string, FingerprintE, FingerprintR> | undefined;
99
+ readonly profileFingerprint?: Effect.Effect<string, FingerprintE, FingerprintR> | undefined;
100
+ readonly snapshot?: Effect.Effect<{
101
+ readonly metadata: PullRequestMetadata;
102
+ readonly files: ReadonlyArray<ChangedFile>;
103
+ }, FingerprintE, FingerprintR> | undefined;
104
+ readonly filterFiles?: ((files: ReadonlyArray<ChangedFile>) => ReadonlyArray<ChangedFile>) | undefined;
105
+ }
106
+ /** Host-derived check conclusion; model verdict prose cannot weaken it. */
107
+ declare const concludeReviewOutcome: (outcome: ReviewRunOutcome) => {
108
+ readonly conclusion: ReviewCheckConclusion;
109
+ readonly reasons: ReadonlyArray<string>;
110
+ };
111
+ /**
112
+ * Harness one already-built reviewer inside the Actions environment: resolve
113
+ * the target from the event, provide the GitHub source/publisher/prior
114
+ * reviews, validate/select bounded continuity scope, write step outputs, and apply
115
+ * the host-derived coverage/blocker gate. Draft and non-PR skips are values;
116
+ * an unchanged reviewed head preserves and enforces its stored conclusion. The reviewer's
117
+ * remaining requirements — its model client, any extra tool handlers — stay
118
+ * visible in `R` for the caller.
119
+ */
120
+ declare const runReviewAction: <E, R, FingerprintE = never, FingerprintR = never>(reviewer: HarnessedReviewer<E, R, FingerprintE, FingerprintR>, options?: {
121
+ readonly post?: boolean | undefined;
122
+ readonly failOn?: FailOnPolicy | undefined;
123
+ /** Skip model execution when the current head already has complete stored coverage. */
124
+ readonly skipUnchanged?: boolean | undefined;
125
+ /** Incremental by default; `final` deliberately re-reviews the full PR diff. */
126
+ readonly reviewMode?: ReviewMode | undefined;
127
+ /** Model binding descriptor for the Actions step summary. */
128
+ readonly modelLabel?: string | undefined;
129
+ /** Explicit test/custom-host history override; GitHub owns the default adapter. */
130
+ readonly priorReviews?: PriorReviews["Service"] | undefined;
131
+ }) => Effect.Effect<{
132
+ _tag: "Skipped";
133
+ reason: string;
134
+ } | {
135
+ reason?: undefined;
136
+ _tag: "Completed";
137
+ outcome: ReviewRunOutcome;
138
+ }, E | FingerprintE | Config.ConfigError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved, FileSystem.FileSystem | ReviewStateAuthenticator | Exclude<FingerprintR, PriorReviews | PullRequestSource | ReviewPublisher> | Exclude<R, PriorReviews | PullRequestSource | ReviewPublisher>>;
139
+ /**
140
+ * The packaged, environment-driven action program: inputs from PR_REVIEW_*,
141
+ * reviewer built from the packaged factory, provider client from the
142
+ * matching credential environment variable.
143
+ */
144
+ declare const reviewActionProgram: Effect.Effect<{
145
+ _tag: "Skipped";
146
+ reason: string;
147
+ } | {
148
+ reason?: undefined;
149
+ _tag: "Completed";
150
+ outcome: ReviewRunOutcome;
151
+ }, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | BudgetExceeded | Config.ConfigError | GitHubApiFailure | GuidanceFileUnreadable | InvalidEffortInput | InvalidMaxDurationInput | import("effect-agent").ModelProtocolError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved | Schema.SchemaError, FileSystem.FileSystem>;
152
+ /** Run the packaged action program on Node; the bundled action entrypoint. */
153
+ declare const main: () => void;
154
+ /** The packaged GitHub Actions surface. */
155
+ declare const PrReviewAction: {
156
+ readonly inputs: () => Effect.Effect<{
157
+ provider: ReviewProvider;
158
+ model: string | undefined;
159
+ effort: number | undefined;
160
+ post: boolean;
161
+ applyVerdict: boolean;
162
+ fanOut: boolean;
163
+ guidance: string | undefined;
164
+ guidanceFile: string | undefined;
165
+ ignore: string[];
166
+ maxFindings: number | undefined;
167
+ maxDurationMinutes: number | undefined;
168
+ reviewMode: "final" | "incremental";
169
+ failOn: "never" | "request-changes";
170
+ skipUnchanged: boolean;
171
+ }, Config.ConfigError | InvalidEffortInput | InvalidMaxDurationInput, never>;
172
+ readonly run: typeof runReviewAction;
173
+ readonly program: Effect.Effect<{
174
+ _tag: "Skipped";
175
+ reason: string;
176
+ } | {
177
+ reason?: undefined;
178
+ _tag: "Completed";
179
+ outcome: ReviewRunOutcome;
180
+ }, import("effect-agent").AgentApprovalDenied | import("effect-agent").AgentApprovalPending | import("effect-agent").AgentChildPending | import("effect-agent").AgentInputError | import("effect-agent").AgentOutputError | import("effect-agent").AgentPolicyError | import("effect/unstable/ai/AiError").AiError | import("effect-agent").BudgetAdapterError | BudgetExceeded | Config.ConfigError | GitHubApiFailure | GuidanceFileUnreadable | InvalidEffortInput | InvalidMaxDurationInput | import("effect-agent").ModelProtocolError | import("effect/PlatformError").PlatformError | PullRequestSourceFailure | ReviewGateFailed | ReviewTargetUnresolved | Schema.SchemaError, FileSystem.FileSystem>;
181
+ readonly main: typeof main;
182
+ };
183
+ //#endregion
184
+ export { FailOnPolicy, GuidanceFileUnreadable, HarnessedReviewer, InvalidMaxDurationInput, MAX_GUIDANCE_FILE_CHARS, PrReviewAction, ResolvedActionInputs, ReviewActionResult, ReviewCheckConclusion, ReviewGateFailed, concludeReviewOutcome, main, resolveActionInputs, resolveGuidance, reviewActionProgram, runReviewAction, writeActionOutputs, writeStepSummary };
185
+ //# sourceMappingURL=action.d.mts.map