@konvert7/klint 0.24.0 → 0.24.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 +24 -0
- package/package.json +5 -5
- package/skill/klint-rules/SKILL.md +47 -5
- package/tools/generate-homebrew-formula.ts +6 -10
package/README.md
CHANGED
|
@@ -97,6 +97,7 @@ klint is for rules that are too project-specific or context-heavy for a formatte
|
|
|
97
97
|
| Layer boundaries | `src/components/**` must not import from `src/data/**` |
|
|
98
98
|
| Singleton ownership | `process.env.API_KEY` may only appear in `src/lib/auth.ts` |
|
|
99
99
|
| Forbidden patterns | `console.log(` is blocked inside hook libraries |
|
|
100
|
+
| Raw JSX elements | `<button>` is blocked outside `src/components/ui/**` |
|
|
100
101
|
| Type-aware mistakes | Promise-returning calls cannot be silently discarded |
|
|
101
102
|
| Repository policy | Custom `klint.rules.ts` rules run with the same severity/config system |
|
|
102
103
|
|
|
@@ -273,6 +274,18 @@ arch:
|
|
|
273
274
|
message: "Libraries should return or throw, not terminate the process"
|
|
274
275
|
```
|
|
275
276
|
|
|
277
|
+
Block raw JSX/HTML elements with `jsx-element` to push consumers onto design-system primitives. It is AST-matched on intrinsic (lowercase) tag names, so it is robust to whitespace, attributes, and lookalikes like `<buttonGroup>`:
|
|
278
|
+
|
|
279
|
+
```yaml
|
|
280
|
+
arch:
|
|
281
|
+
forbidden:
|
|
282
|
+
- jsx-element: ["button", "input", "label"]
|
|
283
|
+
in: ["src/app/**/*.tsx", "src/components/**/*.tsx", "!src/components/ui/**"]
|
|
284
|
+
message: "Use the design-system primitives in @/components/ui/* instead of raw HTML elements"
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
`jsx-element` matches intrinsic HTML elements only — not custom components like `<Button>`. Use `arch.imports` to restrict those.
|
|
288
|
+
|
|
276
289
|
### Singleton Locations
|
|
277
290
|
|
|
278
291
|
Enforce that a pattern appears only in one designated file:
|
|
@@ -286,6 +299,17 @@ arch:
|
|
|
286
299
|
message: "Use the auth module"
|
|
287
300
|
```
|
|
288
301
|
|
|
302
|
+
`singleton` accepts `jsx-element` too — pin a raw element to the one primitive file that is allowed to render it:
|
|
303
|
+
|
|
304
|
+
```yaml
|
|
305
|
+
arch:
|
|
306
|
+
singleton:
|
|
307
|
+
- jsx-element: "button"
|
|
308
|
+
only: "src/components/ui/button.tsx"
|
|
309
|
+
in: ["src/**/*.tsx"]
|
|
310
|
+
message: "Raw <button> belongs only to the Button primitive"
|
|
311
|
+
```
|
|
312
|
+
|
|
289
313
|
### Python Architecture Checks
|
|
290
314
|
|
|
291
315
|
The Rust engine can apply architecture rules to Python projects:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konvert7/klint",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.1",
|
|
4
4
|
"description": "Architecture-as-Code linter for TypeScript. Enforce layer boundaries, import rules, and singleton patterns in YAML.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"zod": "^4.4.3"
|
|
65
65
|
},
|
|
66
66
|
"optionalDependencies": {
|
|
67
|
-
"@konvert7/klint-darwin-arm64": "0.24.
|
|
68
|
-
"@konvert7/klint-darwin-x64": "0.24.
|
|
69
|
-
"@konvert7/klint-linux-x64": "0.24.
|
|
70
|
-
"@konvert7/klint-win32-x64": "0.24.
|
|
67
|
+
"@konvert7/klint-darwin-arm64": "0.24.1",
|
|
68
|
+
"@konvert7/klint-darwin-x64": "0.24.1",
|
|
69
|
+
"@konvert7/klint-linux-x64": "0.24.1",
|
|
70
|
+
"@konvert7/klint-win32-x64": "0.24.1"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@biomejs/biome": "2.4.7",
|
|
@@ -4,6 +4,19 @@ description: Add, modify, or explain klint architecture rules for this repo. Use
|
|
|
4
4
|
argument-hint: <constraint to enforce>
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## Schema
|
|
8
|
+
|
|
9
|
+
The full, authoritative config schema lives in the repo and is the source of truth for every field below:
|
|
10
|
+
|
|
11
|
+
- YAML: <https://github.com/konvert7/klint/blob/main/klint.schema.yaml>
|
|
12
|
+
- JSON: <https://github.com/konvert7/klint/blob/main/klint.schema.json>
|
|
13
|
+
|
|
14
|
+
Wire it into `klint.yaml` for editor autocomplete and validation:
|
|
15
|
+
|
|
16
|
+
```yaml
|
|
17
|
+
# yaml-language-server: $schema=./klint.schema.yaml
|
|
18
|
+
```
|
|
19
|
+
|
|
7
20
|
## Workflow
|
|
8
21
|
|
|
9
22
|
1. **Understand the constraint** — if scope is ambiguous, ask: which files/layers are involved? should it block or warn? are there legitimate exceptions?
|
|
@@ -19,8 +32,10 @@ argument-hint: <constraint to enforce>
|
|
|
19
32
|
|---|---|
|
|
20
33
|
| Layer X must not import from layer Y | `arch.imports` + `deny` |
|
|
21
34
|
| Layer X may only import from Y and Z | `arch.imports` + `allow` |
|
|
22
|
-
| Pattern P must only appear in one designated file | `arch.singleton` |
|
|
23
|
-
| Pattern P must never appear inside a scoped layer | `arch.forbidden` |
|
|
35
|
+
| Pattern P must only appear in one designated file | `arch.singleton` + `pattern` |
|
|
36
|
+
| Pattern P must never appear inside a scoped layer | `arch.forbidden` + `pattern` |
|
|
37
|
+
| Raw HTML/JSX element must never appear in a scoped layer | `arch.forbidden` + `jsx-element` |
|
|
38
|
+
| Raw HTML/JSX element may only appear in one primitive file | `arch.singleton` + `jsx-element` |
|
|
24
39
|
|
|
25
40
|
4. **Read `klint.yaml`** — check existing `arch.layers` and rules before adding anything. Add a new named layer to `arch.layers` if the file group doesn't exist yet.
|
|
26
41
|
|
|
@@ -69,29 +84,56 @@ arch:
|
|
|
69
84
|
```
|
|
70
85
|
|
|
71
86
|
### Singleton — one designated location
|
|
87
|
+
|
|
88
|
+
Pin a `pattern` (literal string) **or** a `jsx-element` (AST-matched tag) to exactly one file. Every other in-scope occurrence is a violation.
|
|
89
|
+
|
|
72
90
|
```yaml
|
|
73
91
|
arch:
|
|
74
92
|
singleton:
|
|
93
|
+
# pattern: literal string match — fires if it appears anywhere except `only`
|
|
75
94
|
- pattern: "process.env.API_KEY"
|
|
76
95
|
only: "src/lib/auth.ts"
|
|
77
|
-
in: ["src/**"] # optional: limit scan scope (default: all files)
|
|
96
|
+
in: ["src/**"] # optional: limit scan scope (default: all files). string OR array
|
|
78
97
|
message: "Use the auth module instead of reading API_KEY directly"
|
|
98
|
+
severity: error # optional — default error; use warn to record without blocking
|
|
99
|
+
|
|
100
|
+
# jsx-element: pin a raw element to its design-system primitive
|
|
101
|
+
- jsx-element: "button" # one tag, or a list: ["button", "input"]
|
|
102
|
+
only: "src/components/ui/button.tsx"
|
|
103
|
+
in: ["src/**/*.tsx"]
|
|
104
|
+
message: "Raw <button> belongs only to the Button primitive"
|
|
79
105
|
```
|
|
80
106
|
|
|
81
|
-
`
|
|
107
|
+
Required: `only` + `message`, plus one of `pattern` / `jsx-element` (not both in the same stanza).
|
|
82
108
|
|
|
83
109
|
### Forbidden — banned pattern in scope
|
|
110
|
+
|
|
111
|
+
Block a `pattern` (literal string) **or** a `jsx-element` (AST-matched tag) inside a scoped layer.
|
|
112
|
+
|
|
84
113
|
```yaml
|
|
85
114
|
arch:
|
|
86
115
|
forbidden:
|
|
116
|
+
# pattern: literal substring — no regex
|
|
87
117
|
- pattern: "console.log("
|
|
88
|
-
in: ["src/lib/**"]
|
|
118
|
+
in: ["src/lib/**"] # string OR array; supports ! negation
|
|
89
119
|
message: "Use the logger — console.log leaks into the agent event stream"
|
|
120
|
+
severity: error # optional — default error; use warn to record without blocking
|
|
121
|
+
|
|
122
|
+
# jsx-element: forbid raw HTML elements outside the design system
|
|
123
|
+
- jsx-element: ["button", "input", "label"]
|
|
124
|
+
in: ["src/app/**/*.tsx", "src/components/**/*.tsx", "!src/components/ui/**"]
|
|
125
|
+
message: "Use the design-system primitives in @/components/ui/* instead of raw HTML elements"
|
|
90
126
|
```
|
|
91
127
|
|
|
128
|
+
Required: `in` + `message`, plus one of `pattern` / `jsx-element` (not both in the same stanza).
|
|
129
|
+
|
|
130
|
+
`jsx-element` matches intrinsic element names on the AST (opening and self-closing tags), so it is robust to whitespace, attributes, and naming collisions like `<buttonGroup>` — unlike a literal `pattern: "<button"` scan. It works on `.tsx`/`.jsx` files in both the TS and Rust engines.
|
|
131
|
+
|
|
92
132
|
## Pitfalls
|
|
93
133
|
|
|
94
134
|
- `pattern` in `singleton` and `forbidden` is a **literal string** — will not catch `process.env["KEY"]` (bracket notation). Grep for both forms if both are possible.
|
|
135
|
+
- `jsx-element` matches **intrinsic** (lowercase HTML) tags only — `button`, `input`, `label`. It does not match custom React components like `<Button>`; to restrict those, use `arch.imports` against the component's module instead.
|
|
136
|
+
- A `forbidden`/`singleton` stanza takes either `pattern` or `jsx-element`, never both — split into two stanzas if you need both.
|
|
95
137
|
- `only` in `singleton` is relative to the project root — use forward slashes on all platforms.
|
|
96
138
|
- `severity: warn` records the violation but does not block the session. Use `error` (the default) to block.
|
|
97
139
|
- Path aliases (`@/*`) resolve via `tsconfig.json` `compilerOptions.paths`, including `extends` chains.
|
|
@@ -19,16 +19,12 @@ class Klint < Formula
|
|
|
19
19
|
version "${version}"
|
|
20
20
|
license "MIT"
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
on_intel do
|
|
29
|
-
url "https://github.com/konvert7/klint/releases/download/native-v${version}/klint-${version}-darwin-x64.tar.gz"
|
|
30
|
-
sha256 "${options.darwinX64Sha}"
|
|
31
|
-
end
|
|
22
|
+
if Hardware::CPU.arm?
|
|
23
|
+
url "https://github.com/konvert7/klint/releases/download/native-v${version}/klint-${version}-darwin-arm64.tar.gz"
|
|
24
|
+
sha256 "${options.darwinArm64Sha}"
|
|
25
|
+
else
|
|
26
|
+
url "https://github.com/konvert7/klint/releases/download/native-v${version}/klint-${version}-darwin-x64.tar.gz"
|
|
27
|
+
sha256 "${options.darwinX64Sha}"
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
def install
|