Documentation
¶
Overview ¶
Package types defines the per-agent abstraction interfaces for `entire review`.
AgentReviewer is the contract every supported agent (claude-code, codex, gemini-cli, future additions) implements in its own package. The orchestrator in cmd/entire/cli/review/run.go consumes this interface, never importing concrete agent packages — that's how new agents land as additive files without touching shared code.
Events flow as a stream: implementations spawn the agent process, parse stdout into a sequence of typed Events (Started, AssistantText, ToolCall, Tokens, Finished, RunError), and surface them via Process.Events. Per-agent quirks (codex's chrome stripping, gemini's stdin requirement, claude's argv shape) are entirely encapsulated inside each agent's adapter — shared code only sees the cleaned event stream.
Living in a subpackage (not the review root package) avoids import cycles: per-agent reviewers and the orchestrator both depend on these types without depending on each other.
Package types — see reviewer.go for package-level rationale.
sink.go defines the consumer-side abstractions for review runs: Sink (event consumer interface), RunSummary (post-run record), AgentRun (per-agent post-run data), and AgentStatus (terminal state enum).
Package types — see reviewer.go for package-level rationale.
template.go provides ReviewerTemplate, a struct that implements AgentReviewer using two caller-supplied functions: BuildCmd (per-agent argv/env construction) and Parser (per-agent stdout-to-Event stream).
All three currently-supported agents (claude-code, codex, gemini-cli) share the Start/Process/Wait/Events scaffolding. Only the build-cmd step and the stdout parser genuinely differ. The template owns the shared lifecycle (spawn → pipe stdout → run parser → forward events → close on exit); each agent supplies the two unique pieces.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrTemplateMisconfigured = errors.New("ReviewerTemplate misconfigured")
ErrTemplateMisconfigured is returned by ReviewerTemplate.Start when one of the required fields (AgentName, BuildCmd, Parser) is unset, or when BuildCmd returns nil. Use errors.Is to detect this in tests or higher layers (e.g., a multi-agent orchestrator that needs to skip a misconfigured agent rather than crashing the whole run).
Functions ¶
This section is empty.
Types ¶
type AgentReviewer ¶
type AgentReviewer interface {
// Name returns the agent's registry key (e.g., "claude-code", "codex",
// "gemini-cli"). Stable identifier; do not change after release without
// updating settings migration.
Name() string
// Start spawns the agent with the given run configuration. The returned
// Process exposes streaming events via Events() and a Wait() that returns
// when the process exits.
//
// Implementations MUST set the ENTIRE_REVIEW_* env vars on the spawned
// child process (see cmd/entire/cli/review/env.go) so the agent's
// lifecycle hooks adopt the session as a review session.
//
// Errors from Start indicate failure to construct or launch the process
// (e.g., binary not on PATH at exec.Cmd.Start time, invalid argv). Once
// Start returns nil, errors during the run flow through Process.Events
// (as RunError) and Process.Wait.
Start(ctx context.Context, run RunConfig) (Process, error)
}
AgentReviewer drives a single agent's review run.
type AgentRun ¶
type AgentRun struct {
Name string
Status AgentStatus
Tokens Tokens
// Buffer accumulates the full event log per agent for post-hoc
// rendering (DumpSink, TUI dump, synthesis).
//
// TODO(memory): At review lengths typical today (~100s of events,
// ~few KB) this is fine. If profiling shows reviews regularly
// exceed ~10MB of buffered events or ~10000 events, swap to a
// token-budgeted ring or stream events to sinks incrementally
// and drop the buffer.
Buffer []Event
StartedAt time.Time
Duration time.Duration
Err error
}
AgentRun is per-agent post-run data.
type AgentStatus ¶
type AgentStatus int
AgentStatus is the terminal state for an agent.
const ( AgentStatusUnknown AgentStatus = iota AgentStatusSucceeded AgentStatusFailed AgentStatusCancelled )
func (AgentStatus) String ¶
func (s AgentStatus) String() string
String returns a human-readable status (used in dump output and TUI).
type AssistantText ¶
type AssistantText struct {
Text string
}
AssistantText is narrative output from the agent (the actual review response, not tool-call chrome or session metadata).
type Event ¶
type Event interface {
// contains filtered or unexported methods
}
Event is the sealed sum type emitted by Process.Events. The unexported isEvent method prevents external packages from adding event variants; adding a new event requires updating this file (and every consumer's type switch — that's intentional, since a new event variant is a contract change).
type Finished ¶
type Finished struct {
Success bool
}
Finished signals the agent has produced its final output and the event stream is about to end. Success indicates the agent self-reported a clean task completion. Success=false means the agent finished its event stream but signaled it did not complete the review task — distinct from process exit failure (which surfaces via Process.Wait, not as an event).
Adapters typically emit this once at the bottom of the event stream, before the channel closes.
type Process ¶
type Process interface {
// Events returns a channel that emits structured events as the agent
// produces output. The channel is closed when the process exits — cleanly,
// with error, or via context cancellation. Consumers should range over it.
Events() <-chan Event
// Wait blocks until the process exits and returns:
// - nil on clean exit (exit code 0)
// - ctx.Err() on cancellation
// - an error wrapping *exec.ExitError on non-zero exit
// - other error types for I/O or pipe failures
//
// Wait must be called exactly once per Process. It is safe to call Wait
// after the Events channel has closed. Consumers must drain Events until
// close before calling Wait; otherwise an implementation that forwards
// parsed events from another goroutine may block while sending.
Wait() error
}
Process represents a running agent review.
type ProcessError ¶
ProcessError wraps a process failure with bounded stderr diagnostics. Unwrap preserves the underlying error, so callers can still use errors.As for *exec.ExitError or errors.Is for lower-level sentinels.
func (*ProcessError) Error ¶
func (e *ProcessError) Error() string
func (*ProcessError) Unwrap ¶
func (e *ProcessError) Unwrap() error
type ReviewerTemplate ¶
type ReviewerTemplate struct {
// AgentName is returned by Name(). Stable identifier per agent.
AgentName string
// BuildCmd constructs the *exec.Cmd to spawn the agent process,
// including argv, stdin (if any), and ENTIRE_REVIEW_* env vars.
// The command MUST NOT have started yet; the template will call Start.
BuildCmd func(ctx context.Context, cfg RunConfig) *exec.Cmd
// Parser converts the agent's stdout stream into a sequence of Events.
// The returned channel must close when stdout closes. Implementations
// must emit Started first, Finished{Success: ...} or RunError last,
// and check scanner.Err() before emitting Finished{Success: true}.
Parser func(stdout io.Reader) <-chan Event
}
ReviewerTemplate implements AgentReviewer for agents whose only per-agent quirks are argv/env construction and stdout parsing. Both fields must be set before Start is called; nil values cause Start to panic immediately.
func (*ReviewerTemplate) Name ¶
func (t *ReviewerTemplate) Name() string
Name returns the agent's stable identifier.
func (*ReviewerTemplate) Start ¶
Start spawns the agent process, wires stdout through the parser, and returns a Process whose Events channel streams the parsed event sequence.
Returns ErrTemplateMisconfigured if AgentName, BuildCmd, or Parser is unset, or if BuildCmd returns nil. These are programmer errors but failing fast with a typed error is friendlier than a downstream nil deref — and it keeps Start from panicking inside a multi-agent fan-out (CU8) where one misconfigured template would otherwise kill the whole run.
type RunConfig ¶
type RunConfig struct {
// PromptOverride, when non-empty, is the exact prompt sent to the agent.
// It preserves settings.ReviewConfig.Prompt's existing verbatim-override
// contract: configured skills are still recorded as structured metadata,
// but they are not prepended to the prompt text.
PromptOverride string
// Skills are skill invocation strings passed to the agent verbatim.
Skills []string
// AlwaysPrompt is the per-agent always-prompt configured in settings.
// Concatenated with Skills + PerRunPrompt + a scope clause to form the
// composed agent prompt.
AlwaysPrompt string
// PerRunPrompt is optional textarea input from a single invocation.
PerRunPrompt string
// ScopeBaseRef is the git ref the review is scoped against (typically the
// closest ancestor branch). Used to compose the scope clause and as the
// base for `git diff` operations the agent may perform.
ScopeBaseRef string
// CheckpointContext is best-effort context derived from checkpoints in the
// branch review scope. It is appended to generated prompts so every agent
// can use checkpoint IDs, file summaries, and transcript lookup commands
// while reviewing. PromptOverride remains verbatim and does not receive
// this context.
CheckpointContext string
// StartingSHA is HEAD at invocation time, propagated to the lifecycle
// hook via ENTIRE_REVIEW_STARTING_SHA so checkpoint metadata records
// the commit that was reviewed.
StartingSHA string
}
RunConfig is the immutable per-run configuration passed to AgentReviewer.Start.
All fields are optional from a marshalling standpoint (zero value is valid), but Skills is typically non-empty in practice — it carries the skill invocations (e.g., "/pr-review-toolkit:review-pr") the configured agent should run.
type RunError ¶
type RunError struct {
Err error
}
RunError reports a non-fatal error during the run (e.g., hook failure, transient stream parse error). Fatal errors that stop the agent surface via Process.Wait, not as events.
type RunSummary ¶
type RunSummary struct {
StartedAt time.Time
FinishedAt time.Time
// Cancelled is true iff the orchestrator's run context was cancelled
// during the run (or before it started). For single-agent runs this
// is equivalent to AgentRuns[0].Status == AgentStatusCancelled. Under
// multi-agent runs (CU8), Cancelled means "the run as a whole was
// cancelled" — individual AgentRuns may have other terminal states
// if they finished before cancellation propagated.
Cancelled bool
AgentRuns []AgentRun
}
RunSummary is the post-run record passed to all sinks.
type Sink ¶
type Sink interface {
// AgentEvent is called for every event emitted by an agent's
// process during the run. Events are delivered in-order within a
// single agent; across agents (CU8 multi-agent) the orchestrator
// serializes calls so sinks see one event at a time.
AgentEvent(agent string, ev Event)
// RunFinished is called once when the run terminates (cleanly,
// failed, or cancelled). Sinks that only act post-run (DumpSink,
// synthesis sink) implement only this method (with a no-op
// AgentEvent).
RunFinished(summary RunSummary)
}
Sink consumes events from a review run. Sinks are passed to the orchestrator at construction time; selecting which sinks compose is the caller's job (TUI vs. non-TTY, synthesis on/off).
Concurrency: AgentEvent and RunFinished are guaranteed to be invoked from a single goroutine — the orchestrator serializes calls even under multi-agent runs (CU8 fans events from N agents into one dispatch loop). Sinks need not internally synchronize.
Sinks MUST NOT block. AgentEvent runs on the dispatch goroutine; a slow sink stalls the entire run and starves all other sinks.
type Started ¶
type Started struct{}
Started signals the agent has begun the review. Adapters typically emit this once at the top of the event stream.
type Tokens ¶
Tokens reports cumulative token counts (running totals, not deltas). Adapters may emit multiple Tokens events during a run; each emission supersedes the prior, so consumers should overwrite (not sum) on receipt. Adapters that only receive aggregate shutdown totals should emit at most one final Tokens event rather than inventing deltas.
type ToolCall ¶
ToolCall reports a tool invocation by the agent. Args is an opaque adapter-defined string — typically JSON for agents that emit structured tool input (e.g., claude-code), or a single-line summary for those that don't (e.g., codex). Shared consumers should treat Args as display-only and not parse it; structured tool data is intentionally not part of this contract.