paperlint 8.0.0 → 9.0.1
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.
- package/.github/CLAUDE.md +22 -0
- package/.github/CLAUDE.md.spec.ts +20 -0
- package/CLAUDE.md +59 -531
- package/CONTRIBUTING.md +7 -6
- package/README.md +4 -3
- package/dist/CLAUDE.md.spec.d.ts +3 -0
- package/dist/CLAUDE.md.spec.d.ts.map +1 -0
- package/dist/CLAUDE.md.spec.js +62 -0
- package/dist/CLAUDE.md.spec.js.map +1 -0
- package/dist/adapters/bibtex/index.d.ts +3 -0
- package/dist/adapters/bibtex/index.d.ts.map +1 -0
- package/dist/adapters/bibtex/index.js +103 -0
- package/dist/adapters/bibtex/index.js.map +1 -0
- package/dist/adapters/latex/filecontents.d.ts +33 -0
- package/dist/adapters/latex/filecontents.d.ts.map +1 -0
- package/dist/adapters/latex/filecontents.js +65 -0
- package/dist/adapters/latex/filecontents.js.map +1 -0
- package/dist/adapters/latex/includes.d.ts +3 -3
- package/dist/adapters/latex/includes.d.ts.map +1 -1
- package/dist/adapters/latex/includes.js +18 -10
- package/dist/adapters/latex/includes.js.map +1 -1
- package/dist/adapters/latex/index.d.ts.map +1 -1
- package/dist/adapters/latex/index.js +2 -0
- package/dist/adapters/latex/index.js.map +1 -1
- package/dist/adapters/latex/nodes.d.ts +12 -0
- package/dist/adapters/latex/nodes.d.ts.map +1 -1
- package/dist/adapters/latex/nodes.js +39 -0
- package/dist/adapters/latex/nodes.js.map +1 -1
- package/dist/adapters/latex/parse.d.ts +7 -1
- package/dist/adapters/latex/parse.d.ts.map +1 -1
- package/dist/adapters/latex/parse.js +55 -6
- package/dist/adapters/latex/parse.js.map +1 -1
- package/dist/adapters/memory/index.d.ts +3 -0
- package/dist/adapters/memory/index.d.ts.map +1 -1
- package/dist/adapters/memory/index.js +9 -0
- package/dist/adapters/memory/index.js.map +1 -1
- package/dist/adapters/references/index.d.ts.map +1 -1
- package/dist/adapters/references/index.js +27 -24
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/adapters/sources-record/index.d.ts +9 -0
- package/dist/adapters/sources-record/index.d.ts.map +1 -0
- package/dist/adapters/sources-record/index.js +68 -0
- package/dist/adapters/sources-record/index.js.map +1 -0
- package/dist/adapters/tex-output/blg.d.ts +9 -0
- package/dist/adapters/tex-output/blg.d.ts.map +1 -0
- package/dist/adapters/tex-output/blg.js +20 -0
- package/dist/adapters/tex-output/blg.js.map +1 -0
- package/dist/adapters/tex-output/fls.d.ts +8 -0
- package/dist/adapters/tex-output/fls.d.ts.map +1 -0
- package/dist/adapters/tex-output/fls.js +16 -0
- package/dist/adapters/tex-output/fls.js.map +1 -0
- package/dist/adapters/tex-output/index.d.ts +7 -0
- package/dist/adapters/tex-output/index.d.ts.map +1 -0
- package/dist/adapters/tex-output/index.js +7 -0
- package/dist/adapters/tex-output/index.js.map +1 -0
- package/dist/bib-rules.d.ts +47 -0
- package/dist/bib-rules.d.ts.map +1 -0
- package/dist/bib-rules.js +127 -0
- package/dist/bib-rules.js.map +1 -0
- package/dist/build.d.ts +29 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +41 -25
- package/dist/build.js.map +1 -1
- package/dist/claim-provenance.d.ts +2 -2
- package/dist/cli.d.ts +6 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +30 -26
- package/dist/cli.js.map +1 -1
- package/dist/domain/paper-source.d.ts +1 -10
- package/dist/domain/paper-source.d.ts.map +1 -1
- package/dist/domain/paper-source.js +34 -24
- package/dist/domain/paper-source.js.map +1 -1
- package/dist/domain/paper-sources.d.ts +72 -0
- package/dist/domain/paper-sources.d.ts.map +1 -0
- package/dist/domain/paper-sources.js +18 -0
- package/dist/domain/paper-sources.js.map +1 -0
- package/dist/domain/sources-record.d.ts +102 -0
- package/dist/domain/sources-record.d.ts.map +1 -0
- package/dist/domain/sources-record.js +38 -0
- package/dist/domain/sources-record.js.map +1 -0
- package/dist/domain/tex-run.d.ts +25 -0
- package/dist/domain/tex-run.d.ts.map +1 -0
- package/dist/domain/tex-run.js +79 -0
- package/dist/domain/tex-run.js.map +1 -0
- package/dist/eslint-rules/CLAUDE.md.spec.d.ts +3 -0
- package/dist/eslint-rules/CLAUDE.md.spec.d.ts.map +1 -0
- package/dist/eslint-rules/CLAUDE.md.spec.js +39 -0
- package/dist/eslint-rules/CLAUDE.md.spec.js.map +1 -0
- package/dist/eslint-rules/install-path-literals.d.ts +1 -1
- package/dist/eslint-rules/install-path-literals.js +4 -4
- package/dist/eslint-rules/install-path-literals.js.map +1 -1
- package/dist/eslint-rules/paper-context.d.ts.map +1 -1
- package/dist/eslint-rules/paper-context.js +4 -3
- package/dist/eslint-rules/paper-context.js.map +1 -1
- package/dist/eslint-rules/paper-typography.d.ts +0 -9
- package/dist/eslint-rules/paper-typography.d.ts.map +1 -1
- package/dist/eslint-rules/paper-typography.js +12 -5
- package/dist/eslint-rules/paper-typography.js.map +1 -1
- package/dist/eslint-rules/pdf-last-page-balance.js +1 -1
- package/dist/latex-log.d.ts +10 -0
- package/dist/latex-log.d.ts.map +1 -1
- package/dist/latex-log.js +10 -0
- package/dist/latex-log.js.map +1 -1
- package/dist/latex-loop.d.ts +2 -0
- package/dist/latex-loop.d.ts.map +1 -1
- package/dist/latex-loop.js.map +1 -1
- package/dist/lib/agent-cli-version.js +1 -1
- package/dist/lib/agent-cli-version.js.map +1 -1
- package/dist/package-dirs.d.ts.map +1 -1
- package/dist/package-dirs.js +3 -2
- package/dist/package-dirs.js.map +1 -1
- package/dist/paper-includes.d.ts +4 -7
- package/dist/paper-includes.d.ts.map +1 -1
- package/dist/paper-includes.js +29 -21
- package/dist/paper-includes.js.map +1 -1
- package/dist/paper-prose.d.ts +2 -2
- package/dist/paper-record.d.ts +25 -0
- package/dist/paper-record.d.ts.map +1 -0
- package/dist/paper-record.js +39 -0
- package/dist/paper-record.js.map +1 -0
- package/dist/paper-sources.d.ts +66 -0
- package/dist/paper-sources.d.ts.map +1 -0
- package/dist/paper-sources.js +92 -0
- package/dist/paper-sources.js.map +1 -0
- package/dist/ports/bib-reader.d.ts +18 -0
- package/dist/ports/bib-reader.d.ts.map +1 -0
- package/dist/ports/bib-reader.js +2 -0
- package/dist/ports/bib-reader.js.map +1 -0
- package/dist/ports/check-references.d.ts +9 -4
- package/dist/ports/check-references.d.ts.map +1 -1
- package/dist/ports/latex.d.ts +15 -0
- package/dist/ports/latex.d.ts.map +1 -1
- package/dist/ports/sources-codec.d.ts +11 -0
- package/dist/ports/sources-codec.d.ts.map +1 -0
- package/dist/ports/sources-codec.js +2 -0
- package/dist/ports/sources-codec.js.map +1 -0
- package/dist/ports/tex-output.d.ts +17 -0
- package/dist/ports/tex-output.d.ts.map +1 -0
- package/dist/ports/tex-output.js +2 -0
- package/dist/ports/tex-output.js.map +1 -0
- package/dist/recorded-bibliography.d.ts +89 -0
- package/dist/recorded-bibliography.d.ts.map +1 -0
- package/dist/recorded-bibliography.js +136 -0
- package/dist/recorded-bibliography.js.map +1 -0
- package/dist/reference-rules.d.ts +5 -5
- package/dist/reference-rules.d.ts.map +1 -1
- package/dist/reference-rules.js +150 -77
- package/dist/reference-rules.js.map +1 -1
- package/dist/references.d.ts +71 -16
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +110 -26
- package/dist/references.js.map +1 -1
- package/dist/register-bands.d.ts +3 -3
- package/dist/register-bands.d.ts.map +1 -1
- package/dist/register-bands.js.map +1 -1
- package/dist/register.d.ts +2 -2
- package/dist/sources-record.d.ts +38 -0
- package/dist/sources-record.d.ts.map +1 -0
- package/dist/sources-record.js +123 -0
- package/dist/sources-record.js.map +1 -0
- package/dist/sources-rules.d.ts +44 -0
- package/dist/sources-rules.d.ts.map +1 -0
- package/dist/sources-rules.js +76 -0
- package/dist/sources-rules.js.map +1 -0
- package/dist/tex-paper.d.ts +10 -15
- package/dist/tex-paper.d.ts.map +1 -1
- package/dist/tex-paper.js +24 -40
- package/dist/tex-paper.js.map +1 -1
- package/dist/tex-requirements.js +1 -1
- package/dist/tex-venue-rules.d.ts +3 -3
- package/dist/tex-venue-rules.d.ts.map +1 -1
- package/dist/tex-venue-rules.js.map +1 -1
- package/dist/toolchain.js +1 -1
- package/docs/configuration.md +12 -4
- package/docs/design/paper-sources.md +197 -0
- package/docs/e2e.md +1 -1
- package/docs/incidents.md +5 -5
- package/docs/package-shape-options.md +1 -1
- package/docs/references.md +34 -8
- package/docs/rules/bib/reachable-entry.md +64 -0
- package/docs/rules/paper/sources-fresh.md +81 -0
- package/docs/rules.md +62 -57
- package/eslint-rules/CLAUDE.md +44 -0
- package/eslint-rules/CLAUDE.md.spec.ts +43 -0
- package/eslint-rules/install-path-literals.harness.mjs +1 -1
- package/eslint-rules/install-path-literals.ts +4 -4
- package/eslint-rules/paper-context.ts +4 -3
- package/eslint-rules/paper-typography.test.mjs +12 -72
- package/eslint-rules/paper-typography.ts +13 -6
- package/eslint-rules/pdf-last-page-balance.ts +1 -1
- package/eslint.config.mjs +28 -3
- package/fixtures/build-e2e/aidc/paper.tex +1 -1
- package/fixtures/build-e2e/anon-ack/paper.tex +1 -1
- package/fixtures/build-e2e/anon-author/paper.tex +1 -1
- package/fixtures/build-e2e/anon-bib/paper.tex +1 -1
- package/fixtures/build-e2e/anon-href/paper.tex +1 -1
- package/fixtures/build-e2e/anon-macro/paper.tex +1 -1
- package/fixtures/build-e2e/anon-pdfauthor/paper.tex +1 -1
- package/fixtures/paper-sources/p1/paper.tex +30 -0
- package/fixtures/paper-sources/p1/refs.bib +6 -0
- package/fixtures/paper-sources/p1/sections/dead.tex +6 -0
- package/fixtures/paper-sources/p1/sections/intro.tex +7 -0
- package/fixtures/paper-sources/p1/sections/parked.tex +6 -0
- package/fixtures/paper-sources/p1/tex-truth.json +37 -0
- package/fixtures/paper-sources/p1/versions/2026-01-01-review.tex +4 -0
- package/fixtures/paper-sources/v1-stale/paper.tex +14 -0
- package/fixtures/paper-sources/v1-stale/refs.bib +6 -0
- package/fixtures/paper-sources/v1-stale/tex-truth.json +32 -0
- package/fixtures/paper-sources/v10-ifthenelse/anon.bib +1 -0
- package/fixtures/paper-sources/v10-ifthenelse/paper.tex +9 -0
- package/fixtures/paper-sources/v10-ifthenelse/real.bib +1 -0
- package/fixtures/paper-sources/v10-ifthenelse/tex-truth.json +28 -0
- package/fixtures/paper-sources/v11-two-blocks/paper.tex +12 -0
- package/fixtures/paper-sources/v11-two-blocks/tex-truth.json +30 -0
- package/fixtures/paper-sources/v13-percent-text/paper.tex +6 -0
- package/fixtures/paper-sources/v13-percent-text/refs.bib +3 -0
- package/fixtures/paper-sources/v13-percent-text/tex-truth.json +30 -0
- package/fixtures/paper-sources/v15-after-end/paper.tex +6 -0
- package/fixtures/paper-sources/v15-after-end/refs.bib +1 -0
- package/fixtures/paper-sources/v15-after-end/tex-truth.json +17 -0
- package/fixtures/paper-sources/v16-included-block/bibblock.tex +3 -0
- package/fixtures/paper-sources/v16-included-block/paper.tex +7 -0
- package/fixtures/paper-sources/v16-included-block/refs.bib +1 -0
- package/fixtures/paper-sources/v16-included-block/tex-truth.json +35 -0
- package/fixtures/paper-sources/v17-include-order/bibsetup.tex +1 -0
- package/fixtures/paper-sources/v17-include-order/first.bib +1 -0
- package/fixtures/paper-sources/v17-include-order/later.bib +1 -0
- package/fixtures/paper-sources/v17-include-order/paper.tex +7 -0
- package/fixtures/paper-sources/v17-include-order/tex-truth.json +40 -0
- package/fixtures/paper-sources/v2-overwrite/paper.tex +14 -0
- package/fixtures/paper-sources/v2-overwrite/refs.bib +6 -0
- package/fixtures/paper-sources/v2-overwrite/tex-truth.json +30 -0
- package/fixtures/paper-sources/v22-parked-thebibliography/paper.tex +7 -0
- package/fixtures/paper-sources/v22-parked-thebibliography/tex-truth.json +17 -0
- package/fixtures/paper-sources/v23-parked-include/old.bib +1 -0
- package/fixtures/paper-sources/v23-parked-include/paper.tex +7 -0
- package/fixtures/paper-sources/v23-parked-include/parked.tex +1 -0
- package/fixtures/paper-sources/v23-parked-include/refs.bib +1 -0
- package/fixtures/paper-sources/v23-parked-include/tex-truth.json +28 -0
- package/fixtures/paper-sources/v24-quoted-fields/paper.tex +6 -0
- package/fixtures/paper-sources/v24-quoted-fields/refs.bib +5 -0
- package/fixtures/paper-sources/v24-quoted-fields/tex-truth.json +32 -0
- package/fixtures/paper-sources/v25-string-differs/paper.tex +10 -0
- package/fixtures/paper-sources/v25-string-differs/refs.bib +2 -0
- package/fixtures/paper-sources/v25-string-differs/tex-truth.json +32 -0
- package/fixtures/paper-sources/v26-comment-in-names/one.bib +1 -0
- package/fixtures/paper-sources/v26-comment-in-names/paper.tex +7 -0
- package/fixtures/paper-sources/v26-comment-in-names/tex-truth.json +32 -0
- package/fixtures/paper-sources/v26-comment-in-names/two.bib +1 -0
- package/fixtures/paper-sources/v27-shared-string/abbreviations.bib +2 -0
- package/fixtures/paper-sources/v27-shared-string/paper.tex +6 -0
- package/fixtures/paper-sources/v27-shared-string/references.bib +6 -0
- package/fixtures/paper-sources/v27-shared-string/tex-truth.json +31 -0
- package/fixtures/paper-sources/v28-shared-string-block/abbreviations.bib +2 -0
- package/fixtures/paper-sources/v28-shared-string-block/paper.tex +14 -0
- package/fixtures/paper-sources/v28-shared-string-block/tex-truth.json +33 -0
- package/fixtures/paper-sources/v29-generated-input/paper.tex +9 -0
- package/fixtures/paper-sources/v29-generated-input/tex-truth.json +24 -0
- package/fixtures/paper-sources/v3-declared/paper.bib +6 -0
- package/fixtures/paper-sources/v3-declared/paper.tex +6 -0
- package/fixtures/paper-sources/v3-declared/tex-truth.json +28 -0
- package/fixtures/paper-sources/v30-name-next-line/paper.tex +14 -0
- package/fixtures/paper-sources/v30-name-next-line/tex-truth.json +30 -0
- package/fixtures/paper-sources/v4-commented/paper.tex +14 -0
- package/fixtures/paper-sources/v4-commented/refs.bib +6 -0
- package/fixtures/paper-sources/v4-commented/tex-truth.json +28 -0
- package/fixtures/paper-sources/v5-percent-entry/paper.tex +20 -0
- package/fixtures/paper-sources/v5-percent-entry/tex-truth.json +37 -0
- package/fixtures/paper-sources/v6-unclosed/paper.tex +6 -0
- package/fixtures/paper-sources/v6-unclosed/refs.bib +5 -0
- package/fixtures/paper-sources/v6-unclosed/tex-truth.json +37 -0
- package/fixtures/paper-sources/v8-jobname/paper.tex +9 -0
- package/fixtures/paper-sources/v8-jobname/tex-truth.json +30 -0
- package/fixtures/paper-sources/v9-two-bibliographies/one.bib +1 -0
- package/fixtures/paper-sources/v9-two-bibliographies/paper.tex +7 -0
- package/fixtures/paper-sources/v9-two-bibliographies/tex-truth.json +35 -0
- package/fixtures/paper-sources/v9-two-bibliographies/two.bib +1 -0
- package/fixtures/paper-typography/clean-paper/paper.tex +1 -1
- package/fixtures/paper-typography/messy-paper/paper.tex +1 -1
- package/hooks/CLAUDE.md +34 -0
- package/hooks/CLAUDE.md.spec.ts +30 -0
- package/lib/agent-cli-version.ts +1 -1
- package/package.json +3 -11
- package/plugin/CLAUDE.md +22 -0
- package/plugin/CLAUDE.md.spec.ts +22 -0
- package/scripts/check.test.ts +23 -1
- package/scripts/check.ts +7 -3
- package/scripts/coverage-config.test.ts +21 -11
- package/scripts/layer-legacy-frozen.test.ts +41 -2
- package/scripts/layer-legacy-frozen.ts +31 -2
- package/skills/CLAUDE.md +19 -0
- package/skills/CLAUDE.md.spec.ts +18 -0
- package/skills/grade-paper-writing/SKILL.md +4 -3
- package/skills/grade-paper-writing/SKILL.md.spec.ts +3 -2
- package/skills/grade-paper-writing/prose-lint.mjs +11 -2
- package/skills/grade-paper-writing/prose-lint.test.ts +52 -4
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +83 -33
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +67 -115
- package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +128 -121
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +21 -102
- package/skills/verify-citations/SKILL.md +7 -4
- package/skills/verify-citations/SKILL.md.spec.ts +6 -3
- package/skills/verify-citations/scripts/bib-authors.check.test.mjs +17 -19
- package/skills/verify-citations/scripts/bib-authors.cli.test.ts +129 -46
- package/skills/verify-citations/scripts/bib-authors.d.mts +22 -2
- package/skills/verify-citations/scripts/bib-authors.mjs +57 -111
- package/skills/verify-citations/scripts/verify-cites.cli.test.ts +16 -0
- package/skills/verify-citations/scripts/verify-cites.d.mts +19 -3
- package/skills/verify-citations/scripts/verify-cites.mjs +42 -108
- package/skills/verify-citations/scripts/verify-cites.test.mjs +23 -36
- package/src/CLAUDE.md +23 -1
- package/src/CLAUDE.md.spec.ts +72 -0
- package/src/adapters/bibtex/index.test.ts +163 -0
- package/src/adapters/bibtex/index.ts +155 -0
- package/src/adapters/latex/filecontents.ts +114 -0
- package/src/adapters/latex/includes.ts +18 -10
- package/src/adapters/latex/index.test.ts +73 -0
- package/src/adapters/latex/index.ts +2 -0
- package/src/adapters/latex/nodes.ts +64 -0
- package/src/adapters/latex/parse.test.ts +38 -0
- package/src/adapters/latex/parse.ts +67 -6
- package/src/adapters/memory/index.ts +17 -0
- package/src/adapters/references/index.test.ts +75 -21
- package/src/adapters/references/index.ts +37 -32
- package/src/adapters/sources-record/index.test.ts +87 -0
- package/src/adapters/sources-record/index.ts +82 -0
- package/src/adapters/tex-output/blg.ts +27 -0
- package/src/adapters/tex-output/fls.ts +24 -0
- package/src/adapters/tex-output/index.test.ts +171 -0
- package/src/adapters/tex-output/index.ts +12 -0
- package/src/bib-rules.test.ts +356 -0
- package/src/bib-rules.ts +228 -0
- package/src/bibliography-at.test.ts +286 -0
- package/src/build.test.ts +210 -0
- package/src/build.ts +101 -36
- package/src/claim-provenance.test.ts +33 -7
- package/src/claim-provenance.ts +2 -2
- package/src/cli.harness.mjs +20 -10
- package/src/cli.test.ts +14 -10
- package/src/cli.ts +37 -28
- package/src/domain/paper-source.test.ts +58 -20
- package/src/domain/paper-source.ts +38 -42
- package/src/domain/paper-sources.ts +94 -0
- package/src/domain/sources-record.test.ts +71 -0
- package/src/domain/sources-record.ts +136 -0
- package/src/domain/tex-run.test.ts +228 -0
- package/src/domain/tex-run.ts +139 -0
- package/src/heading-case.test.ts +24 -10
- package/src/latex-log.ts +20 -0
- package/src/latex-loop.harness.ts +1 -0
- package/src/latex-loop.ts +2 -0
- package/src/linted-set.test.ts +9 -1
- package/src/new-paper.harness.mjs +3 -2
- package/src/new-paper.test.ts +9 -5
- package/src/package-dirs.ts +3 -2
- package/src/paper-includes.test.ts +157 -38
- package/src/paper-includes.ts +39 -35
- package/src/paper-prose.test.ts +34 -5
- package/src/paper-prose.ts +2 -2
- package/src/paper-record.test.ts +173 -0
- package/src/paper-record.ts +66 -0
- package/src/paper-settings-commands.test.ts +5 -2
- package/src/paper-sources.ts +151 -0
- package/src/ports/bib-reader.ts +27 -0
- package/src/ports/check-references.ts +7 -3
- package/src/ports/latex.ts +19 -0
- package/src/ports/sources-codec.ts +11 -0
- package/src/ports/tex-output.ts +17 -0
- package/src/recorded-bibliography.ts +297 -0
- package/src/reference-rules.ts +217 -104
- package/src/references.test.ts +520 -177
- package/src/references.ts +185 -37
- package/src/register-bands.test.ts +5 -1
- package/src/register-bands.ts +3 -5
- package/src/register.test.ts +6 -1
- package/src/register.ts +2 -2
- package/src/rule-cases.test.ts +68 -12
- package/src/rule-docs.test.ts +0 -1
- package/src/sources-record.test.ts +308 -0
- package/src/sources-record.ts +231 -0
- package/src/sources-rules.test.ts +152 -0
- package/src/sources-rules.ts +117 -0
- package/src/tex-paper.test.ts +148 -78
- package/src/tex-paper.ts +31 -61
- package/src/tex-requirements.ts +1 -1
- package/src/tex-venue-rules.test.ts +36 -8
- package/src/tex-venue-rules.ts +3 -5
- package/src/toolchain.ts +1 -1
- package/dist/eslint-rules/bib-reachable-entry.d.ts +0 -22
- package/dist/eslint-rules/bib-reachable-entry.d.ts.map +0 -1
- package/dist/eslint-rules/bib-reachable-entry.js +0 -75
- package/dist/eslint-rules/bib-reachable-entry.js.map +0 -1
- package/eslint-rules/bib-reachable-entry.ts +0 -76
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [],
|
|
10
|
+
"bibdata": [
|
|
11
|
+
"paper"
|
|
12
|
+
],
|
|
13
|
+
"bibtex": {
|
|
14
|
+
"ran": true,
|
|
15
|
+
"databases": [
|
|
16
|
+
"paper.bib"
|
|
17
|
+
],
|
|
18
|
+
"keys": [
|
|
19
|
+
"declared2023"
|
|
20
|
+
],
|
|
21
|
+
"exit": 0,
|
|
22
|
+
"errors": []
|
|
23
|
+
},
|
|
24
|
+
"sha256": {
|
|
25
|
+
"paper.tex": "365c348f503b060973c7b1d5db0348659dffa91d7b149d10181204ae27e31dfb",
|
|
26
|
+
"paper.bib": "efe5f0577c8173e99be73ed728679904dcac9c90b1ec56350cf64d0771f8305e"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
\documentclass{article}
|
|
2
|
+
\begin{filecontents*}
|
|
3
|
+
{refs.bib}
|
|
4
|
+
@misc{nl2024,
|
|
5
|
+
title = {The Name on the Next Line},
|
|
6
|
+
author = {Doe, Jane},
|
|
7
|
+
year = {2024}
|
|
8
|
+
}
|
|
9
|
+
\end{filecontents*}
|
|
10
|
+
\begin{document}
|
|
11
|
+
Text that cites~\cite{nl2024}.
|
|
12
|
+
\bibliographystyle{plain}
|
|
13
|
+
\bibliography{refs}
|
|
14
|
+
\end{document}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [
|
|
10
|
+
"refs.bib"
|
|
11
|
+
],
|
|
12
|
+
"bibdata": [
|
|
13
|
+
"refs"
|
|
14
|
+
],
|
|
15
|
+
"bibtex": {
|
|
16
|
+
"ran": true,
|
|
17
|
+
"databases": [
|
|
18
|
+
"refs.bib"
|
|
19
|
+
],
|
|
20
|
+
"keys": [
|
|
21
|
+
"nl2024"
|
|
22
|
+
],
|
|
23
|
+
"exit": 0,
|
|
24
|
+
"errors": []
|
|
25
|
+
},
|
|
26
|
+
"sha256": {
|
|
27
|
+
"paper.tex": "143d03485e70ffefc525e6f783601c6f71e6650ccf779c77a4d7a8f12ba6075b",
|
|
28
|
+
"refs.bib": "b4c47cdd91aff598589dae3f0f068495af3680e5cdf0bce4747332750812ee1d"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
\documentclass{article}
|
|
2
|
+
% \begin{filecontents*}{refs.bib}
|
|
3
|
+
% @misc{commented2024,
|
|
4
|
+
% title = {The Inline Entry},
|
|
5
|
+
% author = {Doe, Jane},
|
|
6
|
+
% year = {2024},
|
|
7
|
+
% url = {https://example.org/inline}
|
|
8
|
+
% }
|
|
9
|
+
% \end{filecontents*}
|
|
10
|
+
\begin{document}
|
|
11
|
+
Text that cites~\cite{commented2024} and~\cite{stale2020}.
|
|
12
|
+
\bibliographystyle{plain}
|
|
13
|
+
\bibliography{refs}
|
|
14
|
+
\end{document}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [],
|
|
10
|
+
"bibdata": [
|
|
11
|
+
"refs"
|
|
12
|
+
],
|
|
13
|
+
"bibtex": {
|
|
14
|
+
"ran": true,
|
|
15
|
+
"databases": [
|
|
16
|
+
"refs.bib"
|
|
17
|
+
],
|
|
18
|
+
"keys": [
|
|
19
|
+
"stale2020"
|
|
20
|
+
],
|
|
21
|
+
"exit": 0,
|
|
22
|
+
"errors": []
|
|
23
|
+
},
|
|
24
|
+
"sha256": {
|
|
25
|
+
"paper.tex": "a0a0349afca7a2de8b41bdbdf777de14d8e07df5993a351492ca11c858f8c34e",
|
|
26
|
+
"refs.bib": "7a720777755f3dd727c2428f66f06d5f818f367e41fe4c47543aa9f55adfebb4"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
\documentclass{article}
|
|
2
|
+
\begin{filecontents*}[overwrite]{refs.bib}
|
|
3
|
+
@misc{inline2024,
|
|
4
|
+
title = {The Inline Entry},
|
|
5
|
+
author = {Doe, Jane},
|
|
6
|
+
year = {2024},
|
|
7
|
+
url = {https://example.org/inline}
|
|
8
|
+
}
|
|
9
|
+
% @misc{dead2020,
|
|
10
|
+
% title = {The Entry Behind a Percent Sign},
|
|
11
|
+
% author = {Moe, Max},
|
|
12
|
+
% year = {2020},
|
|
13
|
+
% url = {https://example.org/dead}
|
|
14
|
+
% }
|
|
15
|
+
\end{filecontents*}
|
|
16
|
+
\begin{document}
|
|
17
|
+
Text that cites~\cite{inline2024} and~\cite{dead2020}.
|
|
18
|
+
\bibliographystyle{plain}
|
|
19
|
+
\bibliography{refs}
|
|
20
|
+
\end{document}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [
|
|
10
|
+
"refs.bib"
|
|
11
|
+
],
|
|
12
|
+
"bibdata": [
|
|
13
|
+
"refs"
|
|
14
|
+
],
|
|
15
|
+
"bibtex": {
|
|
16
|
+
"ran": true,
|
|
17
|
+
"databases": [
|
|
18
|
+
"refs.bib"
|
|
19
|
+
],
|
|
20
|
+
"keys": [
|
|
21
|
+
"dead2020",
|
|
22
|
+
"inline2024"
|
|
23
|
+
],
|
|
24
|
+
"exit": 2,
|
|
25
|
+
"errors": [
|
|
26
|
+
{
|
|
27
|
+
"message": "You're missing a field name",
|
|
28
|
+
"file": "refs.bib",
|
|
29
|
+
"line": 8
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"sha256": {
|
|
34
|
+
"paper.tex": "f520de6b9f34e249851913d2e9fc23532603378787b034e08e0b43e2bc111994",
|
|
35
|
+
"refs.bib": "247d564a35129b3fa087ae2541cd51130c1e6875fafe5dad36d694f6a4d1b7fc"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [],
|
|
10
|
+
"bibdata": [
|
|
11
|
+
"refs"
|
|
12
|
+
],
|
|
13
|
+
"bibtex": {
|
|
14
|
+
"ran": true,
|
|
15
|
+
"databases": [
|
|
16
|
+
"refs.bib"
|
|
17
|
+
],
|
|
18
|
+
"keys": [
|
|
19
|
+
"a1",
|
|
20
|
+
"a4",
|
|
21
|
+
"a3",
|
|
22
|
+
"a2unclosed"
|
|
23
|
+
],
|
|
24
|
+
"exit": 2,
|
|
25
|
+
"errors": [
|
|
26
|
+
{
|
|
27
|
+
"message": "I was expecting a `,' or a `}'",
|
|
28
|
+
"file": "refs.bib",
|
|
29
|
+
"line": 4
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
"sha256": {
|
|
34
|
+
"paper.tex": "9ad22f9c50070c2620c5bf8885ed53cee4b0901e7bfdc83c61f70902686ac5e0",
|
|
35
|
+
"refs.bib": "1d33d35cf2e384fc54acf45654493881315c98a4b494b952464668d33924aeec"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
\documentclass{article}
|
|
2
|
+
\begin{filecontents*}[overwrite]{\jobname.bib}
|
|
3
|
+
@misc{jkey, title={J}, author={Doe, J}, year={2024}}
|
|
4
|
+
% @misc{jdead, title={D}, author={Doe, J}, year={2020}}
|
|
5
|
+
\end{filecontents*}
|
|
6
|
+
\begin{document}
|
|
7
|
+
Text~\cite{jkey}.
|
|
8
|
+
\bibliographystyle{plain}\bibliography{\jobname}
|
|
9
|
+
\end{document}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [
|
|
10
|
+
"paper.bib"
|
|
11
|
+
],
|
|
12
|
+
"bibdata": [
|
|
13
|
+
"paper"
|
|
14
|
+
],
|
|
15
|
+
"bibtex": {
|
|
16
|
+
"ran": true,
|
|
17
|
+
"databases": [
|
|
18
|
+
"paper.bib"
|
|
19
|
+
],
|
|
20
|
+
"keys": [
|
|
21
|
+
"jkey"
|
|
22
|
+
],
|
|
23
|
+
"exit": 0,
|
|
24
|
+
"errors": []
|
|
25
|
+
},
|
|
26
|
+
"sha256": {
|
|
27
|
+
"paper.tex": "d68bcaabe9be4cbc07f5a1e672e8cd448e96bc9b5134be350d2906ee48834482",
|
|
28
|
+
"paper.bib": "bc5a9faf4bbdcdf22705c4c8b69d656382ab9d1d03f57388c00631c3aa6ebf70"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@misc{onekey, title={One}, author={A, B}, year={2020}}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"inputs": [
|
|
4
|
+
{
|
|
5
|
+
"path": "paper.tex",
|
|
6
|
+
"role": "body"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"written": [],
|
|
10
|
+
"bibdata": [
|
|
11
|
+
"one",
|
|
12
|
+
"two"
|
|
13
|
+
],
|
|
14
|
+
"bibtex": {
|
|
15
|
+
"ran": true,
|
|
16
|
+
"databases": [
|
|
17
|
+
"one.bib"
|
|
18
|
+
],
|
|
19
|
+
"keys": [
|
|
20
|
+
"onekey"
|
|
21
|
+
],
|
|
22
|
+
"exit": 2,
|
|
23
|
+
"errors": [
|
|
24
|
+
{
|
|
25
|
+
"message": "Illegal, another \\bibdata command",
|
|
26
|
+
"file": "paper.aux",
|
|
27
|
+
"line": 5
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"sha256": {
|
|
32
|
+
"paper.tex": "f45db61354f01066eb49ab48d240033bea99ed172f04a2c4558daca8640ce796",
|
|
33
|
+
"one.bib": "61cca311ca7d77570ed410fc536c655ba76d36168fc3e56068235a2c4b16f7bf"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@misc{twokey, title={Two}, author={A, B}, year={2020}}
|
package/hooks/CLAUDE.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- vigiles:sha256:0407b53b2036133e compiled from hooks/CLAUDE.md.spec.ts -->
|
|
2
|
+
|
|
3
|
+
# CLAUDE.md
|
|
4
|
+
|
|
5
|
+
## `hooks/`
|
|
6
|
+
|
|
7
|
+
The hooks this package ships into a consumer's Claude Code session. Loaded when working under
|
|
8
|
+
`hooks/`. Every shipped hook is run in both halves, firing and silent, by `hooks/hooks.harness.ts`.
|
|
9
|
+
|
|
10
|
+
A bug here does not break this repository; it breaks somebody else's whole session. The Bash gate
|
|
11
|
+
fails closed, so a hook that cannot read its config denies every command, including the one that
|
|
12
|
+
would undo it.
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
|
|
16
|
+
### Ship Hook Mjs Never Hook Ts
|
|
17
|
+
|
|
18
|
+
**Guidance only** — A `.ts` hook inside `node_modules` fails to load and blocks every Bash command. Rejected, so not proposed again: a `.hook.ts` twin compiled to the `.mjs` (a twin drifts from its build, and nothing would notice), and a thin `.hook.ts` in the consumer importing the logic from here (`vigiles compile` refuses the import, so the hook can never be re-stamped, and the runtime fails closed on the stale stamp). [Measurements](https://github.com/zernie/paperlint/blob/b4a3dc3a81d436186f41db2d69b65fd93f1af3b6/CLAUDE.md#L272-L357).
|
|
19
|
+
|
|
20
|
+
### No Sibling Imports
|
|
21
|
+
|
|
22
|
+
**Guidance only** — A shipped hook cannot import a sibling module. The papers-root resolver is repeated in each hook, and `hooks.harness.ts` compares the copies.
|
|
23
|
+
|
|
24
|
+
### No Import Shaped Text
|
|
25
|
+
|
|
26
|
+
**Guidance only** — `checkHookImports` (run by `hooks.harness.ts`) is a text regex. Describe a forbidden import in words; never write one, not even in a comment.
|
|
27
|
+
|
|
28
|
+
### One Wiring File
|
|
29
|
+
|
|
30
|
+
**Guidance only** — The wiring is `plugin/hooks/hooks.json`. `paperlint init` merges it into the consumer's `.claude/settings.json`; there is no second copy.
|
|
31
|
+
|
|
32
|
+
### Vigiles Moves With The Consumer
|
|
33
|
+
|
|
34
|
+
**Guidance only** — `vigiles` moves with the consumer's pin, in one pass. A major mismatch makes `PreToolUse` refuse every command. `npm ls vigiles` compares what is installed with the manifest, not with the registry; Dependabot (`.github/dependabot.yml`) carries the registry half.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Compiled to hooks/CLAUDE.md by `npx vigiles compile`. Edit THIS file, never the markdown.
|
|
2
|
+
import { file, guidance, instructionFile, prose } from "vigiles/spec";
|
|
3
|
+
|
|
4
|
+
export default instructionFile({
|
|
5
|
+
sections: {
|
|
6
|
+
"`hooks/`": prose`The hooks this package ships into a consumer's Claude Code session. Loaded when working under
|
|
7
|
+
\`hooks/\`. Every shipped hook is run in both halves, firing and silent, by ${file("hooks/hooks.harness.ts")}.
|
|
8
|
+
|
|
9
|
+
A bug here does not break this repository; it breaks somebody else's whole session. The Bash gate
|
|
10
|
+
fails closed, so a hook that cannot read its config denies every command, including the one that
|
|
11
|
+
would undo it.`,
|
|
12
|
+
},
|
|
13
|
+
rules: {
|
|
14
|
+
"ship-hook-mjs-never-hook-ts": guidance(
|
|
15
|
+
"A `.ts` hook inside `node_modules` fails to load and blocks every Bash command. Rejected, so not proposed again: a `.hook.ts` twin compiled to the `.mjs` (a twin drifts from its build, and nothing would notice), and a thin `.hook.ts` in the consumer importing the logic from here (`vigiles compile` refuses the import, so the hook can never be re-stamped, and the runtime fails closed on the stale stamp). [Measurements](https://github.com/zernie/paperlint/blob/b4a3dc3a81d436186f41db2d69b65fd93f1af3b6/CLAUDE.md#L272-L357).",
|
|
16
|
+
),
|
|
17
|
+
"no-sibling-imports": guidance(
|
|
18
|
+
"A shipped hook cannot import a sibling module. The papers-root resolver is repeated in each hook, and `hooks.harness.ts` compares the copies.",
|
|
19
|
+
),
|
|
20
|
+
"no-import-shaped-text": guidance(
|
|
21
|
+
"`checkHookImports` (run by `hooks.harness.ts`) is a text regex. Describe a forbidden import in words; never write one, not even in a comment.",
|
|
22
|
+
),
|
|
23
|
+
"one-wiring-file": guidance(
|
|
24
|
+
"The wiring is `plugin/hooks/hooks.json`. `paperlint init` merges it into the consumer's `.claude/settings.json`; there is no second copy.",
|
|
25
|
+
),
|
|
26
|
+
"vigiles-moves-with-the-consumer": guidance(
|
|
27
|
+
"`vigiles` moves with the consumer's pin, in one pass. A major mismatch makes `PreToolUse` refuse every command. `npm ls vigiles` compares what is installed with the manifest, not with the registry; Dependabot (`.github/dependabot.yml`) carries the registry half.",
|
|
28
|
+
),
|
|
29
|
+
},
|
|
30
|
+
});
|
package/lib/agent-cli-version.ts
CHANGED
|
@@ -95,7 +95,7 @@ export function observeAgentCli({
|
|
|
95
95
|
|
|
96
96
|
// ⚠️ EXIT 0 AND NOTHING ON STDOUT IS NOT A CLEAN OBSERVATION — it is exactly what the discarded
|
|
97
97
|
// probe looked like, and reporting `characterized against ""` would be the same lie in a new
|
|
98
|
-
// place. This is
|
|
98
|
+
// place. This is the green zero of scripts/rules-see-files.mjs, applied to the check that enforces it.
|
|
99
99
|
if (version === "")
|
|
100
100
|
throw new Error(
|
|
101
101
|
`\`${program} --version\` exited 0 but printed no version on stdout (got ${JSON.stringify(raw)}` +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paperlint",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.1",
|
|
4
4
|
"description": "A linter for scientific papers written in LaTeX: catches mistakes before you submit to a conference or journal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@eslint/markdown": "^8.0.3",
|
|
22
22
|
"@eslint/plugin-kit": "^0.7.2",
|
|
23
|
+
"@retorquere/bibtex-parser": "^10.0.1",
|
|
23
24
|
"@unified-latex/unified-latex-types": "^1.8.4",
|
|
24
25
|
"@unified-latex/unified-latex-util-parse": "^1.8.4",
|
|
25
26
|
"@unified-latex/unified-latex-util-visit": "^1.8.4",
|
|
@@ -33,11 +34,10 @@
|
|
|
33
34
|
"ts-essentials": "^10.2.1",
|
|
34
35
|
"typescript": "^6.0.3",
|
|
35
36
|
"unpdf": "^1.8.1",
|
|
36
|
-
"vigiles": "^
|
|
37
|
+
"vigiles": "^38.2.0",
|
|
37
38
|
"zod": "^4.6.5"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
|
-
"@retorquere/bibtex-parser": "^10.0.1",
|
|
41
41
|
"@semantic-release/commit-analyzer": "13.0.1",
|
|
42
42
|
"@semantic-release/release-notes-generator": "14.1.1",
|
|
43
43
|
"@types/js-yaml": "^4.0.9",
|
|
@@ -56,14 +56,6 @@
|
|
|
56
56
|
"typescript-eslint": "^8.70.1",
|
|
57
57
|
"vitest": "^4.1.11"
|
|
58
58
|
},
|
|
59
|
-
"peerDependencies": {
|
|
60
|
-
"@retorquere/bibtex-parser": "^10.0.1"
|
|
61
|
-
},
|
|
62
|
-
"peerDependenciesMeta": {
|
|
63
|
-
"@retorquere/bibtex-parser": {
|
|
64
|
-
"optional": true
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
59
|
"repository": {
|
|
68
60
|
"type": "git",
|
|
69
61
|
"url": "git+https://github.com/zernie/paperlint.git"
|
package/plugin/CLAUDE.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!-- vigiles:sha256:6312a3b8f9804eba compiled from plugin/CLAUDE.md.spec.ts -->
|
|
2
|
+
|
|
3
|
+
# CLAUDE.md
|
|
4
|
+
|
|
5
|
+
## `plugin/`
|
|
6
|
+
|
|
7
|
+
Not a plugin any more. `plugin/hooks/hooks.json` is the hook wiring that `paperlint init` merges
|
|
8
|
+
into the consumer's `.claude/settings.json`, and it is the only source of that wiring.
|
|
9
|
+
|
|
10
|
+
## Why there is no Claude Code plugin
|
|
11
|
+
|
|
12
|
+
There is no Claude Code plugin or marketplace entry; it was removed in the release after 1.0.0
|
|
13
|
+
(#82). Do not bring it back without answering each of these, measured (`docs/install.md`,
|
|
14
|
+
"Why it is shaped this way"):
|
|
15
|
+
|
|
16
|
+
- **A plugin cannot carry the code.** Claude Code installs a plugin's dependencies with a 60-second
|
|
17
|
+
timeout, and a failed install never blocks the plugin: the hooks load and fail with
|
|
18
|
+
`cannot find module vigiles`, silently.
|
|
19
|
+
- **The skills need the npm package anyway.** 23 of 24 skills ran scripts that resolve only through
|
|
20
|
+
`node_modules/paperlint/`.
|
|
21
|
+
- **Its manifests carried versions nothing updated**, and Claude Code decides plugin updates from
|
|
22
|
+
that number.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Compiled to plugin/CLAUDE.md by `npx vigiles compile`. Edit THIS file, never the markdown.
|
|
2
|
+
import { file, instructionFile, prose } from "vigiles/spec";
|
|
3
|
+
|
|
4
|
+
export default instructionFile({
|
|
5
|
+
sections: {
|
|
6
|
+
"`plugin/`": prose`Not a plugin any more. ${file("plugin/hooks/hooks.json")} is the hook wiring that \`paperlint init\` merges
|
|
7
|
+
into the consumer's \`.claude/settings.json\`, and it is the only source of that wiring.`,
|
|
8
|
+
|
|
9
|
+
"Why there is no Claude Code plugin": prose`There is no Claude Code plugin or marketplace entry; it was removed in the release after 1.0.0
|
|
10
|
+
(#82). Do not bring it back without answering each of these, measured (${file("docs/install.md")},
|
|
11
|
+
"Why it is shaped this way"):
|
|
12
|
+
|
|
13
|
+
- **A plugin cannot carry the code.** Claude Code installs a plugin's dependencies with a 60-second
|
|
14
|
+
timeout, and a failed install never blocks the plugin: the hooks load and fail with
|
|
15
|
+
\`cannot find module vigiles\`, silently.
|
|
16
|
+
- **The skills need the npm package anyway.** 23 of 24 skills ran scripts that resolve only through
|
|
17
|
+
\`node_modules/paperlint/\`.
|
|
18
|
+
- **Its manifests carried versions nothing updated**, and Claude Code decides plugin updates from
|
|
19
|
+
that number.`,
|
|
20
|
+
},
|
|
21
|
+
rules: {},
|
|
22
|
+
});
|
package/scripts/check.test.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import assert from "node:assert/strict";
|
|
7
7
|
import { spawnSync } from "node:child_process";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { test } from "vitest";
|
|
9
|
+
import { test, vi } from "vitest";
|
|
10
10
|
import {
|
|
11
11
|
GATES,
|
|
12
12
|
NOT_COVERED,
|
|
@@ -122,6 +122,28 @@ test("🔴 runGates: a vitest gate that exits 0 but leaves no report is a FAILUR
|
|
|
122
122
|
);
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
+
test("🔴 every gate runs with CI=true, as CI runs it — a local check is the CI check", () => {
|
|
126
|
+
// Libraries change behaviour under CI=true (typescript-eslint infers a single run and parses from
|
|
127
|
+
// disk): a gate run without it passed locally and failed in CI on 2026-10-07.
|
|
128
|
+
// Whatever the caller's shell says: on CI it is already "true", so the test sets it otherwise.
|
|
129
|
+
vi.stubEnv("CI", "false");
|
|
130
|
+
const seen: (string | undefined)[] = [];
|
|
131
|
+
runGates({
|
|
132
|
+
gates: [
|
|
133
|
+
{ name: "a", job: "gates", run: ["true"] },
|
|
134
|
+
{ name: "b", job: "gates", script: "build" },
|
|
135
|
+
],
|
|
136
|
+
spawn: (_cmd, _args, options) => {
|
|
137
|
+
seen.push(options.env["CI"]);
|
|
138
|
+
return { status: 0 };
|
|
139
|
+
},
|
|
140
|
+
write: () => {},
|
|
141
|
+
...capture().io,
|
|
142
|
+
});
|
|
143
|
+
vi.unstubAllEnvs();
|
|
144
|
+
assert.deepEqual(seen, ["true", "true"]);
|
|
145
|
+
});
|
|
146
|
+
|
|
125
147
|
test("run as a program with every gate passing: the plain verdict, exit 0", () => {
|
|
126
148
|
// spawnSync is replaced before check.ts loads, so the real file runs end to end — every gate
|
|
127
149
|
// "passes" in microseconds instead of the eleven real ones running.
|
package/scripts/check.ts
CHANGED
|
@@ -30,8 +30,10 @@
|
|
|
30
30
|
*
|
|
31
31
|
* ── NO `--fast` FLAG, ON PURPOSE ───────────────────────────────────────────────────────────
|
|
32
32
|
* A subset flag re-creates the exact failure above: the cheap half gets run and reported as
|
|
33
|
-
* "the gates".
|
|
34
|
-
*
|
|
33
|
+
* "the gates". Every gate runs with CI=true, as in CI, so a local check is the CI check: the e2e
|
|
34
|
+
* steps are strict (`test/e2e/need.ts`) — a missing prerequisite (no TeX) FAILS with what to
|
|
35
|
+
* install, as it does in CI — and a test that still skips is named in the tail, never counted as a
|
|
36
|
+
* pass. "I ran check" then means one thing.
|
|
35
37
|
*/
|
|
36
38
|
import { spawnSync } from "node:child_process";
|
|
37
39
|
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
@@ -293,7 +295,9 @@ function runEach(
|
|
|
293
295
|
cwd: ROOT,
|
|
294
296
|
stdio: "inherit",
|
|
295
297
|
encoding: "utf8",
|
|
296
|
-
|
|
298
|
+
// CI=true, as CI runs every gate: libraries read it (typescript-eslint infers a single run and
|
|
299
|
+
// parses from disk), so without it a local check is not the CI check (2026-10-07).
|
|
300
|
+
env: { ...process.env, CI: "true", PATH: BIN_FIRST_PATH },
|
|
297
301
|
});
|
|
298
302
|
// 🔴 The exit code is read from the command itself, never from a pipe. `cmd | tail && …`
|
|
299
303
|
// reports the FILTER's status, which is almost always zero — that is how a red harness
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
import assert from "node:assert/strict";
|
|
22
22
|
import { spawnSync } from "node:child_process";
|
|
23
23
|
import { globSync, readFileSync } from "node:fs";
|
|
24
|
-
import { dirname, join, matchesGlob, resolve } from "node:path";
|
|
24
|
+
import { basename, dirname, join, matchesGlob, resolve } from "node:path";
|
|
25
25
|
import { fileURLToPath } from "node:url";
|
|
26
26
|
import yaml from "js-yaml";
|
|
27
27
|
import ts from "typescript";
|
|
@@ -146,16 +146,23 @@ test("every typeOnly exclusion has no runtime code", () => {
|
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
test("every evalOnly exclusion is imported only by an eval or another evalOnly module", () => {
|
|
149
|
-
const
|
|
149
|
+
const only = expand(CONFIG.evalOnly);
|
|
150
|
+
const evalOnly = new Set(only.map((f) => join(ROOT, f)));
|
|
151
|
+
// Any import of one names it — `./x.mjs`, `#lib/x` — so a source whose text holds none of their
|
|
152
|
+
// base names imports none of them, and only the others are parsed.
|
|
153
|
+
const names = only.map((f) => basename(f).replace(/\.[^.]+$/, ""));
|
|
150
154
|
const sources = globSync("**/*.{mjs,ts}", {
|
|
151
155
|
cwd: ROOT,
|
|
152
156
|
exclude: (p) => p === "node_modules" || p === "dist" || p === "coverage",
|
|
153
157
|
});
|
|
154
158
|
const importers = sources.flatMap((f) => {
|
|
155
159
|
const abs = join(ROOT, f);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
160
|
+
const text = readFileSync(abs, "utf8");
|
|
161
|
+
return names.some((n) => text.includes(n))
|
|
162
|
+
? importedPaths(abs, text)
|
|
163
|
+
.filter((target) => evalOnly.has(target))
|
|
164
|
+
.map(() => f)
|
|
165
|
+
: [];
|
|
159
166
|
});
|
|
160
167
|
const outsiders = importers.filter(
|
|
161
168
|
(f) => !f.endsWith(".eval.mjs") && !evalOnly.has(join(ROOT, f)),
|
|
@@ -258,11 +265,13 @@ test("no measured source carries a coverage-ignore comment", () => {
|
|
|
258
265
|
// The scan covers exactly what c8 measures: the same set, derived from the tracked files.
|
|
259
266
|
assert.deepEqual(files, trackedSources().filter(isMeasured));
|
|
260
267
|
assert.ok(files.length > 0);
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
),
|
|
265
|
-
|
|
268
|
+
// An ignore comment's text matches IGNORE, so a source whose text does not holds none, and only
|
|
269
|
+
// the others have their comments read off the tree.
|
|
270
|
+
const offenders = files
|
|
271
|
+
.map((f) => [f, readFileSync(join(ROOT, f), "utf8")] as const)
|
|
272
|
+
.filter(([, text]) => IGNORE.test(text))
|
|
273
|
+
.filter(([f, text]) => comments(f, text).some((c) => IGNORE.test(c)))
|
|
274
|
+
.map(([f]) => f);
|
|
266
275
|
assert.deepEqual(offenders, []);
|
|
267
276
|
});
|
|
268
277
|
|
|
@@ -391,8 +400,9 @@ test("the exclude list is exactly the justified set", () => {
|
|
|
391
400
|
"**/*.test.*",
|
|
392
401
|
// PAID LLM evaluations, never run by `npm test`
|
|
393
402
|
"**/*.eval.mjs",
|
|
394
|
-
// skill sources vigiles compiles
|
|
403
|
+
// skill and CLAUDE.md sources vigiles compiles; a glob's `**` skips a dot directory
|
|
395
404
|
"**/*.spec.ts",
|
|
405
|
+
".github/*.spec.ts",
|
|
396
406
|
// type declarations
|
|
397
407
|
"**/*.d.ts",
|
|
398
408
|
"**/*.d.mts",
|