@motivation-labs/crosscheck 0.9.0 → 0.10.0-beta.40

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 (95) hide show
  1. package/README.md +6 -1
  2. package/README.zh.md +1 -1
  3. package/crosscheck.config.example.yml +8 -0
  4. package/dist/__tests__/board.test.d.ts +2 -0
  5. package/dist/__tests__/board.test.d.ts.map +1 -0
  6. package/dist/__tests__/board.test.js +36 -0
  7. package/dist/__tests__/board.test.js.map +1 -0
  8. package/dist/__tests__/codex.test.d.ts +2 -0
  9. package/dist/__tests__/codex.test.d.ts.map +1 -0
  10. package/dist/__tests__/codex.test.js +58 -0
  11. package/dist/__tests__/codex.test.js.map +1 -0
  12. package/dist/__tests__/loader.test.js +51 -2
  13. package/dist/__tests__/loader.test.js.map +1 -1
  14. package/dist/__tests__/onboard-preservation.test.js +1 -0
  15. package/dist/__tests__/onboard-preservation.test.js.map +1 -1
  16. package/dist/__tests__/optimize.test.js +1 -0
  17. package/dist/__tests__/optimize.test.js.map +1 -1
  18. package/dist/__tests__/repo-picker.test.d.ts +2 -0
  19. package/dist/__tests__/repo-picker.test.d.ts.map +1 -0
  20. package/dist/__tests__/repo-picker.test.js +115 -0
  21. package/dist/__tests__/repo-picker.test.js.map +1 -0
  22. package/dist/__tests__/smart-switch.test.d.ts +2 -0
  23. package/dist/__tests__/smart-switch.test.d.ts.map +1 -0
  24. package/dist/__tests__/smart-switch.test.js +145 -0
  25. package/dist/__tests__/smart-switch.test.js.map +1 -0
  26. package/dist/commands/issue.d.ts.map +1 -1
  27. package/dist/commands/issue.js +5 -2
  28. package/dist/commands/issue.js.map +1 -1
  29. package/dist/commands/onboard.d.ts +1 -0
  30. package/dist/commands/onboard.d.ts.map +1 -1
  31. package/dist/commands/onboard.js +34 -3
  32. package/dist/commands/onboard.js.map +1 -1
  33. package/dist/commands/review.js +15 -14
  34. package/dist/commands/review.js.map +1 -1
  35. package/dist/commands/run.d.ts.map +1 -1
  36. package/dist/commands/run.js +6 -10
  37. package/dist/commands/run.js.map +1 -1
  38. package/dist/commands/serve.d.ts.map +1 -1
  39. package/dist/commands/serve.js +36 -13
  40. package/dist/commands/serve.js.map +1 -1
  41. package/dist/commands/watch.d.ts.map +1 -1
  42. package/dist/commands/watch.js +44 -21
  43. package/dist/commands/watch.js.map +1 -1
  44. package/dist/config/loader.d.ts.map +1 -1
  45. package/dist/config/loader.js +4 -1
  46. package/dist/config/loader.js.map +1 -1
  47. package/dist/config/schema.d.ts +3 -0
  48. package/dist/config/schema.d.ts.map +1 -1
  49. package/dist/config/schema.js +6 -0
  50. package/dist/config/schema.js.map +1 -1
  51. package/dist/lib/board.d.ts +4 -0
  52. package/dist/lib/board.d.ts.map +1 -1
  53. package/dist/lib/board.js +51 -6
  54. package/dist/lib/board.js.map +1 -1
  55. package/dist/lib/clone.d.ts +12 -0
  56. package/dist/lib/clone.d.ts.map +1 -0
  57. package/dist/lib/clone.js +30 -0
  58. package/dist/lib/clone.js.map +1 -0
  59. package/dist/lib/repo-picker.d.ts +6 -0
  60. package/dist/lib/repo-picker.d.ts.map +1 -1
  61. package/dist/lib/repo-picker.js +260 -76
  62. package/dist/lib/repo-picker.js.map +1 -1
  63. package/dist/lib/runner.d.ts +4 -0
  64. package/dist/lib/runner.d.ts.map +1 -1
  65. package/dist/lib/runner.js +23 -19
  66. package/dist/lib/runner.js.map +1 -1
  67. package/dist/lib/sha-cache.d.ts +5 -0
  68. package/dist/lib/sha-cache.d.ts.map +1 -0
  69. package/dist/lib/sha-cache.js +37 -0
  70. package/dist/lib/sha-cache.js.map +1 -0
  71. package/dist/lib/smart-switch.d.ts +44 -0
  72. package/dist/lib/smart-switch.d.ts.map +1 -0
  73. package/dist/lib/smart-switch.js +145 -0
  74. package/dist/lib/smart-switch.js.map +1 -0
  75. package/dist/lib/verdict.d.ts.map +1 -1
  76. package/dist/lib/verdict.js +7 -6
  77. package/dist/lib/verdict.js.map +1 -1
  78. package/dist/lib/workflow.d.ts.map +1 -1
  79. package/dist/lib/workflow.js +3 -2
  80. package/dist/lib/workflow.js.map +1 -1
  81. package/dist/reviewers/claude.d.ts +5 -1
  82. package/dist/reviewers/claude.d.ts.map +1 -1
  83. package/dist/reviewers/claude.js +16 -3
  84. package/dist/reviewers/claude.js.map +1 -1
  85. package/dist/reviewers/codex.d.ts +3 -1
  86. package/dist/reviewers/codex.d.ts.map +1 -1
  87. package/dist/reviewers/codex.js +19 -1
  88. package/dist/reviewers/codex.js.map +1 -1
  89. package/dist/reviewers/fix.d.ts +1 -0
  90. package/dist/reviewers/fix.d.ts.map +1 -1
  91. package/dist/reviewers/fix.js +18 -8
  92. package/dist/reviewers/fix.js.map +1 -1
  93. package/get-started.md +12 -5
  94. package/get-started.zh.md +3 -3
  95. package/package.json +1 -1
@@ -3,6 +3,16 @@ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs';
3
3
  import { tmpdir } from 'os';
4
4
  import { join } from 'path';
5
5
  import { DEFAULT_REVIEW_INSTRUCTIONS } from '../lib/workflow.js';
6
+ // Codex review command outputs [P0]/[P1]/[P2]/[P3] priority markers but never a VERDICT line.
7
+ // Infer the verdict from the highest severity present and append it so parseVerdict() can
8
+ // extract it. Only called when the output doesn't already contain a VERDICT: token.
9
+ export function inferVerdictFromCodexOutput(text) {
10
+ if (/\[P0\]/i.test(text) || /\[P1\]/i.test(text))
11
+ return 'BLOCK';
12
+ if (/\[P2\]/i.test(text) || /\[P3\]/i.test(text))
13
+ return 'NEEDS WORK';
14
+ return 'APPROVE';
15
+ }
6
16
  // Scans stderr bottom-up for the first fatal/error line, skipping Codex header boilerplate.
7
17
  function extractErrorSummary(stderr) {
8
18
  const lines = stderr.split('\n').map(l => l.trim()).filter(Boolean);
@@ -56,7 +66,15 @@ export async function runCodexReview(repoDir, baseBranch, prTitle, quality, vend
56
66
  PATH: `${repoDir}/node_modules/.bin:${process.env.PATH ?? ''}`,
57
67
  },
58
68
  });
59
- return result.stdout.trim() || result.stderr.trim();
69
+ const rawReview = result.stdout.trim() || result.stderr.trim();
70
+ const tokensMatch = (result.stderr ?? '').match(/\btokens?:\s*([\d,]+)/i);
71
+ const tokensUsed = tokensMatch ? parseInt(tokensMatch[1].replace(/,/g, ''), 10) : undefined;
72
+ // Append inferred VERDICT when Codex didn't include one (its review command
73
+ // uses [P1]/[P2]/[P3] markers but never emits a VERDICT: line on its own).
74
+ const review = rawReview.includes('VERDICT:')
75
+ ? rawReview
76
+ : `${rawReview}\n\nVERDICT: ${inferVerdictFromCodexOutput(rawReview)}`;
77
+ return { review, tokensUsed };
60
78
  }
61
79
  catch (err) {
62
80
  const execa = err;
@@ -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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"}
@@ -1,5 +1,6 @@
1
1
  import type { Config } from '../config/schema.js';
2
2
  export declare function runFixStep(tmpDir: string, baseRef: string, prTitle: string, reviewComment: string, instructions: string, config: Config): Promise<{
3
3
  appliedCount: number;
4
+ tokensUsed?: number;
4
5
  }>;
5
6
  //# sourceMappingURL=fix.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAqCjD,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,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6DxD"}
@@ -1,6 +1,7 @@
1
- import { execSync, execFileSync } from 'child_process';
1
+ import { execSync } from 'child_process';
2
2
  import { writeFileSync } from 'fs';
3
3
  import { join } from 'path';
4
+ import { execa } from 'execa';
4
5
  const PROMPT_TEMPLATE = `You opened a pull request that received the following code review.
5
6
 
6
7
  PR title: {PR_TITLE}
@@ -47,15 +48,24 @@ export async function runFixStep(tmpDir, baseRef, prTitle, reviewComment, instru
47
48
  .replace('{DIFF}', diff.slice(0, 16000))
48
49
  .replace('{EXTRA_INSTRUCTIONS}', instructions ? `Additional instructions: ${instructions}` : '');
49
50
  let output = '';
51
+ let tokensUsed;
50
52
  try {
51
- // Pass prompt via stdin same pattern as optimize.ts
52
- output = execFileSync('claude', ['--print', '--output-format', 'text'], {
53
+ const { stdout } = await execa('claude', ['--print', '--output-format', 'json'], {
53
54
  input: prompt,
54
- encoding: 'utf8',
55
55
  timeout: 180_000,
56
56
  env: { ...process.env },
57
- maxBuffer: 10 * 1024 * 1024,
58
- }).trim();
57
+ });
58
+ const raw = stdout.trim();
59
+ try {
60
+ const parsed = JSON.parse(raw);
61
+ output = typeof parsed.result === 'string' ? parsed.result : raw;
62
+ const inTok = parsed.usage?.input_tokens;
63
+ const outTok = parsed.usage?.output_tokens;
64
+ tokensUsed = typeof inTok === 'number' && typeof outTok === 'number' ? inTok + outTok : undefined;
65
+ }
66
+ catch {
67
+ output = raw;
68
+ }
59
69
  }
60
70
  catch (err) {
61
71
  const msg = err instanceof Error ? err.message : String(err);
@@ -65,7 +75,7 @@ export async function runFixStep(tmpDir, baseRef, prTitle, reviewComment, instru
65
75
  throw err;
66
76
  }
67
77
  if (!output || output === 'NO_CHANGES')
68
- return { appliedCount: 0 };
78
+ return { appliedCount: 0, tokensUsed };
69
79
  // Parse <file path="...">content</file> blocks
70
80
  const fileRegex = /<file path="([^"]+)">([\s\S]*?)<\/file>/g;
71
81
  let match;
@@ -82,6 +92,6 @@ export async function runFixStep(tmpDir, baseRef, prTitle, reviewComment, instru
82
92
  }
83
93
  catch { /* skip unwritable paths */ }
84
94
  }
85
- return { appliedCount };
95
+ return { appliedCount, tokensUsed };
86
96
  }
87
97
  //# sourceMappingURL=fix.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fix.js","sourceRoot":"","sources":["../../src/reviewers/fix.ts"],"names":[],"mappings":"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"}
package/get-started.md CHANGED
@@ -786,7 +786,7 @@ If no errors are found in recent logs, crosscheck prints `No errors found in rec
786
786
 
787
787
  On re-runs, `onboard` updates only the fields it collected answers for. Everything else survives unchanged.
788
788
 
789
- **Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `tunnel.*`, `post_review.auto_fix.*`
789
+ **Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `tunnel.*`, `post_review.auto_fix.*`
790
790
 
791
791
  **Initialised on first run, never overwritten:** `routing.allowed_authors`, `routing.author_routes`, `routing.fallback_reviewer`
792
792
 
@@ -798,9 +798,9 @@ On re-runs, `onboard` updates only the fields it collected answers for. Everythi
798
798
 
799
799
  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):
800
800
 
801
- 1. `./crosscheck.config.yml`
802
- 2. `./.crosscheck.yml`
803
- 3. `~/.crosscheck/config.yml` ← **default location**
801
+ 1. `~/.crosscheck/config.yml` ← **default location**
802
+ 2. `./crosscheck.config.yml`
803
+ 3. `./.crosscheck.yml`
804
804
 
805
805
  Run `crosscheck init` to generate `~/.crosscheck/config.yml` with all options documented.
806
806
 
@@ -820,6 +820,13 @@ Logs are written to `~/.crosscheck/logs/YYYY-MM-DD.ndjson` and retained for 30 d
820
820
  # cross-vendor: Claude ↔ Codex review each other
821
821
  mode: cross-vendor
822
822
 
823
+ # ── Clone protocol ────────────────────────────────────────────────────────────
824
+ # ssh — git@github.com:owner/repo.git (uses local SSH keys)
825
+ # https — https://github.com/owner/repo.git (uses GitHub token)
826
+ # Pick https if you have multi-account SSH setup or your default SSH key
827
+ # cannot access target repos. Independent of `gh config get git_protocol`.
828
+ clone_protocol: ssh
829
+
823
830
  # ── Vendors ───────────────────────────────────────────────────────────────────
824
831
  vendors:
825
832
  codex:
@@ -1083,7 +1090,7 @@ GitHub can fire both `opened` and `synchronize` events for the same push. crossc
1083
1090
  - **Webhook signature** — every request verified with HMAC-SHA256 before parsing
1084
1091
  - **Temp isolation** — each PR cloned into a fresh temp dir, deleted after review
1085
1092
  - **Read-only tools** — Claude restricted to `git diff` and `git log` only
1086
- - **No credentials in clones** — `gh repo clone` uses the gh credential helper; no tokens written to disk
1093
+ - **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
1087
1094
 
1088
1095
  ---
1089
1096
 
package/get-started.zh.md CHANGED
@@ -795,9 +795,9 @@ crosscheck issue
795
795
 
796
796
  crosscheck 默认将配置存储在 `~/.crosscheck/config.yml`——跨项目持久化,无需每个仓库都有配置文件。也会在以下位置查找(找到第一个为止):
797
797
 
798
- 1. `./crosscheck.config.yml`
799
- 2. `./.crosscheck.yml`
800
- 3. `~/.crosscheck/config.yml` ← **默认位置**
798
+ 1. `~/.crosscheck/config.yml` ← **默认位置**
799
+ 2. `./crosscheck.config.yml`
800
+ 3. `./.crosscheck.yml`
801
801
 
802
802
  运行 `crosscheck init` 生成带完整注释的 `~/.crosscheck/config.yml`。
803
803
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@motivation-labs/crosscheck",
3
- "version": "0.9.0",
3
+ "version": "0.10.0-beta.40",
4
4
  "description": "Cross-vendor AI code review orchestrator — Claude Code ↔ Codex",
5
5
  "bin": {
6
6
  "crosscheck": "dist/cli.js",