paperlint 2.1.0 → 3.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 (191) hide show
  1. package/CLAUDE.md +6 -1
  2. package/README.md +233 -224
  3. package/action.yml +4 -6
  4. package/dist/adapters/references/index.d.ts +13 -0
  5. package/dist/adapters/references/index.d.ts.map +1 -0
  6. package/dist/adapters/references/index.js +55 -0
  7. package/dist/adapters/references/index.js.map +1 -0
  8. package/dist/adapters/references/reach.io.d.ts +3 -0
  9. package/dist/adapters/references/reach.io.d.ts.map +1 -0
  10. package/dist/adapters/references/reach.io.js +14 -0
  11. package/dist/adapters/references/reach.io.js.map +1 -0
  12. package/dist/build.d.ts +15 -0
  13. package/dist/build.d.ts.map +1 -1
  14. package/dist/build.js +38 -4
  15. package/dist/build.js.map +1 -1
  16. package/dist/cli.d.ts +28 -25
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +277 -265
  19. package/dist/cli.js.map +1 -1
  20. package/dist/doctor.d.ts.map +1 -1
  21. package/dist/doctor.js +40 -72
  22. package/dist/doctor.js.map +1 -1
  23. package/dist/facts-file.d.ts +2 -2
  24. package/dist/facts-file.js +2 -2
  25. package/dist/hooks-settings.d.ts +0 -21
  26. package/dist/hooks-settings.d.ts.map +1 -1
  27. package/dist/hooks-settings.js +17 -135
  28. package/dist/hooks-settings.js.map +1 -1
  29. package/dist/init.d.ts +39 -29
  30. package/dist/init.d.ts.map +1 -1
  31. package/dist/init.js +143 -172
  32. package/dist/init.js.map +1 -1
  33. package/dist/link-skills.d.ts +1 -1
  34. package/dist/link-skills.d.ts.map +1 -1
  35. package/dist/link-skills.js +11 -29
  36. package/dist/link-skills.js.map +1 -1
  37. package/dist/new-paper.d.ts.map +1 -1
  38. package/dist/new-paper.js +2 -13
  39. package/dist/new-paper.js.map +1 -1
  40. package/dist/paper-files.d.ts +63 -0
  41. package/dist/paper-files.d.ts.map +1 -0
  42. package/dist/paper-files.js +69 -0
  43. package/dist/paper-files.js.map +1 -0
  44. package/dist/paper-settings.d.ts +13 -41
  45. package/dist/paper-settings.d.ts.map +1 -1
  46. package/dist/paper-settings.js +71 -71
  47. package/dist/paper-settings.js.map +1 -1
  48. package/dist/ports/check-references.d.ts +31 -0
  49. package/dist/ports/check-references.d.ts.map +1 -0
  50. package/dist/ports/check-references.js +7 -0
  51. package/dist/ports/check-references.js.map +1 -0
  52. package/dist/presets.d.ts +1 -1
  53. package/dist/presets.d.ts.map +1 -1
  54. package/dist/presets.js +4 -6
  55. package/dist/presets.js.map +1 -1
  56. package/dist/reference-rules.d.ts +47 -0
  57. package/dist/reference-rules.d.ts.map +1 -0
  58. package/dist/reference-rules.js +156 -0
  59. package/dist/reference-rules.js.map +1 -0
  60. package/dist/references.d.ts +36 -0
  61. package/dist/references.d.ts.map +1 -0
  62. package/dist/references.js +91 -0
  63. package/dist/references.js.map +1 -0
  64. package/dist/rules-config.d.ts +5 -3
  65. package/dist/rules-config.d.ts.map +1 -1
  66. package/dist/rules-config.js +15 -6
  67. package/dist/rules-config.js.map +1 -1
  68. package/dist/structure.js +3 -3
  69. package/dist/structure.js.map +1 -1
  70. package/dist/tex-requirements.js +2 -2
  71. package/dist/tex-requirements.js.map +1 -1
  72. package/dist/types.d.ts +20 -18
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/venue-rules.d.ts.map +1 -1
  75. package/dist/venue-rules.js +11 -9
  76. package/dist/venue-rules.js.map +1 -1
  77. package/docs/configuration.md +119 -104
  78. package/docs/e2e.md +1 -1
  79. package/docs/install.md +25 -40
  80. package/docs/optional-rules.md +5 -4
  81. package/docs/rules.md +60 -23
  82. package/eslint-rules/bib-reachable-entry.mjs +75 -0
  83. package/eslint-rules/latex-language.mjs +29 -1
  84. package/eslint-rules/paper-stages.harness.mjs +1 -117
  85. package/eslint-rules/paper-stages.mjs +0 -120
  86. package/eslint-rules/paper-stages.mutations.mjs +0 -76
  87. package/eslint-rules/paper-typography.mjs +267 -192
  88. package/eslint-rules/paper-typography.test.mjs +297 -0
  89. package/eslint-rules/papers.harness.mjs +8 -12
  90. package/eslint-rules/papers.mjs +17 -31
  91. package/eslint-rules/pdf-last-page-balance.mjs +4 -7
  92. package/eslint-rules/review-frontmatter.mjs +118 -0
  93. package/eslint-rules/review-frontmatter.schema.json +36 -0
  94. package/eslint-rules/review-frontmatter.test.mjs +118 -0
  95. package/eslint-rules/sibling-frontmatter.mjs +19 -0
  96. package/eslint-rules/sibling-frontmatter.schema.json +14 -0
  97. package/eslint.config.mjs +0 -15
  98. package/fixtures/real-markdown-paper/baseline.json +6 -7
  99. package/hooks/hooks.harness.mjs +39 -98
  100. package/hooks/hooks.mutations.mjs +6 -6
  101. package/hooks/paper-edit-guard.hook.d.mts +2 -3
  102. package/hooks/paper-edit-guard.hook.mjs +31 -42
  103. package/hooks/paper-skills-nudge.hook.mjs +21 -19
  104. package/hooks/paper-status-gates.hook.mjs +21 -19
  105. package/hooks/paper-status-gates.sh +8 -13
  106. package/lib/paper-config.d.mts +15 -25
  107. package/lib/paper-config.harness.mjs +18 -35
  108. package/lib/paper-config.mjs +83 -105
  109. package/lib/paper-config.mutations.mjs +2 -2
  110. package/lib/skill-checks.mjs +1 -1
  111. package/lib/skill-trigger-cases.harness.mjs +9 -8
  112. package/lib/skill-trigger-cases.mjs +7 -15
  113. package/package.json +1 -1
  114. package/scripts/eslint-report-guard.mjs +1 -1
  115. package/scripts/harness-api.frozen.json +0 -3
  116. package/scripts/mutation-batteries.frozen.json +4 -13
  117. package/skills/analyze-sibling-paper/SKILL.md +16 -12
  118. package/skills/analyze-sibling-paper/SKILL.md.spec.ts +15 -11
  119. package/skills/cold-read-diff/SKILL.md +20 -1
  120. package/skills/cold-read-diff/SKILL.md.spec.ts +19 -0
  121. package/skills/grade-paper-writing/SKILL.md +20 -1
  122. package/skills/grade-paper-writing/SKILL.md.spec.ts +19 -0
  123. package/skills/paper-pipeline/scripts/consumer.d.mts +0 -1
  124. package/skills/paper-pipeline/scripts/consumer.harness.mjs +8 -12
  125. package/skills/paper-pipeline/scripts/consumer.mjs +19 -33
  126. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +6 -4
  127. package/skills/paper-pipeline/scripts/run-mechanical.mjs +2 -11
  128. package/skills/plan-paper-timeline/SKILL.md +2 -2
  129. package/skills/plan-paper-timeline/SKILL.md.spec.ts +1 -1
  130. package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +1 -1
  131. package/skills/plan-paper-timeline/plan-paper-timeline.effects.mutations.mjs +2 -2
  132. package/skills/render-paper/check-render.sh +2 -3
  133. package/skills/render-paper/render-paper.harness.mjs +2 -2
  134. package/skills/verify-citations/SKILL.md +10 -1
  135. package/skills/verify-citations/SKILL.md.spec.ts +9 -0
  136. package/skills/verify-citations/scripts/bib-authors.mjs +48 -26
  137. package/src/adapters/references/index.ts +102 -0
  138. package/src/adapters/references/reach.io.ts +12 -0
  139. package/src/build.harness.mjs +8 -4
  140. package/src/build.ts +62 -6
  141. package/src/cli.harness.mjs +147 -292
  142. package/src/cli.mutations.mjs +35 -44
  143. package/src/cli.ts +344 -304
  144. package/src/doctor.harness.mjs +41 -84
  145. package/src/doctor.mutations.mjs +9 -9
  146. package/src/doctor.ts +44 -89
  147. package/src/facts-file.test.ts +0 -7
  148. package/src/facts-file.ts +2 -2
  149. package/src/hooks-settings.harness.mjs +7 -92
  150. package/src/hooks-settings.mutations.mjs +2 -17
  151. package/src/hooks-settings.ts +18 -162
  152. package/src/init.test.ts +206 -0
  153. package/src/init.ts +186 -230
  154. package/src/link-skills.harness.mjs +1 -38
  155. package/src/link-skills.mutations.mjs +9 -5
  156. package/src/link-skills.ts +10 -34
  157. package/src/lint-fix.test.ts +120 -0
  158. package/src/new-paper.test.ts +1 -13
  159. package/src/new-paper.ts +2 -17
  160. package/src/paper-files.test.ts +290 -0
  161. package/src/paper-files.ts +144 -0
  162. package/src/paper-settings-commands.test.ts +84 -121
  163. package/src/paper-settings.test.ts +93 -64
  164. package/src/paper-settings.ts +99 -97
  165. package/src/ports/check-references.ts +28 -0
  166. package/src/presets.ts +5 -15
  167. package/src/reference-rules.ts +229 -0
  168. package/src/references.test.ts +209 -0
  169. package/src/references.ts +138 -0
  170. package/src/rules-config.harness.mjs +24 -8
  171. package/src/rules-config.ts +19 -7
  172. package/src/structure.harness.mjs +3 -1
  173. package/src/structure.ts +3 -3
  174. package/src/tex-requirements.ts +2 -2
  175. package/src/types.ts +30 -18
  176. package/src/venue-rules.test.ts +20 -11
  177. package/src/venue-rules.ts +11 -13
  178. package/eslint-rules/doc-fields.harness.mjs +0 -336
  179. package/eslint-rules/doc-fields.mjs +0 -186
  180. package/eslint-rules/doc-fields.mutations.mjs +0 -96
  181. package/eslint-rules/paper-typography.harness.mjs +0 -291
  182. package/eslint-rules/paper-typography.mutations.mjs +0 -131
  183. package/eslint-rules/review-findings-cause.harness.mjs +0 -228
  184. package/eslint-rules/review-findings-cause.mjs +0 -135
  185. package/eslint-rules/review-findings-cause.mutations.mjs +0 -72
  186. package/fixtures/paper-stages/authors-ran/PIPELINE-STATUS.md +0 -16
  187. package/fixtures/paper-stages/marker-in-prose/PIPELINE-STATUS.md +0 -17
  188. package/fixtures/review-findings-cause/clean.md +0 -17
  189. package/fixtures/review-findings-cause/defect.md +0 -14
  190. package/fixtures/review-findings-cause/old-debt.md +0 -14
  191. package/fixtures/review-findings-cause/quiet-in-fence.md +0 -16
@@ -73,14 +73,15 @@ process.exit(
73
73
  edits: [[CLI, " if (a.missingValue) {", " if (false) {"]],
74
74
  },
75
75
  {
76
- name: "scope gets a default again",
76
+ name: "no papers where the config points reads as a clean run",
77
77
  harness: HARNESS,
78
78
  expect:
79
- "`lint` with NO path AND no config refuses and names BOTH ways out",
79
+ "`lint` with NO path, no config and no papers/ refuses and names BOTH ways out",
80
80
  disables:
81
- 'the "scope is named by the caller" contract. With a default, a user who never ' +
82
- "thought about scope gets a green run over whatever happens to be lying in the directory",
83
- edits: [[CLI, "if (paths.length === 0) {", "if (false) {"]],
81
+ "the guard that makes the `papers` default safe. Without it, a project whose papers " +
82
+ "live elsewhere gets a run over an empty or missing directory instead of the sentence " +
83
+ "naming both ways out",
84
+ edits: [[CLI, " if (empty !== undefined) {", " if (false) {"]],
84
85
  },
85
86
  {
86
87
  name: "the GUARD AGAINST A GREEN ZERO is removed",
@@ -103,26 +104,26 @@ process.exit(
103
104
  edits: [
104
105
  [
105
106
  CLI,
106
- ' if (\n fail?.messageTemplate === "file-not-found" ||\n /No files matching/i.test(fail?.message ?? "")\n )\n results = [];\n else throw e;',
107
+ " if (isEmptySet(e)) results = [];\n else throw e;",
107
108
  " throw e;",
108
109
  ],
109
110
  ],
110
111
  },
111
112
  {
112
- name: "the declaration stops reaching package.json again",
113
+ name: "the declaration stops reaching paperlint.json again",
113
114
  harness: HARNESS,
114
115
  expect:
115
- "🔴 THE DECLARATION SHOWS UP IN package.json — the file the hooks read",
116
+ "🔴 THE DECLARATION SHOWS UP IN paperlint.json — the file the hooks read",
116
117
  disables:
117
118
  "the whole reason this command was rewritten (#33). A hook does not import code and " +
118
- "cannot walk up the tree — it reads a path it is able to name, and that path is " +
119
- "package.json. Without writing there, the install looks like it succeeded, while " +
120
- "`paper-edit-guard` guards the default",
119
+ "cannot walk up the tree — it reads a path it is able to name, and that path is the " +
120
+ "root paperlint.json. Without writing there, the install looks like it succeeded, " +
121
+ "while `paper-edit-guard` guards the default",
121
122
  edits: [
122
123
  [
123
124
  INIT,
124
- ' writeFileSync(\n path,\n JSON.stringify(pkg, null, 2) + (raw.endsWith("\\n") ? "\\n" : ""),\n "utf8",\n );',
125
- " void pkg;",
125
+ " writeFileSync(\n path,\n JSON.stringify(\n { ...settings, [PAPERS_DIR_FIELD]: choice.papers },",
126
+ " (() => {})(\n path,\n JSON.stringify(\n { ...settings, [PAPERS_DIR_FIELD]: choice.papers },",
126
127
  ],
127
128
  ],
128
129
  },
@@ -130,7 +131,7 @@ process.exit(
130
131
  name: "the papers directory is GUESSED again instead of measured",
131
132
  harness: HARNESS,
132
133
  expect:
133
- "🔴 and its value is MEASURED, not taken from the `papers` default",
134
+ "and it says HOW it was measured — otherwise a guess reads as a fact",
134
135
  disables:
135
136
  "measuring instead of guessing. The declaration still gets WRITTEN — i.e. the failure " +
136
137
  "is one-sided and points toward a confident wrong answer: the file says `papers`, the " +
@@ -151,7 +152,13 @@ process.exit(
151
152
  disables:
152
153
  "the ban on silently replacing a consumer's setting. They keep trusting the old " +
153
154
  "value, because nobody told them it changed",
154
- edits: [[INIT, " if (existing !== undefined) {", " if (false) {"]],
155
+ edits: [
156
+ [
157
+ INIT,
158
+ ' if (existing !== undefined)\n return { status: "kept"',
159
+ ' if (false)\n return { status: "kept"',
160
+ ],
161
+ ],
155
162
  },
156
163
  {
157
164
  name: "the default that was taken stops being named",
@@ -221,18 +228,18 @@ process.exit(
221
228
  ],
222
229
  },
223
230
  {
224
- name: "a missing package.json stops being a failure",
231
+ name: "a paperlint.json is written for the default again",
225
232
  harness: HARNESS,
226
233
  expect:
227
- "without package.json init FAILS and carries a remedy, not just a diagnosis",
234
+ "🔴 nothing to measure — the default is taken, and NO paperlint.json is written for it",
228
235
  disables:
229
- "the loudness of a failure where there is NOWHERE to write. A silent zero here is an " +
230
- "install that never happened and reported success",
236
+ "the rule that a project on the defaults needs no config file. Every init would leave " +
237
+ "a file restating the default, and a reader could no longer tell a choice from a default",
231
238
  edits: [
232
239
  [
233
240
  INIT,
234
- " err(\n ` package.json. Run \\`npm init -y\\` here, then \\`npx paperlint init\\` again.`,\n );\n return 2;",
235
- " return 0;",
241
+ ' if (choice.papers === DEFAULT_PAPERS_ROOT)\n return { status: "default"',
242
+ ' if (false)\n return { status: "default"',
236
243
  ],
237
244
  ],
238
245
  },
@@ -270,35 +277,19 @@ process.exit(
270
277
  ],
271
278
  },
272
279
  {
273
- name: "the utility stops reading package.json",
280
+ name: "the utility stops reading paperlint.json",
274
281
  harness: HARNESS,
275
282
  expect:
276
- "🔴 THE UTILITY READS THE DECLARATION FROM package.json — otherwise `paperlint init` sets up something `paperlint lint` cannot see",
277
- disables:
278
- "the link between the install command and the check command. `init` writes one " +
279
- "declaration into package.json, while `lint` looks for it somewhere else — right after " +
280
- 'install the run answers "nothing to lint" over a corpus that is right there',
281
- edits: [
282
- [
283
- CLI,
284
- " if (existsSync(pkg) && declaresSettings(pkg)) return pkg;",
285
- " if (false) return pkg;",
286
- ],
287
- ],
288
- },
289
- {
290
- name: "consumer data stops reaching the rule",
291
- harness: HARNESS,
292
- expect: "the command from options gets through to the rule",
283
+ "🔴 THE UTILITY READS THE DECLARATION FROM paperlint.json — the file `paperlint init` writes and the hooks read",
293
284
  disables:
294
- 'the "mechanism in the package, data with the consumer" boundary: the ' +
295
- "`authorListCommand` option is ignored, and the finding again fails to say WHAT to " +
296
- "run the check with",
285
+ "the link between the install command and the check command. `init` writes the " +
286
+ "declaration into paperlint.json, while `lint` would run on the default — right after " +
287
+ "install it reports on a directory the papers are not in",
297
288
  edits: [
298
289
  [
299
290
  CLI,
300
- "opts.authorListCommand ? { command: opts.authorListCommand } : {},",
301
- "{},",
291
+ " const configPath = existsSync(found) ? found : null;",
292
+ " const configPath = existsSync(found) ? null : null;",
302
293
  ],
303
294
  ],
304
295
  },