@humanbased/crosscheck 1.2.0-beta.81 → 1.2.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 (314) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +375 -182
  3. package/README.zh.md +1 -1
  4. package/crosscheck.config.example.yml +9 -101
  5. package/dist/__tests__/board.test.js +0 -11
  6. package/dist/__tests__/board.test.js.map +1 -1
  7. package/dist/__tests__/codex.test.js +27 -14
  8. package/dist/__tests__/codex.test.js.map +1 -1
  9. package/dist/__tests__/comment-bodies.test.js +1 -49
  10. package/dist/__tests__/comment-bodies.test.js.map +1 -1
  11. package/dist/__tests__/conflict-resolve.test.js +1 -44
  12. package/dist/__tests__/conflict-resolve.test.js.map +1 -1
  13. package/dist/__tests__/fix.test.js +0 -33
  14. package/dist/__tests__/fix.test.js.map +1 -1
  15. package/dist/__tests__/onboard-preservation.test.js +3 -59
  16. package/dist/__tests__/onboard-preservation.test.js.map +1 -1
  17. package/dist/__tests__/optimize.test.js +0 -2
  18. package/dist/__tests__/optimize.test.js.map +1 -1
  19. package/dist/__tests__/repo-picker.test.js +1 -7
  20. package/dist/__tests__/repo-picker.test.js.map +1 -1
  21. package/dist/__tests__/review-comment-body.test.js +0 -35
  22. package/dist/__tests__/review-comment-body.test.js.map +1 -1
  23. package/dist/__tests__/review-models.test.js +3 -19
  24. package/dist/__tests__/review-models.test.js.map +1 -1
  25. package/dist/__tests__/runner.test.js +1 -29
  26. package/dist/__tests__/runner.test.js.map +1 -1
  27. package/dist/cli.js +0 -29
  28. package/dist/cli.js.map +1 -1
  29. package/dist/commands/onboard.d.ts +3 -36
  30. package/dist/commands/onboard.d.ts.map +1 -1
  31. package/dist/commands/onboard.js +42 -233
  32. package/dist/commands/onboard.js.map +1 -1
  33. package/dist/commands/review.d.ts.map +1 -1
  34. package/dist/commands/review.js +6 -65
  35. package/dist/commands/review.js.map +1 -1
  36. package/dist/commands/run.d.ts.map +1 -1
  37. package/dist/commands/run.js +7 -45
  38. package/dist/commands/run.js.map +1 -1
  39. package/dist/commands/status.d.ts.map +1 -1
  40. package/dist/commands/status.js +1 -53
  41. package/dist/commands/status.js.map +1 -1
  42. package/dist/commands/watch.d.ts.map +1 -1
  43. package/dist/commands/watch.js +12 -90
  44. package/dist/commands/watch.js.map +1 -1
  45. package/dist/config/loader.d.ts +1 -3
  46. package/dist/config/loader.d.ts.map +1 -1
  47. package/dist/config/loader.js +0 -13
  48. package/dist/config/loader.js.map +1 -1
  49. package/dist/config/review-model-tiers.json +3 -3
  50. package/dist/config/schema.d.ts +15 -261
  51. package/dist/config/schema.d.ts.map +1 -1
  52. package/dist/config/schema.js +8 -90
  53. package/dist/config/schema.js.map +1 -1
  54. package/dist/github/client.d.ts +1 -21
  55. package/dist/github/client.d.ts.map +1 -1
  56. package/dist/github/client.js +7 -46
  57. package/dist/github/client.js.map +1 -1
  58. package/dist/github/webhook.d.ts +0 -4
  59. package/dist/github/webhook.d.ts.map +1 -1
  60. package/dist/github/webhook.js.map +1 -1
  61. package/dist/issues/ticket-ref.d.ts.map +1 -1
  62. package/dist/issues/ticket-ref.js +5 -6
  63. package/dist/issues/ticket-ref.js.map +1 -1
  64. package/dist/lib/annotation.d.ts +0 -7
  65. package/dist/lib/annotation.d.ts.map +1 -1
  66. package/dist/lib/annotation.js +1 -11
  67. package/dist/lib/annotation.js.map +1 -1
  68. package/dist/lib/board.d.ts +0 -3
  69. package/dist/lib/board.d.ts.map +1 -1
  70. package/dist/lib/board.js +2 -4
  71. package/dist/lib/board.js.map +1 -1
  72. package/dist/lib/clone.d.ts +0 -1
  73. package/dist/lib/clone.d.ts.map +1 -1
  74. package/dist/lib/clone.js +10 -32
  75. package/dist/lib/clone.js.map +1 -1
  76. package/dist/lib/comment-bodies.d.ts +0 -37
  77. package/dist/lib/comment-bodies.d.ts.map +1 -1
  78. package/dist/lib/comment-bodies.js +9 -47
  79. package/dist/lib/comment-bodies.js.map +1 -1
  80. package/dist/lib/repo-picker.d.ts +0 -3
  81. package/dist/lib/repo-picker.d.ts.map +1 -1
  82. package/dist/lib/repo-picker.js +9 -45
  83. package/dist/lib/repo-picker.js.map +1 -1
  84. package/dist/lib/review-models.d.ts +2 -15
  85. package/dist/lib/review-models.d.ts.map +1 -1
  86. package/dist/lib/review-models.js +6 -26
  87. package/dist/lib/review-models.js.map +1 -1
  88. package/dist/lib/runner.d.ts +0 -92
  89. package/dist/lib/runner.d.ts.map +1 -1
  90. package/dist/lib/runner.js +54 -470
  91. package/dist/lib/runner.js.map +1 -1
  92. package/dist/lib/workflow.d.ts +0 -9
  93. package/dist/lib/workflow.d.ts.map +1 -1
  94. package/dist/lib/workflow.js +0 -20
  95. package/dist/lib/workflow.js.map +1 -1
  96. package/dist/reviewers/claude.d.ts +1 -4
  97. package/dist/reviewers/claude.d.ts.map +1 -1
  98. package/dist/reviewers/claude.js +7 -39
  99. package/dist/reviewers/claude.js.map +1 -1
  100. package/dist/reviewers/codex.d.ts +1 -3
  101. package/dist/reviewers/codex.d.ts.map +1 -1
  102. package/dist/reviewers/codex.js +70 -76
  103. package/dist/reviewers/codex.js.map +1 -1
  104. package/dist/reviewers/conflict-resolve.d.ts +1 -3
  105. package/dist/reviewers/conflict-resolve.d.ts.map +1 -1
  106. package/dist/reviewers/conflict-resolve.js +6 -21
  107. package/dist/reviewers/conflict-resolve.js.map +1 -1
  108. package/dist/reviewers/fix.d.ts +2 -5
  109. package/dist/reviewers/fix.d.ts.map +1 -1
  110. package/dist/reviewers/fix.js +10 -26
  111. package/dist/reviewers/fix.js.map +1 -1
  112. package/get-started.md +11 -207
  113. package/package.json +3 -4
  114. package/assets/icon-256.png +0 -0
  115. package/assets/linear-comment.svg +0 -18
  116. package/assets/linear-onboard.svg +0 -30
  117. package/assets/linear-status.svg +0 -23
  118. package/assets/linear-test.svg +0 -34
  119. package/assets/skills/code-review/.crosscheck-skill.json +0 -9
  120. package/assets/skills/code-review/LICENSE +0 -21
  121. package/assets/skills/code-review/SKILL.md +0 -89
  122. package/assets/skills/code-review/agents/openai.yaml +0 -3
  123. package/assets/skills/code-review-skill/.crosscheck-skill.json +0 -9
  124. package/assets/skills/code-review-skill/LICENSE +0 -21
  125. package/assets/skills/code-review-skill/SKILL.md +0 -231
  126. package/assets/skills/code-review-skill/assets/pr-review-template.md +0 -137
  127. package/assets/skills/code-review-skill/assets/review-checklist.md +0 -123
  128. package/assets/skills/code-review-skill/reference/angular.md +0 -768
  129. package/assets/skills/code-review-skill/reference/architecture-review-guide.md +0 -472
  130. package/assets/skills/code-review-skill/reference/c.md +0 -890
  131. package/assets/skills/code-review-skill/reference/code-quality-universal.md +0 -488
  132. package/assets/skills/code-review-skill/reference/code-review-best-practices.md +0 -136
  133. package/assets/skills/code-review-skill/reference/common-bugs-checklist.md +0 -286
  134. package/assets/skills/code-review-skill/reference/cpp.md +0 -893
  135. package/assets/skills/code-review-skill/reference/cross-cutting/async-concurrency-patterns.md +0 -515
  136. package/assets/skills/code-review-skill/reference/cross-cutting/error-handling-principles.md +0 -492
  137. package/assets/skills/code-review-skill/reference/cross-cutting/n-plus-one-queries.md +0 -309
  138. package/assets/skills/code-review-skill/reference/cross-cutting/sql-injection-prevention.md +0 -308
  139. package/assets/skills/code-review-skill/reference/cross-cutting/xss-prevention.md +0 -264
  140. package/assets/skills/code-review-skill/reference/csharp.md +0 -525
  141. package/assets/skills/code-review-skill/reference/css-less-sass.md +0 -661
  142. package/assets/skills/code-review-skill/reference/django.md +0 -985
  143. package/assets/skills/code-review-skill/reference/fastapi.md +0 -580
  144. package/assets/skills/code-review-skill/reference/go.md +0 -993
  145. package/assets/skills/code-review-skill/reference/java.md +0 -409
  146. package/assets/skills/code-review-skill/reference/java8.md +0 -586
  147. package/assets/skills/code-review-skill/reference/kotlin.md +0 -1018
  148. package/assets/skills/code-review-skill/reference/nestjs.md +0 -593
  149. package/assets/skills/code-review-skill/reference/performance-review-guide.md +0 -816
  150. package/assets/skills/code-review-skill/reference/php.md +0 -684
  151. package/assets/skills/code-review-skill/reference/python.md +0 -1073
  152. package/assets/skills/code-review-skill/reference/qt.md +0 -757
  153. package/assets/skills/code-review-skill/reference/react.md +0 -871
  154. package/assets/skills/code-review-skill/reference/ruby.md +0 -964
  155. package/assets/skills/code-review-skill/reference/rust.md +0 -846
  156. package/assets/skills/code-review-skill/reference/security-review-guide.md +0 -494
  157. package/assets/skills/code-review-skill/reference/svelte.md +0 -1064
  158. package/assets/skills/code-review-skill/reference/swift.md +0 -936
  159. package/assets/skills/code-review-skill/reference/typescript.md +0 -1016
  160. package/assets/skills/code-review-skill/reference/vue.md +0 -924
  161. package/assets/skills/code-review-skill/reference/zig.md +0 -440
  162. package/assets/skills/code-review-skill/scripts/pr-analyzer.py +0 -435
  163. package/assets/skills/code-review-skill/scripts/test_pr_analyzer.py +0 -380
  164. package/assets/skills/codebase-design/.crosscheck-skill.json +0 -9
  165. package/assets/skills/codebase-design/DEEPENING.md +0 -37
  166. package/assets/skills/codebase-design/DESIGN-IT-TWICE.md +0 -44
  167. package/assets/skills/codebase-design/LICENSE +0 -21
  168. package/assets/skills/codebase-design/SKILL.md +0 -114
  169. package/assets/skills/codebase-design/agents/openai.yaml +0 -3
  170. package/assets/skills/diagnosing-bugs/.crosscheck-skill.json +0 -9
  171. package/assets/skills/diagnosing-bugs/LICENSE +0 -21
  172. package/assets/skills/diagnosing-bugs/SKILL.md +0 -134
  173. package/assets/skills/diagnosing-bugs/agents/openai.yaml +0 -3
  174. package/assets/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
  175. package/dist/__tests__/can-write-verdict.test.d.ts +0 -2
  176. package/dist/__tests__/can-write-verdict.test.d.ts.map +0 -1
  177. package/dist/__tests__/can-write-verdict.test.js +0 -31
  178. package/dist/__tests__/can-write-verdict.test.js.map +0 -1
  179. package/dist/__tests__/linear-branding.test.d.ts +0 -2
  180. package/dist/__tests__/linear-branding.test.d.ts.map +0 -1
  181. package/dist/__tests__/linear-branding.test.js +0 -156
  182. package/dist/__tests__/linear-branding.test.js.map +0 -1
  183. package/dist/__tests__/linear-client.test.d.ts +0 -2
  184. package/dist/__tests__/linear-client.test.d.ts.map +0 -1
  185. package/dist/__tests__/linear-client.test.js +0 -120
  186. package/dist/__tests__/linear-client.test.js.map +0 -1
  187. package/dist/__tests__/linear-comment.test.d.ts +0 -2
  188. package/dist/__tests__/linear-comment.test.d.ts.map +0 -1
  189. package/dist/__tests__/linear-comment.test.js +0 -151
  190. package/dist/__tests__/linear-comment.test.js.map +0 -1
  191. package/dist/__tests__/linear-identity.test.d.ts +0 -2
  192. package/dist/__tests__/linear-identity.test.d.ts.map +0 -1
  193. package/dist/__tests__/linear-identity.test.js +0 -253
  194. package/dist/__tests__/linear-identity.test.js.map +0 -1
  195. package/dist/__tests__/linear-notify.test.d.ts +0 -2
  196. package/dist/__tests__/linear-notify.test.d.ts.map +0 -1
  197. package/dist/__tests__/linear-notify.test.js +0 -144
  198. package/dist/__tests__/linear-notify.test.js.map +0 -1
  199. package/dist/__tests__/linear-ref.test.d.ts +0 -2
  200. package/dist/__tests__/linear-ref.test.d.ts.map +0 -1
  201. package/dist/__tests__/linear-ref.test.js +0 -261
  202. package/dist/__tests__/linear-ref.test.js.map +0 -1
  203. package/dist/__tests__/linear-test-ref.test.d.ts +0 -2
  204. package/dist/__tests__/linear-test-ref.test.d.ts.map +0 -1
  205. package/dist/__tests__/linear-test-ref.test.js +0 -81
  206. package/dist/__tests__/linear-test-ref.test.js.map +0 -1
  207. package/dist/__tests__/linear-verify.test.d.ts +0 -2
  208. package/dist/__tests__/linear-verify.test.d.ts.map +0 -1
  209. package/dist/__tests__/linear-verify.test.js +0 -132
  210. package/dist/__tests__/linear-verify.test.js.map +0 -1
  211. package/dist/__tests__/linear-worker.test.d.ts +0 -2
  212. package/dist/__tests__/linear-worker.test.d.ts.map +0 -1
  213. package/dist/__tests__/linear-worker.test.js +0 -83
  214. package/dist/__tests__/linear-worker.test.js.map +0 -1
  215. package/dist/__tests__/linear-write-possible.test.d.ts +0 -2
  216. package/dist/__tests__/linear-write-possible.test.d.ts.map +0 -1
  217. package/dist/__tests__/linear-write-possible.test.js +0 -30
  218. package/dist/__tests__/linear-write-possible.test.js.map +0 -1
  219. package/dist/__tests__/repository-guidance.test.d.ts +0 -2
  220. package/dist/__tests__/repository-guidance.test.d.ts.map +0 -1
  221. package/dist/__tests__/repository-guidance.test.js +0 -107
  222. package/dist/__tests__/repository-guidance.test.js.map +0 -1
  223. package/dist/__tests__/review-strategy.test.d.ts +0 -2
  224. package/dist/__tests__/review-strategy.test.d.ts.map +0 -1
  225. package/dist/__tests__/review-strategy.test.js +0 -397
  226. package/dist/__tests__/review-strategy.test.js.map +0 -1
  227. package/dist/__tests__/skill-attribution.test.d.ts +0 -2
  228. package/dist/__tests__/skill-attribution.test.d.ts.map +0 -1
  229. package/dist/__tests__/skill-attribution.test.js +0 -53
  230. package/dist/__tests__/skill-attribution.test.js.map +0 -1
  231. package/dist/__tests__/skill-broker.test.d.ts +0 -2
  232. package/dist/__tests__/skill-broker.test.d.ts.map +0 -1
  233. package/dist/__tests__/skill-broker.test.js +0 -144
  234. package/dist/__tests__/skill-broker.test.js.map +0 -1
  235. package/dist/__tests__/skill-catalog.test.d.ts +0 -2
  236. package/dist/__tests__/skill-catalog.test.d.ts.map +0 -1
  237. package/dist/__tests__/skill-catalog.test.js +0 -40
  238. package/dist/__tests__/skill-catalog.test.js.map +0 -1
  239. package/dist/__tests__/skill-installer.test.d.ts +0 -2
  240. package/dist/__tests__/skill-installer.test.d.ts.map +0 -1
  241. package/dist/__tests__/skill-installer.test.js +0 -96
  242. package/dist/__tests__/skill-installer.test.js.map +0 -1
  243. package/dist/__tests__/skills-config.test.d.ts +0 -2
  244. package/dist/__tests__/skills-config.test.d.ts.map +0 -1
  245. package/dist/__tests__/skills-config.test.js +0 -12
  246. package/dist/__tests__/skills-config.test.js.map +0 -1
  247. package/dist/commands/linear-test.d.ts +0 -18
  248. package/dist/commands/linear-test.d.ts.map +0 -1
  249. package/dist/commands/linear-test.js +0 -130
  250. package/dist/commands/linear-test.js.map +0 -1
  251. package/dist/commands/skill.d.ts +0 -2
  252. package/dist/commands/skill.d.ts.map +0 -1
  253. package/dist/commands/skill.js +0 -16
  254. package/dist/commands/skill.js.map +0 -1
  255. package/dist/config/review-strategy.json +0 -204
  256. package/dist/lib/repository-guidance.d.ts +0 -2
  257. package/dist/lib/repository-guidance.d.ts.map +0 -1
  258. package/dist/lib/repository-guidance.js +0 -55
  259. package/dist/lib/repository-guidance.js.map +0 -1
  260. package/dist/lib/review-strategy.d.ts +0 -92
  261. package/dist/lib/review-strategy.d.ts.map +0 -1
  262. package/dist/lib/review-strategy.js +0 -282
  263. package/dist/lib/review-strategy.js.map +0 -1
  264. package/dist/linear/client.d.ts +0 -18
  265. package/dist/linear/client.d.ts.map +0 -1
  266. package/dist/linear/client.js +0 -67
  267. package/dist/linear/client.js.map +0 -1
  268. package/dist/linear/comment.d.ts +0 -20
  269. package/dist/linear/comment.d.ts.map +0 -1
  270. package/dist/linear/comment.js +0 -57
  271. package/dist/linear/comment.js.map +0 -1
  272. package/dist/linear/identity.d.ts +0 -59
  273. package/dist/linear/identity.d.ts.map +0 -1
  274. package/dist/linear/identity.js +0 -187
  275. package/dist/linear/identity.js.map +0 -1
  276. package/dist/linear/notify.d.ts +0 -35
  277. package/dist/linear/notify.d.ts.map +0 -1
  278. package/dist/linear/notify.js +0 -76
  279. package/dist/linear/notify.js.map +0 -1
  280. package/dist/linear/ref.d.ts +0 -13
  281. package/dist/linear/ref.d.ts.map +0 -1
  282. package/dist/linear/ref.js +0 -90
  283. package/dist/linear/ref.js.map +0 -1
  284. package/dist/linear/verify.d.ts +0 -26
  285. package/dist/linear/verify.d.ts.map +0 -1
  286. package/dist/linear/verify.js +0 -67
  287. package/dist/linear/verify.js.map +0 -1
  288. package/dist/skills/attribution.d.ts +0 -4
  289. package/dist/skills/attribution.d.ts.map +0 -1
  290. package/dist/skills/attribution.js +0 -14
  291. package/dist/skills/attribution.js.map +0 -1
  292. package/dist/skills/broker-server.d.ts +0 -2
  293. package/dist/skills/broker-server.d.ts.map +0 -1
  294. package/dist/skills/broker-server.js +0 -17
  295. package/dist/skills/broker-server.js.map +0 -1
  296. package/dist/skills/broker.d.ts +0 -42
  297. package/dist/skills/broker.d.ts.map +0 -1
  298. package/dist/skills/broker.js +0 -285
  299. package/dist/skills/broker.js.map +0 -1
  300. package/dist/skills/catalog.d.ts +0 -28
  301. package/dist/skills/catalog.d.ts.map +0 -1
  302. package/dist/skills/catalog.js +0 -104
  303. package/dist/skills/catalog.js.map +0 -1
  304. package/dist/skills/installer.d.ts +0 -10
  305. package/dist/skills/installer.d.ts.map +0 -1
  306. package/dist/skills/installer.js +0 -138
  307. package/dist/skills/installer.js.map +0 -1
  308. package/dist/skills/integrity.d.ts +0 -4
  309. package/dist/skills/integrity.d.ts.map +0 -1
  310. package/dist/skills/integrity.js +0 -36
  311. package/dist/skills/integrity.js.map +0 -1
  312. package/docs/dynamic-thoroughness.md +0 -738
  313. package/docs/linear-identity-contract.md +0 -139
  314. package/docs/linear-identity.md +0 -293
@@ -1,282 +0,0 @@
1
- // Resolves the per-PR review strategy: which class a PR falls into, which tier
2
- // and effort that class earns, and which steps run. Reads the versioned policy
3
- // in config/review-strategy.json so the routing decision and the explanation
4
- // posted on the PR come from one place and cannot drift apart.
5
- //
6
- // Two rules constrain what classification may conclude (see
7
- // docs/dynamic-thoroughness.md §6.8):
8
- // - it may set a FLOOR, or promote on CONSEQUENCE (a security path is
9
- // reviewed thoroughly because a miss there is expensive);
10
- // - it may NOT predict that a PR will be hard. Static features do not support
11
- // that inference — difficulty is discovered by reviewing, so escalation is
12
- // driven by measured non-convergence instead (see escalate()).
13
- import { createRequire } from 'module';
14
- import { z } from 'zod';
15
- const require = createRequire(import.meta.url);
16
- /** Ordered effort ladder. Index-based so escalation is a step, not a lookup. */
17
- const EFFORT_LADDER = ['none', 'low', 'medium', 'high', 'xhigh', 'max'];
18
- const MatchSchema = z.object({
19
- all_files_match: z.array(z.string()).optional(),
20
- any_path_matches: z.array(z.string()).optional(),
21
- or_labels: z.array(z.string()).optional(),
22
- or_hotfix_to_default_branch: z.boolean().optional(),
23
- additions_max: z.number().optional(),
24
- deletions_min: z.number().optional(),
25
- doc_fraction_min: z.number().optional(),
26
- config_fraction_min: z.number().optional(),
27
- source_files_max: z.number().optional(),
28
- files_max: z.number().optional(),
29
- src_churn_max: z.number().optional(),
30
- });
31
- const PRClassSchema = z.object({
32
- id: z.string(),
33
- label: z.string(),
34
- match: MatchSchema,
35
- tier: z.enum(['fast', 'balanced', 'thorough']).nullable(),
36
- // Not z.string(): a typo ("higgh") would validate, then read as -1 in
37
- // clampEffort and silently drop the whole class to the model's lowest level.
38
- effort: z.enum(EFFORT_LADDER).nullable(),
39
- steps: z.array(z.string()),
40
- focus: z.string().optional(),
41
- reason: z.string(),
42
- });
43
- const StrategySchema = z.object({
44
- version: z.string(),
45
- updated: z.string(),
46
- models: z.record(z.string(), z.object({
47
- vendor: z.string(),
48
- effort_levels: z.array(z.string()),
49
- }).passthrough()),
50
- banned_models: z.array(z.object({ model: z.string(), reason: z.string() })).default([]),
51
- vendors: z.record(z.string(), z.object({
52
- tiers: z.record(z.string(), z.string()),
53
- }).passthrough()),
54
- domains: z.record(z.string(), z.unknown()),
55
- // .min(1): resolveReviewStrategy falls back to the last entry, which is
56
- // undefined — and throws on `cls.id` — for an empty list.
57
- pr_classes: z.array(PRClassSchema).min(1),
58
- ladder: z.object({
59
- max_blocking_findings: z.number(),
60
- max_rounds: z.number(),
61
- max_wall_clock_min: z.number(),
62
- effort_fallback: z.string(),
63
- }).passthrough(),
64
- }).passthrough();
65
- const raw = require('../config/review-strategy.json');
66
- const STRATEGY = StrategySchema.parse(raw);
67
- const TIER_LADDER = ['fast', 'balanced', 'thorough'];
68
- /** Position on EFFORT_LADDER; -1 for null or an unrecognised level. */
69
- function effortIndex(effort) {
70
- return effort === null ? -1 : EFFORT_LADDER.indexOf(effort);
71
- }
72
- const FRONTEND_EXT = /\.(tsx|jsx|vue|svelte|css|scss|less|html)$/i;
73
- const BACKEND_EXT = /\.(py|go|rs|java|rb|php|sql|ts)$/i;
74
- const DOC_EXT = /\.(md|mdx|rst|adoc)$/i;
75
- const CONFIG_EXT = /(\.(json|ya?ml|toml|ini|lock|txt|csv|svg|png|jpe?g)$|^\.github\/)/i;
76
- // Anchored on path segments and extensions. Unanchored, `spec` matched
77
- // src/lib/pr-spec.ts and `test` matched any latest.ts, routing ordinary source
78
- // PRs to test_only with a test-focused prompt.
79
- const TEST_PATH = /((^|\/)(__tests__|tests?|e2e|fixtures?)(\/|$)|\.(test|spec)\.)/i;
80
- const GENERATED = /((^|\/)(dist|build|node_modules)\/|\.(lock|sum)$|package-lock|pnpm-lock|yarn\.lock|\.(pb|_pb2)\.[a-z]+$|(^|\/)generated\/)/i;
81
- function srcChurnFraction(files) {
82
- if (files.length === 0)
83
- return { doc: 0, config: 0, source: 0 };
84
- const doc = files.filter(f => DOC_EXT.test(f)).length / files.length;
85
- const config = files.filter(f => CONFIG_EXT.test(f)).length / files.length;
86
- const source = files.filter(f => !DOC_EXT.test(f) && !CONFIG_EXT.test(f) && !GENERATED.test(f) && !TEST_PATH.test(f)).length;
87
- return { doc, config, source };
88
- }
89
- /**
90
- * Frontend vs backend, by file-extension majority. `mixed` and `unknown` both
91
- * fall back to backend — the conservative default, because the backend
92
- * preference list is `measured` while the frontend list is still a hypothesis.
93
- */
94
- export function detectDomain(files) {
95
- const fe = files.filter(f => FRONTEND_EXT.test(f)).length;
96
- const be = files.filter(f => BACKEND_EXT.test(f)).length;
97
- return fe > be ? 'frontend' : 'backend';
98
- }
99
- function matches(cls, pr) {
100
- const m = cls.match;
101
- const { files, additions, deletions } = pr;
102
- // An empty match object is the fallthrough class.
103
- if (Object.keys(m).length === 0)
104
- return true;
105
- // Never classify an empty file list as anything but the fallthrough.
106
- if (files.length === 0)
107
- return false;
108
- if (m.all_files_match) {
109
- const res = m.all_files_match.map(p => new RegExp(p, 'i'));
110
- if (!files.every(f => res.some(r => r.test(f))))
111
- return false;
112
- }
113
- // `any_path_matches` is an OR-group with labels and the hotfix rule: any one
114
- // of the three promotes. Only evaluated when the class declares them.
115
- if (m.any_path_matches || m.or_labels || m.or_hotfix_to_default_branch) {
116
- const pathHit = m.any_path_matches
117
- ? files.some(f => m.any_path_matches.some(p => new RegExp(p, 'i').test(f)))
118
- : false;
119
- const labelHit = m.or_labels ? (pr.labels ?? []).some(l => m.or_labels.includes(l)) : false;
120
- const hotfixHit = m.or_hotfix_to_default_branch === true
121
- && /^hotfix/i.test(pr.title ?? '')
122
- && pr.baseRef !== undefined
123
- && pr.baseRef === pr.defaultBranch;
124
- if (!pathHit && !labelHit && !hotfixHit)
125
- return false;
126
- }
127
- if (m.additions_max !== undefined && additions > m.additions_max)
128
- return false;
129
- // A floor on deletions, not merely "some deletions": a +2/-2 typo fix has
130
- // near-zero additions too, and is a modification rather than a removal.
131
- if (m.deletions_min !== undefined && deletions < m.deletions_min)
132
- return false;
133
- const frac = srcChurnFraction(files);
134
- if (m.doc_fraction_min !== undefined && frac.doc < m.doc_fraction_min)
135
- return false;
136
- if (m.config_fraction_min !== undefined && frac.config < m.config_fraction_min)
137
- return false;
138
- if (m.source_files_max !== undefined && frac.source > m.source_files_max)
139
- return false;
140
- if (m.files_max !== undefined && files.length > m.files_max)
141
- return false;
142
- if (m.src_churn_max !== undefined) {
143
- const srcFiles = files.filter(f => !GENERATED.test(f) && !CONFIG_EXT.test(f));
144
- // Churn is only attributable per-file with a full diff; approximate with the
145
- // PR total when the change is entirely source, which is the case that matters.
146
- // Fails CLOSED when churn cannot be attributed: falling back to 0 passed
147
- // every cap, so one stray config file routed a 5,000-line change to the
148
- // core runner into `trivial` — fast tier, no recheck.
149
- const churn = srcFiles.length === files.length ? additions + deletions : Infinity;
150
- if (churn > m.src_churn_max)
151
- return false;
152
- }
153
- return true;
154
- }
155
- /** Classifies a PR against the strategy's ordered class list. First match wins. */
156
- export function resolveReviewStrategy(pr) {
157
- const cls = STRATEGY.pr_classes.find(c => matches(c, pr))
158
- ?? STRATEGY.pr_classes[STRATEGY.pr_classes.length - 1];
159
- return {
160
- version: STRATEGY.version,
161
- classId: cls.id,
162
- classLabel: cls.label,
163
- reason: cls.reason,
164
- tier: cls.tier,
165
- effort: cls.effort,
166
- steps: cls.steps,
167
- ...(cls.focus !== undefined && { focus: cls.focus }),
168
- domain: detectDomain(pr.files),
169
- };
170
- }
171
- /** Effort levels a model accepts. Empty array = the model has no effort control. */
172
- export function effortLevelsFor(model) {
173
- return STRATEGY.models[model]?.effort_levels ?? [];
174
- }
175
- export function isModelBanned(model) {
176
- return STRATEGY.banned_models.some(b => b.model === model);
177
- }
178
- export function strategyModelFor(vendor, tier) {
179
- return STRATEGY.vendors[vendor]?.tiers[tier] ?? null;
180
- }
181
- export function strategyVersion() {
182
- return STRATEGY.version;
183
- }
184
- export function ladderLimits() {
185
- return {
186
- maxRounds: STRATEGY.ladder.max_rounds,
187
- maxBlocking: STRATEGY.ladder.max_blocking_findings,
188
- maxWallClockMin: STRATEGY.ladder.max_wall_clock_min,
189
- };
190
- }
191
- /**
192
- * True when the strategy's model map has an entry for this ID — i.e. its effort
193
- * ladder is known at all. Distinct from an entry whose ladder is empty: haiku's
194
- * `[]` means "no effort control", while a pinned ID or codex under subscription
195
- * auth (where the CLI picks the model) means "capability unknown".
196
- */
197
- function modelIsKnown(model) {
198
- return Object.prototype.hasOwnProperty.call(STRATEGY.models, model);
199
- }
200
- /**
201
- * Escalation for round N. Raises effort where the vendor that will actually run
202
- * can deliver a higher one; where it cannot, degrades to a tier promotion
203
- * instead — `ladder.effort_fallback`.
204
- *
205
- * `lanes` are the vendors in play, not claude alone. Collapsing them produced
206
- * two separate no-ops:
207
- * - judging by the claude tier model on a codex-only install promoted a tier
208
- * every round (haiku exposes no effort ladder) while codex — which accepts
209
- * none…max — sat at the effort it started on;
210
- * - judging by MODEL capability alone made round 3 identical to round 2 on
211
- * claude: claude-opus-5 reasons at `xhigh`, the claude CLI has no flag for
212
- * it, so the wire effort clamped straight back down to round 2's `high`.
213
- *
214
- * So each lane is judged post-clamp, at the wire, and effort rises only when
215
- * EVERY lane rises there. Otherwise the tier is promoted, which every lane can
216
- * express.
217
- *
218
- * The model never weakens across rounds. Scope narrows instead: a recheck
219
- * examines the delta plus the open findings, not the whole PR again.
220
- */
221
- export function escalate(base, round, lanes) {
222
- if (round <= 1)
223
- return base;
224
- const list = typeof lanes === 'string' ? [{ model: lanes }] : lanes;
225
- // Both clamps, in order: what the MODEL can reason at, then what the CLI has a
226
- // flag for. Only the second reaches the wire.
227
- const wire = (lane, effort) => {
228
- const atModel = modelIsKnown(lane.model) ? clampToLevels(effort, effortLevelsFor(lane.model)) : effort;
229
- return lane.accepted ? clampToLevels(atModel, lane.accepted) : atModel;
230
- };
231
- // Compare the target against what the round before already asked for. An exact
232
- // `levels.includes(target)` test made round 3 miss on any model whose ladder
233
- // tops out below xhigh (deepseek: none/high/max) and return base.effort —
234
- // weaker than round 2.
235
- const target = round >= 3 ? 'xhigh' : 'high';
236
- const previousTarget = round >= 3 ? 'high' : base.effort;
237
- const clamped = list.map(lane => wire(lane, target));
238
- const rises = list.length > 0 && list.every((lane, i) => {
239
- const now = clamped[i];
240
- return now !== null && effortIndex(now) > effortIndex(wire(lane, previousTarget) ?? base.effort);
241
- });
242
- // The strongest level any lane accepts; each vendor config is clamped back down
243
- // to its own vocabulary downstream (strategyVendor), so a lane that cannot
244
- // reach it is not sent it.
245
- const best = clamped.reduce((a, b) => (effortIndex(b) > effortIndex(a) ? b : a), null);
246
- if (rises)
247
- return { tier: base.tier, effort: best };
248
- // Effort cannot rise on at least one lane — promote a tier instead (the
249
- // strategy's ladder.effort_fallback), capped at thorough.
250
- const idx = TIER_LADDER.indexOf(base.tier);
251
- const promoted = TIER_LADDER[Math.min(idx + 1, TIER_LADDER.length - 1)];
252
- return { tier: promoted, effort: best ?? base.effort };
253
- }
254
- /** Clamps a requested effort to what the model actually accepts. */
255
- export function clampEffort(model, effort) {
256
- return clampToLevels(effort, effortLevelsFor(model));
257
- }
258
- /**
259
- * Clamps a requested effort to an accepted vocabulary.
260
- *
261
- * Applied twice on the way to a CLI, against two different sets: what the MODEL
262
- * can reason at (`models[].effort_levels` here) and what the VENDOR CLI has a
263
- * flag for (CLAUDE_EFFORT_LEVELS / CODEX_EFFORT_LEVELS in the config schema).
264
- * They are not the same — claude-opus-5 reasons at `xhigh` and the claude CLI
265
- * cannot ask for it — and only the second reaches the wire.
266
- */
267
- export function clampToLevels(effort, levels) {
268
- if (effort === null || levels.length === 0)
269
- return null;
270
- if (levels.includes(effort))
271
- return effort;
272
- // Snap down to the nearest supported level rather than failing the call. When
273
- // the vocabulary has nothing at or below the request, snap UP to its lowest
274
- // level instead — sending an effort that is rejected fails the call outright.
275
- const want = EFFORT_LADDER.indexOf(effort);
276
- for (let i = want; i >= 0; i--) {
277
- if (levels.includes(EFFORT_LADDER[i]))
278
- return EFFORT_LADDER[i];
279
- }
280
- return levels[0] ?? null;
281
- }
282
- //# sourceMappingURL=review-strategy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"review-strategy.js","sourceRoot":"","sources":["../../src/lib/review-strategy.ts"],"names":[],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- import type { FetchLike, ResolvedLinearAuth } from './identity.js';
2
- export interface LinearRequestOptions {
3
- fetchImpl?: FetchLike;
4
- endpoint?: string;
5
- }
6
- export interface LinearIssue {
7
- id: string;
8
- identifier: string;
9
- url: string;
10
- }
11
- export interface LinearComment {
12
- id: string;
13
- url: string;
14
- }
15
- export declare function linearGraphQL<T>(auth: ResolvedLinearAuth, query: string, variables: Record<string, unknown>, opts?: LinearRequestOptions): Promise<T>;
16
- export declare function findIssueByIdentifier(auth: ResolvedLinearAuth, identifier: string, opts?: LinearRequestOptions): Promise<LinearIssue | null>;
17
- export declare function postLinearComment(auth: ResolvedLinearAuth, issueId: string, body: string, opts?: LinearRequestOptions): Promise<LinearComment>;
18
- //# sourceMappingURL=client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/linear/client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAIlE,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;CACZ;AAQD,wBAAsB,aAAa,CAAC,CAAC,EACnC,IAAI,EAAE,kBAAkB,EACxB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,CAAC,CAAC,CA+BZ;AAQD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAa7B;AASD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,aAAa,CAAC,CAgBxB"}
@@ -1,67 +0,0 @@
1
- // All Linear API traffic goes through this module — mirrors the rule that GitHub
2
- // calls go through src/github/client.ts. No raw fetch to api.linear.app elsewhere.
3
- const GRAPHQL_ENDPOINT = 'https://api.linear.app/graphql';
4
- const IDENTIFIER_PATTERN = /^([A-Za-z][A-Za-z0-9]{0,9})-(\d+)$/;
5
- function authHeader(auth) {
6
- return auth.bearer ? `Bearer ${auth.token}` : auth.token;
7
- }
8
- export async function linearGraphQL(auth, query, variables, opts = {}) {
9
- const doFetch = opts.fetchImpl ?? globalThis.fetch;
10
- const endpoint = opts.endpoint ?? GRAPHQL_ENDPOINT;
11
- // The token rides in a header, never in the URL or on argv.
12
- const response = await doFetch(endpoint, {
13
- method: 'POST',
14
- headers: { 'Content-Type': 'application/json', Authorization: authHeader(auth) },
15
- body: JSON.stringify({ query, variables }),
16
- });
17
- const text = await response.text();
18
- if (!response.ok) {
19
- throw new Error(`Linear API request failed (HTTP ${response.status})`);
20
- }
21
- let parsed;
22
- try {
23
- parsed = JSON.parse(text);
24
- }
25
- catch {
26
- throw new Error(`Linear API returned a non-JSON response (HTTP ${response.status})`);
27
- }
28
- if (parsed.errors && parsed.errors.length > 0) {
29
- const detail = parsed.errors.map(e => e.message ?? 'unknown error').join('; ');
30
- throw new Error(`Linear API error: ${detail}`);
31
- }
32
- if (parsed.data === undefined) {
33
- throw new Error('Linear API returned no data');
34
- }
35
- return parsed.data;
36
- }
37
- const FIND_ISSUE = `query($teamKey: String!, $number: Float!) {
38
- issues(first: 1, filter: { team: { key: { eq: $teamKey } }, number: { eq: $number } }) {
39
- nodes { id identifier url }
40
- }
41
- }`;
42
- export async function findIssueByIdentifier(auth, identifier, opts = {}) {
43
- const match = identifier.match(IDENTIFIER_PATTERN);
44
- if (!match) {
45
- throw new Error(`Malformed Linear issue identifier: "${identifier}" (expected e.g. IN-2269)`);
46
- }
47
- const data = await linearGraphQL(auth, FIND_ISSUE, { teamKey: match[1].toUpperCase(), number: Number.parseInt(match[2], 10) }, opts);
48
- return data.issues.nodes[0] ?? null;
49
- }
50
- const CREATE_COMMENT = `mutation($issueId: String!, $body: String!, $createAsUser: String) {
51
- commentCreate(input: { issueId: $issueId, body: $body, createAsUser: $createAsUser }) {
52
- success
53
- comment { id url }
54
- }
55
- }`;
56
- export async function postLinearComment(auth, issueId, body, opts = {}) {
57
- const variables = { issueId, body };
58
- // Only T1 can attribute the write to the app actor.
59
- if (auth.createAsUser)
60
- variables.createAsUser = auth.createAsUser;
61
- const data = await linearGraphQL(auth, CREATE_COMMENT, variables, opts);
62
- if (!data.commentCreate.success || !data.commentCreate.comment) {
63
- throw new Error('Linear rejected the comment mutation');
64
- }
65
- return data.commentCreate.comment;
66
- }
67
- //# sourceMappingURL=client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/linear/client.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- export interface LinearCommentInput {
2
- /** `🤖 {actor} · {product}` — must lead the comment (IN-2260 step 3). */
3
- signature: string;
4
- verdict: string | null;
5
- reviewer: string;
6
- origin: string;
7
- model: string;
8
- prUrl: string;
9
- prTitle: string;
10
- sha?: string;
11
- summary?: string;
12
- service?: string;
13
- /** Workflow step this verdict came from — a recheck must not read as a review. */
14
- stepType?: string;
15
- round?: number;
16
- }
17
- export declare function buildLinearCommentBody(input: LinearCommentInput): string;
18
- export declare function normalizeVerdict(verdict: string | null): string;
19
- export declare function shouldPostToLinear(verdict: string | null, commentOn: readonly string[]): boolean;
20
- //# sourceMappingURL=comment.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comment.d.ts","sourceRoot":"","sources":["../../src/linear/comment.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAsBD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CA6BxE;AAKD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE/D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAGhG"}
@@ -1,57 +0,0 @@
1
- // Body construction for the comment crosscheck posts back to a PR's Linear issue.
2
- import { buildAnnotation } from '../lib/annotation.js';
3
- const DEFAULT_SERVICE = 'crosscheck';
4
- // The visible line must agree with the annotation. Saying "review" on a recheck
5
- // made the human-readable text contradict the type=recheck sitting right below it.
6
- // Returns the whole connective phrase, including the preposition — "fix of" is
7
- // not English, so the label owns it rather than the template appending one.
8
- function stepLabel(stepType) {
9
- switch (stepType) {
10
- case 'recheck': return 'recheck of';
11
- case 'fix': return 'fix for';
12
- case 'conflict-resolve': return 'conflict resolution for';
13
- default: return 'review of';
14
- }
15
- }
16
- // A `]` in the PR title would terminate the markdown link label early.
17
- function escapeLinkLabel(text) {
18
- return text.replace(/([[\]])/g, '\\$1');
19
- }
20
- export function buildLinearCommentBody(input) {
21
- const verdict = input.verdict ?? 'UNKNOWN';
22
- const service = input.service ?? DEFAULT_SERVICE;
23
- const sections = [
24
- input.signature,
25
- '',
26
- // Both halves: the model when the vendor reported one — `default` means it
27
- // chose without saying which, and naming it would be a guess — and the step
28
- // label, so a recheck does not read as a review.
29
- `**${verdict}** — ${input.reviewer}${input.model && input.model !== 'default' ? ` (${input.model})` : ''}` +
30
- ` ${stepLabel(input.stepType)} [${escapeLinkLabel(input.prTitle)}](${input.prUrl})`,
31
- ];
32
- if (input.summary)
33
- sections.push('', input.summary);
34
- // Same annotation schema as the GitHub comment, so one parser reads both.
35
- sections.push('', buildAnnotation({
36
- origin: input.origin,
37
- reviewer: input.reviewer,
38
- model: input.model,
39
- type: input.stepType ?? 'review',
40
- round: input.round ?? 1,
41
- verdict,
42
- service,
43
- ...(input.sha && { sha: input.sha }),
44
- }));
45
- return sections.join('\n');
46
- }
47
- // parseVerdict yields the human spelling `NEEDS WORK`, while config and the
48
- // annotation schema both use `NEEDS_WORK`. Comparing them raw silently dropped
49
- // every NEEDS WORK verdict — the most common actionable one.
50
- export function normalizeVerdict(verdict) {
51
- return (verdict ?? 'UNKNOWN').trim().toUpperCase().replace(/\s+/g, '_');
52
- }
53
- export function shouldPostToLinear(verdict, commentOn) {
54
- const wanted = normalizeVerdict(verdict);
55
- return commentOn.some(v => normalizeVerdict(v) === wanted);
56
- }
57
- //# sourceMappingURL=comment.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"comment.js","sourceRoot":"","sources":["../../src/linear/comment.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAoBtD,MAAM,eAAe,GAAG,YAAY,CAAA;AAEpC,gFAAgF;AAChF,mFAAmF;AACnF,+EAA+E;AAC/E,4EAA4E;AAC5E,SAAS,SAAS,CAAC,QAA4B;IAC7C,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,SAAS,CAAC,CAAC,OAAO,YAAY,CAAA;QACnC,KAAK,KAAK,CAAC,CAAC,OAAO,SAAS,CAAA;QAC5B,KAAK,kBAAkB,CAAC,CAAC,OAAO,yBAAyB,CAAA;QACzD,OAAO,CAAC,CAAC,OAAO,WAAW,CAAA;IAC7B,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;AACzC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,SAAS,CAAA;IAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,eAAe,CAAA;IAEhD,MAAM,QAAQ,GAAG;QACf,KAAK,CAAC,SAAS;QACf,EAAE;QACF,2EAA2E;QAC3E,4EAA4E;QAC5E,iDAAiD;QACjD,KAAK,OAAO,QAAQ,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACxG,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG;KACtF,CAAA;IAED,IAAI,KAAK,CAAC,OAAO;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAEnD,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC;QAChC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,QAAQ,IAAI,QAAQ;QAChC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;QACvB,OAAO;QACP,OAAO;QACP,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;KACrC,CAAC,CAAC,CAAA;IAEH,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC;AAED,4EAA4E;AAC5E,+EAA+E;AAC/E,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,OAAsB;IACrD,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AACzE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAsB,EAAE,SAA4B;IACrF,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IACxC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAA;AAC5D,CAAC"}
@@ -1,59 +0,0 @@
1
- import type { LinearConfig } from '../config/schema.js';
2
- /** Injectable fetch, so tests never touch the network. */
3
- export type FetchLike = (url: string, init: RequestInit) => Promise<Response>;
4
- export type LinearAuthMode = 'api_key' | 'client_credentials';
5
- /** Credentials read from the environment. Resolved in config/loader.ts — never here. */
6
- export interface LinearCredentials {
7
- apiKey?: string;
8
- clientId?: string;
9
- clientSecret?: string;
10
- }
11
- export interface ResolvedLinearAuth {
12
- mode: LinearAuthMode;
13
- /** Bare API key (T0) or minted app token (T1). Never log this. */
14
- token: string;
15
- /** T1 tokens need an `Authorization: Bearer` prefix; T0 keys are sent bare. */
16
- bearer: boolean;
17
- actor: string;
18
- /** Rendered `🤖 {actor} · {product}` line. Leads every write in both tiers. */
19
- signature: string;
20
- /** Set in T1 only — Linear attributes the write to this display name. */
21
- createAsUser?: string;
22
- /** Retained so withWorker() can re-render the signature for a derived actor. */
23
- signatureTemplate: string;
24
- product: string;
25
- }
26
- export interface MintOptions {
27
- fetchImpl?: FetchLike;
28
- }
29
- export interface ResolveOptions extends MintOptions {
30
- /** Product name used in the signature template. */
31
- product?: string;
32
- }
33
- export declare class LinearConfigError extends Error {
34
- readonly userError = true;
35
- constructor(message: string);
36
- }
37
- export declare function isLinearConfigError(err: unknown): boolean;
38
- export interface SignatureVars {
39
- actor: string;
40
- product: string;
41
- /** Reviewer model, e.g. `claude-opus-4.5`. Absent at auth-resolution time. */
42
- model?: string;
43
- /** Reviewing vendor, e.g. `codex`. */
44
- reviewer?: string;
45
- /** Pre-rendered markdown image, or '' when no icon is configured. */
46
- icon?: string;
47
- }
48
- export declare function renderSignature(template: string, vars: SignatureVars): string;
49
- /** Wraps a configured icon URL as inline markdown, or '' when unset. */
50
- export declare function renderIcon(iconUrl: string): string;
51
- export declare function normalizeScopes(scopes: string): string;
52
- export declare function mintAppToken(creds: {
53
- clientId: string;
54
- clientSecret: string;
55
- scopes: string;
56
- }, opts?: MintOptions): Promise<string>;
57
- export declare function resolveLinearAuth(config: LinearConfig, creds: LinearCredentials, opts?: ResolveOptions): Promise<ResolvedLinearAuth>;
58
- export declare function withWorker(auth: ResolvedLinearAuth, worker: string): ResolvedLinearAuth;
59
- //# sourceMappingURL=identity.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/linear/identity.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAIvD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE7E,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,oBAAoB,CAAA;AAE7D,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAA;IACpB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAA;IACjB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,iBAAiB,EAAE,MAAM,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAOD,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,SAAS,QAAO;gBACb,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAMD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAgB7E;AAmBD,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGlD;AAKD,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACjE,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,iBAAiB,EACxB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAwD7B;AAWD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAWvF"}