paperlint 3.1.3 → 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/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
|
@@ -35,29 +35,15 @@ import { sleep, todayUtc } from "./clock.io.ts";
|
|
|
35
35
|
|
|
36
36
|
/** Citations looked up at once (#107). */
|
|
37
37
|
const LOOKUPS_IN_FLIGHT = 6;
|
|
38
|
-
// @ts-expect-error — a skill script in .mjs, it has no types
|
|
39
38
|
import * as cites from "../../../skills/verify-citations/scripts/verify-cites.mjs";
|
|
40
|
-
|
|
39
|
+
import type { CiteVerdict } from "../../../skills/verify-citations/scripts/verify-cites.mjs";
|
|
41
40
|
import * as authors from "../../../skills/verify-citations/scripts/bib-authors.mjs";
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
readonly refused?: readonly string[];
|
|
49
|
-
}
|
|
50
|
-
interface AuthorFinding {
|
|
51
|
-
readonly key: string;
|
|
52
|
-
readonly venue: string;
|
|
53
|
-
readonly missing: readonly string[];
|
|
54
|
-
readonly extra: readonly string[];
|
|
55
|
-
readonly orderDiffers: boolean;
|
|
56
|
-
}
|
|
57
|
-
interface KeyWhy {
|
|
58
|
-
readonly key: string;
|
|
59
|
-
readonly why: string;
|
|
60
|
-
}
|
|
41
|
+
import type {
|
|
42
|
+
AuthorBuckets,
|
|
43
|
+
AuthorFinding,
|
|
44
|
+
BibEntry,
|
|
45
|
+
} from "../../../skills/verify-citations/scripts/bib-authors.mjs";
|
|
46
|
+
import { messageOf } from "../../domain/text.ts";
|
|
61
47
|
|
|
62
48
|
const describeAuthors = (f: AuthorFinding): string =>
|
|
63
49
|
[
|
|
@@ -68,13 +54,6 @@ const describeAuthors = (f: AuthorFinding): string =>
|
|
|
68
54
|
.filter(Boolean)
|
|
69
55
|
.join("; ") + ` (DBLP: ${f.venue})`;
|
|
70
56
|
|
|
71
|
-
interface AuthorBuckets {
|
|
72
|
-
readonly findings: readonly AuthorFinding[];
|
|
73
|
-
readonly skipped: readonly KeyWhy[];
|
|
74
|
-
readonly unchecked: readonly KeyWhy[];
|
|
75
|
-
readonly matched: readonly string[];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
57
|
const authorsOf = (key: string, a: AuthorBuckets): EntryVerdict["authors"] =>
|
|
79
58
|
a.findings.some((f) => f.key === key)
|
|
80
59
|
? "mismatch"
|
|
@@ -90,7 +69,7 @@ const authorsOf = (key: string, a: AuthorBuckets): EntryVerdict["authors"] =>
|
|
|
90
69
|
* confirmed work: a refusal after a confirmation changed nothing.
|
|
91
70
|
*/
|
|
92
71
|
const unconfirmed = (
|
|
93
|
-
c:
|
|
72
|
+
c: CiteVerdict | undefined,
|
|
94
73
|
): readonly (string | undefined)[] =>
|
|
95
74
|
c && c.verdict !== "true"
|
|
96
75
|
? [c.reason, ...(c.refused ?? []).map((r) => `not asked: ${r}`)]
|
|
@@ -99,7 +78,7 @@ const unconfirmed = (
|
|
|
99
78
|
/** One entry's verdict from the two checkers' answers. */
|
|
100
79
|
function entryVerdict(
|
|
101
80
|
key: string,
|
|
102
|
-
found: readonly
|
|
81
|
+
found: readonly CiteVerdict[],
|
|
103
82
|
a: AuthorBuckets,
|
|
104
83
|
): EntryVerdict {
|
|
105
84
|
const c = found.find((x) => x.id === key);
|
|
@@ -119,27 +98,21 @@ function entryVerdict(
|
|
|
119
98
|
};
|
|
120
99
|
}
|
|
121
100
|
|
|
122
|
-
interface BibAuthorsEntry {
|
|
123
|
-
readonly key: string;
|
|
124
|
-
readonly title: string;
|
|
125
|
-
readonly author: string;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
101
|
/** Whether bib-authors will ask DBLP about this entry — the filter its `checkAuthors` applies. */
|
|
129
|
-
const asksDblp = (e:
|
|
102
|
+
const asksDblp = (e: BibEntry): boolean =>
|
|
130
103
|
Boolean(e.title && e.author) &&
|
|
131
|
-
|
|
132
|
-
!
|
|
104
|
+
authors.claimsPublished(e) &&
|
|
105
|
+
!authors.truncated(e.author);
|
|
133
106
|
|
|
134
107
|
/** Is every question this bibliography would ask already answered in `cache`? */
|
|
135
108
|
async function fullyCached(
|
|
136
|
-
citations: readonly
|
|
137
|
-
entries: readonly
|
|
109
|
+
citations: readonly cites.Citation[],
|
|
110
|
+
entries: readonly BibEntry[],
|
|
138
111
|
cache: LookupCache,
|
|
139
112
|
store: Readonly<Record<string, unknown>>,
|
|
140
113
|
): Promise<boolean> {
|
|
141
114
|
const asks = await Promise.all(
|
|
142
|
-
citations.map((c) => cites.wouldAsk(c, store)
|
|
115
|
+
citations.map((c) => cites.wouldAsk(c, store)),
|
|
143
116
|
);
|
|
144
117
|
return (
|
|
145
118
|
!asks.includes(true) &&
|
|
@@ -185,11 +158,11 @@ function cachedDblp(cache: LookupCache, today: () => string) {
|
|
|
185
158
|
if (refused !== null)
|
|
186
159
|
throw new Error(`DBLP refused earlier in this run (${refused})`);
|
|
187
160
|
try {
|
|
188
|
-
const hits =
|
|
161
|
+
const hits = await authors.dblpHits(title);
|
|
189
162
|
dblp.set(dblpTitleKey(title), { fetched: today(), title, hits });
|
|
190
163
|
return hits;
|
|
191
164
|
} catch (e) {
|
|
192
|
-
refused = (e
|
|
165
|
+
refused = messageOf(e);
|
|
193
166
|
throw new Error(`DBLP refused earlier in this run (${refused})`);
|
|
194
167
|
}
|
|
195
168
|
},
|
|
@@ -234,10 +207,8 @@ export const referencesChecker =
|
|
|
234
207
|
async (bib, cache) => {
|
|
235
208
|
// Answers past MAX_AGE_DAYS are left out, so the run asks them again (and `grown` re-dates them).
|
|
236
209
|
const usable = freshPart(cache, today());
|
|
237
|
-
const citations =
|
|
238
|
-
|
|
239
|
-
);
|
|
240
|
-
const parsed = authors.parseBib(bib) as BibAuthorsEntry[];
|
|
210
|
+
const citations = cites.parseBib(bib);
|
|
211
|
+
const parsed = authors.parseBib(bib);
|
|
241
212
|
const store: Record<string, unknown> = Object.fromEntries(
|
|
242
213
|
[...usable.citations].map(([k, v]) => [k, v.response]),
|
|
243
214
|
);
|
|
@@ -252,22 +223,19 @@ export const referencesChecker =
|
|
|
252
223
|
// answer.
|
|
253
224
|
// One breaker for the run: a service that refuses is not asked again, not once per citation
|
|
254
225
|
// (#120). Requests already in flight when it starts refusing still land — at most six.
|
|
255
|
-
const breaker = cites.createBreaker()
|
|
226
|
+
const breaker = cites.createBreaker();
|
|
256
227
|
const d = cachedDblp(usable, today);
|
|
257
228
|
const [found, a] = await Promise.all([
|
|
258
|
-
mapLimit(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
cache: store,
|
|
264
|
-
breaker,
|
|
265
|
-
}) as Promise<CiteResult>,
|
|
229
|
+
mapLimit(citations, LOOKUPS_IN_FLIGHT, (c) =>
|
|
230
|
+
cites.verifyCitationLive(c, {
|
|
231
|
+
cache: store,
|
|
232
|
+
breaker,
|
|
233
|
+
}),
|
|
266
234
|
),
|
|
267
235
|
authors.checkAuthors(parsed, {
|
|
268
236
|
lookup: d.lookup,
|
|
269
237
|
pause: d.pause,
|
|
270
|
-
})
|
|
238
|
+
}),
|
|
271
239
|
]);
|
|
272
240
|
const keys = new Set([
|
|
273
241
|
...found.map((c) => c.id),
|
|
@@ -10,12 +10,10 @@ export async function mapLimit<T, R>(
|
|
|
10
10
|
fn: (item: T) => Promise<R>,
|
|
11
11
|
): Promise<R[]> {
|
|
12
12
|
const out: R[] = new Array<R>(items.length);
|
|
13
|
-
|
|
13
|
+
// ONE iterator shared by every worker: each `next()` hands out the next index exactly once.
|
|
14
|
+
const queue = items.entries();
|
|
14
15
|
const worker = async (): Promise<void> => {
|
|
15
|
-
|
|
16
|
-
const i = next++;
|
|
17
|
-
out[i] = await fn(items[i] as T);
|
|
18
|
-
}
|
|
16
|
+
for (const [i, item] of queue) out[i] = await fn(item);
|
|
19
17
|
};
|
|
20
18
|
await Promise.all(
|
|
21
19
|
Array.from({ length: Math.min(limit, items.length) }, worker),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { messageOf } from "../../domain/text.ts";
|
|
1
2
|
/** Whether the citation services answer at all — the one request that decides "not checked". */
|
|
2
3
|
export async function unreachable(): Promise<string | null> {
|
|
3
4
|
try {
|
|
@@ -7,6 +8,6 @@ export async function unreachable(): Promise<string | null> {
|
|
|
7
8
|
});
|
|
8
9
|
return null;
|
|
9
10
|
} catch (e) {
|
|
10
|
-
return `the citation services cannot be reached (${(e
|
|
11
|
+
return `the citation services cannot be reached (${messageOf(e)})`;
|
|
11
12
|
}
|
|
12
13
|
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import { basename, delimiter, dirname, join } from "node:path";
|
|
21
21
|
import { fileURLToPath } from "node:url";
|
|
22
|
-
import { createChecker } from "../lib/check.
|
|
22
|
+
import { createChecker } from "../lib/check.ts";
|
|
23
23
|
|
|
24
24
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
25
25
|
const E = await import(join(HERE, "build-engine.ts"));
|
package/src/build-engine.test.ts
CHANGED
|
@@ -7,7 +7,7 @@ import assert from "node:assert/strict";
|
|
|
7
7
|
import { chmodSync, mkdirSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
9
9
|
import { test } from "vitest";
|
|
10
|
-
import { useTempDir } from "../test/support.
|
|
10
|
+
import { useTempDir } from "../test/support.ts";
|
|
11
11
|
import { prepareEngine, refusal } from "./build-engine.ts";
|
|
12
12
|
|
|
13
13
|
const work = useTempDir("paperlint-build-engine-test-");
|
|
@@ -34,7 +34,7 @@ async function go(o: Parameters<typeof prepareEngine>[0]) {
|
|
|
34
34
|
err: (l) => err.push(l),
|
|
35
35
|
platform: "linux",
|
|
36
36
|
interactive: true,
|
|
37
|
-
ask:
|
|
37
|
+
ask: () => Promise.resolve("y"),
|
|
38
38
|
...o,
|
|
39
39
|
});
|
|
40
40
|
return { r, out, err };
|
package/src/build-engine.ts
CHANGED
|
@@ -71,7 +71,7 @@ function withDefaults(o: EngineOptions): Resolved {
|
|
|
71
71
|
const r = {
|
|
72
72
|
dryRun: false,
|
|
73
73
|
interactive: false,
|
|
74
|
-
ask:
|
|
74
|
+
ask: () => Promise.resolve(""),
|
|
75
75
|
log: console.log,
|
|
76
76
|
err: console.error,
|
|
77
77
|
// eslint-disable-next-line no-restricted-globals -- legacy I/O, moves behind a port in #76
|
|
@@ -130,7 +130,7 @@ export function gatherFacts(o: Resolved): EngineFacts {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
const names = (missing: readonly string[]): string =>
|
|
133
|
-
`${missing.length} package(s): ${missing.join(", ")}`;
|
|
133
|
+
`${String(missing.length)} package(s): ${missing.join(", ")}`;
|
|
134
134
|
|
|
135
135
|
/** The one line a run without a human gets. It names the command and what is missing. */
|
|
136
136
|
export function refusal(d: EngineDecision, facts: EngineFacts): string {
|
package/src/build.harness.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* The process runner is replaced by a fake that writes what pdflatex and bibtex would write, so
|
|
5
5
|
* these assertions check the SHELL's decisions: what is run, with which environment, in which
|
|
6
6
|
* order, and what is left on disk. Whether a real pdflatex produces a real PDF is the other half,
|
|
7
|
-
* `test/e2e/build.
|
|
7
|
+
* `test/e2e/build.ts`.
|
|
8
8
|
*
|
|
9
9
|
* 🔴 THE TWO THINGS PINNED DOWN HERE THAT A RETURNED OBJECT CANNOT SHOW: a paper-supplied
|
|
10
10
|
* `build.sh` is never executed (checked by the trace it would leave on disk and by the list of
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
import { join, dirname, delimiter } from "node:path";
|
|
24
24
|
import { fileURLToPath } from "node:url";
|
|
25
|
-
import { createChecker } from "../lib/check.
|
|
25
|
+
import { createChecker } from "../lib/check.ts";
|
|
26
26
|
|
|
27
27
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
28
28
|
const {
|
package/src/build.test.ts
CHANGED
|
@@ -8,7 +8,7 @@ import assert from "node:assert/strict";
|
|
|
8
8
|
import { existsSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { test } from "vitest";
|
|
11
|
-
import { useTempDir, writeTree } from "../test/support.
|
|
11
|
+
import { useTempDir, writeTree } from "../test/support.ts";
|
|
12
12
|
import {
|
|
13
13
|
bibInput,
|
|
14
14
|
buildPaper,
|
|
@@ -62,7 +62,7 @@ function bibtexRun(f: Fake, cwd: string) {
|
|
|
62
62
|
? { status: f.bibtex }
|
|
63
63
|
: { status: f.bibtex, stdout: f.bibtexOut };
|
|
64
64
|
}
|
|
65
|
-
function fakeRun(f: Fake): BuildOptions["run"] {
|
|
65
|
+
function fakeRun(f: Fake): NonNullable<BuildOptions["run"]> {
|
|
66
66
|
let pass = 0;
|
|
67
67
|
return ((bin: string, _args: string[], opts: { cwd: string }) => {
|
|
68
68
|
if (bin === f.missing)
|
|
@@ -103,18 +103,19 @@ const page = (words: number, numbered = 0) => ({
|
|
|
103
103
|
});
|
|
104
104
|
const reader =
|
|
105
105
|
(last = page(80)): PdfReader =>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
() =>
|
|
107
|
+
Promise.resolve({
|
|
108
|
+
ok: true,
|
|
109
|
+
facts: {
|
|
110
|
+
pages: 1,
|
|
111
|
+
fonts: {
|
|
112
|
+
kind: "drawn",
|
|
113
|
+
list: [{ kind: "embedded", name: "CMR10", program: "Type1" }],
|
|
114
|
+
},
|
|
115
|
+
last,
|
|
116
|
+
layout: [],
|
|
113
117
|
},
|
|
114
|
-
|
|
115
|
-
layout: [],
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
+
});
|
|
118
119
|
const quiet = () => {};
|
|
119
120
|
/** buildPaper with fakes; the verdict line is what the command would print for it. */
|
|
120
121
|
async function build(dir: string, f: Fake = {}, over: BuildOptions = {}) {
|
|
@@ -332,7 +333,7 @@ test("paths: a paper that IS the working directory is named by its full path", a
|
|
|
332
333
|
const run = await buildPapers([dir], {
|
|
333
334
|
cwd: dir,
|
|
334
335
|
log: (l) => lines.push(l),
|
|
335
|
-
engine:
|
|
336
|
+
engine: () => Promise.resolve(null),
|
|
336
337
|
});
|
|
337
338
|
assert.deepEqual(
|
|
338
339
|
[run, lines],
|
package/src/build.ts
CHANGED
|
@@ -45,7 +45,7 @@ import { delimiter, join, relative } from "node:path";
|
|
|
45
45
|
// eslint-disable-next-line boundaries/dependencies -- legacy layer, moves behind a port in #76
|
|
46
46
|
import { getParser } from "@unified-latex/unified-latex-util-parse";
|
|
47
47
|
import { packageVenuesDir } from "../skills/paper-pipeline/scripts/consumer.mjs";
|
|
48
|
-
import { CONFIG_FILE } from "
|
|
48
|
+
import { CONFIG_FILE } from "#lib/paper-config";
|
|
49
49
|
import {
|
|
50
50
|
declaredVenue,
|
|
51
51
|
factsPath,
|
|
@@ -83,6 +83,10 @@ import {
|
|
|
83
83
|
type Step,
|
|
84
84
|
} from "./latex-loop.ts";
|
|
85
85
|
import type { BuildResult, PlanLine } from "./types.ts";
|
|
86
|
+
import { messageOf, printed } from "./domain/text.ts";
|
|
87
|
+
|
|
88
|
+
/** stdin closed, stdout and stderr captured — the tuple type spawnSync's `stdio` wants. */
|
|
89
|
+
const PIPED: ["ignore", "pipe", "pipe"] = ["ignore", "pipe", "pipe"];
|
|
86
90
|
|
|
87
91
|
/** A directory counts as a paper by the same markers as `structure.ts` — one shared dictionary. */
|
|
88
92
|
export const PAPER_MARKERS = [
|
|
@@ -337,7 +341,7 @@ function spawnOptions(ctx: BuildContext) {
|
|
|
337
341
|
return {
|
|
338
342
|
cwd: ctx.paperDir,
|
|
339
343
|
env: ctx.env,
|
|
340
|
-
stdio:
|
|
344
|
+
stdio: PIPED,
|
|
341
345
|
encoding: "latin1" as const,
|
|
342
346
|
maxBuffer: 64 * 1024 * 1024,
|
|
343
347
|
};
|
|
@@ -376,19 +380,23 @@ function latexPass(
|
|
|
376
380
|
exitCode === 0
|
|
377
381
|
? []
|
|
378
382
|
: written === null
|
|
379
|
-
?
|
|
383
|
+
? lastPrinted(r)
|
|
380
384
|
: errorExcerpt(log).map(fromLatin1),
|
|
381
385
|
};
|
|
382
386
|
}
|
|
383
387
|
|
|
388
|
+
/** The two streams of a finished run, as they really arrive (see `printed`). */
|
|
389
|
+
interface Streams {
|
|
390
|
+
readonly stdout: string | undefined;
|
|
391
|
+
readonly stderr: string | undefined;
|
|
392
|
+
}
|
|
393
|
+
|
|
384
394
|
/**
|
|
385
395
|
* The last lines pdflatex printed, for the run that wrote no log — it died before opening one (a
|
|
386
396
|
* format it cannot load, a missing TeX Live file). Marked by NO_LOG, which the report keys on.
|
|
387
397
|
*/
|
|
388
|
-
function
|
|
389
|
-
const lines = fromLatin1(
|
|
390
|
-
`${String(r.stdout ?? "")}\n${String(r.stderr ?? "")}`,
|
|
391
|
-
)
|
|
398
|
+
function lastPrinted(r: Streams): string[] {
|
|
399
|
+
const lines = fromLatin1(`${printed(r.stdout)}\n${printed(r.stderr)}`)
|
|
392
400
|
.split("\n")
|
|
393
401
|
.filter((l) => l.trim());
|
|
394
402
|
return [NO_LOG, ...lines.slice(-8).map((l) => ` ${l}`)];
|
|
@@ -410,7 +418,7 @@ function bibtexPass(ctx: BuildContext, opts: SpawnOptions): Observation | null {
|
|
|
410
418
|
after: hashes(ctx.paperDir),
|
|
411
419
|
bib,
|
|
412
420
|
errorLines:
|
|
413
|
-
exitCode === 0 ? [] : bibtexExcerpt(fromLatin1(
|
|
421
|
+
exitCode === 0 ? [] : bibtexExcerpt(fromLatin1(printed(r.stdout))),
|
|
414
422
|
};
|
|
415
423
|
}
|
|
416
424
|
|
|
@@ -443,7 +451,7 @@ export function compile(ctx: BuildContext): {
|
|
|
443
451
|
const NO_PDF = `pdflatex exited 0 but wrote no ${JOB}.pdf — does the document have any pages?`;
|
|
444
452
|
|
|
445
453
|
const plural = (n: number, one: string, many: string): string =>
|
|
446
|
-
`${n} ${n === 1 ? one : many}`;
|
|
454
|
+
`${String(n)} ${n === 1 ? one : many}`;
|
|
447
455
|
|
|
448
456
|
export const compileStep: BuildStep = {
|
|
449
457
|
name: "compile",
|
|
@@ -467,7 +475,7 @@ export const compileStep: BuildStep = {
|
|
|
467
475
|
const bin = end.step === "latex" ? "pdflatex" : "bibtex";
|
|
468
476
|
const where =
|
|
469
477
|
end.cause.kind === "exit"
|
|
470
|
-
? `${bin} exited with ${end.cause.code}`
|
|
478
|
+
? `${bin} exited with ${String(end.cause.code)}`
|
|
471
479
|
: `${bin} did not converge`;
|
|
472
480
|
const log = join(
|
|
473
481
|
ctx.paperDir,
|
|
@@ -669,13 +677,14 @@ function baseDefaults({
|
|
|
669
677
|
}
|
|
670
678
|
|
|
671
679
|
/** Without a checker the record says so — never a pass. The CLI wires the real one. */
|
|
672
|
-
const notWired: CheckReferences =
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
680
|
+
const notWired: CheckReferences = (_bib, cache) =>
|
|
681
|
+
Promise.resolve({
|
|
682
|
+
check: {
|
|
683
|
+
kind: "not-checked",
|
|
684
|
+
why: "no reference checker was wired into this build",
|
|
685
|
+
},
|
|
686
|
+
cache,
|
|
687
|
+
});
|
|
679
688
|
|
|
680
689
|
/** banal as the measurer, wired from the build's environment: the one piece of root work left here (#76). */
|
|
681
690
|
function defaultMeasurer(
|
|
@@ -762,7 +771,7 @@ export async function buildPaper(
|
|
|
762
771
|
dir,
|
|
763
772
|
status: "failed",
|
|
764
773
|
plan: [],
|
|
765
|
-
failure: { step: "facts", lines: [(e
|
|
774
|
+
failure: { step: "facts", lines: [messageOf(e)] },
|
|
766
775
|
};
|
|
767
776
|
}
|
|
768
777
|
for (const s of facts.ignoredScripts)
|
|
@@ -853,7 +862,7 @@ export function formatResult(r: BuildResult): string {
|
|
|
853
862
|
function formatFailure(r: BuildResult): string {
|
|
854
863
|
const [head, ...rest] = r.failure?.lines ?? ["failed"];
|
|
855
864
|
return [
|
|
856
|
-
` ✗ ${r.failure?.step ?? "build"}: ${head}`,
|
|
865
|
+
` ✗ ${r.failure?.step ?? "build"}: ${String(head)}`,
|
|
857
866
|
...rest.map((l) => ` ${l}`),
|
|
858
867
|
` ${PDF_REMOVED}`,
|
|
859
868
|
].join("\n");
|
package/src/cli.harness.mjs
CHANGED
|
@@ -28,8 +28,8 @@ import { spawnSync } from "node:child_process";
|
|
|
28
28
|
import { tmpdir } from "node:os";
|
|
29
29
|
import { join, dirname } from "node:path";
|
|
30
30
|
import { fileURLToPath } from "node:url";
|
|
31
|
-
import { PAPERS_DIR_FIELD, findProjectRoot } from "../lib/paper-config.
|
|
32
|
-
import { createChecker } from "../lib/check.
|
|
31
|
+
import { PAPERS_DIR_FIELD, findProjectRoot } from "../lib/paper-config.ts";
|
|
32
|
+
import { createChecker } from "../lib/check.ts";
|
|
33
33
|
|
|
34
34
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
35
35
|
const { run, parseArgs, buildConfig, nextSteps, toPaths, runHook } =
|
|
@@ -635,7 +635,7 @@ check(
|
|
|
635
635
|
|
|
636
636
|
// ── 7-bis. THE SKILLS: WHAT WAS LINKED, AND WHAT WAS LEFT ALONE, BY NAME ────────────
|
|
637
637
|
//
|
|
638
|
-
// The links themselves are `link-skills.harness.
|
|
638
|
+
// The links themselves are `link-skills.harness.ts`'s subject. Here: init REPORTS them, and
|
|
639
639
|
// a name it refused to take does not turn a working install red. The state is handed in so
|
|
640
640
|
// this block does not depend on a package being installed next to the temp project.
|
|
641
641
|
{
|
|
@@ -967,7 +967,7 @@ check(
|
|
|
967
967
|
|
|
968
968
|
// ── STRUCTURE GETS THROUGH TO THE COMMAND ──────────────────────────────────────────────
|
|
969
969
|
//
|
|
970
|
-
// `structure.mjs` is checked separately and in full (`structure.harness.
|
|
970
|
+
// `structure.mjs` is checked separately and in full (`structure.harness.ts`). Here — exactly
|
|
971
971
|
// one fact that harness cannot know: that the module is WIRED IN. A correct module forgotten in
|
|
972
972
|
// `run()` gives zero findings and looks like a clean corpus.
|
|
973
973
|
{
|
|
@@ -1148,7 +1148,7 @@ check(
|
|
|
1148
1148
|
// pnpm: node_modules/vigiles/dist/cli.js DOES NOT
|
|
1149
1149
|
// The old wiring addressed the runtime from the project root and did not resolve under pnpm,
|
|
1150
1150
|
// and `|| exit 2` on PreToolUse(Bash) turned that into a block on ANY command. The end-to-end
|
|
1151
|
-
// half (both installs, real processes) lives in `test/e2e/install.
|
|
1151
|
+
// half (both installs, real processes) lives in `test/e2e/install.ts`; here — the verdicts.
|
|
1152
1152
|
{
|
|
1153
1153
|
const calls = [];
|
|
1154
1154
|
const fake = (code) => (bin, args, opts) => {
|
|
@@ -1258,7 +1258,7 @@ console.log(
|
|
|
1258
1258
|
|
|
1259
1259
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1260
1260
|
// What is left after init is typed in THE SAME TERMINAL. The two `/plugin` lines are gone: the
|
|
1261
|
-
// hooks are written into `.claude/settings.json` by init itself (hooks-settings.harness.
|
|
1261
|
+
// hooks are written into `.claude/settings.json` by init itself (hooks-settings.harness.ts).
|
|
1262
1262
|
|
|
1263
1263
|
{
|
|
1264
1264
|
const steps = nextSteps("papers");
|
package/src/cli.test.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { spawn } from "node:child_process";
|
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
10
|
import { dirname, join } from "node:path";
|
|
11
11
|
import { test } from "vitest";
|
|
12
|
-
import { runNode, useTempDir, writeTree } from "../test/support.
|
|
12
|
+
import { runNode, useTempDir, writeTree } from "../test/support.ts";
|
|
13
13
|
import {
|
|
14
14
|
chooseVenue,
|
|
15
15
|
initTexLive,
|
|
@@ -169,7 +169,12 @@ test("chooseVenue: a preset by path (inside and outside the paper), by prefixed
|
|
|
169
169
|
const choose = (venue: string) =>
|
|
170
170
|
chooseVenue(
|
|
171
171
|
{ venue, kind: null },
|
|
172
|
-
{
|
|
172
|
+
{
|
|
173
|
+
paperDir,
|
|
174
|
+
cwd: dir,
|
|
175
|
+
interactive: false,
|
|
176
|
+
ask: () => Promise.resolve(""),
|
|
177
|
+
},
|
|
173
178
|
);
|
|
174
179
|
const results = await Promise.all([
|
|
175
180
|
choose("./papers/p/mine.jsonc"),
|
|
@@ -354,11 +359,11 @@ test("a paper's paperlint.json that does not parse stops the lint with its path"
|
|
|
354
359
|
});
|
|
355
360
|
const r = paperRuleBlocks([join(dir, "p")]);
|
|
356
361
|
assert.equal(r.ok, false);
|
|
357
|
-
assert.match(
|
|
362
|
+
assert.match(r.error, /^.*rules-broken\/p\/paperlint\.json: /);
|
|
358
363
|
});
|
|
359
364
|
|
|
360
365
|
test("silentOptionalRules: a config with no rules turns nothing on", async () => {
|
|
361
|
-
assert.deepEqual(await silentOptionalRules({} as never, [], {}
|
|
366
|
+
assert.deepEqual(await silentOptionalRules({} as never, [], {}), []);
|
|
362
367
|
});
|
|
363
368
|
|
|
364
369
|
test("init with no path and --format md sets up the current directory", async () => {
|
|
@@ -493,7 +498,9 @@ function newAtTerminal(cwd: string, answers: Record<string, string>) {
|
|
|
493
498
|
child.stdin.write(answer);
|
|
494
499
|
}
|
|
495
500
|
});
|
|
496
|
-
child.on("close", (status) =>
|
|
501
|
+
child.on("close", (status) => {
|
|
502
|
+
done({ status, out });
|
|
503
|
+
});
|
|
497
504
|
});
|
|
498
505
|
}
|
|
499
506
|
|
|
@@ -563,7 +570,7 @@ test("lint with its LaTeX language missing from the install still lints the mark
|
|
|
563
570
|
"papers/p/paper.md": "# P\n\nSome prose.\n",
|
|
564
571
|
"no-latex.mjs":
|
|
565
572
|
"import { register } from 'node:module';\n" +
|
|
566
|
-
"register('data:text/javascript,' + encodeURIComponent(\"export async function resolve(s, c, next) { if (s
|
|
573
|
+
"register('data:text/javascript,' + encodeURIComponent(\"export async function resolve(s, c, next) { if (s === '#eslint-rules/latex-language') throw Object.assign(new Error('gone'), { code: 'ERR_MODULE_NOT_FOUND' }); return next(s, c); }\"));\n",
|
|
567
574
|
});
|
|
568
575
|
const without = runNode(BIN, ["lint", "papers"], {
|
|
569
576
|
cwd: dir,
|