pasika 0.3.7 → 0.3.9
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 +49 -31
- package/dist/eslint/pasika/index.d.ts +41 -23
- package/dist/eslint/pasika/index.js +377 -142
- package/package.json +26 -22
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pasika
|
|
2
2
|
|
|
3
|
-
Documentation, the lint rules derived from it, and the
|
|
3
|
+
Documentation, the lint rules derived from it, and the checks that apply and diagnose both.
|
|
4
4
|
|
|
5
5
|
`pasika` owns the framework's documentation and turns it into checks. Every requirement in `docs/` is recorded in an enforcement registry that says which ESLint rule or `pasika` check governs it — or, when none does, how a reviewer or agent applies it by hand. CI fails when a requirement has no recorded answer.
|
|
6
6
|
|
|
@@ -8,20 +8,24 @@ Documentation, the lint rules derived from it, and the CLI that applies and diag
|
|
|
8
8
|
|
|
9
9
|
```text
|
|
10
10
|
docs/
|
|
11
|
-
repository-policy.md # agent-conduct requirements (Policy)
|
|
12
11
|
repository-policy.md # repo-wide code and documentation requirements (Policy)
|
|
13
12
|
code-organization-guide/ # placement, extraction, module conventions
|
|
14
13
|
documentation-guide/ # how documents themselves are written
|
|
15
14
|
framework-adoption-guide/ # adopting and updating the framework
|
|
16
15
|
styling-guide/ # Tailwind theme, composition, variants, states
|
|
17
|
-
|
|
16
|
+
scripts/
|
|
18
17
|
registry.json # requirement → enforcement, keyed by content hash
|
|
19
18
|
coverage.ts # reconciles the docs against the registry
|
|
19
|
+
utils/ # doc parsing, classification, registry IO
|
|
20
|
+
types/ # registry schema
|
|
21
|
+
constants/
|
|
22
|
+
rfc2119.ts # single source of truth for RFC 2119 vocabulary
|
|
20
23
|
eslint/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
rules/ # the lint rules, with fixture tests beside them
|
|
25
|
+
rules/documentation/ # the documentation-guide rules, linting docs/ itself
|
|
26
|
+
rules/tailwind/ # the Tailwind stylesheet rules
|
|
27
|
+
rules/package-json/ # the package.json rules
|
|
28
|
+
rules/husky/ # the husky-hook rules
|
|
25
29
|
```
|
|
26
30
|
|
|
27
31
|
## Documentation
|
|
@@ -46,27 +50,36 @@ The `text` field is the bullet as written in the document (markdown links and co
|
|
|
46
50
|
|
|
47
51
|
Every requirement carries a `note` explaining how it is met: what the ref'd rule or doctor check does and where it falls short, or — with no `ref` — how a reviewer or agent applies it by hand. When a rule governs the requirement's subject without fully deciding it (e.g. its placement), the `ref` still names that rule and the `note` says what stays judgment, so a partial check never reads as a complete one.
|
|
48
52
|
|
|
49
|
-
`
|
|
53
|
+
`npm run coverage` fails when a requirement has no recorded answer, when its text changed, when it disappeared, when its `ref` names a rule or doctor check that does not exist, or when a requirement a rule governs has no test titled with its text. Confirm a reworded requirement with `npx tsx scripts/coverage.ts --accept`.
|
|
50
54
|
|
|
51
55
|
## Commands
|
|
52
56
|
|
|
53
57
|
The documentation guide itself is linted: the `pasika/*` markdown rules run over `docs/**/*.md` and report title, overview, structure, example-pairing, and RFC 2119 violations at the exact node.
|
|
54
58
|
|
|
59
|
+
The coverage checks are standalone scripts under `scripts/`, run with `tsx`; the drift check is the published `libyear` tool — there is no `pasika` binary:
|
|
60
|
+
|
|
55
61
|
```bash
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
npm run coverage # check that every requirement has recorded enforcement
|
|
63
|
+
npm run coverage -- --accept # record reworded and removed requirements
|
|
64
|
+
npx libyear --limit-major-individual=1 # fail when a dependency trails the latest by >1 major (drift check)
|
|
58
65
|
```
|
|
59
66
|
|
|
60
|
-
Both accept `--json` for agent use
|
|
67
|
+
Both acceptance and the report accept `--json` for agent use:
|
|
61
68
|
|
|
62
|
-
|
|
69
|
+
```bash
|
|
70
|
+
npx tsx scripts/coverage.ts # text report
|
|
71
|
+
npx tsx scripts/coverage.ts --json # full report as JSON
|
|
72
|
+
npx tsx scripts/coverage.ts --accept # record accepted changes
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
A requirement the report shows as `new` is classified with the hash it prints:
|
|
63
76
|
|
|
64
77
|
```bash
|
|
65
|
-
npx
|
|
66
|
-
npx
|
|
78
|
+
npx tsx scripts/coverage.ts --classify d311a1457a --ref pasika/import-boundaries --note "reports imports that cross a feature boundary"
|
|
79
|
+
npx tsx scripts/coverage.ts --classify 041b665bd7 --note "no check can compare against the previous state"
|
|
67
80
|
```
|
|
68
81
|
|
|
69
|
-
The
|
|
82
|
+
The script refuses a hash no requirement has, a `ref` naming a rule or doctor check that does not exist, and a classification without a note — so a mismatch cannot reach the registry by hand. Re-running it on an already-recorded requirement replaces the earlier entry. All of it reads and writes `scripts/registry.json`.
|
|
70
83
|
|
|
71
84
|
## ESLint ruleset
|
|
72
85
|
|
|
@@ -90,14 +103,14 @@ export default eslintConfig;
|
|
|
90
103
|
|
|
91
104
|
### Without Zirka
|
|
92
105
|
|
|
93
|
-
|
|
106
|
+
````ts
|
|
94
107
|
// eslint.config.ts
|
|
95
|
-
import {
|
|
108
|
+
import { pasikaNext } from "pasika/eslint";
|
|
96
109
|
|
|
97
|
-
export default
|
|
98
|
-
```
|
|
110
|
+
export default pasikaNext;
|
|
111
|
+
``` `pasikaNext` is the full flat-config array: the `src/**` TS/TSX and Tailwind stylesheet blocks plus everything in `pasikaRepo`. `pasikaRepo` is the repository-level preset — every block that does not touch `src/**` (the package.json manifest, husky hooks, and docs) — and is a strict subset of `pasikaNext`. The granular rule objects (`tailwindRules`, `repoPackageJsonRules`, `documentationRules`) stay exported for manual wiring.
|
|
99
112
|
|
|
100
|
-
|
|
113
|
+
Because the preset blocks wire ESLint's language plugins, using `pasikaNext` directly (without `zirka`) requires `@eslint/css`, `@eslint/json`, and `@eslint/markdown` to be installed in the consuming project — they are `peerDependencies` of `pasika`. A `zirka`-based setup gets them automatically.
|
|
101
114
|
|
|
102
115
|
### TS/TSX rules
|
|
103
116
|
|
|
@@ -140,11 +153,11 @@ export default [pasikaConfig];
|
|
|
140
153
|
| `pasika/shared-style-dedup` † | A className combo used by two or more components becomes a named utility |
|
|
141
154
|
| `pasika/repeated-structure` | A block of elements repeated two or more times is extracted as a named component |
|
|
142
155
|
| `pasika/sole-state-owner` | A contiguous JSX part that is the sole consumer of a useState hook is extracted into a named component |
|
|
143
|
-
| `pasika/
|
|
156
|
+
| `pasika/config-baseline` | `eslint.config.*` references zirka and `tsconfig.json` exists |
|
|
144
157
|
| `pasika/zod-schema-validation` | Runtime validation through Zod schemas, not hand-written type guards |
|
|
145
158
|
| `pasika/source-under-src` | Application source lives under `src/`, not in root-level folders |
|
|
146
159
|
|
|
147
|
-
###
|
|
160
|
+
### Tailwind rules
|
|
148
161
|
|
|
149
162
|
Applied to `src/**/globals.css` (and other stylesheets) through `@eslint/css` with tolerant Tailwind v4 parsing.
|
|
150
163
|
|
|
@@ -161,20 +174,21 @@ Applied to `src/**/globals.css` (and other stylesheets) through `@eslint/css` wi
|
|
|
161
174
|
| `pasika/theme-variable-namespace` | Utility class groups share a namespace prefix |
|
|
162
175
|
| `pasika/global-css-location` | Global CSS lives in the correct entry point |
|
|
163
176
|
|
|
164
|
-
###
|
|
177
|
+
### Package.json rules
|
|
165
178
|
|
|
166
|
-
Applied to `package.json` through `@eslint/json`.
|
|
179
|
+
Applied to `package.json` through `@eslint/json`. The framework-agnostic subset (`no-vulyk-dependency`, `exact-version`) applies to any repository, including pasika itself; `nextjs-stack` applies to a Next.js/React application.
|
|
167
180
|
|
|
168
|
-
| Rule | Enforces
|
|
169
|
-
| ---------------------------- |
|
|
170
|
-
| `pasika/no-
|
|
171
|
-
| `pasika/
|
|
181
|
+
| Rule | Enforces |
|
|
182
|
+
| ---------------------------- | ----------------------------------------------------------------------------------- |
|
|
183
|
+
| `pasika/no-vulyk-dependency` | `vulyk` is not in `dependencies` |
|
|
184
|
+
| `pasika/exact-version` | Dependency and devDependency versions are pinned exactly, never ranges |
|
|
185
|
+
| `pasika/nextjs-stack` | All Tech Stack Reference packages are listed in `package.json` (Next.js/React apps) |
|
|
172
186
|
|
|
173
187
|
### Documentation rules
|
|
174
188
|
|
|
175
|
-
The `pasika/*` markdown rules enforce the documentation guide over `docs/**/*.md` (24 rules): file-name suffixes and titles, overview presence and length, guide step structure, Incorrect/Correct pairing, policy document shape, reference block headings, RFC 2119 placement, template hygiene, link anchoring, and glossary-term linking. They run through `@eslint/markdown`; `
|
|
189
|
+
The `pasika/*` markdown rules enforce the documentation guide over `docs/**/*.md` (24 rules): file-name suffixes and titles, overview presence and length, guide step structure, Incorrect/Correct pairing, policy document shape, reference block headings, RFC 2119 placement, template hygiene, link anchoring, and glossary-term linking. They run through `@eslint/markdown`; `npm run coverage` verifies each has a test and a registry entry. Pasika's own `docs/` are linted by them in CI (`npm run lint`).
|
|
176
190
|
|
|
177
|
-
Run `
|
|
191
|
+
Run `npx tsx scripts/coverage.ts --json` for the exact requirement each rule covers.
|
|
178
192
|
|
|
179
193
|
### † Cross-file rules
|
|
180
194
|
|
|
@@ -185,6 +199,10 @@ Where a component, hook, value, type, or style belongs depends on which files us
|
|
|
185
199
|
|
|
186
200
|
All are inert in a repository with no `src/` tree.
|
|
187
201
|
|
|
202
|
+
## Runtime dependency on typescript
|
|
203
|
+
|
|
204
|
+
Many of the TS/TSX rules call the TypeScript compiler API directly at lint time, so the published package imports `typescript` at runtime. `tsup` keeps it external (unbundled); `pasika` lists it as a pinned `dependency` so an installing consumer gets a version known to work with the rules. There is no `typescript` `peerDependency`.
|
|
205
|
+
|
|
188
206
|
## Development
|
|
189
207
|
|
|
190
208
|
```bash
|
|
@@ -193,4 +211,4 @@ npm run typecheck
|
|
|
193
211
|
npm run test
|
|
194
212
|
npm run coverage
|
|
195
213
|
npm run build
|
|
196
|
-
|
|
214
|
+
````
|
|
@@ -74,7 +74,7 @@ type JsxOpeningElementNode = Rule.Node & {
|
|
|
74
74
|
parent?: JsxElementNode;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
-
declare const
|
|
77
|
+
declare const documentationRules: {
|
|
78
78
|
"doc-kind-suffix": _eslint_markdown.MarkdownRuleDefinition;
|
|
79
79
|
"title-matches-file-name": _eslint_markdown.MarkdownRuleDefinition;
|
|
80
80
|
"overview-present": _eslint_markdown.MarkdownRuleDefinition;
|
|
@@ -101,7 +101,7 @@ declare const mdRules: {
|
|
|
101
101
|
"glossary-term-linking": _eslint_markdown.MarkdownRuleDefinition;
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
-
declare const
|
|
104
|
+
declare const tailwindRules: {
|
|
105
105
|
"theme-reset": _eslint_css.CSSRuleDefinition;
|
|
106
106
|
"root-variables": _eslint_css.CSSRuleDefinition;
|
|
107
107
|
"apply-usage": _eslint_css.CSSRuleDefinition;
|
|
@@ -115,26 +115,28 @@ declare const cssRules: {
|
|
|
115
115
|
"global-stylesheet": _eslint_css.CSSRuleDefinition;
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
/** Framework-agnostic package.json rules any repository should follow. */
|
|
119
|
+
declare const repoPackageJsonRules: {
|
|
119
120
|
"no-vulyk-dependency": _eslint_json.JSONRuleDefinition;
|
|
120
|
-
"
|
|
121
|
+
"exact-version": _eslint_json.JSONRuleDefinition;
|
|
122
|
+
};
|
|
123
|
+
/** Package.json rules specific to a Next.js (or React) application. */
|
|
124
|
+
declare const nextPackageJsonRules: {
|
|
125
|
+
"nextjs-stack": _eslint_json.JSONRuleDefinition;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
declare const huskyRules: {
|
|
129
|
+
"husky-hook": _eslint_json.JSONRuleDefinition;
|
|
121
130
|
};
|
|
122
131
|
|
|
132
|
+
/** Every source rule, merged so the Next preset applies them all. */
|
|
123
133
|
declare const pasikaRules: {
|
|
124
134
|
"component-placement": eslint.Rule.RuleModule;
|
|
125
|
-
"support-file-placement": eslint.Rule.RuleModule;
|
|
126
135
|
"application-structure": eslint.Rule.RuleModule;
|
|
127
|
-
"named-exports": eslint.Rule.RuleModule;
|
|
128
136
|
"data-testid-case": eslint.Rule.RuleModule;
|
|
129
|
-
"support-folder-shape": eslint.Rule.RuleModule;
|
|
130
|
-
"import-through-index": eslint.Rule.RuleModule;
|
|
131
|
-
"util-file-name": eslint.Rule.RuleModule;
|
|
132
|
-
"no-util-barrel": eslint.Rule.RuleModule;
|
|
133
137
|
"jsx-hygiene": eslint.Rule.RuleModule;
|
|
134
138
|
"interactive-component": eslint.Rule.RuleModule;
|
|
135
139
|
"ui-state": eslint.Rule.RuleModule;
|
|
136
|
-
"filename-case": eslint.Rule.RuleModule;
|
|
137
|
-
"import-boundaries": eslint.Rule.RuleModule;
|
|
138
140
|
"no-mixed-concerns": eslint.Rule.RuleModule;
|
|
139
141
|
"no-arbitrary-tailwind": eslint.Rule.RuleModule;
|
|
140
142
|
"enforce-cn-merge": {
|
|
@@ -149,38 +151,54 @@ declare const pasikaRules: {
|
|
|
149
151
|
JSXAttribute(node: JsxAttributeNode): void;
|
|
150
152
|
};
|
|
151
153
|
};
|
|
154
|
+
"cn-helper": eslint.Rule.RuleModule;
|
|
152
155
|
"enforce-cva-variant-props": eslint.Rule.RuleModule;
|
|
153
156
|
"cva-appearance-props": eslint.Rule.RuleModule;
|
|
154
157
|
"cva-boolean-variants": eslint.Rule.RuleModule;
|
|
155
|
-
"enforce-barrel-exports": eslint.Rule.RuleModule;
|
|
156
158
|
"cross-feature-import": eslint.Rule.RuleModule;
|
|
157
159
|
"pure-function-extract": eslint.Rule.RuleModule;
|
|
158
160
|
"hook-complexity": eslint.Rule.RuleModule;
|
|
159
161
|
"locale-dotted-path": eslint.Rule.RuleModule;
|
|
160
162
|
"locales-location": eslint.Rule.RuleModule;
|
|
161
163
|
"hook-extraction": eslint.Rule.RuleModule;
|
|
162
|
-
"value-extraction": eslint.Rule.RuleModule;
|
|
163
|
-
"config-extraction": eslint.Rule.RuleModule;
|
|
164
164
|
"component-nesting": eslint.Rule.RuleModule;
|
|
165
165
|
"stay-flat": eslint.Rule.RuleModule;
|
|
166
|
-
"type-extraction": eslint.Rule.RuleModule;
|
|
167
166
|
"locale-placement": eslint.Rule.RuleModule;
|
|
168
167
|
"sole-state-owner": eslint.Rule.RuleModule;
|
|
169
168
|
"locale-key-shape": eslint.Rule.RuleModule;
|
|
170
169
|
"shared-style-dedup": eslint.Rule.RuleModule;
|
|
171
170
|
"repeated-structure": eslint.Rule.RuleModule;
|
|
171
|
+
"filename-case": eslint.Rule.RuleModule;
|
|
172
|
+
"import-boundaries": eslint.Rule.RuleModule;
|
|
173
|
+
"named-exports": eslint.Rule.RuleModule;
|
|
174
|
+
"support-file-placement": eslint.Rule.RuleModule;
|
|
175
|
+
"support-folder-shape": eslint.Rule.RuleModule;
|
|
176
|
+
"import-through-index": eslint.Rule.RuleModule;
|
|
177
|
+
"util-file-name": eslint.Rule.RuleModule;
|
|
178
|
+
"no-util-barrel": eslint.Rule.RuleModule;
|
|
179
|
+
"enforce-barrel-exports": eslint.Rule.RuleModule;
|
|
180
|
+
"config-extraction": eslint.Rule.RuleModule;
|
|
181
|
+
"value-extraction": eslint.Rule.RuleModule;
|
|
182
|
+
"type-extraction": eslint.Rule.RuleModule;
|
|
172
183
|
"zod-schema-validation": eslint.Rule.RuleModule;
|
|
173
184
|
"source-under-src": eslint.Rule.RuleModule;
|
|
174
185
|
"config-baseline": eslint.Rule.RuleModule;
|
|
175
186
|
};
|
|
176
187
|
|
|
177
|
-
/** Rule ids as they appear in configuration and in lint output. */
|
|
178
|
-
declare const pasikaRuleIds: string[];
|
|
179
|
-
declare const pasikaMdRuleIds: string[];
|
|
180
|
-
declare const pasikaCssRuleIds: string[];
|
|
181
|
-
declare const pasikaJsonRuleIds: string[];
|
|
182
188
|
/** Every rule id, as they appear in configuration and in lint output. */
|
|
183
189
|
declare const allPasikaRuleIds: string[];
|
|
184
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Repository-level preset: every block that does NOT touch `src/**` — the
|
|
192
|
+
* package.json manifest (including husky hook requirements) and the
|
|
193
|
+
* documentation-guide markdown rules. This governs the repository itself,
|
|
194
|
+
* independent of any application source.
|
|
195
|
+
*/
|
|
196
|
+
declare const pasikaRepo: Linter.Config[];
|
|
197
|
+
/**
|
|
198
|
+
* Framework-wide preset: the full adopted-to-the-framework stack. Anything in
|
|
199
|
+
* `pasikaRepo` plus the `src/**` blocks — TS/TSX source rules and the Tailwind
|
|
200
|
+
* stylesheet rules. `pasikaRepo` is a strict subset of `pasikaNext`.
|
|
201
|
+
*/
|
|
202
|
+
declare const pasikaNext: Linter.Config[];
|
|
185
203
|
|
|
186
|
-
export { allPasikaRuleIds,
|
|
204
|
+
export { allPasikaRuleIds, documentationRules, huskyRules, nextPackageJsonRules, pasikaNext, pasikaRepo, pasikaRules, repoPackageJsonRules, tailwindRules };
|