@avi2dg/checks 0.13.0 → 0.14.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/CHANGELOG.md +124 -0
- package/CONTRIBUTING.md +89 -0
- package/README.md +131 -1216
- package/docs/configs/commit-messages.md +43 -0
- package/docs/configs/dependency-rules.md +62 -0
- package/docs/configs/effect-rules.md +48 -0
- package/docs/configs/quality-file.md +99 -0
- package/docs/design.md +77 -0
- package/docs/gates/checks-backtest.md +50 -0
- package/docs/gates/checks-ci-wiring.md +122 -0
- package/docs/gates/checks-comment-gate.md +58 -0
- package/docs/gates/checks-commit-identity.md +63 -0
- package/docs/gates/checks-docs.md +98 -0
- package/docs/gates/checks-feature-owners.md +113 -0
- package/docs/gates/checks-flake.md +88 -0
- package/docs/gates/checks-lint-coverage.md +49 -0
- package/docs/gates/checks-lint.md +136 -0
- package/docs/gates/checks-mutation-compare.md +84 -0
- package/docs/gates/checks-quality.md +94 -0
- package/docs/gates/checks-size-budget.md +64 -0
- package/docs/gates/checks-suppressions-ratchet.md +51 -0
- package/docs/gates/checks-test-layout.md +77 -0
- package/docs/gates/checks-test.md +75 -0
- package/package.json +7 -2
- package/scripts/doc-rules.ts +4 -3
- package/scripts/doc-templates.ts +10 -5
- package/scripts/quality-file.ts +1 -1
- package/templates/changelog.md +5 -5
- package/templates/claude.md +1 -1
- package/templates/readme.md +3 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# checks-size-budget
|
|
2
|
+
|
|
3
|
+
`checks-size-budget` is the gate that holds production files to the line budget `quality.json` declares, and a reader looks it up when a file or a function runs over it.
|
|
4
|
+
|
|
5
|
+
## What it checks
|
|
6
|
+
|
|
7
|
+
It holds production files to the line budget `quality.json` declares, and lists every other file over it without failing:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
"sources": { "production": ["src/**/*.ts"] },
|
|
11
|
+
"size": { "fileLines": 400, "functionLines": 100, "applies": "changed" }
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
It runs oxlint with a configuration of two rules and nothing else, `max-lines` at `fileLines` and `max-lines-per-function` at `functionLines`, both counting blank and comment lines.
|
|
15
|
+
With `applies` set to `changed` it holds the files under `sources.production` that the range adds or changes, a rename that edits the file included.
|
|
16
|
+
With `all` it holds every file under `sources.production`.
|
|
17
|
+
A file the range deletes or only renames is not held.
|
|
18
|
+
Every other tracked `.ts` or `.tsx` file over the budget, tests and unchanged production files alike, is listed as advisory and never fails the gate.
|
|
19
|
+
`.d.ts` files are not measured.
|
|
20
|
+
|
|
21
|
+
## What it reads
|
|
22
|
+
|
|
23
|
+
It reads each file from the head commit rather than the working tree, so an uncommitted edit neither fails nor passes a range, and a pull request's merge checkout measures what the pull request holds.
|
|
24
|
+
It reads `sources.production` and `size` from `quality.json`.
|
|
25
|
+
oxlint must be on `PATH`, as it is under a package script.
|
|
26
|
+
|
|
27
|
+
## Arguments
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
checks-size-budget <base-ref> <head-ref>
|
|
31
|
+
checks-size-budget <ref>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
With two arguments the range starts where the head branched from the base, at their merge-base.
|
|
35
|
+
With one it is that commit against its parent, or against the empty tree for a repository's first commit.
|
|
36
|
+
|
|
37
|
+
## Exit codes
|
|
38
|
+
|
|
39
|
+
| Code | When |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| 0 | every file it holds keeps within the budget |
|
|
42
|
+
| 1 | a file it holds runs over the budget |
|
|
43
|
+
| 2 | `quality.json` does not decode, a ref does not resolve, or oxlint cannot run |
|
|
44
|
+
|
|
45
|
+
## Sample output
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
size-budget: 1 overrun(s) of 400 lines per file and 100 per function in the production files the range adds or changes:
|
|
49
|
+
src/billing/ledger.ts:12: The function `settle` has too many lines (131). Maximum allowed is 100.
|
|
50
|
+
size-budget: advisory, 1 overrun(s) where the budget does not hold yet:
|
|
51
|
+
tests/e2e/billing.test.ts: File has too many lines (512).
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Opting out
|
|
55
|
+
|
|
56
|
+
A repository that declares no `size` passes.
|
|
57
|
+
`quality.json` refuses a `size` without `sources.production`, which would hold nothing, and with `size` declared `checks-quality` refuses a `sources.production` glob that matches no file.
|
|
58
|
+
A repository that tracks no `.ts` or `.tsx` file leaves it out of `gates.lint`, as [Gate selection](checks-lint.md#gate-selection) says.
|
|
59
|
+
Moving `applies` from `changed` to `all` tightens the budget to every production file, once the advisory list names none.
|
|
60
|
+
|
|
61
|
+
## Related topics
|
|
62
|
+
|
|
63
|
+
- [The quality file](../configs/quality-file.md)
|
|
64
|
+
- [checks-lint](checks-lint.md)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# checks-suppressions-ratchet
|
|
2
|
+
|
|
3
|
+
`checks-suppressions-ratchet` is the gate that holds oxlint's bulk-suppression baseline to counts that only fall, and a reader looks it up when a change raised a count.
|
|
4
|
+
|
|
5
|
+
## What it checks
|
|
6
|
+
|
|
7
|
+
oxlint accepts whatever `oxlint --suppress-all` writes to `oxlint-suppressions.json`, so raising a count to let a new site through passes the lint.
|
|
8
|
+
The ratchet fails naming each file and rule whose count rose or that appeared.
|
|
9
|
+
A count that fell and an entry that went both pass.
|
|
10
|
+
|
|
11
|
+
## What it reads
|
|
12
|
+
|
|
13
|
+
It reads `oxlint-suppressions.json` at a base and at a head, from the directory the command runs in, which is where oxlint writes it.
|
|
14
|
+
A commit without the file counts as empty, so the commit that first adds a baseline fails with every entry appearing.
|
|
15
|
+
|
|
16
|
+
## Arguments
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
checks-suppressions-ratchet <base-ref> <head-ref>
|
|
20
|
+
checks-suppressions-ratchet <ref>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
With two arguments it reads the base where the head branched off, at their merge-base, so a count the base branch lowered since does not read as a rise at the head.
|
|
24
|
+
With one it compares that commit with its parent, or with the empty tree for a repository's first commit.
|
|
25
|
+
|
|
26
|
+
## Exit codes
|
|
27
|
+
|
|
28
|
+
| Code | When |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| 0 | no count rose and no entry appeared |
|
|
31
|
+
| 1 | a count rose or an entry appeared |
|
|
32
|
+
| 2 | a ref does not resolve, the parent exists but is not in the clone, or the file is not oxlint's count per rule per file |
|
|
33
|
+
|
|
34
|
+
## Sample output
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
suppressions-ratchet: 2 count(s) in oxlint-suppressions.json rose or appeared; fix the site instead of suppressing it:
|
|
38
|
+
src/added.ts typescript/no-unsafe-type-assertion appeared with 1
|
|
39
|
+
src/dispatch.ts typescript/no-non-null-assertion rose from 12 to 13
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Opting out
|
|
43
|
+
|
|
44
|
+
It applies to every repository, so no selection leaves it out.
|
|
45
|
+
A repository with no `oxlint-suppressions.json` passes, since both ends count as empty.
|
|
46
|
+
`checks-lint` runs it over each pull request's range, as [checks-lint](checks-lint.md) says.
|
|
47
|
+
|
|
48
|
+
## Related topics
|
|
49
|
+
|
|
50
|
+
- [The Effect rules](../configs/effect-rules.md)
|
|
51
|
+
- [checks-lint](checks-lint.md)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# checks-test-layout
|
|
2
|
+
|
|
3
|
+
`checks-test-layout` is the gate that holds a repository's tests to one layout, and a reader looks it up to learn where a test file goes and what it may import.
|
|
4
|
+
|
|
5
|
+
## What it checks
|
|
6
|
+
|
|
7
|
+
It fails unless the repository holds this shape, and names the file and the path to move it to when it does not.
|
|
8
|
+
|
|
9
|
+
- Every test file is `tests/**/*.test.ts` or `.tsx`.
|
|
10
|
+
A `*.test.ts`, `*.spec.ts` or `*_test.ts` under `src/`, `test/`, `__tests__/` or the repository root fails.
|
|
11
|
+
- `tests/lib/**` holds helpers and `tests/fixtures/**` holds data, and neither may hold a test file.
|
|
12
|
+
Every other directory directly under `tests/` is a test group and may nest as deep as it likes.
|
|
13
|
+
- A test runs at one of two levels.
|
|
14
|
+
A test outside `tests/e2e/` runs in-process, so it may not import `node:child_process`, `net`, `http`, `https`, `http2`, `tls` or `dgram`.
|
|
15
|
+
It may not import `$`, `spawn`, `spawnSync`, `connect`, `serve` or `listen` from `bun`, may not touch `Bun.$` or `Bun.spawn`, and may not call `fetch`.
|
|
16
|
+
A test inside `tests/e2e/` may do all of it.
|
|
17
|
+
Helpers in `tests/lib/**` answer to the same rule, since an in-process test reaches them.
|
|
18
|
+
- `scripts.test` is exactly `checks-test`, which runs `bun test --randomize` as [checks-test](checks-test.md) says.
|
|
19
|
+
- `scripts.lint` runs this check, itself or through `checks-lint` called by its bare bin name.
|
|
20
|
+
- `bunfig.toml` carries every `[test]` key of the shipped preset with the same value.
|
|
21
|
+
`[test].pathIgnorePatterns` is always `["**/tests/quarantine/**"]`, which the check pins itself, so the kit's own repository, whose bunfig is the preset, cannot drift it either.
|
|
22
|
+
Other tables, and extra `[test]` keys, are the repository's own.
|
|
23
|
+
|
|
24
|
+
The in-process half is what a mutation run can mutate.
|
|
25
|
+
`tests/e2e/**` is left out of a mutate scope by construction, because a subprocess kills both the speed and the coverage signal a mutant needs.
|
|
26
|
+
|
|
27
|
+
The preset also skips `tests/quarantine/**` on a default run.
|
|
28
|
+
A test that turns flaky moves there, so the suite stays trustworthy, and the flake still runs on demand:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
bun test --path-ignore-patterns='' tests/quarantine
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## What it reads
|
|
35
|
+
|
|
36
|
+
It reads the working tree.
|
|
37
|
+
It scans the tracked and untracked files that `git ls-files --exclude-standard` reports, so `node_modules/` and every gitignored tree are out of reach, and a local run agrees with CI before `git add`.
|
|
38
|
+
It parses each test and helper with swc and reads import specifiers and identifier use, so a test that only carries `"node:child_process"` as a string is not a violation.
|
|
39
|
+
`tests/fixtures/**` is data and is not parsed.
|
|
40
|
+
It reads `package.json` for `scripts.test` and `scripts.lint`, and compares `bunfig.toml` with the preset the installed kit ships.
|
|
41
|
+
|
|
42
|
+
## Arguments
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
checks-test-layout [<directory>]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
It checks the directory it runs in, or the directory it is given.
|
|
49
|
+
|
|
50
|
+
## Exit codes
|
|
51
|
+
|
|
52
|
+
| Code | When |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| 0 | the repository holds the layout |
|
|
55
|
+
| 1 | a file breaks the layout |
|
|
56
|
+
| 2 | a test, a helper or `package.json` does not parse |
|
|
57
|
+
|
|
58
|
+
## Sample output
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
test-layout: 4 violation(s)
|
|
62
|
+
src/a.test.ts: a test file must live at tests/**/*.test.ts; move it to tests/a.test.ts
|
|
63
|
+
package.json: scripts.test must be exactly "checks-test", which runs bun test --randomize and judges its skips, found "bun test"
|
|
64
|
+
package.json: scripts.lint must run the layout check: add "checks-lint"
|
|
65
|
+
bunfig.toml: bunfig.toml is missing; bun has no bunfig extends, so copy node_modules/@avi2dg/checks/bunfig.toml
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Opting out
|
|
69
|
+
|
|
70
|
+
A repository that tracks no `.ts` or `.tsx` file leaves it out of `gates.lint`, as [Gate selection](checks-lint.md#gate-selection) says, and then needs no `checks-test` script and no `bunfig.toml`.
|
|
71
|
+
A repository that tracks one keeps it.
|
|
72
|
+
|
|
73
|
+
## Related topics
|
|
74
|
+
|
|
75
|
+
- [checks-test](checks-test.md)
|
|
76
|
+
- [checks-flake](checks-flake.md)
|
|
77
|
+
- [checks-mutation-compare](checks-mutation-compare.md)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# checks-test
|
|
2
|
+
|
|
3
|
+
`checks-test` is the entry point that runs the whole suite and refuses a skip the repository has not declared, and a reader looks it up to declare a skip.
|
|
4
|
+
|
|
5
|
+
## What it checks
|
|
6
|
+
|
|
7
|
+
It runs the whole suite with `bun test --randomize`, passes bun's output through, and then reads bun's JUnit report of the same run.
|
|
8
|
+
bun exits 0 with tests skipped, so a green run says nothing about the tests that never ran.
|
|
9
|
+
`checks-test` fails when a test failed, or when a test was skipped without a declaration in `package.json`.
|
|
10
|
+
A test counts as skipped through `test.skip`, `test.skipIf`, `test.if`, `describe.skip` or `test.todo`.
|
|
11
|
+
|
|
12
|
+
A declaration names the test and says why it skips:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
"testSkips": [
|
|
16
|
+
{
|
|
17
|
+
"file": "tests/e2e/docker.test.ts",
|
|
18
|
+
"test": "images > builds the release image",
|
|
19
|
+
"reason": "the runner has no docker daemon",
|
|
20
|
+
"when": "ci"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`file` is the path bun reports, relative to the package root.
|
|
26
|
+
`test` is the name bun's console prints, the describe blocks and the test name joined by ` > `.
|
|
27
|
+
`reason` is required.
|
|
28
|
+
`when` is `ci` or `local` for a test skipped only there, and a declaration without it holds in both.
|
|
29
|
+
|
|
30
|
+
A declaration that holds for the run but matches no skipped test fails a ci run too, so a fixed or renamed test takes its declaration with it.
|
|
31
|
+
A local run only warns about it, because whether a test skips there can hang on the machine, such as a docker daemon being up.
|
|
32
|
+
Files under `tests/quarantine/` are never run and so never reported, as [checks-test-layout](checks-test-layout.md) says.
|
|
33
|
+
|
|
34
|
+
## What it reads
|
|
35
|
+
|
|
36
|
+
It reads bun's JUnit report of its own run, which bun writes to a temporary directory, and `testSkips` in `package.json`.
|
|
37
|
+
It counts a run as `ci` when `CI` is set true, as GitHub Actions sets it, and as `local` otherwise.
|
|
38
|
+
|
|
39
|
+
## Arguments
|
|
40
|
+
|
|
41
|
+
It takes none.
|
|
42
|
+
A `-t` filter would report every test it leaves out as skipped, and a path filter would drop files a declaration names.
|
|
43
|
+
A narrowed run is therefore plain `bun test --randomize` with the arguments.
|
|
44
|
+
|
|
45
|
+
## Exit codes
|
|
46
|
+
|
|
47
|
+
| Code | When |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| 0 | every test that ran passed, and every skip is declared |
|
|
50
|
+
| 1 | a test failed, a skip is undeclared, or in a ci run a declaration is stale |
|
|
51
|
+
| 2 | `testSkips` does not parse, `CI` is set to something other than a boolean, or bun passed without writing its report |
|
|
52
|
+
|
|
53
|
+
## Sample output
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
checks-test: 1 skipped test(s) undeclared and 1 declaration(s) matching no skipped test in this ci run:
|
|
57
|
+
tests/pricing.test.ts:12 pricing > rounds half to even: skipped with no declaration; run it, or declare it in package.json testSkips with its reason
|
|
58
|
+
tests/e2e/docker.test.ts > images > builds the release image: declared, but no such test skipped; delete the declaration
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A run with nothing skipped ends with:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
checks-test: no test skipped
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Opting out
|
|
68
|
+
|
|
69
|
+
A test opts out of a run through its declaration in `testSkips`.
|
|
70
|
+
A repository that tracks TypeScript source runs `checks-test` as `scripts.test`, since [checks-test-layout](checks-test-layout.md) requires it.
|
|
71
|
+
|
|
72
|
+
## Related topics
|
|
73
|
+
|
|
74
|
+
- [checks-test-layout](checks-test-layout.md)
|
|
75
|
+
- [checks-flake](checks-flake.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avi2dg/checks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Deterministic checks shared across the captain's TypeScript repos",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
},
|
|
13
13
|
"type": "module",
|
|
14
14
|
"files": [
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"CONTRIBUTING.md",
|
|
17
|
+
"docs/configs/",
|
|
18
|
+
"docs/design.md",
|
|
19
|
+
"docs/gates/",
|
|
15
20
|
"bunfig.toml",
|
|
16
21
|
"commitlint.config.js",
|
|
17
22
|
"dependency-cruiser.config.js",
|
|
@@ -108,7 +113,7 @@
|
|
|
108
113
|
"checks-docs": "scripts/docs.ts"
|
|
109
114
|
},
|
|
110
115
|
"scripts": {
|
|
111
|
-
"build": "bun build effect-channel/index.ts --outdir dist --target node --format esm && bun build scripts/feature-rules.ts --outdir dist --target node --format esm --packages external && bun scripts/quality-schema.ts && bun scripts/doc-templates-write.ts",
|
|
116
|
+
"build": "bun build effect-channel/index.ts --outdir dist --target node --format esm && bun build scripts/feature-rules.ts --outdir dist --target node --format esm --packages external && bun scripts/quality-schema.ts && bun scripts/doc-templates-write.ts && bun scripts/changelog-write.ts && bun scripts/doc-blocks-write.ts",
|
|
112
117
|
"lint": "oxlint --type-aware && bun scripts/lint.ts && depcruise --config .dependency-cruiser.cjs .",
|
|
113
118
|
"typecheck": "tsc --noEmit && effect-tsgo diagnostics --project tsconfig.json --format text --strict",
|
|
114
119
|
"test": "bun scripts/test.ts"
|
package/scripts/doc-rules.ts
CHANGED
|
@@ -26,14 +26,15 @@ export type Doc = {
|
|
|
26
26
|
|
|
27
27
|
export const ADR_DIRECTORY = "docs/adr/";
|
|
28
28
|
// A generated index takes its shape from its generator.
|
|
29
|
-
const ADR_INDEX = `${ADR_DIRECTORY}README.md`;
|
|
29
|
+
export const ADR_INDEX = `${ADR_DIRECTORY}README.md`;
|
|
30
30
|
const DOCS_DIRECTORY = "docs/";
|
|
31
31
|
|
|
32
|
-
const ROOT_FILES = new Map<string, Kind>([
|
|
32
|
+
export const ROOT_FILES: ReadonlyMap<string, Kind> = new Map<string, Kind>([
|
|
33
33
|
["README.md", "readme"],
|
|
34
34
|
["CHANGELOG.md", "changelog"],
|
|
35
35
|
["AGENTS.md", "agents"],
|
|
36
36
|
["CLAUDE.md", "claude"],
|
|
37
|
+
["CONTRIBUTING.md", "how-to"],
|
|
37
38
|
]);
|
|
38
39
|
|
|
39
40
|
export function placementOf(path: string, docs: Docs | undefined): Placement {
|
|
@@ -113,7 +114,7 @@ function adrProblems(path: string, outline: Outline, records: readonly string[])
|
|
|
113
114
|
return violations;
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
const RELEASED = /^Released (\S+)\.$/;
|
|
117
|
+
export const RELEASED = /^Released (\S+)\.$/;
|
|
117
118
|
|
|
118
119
|
function changelogProblems({ sections }: Outline): readonly Violation[] {
|
|
119
120
|
const releases = sections.filter(({ heading }) => VERSION.test(heading.title));
|
package/scripts/doc-templates.ts
CHANGED
|
@@ -40,7 +40,7 @@ function open(placeholder: string, rule: HeadingRule, presence: Presence, body:
|
|
|
40
40
|
return { type: "open", placeholder, rule, presence, body, ...more };
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
function listed(words: readonly string[]): string {
|
|
43
|
+
export function listed(words: readonly string[]): string {
|
|
44
44
|
return words.length < 2 ? words.join("") : `${words.slice(0, -1).join(", ")} or ${words.at(-1) ?? ""}`;
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -64,7 +64,8 @@ const MAINTAINING = [
|
|
|
64
64
|
"When updating this file, preserve this bar for all agents and keep entries concise.",
|
|
65
65
|
];
|
|
66
66
|
|
|
67
|
-
const CHANGE_GROUPS = ["Breaking changes", "Features", "Fixes", "Performance", "Reverts"];
|
|
67
|
+
export const CHANGE_GROUPS = ["Breaking changes", "Features", "Fixes", "Performance", "Reverts"] as const;
|
|
68
|
+
export type ChangeGroup = (typeof CHANGE_GROUPS)[number];
|
|
68
69
|
|
|
69
70
|
export const TEMPLATES: Readonly<Record<Kind, Template>> = {
|
|
70
71
|
readme: {
|
|
@@ -74,7 +75,11 @@ export const TEMPLATES: Readonly<Record<Kind, Template>> = {
|
|
|
74
75
|
sections: [
|
|
75
76
|
BEFORE_YOU_BEGIN,
|
|
76
77
|
fixed("Install", REQUIRED, ["To install <name>:", "", "1. <step>", "1. <step>", "", "<What you see when it worked.>"]),
|
|
77
|
-
open("<Everyday task, verb first>", "any", REQUIRED,
|
|
78
|
+
open("<Everyday task, verb first, or what the reader looks up>", "any", REQUIRED, [
|
|
79
|
+
...STEPS,
|
|
80
|
+
"",
|
|
81
|
+
"<Or, for what the reader looks up, a table or a list with no steps.>",
|
|
82
|
+
]),
|
|
78
83
|
fixed("Where things are", REQUIRED, ["| Path | What it holds |", "| --- | --- |"]),
|
|
79
84
|
TROUBLESHOOTING,
|
|
80
85
|
RELATED_TOPICS,
|
|
@@ -87,7 +92,7 @@ export const TEMPLATES: Readonly<Record<Kind, Template>> = {
|
|
|
87
92
|
sections: [
|
|
88
93
|
open("<version>", "version", REQUIRED, ["Released <YYYY-MM-DD>."], {
|
|
89
94
|
subsections: CHANGE_GROUPS.map((group) =>
|
|
90
|
-
fixed(group, optional("the release holds no such commit"), ["-
|
|
95
|
+
fixed(group, optional("the release holds no such commit"), ["- **<the commit's scope, when it has one>:** <its description>"]),
|
|
91
96
|
),
|
|
92
97
|
}),
|
|
93
98
|
],
|
|
@@ -121,7 +126,7 @@ export const TEMPLATES: Readonly<Record<Kind, Template>> = {
|
|
|
121
126
|
},
|
|
122
127
|
claude: {
|
|
123
128
|
shape: "exact",
|
|
124
|
-
text: "<!-- Points Claude at AGENTS.md via import
|
|
129
|
+
text: "<!-- Points Claude at AGENTS.md via import; edit AGENTS.md, not this file. -->\n@AGENTS.md\n",
|
|
125
130
|
},
|
|
126
131
|
tutorial: {
|
|
127
132
|
shape: "outline",
|
package/scripts/quality-file.ts
CHANGED
|
@@ -221,7 +221,7 @@ export const Quality = Schema.Struct({
|
|
|
221
221
|
);
|
|
222
222
|
export type Quality = typeof Quality.Type;
|
|
223
223
|
|
|
224
|
-
const LegacyManifest = Schema.Struct({
|
|
224
|
+
export const LegacyManifest = Schema.Struct({
|
|
225
225
|
ciWiring: Schema.optionalKey(
|
|
226
226
|
Schema.Struct({
|
|
227
227
|
gates: Schema.optionalKey(Schema.NonEmptyArray(Command)),
|
package/templates/changelog.md
CHANGED
|
@@ -10,28 +10,28 @@ Released <YYYY-MM-DD>.
|
|
|
10
10
|
|
|
11
11
|
<Leave this section out when the release holds no such commit.>
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- **<the commit's scope, when it has one>:** <its description>
|
|
14
14
|
|
|
15
15
|
### Features
|
|
16
16
|
|
|
17
17
|
<Leave this section out when the release holds no such commit.>
|
|
18
18
|
|
|
19
|
-
-
|
|
19
|
+
- **<the commit's scope, when it has one>:** <its description>
|
|
20
20
|
|
|
21
21
|
### Fixes
|
|
22
22
|
|
|
23
23
|
<Leave this section out when the release holds no such commit.>
|
|
24
24
|
|
|
25
|
-
-
|
|
25
|
+
- **<the commit's scope, when it has one>:** <its description>
|
|
26
26
|
|
|
27
27
|
### Performance
|
|
28
28
|
|
|
29
29
|
<Leave this section out when the release holds no such commit.>
|
|
30
30
|
|
|
31
|
-
-
|
|
31
|
+
- **<the commit's scope, when it has one>:** <its description>
|
|
32
32
|
|
|
33
33
|
### Reverts
|
|
34
34
|
|
|
35
35
|
<Leave this section out when the release holds no such commit.>
|
|
36
36
|
|
|
37
|
-
-
|
|
37
|
+
- **<the commit's scope, when it has one>:** <its description>
|
package/templates/claude.md
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<!-- Points Claude at AGENTS.md via import
|
|
1
|
+
<!-- Points Claude at AGENTS.md via import; edit AGENTS.md, not this file. -->
|
|
2
2
|
@AGENTS.md
|
package/templates/readme.md
CHANGED
|
@@ -15,13 +15,15 @@ To install <name>:
|
|
|
15
15
|
|
|
16
16
|
<What you see when it worked.>
|
|
17
17
|
|
|
18
|
-
## <Everyday task, verb first>
|
|
18
|
+
## <Everyday task, verb first, or what the reader looks up>
|
|
19
19
|
|
|
20
20
|
To <do the task>:
|
|
21
21
|
|
|
22
22
|
1. <step>
|
|
23
23
|
1. <step>
|
|
24
24
|
|
|
25
|
+
<Or, for what the reader looks up, a table or a list with no steps.>
|
|
26
|
+
|
|
25
27
|
## Where things are
|
|
26
28
|
|
|
27
29
|
| Path | What it holds |
|