paperlint 3.0.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +28 -41
- package/.github/workflows/dependabot-automerge.yml +1 -1
- package/CLAUDE.md +51 -56
- package/CONTRIBUTING.md +30 -18
- package/README.md +179 -180
- package/bin/paperlint.test.mjs +45 -0
- package/dist/adapters/node/files.io.d.ts +2 -0
- package/dist/adapters/node/files.io.d.ts.map +1 -1
- package/dist/adapters/node/files.io.js +3 -2
- package/dist/adapters/node/files.io.js.map +1 -1
- package/dist/adapters/pdfjs/fill.d.ts +15 -4
- package/dist/adapters/pdfjs/fill.d.ts.map +1 -1
- package/dist/adapters/pdfjs/fill.js +31 -21
- 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 +14 -5
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/adapters/references/pool.d.ts +8 -0
- package/dist/adapters/references/pool.d.ts.map +1 -0
- package/dist/adapters/references/pool.js +19 -0
- package/dist/adapters/references/pool.js.map +1 -0
- package/dist/build-engine.d.ts.map +1 -1
- package/dist/build-engine.js +6 -2
- package/dist/build-engine.js.map +1 -1
- package/dist/build.d.ts +10 -2
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +29 -11
- package/dist/build.js.map +1 -1
- package/dist/cli.d.ts +93 -6
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +296 -80
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts +27 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +4 -3
- package/dist/doctor.js.map +1 -1
- package/dist/domain/result.d.ts +0 -2
- package/dist/domain/result.d.ts.map +1 -1
- package/dist/domain/result.js +0 -4
- package/dist/domain/result.js.map +1 -1
- package/dist/engine.d.ts +9 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +27 -0
- package/dist/engine.js.map +1 -1
- package/dist/hooks-settings.d.ts +8 -5
- package/dist/hooks-settings.d.ts.map +1 -1
- package/dist/hooks-settings.js +32 -32
- package/dist/hooks-settings.js.map +1 -1
- package/dist/init.d.ts +8 -0
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +4 -4
- package/dist/init.js.map +1 -1
- package/dist/latex-log.d.ts +0 -2
- package/dist/latex-log.d.ts.map +1 -1
- package/dist/latex-log.js +7 -13
- package/dist/latex-log.js.map +1 -1
- package/dist/link-skills.d.ts +15 -2
- package/dist/link-skills.d.ts.map +1 -1
- package/dist/link-skills.js +36 -20
- package/dist/link-skills.js.map +1 -1
- package/dist/new-paper.d.ts +8 -1
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +50 -15
- package/dist/new-paper.js.map +1 -1
- package/dist/paper-files.d.ts +30 -8
- package/dist/paper-files.d.ts.map +1 -1
- package/dist/paper-files.js +59 -30
- package/dist/paper-files.js.map +1 -1
- package/dist/pdf-facts.d.ts +11 -0
- package/dist/pdf-facts.d.ts.map +1 -1
- package/dist/pdf-facts.js +16 -18
- package/dist/pdf-facts.js.map +1 -1
- package/dist/pdf-geometry.js +1 -1
- package/dist/pdf-geometry.js.map +1 -1
- package/dist/presets.d.ts +2 -0
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +3 -1
- package/dist/presets.js.map +1 -1
- package/dist/references.js +2 -2
- package/dist/references.js.map +1 -1
- package/dist/structure.js +1 -1
- package/dist/structure.js.map +1 -1
- package/dist/tex-requirements.d.ts +8 -0
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +6 -5
- package/dist/tex-requirements.js.map +1 -1
- package/dist/toolchain.d.ts +8 -3
- package/dist/toolchain.d.ts.map +1 -1
- package/dist/toolchain.js +26 -10
- package/dist/toolchain.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/venue-rules.d.ts.map +1 -1
- package/dist/venue-rules.js +12 -10
- package/dist/venue-rules.js.map +1 -1
- package/docs/configuration.md +48 -4
- package/docs/prior-art/README.md +1 -1
- package/docs/prior-art/test-tooling.md +7 -30
- package/docs/rules.md +29 -25
- package/docs/skills.md +80 -0
- package/eslint-rules/install-path-literals.harness.mjs +17 -1
- package/eslint-rules/latex-language.harness.mjs +3 -3
- package/eslint-rules/latex-language.mjs +12 -9
- package/eslint-rules/latex-language.test.mjs +200 -0
- package/eslint-rules/paper-research-question.harness.mjs +73 -7
- package/eslint-rules/paper-stages.harness.mjs +9 -14
- package/eslint-rules/paper-stages.test.mjs +135 -0
- package/eslint-rules/paper-typography.mjs +56 -9
- package/eslint-rules/paper-typography.test.mjs +186 -1
- package/eslint-rules/pdf-last-page-balance.harness.mjs +63 -7
- package/eslint-rules/review-frontmatter.mjs +2 -1
- package/eslint-rules/review-frontmatter.schema.json +1 -1
- package/eslint-rules/review-frontmatter.test.mjs +37 -1
- package/eslint-rules/temp-root-realpath.harness.mjs +49 -0
- package/eslint-rules/tex-build.mjs +13 -13
- package/eslint.config.mjs +6 -2
- package/fixtures/toolchain-mirror/catalog.txt +1 -0
- package/fixtures/toolchain-mirror/install-tl +4 -1
- package/fixtures/toolchain-mirror/stub-fmtutil-sys +4 -0
- package/fixtures/toolchain-mirror/stub-tlmgr +15 -0
- package/hooks/hooks.harness.mjs +6 -11
- package/hooks/paper-edit-guard.hook.mjs +2 -2
- package/hooks/paper-edit-guard.test.mjs +61 -0
- package/hooks/paper-skills-nudge.hook.mjs +2 -2
- package/hooks/paper-skills-nudge.test.mjs +38 -0
- package/hooks/paper-status-gates.test.mjs +42 -0
- package/lib/agent-cli-version.harness.mjs +7 -0
- package/lib/check.d.mts +17 -0
- package/lib/check.mjs +50 -0
- package/lib/check.test.ts +67 -0
- package/lib/markdown.mjs +16 -69
- package/lib/markdown.test.mjs +246 -0
- package/lib/paper-config.harness.mjs +28 -9
- package/lib/paper-config.mjs +7 -2
- package/lib/skill-checks.mjs +18 -46
- package/lib/skill-checks.test.mjs +297 -0
- package/lib/skill-corpus.mjs +11 -13
- package/lib/skill-corpus.test.mjs +54 -0
- package/lib/skill-trigger-cases.harness.mjs +57 -4
- package/package.json +6 -5
- package/scripts/check.harness.mjs +4 -10
- package/scripts/check.mjs +45 -42
- package/scripts/check.test.mjs +104 -0
- package/scripts/coverage-config.test.ts +406 -0
- package/scripts/eslint-report-guard.test.mjs +48 -0
- package/scripts/harness-api.frozen.json +0 -2
- package/scripts/layer-legacy-frozen.d.mts +9 -1
- package/scripts/layer-legacy-frozen.mjs +28 -11
- package/scripts/layer-legacy-frozen.test.ts +143 -1
- package/scripts/rules-are-content-only.harness.mjs +3 -11
- package/scripts/rules-are-content-only.mjs +29 -19
- package/scripts/rules-are-content-only.test.mjs +61 -0
- package/scripts/rules-see-files.mjs +11 -9
- package/scripts/rules-see-files.test.mjs +71 -0
- package/scripts/test.mjs +44 -0
- package/scripts/test.test.mjs +52 -0
- package/skills/grade-paper-writing/__snapshots__/prose-lint.test.mjs.snap +57 -0
- package/skills/grade-paper-writing/prose-lint.mjs +31 -12
- package/skills/grade-paper-writing/prose-lint.test.mjs +153 -0
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +3 -3
- package/skills/paper-pipeline/scripts/README.md +13 -132
- package/skills/paper-pipeline/scripts/announce.test.mjs +102 -0
- package/skills/paper-pipeline/scripts/artifact-coverage.test.mjs +86 -0
- package/skills/paper-pipeline/scripts/consumer.d.mts +8 -1
- package/skills/paper-pipeline/scripts/consumer.harness.mjs +3 -3
- package/skills/paper-pipeline/scripts/consumer.mjs +13 -25
- package/skills/paper-pipeline/scripts/consumer.test.mjs +113 -0
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +9 -4
- package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +380 -0
- package/skills/paper-pipeline/scripts/fixtures/scorecard.mjs +71 -0
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +4 -4
- package/skills/paper-pipeline/scripts/generated-code.mjs +3 -2
- package/skills/paper-pipeline/scripts/generated-code.test.mjs +62 -0
- package/skills/paper-pipeline/scripts/ledger.cli.test.mjs +302 -0
- package/skills/paper-pipeline/scripts/ledger.mjs +1 -1
- package/skills/paper-pipeline/scripts/{ledger.selftest.mjs → ledger.test.mjs} +44 -76
- package/skills/paper-pipeline/scripts/pipeline-check.cli.test.mjs +474 -0
- package/skills/paper-pipeline/scripts/pipeline-check.harness.mjs +2 -63
- package/skills/paper-pipeline/scripts/pipeline-check.mjs +37 -21
- package/skills/paper-pipeline/scripts/pipeline-edges.mjs +2 -2
- package/skills/paper-pipeline/scripts/pipeline-edges.test.mjs +73 -0
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +4 -47
- package/skills/paper-pipeline/scripts/population-map.mjs +12 -2
- package/skills/paper-pipeline/scripts/population-map.test.mjs +154 -0
- package/skills/paper-pipeline/scripts/provenance.harness.mjs +26 -0
- package/skills/paper-pipeline/scripts/round-diff.harness.mjs +1 -2
- package/skills/paper-pipeline/scripts/round-diff.mjs +13 -6
- package/skills/paper-pipeline/scripts/round-diff.test.mjs +159 -0
- package/skills/paper-pipeline/scripts/run-mechanical.mjs +30 -6
- package/skills/paper-pipeline/scripts/run-mechanical.test.mjs +468 -0
- package/skills/paper-pipeline/scripts/status.mjs +2 -2
- package/skills/paper-pipeline/scripts/status.test.mjs +232 -0
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +2 -2
- package/skills/render-paper/extract-pdf-facts.harness.mjs +56 -7
- package/skills/tighten-paper/__snapshots__/structure.test.mjs.snap +133 -0
- package/skills/tighten-paper/structure.test.mjs +116 -0
- package/skills/verify-citations/SKILL.md +5 -5
- package/skills/verify-citations/SKILL.md.spec.ts +4 -4
- package/skills/verify-citations/scripts/__snapshots__/verify-cites.net.test.mjs.snap +235 -0
- package/skills/verify-citations/scripts/bib-authors.check.test.mjs +274 -0
- package/skills/verify-citations/scripts/bib-authors.cli.test.mjs +178 -0
- package/skills/verify-citations/scripts/bib-authors.mjs +2 -1
- package/skills/verify-citations/scripts/verify-cites.cli.test.mjs +160 -0
- package/skills/verify-citations/scripts/verify-cites.mjs +96 -96
- package/skills/verify-citations/scripts/verify-cites.net.test.mjs +287 -0
- package/skills/verify-citations/scripts/verify-cites.test.mjs +149 -5
- package/src/adapters/banal/failure.test.ts +70 -1
- package/src/adapters/banal/index.test.ts +16 -0
- package/src/adapters/banal/output.test.ts +5 -0
- package/src/adapters/curl/download.test.ts +43 -1
- package/src/adapters/memory/index.test.ts +25 -0
- package/src/adapters/node/files.io.ts +3 -2
- package/src/adapters/node/files.test.ts +13 -1
- package/src/adapters/node/process.test.ts +38 -0
- package/src/adapters/pdfjs/fill.test.ts +34 -0
- package/src/adapters/pdfjs/fill.ts +44 -25
- package/src/adapters/references/index.test.ts +228 -0
- package/src/adapters/references/index.ts +21 -6
- package/src/adapters/references/pool.test.ts +31 -0
- package/src/adapters/references/pool.ts +24 -0
- package/src/build-engine.harness.mjs +3 -7
- package/src/build-engine.test.ts +137 -0
- package/src/build-engine.ts +6 -1
- package/src/build.harness.mjs +51 -11
- package/src/build.test.ts +362 -0
- package/src/build.ts +40 -14
- package/src/cli.harness.mjs +12 -19
- package/src/cli.test.ts +584 -0
- package/src/cli.ts +409 -94
- package/src/doctor.harness.mjs +3 -8
- package/src/doctor.test.ts +64 -0
- package/src/doctor.ts +12 -4
- package/src/domain/result.test.ts +4 -0
- package/src/domain/result.ts +0 -5
- package/src/engine.harness.mjs +77 -7
- package/src/engine.ts +35 -0
- package/src/facts-file.test.ts +110 -0
- package/src/hooks-settings.harness.mjs +43 -13
- package/src/hooks-settings.ts +41 -35
- package/src/init.test.ts +308 -5
- package/src/init.ts +4 -4
- package/src/latex-log.harness.mjs +32 -7
- package/src/latex-log.ts +6 -13
- package/src/latex-loop.harness.mjs +8 -7
- package/src/link-skills.harness.mjs +3 -8
- package/src/link-skills.test.ts +105 -0
- package/src/link-skills.ts +75 -21
- package/src/linted-set.test.ts +118 -0
- package/src/new-paper.harness.mjs +5 -7
- package/src/new-paper.test.ts +203 -2
- package/src/new-paper.ts +84 -17
- package/src/paper-files.test.ts +122 -5
- package/src/paper-files.ts +99 -39
- package/src/paper-settings-commands.test.ts +41 -5
- package/src/paper-settings.test.ts +20 -0
- package/src/parse-args.test.ts +48 -0
- package/src/pdf-facts.harness.mjs +3 -6
- package/src/pdf-facts.test.ts +144 -0
- package/src/pdf-facts.ts +17 -19
- package/src/pdf-geometry.harness.mjs +3 -7
- package/src/pdf-geometry.ts +1 -1
- package/src/presets.test.ts +2 -0
- package/src/presets.ts +7 -1
- package/src/references.test.ts +97 -0
- package/src/references.ts +2 -2
- package/src/rules-config.harness.mjs +10 -8
- package/src/rules-off.test.ts +111 -0
- package/src/structure.harness.mjs +5 -9
- package/src/structure.ts +1 -1
- package/src/tex-requirements.harness.mjs +34 -7
- package/src/tex-requirements.ts +12 -6
- package/src/toolchain.harness.mjs +44 -13
- package/src/toolchain.test.ts +280 -0
- package/src/toolchain.ts +37 -12
- package/src/types.ts +6 -0
- package/src/venue-rules.test.ts +63 -0
- package/src/venue-rules.ts +14 -12
- package/templates/paper/paperlint.json +1 -1
- package/action.mutations.mjs +0 -162
- package/eslint-rules/install-path-literals.mutations.mjs +0 -62
- package/eslint-rules/latex-language.mutations.mjs +0 -196
- package/eslint-rules/paper-research-question.mutations.mjs +0 -127
- package/eslint-rules/paper-stages.mutations.mjs +0 -81
- package/eslint-rules/papers.mutations.mjs +0 -186
- package/eslint-rules/temp-root-realpath.mutations.mjs +0 -99
- package/eslint-rules/tex-build.mutations.mjs +0 -258
- package/hooks/hooks.mutations.mjs +0 -337
- package/lib/agent-cli-version.mutations.mjs +0 -109
- package/lib/mutation-driver.harness.mjs +0 -227
- package/lib/mutation-driver.mjs +0 -397
- package/lib/mutation-driver.mutations.mjs +0 -68
- package/lib/paper-config.mutations.mjs +0 -143
- package/lib/skill-trigger-cases.mutations.mjs +0 -65
- package/scripts/check.mutations.mjs +0 -110
- package/scripts/exclusive.mjs +0 -138
- package/scripts/mutation-batteries-frozen.harness.mjs +0 -204
- package/scripts/mutation-batteries-frozen.mjs +0 -238
- package/scripts/mutation-batteries.frozen.json +0 -108
- package/scripts/rules-are-content-only.mutations.mjs +0 -81
- package/scripts/rules-see-files.mutations.mjs +0 -131
- package/scripts/run-mutations.mjs +0 -100
- package/skills/paper-pipeline/scripts/artifact-coverage.mutations.mjs +0 -218
- package/skills/paper-pipeline/scripts/consumer.mutations.mjs +0 -190
- package/skills/paper-pipeline/scripts/extract-ref-facts.mutations.mjs +0 -54
- package/skills/paper-pipeline/scripts/generated-code.mutations.mjs +0 -254
- package/skills/paper-pipeline/scripts/pipeline-check.mutations.mjs +0 -54
- package/skills/paper-pipeline/scripts/population-map.mutations.mjs +0 -65
- package/skills/paper-pipeline/scripts/population-map.selftest.mjs +0 -122
- package/skills/paper-pipeline/scripts/provenance.mutations.mjs +0 -59
- package/skills/paper-pipeline/scripts/round-diff.mutations.mjs +0 -276
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.mutations.mjs +0 -65
- package/skills/skill-contract.mutations.mjs +0 -179
- package/src/build.mutations.mjs +0 -196
- package/src/cli.mutations.mjs +0 -414
- package/src/doctor.mutations.mjs +0 -175
- package/src/hooks-settings.mutations.mjs +0 -99
- package/src/link-skills.mutations.mjs +0 -140
- package/src/new-paper.mutations.mjs +0 -79
- package/src/structure.mutations.mjs +0 -83
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Battery for `link-skills.ts`.
|
|
3
|
-
*
|
|
4
|
-
* Every case below reintroduces a way the skills stop being where Claude Code looks — or, worse,
|
|
5
|
-
* a way the linker destroys something the consumer made. Both fail silently in real life: a
|
|
6
|
-
* missing skill is simply absent from the listing, and a replaced directory is simply gone.
|
|
7
|
-
*/
|
|
8
|
-
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { dirname, join, resolve } from "node:path";
|
|
10
|
-
import { runMutations } from "../lib/mutation-driver.mjs";
|
|
11
|
-
|
|
12
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
const ROOT = resolve(HERE, "..");
|
|
14
|
-
const SRC = join(HERE, "link-skills.ts");
|
|
15
|
-
const HARNESS = join(HERE, "link-skills.harness.mjs");
|
|
16
|
-
const CONSUMER = join(
|
|
17
|
-
ROOT,
|
|
18
|
-
"skills",
|
|
19
|
-
"paper-pipeline",
|
|
20
|
-
"scripts",
|
|
21
|
-
"consumer.mjs",
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
process.exit(
|
|
25
|
-
runMutations({
|
|
26
|
-
root: ROOT,
|
|
27
|
-
runner: "node",
|
|
28
|
-
cases: [
|
|
29
|
-
{
|
|
30
|
-
// The definition lives in the port since paperlint#62 (`installedSkills` in consumer.mjs), so
|
|
31
|
-
// the defect is planted THERE and must still die in THIS harness — the evidence that the
|
|
32
|
-
// linker reads it through the shared function rather than through a copy of its own.
|
|
33
|
-
name: "any directory counts as a skill",
|
|
34
|
-
harness: HARNESS,
|
|
35
|
-
expect: "a directory without SKILL.md is not one",
|
|
36
|
-
disables:
|
|
37
|
-
"the definition of a skill. A helper directory beside the skills gets a link, and Claude " +
|
|
38
|
-
"Code lists an entry with no SKILL.md behind it",
|
|
39
|
-
edits: [
|
|
40
|
-
[
|
|
41
|
-
CONSUMER,
|
|
42
|
-
' if (st.isDirectory() && existsSync(join(entry, "SKILL.md")))\n names.push(name);',
|
|
43
|
-
" if (st.isDirectory())\n names.push(name);",
|
|
44
|
-
],
|
|
45
|
-
],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: "the link is written absolute",
|
|
49
|
-
harness: HARNESS,
|
|
50
|
-
expect: "the link is RELATIVE",
|
|
51
|
-
disables:
|
|
52
|
-
"portability of the checkout. An absolute link works on the machine that ran init and " +
|
|
53
|
-
"dangles in every other clone, container and CI runner",
|
|
54
|
-
edits: [
|
|
55
|
-
[
|
|
56
|
-
SRC,
|
|
57
|
-
' symlinkSync(target, entry, "dir");',
|
|
58
|
-
' symlinkSync(resolve(dirname(entry), target), entry, "dir");',
|
|
59
|
-
],
|
|
60
|
-
],
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: "an existing correct link is not recognised",
|
|
64
|
-
harness: HARNESS,
|
|
65
|
-
expect: "a second run reports every link as ALREADY present",
|
|
66
|
-
disables:
|
|
67
|
-
"idempotency. Every re-run of init would report its own links as someone else's " +
|
|
68
|
-
"and tell the consumer to move them",
|
|
69
|
-
edits: [
|
|
70
|
-
[
|
|
71
|
-
SRC,
|
|
72
|
-
' if (realpathSync(entry) === want) return { status: "present" };',
|
|
73
|
-
' if (realpathSync(entry) === "") return { status: "present" };',
|
|
74
|
-
],
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: "a foreign entry is replaced instead of reported",
|
|
79
|
-
harness: HARNESS,
|
|
80
|
-
expect: "a foreign DIRECTORY is left untouched",
|
|
81
|
-
disables:
|
|
82
|
-
"the one promise that makes init safe to run on a real project: a consumer's own skill " +
|
|
83
|
-
"of the same name, or a link they aimed elsewhere, is deleted without a word",
|
|
84
|
-
edits: [
|
|
85
|
-
[
|
|
86
|
-
SRC,
|
|
87
|
-
' symlinkSync,\n} from "node:fs";',
|
|
88
|
-
' symlinkSync,\n rmSync,\n} from "node:fs";',
|
|
89
|
-
],
|
|
90
|
-
[
|
|
91
|
-
SRC,
|
|
92
|
-
' if (!write || seen.status !== "missing")',
|
|
93
|
-
' if (!write || seen.status === "present")',
|
|
94
|
-
],
|
|
95
|
-
[
|
|
96
|
-
SRC,
|
|
97
|
-
' symlinkSync(target, entry, "dir");',
|
|
98
|
-
' rmSync(entry, { recursive: true, force: true });\n symlinkSync(target, entry, "dir");',
|
|
99
|
-
],
|
|
100
|
-
],
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: "the resolved store path is linked instead of the project's own spelling",
|
|
104
|
-
harness: HARNESS,
|
|
105
|
-
expect: "under pnpm the link goes through node_modules/<package>",
|
|
106
|
-
disables:
|
|
107
|
-
"the link surviving an upgrade under pnpm. The store directory carries the version in " +
|
|
108
|
-
"its name; the next install removes it and every skill link dangles until init is re-run",
|
|
109
|
-
edits: [
|
|
110
|
-
[
|
|
111
|
-
SRC,
|
|
112
|
-
" if (realpathSync(candidate) === dir) return { dir, spelled: candidate };",
|
|
113
|
-
' if (realpathSync(candidate) === "") return { dir, spelled: candidate };',
|
|
114
|
-
],
|
|
115
|
-
],
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
name: "doctor's read-only call writes links",
|
|
119
|
-
harness: HARNESS,
|
|
120
|
-
expect:
|
|
121
|
-
"write:false reports every skill as missing and creates nothing",
|
|
122
|
-
disables:
|
|
123
|
-
"the difference between looking and changing. `paperlint doctor` would quietly repair the " +
|
|
124
|
-
"state it is supposed to report, so the report can never show the gap",
|
|
125
|
-
edits: [
|
|
126
|
-
[
|
|
127
|
-
SRC,
|
|
128
|
-
' if (!write || seen.status !== "missing")',
|
|
129
|
-
' if (seen.status !== "missing")',
|
|
130
|
-
],
|
|
131
|
-
[
|
|
132
|
-
SRC,
|
|
133
|
-
" if (write && shipped.names.length > 0) {",
|
|
134
|
-
" if (shipped.names.length > 0) {",
|
|
135
|
-
],
|
|
136
|
-
],
|
|
137
|
-
},
|
|
138
|
-
],
|
|
139
|
-
}),
|
|
140
|
-
);
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Battery for `new-paper.ts`.
|
|
3
|
-
*
|
|
4
|
-
* Every case reintroduces a way `paperlint new` damages a paper folder or produces one the linter
|
|
5
|
-
* refuses — the first a loss nobody notices until the text is gone, the second the exact
|
|
6
|
-
* "missing file on the first run" this command was written to end.
|
|
7
|
-
*/
|
|
8
|
-
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { dirname, join, resolve } from "node:path";
|
|
10
|
-
import { runMutations } from "../lib/mutation-driver.mjs";
|
|
11
|
-
|
|
12
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
const ROOT = resolve(HERE, "..");
|
|
14
|
-
const SRC = join(HERE, "new-paper.ts");
|
|
15
|
-
const HARNESS = join(HERE, "new-paper.harness.mjs");
|
|
16
|
-
|
|
17
|
-
process.exit(
|
|
18
|
-
runMutations({
|
|
19
|
-
root: ROOT,
|
|
20
|
-
runner: "node",
|
|
21
|
-
cases: [
|
|
22
|
-
{
|
|
23
|
-
name: "an existing file is overwritten",
|
|
24
|
-
harness: HARNESS,
|
|
25
|
-
expect: "a second run overwrites nothing",
|
|
26
|
-
disables:
|
|
27
|
-
"the one promise that makes `paperlint new` safe on an existing folder. A scorecard with a " +
|
|
28
|
-
"year of journal in it is replaced by the empty template",
|
|
29
|
-
edits: [
|
|
30
|
-
[
|
|
31
|
-
SRC,
|
|
32
|
-
' if (existsSync(join(dir, file))) {\n files.push({ file, status: "kept" });\n continue;\n }\n',
|
|
33
|
-
"",
|
|
34
|
-
],
|
|
35
|
-
[SRC, '{ encoding: "utf8", flag: "wx" }', '{ encoding: "utf8" }'],
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
name: "a second source is added beside an existing one",
|
|
40
|
-
harness: HARNESS,
|
|
41
|
-
// The first owner is the re-run on a .tex paper asked for md: it must add no paper.md.
|
|
42
|
-
expect: "adds no second source",
|
|
43
|
-
disables:
|
|
44
|
-
"the migration of an old folder: a paper written in Markdown gains a stub paper.tex, " +
|
|
45
|
-
"and every tex rule starts linting a file the author never wrote",
|
|
46
|
-
edits: [
|
|
47
|
-
[
|
|
48
|
-
SRC,
|
|
49
|
-
" return hasSource ? [STATUS_FILE] : [STATUS_FILE, SOURCE_FILE[format]];",
|
|
50
|
-
" return [STATUS_FILE, SOURCE_FILE[format]];",
|
|
51
|
-
],
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "the project's template is ignored",
|
|
56
|
-
harness: HARNESS,
|
|
57
|
-
expect: "is preferred for the file it holds",
|
|
58
|
-
disables:
|
|
59
|
-
"the override slot. A project with its own richer scorecard gets the package's every time",
|
|
60
|
-
edits: [
|
|
61
|
-
[
|
|
62
|
-
SRC,
|
|
63
|
-
" const [src, from] = existsSync(project)",
|
|
64
|
-
" const [src, from] = false",
|
|
65
|
-
],
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "a leading dot is accepted",
|
|
70
|
-
harness: HARNESS,
|
|
71
|
-
expect: "discovery skips dot-directories",
|
|
72
|
-
disables:
|
|
73
|
-
"the refusal of a name that would be created and then never linted — the scaffold " +
|
|
74
|
-
"would sit beside the papers, invisible to every check",
|
|
75
|
-
edits: [[SRC, ' if (name.startsWith("."))', " if (false)"]],
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
}),
|
|
79
|
-
);
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Battery for `structure.ts` — the package's only check whose subject is a file's ABSENCE.
|
|
3
|
-
*
|
|
4
|
-
* A check like this is especially vulnerable to silent failure: it reports on what is missing,
|
|
5
|
-
* so a broken one looks exactly like a clean corpus. This battery exists because the mutation gate
|
|
6
|
-
* refused to accept a harness that nothing could kill.
|
|
7
|
-
*/
|
|
8
|
-
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { dirname, join, resolve } from "node:path";
|
|
10
|
-
import { runMutations } from "../lib/mutation-driver.mjs";
|
|
11
|
-
|
|
12
|
-
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
const ROOT = resolve(HERE, "..");
|
|
14
|
-
const SRC = join(HERE, "structure.ts");
|
|
15
|
-
const HARNESS = join(HERE, "structure.harness.mjs");
|
|
16
|
-
|
|
17
|
-
process.exit(
|
|
18
|
-
runMutations({
|
|
19
|
-
root: ROOT,
|
|
20
|
-
runner: "node",
|
|
21
|
-
cases: [
|
|
22
|
-
{
|
|
23
|
-
name: "generous detection is removed — any directory counts as a paper",
|
|
24
|
-
harness: HARNESS,
|
|
25
|
-
expect:
|
|
26
|
-
"a directory WITHOUT a single pipeline marker is left alone entirely",
|
|
27
|
-
disables:
|
|
28
|
-
"the condition the check uses at all to decide it is looking at a paper. Without it, " +
|
|
29
|
-
"findings would rain down on `data/`, `figures/` and any neighboring directory — and a " +
|
|
30
|
-
"rule that yells at the innocent gets turned off entirely, real findings and all",
|
|
31
|
-
edits: [
|
|
32
|
-
[
|
|
33
|
-
SRC,
|
|
34
|
-
" if (!rules.markers.some((m: string) => existsSync(join(dir, m))))\n continue;",
|
|
35
|
-
" if (false) continue;",
|
|
36
|
-
],
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: "`ignore` stops exempting",
|
|
41
|
-
harness: HARNESS,
|
|
42
|
-
expect: "`ignore` exempts a directory by name",
|
|
43
|
-
disables:
|
|
44
|
-
'the consumer\'s only way to say "this directory is not a paper". Without it, an ' +
|
|
45
|
-
"exemption has to be expressed by renaming the directory",
|
|
46
|
-
edits: [
|
|
47
|
-
[SRC, " if (rules.ignore.includes(name)) continue;\n", ""],
|
|
48
|
-
],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: "the second accepted source form falls out of the defaults",
|
|
52
|
-
harness: HARNESS,
|
|
53
|
-
expect: "`paper.md` counts on equal footing with `paper.tex`",
|
|
54
|
-
disables:
|
|
55
|
-
"the second source form the live corpus keeps. A paper on `paper.md` would become a " +
|
|
56
|
-
'"no source" finding while its source is right there — i.e. the check would yell at ' +
|
|
57
|
-
"the innocent, and such rules get turned off entirely, real findings and all",
|
|
58
|
-
edits: [
|
|
59
|
-
[
|
|
60
|
-
SRC,
|
|
61
|
-
'requireOneOf: [["paper.tex", "paper.md"]]',
|
|
62
|
-
'requireOneOf: [["paper.tex"]]',
|
|
63
|
-
],
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: "the path in a finding goes absolute again",
|
|
68
|
-
harness: HARNESS,
|
|
69
|
-
expect: "and the path is RELATIVE",
|
|
70
|
-
disables:
|
|
71
|
-
"the readability of the finding. An absolute path to the run's temp directory tells " +
|
|
72
|
-
"the reader nothing and on top of that makes the output useless for comparing across machines",
|
|
73
|
-
edits: [
|
|
74
|
-
[
|
|
75
|
-
SRC,
|
|
76
|
-
' return rel &&\n rel !== ".." &&\n !rel.startsWith(`..${sep}`) &&\n !isAbsolute(rel)\n ? rel\n : p;',
|
|
77
|
-
" return p;",
|
|
78
|
-
],
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
}),
|
|
83
|
-
);
|