paperlint 10.3.0 → 10.4.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 +15 -4
- package/README.md +1 -0
- package/dist/CLAUDE.md.spec.d.ts.map +1 -1
- package/dist/CLAUDE.md.spec.js +6 -3
- package/dist/CLAUDE.md.spec.js.map +1 -1
- package/dist/adapters/git/index.d.ts +10 -0
- package/dist/adapters/git/index.d.ts.map +1 -0
- package/dist/adapters/git/index.js +151 -0
- package/dist/adapters/git/index.js.map +1 -0
- package/dist/adapters/latex/captions.d.ts +9 -0
- package/dist/adapters/latex/captions.d.ts.map +1 -0
- package/dist/adapters/latex/captions.js +40 -0
- package/dist/adapters/latex/captions.js.map +1 -0
- package/dist/adapters/latex/index.d.ts +1 -0
- package/dist/adapters/latex/index.d.ts.map +1 -1
- package/dist/adapters/latex/index.js +1 -0
- package/dist/adapters/latex/index.js.map +1 -1
- package/dist/adapters/latex/parse.d.ts.map +1 -1
- package/dist/adapters/latex/parse.js +6 -0
- package/dist/adapters/latex/parse.js.map +1 -1
- package/dist/adapters/memory/index.d.ts +6 -0
- package/dist/adapters/memory/index.d.ts.map +1 -1
- package/dist/adapters/memory/index.js +8 -0
- package/dist/adapters/memory/index.js.map +1 -1
- package/dist/adapters/node/index.d.ts +1 -0
- package/dist/adapters/node/index.d.ts.map +1 -1
- package/dist/adapters/node/index.js +1 -0
- package/dist/adapters/node/index.js.map +1 -1
- package/dist/adapters/node/list-entries.io.d.ts +3 -0
- package/dist/adapters/node/list-entries.io.d.ts.map +1 -0
- package/dist/adapters/node/list-entries.io.js +26 -0
- package/dist/adapters/node/list-entries.io.js.map +1 -0
- package/dist/adapters/study-registry/index.d.ts +70 -10
- package/dist/adapters/study-registry/index.d.ts.map +1 -1
- package/dist/adapters/study-registry/index.js +84 -10
- package/dist/adapters/study-registry/index.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +33 -3
- package/dist/cli.js.map +1 -1
- package/dist/domain/decide-first.d.ts +110 -0
- package/dist/domain/decide-first.d.ts.map +1 -0
- package/dist/domain/decide-first.js +108 -0
- package/dist/domain/decide-first.js.map +1 -0
- package/dist/domain/index-columns.d.ts +45 -0
- package/dist/domain/index-columns.d.ts.map +1 -0
- package/dist/domain/index-columns.js +64 -0
- package/dist/domain/index-columns.js.map +1 -0
- package/dist/domain/study-mode.d.ts +37 -0
- package/dist/domain/study-mode.d.ts.map +1 -0
- package/dist/domain/study-mode.js +45 -0
- package/dist/domain/study-mode.js.map +1 -0
- package/dist/domain/study-registry.d.ts +116 -12
- package/dist/domain/study-registry.d.ts.map +1 -1
- package/dist/domain/study-registry.js +164 -44
- package/dist/domain/study-registry.js.map +1 -1
- package/dist/outputs-before-decision-rule.d.ts +17 -0
- package/dist/outputs-before-decision-rule.d.ts.map +1 -0
- package/dist/outputs-before-decision-rule.js +94 -0
- package/dist/outputs-before-decision-rule.js.map +1 -0
- package/dist/ports/git-history.d.ts +44 -0
- package/dist/ports/git-history.d.ts.map +1 -0
- package/dist/ports/git-history.js +2 -0
- package/dist/ports/git-history.js.map +1 -0
- package/dist/ports/list-entries.d.ts +20 -0
- package/dist/ports/list-entries.d.ts.map +1 -0
- package/dist/ports/list-entries.js +2 -0
- package/dist/ports/list-entries.js.map +1 -0
- package/dist/ports/study-deps.d.ts +14 -0
- package/dist/ports/study-deps.d.ts.map +1 -0
- package/dist/ports/study-deps.js +2 -0
- package/dist/ports/study-deps.js.map +1 -0
- package/dist/ports/study-folder.d.ts +43 -0
- package/dist/ports/study-folder.d.ts.map +1 -0
- package/dist/ports/study-folder.js +2 -0
- package/dist/ports/study-folder.js.map +1 -0
- package/dist/ports/study-registry-codec.d.ts +6 -3
- package/dist/ports/study-registry-codec.d.ts.map +1 -1
- package/dist/presets.d.ts +1 -2
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +1 -2
- package/dist/presets.js.map +1 -1
- package/dist/studies.d.ts +4 -0
- package/dist/studies.d.ts.map +1 -1
- package/dist/studies.js +52 -21
- package/dist/studies.js.map +1 -1
- package/dist/study-folder.d.ts +14 -0
- package/dist/study-folder.d.ts.map +1 -0
- package/dist/study-folder.js +123 -0
- package/dist/study-folder.js.map +1 -0
- package/dist/study-gate.d.ts +14 -0
- package/dist/study-gate.d.ts.map +1 -0
- package/dist/study-gate.js +132 -0
- package/dist/study-gate.js.map +1 -0
- package/dist/study-index-input.d.ts +5 -0
- package/dist/study-index-input.d.ts.map +1 -0
- package/dist/study-index-input.js +18 -0
- package/dist/study-index-input.js.map +1 -0
- package/dist/study-modes.d.ts +56 -0
- package/dist/study-modes.d.ts.map +1 -0
- package/dist/study-modes.js +59 -0
- package/dist/study-modes.js.map +1 -0
- package/dist/study-registry-rule.d.ts +13 -1
- package/dist/study-registry-rule.d.ts.map +1 -1
- package/dist/study-registry-rule.js +33 -21
- package/dist/study-registry-rule.js.map +1 -1
- package/dist/study-run.d.ts +19 -0
- package/dist/study-run.d.ts.map +1 -0
- package/dist/study-run.js +9 -0
- package/dist/study-run.js.map +1 -0
- package/docs/design/study-modes.md +265 -0
- package/docs/design/study-registry.md +6 -0
- package/docs/e2e.md +8 -4
- package/docs/layout.md +22 -19
- package/docs/rules/repro/outputs-before-decision.md +122 -0
- package/docs/rules/repro/study-registered.md +49 -15
- package/docs/rules/tex/heading-case.md +1 -1
- package/docs/rules.md +54 -53
- package/docs/testing.md +1 -0
- package/eslint.config.mjs +36 -24
- package/package.json +2 -1
- package/scripts/check.ts +6 -0
- package/skills/camera-ready/SKILL.md +6 -1
- package/skills/camera-ready/SKILL.md.spec.ts +5 -0
- package/skills/draft-paper/SKILL.md +11 -3
- package/skills/draft-paper/SKILL.md.spec.ts +10 -2
- package/skills/grade-paper-writing/SKILL.md +4 -2
- package/skills/grade-paper-writing/SKILL.md.spec.ts +3 -1
- package/skills/grade-paper-writing/__snapshots__/prose-lint.test.ts.snap +16 -3
- package/skills/grade-paper-writing/prose-lint.mjs +127 -95
- package/skills/grade-paper-writing/prose-lint.test.ts +119 -10
- package/skills/harden-paper/SKILL.md +12 -2
- package/skills/harden-paper/SKILL.md.spec.ts +11 -1
- package/skills/osf-artifact-upload/SKILL.md +7 -1
- package/skills/osf-artifact-upload/SKILL.md.spec.ts +6 -0
- package/skills/pc-panel-review/SKILL.md +10 -3
- package/skills/pc-panel-review/SKILL.md.spec.ts +9 -2
- package/skills/tighten-paper/SKILL.md +5 -1
- package/skills/tighten-paper/SKILL.md.spec.ts +4 -0
- package/src/CLAUDE.md +7 -4
- package/src/CLAUDE.md.spec.ts +6 -3
- package/src/adapters/git/history.test.ts +121 -0
- package/src/adapters/git/index.test.ts +268 -0
- package/src/adapters/git/index.ts +227 -0
- package/src/adapters/latex/captions.test.ts +57 -0
- package/src/adapters/latex/captions.ts +56 -0
- package/src/adapters/latex/index.ts +1 -0
- package/src/adapters/latex/parse.ts +7 -0
- package/src/adapters/memory/index.test.ts +15 -1
- package/src/adapters/memory/index.ts +13 -0
- package/src/adapters/node/index.ts +1 -0
- package/src/adapters/node/list-entries.io.ts +27 -0
- package/src/adapters/node/list-entries.test.ts +61 -0
- package/src/adapters/study-registry/index.test.ts +12 -9
- package/src/adapters/study-registry/index.ts +130 -24
- package/src/adapters/study-registry/mode.test.ts +162 -0
- package/src/cli.ts +47 -3
- package/src/domain/decide-first.test.ts +291 -0
- package/src/domain/decide-first.ts +258 -0
- package/src/domain/index-columns.test.ts +261 -0
- package/src/domain/index-columns.ts +107 -0
- package/src/domain/study-measurements.test.ts +16 -8
- package/src/domain/study-mode.test.ts +55 -0
- package/src/domain/study-mode.ts +78 -0
- package/src/domain/study-registry.test.ts +72 -37
- package/src/domain/study-registry.ts +281 -50
- package/src/new-paper.test.ts +5 -1
- package/src/outputs-before-decision-rule.test.ts +251 -0
- package/src/outputs-before-decision-rule.ts +133 -0
- package/src/ports/git-history.ts +44 -0
- package/src/ports/list-entries.ts +21 -0
- package/src/ports/study-deps.ts +14 -0
- package/src/ports/study-folder.ts +38 -0
- package/src/ports/study-registry-codec.ts +10 -3
- package/src/presets.ts +1 -2
- package/src/rule-cases.test.ts +78 -3
- package/src/studies-index-modes.test.ts +129 -0
- package/src/studies.test.ts +35 -11
- package/src/studies.ts +96 -26
- package/src/study-folder.test.ts +237 -0
- package/src/study-folder.ts +176 -0
- package/src/study-gate.test.ts +467 -0
- package/src/study-gate.ts +234 -0
- package/src/study-index-input.ts +31 -0
- package/src/study-modes.ts +107 -0
- package/src/study-registry-rule.test.ts +285 -11
- package/src/study-registry-rule.ts +64 -35
- package/src/study-run.ts +21 -0
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* file in `repro/`.
|
|
19
19
|
*/
|
|
20
20
|
import { basename, dirname, join, posix } from "node:path";
|
|
21
|
+
import { filter, map, pipe } from "remeda";
|
|
21
22
|
import { callerPath } from "./caller-path.ts";
|
|
22
23
|
import {
|
|
23
24
|
README,
|
|
@@ -30,11 +31,16 @@ import {
|
|
|
30
31
|
PLAN_NAME_PROBLEMS,
|
|
31
32
|
STUDIES_FILE,
|
|
32
33
|
judgeStudies,
|
|
33
|
-
|
|
34
|
+
folderKey,
|
|
35
|
+
planRefs,
|
|
36
|
+
studiesOf,
|
|
34
37
|
studyMessage,
|
|
35
38
|
type PlanState,
|
|
36
39
|
type RegistryState,
|
|
40
|
+
type Study,
|
|
37
41
|
type StudyFinding,
|
|
42
|
+
type Located,
|
|
43
|
+
type PlanRef,
|
|
38
44
|
} from "./domain/study-registry.ts";
|
|
39
45
|
import type { FolderLayoutDeps } from "./folder-layout-rule.ts";
|
|
40
46
|
import type {
|
|
@@ -42,8 +48,11 @@ import type {
|
|
|
42
48
|
FolderRuleModule,
|
|
43
49
|
} from "./folder-venue-rule.ts";
|
|
44
50
|
import type { Files } from "./ports/files.ts";
|
|
51
|
+
import type { ListEntries } from "./ports/list-entries.ts";
|
|
45
52
|
import type { StudyRegistryCodec } from "./ports/study-registry-codec.ts";
|
|
46
53
|
import { reproEntriesOf } from "./repro-layout-rule.ts";
|
|
54
|
+
import type { StudyFolder } from "./ports/study-folder.ts";
|
|
55
|
+
import { studyFolder } from "./study-folder.ts";
|
|
47
56
|
import { rulePageUrl } from "./venue-rules.ts";
|
|
48
57
|
|
|
49
58
|
const STATUS_FILE = "PIPELINE-STATUS.md";
|
|
@@ -51,10 +60,12 @@ const STATUS_FILE = "PIPELINE-STATUS.md";
|
|
|
51
60
|
/** What the rule reads with: the disk, its listings, and the registry's parser. */
|
|
52
61
|
export interface StudyRegistryDeps extends FolderLayoutDeps {
|
|
53
62
|
readonly codec: StudyRegistryCodec;
|
|
63
|
+
/** `repro/`'s entries, links not followed: a study folder that is a link is never read through. */
|
|
64
|
+
readonly entries: ListEntries;
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
/** The text of the file at `p`; null when there is none, or a directory sits there. */
|
|
57
|
-
const textAt = (files: Files, p: string): string | null => {
|
|
68
|
+
export const textAt = (files: Files, p: string): string | null => {
|
|
58
69
|
const b = files.isFile(callerPath(p)) ? files.readBytes(callerPath(p)) : null;
|
|
59
70
|
return b === null ? null : new TextDecoder().decode(b);
|
|
60
71
|
};
|
|
@@ -83,61 +94,79 @@ const studyFolders = (dir: string, deps: FolderLayoutDeps): readonly string[] =>
|
|
|
83
94
|
)
|
|
84
95
|
.map((e) => e.name);
|
|
85
96
|
|
|
86
|
-
/**
|
|
87
|
-
const
|
|
88
|
-
dir: string,
|
|
97
|
+
/** What each `<folder>/<result_file>` of `r`'s rows is, as the study folder's reader finds it. */
|
|
98
|
+
const resultsOf = (
|
|
89
99
|
r: RegistryState,
|
|
90
|
-
|
|
91
|
-
):
|
|
92
|
-
|
|
93
|
-
(r
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
folder: StudyFolder,
|
|
101
|
+
): ReadonlyMap<string, Located> =>
|
|
102
|
+
pipe(
|
|
103
|
+
studiesOf(r),
|
|
104
|
+
filter(hasResultFile),
|
|
105
|
+
map(
|
|
106
|
+
(s) =>
|
|
107
|
+
[
|
|
108
|
+
folderKey(s.folder, s.result_file),
|
|
109
|
+
folder.locate(s.folder, s.result_file),
|
|
110
|
+
] as const,
|
|
111
|
+
),
|
|
112
|
+
(entries) => new Map(entries),
|
|
103
113
|
);
|
|
104
114
|
|
|
115
|
+
/** A row that names a result file. */
|
|
116
|
+
const hasResultFile = (
|
|
117
|
+
s: Study,
|
|
118
|
+
): s is Study & { readonly result_file: string } => s.result_file !== undefined;
|
|
119
|
+
|
|
105
120
|
/**
|
|
106
121
|
* The plan each row of `r` names, read and parsed, by `<folder>/<plan>`; a plan not there is left out.
|
|
107
122
|
* A plan still named `prereg.json` is parsed by the loose schema of its old name.
|
|
108
123
|
*/
|
|
109
|
-
const plansOf = (
|
|
110
|
-
dir: string,
|
|
124
|
+
export const plansOf = (
|
|
111
125
|
r: RegistryState,
|
|
112
|
-
|
|
126
|
+
folder: StudyFolder,
|
|
127
|
+
codec: StudyRegistryCodec,
|
|
113
128
|
): ReadonlyMap<string, PlanState> =>
|
|
114
129
|
new Map(
|
|
115
|
-
(r.kind === "read" ?
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const parse =
|
|
122
|
-
posix.basename(key) === LEGACY_PLAN_FILE
|
|
123
|
-
? deps.codec.parseLegacyPlan
|
|
124
|
-
: deps.codec.parsePlan;
|
|
125
|
-
return [[key, parse(text)]];
|
|
126
|
-
}),
|
|
130
|
+
(r.kind === "read" ? planRefs(r.registry) : []).flatMap((ref) => {
|
|
131
|
+
const state = planStateOf(ref, folder, codec);
|
|
132
|
+
return state === null
|
|
133
|
+
? []
|
|
134
|
+
: [[folderKey(ref.folder, ref.plan), state] as const];
|
|
135
|
+
}),
|
|
127
136
|
);
|
|
128
137
|
|
|
138
|
+
/** The state of the plan `ref` names, read through `folder`; null when it is not there. */
|
|
139
|
+
const planStateOf = (
|
|
140
|
+
{ folder: of, plan, kind }: PlanRef,
|
|
141
|
+
folder: StudyFolder,
|
|
142
|
+
codec: StudyRegistryCodec,
|
|
143
|
+
): PlanState | null => {
|
|
144
|
+
const read = folder.read(of, plan);
|
|
145
|
+
switch (read.kind) {
|
|
146
|
+
case "absent":
|
|
147
|
+
return null;
|
|
148
|
+
case "linked":
|
|
149
|
+
return { kind: "linked", link: read.link };
|
|
150
|
+
case "text":
|
|
151
|
+
return posix.basename(plan) === LEGACY_PLAN_FILE
|
|
152
|
+
? codec.parseLegacyPlan(read.text)
|
|
153
|
+
: codec.parsePlan(read.text, kind);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
129
157
|
/** Every finding of the paper folder `dir`'s study registry — THE function behind both rules. */
|
|
130
158
|
export function studyFindings(
|
|
131
159
|
dir: string,
|
|
132
160
|
deps: StudyRegistryDeps,
|
|
133
161
|
): readonly StudyFinding[] {
|
|
134
162
|
const registry = registryOf(dir, deps);
|
|
163
|
+
const folder = studyFolder(dir, deps);
|
|
135
164
|
return judgeStudies({
|
|
136
165
|
folders: studyFolders(dir, deps),
|
|
137
166
|
registry,
|
|
138
167
|
readme: textAt(deps.files, join(dir, REPRO_DIR, README)),
|
|
139
|
-
|
|
140
|
-
plans: plansOf(
|
|
168
|
+
results: resultsOf(registry, folder),
|
|
169
|
+
plans: plansOf(registry, folder, deps.codec),
|
|
141
170
|
});
|
|
142
171
|
}
|
|
143
172
|
|
package/src/study-run.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** What a `paperlint studies` command on one study comes to: the lines it prints, or its refusal. */
|
|
2
|
+
|
|
3
|
+
/** A refusal: the exit code, and the line that explains it. */
|
|
4
|
+
export interface StudyRefusal {
|
|
5
|
+
readonly code: 1 | 2;
|
|
6
|
+
readonly line: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** What a run came to: the lines it printed, or the refusal. */
|
|
10
|
+
export type StudyRun =
|
|
11
|
+
| { readonly ok: true; readonly lines: readonly string[] }
|
|
12
|
+
| { readonly ok: false; readonly refusal: StudyRefusal };
|
|
13
|
+
|
|
14
|
+
/** A refusal for the paper's state: exit 1. */
|
|
15
|
+
export const refusal = (line: string): StudyRefusal => ({ code: 1, line });
|
|
16
|
+
|
|
17
|
+
/** The run that is `r`. */
|
|
18
|
+
export const refused = (r: StudyRefusal): StudyRun => ({
|
|
19
|
+
ok: false,
|
|
20
|
+
refusal: r,
|
|
21
|
+
});
|