paperlint 3.1.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +12 -7
- package/CLAUDE.md +3 -3
- package/CONTRIBUTING.md +34 -5
- package/dist/adapters/banal/index.d.ts.map +1 -1
- package/dist/adapters/banal/index.js +9 -5
- package/dist/adapters/banal/index.js.map +1 -1
- package/dist/adapters/banal/invocation.d.ts +1 -1
- package/dist/adapters/node/files.io.d.ts.map +1 -1
- package/dist/adapters/node/files.io.js +2 -1
- package/dist/adapters/node/files.io.js.map +1 -1
- package/dist/adapters/node/process.io.d.ts +0 -5
- package/dist/adapters/node/process.io.d.ts.map +1 -1
- package/dist/adapters/node/process.io.js +4 -3
- package/dist/adapters/node/process.io.js.map +1 -1
- package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
- package/dist/adapters/pdfjs/fill.js +13 -7
- package/dist/adapters/pdfjs/fill.js.map +1 -1
- package/dist/adapters/references/index.d.ts.map +1 -1
- package/dist/adapters/references/index.js +4 -5
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/adapters/references/pool.d.ts.map +1 -1
- package/dist/adapters/references/pool.js +4 -5
- package/dist/adapters/references/pool.js.map +1 -1
- package/dist/adapters/references/reach.io.d.ts.map +1 -1
- package/dist/adapters/references/reach.io.js +2 -1
- package/dist/adapters/references/reach.io.js.map +1 -1
- package/dist/build-engine.js +2 -2
- package/dist/build-engine.js.map +1 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +14 -11
- package/dist/build.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +31 -34
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +3 -2
- package/dist/doctor.js.map +1 -1
- package/dist/domain/lookup-cache.d.ts.map +1 -1
- package/dist/domain/lookup-cache.js +10 -8
- package/dist/domain/lookup-cache.js.map +1 -1
- package/dist/domain/text.d.ts +12 -0
- package/dist/domain/text.d.ts.map +1 -1
- package/dist/domain/text.js +17 -0
- package/dist/domain/text.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +4 -3
- package/dist/engine.js.map +1 -1
- package/dist/eslint-rules/bib-reachable-entry.d.ts +22 -0
- package/dist/eslint-rules/bib-reachable-entry.d.ts.map +1 -0
- package/dist/eslint-rules/bib-reachable-entry.js +75 -0
- package/dist/eslint-rules/bib-reachable-entry.js.map +1 -0
- package/dist/eslint-rules/install-path-literals.d.ts +80 -0
- package/dist/eslint-rules/install-path-literals.d.ts.map +1 -0
- package/dist/eslint-rules/install-path-literals.js +105 -0
- package/dist/eslint-rules/install-path-literals.js.map +1 -0
- package/dist/eslint-rules/latex-language.d.ts +136 -0
- package/dist/eslint-rules/latex-language.d.ts.map +1 -0
- package/dist/eslint-rules/latex-language.js +639 -0
- package/dist/eslint-rules/latex-language.js.map +1 -0
- package/dist/eslint-rules/paper-research-question.d.ts +31 -0
- package/dist/eslint-rules/paper-research-question.d.ts.map +1 -0
- package/dist/eslint-rules/paper-research-question.js +188 -0
- package/dist/eslint-rules/paper-research-question.js.map +1 -0
- package/dist/eslint-rules/paper-stages.d.ts +83 -0
- package/dist/eslint-rules/paper-stages.d.ts.map +1 -0
- package/dist/eslint-rules/paper-stages.js +358 -0
- package/dist/eslint-rules/paper-stages.js.map +1 -0
- package/dist/eslint-rules/paper-typography.d.ts +74 -0
- package/dist/eslint-rules/paper-typography.d.ts.map +1 -0
- package/dist/eslint-rules/paper-typography.js +404 -0
- package/dist/eslint-rules/paper-typography.js.map +1 -0
- package/dist/eslint-rules/papers.d.ts +42 -0
- package/dist/eslint-rules/papers.d.ts.map +1 -0
- package/dist/eslint-rules/papers.js +145 -0
- package/dist/eslint-rules/papers.js.map +1 -0
- package/dist/eslint-rules/pdf-last-page-balance.d.ts +72 -0
- package/dist/eslint-rules/pdf-last-page-balance.d.ts.map +1 -0
- package/dist/eslint-rules/pdf-last-page-balance.js +237 -0
- package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -0
- package/dist/eslint-rules/review-frontmatter.d.ts +57 -0
- package/dist/eslint-rules/review-frontmatter.d.ts.map +1 -0
- package/dist/eslint-rules/review-frontmatter.js +126 -0
- package/dist/eslint-rules/review-frontmatter.js.map +1 -0
- package/dist/eslint-rules/review-frontmatter.schema.json +36 -0
- package/dist/eslint-rules/rule-context.d.ts +55 -0
- package/dist/eslint-rules/rule-context.d.ts.map +1 -0
- package/dist/eslint-rules/rule-context.js +9 -0
- package/dist/eslint-rules/rule-context.js.map +1 -0
- package/dist/eslint-rules/sibling-frontmatter.d.ts +25 -0
- package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -0
- package/dist/eslint-rules/sibling-frontmatter.js +16 -0
- package/dist/eslint-rules/sibling-frontmatter.js.map +1 -0
- package/dist/eslint-rules/sibling-frontmatter.schema.json +14 -0
- package/dist/eslint-rules/temp-root-realpath.d.ts +71 -0
- package/dist/eslint-rules/temp-root-realpath.d.ts.map +1 -0
- package/dist/eslint-rules/temp-root-realpath.js +139 -0
- package/dist/eslint-rules/temp-root-realpath.js.map +1 -0
- package/dist/eslint-rules/tex-build.d.ts +35 -0
- package/dist/eslint-rules/tex-build.d.ts.map +1 -0
- package/dist/eslint-rules/tex-build.js +313 -0
- package/dist/eslint-rules/tex-build.js.map +1 -0
- package/dist/facts-file.d.ts.map +1 -1
- package/dist/facts-file.js +2 -1
- package/dist/facts-file.js.map +1 -1
- package/dist/hooks-settings.d.ts +1 -1
- package/dist/hooks-settings.d.ts.map +1 -1
- package/dist/hooks-settings.js +14 -9
- package/dist/hooks-settings.js.map +1 -1
- package/dist/init.d.ts +5 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +15 -7
- package/dist/init.js.map +1 -1
- package/dist/latex-loop.d.ts +2 -2
- package/dist/latex-loop.d.ts.map +1 -1
- package/dist/latex-loop.js +2 -2
- package/dist/latex-loop.js.map +1 -1
- package/dist/lib/agent-cli-version.d.ts +65 -0
- package/dist/lib/agent-cli-version.d.ts.map +1 -0
- package/dist/lib/agent-cli-version.js +77 -0
- package/dist/lib/agent-cli-version.js.map +1 -0
- package/dist/lib/check.d.ts +19 -0
- package/dist/lib/check.d.ts.map +1 -0
- package/dist/lib/check.js +52 -0
- package/dist/lib/check.js.map +1 -0
- package/dist/lib/markdown.d.ts +180 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/markdown.js +302 -0
- package/dist/lib/markdown.js.map +1 -0
- package/dist/lib/paper-config.d.ts +84 -0
- package/dist/lib/paper-config.d.ts.map +1 -0
- package/dist/lib/paper-config.js +142 -0
- package/dist/lib/paper-config.js.map +1 -0
- package/dist/lib/skill-eval-fixture.d.ts +29 -0
- package/dist/lib/skill-eval-fixture.d.ts.map +1 -0
- package/dist/lib/skill-eval-fixture.js +62 -0
- package/dist/lib/skill-eval-fixture.js.map +1 -0
- package/dist/link-skills.d.ts.map +1 -1
- package/dist/link-skills.js +5 -4
- package/dist/link-skills.js.map +1 -1
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +2 -2
- package/dist/new-paper.js.map +1 -1
- package/dist/paper-settings.d.ts.map +1 -1
- package/dist/paper-settings.js +5 -4
- package/dist/paper-settings.js.map +1 -1
- package/dist/pdf-facts.d.ts.map +1 -1
- package/dist/pdf-facts.js +2 -1
- package/dist/pdf-facts.js.map +1 -1
- package/dist/pdf-geometry.d.ts.map +1 -1
- package/dist/pdf-geometry.js +1 -1
- package/dist/pdf-geometry.js.map +1 -1
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +3 -2
- package/dist/presets.js.map +1 -1
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +11 -6
- package/dist/references.js.map +1 -1
- package/dist/rules-config.d.ts.map +1 -1
- package/dist/rules-config.js +6 -3
- package/dist/rules-config.js.map +1 -1
- package/dist/structure.js +1 -1
- package/dist/structure.js.map +1 -1
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +8 -3
- package/dist/tex-requirements.js.map +1 -1
- package/dist/toolchain.d.ts.map +1 -1
- package/dist/toolchain.js +21 -16
- package/dist/toolchain.js.map +1 -1
- package/dist/venue-rules.js +1 -1
- package/dist/venue-rules.js.map +1 -1
- package/docs/e2e.md +7 -7
- package/docs/install.md +1 -1
- package/docs/prior-art/README.md +1 -1
- package/docs/prior-art/package-location.md +5 -5
- package/docs/prior-art/repro/README.md +1 -1
- package/docs/prior-art/test-tooling.md +2 -2
- package/docs/testing.md +11 -8
- package/docs/toolchain.md +1 -1
- package/eslint-rules/{bib-reachable-entry.mjs → bib-reachable-entry.ts} +4 -3
- package/eslint-rules/install-path-literals.harness.mjs +1 -1
- package/eslint-rules/{install-path-literals.mjs → install-path-literals.ts} +16 -8
- package/eslint-rules/latex-language.harness.mjs +2 -2
- package/eslint-rules/latex-language.test.mjs +7 -1
- package/eslint-rules/{latex-language.mjs → latex-language.ts} +297 -109
- package/eslint-rules/paper-research-question.harness.mjs +3 -3
- package/eslint-rules/{paper-research-question.mjs → paper-research-question.ts} +34 -15
- package/eslint-rules/paper-stages.harness.mjs +2 -2
- package/eslint-rules/paper-stages.test.mjs +8 -2
- package/eslint-rules/{paper-stages.mjs → paper-stages.ts} +74 -29
- package/eslint-rules/paper-typography.test.mjs +3 -3
- package/eslint-rules/{paper-typography.mjs → paper-typography.ts} +132 -54
- package/eslint-rules/papers.harness.mjs +2 -2
- package/eslint-rules/{papers.mjs → papers.ts} +7 -4
- package/eslint-rules/pdf-last-page-balance.harness.mjs +3 -3
- package/eslint-rules/{pdf-last-page-balance.mjs → pdf-last-page-balance.ts} +88 -31
- package/eslint-rules/review-frontmatter.test.mjs +2 -2
- package/eslint-rules/{review-frontmatter.mjs → review-frontmatter.ts} +37 -15
- package/eslint-rules/rule-context.ts +62 -0
- package/eslint-rules/{sibling-frontmatter.mjs → sibling-frontmatter.ts} +1 -1
- package/eslint-rules/temp-root-realpath.harness.mjs +1 -1
- package/eslint-rules/{temp-root-realpath.mjs → temp-root-realpath.ts} +19 -6
- package/eslint-rules/tex-build.harness.mjs +2 -2
- package/eslint-rules/{tex-build.mjs → tex-build.ts} +4 -3
- package/eslint.config.mjs +139 -30
- package/fixtures/pdf-facts/README.md +2 -2
- package/fixtures/real-markdown-paper/{baseline.mjs → baseline.ts} +31 -10
- package/hooks/{hooks.harness.mjs → hooks.harness.ts} +51 -34
- package/hooks/paper-edit-guard.hook.mjs +1 -1
- package/hooks/{paper-edit-guard.test.mjs → paper-edit-guard.test.ts} +3 -7
- package/hooks/paper-skills-nudge.hook.mjs +1 -1
- package/hooks/{paper-skills-nudge.test.mjs → paper-skills-nudge.test.ts} +2 -6
- package/hooks/{paper-status-gates.test.mjs → paper-status-gates.test.ts} +2 -6
- package/lib/agent-cli-version.harness.mjs +1 -1
- package/lib/{agent-cli-version.mjs → agent-cli-version.ts} +32 -18
- package/lib/check.test.ts +14 -9
- package/lib/{check.mjs → check.ts} +22 -9
- package/lib/markdown.test.mjs +7 -7
- package/lib/{markdown.mjs → markdown.ts} +68 -29
- package/lib/paper-config.harness.mjs +8 -8
- package/lib/{paper-config.mjs → paper-config.ts} +19 -14
- package/lib/skill-checks.mjs +1 -1
- package/lib/skill-checks.test.mjs +1 -1
- package/lib/skill-corpus.mjs +1 -1
- package/lib/skill-eval-kit.mjs +1 -1
- package/package.json +42 -10
- package/scripts/{check.harness.mjs → check.harness.ts} +111 -10
- package/scripts/{check.test.mjs → check.test.ts} +13 -10
- package/scripts/{check.mjs → check.ts} +116 -42
- package/scripts/coverage-config.test.ts +80 -37
- package/scripts/eslint-report-guard.test.mjs +1 -1
- package/scripts/harness-api.frozen.json +14 -15
- package/scripts/harness-api.test.ts +8 -5
- package/scripts/layer-legacy-frozen.test.ts +17 -13
- package/scripts/{layer-legacy-frozen.mjs → layer-legacy-frozen.ts} +128 -39
- package/scripts/release-config.test.ts +12 -4
- package/scripts/rules-see-files.test.mjs +1 -1
- package/scripts/test.test.ts +78 -0
- package/scripts/test.ts +87 -0
- package/skills/grade-paper-writing/prose-lint.mjs +1 -1
- package/skills/grade-paper-writing/{prose-lint.test.mjs → prose-lint.test.ts} +2 -2
- package/skills/paper-pipeline/description-language.eval.mjs +1 -1
- package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +1 -1
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1 -1
- package/skills/paper-pipeline/pipeline-firing.eval.mjs +1 -1
- package/skills/paper-pipeline/pipeline-language.eval.mjs +1 -1
- package/skills/paper-pipeline/scripts/README.md +1 -1
- package/skills/paper-pipeline/scripts/announce.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/artifact-coverage.mjs +1 -1
- package/skills/paper-pipeline/scripts/{artifact-coverage.test.mjs → artifact-coverage.test.ts} +2 -2
- package/skills/paper-pipeline/scripts/consumer.mjs +1 -5
- package/skills/paper-pipeline/scripts/consumer.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +1 -1
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +1 -4
- package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/fixtures/{scorecard.mjs → scorecard.ts} +36 -7
- package/skills/paper-pipeline/scripts/{generated-code.test.mjs → generated-code.test.ts} +3 -3
- package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +2 -2
- package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +2 -2
- package/skills/paper-pipeline/scripts/pipeline-check.mjs +1 -4
- package/skills/paper-pipeline/scripts/population-map.mjs +1 -4
- package/skills/paper-pipeline/scripts/population-map.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/{round-diff.harness.mjs → round-diff.harness.ts} +45 -18
- package/skills/paper-pipeline/scripts/round-diff.mjs +1 -1
- package/skills/paper-pipeline/scripts/round-diff.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +1 -1
- package/skills/paper-pipeline/scripts/status.test.mjs +1 -1
- package/skills/plan-paper-timeline/fixtures/{fake-google-calendar.mjs → fake-google-calendar.ts} +101 -70
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +3 -3
- package/skills/render-paper/{extract-pdf-facts.harness.mjs → extract-pdf-facts.harness.ts} +34 -9
- package/skills/render-paper/render-paper.harness.mjs +2 -2
- package/skills/tighten-paper/structure.mjs +1 -1
- package/skills/tighten-paper/{structure.test.mjs → structure.test.ts} +4 -3
- package/skills/verify-citations/scripts/{bib-authors.cli.test.mjs → bib-authors.cli.test.ts} +14 -4
- package/skills/verify-citations/scripts/bib-authors.d.mts +63 -0
- package/skills/verify-citations/scripts/bib-authors.mjs +1 -4
- package/skills/verify-citations/scripts/{verify-cites.cli.test.mjs → verify-cites.cli.test.ts} +32 -9
- package/skills/verify-citations/scripts/verify-cites.d.mts +58 -0
- package/skills/verify-citations/scripts/verify-cites.mjs +11 -1
- package/skills/verify-citations/scripts/verify-cites.net.test.mjs +35 -0
- package/skills/verify-citations/scripts/verify-cites.test.mjs +14 -0
- package/src/CLAUDE.md +1 -1
- package/src/adapters/banal/index.test.ts +3 -6
- package/src/adapters/banal/index.ts +7 -4
- package/src/adapters/banal/invocation.test.ts +3 -1
- package/src/adapters/banal/invocation.ts +1 -1
- package/src/adapters/banal/output.test.ts +1 -1
- package/src/adapters/banal/run.test.ts +3 -3
- package/src/adapters/banal/xml.test.ts +1 -1
- package/src/adapters/curl/download.test.ts +4 -2
- package/src/adapters/node/files.io.ts +2 -2
- package/src/adapters/node/files.test.ts +3 -1
- package/src/adapters/node/process.io.ts +4 -3
- package/src/adapters/node/process.test.ts +1 -1
- package/src/adapters/node/workspace.test.ts +3 -1
- package/src/adapters/pdfjs/fill.test.ts +2 -2
- package/src/adapters/pdfjs/fill.ts +14 -7
- package/src/adapters/references/index.test.ts +31 -38
- package/src/adapters/references/index.ts +26 -58
- package/src/adapters/references/pool.ts +3 -5
- package/src/adapters/references/reach.io.ts +2 -1
- package/src/build-engine.harness.mjs +1 -1
- package/src/build-engine.test.ts +2 -2
- package/src/build-engine.ts +2 -2
- package/src/build.harness.mjs +2 -2
- package/src/build.test.ts +15 -14
- package/src/build.ts +28 -19
- package/src/cli.harness.mjs +6 -6
- package/src/cli.test.ts +13 -6
- package/src/cli.ts +39 -37
- package/src/doctor.harness.mjs +3 -3
- package/src/doctor.ts +3 -2
- package/src/domain/lookup-cache.ts +21 -11
- package/src/domain/result.test.ts +2 -2
- package/src/domain/text.test.ts +32 -0
- package/src/domain/text.ts +23 -0
- package/src/engine.harness.mjs +2 -2
- package/src/engine.ts +4 -3
- package/src/facts-file.test.ts +9 -7
- package/src/facts-file.ts +2 -1
- package/src/{hooks-settings.harness.mjs → hooks-settings.harness.ts} +39 -20
- package/src/hooks-settings.ts +20 -9
- package/src/init.test.ts +12 -9
- package/src/init.ts +22 -12
- package/src/{latex-log.harness.mjs → latex-log.harness.ts} +14 -14
- package/src/{latex-loop.harness.mjs → latex-loop.harness.ts} +64 -36
- package/src/latex-loop.ts +3 -3
- package/src/{link-skills.harness.mjs → link-skills.harness.ts} +19 -19
- package/src/link-skills.test.ts +3 -3
- package/src/link-skills.ts +5 -4
- package/src/lint-fix.test.ts +4 -6
- package/src/linted-set.test.ts +2 -2
- package/src/new-paper.harness.mjs +2 -2
- package/src/new-paper.test.ts +8 -10
- package/src/new-paper.ts +2 -2
- package/src/paper-files.test.ts +3 -5
- package/src/paper-settings-commands.test.ts +5 -4
- package/src/paper-settings.test.ts +5 -5
- package/src/paper-settings.ts +8 -9
- package/src/{pdf-facts.harness.mjs → pdf-facts.harness.ts} +9 -8
- package/src/pdf-facts.test.ts +10 -11
- package/src/pdf-facts.ts +2 -1
- package/src/{pdf-geometry.harness.mjs → pdf-geometry.harness.ts} +19 -12
- package/src/pdf-geometry.ts +3 -1
- package/src/presets.ts +3 -2
- package/src/references.test.ts +51 -43
- package/src/references.ts +14 -7
- package/src/{rules-config.harness.mjs → rules-config.harness.ts} +7 -13
- package/src/rules-config.ts +7 -4
- package/src/rules-off.test.ts +6 -4
- package/src/{structure.harness.mjs → structure.harness.ts} +26 -15
- package/src/structure.ts +1 -1
- package/src/{tex-requirements.harness.mjs → tex-requirements.harness.ts} +50 -22
- package/src/tex-requirements.ts +8 -5
- package/src/toolchain.harness.mjs +2 -2
- package/src/toolchain.test.ts +1 -1
- package/src/toolchain.ts +31 -17
- package/src/venue-rules.test.ts +62 -64
- package/src/venue-rules.ts +1 -1
- package/tsconfig.json +6 -3
- package/tsconfig.pkg.json +10 -0
- package/lib/check.d.mts +0 -17
- package/lib/paper-config.d.mts +0 -31
- package/scripts/layer-legacy-frozen.d.mts +0 -36
- package/scripts/rules-are-content-only.harness.mjs +0 -105
- package/scripts/rules-are-content-only.mjs +0 -148
- package/scripts/rules-are-content-only.test.mjs +0 -61
- package/scripts/test.mjs +0 -44
- package/scripts/test.test.mjs +0 -52
- /package/bin/{paperlint.test.mjs → paperlint.test.ts} +0 -0
- /package/lib/{skill-eval-fixture.mjs → skill-eval-fixture.ts} +0 -0
- /package/skills/grade-paper-writing/__snapshots__/{prose-lint.test.mjs.snap → prose-lint.test.ts.snap} +0 -0
- /package/skills/osf-artifact-upload/{osf-artifact-upload.harness.mjs → osf-artifact-upload.harness.ts} +0 -0
- /package/skills/tighten-paper/__snapshots__/{structure.test.mjs.snap → structure.test.ts.snap} +0 -0
|
@@ -32,7 +32,28 @@
|
|
|
32
32
|
// a bare top-level `import` changed the shape of the failure: no `node_modules` → exit 1
|
|
33
33
|
// → **the blocking `pre` gate in paper-lint stops blocking silently**, because
|
|
34
34
|
// PreToolUse counts only exit code 2 as a block. Measured: `ERR_MODULE_NOT_FOUND`, exit 1.
|
|
35
|
-
|
|
35
|
+
import type MarkdownIt from "markdown-it";
|
|
36
|
+
import type { Token } from "markdown-it";
|
|
37
|
+
|
|
38
|
+
/** One ATX heading: its level, its text without the hashes, its 0-based line and line offset. */
|
|
39
|
+
export interface Heading {
|
|
40
|
+
readonly depth: number;
|
|
41
|
+
readonly text: string;
|
|
42
|
+
readonly line: number;
|
|
43
|
+
readonly offset: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** A chunk of the document: the heading it starts with (`null` for the preamble), with and without it. */
|
|
47
|
+
export interface Section {
|
|
48
|
+
readonly heading: Heading | null;
|
|
49
|
+
readonly raw: string;
|
|
50
|
+
readonly body: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** A block tokenizer with markdown-it's shape — the default, or one a test passes. */
|
|
54
|
+
export type Parse = (text: string) => readonly Token[];
|
|
55
|
+
|
|
56
|
+
let md: MarkdownIt | null = null;
|
|
36
57
|
try {
|
|
37
58
|
const { default: MarkdownIt } = await import("markdown-it");
|
|
38
59
|
md = new MarkdownIt();
|
|
@@ -50,7 +71,10 @@ try {
|
|
|
50
71
|
export const MD_AVAILABLE = () => md !== null;
|
|
51
72
|
|
|
52
73
|
/** markdown-it's block tokens for `text`, or null when it did not resolve. A test passes its own. */
|
|
53
|
-
const defaultParse = ()
|
|
74
|
+
const defaultParse = (): Parse | null => {
|
|
75
|
+
const parser = md;
|
|
76
|
+
return parser === null ? null : (text) => parser.parse(text, {});
|
|
77
|
+
};
|
|
54
78
|
|
|
55
79
|
/**
|
|
56
80
|
* The frontmatter is BLANKED with spaces, not cut out: the offsets must stay the
|
|
@@ -60,7 +84,7 @@ const defaultParse = () => (md === null ? null : (text) => md.parse(text, {}));
|
|
|
60
84
|
* sections.
|
|
61
85
|
*/
|
|
62
86
|
const FRONTMATTER_RE = /^---[ \t]*\r?\n[\s\S]*?\r?\n---[ \t]*(?=\r?\n|$)/;
|
|
63
|
-
export function blankFrontmatter(text) {
|
|
87
|
+
export function blankFrontmatter(text: string): string {
|
|
64
88
|
const m = FRONTMATTER_RE.exec(text);
|
|
65
89
|
return m ? m[0].replace(/[^\n]/g, " ") + text.slice(m[0].length) : text;
|
|
66
90
|
}
|
|
@@ -78,7 +102,7 @@ export function blankFrontmatter(text) {
|
|
|
78
102
|
* and rejected: gray-matter"). The value here is one fence instead of eight, and the
|
|
79
103
|
* parsing of VALUES is done by `js-yaml` at the caller.
|
|
80
104
|
*/
|
|
81
|
-
export function frontmatterBlock(text) {
|
|
105
|
+
export function frontmatterBlock(text: string): string | null {
|
|
82
106
|
const m = FRONTMATTER_RE.exec(text);
|
|
83
107
|
if (!m) return null;
|
|
84
108
|
const inner = m[0]
|
|
@@ -96,13 +120,13 @@ export function frontmatterBlock(text) {
|
|
|
96
120
|
* later shown to the user; cutting — where the text is merely counted. Choose by what
|
|
97
121
|
* the caller does, not by taste.
|
|
98
122
|
*/
|
|
99
|
-
export function stripFrontmatter(text) {
|
|
123
|
+
export function stripFrontmatter(text: string): string {
|
|
100
124
|
const m = FRONTMATTER_RE.exec(text);
|
|
101
125
|
return m ? text.slice(m[0].length).replace(/^\r?\n/, "") : text;
|
|
102
126
|
}
|
|
103
127
|
|
|
104
128
|
/** Line-start offsets — so that `token.map` becomes a position in the source string. */
|
|
105
|
-
function lineStarts(text) {
|
|
129
|
+
function lineStarts(text: string): number[] {
|
|
106
130
|
const out = [0];
|
|
107
131
|
for (let i = 0; i < text.length; i++) if (text[i] === "\n") out.push(i + 1);
|
|
108
132
|
return out;
|
|
@@ -121,13 +145,15 @@ function lineStarts(text) {
|
|
|
121
145
|
* under without a blank line would become a level-2 heading per CommonMark. The former
|
|
122
146
|
* regexps knew only ATX, so this preserves the contract rather than narrowing it.
|
|
123
147
|
*/
|
|
124
|
-
export function headings(
|
|
148
|
+
export function headings(
|
|
149
|
+
text: string,
|
|
150
|
+
{ parse = defaultParse() }: { parse?: Parse | null } = {},
|
|
151
|
+
): Heading[] {
|
|
125
152
|
if (parse === null) return [];
|
|
126
153
|
const toks = parse(blankFrontmatter(text));
|
|
127
154
|
const starts = lineStarts(text);
|
|
128
|
-
const out = [];
|
|
129
|
-
for (
|
|
130
|
-
const t = toks[i];
|
|
155
|
+
const out: Heading[] = [];
|
|
156
|
+
for (const [i, t] of toks.entries()) {
|
|
131
157
|
if (t.type !== "heading_open" || !t.map) continue;
|
|
132
158
|
if (!t.markup || !t.markup.startsWith("#")) continue; // setext — see the caveat above
|
|
133
159
|
// markdown-it follows `heading_open` with its `inline` token and maps blocks to lines of the
|
|
@@ -166,18 +192,22 @@ export function headings(text, { parse = defaultParse() } = {}) {
|
|
|
166
192
|
* happened (`recordBlock` in `skill-corpus.mjs` returned a single "#" character for all
|
|
167
193
|
* 21 skills).
|
|
168
194
|
*/
|
|
169
|
-
export function splitSections(
|
|
195
|
+
export function splitSections(
|
|
196
|
+
text: string,
|
|
197
|
+
{ min = 2, max = 6 }: { min?: number; max?: number } = {},
|
|
198
|
+
): Section[] {
|
|
170
199
|
const hs = headings(text).filter((h) => h.depth >= min && h.depth <= max);
|
|
171
|
-
const out = [];
|
|
172
|
-
const
|
|
200
|
+
const out: Section[] = [];
|
|
201
|
+
const [first] = hs;
|
|
202
|
+
const preEnd = first ? first.offset : text.length;
|
|
173
203
|
out.push({
|
|
174
204
|
heading: null,
|
|
175
205
|
raw: text.slice(0, preEnd),
|
|
176
206
|
body: text.slice(0, preEnd),
|
|
177
207
|
});
|
|
178
|
-
for (
|
|
179
|
-
const
|
|
180
|
-
const end =
|
|
208
|
+
for (const [i, h] of hs.entries()) {
|
|
209
|
+
const next = hs[i + 1];
|
|
210
|
+
const end = next ? next.offset : text.length;
|
|
181
211
|
const nl = text.indexOf("\n", h.offset);
|
|
182
212
|
const bodyStart = nl === -1 || nl + 1 > end ? end : nl + 1;
|
|
183
213
|
out.push({
|
|
@@ -221,18 +251,21 @@ export function splitSections(text, { min = 2, max = 6 } = {}) {
|
|
|
221
251
|
* degradation is acceptable (see the module comment), while a silent fallback to a
|
|
222
252
|
* regex would mean a working degraded version that nobody notices.
|
|
223
253
|
*/
|
|
224
|
-
export function fences(text) {
|
|
254
|
+
export function fences(text: string): string[] {
|
|
225
255
|
if (md === null) return [];
|
|
226
|
-
const out = [];
|
|
256
|
+
const out: string[] = [];
|
|
227
257
|
for (const t of md.parse(blankFrontmatter(text), {}))
|
|
228
258
|
if (t.type === "fence" || t.type === "code_block") out.push(t.content);
|
|
229
259
|
return out;
|
|
230
260
|
}
|
|
231
261
|
|
|
232
|
-
export function stripFences(
|
|
262
|
+
export function stripFences(
|
|
263
|
+
text: string,
|
|
264
|
+
{ blank = false }: { blank?: boolean } = {},
|
|
265
|
+
): string {
|
|
233
266
|
if (md === null) return text;
|
|
234
267
|
const lines = text.split("\n");
|
|
235
|
-
const drop = new Set();
|
|
268
|
+
const drop = new Set<number>();
|
|
236
269
|
for (const t of md.parse(blankFrontmatter(text), {}))
|
|
237
270
|
if ((t.type === "fence" || t.type === "code_block") && t.map)
|
|
238
271
|
for (let i = t.map[0]; i < t.map[1]; i++) drop.add(i);
|
|
@@ -249,7 +282,9 @@ export function stripFences(text, { blank = false } = {}) {
|
|
|
249
282
|
* indistinguishable from "the paper has no sections". A confident zero has already been
|
|
250
283
|
* read as a finding four times in this repo; here it is inexpressible.
|
|
251
284
|
*/
|
|
252
|
-
export function requireMarkdown({
|
|
285
|
+
export function requireMarkdown({
|
|
286
|
+
from = import.meta.url,
|
|
287
|
+
}: { from?: string } = {}): void {
|
|
253
288
|
if (MD_AVAILABLE()) return;
|
|
254
289
|
// 🔴 THE CURE DEPENDS ON WHERE THIS COPY RUNS FROM. Measured 2026-09-19: a Claude Code plugin
|
|
255
290
|
// copy is installed without dependencies (`npm pack` strips `package-lock.json`, and the plugin
|
|
@@ -301,23 +336,27 @@ export function requireMarkdown({ from = import.meta.url } = {}) {
|
|
|
301
336
|
* automatically, by the construction of the parser, and not by a separate line-type
|
|
302
337
|
* check.
|
|
303
338
|
*/
|
|
304
|
-
export function paragraphs(text) {
|
|
339
|
+
export function paragraphs(text: string): { line: number; endLine: number }[] {
|
|
305
340
|
if (md === null) return [];
|
|
306
341
|
return md
|
|
307
342
|
.parse(blankFrontmatter(text), {})
|
|
308
|
-
.
|
|
309
|
-
|
|
343
|
+
.flatMap((t) =>
|
|
344
|
+
t.type === "paragraph_open" && t.map
|
|
345
|
+
? [{ line: t.map[0], endLine: t.map[1] }]
|
|
346
|
+
: [],
|
|
347
|
+
);
|
|
310
348
|
}
|
|
311
349
|
|
|
312
|
-
export function tables(
|
|
350
|
+
export function tables(
|
|
351
|
+
text: string,
|
|
352
|
+
): { line: number; endLine: number; rows: string[][] }[] {
|
|
313
353
|
if (md === null) return [];
|
|
314
354
|
const lines = blankFrontmatter(text).split("\n");
|
|
315
|
-
const out = [];
|
|
355
|
+
const out: { line: number; endLine: number; rows: string[][] }[] = [];
|
|
316
356
|
for (const t of md.parse(blankFrontmatter(text), {})) {
|
|
317
357
|
if (t.type !== "table_open" || !t.map) continue;
|
|
318
|
-
const rows = [];
|
|
319
|
-
for (
|
|
320
|
-
const raw = lines[i];
|
|
358
|
+
const rows: string[][] = [];
|
|
359
|
+
for (const raw of lines.slice(t.map[0], t.map[1])) {
|
|
321
360
|
if (/^\s*\|?[\s:|-]+\|?\s*$/.test(raw) && raw.includes("-")) continue; // alignment
|
|
322
361
|
rows.push(
|
|
323
362
|
raw
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Both halves for `lib/paper-config.mjs` — and, more broadly, for the SET of places that
|
|
3
3
|
* publish these two constants.
|
|
4
4
|
*
|
|
5
|
-
* 🔴 WHY THIS CHECK MOVED HERE FROM `hooks/hooks.harness.
|
|
5
|
+
* 🔴 WHY THIS CHECK MOVED HERE FROM `hooks/hooks.harness.ts`. There it compared three hooks
|
|
6
6
|
* against each other — and was right only as far as its COVERAGE was right. Measured
|
|
7
7
|
* 2026-09-18: there were eight declarations across five files, four per constant, and for each
|
|
8
8
|
* constant exactly one copy sat OUTSIDE the comparison (`eslint-rules/papers.mjs`,
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
import { readFileSync, readdirSync } from "node:fs";
|
|
28
28
|
import { dirname, join, relative, resolve } from "node:path";
|
|
29
29
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
30
|
-
import { createChecker } from "./check.
|
|
30
|
+
import { createChecker } from "./check.ts";
|
|
31
31
|
|
|
32
32
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
33
33
|
const ROOT = resolve(HERE, "..");
|
|
@@ -37,15 +37,15 @@ const check = createChecker();
|
|
|
37
37
|
/**
|
|
38
38
|
* Every place that publishes at least one of the two constants. The three hooks duplicate them
|
|
39
39
|
* out of necessity (a compiled hook is forbidden to import anything but `vigiles/hook`); the
|
|
40
|
-
* rest re-export from `lib/paper-config.
|
|
40
|
+
* rest re-export from `lib/paper-config.ts` and are kept in this list for exactly one reason:
|
|
41
41
|
* so a re-export that is one day swapped back for its own declaration gets caught.
|
|
42
42
|
*/
|
|
43
43
|
const CARRIERS = [
|
|
44
|
-
"lib/paper-config.
|
|
44
|
+
"lib/paper-config.ts",
|
|
45
45
|
"hooks/paper-edit-guard.hook.mjs",
|
|
46
46
|
"hooks/paper-skills-nudge.hook.mjs",
|
|
47
47
|
"hooks/paper-status-gates.hook.mjs",
|
|
48
|
-
"eslint-rules/papers.
|
|
48
|
+
"eslint-rules/papers.ts",
|
|
49
49
|
"skills/paper-pipeline/scripts/consumer.mjs",
|
|
50
50
|
];
|
|
51
51
|
|
|
@@ -167,7 +167,7 @@ const loaded = await Promise.all(
|
|
|
167
167
|
"repro",
|
|
168
168
|
]);
|
|
169
169
|
const declares =
|
|
170
|
-
/^(?:export )?const (?:CONFIG_KEY|CONFIG_FILE|DEFAULT_PAPERS_ROOT|PAPERS_DIR_FIELD)\s
|
|
170
|
+
/^(?:export )?const (?:CONFIG_KEY|CONFIG_FILE|DEFAULT_PAPERS_ROOT|PAPERS_DIR_FIELD)\s*(?::[^=]*)?=/m;
|
|
171
171
|
const found = [];
|
|
172
172
|
const walk = (dir) => {
|
|
173
173
|
for (const e of readdirSync(dir, { withFileTypes: true })) {
|
|
@@ -202,7 +202,7 @@ const loaded = await Promise.all(
|
|
|
202
202
|
// every `settingsOf(root)?.<key>` (and the older `[CONFIG_KEY]?.<key>` shape), plus every field of
|
|
203
203
|
// `PaperlintConfig`, the CLI's typed view of the same object.
|
|
204
204
|
{
|
|
205
|
-
const { SETTINGS_KEYS } = await import(join(HERE, "paper-config.
|
|
205
|
+
const { SETTINGS_KEYS } = await import(join(HERE, "paper-config.ts"));
|
|
206
206
|
const ts = (await import("typescript")).default;
|
|
207
207
|
const readKeys = new Set();
|
|
208
208
|
const isConfigKey = (e) =>
|
|
@@ -262,7 +262,7 @@ const loaded = await Promise.all(
|
|
|
262
262
|
// ── the two readers' fallbacks: no marker anywhere up the tree, and JSON that is not an object ──
|
|
263
263
|
{
|
|
264
264
|
const { findProjectRoot, settingsOf } = await import(
|
|
265
|
-
join(HERE, "paper-config.
|
|
265
|
+
join(HERE, "paper-config.ts")
|
|
266
266
|
);
|
|
267
267
|
check(
|
|
268
268
|
"findProjectRoot: no paperlint.json and no package.json up to / — the start directory itself",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* allowing a reach into `child_process`. The restriction is wider than strictly necessary
|
|
10
10
|
* (importing plain constants adds no capability), and that is discussed in zernie/vigiles#245,
|
|
11
11
|
* but until it is relaxed the hooks duplicate, and drift is caught by the cross-check in
|
|
12
|
-
* `hooks/hooks.harness.
|
|
12
|
+
* `hooks/hooks.harness.ts`.
|
|
13
13
|
*
|
|
14
14
|
* 🔴 BUT THE REST WERE DUPLICATING FOR NO REASON AT ALL. `eslint-rules/papers.mjs` and
|
|
15
15
|
* `skills/paper-pipeline/scripts/consumer.mjs` are not hooks, carry no import restriction, and
|
|
@@ -28,7 +28,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
28
28
|
* and the hooks resolve their scripts through it. It equals the package name, and
|
|
29
29
|
* `lib/paper-config.harness.mjs` checks that.
|
|
30
30
|
*/
|
|
31
|
-
export const CONFIG_KEY = "paperlint";
|
|
31
|
+
export const CONFIG_KEY: string = "paperlint";
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* THE SETTINGS FILE, ONE NAME AT TWO LEVELS, ONE SCHEMA (`SETTINGS_KEYS`):
|
|
@@ -41,13 +41,13 @@ export const CONFIG_KEY = "paperlint";
|
|
|
41
41
|
* applied after the root's. A venue preset (`paperlint:<name>`, or the project's own `./x.jsonc`)
|
|
42
42
|
* is the third level, below both.
|
|
43
43
|
*/
|
|
44
|
-
export const CONFIG_FILE = "paperlint.json";
|
|
44
|
+
export const CONFIG_FILE: string = "paperlint.json";
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* The files that make a directory a PAPER. A `paperlint.json` beside one of them is that paper's,
|
|
48
48
|
* never the project's — so walking up from inside a paper does not stop at the paper's own file.
|
|
49
49
|
*/
|
|
50
|
-
export const PAPER_MARKERS = Object.freeze([
|
|
50
|
+
export const PAPER_MARKERS: readonly string[] = Object.freeze([
|
|
51
51
|
"paper.tex",
|
|
52
52
|
"paper.md",
|
|
53
53
|
"draft.md",
|
|
@@ -61,13 +61,16 @@ export const PAPER_MARKERS = Object.freeze([
|
|
|
61
61
|
*
|
|
62
62
|
* @param isFile whether a path exists — `existsSync` by default; `src/` passes its Files port.
|
|
63
63
|
*/
|
|
64
|
-
export function findProjectRoot(
|
|
64
|
+
export function findProjectRoot(
|
|
65
|
+
startDir: string,
|
|
66
|
+
isFile: (path: string) => boolean = existsSync,
|
|
67
|
+
): string {
|
|
65
68
|
const start = resolve(startDir);
|
|
66
|
-
const isPaper = (d) => PAPER_MARKERS.some((m) => isFile(join(d, m)));
|
|
69
|
+
const isPaper = (d: string) => PAPER_MARKERS.some((m) => isFile(join(d, m)));
|
|
67
70
|
// Up from `start` to the first directory `found` accepts; null past the filesystem root. A
|
|
68
71
|
// loop with an exit condition rather than `for (;;)`: the code after an endless loop is a block
|
|
69
72
|
// that can never run, and coverage counts it as one that did not.
|
|
70
|
-
const walk = (found) => {
|
|
73
|
+
const walk = (found: (dir: string) => boolean): string | null => {
|
|
71
74
|
let d = start;
|
|
72
75
|
while (!found(d)) {
|
|
73
76
|
if (dirname(d) === d) return null;
|
|
@@ -82,7 +85,7 @@ export function findProjectRoot(startDir, isFile = existsSync) {
|
|
|
82
85
|
);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
const isObject = (v) =>
|
|
88
|
+
const isObject = (v: unknown): v is Readonly<Record<string, unknown>> =>
|
|
86
89
|
v !== null && typeof v === "object" && !Array.isArray(v);
|
|
87
90
|
|
|
88
91
|
/**
|
|
@@ -90,8 +93,10 @@ const isObject = (v) =>
|
|
|
90
93
|
* such file, or it does not parse, or it is not an object. For readers that only need one key and
|
|
91
94
|
* fall back to its default; `paperlint lint` parses the file strictly and names what is wrong.
|
|
92
95
|
*/
|
|
93
|
-
export function settingsOf(
|
|
94
|
-
|
|
96
|
+
export function settingsOf(
|
|
97
|
+
root: string,
|
|
98
|
+
): Readonly<Record<string, unknown>> | undefined {
|
|
99
|
+
let v: unknown;
|
|
95
100
|
try {
|
|
96
101
|
v = JSON.parse(readFileSync(join(root, CONFIG_FILE), "utf8"));
|
|
97
102
|
} catch {
|
|
@@ -101,7 +106,7 @@ export function settingsOf(root) {
|
|
|
101
106
|
}
|
|
102
107
|
|
|
103
108
|
/** The default papers directory, used when the root `paperlint.json` declares none (or there is none). */
|
|
104
|
-
export const DEFAULT_PAPERS_ROOT = "papers";
|
|
109
|
+
export const DEFAULT_PAPERS_ROOT: string = "papers";
|
|
105
110
|
|
|
106
111
|
/**
|
|
107
112
|
* The field that names the papers directory: `{ "papersDir": "papers" }` in the root
|
|
@@ -112,7 +117,7 @@ export const DEFAULT_PAPERS_ROOT = "papers";
|
|
|
112
117
|
* here. The three hooks cannot import this module, so they keep their own copy, and
|
|
113
118
|
* `lib/paper-config.harness.mjs` checks that every copy matches this one.
|
|
114
119
|
*/
|
|
115
|
-
export const PAPERS_DIR_FIELD = "papersDir";
|
|
120
|
+
export const PAPERS_DIR_FIELD: string = "papersDir";
|
|
116
121
|
|
|
117
122
|
/**
|
|
118
123
|
* Every key a `paperlint.json` may hold — the root's and a paper's, ONE schema — with who reads it.
|
|
@@ -124,7 +129,7 @@ export const PAPERS_DIR_FIELD = "papersDir";
|
|
|
124
129
|
* `PaperlintConfig`, and requires each to be here — so a new reader that forgets this list turns
|
|
125
130
|
* the harness red before a consumer's config does.
|
|
126
131
|
*/
|
|
127
|
-
export const SETTINGS_KEYS = Object.freeze({
|
|
132
|
+
export const SETTINGS_KEYS: Readonly<Record<string, string>> = Object.freeze({
|
|
128
133
|
papersDir: `the papers directory, default "papers" — every command, the hooks`,
|
|
129
134
|
structure: "which files a paper directory must hold — paperlint lint",
|
|
130
135
|
rules:
|
|
@@ -144,7 +149,7 @@ export const SETTINGS_KEYS = Object.freeze({
|
|
|
144
149
|
});
|
|
145
150
|
|
|
146
151
|
/** The keys that only mean something for the whole project: refused in a paper's `paperlint.json`. */
|
|
147
|
-
export const ROOT_ONLY_KEYS = Object.freeze([
|
|
152
|
+
export const ROOT_ONLY_KEYS: readonly string[] = Object.freeze([
|
|
148
153
|
"papersDir",
|
|
149
154
|
"structure",
|
|
150
155
|
"ledger",
|
package/lib/skill-checks.mjs
CHANGED
|
@@ -28,7 +28,7 @@ import { recordCheck } from "vigiles";
|
|
|
28
28
|
// Markup is parsed with a parser (`CLAUDE.md`, 2026-08-11). `requireMarkdown()` is called by
|
|
29
29
|
// `skill-corpus.mjs` on the import below, so by the time anything is parsed here the parser
|
|
30
30
|
// either exists or the process does not.
|
|
31
|
-
import { headings as mdHeadings } from "
|
|
31
|
+
import { headings as mdHeadings } from "#lib/markdown";
|
|
32
32
|
|
|
33
33
|
// 🔴 2026-08-28: nine names were removed from this list, and that is NOT a style cleanup — they
|
|
34
34
|
// had drifted apart from what the file does. `EXCLUDED PIPELINE_MARKER GATE_SKILLS EXPECTED_GATES
|
|
@@ -12,7 +12,7 @@ import { cpSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
12
12
|
import { dirname, join } from "node:path";
|
|
13
13
|
import { fileURLToPath } from "node:url";
|
|
14
14
|
import { test } from "vitest";
|
|
15
|
-
import { useTempDir, writeTree } from "../test/support.
|
|
15
|
+
import { useTempDir, writeTree } from "../test/support.ts";
|
|
16
16
|
|
|
17
17
|
const SHIPPED = join(dirname(fileURLToPath(import.meta.url)), "..", "skills");
|
|
18
18
|
const consumer = useTempDir("skill-checks-");
|
package/lib/skill-corpus.mjs
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
headings as mdHeadings,
|
|
39
39
|
requireMarkdown,
|
|
40
40
|
frontmatterBlock,
|
|
41
|
-
} from "
|
|
41
|
+
} from "#lib/markdown";
|
|
42
42
|
|
|
43
43
|
// Markup is parsed with a real parser (`CLAUDE.md`, 2026-08-11). Here we THROW rather than
|
|
44
44
|
// degrade: this module answers the question "what does the skill corpus contain", and an empty
|
package/lib/skill-eval-kit.mjs
CHANGED
|
@@ -54,7 +54,7 @@ import { resolve } from "node:path";
|
|
|
54
54
|
import { consumerRoot } from "../skills/paper-pipeline/scripts/consumer.mjs";
|
|
55
55
|
|
|
56
56
|
import { BY_SKILL, irrelevantFor } from "./skill-trigger-cases.mjs";
|
|
57
|
-
import { FIXTURE } from "
|
|
57
|
+
import { FIXTURE } from "#lib/skill-eval-fixture";
|
|
58
58
|
|
|
59
59
|
// The CONSUMER's root — the live harness being measured is the consumer's, not this package's.
|
|
60
60
|
const REPO = consumerRoot();
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paperlint",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
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",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "tsc",
|
|
9
|
-
"prepare": "tsc",
|
|
10
|
-
"test": "node scripts/test.
|
|
11
|
-
"coverage": "NODE_OPTIONS=\"--import=./test/coverage-src.
|
|
8
|
+
"build": "tsc -p tsconfig.pkg.json && tsc",
|
|
9
|
+
"prepare": "tsc -p tsconfig.pkg.json && tsc",
|
|
10
|
+
"test": "node scripts/test.ts",
|
|
11
|
+
"coverage": "NODE_OPTIONS=\"--import=./test/coverage-src.ts $NODE_OPTIONS\" c8 --check-coverage npm test --",
|
|
12
12
|
"lint": "eslint .",
|
|
13
|
-
"check": "node scripts/check.
|
|
14
|
-
"test:e2e": "node test/e2e/install.
|
|
13
|
+
"check": "node scripts/check.ts",
|
|
14
|
+
"test:e2e": "node test/e2e/install.ts && node test/e2e/build.ts",
|
|
15
15
|
"fmt": "prettier --write .",
|
|
16
16
|
"fmt:check": "prettier --check ."
|
|
17
17
|
},
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"js-yaml": "^4.1.0",
|
|
25
25
|
"markdown-it": "^14.3.0",
|
|
26
26
|
"ts-essentials": "^10.2.1",
|
|
27
|
-
"typescript": "^
|
|
27
|
+
"typescript": "^6.0.3",
|
|
28
28
|
"unpdf": "^1.8.1",
|
|
29
29
|
"vigiles": "^31.0.1",
|
|
30
30
|
"zod": "^4.6.5"
|
|
@@ -33,9 +33,12 @@
|
|
|
33
33
|
"@retorquere/bibtex-parser": "^10.0.1",
|
|
34
34
|
"@semantic-release/commit-analyzer": "13.0.1",
|
|
35
35
|
"@semantic-release/release-notes-generator": "14.1.1",
|
|
36
|
+
"@types/js-yaml": "^4.0.9",
|
|
37
|
+
"@types/markdown-it": "^14.2.0",
|
|
36
38
|
"@types/node": "^26.6.1",
|
|
37
39
|
"c8": "^12.0.0",
|
|
38
40
|
"conventional-changelog-conventionalcommits": "9.3.1",
|
|
41
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
39
42
|
"eslint-plugin-boundaries": "^7.2.0",
|
|
40
43
|
"eslint-plugin-n": "^18.3.0",
|
|
41
44
|
"prettier": "^3.8.1",
|
|
@@ -72,6 +75,22 @@
|
|
|
72
75
|
"bin": {
|
|
73
76
|
"paperlint": "bin/paperlint.mjs"
|
|
74
77
|
},
|
|
78
|
+
"exports": {
|
|
79
|
+
"./eslint-rules/*.mjs": {
|
|
80
|
+
"types": "./dist/eslint-rules/*.d.ts",
|
|
81
|
+
"default": "./dist/eslint-rules/*.js"
|
|
82
|
+
},
|
|
83
|
+
"./lib/skill-checks.mjs": "./lib/skill-checks.mjs",
|
|
84
|
+
"./lib/skill-corpus.mjs": "./lib/skill-corpus.mjs",
|
|
85
|
+
"./lib/skill-eval-kit.mjs": "./lib/skill-eval-kit.mjs",
|
|
86
|
+
"./lib/skill-trigger-cases.mjs": "./lib/skill-trigger-cases.mjs",
|
|
87
|
+
"./lib/trigger-ledger.mjs": "./lib/trigger-ledger.mjs",
|
|
88
|
+
"./lib/*.mjs": {
|
|
89
|
+
"types": "./dist/lib/*.d.ts",
|
|
90
|
+
"default": "./dist/lib/*.js"
|
|
91
|
+
},
|
|
92
|
+
"./*": "./*"
|
|
93
|
+
},
|
|
75
94
|
"files": [
|
|
76
95
|
".github",
|
|
77
96
|
"CLAUDE.md",
|
|
@@ -93,6 +112,19 @@
|
|
|
93
112
|
"skills",
|
|
94
113
|
"src",
|
|
95
114
|
"templates",
|
|
96
|
-
"tsconfig.json"
|
|
97
|
-
|
|
115
|
+
"tsconfig.json",
|
|
116
|
+
"tsconfig.pkg.json"
|
|
117
|
+
],
|
|
118
|
+
"imports": {
|
|
119
|
+
"#lib/*": {
|
|
120
|
+
"paperlint-source": "./lib/*.ts",
|
|
121
|
+
"types": "./dist/lib/*.d.ts",
|
|
122
|
+
"default": "./dist/lib/*.js"
|
|
123
|
+
},
|
|
124
|
+
"#eslint-rules/*": {
|
|
125
|
+
"paperlint-source": "./eslint-rules/*.ts",
|
|
126
|
+
"types": "./dist/eslint-rules/*.d.ts",
|
|
127
|
+
"default": "./dist/eslint-rules/*.js"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
98
130
|
}
|