@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.
Files changed (381) hide show
  1. package/AGENT.md +207 -0
  2. package/ISSUE.md +234 -0
  3. package/LICENSE +21 -0
  4. package/README.md +234 -0
  5. package/README.zh.md +169 -0
  6. package/assets/logo.png +0 -0
  7. package/assets/screenshot-watch-timing.png +0 -0
  8. package/assets/screenshot-watch-timing.svg +1 -0
  9. package/assets/screenshot-watch.png +0 -0
  10. package/crosscheck.config.example.yml +214 -0
  11. package/dist/__tests__/annotation.test.d.ts +2 -0
  12. package/dist/__tests__/annotation.test.d.ts.map +1 -0
  13. package/dist/__tests__/annotation.test.js +134 -0
  14. package/dist/__tests__/annotation.test.js.map +1 -0
  15. package/dist/__tests__/backtrace.test.d.ts +2 -0
  16. package/dist/__tests__/backtrace.test.d.ts.map +1 -0
  17. package/dist/__tests__/backtrace.test.js +280 -0
  18. package/dist/__tests__/backtrace.test.js.map +1 -0
  19. package/dist/__tests__/board.test.d.ts +2 -0
  20. package/dist/__tests__/board.test.d.ts.map +1 -0
  21. package/dist/__tests__/board.test.js +149 -0
  22. package/dist/__tests__/board.test.js.map +1 -0
  23. package/dist/__tests__/codex.test.d.ts +2 -0
  24. package/dist/__tests__/codex.test.d.ts.map +1 -0
  25. package/dist/__tests__/codex.test.js +92 -0
  26. package/dist/__tests__/codex.test.js.map +1 -0
  27. package/dist/__tests__/comment-bodies.test.d.ts +2 -0
  28. package/dist/__tests__/comment-bodies.test.d.ts.map +1 -0
  29. package/dist/__tests__/comment-bodies.test.js +75 -0
  30. package/dist/__tests__/comment-bodies.test.js.map +1 -0
  31. package/dist/__tests__/conflict-resolve.test.d.ts +2 -0
  32. package/dist/__tests__/conflict-resolve.test.d.ts.map +1 -0
  33. package/dist/__tests__/conflict-resolve.test.js +123 -0
  34. package/dist/__tests__/conflict-resolve.test.js.map +1 -0
  35. package/dist/__tests__/crosscheck-commit.test.d.ts +2 -0
  36. package/dist/__tests__/crosscheck-commit.test.d.ts.map +1 -0
  37. package/dist/__tests__/crosscheck-commit.test.js +13 -0
  38. package/dist/__tests__/crosscheck-commit.test.js.map +1 -0
  39. package/dist/__tests__/detector.test.d.ts +2 -0
  40. package/dist/__tests__/detector.test.d.ts.map +1 -0
  41. package/dist/__tests__/detector.test.js +112 -0
  42. package/dist/__tests__/detector.test.js.map +1 -0
  43. package/dist/__tests__/diagnose.test.d.ts +2 -0
  44. package/dist/__tests__/diagnose.test.d.ts.map +1 -0
  45. package/dist/__tests__/diagnose.test.js +164 -0
  46. package/dist/__tests__/diagnose.test.js.map +1 -0
  47. package/dist/__tests__/diff-hash.test.d.ts +2 -0
  48. package/dist/__tests__/diff-hash.test.d.ts.map +1 -0
  49. package/dist/__tests__/diff-hash.test.js +126 -0
  50. package/dist/__tests__/diff-hash.test.js.map +1 -0
  51. package/dist/__tests__/durations.test.d.ts +2 -0
  52. package/dist/__tests__/durations.test.d.ts.map +1 -0
  53. package/dist/__tests__/durations.test.js +26 -0
  54. package/dist/__tests__/durations.test.js.map +1 -0
  55. package/dist/__tests__/event-fields.test.d.ts +2 -0
  56. package/dist/__tests__/event-fields.test.d.ts.map +1 -0
  57. package/dist/__tests__/event-fields.test.js +50 -0
  58. package/dist/__tests__/event-fields.test.js.map +1 -0
  59. package/dist/__tests__/filter.test.d.ts +2 -0
  60. package/dist/__tests__/filter.test.d.ts.map +1 -0
  61. package/dist/__tests__/filter.test.js +21 -0
  62. package/dist/__tests__/filter.test.js.map +1 -0
  63. package/dist/__tests__/fix.test.d.ts +2 -0
  64. package/dist/__tests__/fix.test.d.ts.map +1 -0
  65. package/dist/__tests__/fix.test.js +124 -0
  66. package/dist/__tests__/fix.test.js.map +1 -0
  67. package/dist/__tests__/github-client.test.d.ts +2 -0
  68. package/dist/__tests__/github-client.test.d.ts.map +1 -0
  69. package/dist/__tests__/github-client.test.js +22 -0
  70. package/dist/__tests__/github-client.test.js.map +1 -0
  71. package/dist/__tests__/github-scan-client.test.d.ts +2 -0
  72. package/dist/__tests__/github-scan-client.test.d.ts.map +1 -0
  73. package/dist/__tests__/github-scan-client.test.js +100 -0
  74. package/dist/__tests__/github-scan-client.test.js.map +1 -0
  75. package/dist/__tests__/is-fresh-review-comment.test.d.ts +2 -0
  76. package/dist/__tests__/is-fresh-review-comment.test.d.ts.map +1 -0
  77. package/dist/__tests__/is-fresh-review-comment.test.js +86 -0
  78. package/dist/__tests__/is-fresh-review-comment.test.js.map +1 -0
  79. package/dist/__tests__/issue.test.d.ts +2 -0
  80. package/dist/__tests__/issue.test.d.ts.map +1 -0
  81. package/dist/__tests__/issue.test.js +259 -0
  82. package/dist/__tests__/issue.test.js.map +1 -0
  83. package/dist/__tests__/kickass.test.d.ts +2 -0
  84. package/dist/__tests__/kickass.test.d.ts.map +1 -0
  85. package/dist/__tests__/kickass.test.js +268 -0
  86. package/dist/__tests__/kickass.test.js.map +1 -0
  87. package/dist/__tests__/loader.test.d.ts +2 -0
  88. package/dist/__tests__/loader.test.d.ts.map +1 -0
  89. package/dist/__tests__/loader.test.js +180 -0
  90. package/dist/__tests__/loader.test.js.map +1 -0
  91. package/dist/__tests__/onboard-preservation.test.d.ts +2 -0
  92. package/dist/__tests__/onboard-preservation.test.d.ts.map +1 -0
  93. package/dist/__tests__/onboard-preservation.test.js +506 -0
  94. package/dist/__tests__/onboard-preservation.test.js.map +1 -0
  95. package/dist/__tests__/optimize.test.d.ts +2 -0
  96. package/dist/__tests__/optimize.test.d.ts.map +1 -0
  97. package/dist/__tests__/optimize.test.js +101 -0
  98. package/dist/__tests__/optimize.test.js.map +1 -0
  99. package/dist/__tests__/post-review-comment.test.d.ts +2 -0
  100. package/dist/__tests__/post-review-comment.test.d.ts.map +1 -0
  101. package/dist/__tests__/post-review-comment.test.js +44 -0
  102. package/dist/__tests__/post-review-comment.test.js.map +1 -0
  103. package/dist/__tests__/pr-lock.test.d.ts +2 -0
  104. package/dist/__tests__/pr-lock.test.d.ts.map +1 -0
  105. package/dist/__tests__/pr-lock.test.js +115 -0
  106. package/dist/__tests__/pr-lock.test.js.map +1 -0
  107. package/dist/__tests__/pr-picker.test.d.ts +2 -0
  108. package/dist/__tests__/pr-picker.test.d.ts.map +1 -0
  109. package/dist/__tests__/pr-picker.test.js +57 -0
  110. package/dist/__tests__/pr-picker.test.js.map +1 -0
  111. package/dist/__tests__/pr-status-scan.test.d.ts +2 -0
  112. package/dist/__tests__/pr-status-scan.test.d.ts.map +1 -0
  113. package/dist/__tests__/pr-status-scan.test.js +92 -0
  114. package/dist/__tests__/pr-status-scan.test.js.map +1 -0
  115. package/dist/__tests__/pr-status.test.d.ts +2 -0
  116. package/dist/__tests__/pr-status.test.d.ts.map +1 -0
  117. package/dist/__tests__/pr-status.test.js +346 -0
  118. package/dist/__tests__/pr-status.test.js.map +1 -0
  119. package/dist/__tests__/repo-picker.test.d.ts +2 -0
  120. package/dist/__tests__/repo-picker.test.d.ts.map +1 -0
  121. package/dist/__tests__/repo-picker.test.js +115 -0
  122. package/dist/__tests__/repo-picker.test.js.map +1 -0
  123. package/dist/__tests__/review-comment-body.test.d.ts +2 -0
  124. package/dist/__tests__/review-comment-body.test.d.ts.map +1 -0
  125. package/dist/__tests__/review-comment-body.test.js +54 -0
  126. package/dist/__tests__/review-comment-body.test.js.map +1 -0
  127. package/dist/__tests__/review-models.test.d.ts +2 -0
  128. package/dist/__tests__/review-models.test.d.ts.map +1 -0
  129. package/dist/__tests__/review-models.test.js +39 -0
  130. package/dist/__tests__/review-models.test.js.map +1 -0
  131. package/dist/__tests__/review-status.test.d.ts +2 -0
  132. package/dist/__tests__/review-status.test.d.ts.map +1 -0
  133. package/dist/__tests__/review-status.test.js +95 -0
  134. package/dist/__tests__/review-status.test.js.map +1 -0
  135. package/dist/__tests__/runner.test.d.ts +2 -0
  136. package/dist/__tests__/runner.test.d.ts.map +1 -0
  137. package/dist/__tests__/runner.test.js +204 -0
  138. package/dist/__tests__/runner.test.js.map +1 -0
  139. package/dist/__tests__/scan-cache.test.d.ts +2 -0
  140. package/dist/__tests__/scan-cache.test.d.ts.map +1 -0
  141. package/dist/__tests__/scan-cache.test.js +59 -0
  142. package/dist/__tests__/scan-cache.test.js.map +1 -0
  143. package/dist/__tests__/scan-client.test.d.ts +2 -0
  144. package/dist/__tests__/scan-client.test.d.ts.map +1 -0
  145. package/dist/__tests__/scan-client.test.js +30 -0
  146. package/dist/__tests__/scan-client.test.js.map +1 -0
  147. package/dist/__tests__/scan.test.d.ts +2 -0
  148. package/dist/__tests__/scan.test.d.ts.map +1 -0
  149. package/dist/__tests__/scan.test.js +115 -0
  150. package/dist/__tests__/scan.test.js.map +1 -0
  151. package/dist/__tests__/scopes.test.d.ts +2 -0
  152. package/dist/__tests__/scopes.test.d.ts.map +1 -0
  153. package/dist/__tests__/scopes.test.js +101 -0
  154. package/dist/__tests__/scopes.test.js.map +1 -0
  155. package/dist/__tests__/sha-cache.test.d.ts +2 -0
  156. package/dist/__tests__/sha-cache.test.d.ts.map +1 -0
  157. package/dist/__tests__/sha-cache.test.js +40 -0
  158. package/dist/__tests__/sha-cache.test.js.map +1 -0
  159. package/dist/__tests__/smart-switch.test.d.ts +2 -0
  160. package/dist/__tests__/smart-switch.test.d.ts.map +1 -0
  161. package/dist/__tests__/smart-switch.test.js +145 -0
  162. package/dist/__tests__/smart-switch.test.js.map +1 -0
  163. package/dist/ck.d.ts +3 -0
  164. package/dist/ck.d.ts.map +1 -0
  165. package/dist/ck.js +8 -0
  166. package/dist/ck.js.map +1 -0
  167. package/dist/cli.d.ts +3 -0
  168. package/dist/cli.d.ts.map +1 -0
  169. package/dist/cli.js +132 -0
  170. package/dist/cli.js.map +1 -0
  171. package/dist/commands/diagnose.d.ts +54 -0
  172. package/dist/commands/diagnose.d.ts.map +1 -0
  173. package/dist/commands/diagnose.js +294 -0
  174. package/dist/commands/diagnose.js.map +1 -0
  175. package/dist/commands/impact.d.ts +38 -0
  176. package/dist/commands/impact.d.ts.map +1 -0
  177. package/dist/commands/impact.js +210 -0
  178. package/dist/commands/impact.js.map +1 -0
  179. package/dist/commands/init.d.ts +12 -0
  180. package/dist/commands/init.d.ts.map +1 -0
  181. package/dist/commands/init.js +183 -0
  182. package/dist/commands/init.js.map +1 -0
  183. package/dist/commands/issue.d.ts +25 -0
  184. package/dist/commands/issue.d.ts.map +1 -0
  185. package/dist/commands/issue.js +445 -0
  186. package/dist/commands/issue.js.map +1 -0
  187. package/dist/commands/kickass.d.ts +59 -0
  188. package/dist/commands/kickass.d.ts.map +1 -0
  189. package/dist/commands/kickass.js +288 -0
  190. package/dist/commands/kickass.js.map +1 -0
  191. package/dist/commands/onboard.d.ts +70 -0
  192. package/dist/commands/onboard.d.ts.map +1 -0
  193. package/dist/commands/onboard.js +883 -0
  194. package/dist/commands/onboard.js.map +1 -0
  195. package/dist/commands/optimize.d.ts +16 -0
  196. package/dist/commands/optimize.d.ts.map +1 -0
  197. package/dist/commands/optimize.js +244 -0
  198. package/dist/commands/optimize.js.map +1 -0
  199. package/dist/commands/review.d.ts +2 -0
  200. package/dist/commands/review.d.ts.map +1 -0
  201. package/dist/commands/review.js +118 -0
  202. package/dist/commands/review.js.map +1 -0
  203. package/dist/commands/run.d.ts +13 -0
  204. package/dist/commands/run.d.ts.map +1 -0
  205. package/dist/commands/run.js +243 -0
  206. package/dist/commands/run.js.map +1 -0
  207. package/dist/commands/scan.d.ts +94 -0
  208. package/dist/commands/scan.d.ts.map +1 -0
  209. package/dist/commands/scan.js +276 -0
  210. package/dist/commands/scan.js.map +1 -0
  211. package/dist/commands/serve.d.ts +9 -0
  212. package/dist/commands/serve.d.ts.map +1 -0
  213. package/dist/commands/serve.js +402 -0
  214. package/dist/commands/serve.js.map +1 -0
  215. package/dist/commands/status.d.ts +2 -0
  216. package/dist/commands/status.d.ts.map +1 -0
  217. package/dist/commands/status.js +89 -0
  218. package/dist/commands/status.js.map +1 -0
  219. package/dist/commands/watch.d.ts +9 -0
  220. package/dist/commands/watch.d.ts.map +1 -0
  221. package/dist/commands/watch.js +902 -0
  222. package/dist/commands/watch.js.map +1 -0
  223. package/dist/config/loader.d.ts +47 -0
  224. package/dist/config/loader.d.ts.map +1 -0
  225. package/dist/config/loader.js +334 -0
  226. package/dist/config/loader.js.map +1 -0
  227. package/dist/config/schema.d.ts +814 -0
  228. package/dist/config/schema.d.ts.map +1 -0
  229. package/dist/config/schema.js +152 -0
  230. package/dist/config/schema.js.map +1 -0
  231. package/dist/github/client.d.ts +139 -0
  232. package/dist/github/client.d.ts.map +1 -0
  233. package/dist/github/client.js +711 -0
  234. package/dist/github/client.js.map +1 -0
  235. package/dist/github/detector.d.ts +12 -0
  236. package/dist/github/detector.d.ts.map +1 -0
  237. package/dist/github/detector.js +120 -0
  238. package/dist/github/detector.js.map +1 -0
  239. package/dist/github/merge.d.ts +9 -0
  240. package/dist/github/merge.d.ts.map +1 -0
  241. package/dist/github/merge.js +33 -0
  242. package/dist/github/merge.js.map +1 -0
  243. package/dist/github/review-status.d.ts +6 -0
  244. package/dist/github/review-status.d.ts.map +1 -0
  245. package/dist/github/review-status.js +51 -0
  246. package/dist/github/review-status.js.map +1 -0
  247. package/dist/github/webhook.d.ts +41 -0
  248. package/dist/github/webhook.d.ts.map +1 -0
  249. package/dist/github/webhook.js +50 -0
  250. package/dist/github/webhook.js.map +1 -0
  251. package/dist/lib/annotation.d.ts +23 -0
  252. package/dist/lib/annotation.d.ts.map +1 -0
  253. package/dist/lib/annotation.js +103 -0
  254. package/dist/lib/annotation.js.map +1 -0
  255. package/dist/lib/backtrace.d.ts +40 -0
  256. package/dist/lib/backtrace.d.ts.map +1 -0
  257. package/dist/lib/backtrace.js +169 -0
  258. package/dist/lib/backtrace.js.map +1 -0
  259. package/dist/lib/board.d.ts +74 -0
  260. package/dist/lib/board.d.ts.map +1 -0
  261. package/dist/lib/board.js +640 -0
  262. package/dist/lib/board.js.map +1 -0
  263. package/dist/lib/clone.d.ts +12 -0
  264. package/dist/lib/clone.d.ts.map +1 -0
  265. package/dist/lib/clone.js +30 -0
  266. package/dist/lib/clone.js.map +1 -0
  267. package/dist/lib/comment-bodies.d.ts +17 -0
  268. package/dist/lib/comment-bodies.d.ts.map +1 -0
  269. package/dist/lib/comment-bodies.js +51 -0
  270. package/dist/lib/comment-bodies.js.map +1 -0
  271. package/dist/lib/crosscheck-commit.d.ts +2 -0
  272. package/dist/lib/crosscheck-commit.d.ts.map +1 -0
  273. package/dist/lib/crosscheck-commit.js +4 -0
  274. package/dist/lib/crosscheck-commit.js.map +1 -0
  275. package/dist/lib/diff-hash.d.ts +16 -0
  276. package/dist/lib/diff-hash.d.ts.map +1 -0
  277. package/dist/lib/diff-hash.js +71 -0
  278. package/dist/lib/diff-hash.js.map +1 -0
  279. package/dist/lib/durations.d.ts +5 -0
  280. package/dist/lib/durations.d.ts.map +1 -0
  281. package/dist/lib/durations.js +39 -0
  282. package/dist/lib/durations.js.map +1 -0
  283. package/dist/lib/event-fields.d.ts +6 -0
  284. package/dist/lib/event-fields.d.ts.map +1 -0
  285. package/dist/lib/event-fields.js +20 -0
  286. package/dist/lib/event-fields.js.map +1 -0
  287. package/dist/lib/filter.d.ts +2 -0
  288. package/dist/lib/filter.d.ts.map +1 -0
  289. package/dist/lib/filter.js +4 -0
  290. package/dist/lib/filter.js.map +1 -0
  291. package/dist/lib/fortune.d.ts +2 -0
  292. package/dist/lib/fortune.d.ts.map +1 -0
  293. package/dist/lib/fortune.js +26 -0
  294. package/dist/lib/fortune.js.map +1 -0
  295. package/dist/lib/languages.d.ts +3 -0
  296. package/dist/lib/languages.d.ts.map +1 -0
  297. package/dist/lib/languages.js +26 -0
  298. package/dist/lib/languages.js.map +1 -0
  299. package/dist/lib/log-analysis.d.ts +17 -0
  300. package/dist/lib/log-analysis.d.ts.map +1 -0
  301. package/dist/lib/log-analysis.js +72 -0
  302. package/dist/lib/log-analysis.js.map +1 -0
  303. package/dist/lib/logger.d.ts +14 -0
  304. package/dist/lib/logger.d.ts.map +1 -0
  305. package/dist/lib/logger.js +84 -0
  306. package/dist/lib/logger.js.map +1 -0
  307. package/dist/lib/port.d.ts +2 -0
  308. package/dist/lib/port.d.ts.map +1 -0
  309. package/dist/lib/port.js +21 -0
  310. package/dist/lib/port.js.map +1 -0
  311. package/dist/lib/pr-lock.d.ts +4 -0
  312. package/dist/lib/pr-lock.d.ts.map +1 -0
  313. package/dist/lib/pr-lock.js +91 -0
  314. package/dist/lib/pr-lock.js.map +1 -0
  315. package/dist/lib/pr-picker.d.ts +10 -0
  316. package/dist/lib/pr-picker.d.ts.map +1 -0
  317. package/dist/lib/pr-picker.js +80 -0
  318. package/dist/lib/pr-picker.js.map +1 -0
  319. package/dist/lib/pr-status.d.ts +206 -0
  320. package/dist/lib/pr-status.d.ts.map +1 -0
  321. package/dist/lib/pr-status.js +613 -0
  322. package/dist/lib/pr-status.js.map +1 -0
  323. package/dist/lib/repo-picker.d.ts +23 -0
  324. package/dist/lib/repo-picker.d.ts.map +1 -0
  325. package/dist/lib/repo-picker.js +411 -0
  326. package/dist/lib/repo-picker.js.map +1 -0
  327. package/dist/lib/review-models.d.ts +7 -0
  328. package/dist/lib/review-models.d.ts.map +1 -0
  329. package/dist/lib/review-models.js +32 -0
  330. package/dist/lib/review-models.js.map +1 -0
  331. package/dist/lib/runner.d.ts +65 -0
  332. package/dist/lib/runner.d.ts.map +1 -0
  333. package/dist/lib/runner.js +710 -0
  334. package/dist/lib/runner.js.map +1 -0
  335. package/dist/lib/scan-cache.d.ts +31 -0
  336. package/dist/lib/scan-cache.d.ts.map +1 -0
  337. package/dist/lib/scan-cache.js +112 -0
  338. package/dist/lib/scan-cache.js.map +1 -0
  339. package/dist/lib/scopes.d.ts +16 -0
  340. package/dist/lib/scopes.d.ts.map +1 -0
  341. package/dist/lib/scopes.js +37 -0
  342. package/dist/lib/scopes.js.map +1 -0
  343. package/dist/lib/sha-cache.d.ts +7 -0
  344. package/dist/lib/sha-cache.d.ts.map +1 -0
  345. package/dist/lib/sha-cache.js +44 -0
  346. package/dist/lib/sha-cache.js.map +1 -0
  347. package/dist/lib/smart-switch.d.ts +44 -0
  348. package/dist/lib/smart-switch.d.ts.map +1 -0
  349. package/dist/lib/smart-switch.js +145 -0
  350. package/dist/lib/smart-switch.js.map +1 -0
  351. package/dist/lib/verdict.d.ts +9 -0
  352. package/dist/lib/verdict.d.ts.map +1 -0
  353. package/dist/lib/verdict.js +52 -0
  354. package/dist/lib/verdict.js.map +1 -0
  355. package/dist/lib/workflow.d.ts +85 -0
  356. package/dist/lib/workflow.d.ts.map +1 -0
  357. package/dist/lib/workflow.js +116 -0
  358. package/dist/lib/workflow.js.map +1 -0
  359. package/dist/reviewers/address.d.ts +5 -0
  360. package/dist/reviewers/address.d.ts.map +1 -0
  361. package/dist/reviewers/address.js +87 -0
  362. package/dist/reviewers/address.js.map +1 -0
  363. package/dist/reviewers/claude.d.ts +12 -0
  364. package/dist/reviewers/claude.d.ts.map +1 -0
  365. package/dist/reviewers/claude.js +78 -0
  366. package/dist/reviewers/claude.js.map +1 -0
  367. package/dist/reviewers/codex.d.ts +9 -0
  368. package/dist/reviewers/codex.d.ts.map +1 -0
  369. package/dist/reviewers/codex.js +121 -0
  370. package/dist/reviewers/codex.js.map +1 -0
  371. package/dist/reviewers/conflict-resolve.d.ts +15 -0
  372. package/dist/reviewers/conflict-resolve.d.ts.map +1 -0
  373. package/dist/reviewers/conflict-resolve.js +219 -0
  374. package/dist/reviewers/conflict-resolve.js.map +1 -0
  375. package/dist/reviewers/fix.d.ts +7 -0
  376. package/dist/reviewers/fix.d.ts.map +1 -0
  377. package/dist/reviewers/fix.js +197 -0
  378. package/dist/reviewers/fix.js.map +1 -0
  379. package/get-started.md +1271 -0
  380. package/get-started.zh.md +1208 -0
  381. package/package.json +75 -0
package/README.zh.md ADDED
@@ -0,0 +1,169 @@
1
+ <div align="right">
2
+ <h5><a href="./README.md">🌐 &nbsp;English</a></h5>
3
+ </div>
4
+
5
+ <p align="center">
6
+ <img src="./assets/logo.png" alt="crosscheck" width="160" />
7
+ </p>
8
+
9
+ <p align="center"><em>用 crosscheck 构建 crosscheck。</em></p>
10
+
11
+ # crosscheck
12
+
13
+ **为使用 Claude Code 和 Codex 的开发者打造的自动化 AI Code Review——按你的方式配置,零额外基础设施。**
14
+
15
+ 当你的 AI Agent 提交 PR 时,另一个 AI 负责审查。发现问题后,原作者 Agent 自动修复并提交跟进 PR。整个流程运行在你已有的订阅上,一条命令即可启动。
16
+
17
+ ---
18
+
19
+ ## 核心亮点
20
+
21
+ - **可定制的审查工作流** — 灵活配置完整流水线:仅审查、审查 + 自动修复,或审查 + 修复 + 复查。每个步骤均可定制审查指令,无需手动编辑 Prompt。
22
+ - **跨供应商模式与单供应商模式** — 跨供应商模式将每个 PR 路由给对手 AI 进行独立审查;单供应商模式则使用你拥有的任意一个 AI。一行配置即可切换。
23
+ - **订阅驱动,无需按 token 计费** — 通过 `claude` 和 `codex` 命令行工具运行,使用你已有的 Claude Pro/Max 和 ChatGPT Plus/Pro 订阅。无需 API Key,无额外审查费用。
24
+ - **`watch` 个人使用,`serve` 服务团队** — `crosscheck watch` 在本地笔记本运行并自动建立隧道,适合个人开发者。`crosscheck serve` 绑定到共享机器的固定端口,让整个团队无需任何人保持笔记本在线即可获得覆盖。
25
+
26
+ ---
27
+
28
+ ## 快速开始
29
+
30
+ ```bash
31
+ # 1. 安装 crosscheck 及 Agent CLI
32
+ npm install -g @humanbased/crosscheck
33
+ npm install -g @anthropic-ai/claude-code && claude # 需要 Claude Pro/Max 订阅
34
+ npm install -g @openai/codex && codex login --device-auth # 需要 ChatGPT Plus/Pro 订阅
35
+ brew install gh && gh auth login # GitHub CLI
36
+
37
+ # 2. 引导式配置——选择仓库、供应商模式、工作流流水线
38
+ crosscheck onboard
39
+
40
+ # 3. 启动监听
41
+ crosscheck watch # 个人笔记本
42
+ crosscheck serve # 团队常驻服务器
43
+ ```
44
+
45
+ `crosscheck onboard` 将引导你完成仓库选择、供应商模式、流水线步骤和隧道选择。完成后,运行 `watch` 或 `serve` 即可。
46
+
47
+ ---
48
+
49
+ ## 运行效果
50
+
51
+ ```
52
+ $ crosscheck watch
53
+
54
+ "Move fast and review things."
55
+
56
+ profile personal · cross-vendor · balanced
57
+ users your-github-login (5 repos)
58
+ auto-fix on_issues · same-as-author · pull_request
59
+ config ./crosscheck.config.yml
60
+
61
+ ✓ 隧道已就绪: https://abc123.lhr.life
62
+ ✓ 已为 your-org/your-repo 注册 Webhook
63
+ 等待 PR 事件 — 按 Ctrl+C 停止。
64
+
65
+ PR #47 opened: add retry logic for flaky network calls
66
+ origin=claude reviewer=codex
67
+ codex reviewing... (12s)
68
+ NEEDS WORK
69
+ auto-fix claude fixing...
70
+ fix PR #48 opened → github.com/your-org/your-repo/pull/48
71
+
72
+ PR #49 opened: implement caching layer
73
+ origin=codex reviewer=claude
74
+ claude reviewing... (18s)
75
+ APPROVE
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 命令列表
81
+
82
+ ```bash
83
+ crosscheck init # 检查环境,生成初始配置文件
84
+ crosscheck onboard # 引导式配置——选择仓库、模式和流水线
85
+ crosscheck review <pr-url> # 对指定 PR 进行一次性审查
86
+ crosscheck watch # 个人使用——隧道 + 自动 Webhook + 本地监听
87
+ crosscheck serve # 团队使用——固定端口,一次性注册 Webhook
88
+ crosscheck status # 查看认证状态、配置摘要、CLI 版本
89
+ ```
90
+
91
+ **持续改进** *(实验性)*
92
+
93
+ ```bash
94
+ crosscheck diagnose # 从审查日志中提取失败模式
95
+ crosscheck optimize [--apply] # 根据 diagnose 输出重写审查指令
96
+ crosscheck impact [--money] # 节省时间、发现问题、代码质量趋势报告
97
+ crosscheck issue # 从近期错误日志起草并提交 Bug 报告
98
+ ```
99
+
100
+ ---
101
+
102
+ ## 配置说明
103
+
104
+ 配置文件位于 `~/.crosscheck/config.yml`,一个文件覆盖所有仓库。运行 `crosscheck init` 生成,或通过 `crosscheck onboard` 自动写入。项目根目录下的 `crosscheck.config.yml` 或 `.crosscheck.yml` 仅在 home 配置缺失时作为回退使用。
105
+
106
+ ```yaml
107
+ orgs:
108
+ - your-org
109
+
110
+ routing:
111
+ allowed_authors:
112
+ - your-github-login
113
+
114
+ quality:
115
+ tier: balanced # fast(快速)| balanced(均衡)| thorough(深度)
116
+
117
+ post_review:
118
+ auto_fix:
119
+ enabled: true
120
+ trigger: on_issues # on_issues | always | never
121
+ fixer: same-as-author
122
+ delivery:
123
+ mode: pull_request
124
+ ```
125
+
126
+ 完整配置参考:[get-started.zh.md](./get-started.zh.md)
127
+
128
+ ---
129
+
130
+ ## 部署方式
131
+
132
+ **个人使用(`crosscheck watch`)** — 运行在你的笔记本上。通过 `localhost.run` 建立 SSH 隧道,无需端口转发,无需云账号。隧道断开时健康检查会自动重连。
133
+
134
+ **团队使用(`crosscheck serve`)** — 绑定到具有公网 IP 的机器上的固定端口,手动注册一次 Webhook,整个团队即可获得覆盖,无需任何人保持笔记本在线。
135
+
136
+ ---
137
+
138
+ ## 系统要求
139
+
140
+ | | 最低版本 |
141
+ |---|---|
142
+ | Node.js | 18+ |
143
+ | Claude Code CLI | 最新版 — `npm install -g @anthropic-ai/claude-code` |
144
+ | Codex CLI | 最新版 — `npm install -g @openai/codex` |
145
+ | GitHub CLI | 2.65+ — `brew install gh` |
146
+
147
+ 运行 `gh auth login` 后,`GITHUB_TOKEN` 会自动获取,无需手动导出。
148
+
149
+ ---
150
+
151
+ ## 文档
152
+
153
+ | | |
154
+ |---|---|
155
+ | **[get-started.zh.md](./get-started.zh.md)** | 完整安装指南——前置条件、所有命令与参数、完整配置参考、常见问题 |
156
+ | **[crosscheck.config.example.yml](./crosscheck.config.example.yml)** | 带注释的配置文件示例(每个选项均有说明) |
157
+ | **[CHANGELOG.md](./CHANGELOG.md)** | 版本发布记录 |
158
+
159
+ ---
160
+
161
+ ## 参与贡献
162
+
163
+ 欢迎提交 Issue 和 PR:[github.com/humanbased-ai/crosscheck](https://github.com/humanbased-ai/crosscheck)
164
+
165
+ ---
166
+
167
+ ## 许可证
168
+
169
+ [MIT](./LICENSE) — Copyright (c) 2025–2026 HumanBased AI.
Binary file
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="940" height="494.2"><rect width="940" height="494.2" rx="5" ry="5" class="a"/><svg y="0%" x="0%"><circle cx="20" cy="20" r="6" fill="#ff5f58"/><circle cx="40" cy="20" r="6" fill="#ffbd2e"/><circle cx="60" cy="20" r="6" fill="#18c132"/></svg><svg height="434.2" viewBox="0 0 90 43.42" width="900" x="15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="50"><style>@keyframes o{0%{transform:translateX(-90px)}5.3%{transform:translateX(-180px)}10.5%{transform:translateX(-270px)}15.8%{transform:translateX(-360px)}21.1%{transform:translateX(-450px)}26.3%{transform:translateX(-540px)}31.6%{transform:translateX(-630px)}36.8%{transform:translateX(-720px)}42.1%{transform:translateX(-810px)}47.4%{transform:translateX(-900px)}52.6%{transform:translateX(-990px)}57.9%{transform:translateX(-1080px)}63.2%{transform:translateX(-1170px)}68.4%{transform:translateX(-1260px)}73.7%{transform:translateX(-1350px)}78.9%{transform:translateX(-1440px)}84.2%{transform:translateX(-1530px)}89.5%{transform:translateX(-1620px)}94.7%{transform:translateX(-1710px)}to{transform:translateX(-1800px)}}.a{fill:#282d35}.f,.g,.h{fill:#b9c0cb;white-space:pre}.g,.h{fill:#a8cc8c}.h{fill:#b9c0cb;font-weight:700}.i,.j,.k,.l{fill:#b9bfca;white-space:pre}.j,.k,.l{fill:#dbab79}.k,.l{fill:#66c2cd}.l{fill:#71bef2}</style><g font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace" font-size="1.67"><defs><symbol id="1"><text y="1.67" class="f">────────────────────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="2"><text y="1.67" class="g">●</text><text x="2.004" y="1.67" class="h">crosscheck</text><text x="14.028" y="1.67" class="f">cross-vendor</text><text x="27.054" y="1.67" class="f">·</text><text x="29.058" y="1.67" class="f">thorough</text></symbol><symbol id="3"><text x="39.078" y="1.67" class="f">workflow:</text><text x="49.098" y="1.67" class="f">review</text><text x="56.112" y="1.67" class="f">→</text><text x="58.116" y="1.67" class="f">fix</text><text x="62.124" y="1.67" class="f">→</text><text x="64.128" y="1.67" class="f">recheck</text></symbol><symbol id="4"><text x="73.146" y="1.67" class="f">vendors:</text><text x="83.166" y="1.67" class="f">claude</text></symbol><symbol id="5"><text y="1.67" class="f">·</text><text x="2.004" y="1.67" class="f">codex</text></symbol><symbol id="6"><text x="7.014" y="1.67" class="f">───────────────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="7"><text y="1.67" class="f">─────</text></symbol><symbol id="8"><text x="7.014" y="1.67" class="f">PRs:</text><text x="12.024" y="1.67" class="f">4</text><text x="14.028" y="1.67" class="f">·</text><text x="16.032" y="1.67" class="f">CRs:</text><text x="21.042" y="1.67" class="f">3</text><text x="23.046" y="1.67" class="f">·</text><text x="25.05" y="1.67" class="f">fixes:</text><text x="32.064" y="1.67" class="f">2</text><text x="35.07" y="1.67" class="f">│</text><text x="38.076" y="1.67" class="f">avg</text><text x="42.084" y="1.67" class="f">CR:</text><text x="46.092" y="1.67" class="i">1m34s</text><text x="53.106" y="1.67" class="f">│</text><text x="56.112" y="1.67" class="f">↑</text><text x="58.116" y="1.67" class="f">18:42</text></symbol><symbol id="9"><text x="65.13" y="1.67" class="f">tunnel:</text><text x="75.15" y="1.67" class="f">e3f9a1.smee.io</text></symbol><symbol id="10"><text y="1.67" class="g">✓</text></symbol><symbol id="11"><text x="3.006" y="1.67" class="f">10:17</text><text x="9.018" y="1.67" class="f">PM</text><text x="13.026" y="1.67" class="f">PR</text><text x="16.032" y="1.67" class="f">#111</text><text x="21.042" y="1.67" class="f">opened</text><text x="29.058" y="1.67" class="f">feat/login</text><text x="43.086" y="1.67" class="f">origin=</text><text x="50.1" y="1.67" class="j">claude</text><text x="58.116" y="1.67" class="f">via=body</text><text x="68.136" y="1.67" class="f">reviewer=</text><text x="77.154" y="1.67" class="k">codex</text></symbol><symbol id="12"><text x="84.168" y="1.67" class="f">10:22</text></symbol><symbol id="13"><text y="1.67" class="f">PM</text><text x="4.008" y="1.67" class="f">PR</text><text x="7.014" y="1.67" class="f">#112</text><text x="12.024" y="1.67" class="f">opened</text><text x="20.04" y="1.67" class="f">fix/null-ptr</text><text x="34.068" y="1.67" class="f">origin=</text><text x="41.082" y="1.67" class="j">codex</text><text x="49.098" y="1.67" class="f">via=commits</text><text x="62.124" y="1.67" class="f">reviewer=</text><text x="71.142" y="1.67" class="k">claude</text></symbol><symbol id="14"><text x="77.154" y="1.67" class="f">─────────────</text></symbol><symbol id="15"><text y="1.67" class="f">───────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="16"><text x="77.154" y="1.67" class="g">✓</text><text x="79.158" y="1.67" class="f">#109</text><text x="85.17" y="1.67" class="f">org/r</text></symbol><symbol id="17"><text y="1.67" class="f">epo</text><text x="5.01" y="1.67" class="f">feat/auth</text><text x="18.036" y="1.67" class="f">CR:</text><text x="22.044" y="1.67" class="g">APPROVE</text><text x="31.062" y="1.67" class="f">(43s)</text><text x="38.076" y="1.67" class="f">→</text><text x="40.08" y="1.67" class="k">https://github.com/org/repo/pull/109</text></symbol><symbol id="18"><text x="78.156" y="1.67" class="g">✓</text><text x="80.16" y="1.67" class="f">#110</text><text x="86.172" y="1.67" class="f">org/</text></symbol><symbol id="19"><text y="1.67" class="f">repo</text><text x="6.012" y="1.67" class="f">fix/crash</text><text x="19.038" y="1.67" class="f">CR:</text><text x="23.046" y="1.67" class="j">NEEDS</text><text x="29.058" y="1.67" class="j">WORK</text><text x="34.068" y="1.67" class="f">·</text><text x="36.072" y="1.67" class="f">fix</text><text x="40.08" y="1.67" class="f">2</text><text x="43.086" y="1.67" class="f">(2m08s)</text><text x="52.104" y="1.67" class="f">→</text><text x="54.108" y="1.67" class="k">https://github.com/org/repo/pull/110</text></symbol><symbol id="20"><text x="2.004" y="1.67" class="g">⠋</text><text x="4.008" y="1.67" class="h">#111</text><text x="10.02" y="1.67" class="i">org/repo</text><text x="20.04" y="1.67" class="f">feat/login</text><text x="46.092" y="1.67" class="f">started</text><text x="54.108" y="1.67" class="f">10:17</text><text x="60.12" y="1.67" class="f">PM</text><text x="64.128" y="1.67" class="f">4m05s</text><text x="71.142" y="1.67" class="g">⠋</text><text x="73.146" y="1.67" class="f">rechecking…</text></symbol><symbol id="21"><text x="86.172" y="1.67" class="f">PR</text><text x="89.178" y="1.67" class="l">█</text></symbol><symbol id="22"><text y="1.67" class="l">█████████</text><text x="10.02" y="1.67" class="f">711loc</text><text x="17.034" y="1.67" class="f">|</text><text x="19.038" y="1.67" class="f">CR</text><text x="22.044" y="1.67" class="j">████████</text><text x="31.062" y="1.67" class="j">2</text><text x="33.066" y="1.67" class="j">issues</text><text x="40.08" y="1.67" class="j">(NEEDS</text><text x="47.094" y="1.67" class="j">WORK,</text><text x="53.106" y="1.67" class="j">3.2K)</text><text x="59.118" y="1.67" class="f">codex</text><text x="65.13" y="1.67" class="f">·</text><text x="67.134" y="1.67" class="f">thorough</text><text x="76.152" y="1.67" class="f">|</text><text x="78.156" y="1.67" class="f">Fix</text><text x="82.164" y="1.67" class="k">███</text><text x="85.17" y="1.67" class="f">░░░</text><text x="89.178" y="1.67" class="k">✓</text></symbol><symbol id="23"><text x="1.002" y="1.67" class="k">1</text><text x="3.006" y="1.67" class="k">applied</text><text x="11.022" y="1.67" class="f">(2K)</text><text x="16.032" y="1.67" class="f">|</text><text x="18.036" y="1.67" class="f">Recheck</text><text x="26.052" y="1.67" class="f">░░░░░</text></symbol><symbol id="24"><text x="33.066" y="1.67" class="g">⠋</text><text x="35.07" y="1.67" class="h">#112</text><text x="41.082" y="1.67" class="i">org/repo</text><text x="51.102" y="1.67" class="f">fix/null-ptr</text><text x="83.166" y="1.67" class="f">started</text></symbol><symbol id="25"><text x="1.002" y="1.67" class="f">10:22</text><text x="7.014" y="1.67" class="f">PM</text><text x="11.022" y="1.67" class="f">8s</text><text x="15.03" y="1.67" class="g">⠋</text><text x="17.034" y="1.67" class="f">reviewing…</text></symbol><symbol id="26"><text x="29.058" y="1.67" class="f">PR</text><text x="32.064" y="1.67" class="l">███</text><text x="35.07" y="1.67" class="f">░░░░░░░</text><text x="43.086" y="1.67" class="f">42loc</text><text x="49.098" y="1.67" class="f">|</text><text x="51.102" y="1.67" class="f">CR</text><text x="54.108" y="1.67" class="f">░░░░░░░░</text><text x="63.126" y="1.67" class="f">queued</text><text x="70.14" y="1.67" class="f">|</text><text x="72.144" y="1.67" class="f">Fix</text><text x="76.152" y="1.67" class="f">░░░░░░</text><text x="83.166" y="1.67" class="f">queued</text></symbol><symbol id="27"><text x="89.178" y="1.67" class="f">─</text></symbol><symbol id="28"><text y="1.67" class="f">───────────────────────────────────────────────────────────────────────────────────────</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h90v20H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h90v43.42H0z"/><g style="animation-duration:.9500000000000003s;animation-iteration-count:infinite;animation-name:o;animation-timing-function:steps(1,end)"><svg width="1890"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="90"><use xlink:href="#a"/><use xlink:href="#b" x="87.996" y="2.146"/><use xlink:href="#1"/></svg><svg x="180"><use xlink:href="#a"/><use xlink:href="#b" x="36.996" y="6.488"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/></svg><svg x="270"><use xlink:href="#a"/><use xlink:href="#b" x="70.996" y="8.659"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/></svg><svg x="360"><use xlink:href="#a"/><use xlink:href="#b" x="6.996" y="13.001"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/></svg><svg x="450"><use xlink:href="#a"/><use xlink:href="#b" x="4.996" y="17.343"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/></svg><svg x="540"><use xlink:href="#a"/><use xlink:href="#b" x="62.996" y="19.514"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/></svg><svg x="630"><use xlink:href="#a"/><use xlink:href="#b" x=".996" y="23.856"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/></svg><svg x="720"><use xlink:href="#a"/><use xlink:href="#b" x="81.996" y="26.027"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/></svg><svg x="810"><use xlink:href="#a"/><use xlink:href="#b" x="76.996" y="30.369"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/></svg><svg x="900"><use xlink:href="#a"/><use xlink:href="#b" x="74.996" y="34.711"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#15" y="32.565"/></svg><svg x="990"><use xlink:href="#a"/><use xlink:href="#b" x="75.996" y="39.053"/><use xlink:href="#1"/><use xlink:href="#2" y="4.342"/><use xlink:href="#3" y="6.513"/><use xlink:href="#4" y="8.684"/><use xlink:href="#5" y="10.855"/><use xlink:href="#6" y="13.026"/><use xlink:href="#7" y="15.197"/><use xlink:href="#8" y="17.368"/><use xlink:href="#9" y="19.539"/><use xlink:href="#10" y="21.71"/><use xlink:href="#11" y="23.881"/><use xlink:href="#12" y="26.052"/><use xlink:href="#13" y="28.223"/><use xlink:href="#14" y="30.394"/><use xlink:href="#15" y="32.565"/><use xlink:href="#16" y="34.736"/><use xlink:href="#17" y="36.907"/></svg><svg x="1080"><use xlink:href="#a"/><use xlink:href="#b" x="89.996" y="41.224"/><use xlink:href="#2" y="2.171"/><use xlink:href="#3" y="4.342"/><use xlink:href="#4" y="6.513"/><use xlink:href="#5" y="8.684"/><use xlink:href="#6" y="10.855"/><use xlink:href="#7" y="13.026"/><use xlink:href="#8" y="15.197"/><use xlink:href="#9" y="17.368"/><use xlink:href="#10" y="19.539"/><use xlink:href="#11" y="21.71"/><use xlink:href="#12" y="23.881"/><use xlink:href="#13" y="26.052"/><use xlink:href="#14" y="28.223"/><use xlink:href="#15" y="30.394"/><use xlink:href="#16" y="32.565"/><use xlink:href="#17" y="34.736"/><use xlink:href="#18" y="36.907"/><use xlink:href="#19" y="39.078"/></svg><svg x="1170"><use xlink:href="#a"/><use xlink:href="#b" x="89.996" y="41.224"/><use xlink:href="#2"/><use xlink:href="#3" y="2.171"/><use xlink:href="#4" y="4.342"/><use xlink:href="#5" y="6.513"/><use xlink:href="#6" y="8.684"/><use xlink:href="#7" y="10.855"/><use xlink:href="#8" y="13.026"/><use xlink:href="#9" y="15.197"/><use xlink:href="#10" y="17.368"/><use xlink:href="#11" y="19.539"/><use xlink:href="#12" y="21.71"/><use xlink:href="#13" y="23.881"/><use xlink:href="#14" y="26.052"/><use xlink:href="#15" y="28.223"/><use xlink:href="#16" y="30.394"/><use xlink:href="#17" y="32.565"/><use xlink:href="#18" y="34.736"/><use xlink:href="#19" y="36.907"/></svg><svg x="1260"><use xlink:href="#a"/><use xlink:href="#b" x="83.996" y="41.224"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/><use xlink:href="#11" y="15.197"/><use xlink:href="#12" y="17.368"/><use xlink:href="#13" y="19.539"/><use xlink:href="#14" y="21.71"/><use xlink:href="#15" y="23.881"/><use xlink:href="#16" y="26.052"/><use xlink:href="#17" y="28.223"/><use xlink:href="#18" y="30.394"/><use xlink:href="#19" y="32.565"/><use xlink:href="#20" y="39.078"/></svg><svg x="1350"><use xlink:href="#a"/><use xlink:href="#b" x="30.996" y="41.224"/><use xlink:href="#7"/><use xlink:href="#8" y="2.171"/><use xlink:href="#9" y="4.342"/><use xlink:href="#10" y="6.513"/><use xlink:href="#11" y="8.684"/><use xlink:href="#12" y="10.855"/><use xlink:href="#13" y="13.026"/><use xlink:href="#14" y="15.197"/><use xlink:href="#15" y="17.368"/><use xlink:href="#16" y="19.539"/><use xlink:href="#17" y="21.71"/><use xlink:href="#18" y="23.881"/><use xlink:href="#19" y="26.052"/><use xlink:href="#20" y="32.565"/><use xlink:href="#21" y="34.736"/><use xlink:href="#22" y="36.907"/><use xlink:href="#23" y="39.078"/></svg><svg x="1440"><use xlink:href="#a"/><use xlink:href="#b" x="30.996" y="41.224"/><use xlink:href="#8"/><use xlink:href="#9" y="2.171"/><use xlink:href="#10" y="4.342"/><use xlink:href="#11" y="6.513"/><use xlink:href="#12" y="8.684"/><use xlink:href="#13" y="10.855"/><use xlink:href="#14" y="13.026"/><use xlink:href="#15" y="15.197"/><use xlink:href="#16" y="17.368"/><use xlink:href="#17" y="19.539"/><use xlink:href="#18" y="21.71"/><use xlink:href="#19" y="23.881"/><use xlink:href="#20" y="30.394"/><use xlink:href="#21" y="32.565"/><use xlink:href="#22" y="34.736"/><use xlink:href="#23" y="36.907"/></svg><svg x="1530"><use xlink:href="#a"/><use xlink:href="#b" x="26.996" y="41.224"/><use xlink:href="#10"/><use xlink:href="#11" y="2.171"/><use xlink:href="#12" y="4.342"/><use xlink:href="#13" y="6.513"/><use xlink:href="#14" y="8.684"/><use xlink:href="#15" y="10.855"/><use xlink:href="#16" y="13.026"/><use xlink:href="#17" y="15.197"/><use xlink:href="#18" y="17.368"/><use xlink:href="#19" y="19.539"/><use xlink:href="#20" y="26.052"/><use xlink:href="#21" y="28.223"/><use xlink:href="#22" y="30.394"/><use xlink:href="#23" y="32.565"/><use xlink:href="#24" y="36.907"/><use xlink:href="#25" y="39.078"/></svg><svg x="1620"><use xlink:href="#a"/><use xlink:href="#b" x="88.996" y="41.224"/><use xlink:href="#11"/><use xlink:href="#12" y="2.171"/><use xlink:href="#13" y="4.342"/><use xlink:href="#14" y="6.513"/><use xlink:href="#15" y="8.684"/><use xlink:href="#16" y="10.855"/><use xlink:href="#17" y="13.026"/><use xlink:href="#18" y="15.197"/><use xlink:href="#19" y="17.368"/><use xlink:href="#20" y="23.881"/><use xlink:href="#21" y="26.052"/><use xlink:href="#22" y="28.223"/><use xlink:href="#23" y="30.394"/><use xlink:href="#24" y="34.736"/><use xlink:href="#25" y="36.907"/><use xlink:href="#26" y="39.078"/></svg><svg x="1710"><use xlink:href="#a"/><use xlink:href="#b" x="86.996" y="41.224"/><use xlink:href="#13"/><use xlink:href="#14" y="2.171"/><use xlink:href="#15" y="4.342"/><use xlink:href="#16" y="6.513"/><use xlink:href="#17" y="8.684"/><use xlink:href="#18" y="10.855"/><use xlink:href="#19" y="13.026"/><use xlink:href="#20" y="19.539"/><use xlink:href="#21" y="21.71"/><use xlink:href="#22" y="23.881"/><use xlink:href="#23" y="26.052"/><use xlink:href="#24" y="30.394"/><use xlink:href="#25" y="32.565"/><use xlink:href="#26" y="34.736"/><use xlink:href="#27" y="36.907"/><use xlink:href="#28" y="39.078"/></svg><svg x="1800"><use xlink:href="#a"/><use xlink:href="#b" x="86.996" y="41.224"/><use xlink:href="#14"/><use xlink:href="#15" y="2.171"/><use xlink:href="#16" y="4.342"/><use xlink:href="#17" y="6.513"/><use xlink:href="#18" y="8.684"/><use xlink:href="#19" y="10.855"/><use xlink:href="#20" y="17.368"/><use xlink:href="#21" y="19.539"/><use xlink:href="#22" y="21.71"/><use xlink:href="#23" y="23.881"/><use xlink:href="#24" y="28.223"/><use xlink:href="#25" y="30.394"/><use xlink:href="#26" y="32.565"/><use xlink:href="#27" y="34.736"/><use xlink:href="#28" y="36.907"/></svg></svg></g></g></svg></svg>
Binary file
@@ -0,0 +1,214 @@
1
+ # crosscheck.config.yml
2
+ # This file is designed to be easily read and modified by coding agents.
3
+ # All fields are optional — crosscheck uses sensible defaults.
4
+
5
+ # ─── Deployment ──────────────────────────────────────────────────────────────
6
+ # Set automatically on first run of `crosscheck watch` or `crosscheck serve`.
7
+ # personal — monitor your own repos and orgs; review only PRs you author
8
+ # team — monitor org repos only; review all PRs from any author
9
+ # Absent = first-run prompt will ask you to choose.
10
+ # deployment: personal
11
+
12
+ # ─── Mode ────────────────────────────────────────────────────────────────────
13
+ # single-vendor: one AI reviews all PRs
14
+ # cross-vendor: each AI reviews the other's PRs (Claude ↔ Codex)
15
+ mode: cross-vendor
16
+
17
+ # ─── Clone protocol ──────────────────────────────────────────────────────────
18
+ # How crosscheck clones PR repos for review.
19
+ # ssh — git@github.com:owner/repo.git (uses your local SSH keys)
20
+ # https — https://github.com/owner/repo.git (uses GitHub token)
21
+ # Pick https if you have a multi-account SSH setup or your default SSH key
22
+ # cannot access target repos. Independent of `gh config get git_protocol`.
23
+ clone_protocol: ssh
24
+
25
+ # ─── Vendors ─────────────────────────────────────────────────────────────────
26
+ vendors:
27
+ codex:
28
+ enabled: true
29
+ model: o4-mini # o4-mini | o3 | gpt-4o (cost/quality tradeoff)
30
+ auth: subscription # subscription (device-auth OAuth) | api-key
31
+
32
+ claude:
33
+ enabled: true
34
+ model: sonnet # haiku | sonnet | opus
35
+ effort: medium # low | medium | high | max
36
+
37
+ # ─── Quality & Focus ─────────────────────────────────────────────────────────
38
+ quality:
39
+ tier: balanced # fast | balanced | thorough
40
+ #
41
+ # Tier determines the model and effort level used for each vendor:
42
+ #
43
+ # tier claude codex time cost
44
+ # ───────── ─────────────────── ─────────── ─────── ──────
45
+ # fast haiku · low o4-mini · low ~10s lowest
46
+ # balanced sonnet · medium o4-mini · med ~30s standard
47
+ # thorough sonnet · max o3 · high ~60s higher
48
+ #
49
+ # crosscheck onboard writes these automatically when you pick a tier.
50
+ # You can override individual vendor settings in the vendors: block below.
51
+
52
+ focus: # optional — narrows review scope
53
+ - security
54
+ - types
55
+ - performance
56
+ # - naming
57
+ # - test-coverage
58
+ # - documentation
59
+
60
+ custom_prompt: | # optional — appended to every review
61
+ Focus on correctness and security. Be concise.
62
+
63
+ # ─── Budget ──────────────────────────────────────────────────────────────────
64
+ budget:
65
+ codex_monthly_usd: 20 # null = unlimited (use if on subscription)
66
+ per_review_usd: 2.00 # hard stop per single review
67
+
68
+ # ── Orgs (watch/serve mode) ───────────────────────────────────────────────────
69
+ # Monitor entire orgs — all repos get covered with one webhook per org.
70
+ # Takes priority over `repos` when both are set.
71
+ orgs:
72
+ - motivation-labs
73
+ - codatta
74
+
75
+ # ─── Users ───────────────────────────────────────────────────────────────────
76
+ # Monitor all repos owned by personal GitHub accounts (non-org).
77
+ # At startup, crosscheck enumerates each user's repos and registers webhooks.
78
+ # Useful when your AI agents open PRs across many personal repos.
79
+ # Combines with `orgs` and `repos` — all configured sources are additive.
80
+ # users:
81
+ # - beingzy # your personal account
82
+ # - my-agent-login # a bot account that pushes to its own repos
83
+
84
+ # ─── Repos ───────────────────────────────────────────────────────────────────
85
+ # Omit entirely to auto-detect from `git remote` (useful in watch mode)
86
+ # repos: still works for monitoring specific repos only
87
+ # repos:
88
+ # - owner: acme
89
+ # name: specific-repo
90
+ repos:
91
+ - owner: codatta
92
+ name: my-repo
93
+
94
+ # ─── Routing ─────────────────────────────────────────────────────────────────
95
+ routing:
96
+ # Restrict reviews to PRs opened by these GitHub logins.
97
+ # Auto-filled with your login by `crosscheck init` or first `crosscheck watch`.
98
+ # Empty list = no author restriction (applies body-pattern check only).
99
+ # allowed_authors:
100
+ # - beingzy # your personal account (Claude Code runs as you)
101
+ # - my-org-bot # a dedicated bot account
102
+
103
+ # Author-based routing fallback — maps GitHub login → vendor origin.
104
+ # Used when no body / commit / branch pattern matches. Lets you skip the attribution
105
+ # footer requirement when an author consistently uses a single agent.
106
+ # beingzy: claude → PRs from beingzy treated as Claude-authored → Codex reviews them
107
+ # my-bot: codex → PRs from my-bot treated as Codex-authored → Claude reviews them
108
+ # NOTE: in `mode: cross-vendor` with BOTH vendors enabled, this map is bypassed —
109
+ # if the same author commits via both agents, a static route is structurally wrong.
110
+ # In that case, rely on attribution detection (body / commits / branch) and
111
+ # `fallback_reviewer` below for PRs with no attribution markers.
112
+ # author_routes:
113
+ # beingzy: claude
114
+
115
+ # Fallback reviewer when origin cannot be determined (no pattern/branch/route matched).
116
+ # 'auto' = pick whichever vendor is currently authenticated (codex first, then claude).
117
+ # 'codex' / 'claude' = always use that vendor.
118
+ # null = skip the PR (legacy cross-vendor behaviour).
119
+ fallback_reviewer: auto
120
+
121
+ # Branch-prefix routing — checked when body and commit patterns don't match.
122
+ # Agents should branch with these prefixes (claude/* and codex/*) so origin is
123
+ # always detectable even without attribution text in the PR body.
124
+ claude_branch_prefixes:
125
+ - "claude/"
126
+ codex_branch_prefixes:
127
+ - "codex/"
128
+
129
+ # Body and commit pattern matching — checked first, before branch prefix.
130
+ # Patterns are matched against both the PR body and commit messages (Co-Authored-By trailers).
131
+ codex_reviews_patterns:
132
+ - "Generated with \\[Claude Code\\]" # PR body attribution footer
133
+ - "Co-Authored-By: Claude" # commit trailer added by Claude Code
134
+ claude_reviews_patterns:
135
+ - "Generated with \\[OpenAI Codex\\]" # PR body attribution footer
136
+ - "Co-Authored-By: codex" # commit trailer added by Codex
137
+
138
+ # ─── Tunnel (watch mode only) ────────────────────────────────────────────────
139
+ # Controls how crosscheck watch receives GitHub webhook events on your laptop.
140
+ #
141
+ # localhost.run (default) — zero config, SSH tunnel, random URL each restart.
142
+ # No install required. URL changes on reconnect → webhook re-registered automatically.
143
+ # Limitation: events delivered while the tunnel is down are lost.
144
+ #
145
+ # smee — webhook relay via smee.io. Stable channel URL; events are queued and
146
+ # replayed even when your laptop is offline or watch is restarted.
147
+ # Setup:
148
+ # 1. npm install -g smee-client
149
+ # 2. Visit https://smee.io/new — copy the channel URL
150
+ # 3. Point your GitHub org/repo webhook Payload URL to the channel URL
151
+ # 4. Set tunnel.smee_channel below
152
+ #
153
+ # tunnel:
154
+ # backend: smee
155
+ # smee_channel: https://smee.io/your-channel-id
156
+
157
+ # ─── Server (serve mode only) ────────────────────────────────────────────────
158
+ server:
159
+ port: 7891
160
+ webhook_path: /webhook
161
+ # pid_file: ~/.crosscheck/crosscheck.pid # for daemon management
162
+
163
+ # ─── Post-Review Auto-Fix ────────────────────────────────────────────────────
164
+ # Controls HOW fixes are delivered after the agent applies them.
165
+ # Step sequencing (whether to run fix/recheck, trigger conditions, vendor assignment)
166
+ # is configured in ~/.crosscheck/workflow.yml.
167
+ #
168
+ post_review:
169
+ auto_fix:
170
+ delivery:
171
+ mode: pull_request # pull_request | commit | comment
172
+ # pull_request → fix PR targets the original branch; human approves before merge
173
+ # commit → fixes pushed directly onto the original PR branch
174
+ # comment → suggested fixes posted as review comments only
175
+ pr_title: "fix: address CR issues in #{original_pr_title}"
176
+ label: cr-autofix # GitHub label applied to the fix PR
177
+
178
+ # ─── Backtrace ───────────────────────────────────────────────────────────────
179
+ # On startup, scan all open PRs in the monitored scope and review any that have
180
+ # never received a [crosscheck] comment. Ensures coverage for PRs opened while
181
+ # crosscheck was offline or before it was first set up.
182
+ # Off by default — enable with the config below or pass --backtrace at startup.
183
+ # backtrace:
184
+ # enabled: true # set to true to enable the startup scan (or pass --backtrace)
185
+
186
+ # ─── Logs ────────────────────────────────────────────────────────────────────
187
+ # Structured debug logs written to ~/.crosscheck/logs/YYYY-MM-DD.ndjson
188
+ # Each line is a JSON object: { ts, level, event, ...context }
189
+ logs:
190
+ enabled: true
191
+ retention_days: 7 # delete files older than N days (min: 1, max: 30)
192
+
193
+ # ─── Display ─────────────────────────────────────────────────────────────────
194
+ # Terminal output theme for crosscheck watch.
195
+ # Override individual colors using chalk color names (red, green, blue, cyan,
196
+ # yellow, magenta, white, gray, dim, bold) or hex values (#rrggbb).
197
+ # display:
198
+ # theme:
199
+ # bar_fill: blue # filled █ segments on the PR size bar
200
+ # bar_empty: dim # empty ░ segments (all bars)
201
+ # cr_approve: green # CR bar + verdict label when APPROVE
202
+ # cr_needs_work: yellow # CR bar + verdict label when NEEDS WORK
203
+ # cr_block: red # CR bar + verdict label when BLOCK
204
+ # fix_fill: cyan # filled segments on the FIX bar
205
+
206
+
207
+ # ─── Branding ────────────────────────────────────────────────────────────────
208
+ # Customize how crosscheck identifies itself in review comments.
209
+ # Useful for teams, shared services, or personal branding.
210
+ # brand:
211
+ # service_name: crosscheck # shown in comment headers (default: crosscheck)
212
+ # comment_header: "" # text prepended to every review comment
213
+ # comment_footer: "" # text appended to every review comment
214
+ # reviewer_attribution: "" # replaces "Reviewed by {vendor}" attribution line
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=annotation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/annotation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildAnnotation, buildCommitTrailers, parseAnnotation, parseAnnotationFieldsFenced, } from '../lib/annotation.js';
3
+ describe('crosscheck annotation contract', () => {
4
+ const stepTypes = ['review', 'recheck', 'fix', 'conflict-resolve'];
5
+ for (const type of stepTypes) {
6
+ it(`round-trips ${type} annotations`, () => {
7
+ const annotation = {
8
+ origin: 'claude',
9
+ reviewer: 'codex',
10
+ model: 'gpt-5',
11
+ type,
12
+ round: 2,
13
+ verdict: 'NEEDS_WORK',
14
+ service: 'crosscheck',
15
+ };
16
+ expect(parseAnnotation(buildAnnotation(annotation))).toEqual(annotation);
17
+ });
18
+ }
19
+ it('pins the emitted field order per type for snapshot stability', () => {
20
+ const snapshots = stepTypes.map(type => buildAnnotation({
21
+ origin: 'claude',
22
+ reviewer: 'codex',
23
+ model: 'gpt-5',
24
+ type,
25
+ round: 3,
26
+ verdict: 'BLOCK',
27
+ service: 'crosscheck',
28
+ }));
29
+ expect(snapshots).toEqual([
30
+ '<!-- crosscheck: origin=claude reviewer=codex model=gpt-5 type=review round=3 verdict=BLOCK service=crosscheck -->',
31
+ '<!-- crosscheck: origin=claude reviewer=codex model=gpt-5 type=recheck round=3 verdict=BLOCK service=crosscheck -->',
32
+ '<!-- crosscheck: origin=claude reviewer=codex model=gpt-5 type=fix round=3 verdict=BLOCK service=crosscheck -->',
33
+ '<!-- crosscheck: origin=claude reviewer=codex model=gpt-5 type=conflict-resolve round=3 verdict=BLOCK service=crosscheck -->',
34
+ ]);
35
+ });
36
+ it('appends optional head sha after stable v2 fields', () => {
37
+ const annotation = buildAnnotation({
38
+ origin: 'claude',
39
+ reviewer: 'codex',
40
+ model: 'gpt-5',
41
+ type: 'review',
42
+ round: 3,
43
+ verdict: 'BLOCK',
44
+ service: 'crosscheck',
45
+ sha: 'abc1234',
46
+ });
47
+ expect(annotation).toBe('<!-- crosscheck: origin=claude reviewer=codex model=gpt-5 type=review round=3 verdict=BLOCK service=crosscheck sha=abc1234 -->');
48
+ expect(parseAnnotation(annotation)).toEqual({
49
+ origin: 'claude',
50
+ reviewer: 'codex',
51
+ model: 'gpt-5',
52
+ type: 'review',
53
+ round: 3,
54
+ verdict: 'BLOCK',
55
+ service: 'crosscheck',
56
+ sha: 'abc1234',
57
+ });
58
+ });
59
+ it('preserves bare marker handling when sha-like fields are absent', () => {
60
+ expect(parseAnnotation('<!-- crosscheck: fix_applied -->')).toBeNull();
61
+ });
62
+ it('parses legacy annotations with documented defaults', () => {
63
+ expect(parseAnnotation('<!-- crosscheck: origin=claude reviewer=codex verdict=APPROVE type=review -->')).toEqual({
64
+ origin: 'claude',
65
+ reviewer: 'codex',
66
+ model: 'default',
67
+ type: 'review',
68
+ round: 1,
69
+ verdict: 'APPROVE',
70
+ service: 'crosscheck',
71
+ });
72
+ });
73
+ it('keeps verdict-less review annotations parseable for freshness detection', () => {
74
+ expect(parseAnnotation('<!-- crosscheck: origin=claude reviewer=codex type=review -->')).toEqual({
75
+ origin: 'claude',
76
+ reviewer: 'codex',
77
+ model: 'default',
78
+ type: 'review',
79
+ round: 1,
80
+ verdict: 'UNKNOWN',
81
+ service: 'crosscheck',
82
+ });
83
+ });
84
+ it('parses fields order-independently and ignores unknown fields', () => {
85
+ expect(parseAnnotation('<!-- crosscheck: service=custom verdict=BLOCK extra=yes round=4 type=recheck model=claude-opus reviewer=claude origin=codex -->')).toEqual({
86
+ origin: 'codex',
87
+ reviewer: 'claude',
88
+ model: 'claude-opus',
89
+ type: 'recheck',
90
+ round: 4,
91
+ verdict: 'BLOCK',
92
+ service: 'custom',
93
+ });
94
+ });
95
+ it('uses the footer annotation when the body quotes older markers', () => {
96
+ const body = 'Quoted marker `<!-- crosscheck: origin=claude reviewer=codex verdict=BLOCK type=review -->`\n\n'
97
+ + '<!-- crosscheck: origin=claude reviewer=codex model=gpt-5 type=recheck round=2 verdict=APPROVE service=crosscheck -->';
98
+ expect(parseAnnotation(body)?.type).toBe('recheck');
99
+ });
100
+ it('returns null for bare summary markers', () => {
101
+ expect(parseAnnotation('<!-- crosscheck: fix_applied -->')).toBeNull();
102
+ });
103
+ it('skips fenced annotations and parses the footer annotation', () => {
104
+ const body = [
105
+ 'Example:',
106
+ '```',
107
+ '<!-- crosscheck: origin=claude reviewer=codex type=review verdict=BLOCK -->',
108
+ '```',
109
+ '<!-- crosscheck: origin=codex reviewer=claude type=recheck verdict=APPROVE -->',
110
+ ].join('\n');
111
+ expect(parseAnnotation(body)?.type).toBe('recheck');
112
+ expect(parseAnnotation(body)?.verdict).toBe('APPROVE');
113
+ });
114
+ it('exposes bare summary markers through the fenced field parser', () => {
115
+ const fields = parseAnnotationFieldsFenced('<!-- crosscheck: fix_applied -->');
116
+ expect(fields?.get('__marker__')).toBe('fix_applied');
117
+ });
118
+ });
119
+ describe('crosscheck commit trailers', () => {
120
+ it('emits reviewer, model, step, and service trailers', () => {
121
+ expect(buildCommitTrailers({
122
+ reviewer: 'claude',
123
+ model: 'default',
124
+ step: 'fix',
125
+ service: 'crosscheck',
126
+ })).toBe([
127
+ 'Crosscheck-Reviewer: claude',
128
+ 'Crosscheck-Model: default',
129
+ 'Crosscheck-Step: fix',
130
+ 'Crosscheck-Service: crosscheck',
131
+ ].join('\n'));
132
+ });
133
+ });
134
+ //# sourceMappingURL=annotation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation.test.js","sourceRoot":"","sources":["../../src/__tests__/annotation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backtrace.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backtrace.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/backtrace.test.ts"],"names":[],"mappings":""}