paperlint 3.2.0 → 4.1.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 +16 -23
- package/CLAUDE.md +33 -13
- package/CONTRIBUTING.md +23 -7
- package/README.md +11 -8
- package/dist/adapters/banal/failure.d.ts +1 -7
- package/dist/adapters/banal/failure.d.ts.map +1 -1
- package/dist/adapters/banal/failure.js +5 -7
- package/dist/adapters/banal/failure.js.map +1 -1
- package/dist/adapters/banal/index.d.ts.map +1 -1
- package/dist/adapters/banal/index.js +8 -11
- package/dist/adapters/banal/index.js.map +1 -1
- package/dist/adapters/banal/install.d.ts.map +1 -1
- package/dist/adapters/banal/install.js +4 -3
- package/dist/adapters/banal/install.js.map +1 -1
- package/dist/adapters/banal/invocation.d.ts +10 -5
- package/dist/adapters/banal/invocation.d.ts.map +1 -1
- package/dist/adapters/banal/invocation.js +13 -1
- package/dist/adapters/banal/invocation.js.map +1 -1
- package/dist/adapters/banal/locate.d.ts +12 -9
- package/dist/adapters/banal/locate.d.ts.map +1 -1
- package/dist/adapters/banal/locate.js +19 -12
- package/dist/adapters/banal/locate.js.map +1 -1
- package/dist/adapters/banal/run.d.ts +10 -1
- package/dist/adapters/banal/run.d.ts.map +1 -1
- package/dist/adapters/banal/run.js +8 -4
- package/dist/adapters/banal/run.js.map +1 -1
- package/dist/adapters/banal/settings.d.ts +1 -1
- package/dist/adapters/banal/settings.d.ts.map +1 -1
- package/dist/adapters/banal/settings.js +2 -1
- package/dist/adapters/banal/settings.js.map +1 -1
- package/dist/adapters/latex/document-class.d.ts +22 -0
- package/dist/adapters/latex/document-class.d.ts.map +1 -0
- package/dist/adapters/latex/document-class.js +102 -0
- package/dist/adapters/latex/document-class.js.map +1 -0
- package/dist/adapters/latex/hidden.d.ts +16 -0
- package/dist/adapters/latex/hidden.d.ts.map +1 -0
- package/dist/adapters/latex/hidden.js +49 -0
- package/dist/adapters/latex/hidden.js.map +1 -0
- package/dist/adapters/latex/index.d.ts +29 -0
- package/dist/adapters/latex/index.d.ts.map +1 -0
- package/dist/adapters/latex/index.js +18 -0
- package/dist/adapters/latex/index.js.map +1 -0
- package/dist/adapters/latex/nodes.d.ts +54 -0
- package/dist/adapters/latex/nodes.d.ts.map +1 -0
- package/dist/adapters/latex/nodes.js +93 -0
- package/dist/adapters/latex/nodes.js.map +1 -0
- package/dist/adapters/latex/outline.d.ts +10 -0
- package/dist/adapters/latex/outline.d.ts.map +1 -0
- package/dist/adapters/latex/outline.js +39 -0
- package/dist/adapters/latex/outline.js.map +1 -0
- package/dist/adapters/latex/parse.d.ts +42 -0
- package/dist/adapters/latex/parse.d.ts.map +1 -0
- package/dist/adapters/latex/parse.js +94 -0
- package/dist/adapters/latex/parse.js.map +1 -0
- package/dist/adapters/latex/rendered.d.ts +10 -0
- package/dist/adapters/latex/rendered.d.ts.map +1 -0
- package/dist/adapters/latex/rendered.js +39 -0
- package/dist/adapters/latex/rendered.js.map +1 -0
- package/dist/adapters/memory/index.d.ts.map +1 -1
- package/dist/adapters/memory/index.js +8 -2
- package/dist/adapters/memory/index.js.map +1 -1
- package/dist/adapters/node/process.io.d.ts +6 -3
- package/dist/adapters/node/process.io.d.ts.map +1 -1
- package/dist/adapters/node/process.io.js.map +1 -1
- package/dist/adapters/node/workspace.io.d.ts.map +1 -1
- package/dist/adapters/node/workspace.io.js +4 -2
- package/dist/adapters/node/workspace.io.js.map +1 -1
- package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
- package/dist/adapters/pdfjs/fill.js +12 -12
- 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 -2
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/build-engine.d.ts +1 -1
- package/dist/build-engine.d.ts.map +1 -1
- package/dist/build-engine.js +8 -1
- package/dist/build-engine.js.map +1 -1
- package/dist/build.d.ts +2 -3
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +9 -10
- package/dist/build.js.map +1 -1
- package/dist/caller-path.d.ts +3 -0
- package/dist/caller-path.d.ts.map +1 -0
- package/dist/caller-path.js +13 -0
- package/dist/caller-path.js.map +1 -0
- package/dist/cli.d.ts +10 -17
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +91 -17
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts +12 -3
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/domain/paths.d.ts +8 -2
- package/dist/domain/paths.d.ts.map +1 -1
- package/dist/domain/paths.js +12 -1
- package/dist/domain/paths.js.map +1 -1
- package/dist/domain/ready.d.ts +24 -0
- package/dist/domain/ready.d.ts.map +1 -0
- package/dist/domain/ready.js +11 -0
- package/dist/domain/ready.js.map +1 -0
- package/dist/domain/record.d.ts +8 -0
- package/dist/domain/record.d.ts.map +1 -0
- package/dist/domain/record.js +8 -0
- package/dist/domain/record.js.map +1 -0
- package/dist/domain/sha256.d.ts.map +1 -1
- package/dist/domain/sha256.js +4 -2
- package/dist/domain/sha256.js.map +1 -1
- package/dist/domain/tex-document.d.ts +84 -0
- package/dist/domain/tex-document.d.ts.map +1 -0
- package/dist/domain/tex-document.js +43 -0
- package/dist/domain/tex-document.js.map +1 -0
- package/dist/engine.d.ts +23 -22
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js.map +1 -1
- package/dist/eslint-rules/bib-reachable-entry.d.ts +1 -1
- package/dist/eslint-rules/bib-reachable-entry.js.map +1 -1
- package/dist/eslint-rules/install-path-literals.d.ts +2 -2
- package/dist/eslint-rules/install-path-literals.js.map +1 -1
- package/dist/eslint-rules/paper-research-question.d.ts +1 -1
- package/dist/eslint-rules/paper-research-question.js.map +1 -1
- package/dist/eslint-rules/paper-stages.d.ts +2 -2
- package/dist/eslint-rules/paper-stages.js.map +1 -1
- package/dist/eslint-rules/paper-typography.d.ts +6 -6
- package/dist/eslint-rules/paper-typography.js.map +1 -1
- package/dist/eslint-rules/pdf-last-page-balance.d.ts +1 -1
- package/dist/eslint-rules/pdf-last-page-balance.js.map +1 -1
- package/dist/eslint-rules/review-frontmatter.d.ts +2 -2
- package/dist/eslint-rules/review-frontmatter.js.map +1 -1
- package/dist/eslint-rules/sibling-frontmatter.d.ts +1 -1
- package/dist/eslint-rules/sibling-frontmatter.d.ts.map +1 -1
- package/dist/eslint-rules/temp-root-realpath.d.ts +1 -1
- package/dist/eslint-rules/temp-root-realpath.js.map +1 -1
- package/dist/eslint-rules/tex-build.d.ts +2 -2
- package/dist/eslint-rules/tex-build.js.map +1 -1
- package/dist/facts-file.d.ts.map +1 -1
- package/dist/facts-file.js +31 -28
- package/dist/facts-file.js.map +1 -1
- package/dist/hooks-settings.d.ts.map +1 -1
- package/dist/hooks-settings.js +17 -2
- package/dist/hooks-settings.js.map +1 -1
- package/dist/init.d.ts +3 -4
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +18 -8
- package/dist/init.js.map +1 -1
- package/dist/lib/paper-config.d.ts.map +1 -1
- package/dist/lib/paper-config.js +1 -5
- package/dist/lib/paper-config.js.map +1 -1
- package/dist/new-paper.d.ts +5 -0
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +8 -1
- package/dist/new-paper.js.map +1 -1
- package/dist/package-dirs.d.ts +5 -0
- package/dist/package-dirs.d.ts.map +1 -0
- package/dist/package-dirs.js +14 -0
- package/dist/package-dirs.js.map +1 -0
- package/dist/paper-files.d.ts +4 -4
- package/dist/paper-files.d.ts.map +1 -1
- package/dist/paper-files.js +6 -6
- package/dist/paper-files.js.map +1 -1
- package/dist/paper-settings.js +3 -3
- package/dist/paper-settings.js.map +1 -1
- package/dist/pdf-facts.d.ts +51 -1
- package/dist/pdf-facts.d.ts.map +1 -1
- package/dist/pdf-facts.js +23 -15
- package/dist/pdf-facts.js.map +1 -1
- package/dist/pdf-geometry.d.ts.map +1 -1
- package/dist/pdf-geometry.js +2 -3
- package/dist/pdf-geometry.js.map +1 -1
- package/dist/ports/latex.d.ts +24 -0
- package/dist/ports/latex.d.ts.map +1 -0
- package/dist/ports/latex.js +2 -0
- package/dist/ports/latex.js.map +1 -0
- package/dist/ports/tool-installer.d.ts +2 -14
- package/dist/ports/tool-installer.d.ts.map +1 -1
- package/dist/presets.d.ts +15 -2
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +35 -10
- package/dist/presets.js.map +1 -1
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +4 -4
- package/dist/references.js.map +1 -1
- package/dist/rules-config.d.ts +26 -1
- package/dist/rules-config.d.ts.map +1 -1
- package/dist/rules-config.js +9 -9
- package/dist/rules-config.js.map +1 -1
- package/dist/tex-requirements.d.ts +15 -0
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +28 -10
- package/dist/tex-requirements.js.map +1 -1
- package/dist/tex-venue-rules.d.ts +83 -0
- package/dist/tex-venue-rules.d.ts.map +1 -0
- package/dist/tex-venue-rules.js +254 -0
- package/dist/tex-venue-rules.js.map +1 -0
- package/dist/types.d.ts +5 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/venue-rules.d.ts +1 -1
- package/dist/venue-rules.d.ts.map +1 -1
- package/dist/venue-rules.js +20 -7
- package/dist/venue-rules.js.map +1 -1
- package/docs/configuration.md +5 -4
- package/docs/e2e.md +69 -40
- 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 +21 -10
- package/docs/rules/tex/required-section.md +73 -0
- package/docs/rules/tex/template.md +62 -0
- package/docs/rules/tex/venue-leftover.md +71 -0
- package/docs/rules.md +70 -48
- package/docs/testing.md +17 -4
- package/docs/texlive-install-decision.md +1 -1
- package/docs/toolchain.md +2 -2
- package/eslint-rules/bib-reachable-entry.ts +1 -1
- package/eslint-rules/install-path-literals.ts +2 -2
- package/eslint-rules/paper-research-question.ts +1 -1
- package/eslint-rules/paper-stages.ts +2 -2
- package/eslint-rules/paper-typography.ts +2 -2
- package/eslint-rules/pdf-last-page-balance.ts +1 -1
- package/eslint-rules/review-frontmatter.ts +1 -1
- package/eslint-rules/temp-root-realpath.ts +1 -1
- package/eslint-rules/tex-build.ts +2 -2
- package/eslint.config.mjs +162 -15
- package/fixtures/build-e2e/acmart/expect.json +26 -0
- package/fixtures/build-e2e/aidc/PIPELINE-STATUS.md +3 -0
- package/fixtures/build-e2e/aidc/expect.json +14 -0
- package/fixtures/build-e2e/aidc/paper.tex +46 -0
- package/fixtures/build-e2e/aidc/paperlint.json +1 -0
- package/fixtures/build-e2e/broken/expect.json +11 -0
- package/fixtures/build-e2e/cite/expect.json +27 -0
- package/fixtures/build-e2e/empty/expect.json +12 -0
- package/fixtures/build-e2e/fallback/expect.json +53 -0
- package/fixtures/build-e2e/guards/expect.json +6 -0
- package/fixtures/build-e2e/no-source/expect.json +10 -0
- package/fixtures/build-e2e/unbalanced/expect.json +60 -0
- package/fixtures/install-path-literals/clean.fixture.mjs +1 -1
- package/fixtures/install-path-literals/clean.md +2 -2
- package/fixtures/install-path-literals/defect.fixture.mjs +1 -1
- package/fixtures/install-path-literals/defect.md +2 -2
- package/fixtures/pdf-facts/README.md +1 -1
- package/fixtures/real-markdown-paper/baseline.ts +1 -1
- package/fixtures/render-paper/build-clean.sh +3 -5
- package/hooks/paper-status-gates.sh +9 -19
- package/lib/paper-config.harness.mjs +1 -1
- package/lib/paper-config.ts +1 -5
- package/lib/skill-checks.mjs +24 -381
- package/lib/skill-checks.test.mjs +63 -115
- package/lib/skill-corpus.mjs +10 -251
- package/lib/skill-corpus.test.mjs +2 -13
- package/lib/skill-trigger-cases.mjs +1 -1
- package/package.json +13 -2
- package/{skills/submit-paper/references/venues → presets}/acm-sigconf.jsonc +4 -1
- package/{skills/submit-paper/references/venues → presets}/agenticdev.jsonc +4 -0
- package/presets/aidc.jsonc +73 -0
- package/{skills/submit-paper/references/venues → presets}/aisec.jsonc +4 -0
- package/presets/ieee-conference.jsonc +66 -0
- package/{skills/submit-paper/references/venues → presets}/realm.jsonc +8 -1
- package/{skills/submit-paper/references/venues → presets/tex}/paper-guards.tex +1 -1
- package/{skills/submit-paper/references/venues → presets}/venue-profile.schema.json +30 -2
- package/scripts/check.harness.ts +64 -10
- package/scripts/check.test.ts +60 -13
- package/scripts/check.ts +83 -30
- package/scripts/coverage-config.test.ts +0 -1
- package/scripts/harness-api.frozen.json +0 -1
- package/scripts/test.test.ts +1 -1
- package/scripts/test.ts +1 -1
- package/skills/analyze-sibling-paper/SKILL.md +1 -39
- package/skills/analyze-sibling-paper/SKILL.md.spec.ts +0 -38
- package/skills/argument-arc/SKILL.md +2 -36
- package/skills/argument-arc/SKILL.md.spec.ts +1 -43
- package/skills/build-benchmark/SKILL.md +1 -41
- package/skills/build-benchmark/SKILL.md.spec.ts +0 -40
- package/skills/camera-ready/SKILL.md +1 -34
- package/skills/camera-ready/SKILL.md.spec.ts +0 -33
- package/skills/cold-read-diff/SKILL.md +1 -35
- package/skills/cold-read-diff/SKILL.md.spec.ts +0 -34
- package/skills/draft-paper/SKILL.md +2 -41
- package/skills/draft-paper/SKILL.md.spec.ts +1 -50
- package/skills/extend-paper/SKILL.md +2 -33
- package/skills/extend-paper/SKILL.md.spec.ts +1 -42
- package/skills/find-venue/SKILL.md +2 -38
- package/skills/find-venue/SKILL.md.spec.ts +1 -47
- package/skills/grade-paper-writing/SKILL.md +3 -38
- package/skills/grade-paper-writing/SKILL.md.spec.ts +2 -47
- package/skills/grade-paper-writing/prose-lint.mjs +2 -3
- package/skills/grade-paper-writing/prose-lint.test.ts +1 -1
- package/skills/harden-paper/SKILL.md +1 -39
- package/skills/harden-paper/SKILL.md.spec.ts +0 -38
- package/skills/map-prior-work/SKILL.md +1 -35
- package/skills/map-prior-work/SKILL.md.spec.ts +0 -34
- package/skills/osf-artifact-upload/osf-artifact-upload.harness.ts +3 -4
- package/skills/paper-adversarial-review/SKILL.md +2 -35
- package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -43
- package/skills/paper-pipeline/PIPELINE-MAP.md +2 -2
- package/skills/paper-pipeline/SKILL.md +3 -29
- package/skills/paper-pipeline/SKILL.md.spec.ts +2 -28
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +1 -1
- package/skills/paper-pipeline/paper-pipeline.harness.mjs +25 -40
- package/skills/paper-pipeline/references/acceptance-gate.md +1 -6
- package/skills/paper-pipeline/references/pipeline-status-template.md +8 -35
- package/skills/paper-pipeline/scripts/README.md +30 -225
- package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +4 -8
- package/skills/paper-pipeline/scripts/consumer.d.mts +0 -2
- package/skills/paper-pipeline/scripts/consumer.harness.mjs +6 -104
- package/skills/paper-pipeline/scripts/consumer.mjs +24 -119
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +2 -3
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +3 -3
- package/skills/paper-status/SKILL.md +2 -42
- package/skills/paper-status/SKILL.md.spec.ts +1 -41
- package/skills/pc-panel-review/SKILL.md +2 -46
- package/skills/pc-panel-review/SKILL.md.spec.ts +1 -45
- package/skills/plan-paper-timeline/SKILL.md +2 -36
- package/skills/plan-paper-timeline/SKILL.md.spec.ts +0 -36
- package/skills/render-paper/SKILL.md +2 -38
- package/skills/render-paper/SKILL.md.spec.ts +1 -37
- package/skills/render-paper/check-render.sh +16 -63
- package/skills/render-paper/render-paper.harness.mjs +17 -59
- package/skills/research-ideate/SKILL.md +2 -39
- package/skills/research-ideate/SKILL.md.spec.ts +1 -47
- package/skills/study-accepted-papers/SKILL.md +1 -34
- package/skills/study-accepted-papers/SKILL.md.spec.ts +0 -33
- package/skills/submit-paper/SKILL.md +1 -33
- package/skills/submit-paper/SKILL.md.spec.ts +0 -32
- package/skills/sweep-design-space/SKILL.md +1 -38
- package/skills/sweep-design-space/SKILL.md.spec.ts +0 -37
- package/skills/tighten-paper/SKILL.md +2 -39
- package/skills/tighten-paper/SKILL.md.spec.ts +1 -47
- package/skills/tighten-paper/structure.mjs +4 -11
- package/skills/verify-citations/SKILL.md +2 -38
- package/skills/verify-citations/SKILL.md.spec.ts +1 -37
- package/src/adapters/banal/failure.ts +9 -10
- package/src/adapters/banal/index.test.ts +3 -3
- package/src/adapters/banal/index.ts +8 -10
- package/src/adapters/banal/install.ts +9 -4
- package/src/adapters/banal/invocation.test.ts +20 -8
- package/src/adapters/banal/invocation.ts +24 -9
- package/src/adapters/banal/locate.test.ts +2 -2
- package/src/adapters/banal/locate.ts +27 -21
- package/src/adapters/banal/output.test.ts +1 -1
- package/src/adapters/banal/run.test.ts +3 -3
- package/src/adapters/banal/run.ts +16 -10
- package/src/adapters/banal/settings.ts +2 -2
- package/src/adapters/banal/xml.test.ts +1 -1
- package/src/adapters/curl/download.test.ts +4 -4
- package/src/adapters/latex/document-class.ts +147 -0
- package/src/adapters/latex/hidden.ts +70 -0
- package/src/adapters/latex/index.test.ts +361 -0
- package/src/adapters/latex/index.ts +55 -0
- package/src/adapters/latex/nodes.ts +141 -0
- package/src/adapters/latex/outline.ts +64 -0
- package/src/adapters/latex/parse.ts +136 -0
- package/src/adapters/latex/rendered.ts +59 -0
- package/src/adapters/memory/index.ts +4 -3
- package/src/adapters/node/files.test.ts +5 -3
- package/src/adapters/node/process.io.ts +9 -2
- package/src/adapters/node/process.test.ts +4 -4
- package/src/adapters/node/workspace.io.ts +9 -4
- package/src/adapters/pdfjs/fill.test.ts +1 -1
- package/src/adapters/pdfjs/fill.ts +18 -10
- package/src/adapters/references/index.ts +7 -2
- package/src/build-engine.test.ts +11 -6
- package/src/build-engine.ts +10 -5
- package/src/build.harness.mjs +5 -7
- package/src/build.test.ts +10 -11
- package/src/build.ts +12 -13
- package/src/caller-path.ts +13 -0
- package/src/cli.harness.mjs +1 -3
- package/src/cli.test.ts +21 -16
- package/src/cli.ts +115 -33
- package/src/doctor.test.ts +1 -1
- package/src/doctor.ts +14 -5
- package/src/domain/paths.test.ts +15 -0
- package/src/domain/paths.ts +20 -1
- package/src/domain/ready.ts +31 -0
- package/src/domain/record.test.ts +20 -0
- package/src/domain/record.ts +12 -0
- package/src/domain/sha256.ts +5 -3
- package/src/domain/tex-document.test.ts +80 -0
- package/src/domain/tex-document.ts +110 -0
- package/src/engine.harness.mjs +1 -1
- package/src/engine.ts +30 -2
- package/src/facts-file.test.ts +4 -7
- package/src/facts-file.ts +45 -30
- package/src/hooks-settings.harness.ts +17 -0
- package/src/hooks-settings.ts +28 -4
- package/src/init.test.ts +25 -5
- package/src/init.ts +26 -12
- package/src/latex-loop.harness.ts +1 -1
- package/src/new-paper.harness.mjs +7 -23
- package/src/new-paper.test.ts +28 -3
- package/src/new-paper.ts +15 -3
- package/src/package-dirs.ts +17 -0
- package/src/paper-files.test.ts +22 -19
- package/src/paper-files.ts +16 -27
- package/src/paper-settings-commands.test.ts +6 -1
- package/src/paper-settings.test.ts +2 -2
- package/src/paper-settings.ts +5 -5
- package/src/pdf-facts.test.ts +16 -5
- package/src/pdf-facts.ts +79 -22
- package/src/pdf-geometry.ts +5 -3
- package/src/ports/latex.ts +29 -0
- package/src/ports/tool-installer.ts +2 -17
- package/src/presets.test.ts +65 -4
- package/src/presets.ts +65 -28
- package/src/references.test.ts +25 -19
- package/src/references.ts +4 -5
- package/src/rule-cases.test.ts +474 -0
- package/src/rule-docs.test.ts +159 -0
- package/src/rules-config.ts +40 -11
- package/src/tex-requirements.harness.ts +13 -23
- package/src/tex-requirements.test.ts +21 -0
- package/src/tex-requirements.ts +64 -14
- package/src/tex-venue-rules.test.ts +659 -0
- package/src/tex-venue-rules.ts +429 -0
- package/src/toolchain.harness.mjs +1 -1
- package/src/toolchain.test.ts +9 -5
- package/src/toolchain.ts +2 -2
- package/src/types.ts +5 -3
- package/src/venue-rules.test.ts +104 -8
- package/src/venue-rules.ts +22 -12
- package/templates/paper/paper.tex +2 -1
- package/skills/paper-pipeline/scripts/announce.mjs +0 -67
- package/skills/paper-pipeline/scripts/announce.test.mjs +0 -102
- package/skills/paper-pipeline/scripts/fixtures/clean/PIPELINE-STATUS.md +0 -51
- package/skills/paper-pipeline/scripts/fixtures/dirty/PIPELINE-STATUS.md +0 -52
- package/skills/paper-pipeline/scripts/fixtures/dirty/paper.md +0 -6
- package/skills/paper-pipeline/scripts/fixtures/scorecard.ts +0 -100
- package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +0 -302
- package/skills/paper-pipeline/scripts/ledger.mjs +0 -623
- package/skills/paper-pipeline/scripts/ledger.test.mjs +0 -254
- package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +0 -474
- package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +0 -328
- package/skills/paper-pipeline/scripts/pipeline-check.mjs +0 -750
- package/skills/paper-pipeline/scripts/pipeline-edges.mjs +0 -169
- package/skills/paper-pipeline/scripts/pipeline-edges.test.mjs +0 -73
- package/skills/paper-pipeline/scripts/run-mechanical.mjs +0 -648
- package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +0 -468
- package/skills/paper-pipeline/scripts/status.mjs +0 -295
- package/skills/paper-pipeline/scripts/status.test.mjs +0 -232
- /package/{skills/submit-paper/references/venues → presets/tex}/agenticdev.tex +0 -0
- /package/{skills/submit-paper/references/venues → presets}/tex-base.jsonc +0 -0
package/src/rules-config.ts
CHANGED
|
@@ -39,11 +39,40 @@ export interface RuleBlock {
|
|
|
39
39
|
readonly rules: Readonly<Record<string, RuleEntry>>;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* A plugin as a config block registers it, typed to what paperlint reads of it: its rules, and the
|
|
44
|
+
* languages it brings (`tex` brings LaTeX).
|
|
45
|
+
*/
|
|
46
|
+
export interface ConfigPlugin {
|
|
47
|
+
readonly rules?: Readonly<Record<string, unknown>>;
|
|
48
|
+
readonly languages?: Readonly<Record<string, unknown>>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* An ESLint config block as paperlint builds and reads one. Not `Linter.Config`: ESLint types a
|
|
53
|
+
* plugin's rule as one that runs on ANY language, and paperlint's rules are written for the language
|
|
54
|
+
* they read (LaTeX, markdown), so none of them is assignable to it. ESLint checks a block when it
|
|
55
|
+
* loads it; `eslintConfig` in cli.ts is the one place these blocks become `Linter.Config`.
|
|
56
|
+
*/
|
|
57
|
+
export interface ConfigBlock {
|
|
58
|
+
readonly name?: string;
|
|
59
|
+
readonly basePath?: string;
|
|
60
|
+
readonly files?: readonly (string | readonly string[])[];
|
|
61
|
+
readonly ignores?: readonly string[];
|
|
62
|
+
readonly plugins?: Readonly<Record<string, ConfigPlugin>>;
|
|
63
|
+
readonly language?: string;
|
|
64
|
+
readonly languageOptions?: Readonly<Record<string, unknown>>;
|
|
65
|
+
readonly linterOptions?: Readonly<Record<string, unknown>>;
|
|
66
|
+
readonly rules?: Readonly<Record<string, unknown>>;
|
|
67
|
+
}
|
|
68
|
+
|
|
42
69
|
export type Parsed<T> =
|
|
43
70
|
| { readonly ok: true; readonly value: T }
|
|
44
71
|
| { readonly ok: false; readonly error: string };
|
|
45
72
|
|
|
46
|
-
const SEVERITIES: readonly
|
|
73
|
+
const SEVERITIES: readonly Severity[] = ["off", "warn", "error", 0, 1, 2];
|
|
74
|
+
const isSeverity = (v: unknown): v is Severity =>
|
|
75
|
+
SEVERITIES.some((s) => s === v);
|
|
47
76
|
|
|
48
77
|
const BLOCK_KEYS = new Set(["files", "ignores", "rules"]);
|
|
49
78
|
|
|
@@ -61,9 +90,10 @@ const isStringList = (v: unknown): v is string[] =>
|
|
|
61
90
|
|
|
62
91
|
/** A severity, or `[severity, ...options]`. */
|
|
63
92
|
function parseEntry(v: unknown): RuleEntry | null {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
93
|
+
const entry: readonly unknown[] = Array.isArray(v) ? v : [v];
|
|
94
|
+
const [sev, ...options] = entry;
|
|
95
|
+
if (!isSeverity(sev)) return null;
|
|
96
|
+
return Array.isArray(v) ? [sev, ...options] : sev;
|
|
67
97
|
}
|
|
68
98
|
|
|
69
99
|
/**
|
|
@@ -105,8 +135,8 @@ function badGlobs(o: Record<string, unknown>, at: string): string | null {
|
|
|
105
135
|
|
|
106
136
|
/** The block's `files`/`ignores`, present only when given. */
|
|
107
137
|
const globsOf = (o: Record<string, unknown>) => ({
|
|
108
|
-
...(o["files"] ? { files: o["files"]
|
|
109
|
-
...(o["ignores"] ? { ignores: o["ignores"]
|
|
138
|
+
...(isStringList(o["files"]) ? { files: o["files"] } : {}),
|
|
139
|
+
...(isStringList(o["ignores"]) ? { ignores: o["ignores"] } : {}),
|
|
110
140
|
});
|
|
111
141
|
|
|
112
142
|
const isRecord = (v: unknown): v is Record<string, unknown> =>
|
|
@@ -182,16 +212,15 @@ export function parseRuleBlocks(
|
|
|
182
212
|
* `foreign` (a dependency's plugin, such as `@eslint/markdown`) are not paperlint's and are skipped.
|
|
183
213
|
*/
|
|
184
214
|
export function shippedRuleIds(
|
|
185
|
-
config: readonly
|
|
215
|
+
config: readonly ConfigBlock[],
|
|
186
216
|
foreign: readonly unknown[],
|
|
187
217
|
): Set<string> {
|
|
188
218
|
const ids = new Set<string>();
|
|
189
219
|
for (const block of config) {
|
|
190
|
-
const
|
|
191
|
-
for (const [name, plugin] of Object.entries(plugins ?? {})) {
|
|
220
|
+
for (const [name, plugin] of Object.entries(block.plugins ?? {})) {
|
|
192
221
|
if (foreign.includes(plugin)) continue;
|
|
193
|
-
const
|
|
194
|
-
|
|
222
|
+
for (const rule of Object.keys(plugin.rules ?? {}))
|
|
223
|
+
ids.add(`${name}/${rule}`);
|
|
195
224
|
}
|
|
196
225
|
}
|
|
197
226
|
return ids;
|
|
@@ -16,22 +16,12 @@ import {
|
|
|
16
16
|
writeFileSync,
|
|
17
17
|
} from "node:fs";
|
|
18
18
|
import { tmpdir } from "node:os";
|
|
19
|
-
import {
|
|
20
|
-
import { fileURLToPath } from "node:url";
|
|
21
|
-
import ts from "typescript";
|
|
22
|
-
import { z } from "zod";
|
|
19
|
+
import { join } from "node:path";
|
|
23
20
|
import { createChecker } from "../lib/check.ts";
|
|
24
21
|
|
|
25
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
26
|
-
const VENUES = join(
|
|
27
|
-
HERE,
|
|
28
|
-
"..",
|
|
29
|
-
"skills",
|
|
30
|
-
"submit-paper",
|
|
31
|
-
"references",
|
|
32
|
-
"venues",
|
|
33
|
-
);
|
|
34
22
|
const R = await import("./tex-requirements.ts");
|
|
23
|
+
const { parseTemplate } = await import("./adapters/latex/index.ts");
|
|
24
|
+
const VENUES = (await import("./package-dirs.ts")).presetsDir();
|
|
35
25
|
|
|
36
26
|
const check = createChecker();
|
|
37
27
|
const throws = (fn: () => unknown): string => {
|
|
@@ -70,15 +60,15 @@ check(
|
|
|
70
60
|
"cm-super" in base.packages,
|
|
71
61
|
);
|
|
72
62
|
|
|
73
|
-
// The
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
).template;
|
|
63
|
+
// The class each profile's template names, as the parser reads it — never a line of text.
|
|
64
|
+
const presetOf = (v: string) =>
|
|
65
|
+
R.parsePreset(
|
|
66
|
+
readFileSync(join(VENUES, `${v}.jsonc`), "utf8"),
|
|
67
|
+
`${v}.jsonc`,
|
|
68
|
+
VENUES,
|
|
69
|
+
);
|
|
70
|
+
const templateOf = (v: string): string | undefined =>
|
|
71
|
+
parseTemplate(presetOf(v).template ?? "")?.cls;
|
|
82
72
|
const acm = venues.filter((v) => templateOf(v) === "acmart");
|
|
83
73
|
check(
|
|
84
74
|
"at least one acmart venue is shipped (else the next checks see nothing)",
|
|
@@ -108,7 +98,7 @@ for (const v of acm) {
|
|
|
108
98
|
// declares the template's packages, so this holds by construction; the check stays for any two
|
|
109
99
|
// standalone presets that name the same template.
|
|
110
100
|
const byTemplate = new Map<unknown, string[]>();
|
|
111
|
-
for (const v of venues) {
|
|
101
|
+
for (const v of venues.filter((x) => presetOf(x).extends === null)) {
|
|
112
102
|
const t = templateOf(v);
|
|
113
103
|
byTemplate.set(t, [...(byTemplate.get(t) ?? []), v]);
|
|
114
104
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "vitest";
|
|
3
|
+
import { loadTypescript } from "./tex-requirements.ts";
|
|
4
|
+
|
|
5
|
+
test("loadTypescript refuses a module without the two functions a profile is read with", () => {
|
|
6
|
+
assert.throws(
|
|
7
|
+
() => loadTypescript(() => ({})),
|
|
8
|
+
/loaded without parseConfigFileTextToJson/,
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("loadTypescript hands back what `require` loaded when it has them", () => {
|
|
13
|
+
const ts = {
|
|
14
|
+
parseConfigFileTextToJson: () => ({ config: {} }),
|
|
15
|
+
flattenDiagnosticMessageText: () => "",
|
|
16
|
+
};
|
|
17
|
+
assert.equal(
|
|
18
|
+
loadTypescript(() => ts),
|
|
19
|
+
ts,
|
|
20
|
+
);
|
|
21
|
+
});
|
package/src/tex-requirements.ts
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* `TexRequirements` and never looks at the text again; a malformed profile throws with the path
|
|
17
17
|
* of every violation, it is never read as "no packages".
|
|
18
18
|
*
|
|
19
|
-
* Where the profiles live is answered by `
|
|
20
|
-
* allowed to know where this package is installed (rule 10).
|
|
19
|
+
* Where the profiles live is answered by `presetsDir()` in `package-dirs.ts` — the one module
|
|
20
|
+
* allowed to know where this package's data is installed (rule 10).
|
|
21
21
|
*/
|
|
22
22
|
// eslint-disable-next-line boundaries/dependencies -- legacy I/O, moves behind a port in #76
|
|
23
23
|
import { readFileSync, readdirSync } from "node:fs";
|
|
@@ -25,8 +25,9 @@ import { createRequire } from "node:module";
|
|
|
25
25
|
import { join } from "node:path";
|
|
26
26
|
// eslint-disable-next-line boundaries/dependencies -- legacy layer, moves behind a port in #76
|
|
27
27
|
import Ajv from "ajv";
|
|
28
|
-
import {
|
|
28
|
+
import { presetsDir } from "./package-dirs.ts";
|
|
29
29
|
import { CONFIG_FILE } from "#lib/paper-config";
|
|
30
|
+
import { fieldOf } from "./domain/record.ts";
|
|
30
31
|
|
|
31
32
|
/** CTAN package name → the names that prove it is installed. */
|
|
32
33
|
export type PackageProofs = Readonly<Record<string, readonly string[]>>;
|
|
@@ -51,15 +52,37 @@ const PROFILE_EXT = ".jsonc";
|
|
|
51
52
|
|
|
52
53
|
export const NO_REQUIREMENTS: TexRequirements = { packages: {}, tools: {} };
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
/** The two functions of `typescript` a profile is read with. */
|
|
56
|
+
type TsJsonc = Pick<
|
|
57
|
+
typeof import("typescript"),
|
|
58
|
+
"parseConfigFileTextToJson" | "flattenDiagnosticMessageText"
|
|
59
|
+
>;
|
|
60
|
+
|
|
61
|
+
const isTsJsonc = (m: unknown): m is TsJsonc =>
|
|
62
|
+
typeof fieldOf(m, "parseConfigFileTextToJson") === "function" &&
|
|
63
|
+
typeof fieldOf(m, "flattenDiagnosticMessageText") === "function";
|
|
64
|
+
|
|
65
|
+
/** `typescript` as `load` returns it — `require` answers `any` — checked for the two functions used. */
|
|
66
|
+
export function loadTypescript(load: (id: string) => unknown): TsJsonc {
|
|
67
|
+
const m = load("typescript");
|
|
68
|
+
if (!isTsJsonc(m))
|
|
69
|
+
throw new Error(
|
|
70
|
+
"`typescript` loaded without parseConfigFileTextToJson — reinstall this package",
|
|
71
|
+
);
|
|
72
|
+
return m;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let ts: TsJsonc | null = null;
|
|
56
76
|
/** TypeScript is loaded only when a profile is read: `paperlint lint` never pays for it. */
|
|
57
|
-
function typescript():
|
|
58
|
-
ts ??= createRequire(import.meta.url)
|
|
77
|
+
function typescript(): TsJsonc {
|
|
78
|
+
ts ??= loadTypescript(createRequire(import.meta.url));
|
|
59
79
|
return ts;
|
|
60
80
|
}
|
|
61
81
|
|
|
62
82
|
type Validate = ReturnType<Ajv.Ajv["compile"]>;
|
|
83
|
+
/** `PresetJson` is the TypeScript side of the profile schema: a document the schema accepts is one. */
|
|
84
|
+
const matchesSchema = (v: unknown, validate: Validate): v is PresetJson =>
|
|
85
|
+
validate(v) === true;
|
|
63
86
|
const validators = new Map<string, Validate>();
|
|
64
87
|
function validatorFor(dir: string): Validate {
|
|
65
88
|
const known = validators.get(dir);
|
|
@@ -125,6 +148,13 @@ export const NO_FORMAT: VenueFormat = {
|
|
|
125
148
|
kinds: new Map(),
|
|
126
149
|
};
|
|
127
150
|
|
|
151
|
+
/** A section a venue requires: its exact title, and whether it must close the paper. */
|
|
152
|
+
export interface RequiredSection {
|
|
153
|
+
readonly title: string;
|
|
154
|
+
/** "last": after every section of the body; null: anywhere. */
|
|
155
|
+
readonly position: "last" | null;
|
|
156
|
+
}
|
|
157
|
+
|
|
128
158
|
/**
|
|
129
159
|
* One preset FILE, parsed — before its `extends` chain is resolved (`src/presets.ts` does that).
|
|
130
160
|
* A preset is a venue or a template family: `{ extends?, name?, template?, format?, tex?, rules? }`.
|
|
@@ -134,7 +164,12 @@ export interface PresetFile {
|
|
|
134
164
|
readonly extends: string | null;
|
|
135
165
|
/** A display name for messages; the file name otherwise. */
|
|
136
166
|
readonly name: string | null;
|
|
167
|
+
/** The `\\documentclass` the venue's template uses, as the file spells it; null when it names none. */
|
|
137
168
|
readonly template: string | null;
|
|
169
|
+
/** Other names the venue goes by in a paper's text; empty when the file names none. */
|
|
170
|
+
readonly aliases: readonly string[];
|
|
171
|
+
/** Sections the venue requires; null when the file names none (a child's list replaces its parent's). */
|
|
172
|
+
readonly requiredSections: readonly RequiredSection[] | null;
|
|
138
173
|
/** Null when the file declares no `tex` block (allowed only with `extends`). */
|
|
139
174
|
readonly tex: TexRequirements | null;
|
|
140
175
|
readonly format: VenueFormat;
|
|
@@ -165,6 +200,11 @@ interface PresetJson {
|
|
|
165
200
|
readonly extends?: string;
|
|
166
201
|
readonly name?: string;
|
|
167
202
|
readonly template?: string;
|
|
203
|
+
readonly aliases?: readonly string[];
|
|
204
|
+
readonly required_sections?: readonly {
|
|
205
|
+
readonly title: string;
|
|
206
|
+
readonly position?: "last";
|
|
207
|
+
}[];
|
|
168
208
|
/** The schema requires `packages` in a `tex` block; `tools` is optional. */
|
|
169
209
|
readonly tex?: Pick<TexRequirements, "packages"> &
|
|
170
210
|
Partial<Pick<TexRequirements, "tools">>;
|
|
@@ -202,6 +242,14 @@ function formatOf(j: FormatJson = {}): VenueFormat {
|
|
|
202
242
|
};
|
|
203
243
|
}
|
|
204
244
|
|
|
245
|
+
/** A preset's `required_sections`, or null when it names none. */
|
|
246
|
+
const sectionsOf = (
|
|
247
|
+
r: PresetJson["required_sections"],
|
|
248
|
+
): readonly RequiredSection[] | null =>
|
|
249
|
+
r === undefined
|
|
250
|
+
? null
|
|
251
|
+
: r.map((x) => ({ title: x.title, position: orNull(x.position) }));
|
|
252
|
+
|
|
205
253
|
/**
|
|
206
254
|
* The text of one preset file → the typed file, or an Error naming every problem. The ONE parser
|
|
207
255
|
* of a preset: the toolchain reads its `tex`, the venue rules its `format`, the config its `rules`.
|
|
@@ -213,7 +261,7 @@ function formatOf(j: FormatJson = {}): VenueFormat {
|
|
|
213
261
|
export function parsePreset(
|
|
214
262
|
text: string,
|
|
215
263
|
file: string,
|
|
216
|
-
dir: string =
|
|
264
|
+
dir: string = presetsDir(),
|
|
217
265
|
): PresetFile {
|
|
218
266
|
const parsed = typescript().parseConfigFileTextToJson(file, text);
|
|
219
267
|
const config: unknown = parsed.config;
|
|
@@ -223,15 +271,17 @@ export function parsePreset(
|
|
|
223
271
|
`${file}: not valid JSONC — ${typescript().flattenDiagnosticMessageText(error.messageText, " ")}`,
|
|
224
272
|
);
|
|
225
273
|
const validate = validatorFor(dir);
|
|
226
|
-
if (!
|
|
274
|
+
if (!matchesSchema(config, validate))
|
|
227
275
|
throw new Error(
|
|
228
276
|
`${file} does not match ${SCHEMA_FILE}:\n ${violations(file, validate).join("\n ")}`,
|
|
229
277
|
);
|
|
230
|
-
const j = config
|
|
278
|
+
const j = config;
|
|
231
279
|
return {
|
|
232
280
|
extends: orNull(j.extends),
|
|
233
281
|
name: orNull(j.name),
|
|
234
282
|
template: orNull(j.template),
|
|
283
|
+
aliases: j.aliases ?? [],
|
|
284
|
+
requiredSections: sectionsOf(j.required_sections),
|
|
235
285
|
tex: j.tex ? { packages: j.tex.packages, tools: j.tex.tools ?? {} } : null,
|
|
236
286
|
format: formatOf(j.format),
|
|
237
287
|
rules: j.rules ?? {},
|
|
@@ -242,7 +292,7 @@ export function parsePreset(
|
|
|
242
292
|
export function parseProfile(
|
|
243
293
|
text: string,
|
|
244
294
|
file: string,
|
|
245
|
-
dir: string =
|
|
295
|
+
dir: string = presetsDir(),
|
|
246
296
|
): TexRequirements {
|
|
247
297
|
return parsePreset(text, file, dir).tex ?? NO_REQUIREMENTS;
|
|
248
298
|
}
|
|
@@ -264,7 +314,7 @@ function readProfile(dir: string, file: string): TexRequirements {
|
|
|
264
314
|
}
|
|
265
315
|
|
|
266
316
|
/** The venues that have a profile — every `.jsonc` in the directory except the base set. */
|
|
267
|
-
export function venueNames(dir: string =
|
|
317
|
+
export function venueNames(dir: string = presetsDir()): string[] {
|
|
268
318
|
return readdirSync(dir)
|
|
269
319
|
.filter((f) => f.endsWith(PROFILE_EXT) && f !== BASE_PROFILE)
|
|
270
320
|
.map((f) => f.slice(0, -PROFILE_EXT.length))
|
|
@@ -302,7 +352,7 @@ export function packageNames(tex: TexRequirements): string[] {
|
|
|
302
352
|
*/
|
|
303
353
|
export function requirementsFor(
|
|
304
354
|
preset: { readonly label: string; readonly tex: TexRequirements } | null,
|
|
305
|
-
dir: string =
|
|
355
|
+
dir: string = presetsDir(),
|
|
306
356
|
): PaperRequirements {
|
|
307
357
|
const base = readProfile(dir, BASE_PROFILE);
|
|
308
358
|
return preset === null
|
|
@@ -322,7 +372,7 @@ export function requirementsFor(
|
|
|
322
372
|
* builds any paper.
|
|
323
373
|
*/
|
|
324
374
|
export function declaredUnion(
|
|
325
|
-
dir: string =
|
|
375
|
+
dir: string = presetsDir(),
|
|
326
376
|
extra: readonly TexRequirements[] = [],
|
|
327
377
|
): {
|
|
328
378
|
readonly tex: TexRequirements;
|