@humanbased/crosscheck 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +207 -0
- package/ISSUE.md +234 -0
- package/LICENSE +21 -0
- package/README.md +234 -0
- package/README.zh.md +169 -0
- package/assets/logo.png +0 -0
- package/assets/screenshot-watch-timing.png +0 -0
- package/assets/screenshot-watch-timing.svg +1 -0
- package/assets/screenshot-watch.png +0 -0
- package/crosscheck.config.example.yml +214 -0
- package/dist/__tests__/annotation.test.d.ts +2 -0
- package/dist/__tests__/annotation.test.d.ts.map +1 -0
- package/dist/__tests__/annotation.test.js +134 -0
- package/dist/__tests__/annotation.test.js.map +1 -0
- package/dist/__tests__/backtrace.test.d.ts +2 -0
- package/dist/__tests__/backtrace.test.d.ts.map +1 -0
- package/dist/__tests__/backtrace.test.js +280 -0
- package/dist/__tests__/backtrace.test.js.map +1 -0
- package/dist/__tests__/board.test.d.ts +2 -0
- package/dist/__tests__/board.test.d.ts.map +1 -0
- package/dist/__tests__/board.test.js +149 -0
- package/dist/__tests__/board.test.js.map +1 -0
- package/dist/__tests__/codex.test.d.ts +2 -0
- package/dist/__tests__/codex.test.d.ts.map +1 -0
- package/dist/__tests__/codex.test.js +92 -0
- package/dist/__tests__/codex.test.js.map +1 -0
- package/dist/__tests__/comment-bodies.test.d.ts +2 -0
- package/dist/__tests__/comment-bodies.test.d.ts.map +1 -0
- package/dist/__tests__/comment-bodies.test.js +75 -0
- package/dist/__tests__/comment-bodies.test.js.map +1 -0
- package/dist/__tests__/conflict-resolve.test.d.ts +2 -0
- package/dist/__tests__/conflict-resolve.test.d.ts.map +1 -0
- package/dist/__tests__/conflict-resolve.test.js +123 -0
- package/dist/__tests__/conflict-resolve.test.js.map +1 -0
- package/dist/__tests__/crosscheck-commit.test.d.ts +2 -0
- package/dist/__tests__/crosscheck-commit.test.d.ts.map +1 -0
- package/dist/__tests__/crosscheck-commit.test.js +13 -0
- package/dist/__tests__/crosscheck-commit.test.js.map +1 -0
- package/dist/__tests__/detector.test.d.ts +2 -0
- package/dist/__tests__/detector.test.d.ts.map +1 -0
- package/dist/__tests__/detector.test.js +112 -0
- package/dist/__tests__/detector.test.js.map +1 -0
- package/dist/__tests__/diagnose.test.d.ts +2 -0
- package/dist/__tests__/diagnose.test.d.ts.map +1 -0
- package/dist/__tests__/diagnose.test.js +164 -0
- package/dist/__tests__/diagnose.test.js.map +1 -0
- package/dist/__tests__/diff-hash.test.d.ts +2 -0
- package/dist/__tests__/diff-hash.test.d.ts.map +1 -0
- package/dist/__tests__/diff-hash.test.js +126 -0
- package/dist/__tests__/diff-hash.test.js.map +1 -0
- package/dist/__tests__/durations.test.d.ts +2 -0
- package/dist/__tests__/durations.test.d.ts.map +1 -0
- package/dist/__tests__/durations.test.js +26 -0
- package/dist/__tests__/durations.test.js.map +1 -0
- package/dist/__tests__/event-fields.test.d.ts +2 -0
- package/dist/__tests__/event-fields.test.d.ts.map +1 -0
- package/dist/__tests__/event-fields.test.js +50 -0
- package/dist/__tests__/event-fields.test.js.map +1 -0
- package/dist/__tests__/filter.test.d.ts +2 -0
- package/dist/__tests__/filter.test.d.ts.map +1 -0
- package/dist/__tests__/filter.test.js +21 -0
- package/dist/__tests__/filter.test.js.map +1 -0
- package/dist/__tests__/fix.test.d.ts +2 -0
- package/dist/__tests__/fix.test.d.ts.map +1 -0
- package/dist/__tests__/fix.test.js +124 -0
- package/dist/__tests__/fix.test.js.map +1 -0
- package/dist/__tests__/github-client.test.d.ts +2 -0
- package/dist/__tests__/github-client.test.d.ts.map +1 -0
- package/dist/__tests__/github-client.test.js +22 -0
- package/dist/__tests__/github-client.test.js.map +1 -0
- package/dist/__tests__/github-scan-client.test.d.ts +2 -0
- package/dist/__tests__/github-scan-client.test.d.ts.map +1 -0
- package/dist/__tests__/github-scan-client.test.js +100 -0
- package/dist/__tests__/github-scan-client.test.js.map +1 -0
- package/dist/__tests__/is-fresh-review-comment.test.d.ts +2 -0
- package/dist/__tests__/is-fresh-review-comment.test.d.ts.map +1 -0
- package/dist/__tests__/is-fresh-review-comment.test.js +86 -0
- package/dist/__tests__/is-fresh-review-comment.test.js.map +1 -0
- package/dist/__tests__/issue.test.d.ts +2 -0
- package/dist/__tests__/issue.test.d.ts.map +1 -0
- package/dist/__tests__/issue.test.js +259 -0
- package/dist/__tests__/issue.test.js.map +1 -0
- package/dist/__tests__/kickass.test.d.ts +2 -0
- package/dist/__tests__/kickass.test.d.ts.map +1 -0
- package/dist/__tests__/kickass.test.js +268 -0
- package/dist/__tests__/kickass.test.js.map +1 -0
- package/dist/__tests__/loader.test.d.ts +2 -0
- package/dist/__tests__/loader.test.d.ts.map +1 -0
- package/dist/__tests__/loader.test.js +180 -0
- package/dist/__tests__/loader.test.js.map +1 -0
- package/dist/__tests__/onboard-preservation.test.d.ts +2 -0
- package/dist/__tests__/onboard-preservation.test.d.ts.map +1 -0
- package/dist/__tests__/onboard-preservation.test.js +506 -0
- package/dist/__tests__/onboard-preservation.test.js.map +1 -0
- package/dist/__tests__/optimize.test.d.ts +2 -0
- package/dist/__tests__/optimize.test.d.ts.map +1 -0
- package/dist/__tests__/optimize.test.js +101 -0
- package/dist/__tests__/optimize.test.js.map +1 -0
- package/dist/__tests__/post-review-comment.test.d.ts +2 -0
- package/dist/__tests__/post-review-comment.test.d.ts.map +1 -0
- package/dist/__tests__/post-review-comment.test.js +44 -0
- package/dist/__tests__/post-review-comment.test.js.map +1 -0
- package/dist/__tests__/pr-lock.test.d.ts +2 -0
- package/dist/__tests__/pr-lock.test.d.ts.map +1 -0
- package/dist/__tests__/pr-lock.test.js +115 -0
- package/dist/__tests__/pr-lock.test.js.map +1 -0
- package/dist/__tests__/pr-picker.test.d.ts +2 -0
- package/dist/__tests__/pr-picker.test.d.ts.map +1 -0
- package/dist/__tests__/pr-picker.test.js +57 -0
- package/dist/__tests__/pr-picker.test.js.map +1 -0
- package/dist/__tests__/pr-status-scan.test.d.ts +2 -0
- package/dist/__tests__/pr-status-scan.test.d.ts.map +1 -0
- package/dist/__tests__/pr-status-scan.test.js +92 -0
- package/dist/__tests__/pr-status-scan.test.js.map +1 -0
- package/dist/__tests__/pr-status.test.d.ts +2 -0
- package/dist/__tests__/pr-status.test.d.ts.map +1 -0
- package/dist/__tests__/pr-status.test.js +346 -0
- package/dist/__tests__/pr-status.test.js.map +1 -0
- package/dist/__tests__/repo-picker.test.d.ts +2 -0
- package/dist/__tests__/repo-picker.test.d.ts.map +1 -0
- package/dist/__tests__/repo-picker.test.js +115 -0
- package/dist/__tests__/repo-picker.test.js.map +1 -0
- package/dist/__tests__/review-comment-body.test.d.ts +2 -0
- package/dist/__tests__/review-comment-body.test.d.ts.map +1 -0
- package/dist/__tests__/review-comment-body.test.js +54 -0
- package/dist/__tests__/review-comment-body.test.js.map +1 -0
- package/dist/__tests__/review-models.test.d.ts +2 -0
- package/dist/__tests__/review-models.test.d.ts.map +1 -0
- package/dist/__tests__/review-models.test.js +39 -0
- package/dist/__tests__/review-models.test.js.map +1 -0
- package/dist/__tests__/review-status.test.d.ts +2 -0
- package/dist/__tests__/review-status.test.d.ts.map +1 -0
- package/dist/__tests__/review-status.test.js +95 -0
- package/dist/__tests__/review-status.test.js.map +1 -0
- package/dist/__tests__/runner.test.d.ts +2 -0
- package/dist/__tests__/runner.test.d.ts.map +1 -0
- package/dist/__tests__/runner.test.js +204 -0
- package/dist/__tests__/runner.test.js.map +1 -0
- package/dist/__tests__/scan-cache.test.d.ts +2 -0
- package/dist/__tests__/scan-cache.test.d.ts.map +1 -0
- package/dist/__tests__/scan-cache.test.js +59 -0
- package/dist/__tests__/scan-cache.test.js.map +1 -0
- package/dist/__tests__/scan-client.test.d.ts +2 -0
- package/dist/__tests__/scan-client.test.d.ts.map +1 -0
- package/dist/__tests__/scan-client.test.js +30 -0
- package/dist/__tests__/scan-client.test.js.map +1 -0
- package/dist/__tests__/scan.test.d.ts +2 -0
- package/dist/__tests__/scan.test.d.ts.map +1 -0
- package/dist/__tests__/scan.test.js +115 -0
- package/dist/__tests__/scan.test.js.map +1 -0
- package/dist/__tests__/scopes.test.d.ts +2 -0
- package/dist/__tests__/scopes.test.d.ts.map +1 -0
- package/dist/__tests__/scopes.test.js +101 -0
- package/dist/__tests__/scopes.test.js.map +1 -0
- package/dist/__tests__/sha-cache.test.d.ts +2 -0
- package/dist/__tests__/sha-cache.test.d.ts.map +1 -0
- package/dist/__tests__/sha-cache.test.js +40 -0
- package/dist/__tests__/sha-cache.test.js.map +1 -0
- package/dist/__tests__/smart-switch.test.d.ts +2 -0
- package/dist/__tests__/smart-switch.test.d.ts.map +1 -0
- package/dist/__tests__/smart-switch.test.js +145 -0
- package/dist/__tests__/smart-switch.test.js.map +1 -0
- package/dist/ck.d.ts +3 -0
- package/dist/ck.d.ts.map +1 -0
- package/dist/ck.js +8 -0
- package/dist/ck.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +132 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/diagnose.d.ts +54 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +294 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/impact.d.ts +38 -0
- package/dist/commands/impact.d.ts.map +1 -0
- package/dist/commands/impact.js +210 -0
- package/dist/commands/impact.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +183 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/issue.d.ts +25 -0
- package/dist/commands/issue.d.ts.map +1 -0
- package/dist/commands/issue.js +445 -0
- package/dist/commands/issue.js.map +1 -0
- package/dist/commands/kickass.d.ts +59 -0
- package/dist/commands/kickass.d.ts.map +1 -0
- package/dist/commands/kickass.js +288 -0
- package/dist/commands/kickass.js.map +1 -0
- package/dist/commands/onboard.d.ts +70 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +883 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/optimize.d.ts +16 -0
- package/dist/commands/optimize.d.ts.map +1 -0
- package/dist/commands/optimize.js +244 -0
- package/dist/commands/optimize.js.map +1 -0
- package/dist/commands/review.d.ts +2 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +118 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/run.d.ts +13 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +243 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scan.d.ts +94 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +276 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/serve.d.ts +9 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +402 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +89 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/watch.d.ts +9 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +902 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/loader.d.ts +47 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +334 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +814 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +152 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/github/client.d.ts +139 -0
- package/dist/github/client.d.ts.map +1 -0
- package/dist/github/client.js +711 -0
- package/dist/github/client.js.map +1 -0
- package/dist/github/detector.d.ts +12 -0
- package/dist/github/detector.d.ts.map +1 -0
- package/dist/github/detector.js +120 -0
- package/dist/github/detector.js.map +1 -0
- package/dist/github/merge.d.ts +9 -0
- package/dist/github/merge.d.ts.map +1 -0
- package/dist/github/merge.js +33 -0
- package/dist/github/merge.js.map +1 -0
- package/dist/github/review-status.d.ts +6 -0
- package/dist/github/review-status.d.ts.map +1 -0
- package/dist/github/review-status.js +51 -0
- package/dist/github/review-status.js.map +1 -0
- package/dist/github/webhook.d.ts +41 -0
- package/dist/github/webhook.d.ts.map +1 -0
- package/dist/github/webhook.js +50 -0
- package/dist/github/webhook.js.map +1 -0
- package/dist/lib/annotation.d.ts +23 -0
- package/dist/lib/annotation.d.ts.map +1 -0
- package/dist/lib/annotation.js +103 -0
- package/dist/lib/annotation.js.map +1 -0
- package/dist/lib/backtrace.d.ts +40 -0
- package/dist/lib/backtrace.d.ts.map +1 -0
- package/dist/lib/backtrace.js +169 -0
- package/dist/lib/backtrace.js.map +1 -0
- package/dist/lib/board.d.ts +74 -0
- package/dist/lib/board.d.ts.map +1 -0
- package/dist/lib/board.js +640 -0
- package/dist/lib/board.js.map +1 -0
- package/dist/lib/clone.d.ts +12 -0
- package/dist/lib/clone.d.ts.map +1 -0
- package/dist/lib/clone.js +30 -0
- package/dist/lib/clone.js.map +1 -0
- package/dist/lib/comment-bodies.d.ts +17 -0
- package/dist/lib/comment-bodies.d.ts.map +1 -0
- package/dist/lib/comment-bodies.js +51 -0
- package/dist/lib/comment-bodies.js.map +1 -0
- package/dist/lib/crosscheck-commit.d.ts +2 -0
- package/dist/lib/crosscheck-commit.d.ts.map +1 -0
- package/dist/lib/crosscheck-commit.js +4 -0
- package/dist/lib/crosscheck-commit.js.map +1 -0
- package/dist/lib/diff-hash.d.ts +16 -0
- package/dist/lib/diff-hash.d.ts.map +1 -0
- package/dist/lib/diff-hash.js +71 -0
- package/dist/lib/diff-hash.js.map +1 -0
- package/dist/lib/durations.d.ts +5 -0
- package/dist/lib/durations.d.ts.map +1 -0
- package/dist/lib/durations.js +39 -0
- package/dist/lib/durations.js.map +1 -0
- package/dist/lib/event-fields.d.ts +6 -0
- package/dist/lib/event-fields.d.ts.map +1 -0
- package/dist/lib/event-fields.js +20 -0
- package/dist/lib/event-fields.js.map +1 -0
- package/dist/lib/filter.d.ts +2 -0
- package/dist/lib/filter.d.ts.map +1 -0
- package/dist/lib/filter.js +4 -0
- package/dist/lib/filter.js.map +1 -0
- package/dist/lib/fortune.d.ts +2 -0
- package/dist/lib/fortune.d.ts.map +1 -0
- package/dist/lib/fortune.js +26 -0
- package/dist/lib/fortune.js.map +1 -0
- package/dist/lib/languages.d.ts +3 -0
- package/dist/lib/languages.d.ts.map +1 -0
- package/dist/lib/languages.js +26 -0
- package/dist/lib/languages.js.map +1 -0
- package/dist/lib/log-analysis.d.ts +17 -0
- package/dist/lib/log-analysis.d.ts.map +1 -0
- package/dist/lib/log-analysis.js +72 -0
- package/dist/lib/log-analysis.js.map +1 -0
- package/dist/lib/logger.d.ts +14 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +84 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/port.d.ts +2 -0
- package/dist/lib/port.d.ts.map +1 -0
- package/dist/lib/port.js +21 -0
- package/dist/lib/port.js.map +1 -0
- package/dist/lib/pr-lock.d.ts +4 -0
- package/dist/lib/pr-lock.d.ts.map +1 -0
- package/dist/lib/pr-lock.js +91 -0
- package/dist/lib/pr-lock.js.map +1 -0
- package/dist/lib/pr-picker.d.ts +10 -0
- package/dist/lib/pr-picker.d.ts.map +1 -0
- package/dist/lib/pr-picker.js +80 -0
- package/dist/lib/pr-picker.js.map +1 -0
- package/dist/lib/pr-status.d.ts +206 -0
- package/dist/lib/pr-status.d.ts.map +1 -0
- package/dist/lib/pr-status.js +613 -0
- package/dist/lib/pr-status.js.map +1 -0
- package/dist/lib/repo-picker.d.ts +23 -0
- package/dist/lib/repo-picker.d.ts.map +1 -0
- package/dist/lib/repo-picker.js +411 -0
- package/dist/lib/repo-picker.js.map +1 -0
- package/dist/lib/review-models.d.ts +7 -0
- package/dist/lib/review-models.d.ts.map +1 -0
- package/dist/lib/review-models.js +32 -0
- package/dist/lib/review-models.js.map +1 -0
- package/dist/lib/runner.d.ts +65 -0
- package/dist/lib/runner.d.ts.map +1 -0
- package/dist/lib/runner.js +710 -0
- package/dist/lib/runner.js.map +1 -0
- package/dist/lib/scan-cache.d.ts +31 -0
- package/dist/lib/scan-cache.d.ts.map +1 -0
- package/dist/lib/scan-cache.js +112 -0
- package/dist/lib/scan-cache.js.map +1 -0
- package/dist/lib/scopes.d.ts +16 -0
- package/dist/lib/scopes.d.ts.map +1 -0
- package/dist/lib/scopes.js +37 -0
- package/dist/lib/scopes.js.map +1 -0
- package/dist/lib/sha-cache.d.ts +7 -0
- package/dist/lib/sha-cache.d.ts.map +1 -0
- package/dist/lib/sha-cache.js +44 -0
- package/dist/lib/sha-cache.js.map +1 -0
- package/dist/lib/smart-switch.d.ts +44 -0
- package/dist/lib/smart-switch.d.ts.map +1 -0
- package/dist/lib/smart-switch.js +145 -0
- package/dist/lib/smart-switch.js.map +1 -0
- package/dist/lib/verdict.d.ts +9 -0
- package/dist/lib/verdict.d.ts.map +1 -0
- package/dist/lib/verdict.js +52 -0
- package/dist/lib/verdict.js.map +1 -0
- package/dist/lib/workflow.d.ts +85 -0
- package/dist/lib/workflow.d.ts.map +1 -0
- package/dist/lib/workflow.js +116 -0
- package/dist/lib/workflow.js.map +1 -0
- package/dist/reviewers/address.d.ts +5 -0
- package/dist/reviewers/address.d.ts.map +1 -0
- package/dist/reviewers/address.js +87 -0
- package/dist/reviewers/address.js.map +1 -0
- package/dist/reviewers/claude.d.ts +12 -0
- package/dist/reviewers/claude.d.ts.map +1 -0
- package/dist/reviewers/claude.js +78 -0
- package/dist/reviewers/claude.js.map +1 -0
- package/dist/reviewers/codex.d.ts +9 -0
- package/dist/reviewers/codex.d.ts.map +1 -0
- package/dist/reviewers/codex.js +121 -0
- package/dist/reviewers/codex.js.map +1 -0
- package/dist/reviewers/conflict-resolve.d.ts +15 -0
- package/dist/reviewers/conflict-resolve.d.ts.map +1 -0
- package/dist/reviewers/conflict-resolve.js +219 -0
- package/dist/reviewers/conflict-resolve.js.map +1 -0
- package/dist/reviewers/fix.d.ts +7 -0
- package/dist/reviewers/fix.d.ts.map +1 -0
- package/dist/reviewers/fix.js +197 -0
- package/dist/reviewers/fix.js.map +1 -0
- package/get-started.md +1271 -0
- package/get-started.zh.md +1208 -0
- package/package.json +75 -0
package/get-started.md
ADDED
|
@@ -0,0 +1,1271 @@
|
|
|
1
|
+
<div align="right">
|
|
2
|
+
<h5><a href="./get-started.zh.md">🌏 中文</a></h5>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# crosscheck — Get Started
|
|
6
|
+
|
|
7
|
+
## Table of contents
|
|
8
|
+
|
|
9
|
+
- [Prerequisites](#prerequisites)
|
|
10
|
+
- [Install](#install)
|
|
11
|
+
- [Environment variables](#environment-variables)
|
|
12
|
+
- [Step 1 — Check your environment](#step-1--check-your-environment)
|
|
13
|
+
- [Step 2 — Test with a single PR](#step-2--test-with-a-single-pr)
|
|
14
|
+
- [Step 3 — Choose a deployment mode](#step-3--choose-a-deployment-mode)
|
|
15
|
+
- [Step 4 — Verify it's working](#step-4--verify-its-working)
|
|
16
|
+
- [Commands](#commands)
|
|
17
|
+
- [init](#crosscheck-init)
|
|
18
|
+
- [onboard](#crosscheck-onboard)
|
|
19
|
+
- [review](#crosscheck-review-pr-url)
|
|
20
|
+
- [run](#crosscheck-run-pr-url)
|
|
21
|
+
- [watch](#crosscheck-watch)
|
|
22
|
+
- [serve](#crosscheck-serve-beta)
|
|
23
|
+
- [status](#crosscheck-status)
|
|
24
|
+
- [diagnose](#crosscheck-diagnose)
|
|
25
|
+
- [optimize](#crosscheck-optimize)
|
|
26
|
+
- [impact](#crosscheck-impact)
|
|
27
|
+
- [issue](#crosscheck-issue)
|
|
28
|
+
- [Configuration](#configuration)
|
|
29
|
+
- [How it works](#how-it-works)
|
|
30
|
+
- [Post-review auto-fix](#post-review-auto-fix)
|
|
31
|
+
- [FAQ](#faq)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
You need three CLIs installed and authenticated before crosscheck can run reviews.
|
|
38
|
+
|
|
39
|
+
### Claude Code
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install -g @anthropic-ai/claude-code
|
|
43
|
+
claude # follow prompts to sign in to claude.ai
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Requires a Claude Pro or Max plan. Reviews use your subscription quota — no per-token API billing.
|
|
47
|
+
|
|
48
|
+
### Codex
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install -g @openai/codex
|
|
52
|
+
codex login --device-auth # OAuth sign-in with your ChatGPT account
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Requires a ChatGPT Plus or Pro plan. When authenticated via `--device-auth`, reviews run against your subscription — no API key needed.
|
|
56
|
+
|
|
57
|
+
If you prefer to use an OpenAI API key instead:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
printenv OPENAI_API_KEY | codex login --with-api-key
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Then set `auth: api-key` in your config to enable model selection.
|
|
64
|
+
|
|
65
|
+
### GitHub CLI
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
brew install gh # macOS
|
|
69
|
+
gh auth login
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Used for cloning PR branches and (in watch mode) registering webhooks automatically.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Install
|
|
77
|
+
|
|
78
|
+
**Stable (recommended):**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install -g @humanbased/crosscheck
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Beta (latest features, may have rough edges):**
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install -g @humanbased/crosscheck@beta
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**npx — no install:**
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx @humanbased/crosscheck <command>
|
|
94
|
+
npx @humanbased/crosscheck@beta <command>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**From source:**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git clone https://github.com/humanbased-ai/crosscheck
|
|
101
|
+
cd crosscheck
|
|
102
|
+
npm install && npm run build && npm link
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Environment variables
|
|
108
|
+
|
|
109
|
+
### GitHub auth — two options (pick one)
|
|
110
|
+
|
|
111
|
+
**Option 1 — gh CLI (recommended):** authenticate once and crosscheck picks up the token automatically:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
gh auth login
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Option 2 — Personal access token:** useful in CI or if you prefer an explicit token:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
export GITHUB_TOKEN=ghp_...
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
A classic PAT needs `repo` and `admin:org_hook` scopes (org-level webhooks require `admin:org_hook`; repo-level only needs `repo`).
|
|
124
|
+
Generate one at [github.com/settings/tokens](https://github.com/settings/tokens).
|
|
125
|
+
|
|
126
|
+
If both are present, crosscheck prefers the `gh` keyring token (always fresh) and uses `GITHUB_TOKEN` as a fallback.
|
|
127
|
+
|
|
128
|
+
### Webhook secret — auto-managed
|
|
129
|
+
|
|
130
|
+
`CROSSCHECK_WEBHOOK_SECRET` is **optional**. If you don't set it, crosscheck generates a random secret on first use and saves it to `~/.crosscheck/webhook-secret` (readable only by you). It's reused automatically on every subsequent run.
|
|
131
|
+
|
|
132
|
+
To retrieve it later (e.g. to register a webhook manually):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
cat ~/.crosscheck/webhook-secret
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
To use your own secret instead, set it in your shell profile:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
export CROSSCHECK_WEBHOOK_SECRET=your-secret
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Step 1 — Set up crosscheck
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
crosscheck onboard
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`crosscheck onboard` is the recommended first step. It checks your CLIs, walks you through deployment mode, repo selection, review mode, and workflow pipeline, then writes a ready-to-use config — all in one session. See the [`crosscheck onboard`](#crosscheck-onboard) command reference for the full six-step walkthrough.
|
|
153
|
+
|
|
154
|
+
Once it completes, go straight to `crosscheck watch`. There is no separate init step required.
|
|
155
|
+
|
|
156
|
+
> If you prefer to skip the wizard and configure manually, run `crosscheck init` to generate a starter config, then edit `~/.crosscheck/config.yml` directly.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Step 2 — Test with a single PR
|
|
161
|
+
|
|
162
|
+
Before running continuously, verify end-to-end with one PR:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
crosscheck review https://github.com/owner/repo/pull/123 --reviewer codex
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
This clones the PR branch, runs Codex review against the base branch, and posts a comment to the PR. If it completes without error, your setup is working.
|
|
169
|
+
|
|
170
|
+
Try Claude as reviewer too:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
crosscheck review https://github.com/owner/repo/pull/123 --reviewer claude
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Step 3 — Choose a deployment mode
|
|
179
|
+
|
|
180
|
+
### Personal vs team
|
|
181
|
+
|
|
182
|
+
On first run, `crosscheck watch` (or `crosscheck serve`) will ask how you're using it:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
How are you using crosscheck?
|
|
186
|
+
|
|
187
|
+
[1] personal — monitor all your repos and orgs; review only PRs you author
|
|
188
|
+
[2] team — monitor org repos only; review all PRs from any author
|
|
189
|
+
|
|
190
|
+
Choice [1]:
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The choice is saved to `crosscheck.config.yml` as `deployment: personal` or `deployment: team`.
|
|
194
|
+
|
|
195
|
+
**Personal mode** (default, recommended for individuals)
|
|
196
|
+
- Monitors all repos under your personal GitHub account + all orgs you belong to
|
|
197
|
+
- Only reviews PRs you authored — ignores everyone else's
|
|
198
|
+
- Sets `routing.allowed_authors` to your GitHub login automatically
|
|
199
|
+
|
|
200
|
+
**Team mode** (recommended for shared machines)
|
|
201
|
+
- Monitors all orgs you belong to (no personal repos)
|
|
202
|
+
- Reviews all PRs from any author — no author filter applied
|
|
203
|
+
|
|
204
|
+
You can override the saved choice for a single session without touching the config:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
crosscheck watch --personal # personal mode this session only
|
|
208
|
+
crosscheck watch --team # team mode this session only
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
To re-run the prompt and permanently change your choice:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
crosscheck watch --reconfigure
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Watch mode — for your development machine
|
|
218
|
+
|
|
219
|
+
Starts a local server and opens a tunnel via `localhost.run` (SSH, no install needed) so GitHub can reach your laptop. Registers webhooks automatically. Supports org-level coverage or per-repo. Runs while your terminal is open.
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# Monitor entire orgs (set in crosscheck.config.yml)
|
|
223
|
+
crosscheck watch
|
|
224
|
+
|
|
225
|
+
# Or run inside a repo — auto-detects from git remote
|
|
226
|
+
cd /path/to/your/repo && crosscheck watch
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
crosscheck watch
|
|
231
|
+
|
|
232
|
+
orgs humanbased-ai, codatta
|
|
233
|
+
mode cross-vendor
|
|
234
|
+
quality balanced
|
|
235
|
+
config ./crosscheck.config.yml ← edit to change above
|
|
236
|
+
|
|
237
|
+
✓ tunnel ready: https://abc123.lhr.life
|
|
238
|
+
tunnel https://abc123.lhr.life
|
|
239
|
+
✓ webhook registered for humanbased-ai
|
|
240
|
+
|
|
241
|
+
Waiting for PR events — Ctrl+C to stop.
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
When you press `Ctrl+C`, the SSH tunnel and any registered webhooks are cleaned up automatically.
|
|
245
|
+
|
|
246
|
+
**Token scope for org webhooks:** `GITHUB_TOKEN` needs `write:org` scope for org-level coverage. For repo-level, `repo` scope is sufficient.
|
|
247
|
+
|
|
248
|
+
### Serve mode [BETA] — for an always-on machine (mac-mini, home server)
|
|
249
|
+
|
|
250
|
+
> **Beta:** `serve` is functional but not yet battle-tested in production. Report issues at [github.com/humanbased-ai/crosscheck/issues](https://github.com/humanbased-ai/crosscheck/issues).
|
|
251
|
+
|
|
252
|
+
Listens on a fixed port. You register the webhook(s) manually once and they stay registered.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
crosscheck serve
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
crosscheck serving
|
|
260
|
+
⚠ serve is in beta — report issues at github.com/humanbased-ai/crosscheck/issues
|
|
261
|
+
|
|
262
|
+
mode cross-vendor
|
|
263
|
+
quality balanced
|
|
264
|
+
port 7891
|
|
265
|
+
endpoint http://your-machine.local:7891/webhook
|
|
266
|
+
|
|
267
|
+
Register the endpoint above as a GitHub org webhook (content-type: application/json).
|
|
268
|
+
→ https://github.com/organizations/humanbased-ai/settings/hooks
|
|
269
|
+
→ https://github.com/organizations/codatta/settings/hooks
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**For org-level coverage** (covers all repos in the org), register at:
|
|
273
|
+
`https://github.com/organizations/<org>/settings/hooks`
|
|
274
|
+
|
|
275
|
+
**For repo-level coverage**, register at:
|
|
276
|
+
`https://github.com/<owner>/<repo>/settings/hooks`
|
|
277
|
+
|
|
278
|
+
- Payload URL: `http://your-machine:7891/webhook`
|
|
279
|
+
- Content type: `application/json`
|
|
280
|
+
- Secret: your `CROSSCHECK_WEBHOOK_SECRET` value
|
|
281
|
+
- Which events: **Pull requests** only
|
|
282
|
+
|
|
283
|
+
**Running as a background service (macOS launchd):**
|
|
284
|
+
|
|
285
|
+
```xml
|
|
286
|
+
<!-- ~/Library/LaunchAgents/dev.crosscheck.plist -->
|
|
287
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
288
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
289
|
+
<plist version="1.0">
|
|
290
|
+
<dict>
|
|
291
|
+
<key>Label</key><string>dev.crosscheck</string>
|
|
292
|
+
<key>ProgramArguments</key>
|
|
293
|
+
<array>
|
|
294
|
+
<string>/usr/local/bin/crosscheck</string>
|
|
295
|
+
<string>serve</string>
|
|
296
|
+
</array>
|
|
297
|
+
<key>EnvironmentVariables</key>
|
|
298
|
+
<dict>
|
|
299
|
+
<key>GITHUB_TOKEN</key><string>ghp_your_token</string>
|
|
300
|
+
<key>CROSSCHECK_WEBHOOK_SECRET</key><string>your_secret</string>
|
|
301
|
+
</dict>
|
|
302
|
+
<key>RunAtLoad</key><true/>
|
|
303
|
+
<key>KeepAlive</key><true/>
|
|
304
|
+
<key>StandardOutPath</key><string>/tmp/crosscheck.log</string>
|
|
305
|
+
<key>StandardErrorPath</key><string>/tmp/crosscheck.error.log</string>
|
|
306
|
+
</dict>
|
|
307
|
+
</plist>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
launchctl load ~/Library/LaunchAgents/dev.crosscheck.plist
|
|
312
|
+
launchctl start dev.crosscheck
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Running with pm2 (cross-platform):**
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
npm install -g pm2
|
|
319
|
+
pm2 start crosscheck -- serve
|
|
320
|
+
pm2 save && pm2 startup
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## Step 4 — Verify it's working
|
|
326
|
+
|
|
327
|
+
Open a PR (or push to an existing one). You should see:
|
|
328
|
+
|
|
329
|
+
1. A log line in your terminal when the event arrives
|
|
330
|
+
2. A code review comment posted to the PR within ~60 seconds
|
|
331
|
+
|
|
332
|
+
If it doesn't appear, run `crosscheck status` to check auth and config, then check your GitHub webhook delivery log at `Settings → Webhooks → Recent Deliveries`.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Commands
|
|
337
|
+
|
|
338
|
+
### `crosscheck init`
|
|
339
|
+
|
|
340
|
+
Checks your environment and writes a starter config file.
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
crosscheck init
|
|
344
|
+
crosscheck init --config /path/to/crosscheck.config.yml
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
What it checks: `codex` CLI, `claude` CLI, `gh` CLI, `GITHUB_TOKEN`, `CROSSCHECK_WEBHOOK_SECRET`.
|
|
348
|
+
|
|
349
|
+
| Flag | Description |
|
|
350
|
+
|---|---|
|
|
351
|
+
| `-c, --config <path>` | Write the config file to a specific path |
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
### `crosscheck onboard`
|
|
356
|
+
|
|
357
|
+
The recommended first-time setup command. Walks through seven steps interactively and writes a ready-to-use config.
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
crosscheck onboard
|
|
361
|
+
crosscheck onboard --yes # accept all defaults non-interactively
|
|
362
|
+
crosscheck onboard --personal # force personal mode for this session
|
|
363
|
+
crosscheck onboard --team # force team mode for this session
|
|
364
|
+
crosscheck onboard --reconfigure # re-run setup even if config already exists
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
**The seven steps:**
|
|
368
|
+
|
|
369
|
+
**Step 1 — Environment check.** Verifies codex CLI, claude CLI, gh CLI, and GitHub token. At least one AI CLI must be authenticated; gh auth is always required. Prints ✓/✗ with fix hints.
|
|
370
|
+
|
|
371
|
+
**Step 2 — Deployment mode.** Choose how crosscheck scopes itself:
|
|
372
|
+
- `personal` — monitors your personal repos + all orgs you belong to; reviews only PRs you author
|
|
373
|
+
- `team` — monitors org repos only; reviews all PRs from any author
|
|
374
|
+
|
|
375
|
+
**Step 3 — Repo selection.** Lists accessible repos and orgs; you pick which ones to watch. Org-level selection covers all repos in the org with one webhook.
|
|
376
|
+
|
|
377
|
+
**Step 4 — Review mode.** If both CLIs are available, choose:
|
|
378
|
+
- `cross-vendor` — Claude reviews Codex PRs; Codex reviews Claude PRs (recommended when using both agents)
|
|
379
|
+
- `single-vendor` — one AI reviews all PRs (default when only one CLI is installed)
|
|
380
|
+
|
|
381
|
+
**Step 5 — Workflow pipeline.** Choose what happens after a review:
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
[1] review only — AI posts a comment; you handle fixes
|
|
385
|
+
[2] review → fix — AI reviews, then auto-applies fixes (recommended)
|
|
386
|
+
[3] review → fix → re-check — full loop: review, fix, re-review to confirm
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
The `review → fix → re-check` option writes a `~/.crosscheck/workflow.yml` with all three pipeline steps configured.
|
|
390
|
+
|
|
391
|
+
**Step 6 — Connection type.** Choose how GitHub webhooks reach your local server:
|
|
392
|
+
- `localhost.run` — zero-config SSH tunnel; reconnects automatically, no install required *(default)*
|
|
393
|
+
- `smee.io` — webhook relay; events queued while offline, stable channel URL (requires `npm install -g smee-client` and `tunnel.smee_channel` in config)
|
|
394
|
+
|
|
395
|
+
**Step 7 — Review and write config.** Shows a summary of all choices and writes `~/.crosscheck/config.yml` (and `workflow.yml` if re-check was selected).
|
|
396
|
+
|
|
397
|
+
```
|
|
398
|
+
crosscheck onboard
|
|
399
|
+
|
|
400
|
+
Step 1 — environment check
|
|
401
|
+
✓ codex CLI codex-cli 0.128.0 — authenticated
|
|
402
|
+
✓ claude CLI 2.1.x (Claude Code)
|
|
403
|
+
✓ gh CLI gh version 2.65.0
|
|
404
|
+
✓ GITHUB_TOKEN set (gh auth login)
|
|
405
|
+
|
|
406
|
+
Step 2 — deployment mode
|
|
407
|
+
[1] personal [2] team
|
|
408
|
+
Choice [1]: 1
|
|
409
|
+
|
|
410
|
+
Step 3 — select repos to monitor
|
|
411
|
+
[1] humanbased-ai (org · 12 repos)
|
|
412
|
+
[2] codatta (org · 5 repos)
|
|
413
|
+
[3] your-github-login (personal · 8 repos)
|
|
414
|
+
Select [all]: 1,3
|
|
415
|
+
|
|
416
|
+
Step 4 — review mode
|
|
417
|
+
[1] cross-vendor [2] single-vendor
|
|
418
|
+
Choice [1]: 1
|
|
419
|
+
|
|
420
|
+
Step 5 — workflow pipeline
|
|
421
|
+
[1] review only [2] review → fix [3] review → fix → re-check
|
|
422
|
+
Choice [2]: 3
|
|
423
|
+
|
|
424
|
+
Step 6 — connection type
|
|
425
|
+
[1] localhost.run [2] smee.io
|
|
426
|
+
Choice [1]: 1
|
|
427
|
+
|
|
428
|
+
Step 7 — review and write config
|
|
429
|
+
deployment personal
|
|
430
|
+
connection localhost.run
|
|
431
|
+
orgs humanbased-ai
|
|
432
|
+
users your-github-login (8 repos)
|
|
433
|
+
mode cross-vendor
|
|
434
|
+
pipeline review-fix-recheck
|
|
435
|
+
config ~/.crosscheck/config.yml
|
|
436
|
+
|
|
437
|
+
✓ config written to ~/.crosscheck/config.yml
|
|
438
|
+
✓ workflow written to ~/.crosscheck/workflow.yml
|
|
439
|
+
|
|
440
|
+
Next: run crosscheck watch to start reviewing PRs.
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
> **`crosscheck init` vs `crosscheck onboard`** — `init` is a lightweight environment check only (no repo selection, no pipeline prompt). Use it for a quick health check or in CI. `onboard` is the full first-time setup wizard.
|
|
444
|
+
|
|
445
|
+
| Flag | Description |
|
|
446
|
+
|---|---|
|
|
447
|
+
| `-c, --config <path>` | Write the config to a specific path |
|
|
448
|
+
| `-y, --yes` | Accept all defaults without interactive prompts |
|
|
449
|
+
| `--personal` | Use personal deployment mode for this session only |
|
|
450
|
+
| `--team` | Use team deployment mode for this session only |
|
|
451
|
+
| `--reconfigure` | Re-run setup even if `deployment` is already set in config |
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
### `crosscheck review <pr-url>`
|
|
456
|
+
|
|
457
|
+
Manually triggers a review for a single PR.
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
crosscheck review https://github.com/owner/repo/pull/123
|
|
461
|
+
crosscheck review https://github.com/owner/repo/pull/123 --reviewer codex
|
|
462
|
+
crosscheck review https://github.com/owner/repo/pull/123 --reviewer claude
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
| Flag | Description |
|
|
466
|
+
|---|---|
|
|
467
|
+
| `-r, --reviewer codex\|claude` | Skip auto-detection and force a specific reviewer |
|
|
468
|
+
| `-c, --config <path>` | Use a specific config file |
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
### `crosscheck run <pr-url>`
|
|
473
|
+
|
|
474
|
+
Executes the full configured workflow against a single PR: review → auto-fix → recheck. Where `crosscheck review` stops after posting a comment, `crosscheck run` closes the loop — if issues are found, the authoring agent opens a fix PR and crosscheck re-reviews it.
|
|
475
|
+
|
|
476
|
+
```bash
|
|
477
|
+
crosscheck run https://github.com/owner/repo/pull/123
|
|
478
|
+
crosscheck run https://github.com/owner/repo/pull/123 --reviewer claude
|
|
479
|
+
crosscheck run https://github.com/owner/repo/pull/123 --steps review,fix
|
|
480
|
+
crosscheck run https://github.com/owner/repo/pull/123 --dry-run
|
|
481
|
+
crosscheck run https://github.com/owner/repo/pull/123 --expected-head-sha abc1234
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
The workflow executed is loaded from `.crosscheck/workflow.yml` in the repo root (if present) or falls back to the built-in default pipeline (review only). Use `crosscheck run` to test your full pipeline end-to-end against a real PR.
|
|
485
|
+
|
|
486
|
+
| Flag | Description |
|
|
487
|
+
|---|---|
|
|
488
|
+
| `-r, --reviewer codex\|claude` | Force a specific reviewer; skip auto-detection |
|
|
489
|
+
| `--steps <list>` | Run only the listed step types, comma-separated: `review`, `fix`, `recheck` |
|
|
490
|
+
| `--dry-run` | Run the review but do not post a comment or apply fixes |
|
|
491
|
+
| `--expected-head-sha <sha>` | Skip if the PR head changed since the command was queued |
|
|
492
|
+
| `-c, --config <path>` | Use a specific config file |
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
### `crosscheck scan`
|
|
497
|
+
|
|
498
|
+
Scans monitored open PRs and shows which crosscheck workflow state each PR is in.
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
crosscheck scan
|
|
502
|
+
crosscheck scan --tidy
|
|
503
|
+
crosscheck scan --force --stale-after 2h
|
|
504
|
+
crosscheck scan --json
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
| Flag | Description |
|
|
508
|
+
|---|---|
|
|
509
|
+
| `--tidy` | Show only stale PRs that need attention |
|
|
510
|
+
| `--force` | Bypass the short-lived scan cache |
|
|
511
|
+
| `--stale-after <duration>` | Treat PRs as stale after a duration like `30m`, `2h`, or `1d` |
|
|
512
|
+
| `--json` | Emit raw scan data for scripts |
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
### `crosscheck kickass`
|
|
517
|
+
|
|
518
|
+
Selects stale PRs from the operator queue and advances each one with the safest next action: review, fix, recheck, or merge. The command revalidates the PR head before each mutation and prints an execution summary when it finishes.
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
crosscheck kickass --dry-run
|
|
522
|
+
crosscheck kickass --force --stale-after 2h
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
| Flag | Description |
|
|
526
|
+
|---|---|
|
|
527
|
+
| `--dry-run` | Print the selected actions without mutating PRs |
|
|
528
|
+
| `--force` | Bypass the short-lived scan cache |
|
|
529
|
+
| `--stale-after <duration>` | Only queue PRs stale for at least this duration |
|
|
530
|
+
|
|
531
|
+
---
|
|
532
|
+
|
|
533
|
+
### `crosscheck watch`
|
|
534
|
+
|
|
535
|
+
Local dev mode. Auto-creates a smee.io tunnel, registers the webhook, cleans up on exit.
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
cd /path/to/your/repo
|
|
539
|
+
crosscheck watch
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Uses `localhost.run` (SSH) to open a public tunnel — SSH is pre-installed on macOS/Linux, no extra install or account needed. Requires `GITHUB_TOKEN` with `write:org` scope for org-level coverage, or `repo` scope for repo-level.
|
|
543
|
+
|
|
544
|
+
| Flag | Description |
|
|
545
|
+
|---|---|
|
|
546
|
+
| `-c, --config <path>` | Use a specific config file |
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
### `crosscheck serve` [BETA]
|
|
551
|
+
|
|
552
|
+
Always-on mode. Listens on a fixed port; you register webhooks once manually.
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
crosscheck serve
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
| Flag | Description |
|
|
559
|
+
|---|---|
|
|
560
|
+
| `-c, --config <path>` | Use a specific config file |
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
### `crosscheck status`
|
|
565
|
+
|
|
566
|
+
Shows auth state, config summary, and CLI versions.
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
crosscheck status
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
```
|
|
573
|
+
crosscheck status
|
|
574
|
+
|
|
575
|
+
Auth
|
|
576
|
+
✓ codex authenticated
|
|
577
|
+
✓ claude 2.1.x (Claude Code)
|
|
578
|
+
✓ GITHUB_TOKEN via gh auth login
|
|
579
|
+
✓ WEBHOOK_SECRET auto-managed at ~/.crosscheck/webhook-secret
|
|
580
|
+
|
|
581
|
+
Config
|
|
582
|
+
mode cross-vendor
|
|
583
|
+
quality tier balanced
|
|
584
|
+
codex auth subscription
|
|
585
|
+
claude model sonnet
|
|
586
|
+
per-review budget $2.00/review
|
|
587
|
+
|
|
588
|
+
Impact
|
|
589
|
+
summary 47 reviews · ~43h saved · 19 issues caught
|
|
590
|
+
(run crosscheck impact for details)
|
|
591
|
+
|
|
592
|
+
Logs
|
|
593
|
+
path ~/.crosscheck/logs/
|
|
594
|
+
today 2026-05-08.ndjson (12 entries)
|
|
595
|
+
|
|
596
|
+
CLIs
|
|
597
|
+
codex codex-cli 0.128.0
|
|
598
|
+
claude 2.1.x (Claude Code)
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
| Flag | Description |
|
|
602
|
+
|---|---|
|
|
603
|
+
| `-c, --config <path>` | Check status against a specific config file |
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
### `crosscheck diagnose`
|
|
608
|
+
|
|
609
|
+
Reads `~/.crosscheck/logs/` and surfaces failure patterns, reviewer performance, and improvement suggestions.
|
|
610
|
+
|
|
611
|
+
```bash
|
|
612
|
+
crosscheck diagnose
|
|
613
|
+
crosscheck diagnose --since 2026-05-01
|
|
614
|
+
crosscheck diagnose --json
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
```
|
|
618
|
+
crosscheck diagnose
|
|
619
|
+
|
|
620
|
+
Period 2026-05-07 → 2026-05-08 (1 log file)
|
|
621
|
+
|
|
622
|
+
Reviews
|
|
623
|
+
total 6
|
|
624
|
+
successful 3
|
|
625
|
+
failed 3 (50% failure rate)
|
|
626
|
+
|
|
627
|
+
Reviewer performance
|
|
628
|
+
codex 1/4 success 25%
|
|
629
|
+
claude 2/2 success 100%
|
|
630
|
+
|
|
631
|
+
Verdict distribution
|
|
632
|
+
APPROVE 2 (67%)
|
|
633
|
+
NEEDS WORK 1 (33%)
|
|
634
|
+
BLOCK 0 (0%)
|
|
635
|
+
|
|
636
|
+
Error patterns
|
|
637
|
+
✗ command not found: tsc ×2 (codex)
|
|
638
|
+
✗ base branch missing: staging ×2
|
|
639
|
+
|
|
640
|
+
Languages detected
|
|
641
|
+
typescript, nodejs
|
|
642
|
+
|
|
643
|
+
Suggestions
|
|
644
|
+
→ tsc: command not found ×2 (codex)
|
|
645
|
+
add to workflow.yml review step instructions: "Do not run tsc, ts-node, or tsx."
|
|
646
|
+
→ base branch 'staging' not found ×2 — verify branch is fetched before review
|
|
647
|
+
|
|
648
|
+
Run `crosscheck optimize` to apply suggestions automatically.
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
| Flag | Description |
|
|
652
|
+
|---|---|
|
|
653
|
+
| `--json` | Output full report as JSON (for scripting or piping to `optimize`) |
|
|
654
|
+
| `--since <YYYY-MM-DD>` | Limit analysis to logs from this date onward |
|
|
655
|
+
|
|
656
|
+
---
|
|
657
|
+
|
|
658
|
+
### `crosscheck optimize`
|
|
659
|
+
|
|
660
|
+
Runs `diagnose` internally, selects the best available AI agent, and generates improved instructions for the review step in `~/.crosscheck/workflow.yml`. Dry-run by default — shows a diff without writing.
|
|
661
|
+
|
|
662
|
+
```bash
|
|
663
|
+
crosscheck optimize # show diff only
|
|
664
|
+
crosscheck optimize --apply # apply the changes
|
|
665
|
+
crosscheck optimize --agent codex --apply
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
```
|
|
669
|
+
Running diagnose...
|
|
670
|
+
agent claude (default — both enabled, no data)
|
|
671
|
+
|
|
672
|
+
diff /Users/you/.crosscheck/workflow.yml (review step)
|
|
673
|
+
|
|
674
|
+
+## Constraints
|
|
675
|
+
+
|
|
676
|
+
+- Do not run tsc, ts-node, or tsx.
|
|
677
|
+
+- Do not run npm, npx, yarn, or pnpm.
|
|
678
|
+
...
|
|
679
|
+
|
|
680
|
+
Run with --apply to write changes to /Users/you/.crosscheck/workflow.yml (review step)
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
**Which agent does `optimize` use?**
|
|
684
|
+
|
|
685
|
+
`optimize` picks the agent automatically based on your config and log history:
|
|
686
|
+
|
|
687
|
+
1. If only one vendor is enabled → uses that one.
|
|
688
|
+
2. If both are enabled → uses whichever has the higher success rate in recent logs.
|
|
689
|
+
3. If rates are equal or no log data → defaults to `claude`.
|
|
690
|
+
4. `--agent claude|codex` overrides all of the above.
|
|
691
|
+
|
|
692
|
+
| Flag | Description |
|
|
693
|
+
|---|---|
|
|
694
|
+
| `--apply` | Write the improved instructions to the review step in `~/.crosscheck/workflow.yml` (default is dry-run) |
|
|
695
|
+
| `--dry-run` | Show diff without writing (default behavior, explicit alias) |
|
|
696
|
+
| `--agent <claude\|codex>` | Force a specific agent regardless of config or log data |
|
|
697
|
+
| `--since <YYYY-MM-DD>` | Limit the diagnose window used as input |
|
|
698
|
+
| `-c, --config <path>` | Config file path |
|
|
699
|
+
|
|
700
|
+
---
|
|
701
|
+
|
|
702
|
+
### `crosscheck impact`
|
|
703
|
+
|
|
704
|
+
Reports cumulative value from review history: time saved, issues caught, and code quality trends. Reads from `~/.crosscheck/logs/` — no network calls.
|
|
705
|
+
|
|
706
|
+
```bash
|
|
707
|
+
crosscheck impact
|
|
708
|
+
crosscheck impact --money
|
|
709
|
+
crosscheck impact --since 2026-01-01
|
|
710
|
+
crosscheck impact --json
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
```
|
|
714
|
+
crosscheck impact (all time · 47 reviews)
|
|
715
|
+
|
|
716
|
+
Time saved
|
|
717
|
+
──────────────────────────────────────────────
|
|
718
|
+
Reviews run 47
|
|
719
|
+
Avg AI review time ~14 min
|
|
720
|
+
Assumed human time 60 min ⓘ
|
|
721
|
+
Total time saved ~43 h
|
|
722
|
+
|
|
723
|
+
Issues caught
|
|
724
|
+
──────────────────────────────────────────────
|
|
725
|
+
APPROVE 28 (60%)
|
|
726
|
+
NEEDS WORK 14 (30%) ← actionable feedback
|
|
727
|
+
BLOCK 5 (11%) ← potential bugs / breaking changes
|
|
728
|
+
Total issues caught 19
|
|
729
|
+
|
|
730
|
+
Code quality trend (BLOCK rate, weekly)
|
|
731
|
+
──────────────────────────────────────────────
|
|
732
|
+
May W1 ████████████████ 22%
|
|
733
|
+
May W2 ████████████ 17%
|
|
734
|
+
May W3 ████████ 11% ↓ improving
|
|
735
|
+
|
|
736
|
+
ⓘ assumes 60 min avg human review — set impact.assumed_human_review_minutes to adjust
|
|
737
|
+
Run crosscheck impact --money for a rough monetary estimate.
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
| Flag | Description |
|
|
741
|
+
|---|---|
|
|
742
|
+
| `--money` | Append a monetary estimate based on `impact.hourly_rate_usd` and `impact.defect_cost_usd` |
|
|
743
|
+
| `--since <YYYY-MM-DD>` | Limit the analysis to logs from this date onward |
|
|
744
|
+
| `--json` | Output the full report as JSON |
|
|
745
|
+
| `-c, --config <path>` | Config file path |
|
|
746
|
+
|
|
747
|
+
The monetary estimate formula: `(hours_saved × hourly_rate_usd) + (issues_caught × defect_cost_usd)`. Defaults: `$150/hr`, `$150/issue`. Both configurable in `crosscheck.config.yml` under `impact`.
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
### `crosscheck issue`
|
|
752
|
+
|
|
753
|
+
Reads recent error logs, uses your best-performing AI agent to draft a GitHub issue, asks three short follow-up questions, and submits to `humanbased-ai/crosscheck` after you confirm. No manual log-digging or issue writing required.
|
|
754
|
+
|
|
755
|
+
```bash
|
|
756
|
+
crosscheck issue # interactive — review draft before submitting
|
|
757
|
+
crosscheck issue --dry-run # print draft only, never submit
|
|
758
|
+
crosscheck issue --yes # submit immediately after displaying draft
|
|
759
|
+
crosscheck issue --since 2026-05-01
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
```
|
|
763
|
+
crosscheck issue
|
|
764
|
+
|
|
765
|
+
Scanning logs (last 3 days)...
|
|
766
|
+
Found error pattern: command_not_found: tsc ×4 (codex)
|
|
767
|
+
|
|
768
|
+
Can you reproduce this consistently?
|
|
769
|
+
[1] Every time [2] Sometimes [3] Happened once
|
|
770
|
+
Choice [1]: 1
|
|
771
|
+
|
|
772
|
+
Which command triggered this?
|
|
773
|
+
[1] watch [2] serve [3] review [4] Unknown
|
|
774
|
+
Choice [1]: 1
|
|
775
|
+
|
|
776
|
+
Is this blocking you?
|
|
777
|
+
[1] Blocked [2] Degraded [3] Cosmetic
|
|
778
|
+
Choice [2]: 2
|
|
779
|
+
|
|
780
|
+
Draft issue:
|
|
781
|
+
────────────────────────────────────────────────────────
|
|
782
|
+
TITLE: codex: command not found: tsc during review in temp clone
|
|
783
|
+
|
|
784
|
+
## Description
|
|
785
|
+
When crosscheck runs a Codex review, the reviewer tries to execute `tsc`
|
|
786
|
+
...
|
|
787
|
+
|
|
788
|
+
Submit to humanbased-ai/crosscheck? [y/N]: y
|
|
789
|
+
✓ https://github.com/humanbased-ai/crosscheck/issues/99
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
If no errors are found in recent logs, crosscheck prints `No errors found in recent logs — nothing to report` and exits cleanly.
|
|
793
|
+
|
|
794
|
+
| Flag | Description |
|
|
795
|
+
|---|---|
|
|
796
|
+
| `--since <YYYY-MM-DD>` | Limit log scan to this date onward (default: last 3 days) |
|
|
797
|
+
| `--dry-run` | Print the draft without submitting |
|
|
798
|
+
| `-y, --yes` | Submit immediately after displaying the draft (skip confirmation) |
|
|
799
|
+
| `-c, --config <path>` | Config file path |
|
|
800
|
+
|
|
801
|
+
---
|
|
802
|
+
|
|
803
|
+
## Customization home
|
|
804
|
+
|
|
805
|
+
`~/.crosscheck/` is the persistent home for everything crosscheck learns and configures. Back it up before a machine migration and a reinstall is instant — run `crosscheck onboard` and press Enter through each step to confirm your previous settings.
|
|
806
|
+
|
|
807
|
+
### Files in `~/.crosscheck/`
|
|
808
|
+
|
|
809
|
+
| File | Written by | Read by | Purpose |
|
|
810
|
+
|---|---|---|---|
|
|
811
|
+
| `config.yml` | `onboard`, `init`, `watch`/`serve` (first run) | all commands | Main config — deployment, repos, mode, vendors, quality, tunnel, routing, budget, branding |
|
|
812
|
+
| `workflow.yml` | `onboard` (first run only) | `watch`, `serve`, `run` | Global pipeline steps with per-step inline instructions. Written once on first onboard; never overwritten on re-runs — edit freely |
|
|
813
|
+
| `webhook-secret` | auto-generated on first use | `watch`, `serve` | HMAC secret for GitHub webhook signature verification — reused across restarts |
|
|
814
|
+
| `logs/YYYY-MM-DD.ndjson` | `watch`, `serve` | `diagnose`, `optimize`, `impact`, `issue` | Structured review event log, one file per day |
|
|
815
|
+
|
|
816
|
+
### Per-project overrides (checked before the global files)
|
|
817
|
+
|
|
818
|
+
| File | Read by | Purpose |
|
|
819
|
+
|---|---|---|
|
|
820
|
+
| `.crosscheck/workflow.yml` *(in repo)* | `watch`, `serve`, `run` | Per-project pipeline — takes priority over `~/.crosscheck/workflow.yml` |
|
|
821
|
+
| `.crosscheck/AGENT.md` *(in repo)* | `optimize` | Per-project harness — takes priority over bundled `AGENT.md` |
|
|
822
|
+
| `AGENT.md` *(bundled with crosscheck)* | `optimize` | Default harness — shipped with the package, always available as fallback |
|
|
823
|
+
|
|
824
|
+
### What `crosscheck onboard` owns vs. preserves
|
|
825
|
+
|
|
826
|
+
On re-runs, `onboard` updates only the fields it collected answers for. Everything else survives unchanged.
|
|
827
|
+
|
|
828
|
+
**Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `tunnel.*`, `post_review.auto_fix.*`
|
|
829
|
+
|
|
830
|
+
**Initialised on first run, never overwritten:** `routing.allowed_authors`, `routing.author_routes`, `routing.fallback_reviewer`
|
|
831
|
+
|
|
832
|
+
**Never touched by onboard:** `quality.focus`, `quality.custom_prompt`, `budget.*`, `branding.*`, `server.*`, `logs.*`, `backtrace.*`, `workflow.yml` (after first write), harness files
|
|
833
|
+
|
|
834
|
+
---
|
|
835
|
+
|
|
836
|
+
## Configuration
|
|
837
|
+
|
|
838
|
+
crosscheck stores its config in `~/.crosscheck/config.yml` by default — persistent across projects, no per-repo file needed. It also looks in these locations (first found wins):
|
|
839
|
+
|
|
840
|
+
1. `~/.crosscheck/config.yml` ← **default location**
|
|
841
|
+
2. `./crosscheck.config.yml`
|
|
842
|
+
3. `./.crosscheck.yml`
|
|
843
|
+
|
|
844
|
+
Run `crosscheck init` to generate `~/.crosscheck/config.yml` with all options documented.
|
|
845
|
+
|
|
846
|
+
Logs are written to `~/.crosscheck/logs/YYYY-MM-DD.ndjson` and retained for 30 days by default.
|
|
847
|
+
|
|
848
|
+
### Full reference
|
|
849
|
+
|
|
850
|
+
```yaml
|
|
851
|
+
# ── Deployment ────────────────────────────────────────────────────────────────
|
|
852
|
+
# Set automatically on first run. Re-run the prompt with: crosscheck watch --reconfigure
|
|
853
|
+
# personal — monitor your repos + orgs; review only your PRs
|
|
854
|
+
# team — monitor org repos only; review all PRs from any author
|
|
855
|
+
# deployment: personal
|
|
856
|
+
|
|
857
|
+
# ── Mode ──────────────────────────────────────────────────────────────────────
|
|
858
|
+
# single-vendor: one AI reviews all PRs
|
|
859
|
+
# cross-vendor: Claude ↔ Codex review each other
|
|
860
|
+
mode: cross-vendor
|
|
861
|
+
|
|
862
|
+
# ── Clone protocol ────────────────────────────────────────────────────────────
|
|
863
|
+
# ssh — git@github.com:owner/repo.git (uses local SSH keys)
|
|
864
|
+
# https — https://github.com/owner/repo.git (uses GitHub token)
|
|
865
|
+
# Pick https if you have multi-account SSH setup or your default SSH key
|
|
866
|
+
# cannot access target repos. Independent of `gh config get git_protocol`.
|
|
867
|
+
clone_protocol: ssh
|
|
868
|
+
|
|
869
|
+
# ── Vendors ───────────────────────────────────────────────────────────────────
|
|
870
|
+
vendors:
|
|
871
|
+
codex:
|
|
872
|
+
enabled: true
|
|
873
|
+
auth: subscription # subscription | api-key
|
|
874
|
+
model: o4-mini # only used when auth: api-key
|
|
875
|
+
|
|
876
|
+
claude:
|
|
877
|
+
enabled: true
|
|
878
|
+
model: sonnet # haiku | sonnet | opus
|
|
879
|
+
effort: medium # low | medium | high | max
|
|
880
|
+
|
|
881
|
+
# ── Quality ───────────────────────────────────────────────────────────────────
|
|
882
|
+
quality:
|
|
883
|
+
tier: balanced # fast | balanced | thorough
|
|
884
|
+
focus: # narrows review scope (optional)
|
|
885
|
+
- security
|
|
886
|
+
- types
|
|
887
|
+
- performance
|
|
888
|
+
custom_prompt: | # appended to every review prompt
|
|
889
|
+
Be concise. Flag only issues that would block a merge.
|
|
890
|
+
|
|
891
|
+
# ── Budget ────────────────────────────────────────────────────────────────────
|
|
892
|
+
budget:
|
|
893
|
+
codex_monthly_usd: 20 # null = unlimited; only applies when auth: api-key
|
|
894
|
+
per_review_usd: 2.00 # passed to claude --max-budget-usd
|
|
895
|
+
|
|
896
|
+
# ── Orgs — covers all repos in each org with one webhook ─────────────────────
|
|
897
|
+
orgs:
|
|
898
|
+
- humanbased-ai
|
|
899
|
+
- codatta
|
|
900
|
+
|
|
901
|
+
# ── Users — monitors all repos owned by personal GitHub accounts (non-org) ───
|
|
902
|
+
# At startup, crosscheck enumerates each user's repos and registers webhooks.
|
|
903
|
+
# Useful when your AI agents open PRs across many personal repos.
|
|
904
|
+
# Combines with `orgs` and `repos` — all configured sources are additive.
|
|
905
|
+
users:
|
|
906
|
+
- beingzy # your personal account
|
|
907
|
+
# - my-agent-login # a bot account that pushes to its own repos
|
|
908
|
+
|
|
909
|
+
# ── Repos — for monitoring specific repos only ────────────────────────────────
|
|
910
|
+
# Omit when using `orgs`/`users`. Auto-detected from git remote if all are empty.
|
|
911
|
+
repos:
|
|
912
|
+
- owner: acme
|
|
913
|
+
name: specific-repo
|
|
914
|
+
|
|
915
|
+
# ── Routing ───────────────────────────────────────────────────────────────────
|
|
916
|
+
routing:
|
|
917
|
+
# Origin is detected via a four-signal chain:
|
|
918
|
+
# 1. PR body patterns below (fastest)
|
|
919
|
+
# 2. Commit message Co-Authored-By: trailers (API call, non-fatal if it fails)
|
|
920
|
+
# 3. Branch prefix (claude/ or codex/)
|
|
921
|
+
# 4. author_routes fallback (last resort)
|
|
922
|
+
codex_reviews_patterns:
|
|
923
|
+
- "Generated with \\[Claude Code\\]" # Claude Code attribution footer
|
|
924
|
+
- "Co-Authored-By: Claude" # commit trailer
|
|
925
|
+
claude_reviews_patterns:
|
|
926
|
+
- "Generated with \\[OpenAI Codex\\]" # Codex attribution footer
|
|
927
|
+
- "Co-Authored-By: codex" # commit trailer
|
|
928
|
+
|
|
929
|
+
# Branch prefix detection (signal 3). Claude Code uses claude/, Codex uses codex/.
|
|
930
|
+
claude_branch_prefixes:
|
|
931
|
+
- "claude/"
|
|
932
|
+
codex_branch_prefixes:
|
|
933
|
+
- "codex/"
|
|
934
|
+
|
|
935
|
+
# Restrict reviews to PRs opened by these GitHub logins.
|
|
936
|
+
# Auto-filled with your GitHub login by `crosscheck init` or first `crosscheck watch`.
|
|
937
|
+
# Empty = no restriction (all matching PRs reviewed).
|
|
938
|
+
allowed_authors:
|
|
939
|
+
- your-github-login # auto-detected from gh auth
|
|
940
|
+
|
|
941
|
+
# Author-based routing fallback (signal 4) — used when no pattern or prefix matches.
|
|
942
|
+
# Maps GitHub login → vendor origin so crosscheck routes PRs even without
|
|
943
|
+
# the attribution footer (e.g. when creating PRs via gh CLI directly).
|
|
944
|
+
author_routes:
|
|
945
|
+
your-github-login: claude # your PRs → treated as Claude-authored → Codex reviews
|
|
946
|
+
|
|
947
|
+
# ── Tunnel (watch mode only) ──────────────────────────────────────────────────
|
|
948
|
+
# localhost.run (default) — SSH tunnel, zero install, URL changes on reconnect.
|
|
949
|
+
# smee — stable relay via smee.io; events queued while offline.
|
|
950
|
+
# Setup: npm install -g smee-client, visit https://smee.io/new
|
|
951
|
+
tunnel:
|
|
952
|
+
backend: localhost.run
|
|
953
|
+
# backend: smee
|
|
954
|
+
# smee_channel: https://smee.io/your-channel-id
|
|
955
|
+
|
|
956
|
+
# ── Impact reporting ──────────────────────────────────────────────────────────
|
|
957
|
+
# Used by `crosscheck impact` to calculate estimated time and monetary value.
|
|
958
|
+
impact:
|
|
959
|
+
assumed_human_review_minutes: 60 # baseline for time-saved calculation
|
|
960
|
+
hourly_rate_usd: 150 # for --money estimate
|
|
961
|
+
defect_cost_usd: 150 # per issue caught, for --money estimate
|
|
962
|
+
|
|
963
|
+
# ── Post-review auto-fix ──────────────────────────────────────────────────────
|
|
964
|
+
# Controls HOW fixes are delivered. Step sequencing (which steps run, when,
|
|
965
|
+
# and with which vendor) is configured in ~/.crosscheck/workflow.yml.
|
|
966
|
+
post_review:
|
|
967
|
+
auto_fix:
|
|
968
|
+
delivery:
|
|
969
|
+
mode: pull_request # pull_request | commit | comment
|
|
970
|
+
# pull_request → fix PR targets original branch; human approves before merge
|
|
971
|
+
# commit → fixes pushed directly onto the original PR branch
|
|
972
|
+
# comment → suggested fixes posted as review comments only
|
|
973
|
+
pr_title: "fix: address CR issues in #{original_pr_title}"
|
|
974
|
+
label: cr-autofix # GitHub label applied to the fix PR
|
|
975
|
+
|
|
976
|
+
# ── Backtrace ─────────────────────────────────────────────────────────────────
|
|
977
|
+
# On startup, scan all open PRs in the monitored scope and review any that
|
|
978
|
+
# haven't received a [crosscheck] comment yet. Off by default.
|
|
979
|
+
# Enable with:
|
|
980
|
+
# backtrace.enabled: true (persistent — runs every startup)
|
|
981
|
+
# --backtrace flag (this session only)
|
|
982
|
+
# --no-backtrace flag (suppress even when enabled: true)
|
|
983
|
+
# backtrace:
|
|
984
|
+
# enabled: true
|
|
985
|
+
|
|
986
|
+
# ── Server ────────────────────────────────────────────────────────────────────
|
|
987
|
+
server:
|
|
988
|
+
port: 7891
|
|
989
|
+
webhook_path: /webhook
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
### Quality tiers
|
|
993
|
+
|
|
994
|
+
| Tier | Speed | Depth | Best for |
|
|
995
|
+
|---|---|---|---|
|
|
996
|
+
| `fast` | ~10s | Top issues only | High-volume repos, draft PRs |
|
|
997
|
+
| `balanced` | ~30s | Full review, all issues explained | Default for most teams |
|
|
998
|
+
| `thorough` | ~60–90s | Deep multi-pass, architecture + security | Before merging to main |
|
|
999
|
+
|
|
1000
|
+
### Routing patterns
|
|
1001
|
+
|
|
1002
|
+
Patterns are matched against the PR body as case-insensitive regular expressions.
|
|
1003
|
+
|
|
1004
|
+
- `codex_reviews_patterns` — PRs matching these are reviewed by Codex
|
|
1005
|
+
- `claude_reviews_patterns` — PRs matching these are reviewed by Claude
|
|
1006
|
+
|
|
1007
|
+
To also review human PRs, add a catch-all:
|
|
1008
|
+
|
|
1009
|
+
```yaml
|
|
1010
|
+
routing:
|
|
1011
|
+
codex_reviews_patterns:
|
|
1012
|
+
- "Generated with \\[Claude Code\\]"
|
|
1013
|
+
- ".*" # Codex reviews all PRs
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
### Minimal config
|
|
1017
|
+
|
|
1018
|
+
```yaml
|
|
1019
|
+
mode: cross-vendor
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
Everything else uses defaults.
|
|
1023
|
+
|
|
1024
|
+
---
|
|
1025
|
+
|
|
1026
|
+
## How it works
|
|
1027
|
+
|
|
1028
|
+
```
|
|
1029
|
+
GitHub repo
|
|
1030
|
+
│ pull_request event (opened / synchronize)
|
|
1031
|
+
▼
|
|
1032
|
+
crosscheck webhook server
|
|
1033
|
+
│
|
|
1034
|
+
├─ verify HMAC-SHA256 signature
|
|
1035
|
+
├─ detect PR origin from body patterns
|
|
1036
|
+
├─ assign reviewer (opposite vendor in cross-vendor mode)
|
|
1037
|
+
│
|
|
1038
|
+
▼
|
|
1039
|
+
clone PR branch into temp directory
|
|
1040
|
+
│
|
|
1041
|
+
├─ codex review --base <branch> ← non-interactive Codex review
|
|
1042
|
+
│ or
|
|
1043
|
+
└─ claude --print --bare ... ← non-interactive Claude review
|
|
1044
|
+
│
|
|
1045
|
+
▼
|
|
1046
|
+
post comment to PR via GitHub API
|
|
1047
|
+
delete temp clone
|
|
1048
|
+
│
|
|
1049
|
+
▼ post_review.auto_fix (if enabled and issues found)
|
|
1050
|
+
authoring vendor reads review comment
|
|
1051
|
+
│
|
|
1052
|
+
├─ claude --print ... (Claude authored the PR)
|
|
1053
|
+
│ or
|
|
1054
|
+
└─ codex ... (Codex authored the PR)
|
|
1055
|
+
│
|
|
1056
|
+
▼
|
|
1057
|
+
opens fix PR → fix/cr-<pr-number>-review-issues → original branch
|
|
1058
|
+
(you review and merge the fix PR; original PR updates automatically)
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
### PR origin detection
|
|
1062
|
+
|
|
1063
|
+
crosscheck uses a four-signal chain to determine whether a PR was authored by Claude Code, Codex, or a human:
|
|
1064
|
+
|
|
1065
|
+
1. **PR body** — looks for attribution footers (e.g. `Generated with [Claude Code]`)
|
|
1066
|
+
2. **Commit messages** — scans all commit messages for `Co-Authored-By:` trailers
|
|
1067
|
+
3. **Branch prefix** — `claude/` → Claude origin; `codex/` → Codex origin
|
|
1068
|
+
4. **`author_routes`** — per-login fallback in config
|
|
1069
|
+
|
|
1070
|
+
If none match, origin is `human` and the PR is skipped in cross-vendor mode.
|
|
1071
|
+
|
|
1072
|
+
| Default pattern | Matches |
|
|
1073
|
+
|---|---|
|
|
1074
|
+
| `Generated with \[Claude Code\]` | Claude Code attribution footer in PR body |
|
|
1075
|
+
| `Generated with \[OpenAI Codex\]` | Codex attribution footer in PR body |
|
|
1076
|
+
| `Co-Authored-By: Claude` | Commit trailers from Claude Code |
|
|
1077
|
+
| `Co-Authored-By: codex` | Commit trailers from Codex |
|
|
1078
|
+
| branch prefix `claude/` | Branch naming convention for Claude-authored PRs |
|
|
1079
|
+
| branch prefix `codex/` | Branch naming convention for Codex-authored PRs |
|
|
1080
|
+
|
|
1081
|
+
### Reviewer assignment
|
|
1082
|
+
|
|
1083
|
+
| Mode | PR origin | Reviewer |
|
|
1084
|
+
|---|---|---|
|
|
1085
|
+
| `cross-vendor` | claude | Codex |
|
|
1086
|
+
| `cross-vendor` | codex | Claude |
|
|
1087
|
+
| `cross-vendor` | human | None — skipped |
|
|
1088
|
+
| `single-vendor` | any | First enabled vendor |
|
|
1089
|
+
|
|
1090
|
+
### How Codex reviews run
|
|
1091
|
+
|
|
1092
|
+
```bash
|
|
1093
|
+
codex review --base <base-branch> --title "<pr-title>"
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
The `--base` flag diffs current HEAD against the base branch — exactly the PR diff. With `auth: subscription`, no model flag is passed. With `auth: api-key`, the model is selected by quality tier (`fast` → `gpt-4o-mini`, `balanced` → `o4-mini`, `thorough` → `o3`).
|
|
1097
|
+
|
|
1098
|
+
### How Claude reviews run
|
|
1099
|
+
|
|
1100
|
+
```bash
|
|
1101
|
+
claude \
|
|
1102
|
+
--print --bare \
|
|
1103
|
+
--model claude-sonnet-4-6 \
|
|
1104
|
+
--effort medium \
|
|
1105
|
+
--max-budget-usd 2.00 \
|
|
1106
|
+
--output-last-message /tmp/review.md \
|
|
1107
|
+
--allowedTools "Bash(git diff),Bash(git log)" \
|
|
1108
|
+
"<prompt>"
|
|
1109
|
+
```
|
|
1110
|
+
|
|
1111
|
+
`--bare` makes execution fast and deterministic. `--allowedTools` limits Claude to read-only git operations on the cloned repo.
|
|
1112
|
+
|
|
1113
|
+
### Deduplication
|
|
1114
|
+
|
|
1115
|
+
**What's implemented today**
|
|
1116
|
+
|
|
1117
|
+
GitHub can fire both `opened` and `synchronize` events for the same push. crosscheck tracks `owner/repo#pr@sha` in an in-memory set and drops duplicate events for the same commit within the same running process.
|
|
1118
|
+
|
|
1119
|
+
**Known gap — concurrent sessions**
|
|
1120
|
+
|
|
1121
|
+
If `crosscheck run <pr-url>` is invoked while a `watch`/`serve` daemon is already reviewing the same PR (or two machines pick up the same webhook), both sessions will pass the current check — which only looks at already-posted comments — and both will post a review. This is a known race condition.
|
|
1122
|
+
|
|
1123
|
+
The fix (file lock for same-machine + GitHub commit status for cross-machine) is tracked as a P0 item and not yet implemented. Until it lands, avoid running `crosscheck run` manually on a PR that your `watch`/`serve` daemon is actively processing.
|
|
1124
|
+
|
|
1125
|
+
### Watch vs serve
|
|
1126
|
+
|
|
1127
|
+
| | `watch` | `serve` [BETA] |
|
|
1128
|
+
|---|---|---|
|
|
1129
|
+
| Tunnel | `localhost.run` via SSH (no install) | None — direct port |
|
|
1130
|
+
| Webhook | Auto-managed, cleaned up on exit | Manual, permanent |
|
|
1131
|
+
| Scope | Org-level or repo-level | Org-level or repo-level |
|
|
1132
|
+
| Machine | Developer laptop | mac-mini / server |
|
|
1133
|
+
| Lifecycle | Tied to terminal | Daemon / service |
|
|
1134
|
+
|
|
1135
|
+
### Security
|
|
1136
|
+
|
|
1137
|
+
- **Webhook signature** — every request verified with HMAC-SHA256 before parsing
|
|
1138
|
+
- **Temp isolation** — each PR cloned into a fresh temp dir, deleted after review
|
|
1139
|
+
- **Read-only tools** — Claude restricted to `git diff` and `git log` only
|
|
1140
|
+
- **Temp credential isolation** — with `clone_protocol: ssh` (default) no tokens touch disk; with `clone_protocol: https` a short-lived token is embedded in the temp clone's remote URL and removed when the temp dir is deleted after review
|
|
1141
|
+
|
|
1142
|
+
---
|
|
1143
|
+
|
|
1144
|
+
## Post-review auto-fix
|
|
1145
|
+
|
|
1146
|
+
When `post_review.auto_fix.enabled` is `true` (the default), crosscheck completes the full loop automatically after every review that finds issues:
|
|
1147
|
+
|
|
1148
|
+
```
|
|
1149
|
+
agent opens PR #42 → opposite vendor reviews → issues found?
|
|
1150
|
+
│ yes
|
|
1151
|
+
authoring vendor generates fixes
|
|
1152
|
+
│
|
|
1153
|
+
fix PR #43 opened → feat/my-feature
|
|
1154
|
+
│
|
|
1155
|
+
you review and merge PR #43
|
|
1156
|
+
│
|
|
1157
|
+
PR #42 updates → you merge to main
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
**Key design decisions:**
|
|
1161
|
+
|
|
1162
|
+
| Setting | Default | Why |
|
|
1163
|
+
|---|---|---|
|
|
1164
|
+
| `fixer: same-as-author` | the vendor that wrote the PR also fixes it | The authoring agent knows its own code and style best |
|
|
1165
|
+
| `delivery: pull_request` | opens a new PR, doesn't push directly | You stay in the loop — no code lands without your approval |
|
|
1166
|
+
| `trigger: on_issues` | only fires when the reviewer found warnings or worse | Skips the fix step on clean PRs |
|
|
1167
|
+
| `min_severity: warning` | ignores info/cosmetic findings | Avoids noisy fix PRs for style-only comments |
|
|
1168
|
+
|
|
1169
|
+
**Fix PR branch naming:** `fix/cr-<original-pr-number>-review-issues`
|
|
1170
|
+
|
|
1171
|
+
**Original PR number:** never changes. The fix PR targets the original branch; once merged, its commits appear in the original PR automatically.
|
|
1172
|
+
|
|
1173
|
+
**To disable:** set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`.
|
|
1174
|
+
|
|
1175
|
+
---
|
|
1176
|
+
|
|
1177
|
+
## FAQ
|
|
1178
|
+
|
|
1179
|
+
### How does crosscheck improve over time?
|
|
1180
|
+
|
|
1181
|
+
Every review — success or failure — is appended to `~/.crosscheck/logs/YYYY-MM-DD.ndjson`. Running `crosscheck diagnose` reads those logs and surfaces patterns: which commands failed, which reviewer is struggling, which language-specific tools were missing. Running `crosscheck optimize` feeds that report into your best-performing AI agent (guided by the bundled `AGENT.md`) and updates the `instructions` field of the review step in `~/.crosscheck/workflow.yml`. The improvements take effect immediately on the next PR.
|
|
1182
|
+
|
|
1183
|
+
### Which agent does `crosscheck optimize` use?
|
|
1184
|
+
|
|
1185
|
+
It picks automatically:
|
|
1186
|
+
1. If only one vendor is enabled in your config → uses that one.
|
|
1187
|
+
2. Both enabled → whichever has the higher success rate in recent logs.
|
|
1188
|
+
3. Equal rates or no data → defaults to `claude`.
|
|
1189
|
+
4. You can always override: `crosscheck optimize --agent codex`.
|
|
1190
|
+
|
|
1191
|
+
The agent used for `optimize` is independent of which agent reviews your PRs — `optimize` is about improving the instructions, not reviewing code.
|
|
1192
|
+
|
|
1193
|
+
### How do I customize reviewer behavior?
|
|
1194
|
+
|
|
1195
|
+
The primary place is the workflow file. Each step has an `instructions` field that is passed verbatim to the reviewer or fixer agent:
|
|
1196
|
+
|
|
1197
|
+
```yaml
|
|
1198
|
+
# .crosscheck/workflow.yml
|
|
1199
|
+
steps:
|
|
1200
|
+
- name: review
|
|
1201
|
+
type: review
|
|
1202
|
+
reviewer: auto
|
|
1203
|
+
instructions: |
|
|
1204
|
+
Do not suggest TypeScript patterns — this is a Rust project.
|
|
1205
|
+
Focus on memory safety and error handling.
|
|
1206
|
+
## Verdict
|
|
1207
|
+
End with: VERDICT: APPROVE | NEEDS_WORK | BLOCK
|
|
1208
|
+
- name: fix
|
|
1209
|
+
type: fix
|
|
1210
|
+
reviewer: origin
|
|
1211
|
+
when: "review.verdict != 'APPROVE'"
|
|
1212
|
+
instructions: "Only fix issues explicitly called out. Do not refactor unrelated code."
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
`crosscheck optimize --apply` updates the review step's `instructions` field in `~/.crosscheck/workflow.yml` to persist learned improvements across sessions.
|
|
1216
|
+
|
|
1217
|
+
To reset the review step instructions to defaults, delete `~/.crosscheck/workflow.yml` and re-run `crosscheck onboard` — it will regenerate the file with the built-in defaults.
|
|
1218
|
+
|
|
1219
|
+
### Can I have per-project workflow?
|
|
1220
|
+
|
|
1221
|
+
Yes. Create `.crosscheck/workflow.yml` in your repo root. crosscheck loads it automatically and uses it instead of the built-in default pipeline. This is the recommended way to customize reviewer behavior — it keeps all per-project settings in one file under version control.
|
|
1222
|
+
|
|
1223
|
+
### What is `AGENT.md`?
|
|
1224
|
+
|
|
1225
|
+
`AGENT.md` is the harness document that guides the AI during `crosscheck optimize`. It defines the input/output contract, language-detection rules, constraint-writing guidelines, and quality principles. It ships bundled with crosscheck so `optimize` works out of the box.
|
|
1226
|
+
|
|
1227
|
+
You can override it by placing an `AGENT.md` at your project root or `.crosscheck/AGENT.md`. crosscheck checks for a local override first, then falls back to the bundled version. This lets teams customize the optimization logic for their specific stack or conventions.
|
|
1228
|
+
|
|
1229
|
+
### Why did my review fail with "command not found"?
|
|
1230
|
+
|
|
1231
|
+
The reviewer (codex or claude) tried to run a CLI tool (e.g. `tsc`, `pytest`) that isn't available in the temporary clone. The clone is a shallow `git` checkout with no `node_modules` or other installed dependencies. Run `crosscheck diagnose` to see which commands failed, then `crosscheck optimize --apply` to add the appropriate constraints to the review step in `~/.crosscheck/workflow.yml` so the reviewer stops trying.
|
|
1232
|
+
|
|
1233
|
+
### Why did my review fail with "no such branch"?
|
|
1234
|
+
|
|
1235
|
+
crosscheck fetches the PR base branch (e.g. `staging`) into the temp clone before running the reviewer. If that fetch fails (network issue, branch deleted, insufficient token scope), the reviewer cannot diff correctly. Check:
|
|
1236
|
+
- The base branch exists and is accessible with your token.
|
|
1237
|
+
- Your `GITHUB_TOKEN` has `repo` scope.
|
|
1238
|
+
- The branch name in the PR matches what's on the remote.
|
|
1239
|
+
|
|
1240
|
+
### How do I use smee.io instead of localhost.run?
|
|
1241
|
+
|
|
1242
|
+
`localhost.run` (the default) drops events if your laptop is offline when GitHub fires the webhook. [smee.io](https://smee.io) queues events and replays them when your laptop reconnects — useful when the reviewer machine isn't always on.
|
|
1243
|
+
|
|
1244
|
+
```bash
|
|
1245
|
+
npm install -g smee-client
|
|
1246
|
+
```
|
|
1247
|
+
|
|
1248
|
+
Visit [smee.io/new](https://smee.io/new) and copy the channel URL. Then in `~/.crosscheck/config.yml`:
|
|
1249
|
+
|
|
1250
|
+
```yaml
|
|
1251
|
+
tunnel:
|
|
1252
|
+
backend: smee
|
|
1253
|
+
smee_channel: https://smee.io/your-channel-id
|
|
1254
|
+
```
|
|
1255
|
+
|
|
1256
|
+
crosscheck registers the smee channel URL as your GitHub webhook automatically on first `watch` start. The channel URL never changes, so no re-registration is needed on restart. Unlike `localhost.run`, events are queued while you're offline and replayed when you reconnect.
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
### Can I disable the auto-fix step?
|
|
1260
|
+
|
|
1261
|
+
Yes. Set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`. You can also raise `min_severity` to `error` to limit fixes to blocking issues only.
|
|
1262
|
+
|
|
1263
|
+
To push fixes directly without a separate PR (skipping your review), switch to `delivery: commit`. To get suggested fixes as review comments without any code push, use `delivery: comment`.
|
|
1264
|
+
|
|
1265
|
+
### Why does the fixer use the same vendor that wrote the PR?
|
|
1266
|
+
|
|
1267
|
+
The authoring agent has the most context about its own code — the same style, constraints, and intent behind the original changes. Using `fixer: same-as-author` keeps the feedback loop tight: the agent writes the code, another agent reviews it, the original agent fixes it. You can override this to `same-as-reviewer`, `codex`, or `claude` if you prefer a different arrangement.
|
|
1268
|
+
|
|
1269
|
+
### Does optimize run automatically?
|
|
1270
|
+
|
|
1271
|
+
No — `crosscheck optimize` is always user-triggered. You run it when you want to improve instructions. There is no background daemon or scheduled job. A future version may add an optional `--schedule` mode, but the default will always be manual to keep you in control of what gets written to `~/.crosscheck/workflow.yml`.
|