@motivation-labs/crosscheck 0.4.0 → 0.4.1-beta.1216e4e.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.
Files changed (90) hide show
  1. package/README.md +26 -9
  2. package/crosscheck.config.example.yml +98 -5
  3. package/dist/__tests__/backtrace.test.d.ts +2 -0
  4. package/dist/__tests__/backtrace.test.d.ts.map +1 -0
  5. package/dist/__tests__/backtrace.test.js +158 -0
  6. package/dist/__tests__/backtrace.test.js.map +1 -0
  7. package/dist/__tests__/loader.test.d.ts +2 -0
  8. package/dist/__tests__/loader.test.d.ts.map +1 -0
  9. package/dist/__tests__/loader.test.js +131 -0
  10. package/dist/__tests__/loader.test.js.map +1 -0
  11. package/dist/__tests__/optimize.test.js +16 -3
  12. package/dist/__tests__/optimize.test.js.map +1 -1
  13. package/dist/ck.d.ts +3 -0
  14. package/dist/ck.d.ts.map +1 -0
  15. package/dist/ck.js +8 -0
  16. package/dist/ck.js.map +1 -0
  17. package/dist/cli.js +12 -4
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/diagnose.d.ts +1 -0
  20. package/dist/commands/diagnose.d.ts.map +1 -1
  21. package/dist/commands/diagnose.js +14 -0
  22. package/dist/commands/diagnose.js.map +1 -1
  23. package/dist/commands/init.d.ts.map +1 -1
  24. package/dist/commands/init.js +63 -29
  25. package/dist/commands/init.js.map +1 -1
  26. package/dist/commands/review.d.ts.map +1 -1
  27. package/dist/commands/review.js +12 -6
  28. package/dist/commands/review.js.map +1 -1
  29. package/dist/commands/serve.d.ts +7 -1
  30. package/dist/commands/serve.d.ts.map +1 -1
  31. package/dist/commands/serve.js +152 -34
  32. package/dist/commands/serve.js.map +1 -1
  33. package/dist/commands/status.d.ts.map +1 -1
  34. package/dist/commands/status.js +1 -0
  35. package/dist/commands/status.js.map +1 -1
  36. package/dist/commands/watch.d.ts +7 -1
  37. package/dist/commands/watch.d.ts.map +1 -1
  38. package/dist/commands/watch.js +348 -135
  39. package/dist/commands/watch.js.map +1 -1
  40. package/dist/config/loader.d.ts +10 -0
  41. package/dist/config/loader.d.ts.map +1 -1
  42. package/dist/config/loader.js +196 -0
  43. package/dist/config/loader.js.map +1 -1
  44. package/dist/config/schema.d.ts +461 -35
  45. package/dist/config/schema.d.ts.map +1 -1
  46. package/dist/config/schema.js +72 -5
  47. package/dist/config/schema.js.map +1 -1
  48. package/dist/github/client.d.ts +26 -0
  49. package/dist/github/client.d.ts.map +1 -1
  50. package/dist/github/client.js +159 -2
  51. package/dist/github/client.js.map +1 -1
  52. package/dist/github/detector.d.ts +9 -2
  53. package/dist/github/detector.d.ts.map +1 -1
  54. package/dist/github/detector.js +86 -10
  55. package/dist/github/detector.js.map +1 -1
  56. package/dist/lib/backtrace.d.ts +20 -0
  57. package/dist/lib/backtrace.d.ts.map +1 -0
  58. package/dist/lib/backtrace.js +75 -0
  59. package/dist/lib/backtrace.js.map +1 -0
  60. package/dist/lib/board.d.ts +54 -0
  61. package/dist/lib/board.d.ts.map +1 -0
  62. package/dist/lib/board.js +406 -0
  63. package/dist/lib/board.js.map +1 -0
  64. package/dist/lib/runner.d.ts +10 -1
  65. package/dist/lib/runner.d.ts.map +1 -1
  66. package/dist/lib/runner.js +129 -51
  67. package/dist/lib/runner.js.map +1 -1
  68. package/dist/lib/verdict.d.ts +1 -0
  69. package/dist/lib/verdict.d.ts.map +1 -1
  70. package/dist/lib/verdict.js +27 -7
  71. package/dist/lib/verdict.js.map +1 -1
  72. package/dist/lib/workflow.d.ts +14 -14
  73. package/dist/lib/workflow.d.ts.map +1 -1
  74. package/dist/lib/workflow.js +22 -5
  75. package/dist/lib/workflow.js.map +1 -1
  76. package/dist/reviewers/claude.d.ts +1 -1
  77. package/dist/reviewers/claude.d.ts.map +1 -1
  78. package/dist/reviewers/claude.js +4 -6
  79. package/dist/reviewers/claude.js.map +1 -1
  80. package/dist/reviewers/codex.d.ts +2 -2
  81. package/dist/reviewers/codex.d.ts.map +1 -1
  82. package/dist/reviewers/codex.js +6 -6
  83. package/dist/reviewers/codex.js.map +1 -1
  84. package/dist/reviewers/fix.d.ts +5 -0
  85. package/dist/reviewers/fix.d.ts.map +1 -0
  86. package/dist/reviewers/fix.js +87 -0
  87. package/dist/reviewers/fix.js.map +1 -0
  88. package/get-started.md +202 -23
  89. package/get-started.zh.md +2 -3
  90. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AA+BxD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,GAAE,cAAc,GAAG,SAA0B,EACrD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ/E"}
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AA+B3E,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,iBAAiB,EACzB,gBAAgB,CAAC,EAAE,MAAM,EACzB,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ/E"}
@@ -27,10 +27,10 @@ const TIER_TIMEOUT_MS = {
27
27
  balanced: 600_000,
28
28
  thorough: 1_200_000,
29
29
  };
30
- export async function runCodexReview(repoDir, baseBranch, prTitle, quality, overrideModel, authMode = 'subscription', onLog) {
30
+ export async function runCodexReview(repoDir, baseBranch, prTitle, quality, vendor, stepInstructions, onLog) {
31
31
  // subscription auth has a fixed model set by ChatGPT plan; only override for api-key
32
- const model = authMode === 'api-key'
33
- ? (overrideModel ?? TIER_MODELS_API[quality.tier] ?? 'o4-mini')
32
+ const model = vendor.auth === 'api-key'
33
+ ? (vendor.model ?? TIER_MODELS_API[quality.tier] ?? 'o4-mini')
34
34
  : undefined;
35
35
  const tmpFile = join(mkdtempSync(join(tmpdir(), 'crosscheck-')), 'review.md');
36
36
  // --base and [PROMPT] are mutually exclusive in codex review;
@@ -39,9 +39,9 @@ export async function runCodexReview(repoDir, baseBranch, prTitle, quality, over
39
39
  ? `Focus areas: ${quality.focus.join(', ')}. `
40
40
  : '';
41
41
  const customNote = quality.custom_prompt ?? '';
42
- // Adaptive instructions from ~/.crosscheck/instructions.md (managed by `crosscheck optimize`)
43
- const adaptiveInstructions = readInstructions(repoDir);
44
- const instructionsNote = [focusNote, customNote, adaptiveInstructions].filter(Boolean).join('\n\n');
42
+ // stepInstructions from workflow step takes precedence; fall back to ~/.crosscheck/instructions.md
43
+ const behaviorInstructions = stepInstructions !== undefined ? stepInstructions : readInstructions(repoDir);
44
+ const instructionsNote = [focusNote, customNote, behaviorInstructions].filter(Boolean).join('\n\n');
45
45
  mkdirSync(`${repoDir}/.codex`, { recursive: true });
46
46
  writeFileSync(`${repoDir}/.codex/instructions`, instructionsNote);
47
47
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/reviewers/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Config } from '../config/schema.js';
2
+ export declare function runFixStep(tmpDir: string, baseRef: string, prTitle: string, reviewComment: string, instructions: string, config: Config): Promise<{
3
+ appliedCount: number;
4
+ }>;
5
+ //# sourceMappingURL=fix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAgCjD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAqDnC"}
@@ -0,0 +1,87 @@
1
+ import { execSync, execFileSync } from 'child_process';
2
+ import { writeFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ const PROMPT_TEMPLATE = `You opened a pull request that received the following code review.
5
+
6
+ PR title: {PR_TITLE}
7
+
8
+ Code review comment:
9
+ ---
10
+ {REVIEW_COMMENT}
11
+ ---
12
+
13
+ Diff of your changes (base..head):
14
+ ---
15
+ {DIFF}
16
+ ---
17
+
18
+ {EXTRA_INSTRUCTIONS}
19
+
20
+ Please address the issues raised in the review. Rules:
21
+ - Only fix what the review explicitly calls out
22
+ - Do not refactor unrelated code, rename variables, or add tests unless asked
23
+ - If a comment requires deeper understanding of business logic, skip it
24
+ - If the review has no actionable code changes, output exactly: NO_CHANGES
25
+
26
+ For each file you need to change, output the complete new file content using this format:
27
+
28
+ <file path="relative/path/to/file.ext">
29
+ [complete file content]
30
+ </file>
31
+
32
+ Output ONLY <file> blocks or NO_CHANGES. No other text.`;
33
+ export async function runFixStep(tmpDir, baseRef, prTitle, reviewComment, instructions, config) {
34
+ let diff = '';
35
+ try {
36
+ diff = execSync(`git diff origin/${baseRef}...HEAD`, { cwd: tmpDir, encoding: 'utf8' });
37
+ }
38
+ catch {
39
+ try {
40
+ diff = execSync('git diff HEAD~1', { cwd: tmpDir, encoding: 'utf8' });
41
+ }
42
+ catch { /* proceed with empty diff */ }
43
+ }
44
+ const prompt = PROMPT_TEMPLATE
45
+ .replace('{PR_TITLE}', prTitle)
46
+ .replace('{REVIEW_COMMENT}', reviewComment.slice(0, 8000))
47
+ .replace('{DIFF}', diff.slice(0, 16000))
48
+ .replace('{EXTRA_INSTRUCTIONS}', instructions ? `Additional instructions: ${instructions}` : '');
49
+ let output = '';
50
+ try {
51
+ // Pass prompt via stdin — same pattern as optimize.ts
52
+ output = execFileSync('claude', ['--print', '--output-format', 'text'], {
53
+ input: prompt,
54
+ encoding: 'utf8',
55
+ timeout: 180_000,
56
+ env: { ...process.env },
57
+ maxBuffer: 10 * 1024 * 1024,
58
+ }).trim();
59
+ }
60
+ catch (err) {
61
+ const msg = err instanceof Error ? err.message : String(err);
62
+ if (/not logged in|auth|credential/i.test(msg)) {
63
+ throw new Error('claude auth failure during fix step — run: claude auth login');
64
+ }
65
+ throw err;
66
+ }
67
+ if (!output || output === 'NO_CHANGES')
68
+ return { appliedCount: 0 };
69
+ // Parse <file path="...">content</file> blocks
70
+ const fileRegex = /<file path="([^"]+)">([\s\S]*?)<\/file>/g;
71
+ let match;
72
+ let appliedCount = 0;
73
+ while ((match = fileRegex.exec(output)) !== null) {
74
+ const [, filePath, rawContent] = match;
75
+ // Reject paths that escape the repo (e.g. ../../etc/passwd)
76
+ if (filePath.includes('..') || filePath.startsWith('/'))
77
+ continue;
78
+ const absPath = join(tmpDir, filePath);
79
+ try {
80
+ writeFileSync(absPath, rawContent.replace(/^\n/, ''));
81
+ appliedCount++;
82
+ }
83
+ catch { /* skip unwritable paths */ }
84
+ }
85
+ return { appliedCount };
86
+ }
87
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"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"}
package/get-started.md CHANGED
@@ -24,6 +24,7 @@
24
24
  - [impact](#crosscheck-impact)
25
25
  - [Configuration](#configuration)
26
26
  - [How it works](#how-it-works)
27
+ - [Post-review auto-fix](#post-review-auto-fix)
27
28
  - [FAQ](#faq)
28
29
 
29
30
  ---
@@ -145,7 +146,7 @@ export CROSSCHECK_WEBHOOK_SECRET=your-secret
145
146
  crosscheck init
146
147
  ```
147
148
 
148
- This scans your machine, reports the status of every dependency, and writes a starter `crosscheck.config.yml` to the current directory.
149
+ This scans your machine, reports the status of every dependency, writes a starter `crosscheck.config.yml`, and auto-fills `routing.allowed_authors` with your GitHub login.
149
150
 
150
151
  ```
151
152
  crosscheck — environment check
@@ -155,8 +156,12 @@ crosscheck — environment check
155
156
  ✓ gh CLI gh version 2.65.0
156
157
  ✓ GITHUB_TOKEN set (gh auth login)
157
158
  ✓ WEBHOOK_SECRET auto-managed at ~/.crosscheck/webhook-secret
159
+
160
+ ✓ allowed_authors set to beingzy (github)
158
161
  ```
159
162
 
163
+ `allowed_authors` is detected from `gh auth login` — crosscheck will only review PRs you open, which is the right default when you're the one running the AI agents. If you run `crosscheck watch` before running `init`, the same detection runs automatically on first launch.
164
+
160
165
  Fix any failures before continuing.
161
166
 
162
167
  ---
@@ -181,6 +186,43 @@ crosscheck review https://github.com/owner/repo/pull/123 --reviewer claude
181
186
 
182
187
  ## Step 3 — Choose a deployment mode
183
188
 
189
+ ### Personal vs team
190
+
191
+ On first run, `crosscheck watch` (or `crosscheck serve`) will ask how you're using it:
192
+
193
+ ```
194
+ How are you using crosscheck?
195
+
196
+ [1] personal — monitor all your repos and orgs; review only PRs you author
197
+ [2] team — monitor org repos only; review all PRs from any author
198
+
199
+ Choice [1]:
200
+ ```
201
+
202
+ The choice is saved to `crosscheck.config.yml` as `deployment: personal` or `deployment: team`.
203
+
204
+ **Personal mode** (default, recommended for individuals)
205
+ - Monitors all repos under your personal GitHub account + all orgs you belong to
206
+ - Only reviews PRs you authored — ignores everyone else's
207
+ - Sets `routing.allowed_authors` to your GitHub login automatically
208
+
209
+ **Team mode** (recommended for shared machines)
210
+ - Monitors all orgs you belong to (no personal repos)
211
+ - Reviews all PRs from any author — no author filter applied
212
+
213
+ You can override the saved choice for a single session without touching the config:
214
+
215
+ ```bash
216
+ crosscheck watch --personal # personal mode this session only
217
+ crosscheck watch --team # team mode this session only
218
+ ```
219
+
220
+ To re-run the prompt and permanently change your choice:
221
+
222
+ ```bash
223
+ crosscheck watch --reconfigure
224
+ ```
225
+
184
226
  ### Watch mode — for your development machine
185
227
 
186
228
  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.
@@ -557,17 +599,25 @@ The monetary estimate formula: `(hours_saved × hourly_rate_usd) + (issues_caugh
557
599
 
558
600
  ## Configuration
559
601
 
560
- crosscheck looks for a config file in these locations (first found wins):
602
+ 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):
561
603
 
562
604
  1. `./crosscheck.config.yml`
563
605
  2. `./.crosscheck.yml`
564
- 3. `~/.crosscheck/config.yml`
606
+ 3. `~/.crosscheck/config.yml` ← **default location**
607
+
608
+ Run `crosscheck init` to generate `~/.crosscheck/config.yml` with all options documented.
565
609
 
566
- Run `crosscheck init` to generate a starter file with all options commented.
610
+ Logs are written to `~/.crosscheck/logs/YYYY-MM-DD.ndjson` and retained for 30 days by default.
567
611
 
568
612
  ### Full reference
569
613
 
570
614
  ```yaml
615
+ # ── Deployment ────────────────────────────────────────────────────────────────
616
+ # Set automatically on first run. Re-run the prompt with: crosscheck watch --reconfigure
617
+ # personal — monitor your repos + orgs; review only your PRs
618
+ # team — monitor org repos only; review all PRs from any author
619
+ # deployment: personal
620
+
571
621
  # ── Mode ──────────────────────────────────────────────────────────────────────
572
622
  # single-vendor: one AI reviews all PRs
573
623
  # cross-vendor: Claude ↔ Codex review each other
@@ -601,31 +651,55 @@ budget:
601
651
  per_review_usd: 2.00 # passed to claude --max-budget-usd
602
652
 
603
653
  # ── Orgs — covers all repos in each org with one webhook ─────────────────────
604
- # Takes priority over `repos` when both are set.
605
654
  orgs:
606
655
  - motivation-labs
607
656
  - codatta
608
657
 
658
+ # ── Users — monitors all repos owned by personal GitHub accounts (non-org) ───
659
+ # At startup, crosscheck enumerates each user's repos and registers webhooks.
660
+ # Useful when your AI agents open PRs across many personal repos.
661
+ # Combines with `orgs` and `repos` — all configured sources are additive.
662
+ users:
663
+ - beingzy # your personal account
664
+ # - my-agent-login # a bot account that pushes to its own repos
665
+
609
666
  # ── Repos — for monitoring specific repos only ────────────────────────────────
610
- # Omit when using `orgs`. In watch mode, auto-detected from git remote if empty.
667
+ # Omit when using `orgs`/`users`. Auto-detected from git remote if all are empty.
611
668
  repos:
612
669
  - owner: acme
613
670
  name: specific-repo
614
671
 
615
672
  # ── Routing ───────────────────────────────────────────────────────────────────
616
673
  routing:
674
+ # Origin is detected via a four-signal chain:
675
+ # 1. PR body patterns below (fastest)
676
+ # 2. Commit message Co-Authored-By: trailers (API call, non-fatal if it fails)
677
+ # 3. Branch prefix (claude/ or codex/)
678
+ # 4. author_routes fallback (last resort)
617
679
  codex_reviews_patterns:
618
- - "Generated with \\[Claude Code\\]"
680
+ - "Generated with \\[Claude Code\\]" # Claude Code attribution footer
681
+ - "Co-Authored-By: Claude" # commit trailer
619
682
  claude_reviews_patterns:
620
- - "Generated with \\[OpenAI Codex\\]"
621
- - "Co-Authored-By: codex"
683
+ - "Generated with \\[OpenAI Codex\\]" # Codex attribution footer
684
+ - "Co-Authored-By: codex" # commit trailer
685
+
686
+ # Branch prefix detection (signal 3). Claude Code uses claude/, Codex uses codex/.
687
+ claude_branch_prefixes:
688
+ - "claude/"
689
+ codex_branch_prefixes:
690
+ - "codex/"
622
691
 
623
692
  # Restrict reviews to PRs opened by these GitHub logins.
624
- # Recommended: set to the accounts your AI agents use.
693
+ # Auto-filled with your GitHub login by `crosscheck init` or first `crosscheck watch`.
625
694
  # Empty = no restriction (all matching PRs reviewed).
626
695
  allowed_authors:
627
- - your-claude-bot-account
628
- - your-codex-bot-account
696
+ - your-github-login # auto-detected from gh auth
697
+
698
+ # Author-based routing fallback (signal 4) — used when no pattern or prefix matches.
699
+ # Maps GitHub login → vendor origin so crosscheck routes PRs even without
700
+ # the attribution footer (e.g. when creating PRs via gh CLI directly).
701
+ author_routes:
702
+ your-github-login: claude # your PRs → treated as Claude-authored → Codex reviews
629
703
 
630
704
  # ── Tunnel (watch mode only) ──────────────────────────────────────────────────
631
705
  # localhost.run (default) — SSH tunnel, zero install, URL changes on reconnect.
@@ -643,6 +717,26 @@ impact:
643
717
  hourly_rate_usd: 150 # for --money estimate
644
718
  defect_cost_usd: 150 # per issue caught, for --money estimate
645
719
 
720
+ # ── Post-review auto-fix ──────────────────────────────────────────────────────
721
+ # Runs after each review. When issues are found, the authoring vendor opens a
722
+ # fix PR targeting the original branch. You approve and merge it; the original
723
+ # PR updates automatically.
724
+ post_review:
725
+ auto_fix:
726
+ enabled: true
727
+ trigger: on_issues # on_issues | always | never
728
+ min_severity: warning # error | warning | info — skip cosmetic findings
729
+ # same-as-author: the vendor that wrote the PR also applies the fix
730
+ # In cross-vendor mode: Claude-authored → Claude fixes; Codex-authored → Codex fixes
731
+ fixer: same-as-author # same-as-author | same-as-reviewer | codex | claude
732
+ delivery:
733
+ mode: pull_request # pull_request | commit | comment
734
+ # pull_request → fix PR targets original branch; human approves before merge
735
+ # commit → fixes pushed directly onto the original PR branch
736
+ # comment → suggested fixes posted as review comments only
737
+ pr_title: "fix: address CR issues in #{original_pr_title}"
738
+ label: cr-autofix # GitHub label applied to the fix PR
739
+
646
740
  # ── Server ────────────────────────────────────────────────────────────────────
647
741
  server:
648
742
  port: 7891
@@ -705,15 +799,38 @@ clone PR branch into temp directory
705
799
 
706
800
  post comment to PR via GitHub API
707
801
  delete temp clone
802
+
803
+ ▼ post_review.auto_fix (if enabled and issues found)
804
+ authoring vendor reads review comment
805
+
806
+ ├─ claude --print ... (Claude authored the PR)
807
+ │ or
808
+ └─ codex ... (Codex authored the PR)
809
+
810
+
811
+ opens fix PR → fix/cr-<pr-number>-review-issues → original branch
812
+ (you review and merge the fix PR; original PR updates automatically)
708
813
  ```
709
814
 
710
815
  ### PR origin detection
711
816
 
817
+ crosscheck uses a four-signal chain to determine whether a PR was authored by Claude Code, Codex, or a human:
818
+
819
+ 1. **PR body** — looks for attribution footers (e.g. `Generated with [Claude Code]`)
820
+ 2. **Commit messages** — scans all commit messages for `Co-Authored-By:` trailers
821
+ 3. **Branch prefix** — `claude/` → Claude origin; `codex/` → Codex origin
822
+ 4. **`author_routes`** — per-login fallback in config
823
+
824
+ If none match, origin is `human` and the PR is skipped in cross-vendor mode.
825
+
712
826
  | Default pattern | Matches |
713
827
  |---|---|
714
- | `Generated with \[Claude Code\]` | PRs opened by Claude Code |
715
- | `Generated with \[OpenAI Codex\]` | PRs opened by Codex CLI |
716
- | `Co-Authored-By: codex` | Commits co-authored by Codex |
828
+ | `Generated with \[Claude Code\]` | Claude Code attribution footer in PR body |
829
+ | `Generated with \[OpenAI Codex\]` | Codex attribution footer in PR body |
830
+ | `Co-Authored-By: Claude` | Commit trailers from Claude Code |
831
+ | `Co-Authored-By: codex` | Commit trailers from Codex |
832
+ | branch prefix `claude/` | Branch naming convention for Claude-authored PRs |
833
+ | branch prefix `codex/` | Branch naming convention for Codex-authored PRs |
717
834
 
718
835
  ### Reviewer assignment
719
836
 
@@ -770,6 +887,39 @@ GitHub can fire both `opened` and `synchronize` events for the same push. crossc
770
887
 
771
888
  ---
772
889
 
890
+ ## Post-review auto-fix
891
+
892
+ When `post_review.auto_fix.enabled` is `true` (the default), crosscheck completes the full loop automatically after every review that finds issues:
893
+
894
+ ```
895
+ agent opens PR #42 → opposite vendor reviews → issues found?
896
+ │ yes
897
+ authoring vendor generates fixes
898
+
899
+ fix PR #43 opened → feat/my-feature
900
+
901
+ you review and merge PR #43
902
+
903
+ PR #42 updates → you merge to main
904
+ ```
905
+
906
+ **Key design decisions:**
907
+
908
+ | Setting | Default | Why |
909
+ |---|---|---|
910
+ | `fixer: same-as-author` | the vendor that wrote the PR also fixes it | The authoring agent knows its own code and style best |
911
+ | `delivery: pull_request` | opens a new PR, doesn't push directly | You stay in the loop — no code lands without your approval |
912
+ | `trigger: on_issues` | only fires when the reviewer found warnings or worse | Skips the fix step on clean PRs |
913
+ | `min_severity: warning` | ignores info/cosmetic findings | Avoids noisy fix PRs for style-only comments |
914
+
915
+ **Fix PR branch naming:** `fix/cr-<original-pr-number>-review-issues`
916
+
917
+ **Original PR number:** never changes. The fix PR targets the original branch; once merged, its commits appear in the original PR automatically.
918
+
919
+ **To disable:** set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`.
920
+
921
+ ---
922
+
773
923
  ## FAQ
774
924
 
775
925
  ### How does crosscheck improve over time?
@@ -786,19 +936,38 @@ It picks automatically:
786
936
 
787
937
  The agent used for `optimize` is independent of which agent reviews your PRs — `optimize` is about improving the instructions, not reviewing code.
788
938
 
789
- ### What is `~/.crosscheck/instructions.md` and can I edit it?
939
+ ### How do I customize reviewer behavior?
790
940
 
791
- Yes it is a plain Markdown file that both `codex` and `claude` read before every review. On first use, crosscheck seeds it with safe defaults (no build-tool constraints, a focused review prompt, and the VERDICT format). You can edit it manually at any time. `crosscheck optimize --apply` rewrites it, so keep a backup or use version control if you've made custom edits you want to preserve.
941
+ The primary place is the workflow file. Each step has an `instructions` field that is passed verbatim to the reviewer or fixer agent:
792
942
 
793
- To reset to defaults, delete the file:
943
+ ```yaml
944
+ # .crosscheck/workflow.yml
945
+ steps:
946
+ - name: review
947
+ type: review
948
+ reviewer: auto
949
+ instructions: |
950
+ Do not suggest TypeScript patterns — this is a Rust project.
951
+ Focus on memory safety and error handling.
952
+ ## Verdict
953
+ End with: VERDICT: APPROVE | NEEDS_WORK | BLOCK
954
+ - name: fix
955
+ type: fix
956
+ reviewer: origin
957
+ when: "review.verdict != 'APPROVE'"
958
+ instructions: "Only fix issues explicitly called out. Do not refactor unrelated code."
959
+ ```
960
+
961
+ `~/.crosscheck/instructions.md` serves as a fallback when a workflow step has no `instructions:` field. `crosscheck optimize --apply` writes to that file to persist learned improvements across sessions.
962
+
963
+ To reset instructions.md to defaults, delete the file:
794
964
  ```bash
795
965
  rm ~/.crosscheck/instructions.md
796
966
  ```
797
- The next review will re-seed it from the built-in defaults.
798
967
 
799
- ### Can I have per-project instructions?
968
+ ### Can I have per-project workflow?
800
969
 
801
- Yes. Create `.crosscheck/instructions.md` in your repo root. crosscheck checks for a project-level file first and uses it instead of the user-level one. This lets you enforce project-specific constraints (e.g. "this is a Rust project do not suggest TypeScript patterns") without affecting other repos.
970
+ 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.
802
971
 
803
972
  ### What is `AGENT.md`?
804
973
 
@@ -825,7 +994,7 @@ crosscheck fetches the PR base branch (e.g. `staging`) into the temp clone befor
825
994
  npm install -g smee-client
826
995
  ```
827
996
 
828
- Visit [smee.io/new](https://smee.io/new) and copy the channel URL. Then in `crosscheck.config.yml`:
997
+ Visit [smee.io/new](https://smee.io/new) and copy the channel URL. Then in `~/.crosscheck/config.yml`:
829
998
 
830
999
  ```yaml
831
1000
  tunnel:
@@ -833,8 +1002,18 @@ tunnel:
833
1002
  smee_channel: https://smee.io/your-channel-id
834
1003
  ```
835
1004
 
836
- Register the smee channel URL as your GitHub webhook Payload URL once. crosscheck will forward events from the channel to the local server automatically. Unlike `localhost.run`, no re-registration is needed on restart.
1005
+ 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.
1006
+
1007
+
1008
+ ### Can I disable the auto-fix step?
1009
+
1010
+ 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.
1011
+
1012
+ 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`.
1013
+
1014
+ ### Why does the fixer use the same vendor that wrote the PR?
837
1015
 
1016
+ 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.
838
1017
 
839
1018
  ### Does optimize run automatically?
840
1019
 
package/get-started.zh.md CHANGED
@@ -620,11 +620,10 @@ routing:
620
620
  - "Co-Authored-By: codex"
621
621
 
622
622
  # 将审查限制为这些 GitHub 账号提交的 PR。
623
- # 推荐:设置为你的 AI Agent 使用的账号。
623
+ # `crosscheck init` 或首次运行 `crosscheck watch` 时自动从 gh auth 检测并填入。
624
624
  # 为空 = 不限制(所有匹配的 PR 都会被审查)。
625
625
  allowed_authors:
626
- - your-claude-bot-account
627
- - your-codex-bot-account
626
+ - your-github-login # 从 gh auth 自动检测
628
627
 
629
628
  # ── 隧道(仅 watch 模式)──────────────────────────────────────────────────
630
629
  # localhost.run(默认)—— SSH 隧道,零安装,URL 重连后会变化。
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@motivation-labs/crosscheck",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-beta.1216e4e.0",
4
4
  "description": "Cross-vendor AI code review orchestrator — Claude Code ↔ Codex",
5
5
  "bin": {
6
- "crosscheck": "dist/cli.js"
6
+ "crosscheck": "dist/cli.js",
7
+ "ck": "dist/ck.js"
7
8
  },
8
9
  "type": "module",
9
10
  "files": [
@@ -20,7 +21,7 @@
20
21
  "node": ">=18"
21
22
  },
22
23
  "scripts": {
23
- "build": "tsc && chmod +x dist/cli.js",
24
+ "build": "tsc && chmod +x dist/cli.js dist/ck.js",
24
25
  "dev": "tsx src/cli.ts",
25
26
  "typecheck": "tsc --noEmit",
26
27
  "test": "vitest run",