paperlint 7.2.0 → 9.0.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 (474) hide show
  1. package/CLAUDE.md +9 -25
  2. package/CONTRIBUTING.md +5 -4
  3. package/README.md +4 -3
  4. package/dist/adapters/bibtex/index.d.ts +3 -0
  5. package/dist/adapters/bibtex/index.d.ts.map +1 -0
  6. package/dist/adapters/bibtex/index.js +103 -0
  7. package/dist/adapters/bibtex/index.js.map +1 -0
  8. package/dist/adapters/latex/filecontents.d.ts +33 -0
  9. package/dist/adapters/latex/filecontents.d.ts.map +1 -0
  10. package/dist/adapters/latex/filecontents.js +65 -0
  11. package/dist/adapters/latex/filecontents.js.map +1 -0
  12. package/dist/adapters/latex/includes.d.ts +3 -3
  13. package/dist/adapters/latex/includes.d.ts.map +1 -1
  14. package/dist/adapters/latex/includes.js +18 -10
  15. package/dist/adapters/latex/includes.js.map +1 -1
  16. package/dist/adapters/latex/index.d.ts.map +1 -1
  17. package/dist/adapters/latex/index.js +2 -0
  18. package/dist/adapters/latex/index.js.map +1 -1
  19. package/dist/adapters/latex/nodes.d.ts +12 -0
  20. package/dist/adapters/latex/nodes.d.ts.map +1 -1
  21. package/dist/adapters/latex/nodes.js +39 -0
  22. package/dist/adapters/latex/nodes.js.map +1 -1
  23. package/dist/adapters/latex/parse.d.ts +7 -1
  24. package/dist/adapters/latex/parse.d.ts.map +1 -1
  25. package/dist/adapters/latex/parse.js +55 -6
  26. package/dist/adapters/latex/parse.js.map +1 -1
  27. package/dist/adapters/memory/index.d.ts +3 -0
  28. package/dist/adapters/memory/index.d.ts.map +1 -1
  29. package/dist/adapters/memory/index.js +9 -0
  30. package/dist/adapters/memory/index.js.map +1 -1
  31. package/dist/adapters/references/index.d.ts.map +1 -1
  32. package/dist/adapters/references/index.js +27 -24
  33. package/dist/adapters/references/index.js.map +1 -1
  34. package/dist/adapters/sources-record/index.d.ts +9 -0
  35. package/dist/adapters/sources-record/index.d.ts.map +1 -0
  36. package/dist/adapters/sources-record/index.js +68 -0
  37. package/dist/adapters/sources-record/index.js.map +1 -0
  38. package/dist/adapters/tex-output/blg.d.ts +9 -0
  39. package/dist/adapters/tex-output/blg.d.ts.map +1 -0
  40. package/dist/adapters/tex-output/blg.js +20 -0
  41. package/dist/adapters/tex-output/blg.js.map +1 -0
  42. package/dist/adapters/tex-output/fls.d.ts +8 -0
  43. package/dist/adapters/tex-output/fls.d.ts.map +1 -0
  44. package/dist/adapters/tex-output/fls.js +16 -0
  45. package/dist/adapters/tex-output/fls.js.map +1 -0
  46. package/dist/adapters/tex-output/index.d.ts +7 -0
  47. package/dist/adapters/tex-output/index.d.ts.map +1 -0
  48. package/dist/adapters/tex-output/index.js +7 -0
  49. package/dist/adapters/tex-output/index.js.map +1 -0
  50. package/dist/bib-rules.d.ts +47 -0
  51. package/dist/bib-rules.d.ts.map +1 -0
  52. package/dist/bib-rules.js +127 -0
  53. package/dist/bib-rules.js.map +1 -0
  54. package/dist/build.d.ts +29 -1
  55. package/dist/build.d.ts.map +1 -1
  56. package/dist/build.js +41 -30
  57. package/dist/build.js.map +1 -1
  58. package/dist/claim-provenance.d.ts +2 -2
  59. package/dist/cli.d.ts +9 -5
  60. package/dist/cli.d.ts.map +1 -1
  61. package/dist/cli.js +43 -68
  62. package/dist/cli.js.map +1 -1
  63. package/dist/domain/paper-source.d.ts +1 -10
  64. package/dist/domain/paper-source.d.ts.map +1 -1
  65. package/dist/domain/paper-source.js +34 -24
  66. package/dist/domain/paper-source.js.map +1 -1
  67. package/dist/domain/paper-sources.d.ts +72 -0
  68. package/dist/domain/paper-sources.d.ts.map +1 -0
  69. package/dist/domain/paper-sources.js +18 -0
  70. package/dist/domain/paper-sources.js.map +1 -0
  71. package/dist/domain/sources-record.d.ts +102 -0
  72. package/dist/domain/sources-record.d.ts.map +1 -0
  73. package/dist/domain/sources-record.js +38 -0
  74. package/dist/domain/sources-record.js.map +1 -0
  75. package/dist/domain/tex-run.d.ts +25 -0
  76. package/dist/domain/tex-run.d.ts.map +1 -0
  77. package/dist/domain/tex-run.js +79 -0
  78. package/dist/domain/tex-run.js.map +1 -0
  79. package/dist/eslint-rules/latex-language.d.ts.map +1 -1
  80. package/dist/eslint-rules/latex-language.js +10 -13
  81. package/dist/eslint-rules/latex-language.js.map +1 -1
  82. package/dist/eslint-rules/paper-context.d.ts.map +1 -1
  83. package/dist/eslint-rules/paper-context.js +6 -5
  84. package/dist/eslint-rules/paper-context.js.map +1 -1
  85. package/dist/eslint-rules/paper-typography.d.ts +0 -9
  86. package/dist/eslint-rules/paper-typography.d.ts.map +1 -1
  87. package/dist/eslint-rules/paper-typography.js +34 -96
  88. package/dist/eslint-rules/paper-typography.js.map +1 -1
  89. package/dist/eslint-rules/papers.d.ts +1 -3
  90. package/dist/eslint-rules/papers.d.ts.map +1 -1
  91. package/dist/eslint-rules/papers.js +2 -4
  92. package/dist/eslint-rules/papers.js.map +1 -1
  93. package/dist/eslint-rules/tex-build.d.ts.map +1 -1
  94. package/dist/eslint-rules/tex-build.js +8 -25
  95. package/dist/eslint-rules/tex-build.js.map +1 -1
  96. package/dist/init.d.ts +1 -4
  97. package/dist/init.d.ts.map +1 -1
  98. package/dist/init.js +3 -9
  99. package/dist/init.js.map +1 -1
  100. package/dist/latex-log.d.ts +10 -0
  101. package/dist/latex-log.d.ts.map +1 -1
  102. package/dist/latex-log.js +10 -0
  103. package/dist/latex-log.js.map +1 -1
  104. package/dist/latex-loop.d.ts +2 -0
  105. package/dist/latex-loop.d.ts.map +1 -1
  106. package/dist/latex-loop.js.map +1 -1
  107. package/dist/lib/markdown.d.ts +5 -81
  108. package/dist/lib/markdown.d.ts.map +1 -1
  109. package/dist/lib/markdown.js +5 -116
  110. package/dist/lib/markdown.js.map +1 -1
  111. package/dist/lib/paper-config.d.ts.map +1 -1
  112. package/dist/lib/paper-config.js +0 -2
  113. package/dist/lib/paper-config.js.map +1 -1
  114. package/dist/lib/skill-eval-fixture.d.ts +6 -4
  115. package/dist/lib/skill-eval-fixture.d.ts.map +1 -1
  116. package/dist/lib/skill-eval-fixture.js +25 -18
  117. package/dist/lib/skill-eval-fixture.js.map +1 -1
  118. package/dist/new-paper.d.ts +5 -11
  119. package/dist/new-paper.d.ts.map +1 -1
  120. package/dist/new-paper.js +12 -23
  121. package/dist/new-paper.js.map +1 -1
  122. package/dist/package-dirs.d.ts.map +1 -1
  123. package/dist/package-dirs.js +3 -2
  124. package/dist/package-dirs.js.map +1 -1
  125. package/dist/paper-files.d.ts +4 -4
  126. package/dist/paper-includes.d.ts +4 -7
  127. package/dist/paper-includes.d.ts.map +1 -1
  128. package/dist/paper-includes.js +29 -21
  129. package/dist/paper-includes.js.map +1 -1
  130. package/dist/paper-prose.d.ts +17 -0
  131. package/dist/paper-prose.d.ts.map +1 -0
  132. package/dist/paper-prose.js +46 -0
  133. package/dist/paper-prose.js.map +1 -0
  134. package/dist/paper-record.d.ts +25 -0
  135. package/dist/paper-record.d.ts.map +1 -0
  136. package/dist/paper-record.js +39 -0
  137. package/dist/paper-record.js.map +1 -0
  138. package/dist/paper-sources.d.ts +66 -0
  139. package/dist/paper-sources.d.ts.map +1 -0
  140. package/dist/paper-sources.js +92 -0
  141. package/dist/paper-sources.js.map +1 -0
  142. package/dist/ports/bib-reader.d.ts +18 -0
  143. package/dist/ports/bib-reader.d.ts.map +1 -0
  144. package/dist/ports/bib-reader.js +2 -0
  145. package/dist/ports/bib-reader.js.map +1 -0
  146. package/dist/ports/check-references.d.ts +9 -4
  147. package/dist/ports/check-references.d.ts.map +1 -1
  148. package/dist/ports/latex.d.ts +15 -0
  149. package/dist/ports/latex.d.ts.map +1 -1
  150. package/dist/ports/sources-codec.d.ts +11 -0
  151. package/dist/ports/sources-codec.d.ts.map +1 -0
  152. package/dist/ports/sources-codec.js +2 -0
  153. package/dist/ports/sources-codec.js.map +1 -0
  154. package/dist/ports/tex-output.d.ts +17 -0
  155. package/dist/ports/tex-output.d.ts.map +1 -0
  156. package/dist/ports/tex-output.js +2 -0
  157. package/dist/ports/tex-output.js.map +1 -0
  158. package/dist/recorded-bibliography.d.ts +89 -0
  159. package/dist/recorded-bibliography.d.ts.map +1 -0
  160. package/dist/recorded-bibliography.js +136 -0
  161. package/dist/recorded-bibliography.js.map +1 -0
  162. package/dist/reference-rules.d.ts +5 -5
  163. package/dist/reference-rules.d.ts.map +1 -1
  164. package/dist/reference-rules.js +150 -77
  165. package/dist/reference-rules.js.map +1 -1
  166. package/dist/references.d.ts +71 -16
  167. package/dist/references.d.ts.map +1 -1
  168. package/dist/references.js +110 -26
  169. package/dist/references.js.map +1 -1
  170. package/dist/register-bands.d.ts +3 -3
  171. package/dist/register-bands.d.ts.map +1 -1
  172. package/dist/register-bands.js.map +1 -1
  173. package/dist/register.d.ts +2 -2
  174. package/dist/sources-record.d.ts +38 -0
  175. package/dist/sources-record.d.ts.map +1 -0
  176. package/dist/sources-record.js +123 -0
  177. package/dist/sources-record.js.map +1 -0
  178. package/dist/sources-rules.d.ts +44 -0
  179. package/dist/sources-rules.d.ts.map +1 -0
  180. package/dist/sources-rules.js +76 -0
  181. package/dist/sources-rules.js.map +1 -0
  182. package/dist/structure.d.ts.map +1 -1
  183. package/dist/structure.js +4 -3
  184. package/dist/structure.js.map +1 -1
  185. package/dist/tex-paper.d.ts +10 -15
  186. package/dist/tex-paper.d.ts.map +1 -1
  187. package/dist/tex-paper.js +24 -40
  188. package/dist/tex-paper.js.map +1 -1
  189. package/dist/tex-venue-rules.d.ts +3 -3
  190. package/dist/tex-venue-rules.d.ts.map +1 -1
  191. package/dist/tex-venue-rules.js.map +1 -1
  192. package/dist/types.d.ts +0 -2
  193. package/dist/types.d.ts.map +1 -1
  194. package/docs/configuration.md +18 -12
  195. package/docs/design/paper-sources.md +197 -0
  196. package/docs/e2e.md +4 -6
  197. package/docs/package-shape-options.md +1 -1
  198. package/docs/prior-art/paper-folder-scaffolding.md +24 -29
  199. package/docs/references.md +34 -8
  200. package/docs/rules/bib/reachable-entry.md +64 -0
  201. package/docs/rules/paper/sources-fresh.md +81 -0
  202. package/docs/rules/tex/claim-provenance.md +0 -1
  203. package/docs/rules.md +62 -61
  204. package/eslint-rules/latex-language.harness.mjs +3 -3
  205. package/eslint-rules/latex-language.ts +10 -13
  206. package/eslint-rules/paper-context.ts +6 -5
  207. package/eslint-rules/paper-typography.test.mjs +29 -157
  208. package/eslint-rules/paper-typography.ts +35 -104
  209. package/eslint-rules/papers.harness.mjs +1 -1
  210. package/eslint-rules/papers.ts +2 -4
  211. package/eslint-rules/tex-build.harness.mjs +2 -2
  212. package/eslint-rules/tex-build.ts +8 -25
  213. package/eslint.config.mjs +22 -1
  214. package/fixtures/build-e2e/aidc/paper.tex +1 -1
  215. package/fixtures/build-e2e/anon-ack/paper.tex +1 -1
  216. package/fixtures/build-e2e/anon-author/paper.tex +1 -1
  217. package/fixtures/build-e2e/anon-bib/paper.tex +1 -1
  218. package/fixtures/build-e2e/anon-href/paper.tex +1 -1
  219. package/fixtures/build-e2e/anon-macro/paper.tex +1 -1
  220. package/fixtures/build-e2e/anon-pdfauthor/paper.tex +1 -1
  221. package/fixtures/paper-sources/p1/paper.tex +30 -0
  222. package/fixtures/paper-sources/p1/refs.bib +6 -0
  223. package/fixtures/paper-sources/p1/sections/dead.tex +6 -0
  224. package/fixtures/paper-sources/p1/sections/intro.tex +7 -0
  225. package/fixtures/paper-sources/p1/sections/parked.tex +6 -0
  226. package/fixtures/paper-sources/p1/tex-truth.json +37 -0
  227. package/fixtures/paper-sources/p1/versions/2026-01-01-review.tex +4 -0
  228. package/fixtures/paper-sources/v1-stale/paper.tex +14 -0
  229. package/fixtures/paper-sources/v1-stale/refs.bib +6 -0
  230. package/fixtures/paper-sources/v1-stale/tex-truth.json +32 -0
  231. package/fixtures/paper-sources/v10-ifthenelse/anon.bib +1 -0
  232. package/fixtures/paper-sources/v10-ifthenelse/paper.tex +9 -0
  233. package/fixtures/paper-sources/v10-ifthenelse/real.bib +1 -0
  234. package/fixtures/paper-sources/v10-ifthenelse/tex-truth.json +28 -0
  235. package/fixtures/paper-sources/v11-two-blocks/paper.tex +12 -0
  236. package/fixtures/paper-sources/v11-two-blocks/tex-truth.json +30 -0
  237. package/fixtures/paper-sources/v13-percent-text/paper.tex +6 -0
  238. package/fixtures/paper-sources/v13-percent-text/refs.bib +3 -0
  239. package/fixtures/paper-sources/v13-percent-text/tex-truth.json +30 -0
  240. package/fixtures/paper-sources/v15-after-end/paper.tex +6 -0
  241. package/fixtures/paper-sources/v15-after-end/refs.bib +1 -0
  242. package/fixtures/paper-sources/v15-after-end/tex-truth.json +17 -0
  243. package/fixtures/paper-sources/v16-included-block/bibblock.tex +3 -0
  244. package/fixtures/paper-sources/v16-included-block/paper.tex +7 -0
  245. package/fixtures/paper-sources/v16-included-block/refs.bib +1 -0
  246. package/fixtures/paper-sources/v16-included-block/tex-truth.json +35 -0
  247. package/fixtures/paper-sources/v17-include-order/bibsetup.tex +1 -0
  248. package/fixtures/paper-sources/v17-include-order/first.bib +1 -0
  249. package/fixtures/paper-sources/v17-include-order/later.bib +1 -0
  250. package/fixtures/paper-sources/v17-include-order/paper.tex +7 -0
  251. package/fixtures/paper-sources/v17-include-order/tex-truth.json +40 -0
  252. package/fixtures/paper-sources/v2-overwrite/paper.tex +14 -0
  253. package/fixtures/paper-sources/v2-overwrite/refs.bib +6 -0
  254. package/fixtures/paper-sources/v2-overwrite/tex-truth.json +30 -0
  255. package/fixtures/paper-sources/v22-parked-thebibliography/paper.tex +7 -0
  256. package/fixtures/paper-sources/v22-parked-thebibliography/tex-truth.json +17 -0
  257. package/fixtures/paper-sources/v23-parked-include/old.bib +1 -0
  258. package/fixtures/paper-sources/v23-parked-include/paper.tex +7 -0
  259. package/fixtures/paper-sources/v23-parked-include/parked.tex +1 -0
  260. package/fixtures/paper-sources/v23-parked-include/refs.bib +1 -0
  261. package/fixtures/paper-sources/v23-parked-include/tex-truth.json +28 -0
  262. package/fixtures/paper-sources/v24-quoted-fields/paper.tex +6 -0
  263. package/fixtures/paper-sources/v24-quoted-fields/refs.bib +5 -0
  264. package/fixtures/paper-sources/v24-quoted-fields/tex-truth.json +32 -0
  265. package/fixtures/paper-sources/v25-string-differs/paper.tex +10 -0
  266. package/fixtures/paper-sources/v25-string-differs/refs.bib +2 -0
  267. package/fixtures/paper-sources/v25-string-differs/tex-truth.json +32 -0
  268. package/fixtures/paper-sources/v26-comment-in-names/one.bib +1 -0
  269. package/fixtures/paper-sources/v26-comment-in-names/paper.tex +7 -0
  270. package/fixtures/paper-sources/v26-comment-in-names/tex-truth.json +32 -0
  271. package/fixtures/paper-sources/v26-comment-in-names/two.bib +1 -0
  272. package/fixtures/paper-sources/v27-shared-string/abbreviations.bib +2 -0
  273. package/fixtures/paper-sources/v27-shared-string/paper.tex +6 -0
  274. package/fixtures/paper-sources/v27-shared-string/references.bib +6 -0
  275. package/fixtures/paper-sources/v27-shared-string/tex-truth.json +31 -0
  276. package/fixtures/paper-sources/v28-shared-string-block/abbreviations.bib +2 -0
  277. package/fixtures/paper-sources/v28-shared-string-block/paper.tex +14 -0
  278. package/fixtures/paper-sources/v28-shared-string-block/tex-truth.json +33 -0
  279. package/fixtures/paper-sources/v29-generated-input/paper.tex +9 -0
  280. package/fixtures/paper-sources/v29-generated-input/tex-truth.json +24 -0
  281. package/fixtures/paper-sources/v3-declared/paper.bib +6 -0
  282. package/fixtures/paper-sources/v3-declared/paper.tex +6 -0
  283. package/fixtures/paper-sources/v3-declared/tex-truth.json +28 -0
  284. package/fixtures/paper-sources/v30-name-next-line/paper.tex +14 -0
  285. package/fixtures/paper-sources/v30-name-next-line/tex-truth.json +30 -0
  286. package/fixtures/paper-sources/v4-commented/paper.tex +14 -0
  287. package/fixtures/paper-sources/v4-commented/refs.bib +6 -0
  288. package/fixtures/paper-sources/v4-commented/tex-truth.json +28 -0
  289. package/fixtures/paper-sources/v5-percent-entry/paper.tex +20 -0
  290. package/fixtures/paper-sources/v5-percent-entry/tex-truth.json +37 -0
  291. package/fixtures/paper-sources/v6-unclosed/paper.tex +6 -0
  292. package/fixtures/paper-sources/v6-unclosed/refs.bib +5 -0
  293. package/fixtures/paper-sources/v6-unclosed/tex-truth.json +37 -0
  294. package/fixtures/paper-sources/v8-jobname/paper.tex +9 -0
  295. package/fixtures/paper-sources/v8-jobname/tex-truth.json +30 -0
  296. package/fixtures/paper-sources/v9-two-bibliographies/one.bib +1 -0
  297. package/fixtures/paper-sources/v9-two-bibliographies/paper.tex +7 -0
  298. package/fixtures/paper-sources/v9-two-bibliographies/tex-truth.json +35 -0
  299. package/fixtures/paper-sources/v9-two-bibliographies/two.bib +1 -0
  300. package/fixtures/paper-typography/clean-paper/paper.tex +1 -1
  301. package/fixtures/paper-typography/messy-paper/paper.tex +1 -1
  302. package/hooks/hooks.harness.ts +15 -15
  303. package/hooks/paper-edit-guard.hook.mjs +5 -8
  304. package/hooks/paper-edit-guard.test.ts +12 -3
  305. package/hooks/paper-skills-nudge.hook.mjs +2 -3
  306. package/hooks/paper-skills-nudge.test.ts +13 -3
  307. package/hooks/paper-status-gates.hook.mjs +2 -2
  308. package/hooks/paper-status-gates.test.ts +14 -2
  309. package/lib/markdown.test.mjs +5 -60
  310. package/lib/markdown.ts +9 -136
  311. package/lib/paper-config.ts +0 -2
  312. package/lib/skill-checks.test.mjs +4 -1
  313. package/lib/skill-eval-fixture.ts +25 -18
  314. package/package.json +2 -12
  315. package/presets/realm.jsonc +1 -1
  316. package/scripts/check.test.ts +23 -1
  317. package/scripts/check.ts +7 -3
  318. package/scripts/coverage-config.test.ts +19 -10
  319. package/scripts/harness-api.frozen.json +0 -5
  320. package/scripts/layer-legacy-frozen.test.ts +41 -2
  321. package/scripts/layer-legacy-frozen.ts +31 -2
  322. package/skills/cold-read-diff/SKILL.md +3 -3
  323. package/skills/cold-read-diff/SKILL.md.spec.ts +2 -2
  324. package/skills/grade-paper-writing/SKILL.md +15 -22
  325. package/skills/grade-paper-writing/SKILL.md.spec.ts +14 -21
  326. package/skills/grade-paper-writing/__snapshots__/prose-lint.test.ts.snap +40 -26
  327. package/skills/grade-paper-writing/prose-lint.mjs +117 -278
  328. package/skills/grade-paper-writing/prose-lint.test.ts +230 -79
  329. package/skills/paper-adversarial-review/SKILL.md +2 -2
  330. package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -1
  331. package/skills/paper-pipeline/SKILL.md +9 -12
  332. package/skills/paper-pipeline/SKILL.md.spec.ts +8 -11
  333. package/skills/paper-pipeline/description-language.eval.mjs +25 -15
  334. package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +25 -15
  335. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +25 -15
  336. package/skills/paper-pipeline/pipeline-firing.eval.mjs +27 -16
  337. package/skills/paper-pipeline/pipeline-language.eval.mjs +25 -15
  338. package/skills/paper-pipeline/references/acceptance-gate.md +16 -20
  339. package/skills/paper-pipeline/references/artifact-checklist.md +4 -5
  340. package/skills/paper-pipeline/references/pipeline-status-template.md +1 -1
  341. package/skills/paper-pipeline/scripts/README.md +0 -4
  342. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +91 -105
  343. package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +85 -241
  344. package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +166 -153
  345. package/skills/paper-pipeline/scripts/generated-code.harness.mjs +3 -3
  346. package/skills/paper-status/SKILL.md +2 -2
  347. package/skills/paper-status/SKILL.md.spec.ts +1 -1
  348. package/skills/render-paper/SKILL.md +2 -2
  349. package/skills/render-paper/SKILL.md.spec.ts +1 -1
  350. package/skills/render-paper/extract-pdf-facts.mjs +2 -2
  351. package/skills/tighten-paper/SKILL.md +29 -42
  352. package/skills/tighten-paper/SKILL.md.spec.ts +28 -41
  353. package/skills/verify-citations/SKILL.md +7 -4
  354. package/skills/verify-citations/SKILL.md.spec.ts +6 -3
  355. package/skills/verify-citations/scripts/bib-authors.check.test.mjs +17 -32
  356. package/skills/verify-citations/scripts/bib-authors.cli.test.ts +138 -43
  357. package/skills/verify-citations/scripts/bib-authors.d.mts +22 -2
  358. package/skills/verify-citations/scripts/bib-authors.mjs +54 -193
  359. package/skills/verify-citations/scripts/bib-authors.test.mjs +1 -44
  360. package/skills/verify-citations/scripts/verify-cites.cli.test.ts +16 -0
  361. package/skills/verify-citations/scripts/verify-cites.d.mts +19 -3
  362. package/skills/verify-citations/scripts/verify-cites.mjs +42 -108
  363. package/skills/verify-citations/scripts/verify-cites.test.mjs +23 -36
  364. package/src/adapters/bibtex/index.test.ts +163 -0
  365. package/src/adapters/bibtex/index.ts +155 -0
  366. package/src/adapters/latex/filecontents.ts +114 -0
  367. package/src/adapters/latex/includes.ts +18 -10
  368. package/src/adapters/latex/index.test.ts +73 -0
  369. package/src/adapters/latex/index.ts +2 -0
  370. package/src/adapters/latex/nodes.ts +64 -0
  371. package/src/adapters/latex/parse.test.ts +38 -0
  372. package/src/adapters/latex/parse.ts +67 -6
  373. package/src/adapters/memory/index.ts +17 -0
  374. package/src/adapters/references/index.test.ts +75 -21
  375. package/src/adapters/references/index.ts +37 -32
  376. package/src/adapters/sources-record/index.test.ts +87 -0
  377. package/src/adapters/sources-record/index.ts +82 -0
  378. package/src/adapters/tex-output/blg.ts +27 -0
  379. package/src/adapters/tex-output/fls.ts +24 -0
  380. package/src/adapters/tex-output/index.test.ts +171 -0
  381. package/src/adapters/tex-output/index.ts +12 -0
  382. package/src/bib-rules.test.ts +356 -0
  383. package/src/bib-rules.ts +228 -0
  384. package/src/bibliography-at.test.ts +286 -0
  385. package/src/build.harness.mjs +2 -2
  386. package/src/build.test.ts +211 -1
  387. package/src/build.ts +101 -41
  388. package/src/claim-provenance.test.ts +33 -7
  389. package/src/claim-provenance.ts +2 -2
  390. package/src/cli.harness.mjs +46 -56
  391. package/src/cli.test.ts +44 -48
  392. package/src/cli.ts +51 -82
  393. package/src/domain/paper-source.test.ts +58 -20
  394. package/src/domain/paper-source.ts +38 -42
  395. package/src/domain/paper-sources.ts +94 -0
  396. package/src/domain/sources-record.test.ts +71 -0
  397. package/src/domain/sources-record.ts +136 -0
  398. package/src/domain/tex-run.test.ts +228 -0
  399. package/src/domain/tex-run.ts +139 -0
  400. package/src/folder-venue-rule.test.ts +1 -1
  401. package/src/heading-case.test.ts +24 -10
  402. package/src/init.test.ts +6 -7
  403. package/src/init.ts +3 -22
  404. package/src/latex-log.ts +20 -0
  405. package/src/latex-loop.harness.ts +1 -0
  406. package/src/latex-loop.ts +2 -0
  407. package/src/lint-fix.test.ts +10 -4
  408. package/src/linted-set.test.ts +9 -1
  409. package/src/new-paper.harness.mjs +12 -30
  410. package/src/new-paper.test.ts +15 -11
  411. package/src/new-paper.ts +11 -30
  412. package/src/package-dirs.ts +3 -2
  413. package/src/paper-files.test.ts +5 -4
  414. package/src/paper-files.ts +4 -4
  415. package/src/paper-includes.test.ts +157 -38
  416. package/src/paper-includes.ts +39 -35
  417. package/src/paper-prose.test.ts +78 -0
  418. package/src/paper-prose.ts +67 -0
  419. package/src/paper-record.test.ts +173 -0
  420. package/src/paper-record.ts +66 -0
  421. package/src/paper-settings-commands.test.ts +5 -2
  422. package/src/paper-sources.ts +151 -0
  423. package/src/parse-args.test.ts +0 -1
  424. package/src/ports/bib-reader.ts +27 -0
  425. package/src/ports/check-references.ts +7 -3
  426. package/src/ports/latex.ts +19 -0
  427. package/src/ports/sources-codec.ts +11 -0
  428. package/src/ports/tex-output.ts +17 -0
  429. package/src/recorded-bibliography.ts +297 -0
  430. package/src/reference-rules.ts +217 -104
  431. package/src/references.test.ts +520 -177
  432. package/src/references.ts +185 -37
  433. package/src/register-bands.test.ts +5 -1
  434. package/src/register-bands.ts +3 -5
  435. package/src/register.test.ts +6 -1
  436. package/src/register.ts +2 -2
  437. package/src/rule-cases.test.ts +68 -12
  438. package/src/rule-docs.test.ts +0 -1
  439. package/src/sources-record.test.ts +308 -0
  440. package/src/sources-record.ts +231 -0
  441. package/src/sources-rules.test.ts +152 -0
  442. package/src/sources-rules.ts +117 -0
  443. package/src/structure.harness.ts +5 -11
  444. package/src/structure.ts +4 -3
  445. package/src/tex-paper.test.ts +148 -78
  446. package/src/tex-paper.ts +31 -61
  447. package/src/tex-venue-rules.test.ts +36 -8
  448. package/src/tex-venue-rules.ts +3 -5
  449. package/src/types.ts +0 -2
  450. package/dist/eslint-rules/bib-reachable-entry.d.ts +0 -22
  451. package/dist/eslint-rules/bib-reachable-entry.d.ts.map +0 -1
  452. package/dist/eslint-rules/bib-reachable-entry.js +0 -75
  453. package/dist/eslint-rules/bib-reachable-entry.js.map +0 -1
  454. package/eslint-rules/bib-reachable-entry.ts +0 -76
  455. package/fixtures/real-markdown-paper/baseline.json +0 -22
  456. package/fixtures/real-markdown-paper/baseline.ts +0 -70
  457. package/skills/paper-pipeline/PIPELINE-MAP.md +0 -381
  458. package/skills/paper-pipeline/pipeline-firing.baseline.json +0 -270
  459. package/skills/paper-pipeline/references/sweep-2026-08-09-ideal-pipeline.md +0 -585
  460. package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +0 -492
  461. package/skills/paper-pipeline/scripts/artifact-coverage.mjs +0 -397
  462. package/skills/paper-pipeline/scripts/artifact-coverage.test.ts +0 -86
  463. package/skills/paper-pipeline/scripts/check-provenance.mjs +0 -184
  464. package/skills/paper-pipeline/scripts/population-map.harness.mjs +0 -135
  465. package/skills/paper-pipeline/scripts/population-map.mjs +0 -188
  466. package/skills/paper-pipeline/scripts/population-map.test.mjs +0 -154
  467. package/skills/paper-pipeline/scripts/provenance.harness.mjs +0 -266
  468. package/skills/paper-pipeline/scripts/round-diff.harness.ts +0 -907
  469. package/skills/paper-pipeline/scripts/round-diff.mjs +0 -583
  470. package/skills/paper-pipeline/scripts/round-diff.test.mjs +0 -159
  471. package/skills/tighten-paper/__snapshots__/structure.test.ts.snap +0 -133
  472. package/skills/tighten-paper/structure.mjs +0 -364
  473. package/skills/tighten-paper/structure.test.ts +0 -117
  474. package/templates/paper/paper.md +0 -4
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The schema of `_build/sources.json`: the one text it is parsed from, and every way a file can fail to
3
+ * be a record of this schema — refused by name, never read as a record.
4
+ */
5
+ import { describe, expect, it } from "vitest";
6
+ import {
7
+ serializeSourcesRecord,
8
+ type SourcesRecord,
9
+ } from "../../domain/sources-record.ts";
10
+ import { sourcesCodec } from "./index.ts";
11
+
12
+ const parseSourcesRecord = sourcesCodec.parse;
13
+ const A = "a".repeat(64);
14
+
15
+ const RECORD: SourcesRecord = {
16
+ schema: 1,
17
+ inputs: [
18
+ { path: "paper.tex", role: "body" },
19
+ { path: "macros.tex", role: "preamble" },
20
+ ],
21
+ written: ["refs.bib"],
22
+ bibdata: ["refs"],
23
+ bibtex: {
24
+ ran: true,
25
+ databases: ["refs.bib"],
26
+ keys: ["k1"],
27
+ exit: 2,
28
+ errors: [{ message: "bad", file: "refs.bib", line: 4 }],
29
+ },
30
+ sha256: { "paper.tex": A, "macros.tex": null },
31
+ };
32
+
33
+ describe("parsing a sources.json", () => {
34
+ it("what serialize wrote parses back to the same record, and the text ends with a newline", () => {
35
+ const text = serializeSourcesRecord(RECORD);
36
+ expect(text.endsWith("}\n")).toBe(true);
37
+ expect(parseSourcesRecord(text)).toEqual({ ok: true, record: RECORD });
38
+ });
39
+
40
+ it("a build that ran no bibtex parses too", () => {
41
+ const record: SourcesRecord = { ...RECORD, bibtex: { ran: false } };
42
+ expect(parseSourcesRecord(serializeSourcesRecord(record))).toEqual({
43
+ ok: true,
44
+ record,
45
+ });
46
+ });
47
+
48
+ it("text that is not JSON is refused by name", () => {
49
+ expect(parseSourcesRecord("{")).toEqual({
50
+ ok: false,
51
+ why: "sources.json is not JSON",
52
+ });
53
+ });
54
+
55
+ it("another schema number is refused by name, not read as this one", () => {
56
+ expect(parseSourcesRecord('{"schema":2}')).toEqual({
57
+ ok: false,
58
+ why: "sources.json is schema 2, this paperlint reads schema 1",
59
+ });
60
+ expect(parseSourcesRecord("[]")).toEqual({
61
+ ok: false,
62
+ why: "sources.json is schema unknown, this paperlint reads schema 1",
63
+ });
64
+ expect(parseSourcesRecord('{"schema":"1"}')).toEqual({
65
+ ok: false,
66
+ why: "sources.json is schema unknown, this paperlint reads schema 1",
67
+ });
68
+ });
69
+
70
+ it("a record of this schema that is not shaped like one names where", () => {
71
+ const bad = (patch: object): string => {
72
+ const r = parseSourcesRecord(JSON.stringify({ ...RECORD, ...patch }));
73
+ return r.ok ? "accepted" : r.why;
74
+ };
75
+ expect(bad({ inputs: "paper.tex" })).toContain("inputs");
76
+ expect(bad({ sha256: { "paper.tex": "not a digest" } })).toContain(
77
+ "sha256.paper.tex",
78
+ );
79
+ expect(bad({ bibtex: { ran: "yes" } })).toContain("bibtex");
80
+ expect(bad({ inputs: [{ path: "a.tex", role: "main" }] })).toContain(
81
+ "inputs.0.role",
82
+ );
83
+ expect(parseSourcesRecord(JSON.stringify({ schema: 1 }))).toMatchObject({
84
+ ok: false,
85
+ });
86
+ });
87
+ });
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The schema of `_build/sources.json` — the one place its shape is checked (docs/design/paper-sources.md
3
+ * §1). The text is parsed once, here, into the domain's `SourcesRecord`; whatever reads a record after
4
+ * it never re-validates. A record of another schema number is refused by name, not read as this one.
5
+ */
6
+ import { z } from "zod";
7
+ import {
8
+ SOURCES_FILE,
9
+ SOURCES_SCHEMA,
10
+ type ParsedRecord,
11
+ } from "../../domain/sources-record.ts";
12
+ import type { SourcesCodec } from "../../ports/sources-codec.ts";
13
+
14
+ const SHA256 = /^[0-9a-f]{64}$/;
15
+
16
+ const bibtexError = z.object({
17
+ message: z.string(),
18
+ file: z.string(),
19
+ line: z.number().int().nullable(),
20
+ });
21
+
22
+ const recordSchema = z.object({
23
+ schema: z.literal(SOURCES_SCHEMA),
24
+ inputs: z.array(
25
+ z.object({ path: z.string(), role: z.enum(["preamble", "body"]) }),
26
+ ),
27
+ written: z.array(z.string()),
28
+ bibdata: z.array(z.string()),
29
+ bibtex: z.discriminatedUnion("ran", [
30
+ z.object({ ran: z.literal(false) }),
31
+ z.object({
32
+ ran: z.literal(true),
33
+ databases: z.array(z.string()),
34
+ keys: z.array(z.string()),
35
+ exit: z.number().int(),
36
+ errors: z.array(bibtexError),
37
+ }),
38
+ ]),
39
+ sha256: z.record(z.string(), z.string().regex(SHA256).nullable()),
40
+ });
41
+
42
+ /** The JSON `text` holds, or undefined when it is not JSON. */
43
+ function jsonOf(text: string): unknown {
44
+ try {
45
+ return JSON.parse(text);
46
+ } catch {
47
+ return undefined;
48
+ }
49
+ }
50
+
51
+ /** The `schema` field of a parsed file, whatever it holds, or undefined when there is none. */
52
+ const schemaOf = (json: unknown): unknown =>
53
+ typeof json === "object" && json !== null && "schema" in json
54
+ ? json.schema
55
+ : undefined;
56
+
57
+ /**
58
+ * A `sources.json`'s text, parsed once at the boundary: the record, or the one reason it is not one.
59
+ * A record of another schema number is refused by name, not read as this one.
60
+ */
61
+ export function parseSourcesRecord(text: string): ParsedRecord {
62
+ const json = jsonOf(text);
63
+ if (json === undefined)
64
+ return { ok: false, why: `${SOURCES_FILE} is not JSON` };
65
+ const schema = schemaOf(json);
66
+ if (schema !== SOURCES_SCHEMA)
67
+ return {
68
+ ok: false,
69
+ why: `${SOURCES_FILE} is schema ${typeof schema === "number" ? String(schema) : "unknown"}, this paperlint reads schema ${String(SOURCES_SCHEMA)}`,
70
+ };
71
+ const parsed = recordSchema.safeParse(json);
72
+ if (parsed.success) return { ok: true, record: parsed.data };
73
+ const issues = parsed.error.issues.map(
74
+ (i) => `${i.path.join(".")} ${i.message}`,
75
+ );
76
+ return {
77
+ ok: false,
78
+ why: `${SOURCES_FILE} does not match schema ${String(SOURCES_SCHEMA)}: ${issues.join("; ")}`,
79
+ };
80
+ }
81
+
82
+ export const sourcesCodec: SourcesCodec = { parse: parseSourcesRecord };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The errors in bibtex's log (`paper.blg`). bibtex ends an error with the place it was reading —
3
+ * `---line 4 of file refs.bib`, or `---while reading file paper.aux` when it names no line — and a
4
+ * warning with a single dash (`--line 1 of file x.bib`), so the three dashes are the whole grammar.
5
+ * The message is what stands before them on the line, or, when they start the line, the line before.
6
+ */
7
+ import type { BibtexError } from "../../domain/sources-record.ts";
8
+
9
+ const PLACE = /^(.*?)---(?:line (\d+) of file|while reading file) (.+)$/;
10
+ const LINE_NUMBER = /---line (\d+) of file/;
11
+
12
+ export function parseBlgErrors(blg: string): readonly BibtexError[] {
13
+ const rows = blg.split(/\r?\n/);
14
+ return rows.flatMap((row, i): readonly BibtexError[] => {
15
+ const m = PLACE.exec(row);
16
+ if (m === null) return [];
17
+ const [, before = "", , file = ""] = m;
18
+ const line = LINE_NUMBER.exec(row)?.[1];
19
+ return [
20
+ {
21
+ message: (before === "" ? (rows[i - 1] ?? "") : before).trim(),
22
+ file: file.trim(),
23
+ line: line === undefined ? null : Number(line),
24
+ },
25
+ ];
26
+ });
27
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * pdflatex's `-recorder` file (`paper.fls`): one line per file TeX opened — `INPUT <path>` to read
3
+ * it, `OUTPUT <path>` to write it — in the order TeX opened them, and a `PWD <dir>` line first. The
4
+ * format has no quoting: a path is the rest of its line.
5
+ */
6
+ import type { Fls, FlsLine } from "../../domain/tex-run.ts";
7
+
8
+ const OPS = ["INPUT", "OUTPUT"] as const;
9
+
10
+ /** `INPUT a.tex` → the line; anything else (`PWD …`, a blank, a word with no path) → none. */
11
+ function lineOf(raw: string): readonly FlsLine[] {
12
+ const op = OPS.find((o) => raw.startsWith(`${o} `));
13
+ const path = op === undefined ? "" : raw.slice(op.length + 1).trimEnd();
14
+ return op === undefined || path === "" ? [] : [{ op, path }];
15
+ }
16
+
17
+ export function parseFls(text: string): Fls {
18
+ const rows = text.split(/\r?\n/);
19
+ const pwd = rows.find((r) => r.startsWith("PWD "));
20
+ return {
21
+ pwd: pwd === undefined ? null : pwd.slice("PWD ".length).trimEnd(),
22
+ lines: rows.flatMap(lineOf),
23
+ };
24
+ }
@@ -0,0 +1,171 @@
1
+ /**
2
+ * The readers of what TeX writes beside a paper — `.fls` (pdflatex `-recorder`) and the errors in
3
+ * bibtex's `.blg` — on files captured whole from real runs of the planted papers in
4
+ * `fixtures/paper-sources/` (test/fixtures/tex-output/README.md), not on text written for the test.
5
+ */
6
+ import { readFileSync } from "node:fs";
7
+ import { dirname, join } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { describe, expect, it } from "vitest";
10
+ import { texOutput } from "./index.ts";
11
+
12
+ const CAPTURES = join(
13
+ dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url))))),
14
+ "test",
15
+ "fixtures",
16
+ "tex-output",
17
+ );
18
+ const capture = (paper: string, file: string): string =>
19
+ readFileSync(join(CAPTURES, paper, file), "utf8");
20
+
21
+ /** The lines that name a file of the paper: not the TeX tree's (absolute) files. */
22
+ const ofPaper = (text: string) =>
23
+ texOutput.fls(text).lines.filter((l) => !l.path.startsWith("/"));
24
+
25
+ describe("the .fls reader", () => {
26
+ it("reads every INPUT and OUTPUT line in order, and the directory pdflatex ran in", () => {
27
+ const fls = texOutput.fls(capture("v8-jobname", "paper.fls"));
28
+ expect(fls.pwd).toBe("/work/paper");
29
+ expect(fls.lines.filter((l) => !l.path.startsWith("/"))).toEqual([
30
+ { op: "INPUT", path: "paper.tex" },
31
+ { op: "OUTPUT", path: "paper.log" },
32
+ { op: "INPUT", path: "./paper.bib" },
33
+ { op: "INPUT", path: "paper.bib" },
34
+ { op: "OUTPUT", path: "paper.bib" },
35
+ { op: "INPUT", path: "./paper.aux" },
36
+ { op: "INPUT", path: "./paper.aux" },
37
+ { op: "INPUT", path: "paper.aux" },
38
+ { op: "OUTPUT", path: "paper.aux" },
39
+ { op: "INPUT", path: "./paper.bbl" },
40
+ { op: "INPUT", path: "./paper.bbl" },
41
+ { op: "INPUT", path: "paper.bbl" },
42
+ { op: "OUTPUT", path: "paper.pdf" },
43
+ { op: "INPUT", path: "paper.aux" },
44
+ ]);
45
+ });
46
+
47
+ it("keeps the TeX tree's files too, as the absolute paths TeX opened", () => {
48
+ const fls = texOutput.fls(capture("v3-declared", "paper.fls"));
49
+ expect(fls.lines.slice(0, 4)).toEqual([
50
+ { op: "INPUT", path: "/usr/share/texlive/texmf.cnf" },
51
+ { op: "INPUT", path: "/usr/share/texlive/texmf-dist/web2c/texmf.cnf" },
52
+ {
53
+ op: "INPUT",
54
+ path: "/usr/share/texlive/texmf-var/web2c/pdftex/pdflatex.fmt",
55
+ },
56
+ { op: "INPUT", path: "paper.tex" },
57
+ ]);
58
+ });
59
+ });
60
+
61
+ describe("the .fls reader, on the shapes of a real run", () => {
62
+ it("a file in a folder keeps its folder; a first pass has no .aux to read yet; a block over a .bib that is already there writes nothing", () => {
63
+ expect(ofPaper(capture("p1", "first-pass.fls"))).toEqual([
64
+ { op: "INPUT", path: "paper.tex" },
65
+ { op: "OUTPUT", path: "paper.log" },
66
+ { op: "INPUT", path: "./refs.bib" },
67
+ { op: "INPUT", path: "refs.bib" },
68
+ { op: "OUTPUT", path: "paper.aux" },
69
+ { op: "INPUT", path: "./sections/intro.tex" },
70
+ { op: "INPUT", path: "./sections/intro.tex" },
71
+ { op: "INPUT", path: "./sections/intro.tex" },
72
+ { op: "INPUT", path: "./sections/intro.tex" },
73
+ { op: "INPUT", path: "sections/intro.tex" },
74
+ { op: "OUTPUT", path: "paper.pdf" },
75
+ { op: "INPUT", path: "paper.aux" },
76
+ ]);
77
+ });
78
+
79
+ it("a path with a space is the whole rest of the line; text that is not a line of the format is skipped", () => {
80
+ expect(
81
+ texOutput.fls(
82
+ "PWD /a b/p\nINPUT my file.tex\nOUTPUT out dir/x.aux\nsomething else\nINPUT\n",
83
+ ),
84
+ ).toEqual({
85
+ pwd: "/a b/p",
86
+ lines: [
87
+ { op: "INPUT", path: "my file.tex" },
88
+ { op: "OUTPUT", path: "out dir/x.aux" },
89
+ ],
90
+ });
91
+ });
92
+
93
+ it("an .fls with no PWD line has no directory", () => {
94
+ expect(texOutput.fls("INPUT paper.tex\n")).toEqual({
95
+ pwd: null,
96
+ lines: [{ op: "INPUT", path: "paper.tex" }],
97
+ });
98
+ });
99
+ });
100
+
101
+ describe("the .blg error reader", () => {
102
+ it("a run that ends well reports none, warnings included", () => {
103
+ expect(texOutput.blgErrors(capture("v3-declared", "paper.blg"))).toEqual(
104
+ [],
105
+ );
106
+ expect(
107
+ texOutput.blgErrors(
108
+ "Database file #1: x.bib\nWarning--I'm ignoring a's extra \"year\" field\n--line 1 of file x.bib\n",
109
+ ),
110
+ ).toEqual([]);
111
+ });
112
+ });
113
+
114
+ describe("the .blg error reader, on what real runs reported", () => {
115
+ it("an entry never closed: the message before the dashes, the file and the line after", () => {
116
+ expect(texOutput.blgErrors(capture("v6-unclosed", "paper.blg"))).toEqual([
117
+ {
118
+ message: "I was expecting a `,' or a `}'",
119
+ file: "refs.bib",
120
+ line: 4,
121
+ },
122
+ ]);
123
+ });
124
+
125
+ it("a second \\bibdata command is an error in the .aux", () => {
126
+ expect(
127
+ texOutput.blgErrors(capture("v9-two-bibliographies", "paper.blg")),
128
+ ).toEqual([
129
+ {
130
+ message: "Illegal, another \\bibdata command",
131
+ file: "paper.aux",
132
+ line: 5,
133
+ },
134
+ ]);
135
+ });
136
+
137
+ it("dashes on the first line of the log have no message before them", () => {
138
+ expect(texOutput.blgErrors("---line 1 of file paper.aux\n")).toEqual([
139
+ { message: "", file: "paper.aux", line: 1 },
140
+ ]);
141
+ });
142
+
143
+ it("a message on the line before its dashes, and an error with no line", () => {
144
+ expect(
145
+ texOutput.blgErrors(
146
+ [
147
+ "The style file: plain.bst",
148
+ "I couldn't open database file paper.bib",
149
+ "---line 4 of file paper.aux",
150
+ " : \\bibdata{paper",
151
+ " : }",
152
+ "I'm skipping whatever remains of this command",
153
+ "I found no database files---while reading file paper.aux",
154
+ 'Warning--I didn\'t find a database entry for "declared2023"',
155
+ "(There were 2 error messages)",
156
+ ].join("\n"),
157
+ ),
158
+ ).toEqual([
159
+ {
160
+ message: "I couldn't open database file paper.bib",
161
+ file: "paper.aux",
162
+ line: 4,
163
+ },
164
+ {
165
+ message: "I found no database files",
166
+ file: "paper.aux",
167
+ line: null,
168
+ },
169
+ ]);
170
+ });
171
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The readers of what TeX writes beside a paper: pdflatex's `-recorder` file and bibtex's errors.
3
+ * One implementation of `TexOutput` (`src/ports/tex-output.ts`).
4
+ */
5
+ import type { TexOutput } from "../../ports/tex-output.ts";
6
+ import { parseBlgErrors } from "./blg.ts";
7
+ import { parseFls } from "./fls.ts";
8
+
9
+ export const texOutput: TexOutput = {
10
+ fls: parseFls,
11
+ blgErrors: parseBlgErrors,
12
+ };