live 模式通过不同源/端口代理应用,host 作用域会话 cookie 不会自动共享,需用 --cookie、--cookie-file 或 --cdp-url 转发;story mode 从终端运行会调用全局 agent_cmd 产生额外 LLM 费用;从源码构建需要 Go 1.26+
crit
tomasz-tomczykMIT活跃维护在浏览器里审查 AI 编码代理生成的计划、代码 diff 和运行中的应用,本地优先,兼容任意代理。
Review AI coding agents' plans, diffs and running apps in the browser. Local-first, works with any agent.
brew install crit
claude plugin marketplace add tomasz-tomczyk/crit
claude plugin install crit@critREADME 未说明硬件要求;以单个二进制在本地运行,未提及显存或 GPU 需求
在浏览器里审阅 AI 编码代理的计划、diff 和运行中的应用,点行留言反馈给代理
在浏览器里审查 AI 编码代理生成的计划、代码 diff 和运行中的应用,本地优先,兼容任意代理。
核心能力
- 按输出类型切换审阅界面:Markdown 计划、git diff、运行中应用、静态 HTML
- 点击具体行或元素留下评论,代理读取后据此修改
- 自动检测仓库改动并以语法高亮 diff 展示
- story mode 为大型分支或 PR 生成分章节的变更概览
- 单二进制本地运行,支持 Claude Code、Cursor、Codex 等多种代理
容易踩的坑
- v0.23.2最新正式版2026-10-31 · 2026-10-31 13:10 UTC
What's Changed
Review page
If files change on disk during a round, the review offers a reload, and a later refetch keeps that to a single toast.
- feat(web): offer a reload when files change during a round (#1084) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1084 - Thank you!
- fix(web): ignore a superseded round refetch and keep a single files-changed toast (#1135) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1135
Put CSS in
~/.crit/custom.cssand the review page loads it.- feat: personal stylesheet at ~/.crit/custom.css (#1081) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1081 - Thank you!
- fix(web): finish a review once on a double or triple click (#1123) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1123 - Thank you!
- fix(web): keep the reader in place when a new round adds lines above by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1115 - Thank you!
- fix(web): [ / ] comment navigation stops at review comments (#1091) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1091 - Thank you!
- fix(web): give headings GitHub's slugs so in-document links jump (#1118) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1118 - Thank you!
- fix(web): give success toasts an elevated surface (#1121) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1121 - Thank you @jmacek for reporting!
Story
- fix(story): stop the story daemon opening its own browser tab (#1130) by @BrentLayne in https://github.com/tomasz-tomczyk/crit/pull/1130 - Thank you!
- fix(story): open the story view when a review is already running (#1133) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1133
Sharing
Reviews that never stored
share_base_urlno longer fall back to the current deployment. Re-bind one withcrit share --share-url. Unpublish still keeps its token when the target cannot be resolved.- Stop guessing a share deployment from a legacy review URL. (#1128) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1128
- fix(share): keep the unpublish token when a share target cannot be resolved (#1134) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1134
Daemon
- fix(daemon): run the Windows daemon in its own hidden console (#1116) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1116 - Thank you!
- fix: preserve plan comments across daemon restarts (#1120) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1120 - Thank you @BearKid for reporting!
General
- Document the community Arch Linux install (#1127) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1127 - Thank you @aelesbao for suggesting!
Dependencies
- chore(deps-dev): bump eslint from 10.12.0 to 10.13.0 (#1113) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1113
- chore(deps-dev): bump @playwright/test from 1.59.1 to 1.64.1 by @tomasz-tomczyk
Internal refactors
- test(e2e): find a match near the lazy threshold in the tree-pin test (#1117) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1117 - Thank you!
New Contributors
- @BrentLayne made their first contribution in https://github.com/tomasz-tomczyk/crit/pull/1130
Full Changelog: https://github.com/tomasz-tomczyk/crit/compare/v0.23.1...v0.23.2
- v0.23.12026-10-23 · 2026-10-23 13:03 UTC
查看更新说明
What's Changed
Markdown source and new shortcuts
In files mode, Markdown files now have a Source button that shows the whole file as code, so you can read and comment on the raw Markdown even when there is no diff.
Press
ato toggle a file as viewed andoto collapse or expand it, in the review list and in story chapters. Both can be rebound in Settings → Shortcuts.- feat(web): show a markdown file's source in files mode (#1106) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1106 - Thank you!
- feat(web): add shortcuts to toggle viewed (a) and collapse (o) (#1049) by @esnssr in https://github.com/tomasz-tomczyk/crit/pull/1049 - Thank you!
Comments are kept across concurrent writes
- fix: keep crit comment replies when a daemon write is pending (#1060) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1060 - Thank you!
- fix: serialize review saves and hosted comment merges (#1074) by @John-Isr in https://github.com/tomasz-tomczyk/crit/pull/1074 - Thank you!
- fix: keep comments across concurrent review file writes (#1093) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1093
- fix: keep reply resolve state across daemon writes, and release-audit cleanups (#1111) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1111
Security
- fix: sanitize raw HTML in reviewed Markdown documents (#1088) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1088
- fix: package.json & package-lock.json to reduce vulnerabilities (#1089) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1089
- fix(web): stop reviewed markdown from reusing page ids and classes, and release-audit cleanups (#1112) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1112
Scrolling and navigation
- fix(web): scroll straight to a comment ref already on the page (#1095) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1095 - Thank you!
- fix(web): a thread that grows in Document view no longer moves the page (#1072) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1072 - Thank you!
- fix(web): let the tree follow the scroll when the found file is off screen (#1062) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1062 - Thank you!
- fix(web): review comment cards in the panel scroll all the way back (#1110) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1110
- fix(web): keep the thread in place when the top edge cuts the file header (#1092) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1092
Fixes
- fix(web): highlight quoted diagram text in the drawn diagram (#1098) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1098 - Thank you!
- fix(session): drop binary and ignored files from range reviews (#1108) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1108 - Thank you!
- fix(web): match error toast styles to the toast-error class (#1086) by @jmacek in https://github.com/tomasz-tomczyk/crit/pull/1086 - Thank you!
- fix: scope=all re-queries git, and a pinned commit no longer overrides the scope (#1076) by @Jainbaba in https://github.com/tomasz-tomczyk/crit/pull/1076 - Thank you!
- fix: track Story viewed state per hunk (#1073) by @John-Isr in https://github.com/tomasz-tomczyk/crit/pull/1073 - Thank you!
- fix: read git paths verbatim so non-ASCII file names open (#1078) by @Flamintus in https://github.com/tomasz-tomczyk/crit/pull/1078 - Thank you!
Dependencies
- chore(deps): bump mermaid from 12.1.0 to 12.2.0 (#1069) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1069
- chore(deps): bump dompurify from 3.4.16 to 3.4.17 (#1070) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1070
Internal refactors
- chore: read vendored asset versions from the lockfile (#1090) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1090
- test(e2e): wait for pending diagrams before calling the review pane settled (#1
- v0.23.02026-10-16 · 2026-10-16 19:27 UTC
查看更新说明
What's Changed
Mermaid files and the renderer registry
.mermaidand.mmdfiles open with a Diagram / Source toggle. In files mode they open on Diagram; in git mode they open on Source, which is the diff. Click a node, edge label or actor to comment on the line that defines it. Expand opens the diagram fullscreen with pan and zoom.This runs on a new renderer registry, and Mermaid fences in markdown now use it too. New renderers (for example Arazzo workflows) are added to Crit the same way. Crit does not load renderer scripts from outside its embedded assets. See
docs/renderers.md. Mermaid is now on v12.Find in diff
The review list only keeps rows near the viewport in the page, so the browser's own find missed most matches. Cmd+F (Ctrl+F off macOS) now opens a find bar that searches all files, loads lazy files in the background, and jumps to each match. Enter / Shift+Enter or Cmd+G / Shift+Cmd+G step through matches, Alt+C toggles match case, and Esc closes. Select text first to fill the bar. Press Cmd+F a second time to get the browser's find. Plan and Document reviews keep the browser's find.
- feat(web): add a pluggable renderer registry with mermaid files render (#1043) by @akaguny in https://github.com/tomasz-tomczyk/crit/pull/1043 - Thank you!
- feat: find in diff that reaches rows outside the viewport (#1059) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1059 - Thank you @radeusgd for reporting!
- fix(web): Esc peels one layer with find open, cache rendered diagrams (#1066) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1066
Integrations
- feat(integrations): add omp review skills (#1038) by @endophysics in https://github.com/tomasz-tomczyk/crit/pull/1038 - Thank you!
- feat(integrations): add OMO review skills (#1022) by @endophysics in https://github.com/tomasz-tomczyk/crit/pull/1022 - Thank you!
- fix: plan-hook tells the agent to resubmit the plan, not run crit plan (#1041) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1041 - Thank you @mariaines for reporting!
- fix(integrations): keep reply explanations in Crit, not chat (#1042) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1042
Fixes
- fix(web): keep focus in a reply draft when comments change (#1051) by @schrek1 in https://github.com/tomasz-tomczyk/crit/pull/1051 - Thank you!
- fix: stop test helpers from clearing GIT_* env vars in the crit binary (#1064) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1064
Dependencies
- chore(deps): bump mermaid from 11.17.2 to 12.1.0 (#1047) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1047
- chore(deps): bump @pierre/diffs from 1.5.1 to 1.5.2 (#1048) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1048
- chore(deps): bump dompurify from 3.4.15 to 3.4.16 (#1016) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1016
- chore(deps-dev): bump shiki from 4.4.3 to 4.5.0 (#1044) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1044
- chore(deps-dev): bump eslint from 10.11.0 to 10.12.0 (#1045) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1045
- chore(deps-dev): bump stylelint from 17.15.0 to 17.16.0 (#1046) by @dependabot in https://github.com/tomasz-tomczyk/crit/pull/1046
Internal refactors
- test: finish test isolation from #1053 and #1056, drop dead hint code (#1065) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1065
- test(e2e): merge E2E specs to cut page loads in half (#1055) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1055
- test: stop git auto-maintenance in test repos (#1056) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1056
- test(e2e): start each project when its own fixture is ready (#1054) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1054
- test:
- v0.22.02026-10-07 · 2026-10-07 12:41 UTC
查看更新说明
What's Changed
Rendered Before/After for markdown
In diff mode, each markdown file gets a Document | Rendered | Diff toggle. Rendered shows the old and new versions of the document, split or unified, using the same toggle as the source diff. Comments on deleted lines show on the Before side.
crit-tui for Claude Code
crit-tui is a second plugin in the crit marketplace. It needs Claude Code 2.1.287 or later and is versioned on its own (0.1.0), so the main
critplugin does not change./plugin marketplace add tomasz-tomczyk/crit /plugin install crit-tui@crit/crit-tuiopens a pane with the conversation, the git diff, or a file. Select text, presscto comment, andsto send all new comments to Claude in one prompt. Claude replies in each thread. Comments are stored through the crit CLI, socrit commentsand the browser see the same review. This is an early version.- feat(web): add rendered Before/After view for markdown in diff mode (#1030) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1030
- feat(claude-code): add crit-tui, an early review pane mod for Claude Code (#1015) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1015
CLI
- feat(cli): pin live and preview reviews from crit comment (#1027) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1027
- feat(plan): add --no-wait to save a plan version without a review (#1014) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1014
- feat(cli): accept quote and quote_offset in crit comment --json (#1013) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1013
- fix(skill): wait up to 24h for Claude Code reviews (#1033) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1033
Review page
- fix(web): order file tree folders like the review list by @fhucko in https://github.com/tomasz-tomczyk/crit/pull/1020 - Thank you!
- fix: show comments on files past the eager load limit on open (#1034) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1034 - Thank you @fhucko for reporting!
- fix(web): place old-side comments, load comments once, git-only Rendered (#1036) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1036
- fix: center plan review conversation (#1031) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1031
- fix: whitespace-ignored diff uses range SHAs in PR focus (#1028) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1028
- fix(web): close the gap before filenames in file headers (#1021) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1021
Sharing
- fix(share): keep local comment lines when crit-web's copy is stale (#1037) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1037
- fix: pull carried share comments back before the next upload (#1029) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1029
Documentation
- docs: fix stale install table, drop em dashes (#1024) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1024
- Tighten README copy: grammar, parallel bullets, heading level (#1023) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1023
- docs(skills): show --file for bulk comment replies (#1018) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1018
Internal refactors
- fix(session): recognize syscall.Errno in Windows transient I/O retry by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/commit/57da7d6e
- test(e2e): synchronize mobile affordance assertions (#1025) by @hermes-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1025
- test(e2e): wait for Pierre navigation to settle (#1017) by @hermes-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1017
Full Changelog: https://github.com/tomasz-tomczyk/crit/compare/v0.21.1...v0.22.0
- v0.21.12026-10-02 · 2026-10-02 10:50 UTC
查看更新说明
What's Changed
Daemon and approve
- fix: stop the daemon over HTTP on approve and crit stop (#1001) by @fhucko in https://github.com/tomasz-tomczyk/crit/pull/1001 - Thank you!
- fix(web): lock the finish button once the server has stopped (#1002) by @fhucko in https://github.com/tomasz-tomczyk/crit/pull/1002 - Thank you!
- fix(daemon): delete the session lock file before unlocking it (#1003) by @fhucko in https://github.com/tomasz-tomczyk/crit/pull/1003 - Thank you!
OpenCode
- fix: support OpenCode v2 plugin integrations (#1007) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1007 - Thank you @manubhai04 for reporting!
- fix(opencode): migrate unedited v1 plugins from older releases to v2 (#1010) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1010
Review page
- fix: scroll document comments within Pierre list (#1006) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1006 - Thank you @mythosil for reporting!
- feat(web): border each file and use the code background for comment rows (#1004) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1004
- feat(web): left-align file-level comments in diffs (#1008) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1008
- fix: wait for review list scroll before comment alignment (#1009) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1009
- fix(web): clean up review CSS and drop stale comment jumps (#1011) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1011
Internal refactors
- ci: split e2e-windows across a 2-VM matrix (#1000) by @tomasz-tomczyk in https://github.com/tomasz-tomczyk/crit/pull/1000
New Contributors
- @fhucko made their first contribution in https://github.com/tomasz-tomczyk/crit/pull/1001
Full Changelog: https://github.com/tomasz-tomczyk/crit/compare/v0.21.0...v0.21.1
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Crit
Review your coding agent's plans, diffs and running apps in the browser. Click a line, leave a comment, and the agent gets it.

Adaptive UI for each type of output
To an agent, plans and code are both just text. To you, reviewing a plan and reviewing a web app are different jobs.
Crit gives each type of output its own review UI. Point at the exact thing that's wrong and leave a comment for the agent:
crit plan.mdrenders a markdown file with review comments.critfinds your git changes and shows them as syntax-highlighted diffs.crit http://localhost:3000proxies your running app and adds a review layer on top.crit landing.htmlrenders a static HTML file you can click and comment on.
Everything runs locally from a single binary.
Quickstart
1. Install Crit binary
Brew:
brew install crit
Go:
go install github.com/tomasz-tomczyk/crit/cmd/crit@latest
Nix:
nix profile install github:tomasz-tomczyk/crit
Arch Linux:
yay -S crit.md-bin
AUR package, maintained outside this project. Any AUR helper works in place of
yay.
Windows:
iwr https://github.com/tomasz-tomczyk/crit/releases/latest/download/crit-windows-amd64.exe -OutFile crit.exe
Note: Then move crit.exe somewhere on your PATH. ARM64 users: swap amd64 for arm64. WSL users: use the Linux binary instead.
Or download the latest release from GitHub.
2. Integrate with your agent
Claude Code:
claude plugin marketplace add tomasz-tomczyk/crit
claude plugin install crit@crit
Crit also works with Cursor, GitHub Copilot, OpenCode, OMO, omp, Codex, Gemini, Qwen, Hermes, Windsurf, Cline, Grok, Aider, and Pi — any agent that can read a file and run a command. See integrations/ for all install methods and details.
3. Tell your agent to use crit
Most integrations include a /crit slash command that automates the full review loop.
The agent launches Crit, waits for your review, then acts on the feedback.
Repeat until you approve.
Here's a 2-minute demo walkthrough of plan review and branch review:
![]()
Usage
The recommended way is to run the /crit command in your agent after any piece of work, whether it wrote a plan or changed code. You can also launch Crit yourself in a terminal and paste the prompt back to your agent when you finish.
crit # auto-detect changed files in your repo
crit plan.md # review a specific file
crit plan.md api-spec.md # review multiple files
crit http://localhost:3000 # review a running dev server
crit landing.html # review a static HTML file
In your agent chat, run /crit with any of the arguments above. Run it bare and the agent picks what to launch from the conversation.
Story mode
For larger branch, PR, MR, or range reviews, story mode adds a chaptered overview of the diff — thematic chapters, a prologue, and a support bucket for noise — so you can understand the shape of the change before line-by-line review. It is an explainer, not a reviewer.
Recommended: invoke /crit-story (or $crit-story, /skill:crit-story,
depending on your agent) after crit install <tool>. Your agent authors the
story in-session via crit story --prep / --story-file. Only run it when you
explicitly ask — agents will not infer it from a normal /crit review.
Alternative: crit story from the terminal uses your global agent_cmd
(separate LLM spend). Generation is LLM-driven exploration — cost depends on
change complexity more than raw file/diff size, and does not scale linearly.
In our experience, complex PRs (~20–50 files, ~2k–5k lines) land around
$1–$1.40 with Claude Opus 5. See the story mode guide
for commands, custom prompts, JSON shape, and token-cost notes.
Live mode
crit live <url> (or crit <url>) proxies a running dev server through Crit's review UI. Crit's iframe loads the app on a different origin/port than your browser tab, so host-scoped session cookies are not shared automatically. If the direct URL works but Crit shows a login page or hydration mismatch, forward the upstream cookies:
# one-off
crit live http://localhost:4000/dashboard --cookie "_crit_key=..."
# repeatable (Netscape jar or raw Cookie header lines)
crit live http://localhost:4000/dashboard --cookie-file .crit/live-cookies.txt
# reuse cookies from a Chrome session with remote debugging enabled
crit live http://localhost:4000/dashboard --cdp-url http://127.0.0.1:9222
Getting cookies: log in to the app in your browser, then copy the session cookie from DevTools (Application → Cookies), export a cookie jar, or start Chrome with --remote-debugging-port=9222 and pass --cdp-url so Crit reads cookies for the target origin automatically.
Config (global or project .crit.config.json; project overrides global):
{
"live_cookie_file": ".crit/live-cookies.txt",
"live_cdp_url": "http://127.0.0.1:9222"
}
Relative paths resolve from the repo root. Prefer a gitignored file under .crit/ over committing live_cookie inline. Run crit live --help for all flags.
If Comment/Pin stays unavailable, or a framework needs local CSP / iframe tweaks, see the live mode guide (injection model, common failures, Phoenix / Vite / Next.js recipes).
crit status # show review file path and daemon status
crit resume # pick a previous review to reopen
crit stats # show lifetime review statistics
crit cleanup # delete stale review files
crit resume lists every review in ~/.crit/reviews, newest first, with its branch or files, directory, age, and open comment count. Choosing one reconnects to its daemon, or restarts the daemon in the directory the review came from when it has stopped — so you can resume a review from anywhere. Pass --list to print the list instead, or a session ID to skip the picker.
Features
Round-to-round diff
After your agent edits the file, Crit shows a split or unified diff of what changed - toggle it in the header.
Split view

Unified view

Inline comments: single lines and ranges
Click a line number to comment. Drag to select a range. Comments are rendered inline after their referenced lines, just like a GitHub PR review.

Programmatic comments
AI agents can use crit comment to add inline review comments without opening the browser UI or constructing JSON manually:
crit comment src/auth.go:42 'Missing null check'
crit comment src/handler.go:15-28 'Error handling issue'
crit comment --selector 'h1' 'Heading is vague' # live app or HTML preview
crit comment --selector '#save' --route /settings 'Save stays disabled'
crit comment --session 839f3b4cd5d6 src/auth.go:42 'Target this review'
echo '[{"body":"Overall feedback"}]' | crit comment --session 839f3b4cd5d6 --json
crit comment --output ~/.crit src/auth.go:42 'comment' # same as default (~/.crit/reviews/<key>/)
crit comment --output .crit src/auth.go:42 'comment' # in-repo: .crit/reviews/<key>/
crit comment --clear # remove the review file
Comments are appended to the review file (stored in ~/.crit/reviews/) and created automatically if it doesn't exist. Run crit status to see active review session IDs and paths. If multiple sessions match the same directory and branch, select one with --session <id> on crit comment, crit comments, crit share, crit push, or crit pull; an unqualified command fails instead of guessing.
Share for Async Review
Want a second opinion before handing off to the agent? Click the Share button to upload your review and get a public URL anyone can open in a browser, no install needed. Each reviewer's comments are color-coded by author. Unpublish anytime.
You can also share directly from the CLI without starting the browser UI:
crit share plan.md # share files and print the URL
crit share plan.md --qr # also print a QR code in the terminal
crit share plan.md --org acme # share under an organization
crit share plan.md --org acme --visibility unlisted # org share with explicit visibility
crit unpublish # remove the shared review
When sharing under an org, visibility defaults to organization (members only). Override with --visibility (organization, unlisted, or public). The browser UI shows an org picker when you're signed in and belong to an organization.
Sharing uses crit.md when no sharing key exists. To use several deployments, configure global share_targets; the browser asks for a destination and each review stays bound to its first destination:
{"share_targets":[
{"name":"Acme Crit","url":"https://crit.acme.com","default":true,"proxy_auth":true},
{"name":"crit.md","url":"https://crit.md"}
]}
Run crit auth login --share-url https://crit.acme.com to add or authenticate a target, and add --set-default to make it the CLI default. crit auth status lists every target. An explicit "share_targets": [] disables sharing and never injects crit.md. Legacy share_url remains readable; crit config --migrate converts it atomically. --share-url and CRIT_SHARE_URL are process-only overrides and never persist a new target; an explicitly empty CRIT_SHARE_URL disables sharing for that process.
A review saved before share_base_url existed does not guess a deployment from the share link, and it does not fall back to the current default. Re-bind it with crit share --share-url https://crit.acme.com plan.md, where that URL is still a configured target. If a saved base URL is no longer in your config, Crit names that missing instance instead of sending the review somewhere else.
If a target sits behind an SSO reverse proxy, set proxy_auth: true on that target. Browser-driven Share / Pull / Re-share / Unpublish then use its popup relay; terminal operations remain unavailable for that target.
Authentication
You can share anonymously or you can create a free crit.md account (using GitHub oAuth). To authenticate with crit-web (for sharing and other features that require an account):
crit auth login # opens browser to log in
crit auth login --share-url https://crit.acme.com --set-default
crit auth status # list targets and identities
crit auth logout --share-url https://crit.md
crit auth login uses the OAuth Device Flow - it opens your browser, you confirm, and the CLI receives a token automatically. The token is stored in your global config (~/.crit.config.json).
GitHub PR and GitLab MR Sync
Crit can review and sync comments bidirectionally with GitHub pull requests and GitLab merge requests. Install and authenticate the CLI for your forge: GitHub CLI (gh auth login) or GitLab CLI (glab auth login). GitLab.com, self-managed GitLab hosts, nested groups, and cross-project merge requests are supported.
Crit auto-detects GitHub or GitLab from the repository remote. Set "forge": "github" or "forge": "gitlab" in config to override ambiguous/self-managed remotes, or pass --forge to crit pull and crit push. GitLab's base URL is configured once with gitlab_url and defaults to https://gitlab.com; set it to your self-managed instance in .crit.config.json. MR URLs remain valid change identifiers, but their host must match the configured gitlab_url.
Open a remote change for review
crit pr 42 # GitHub pull request
crit mr 42 # GitLab MR in the current project
crit mr https://gitlab.com/group/sub/project/-/merge_requests/42
crit review --mr 42 --remote # read MR files via GitLab instead of local git
Pull comments
crit pull # auto-detect from current branch and remote
crit pull 42 # explicit PR number or MR IID
crit pull --forge gitlab 42 # explicit provider
crit pull https://gitlab.com/group/project/-/merge_requests/42
Push comments and review outcomes
crit push # auto-detect PR/MR from current branch
crit push --dry-run # preview without posting
crit push --message "Round 2" # add a review summary
crit push --event approve 42 # approve
crit push --event request-changes --forge gitlab 42
Sync viewed files with GitHub
When you review with crit --pr, files you mark as viewed can be ticked in the PR's "Files changed" tab, and the other way round:
crit push --viewed # tick your viewed files on the PR
crit push --viewed --dry-run # preview what would change
crit pull --viewed # bring in files ticked on GitHub
Push skips files that changed since you viewed them, files marked by auto_viewed_patterns, and marks made outside the PR's own diff. Unticking a file in Crit unticks it on GitHub. Your marks stay available after you finish a review, so you can push them afterwards. Pull adds GitHub's ticks but keeps any file you unticked in Crit; an open review page shows them after a reload. GitLab has no equivalent, so --viewed is an error there.
GitLab inline comments are published as a single review using Draft Notes. request-changes requires GitLab support for the reviewer_state=requested_changes bulk-publish option; Crit reports an error instead of silently downgrading the outcome. Pulling again imports replies, edits, deletes, and discussion resolution without duplicating local comments.
Send to agent (experimental)
Click "Send now" on any comment during a review to get an AI agent response in real-time. This feature only appears when agent_cmd is configured.
The agent reads the comment context, addresses it (editing code if needed), and replies
inline - all while you continue reviewing.

Configure in ~/.crit.config.json (global config only):
{
"agent_cmd": "claude --dangerously-skip-permissions -p"
}
Security note:
agent_cmdis read exclusively from your global~/.crit.config.json. Project-level.crit.config.jsonfiles cannot set it. This prevents a malicious repository from executing arbitrary commands when you trigger "Send to agent".
Permission modes
Agents need tool permissions to edit files on your behalf. How you grant them depends on your trust level:
| Mode | Command | What the agent can do |
|---|---|---|
| Full access | claude --dangerously-skip-permissions -p | Read, write, and run any tool. Simplest option - recommended for trusted repos. |
| Selective access | claude --allowedTools Edit,Read,Bash,Write,Glob,Grep -p | Only the listed tools are permitted. Good middle ground. |
| No permissions | claude -p | The agent can respond to comments but cannot edit files. Useful for Q&A-only workflows. |
How it works
- The agent receives the comment text, quoted text (if text was selected), file path, and line range on stdin.
- The agent's stdout is captured and posted as a reply to the comment automatically.
- If the agent edits files, Crit detects the changes via file watching and updates the UI.
Live threads
After the first agent interaction, the comment becomes a live thread:
- Further replies you post in the thread are automatically sent to the agent - no need to click "Send to agent" again.
- The agent sees the full conversation history, so it can build on previous context.
- Live threads show a ⚡ live badge and green glow - the agent will respond immediately to further replies.
Supported agents
| Agent | agent_cmd value |
|---|---|
| Claude Code | claude -p |
| OpenCode | opencode run |
| Cline | cline --pipe |
| Aider | aider --message-file - |
| Cursor (experimental) | cursor --pipe |
Tip: Claude Code still prompts for permission in
-pmode. To let it edit files freely, useclaude --dangerously-skip-permissions -pinstead. The other agents already operate without permission prompts in their pipe/non-interactive modes.You can also specify a model with
--model(e.g.claude --model sonnet -p).
Everything else
- Per-branch review isolation. Each branch gets its own review file — switch branches freely without losing comments. Review data lives in
~/.crit/reviews/, not your repo. - Draft autosave. Close your browser mid-review and pick up exactly where you left off.
- Vim keybindings.
j/kto navigate,cto comment,Shift+Fto finish.?for the full reference. - Concurrent reviews. Each instance runs on its own port - review multiple plans at once.
- Syntax highlighting. Code blocks are highlighted and split per-line, so you can comment on individual lines inside a fence.
- Diagrams and custom renderers. Mermaid fences render as diagrams, and
.mermaid/.mmdfiles get a Diagram / Source toggle. In a Mermaid file, click a diagram node to comment on the line that defines it. See the renderers guide. - Live file watching. Each new round loads the latest files. If a file under review changes during a round (in files and plan mode), Crit offers to reload the files in place, keeping your place and any comment you're writing. Comments move to their new lines at the next round, so until then one below an added or removed line can sit slightly off, as after a browser refresh.
- Paired UI and code themes. Choose light and dark Shiki-based palettes in Settings; code, rendered markdown and review UI share their colours. System/Light/Dark selects the active palette. Preferences persist in a cookie across ports.
- Configurable code font. Code-review Settings → Display → Code font lists coding/monospace fonts detected by the local Crit daemon, plus Default, System monospace, and a custom
font-familyfallback. Applies to code and diffs, and persists across sessions. - Local by default. Server binds to
127.0.0.1. Your files stay on your machine unless you explicitly share. Non-loopback listen hosts andpublic_urlrequire--allow-unauthenticated-network(orCRIT_ALLOW_UNAUTHENTICATED_NETWORK=1) because Crit has no network authentication — prefer SSH forwarding, Tailscale Serve to loopback, or Docker-p 127.0.0.1:…. - Collapsing generated files. Honors
linguist-generatedin.gitattributes— matching files appear collapsed by default. - No analytics or tracking. Crit collects zero telemetry. No usage stats, no crash reports, no phone-home. If we ever add anonymous usage statistics in the future, they will be explicitly opt-in.
- Update check. On startup, Crit makes one network request to check for a newer version and prints a notice if one is available. Set
CRIT_NO_UPDATE_CHECK=1to disable it.
Configuration
Crit supports persistent configuration via JSON files so you don't have to pass the same flags every time.
| File | Scope | Location |
|---|---|---|
~/.crit.config.json | Global | Applies to all projects |
.crit.config.json | Project | Repo root (from git rev-parse --show-toplevel) |
Project config overrides global. CLI flags and env vars override both.
crit config --generate > ~/.crit.config.json # scaffold a starter config file
crit config # view resolved config (merged global + project)
Config keys
All keys are optional — omit any you don't need.
| Key | Type | Default | Description |
|---|---|---|---|
port | int | 0 (random) | Port for the local server. 0 picks a random available port. |
host | string | "127.0.0.1" | Listen host (global/CLI/env only). Non-loopback values also require --allow-unauthenticated-network / CRIT_ALLOW_UNAUTHENTICATED_NETWORK=1. Prefer loopback + SSH/Tailscale/Docker host-loopback publish. |
no_open | bool | false | Don't auto-open the browser when starting a review. |
quiet | bool | false | On success, suppress daemon connect/start lines, integration tips, and the session summary. Errors, approved:, and the finish prompt are unchanged. |
output | string | ~/.crit | Crit data root for reviews. Reviews live in <root>/reviews/<key>/ (same layout as the default). |
author | string | VCS user name | Author name shown on comments. Falls back to your configured VCS user name. |
forge | string | "auto" | Remote review provider: "auto", "github", or "gitlab". Auto-detection uses the repository remote; set this for ambiguous self-managed hosts. |
gitlab_url | string | "https://gitlab.com" | GitLab base URL used for every MR operation. Set once for a self-managed instance; MR URL arguments must use the same host. |
base_branch | string | auto-detected | Base branch to diff against (e.g. "main", "develop"). Overrides auto-detection. |
ignore_patterns | string[] | [".crit/"] | File patterns to exclude from git-mode file lists. Global and project patterns are merged. |
auto_viewed_patterns | string[] | [] | File patterns auto-marked as viewed (collapsed) once when a review opens — e.g. ["*.lock", "generated/", "PLAN.md"]. Manually un-marking a file keeps it open. Global and project patterns are merged. |
default_markdown_view | string | "" (diff in git mode) | Initial view for markdown files (Document/Diff toggle) in git mode: "document" opens them in document view, "diff" (or unset) keeps diff view. File mode is always document view. Project overrides global. |
cleanup_on_approve | bool | true | Automatically delete the review file when you approve with no unresolved comments. Set to false to preserve review history. |
notify_on_round_ready | bool | false | Opt in to a desktop notification when a review round becomes ready for you (after the agent finishes addressing comments). On macOS, install terminal-notifier (brew install terminal-notifier) so clicking the notification opens the review URL — without it, clicking falls back to AppleScript's display notification, which macOS attributes to Script Editor and activates that instead of your browser. |
no_update_check | bool | false | Don't check for new versions on startup. |
no_integration_check | bool | false | Skip the integration config freshness check on startup. |
vcs | string | auto-detected | Preferred VCS backend: "git", "sl", or "jj". When set, crit uses this VCS instead of auto-detecting. Falls back to git if the configured VCS isn't available. Can also be set via --vcs CLI flag (flag takes precedence over config). |
live_cookie | string | "" | Cookie header value forwarded to the upstream app in live mode (e.g. "_crit_key=..."). Global or project. Prefer live_cookie_file for secrets. |
live_cookie_file | string | "" | Path to a file with upstream cookies for live mode (raw header lines or Netscape jar). Global or project; relative paths resolve from repo root. |
live_cdp_url | string | "" | Chrome DevTools URL (e.g. http://127.0.0.1:9222) to reuse browser cookies for the live upstream. Global or project. |
prompts | object | {} | Custom finish-hook templates (project overrides global per key). See Agent prompts. |
hooks | object | {} | Custom finish-hook commands executed at Finish/Approve (project overrides global per key). Deterministic side effects — crit pipes a JSON payload to stdin and sets CRIT_* env vars. See Command hooks. |
Agent prompts
Customize what Crit tells your agent when you Finish Review or Approve. Hooks are templates in global or project config (prompts map) and .crit/prompts/*.md files.
See the agent prompts guide for hook reference, template variables, trust flow, and examples.
Command hooks
Run your own scripts when you Finish Review or Approve — deterministic side effects, no LLM in the loop. Crit pipes a JSON payload to the hook's stdin and sets CRIT_* env vars (review path, session key, mode, unresolved count, files-with-comments, …). Keys and resolution mirror the prompt system (on_finish_unresolved / on_finish_approved, optionally :files / :diff / :live / :preview), and project hooks go through the same trust gate as project prompts.
# ~/.crit.config.json
{
"hooks": {
"on_finish_unresolved": "inline:rsync -a \"$CRIT_REVIEW_PATH\" ~/reviews/$CRIT_SESSION_KEY.json",
"on_finish_approved": "file:~/.crit/hooks/approved.sh"
}
}
See the command hooks guide for the full env-var/stdin reference, trust flow, and examples (including the “snapshot commented-on files” recipe). Reference example hook scripts live under docs/example-hooks/ in the repo — they're documentation, not installed by crit install and not tracked among the integrations (hooks are opt-in and not used by default).
Global-only config keys
These keys can only be set in ~/.crit.config.json (global). Project-level .crit.config.json cannot override them — this prevents a malicious repository from hijacking local commands or redirecting share requests.
| Key | Type | Default | Description |
|---|---|---|---|
agent_cmd | string | "" | Shell command for "Send to agent" (e.g. "claude -p"). See Send to agent. |
open_cmd | string | "" | Custom command to open review URLs — receives the URL as its only argument (must be a single executable, no flags). Use when the browser isn't on the machine running crit, e.g. crit runs on a remote host over SSH and a small wrapper script opens the URL on your local machine. When unset, crit uses the platform default opener. |
share_targets | array | implicit crit.md when absent | Deployment list with per-target name, url, default, proxy_auth, nested auth, and public share_consented. An explicit empty array disables sharing. |
auth_token | string | "" | Legacy singleton token; read only while share_targets is absent. |
share_url | string | implicit "https://crit.md" | Legacy singleton URL. An explicitly empty value disables sharing; migrate with crit config --migrate. |
public_url | string | "" | Advertised base URL for stderr and browser-open (e.g. https://machine.ts.net via tailscale serve). Listen address unchanged. Requires --allow-unauthenticated-network / CRIT_ALLOW_UNAUTHENTICATED_NETWORK=1. |
share_consented | bool | false | Written automatically to true after you confirm the first-time share prompt. Reset to false to see the prompt again. Not used when share_url is a custom (self-hosted) URL. |
proxy_auth | bool | false | When true, share / pull / unpublish / re-share use the browser popup relay instead of the local Go server contacting crit-web directly. Use when crit-web is behind an SSO reverse proxy that the terminal cannot authenticate against. No flag or env var — this is a property of the deployment, not a per-invocation choice. |
plan_approve_mode | string | unset | Claude Code permission mode after Crit approves an ExitPlanMode hook: default, manual, acceptEdits, plan, auto, dontAsk, or bypassPermissions. The update uses destination: "session", so it lasts only for the current Claude Code session. See Claude Code plan approval mode. |
close_on_approve_after_ms | int | unset (disabled) | Auto-close the review tab this many milliseconds after you Approve with no unresolved comments. Unset means no auto-close (current behavior); negative values are treated as unset. A Cancel button during the countdown skips the close for that approval. |
stale_review_days | int | 14 | Delete reviews untouched for this many days in the background sweep that runs when a review starts. Unset or non-positive values use the default. crit cleanup --days N is unaffected. |
CLI flags
| Flag | Short | Equivalent config key | Description |
|---|---|---|---|
--port | -p | port | Port to listen on |
--host | host | Listen host (default 127.0.0.1) | |
--public-url | public_url | Advertised review URL (listen unchanged) | |
--allow-unauthenticated-network | — | Required with non-loopback --host or any --public-url | |
--no-open | no_open | Don't auto-open browser | |
--share-url | share_url | Share service URL | |
--output | -o | output | Crit data root for reviews (<root>/reviews/<key>/). |
--quiet | -q | quiet | On success, suppress connect/start status, tips, and session summary |
--base-branch | base_branch | Base branch to diff against | |
--vcs | vcs | VCS backend (git, sl, or jj) | |
--no-ignore | Temporarily bypass all ignore patterns | ||
--version | -v | Print version and exit |
Live mode only (crit live <url> — see crit live --help):
| Flag | Equivalent config key | Description |
|---|---|---|
--cookie | live_cookie | Upstream cookie value (repeatable) |
--cookie-file | live_cookie_file | File with upstream cookies |
--cdp-url | live_cdp_url | Chrome DevTools URL to reuse browser cookies |
Ignore patterns
Patterns from global and project configs are merged. Supported syntax:
| Pattern | Matches |
|---|---|
*.lock | Files ending in .lock anywhere in tree |
vendor/ | All files under vendor/ |
package-lock.json | Exact filename anywhere in tree |
generated/*.pb.go | Path prefix with glob (filepath.Match syntax) |
Use --no-ignore to temporarily bypass all patterns:
crit --no-ignore
Custom styles
To restyle Crit with your own CSS, create ~/.crit/custom.css. Every Crit page (reviews, live mode and the theme preview) loads it after Crit's own styles, reading it fresh each time, so edit the file and reload the tab to see changes. If the file can't be read, Crit logs why and uses its own styles. In review and live mode, Settings → Configuration shows whether the file exists and its path, and Settings → Display has a "Use custom CSS" switch to turn it off without deleting it.
Crit marks the page with the mode in use, data-crit-mode="light" or "dark" (also when following the system setting), so you can keep everything for one mode in one block. Override theme variables and nest element rules inside it:
:root[data-crit-mode="dark"] {
/* the block a comment is on, and the exact words it quotes */
--crit-comment-range-bg: rgba(83, 155, 245, 0.15);
--crit-quote-highlight-bg: rgba(83, 155, 245, 0.28);
.line-block.has-comment { box-shadow: inset 3px 0 0 #539bf5; }
}
:root[data-crit-mode="light"] {
--crit-comment-range-bg: rgba(9, 105, 218, 0.10);
--crit-quote-highlight-bg: rgba(9, 105, 218, 0.18);
.line-block.has-comment { box-shadow: inset 3px 0 0 #0969da; }
}
For a single value that differs by mode, light-dark(light, dark) also works.
Code diffs are drawn inside shadow roots, which page CSS cannot reach with selectors; only inherited CSS variables (such as the ones above, or --diffs-* overrides) get through. Override the derived --crit-* variables, as above: the palette's own --crit-palette-* values are set inline on <html>, so they only change with !important. Class names are not a stable API and may change between releases.
Environment variables
| Variable | Description |
|---|---|
CRIT_PORT | Default port for the local server |
CRIT_HOST | Listen host (default 127.0.0.1) |
CRIT_PUBLIC_URL | Advertised review URL (e.g. tailscale serve) |
CRIT_ALLOW_UNAUTHENTICATED_NETWORK | Allow non-loopback host / public_url (1/true/yes/on) |
CRIT_SHARE_URL | Override the share service URL |
CRIT_AUTH_TOKEN | Override the auth token (skips crit auth login) |
CRIT_NO_UPDATE_CHECK | Disable the update check on startup |
CRIT_NO_INTEGRATION_CHECK | Skip integration config freshness checks |
Other Install Methods
Build from Source
Requires Go 1.26+:
git clone https://github.com/tomasz-tomczyk/crit.git
cd crit
go build -o crit ./cmd/crit
mv crit /usr/local/bin/
Go
go install github.com/tomasz-tomczyk/crit/cmd/crit@latest
Nix
nix run github:tomasz-tomczyk/crit -- --help
Or add it to a flake.nix:
inputs.crit.url = "github:tomasz-tomczyk/crit";
Download Binary
Grab the latest binary for your platform from Releases.
Windows
Native Windows: download crit-windows-amd64.exe (or crit-windows-arm64.exe) from Releases, rename to crit.exe, and place it on your PATH.
WSL: install the Linux binary as you would on Linux (go install, nix run, or download crit-linux-amd64 from Releases). Crit detects WSL and opens URLs in your Windows host browser via wslview / powershell.exe / cmd.exe.
Docker (sandboxed agents)
For running crit alongside an AI agent inside a container, with the review UI reachable from your host browser, see integrations/docker/. Includes a working Dockerfile + entrypoint.sh that bridges crit's loopback-bound server via socat. Publish with -p 127.0.0.1:8080:8080 so the host mapping stays on loopback.
Acknowledgements
Crit embeds the following open-source libraries:
- markdown-it: Markdown parser
- @pierre/diffs: Diff and code rendering
- Shiki: Syntax highlighting and code themes
- Mermaid: Diagram rendering