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
package/src/build.ts
CHANGED
|
@@ -187,11 +187,16 @@ function argText(arg: LatexArgument | undefined): string {
|
|
|
187
187
|
.join("");
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
/** A unified-latex AST, or null when the text does not parse. */
|
|
191
|
-
function parseTex(
|
|
190
|
+
/** A unified-latex AST, or null when the text does not parse. `parse` is unified-latex's parser. */
|
|
191
|
+
function parseTex(
|
|
192
|
+
tex: string,
|
|
193
|
+
parse: (tex: string) => LatexRoot = (t) => getParser().parse(t),
|
|
194
|
+
): LatexRoot | null {
|
|
192
195
|
try {
|
|
193
|
-
return
|
|
196
|
+
return parse(tex);
|
|
194
197
|
} catch {
|
|
198
|
+
// The parser recurses per group: ~20 000 nested `{` exhaust the stack (RangeError). Such a
|
|
199
|
+
// file has no class to report, and must not fail the build at `facts` for it.
|
|
195
200
|
return null;
|
|
196
201
|
}
|
|
197
202
|
}
|
|
@@ -200,8 +205,11 @@ function parseTex(tex: string): LatexRoot | null {
|
|
|
200
205
|
* `\documentclass[opts]{name}`, read by the unified-latex parser the lint rules already use —
|
|
201
206
|
* so a `\documentclass` inside a comment is a comment, not a class.
|
|
202
207
|
*/
|
|
203
|
-
export function parseDocumentclass(
|
|
204
|
-
|
|
208
|
+
export function parseDocumentclass(
|
|
209
|
+
tex: string,
|
|
210
|
+
{ parse }: { parse?: (tex: string) => LatexRoot } = {},
|
|
211
|
+
): PaperFacts["documentclass"] {
|
|
212
|
+
return documentclassOf(parseTex(tex, parse));
|
|
205
213
|
}
|
|
206
214
|
|
|
207
215
|
function documentclassOf(ast: LatexRoot | null): PaperFacts["documentclass"] {
|
|
@@ -354,9 +362,8 @@ function latexPass(
|
|
|
354
362
|
const r = ctx.run("pdflatex", pdflatexArgs(final), opts);
|
|
355
363
|
if (r.error) return null;
|
|
356
364
|
const exitCode = r.status ?? 1;
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
);
|
|
365
|
+
const written = readOr(join(ctx.paperDir, `${JOB}.log`), "latin1");
|
|
366
|
+
const log = unwrapLog(written ?? "");
|
|
360
367
|
return {
|
|
361
368
|
step: "latex",
|
|
362
369
|
final,
|
|
@@ -365,10 +372,30 @@ function latexPass(
|
|
|
365
372
|
after: hashes(ctx.paperDir),
|
|
366
373
|
markers: logMarkers(log),
|
|
367
374
|
bib: bibInput(ctx.paperDir),
|
|
368
|
-
errorLines:
|
|
375
|
+
errorLines:
|
|
376
|
+
exitCode === 0
|
|
377
|
+
? []
|
|
378
|
+
: written === null
|
|
379
|
+
? printed(r)
|
|
380
|
+
: errorExcerpt(log).map(fromLatin1),
|
|
369
381
|
};
|
|
370
382
|
}
|
|
371
383
|
|
|
384
|
+
/**
|
|
385
|
+
* The last lines pdflatex printed, for the run that wrote no log — it died before opening one (a
|
|
386
|
+
* format it cannot load, a missing TeX Live file). Marked by NO_LOG, which the report keys on.
|
|
387
|
+
*/
|
|
388
|
+
function printed(r: { stdout?: unknown; stderr?: unknown }): string[] {
|
|
389
|
+
const lines = fromLatin1(
|
|
390
|
+
`${String(r.stdout ?? "")}\n${String(r.stderr ?? "")}`,
|
|
391
|
+
)
|
|
392
|
+
.split("\n")
|
|
393
|
+
.filter((l) => l.trim());
|
|
394
|
+
return [NO_LOG, ...lines.slice(-8).map((l) => ` ${l}`)];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const NO_LOG = `pdflatex wrote no ${JOB}.log — the last lines it printed:`;
|
|
398
|
+
|
|
372
399
|
/** One bibtex run, on the input the `.aux` names BEFORE it runs, or null when it could not start. */
|
|
373
400
|
function bibtexPass(ctx: BuildContext, opts: SpawnOptions): Observation | null {
|
|
374
401
|
const before = hashes(ctx.paperDir);
|
|
@@ -395,6 +422,9 @@ export function compile(ctx: BuildContext): {
|
|
|
395
422
|
} {
|
|
396
423
|
const history: Observation[] = [];
|
|
397
424
|
const opts = spawnOptions(ctx);
|
|
425
|
+
// Every log this loop reads is one its own pdflatex wrote. A pdflatex that dies before opening
|
|
426
|
+
// paper.log would otherwise have an earlier build's error quoted as this one's.
|
|
427
|
+
rmSync(join(ctx.paperDir, `${JOB}.log`), { force: true });
|
|
398
428
|
const runs = { latex: 0, bibtex: 0 };
|
|
399
429
|
for (;;) {
|
|
400
430
|
const step = nextStep(summarize(history));
|
|
@@ -450,7 +480,7 @@ export const compileStep: BuildStep = {
|
|
|
450
480
|
...(end.lines.length
|
|
451
481
|
? end.lines
|
|
452
482
|
: ["(no error line found in the log)"]),
|
|
453
|
-
`full log: ${log}
|
|
483
|
+
...(end.lines[0] === NO_LOG ? [] : [`full log: ${log}`]),
|
|
454
484
|
],
|
|
455
485
|
};
|
|
456
486
|
}
|
|
@@ -828,10 +858,6 @@ function formatRefusal(r: BuildResult): string {
|
|
|
828
858
|
return r.staleRemoved ? `${refused}\n ${PDF_REMOVED}` : refused;
|
|
829
859
|
}
|
|
830
860
|
|
|
831
|
-
export function formatResults(results: readonly BuildResult[]): string {
|
|
832
|
-
return results.map(formatResult).join("\n");
|
|
833
|
-
}
|
|
834
|
-
|
|
835
861
|
/**
|
|
836
862
|
* 🔴 "Nothing to compile" COUNTS AS A REFUSAL on a par with a failed build. Failing to tell these
|
|
837
863
|
* two apart is what once produced a green run over a paper no job had built.
|
package/src/cli.harness.mjs
CHANGED
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
* leaked out of the depths of eslint-helpers.
|
|
12
12
|
* Both are pinned down by the assertions below so there is no going back.
|
|
13
13
|
*/
|
|
14
|
-
import assert from "node:assert/strict";
|
|
15
|
-
import { recordCheck } from "vigiles";
|
|
16
14
|
import { load as yamlLoad } from "js-yaml";
|
|
17
15
|
import {
|
|
18
16
|
mkdtempSync,
|
|
@@ -31,6 +29,7 @@ import { tmpdir } from "node:os";
|
|
|
31
29
|
import { join, dirname } from "node:path";
|
|
32
30
|
import { fileURLToPath } from "node:url";
|
|
33
31
|
import { PAPERS_DIR_FIELD, findProjectRoot } from "../lib/paper-config.mjs";
|
|
32
|
+
import { createChecker } from "../lib/check.mjs";
|
|
34
33
|
|
|
35
34
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
36
35
|
const { run, parseArgs, buildConfig, nextSteps, toPaths, runHook } =
|
|
@@ -39,14 +38,9 @@ const { init, choosePapers, offerWorkflow, missingPrograms, WORKFLOW_PATH } =
|
|
|
39
38
|
await import(join(HERE, "init.ts"));
|
|
40
39
|
const { PROGRAMS } = await import(join(HERE, "doctor.ts"));
|
|
41
40
|
|
|
42
|
-
let n = 0;
|
|
43
41
|
// Counted by vigiles too: `init` now loads `vigiles/claude-code` for its merge, and a harness that
|
|
44
42
|
// loads vigiles without recording a check is reported as having verified nothing.
|
|
45
|
-
const check = (
|
|
46
|
-
assert.ok(cond, label);
|
|
47
|
-
recordCheck(label);
|
|
48
|
-
n++;
|
|
49
|
-
};
|
|
43
|
+
const check = createChecker();
|
|
50
44
|
|
|
51
45
|
/** Runs the utility with output captured — quieter and faster than spawning a process. */
|
|
52
46
|
async function cli(args, cwd) {
|
|
@@ -73,10 +67,9 @@ async function cli(args, cwd) {
|
|
|
73
67
|
};
|
|
74
68
|
} catch (e) {
|
|
75
69
|
// 🔴 A LEAKED EXCEPTION IS A PROPERTY THAT MUST BE ASSERTED, NOT CAUGHT BY LETTING THE
|
|
76
|
-
// HARNESS CRASH.
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
// real defect looked like a weak test.
|
|
70
|
+
// HARNESS CRASH. Removing the catch around ESLint brings the whole harness down with a
|
|
71
|
+
// stack trace instead of a clean, named assertion failure — i.e. the real defect would
|
|
72
|
+
// look like a broken test, not a caught one.
|
|
80
73
|
return {
|
|
81
74
|
code: 99,
|
|
82
75
|
out: `THREW: ${e?.message ?? e}`,
|
|
@@ -537,8 +530,8 @@ check(
|
|
|
537
530
|
// declaration had already been written — i.e. the install both succeeded and looked like
|
|
538
531
|
// a crash.
|
|
539
532
|
// 🔴 THE `.catch` HERE IS LOAD-BEARING, NOT CAUTION. A leaked exception is a PROPERTY that
|
|
540
|
-
// gets asserted;
|
|
541
|
-
//
|
|
533
|
+
// gets asserted; without it, the harness crashes instead of failing a named assertion,
|
|
534
|
+
// i.e. the real defect would look like a hole in the test rather than a caught one.
|
|
542
535
|
const aborted = await offerWorkflow(dir, "writing", {
|
|
543
536
|
interactive: true,
|
|
544
537
|
ask: async () => {
|
|
@@ -599,7 +592,7 @@ check(
|
|
|
599
592
|
});
|
|
600
593
|
// 🔴 JUDGE ONLY init's OWN REPORT, BEFORE doctor's banner. The first version of these
|
|
601
594
|
// three assertions looked at the WHOLE output — and doctor also prints `✗ pdflatex` and
|
|
602
|
-
// the same install command.
|
|
595
|
+
// the same install command. A version of init with the remedy stripped OUT still stayed
|
|
603
596
|
// green: the assertion found a line printed by a different command and reported coverage
|
|
604
597
|
// that did not exist.
|
|
605
598
|
const own = out.text().split("── paperlint doctor")[0];
|
|
@@ -996,7 +989,7 @@ check(
|
|
|
996
989
|
);
|
|
997
990
|
check(
|
|
998
991
|
"and the finding is printed before the ESLint report, with its consequence",
|
|
999
|
-
/missing `PIPELINE-STATUS\.md`/.test(r.out) && /
|
|
992
|
+
/missing `PIPELINE-STATUS\.md`/.test(r.out) && /are skipped/.test(r.out),
|
|
1000
993
|
);
|
|
1001
994
|
check(
|
|
1002
995
|
'and it does NOT print "no findings" over something that was found',
|
|
@@ -1260,7 +1253,7 @@ check(
|
|
|
1260
1253
|
}
|
|
1261
1254
|
|
|
1262
1255
|
console.log(
|
|
1263
|
-
`✓ ${String(
|
|
1256
|
+
`✓ ${String(check.count)} assertions passed — paperlint lint, one command instead of hand-rolled config`,
|
|
1264
1257
|
);
|
|
1265
1258
|
|
|
1266
1259
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -1783,7 +1776,7 @@ console.log(
|
|
|
1783
1776
|
"🔴 an optional rule turned on for a glob that reaches no paper.tex FAILS the run — not a green zero",
|
|
1784
1777
|
silent.code === 1 &&
|
|
1785
1778
|
silent.out.includes(
|
|
1786
|
-
'pdf/last-page-balance is turned on in "rules", but no
|
|
1779
|
+
'pdf/last-page-balance is turned on in "rules", but no paper.tex of the project gets it',
|
|
1787
1780
|
),
|
|
1788
1781
|
);
|
|
1789
1782
|
settings({
|
|
@@ -1799,5 +1792,5 @@ console.log(
|
|
|
1799
1792
|
}
|
|
1800
1793
|
|
|
1801
1794
|
console.log(
|
|
1802
|
-
`✓ ${String(
|
|
1795
|
+
`✓ ${String(check.count)} assertions in total, including init's hooks and paperlint new`,
|
|
1803
1796
|
);
|