Documentation
¶
Overview ¶
Package diffview renders unified diffs from `gh pr diff` in a TUI.
Index ¶
- Constants
- func DetectNewSymbols(path string, lines []Line) []string
- func IsCIRelated(path string) bool
- type CIRisk
- type CISignal
- type DupeFinding
- type DupeSignal
- type File
- type Highlighter
- type Line
- type LineKind
- type Model
- type PlanSeverity
- type PlanSignal
- type PromptInjectSeverity
- type PromptInjectSignal
Constants ¶
const PlanNudgeMessage = `This PR is too large for me to review without a clearer implementation plan. ` +
`Can you break it into smaller scoped units, or add a summary of what each part does and ` +
`why it's structured this way? Happy to review after that.
(via [chainrail](https://github.com/brayschurman/chainrail))`
PlanNudgeMessage is the templated comment chainrail posts when the reviewer presses P on a PR with no plan. Copy-paste from the GitHub agent-PR review article.
Variables ¶
This section is empty.
Functions ¶
func DetectNewSymbols ¶ added in v0.1.18
DetectNewSymbols extracts identifiers introduced in this file's added lines. Only looks at LineAdd entries. Returns deduplicated names in declaration order.
func IsCIRelated ¶ added in v0.1.17
IsCIRelated reports whether a path is one of the file kinds whose changes affect CI behavior (workflows, test/build configs, coverage).
Types ¶
type CIRisk ¶ added in v0.1.17
type CIRisk int
CIRisk classifies how a file affects CI confidence. Used to pin risky files to the top of the sidebar and to gate 100% progress.
type CISignal ¶ added in v0.1.17
type CISignal struct {
Risk CIRisk
Reasons []string // human-readable summary, e.g. "test marked .skip" or "continue-on-error added"
}
CISignal is a per-file detection result.
func DetectCIRisk ¶ added in v0.1.17
DetectCIRisk inspects a file's path and diff body for CI-related changes and returns a CISignal. Returns CIRiskNone for files that don't match any CI-relevant path pattern.
Content-level weakening signals are only inspected on workflow files (where they're unambiguous). For other config files we conservatively report CIRiskConfig — the reviewer's judgment is the gate.
type DupeFinding ¶ added in v0.1.18
type DupeFinding struct {
Symbol string // newly-added identifier
Candidates []string // up to 5 "path:line" matches outside this file
}
DupeFinding is one newly-added symbol and the repo locations where a similar identifier already exists.
type DupeSignal ¶ added in v0.1.18
type DupeSignal struct {
// Symbols added by this file's diff that have prior-art candidates.
Findings []DupeFinding
}
DupeSignal records possible-duplicate findings for one file: each newly-added top-level symbol and where else in the repo a similar name appears outside this PR.
func DetectDupes ¶ added in v0.1.18
func DetectDupes(path string, lines []Line, repoRoot string, excludedPaths map[string]bool) DupeSignal
DetectDupes runs a repo-wide grep for each newly-added symbol from the file's diff, excluding paths inside the PR itself. Returns nil if no candidates are found or the grep fails.
repoRoot is the working directory for `git grep`. excludedPaths are file paths in the PR that should be filtered out of grep results (so a symbol declaration doesn't match itself).
type File ¶
File is one file's worth of changes from a unified diff.
type Highlighter ¶
type Highlighter struct {
// contains filtered or unexported fields
}
Highlighter colorizes diff content lines using chroma based on file extension. Lexers and the formatter are looked up once per extension and reused. When NO_COLOR is set or the lexer is unknown, Highlight returns the input unchanged.
func NewHighlighter ¶
func NewHighlighter() *Highlighter
func (*Highlighter) Highlight ¶
func (h *Highlighter) Highlight(path, src string) string
Highlight returns the colorized form of src for the lexer matching path's extension. Falls back to src on any error or when disabled.
func (*Highlighter) HighlightWithBg ¶ added in v0.1.14
func (h *Highlighter) HighlightWithBg(path, src string, bg lipgloss.Color) string
HighlightWithBg tokenises src with the lexer for path and renders each token with both its syntax foreground AND the given diff background. This gives the hunk/diffs.com look where chroma's colors stay vivid on top of a soft +/- tint, without relying on fragile mid-stream ANSI rewriting.
Returns src wrapped in a single bg style if no lexer matches or highlighting is disabled. The caller is responsible for any extra padding needed to reach a target pane width.
type Line ¶
Line is one rendered line of the diff (file header, hunk header, or content). Kind drives coloring; Text is the raw text without trailing newline.
type Model ¶
type Model struct {
Title string // e.g. "#687 wall drawing UX"
Files []File
// BlobByPath maps file path -> blob SHA for the PR's current head, used
// to detect "changed since you checked" against persisted review state.
BlobByPath map[string]string
// CISignals records the per-file CI risk classification computed once
// at load time. Populated by ensureDetectors.
CISignals map[string]CISignal
// DupeSignals records possible-duplicate symbol findings per file.
// Computed once after the Files slice is set when a repo root is
// available. Empty when no repo root is configured (test contexts).
DupeSignals map[string]DupeSignal
// PromptInjectSignals records workflow-file prompt-injection findings.
// Populated by runDetectors.
PromptInjectSignals map[string]PromptInjectSignal
// PRBody is the PR description text — used by the plan detector.
PRBody string
// PlanSignal is the verdict from DetectPlan on PRBody.
PlanSignal PlanSignal
// PRNumber for posting the nudge comment.
PRNumber int
// PlanNudger sends the nudge comment when the reviewer presses P.
// Optional; nil disables the nudge.
PlanNudger func(number int, body string) error
// RepoRoot is the local filesystem path of the repo, used by the
// duplicate-detector's git grep. Optional; when unset, dupe detection
// is skipped.
RepoRoot string
// ReviewState is the loaded per-file checklist for this PR. Optional;
// when nil, review-tracking UI is hidden entirely. The owner+repo+number
// fields are kept here so Save can write back to the right key.
ReviewState *reviewstate.PRState
ReviewStore *reviewstate.Store
RepoOwner string
RepoName string
// contains filtered or unexported fields
}
Model is the bubbletea model for the PR diff viewer.
func (*Model) RunRepoDetectors ¶ added in v0.1.18
func (m *Model) RunRepoDetectors()
runRepoDetectors runs detectors that need filesystem access (i.e. git grep for dupe detection). Called by the caller (cmd/view.go) after it discovers the repo root, since the diffview package doesn't shell out by itself in the New constructor.
type PlanSeverity ¶ added in v0.1.20
type PlanSeverity int
PlanSeverity classifies how much structure / scope the PR description has. "Plan" here means: does the reviewer have enough context to scope a review, or is the PR a "just look at the diff" wall of agent output?
const ( PlanPresent PlanSeverity = iota // structured body, multiple sections / bullets / >200 chars PlanThin // 50–200 chars, no structure — usable but minimal PlanMissing // empty or <50 chars )
type PlanSignal ¶ added in v0.1.20
type PlanSignal struct {
Severity PlanSeverity
Chars int
HasHeading bool
HasBullets bool
HasCode bool
}
PlanSignal captures the verdict on a PR body.
func DetectPlan ¶ added in v0.1.20
func DetectPlan(body string) PlanSignal
DetectPlan inspects a PR body and returns a structured verdict.
type PromptInjectSeverity ¶ added in v0.1.19
type PromptInjectSeverity int
PromptInjectSeverity classifies how dangerous a workflow file's diff is.
const ( PromptInjectNone PromptInjectSeverity = iota PromptInjectSuspect // untrusted input *or* LLM, not both PromptInjectHigh // untrusted input AND LLM in same file PromptInjectCritical // pull_request.body → LLM, plus shell exec or write-token )
type PromptInjectSignal ¶ added in v0.1.19
type PromptInjectSignal struct {
Severity PromptInjectSeverity
Reasons []string
}
PromptInjectSignal captures one workflow file's prompt-injection risk.
func DetectPromptInjection ¶ added in v0.1.19
func DetectPromptInjection(path string, lines []Line) PromptInjectSignal
DetectPromptInjection inspects workflow YAML for the prompt-injection pattern: untrusted user input interpolated into a step that calls an LLM or executes the model's output. Returns PromptInjectNone for non-workflow files and workflows without the dangerous patterns.
We deliberately work on the *whole file body* — not just the diff — so a workflow that *already* had the dangerous pattern but is now being modified for any reason still surfaces. Reviewing the addition triggers reviewing the file's security posture.