Releases: selyafi/diffsmith
Release list
diffsmith 0.4.1
v0.4.1 — 2026-06-29
Fixed
- The inbox no longer breaks on GitLab. v0.4.0 pinned the host on
glab mr listwith--hostname, but that subcommand has no such flag
(onlyglab apidoes), so every inbox fetch failed with
Unknown flag: --hostname. The host is now pinned via a full URL in
--repo— the mechanismglab mr listactually supports — mirroring how
mr diff/mr viewalready target self-hosted instances. (diffsmith-1bk)
diffsmith 0.4.0
v0.4.0 — 2026-06-22
Added
- The inbox now shows review-discussion signal at a glance for every PR/MR
row: comment count, human commenters (bots filtered out), and
resolved vs unresolved review-thread counts — across both GitHub PRs
and GitLab MRs. GitHub fetches it in a single GraphQL call; GitLab adds
bounded-concurrent per-MR discussion lookups. Unresolved counts are
highlighted, and a row whose enrichment can't be fetched renders?
rather than a misleading0. Pin--hostnameis honored so self-hosted
GitLab works. (Known limit: counts cap at 100 threads/discussions per
row; full pagination is a tracked follow-up.)
diffsmith 0.3.2
v0.3.2 — 2026-06-20
Changed
- Reviews are now multi-angle and cross-verified, applied to every model
(codex, claude, antigravity) and every review — no new flags, no extra
model calls. The review prompt asks each model to scan the diff across
explicit angles (line-by-line correctness, removed-behavior / dropped
guards, in-hunk contract breaks, language pitfalls) and to name a
concrete failure scenario for each finding or drop it. When two or more
models run, the synthesis pass is now an adversarial verify+merge: it
keeps a finding only if it grounds to the diff, and treats agreement
between reviewers as a confidence signal, not a requirement (a real
single-model finding is kept).
diffsmith 0.3.1
v0.3.1 — 2026-06-19
Added
--antigravity-modelflag (and$DIFFSMITH_ANTIGRAVITY_MODEL): choose
the model the Antigravity (agy) adapter runs — e.g.
Gemini 3.1 Pro (High),Claude Opus 4.6 (Thinking),GPT-OSS 120B (Medium). Runagy modelsfor the catalog. The flag wins over the env
var; an empty value keeps the pinned default.
Changed
- The Antigravity adapter now pins
Gemini 3.1 Pro (High)by default
instead of relying on agy's session default (oftenGemini 3.5 Flash).
This makes reviews reproducible across machines and keeps antigravity a
distinct model family (Google) from codex (GPT) and claude (Claude).
Override with--antigravity-model/$DIFFSMITH_ANTIGRAVITY_MODEL.
diffsmith 0.3.0
v0.3.0 — 2026-06-19
Added
-
Antigravity (
agy) model adapter — a full peer of the Codex and
Claude adapters (reviewer, synthesizer, and input-budget setter).
Driven non-interactively viaagy --print=- --print-timeout <dur>
with the prompt piped over stdin; the print-timeout derives from the
call's ctx deadline so--model-timeoutgoverns antigravity like the
other adapters. Requires a one-time interactiveagylogin (the OAuth
token then persists). Restores a third model after the Gemini removal
below. -
--include <pattern>flag (repeatable, onreview,inbox, and
barediffsmith): the allowlist counterpart of--exclude. Keeps
only files matching at least one pattern and drops the rest before
the prompt is built, for reviews that should focus on one area of a
large diff. Same gitignore-lite rules as--exclude(trailing/=
directory tree at any depth; no/= basename glob; otherwise
full-path glob), and renames are kept when either side matches.
--includeruns first, then--excludecarves exceptions out of the
kept set (--include 'internal/' --exclude 'internal/gen/'). The
narrowing is surfaced in the run summary (or stderr for
--print-prompt/--dry-run), malformed globs fail up front, and an
--includethat matches no changed file is a clean error before any
model call. The adapters' over-budget hint now names both flags.
Changed
- BREAKING: removed the Gemini (
gemini) model adapter. Google
discontinued thegemini-clifree-tier OAuth client, so it could no
longer authenticate for free-tier users; Antigravity (agy) replaces
it as the third model. Selectable models are nowcodex,claude,
andantigravity— anyone scripting--model geminimust switch.
diffsmith 0.2.2
v0.2.2 — 2026-06-12
Added
--exclude <pattern>flag (repeatable, onreview,inbox, and
barediffsmith): drop files from the review diff before the prompt
is built, for diffs dominated by lockfiles, vendored deps, or
generated code. Gitignore-lite rules: a trailing/excludes a
directory tree at any depth (vendor/); a pattern without/
matches basenames anywhere (*.lock); anything else is a full-path
glob (internal/gen/*.go). Renames are excluded when either side
matches. Exclusions are surfaced in the run summary (or stderr for
--print-prompt/--dry-run), malformed globs fail up front, and
excluding every changed file is a clean error before any model call.
The adapters' budget-exceeded hint now points at the flag.
(diffsmith-7k3)
Fixed
- GitHub Releases publish with their release notes again:
changelog.disablein the goreleaser config silently discarded the
notes file the workflow extracts from CHANGELOG.md, so every release
through v0.2.1 shipped with an empty body (since backfilled). The
release workflow now also fails loudly if the published body comes
out empty. (diffsmith-8jw)
diffsmith 0.2.1
v0.2.1 — 2026-06-11
Fixed
- Codex reviews work again:
codex execnow receives
--skip-git-repo-check, without which codex refuses to start in the
isolated temp working directory introduced in v0.2.0
(diffsmith-4tz) and every codex review — and any codex-led
synthesis — failed with "Not inside a trusted directory". The gemini
adapter received its equivalent--skip-trustin that release; the
codex flag was missed. (diffsmith-ce8) - When every reviewer fails, context-fetch notes (e.g. "acceptance
criteria unavailable: …") are now folded into the error itself
instead of a status line the error screen never renders, so the
failure output explains both what failed and what review context was
missing. (diffsmith-h7a)
diffsmith 0.2.0
v0.2.0 — 2026-06-11
Added
- Reviewer context: diffsmith sends the PR/MR description and the
acceptance criteria from issues the PR/MR formally closes (resolved
viagh/glab), rendered in a# Intentsection before the diff so
reviewers can flag scope drift and unmet acceptance criteria. The
description is captured for free during fetch; linked-issue resolution
is an optional provider capability (GitHubclosingIssuesReferences→
gh issue view; GitLabglab api .../closes_issues). Context is
budget-capped (8 KiB description, 8 KiB per issue body, first 10
issues) and any truncation or fetch failure is surfaced in the run
summary — never silent.--no-contextopts out, withholding the
description and skipping the linked-issue fetch entirely.
(diffsmith-144) --model-timeout <dur>flag: a per-model wall-clock cap (default
10m) on every entry point. A model exceeding it is cancelled and
dropped from the review, so one hung reviewer CLI can no longer block
the parallel fan-out. (diffsmith-ptr)
Changed
- Reviewer model CLIs (
codex,claude,gemini) now run in an
isolated temporary working directory instead of the caller's cwd, so
they no longer autoload the project's.agents/skills,AGENTS.md,
orCLAUDE.md— protecting the no-auto-post guarantee against a
reviewer CLI picking up project-level instructions.$HOME-based
auth is untouched. (diffsmith-4tz)
Fixed
- Parse failures now preserve the full model output:
ParseError.Raw
retains the complete payload (previously truncated to 200 chars), and
the dropped-model run summary surfaces a bounded snippet so a model
returning malformed JSON leaves a diagnosable trace instead of
vanishing. (diffsmith-2xy)
diffsmith 0.1.7
v0.1.7 — 2026-05-27
Added
--input-budget <bytes>flag overrides the per-adapter prompt-size
cap on every entry point (review,inbox, barediffsmith).
Zero (the default) keeps each adapter's compiled-in budget. Routes
throughmodel.InputBudgetSetter, which all three working adapters
(codex, claude, gemini) implement. (diffsmith-uc1)
Changed
- Default
DefaultInputBudgetBytesraised from 256 KiB to 1 MiB on
codex, claude, and gemini adapters. The original 256 KiB cap was
calibrated by spike S9 long before the GitHub files-API fetch
fallback (diffsmith-5n4) made larger PRs reachable; 1 MiB sits
well below every working adapter's advertised context window while
unblocking realistic medium PRs without a flag override.
(diffsmith-uc1) - Budget-exceeded error message now points users at the new
--input-budgetflag in addition to "review a smaller PR or filter
files". (diffsmith-uc1)
Fixed
- GitHub adapter now falls back to the pull-request files API
(gh api repos/{o}/{r}/pulls/{N}/files --paginate) when
gh pr diffhits the GitHub 20,000-line server-side cap and
returns HTTP 406. Per-file patches are reassembled into a
synthetic unified diff covering modified, added, removed,
renamed, and copied files. Files whosepatchfield is null
(per-file ~3MB cap) are announced on stderr and skipped rather
than aborting the review. (diffsmith-5n4)
diffsmith 0.1.6
v0.1.6 — 2026-05-27
Security
- Trust-boundary fix for the TUI post flag: pressing
pnow only
takes effect on approved findings; pending and dismissed findings
cannot be marked for upstream posting.GetFindingsMarkedForPost
filters at read time so a finding that was approved-then-dismissed
is no longer returned.DismissCurrentalso clears the post mark
so ana → p → d → asequence can no longer silently resurrect a
previously-marked finding into the post-bound set. The TUI's
[post]row badge now consults the same predicate as the post
filter, so the badge can never claim a finding is queued when the
filter would drop it. (diffsmith-dvz.2, post-dvz follow-up) - Root command help and canonical docs (security-and-privacy,
v1-scope, roadmap, diffsmith-v1-design, prd, confidence-and-
validation, implementation-plan, release-plan) reconciled to
describe opt-in posting accurately: diffsmith never posts without
an explicit per-runyconfirmation, andpnow requires a
priora. Legacy "never posts" / "no direct posting in v1"
claims were dangerously stale for a tool that handles private
code. (diffsmith-dvz.3) - Synthesis injection live smoke (
TestSynthesisInjectionLiveCodex)
broadened to check title, suggested_comment, evidence, and
fix_hint against the full canary set. Strict sentinels are
checked across all four user-readable fields; soft canaries
(plain-English fragments the lead may legitimately quote when
narrating the attack) are checked in title only, so responsible
defense commentary doesn't false-positive. (diffsmith-dvz.8,
diffsmith-e2g)
Added
--debugflag ondiffsmith review(and on the inbox / bare-root
flows) expands the post-TUI quarantine section: each rejected
candidate is printed with(file:line), title, and the validator's
rejection reason. Default-off path keeps the compact
(N quarantined; pass --debug to inspect)counter, matching what
the previous build wrongly promised. (diffsmith-dvz.6)--print-payloadis now host-aware: on a GitHub PR it prints the
GraphQLaddPullRequestReviewThreadinput as before; on a GitLab
MR it prints the discussions API JSON body withpositionfields
(base/head/start SHA, position_type, new_path, old_path, new_line).
Unknown hosts produce anunsupported hosterror rather than
silently defaulting to GitHub. The preview also mirrors
submitGitLab's missing-diff-refs guard, so it can no longer claim
success where a real submit would fail. (diffsmith-dvz.5,
diffsmith-696, post-dvz follow-up)- GitLab posting now respects file renames:
Poster.OldPaths
carries the post-image → pre-image rename map built from the
parsed diff, andsubmitGitLabuses it to populate
position.old_pathcorrectly for renamed-with-hunks files.
Same-path files don't need a map entry. GitHub posting is
unchanged. (diffsmith-dvz.4) --repostand--debugare now also exposed ondiffsmith inbox
and barediffsmith(no subcommand). Previously each entry point
carried a different subset of the post-flow flags, so users had
to reach fordiffsmith reviewjust to bypass dedup or expand
quarantined output. A singleregisterPostFlowFlagshelper now
registers all three on every entry point. (diffsmith-3e8)
Changed
- GitHub PR comment dedup is now keyed by an invisible HTML-comment
marker (<!-- diffsmith -->) rather than the visible
**diffsmith review**header. The visible body is now compact:
GitHub renders**[severity] Title**then the comment; GitLab
renders**severity** (NN%)then the comment — no more
model: codex,or**diffsmith review** —preamble. Existing
diffsmith comments posted by v0.1.5 do NOT carry the new marker,
so the first v0.1.6 rerun against a PR/MR with prior comments
will re-post them as duplicates (one-shot migration cost).
Workaround: pass--reposton the first v0.1.6 run, or accept
the duplicates and resolve them manually. (diffsmith-dvz.1,
post-dvz format change) model.Modelinterface split intomodel.Reviewer(base:
Name/Preflight/Review) andmodel.Synthesizer(optional:
Synthesize). The synthesis call site type-asserts
model.Synthesizerand surfaces a status message when a
candidate doesn't satisfy it, so an experimental/review-only
adapter (antigravity) no longer needs to carry a stub
Synthesizethat exists only to satisfy the old composite
interface.model.Modelis kept as a type alias toReviewer
for backward compatibility. Compile-time guards
(var _ model.Synthesizer = (*Adapter)(nil)) on codex, claude,
and gemini lock the capability so a future refactor that drops
Synthesize fails to build immediately. (diffsmith-dvz.7,
diffsmith-0hy)
Fixed
- GitHub dedup now recognises its own comments. The body posted by
formatBodydid not start with the**diffsmith review**prefix
thatfetchExistingGitHubKeysexpected, so dedup silently treated
every prior comment as human content and re-posted every finding
on every run. Fixed by switching the marker to the invisible
HTML-comment form and matching withstrings.Containsinstead of
HasPrefix; a regression test pins the format-vs-dedup contract
using a formatBody-produced body. (diffsmith-dvz.1) - Synthesis loop no longer silently advances when an adapter returns
(nil, nil).attemptSynthesisnow treats the undefined-shape
return as an explicit skip, surfaces it via a PhaseStatusMsg, and
appends it to the run summary so the user has a persistent audit
trail. Previously the loop's two-branch logic (if err==nil && synth!=nil; if err!=nil) left a third case where nothing fired
andfinalstayed assurviving[0]under the impression
synthesis succeeded. (diffsmith-4f8,diffsmith-wfq)
Internal
- Architecture review (epic
diffsmith-dvz) and the post-review
follow-up sweep filed and closed 9 tickets covering trust
boundary, dedup contract, host-specific posting, debug surface,
interface split, and quality follow-ups.