paperlint 10.4.0 → 11.0.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/deadlines.yml +27 -7
- package/README.md +16 -15
- 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/hotcrp/index.d.ts +6 -4
- package/dist/adapters/hotcrp/index.d.ts.map +1 -1
- package/dist/adapters/hotcrp/index.js +6 -4
- package/dist/adapters/hotcrp/index.js.map +1 -1
- package/dist/adapters/hotcrp/portal.io.d.ts +3 -1
- package/dist/adapters/hotcrp/portal.io.d.ts.map +1 -1
- package/dist/adapters/hotcrp/portal.io.js +36 -11
- package/dist/adapters/hotcrp/portal.io.js.map +1 -1
- package/dist/adapters/hotcrp/response.d.ts +6 -1
- package/dist/adapters/hotcrp/response.d.ts.map +1 -1
- package/dist/adapters/hotcrp/response.js +17 -0
- package/dist/adapters/hotcrp/response.js.map +1 -1
- package/dist/adapters/hotcrp/site.d.ts +9 -0
- package/dist/adapters/hotcrp/site.d.ts.map +1 -0
- package/dist/adapters/hotcrp/site.js +22 -0
- package/dist/adapters/hotcrp/site.js.map +1 -0
- package/dist/adapters/hotcrp/token.d.ts +13 -0
- package/dist/adapters/hotcrp/token.d.ts.map +1 -0
- package/dist/adapters/hotcrp/token.js +48 -0
- package/dist/adapters/hotcrp/token.js.map +1 -0
- package/dist/adapters/latex/abstract.d.ts +22 -0
- package/dist/adapters/latex/abstract.d.ts.map +1 -0
- package/dist/adapters/latex/abstract.js +187 -0
- package/dist/adapters/latex/abstract.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/headings.d.ts +6 -0
- package/dist/adapters/latex/headings.d.ts.map +1 -1
- package/dist/adapters/latex/headings.js +5 -4
- package/dist/adapters/latex/headings.js.map +1 -1
- 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 +3 -0
- package/dist/adapters/latex/index.js.map +1 -1
- package/dist/adapters/latex/parse.d.ts +15 -0
- package/dist/adapters/latex/parse.d.ts.map +1 -1
- package/dist/adapters/latex/parse.js +64 -1
- package/dist/adapters/latex/parse.js.map +1 -1
- package/dist/adapters/node/list-entries.io.d.ts.map +1 -1
- package/dist/adapters/node/list-entries.io.js +3 -1
- package/dist/adapters/node/list-entries.io.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -8
- package/dist/cli.js.map +1 -1
- package/dist/cycle-rules.d.ts.map +1 -1
- package/dist/cycle-rules.js +3 -4
- package/dist/cycle-rules.js.map +1 -1
- package/dist/domain/deadline.d.ts +8 -1
- package/dist/domain/deadline.d.ts.map +1 -1
- package/dist/domain/deadline.js +26 -12
- package/dist/domain/deadline.js.map +1 -1
- package/dist/domain/decide-first.d.ts +11 -1
- package/dist/domain/decide-first.d.ts.map +1 -1
- package/dist/domain/decide-first.js +6 -0
- package/dist/domain/decide-first.js.map +1 -1
- package/dist/domain/index-columns.d.ts.map +1 -1
- package/dist/domain/index-columns.js +2 -0
- package/dist/domain/index-columns.js.map +1 -1
- package/dist/domain/portal-token.d.ts +44 -0
- package/dist/domain/portal-token.d.ts.map +1 -0
- package/dist/domain/portal-token.js +32 -0
- package/dist/domain/portal-token.js.map +1 -0
- package/dist/domain/study-registry.d.ts +65 -8
- package/dist/domain/study-registry.d.ts.map +1 -1
- package/dist/domain/study-registry.js +63 -19
- package/dist/domain/study-registry.js.map +1 -1
- package/dist/domain/submission.d.ts +30 -0
- package/dist/domain/submission.d.ts.map +1 -1
- package/dist/domain/submission.js +68 -0
- package/dist/domain/submission.js.map +1 -1
- package/dist/lib/paper-config.d.ts +1 -1
- package/dist/lib/paper-config.d.ts.map +1 -1
- package/dist/lib/paper-config.js +6 -4
- package/dist/lib/paper-config.js.map +1 -1
- package/dist/outputs-before-decision-rule.d.ts +1 -1
- package/dist/outputs-before-decision-rule.d.ts.map +1 -1
- package/dist/outputs-before-decision-rule.js +21 -17
- package/dist/outputs-before-decision-rule.js.map +1 -1
- package/dist/paper-settings.d.ts +3 -1
- package/dist/paper-settings.d.ts.map +1 -1
- package/dist/paper-settings.js +11 -5
- package/dist/paper-settings.js.map +1 -1
- package/dist/ports/latex.d.ts +23 -0
- package/dist/ports/latex.d.ts.map +1 -1
- package/dist/ports/list-entries.d.ts +7 -4
- package/dist/ports/list-entries.d.ts.map +1 -1
- 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/submission-portal.d.ts +39 -2
- package/dist/ports/submission-portal.d.ts.map +1 -1
- package/dist/ports/venue-deadlines.d.ts +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.map +1 -1
- package/dist/studies.js +10 -7
- 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 +1 -1
- package/dist/study-gate.d.ts.map +1 -1
- package/dist/study-gate.js +65 -28
- package/dist/study-gate.js.map +1 -1
- package/dist/study-index-input.d.ts +1 -1
- package/dist/study-index-input.d.ts.map +1 -1
- package/dist/study-index-input.js +8 -3
- package/dist/study-index-input.js.map +1 -1
- package/dist/study-modes.d.ts +38 -27
- package/dist/study-modes.d.ts.map +1 -1
- package/dist/study-modes.js +42 -53
- package/dist/study-modes.js.map +1 -1
- package/dist/study-registry-rule.d.ts +2 -6
- package/dist/study-registry-rule.d.ts.map +1 -1
- package/dist/study-registry-rule.js +32 -41
- package/dist/study-registry-rule.js.map +1 -1
- package/dist/submission.d.ts +49 -11
- package/dist/submission.d.ts.map +1 -1
- package/dist/submission.js +332 -44
- package/dist/submission.js.map +1 -1
- package/docs/configuration.md +2 -1
- package/docs/design/study-modes.md +46 -28
- package/docs/rules/cycle/record.md +9 -6
- package/docs/rules/repro/outputs-before-decision.md +3 -0
- package/docs/rules/repro/study-registered.md +3 -2
- package/docs/rules/tex/heading-case.md +1 -1
- package/docs/submission.md +47 -48
- package/eslint.config.mjs +39 -24
- package/lib/paper-config.ts +7 -4
- package/package.json +6 -1
- package/presets/msr.jsonc +9 -7
- package/presets/msr.md +14 -10
- package/scripts/check.ts +1 -1
- package/scripts/refresh-deadlines/compare.test.ts +75 -0
- package/scripts/refresh-deadlines/compare.ts +101 -0
- package/scripts/refresh-deadlines/main.test.ts +140 -0
- package/scripts/refresh-deadlines/main.ts +56 -0
- package/scripts/refresh-deadlines/refresh.test.ts +287 -0
- package/scripts/refresh-deadlines/refresh.ts +183 -0
- 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/submission-portal/SKILL.md +60 -44
- package/skills/submission-portal/SKILL.md.spec.ts +62 -43
- package/skills/submission-portal/submission-portal.test.ts +4 -73
- package/src/CLAUDE.md +7 -4
- package/src/CLAUDE.md.spec.ts +6 -3
- package/src/adapters/hotcrp/cassette/README.md +4 -4
- package/src/adapters/hotcrp/cassette/deadlines-msr2027.html +9 -9
- package/src/adapters/hotcrp/deadlines.io.test.ts +2 -2
- package/src/adapters/hotcrp/deadlines.test.ts +3 -3
- package/src/adapters/hotcrp/index.ts +15 -3
- package/src/adapters/hotcrp/portal.io.ts +61 -17
- package/src/adapters/hotcrp/portal.test.ts +105 -1
- package/src/adapters/hotcrp/response.ts +21 -0
- package/src/adapters/hotcrp/site.ts +34 -0
- package/src/adapters/hotcrp/token.test.ts +69 -0
- package/src/adapters/hotcrp/token.ts +51 -0
- package/src/adapters/latex/abstract.test.ts +280 -0
- package/src/adapters/latex/abstract.ts +272 -0
- package/src/adapters/latex/captions.test.ts +57 -0
- package/src/adapters/latex/captions.ts +56 -0
- package/src/adapters/latex/headings.ts +5 -4
- package/src/adapters/latex/index.test.ts +31 -1
- package/src/adapters/latex/index.ts +3 -0
- package/src/adapters/latex/parse.ts +71 -3
- package/src/adapters/node/list-entries.io.ts +2 -1
- package/src/adapters/node/list-entries.test.ts +18 -0
- package/src/cli.test.ts +20 -8
- package/src/cli.ts +22 -13
- package/src/cycle-rules.test.ts +6 -6
- package/src/cycle-rules.ts +7 -4
- package/src/domain/deadline.test.ts +31 -2
- package/src/domain/deadline.ts +42 -16
- package/src/domain/decide-first.test.ts +33 -0
- package/src/domain/decide-first.ts +16 -1
- package/src/domain/index-columns.test.ts +49 -4
- package/src/domain/index-columns.ts +2 -0
- package/src/domain/portal-token.test.ts +55 -0
- package/src/domain/portal-token.ts +63 -0
- package/src/domain/study-measurements.test.ts +7 -3
- package/src/domain/study-registry.test.ts +34 -6
- package/src/domain/study-registry.ts +123 -31
- package/src/domain/submission.test.ts +88 -0
- package/src/domain/submission.ts +99 -0
- package/src/new-paper.test.ts +1 -0
- package/src/outputs-before-decision-rule.test.ts +47 -2
- package/src/outputs-before-decision-rule.ts +31 -22
- package/src/paper-settings.test.ts +20 -0
- package/src/paper-settings.ts +17 -5
- package/src/ports/latex.ts +25 -0
- package/src/ports/list-entries.ts +7 -4
- package/src/ports/study-deps.ts +14 -0
- package/src/ports/study-folder.ts +38 -0
- package/src/ports/submission-portal.ts +43 -1
- package/src/ports/venue-deadlines.ts +1 -1
- package/src/presets.test.ts +8 -5
- package/src/presets.ts +1 -2
- package/src/studies-index-modes.test.ts +2 -2
- package/src/studies.ts +19 -10
- package/src/study-folder.test.ts +237 -0
- package/src/study-folder.ts +176 -0
- package/src/study-gate.test.ts +158 -7
- package/src/study-gate.ts +127 -54
- package/src/study-index-input.ts +12 -4
- package/src/study-modes.ts +67 -80
- package/src/study-registry-rule.test.ts +87 -0
- package/src/study-registry-rule.ts +58 -66
- package/src/submission-new.test.ts +569 -0
- package/src/submission-show.test.ts +210 -0
- package/src/submission-update.test.ts +160 -0
- package/src/submission.test.ts +140 -518
- package/src/submission.ts +494 -61
- package/scripts/refresh-deadlines.test.ts +0 -431
- package/scripts/refresh-deadlines.ts +0 -387
|
@@ -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,
|
|
@@ -29,13 +30,17 @@ import {
|
|
|
29
30
|
LEGACY_PLAN_FILE,
|
|
30
31
|
PLAN_NAME_PROBLEMS,
|
|
31
32
|
STUDIES_FILE,
|
|
32
|
-
isFolderName,
|
|
33
33
|
judgeStudies,
|
|
34
|
+
folderKey,
|
|
34
35
|
planRefs,
|
|
36
|
+
studiesOf,
|
|
35
37
|
studyMessage,
|
|
36
38
|
type PlanState,
|
|
37
39
|
type RegistryState,
|
|
40
|
+
type Study,
|
|
38
41
|
type StudyFinding,
|
|
42
|
+
type Located,
|
|
43
|
+
type PlanRef,
|
|
39
44
|
} from "./domain/study-registry.ts";
|
|
40
45
|
import type { FolderLayoutDeps } from "./folder-layout-rule.ts";
|
|
41
46
|
import type {
|
|
@@ -46,6 +51,8 @@ import type { Files } from "./ports/files.ts";
|
|
|
46
51
|
import type { ListEntries } from "./ports/list-entries.ts";
|
|
47
52
|
import type { StudyRegistryCodec } from "./ports/study-registry-codec.ts";
|
|
48
53
|
import { reproEntriesOf } from "./repro-layout-rule.ts";
|
|
54
|
+
import type { StudyFolder } from "./ports/study-folder.ts";
|
|
55
|
+
import { studyFolder } from "./study-folder.ts";
|
|
49
56
|
import { rulePageUrl } from "./venue-rules.ts";
|
|
50
57
|
|
|
51
58
|
const STATUS_FILE = "PIPELINE-STATUS.md";
|
|
@@ -57,30 +64,6 @@ export interface StudyRegistryDeps extends FolderLayoutDeps {
|
|
|
57
64
|
readonly entries: ListEntries;
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
/** The names at the top of `<dir>/repro/` that are symbolic links. */
|
|
61
|
-
const linksIn = (
|
|
62
|
-
dir: string,
|
|
63
|
-
deps: Pick<StudyRegistryDeps, "entries">,
|
|
64
|
-
): ReadonlySet<string> =>
|
|
65
|
-
new Set(
|
|
66
|
-
deps
|
|
67
|
-
.entries(callerPath(join(dir, REPRO_DIR)))
|
|
68
|
-
.filter((e) => e.kind === "symlink")
|
|
69
|
-
.map((e) => e.name),
|
|
70
|
-
);
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* The test every reader of a study's folder passes a row through: its folder is one folder name
|
|
74
|
-
* inside `repro/` (`isFolderName`) and not a symbolic link, which would lead the reads anywhere.
|
|
75
|
-
*/
|
|
76
|
-
export const readableFolders = (
|
|
77
|
-
dir: string,
|
|
78
|
-
deps: Pick<StudyRegistryDeps, "entries">,
|
|
79
|
-
): ((folder: string) => boolean) => {
|
|
80
|
-
const links = linksIn(dir, deps);
|
|
81
|
-
return (folder) => isFolderName(folder) && !links.has(folder);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
67
|
/** The text of the file at `p`; null when there is none, or a directory sits there. */
|
|
85
68
|
export const textAt = (files: Files, p: string): string | null => {
|
|
86
69
|
const b = files.isFile(callerPath(p)) ? files.readBytes(callerPath(p)) : null;
|
|
@@ -111,70 +94,79 @@ const studyFolders = (dir: string, deps: FolderLayoutDeps): readonly string[] =>
|
|
|
111
94
|
)
|
|
112
95
|
.map((e) => e.name);
|
|
113
96
|
|
|
114
|
-
/**
|
|
115
|
-
const
|
|
116
|
-
dir: string,
|
|
97
|
+
/** What each `<folder>/<result_file>` of `r`'s rows is, as the study folder's reader finds it. */
|
|
98
|
+
const resultsOf = (
|
|
117
99
|
r: RegistryState,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
!p.includes("\0") &&
|
|
132
|
-
files.isFile(callerPath(join(dir, REPRO_DIR, p))),
|
|
133
|
-
),
|
|
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),
|
|
134
113
|
);
|
|
135
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
|
+
|
|
136
120
|
/**
|
|
137
121
|
* The plan each row of `r` names, read and parsed, by `<folder>/<plan>`; a plan not there is left out.
|
|
138
122
|
* A plan still named `prereg.json` is parsed by the loose schema of its old name.
|
|
139
123
|
*/
|
|
140
124
|
export const plansOf = (
|
|
141
|
-
dir: string,
|
|
142
125
|
r: RegistryState,
|
|
143
|
-
|
|
144
|
-
|
|
126
|
+
folder: StudyFolder,
|
|
127
|
+
codec: StudyRegistryCodec,
|
|
145
128
|
): ReadonlyMap<string, PlanState> =>
|
|
146
129
|
new Map(
|
|
147
|
-
(r.kind === "read" ? planRefs(r.registry) : [])
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (text === null) return [];
|
|
154
|
-
return [
|
|
155
|
-
[
|
|
156
|
-
key,
|
|
157
|
-
posix.basename(key) === LEGACY_PLAN_FILE
|
|
158
|
-
? deps.codec.parseLegacyPlan(text)
|
|
159
|
-
: deps.codec.parsePlan(text, kind),
|
|
160
|
-
],
|
|
161
|
-
];
|
|
162
|
-
}),
|
|
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
|
+
}),
|
|
163
136
|
);
|
|
164
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
|
+
|
|
165
157
|
/** Every finding of the paper folder `dir`'s study registry — THE function behind both rules. */
|
|
166
158
|
export function studyFindings(
|
|
167
159
|
dir: string,
|
|
168
160
|
deps: StudyRegistryDeps,
|
|
169
161
|
): readonly StudyFinding[] {
|
|
170
|
-
const readable = readableFolders(dir, deps);
|
|
171
162
|
const registry = registryOf(dir, deps);
|
|
163
|
+
const folder = studyFolder(dir, deps);
|
|
172
164
|
return judgeStudies({
|
|
173
165
|
folders: studyFolders(dir, deps),
|
|
174
166
|
registry,
|
|
175
167
|
readme: textAt(deps.files, join(dir, REPRO_DIR, README)),
|
|
176
|
-
|
|
177
|
-
plans: plansOf(
|
|
168
|
+
results: resultsOf(registry, folder),
|
|
169
|
+
plans: plansOf(registry, folder, deps.codec),
|
|
178
170
|
});
|
|
179
171
|
}
|
|
180
172
|
|