Two files, one repository
microsoft/TypeScript ships 2 formats across 2 indexed files. The question worth asking is whether the second one says anything the first does not.
| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 3 | 0 | 31 | 9% |
| Commands | 0 | 0 | 16 | 0% |
| Section tags | 2 | 0 | 10 | 17% |
What each file covers
Sections
3 shared · 0 only in A · 31 only in B- + Guide for Copilot
- + Build Instructions Summary
- + Setup
- + Common Build Tasks
- + Fourslash Test Syntax Guide
- + Basic Structure
- + Key Syntax Elements
- + Common API Patterns
- + Simple Example
- + Compiler Test Syntax Guide
- + Compiler Directives
- + Common Directives
- + Multi-file Tests
- + Error Expectations
- + Type Testing Patterns
- + Test Writing Best Practices
- + For Fourslash Tests
- + For Compiler Tests
- + General Guidelines
- + Running Specific Tests
- + Run a specific fourslash test
- + Run a specific compiler test
- + Run tests matching a pattern
- + Important Guidelines
- + 🚨 CRITICAL: Before Finishing Your Work 🚨
- + Keeping Things Tidy
- + Test Locations
- + Performance Expectations
- + Working with Issues
- + Debugging Tips
- + Recommended Workflow
- 🚨 CRITICAL: This Repository Is in Maintenance Mode 🚨
- ❌ DO NOT create coding PRs for this repository
- Required behavior for coding agents
Commands
0 shared · 0 only in A · 16 only in B- + npx hereby local
- + npx hereby clean
- + npx hereby tests
- + npx hereby runtests
- + npx hereby runtests-parallel
- + npx hereby runtests --runner=fourslash
- + npx hereby runtests --runner=compiler
- + npx hereby runtests --tests=<testPath>
- + npx hereby baseline-accept
- + npx hereby lint
- + npx hereby format
- + npx hereby runtests --tests=tests/cases/fourslash/completionForObjectProperty.ts
- + npx hereby runtests --tests=tests/cases/compiler/abstractClassUnionInstantiation.ts
- + npx hereby runtests --tests=tests/cases/fourslash/completion*.ts
- + git clone --depth=1 https://github.com/microsoft/TypeScript
- + npm ci
Section tags
2 shared · 0 only in A · 10 only in B- + setup
- + build
- + test
- + lint-format
- + code-style
- + architecture
- + types
- + api
- + performance
- + agent-behaviour
- git-pr
- do-not
Line diff
microsoft/TypeScript · AGENTS.md
@@ −27 @@
27
28---
29
30For detailed build instructions, test writing guides, and workflow recommendations, see [`.github/copilot-instructions.md`](.github/copilot-instructions.md).
31
microsoft/TypeScript · .github/copilot-instructions.md
@@ +27 @@
27
28---
29
30# Guide for Copilot
31
32This document provides a concise guide for writing TypeScript fourslash tests and compiler tests, along with build instructions.
33
34## Build Instructions Summary
35
36### Setup
371. Install Node.js (current or LTS)
382. Clone the repository: `git clone --depth=1 https://github.com/microsoft/TypeScript`
393. Install dependencies: `npm ci`
40
41### Common Build Tasks
42```bash
43npx hereby local # Build the compiler into built/local
44npx hereby clean # Delete the built compiler
45npx hereby tests # Build the test infrastructure
46npx hereby runtests # Run all tests
47npx hereby runtests-parallel # Run tests in parallel 🚨 MANDATORY BEFORE FINISHING!
48npx hereby runtests --runner=fourslash # Run only fourslash tests
49npx hereby runtests --runner=compiler # Run only compiler tests
50npx hereby runtests --tests=<testPath> # Run specific test
51npx hereby baseline-accept # Accept new test baselines
52npx hereby lint # Run eslint 🚨 MANDATORY BEFORE FINISHING!
53npx hereby format # Run code formatting 🚨 MANDATORY BEFORE FINISHING!
54```
55
56## Fourslash Test Syntax Guide
57
58Fourslash tests are interactive TypeScript language service tests. They validate IDE features like completions, quick info, navigation, and refactoring.
59
60### Basic Structure
61```typescript
62/// <reference path='fourslash.ts'/>
63
64////code goes here with /*markers*/
65
66// Test assertions go here
67```
68
69### Key Syntax Elements
70
71#### 1. Source Code Definition
72Use `////` to define source code lines:
73```typescript
74////function foo(x: number) {
75//// return x + 1;
76////}
77////let result = foo(/*marker*/42);
78```
79
80#### 2. Markers for Positioning
81Use `/**/` for anonymous markers or `/*name*/` for named markers:
82```typescript
83////let x = /*1*/someValue;
84////let y = /*cursor*/anotherValue;
85```
86
87#### 3. Multi-file Tests
88Use `// @Filename:` to define multiple files:
89```typescript
90// @Filename: /a.ts
91////export const value = 42;
92
93// @Filename: /b.ts
94////import { value } from './a';
95////console.log(/*marker*/value);
96```
97
98#### 4. Ranges
99Use `[|text|]` to define text ranges:
100```typescript
101////function test() {
102//// [|return 42;|]
103////}
104```
105
106### Common API Patterns
107
108#### Navigation & Positioning
109```typescript
110goTo.marker("markerName"); // Navigate to marker
111goTo.marker(); // Navigate to anonymous marker /**/
112```
113
114#### Verification (Prefer these over baselines)
115```typescript
116verify.currentLineContentIs("expected content");
117verify.completions({ includes: "itemName" });
118verify.completions({ excludes: "itemName" });
119verify.quickInfoIs("expected info");
120verify.codeFix({
121 description: "Fix description",
122 newFileContent: "expected content after fix"
123});
124```
125
126#### Completions Testing
127```typescript
128verify.completions({
129 marker: "1",
130 includes: { name: "foo", source: "/a", hasAction: true },
131 isNewIdentifierLocation: true,
132 preferences: { includeCompletionsForModuleExports: true }
133});
134```
135
136#### Code Fixes Testing
137```typescript
138verify.codeFix({
139 description: "Add missing property",
140 index: 0,
141 newFileContent: `class C {
142 property: string;
143 method() { this.property = "value"; }
144}`
145});
146```
147
148#### Formatting
149```typescript
150format.document();
151verify.currentLineContentIs("formatted content");
152```
153
154### Simple Example
155```typescript
156/// <reference path='fourslash.ts'/>
157
158////interface User {
159//// name: string;
160////}
161////
162////const user: User = {
163//// /*completion*/
164////};
165
166verify.completions({
167 marker: "completion",
168 includes: { name: "name", sortText: "0" }
169});
170```
171
172## Compiler Test Syntax Guide
173
174Compiler tests validate TypeScript compilation behavior, type checking, and error reporting.
175
176### Basic Structure
177- Simple `.ts` files in `tests/cases/compiler/`
178- Use comments to indicate expected behavior
179- No special test harness - just TypeScript code
180
181### Compiler Directives
182Use `// @directive: value` for compiler options:
183```typescript
184// @strict: true
185// @target: ES2015
186// @lib: ES2015,DOM
187
188let x: string = 42; // Error expected
189```
190
191### Common Directives
192```typescript
193// @strict: true/false
194// @noImplicitAny: true/false
195// @target: ES5/ES2015/ES2020/ESNext
196// @module: commonjs/amd/es6/esnext
197// @lib: ES5,DOM/ES2015/ES2020
198// @declaration: true/false
199// @skipLibCheck: true/false
200```
201
202### Multi-file Tests
203```typescript
204// @Filename: helper.ts
205export function helper(x: number): string {
206 return x.toString();
207}
208
209// @Filename: main.ts
210import { helper } from "./helper";
211const result = helper(42);
212```
213
214### Error Expectations
215Use comments to document expected behavior:
216```typescript
217abstract class Base {
218 abstract method(): void;
219}
220
221class Derived extends Base {
222 // Missing implementation - should error
223}
224
225new Base(); // Should error - cannot instantiate abstract class
226```
227
228### Type Testing Patterns
229```typescript
230// Test type inference
231let inferred = [1, 2, 3]; // Should infer number[]
232
233// Test type compatibility
234type A = { x: number };
235type B = { x: number; y: string };
236let a: A = { x: 1 };
237let b: B = { x: 1, y: "hello" };
238a = b; // Should work - B is assignable to A
239b = a; // Should error - A missing property y
240```
241
242### Simple Example
243```typescript
244// Test that optional properties work correctly
245interface Config {
246 required: string;
247 optional?: number;
248}
249
250const config1: Config = { required: "test" }; // Should work
251const config2: Config = { required: "test", optional: 42 }; // Should work
252const config3: Config = { optional: 42 }; // Should error - missing required
253```
254
255## Test Writing Best Practices
256
257### For Fourslash Tests
2581. **Prefer validation over baselines** - Use `verify.currentLineContentIs()` instead of `verify.baseline*()`
2592. **Use simple, focused examples** - Test one feature at a time
2603. **Name markers clearly** - Use descriptive marker names like `/*completion*/`
2614. **Test the simplest form first** - Start with basic cases before complex scenarios
262
263### For Compiler Tests
2641. **Use clear file names** - Name tests after the feature being tested
2652. **Add explanatory comments** - Document expected behavior with comments
2663. **Test error cases** - Include both valid and invalid code examples
2674. **Keep tests focused** - One primary feature per test file
268
269### General Guidelines
2701. **Make tests deterministic** - Avoid random or environment-dependent behavior
2712. **Use realistic examples** - Test scenarios developers actually encounter
2723. **Start simple** - Begin with the most basic case of a feature
2734. **Test edge cases** - Include boundary conditions and error scenarios
274
275## Running Specific Tests
276
277```bash
278# Run a specific fourslash test
279npx hereby runtests --tests=tests/cases/fourslash/completionForObjectProperty.ts
280
281# Run a specific compiler test
282npx hereby runtests --tests=tests/cases/compiler/abstractClassUnionInstantiation.ts
283
284# Run tests matching a pattern
285npx hereby runtests --tests=tests/cases/fourslash/completion*.ts
286```
287
288## Important Guidelines
289
290### 🚨 CRITICAL: Before Finishing Your Work 🚨
291
292**THESE STEPS ARE MANDATORY BEFORE COMMITTING/PUSHING ANY CHANGES:**
293
2941. **MUST RUN:** `npx hereby runtests-parallel` (even though it takes 10-15 minutes)
2952. **MUST RUN:** `npx hereby lint` and fix ALL lint issues
2963. **MUST RUN:** `npx hereby format` as the final step
297
298**❌ PRs that fail these checks will be rejected without review.**
299
300### Keeping Things Tidy
301
302- You can assume lint, tests, and formatting are clean on a fresh clone
303- Only run these verification steps AFTER making changes to code
304- Run `npx hereby lint` and fix ALL issues after making changes
305- Run `npx hereby format` as your final step after making changes
306
307### Test Locations
308
309- Only add testcases in `tests/cases/compiler` or `tests/cases/fourslash`
310- Filenames in `tests/cases/compiler` must always end with `.ts`, not `.d.ts`
311- Do not write direct unit tests as they are almost never the correct test format for our repo
312
313### Performance Expectations
314
315- Running a set of tests may take up to 4 minutes
316- A full test run may take up to 15 minutes
317
318### Working with Issues
319
320- Maintainer comments in the issue should generally take priority over OP's comments
321- Maintainers might give you hints on where to start. They are not always right, but a good place to start
322
323### Debugging Tips
324
325printf debugging is going to be very useful as you are figuring things out.
326To do this, use `console.log`, but you'll need to `ts-ignore` it.
327Write something like this:
328```ts,diff
329function checkSomething(n: Node) {
330 doSomething(n);
331+ // @ts-ignore DEBUG CODE ONLY, REMOVE ME WHEN DONE
332+ console.log(`Got node with pos = ${n.pos}`);
333 doSomethingElse(n);
334}
335```
336We have a lot of enums so you might want to print back their symbolic name, to do this, index back into the name of the enum
337```ts
338 // @ts-ignore DEBUG CODE ONLY, REMOVE ME WHEN DONE
339 console.log(`Got node with kind = ${SyntaxKind[n.kind]}`);
340```
341
342## Recommended Workflow
343
344When fixing bugs or implementing features, follow this workflow:
345
3461. **Make a testcase that demonstrates the behavior**
347 - Run it (by itself) and review the baselines it generates to ensure it demonstrates the bug
348 - Add the test and its baselines in one commit
349
3502. **Fix the bug by changing code as appropriate**
351 - Put this fix in another commit
352
3533. **Run the test you wrote again**
354 - Ensure the baselines change in a way that demonstrates that the bug is fixed
355 - Put this baseline diff in its own commit
356
3574. **Add more testing**
358 - Once you've got the basics figured out, enhance your test to cover edge cases and other variations
359 - Run the test again and commit the baseline diff along with the test edit
360
3615. **🚨 MANDATORY: Run all other tests to ensure you didn't break anything**
362 - **REQUIRED:** Run `npx hereby runtests-parallel` and wait for it to finish (10-15 minutes is normal!)
363 - **THIS STEP CANNOT BE SKIPPED** - patience is essential!
364 - Some collateral baseline changes are normal, but review for correctness
365 - Put these diffs in another commit
366
3676. **🚨 MANDATORY: Lint and format your changes**
368 - **REQUIRED:** Run `npx hereby lint` and fix ALL issues
369 - **REQUIRED:** Run `npx hereby format` before you're done
370 - **YOU CANNOT FINISH WITHOUT THESE STEPS**
371 - Double-check your line endings. Source files in this repo typically use CRLF line endings. Fix all line endings to be consistent before you wrap up
372
@@ −27 +27 @@
2727
2828 ---
2929
30−For detailed build instructions, test writing guides, and workflow recommendations, see [`.github/copilot-instructions.md`](.github/copilot-instructions.md).
30+# Guide for Copilot
31+
32+This document provides a concise guide for writing TypeScript fourslash tests and compiler tests, along with build instructions.
33+
34+## Build Instructions Summary
35+
36+### Setup
37+1. Install Node.js (current or LTS)
38+2. Clone the repository: `git clone --depth=1 https://github.com/microsoft/TypeScript`
39+3. Install dependencies: `npm ci`
40+
41+### Common Build Tasks
42+```bash
43+npx hereby local # Build the compiler into built/local
44+npx hereby clean # Delete the built compiler
45+npx hereby tests # Build the test infrastructure
46+npx hereby runtests # Run all tests
47+npx hereby runtests-parallel # Run tests in parallel 🚨 MANDATORY BEFORE FINISHING!
48+npx hereby runtests --runner=fourslash # Run only fourslash tests
49+npx hereby runtests --runner=compiler # Run only compiler tests
50+npx hereby runtests --tests=<testPath> # Run specific test
51+npx hereby baseline-accept # Accept new test baselines
52+npx hereby lint # Run eslint 🚨 MANDATORY BEFORE FINISHING!
53+npx hereby format # Run code formatting 🚨 MANDATORY BEFORE FINISHING!
54+```
55+
56+## Fourslash Test Syntax Guide
57+
58+Fourslash tests are interactive TypeScript language service tests. They validate IDE features like completions, quick info, navigation, and refactoring.
59+
60+### Basic Structure
61+```typescript
62+/// <reference path='fourslash.ts'/>
63+
64+////code goes here with /*markers*/
65+
66+// Test assertions go here
67+```
68+
69+### Key Syntax Elements
70+
71+#### 1. Source Code Definition
72+Use `////` to define source code lines:
73+```typescript
74+////function foo(x: number) {
75+//// return x + 1;
76+////}
77+////let result = foo(/*marker*/42);
78+```
79+
80+#### 2. Markers for Positioning
81+Use `/**/` for anonymous markers or `/*name*/` for named markers:
82+```typescript
83+////let x = /*1*/someValue;
84+////let y = /*cursor*/anotherValue;
85+```
86+
87+#### 3. Multi-file Tests
88+Use `// @Filename:` to define multiple files:
89+```typescript
90+// @Filename: /a.ts
91+////export const value = 42;
92+
93+// @Filename: /b.ts
94+////import { value } from './a';
95+////console.log(/*marker*/value);
96+```
97+
98+#### 4. Ranges
99+Use `[|text|]` to define text ranges:
100+```typescript
101+////function test() {
102+//// [|return 42;|]
103+////}
104+```
105+
106+### Common API Patterns
107+
108+#### Navigation & Positioning
109+```typescript
110+goTo.marker("markerName"); // Navigate to marker
111+goTo.marker(); // Navigate to anonymous marker /**/
112+```
113+
114+#### Verification (Prefer these over baselines)
115+```typescript
116+verify.currentLineContentIs("expected content");
117+verify.completions({ includes: "itemName" });
118+verify.completions({ excludes: "itemName" });
119+verify.quickInfoIs("expected info");
120+verify.codeFix({
121+ description: "Fix description",
122+ newFileContent: "expected content after fix"
123+});
124+```
125+
126+#### Completions Testing
127+```typescript
128+verify.completions({
129+ marker: "1",
130+ includes: { name: "foo", source: "/a", hasAction: true },
131+ isNewIdentifierLocation: true,
132+ preferences: { includeCompletionsForModuleExports: true }
133+});
134+```
135+
136+#### Code Fixes Testing
137+```typescript
138+verify.codeFix({
139+ description: "Add missing property",
140+ index: 0,
141+ newFileContent: `class C {
142+ property: string;
143+ method() { this.property = "value"; }
144+}`
145+});
146+```
147+
148+#### Formatting
149+```typescript
150+format.document();
151+verify.currentLineContentIs("formatted content");
152+```
153+
154+### Simple Example
155+```typescript
156+/// <reference path='fourslash.ts'/>
157+
158+////interface User {
159+//// name: string;
160+////}
161+////
162+////const user: User = {
163+//// /*completion*/
164+////};
165+
166+verify.completions({
167+ marker: "completion",
168+ includes: { name: "name", sortText: "0" }
169+});
170+```
171+
172+## Compiler Test Syntax Guide
173+
174+Compiler tests validate TypeScript compilation behavior, type checking, and error reporting.
175+
176+### Basic Structure
177+- Simple `.ts` files in `tests/cases/compiler/`
178+- Use comments to indicate expected behavior
179+- No special test harness - just TypeScript code
180+
181+### Compiler Directives
182+Use `// @directive: value` for compiler options:
183+```typescript
184+// @strict: true
185+// @target: ES2015
186+// @lib: ES2015,DOM
187+
188+let x: string = 42; // Error expected
189+```
190+
191+### Common Directives
192+```typescript
193+// @strict: true/false
194+// @noImplicitAny: true/false
195+// @target: ES5/ES2015/ES2020/ESNext
196+// @module: commonjs/amd/es6/esnext
197+// @lib: ES5,DOM/ES2015/ES2020
198+// @declaration: true/false
199+// @skipLibCheck: true/false
200+```
201+
202+### Multi-file Tests
203+```typescript
204+// @Filename: helper.ts
205+export function helper(x: number): string {
206+ return x.toString();
207+}
208+
209+// @Filename: main.ts
210+import { helper } from "./helper";
211+const result = helper(42);
212+```
213+
214+### Error Expectations
215+Use comments to document expected behavior:
216+```typescript
217+abstract class Base {
218+ abstract method(): void;
219+}
220+
221+class Derived extends Base {
222+ // Missing implementation - should error
223+}
224+
225+new Base(); // Should error - cannot instantiate abstract class
226+```
227+
228+### Type Testing Patterns
229+```typescript
230+// Test type inference
231+let inferred = [1, 2, 3]; // Should infer number[]
232+
233+// Test type compatibility
234+type A = { x: number };
235+type B = { x: number; y: string };
236+let a: A = { x: 1 };
237+let b: B = { x: 1, y: "hello" };
238+a = b; // Should work - B is assignable to A
239+b = a; // Should error - A missing property y
240+```
241+
242+### Simple Example
243+```typescript
244+// Test that optional properties work correctly
245+interface Config {
246+ required: string;
247+ optional?: number;
248+}
249+
250+const config1: Config = { required: "test" }; // Should work
251+const config2: Config = { required: "test", optional: 42 }; // Should work
252+const config3: Config = { optional: 42 }; // Should error - missing required
253+```
254+
255+## Test Writing Best Practices
256+
257+### For Fourslash Tests
258+1. **Prefer validation over baselines** - Use `verify.currentLineContentIs()` instead of `verify.baseline*()`
259+2. **Use simple, focused examples** - Test one feature at a time
260+3. **Name markers clearly** - Use descriptive marker names like `/*completion*/`
261+4. **Test the simplest form first** - Start with basic cases before complex scenarios
262+
263+### For Compiler Tests
264+1. **Use clear file names** - Name tests after the feature being tested
265+2. **Add explanatory comments** - Document expected behavior with comments
266+3. **Test error cases** - Include both valid and invalid code examples
267+4. **Keep tests focused** - One primary feature per test file
268+
269+### General Guidelines
270+1. **Make tests deterministic** - Avoid random or environment-dependent behavior
271+2. **Use realistic examples** - Test scenarios developers actually encounter
272+3. **Start simple** - Begin with the most basic case of a feature
273+4. **Test edge cases** - Include boundary conditions and error scenarios
274+
275+## Running Specific Tests
276+
277+```bash
278+# Run a specific fourslash test
279+npx hereby runtests --tests=tests/cases/fourslash/completionForObjectProperty.ts
280+
281+# Run a specific compiler test
282+npx hereby runtests --tests=tests/cases/compiler/abstractClassUnionInstantiation.ts
283+
284+# Run tests matching a pattern
285+npx hereby runtests --tests=tests/cases/fourslash/completion*.ts
286+```
287+
288+## Important Guidelines
289+
290+### 🚨 CRITICAL: Before Finishing Your Work 🚨
291+
292+**THESE STEPS ARE MANDATORY BEFORE COMMITTING/PUSHING ANY CHANGES:**
293+
294+1. **MUST RUN:** `npx hereby runtests-parallel` (even though it takes 10-15 minutes)
295+2. **MUST RUN:** `npx hereby lint` and fix ALL lint issues
296+3. **MUST RUN:** `npx hereby format` as the final step
297+
298+**❌ PRs that fail these checks will be rejected without review.**
299+
300+### Keeping Things Tidy
301+
302+- You can assume lint, tests, and formatting are clean on a fresh clone
303+- Only run these verification steps AFTER making changes to code
304+- Run `npx hereby lint` and fix ALL issues after making changes
305+- Run `npx hereby format` as your final step after making changes
306+
307+### Test Locations
308+
309+- Only add testcases in `tests/cases/compiler` or `tests/cases/fourslash`
310+- Filenames in `tests/cases/compiler` must always end with `.ts`, not `.d.ts`
311+- Do not write direct unit tests as they are almost never the correct test format for our repo
312+
313+### Performance Expectations
314+
315+- Running a set of tests may take up to 4 minutes
316+- A full test run may take up to 15 minutes
317+
318+### Working with Issues
319+
320+- Maintainer comments in the issue should generally take priority over OP's comments
321+- Maintainers might give you hints on where to start. They are not always right, but a good place to start
322+
323+### Debugging Tips
324+
325+printf debugging is going to be very useful as you are figuring things out.
326+To do this, use `console.log`, but you'll need to `ts-ignore` it.
327+Write something like this:
328+```ts,diff
329+function checkSomething(n: Node) {
330+ doSomething(n);
331++ // @ts-ignore DEBUG CODE ONLY, REMOVE ME WHEN DONE
332++ console.log(`Got node with pos = ${n.pos}`);
333+ doSomethingElse(n);
334+}
335+```
336+We have a lot of enums so you might want to print back their symbolic name, to do this, index back into the name of the enum
337+```ts
338+ // @ts-ignore DEBUG CODE ONLY, REMOVE ME WHEN DONE
339+ console.log(`Got node with kind = ${SyntaxKind[n.kind]}`);
340+```
341+
342+## Recommended Workflow
343+
344+When fixing bugs or implementing features, follow this workflow:
345+
346+1. **Make a testcase that demonstrates the behavior**
347+ - Run it (by itself) and review the baselines it generates to ensure it demonstrates the bug
348+ - Add the test and its baselines in one commit
349+
350+2. **Fix the bug by changing code as appropriate**
351+ - Put this fix in another commit
352+
353+3. **Run the test you wrote again**
354+ - Ensure the baselines change in a way that demonstrates that the bug is fixed
355+ - Put this baseline diff in its own commit
356+
357+4. **Add more testing**
358+ - Once you've got the basics figured out, enhance your test to cover edge cases and other variations
359+ - Run the test again and commit the baseline diff along with the test edit
360+
361+5. **🚨 MANDATORY: Run all other tests to ensure you didn't break anything**
362+ - **REQUIRED:** Run `npx hereby runtests-parallel` and wait for it to finish (10-15 minutes is normal!)
363+ - **THIS STEP CANNOT BE SKIPPED** - patience is essential!
364+ - Some collateral baseline changes are normal, but review for correctness
365+ - Put these diffs in another commit
366+
367+6. **🚨 MANDATORY: Lint and format your changes**
368+ - **REQUIRED:** Run `npx hereby lint` and fix ALL issues
369+ - **REQUIRED:** Run `npx hereby format` before you're done
370+ - **YOU CANNOT FINISH WITHOUT THESE STEPS**
371+ - Double-check your line endings. Source files in this repo typically use CRLF line endings. Fix all line endings to be consistent before you wrap up
31372
