Commit graph

554 commits

Author SHA1 Message Date
Magnus
7ce7cf78a2
feat(providers): add glm-5.3 to the Z.AI Coding Plan provider (#915)
Some checks are pending
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
2026-08-15 10:45:49 +08:00
董艺宽
0c8c0670f2
docs(cli): document review no-filter option (#871)
Some checks are pending
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / build (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
2026-08-14 17:54:10 +08:00
Gongyl01
31db10fa63
fix(resume): preserve checkpoints after Ctrl-C (#902)
* fix(resume): preserve checkpoints after Ctrl-C

* fix(resume): tighten cancellation dispatch
2026-08-14 17:42:24 +08:00
xujiejie
e770791b69
ci: skip CI runs for documentation-only changes (#907)
Add paths-ignore to the push and pull_request triggers so changes that
no CI step scans (markdown files, LICENSE, .gitignore) no longer spin
up the full suite. Source-relevant paths (.yml/.yaml, workflow files,
action.yml) stay triggerable.

Closes #905
2026-08-14 17:36:37 +08:00
Kite
160046124f
feat(pages): add MacOS, Linux, and Windows install channels to hero section (#904)
Add platform-specific install options (curl|sh for MacOS/Linux,
irm|iex for Windows) to the 'More' dropdown in the homepage hero.

- Add apple.svg, linux.svg, windows.svg icons
- Add three new secondary install channels with OS-specific commands
- Reorder MacPorts to the bottom of the dropdown
- Add i18n keys for all four locales
- Fix dropdown clipping by removing overflow:hidden on hero section
- Fix dropdown alignment (left:0 instead of right:0)
2026-08-14 17:32:04 +08:00
AllenJoe
0b7492b04d
feat(telemetry): display session ID in terminal summary output (#870)
Print the review session UUID on a separate line after the terminal
summary so users can copy it for `ocr resume` without --format json or
filesystem browsing. The line is omitted when the session ID is empty
(e.g. when session persistence is unavailable). JSON output is unchanged.

Co-authored-by: Kite <254839944+lizhengfeng101@users.noreply.github.com>
2026-08-14 17:22:24 +08:00
NielsRogge
9a151a2f93
Link AACR-Bench dataset from README (#901) 2026-08-14 17:09:51 +08:00
Abdul Moiz Hussain
f1c79be86a
feat(pages): serve install scripts from custom domain (#797)
* feat(pages): serve install scripts from custom domain

* fix: update ru/installation.md URLs and add sh -n syntax check

- Update Russian installation docs to use open-codereview.ai URLs
- Add sh -n syntax validation in deploy workflow per review feedback

---------

Co-authored-by: kite <lizhengfeng.lzf@alibaba-inc.com>
2026-08-14 16:06:37 +08:00
Tao Xin
d59eddaa5a
feat(pages): add macports to pages homepage (#873)
* docs: translations update keys

* tsx: new macports hero and import mp svg icon

* new macports svg

* add options

* keys translations

* tsx updates

* fix typo

* fixes

* tests: new
2026-08-14 15:30:32 +08:00
林SO
92fd0d088e
fix(opencode): separate per-file and overall timeouts (#717)
* fix(opencode): separate per-file and overall timeouts

* fix(opencode): default to 30-minute overall timeout instead of no timeout

Defense in depth: when overallTimeoutMinutes is not configured,
apply a 30-minute watchdog so genuinely stuck processes are reaped
even if the abort signal never fires.

---------

Co-authored-by: kite <lizhengfeng.lzf@alibaba-inc.com>
2026-08-14 15:19:02 +08:00
Xupeng
6546da9885
feat(provider): support custom Base URL for LiteLLM/built-in providers (#729)
* feat(provider): add editable Base URL step to official provider wizard

The official-provider tab in `ocr config provider` only captured API key
and model, with no way to override a preset provider's Base URL. The
resolver already honored `entry.URL` over `preset.BaseURL`, but the TUI
never exposed it — litellm (a self-hosted gateway rarely at
http://localhost:4000/v1) was the canonical pain point.

Add a Base URL step to the official-tab flow (stepModel -> stepBaseURL ->
stepAPIKey), pre-filled with the effective URL (configured override or
preset default). Persist `providers.<name>.url` only when the entered
value differs from the preset default, so the preset remains the fallback
and configs without an explicit url are unchanged. Custom/manual tabs are
unaffected.

Add resolver regression tests (litellm override + default fallback) and
TUI tests (pre-fill with preset/override, Esc navigation, persistence of
override vs. clearing on preset default). Update the four official-tab
tests that assumed stepModel -> stepAPIKey to traverse the new step.

* feat(provider): surface override Base URL in model picker and document it

With the wizard now able to set a Base URL override for built-in
providers, make the override visible and discoverable.

- `ocr config model` shows the effective Base URL for a preset provider
  (the configured `providers.<name>.url` override, or the preset default
  when none is set) so users can confirm their gateway is in use.
- The provider-wizard model-selection step shows the same effective URL
  via a tab-aware `effectiveBaseURL()` helper (official override/preset,
  or custom provider URL).
- Document `providers.<name>.url` as a built-in provider override in the
  configuration docs, with a litellm example and the preset-as-default
  semantics; note the wizard's editable Base URL step.

Add tests covering the model-selector display (override vs preset
default) and the wizard's effectiveBaseURL resolution.

* fix(provider): address PR review — URL trim, validation, dead code, Esc display

Address 4 of 5 code review findings on PR #729:

1. URL trim consistency (provider_cmd.go): trim the Base URL once and use
   the trimmed value for both comparison and persistence, preventing
   whitespace-polluted URLs from being written to config.

2. URL format validation (provider_cmd.go): validate that the Base URL
   has an http/https scheme and non-empty host before persisting, giving
   immediate feedback instead of a runtime failure. Rejects malformed
   values like bare hosts or ftp:// schemes.

3. Dead code removal (provider_tui.go): remove the init-time pre-fill of
   officialURLInput that is always overwritten by loadOfficialURL() when
   the user enters the Base URL step. Pre-fill logic now lives in a
   single place.

4. effectiveBaseURL reflects pending edit (provider_tui.go): when the
   user edits the Base URL and presses Esc back to model selection,
   effectiveBaseURL() now returns the in-progress value from
   officialURLInput instead of the stale on-disk config.

The SSRF/private-IP finding (#2 in review) is not addressed — it is a
false positive for a local CLI tool where localhost and private network
endpoints are the primary use case (the litellm preset default is
http://localhost:4000/v1).

* feat(provider): implement URL trimming and validation for provider configuration

* fix(provider): remove obsolete official URL handling

---------

Co-authored-by: Kite <254839944+lizhengfeng101@users.noreply.github.com>
2026-08-14 14:04:10 +08:00
xujiejie
51750bfe02
test(agent): add end-to-end regression test for review item fingerprint stability (#898) 2026-08-14 12:39:53 +08:00
Tao Xin
ab741e6334
docs(pages): update CLI reference and i18n for --format sarif (#874)
* docs: update cli-refs

* docs: update ci.md

* i18n: update corresponding keys
2026-08-14 12:00:38 +08:00
Gongyl01
c35ddd7223
feat(resume): add trusted resume validation and transition lineage (#786) (#845)
* feat(resume): verify input identity before reusing checkpoints

`ocr review --resume` admitted a session whenever the ref text matched, which
is neither sufficient nor necessary evidence about the input: `abc1234` and
`abc1234def` name the same commit, while a branch name that did not change can
name a new one. Resuming then mixed comments computed from one input with
comments computed from another, and nothing in the report distinguished them.

Compare the resolved input identity instead. agent.ResolveIdentity replays the
run's own selection — the same diff load and the same two filter passes — and
returns the identity a real run would record, so the parent manifest and the
child candidate are directly comparable. Any mismatch on mode, repository,
source artifact or rule config rejects the whole resume rather than degrading
to partial reuse. A provider or model change must be asked for with --provider
or --model; one that arrived through config or the environment is rejected.

Two behaviour changes fall out of this. Ref text no longer decides admission,
so ValidateOptions only checks the review mode. A parent that completed zero
items is now admitted: its manifest is verifiable, so its selected set is
simply re-dispatched, which is the case resume exists for.

Reuse is then gated on the parent manifest rather than on the checkpoint lines:
only a fingerprint the manifest claims as completed or reused is reused, which
keeps the manifest the single source of coverage truth. That gate is also what
makes an unreadable checkpoint survivable, so review loads through
LoadReviewResumeState, which drops lines it cannot parse — the file such a line
described is simply reviewed again, instead of one truncated write costing every
other file its checkpoint. Scan keeps the strict LoadResumeState, because with
no manifest to arbitrate, a dropped line cannot be told apart from a checkpoint
that was never written.

Rejection happens strictly before agent.New, because session.New writes
session_start the moment it is called — validating any later would leave an
orphan session behind every rejection. Keeping it there needs the run to review
exactly what was admitted, so the pre-flight hands back the commit endpoints it
resolved that identity from, and a resumed run loads its diff from those instead
of from the refs the user typed; file_read reads at the same sealed head. Both
loads then see the same immutable objects, so a ref moving after admission can
no longer change what the run reviews, and no mid-run re-check is needed to
discover that it did. An accepted resume records one
resume_lineage event naming the parent run and the provider/model endpoints,
surfaced by `ocr session show`; it carries non-secret labels only.

Interrupted runs become unresumable, since session_end is the sole carrier of
run_manifest. That is deliberate: an unverifiable input is exactly what this
change refuses to build on, and the error says so rather than reporting the
parent as unproductive.

Refs #786

* fix(resume): freeze refs before loading identity diff

* test(resume): cover sealed input resolution
2026-08-14 11:31:40 +08:00
Hyeseong Kim
144607f826
feat(llm): task-scoped session affinity for prompt caching (#332)
* feat(llm): task-scoped session affinity via {ocr_session_key} template variable

Derive a prompt-cache affinity key per LLM conversation, scoped to the
review session and the task within it (<session-id>-<task-type>-<hash>).
Review/scan runs bind the session ID into the request context and each
task conversation refines it where it starts, so every request carries
the real OCR session's key at per-conversation granularity — the
granularity provider prompt caches reuse prefixes at.

Embedding the {ocr_session_key} placeholder in extra_headers or
extra_body values is the opt-in: clients expand it per request, and
requests without it are unchanged. OCR never enforces a parameter or
header name, so any provider convention works with existing config
fields, e.g.:

  extra_body:    {"prompt_cache_key": "{ocr_session_key}"}   (OpenAI)
  extra_headers: x-session-affinity={ocr_session_key}        (gateways)

Closes #229

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* add license headers

* edit docs

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 11:23:44 +08:00
林SO
590a6f3616
fix(agent): stabilize review item fingerprints (#732)
Normalize position-dependent trailing line endings before hashing per-file diffs so unchanged files can be reused across resumed reviews.

Co-authored-by: Kite <254839944+lizhengfeng101@users.noreply.github.com>
2026-08-14 11:15:50 +08:00
Kite
3496360c40
ci: bump Go image to 1.26.6 to clear stdlib vulnerabilities (#896)
Some checks are pending
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
govulncheck now fails on golang:1.26.5: the Go vulnerability database
lists fixes in 1.26.6 for seven standard-library issues reachable from
this module (GO-2026-6218, -6091, -6090, -6089, -6088, -5972, -5026),
via net/url, html/template, crypto/tls, net/http, encoding/xml and
encoding/asn1. Nothing in the module's own code changed — the step
turned red when the database was updated, and because Govulncheck runs
before "Test with coverage", every PR is now blocked before a single
test executes.

Bump the pinned image in the test, cross-compile and release jobs, and
refresh the stale version reference in the translation-sync comment so
it keeps matching the other jobs.

Verified locally under go1.26.6: govulncheck reports no vulnerabilities
and exits 0, gofmt -s and go vet are clean, go mod tidy is a no-op, and
the full test suite passes (23 packages).
2026-08-14 10:54:02 +08:00
超級の新人
5fafe82972
fix(cmd): report expected arguments when positional count is wrong (#892)
Some checks are pending
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Cobra's default message for a wrong positional-argument count ("accepts
2 arg(s), received 1") names neither the command nor what it expects, and
the root command sets SilenceUsage, so no usage block follows it. Running
"ocr config set provider" gave the user nothing to act on.

Add exactArgs and minimumArgs, drop-in replacements for cobra.ExactArgs
and cobra.MinimumNArgs that build the message from metadata the command
already declares: the positional signature in Use, plus Example and
ValidArgs where present. The guidance therefore cannot drift from the
command's own help output, and no command carries a hand-written error
string. This mirrors how flagErrorWithSuggestion handles the analogous
flag-error case.

Wire the seven commands that take positional arguments: config set,
config unset, rules check, session show, session comments, delegate rule
and completion. Exit codes are unchanged; only the message text differs.
The supplied count is deliberately not echoed back, since it adds nothing
the user cannot see in the line they just typed.

A tree walk over the command tree fails if a command declaring positional
placeholders still reports the raw count message, so wiring a new command
to cobra.ExactArgs directly is caught by tests.

Fixes #890
2026-08-13 20:44:04 +08:00
Shivam
8ce52972cd
fix: make FileFilter patterns case-insensitive (#859)
Some checks are pending
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
Deploy Pages / build (push) Waiting to run
* fix: make file filter patterns case-insensitive

* test: strengthen case-insensitive file filter coverage
2026-08-13 18:43:47 +08:00
超級の新人
0e5fab8152
feat(action): render category/severity badge as a shields.io image (#882) (#885)
Replace the plain-text badge line in GitHub review and summary comments
with a single static shields.io badge in the format
img.shields.io/badge/<category>-<severity>-<color>, with the color keyed
off severity (low green, medium orange, high red, critical darkred).

The image renders only when both fields are known enum members; missing
or unknown metadata falls back to the existing plain-text badge so
arbitrary model output is never hotlinked into an image URL. The image
alt text keeps the plain-text badge content for screen readers and
image-load failures, the hidden ocr-id marker stays first, and the CLI's
buildBadge output is unchanged.
2026-08-13 16:18:00 +08:00
Tao Xin
9148bfdded
chore: remove Chinese doc references from retry test comments (#886)
* remove invalid refs and add bypasses

* chore: retrigger tests
2026-08-13 15:41:28 +08:00
kite
da972b23e0
feat(llmloop): add grace round after tool-request budget exhausted (#872)
* feat(llmloop): add grace round after tool-request budget exhausted

When RunPerFile exits because MaxToolRequestTimes reaches zero, perform
one additional LLM call with only code_comment and task_done available.
This gives the model a final chance to submit findings it identified but
had not yet reported, preventing loss of review comments on budget stop.

* fix(llmloop): address review comments on grace round

- Check ctx.Err() before making the grace round LLM call to avoid
  wasted API calls when the context is already cancelled.
- Pass messages copy to AppendTaskRecord and call rec.SetResponse so
  the grace round interaction is visible in session/debug logs.

* test(llmloop): add unit tests for grace round

Cover three scenarios:
- Grace round fires and collects code_comment on budget exhaustion
- Grace round is skipped when context is already cancelled
- Grace round is NOT triggered on StopEmptyRounds
2026-08-13 15:23:47 +08:00
kite
450dd6d1d6
chore(ci): fail CI when unapproved non-English text appears in source files (#876)
* fix(prompt): replace the fullwidth colon in the file_read tool description

tools.json advertised the example output as "File:path/to/example.go" with
a fullwidth colon (U+FF1A), while file_read.go actually emits "File: %s".
The description is sent to the model on every review, so the example did
not match the output it was describing.

Also switches action.yml's OCR_LANGUAGE example from 中文 to Chinese, for
the same reason as #861: the value is fed to the LLM and Chinese is what
the rest of the project uses.

* chore(ci): fail CI when CJK characters appear in source files

Comments, identifiers and strings in this repository are meant to be
English, but nothing enforced it — #861 had to clean up leftovers by hand,
and the same drift keeps arriving through generated code and contributions
written internally.

scripts/verify-cjk.go walks the index plus untracked files and reports Han
ideographs, kana, CJK punctuation and fullwidth forms. Written in Go rather
than shell so it does not depend on the container's grep having PCRE, and so
`unicode.Is` decides what counts as CJK instead of a byte range that would
flag the em dashes used throughout the comments. `//go:build ignore` keeps
it out of ./..., so it does not affect go vet, go build or the coverage
threshold.

Untracked files are included (--others --exclude-standard) so a new file is
checked before it lands: while writing this, the script's own comment used
Chinese punctuation as an example and went unreported until it was staged.

Two escape hatches, preferring the narrow one: an `allow-cjk: <reason>`
marker comment on a single line, or a prefix in allowedPrefixes for a whole
tree. 23 existing lines get markers (UTF-8 encoding fixtures, multibyte
truncation fixtures, language-switcher labels, the fullwidth bar used as a
terminal cursor). pages/src/i18n/ is allowlisted as translated UI copy;
extensions/vscode/ is allowlisted TEMPORARILY — its comments, test names
and zh-cn NLS bundle are still Chinese and need a follow-up pass.

Wired into CI next to the license and action-pin checks, plus
`make cjk-check` and `make check` for local runs.

* chore(ci): generalise the CJK check to all non-English text

Addresses the review feedback, and widens the rule that the feedback
exposed.

Review feedback:

- exemptMarker requires its colon, so a bare "allow-cjk" can no longer
  exempt a line without giving a reason.
- The script is named for CJK but missed Hangul.
- git ls-files gains -z, so paths that are not plain ASCII arrive
  unquoted, and its stderr is reported rather than a bare exit status.
- main discarded run()'s error entirely and only called os.Exit(1),
  which is what made the lost stderr invisible in the first place.
- The CI step and AGENTS.md say "unapproved", since escape hatches exist.

The check was skewed by writing system rather than by language. In one
array the 'zh' and 'ja' labels each needed a marker while the adjacent
'ru' label passed untouched, and nine lines of Russian sat in the tree
unflagged: two language-switcher labels and the heading-ID fixtures.
Contributors writing Chinese had to justify every line; contributors
writing Russian had nothing to justify.

The rule is now "a letter outside ASCII", since written English needs no
letter beyond the ASCII 26 -- Cyrillic and Han as much as the diacritics
that spell German or Vietnamese. Scripts are not enumerated, so one
nobody has contributed in yet is covered when it arrives. Common and
Inherited pass, so letterlike symbols (U+2139, U+2113) are not mistaken
for prose, and combining accents are caught, so the decomposed spelling
of an accented letter cannot slip through. Symbols and emoji stay out of
scope by construction: they are not letters.

Renamed to scripts/verify-english-only.go and make english-check, and
the marker to allow-non-english:. Text spelled entirely in ASCII still
takes a dictionary to identify and stays a matter for review.

* docs(agents): restate the English-only rule as rule, homes, hatches

The rule was one dense bullet that led with the detection mechanism and
mentioned the exemptions only in passing, which is the wrong order for
the reader: an agent needs to know where a translation may go before it
needs to know which Unicode scripts are flagged. Split into three.

The homes are now spelled out from what the tree actually holds, rather
than left as "<locale> docs or an i18n table": README and CONTRIBUTING
in zh-CN, ja-JP, ko-KR and ru-RU; the doc pages under
pages/src/content/docs/ in en, zh, ja and ru; the UI copy tables in
pages/src/i18n/. Also why the two are exempt for different reasons --
Markdown by extension, the i18n tables by prefix because they are .ts --
since that decides where a new translation can safely go.

Drops the enumerated list of what "make check" runs. It duplicated the
Makefile, went stale the moment a check was added (this PR had to edit
it), and told an agent nothing it would not read in the output anyway.
What is worth saying is that the target writes to the tree.

* fix(ci): detect U+FE10–FE6F CJK punctuation in english-only check

The vertical forms (U+FE10–FE19), CJK compatibility forms (U+FE30–FE4F)
and small form variants (U+FE50–FE6F) were not caught, even though their
fullwidth counterparts (U+FF00–FFEF) already were. A small question mark
(U+FE56 ﹖) or vertical comma (U+FE10 ︐) left in source reads as correct
English punctuation and is invisible in review — the same class of typo
the fullwidth range already defends against.

Skip U+FE20–FE2F (Combining Half Marks) which are used in Latin text.
2026-08-13 14:43:55 +08:00
Gongyl01
082c776ab0
Feat/llm retry report:SDK retry-attempt observability for review (#785) (#790)
* feat(llm): add retry report data layer

Add the internal data layer for an explicit LLM request retry report: request
identity, attempt classification, and a per-run collector that freezes into an
immutable report. No behavior change — nothing is mounted on any client and no
output is produced, so this is inert until the observer is wired up.

- RequestMeta identifies one logical request (provider, model, file path, task
  type, request no) and travels through the request context, so the
  single-method LLMClient interface and every call site stay unchanged.
- logical_request_id is SHA-256 over a canonical NUL-terminated encoding of
  run_id plus the meta. It is computed in Freeze, so the collector can be
  constructed before the session exists.
- classifyAttempt derives error_class and failure_phase from the HTTP status
  and the Go error type only, never from error message text. A non-2xx status
  outranks the error, since it is the stronger fact.
- RetryCollector is created per run with no package-level state, is safe for
  concurrent use, and drops attempts that carry no identity, which is how scan
  and llm test requests stay out of the report.
- The request outcome is decided once, in Finalize, from the attempt sequence
  plus the returned error and the parent context state, rather than inferred
  from the last attempt: cancelling during backoff produces no new attempt, so
  the sequence still ends in an error while the outcome is cancelled.
- Freeze recomputes every aggregate from the listed requests and returns a
  construction error instead of publishing self-contradictory numbers. Ordering
  bugs (double Finalize, mutation after Finalize) are recorded as violations
  and surface there.

The report has no free-text field, so there is nothing to redact: no bodies,
prompts, URLs or raw SDK error strings. A test pins the exact set of plain
string fields so adding one has to be argued for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: 艺临 <gongyiling.gyl@alibaba-inc.com>

* feat(llm): observe retry attempts via SDK middleware

Mount a shared observer on all three LLM clients (Anthropic, OpenAI Chat
Completions, OpenAI Responses) through option.WithMiddleware, so every real
HTTP attempt the SDK retry loop makes is recorded against the logical request
that issued it.

The observer reads response headers only -- status code, request-id /
x-request-id, Retry-After (all three forms, at the SDK's own precedence),
x-should-retry -- and never touches the body, which the SDK owns and closes
before retrying. Attempts without a RequestMeta on the context are dropped
whole, which is how scan and `ocr llm test` stay out of the report.

RecordAttempt now takes the attempt's start and end timestamps instead of
pre-computed durations. observed_backoff_ms spans two attempts, so only the
collector can derive it; deriving both durations there also means the observer
cannot desynchronize numbering from the real call order. No clock abstraction
is needed and the values stay deterministic in tests.

The collector is reached through an unexported ClientConfig field rather than
new constructor parameters, keeping the three exported constructors unchanged.
It is created per run in loadLLMRuntime, not package-level, so two runs in one
process cannot share data. Nothing consumes it yet -- P5 calls Freeze at the
run boundary.

The roadmap's X-Stainless-Retry-Count cross-check is deliberately not
implemented: the SDK stops maintaining that header once ExtraHeaders overrides
it, so the mismatch branch is only reachable from a legitimate configuration,
and the desync it guards against is already caught at build time by the
exhaustion and recovery tests asserting exact attempt counts.

WithMaxRetries(5) and WithRequestTimeout are untouched; the SDK's retry
decisions are observed, never overridden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(llm): correct attempts and finalize requests at the client boundary

The middleware can only observe real HTTP attempts, so an HTTP 200 that
carried a truncated body, undecodable JSON, a mid-stream failure, or a dead
Responses object was recorded as a success. Each client now corrects its last
attempt before returning and finalizes the logical request exactly once.

- add retry_boundary.go: classifyBoundaryError (unrecognized errors are left
  alone rather than bucketed as unknown, since the only way left to tell them
  apart would be message text), classifyStreamError, reviseAttempt,
  finalizeRequest, streamIntegrityError and the panic sentinel
- defer the boundary on all three CompletionsWithCtx, which now use named
  results; correction runs before Finalize, as the reverse order would be a
  "revised after Finalize" violation and drop the whole run's report
- correct both EOF branches ahead of their ctx early return, so a parent
  cancel between the two SDK calls cannot leave a truncated attempt as success
- split completionsStreaming into a wrapper with a single exit, so the four
  inner returns need no correction call of their own
- replace the three bare fmt.Errorf stream integrity errors with a dedicated
  type, messages unchanged
- parentCancelled reads only context.Canceled: the per-attempt deadline from
  WithRequestTimeout must surface as failed, not as a user abort
- drop finalizeForTest from the observer tests; every case now reaches Freeze
  through a client, so a missing defer fails that case instead of passing

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(llm): stamp request identity on review LLM requests

review 的五类逻辑请求在调用 SDK 前建立 RequestMeta,使 observer 能按请求身份收集 attempt;scan 的六类请求保持无 meta、不进报告。

- Deps 增加 NewRequestMeta 工厂字段:review 在 agent.New 注入闭包,scan 保持 nil;不用空 provider 当开关,空串是 unnamed endpoint 的合法值
- main_task / memory compression / re-location / plan / review filter 五个落点遵循固定顺序:AppendTaskRecord -> requestCtx -> 请求
- compression 的记录创建移到请求之前,使 request_no 在请求发起时即存在;orphan llm_request 对 resume 无害(applyResumeLine 无该分支),补回归断言
- ReLocateComment 拆出纯 prompt 构造 BuildReLocationMessages,internal/diff 不接触 session / meta;Duration 口径保持含 prompt 构造时间不变
- 导出 RequestMetaFromContext,供 llmloop / agent / scan 三包的测试跨包验收请求身份

* feat(cmd): publish the frozen retry report at the run boundary

在 review 运行边界冻结重试报告并经两个出口发布;scan 与 llm test 输出不变,session JSONL 与 run manifest 契约不动。

- Runner 增加后台 WaitGroup 与 WaitBackground():agent.Run 在 dispatchSubtasks 之后、finalizeManifest 之前收口 async compression,消除 Freeze 见到未 Finalize 请求而吞掉整份报告的竞态;不加第二个超时,等待依赖 SDK 遵守取消契约
- review_cmd.go 在 ag.Run 返回后调用 Freeze,run_id 取 session 内存 UUID 而非持久化门控的 SessionID();构造错误并入 emitErr 而非 runErr,不包装成 review failed、不触发失败 usage、不打 --resume 提示
- 报告以末位参数传给 emitRunResult / outputJSONWithWarnings,不扩展 ResultProvider;双出口去重:emitRunResult 已执行时 emitFailureUsage 不重复携带
- 终端摘要走 stdout,位于评审结果与项目摘要之间,全量渲染不截断,file_path / task_type 经 sanitizeTerminal 防控制字符注入
- JSON 在 jsonOutput 末位追加 retry_report(omitempty),直接复用 llm.RetryReport 的字段与 tag;首次成功运行输出逐字节不变
- 端到端:假 Anthropic server + 真 git 仓库驱动 runReview,覆盖干净运行、recovered+failed、全失败去重、Freeze 构造错误、session 持久化失败五个场景;manual_e2e tag 保留写码前的手工验证夹具

* test(cmd): consolidate retry report tests by responsibility

The retry-report tests for #368 P5 split coverage of emitRunResult and
emitFailureUsage into their own file, leaving the review-run emit
functions tested in two places. Move those emit-boundary cases into
emit_run_result_test.go beside the pre-existing emitRunResult tests, and
rename the remaining file to retry_report_render_test.go so it holds only
the report-rendering cases (outputRetryReportText, the JSON key-set
allowlist, retryAttemptChain). The shared retryReportFixture stays with
the rendering tests; both files are package main so it is still reachable.

No test logic changes; only relocation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: separate cancelled retry requests

---------

Signed-off-by: 艺临 <gongyiling.gyl@alibaba-inc.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 14:31:18 +08:00
Syt3s
140871d70f
feat(cmd): add SARIF output format (#820)
Some checks are pending
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / build (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
2026-08-12 18:03:34 +08:00
Syt3s
552dc95147
feat(cmd): add no-review cmd (#835)
* feat(cmd): add no-review cmd

* docs(flags): improve --no-filter help text for clarity

---------

Co-authored-by: kite <lizhengfeng.lzf@alibaba-inc.com>
2026-08-12 16:44:35 +08:00
kite
980f21d6f2
chore: remove leftover Chinese from the Go core, CI examples and pages comments (#861)
* docs(comments): translate Chinese comments to English

Rewrite the remaining Chinese code comments outside the VSCode extension
in English, so the Go core and the pages site read consistently.

- allowed_ext.go: translate the default_exclude_patterns.json package doc.
  Quote the wildcards ("*", "**", "{a,b,c}") so gofmt stops reflowing the
  leading "*" as a markdown bullet, which had swallowed the first entry's
  wildcard and broken the list alignment in godoc.
- HighlightsSection.tsx: translate three comments in parseStatValue and
  CountUpValue.

* docs(examples): use "Chinese" instead of "中文" in OCR_LANGUAGE examples

The language config value is fed to the LLM, which understands "Chinese"
just as well, and "Chinese" is what the rest of the project already uses
(skills/open-code-review/SKILL.md, config_cmd_test.go, ApplyLanguage).
Keeps the GitLab CI example's inline docs fully English.

* fix(agent): drop the unreachable Chinese branch from planBlockPattern

task_template.json ships a single English template ("### Review Plan
(Optional)") and is embedded via go:embed with no override path, so the
"审查计划" alternative could never match anything. It came from the
pre-open-source template and survived the #33 fix as dead defensive code.

Drops the two test cases that only exercised that alternative.
2026-08-12 15:58:23 +08:00
Tao Xin
a7f149929a
fix(LE): normalize line endings via .gitattributes (#858)
* add .gitattributes

* agents.md: add instructions

* add workflow step

* docs: update

* fix

* remove svg from .gitattributes
2026-08-12 14:55:58 +08:00
Ziyang Guo
5b37b5f8e2
fix(diff): match gitignore directory patterns (#853)
Match directory-only patterns against ancestor paths with glob and root-anchor semantics aligned to Git. Add regression coverage for nested, globstar, component-glob, and anchored patterns.

Test: make test
2026-08-12 14:28:51 +08:00
hezheng.lsw
56a3937b35
feat(pages): redesign hero with two-column layout and three install channels (#408)
* feat(pages): redesign hero with two-column layout and three install channels

- Change hero from centered stack to desktop two-column layout (text left, terminal right)
- Replace top install badge with three install channels: npm, macOS/Linux, Windows PowerShell
- Add brand icons (npm/apple/linux/windows) with #ffffff 90% opacity
- Interleave apple/linux icons within the macOS / Linux label
- Add i18n keys hero.installNpm/installUnix/installWindows for en/zh/ja
- Adjust hero title to three lines (en) and content paddingTop

* feat(hero): replace platform channels with npm+brew tab switcher, optimize layout

- Replace unix/windows install channels with npm + Homebrew tab switcher
- Use official Homebrew SVG icon (white monochrome)
- CTA buttons: height 32→40px, hover scale + shadow micro-interactions
- Section height: fixed px → minHeight + paddingBottom (removes dead space)
- Tab labels: simplified to 'npm' / 'Homebrew' (brand casing)
- Remove unused apple/linux/windows SVG assets
- Add missing i18n keys for ru locale

* fix(hero): improve tab selected state visibility and minor layout fixes

- Tab selected: fontWeight 600 + pure white text for better contrast
- Tab padding: 14px → 9px for tighter fit
- Button type='button' to prevent form submission
- Mobile minHeight: 'auto' → 600 to prevent background collapse
- Remove redundant ternary in alignItems

---------

Co-authored-by: kite <lizhengfeng.lzf@alibaba-inc.com>
2026-08-12 14:21:15 +08:00
Tao Xin
73c7f0f714
feat(providers): add siliconflow (GLOBAL) to built-in providers (#772)
* outline siliconflow provider structure

* tests: add siliconflow to expected providers

* docs: update

* add models

* fix alphabet order

* Update internal/llm/providers.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: naming to avoid clashing with cn version

* feat(providers): update SiliconFlow models and remove stale entries

* Remove LongCat-2.0 from models list

* fix: correct indentation (spaces → tabs) in siliconflow provider

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: kite <lizhengfeng.lzf@alibaba-inc.com>
2026-08-12 11:29:11 +08:00
Tao Xin
4068a4bd25
feat(providers): add siliconflow-cn as a built-in model provider (#775)
Some checks are pending
Deploy Pages / build (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
2026-08-11 22:12:31 +08:00
Nefelibata
4f7d78f28d
docs(skill): avoid output truncation in agent skill instructions (#809) 2026-08-11 20:43:11 +08:00
Tao Xin
a9449db5d3
feat(llm): add novita api as a default provider (#829)
* feat(llm): add Novita AI as a built-in provider

Novita's endpoint (https://api.novita.ai/v3/openai) is OpenAI-compatible,
so it registers like the other OpenAI-protocol providers (deepseek, kimi,
z-ai, ...). Adds the registry entry, the matching name in the
provider-order test, and the provider table in the en/zh/ja
configuration docs. Model ids are taken from the live
/v3/openai/models endpoint.

* fix(llm): correct Novita base URL to current documented endpoint

The registry entry, tests-adjacent docs tables (en/ja/zh configuration.md)
used https://api.novita.ai/v3/openai. That path still resolves today, but
Novita's current documentation (novita.ai/docs/guides/llm-api) no longer
shows it; the current documented OpenAI-compatible endpoint is
https://api.novita.ai/openai. Verified live 2026-08-01: both paths return
identical /models and /chat/completions results, so this is a stale-citation
fix, not a functional break.

* Recommend Novita's current flagship models

The models listed for Novita were older ids that no longer reflect what
the platform leads with. Point the recommendations at the three current
flagships instead, each verified against api.novita.ai:

  moonshotai/kimi-k3              1M context, native vision
  zai-org/glm-5.2                 1M context, long-horizon agentic work
  deepseek/deepseek-v4-flash-0731 1M context, cheapest of the three

Context windows, output limits, input modalities and pricing were taken
from the live /openai/v1/models response rather than carried over.

* Apply suggestion from @wu21-web

Co-authored-by: Tao Xin <wu2196674@icloud.com>

* Sync provider registry with upstream to resolve merge conflict

Rebase-equivalent update of internal/llm/providers.go,
internal/llm/providers_test.go, and the en/ja/zh/ru configuration docs
to match upstream/main's current content (minimax-cn, mistral, model
list refreshes) while keeping the novita entry this branch adds. This
is a targeted content sync of the six files that conflicted, not a
full merge, so unrelated upstream changes (workflows, CI, etc.) are
left untouched. Also adds the novita row to the ru docs table, which
was missing.

---------

Co-authored-by: kite <254839944+lizhengfeng101@users.noreply.github.com>
2026-08-11 20:15:52 +08:00
Fanzzzd
7e52a4fd55
fix(action): pin nested action references to full commit SHAs (#836)
Some checks are pending
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / test (push) Waiting to run
Deploy Pages / build (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
* fix(action): pin nested action references to full commit SHAs

A consumer who SHA-pins alibaba/open-code-review still ran whatever the
floating actions/* tags inside action.yml pointed at, so the outer pin
did not actually freeze the workflow. Pin all four nested references to
full commit SHAs with a trailing version comment, enforce the invariant
with scripts/verify-action-pins.sh in CI, and document the dual pin
(action SHA + ocr_version) that reproducible setups need.

Refs #816

* fix(scripts): fail the pin check when action.yml is missing
2026-08-11 15:36:13 +08:00
祈愿Qiii
e188e69c8e docs: add retry_codes configuration documentation (#827)
* docs: document retry_codes configuration

* docs: align retry_codes provider terminology

* docs: improve retry_codes CLI wording

* docs: refine Russian retry wording
2026-08-11 14:56:37 +08:00
Abdul Moiz Hussain
071debe624
feat(viewer): add review comment tag filters (#779)
Some checks are pending
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
* feat(viewer): add review comment tag filters

* fix(viewer): normalize filter chip state values

Use the same empty-string fallback when updating filter-chip active state as
when handling clicks, preventing filters without a value attribute from
appearing inactive after selection.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(viewer): improve comment tag filter controls

* fix(viewer): support combined comment filters

* fix(viewer): simplify active filter chip ring

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-08-10 23:45:51 +08:00
xujiejie
db117ad083
feat(llm): add dynamic cache breakpoint on last message for Anthropic (#828)
Mark the last content block of the final message with ephemeral
cache_control so multi-turn conversations cache the growing history,
not just the static system+tools prefix. Each turn then reads the
previous full prefix and only writes the new delta.
2026-08-10 21:50:01 +08:00
Tao Xin
372d3dd160
fix(codeql): Workflow does not contain permissions (#814)
* fix(codeql): Workflow does not contain permissions

* 更新 translation-sync.yml

Co-authored-by: Lei Zhang <61303077+stay-foolish-forever@users.noreply.github.com>

---------

Co-authored-by: Lei Zhang <61303077+stay-foolish-forever@users.noreply.github.com>
2026-08-10 19:11:39 +08:00
林SO
7340d96b2a
fix(viewer): stack suggested code panels (#739) 2026-08-10 19:05:31 +08:00
kite
440ee692c7
docs: add AGENTS.md and track CLAUDE.md for shared agent guidelines (#826)
- Create AGENTS.md with project guidelines for all AI coding assistants
- Simplify CLAUDE.md to reference AGENTS.md
- Remove CLAUDE.md from .gitignore so it can be tracked in the repo
2026-08-10 18:01:39 +08:00
kite
c89282f4db
feat(llm): support custom retry status codes via retry_codes config (#818)
Some checks are pending
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
Deploy Pages / build (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
* feat(llm): support custom retry status codes via retry_codes config

Add a retry_codes configuration field that allows users to specify
additional HTTP status codes (4xx) that should trigger exponential
backoff retry. This targets self-hosted LLM clusters that misuse
status codes like 403 or 400 for rate limiting.

Implementation uses SDK middleware to inject the x-should-retry: true
response header when a configured status code is encountered, leveraging
the existing SDK retry mechanism (up to 5 retries with exponential
backoff) without any SDK modifications.

Configuration is supported via:
- Provider config: providers.<name>.retry_codes / custom_providers.<name>.retry_codes
- Legacy llm config: llm.retry_codes
- CLI: ocr config set providers.<name>.retry_codes 403,400

Also fixes cloneProviderEntry to copy previously missing fields
(TimeoutSec, ExtraHeaders, RetryCodes) for TUI rollback correctness.

* test(llm): add unit tests for retry_codes feature

Cover ParseRetryCodes validation, retryCodesMiddleware behavior,
resolver integration (provider and legacy config paths, invalid codes),
and end-to-end retry via httptest for both OpenAI and Anthropic clients.

* feat(llm): silently filter redundant retry_codes (408/409/429) instead of erroring

Replace validateRetryCodes with sanitizeRetryCodes that filters out
SDK-default codes and returns warnings. The resolve phase silently
drops redundant codes without interrupting startup. The config set
command prints warnings to stderr so users are informed.

This makes the tool friendlier for users migrating from other tools
who habitually configure 429 and similar codes.

* test(tui): add coverage for cloneProviderEntry deep-copy of TimeoutSec/RetryCodes/ExtraHeaders

Verify that the clone correctly copies these fields and that
mutations to the clone do not affect the original. Also pin the
nil-stays-nil behavior for RetryCodes and ExtraHeaders.

* docs(llm): fix contradictory ParseRetryCodes comment

* test(config): cover retry_codes warning output in config set path

Verify that redundant codes (429, 408) emit a WARNING to stderr while
still writing the valid codes to config. Also verify that valid-only
codes produce no warning output.
2026-08-10 16:52:17 +08:00
xujiejie
71d29810be
feat(llmloop): backfill comment thinking from turn output (#773)
* feat(llmloop): backfill comment thinking from the turn's reasoning or message

Expose ChatResponse.ReasoningContent and backfill per-comment thinking
with the current turn's reasoning content, falling back to the assistant
message for models that do not expose reasoning, so --format json output
carries thinking even when the model omits it.

* fix(llmloop): drop content fallback for comment thinking backfill

The turn's assistant message is usually a short user-facing preamble
rather than real reasoning, so backfill per-comment thinking only from
the model's native reasoning_content and leave it empty otherwise.

Add a full-wiring RunPerFile test for the reasoning backfill and a
regression test that fails if the content fallback returns. Sync the
thinking docs across en/zh/ja/ru.

* docs(llmloop): note that turn-level thinking is shared by design

Document in the main loop and at the code_comment backfill site that
the model emits reasoning once per turn, so every tool call and
comment in the same turn intentionally shares the same thinking.
2026-08-10 14:52:51 +08:00
kite
3c0f00a765
feat(pages): show live npm downloads in highlights stats (#794)
Some checks are pending
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / build (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
* feat(pages): show live npm downloads in highlights stats

Add a useNpmDownloads hook that fetches real monthly download counts
from the npm registry API at runtime, and surface them in the
Highlights section, falling back to a static i18n value while loading
or on error. Also refresh the stats row copy and ordering, and sync
the label/caption/value changes across en, zh, ja and ru.

The hook encodes the (scoped) package name into the request URL and
aborts the fetch after a timeout so the UI degrades promptly on a
slow or unresponsive network.

* docs(pages): translate highlights npm-downloads comments to English

* fix(pages): give stat3 a distinct caption and refactor npm-downloads hook

- Give highlights stat3 its own caption instead of duplicating stat1's
  'battle-tested' text across all four locales
- Correct the Russian stat3 label to match 'real-world tasks' in the
  other locales
- Refactor the npm-downloads fetch to async/await and clear the timeout
  in a finally block so it no longer lingers after the request settles
2026-08-09 20:38:03 +08:00
Tao Xin
f44821d9aa
fix: no pages deployment on forks (#793)
Some checks are pending
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
2026-08-09 12:44:51 +08:00
Komali Beeram
da3771fb2b
feat(allowlist): add Nim support (#798) (#799) 2026-08-09 12:30:39 +08:00
Tao Xin
c5621fc84b
docs: fix invalid subject (#795)
contributers cannot be pushed
2026-08-09 12:09:41 +08:00
Tao Xin
8aa5cd3bad
docs: remove stale ocr session comments from README and migrate to site docs (#774)
Some checks are pending
CI / cross-compile (arm64, darwin) (push) Waiting to run
CI / cross-compile (arm64, linux) (push) Waiting to run
CI / cross-compile (arm64, windows) (push) Waiting to run
CI / test (push) Waiting to run
CI / cross-compile (amd64, darwin) (push) Waiting to run
CI / cross-compile (amd64, windows) (push) Waiting to run
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Pages / build (push) Waiting to run
Deploy Pages / deploy (push) Blocked by required conditions
* docs: fill in missing translations

* Revert "docs: fill in missing translations"

This reverts commit c881e5da292c9f6ed8e962edea22166da4020d71.

* remove stale content from README
2026-08-08 21:26:16 +08:00
Zhiming Wang
c3e8a46323
fix(cli): stop preview from creating a review session (#784)
runPreview, runScanPreview, and delegate's preview each built a throwaway
agent via agent.New / scan.NewAgent purely to reach Preview. Both
constructors auto-create a session, and session.New opens persistence and
buffers a session_start record, so every preview created a JSONL file
under the OCR home. Preview never runs or finalizes a review, so that
file was left unfinalized and usually empty.

Make the exported entry point a package-level Preview(ctx, args) in both
internal/agent and internal/scan. It builds only what file selection
needs, so there is no session, manifest, or runner to leak. The existing
bodies stay as unexported methods, keeping the in-package tests
(including scan's regression test that Preview must not mutate a.items).

Deleting the file afterwards was rejected: it would still leak on crash
and would keep the wrong abstraction.

Tests assert at the CLI boundary, with a temporary OCR home, that no
session store is created by any of the three preview commands. They also
neutralize global git config, which git resolves via XDG_CONFIG_HOME
independently of HOME.
2026-08-08 20:55:54 +08:00
Shaurya Kesarwani
3bf5ca2bbd
fix(pages): keep previous page visible during lazy route transitions (#792)
Navigating to a lazy-loaded page (/benchmark, /quickstart, /docs, /blog)
re-triggered the Suspense fallback — a plain black div — producing a black
screen flash while the chunk downloaded.

Route changes are now applied inside a React transition via a new
useTransitionedLocation hook: <Routes> renders from a location that trails
useLocation() by one startTransition, so a suspending route keeps the
current page on screen until its chunk is ready. The black fallback still
shows on first paint, preserving the intentional dark background on
initial load. ScrollToTop now follows the displayed location, so the
scroll reset happens when the new page actually appears.

Fixes #788
2026-08-08 20:31:42 +08:00