@apptoolkit/harness 1.0.0 → 1.0.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/README.md +20 -45
- package/{dist/bun/npm/harness.js → harness.js} +3 -3
- package/package.json +9 -23
- package/{dist/bun/npm/payload → payload}/harness/runtime/harness.mjs +3 -3
- package/dist/apptoolkit-harness-1.0.0.tgz +0 -0
- package/dist/bun/apptoolkit-harness-1.0.0.tgz +0 -0
- package/dist/bun/native/README.md +0 -33
- package/dist/bun/native/harness +0 -4
- package/dist/bun/native/payload/harness/runtime/harness.mjs +0 -104
- package/dist/bun/npm/LICENSE +0 -21
- package/dist/bun/npm/README.md +0 -33
- package/dist/bun/npm/package.json +0 -23
- package/dist/bun/npm/payload/HARNESS.md +0 -21
- package/dist/bun/npm/payload/author-style/README.md +0 -56
- package/dist/bun/npm/payload/author-style/biome-core.json +0 -57
- package/dist/bun/npm/payload/author-style/biome-react.json +0 -9
- package/dist/bun/npm/payload/author-style/biome-sql.json +0 -9
- package/dist/bun/npm/payload/author-style/bun.lock +0 -37
- package/dist/bun/npm/payload/author-style/check.llm.md +0 -17
- package/dist/bun/npm/payload/author-style/check.test.llm.md +0 -17
- package/dist/bun/npm/payload/author-style/check.test.ts +0 -238
- package/dist/bun/npm/payload/author-style/check.ts +0 -181
- package/dist/bun/npm/payload/author-style/member-spacing.test.ts +0 -172
- package/dist/bun/npm/payload/author-style/member-spacing.ts +0 -106
- package/dist/bun/npm/payload/author-style/package.json +0 -18
- package/dist/bun/npm/payload/author-style/plugins/class-member-order.grit +0 -133
- package/dist/bun/npm/payload/author-style/plugins/event-handler-names.grit +0 -110
- package/dist/bun/npm/payload/author-style/plugins/explicit-arrow-body.grit +0 -15
- package/dist/bun/npm/payload/author-style/plugins/explicit-source-constructs.grit +0 -10
- package/dist/bun/npm/payload/author-style/plugins/react-arrow-body.grit +0 -85
- package/dist/bun/npm/payload/author-style/plugins/sql-style.grit +0 -125
- package/dist/bun/npm/payload/author-style/react-module.llm.md +0 -17
- package/dist/bun/npm/payload/author-style/react-module.test.ts +0 -150
- package/dist/bun/npm/payload/author-style/react-module.ts +0 -255
- package/dist/bun/npm/payload/author-style/source-policy.llm.md +0 -17
- package/dist/bun/npm/payload/author-style/source-policy.test.ts +0 -70
- package/dist/bun/npm/payload/author-style/source-policy.ts +0 -215
- package/dist/bun/npm/payload/author-style/spacing.llm.md +0 -17
- package/dist/bun/npm/payload/author-style/spacing.test.ts +0 -174
- package/dist/bun/npm/payload/author-style/spacing.ts +0 -211
- package/dist/bun/npm/payload/harness/POLICY.md +0 -33
- package/dist/bun/npm/payload/harness/PROJECT.md +0 -26
- package/dist/bun/npm/payload/harness/REVIEW.md +0 -17
- package/dist/bun/npm/payload/harness/TEMPLATES.md +0 -20
- package/dist/bun/npm/payload/harness/WORKFLOWS.md +0 -65
- package/dist/bun/npm/payload/harness/runtime/ZOD-LICENSE +0 -21
- package/dist/bun/npm/payload/harness/services/README.md +0 -26
- package/dist/bun/npm/payload/harness/services/penpot.json +0 -7
- package/dist/bun/npm/payload/harness/services/plane.json +0 -9
- package/dist/bun/npm/payload/harness/workflows/W01.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W02.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W03.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W04.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W05.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W06.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W07.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W08.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W09.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W10.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W11.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W12.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W13.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W14.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W15.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W16.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W17.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W18.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W19.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W20.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W21.md +0 -15
- package/dist/bun/npm/payload/harness/workflows/W22.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W23.md +0 -21
- package/dist/bun/npm/payload/harness/workflows/W24.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W25.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W26.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W27.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W28.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W29.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W30.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W31.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W32.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W33.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W34.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W35.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W36.md +0 -13
- package/dist/bun/npm/payload/harness/workflows/W37.md +0 -13
- package/dist/npm/LICENSE +0 -21
- package/dist/npm/README.md +0 -30
- package/dist/npm/harness.js +0 -104
- package/dist/npm/package.json +0 -25
- package/dist/npm/payload/HARNESS.md +0 -21
- package/dist/npm/payload/author-style/README.md +0 -56
- package/dist/npm/payload/author-style/biome-core.json +0 -57
- package/dist/npm/payload/author-style/biome-react.json +0 -9
- package/dist/npm/payload/author-style/biome-sql.json +0 -9
- package/dist/npm/payload/author-style/check.llm.md +0 -17
- package/dist/npm/payload/author-style/check.test.llm.md +0 -17
- package/dist/npm/payload/author-style/check.test.ts +0 -224
- package/dist/npm/payload/author-style/check.ts +0 -179
- package/dist/npm/payload/author-style/member-spacing.test.ts +0 -172
- package/dist/npm/payload/author-style/member-spacing.ts +0 -106
- package/dist/npm/payload/author-style/package-lock.json +0 -180
- package/dist/npm/payload/author-style/package.json +0 -17
- package/dist/npm/payload/author-style/plugins/class-member-order.grit +0 -133
- package/dist/npm/payload/author-style/plugins/event-handler-names.grit +0 -110
- package/dist/npm/payload/author-style/plugins/explicit-arrow-body.grit +0 -15
- package/dist/npm/payload/author-style/plugins/explicit-source-constructs.grit +0 -10
- package/dist/npm/payload/author-style/plugins/react-arrow-body.grit +0 -85
- package/dist/npm/payload/author-style/plugins/sql-style.grit +0 -125
- package/dist/npm/payload/author-style/react-module.llm.md +0 -17
- package/dist/npm/payload/author-style/react-module.test.ts +0 -150
- package/dist/npm/payload/author-style/react-module.ts +0 -255
- package/dist/npm/payload/author-style/source-policy.llm.md +0 -17
- package/dist/npm/payload/author-style/source-policy.test.ts +0 -70
- package/dist/npm/payload/author-style/source-policy.ts +0 -215
- package/dist/npm/payload/author-style/spacing.llm.md +0 -17
- package/dist/npm/payload/author-style/spacing.test.ts +0 -174
- package/dist/npm/payload/author-style/spacing.ts +0 -211
- package/dist/npm/payload/harness/POLICY.md +0 -33
- package/dist/npm/payload/harness/PROJECT.md +0 -26
- package/dist/npm/payload/harness/REVIEW.md +0 -17
- package/dist/npm/payload/harness/TEMPLATES.md +0 -20
- package/dist/npm/payload/harness/WORKFLOWS.md +0 -65
- package/dist/npm/payload/harness/runtime/ZOD-LICENSE +0 -21
- package/dist/npm/payload/harness/runtime/harness.mjs +0 -104
- package/dist/npm/payload/harness/services/README.md +0 -26
- package/dist/npm/payload/harness/services/penpot.json +0 -7
- package/dist/npm/payload/harness/services/plane.json +0 -9
- package/dist/npm/payload/harness/workflows/W01.md +0 -13
- package/dist/npm/payload/harness/workflows/W02.md +0 -13
- package/dist/npm/payload/harness/workflows/W03.md +0 -13
- package/dist/npm/payload/harness/workflows/W04.md +0 -13
- package/dist/npm/payload/harness/workflows/W05.md +0 -13
- package/dist/npm/payload/harness/workflows/W06.md +0 -13
- package/dist/npm/payload/harness/workflows/W07.md +0 -13
- package/dist/npm/payload/harness/workflows/W08.md +0 -13
- package/dist/npm/payload/harness/workflows/W09.md +0 -13
- package/dist/npm/payload/harness/workflows/W10.md +0 -13
- package/dist/npm/payload/harness/workflows/W11.md +0 -13
- package/dist/npm/payload/harness/workflows/W12.md +0 -13
- package/dist/npm/payload/harness/workflows/W13.md +0 -13
- package/dist/npm/payload/harness/workflows/W14.md +0 -13
- package/dist/npm/payload/harness/workflows/W15.md +0 -13
- package/dist/npm/payload/harness/workflows/W16.md +0 -13
- package/dist/npm/payload/harness/workflows/W17.md +0 -13
- package/dist/npm/payload/harness/workflows/W18.md +0 -13
- package/dist/npm/payload/harness/workflows/W19.md +0 -13
- package/dist/npm/payload/harness/workflows/W20.md +0 -13
- package/dist/npm/payload/harness/workflows/W21.md +0 -15
- package/dist/npm/payload/harness/workflows/W22.md +0 -13
- package/dist/npm/payload/harness/workflows/W23.md +0 -21
- package/dist/npm/payload/harness/workflows/W24.md +0 -13
- package/dist/npm/payload/harness/workflows/W25.md +0 -13
- package/dist/npm/payload/harness/workflows/W26.md +0 -13
- package/dist/npm/payload/harness/workflows/W27.md +0 -13
- package/dist/npm/payload/harness/workflows/W28.md +0 -13
- package/dist/npm/payload/harness/workflows/W29.md +0 -13
- package/dist/npm/payload/harness/workflows/W30.md +0 -13
- package/dist/npm/payload/harness/workflows/W31.md +0 -13
- package/dist/npm/payload/harness/workflows/W32.md +0 -13
- package/dist/npm/payload/harness/workflows/W33.md +0 -13
- package/dist/npm/payload/harness/workflows/W34.md +0 -13
- package/dist/npm/payload/harness/workflows/W35.md +0 -13
- package/dist/npm/payload/harness/workflows/W36.md +0 -13
- package/dist/npm/payload/harness/workflows/W37.md +0 -13
- /package/{dist/bun/native/LICENSE → LICENSE} +0 -0
- /package/{dist/bun/native/payload → payload}/HARNESS.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/README.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/biome-core.json +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/biome-react.json +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/biome-sql.json +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/bun.lock +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/check.llm.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/check.test.llm.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/check.test.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/check.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/member-spacing.test.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/member-spacing.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/package.json +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/plugins/class-member-order.grit +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/plugins/event-handler-names.grit +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/plugins/explicit-arrow-body.grit +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/plugins/explicit-source-constructs.grit +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/plugins/react-arrow-body.grit +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/plugins/sql-style.grit +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/react-module.llm.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/react-module.test.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/react-module.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/source-policy.llm.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/source-policy.test.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/source-policy.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/spacing.llm.md +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/spacing.test.ts +0 -0
- /package/{dist/bun/native/payload → payload}/author-style/spacing.ts +0 -0
- /package/{dist/bun/native/payload → payload}/harness/POLICY.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/PROJECT.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/REVIEW.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/TEMPLATES.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/WORKFLOWS.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/runtime/ZOD-LICENSE +0 -0
- /package/{dist/bun/native/payload → payload}/harness/services/README.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/services/penpot.json +0 -0
- /package/{dist/bun/native/payload → payload}/harness/services/plane.json +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W01.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W02.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W03.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W04.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W05.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W06.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W07.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W08.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W09.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W10.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W11.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W12.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W13.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W14.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W15.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W16.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W17.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W18.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W19.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W20.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W21.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W22.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W23.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W24.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W25.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W26.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W27.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W28.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W29.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W30.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W31.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W32.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W33.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W34.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W35.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W36.md +0 -0
- /package/{dist/bun/native/payload → payload}/harness/workflows/W37.md +0 -0
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Personal code style
|
|
2
|
-
|
|
3
|
-
Use this profile whenever an agent writes or changes authored TypeScript in a project without an applicable Biome configuration. It supplies a pinned Biome dependency, configuration, structural lint rules and a small TypeScript parser supplement. The tool reads only the explicitly selected source files for its supplementary checks and never writes target files.
|
|
4
|
-
|
|
5
|
-
- [Writing rules](#writing-rules): Read before editing code.
|
|
6
|
-
- [Deterministic checks](#deterministic-checks): Select an appropriate profile.
|
|
7
|
-
- [Install and run](#install-and-run): Run after each code edit batch and before handoff. See the [checker map](check.llm.md) when maintaining the tool.
|
|
8
|
-
- [Evidence and precedence](#evidence-and-precedence): Determine what is personal, historical or specific to a project.
|
|
9
|
-
|
|
10
|
-
## Writing rules
|
|
11
|
-
|
|
12
|
-
1. Write code in execution order. Name intermediate values when nesting hides decisions. Use explicit guards and braces, keep related steps together and separate preparation, reads, decisions, writes and returns when they serve different purposes. Keep a simple expression concise.
|
|
13
|
-
2. Define domain contracts before behavior. Keep a schema and its inferred types together and validate untrusted data before it enters domain logic. Reuse the accepted validation contract. Ask before adding Zod to a target that does not have it. Use explicit projections at public boundaries.
|
|
14
|
-
3. Keep transport and framework adapters focused. Separate domain decisions from persistence and wire explicit dependencies. Preserve the project's established class, module or functional organization. In classes, order static properties and methods before the constructor and instance properties and methods after it. Put private or protected members before public members in the corresponding group. Prefer constructor parameter properties for retained values and keep related operations in workflow order.
|
|
15
|
-
4. Use descriptive names and structure to explain behavior. Preserve rationale in the project's decision, ticket or review record. Keep a cause and useful context when operations fail. Prove guards, recovery and failure behavior through focused tests. Do not copy historical workarounds or weaken types to make checks pass.
|
|
16
|
-
5. Scope component rules to reusable React components. Prefer a named PascalCase `const`, explicit `FC` props and a default export when compatible with local rules. Keep props near their component and keep inline event callbacks to a single simple call. Use descriptive local `handle…` names. Treat framework entry points, generic components and library-owned wrappers according to their actual contract.
|
|
17
|
-
|
|
18
|
-
## Deterministic checks
|
|
19
|
-
|
|
20
|
-
| Area | Enforcement |
|
|
21
|
-
| --- | --- |
|
|
22
|
-
| Format | Biome uses two spaces, LF, a 120-column line width, single quotes in TypeScript, double quotes in JSX, semicolons, trailing commas and parenthesized arrow parameters. |
|
|
23
|
-
| Structure | Biome and the bundled Grit plugins check braces, explicit class accessibility, supported member-order inversions, multiline or branching arrow bodies and increment/decrement operators. The TypeScript supplement checks statement phase boundaries and class member separation, keeping overloads grouped. |
|
|
24
|
-
| Types and source | Biome rejects explicit `any`, non-null assertions, selected suppression directives and configured unsafe type patterns. Grit rejects explicit `unknown` type nodes. The TypeScript supplement checks double assertions, explanatory comments and top-level inferred types derived directly from a same-file schema via a recognized Zod import. It preserves parsed TypeScript reference directives and exact SQL markers before supported tagged templates. |
|
|
25
|
-
| `react` | Includes the common checks plus selected JSX components, exports, `FC` typing, inline event call shape and local event names. It recognizes direct imported React `memo` and `forwardRef`. Select reusable component files. Other wrappers, arbitrary aliases and semantic event binding still need review. |
|
|
26
|
-
| `sql` | Includes the common checks plus a lexical check for supported templates with a direct `sql` tag. Select it only where the project's `sql` tag is PostgreSQL. It does not resolve aliases or parse the SQL dialect. Unsupported fragments remain outside the check. |
|
|
27
|
-
|
|
28
|
-
Keep the native type checker, focused behavior tests, independent technical audit and separate code review. Static checks do not prove meaningful names, correct schema ownership, safe public exposure, awaited authorization, rejection handling, transaction semantics or test adequacy. A successful check reports a result for the selected files and patterns. It does not establish whole-project coverage.
|
|
29
|
-
|
|
30
|
-
## Install and run
|
|
31
|
-
|
|
32
|
-
Use the installed `llm/author-style/` directory in the adopting project. Keep its package manifest and `bun.lock` together. Run these commands from the adopting project's root with RTK and Bun 1.4.2 or later.
|
|
33
|
-
|
|
34
|
-
```text
|
|
35
|
-
rtk proxy bun install --cwd llm/author-style --frozen-lockfile --ignore-scripts
|
|
36
|
-
rtk proxy bun run --cwd llm/author-style check --root /absolute/project path/to/changed.ts
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
The Bun install command installs the isolated verifier and its platform binary inside `llm/author-style/`. Keep the application's own dependencies, lockfile and package manager. Use explicit paths under the actual project root. Quote paths containing spaces and pass `--` before paths beginning with a hyphen. Supported inputs are `.ts`, `.tsx`, `.mts` and `.cts`. A selection can include new and existing files. The verifier reads the whole selected file, so keep inherited violations separate and do not reformat unrelated code. The command rejects symlinks, known generated or dependency directories, generated headers and out-of-root paths.
|
|
40
|
-
|
|
41
|
-
```text
|
|
42
|
-
rtk proxy bun run --cwd llm/author-style check --root /absolute/project --profile react src/Panel.tsx
|
|
43
|
-
rtk proxy bun run --cwd llm/author-style check --root /absolute/project --profile sql src/queries.ts
|
|
44
|
-
rtk proxy bun run --cwd llm/author-style check --root /absolute/project --lint-only src/service.ts
|
|
45
|
-
rtk proxy bun run --cwd llm/author-style test
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
For an existing project, follow its own rules and tools first. The verifier refuses a selected file when it finds a native `biome.json` or `biome.jsonc` in its directory or an ancestor. If another formatter is authoritative and its lint policy is compatible, select `--lint-only` to omit personal formatting and spacing. If the existing lint policy conflicts, follow the project and record the difference. The verifier does not select or replace an ESLint, Prettier or other configuration on its own. Native Biome warnings, including an oversized selected file, cause a failed check. A native failure prevents the supplementary checks from running. Resolve the reported cause and rerun the same selection.
|
|
49
|
-
|
|
50
|
-
Record the selected paths and result in the normal verification evidence. Add this instruction to the adopting agent's entry point or shared verification instructions. Every agent should run the same command after a code edit batch and before delivery. The package installs no editor, Git, CI or model-specific hook.
|
|
51
|
-
|
|
52
|
-
> After each code edit batch and before handoff, run the project's applicable Biome checks. When no applicable Biome configuration exists, run the compatible profile in `llm/author-style/README.md` on the edited TypeScript files. Use the project's established formatter and lint policy first. Record the result with the other verification evidence.
|
|
53
|
-
|
|
54
|
-
## Evidence and precedence
|
|
55
|
-
|
|
56
|
-
Use the target project rules where established. Document and test a mechanical correction before changing a shared rule.
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"plugins": [
|
|
4
|
-
"./plugins/class-member-order.grit",
|
|
5
|
-
"./plugins/explicit-arrow-body.grit",
|
|
6
|
-
"./plugins/explicit-source-constructs.grit"
|
|
7
|
-
],
|
|
8
|
-
"formatter": {
|
|
9
|
-
"indentStyle": "space",
|
|
10
|
-
"indentWidth": 2,
|
|
11
|
-
"lineEnding": "lf",
|
|
12
|
-
"lineWidth": 120
|
|
13
|
-
},
|
|
14
|
-
"javascript": {
|
|
15
|
-
"formatter": {
|
|
16
|
-
"quoteStyle": "single",
|
|
17
|
-
"jsxQuoteStyle": "double",
|
|
18
|
-
"quoteProperties": "asNeeded",
|
|
19
|
-
"trailingCommas": "all",
|
|
20
|
-
"semicolons": "always",
|
|
21
|
-
"arrowParentheses": "always",
|
|
22
|
-
"bracketSameLine": false,
|
|
23
|
-
"bracketSpacing": true
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"assist": {
|
|
27
|
-
"enabled": false
|
|
28
|
-
},
|
|
29
|
-
"linter": {
|
|
30
|
-
"rules": {
|
|
31
|
-
"recommended": false,
|
|
32
|
-
"correctness": {
|
|
33
|
-
"noUnusedImports": "error",
|
|
34
|
-
"noUnusedPrivateClassMembers": "error",
|
|
35
|
-
"noUnusedVariables": "error"
|
|
36
|
-
},
|
|
37
|
-
"nursery": {
|
|
38
|
-
"noFloatingPromises": "error",
|
|
39
|
-
"noMisusedPromises": "error",
|
|
40
|
-
"noUnsafeTypeAssertion": "error"
|
|
41
|
-
},
|
|
42
|
-
"style": {
|
|
43
|
-
"noNonNullAssertion": "error",
|
|
44
|
-
"useBlockStatements": "error",
|
|
45
|
-
"useConsistentMemberAccessibility": {
|
|
46
|
-
"level": "error",
|
|
47
|
-
"options": { "accessibility": "explicit" }
|
|
48
|
-
},
|
|
49
|
-
"useImportType": "error"
|
|
50
|
-
},
|
|
51
|
-
"suspicious": {
|
|
52
|
-
"noExplicitAny": "error",
|
|
53
|
-
"noTsIgnore": "error"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"lockfileVersion": 2,
|
|
3
|
-
"configVersion": 0,
|
|
4
|
-
"workspaces": {
|
|
5
|
-
"": {
|
|
6
|
-
"name": "harness-author-style",
|
|
7
|
-
"devDependencies": {
|
|
8
|
-
"@biomejs/biome": "2.5.15",
|
|
9
|
-
"typescript": "5.9.3",
|
|
10
|
-
"zod": "4.6.7",
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
"packages": {
|
|
15
|
-
"@biomejs/biome": ["@biomejs/biome@2.5.15", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.15", "@biomejs/cli-darwin-x64": "2.5.15", "@biomejs/cli-linux-arm64": "2.5.15", "@biomejs/cli-linux-arm64-musl": "2.5.15", "@biomejs/cli-linux-x64": "2.5.15", "@biomejs/cli-linux-x64-musl": "2.5.15", "@biomejs/cli-win32-arm64": "2.5.15", "@biomejs/cli-win32-x64": "2.5.15" }, "bin": { "biome": "bin/biome" } }, "sha512-WZTW4slm/pdkh92K6t/3aEN++44JD1PQ7squ7RCMLI1flHGl43DVOIGXvCjHiZgBMO1V4uYxoFNtqrIA4qGuIQ=="],
|
|
16
|
-
|
|
17
|
-
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.15", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BZVzFhJ/mUvTLMYbc9x6el0o2Uv5zP7bACYyhFb6fSc1giroXm7PL0a5KqMJ9F+/BnkYRjagD/ROSDVOZ6eapg=="],
|
|
18
|
-
|
|
19
|
-
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.15", "", { "os": "darwin", "cpu": "x64" }, "sha512-V5Kw63V+fVGNFhFrizDxMbGXAzZCh8kYzJpy3GI6gTapWDg7bZK9oYC9CbVgQSEdTnupz0U5Efz8Ev+5vdBBXw=="],
|
|
20
|
-
|
|
21
|
-
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-XaG7P7eeSLYETD3K9grfB0mQmpLQZjygdbsxekWBJAg4am79fGAtRpfRyNnTvXB2fZFNnJZG3nXm7HBat0+VUw=="],
|
|
22
|
-
|
|
23
|
-
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.15", "", { "os": "linux", "cpu": "arm64" }, "sha512-tGzZUTcJCV7tj5Adh/Gn6nR4MycqA3iohq2LEcrarAgRBkU0h0OKd2UzCRkOsOYOuUGaUJb4YmqRqyy2feGGSw=="],
|
|
24
|
-
|
|
25
|
-
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.15", "", { "os": "linux", "cpu": "x64" }, "sha512-xE4iEW/3LqlYj9GFgGrFsFSH51dEEpUbYWBfeOv0q87WkUDxK2o/HhreSb7qMJqck70RVM6Lg96hgedcAYcOkA=="],
|
|
26
|
-
|
|
27
|
-
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.15", "", { "os": "linux", "cpu": "x64" }, "sha512-IlxUcyxilVGPsE008x13pWdkTbU3nQpP2i9b5UrbOYj6goBkKsRX1XB7yJLcV+O1H9LBchIIm4adOaVLZBX0ZQ=="],
|
|
28
|
-
|
|
29
|
-
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.15", "", { "os": "win32", "cpu": "arm64" }, "sha512-2kPKzhNlm8C+Ru3GcO0Me2ODkCBLrVOUNuyi84RJyWDVKAA4+Kjj3jMjL938lF6BRfvltC4vB2nPY9SvN51Ovg=="],
|
|
30
|
-
|
|
31
|
-
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.15", "", { "os": "win32", "cpu": "x64" }, "sha512-yAzh4UqEImV6Hcy0zjUqNfJAsUhoD64FBQCdTG8Md/Z2wQeVP/ZmJ3XRYAs1g8J9fjTFyl2fCtc5FB5til47+g=="],
|
|
32
|
-
|
|
33
|
-
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
34
|
-
|
|
35
|
-
"zod": ["zod@4.6.7", "", {}, "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg=="],
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Author style checker map
|
|
2
|
-
|
|
3
|
-
- [Inputs and project authority](#inputs-and-project-authority)
|
|
4
|
-
- [Native and parser checks](#native-and-parser-checks)
|
|
5
|
-
- [Verification and recovery](#verification-and-recovery)
|
|
6
|
-
|
|
7
|
-
## Inputs and project authority
|
|
8
|
-
|
|
9
|
-
Start in `check.ts` at `checkFiles`. The request schema describes the project root, selected files, profile and mode. `targetRelativePath` establishes containment and `configuredBiome` detects local Biome configuration. See [install and run](README.md#install-and-run) for adoption, supported files and exclusions.
|
|
10
|
-
|
|
11
|
-
## Native and parser checks
|
|
12
|
-
|
|
13
|
-
The `configurations` map selects the isolated Biome configuration. The checker uses the locked package, clears `BIOME_BINARY`, and starts Bun without dotenv loading or automatic installs. It propagates the native status. `findSourcePolicyIssues`, `findSpacingIssues`, `findMemberSpacingIssues` and `findReactModuleIssues` inspect the selected source without writing. The [check matrix](README.md#deterministic-checks) lists supported patterns and separate review boundaries.
|
|
14
|
-
|
|
15
|
-
## Verification and recovery
|
|
16
|
-
|
|
17
|
-
`check.test.ts` covers installation layout, native and project authority checks, selected inputs and supplementary results. The individual parser test files cover exact constructs and boundaries. See [install and run](README.md#install-and-run) for the test command. Do not treat a skipped, failed or interrupted check as evidence that selected code passed.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Checker integration test map
|
|
2
|
-
|
|
3
|
-
- [Installed layout and source selection](#installed-layout-and-source-selection)
|
|
4
|
-
- [Native profiles and policy](#native-profiles-and-policy)
|
|
5
|
-
- [Failure paths](#failure-paths)
|
|
6
|
-
|
|
7
|
-
## Installed layout and source selection
|
|
8
|
-
|
|
9
|
-
`runs when the profile is installed under the adopting project llm directory` covers private configuration discovery. `uses the isolated formatter and linter on exact paths outside the harness without writing` covers exact file names, unselected files and byte preservation.
|
|
10
|
-
|
|
11
|
-
## Native profiles and policy
|
|
12
|
-
|
|
13
|
-
`enforces core types, explicit updates, braces, branches and class layout` exercises the real engine and a rejected environment override. `uses the pinned Biome launcher when the target dotenv defines another binary` covers Bun subprocess isolation. `uses separately selected React and tagged SQL checks` distinguishes profile findings from the common configuration.
|
|
14
|
-
|
|
15
|
-
## Failure paths
|
|
16
|
-
|
|
17
|
-
`fails a mixed selection when Biome cannot check an oversized file` protects against partial checks reported as success. `refuses existing configurations, generated files, symlinks and an empty file selection` checks scope and authority. Supplementary parser cases have their own focused test files.
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { spawnSync } from 'node:child_process';
|
|
3
|
-
import { cpSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { test } from 'node:test';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
8
|
-
|
|
9
|
-
const checker = fileURLToPath(new URL('check.ts', import.meta.url));
|
|
10
|
-
|
|
11
|
-
function executeFrom(entry: string, root: string, args: string[], env = process.env) {
|
|
12
|
-
const result = spawnSync(process.execPath, [entry, '--root', root, ...args], { encoding: 'utf8', env });
|
|
13
|
-
|
|
14
|
-
if (result.error) {
|
|
15
|
-
throw result.error;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return result;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function execute(root: string, ...args: string[]) {
|
|
22
|
-
return executeFrom(checker, root, args);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
test('runs when the profile is installed under the adopting project llm directory', (context) => {
|
|
26
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
27
|
-
|
|
28
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
29
|
-
|
|
30
|
-
const profile = join(root, 'llm', 'author-style');
|
|
31
|
-
|
|
32
|
-
mkdirSync(profile, { recursive: true });
|
|
33
|
-
|
|
34
|
-
const packageDirectory = fileURLToPath(new URL('.', import.meta.url));
|
|
35
|
-
|
|
36
|
-
for (const file of [
|
|
37
|
-
'check.ts',
|
|
38
|
-
'source-policy.ts',
|
|
39
|
-
'spacing.ts',
|
|
40
|
-
'member-spacing.ts',
|
|
41
|
-
'react-module.ts',
|
|
42
|
-
'package.json',
|
|
43
|
-
'biome-core.json',
|
|
44
|
-
'plugins',
|
|
45
|
-
]) {
|
|
46
|
-
cpSync(join(packageDirectory, file), join(profile, file), { recursive: true });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
symlinkSync(join(packageDirectory, 'node_modules'), join(profile, 'node_modules'), 'dir');
|
|
50
|
-
writeFileSync(join(root, 'entry.ts'), 'export const sample = true;\n');
|
|
51
|
-
|
|
52
|
-
const result = executeFrom(join(profile, 'check.ts'), root, ['entry.ts']);
|
|
53
|
-
|
|
54
|
-
assert.equal(result.status, 0, result.stderr);
|
|
55
|
-
assert.match(result.stdout, /Checked 1 file/);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test('uses the isolated formatter and linter on exact paths outside the harness without writing', (context) => {
|
|
59
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
60
|
-
|
|
61
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
62
|
-
|
|
63
|
-
const clean = join(root, 'has spaces.ts');
|
|
64
|
-
const poorlyFormatted = "export const label='one'\n";
|
|
65
|
-
|
|
66
|
-
writeFileSync(clean, poorlyFormatted);
|
|
67
|
-
writeFileSync(join(root, 'unselected.ts'), 'export const counter: any = 0;\n');
|
|
68
|
-
|
|
69
|
-
const failure = execute(root, 'has spaces.ts');
|
|
70
|
-
|
|
71
|
-
assert.equal(failure.status, 1);
|
|
72
|
-
assert.match(failure.stderr, /Formatter would have printed/);
|
|
73
|
-
assert.equal(readFileSync(clean, 'utf8'), poorlyFormatted);
|
|
74
|
-
|
|
75
|
-
const lintOnly = execute(root, '--lint-only', 'has spaces.ts');
|
|
76
|
-
|
|
77
|
-
assert.equal(lintOnly.status, 0, lintOnly.stderr);
|
|
78
|
-
|
|
79
|
-
writeFileSync(clean, 'export const label = `line\n// @generated\nline`;\n');
|
|
80
|
-
|
|
81
|
-
const success = execute(root, clean);
|
|
82
|
-
|
|
83
|
-
assert.equal(success.status, 0, success.stderr);
|
|
84
|
-
assert.match(success.stdout, /Checked 1 file/);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test('enforces core types, explicit updates, braces, branches and class layout', (context) => {
|
|
88
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
89
|
-
|
|
90
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
91
|
-
|
|
92
|
-
writeFileSync(
|
|
93
|
-
join(root, 'shape.ts'),
|
|
94
|
-
[
|
|
95
|
-
'export class Selection {',
|
|
96
|
-
' public choose(flag: boolean): number {',
|
|
97
|
-
' let count = 1;',
|
|
98
|
-
' if (flag) count++;',
|
|
99
|
-
' return count;',
|
|
100
|
-
' }',
|
|
101
|
-
' public static create(): Selection {',
|
|
102
|
-
' return new Selection();',
|
|
103
|
-
' }',
|
|
104
|
-
'}',
|
|
105
|
-
'export const resolve = (value: boolean): string => (value ? "a" : "b");',
|
|
106
|
-
'export const loose: any = 1;',
|
|
107
|
-
'export const ambiguous: unknown = 2;',
|
|
108
|
-
].join('\n'),
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
const result = executeFrom(checker, root, ['--lint-only', 'shape.ts'], {
|
|
112
|
-
...process.env,
|
|
113
|
-
BIOME_BINARY: process.execPath,
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
assert.equal(result.status, 1);
|
|
117
|
-
assert.match(result.stderr, /Use an explicit update/);
|
|
118
|
-
assert.match(result.stderr, /useBlockStatements/);
|
|
119
|
-
assert.match(result.stderr, /explicit return/);
|
|
120
|
-
assert.match(result.stderr, /class member order/i);
|
|
121
|
-
assert.match(result.stderr, /noExplicitAny/);
|
|
122
|
-
assert.match(result.stderr, /Use an explicit domain type/);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
test('uses the pinned Biome launcher when the target dotenv defines another binary', (context) => {
|
|
126
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
127
|
-
|
|
128
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
129
|
-
|
|
130
|
-
writeFileSync(join(root, '.env'), `BIOME_BINARY=${process.execPath}\n`);
|
|
131
|
-
writeFileSync(join(root, 'entry.ts'), 'export const sample = true;\n');
|
|
132
|
-
|
|
133
|
-
const result = execute(root, 'entry.ts');
|
|
134
|
-
|
|
135
|
-
assert.equal(result.status, 0, result.stderr);
|
|
136
|
-
assert.match(result.stdout, /Checked 1 file/);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
test('uses separately selected React and tagged SQL checks', (context) => {
|
|
140
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
141
|
-
|
|
142
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
143
|
-
|
|
144
|
-
writeFileSync(join(root, 'Panel.tsx'), 'export default function Panel() { return <p>Hello</p>; }\n');
|
|
145
|
-
writeFileSync(join(root, 'Card.tsx'), 'const Card = () => <p>Hello</p>;\nexport default Card;\n');
|
|
146
|
-
writeFileSync(join(root, 'helper.ts'), 'export const UppercaseHelper = () => 1;\n');
|
|
147
|
-
writeFileSync(
|
|
148
|
-
join(root, 'query.ts'),
|
|
149
|
-
'export const find = (sql: (strings: TemplateStringsArray) => string) => sql`select id from records`;\n',
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
const core = execute(root, '--lint-only', 'Panel.tsx', 'query.ts');
|
|
153
|
-
|
|
154
|
-
assert.equal(core.status, 0, core.stderr);
|
|
155
|
-
|
|
156
|
-
const react = execute(root, '--profile', 'react', '--lint-only', 'Panel.tsx');
|
|
157
|
-
|
|
158
|
-
assert.equal(react.status, 1);
|
|
159
|
-
assert.match(react.stderr, /named const component/);
|
|
160
|
-
|
|
161
|
-
const arrow = execute(root, '--profile', 'react', '--lint-only', 'Card.tsx');
|
|
162
|
-
|
|
163
|
-
assert.equal(arrow.status, 1);
|
|
164
|
-
assert.match(arrow.stderr, /Annotate React arrow components/);
|
|
165
|
-
|
|
166
|
-
const helper = execute(root, '--profile', 'react', '--lint-only', 'helper.ts');
|
|
167
|
-
|
|
168
|
-
assert.equal(helper.status, 0, helper.stderr);
|
|
169
|
-
|
|
170
|
-
writeFileSync(
|
|
171
|
-
join(root, 'event.tsx'),
|
|
172
|
-
'export const view = <button onClick={() => { console.log("clicked"); }}>Go</button>;\n',
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
const plainEvent = execute(root, '--lint-only', 'event.tsx');
|
|
176
|
-
|
|
177
|
-
assert.equal(plainEvent.status, 0, plainEvent.stderr);
|
|
178
|
-
|
|
179
|
-
const reactEvent = execute(root, '--profile', 'react', '--lint-only', 'event.tsx');
|
|
180
|
-
|
|
181
|
-
assert.equal(reactEvent.status, 1);
|
|
182
|
-
assert.match(reactEvent.stderr, /inline JSX handler as one call expression/);
|
|
183
|
-
|
|
184
|
-
const sql = execute(root, '--profile', 'sql', '--lint-only', 'query.ts');
|
|
185
|
-
|
|
186
|
-
assert.equal(sql.status, 1);
|
|
187
|
-
assert.match(sql.stderr, /SQL keywords/i);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
test('fails a mixed selection when Biome cannot check an oversized file', (context) => {
|
|
191
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
192
|
-
|
|
193
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
194
|
-
writeFileSync(join(root, 'small.ts'), 'export const sample = true;\n');
|
|
195
|
-
writeFileSync(join(root, 'large.ts'), `export const sample = '${'a'.repeat(1024 * 1024)}';\n`);
|
|
196
|
-
|
|
197
|
-
const result = execute(root, '--lint-only', 'small.ts', 'large.ts');
|
|
198
|
-
|
|
199
|
-
assert.equal(result.status, 1);
|
|
200
|
-
assert.match(result.stderr, /exceeds the configured maximum/);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test('refuses existing configurations, generated files, symlinks and an empty file selection', (context) => {
|
|
204
|
-
const root = mkdtempSync(join(tmpdir(), 'harness-style-'));
|
|
205
|
-
|
|
206
|
-
context.after(() => rmSync(root, { recursive: true, force: true }));
|
|
207
|
-
|
|
208
|
-
mkdirSync(join(root, 'app'));
|
|
209
|
-
writeFileSync(join(root, 'app', 'biome.jsonc'), '{}\n');
|
|
210
|
-
writeFileSync(join(root, 'app', 'module.ts'), 'export const sample = true;\n');
|
|
211
|
-
writeFileSync(join(root, 'generated.ts'), '// @generated\nexport const sample = true;\n');
|
|
212
|
-
symlinkSync(join(root, 'generated.ts'), join(root, 'linked.ts'));
|
|
213
|
-
|
|
214
|
-
const expected = [
|
|
215
|
-
{ files: ['app/module.ts'], message: /project's configured Biome checks/ },
|
|
216
|
-
{ files: ['generated.ts'], message: /instead of a generated artifact/ },
|
|
217
|
-
{ files: ['linked.ts'], message: /instead of a symbolic link/ },
|
|
218
|
-
{ files: ['../outside.ts'], message: /inside/ },
|
|
219
|
-
{ files: [], message: /Supply the files you changed/ },
|
|
220
|
-
];
|
|
221
|
-
|
|
222
|
-
for (const { files, message } of expected) {
|
|
223
|
-
const result = execute(root, ...files);
|
|
224
|
-
|
|
225
|
-
assert.equal(result.status, 1);
|
|
226
|
-
assert.match(result.stderr, message);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const child = join(root, 'app', 'child');
|
|
230
|
-
|
|
231
|
-
mkdirSync(child);
|
|
232
|
-
writeFileSync(join(child, 'module.ts'), 'export const sample = true;\n');
|
|
233
|
-
|
|
234
|
-
const parentConfiguration = execute(child, 'module.ts');
|
|
235
|
-
|
|
236
|
-
assert.equal(parentConfiguration.status, 1);
|
|
237
|
-
assert.match(parentConfiguration.stderr, /project's configured Biome checks/);
|
|
238
|
-
});
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { lstatSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
3
|
-
import { createRequire } from 'node:module';
|
|
4
|
-
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { parseArgs } from 'node:util';
|
|
7
|
-
import { z } from 'zod';
|
|
8
|
-
import { findMemberSpacingIssues } from './member-spacing.ts';
|
|
9
|
-
import { findReactModuleIssues } from './react-module.ts';
|
|
10
|
-
import { findSourcePolicyIssues, hasGeneratedHeader } from './source-policy.ts';
|
|
11
|
-
import { findSpacingIssues } from './spacing.ts';
|
|
12
|
-
|
|
13
|
-
const requestSchema = z.object({
|
|
14
|
-
root: z.string().refine(isAbsolute, 'Supply the absolute project directory with --root.'),
|
|
15
|
-
profile: z.enum(['core', 'react', 'sql']),
|
|
16
|
-
lintOnly: z.boolean(),
|
|
17
|
-
files: z.array(z.string().min(1)).min(1, 'Supply the files you changed.'),
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const sourceExtension = /\.(?:[cm]?ts|tsx)$/;
|
|
21
|
-
const protectedDirectories = new Set(['node_modules', '.git', '.next', 'coverage', 'dist', 'out']);
|
|
22
|
-
const nativeConfigurations = ['biome.json', 'biome.jsonc'];
|
|
23
|
-
const configurations = { core: 'biome-core.json', react: 'biome-react.json', sql: 'biome-sql.json' };
|
|
24
|
-
const requireFromProfile = createRequire(import.meta.url);
|
|
25
|
-
|
|
26
|
-
function targetRelativePath(root: string, file: string): string {
|
|
27
|
-
const path = relative(root, file);
|
|
28
|
-
|
|
29
|
-
if (!path || path === '..' || path.startsWith(`..${sep}`) || isAbsolute(path)) {
|
|
30
|
-
throw new Error(`Choose a source file inside ${root}: ${file}`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return path;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function configuredBiome(file: string): string | undefined {
|
|
37
|
-
let directory = dirname(file);
|
|
38
|
-
|
|
39
|
-
for (;;) {
|
|
40
|
-
for (const name of nativeConfigurations) {
|
|
41
|
-
const path = join(directory, name);
|
|
42
|
-
|
|
43
|
-
if (lstatSync(path, { throwIfNoEntry: false })) {
|
|
44
|
-
return path;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const parent = dirname(directory);
|
|
49
|
-
|
|
50
|
-
if (directory === parent) {
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
directory = parent;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function checkFiles(argumentsList: string[]): number {
|
|
59
|
-
const parsed = parseArgs({
|
|
60
|
-
args: argumentsList,
|
|
61
|
-
allowPositionals: true,
|
|
62
|
-
options: {
|
|
63
|
-
root: { type: 'string' },
|
|
64
|
-
profile: { type: 'string', default: 'core' },
|
|
65
|
-
'lint-only': { type: 'boolean', default: false },
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
const request = requestSchema.parse({
|
|
69
|
-
root: parsed.values.root,
|
|
70
|
-
profile: parsed.values.profile,
|
|
71
|
-
lintOnly: parsed.values['lint-only'],
|
|
72
|
-
files: parsed.positionals,
|
|
73
|
-
});
|
|
74
|
-
const requestedRoot = resolve(request.root);
|
|
75
|
-
const root = realpathSync(requestedRoot);
|
|
76
|
-
|
|
77
|
-
if (!statSync(root).isDirectory()) {
|
|
78
|
-
throw new Error(`The project root must be a directory: ${root}`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const sources = new Map<string, string>();
|
|
82
|
-
|
|
83
|
-
for (const file of request.files) {
|
|
84
|
-
const requestedPath = resolve(requestedRoot, file);
|
|
85
|
-
let lexicalRoot = requestedRoot;
|
|
86
|
-
|
|
87
|
-
if (isAbsolute(file) && requestedPath.startsWith(`${root}${sep}`)) {
|
|
88
|
-
lexicalRoot = root;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const path = targetRelativePath(lexicalRoot, requestedPath);
|
|
92
|
-
const expectedPath = join(root, path);
|
|
93
|
-
const sourcePath = realpathSync(expectedPath);
|
|
94
|
-
|
|
95
|
-
if (expectedPath !== sourcePath) {
|
|
96
|
-
throw new Error(`Use the direct source path instead of a symbolic link: ${path}`);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (!sourceExtension.test(path) || !statSync(sourcePath).isFile()) {
|
|
100
|
-
throw new Error(`Choose an authored TypeScript or TSX file: ${path}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (path.split(sep).some((part) => protectedDirectories.has(part))) {
|
|
104
|
-
throw new Error(`Choose an authored file outside generated, dependency and Git directories: ${path}`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const existingConfiguration = configuredBiome(sourcePath);
|
|
108
|
-
|
|
109
|
-
if (existingConfiguration) {
|
|
110
|
-
throw new Error(`Use the project's configured Biome checks for ${path}: ${existingConfiguration}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const source = readFileSync(sourcePath, 'utf8');
|
|
114
|
-
|
|
115
|
-
if (hasGeneratedHeader(source)) {
|
|
116
|
-
throw new Error(`Choose an authored source file instead of a generated artifact: ${path}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
sources.set(path, source);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const config = fileURLToPath(new URL(configurations[request.profile], import.meta.url));
|
|
123
|
-
const biome = requireFromProfile.resolve('@biomejs/biome/bin/biome');
|
|
124
|
-
const runtimeArguments = process.versions.bun ? ['--no-env-file', '--no-install'] : [];
|
|
125
|
-
const environment = { ...process.env };
|
|
126
|
-
|
|
127
|
-
delete environment.BIOME_BINARY;
|
|
128
|
-
|
|
129
|
-
const result = spawnSync(
|
|
130
|
-
process.execPath,
|
|
131
|
-
[
|
|
132
|
-
...runtimeArguments,
|
|
133
|
-
biome,
|
|
134
|
-
request.lintOnly ? 'lint' : 'check',
|
|
135
|
-
`--config-path=${config}`,
|
|
136
|
-
'--error-on-warnings',
|
|
137
|
-
'--',
|
|
138
|
-
...sources.keys(),
|
|
139
|
-
],
|
|
140
|
-
{ cwd: root, env: environment, stdio: 'inherit' },
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
if (result.error) {
|
|
144
|
-
throw new Error(`Cannot launch Biome in ${root}: ${result.error.message}`, { cause: result.error });
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (result.status === null) {
|
|
148
|
-
throw new Error(`Biome did not complete in ${root}${result.signal ? ` (${result.signal})` : ''}.`);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (result.status !== 0) {
|
|
152
|
-
return result.status;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
let count = 0;
|
|
156
|
-
|
|
157
|
-
for (const [path, source] of sources) {
|
|
158
|
-
const spacing = request.lintOnly
|
|
159
|
-
? []
|
|
160
|
-
: [...findSpacingIssues(source, path), ...findMemberSpacingIssues(source, path)];
|
|
161
|
-
const react = request.profile === 'react' ? findReactModuleIssues(source, path) : [];
|
|
162
|
-
|
|
163
|
-
if (readFileSync(join(root, path), 'utf8') !== source) {
|
|
164
|
-
throw new Error(`The source changed during verification. Run the check again: ${path}`);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
for (const { line, column, message } of [...findSourcePolicyIssues(source, path), ...spacing, ...react]) {
|
|
168
|
-
process.stderr.write(`${path}:${line}:${column} ${message}\n`);
|
|
169
|
-
count += 1;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return count > 0 ? 1 : 0;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
process.exitCode = checkFiles(process.argv.slice(2));
|
|
178
|
-
} catch (error) {
|
|
179
|
-
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
180
|
-
process.exitCode = 1;
|
|
181
|
-
}
|