@hominis/fireforge 0.49.2 → 0.51.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 (400) hide show
  1. package/CHANGELOG.md +87 -1
  2. package/README.md +1 -1
  3. package/dist/bin/fireforge.js +6 -0
  4. package/dist/build-info.json +4 -4
  5. package/dist/src/commands/build-prelock.d.ts +20 -0
  6. package/dist/src/commands/build-prelock.js +50 -0
  7. package/dist/src/commands/build.d.ts +3 -1
  8. package/dist/src/commands/build.js +13 -6
  9. package/dist/src/commands/check-report.d.ts +41 -0
  10. package/dist/src/commands/check-report.js +91 -0
  11. package/dist/src/commands/check-run.d.ts +33 -0
  12. package/dist/src/commands/check-run.js +112 -0
  13. package/dist/src/commands/check-steps.d.ts +75 -0
  14. package/dist/src/commands/check-steps.js +200 -0
  15. package/dist/src/commands/check.d.ts +32 -0
  16. package/dist/src/commands/check.js +160 -0
  17. package/dist/src/commands/config.js +5 -6
  18. package/dist/src/commands/declarations-report.d.ts +43 -0
  19. package/dist/src/commands/declarations-report.js +76 -0
  20. package/dist/src/commands/doctor-engine-eslint.js +6 -1
  21. package/dist/src/commands/doctor-source-pin.js +4 -1
  22. package/dist/src/commands/export-adopt-check.d.ts +38 -0
  23. package/dist/src/commands/export-adopt-check.js +98 -0
  24. package/dist/src/commands/export-flow.js +29 -14
  25. package/dist/src/commands/export-placement-gate.d.ts +6 -2
  26. package/dist/src/commands/export-placement-gate.js +8 -0
  27. package/dist/src/commands/export-shared.d.ts +2 -1
  28. package/dist/src/commands/export-staged-registration.d.ts +46 -0
  29. package/dist/src/commands/export-staged-registration.js +91 -0
  30. package/dist/src/commands/forward-import-remedy.d.ts +32 -0
  31. package/dist/src/commands/forward-import-remedy.js +63 -0
  32. package/dist/src/commands/furnace/apply.js +3 -3
  33. package/dist/src/commands/furnace/chrome-doc-remove.d.ts +2 -1
  34. package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
  35. package/dist/src/commands/furnace/chrome-doc.d.ts +2 -1
  36. package/dist/src/commands/furnace/chrome-doc.js +2 -2
  37. package/dist/src/commands/furnace/create.js +2 -2
  38. package/dist/src/commands/furnace/deploy-named.d.ts +48 -0
  39. package/dist/src/commands/furnace/deploy-named.js +107 -0
  40. package/dist/src/commands/furnace/deploy.d.ts +3 -2
  41. package/dist/src/commands/furnace/deploy.js +50 -86
  42. package/dist/src/commands/furnace/diff.js +26 -3
  43. package/dist/src/commands/furnace/index.js +66 -41
  44. package/dist/src/commands/furnace/init.js +13 -6
  45. package/dist/src/commands/furnace/override.js +4 -2
  46. package/dist/src/commands/furnace/preview.js +4 -3
  47. package/dist/src/commands/furnace/refresh.js +2 -2
  48. package/dist/src/commands/furnace/remove.js +4 -3
  49. package/dist/src/commands/furnace/rename-dry-run.d.ts +29 -0
  50. package/dist/src/commands/furnace/rename-dry-run.js +127 -0
  51. package/dist/src/commands/furnace/rename-helpers.d.ts +7 -0
  52. package/dist/src/commands/furnace/rename-helpers.js +15 -1
  53. package/dist/src/commands/furnace/rename-registrations.d.ts +41 -0
  54. package/dist/src/commands/furnace/rename-registrations.js +98 -0
  55. package/dist/src/commands/furnace/rename.d.ts +2 -1
  56. package/dist/src/commands/furnace/rename.js +28 -66
  57. package/dist/src/commands/furnace/scan.d.ts +9 -4
  58. package/dist/src/commands/furnace/scan.js +11 -9
  59. package/dist/src/commands/furnace/sync.js +3 -2
  60. package/dist/src/commands/furnace/validate-report.d.ts +45 -0
  61. package/dist/src/commands/furnace/validate-report.js +91 -0
  62. package/dist/src/commands/furnace/validate.d.ts +1 -1
  63. package/dist/src/commands/furnace/validate.js +151 -113
  64. package/dist/src/commands/furnace/validation-output.js +14 -3
  65. package/dist/src/commands/lint-per-patch.js +36 -61
  66. package/dist/src/commands/lint-per-run-checkjs.js +2 -2
  67. package/dist/src/commands/lint-report.d.ts +8 -4
  68. package/dist/src/commands/lint-report.js +20 -5
  69. package/dist/src/commands/lint.js +15 -34
  70. package/dist/src/commands/manifest.js +4 -0
  71. package/dist/src/commands/park.d.ts +22 -0
  72. package/dist/src/commands/park.js +232 -0
  73. package/dist/src/commands/patch/delete-gap-notice.js +3 -1
  74. package/dist/src/commands/patch/delete.d.ts +1 -1
  75. package/dist/src/commands/patch/delete.js +24 -104
  76. package/dist/src/commands/patch/index.d.ts +3 -3
  77. package/dist/src/commands/patch/index.js +10 -4
  78. package/dist/src/commands/patch/lint-ignore-from.d.ts +44 -0
  79. package/dist/src/commands/patch/lint-ignore-from.js +142 -0
  80. package/dist/src/commands/patch/lint-ignore.d.ts +5 -1
  81. package/dist/src/commands/patch/lint-ignore.js +78 -31
  82. package/dist/src/commands/patch/move-files-create.js +34 -18
  83. package/dist/src/commands/patch/move-files-into.js +15 -7
  84. package/dist/src/commands/patch/move-files.js +6 -2
  85. package/dist/src/commands/patch/removal-created-files.d.ts +48 -0
  86. package/dist/src/commands/patch/removal-created-files.js +83 -0
  87. package/dist/src/commands/patch/removal-dependents.d.ts +63 -0
  88. package/dist/src/commands/patch/removal-dependents.js +133 -0
  89. package/dist/src/commands/patch/rename.js +20 -1
  90. package/dist/src/commands/patch/reserve.d.ts +33 -0
  91. package/dist/src/commands/patch/reserve.js +152 -0
  92. package/dist/src/commands/patch/retire.d.ts +34 -0
  93. package/dist/src/commands/patch/retire.js +133 -0
  94. package/dist/src/commands/patch/split-plan.d.ts +17 -8
  95. package/dist/src/commands/patch/split-plan.js +60 -28
  96. package/dist/src/commands/patch/split-staged.d.ts +108 -0
  97. package/dist/src/commands/patch/split-staged.js +202 -0
  98. package/dist/src/commands/patch/split.d.ts +5 -0
  99. package/dist/src/commands/patch/split.js +62 -17
  100. package/dist/src/commands/patch/stage.d.ts +34 -0
  101. package/dist/src/commands/patch/stage.js +153 -0
  102. package/dist/src/commands/patch/staged-dependency-batch.d.ts +48 -0
  103. package/dist/src/commands/patch/staged-dependency-batch.js +176 -0
  104. package/dist/src/commands/patch/staged-dependency-entries.d.ts +36 -0
  105. package/dist/src/commands/patch/staged-dependency-entries.js +52 -0
  106. package/dist/src/commands/patch/staged-dependency-from.d.ts +14 -0
  107. package/dist/src/commands/patch/staged-dependency-from.js +108 -0
  108. package/dist/src/commands/patch/staged-dependency-remove.d.ts +31 -0
  109. package/dist/src/commands/patch/staged-dependency-remove.js +80 -0
  110. package/dist/src/commands/patch/staged-dependency.js +54 -139
  111. package/dist/src/commands/re-export-adjacent-registrations.d.ts +20 -0
  112. package/dist/src/commands/re-export-adjacent-registrations.js +75 -0
  113. package/dist/src/commands/re-export-adjacent.d.ts +50 -2
  114. package/dist/src/commands/re-export-adjacent.js +160 -40
  115. package/dist/src/commands/re-export-bulk-scan.d.ts +2 -1
  116. package/dist/src/commands/re-export-bulk-scan.js +22 -7
  117. package/dist/src/commands/re-export-drift.d.ts +36 -8
  118. package/dist/src/commands/re-export-drift.js +73 -49
  119. package/dist/src/commands/re-export-files.js +11 -8
  120. package/dist/src/commands/re-export-hunks.d.ts +35 -0
  121. package/dist/src/commands/re-export-hunks.js +220 -0
  122. package/dist/src/commands/re-export-lint.d.ts +2 -1
  123. package/dist/src/commands/re-export-lint.js +23 -10
  124. package/dist/src/commands/re-export-options.js +74 -6
  125. package/dist/src/commands/re-export-preflight.d.ts +23 -0
  126. package/dist/src/commands/re-export-preflight.js +160 -0
  127. package/dist/src/commands/re-export-purity-scope.d.ts +18 -0
  128. package/dist/src/commands/re-export-purity-scope.js +131 -0
  129. package/dist/src/commands/re-export-register.js +56 -17
  130. package/dist/src/commands/re-export-removed.d.ts +13 -2
  131. package/dist/src/commands/re-export-removed.js +57 -12
  132. package/dist/src/commands/re-export-scan-owner.d.ts +44 -0
  133. package/dist/src/commands/re-export-scan-owner.js +116 -0
  134. package/dist/src/commands/re-export-scan.d.ts +19 -9
  135. package/dist/src/commands/re-export-scan.js +60 -24
  136. package/dist/src/commands/re-export-single.js +122 -46
  137. package/dist/src/commands/re-export-stale-registrations.d.ts +18 -0
  138. package/dist/src/commands/re-export-stale-registrations.js +62 -0
  139. package/dist/src/commands/re-export-summary.d.ts +28 -0
  140. package/dist/src/commands/re-export-summary.js +36 -0
  141. package/dist/src/commands/re-export.js +71 -57
  142. package/dist/src/commands/rebase/index.js +17 -17
  143. package/dist/src/commands/run.js +16 -2
  144. package/dist/src/commands/status-check.d.ts +55 -16
  145. package/dist/src/commands/status-check.js +92 -37
  146. package/dist/src/commands/status-json.d.ts +22 -9
  147. package/dist/src/commands/status-json.js +47 -32
  148. package/dist/src/commands/status-output.js +3 -1
  149. package/dist/src/commands/status-scope.d.ts +37 -0
  150. package/dist/src/commands/status-scope.js +54 -0
  151. package/dist/src/commands/status.js +66 -23
  152. package/dist/src/commands/test-browser-preflight.js +19 -3
  153. package/dist/src/commands/test-build-furnace.d.ts +22 -0
  154. package/dist/src/commands/test-build-furnace.js +54 -0
  155. package/dist/src/commands/test-build-phase.js +64 -41
  156. package/dist/src/commands/test-checkjs.js +10 -2
  157. package/dist/src/commands/test-diagnose.js +7 -0
  158. package/dist/src/commands/test-dispatch.d.ts +39 -0
  159. package/dist/src/commands/test-dispatch.js +211 -0
  160. package/dist/src/commands/test-furnace-reach.d.ts +37 -0
  161. package/dist/src/commands/test-furnace-reach.js +132 -0
  162. package/dist/src/commands/test-modes.d.ts +16 -1
  163. package/dist/src/commands/test-modes.js +24 -1
  164. package/dist/src/commands/test-multi-verdict.d.ts +61 -0
  165. package/dist/src/commands/test-multi-verdict.js +111 -0
  166. package/dist/src/commands/test-orchestrate.d.ts +52 -0
  167. package/dist/src/commands/test-orchestrate.js +240 -0
  168. package/dist/src/commands/test-perf-scope.d.ts +50 -0
  169. package/dist/src/commands/test-perf-scope.js +138 -0
  170. package/dist/src/commands/test-prelock.d.ts +51 -0
  171. package/dist/src/commands/test-prelock.js +273 -0
  172. package/dist/src/commands/test-register.js +69 -10
  173. package/dist/src/commands/test-results.d.ts +62 -0
  174. package/dist/src/commands/test-results.js +62 -0
  175. package/dist/src/commands/test-run.d.ts +13 -55
  176. package/dist/src/commands/test-run.js +74 -99
  177. package/dist/src/commands/test-shards.d.ts +110 -0
  178. package/dist/src/commands/test-shards.js +255 -0
  179. package/dist/src/commands/test-stale-gate.d.ts +5 -1
  180. package/dist/src/commands/test-stale-gate.js +60 -28
  181. package/dist/src/commands/test-verdict.d.ts +11 -1
  182. package/dist/src/commands/test-verdict.js +28 -1
  183. package/dist/src/commands/test.d.ts +6 -1
  184. package/dist/src/commands/test.js +120 -124
  185. package/dist/src/commands/token-lint.d.ts +14 -0
  186. package/dist/src/commands/token-lint.js +151 -0
  187. package/dist/src/commands/token.js +10 -0
  188. package/dist/src/commands/verify-scope.d.ts +28 -0
  189. package/dist/src/commands/verify-scope.js +67 -0
  190. package/dist/src/commands/verify.d.ts +10 -2
  191. package/dist/src/commands/verify.js +67 -36
  192. package/dist/src/core/build-baseline-types.d.ts +46 -0
  193. package/dist/src/core/build-baseline-validate.js +19 -0
  194. package/dist/src/core/build-baseline.d.ts +5 -1
  195. package/dist/src/core/build-baseline.js +3 -1
  196. package/dist/src/core/build-overwrite-guard.d.ts +50 -0
  197. package/dist/src/core/build-overwrite-guard.js +84 -4
  198. package/dist/src/core/build-prepare.d.ts +13 -0
  199. package/dist/src/core/build-prepare.js +42 -10
  200. package/dist/src/core/build-run-record.d.ts +74 -0
  201. package/dist/src/core/build-run-record.js +136 -0
  202. package/dist/src/core/checkjs-support-heads.d.ts +41 -0
  203. package/dist/src/core/checkjs-support-heads.js +104 -0
  204. package/dist/src/core/config-paths.d.ts +2 -2
  205. package/dist/src/core/config-paths.js +10 -0
  206. package/dist/src/core/config-validate-check.d.ts +8 -0
  207. package/dist/src/core/config-validate-check.js +219 -0
  208. package/dist/src/core/config-validate-file-size.d.ts +9 -6
  209. package/dist/src/core/config-validate-file-size.js +91 -2
  210. package/dist/src/core/config-validate-history.d.ts +11 -0
  211. package/dist/src/core/config-validate-history.js +38 -0
  212. package/dist/src/core/config-validate-patch-policy.js +100 -0
  213. package/dist/src/core/config-validate-test-toolchains.js +21 -0
  214. package/dist/src/core/config-validate-token-scales.d.ts +9 -0
  215. package/dist/src/core/config-validate-token-scales.js +92 -0
  216. package/dist/src/core/config-validate.js +20 -5
  217. package/dist/src/core/config.d.ts +5 -0
  218. package/dist/src/core/config.js +16 -0
  219. package/dist/src/core/coverage-dispatch.d.ts +24 -0
  220. package/dist/src/core/coverage-dispatch.js +44 -0
  221. package/dist/src/core/coverage-extend.d.ts +70 -45
  222. package/dist/src/core/coverage-extend.js +199 -144
  223. package/dist/src/core/coverage-records.d.ts +108 -0
  224. package/dist/src/core/coverage-records.js +384 -0
  225. package/dist/src/core/destructive.d.ts +7 -4
  226. package/dist/src/core/destructive.js +10 -10
  227. package/dist/src/core/engine-session-lock.d.ts +16 -1
  228. package/dist/src/core/engine-session-lock.js +38 -10
  229. package/dist/src/core/export-moved-code-shape.d.ts +49 -11
  230. package/dist/src/core/export-moved-code-shape.js +135 -44
  231. package/dist/src/core/file-lock-queue.d.ts +67 -0
  232. package/dist/src/core/file-lock-queue.js +221 -0
  233. package/dist/src/core/file-lock-shared.d.ts +57 -0
  234. package/dist/src/core/file-lock-shared.js +117 -0
  235. package/dist/src/core/file-lock.d.ts +13 -25
  236. package/dist/src/core/file-lock.js +163 -140
  237. package/dist/src/core/furnace-apply-output.d.ts +10 -0
  238. package/dist/src/core/furnace-apply-output.js +31 -1
  239. package/dist/src/core/furnace-apply.js +22 -12
  240. package/dist/src/core/furnace-composed-source.d.ts +76 -0
  241. package/dist/src/core/furnace-composed-source.js +167 -0
  242. package/dist/src/core/furnace-config-validate-exceptions.d.ts +16 -0
  243. package/dist/src/core/furnace-config-validate-exceptions.js +102 -0
  244. package/dist/src/core/furnace-config-validate.js +14 -0
  245. package/dist/src/core/furnace-css-fragments.d.ts +10 -0
  246. package/dist/src/core/furnace-css-fragments.js +26 -0
  247. package/dist/src/core/furnace-operation.d.ts +3 -3
  248. package/dist/src/core/furnace-registration-jar-inplace.d.ts +12 -0
  249. package/dist/src/core/furnace-registration-jar-inplace.js +80 -0
  250. package/dist/src/core/furnace-registration-remove.d.ts +22 -1
  251. package/dist/src/core/furnace-registration-remove.js +53 -17
  252. package/dist/src/core/furnace-registration-rename.d.ts +26 -0
  253. package/dist/src/core/furnace-registration-rename.js +77 -0
  254. package/dist/src/core/furnace-registration.d.ts +14 -4
  255. package/dist/src/core/furnace-registration.js +44 -10
  256. package/dist/src/core/furnace-staleness.d.ts +7 -0
  257. package/dist/src/core/furnace-staleness.js +34 -24
  258. package/dist/src/core/furnace-validate-accessibility.d.ts +8 -4
  259. package/dist/src/core/furnace-validate-accessibility.js +71 -28
  260. package/dist/src/core/furnace-validate-exceptions.d.ts +48 -0
  261. package/dist/src/core/furnace-validate-exceptions.js +80 -0
  262. package/dist/src/core/furnace-validate-icon-button.d.ts +7 -0
  263. package/dist/src/core/furnace-validate-icon-button.js +78 -0
  264. package/dist/src/core/furnace-validate.js +1 -1
  265. package/dist/src/core/harness-port-fallback.d.ts +60 -0
  266. package/dist/src/core/harness-port-fallback.js +96 -0
  267. package/dist/src/core/history-log-file.d.ts +61 -0
  268. package/dist/src/core/history-log-file.js +164 -0
  269. package/dist/src/core/history-log.d.ts +2 -1
  270. package/dist/src/core/history-log.js +2 -1
  271. package/dist/src/core/json-preserving-edit.d.ts +22 -0
  272. package/dist/src/core/json-preserving-edit.js +199 -0
  273. package/dist/src/core/line-prefixer.d.ts +18 -0
  274. package/dist/src/core/line-prefixer.js +34 -0
  275. package/dist/src/core/mach.d.ts +7 -0
  276. package/dist/src/core/mach.js +32 -10
  277. package/dist/src/core/module-resolution-preflight.d.ts +19 -3
  278. package/dist/src/core/module-resolution-preflight.js +24 -6
  279. package/dist/src/core/negative-control-compiled.d.ts +27 -0
  280. package/dist/src/core/negative-control-compiled.js +73 -0
  281. package/dist/src/core/negative-control-diff.d.ts +51 -0
  282. package/dist/src/core/negative-control-diff.js +179 -0
  283. package/dist/src/core/negative-control.d.ts +150 -0
  284. package/dist/src/core/negative-control.js +399 -0
  285. package/dist/src/core/objdir-install-manifests.d.ts +73 -0
  286. package/dist/src/core/objdir-install-manifests.js +226 -0
  287. package/dist/src/core/park-store.d.ts +63 -0
  288. package/dist/src/core/park-store.js +216 -0
  289. package/dist/src/core/patch-export-update.d.ts +6 -0
  290. package/dist/src/core/patch-export-update.js +13 -3
  291. package/dist/src/core/patch-export.d.ts +3 -2
  292. package/dist/src/core/patch-export.js +22 -16
  293. package/dist/src/core/patch-files.js +26 -8
  294. package/dist/src/core/patch-lint-checkjs-any-import.d.ts +39 -0
  295. package/dist/src/core/patch-lint-checkjs-any-import.js +63 -0
  296. package/dist/src/core/patch-lint-checkjs-diagnostics.d.ts +17 -0
  297. package/dist/src/core/patch-lint-checkjs-diagnostics.js +32 -0
  298. package/dist/src/core/patch-lint-checkjs.d.ts +10 -1
  299. package/dist/src/core/patch-lint-checkjs.js +20 -13
  300. package/dist/src/core/patch-lint-code-lines.d.ts +59 -0
  301. package/dist/src/core/patch-lint-code-lines.js +105 -0
  302. package/dist/src/core/patch-lint-cross.d.ts +3 -1
  303. package/dist/src/core/patch-lint-cross.js +17 -4
  304. package/dist/src/core/patch-lint-css.d.ts +8 -2
  305. package/dist/src/core/patch-lint-css.js +24 -14
  306. package/dist/src/core/patch-lint-file-size.d.ts +12 -5
  307. package/dist/src/core/patch-lint-file-size.js +22 -11
  308. package/dist/src/core/patch-lint-forward-registration-extended.d.ts +23 -0
  309. package/dist/src/core/patch-lint-forward-registration-extended.js +36 -11
  310. package/dist/src/core/patch-lint-forward-registration.js +10 -0
  311. package/dist/src/core/patch-lint-ignore.d.ts +196 -0
  312. package/dist/src/core/patch-lint-ignore.js +429 -0
  313. package/dist/src/core/patch-lint-ownership.d.ts +10 -0
  314. package/dist/src/core/patch-lint-ownership.js +26 -0
  315. package/dist/src/core/patch-lint-size-thresholds.d.ts +52 -0
  316. package/dist/src/core/patch-lint-size-thresholds.js +110 -0
  317. package/dist/src/core/patch-lint-size.d.ts +117 -0
  318. package/dist/src/core/patch-lint-size.js +331 -0
  319. package/dist/src/core/patch-lint-staged-registration.d.ts +18 -1
  320. package/dist/src/core/patch-lint-staged-registration.js +20 -0
  321. package/dist/src/core/patch-lint-token-scale.d.ts +57 -0
  322. package/dist/src/core/patch-lint-token-scale.js +286 -0
  323. package/dist/src/core/patch-lint.d.ts +11 -83
  324. package/dist/src/core/patch-lint.js +66 -288
  325. package/dist/src/core/patch-lock.js +7 -6
  326. package/dist/src/core/patch-manifest-consistency.js +7 -6
  327. package/dist/src/core/patch-manifest-io.d.ts +6 -3
  328. package/dist/src/core/patch-manifest-io.js +27 -9
  329. package/dist/src/core/patch-manifest-key-order.d.ts +24 -0
  330. package/dist/src/core/patch-manifest-key-order.js +61 -0
  331. package/dist/src/core/patch-manifest-stage.d.ts +46 -0
  332. package/dist/src/core/patch-manifest-stage.js +96 -0
  333. package/dist/src/core/patch-manifest-validate.js +61 -3
  334. package/dist/src/core/patch-order-legal.d.ts +26 -0
  335. package/dist/src/core/patch-order-legal.js +88 -0
  336. package/dist/src/core/patch-policy-content.d.ts +40 -0
  337. package/dist/src/core/patch-policy-content.js +216 -0
  338. package/dist/src/core/patch-policy.d.ts +22 -5
  339. package/dist/src/core/patch-policy.js +26 -12
  340. package/dist/src/core/patch-retired.d.ts +57 -0
  341. package/dist/src/core/patch-retired.js +92 -0
  342. package/dist/src/core/patch-subset.d.ts +16 -0
  343. package/dist/src/core/patch-subset.js +66 -0
  344. package/dist/src/core/preflight-wait.d.ts +20 -0
  345. package/dist/src/core/preflight-wait.js +38 -0
  346. package/dist/src/core/rebase-from-version.d.ts +46 -0
  347. package/dist/src/core/rebase-from-version.js +71 -0
  348. package/dist/src/core/run-log.d.ts +26 -0
  349. package/dist/src/core/run-log.js +106 -4
  350. package/dist/src/core/run-profile.d.ts +7 -0
  351. package/dist/src/core/run-profile.js +7 -1
  352. package/dist/src/core/smoke-patterns.d.ts +5 -0
  353. package/dist/src/core/smoke-patterns.js +13 -0
  354. package/dist/src/core/test-harness-crash.d.ts +19 -1
  355. package/dist/src/core/test-harness-crash.js +8 -9
  356. package/dist/src/core/test-harness-signature.d.ts +33 -0
  357. package/dist/src/core/test-harness-signature.js +23 -1
  358. package/dist/src/core/test-raw-log.d.ts +66 -0
  359. package/dist/src/core/test-raw-log.js +122 -0
  360. package/dist/src/core/test-run-completeness.d.ts +90 -0
  361. package/dist/src/core/test-run-completeness.js +184 -0
  362. package/dist/src/core/test-stale-check.d.ts +27 -1
  363. package/dist/src/core/test-stale-check.js +39 -49
  364. package/dist/src/core/test-stale-exempt.d.ts +40 -0
  365. package/dist/src/core/test-stale-exempt.js +70 -0
  366. package/dist/src/core/test-xpcshell-retry.d.ts +2 -0
  367. package/dist/src/core/test-xpcshell-retry.js +2 -1
  368. package/dist/src/core/token-lint.d.ts +53 -0
  369. package/dist/src/core/token-lint.js +131 -0
  370. package/dist/src/core/token-sibling-sheets.d.ts +46 -0
  371. package/dist/src/core/token-sibling-sheets.js +119 -0
  372. package/dist/src/core/tree-guard.js +5 -0
  373. package/dist/src/core/typecheck-shim.d.ts +6 -2
  374. package/dist/src/core/typecheck-shim.js +205 -4
  375. package/dist/src/core/typecheck.js +3 -1
  376. package/dist/src/index.d.ts +14 -3
  377. package/dist/src/index.js +6 -1
  378. package/dist/src/types/commands/index.d.ts +2 -2
  379. package/dist/src/types/commands/options.d.ts +212 -24
  380. package/dist/src/types/commands/patches.d.ts +118 -1
  381. package/dist/src/types/config.d.ts +264 -0
  382. package/dist/src/types/config.js +9 -0
  383. package/dist/src/types/furnace.d.ts +63 -1
  384. package/dist/src/types/furnace.js +7 -0
  385. package/dist/src/types/index.d.ts +1 -1
  386. package/dist/src/utils/options.d.ts +36 -7
  387. package/dist/src/utils/options.js +94 -8
  388. package/dist/src/utils/path-glob.d.ts +15 -0
  389. package/dist/src/utils/path-glob.js +47 -0
  390. package/dist/src/utils/regex.d.ts +15 -3
  391. package/dist/src/utils/regex.js +37 -16
  392. package/docs/configuration.md +369 -11
  393. package/docs/exit-codes.md +18 -1
  394. package/docs/furnace.md +139 -3
  395. package/docs/lifecycle-invariants.md +65 -30
  396. package/docs/machine-output.md +120 -12
  397. package/docs/patch-workflow.md +458 -22
  398. package/docs/run-logs.md +20 -1
  399. package/docs/testing.md +346 -21
  400. package/package.json +3 -3
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Patch-size lint: the `large-patch-lines` and `large-patch-files` rules,
3
+ * the tier decision they share, and the measurement they read.
4
+ *
5
+ * Split out of `patch-lint.ts` (per-file line budget). `patch-lint.ts`
6
+ * re-exports this module's surface so callers keep importing from there.
7
+ */
8
+ import type { PatchLintIssue } from '../types/commands/index.js';
9
+ import type { FireForgeConfig, PatchLintPatchSizeMetric } from '../types/config.js';
10
+ import { type PatchSizeThresholds, type PatchSizeTierName } from './patch-lint-size-thresholds.js';
11
+ /**
12
+ * Returns true if the file path looks like a test file.
13
+ * Matches paths containing `/test/` or filenames starting with
14
+ * `browser_`, `test_`, or `xpcshell_` (all `.js`). This is the test class
15
+ * of both size rules: `file-too-large` picks the test thresholds with it,
16
+ * and the patch-size tier and the `addedCode` per-class split read it.
17
+ */
18
+ export declare function isTestFile(file: string): boolean;
19
+ /**
20
+ * Counts the total lines in a unified diff and the number of non-binary
21
+ * text lines, so binary hunks do not inflate patch size checks.
22
+ *
23
+ * Line counting agrees with `wc -l`: a trailing newline does not add a
24
+ * phantom empty line to either `total` or the binary-hunk accounting.
25
+ *
26
+ * @param diffContent - Raw unified diff string
27
+ * @returns Object with `total` line count and `textLines` (total minus binary hunk lines)
28
+ */
29
+ export declare function countNonBinaryDiffLines(diffContent: string): {
30
+ total: number;
31
+ textLines: number;
32
+ };
33
+ /**
34
+ * Describes which tier `resolvePatchSizeTier` selected and why.
35
+ * Consumers that want to surface the tier choice to the operator
36
+ * (e.g. a one-line `info()` when branding thresholds kick in) read
37
+ * this alongside the issues array from `lintPatchSize`.
38
+ */
39
+ export type PatchSizeTierDecision = {
40
+ tier: 'general';
41
+ } | {
42
+ tier: 'test';
43
+ } | {
44
+ tier: 'branding';
45
+ source: 'auto' | 'explicit';
46
+ };
47
+ /**
48
+ * Decides which patch-size threshold tier applies to a patch.
49
+ * Exported so `runPatchLint` and the per-patch `lint` command can
50
+ * surface the tier choice to the operator *without* depending on
51
+ * `lintPatchSize`'s internal return shape.
52
+ *
53
+ * Precedence: test > branding (explicit) > branding (auto) > general.
54
+ * The test tier beats branding because a table-driven regression test
55
+ * is legitimately large independent of whether the patch also claims
56
+ * branding shape, and the test-tier thresholds are already more
57
+ * permissive than branding, so "tests beat branding" is the
58
+ * defensive-for-tests choice.
59
+ */
60
+ export declare function resolvePatchSizeTier(filesAffected: ReadonlyArray<string>, patchTier?: 'branding'): PatchSizeTierDecision;
61
+ /**
62
+ * The size thresholds a tier enforces, with `patchLint.patchSizeThresholds`
63
+ * applied when `config` is passed. Public-API companion to
64
+ * {@link resolvePatchSizeTier} / {@link countNonBinaryDiffLines} so
65
+ * consumers can build waiver-freshness checks against the same numbers
66
+ * `large-patch-lines` / `large-patch-files` fire on instead of mirroring
67
+ * them. Without `config` it returns the built-in defaults.
68
+ *
69
+ * @param tier - The tier to read
70
+ * @param config - The project configuration, whose overrides apply
71
+ */
72
+ export declare function getPatchSizeThresholds(tier: PatchSizeTierName, config?: Pick<FireForgeConfig, 'patchLint'>): PatchSizeThresholds;
73
+ /** What a patch measures under the configured patch-size metric. */
74
+ export interface PatchSizeMeasurement {
75
+ /** The metric `lines` is counted in. */
76
+ metric: PatchLintPatchSizeMetric;
77
+ /** Counted lines, registration files left out. */
78
+ lines: number;
79
+ /**
80
+ * Of `lines`, those in test files. Only `addedCode` attributes lines per
81
+ * file, so this is 0 under `diff`.
82
+ */
83
+ testLines: number;
84
+ /** Files `large-patch-files` counts: the patch's files minus registration files. */
85
+ files: number;
86
+ /** Files left out of both counts as registration files. */
87
+ registrationFiles: number;
88
+ }
89
+ /**
90
+ * Measures a patch under `patchLint.patchSizeMetric`.
91
+ *
92
+ * `diff` counts the non-binary lines of the unified diff, headers and
93
+ * context included. `addedCode` counts the added lines that carry code,
94
+ * judged on each file's post-image read from `repoDir` (a hunk can start
95
+ * inside a block comment, so the `+` lines alone cannot tell), and skips
96
+ * lines inside Furnace fragment expansions. Files matching
97
+ * `patchLint.patchSizeRegistrationFiles` count toward neither number.
98
+ *
99
+ * @param repoDir - Engine directory holding the post-images
100
+ * @param diffContent - The patch's unified diff
101
+ * @param filesAffected - The patch's files
102
+ * @param config - Project configuration
103
+ */
104
+ export declare function measurePatchSize(repoDir: string, diffContent: string, filesAffected: readonly string[], config: Pick<FireForgeConfig, 'patchLint'>): Promise<PatchSizeMeasurement>;
105
+ /**
106
+ * Checks patch size against the tier's thresholds.
107
+ *
108
+ * @param filesAffected - Files touched by the patch
109
+ * @param measured - The {@link measurePatchSize} result, or a bare
110
+ * non-binary diff line count (the `diff` metric over every file)
111
+ * @param patchTier - Optional explicit tier override declared on
112
+ * `PatchMetadata.tier`. When `"branding"`, forces the branding
113
+ * thresholds regardless of `filesAffected`. Tests still win over
114
+ * branding (precedence `test > branding > general`).
115
+ * @param config - Project configuration, for `patchLint.patchSizeThresholds`
116
+ */
117
+ export declare function lintPatchSize(filesAffected: string[], measured: number | PatchSizeMeasurement, patchTier?: 'branding', config?: Pick<FireForgeConfig, 'patchLint'>): PatchLintIssue[];
@@ -0,0 +1,331 @@
1
+ // SPDX-License-Identifier: EUPL-1.2
2
+ /**
3
+ * Patch-size lint: the `large-patch-lines` and `large-patch-files` rules,
4
+ * the tier decision they share, and the measurement they read.
5
+ *
6
+ * Split out of `patch-lint.ts` (per-file line budget). `patch-lint.ts`
7
+ * re-exports this module's surface so callers keep importing from there.
8
+ */
9
+ import { join } from 'node:path';
10
+ import { pathExists, readText } from '../utils/fs.js';
11
+ import { codeLineMask } from './patch-lint-code-lines.js';
12
+ import { AGGREGATE_PATCH_FILE } from './patch-lint-diff-tag.js';
13
+ import { isPatchSizeRegistrationFile, resolvePatchSizeThresholds, } from './patch-lint-size-thresholds.js';
14
+ import { parseDiffGitHeader, parseDiffSections } from './patch-parse.js';
15
+ /**
16
+ * Shared remedy sentence for the over-budget findings. Every place an
17
+ * operator stands when a patch outgrows its budget must name the
18
+ * sanctioned one-transaction way out, or they reach for the wrong tools
19
+ * first. One constant, so the wording cannot drift.
20
+ */
21
+ const SPLIT_HINT = 'Consider splitting into smaller, focused patches — ' +
22
+ '"fireforge patch move-files <from> <to> --file <path> --create --order <n>" ' +
23
+ 'moves files into a new patch in one transaction.';
24
+ /**
25
+ * Fixed allowlist of non-branding sibling paths that real-world Firefox
26
+ * branding patches legitimately need to touch to register the new branding
27
+ * flavor with the top-level configure. A predicate requiring every file to
28
+ * live under `browser/branding/` drops a branding patch that also touches
29
+ * `browser/moz.configure` (the canonical registration point) into the
30
+ * general lint tier.
31
+ *
32
+ * Narrow on purpose: add entries only when a genuine branding patch
33
+ * cannot be expressed without a specific registration sibling. Pinned
34
+ * against ESR 140.x conventions at time of writing.
35
+ */
36
+ const BRANDING_REGISTRATION_FILES = new Set([
37
+ 'browser/moz.configure',
38
+ 'browser/confvars.sh',
39
+ ]);
40
+ /**
41
+ * Returns true when a patch qualifies for the branding threshold tier:
42
+ * every file lives either under `browser/branding/` or in the narrow
43
+ * registration allowlist, and the patch contains at least one file
44
+ * under `browser/branding/` (guard against a config-only patch
45
+ * accidentally qualifying as branding).
46
+ */
47
+ function isBrandingOnlyPatch(files) {
48
+ if (files.length === 0)
49
+ return false;
50
+ let hasBrandingFile = false;
51
+ for (const file of files) {
52
+ if (file.startsWith('browser/branding/')) {
53
+ hasBrandingFile = true;
54
+ continue;
55
+ }
56
+ if (BRANDING_REGISTRATION_FILES.has(file))
57
+ continue;
58
+ return false;
59
+ }
60
+ return hasBrandingFile;
61
+ }
62
+ /**
63
+ * Returns true if the file path looks like a test file.
64
+ * Matches paths containing `/test/` or filenames starting with
65
+ * `browser_`, `test_`, or `xpcshell_` (all `.js`). This is the test class
66
+ * of both size rules: `file-too-large` picks the test thresholds with it,
67
+ * and the patch-size tier and the `addedCode` per-class split read it.
68
+ */
69
+ export function isTestFile(file) {
70
+ if (file.includes('/test/'))
71
+ return true;
72
+ const basename = file.split('/').pop() ?? '';
73
+ return /^(?:browser_|test_|xpcshell_).*\.js$/.test(basename);
74
+ }
75
+ /**
76
+ * Counts the total lines in a unified diff and the number of non-binary
77
+ * text lines, so binary hunks do not inflate patch size checks.
78
+ *
79
+ * Line counting agrees with `wc -l`: a trailing newline does not add a
80
+ * phantom empty line to either `total` or the binary-hunk accounting.
81
+ *
82
+ * @param diffContent - Raw unified diff string
83
+ * @returns Object with `total` line count and `textLines` (total minus binary hunk lines)
84
+ */
85
+ export function countNonBinaryDiffLines(diffContent) {
86
+ return countDiffLines(diffContent, () => false);
87
+ }
88
+ /**
89
+ * {@link countNonBinaryDiffLines} with whole file sections left out of
90
+ * `textLines` when `isExcluded` names their path (registration files).
91
+ */
92
+ function countDiffLines(diffContent, isExcluded) {
93
+ const lines = diffContent.split('\n');
94
+ if (lines[lines.length - 1] === '')
95
+ lines.pop();
96
+ const total = lines.length;
97
+ let uncounted = 0;
98
+ let inBinaryHunk = false;
99
+ let inExcluded = false;
100
+ for (const line of lines) {
101
+ if (line.startsWith('GIT binary patch')) {
102
+ inBinaryHunk = true;
103
+ }
104
+ else if (line.startsWith('diff --git ')) {
105
+ inBinaryHunk = false;
106
+ const header = parseDiffGitHeader(line);
107
+ inExcluded = header !== null && isExcluded(header.targetPath);
108
+ }
109
+ if (inBinaryHunk || inExcluded) {
110
+ uncounted++;
111
+ }
112
+ }
113
+ return { total, textLines: total - uncounted };
114
+ }
115
+ /**
116
+ * Decides which patch-size threshold tier applies to a patch.
117
+ * Exported so `runPatchLint` and the per-patch `lint` command can
118
+ * surface the tier choice to the operator *without* depending on
119
+ * `lintPatchSize`'s internal return shape.
120
+ *
121
+ * Precedence: test > branding (explicit) > branding (auto) > general.
122
+ * The test tier beats branding because a table-driven regression test
123
+ * is legitimately large independent of whether the patch also claims
124
+ * branding shape, and the test-tier thresholds are already more
125
+ * permissive than branding, so "tests beat branding" is the
126
+ * defensive-for-tests choice.
127
+ */
128
+ export function resolvePatchSizeTier(filesAffected, patchTier) {
129
+ const allTests = filesAffected.length > 0 && filesAffected.every(isTestFile);
130
+ if (allTests)
131
+ return { tier: 'test' };
132
+ if (patchTier === 'branding')
133
+ return { tier: 'branding', source: 'explicit' };
134
+ if (isBrandingOnlyPatch(filesAffected))
135
+ return { tier: 'branding', source: 'auto' };
136
+ return { tier: 'general' };
137
+ }
138
+ /**
139
+ * The size thresholds a tier enforces, with `patchLint.patchSizeThresholds`
140
+ * applied when `config` is passed. Public-API companion to
141
+ * {@link resolvePatchSizeTier} / {@link countNonBinaryDiffLines} so
142
+ * consumers can build waiver-freshness checks against the same numbers
143
+ * `large-patch-lines` / `large-patch-files` fire on instead of mirroring
144
+ * them. Without `config` it returns the built-in defaults.
145
+ *
146
+ * @param tier - The tier to read
147
+ * @param config - The project configuration, whose overrides apply
148
+ */
149
+ export function getPatchSizeThresholds(tier, config) {
150
+ return resolvePatchSizeThresholds(tier, config?.patchLint?.patchSizeThresholds);
151
+ }
152
+ /**
153
+ * Measures a patch under `patchLint.patchSizeMetric`.
154
+ *
155
+ * `diff` counts the non-binary lines of the unified diff, headers and
156
+ * context included. `addedCode` counts the added lines that carry code,
157
+ * judged on each file's post-image read from `repoDir` (a hunk can start
158
+ * inside a block comment, so the `+` lines alone cannot tell), and skips
159
+ * lines inside Furnace fragment expansions. Files matching
160
+ * `patchLint.patchSizeRegistrationFiles` count toward neither number.
161
+ *
162
+ * @param repoDir - Engine directory holding the post-images
163
+ * @param diffContent - The patch's unified diff
164
+ * @param filesAffected - The patch's files
165
+ * @param config - Project configuration
166
+ */
167
+ export async function measurePatchSize(repoDir, diffContent, filesAffected, config) {
168
+ const globs = config.patchLint?.patchSizeRegistrationFiles ?? [];
169
+ const isRegistration = (file) => isPatchSizeRegistrationFile(file, globs);
170
+ const registrationFiles = filesAffected.filter(isRegistration).length;
171
+ const files = filesAffected.length - registrationFiles;
172
+ if (config.patchLint?.patchSizeMetric !== 'addedCode') {
173
+ const lines = countDiffLines(diffContent, isRegistration).textLines;
174
+ return { metric: 'diff', lines, testLines: 0, files, registrationFiles };
175
+ }
176
+ let lines = 0;
177
+ let testLines = 0;
178
+ for (const section of parseDiffSections(diffContent)) {
179
+ if (section.isBinary || isRegistration(section.targetPath))
180
+ continue;
181
+ const counted = await countAddedCodeLines(repoDir, section);
182
+ lines += counted;
183
+ if (isTestFile(section.targetPath))
184
+ testLines += counted;
185
+ }
186
+ return { metric: 'addedCode', lines, testLines, files, registrationFiles };
187
+ }
188
+ /**
189
+ * Counts one section's added lines that carry code in the post-image.
190
+ * Without a readable post-image, every non-blank added line counts: the
191
+ * upper bound, so a missing file never shrinks the measurement.
192
+ */
193
+ async function countAddedCodeLines(repoDir, section) {
194
+ const path = join(repoDir, section.targetPath);
195
+ const mask = (await pathExists(path))
196
+ ? codeLineMask(section.targetPath, await readText(path)).code
197
+ : undefined;
198
+ let count = 0;
199
+ for (const hunk of section.hunks) {
200
+ let newLine = hunk.newStart;
201
+ for (const line of hunk.lines) {
202
+ if (line.startsWith('\\') || line.startsWith('-'))
203
+ continue;
204
+ if (line.startsWith('+')) {
205
+ const isCode = mask ? mask[newLine - 1] === true : line.slice(1).trim() !== '';
206
+ if (isCode)
207
+ count++;
208
+ }
209
+ newLine++;
210
+ }
211
+ }
212
+ return count;
213
+ }
214
+ function bandFor(count, thresholds) {
215
+ if (thresholds.error !== null && count > thresholds.error)
216
+ return 'error';
217
+ if (count > thresholds.warning)
218
+ return 'warning';
219
+ if (count > thresholds.notice)
220
+ return 'notice';
221
+ return undefined;
222
+ }
223
+ /**
224
+ * Renders a patch-size finding. The notice band is advisory and says so;
225
+ * the warning band names what a `--max-warnings 0` gate does with it and
226
+ * where to tune it; the split hint rides on the bands that can fail a gate.
227
+ */
228
+ function formatPatchSizeMessage(subject, band, thresholds) {
229
+ const errorPart = thresholds.error === null ? '' : `, error threshold: ${thresholds.error}`;
230
+ if (band === 'error') {
231
+ return `${subject} (error threshold: ${thresholds.error}). ${SPLIT_HINT}`;
232
+ }
233
+ if (band === 'notice') {
234
+ return (`${subject}, over the design target of ${thresholds.notice} ` +
235
+ `(warning threshold: ${thresholds.warning}${errorPart}). ` +
236
+ 'Advisory; does not fail --max-warnings 0.');
237
+ }
238
+ return (`${subject} (warning threshold: ${thresholds.warning}${errorPart}). ` +
239
+ 'Reported as a warning, which a gate running --max-warnings 0 treats as a failure; ' +
240
+ 'tune "patchLint.patchSizeThresholds" if these limits are wrong for this project. ' +
241
+ SPLIT_HINT);
242
+ }
243
+ /**
244
+ * The line-count comparisons for a patch. Under `addedCode` a general-tier
245
+ * patch splits per class: test files against the test tier's lines,
246
+ * everything else against the general tier's, so a test riding with its
247
+ * subject is held to the same budget as a test-only patch.
248
+ */
249
+ function lineChecks(measurement, tier, thresholds, config) {
250
+ const perClass = measurement.metric === 'addedCode' && tier === 'general';
251
+ if (!perClass) {
252
+ return [{ count: measurement.lines, thresholds: thresholds.lines, scope: '' }];
253
+ }
254
+ if (measurement.testLines === 0) {
255
+ return [
256
+ { count: measurement.lines, thresholds: thresholds.lines, scope: '', share: 'product' },
257
+ ];
258
+ }
259
+ return [
260
+ {
261
+ count: measurement.lines - measurement.testLines,
262
+ thresholds: thresholds.lines,
263
+ scope: ' in non-test files',
264
+ share: 'product',
265
+ },
266
+ {
267
+ count: measurement.testLines,
268
+ thresholds: getPatchSizeThresholds('test', config).lines,
269
+ scope: ' in test files (test tier)',
270
+ share: 'test',
271
+ },
272
+ ];
273
+ }
274
+ /**
275
+ * Checks patch size against the tier's thresholds.
276
+ *
277
+ * @param filesAffected - Files touched by the patch
278
+ * @param measured - The {@link measurePatchSize} result, or a bare
279
+ * non-binary diff line count (the `diff` metric over every file)
280
+ * @param patchTier - Optional explicit tier override declared on
281
+ * `PatchMetadata.tier`. When `"branding"`, forces the branding
282
+ * thresholds regardless of `filesAffected`. Tests still win over
283
+ * branding (precedence `test > branding > general`).
284
+ * @param config - Project configuration, for `patchLint.patchSizeThresholds`
285
+ */
286
+ export function lintPatchSize(filesAffected, measured, patchTier, config) {
287
+ const measurement = typeof measured === 'number'
288
+ ? {
289
+ metric: 'diff',
290
+ lines: measured,
291
+ testLines: 0,
292
+ files: filesAffected.length,
293
+ registrationFiles: 0,
294
+ }
295
+ : measured;
296
+ const issues = [];
297
+ // Both rules read off the same decision so the file-count and line-count
298
+ // rules cannot disagree about which tier applies.
299
+ const decision = resolvePatchSizeTier(filesAffected, patchTier);
300
+ const thresholds = getPatchSizeThresholds(decision.tier, config);
301
+ const filesBand = bandFor(measurement.files, thresholds.files);
302
+ if (filesBand !== undefined) {
303
+ const registration = measurement.registrationFiles > 0
304
+ ? ` (not counting ${measurement.registrationFiles} registration file(s))`
305
+ : '';
306
+ issues.push({
307
+ file: AGGREGATE_PATCH_FILE,
308
+ check: 'large-patch-files',
309
+ message: formatPatchSizeMessage(`Patch affects ${measurement.files} files${registration}`, filesBand, thresholds.files),
310
+ severity: filesBand,
311
+ measurement: measurement.files,
312
+ });
313
+ }
314
+ for (const check of lineChecks(measurement, decision.tier, thresholds, config)) {
315
+ const band = bandFor(check.count, check.thresholds);
316
+ if (band === undefined)
317
+ continue;
318
+ const subject = measurement.metric === 'addedCode'
319
+ ? `Patch adds ${check.count} code lines${check.scope}`
320
+ : `Patch is ${check.count} lines`;
321
+ issues.push({
322
+ file: AGGREGATE_PATCH_FILE,
323
+ check: 'large-patch-lines',
324
+ message: formatPatchSizeMessage(subject, band, check.thresholds),
325
+ severity: band,
326
+ measurement: check.count,
327
+ ...(check.share !== undefined ? { share: check.share } : {}),
328
+ });
329
+ }
330
+ return issues;
331
+ }
@@ -1,4 +1,11 @@
1
- import type { PatchStagedRegistration } from '../types/commands/index.js';
1
+ import type { PatchStagedForwardImport, PatchStagedRegistration } from '../types/commands/index.js';
2
+ /**
3
+ * The `--reason` argument every printed `patch staged-dependency --add`
4
+ * remedy ends with. A declaration without a reason reads as unreviewed
5
+ * residue to a queue audit, so the paste-and-run command asks for one
6
+ * rather than inviting the operator to leave it out.
7
+ */
8
+ export declare const STAGED_DEPENDENCY_REASON_PLACEHOLDER = "--reason '<why this patch references a file the owner creates later>'";
2
9
  /** A patch that creates a given path, with its position in the queue. */
3
10
  export interface NewFileOwner {
4
11
  filename: string;
@@ -59,3 +66,13 @@ export declare function describeRegistrationFailure(failure: StagedRegistrationF
59
66
  * forward-registration remedy leave the declaring patch red.
60
67
  */
61
68
  export declare function quoteRegistrationLine(line: string): string;
69
+ /**
70
+ * The `staged-dependency-unused` fingerprint for one declaration on
71
+ * `holder`, the one spelling both the rule and the callers that need to
72
+ * recognise its findings (`patch split`/`move-files --create` deciding which
73
+ * declarations a move made unused) build it with.
74
+ *
75
+ * @param holder - Filename of the patch carrying the declaration
76
+ * @param declaration - Either declaration kind
77
+ */
78
+ export declare function stagedDependencyUnusedFingerprint(holder: string, declaration: PatchStagedForwardImport | PatchStagedRegistration): string;
@@ -12,6 +12,13 @@
12
12
  * `patch-lint-forward-registration.ts`, with no registrar or rule of its own.
13
13
  */
14
14
  import { basename } from 'node:path';
15
+ /**
16
+ * The `--reason` argument every printed `patch staged-dependency --add`
17
+ * remedy ends with. A declaration without a reason reads as unreviewed
18
+ * residue to a queue audit, so the paste-and-run command asks for one
19
+ * rather than inviting the operator to leave it out.
20
+ */
21
+ export const STAGED_DEPENDENCY_REASON_PLACEHOLDER = "--reason '<why this patch references a file the owner creates later>'";
15
22
  /**
16
23
  * Later-in-apply-order predicate shared by the forward-import scan, the
17
24
  * forward-registration rule and the registration validation: strictly
@@ -88,3 +95,16 @@ function isRegistrationLinePresent(entry, registration) {
88
95
  export function quoteRegistrationLine(line) {
89
96
  return line.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
90
97
  }
98
+ /**
99
+ * The `staged-dependency-unused` fingerprint for one declaration on
100
+ * `holder`, the one spelling both the rule and the callers that need to
101
+ * recognise its findings (`patch split`/`move-files --create` deciding which
102
+ * declarations a move made unused) build it with.
103
+ *
104
+ * @param holder - Filename of the patch carrying the declaration
105
+ * @param declaration - Either declaration kind
106
+ */
107
+ export function stagedDependencyUnusedFingerprint(holder, declaration) {
108
+ const matcher = 'specifier' in declaration ? declaration.specifier : `reg:${declaration.line}`;
109
+ return `staged-dependency-unused|${holder}|${declaration.file}|${matcher}|${declaration.creates}|${declaration.owner ?? ''}`;
110
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * `token-scale`: values of governed CSS properties must resolve to a token
3
+ * on the property's scale (`patchLint.tokenScales`).
4
+ *
5
+ * The raw-colour and token-prefix rules stop a patch from inventing colours
6
+ * or referencing foreign custom properties, but say nothing about
7
+ * `gap: 7px`, `font-size: 13px` or `z-index: 9999`. Those are the values a
8
+ * design scale exists to remove, and without a rule they drift back one
9
+ * literal at a time. A scale names its properties, the token prefix (or
10
+ * prefixes) that defines its steps, and the literals that are not steps at
11
+ * all (`0`, `auto`, a percentage).
12
+ *
13
+ * Judged per value atom, after peeling `var()` innermost-first so a fallback
14
+ * is held to the same scale as the token it backs: `var(--x-gap, 7px)` is a
15
+ * literal in disguise. `calc()`, `min()`, `max()` and `clamp()` are
16
+ * transparent, so a value built from tokens passes and one that adds a raw
17
+ * length does not. Inside them, `allowInCalc` names literals legal only
18
+ * there (a unitless multiplier), and `offsetCap` lets a declaration
19
+ * subtract a few px from a token (a border inset) without allowing the px
20
+ * value anywhere else.
21
+ *
22
+ * Declarations inside descriptor at-rules (`@font-face`, `@counter-style`,
23
+ * `@property`, `@page`, …) are not property declarations and are not
24
+ * judged: `font-weight` in `@font-face` names a face, not a type step.
25
+ *
26
+ * Runs over CSS files the patch creates, not files it modifies: an upstream
27
+ * stylesheet is not the fork's to put on a scale. A file a scale `exclude`s
28
+ * is not judged against that scale. A line carrying
29
+ * `fireforge-ignore: token-scale` is skipped. A scale with `minFiles` also
30
+ * fails the queue (`token-scale-vacuous`) when fewer created files carry
31
+ * its properties, so an emptied scan set cannot pass by judging nothing.
32
+ */
33
+ import type { PatchLintIssue } from '../types/commands/index.js';
34
+ import type { PatchLintTokenScale } from '../types/config.js';
35
+ /**
36
+ * Returns the first atom of `value` that is off `scale`, or undefined when
37
+ * every atom resolves to the scale.
38
+ */
39
+ export declare function findOffScaleAtom(value: string, scale: PatchLintTokenScale): string | undefined;
40
+ /**
41
+ * Lints one patch-created CSS file against the configured scales.
42
+ *
43
+ * @param file - Engine-relative path, for the issue and the `exclude` globs
44
+ * @param css - The file's full content
45
+ * @param scales - `patchLint.tokenScales`
46
+ * @returns One `token-scale` error per off-scale declaration
47
+ */
48
+ export declare function lintTokenScales(file: string, css: string, scales: readonly PatchLintTokenScale[]): PatchLintIssue[];
49
+ /**
50
+ * The `minFiles` floor of every scale over the queue's created stylesheets:
51
+ * one `token-scale-vacuous` error per scale that fewer created CSS files
52
+ * (outside its `exclude`) carry a declaration of.
53
+ *
54
+ * @param createdFiles - Every patch-created file's path and content
55
+ * @param scales - `patchLint.tokenScales`
56
+ */
57
+ export declare function lintTokenScaleFloors(createdFiles: Iterable<readonly [string, string]>, scales: readonly PatchLintTokenScale[]): PatchLintIssue[];