pasika 0.5.16 → 0.5.18

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 CHANGED
@@ -9,10 +9,10 @@ Documentation, the lint rules derived from it, and the checks that apply and dia
9
9
  ```text
10
10
  docs/
11
11
  repository-policy.md # repo-wide code and documentation requirements (Policy)
12
- code-organization-guide/ # placement, extraction, module conventions
12
+ next-codebase-guide/ # placement, extraction, module conventions
13
13
  documentation-guide/ # how documents themselves are written
14
14
  pasika-adoption-guide/ # adopting and updating the framework
15
- styling-guide/ # Tailwind theme, composition, variants, states
15
+ next-tailwind-guide/ # Tailwind theme, composition, variants, states
16
16
  scripts/
17
17
  registry.json # requirement → enforcement, keyed by content hash
18
18
  coverage.ts # reconciles the docs against the registry
@@ -39,7 +39,7 @@ Requirements are identified by a hash of their canonical text, not by a hand-wri
39
39
 
40
40
  ```jsonc
41
41
  {
42
- "doc": "code-organization-guide/rules/no-mixed-concerns-rule.md",
42
+ "doc": "next-codebase-guide/rules/no-mixed-concerns-rule.md",
43
43
  "text": "A .tsx file that defines a component MUST contain exactly one component.",
44
44
  "hash": "b19fe3bd34",
45
45
  "ref": "pasika/no-mixed-concerns",
@@ -88,8 +88,8 @@ The script refuses a hash no requirement has, a `ref` naming a rule that does no
88
88
 
89
89
  ```bash
90
90
  npm run build
91
- npm run dogfood -- ../some/repo # nextjsApp preset (default)
92
- npm run dogfood -- ../some/repo --preset=typescriptApp
91
+ npm run dogfood -- ../some/repo # pasikaNextjsApp preset (default)
92
+ npm run dogfood -- ../some/repo --preset=pasikaApp
93
93
  npm run dogfood -- ../some/repo --pasika-only # tally only pasika/* rules
94
94
  npm run dogfood -- ../some/repo --rule=css-entry-point --findings
95
95
  npm run dogfood -- ../some/repo --json # machine-readable report
@@ -115,18 +115,18 @@ const { eslintConfig } = styleguide({
115
115
  export default eslintConfig;
116
116
  ```
117
117
 
118
- For a plain TypeScript repository, enable `pasikaTypescriptApp` instead of `pasikaNextjsApp`; that preset covers the manifest, the zirka contract, and the docs only — the `src/**` source rules belong to the Next.js app preset. `zirka` composes the pasika ruleset over four file scopes: TS/TSX under `src/**`, `globals.css` and other stylesheets, `package.json`, and markdown — each with its own ESLint language.
118
+ For a plain TypeScript repository, enable `pasikaApp` instead of `pasikaNextjsApp`; that preset covers the manifest, the zirka contract, and the docs only — the `src/**` source rules belong to the Next.js app preset. `zirka` composes the pasika ruleset over four file scopes: TS/TSX under `src/**`, `globals.css` and other stylesheets, `package.json`, and markdown — each with its own ESLint language.
119
119
 
120
120
  ### Without Zirka
121
121
 
122
122
  ```ts
123
123
  // eslint.config.ts — plain TypeScript repository
124
- import { typescriptApp } from "pasika/eslint";
124
+ import { pasikaApp } from "pasika/eslint";
125
125
 
126
- export default typescriptApp;
126
+ export default pasikaApp;
127
127
  ```
128
128
 
129
- `typescriptApp` is the plain-TypeScript-repository preset — the package.json manifest, the zirka configuration contract, and the docs. It carries no `src/**` source block: source linting is the Next.js app's job. `nextjsApp` is the full framework preset: everything in `typescriptApp` plus the Next.js-stack manifest requirement, the `src/**` app source rules, and the Tailwind stylesheet blocks. The granular rule objects (`tailwindRules`, `repoPackageJsonRules`, `documentationRules`) stay exported for manual wiring.
129
+ `pasikaApp` is the plain-TypeScript-repository preset — the package.json manifest, the zirka configuration contract, and the docs. It carries no `src/**` source block: source linting is the Next.js app's job. `pasikaNextjsApp` is the full framework preset: everything in `pasikaApp` plus the Next.js-stack manifest requirement, the `src/**` app source rules, and the Tailwind stylesheet blocks. The granular rule objects (`tailwindRules`, `repoPackageJsonRules`, `documentationRules`) stay exported for manual wiring.
130
130
 
131
131
  The `src/**` blocks ship `@typescript-eslint/parser` themselves, so a standalone preset parses `.ts`/`.tsx` correctly on its own (`pasika` lists it as a runtime dependency).
132
132
 
@@ -246,13 +246,16 @@ declare const allPasikaRuleIds: string[];
246
246
  * source block: source linting is the Next.js app's job.
247
247
  * Use this for a plain TypeScript repository that does not adopt the framework.
248
248
  */
249
- declare const typescriptApp: Linter.Config[];
249
+ declare const pasikaApp: Linter.Config[];
250
250
  /**
251
251
  * Next.js app preset: the full adopted-to-the-framework stack. Anything in
252
- * `typescriptApp` plus the framework-only blocks — the Next.js-stack manifest
252
+ * `pasikaApp` plus the framework-only blocks — the Next.js-stack manifest
253
253
  * requirement, the `src/**` app source rules, and the Tailwind stylesheet
254
- * rules. `typescriptApp` is a strict subset of `nextjsApp`.
254
+ * rules. `pasikaApp` is a strict subset of `pasikaNextjsApp`. Consuming this
255
+ * preset (spreading or iterating it) runs the TypeScript alignment diagnostic
256
+ * first, so a mismatched compiler major fails config load with an actionable
257
+ * error instead of crashing every type-aware rule later.
255
258
  */
256
- declare const nextjsApp: Linter.Config[];
259
+ declare const pasikaNextjsApp: Linter.Config[];
257
260
 
258
- export { allPasikaRuleIds, documentationRules, huskyRules, nextjsApp, nextjsPackageJsonRules, pasikaPlugin, repoPackageJsonRules, tailwindRules, typescriptApp, vulykRules };
261
+ export { allPasikaRuleIds, documentationRules, huskyRules, nextjsPackageJsonRules, pasikaApp, pasikaNextjsApp, pasikaPlugin, repoPackageJsonRules, tailwindRules, vulykRules };
@@ -4,6 +4,53 @@ import jsonPlugin from "@eslint/json";
4
4
  import markdown from "@eslint/markdown";
5
5
  import tsParser from "@typescript-eslint/parser";
6
6
 
7
+ // eslint/ts-alignment.ts
8
+ import { readFileSync } from "fs";
9
+ import { createRequire } from "module";
10
+ import { join } from "path";
11
+ var ownRequire = createRequire(import.meta.url);
12
+ var majorOf = (version) => Number(version.split(".")[0]);
13
+ function versionOf(packagePath) {
14
+ try {
15
+ const parsed = JSON.parse(readFileSync(packagePath, "utf8"));
16
+ if (typeof parsed !== "object" || parsed === null || !("version" in parsed)) return null;
17
+ return typeof parsed.version === "string" ? parsed.version : null;
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ function resolveTypescriptAlignment() {
23
+ let bundled = null;
24
+ try {
25
+ bundled = versionOf(ownRequire.resolve("typescript/package.json"));
26
+ } catch {
27
+ bundled = null;
28
+ }
29
+ let resolved = null;
30
+ try {
31
+ const consumerRequire = createRequire(join(process.cwd(), "package.json"));
32
+ resolved = versionOf(consumerRequire.resolve("typescript/package.json"));
33
+ } catch {
34
+ resolved = null;
35
+ }
36
+ return { bundled, resolved };
37
+ }
38
+ function alignmentError(bundled, resolved) {
39
+ if (bundled === null || resolved === null) return null;
40
+ const bundledMajor = majorOf(bundled);
41
+ const resolvedMajor = majorOf(resolved);
42
+ if (bundledMajor === resolvedMajor) return null;
43
+ const direction = resolvedMajor < bundledMajor ? `Upgrade your typescript to ^${String(bundledMajor)} (pinned exact) so a single hoisted copy serves the whole pipeline.` : `Your repository is ahead of the compiler pasika ships. Pin typescript to ^${String(bundledMajor)} for now and upgrade pasika when it bundles the newer major.`;
44
+ return new Error(
45
+ `[pasika] TypeScript major mismatch: the pasikaNextjsApp preset parses src/** with its bundled @typescript-eslint/parser, which runs on typescript ${bundled}; your repository resolves typescript ${resolved} for the type-aware rules. Two TypeScript majors mean the types the parser builds use a different TypeFlags layout than the rules expect, so every type-aware rule crashes (e.g. "undefined is not iterable" in ts-api-utils). Align them on ${String(bundledMajor)}, then lint will run again. ${direction}`
46
+ );
47
+ }
48
+ function assertTypescriptAlignment() {
49
+ const { bundled, resolved } = resolveTypescriptAlignment();
50
+ const error = alignmentError(bundled, resolved);
51
+ if (error) throw error;
52
+ }
53
+
7
54
  // eslint/rules/filename-case.ts
8
55
  import path2 from "path";
9
56
 
@@ -395,7 +442,7 @@ var noMixedConcernsRule = {
395
442
  for (const extra of components.slice(1)) {
396
443
  context.report({
397
444
  loc: { line: 1, column: 0 },
398
- message: `File defines multiple components. "${extra.name}" is an extra component. Move it to its own file. Each component file MUST define exactly one component. See docs/code-organization-guide/rules/no-mixed-concerns-rule.md`
445
+ message: `File defines multiple components. "${extra.name}" is an extra component. Move it to its own file. Each component file MUST define exactly one component. See docs/next-codebase-guide/rules/no-mixed-concerns-rule.md`
399
446
  });
400
447
  }
401
448
  }
@@ -421,7 +468,7 @@ var noArbitraryTailwindRule = {
421
468
  if (!match) return;
422
469
  context.report({
423
470
  node,
424
- message: `Tailwind arbitrary-value class "${match[0]}" is not allowed. Use a named token or custom utility. See docs/styling-guide/rules/arbitrary-value-rule.md`
471
+ message: `Tailwind arbitrary-value class "${match[0]}" is not allowed. Use a named token or custom utility. See docs/next-tailwind-guide/rules/arbitrary-value-rule.md`
425
472
  });
426
473
  }
427
474
  function checkExpression(node, expression) {
@@ -473,7 +520,7 @@ var noArbitraryTailwindRule = {
473
520
  };
474
521
 
475
522
  // eslint/rules/unknown-utility.ts
476
- import { readdirSync, readFileSync, statSync } from "fs";
523
+ import { readdirSync, readFileSync as readFileSync2, statSync } from "fs";
477
524
  import path5 from "path";
478
525
  var PREFIX_NAMESPACES = {
479
526
  bg: ["color"],
@@ -752,7 +799,7 @@ function readInventory(files) {
752
799
  for (const file of files) {
753
800
  let css2;
754
801
  try {
755
- css2 = readFileSync(file, "utf8");
802
+ css2 = readFileSync2(file, "utf8");
756
803
  } catch {
757
804
  continue;
758
805
  }
@@ -922,7 +969,7 @@ import path7 from "path";
922
969
 
923
970
  // eslint/project/parse-module.ts
924
971
  import path6 from "path";
925
- import { readFileSync as readFileSync2 } from "fs";
972
+ import { readFileSync as readFileSync3 } from "fs";
926
973
  import ts2 from "typescript";
927
974
  var isPascalCase3 = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
928
975
  var isHookName = (name) => /^use[A-Z]/.test(name);
@@ -959,7 +1006,7 @@ function classifyValue(name, initializer, isTsx) {
959
1006
  return "constant";
960
1007
  }
961
1008
  function parseModule(file) {
962
- const text = readFileSync2(file, "utf8");
1009
+ const text = readFileSync3(file, "utf8");
963
1010
  const isTsx = file.endsWith(".tsx") || file.endsWith(".jsx");
964
1011
  const sourceFile = ts2.createSourceFile(file, text, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TSX);
965
1012
  const imports = [];
@@ -1178,7 +1225,7 @@ var enforceCnMergeRule = {
1178
1225
  if (isComponentProp && attributeName !== "className" && attributeName.endsWith("ClassName")) {
1179
1226
  context.report({
1180
1227
  node,
1181
- message: "Expose appearance through typed variant props instead of separate internal class-name props. See docs/styling-guide/rules/class-composition-rule.md"
1228
+ message: "Expose appearance through typed variant props instead of separate internal class-name props. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1182
1229
  });
1183
1230
  return;
1184
1231
  }
@@ -1192,7 +1239,7 @@ var enforceCnMergeRule = {
1192
1239
  if (invalidClass) {
1193
1240
  context.report({
1194
1241
  node,
1195
- message: `Passed className contains non-layout utility "${invalidClass}". Expose appearance through typed variant props. See docs/styling-guide/rules/class-composition-rule.md`
1242
+ message: `Passed className contains non-layout utility "${invalidClass}". Expose appearance through typed variant props. See docs/next-tailwind-guide/rules/class-composition-rule.md`
1196
1243
  });
1197
1244
  }
1198
1245
  return;
@@ -1201,7 +1248,7 @@ var enforceCnMergeRule = {
1201
1248
  if (classCount(valueNode.value) > 5) {
1202
1249
  context.report({
1203
1250
  node,
1204
- message: "Static className with more than 5 classes must use cn() with grouped string literals. See docs/styling-guide/rules/class-composition-rule.md"
1251
+ message: "Static className with more than 5 classes must use cn() with grouped string literals. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1205
1252
  });
1206
1253
  }
1207
1254
  return;
@@ -1211,28 +1258,28 @@ var enforceCnMergeRule = {
1211
1258
  if (expr.type === "BinaryExpression" && expr.operator === "+") {
1212
1259
  context.report({
1213
1260
  node,
1214
- message: "Use cn() instead of + operator for className. See docs/styling-guide/rules/class-composition-rule.md"
1261
+ message: "Use cn() instead of + operator for className. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1215
1262
  });
1216
1263
  return;
1217
1264
  }
1218
1265
  if (expr.type === "TemplateLiteral" && expr.expressions.length > 0) {
1219
1266
  context.report({
1220
1267
  node,
1221
- message: "Use cn() instead of template literals with conditionals for className. See docs/styling-guide/rules/class-composition-rule.md"
1268
+ message: "Use cn() instead of template literals with conditionals for className. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1222
1269
  });
1223
1270
  return;
1224
1271
  }
1225
1272
  if (expr.type === "LogicalExpression" || expr.type === "ConditionalExpression") {
1226
1273
  context.report({
1227
1274
  node,
1228
- message: "Use cn() for conditional classes in className. See docs/styling-guide/rules/class-composition-rule.md"
1275
+ message: "Use cn() for conditional classes in className. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1229
1276
  });
1230
1277
  return;
1231
1278
  }
1232
1279
  if (expr.type === "Literal" && typeof expr.value === "string" && classCount(expr.value) > 5) {
1233
1280
  context.report({
1234
1281
  node,
1235
- message: "Static className with more than 5 classes must use cn() with grouped string literals. See docs/styling-guide/rules/class-composition-rule.md"
1282
+ message: "Static className with more than 5 classes must use cn() with grouped string literals. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1236
1283
  });
1237
1284
  return;
1238
1285
  }
@@ -1241,7 +1288,7 @@ var enforceCnMergeRule = {
1241
1288
  if (arg.type === "Literal" && typeof arg.value === "string" && classCount(arg.value) > 5) {
1242
1289
  context.report({
1243
1290
  node: arg,
1244
- message: "Each cn() string argument must contain at most 5 class names. Group by styling concern. See docs/styling-guide/rules/class-composition-rule.md"
1291
+ message: "Each cn() string argument must contain at most 5 class names. Group by styling concern. See docs/next-tailwind-guide/rules/class-composition-rule.md"
1245
1292
  });
1246
1293
  }
1247
1294
  }
@@ -1339,7 +1386,7 @@ var enforceCvaVariantPropsRule = {
1339
1386
  if (variantNames.includes(keyName2)) {
1340
1387
  context.report({
1341
1388
  node,
1342
- message: `Variant prop "${keyName2}" duplicates CVA variant values. Use VariantProps<typeof variants> instead of manually writing union types. See docs/styling-guide/rules/component-variant-rule.md`
1389
+ message: `Variant prop "${keyName2}" duplicates CVA variant values. Use VariantProps<typeof variants> instead of manually writing union types. See docs/next-tailwind-guide/rules/component-variant-rule.md`
1343
1390
  });
1344
1391
  return;
1345
1392
  }
@@ -1407,7 +1454,7 @@ var enforceBarrelExportsRule = {
1407
1454
  if (!reExportedNames.has(parentName)) {
1408
1455
  context.report({
1409
1456
  loc: { line: 1, column: 0 },
1410
- message: `index.ts in "${folderName}/" must re-export "${parentName}". See docs/code-organization-guide/rules/folder-nesting-rule.md`
1457
+ message: `index.ts in "${folderName}/" must re-export "${parentName}". See docs/next-codebase-guide/rules/folder-nesting-rule.md`
1411
1458
  });
1412
1459
  return;
1413
1460
  }
@@ -1415,7 +1462,7 @@ var enforceBarrelExportsRule = {
1415
1462
  if (nonParentExports.length > 0) {
1416
1463
  context.report({
1417
1464
  loc: { line: 1, column: 0 },
1418
- message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${parentName}" may be re-exported. See docs/code-organization-guide/rules/folder-nesting-rule.md`
1465
+ message: `index.ts must not re-export exclusive children: ${nonParentExports.join(", ")}. Only "${parentName}" may be re-exported. See docs/next-codebase-guide/rules/folder-nesting-rule.md`
1419
1466
  });
1420
1467
  }
1421
1468
  }
@@ -1559,7 +1606,7 @@ var componentPlacementRule = {
1559
1606
  context.report({
1560
1607
  node,
1561
1608
  loc: { line: 1, column: 0 },
1562
- message: `This component has no consumer outside src/app/ or a configuration module, so it belongs in the feature folder it represents, not in ${formatFolder(currentFolder)}. See docs/code-organization-guide/rules/component-placement-rule.md`
1609
+ message: `This component has no consumer outside src/app/ or a configuration module, so it belongs in the feature folder it represents, not in ${formatFolder(currentFolder)}. See docs/next-codebase-guide/rules/component-placement-rule.md`
1563
1610
  });
1564
1611
  }
1565
1612
  return;
@@ -1570,7 +1617,7 @@ var componentPlacementRule = {
1570
1617
  context.report({
1571
1618
  node,
1572
1619
  loc: { line: 1, column: 0 },
1573
- message: `Move this component to ${formatFolder(placement.expectedFolder)} \u2014 ${explanation}. Imported by ${describeConsumers(placement.countedConsumers, sourceRoot)}. See docs/code-organization-guide/rules/component-placement-rule.md`
1620
+ message: `Move this component to ${formatFolder(placement.expectedFolder)} \u2014 ${explanation}. Imported by ${describeConsumers(placement.countedConsumers, sourceRoot)}. See docs/next-codebase-guide/rules/component-placement-rule.md`
1574
1621
  });
1575
1622
  }
1576
1623
  };
@@ -1857,7 +1904,7 @@ var namedExportsRule = {
1857
1904
  ExportDefaultDeclaration(node) {
1858
1905
  context.report({
1859
1906
  node,
1860
- message: "Files that export values must use named exports unless a framework or third-party package requires a different export style for that file. See docs/code-organization-guide/rules/exports-and-imports-rule.md"
1907
+ message: "Files that export values must use named exports unless a framework or third-party package requires a different export style for that file. See docs/next-codebase-guide/rules/exports-and-imports-rule.md"
1861
1908
  });
1862
1909
  }
1863
1910
  };
@@ -1928,7 +1975,7 @@ var dataTestIdCaseRule = {
1928
1975
  } else if (component.smart) {
1929
1976
  context.report({
1930
1977
  node,
1931
- message: `Smart component "${component.name}" has no single outer element; wrap its content in one outer element with data-testid="${component.name}" instead of rendering multiple roots. See docs/code-organization-guide/rules/smart-vs-dumb-component-rule.md`
1978
+ message: `Smart component "${component.name}" has no single outer element; wrap its content in one outer element with data-testid="${component.name}" instead of rendering multiple roots. See docs/next-codebase-guide/rules/smart-vs-dumb-component-rule.md`
1932
1979
  });
1933
1980
  }
1934
1981
  }
@@ -1986,7 +2033,7 @@ var supportFolderShapeRule = {
1986
2033
  if (missing.length === 0) return;
1987
2034
  context.report({
1988
2035
  node,
1989
- message: `${folder}/index.ts must named-re-export every support file: ${missing.join(", ")}. See docs/code-organization-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`
2036
+ message: `${folder}/index.ts must named-re-export every support file: ${missing.join(", ")}. See docs/next-codebase-guide/rules/${folder === "constants" ? "constants" : "types-and-schemas"}-rule.md`
1990
2037
  });
1991
2038
  }
1992
2039
  };
@@ -2021,7 +2068,7 @@ var importThroughIndexRule = {
2021
2068
  const expected = `@/${folderIndex.join("/")}`;
2022
2069
  context.report({
2023
2070
  node,
2024
- message: `Import support files through ${expected} instead of "${specifier}". See the code-organization-guide exports and imports rules.`
2071
+ message: `Import support files through ${expected} instead of "${specifier}". See the next-codebase-guide exports and imports rules.`
2025
2072
  });
2026
2073
  }
2027
2074
  }
@@ -2108,7 +2155,7 @@ var noUtilBarrelRule = {
2108
2155
  if (utilsIndex < 0 || !path19.basename(target).startsWith("index.")) continue;
2109
2156
  context.report({
2110
2157
  node,
2111
- message: `Import utilities directly instead of through "${specifier}". See docs/code-organization-guide/rules/utilities-rule.md`
2158
+ message: `Import utilities directly instead of through "${specifier}". See docs/next-codebase-guide/rules/utilities-rule.md`
2112
2159
  });
2113
2160
  }
2114
2161
  }
@@ -2207,7 +2254,7 @@ var jsxHygieneRule = {
2207
2254
  if (!violation) return;
2208
2255
  context.report({
2209
2256
  node,
2210
- message: `Extract ${violation} from JSX before return. See docs/code-organization-guide/rules/jsx-hygiene-rule.md`
2257
+ message: `Extract ${violation} from JSX before return. See docs/next-codebase-guide/rules/jsx-hygiene-rule.md`
2211
2258
  });
2212
2259
  }
2213
2260
  return {
@@ -2389,7 +2436,7 @@ var interactiveComponentRule = {
2389
2436
  if (name === void 0) return;
2390
2437
  context.report({
2391
2438
  node,
2392
- message: `Extract the interactive <${name}> into a descriptive component. See docs/code-organization-guide/rules/interactive-component-rule.md`
2439
+ message: `Extract the interactive <${name}> into a descriptive component. See docs/next-codebase-guide/rules/interactive-component-rule.md`
2393
2440
  });
2394
2441
  }
2395
2442
  };
@@ -2453,7 +2500,7 @@ var uiStateRule = {
2453
2500
  if (!hasNativeState) {
2454
2501
  context.report({
2455
2502
  node: attribute,
2456
- message: `UI state prop "${name}" should be expressed with a native or ARIA state attribute. See docs/styling-guide/rules/component-ui-state-rule.md`
2503
+ message: `UI state prop "${name}" should be expressed with a native or ARIA state attribute. See docs/next-tailwind-guide/rules/component-ui-state-rule.md`
2457
2504
  });
2458
2505
  }
2459
2506
  }
@@ -2470,7 +2517,7 @@ var uiStateRule = {
2470
2517
  if (classes.length > 0 && !classes.some((className) => STATE_CLASS_RE.test(className))) {
2471
2518
  context.report({
2472
2519
  node: attribute,
2473
- message: "Use a Tailwind state variant for a UI state instead of conditional replacement classes. See docs/styling-guide/rules/component-ui-state-rule.md"
2520
+ message: "Use a Tailwind state variant for a UI state instead of conditional replacement classes. See docs/next-tailwind-guide/rules/component-ui-state-rule.md"
2474
2521
  });
2475
2522
  }
2476
2523
  }
@@ -2532,7 +2579,7 @@ var cvaAppearancePropsRule = {
2532
2579
  if (typeAnnotation.type === "TSUnionType" || typeAnnotation.type === "TSTypeLiteral") {
2533
2580
  context.report({
2534
2581
  node,
2535
- message: `Visual option prop "${keyName2}" must be defined through a cva() call rather than a manual union type. See docs/styling-guide/rules/component-variant-rule.md`
2582
+ message: `Visual option prop "${keyName2}" must be defined through a cva() call rather than a manual union type. See docs/next-tailwind-guide/rules/component-variant-rule.md`
2536
2583
  });
2537
2584
  }
2538
2585
  }
@@ -2606,7 +2653,7 @@ var cvaBooleanVariantsRule = {
2606
2653
  if (info.variantNames.has(propName)) {
2607
2654
  context.report({
2608
2655
  node,
2609
- message: `Boolean prop "${propName}" is used as a standalone conditional in cn() but is also defined as a CVA variant. Move it to one place: either CVA (with both true/false treatments) or cn() (standalone). See docs/styling-guide/rules/component-variant-rule.md`
2656
+ message: `Boolean prop "${propName}" is used as a standalone conditional in cn() but is also defined as a CVA variant. Move it to one place: either CVA (with both true/false treatments) or cn() (standalone). See docs/next-tailwind-guide/rules/component-variant-rule.md`
2610
2657
  });
2611
2658
  }
2612
2659
  }
@@ -2665,7 +2712,7 @@ var crossFeatureImportRule = {
2665
2712
  const names = [...importedFeatures].sort().join(", ");
2666
2713
  context.report({
2667
2714
  node,
2668
- message: `This component imports from two or more feature folders (${names}) and must live in src/compositions/. See docs/code-organization-guide/rules/component-placement-rule.md`
2715
+ message: `This component imports from two or more feature folders (${names}) and must live in src/compositions/. See docs/next-codebase-guide/rules/component-placement-rule.md`
2669
2716
  });
2670
2717
  }
2671
2718
  }
@@ -2713,7 +2760,7 @@ var pureFunctionExtractRule = {
2713
2760
  function report3(node, name) {
2714
2761
  context.report({
2715
2762
  node,
2716
- message: `Extract pure function "${name}" to utils/. See docs/code-organization-guide/rules/utilities-rule.md`
2763
+ message: `Extract pure function "${name}" to utils/. See docs/next-codebase-guide/rules/utilities-rule.md`
2717
2764
  });
2718
2765
  }
2719
2766
  return {
@@ -2812,12 +2859,12 @@ var hookComplexityRule = {
2812
2859
  if (imperativeCount >= 2 && !inSupportFolder) {
2813
2860
  context.report({
2814
2861
  node,
2815
- message: `Hook "${name}" has ${String(imperativeCount)} imperative categories and must be extracted to a hooks/ folder. See docs/code-organization-guide/rules/hook-extraction-rule.md`
2862
+ message: `Hook "${name}" has ${String(imperativeCount)} imperative categories and must be extracted to a hooks/ folder. See docs/next-codebase-guide/rules/hook-extraction-rule.md`
2816
2863
  });
2817
2864
  } else if (imperativeCount < 2 && inSupportFolder) {
2818
2865
  context.report({
2819
2866
  node,
2820
- message: `Hook "${name}" has fewer than two imperative categories and must stay inline in its consumer file. See docs/code-organization-guide/rules/hook-extraction-rule.md`
2867
+ message: `Hook "${name}" has fewer than two imperative categories and must stay inline in its consumer file. See docs/next-codebase-guide/rules/hook-extraction-rule.md`
2821
2868
  });
2822
2869
  }
2823
2870
  }
@@ -2964,7 +3011,7 @@ var hookExtractionRule = {
2964
3011
  context.report({
2965
3012
  node,
2966
3013
  loc: { line: exp.line, column: 0 },
2967
- message: `Hook "${exp.name}" has ${String(consumers?.size ?? 0)} consumers; extract it to its own file in a hooks/ folder. See docs/code-organization-guide/rules/hook-extraction-rule.md`
3014
+ message: `Hook "${exp.name}" has ${String(consumers?.size ?? 0)} consumers; extract it to its own file in a hooks/ folder. See docs/next-codebase-guide/rules/hook-extraction-rule.md`
2968
3015
  });
2969
3016
  }
2970
3017
  }
@@ -2997,7 +3044,7 @@ var valueExtractionRule = {
2997
3044
  context.report({
2998
3045
  node,
2999
3046
  loc: { line: 1, column: 0 },
3000
- message: `This file in src/app/ is imported by ${describeConsumers(outsideApp, sourceRoot)} outside src/app/. Extract the value to a shared or feature folder so it can be imported independently. See docs/code-organization-guide/rules/constants-rule.md`
3047
+ message: `This file in src/app/ is imported by ${describeConsumers(outsideApp, sourceRoot)} outside src/app/. Extract the value to a shared or feature folder so it can be imported independently. See docs/next-codebase-guide/rules/constants-rule.md`
3001
3048
  });
3002
3049
  }
3003
3050
  };
@@ -3033,12 +3080,12 @@ var configExtractionRule = {
3033
3080
  if (outsideConfig.length > 0) {
3034
3081
  findings.push({
3035
3082
  line: exp.line,
3036
- message: `${exp.kind} "${exp.name}" in a configuration module is imported by ${describeConsumers(outsideConfig, sourceRoot)} outside src/config/. Move it to the matching root support folder. See docs/code-organization-guide/rules/configuration-rule.md`
3083
+ message: `${exp.kind} "${exp.name}" in a configuration module is imported by ${describeConsumers(outsideConfig, sourceRoot)} outside src/config/. Move it to the matching root support folder. See docs/next-codebase-guide/rules/configuration-rule.md`
3037
3084
  });
3038
3085
  } else if (consumers.length > 0) {
3039
3086
  findings.push({
3040
3087
  line: exp.line,
3041
- message: `${exp.kind} "${exp.name}" is used only to implement this configuration module; extract it to the module's ${exp.kind === "schema" ? "schemas/" : "types/"} folder even with one consumer. See docs/code-organization-guide/rules/configuration-rule.md`
3088
+ message: `${exp.kind} "${exp.name}" is used only to implement this configuration module; extract it to the module's ${exp.kind === "schema" ? "schemas/" : "types/"} folder even with one consumer. See docs/next-codebase-guide/rules/configuration-rule.md`
3042
3089
  });
3043
3090
  }
3044
3091
  }
@@ -3090,7 +3137,7 @@ var componentNestingRule = {
3090
3137
  context.report({
3091
3138
  node,
3092
3139
  loc: { line: 1, column: 0 },
3093
- message: `This component is nested in src/${folder.join("/")}/ but its folder has no exclusive child components \u2014 only support files. Flatten it back into src/${flatFolder}/. See docs/code-organization-guide/rules/folder-nesting-rule.md`
3140
+ message: `This component is nested in src/${folder.join("/")}/ but its folder has no exclusive child components \u2014 only support files. Flatten it back into src/${flatFolder}/. See docs/next-codebase-guide/rules/folder-nesting-rule.md`
3094
3141
  });
3095
3142
  }
3096
3143
  };
@@ -3141,7 +3188,7 @@ var stayFlatRule = {
3141
3188
  context.report({
3142
3189
  node,
3143
3190
  loc: { line: 1, column: 0 },
3144
- message: `This component has exclusive child component(s) ${childNames.join(", ")}; nest it in a folder named after it inside src/features/${featureName}/. See docs/code-organization-guide/rules/folder-nesting-rule.md`
3191
+ message: `This component has exclusive child component(s) ${childNames.join(", ")}; nest it in a folder named after it inside src/features/${featureName}/. See docs/next-codebase-guide/rules/folder-nesting-rule.md`
3145
3192
  });
3146
3193
  }
3147
3194
  };
@@ -3180,7 +3227,7 @@ var typeExtractionRule = {
3180
3227
  if (independent2.length === 0) continue;
3181
3228
  findings.push({
3182
3229
  line: exp.line,
3183
- message: `${exp.kind} "${exp.name}" is imported by ${describeConsumers(independent2, sourceRoot)} without the component "${componentExport.name}" that defines it. Extract it to a types/ or schemas/ folder. See docs/code-organization-guide/rules/types-and-schemas-rule.md`
3230
+ message: `${exp.kind} "${exp.name}" is imported by ${describeConsumers(independent2, sourceRoot)} without the component "${componentExport.name}" that defines it. Extract it to a types/ or schemas/ folder. See docs/next-codebase-guide/rules/types-and-schemas-rule.md`
3184
3231
  });
3185
3232
  continue;
3186
3233
  }
@@ -3191,7 +3238,7 @@ var typeExtractionRule = {
3191
3238
  if (independent.length === 0) continue;
3192
3239
  findings.push({
3193
3240
  line: exp.line,
3194
- message: `${exp.kind} "${exp.name}" is imported by ${describeConsumers(independent, sourceRoot)} without using the code in this file. Extract it to a types/ or schemas/ folder. See docs/code-organization-guide/rules/types-and-schemas-rule.md`
3241
+ message: `${exp.kind} "${exp.name}" is imported by ${describeConsumers(independent, sourceRoot)} without using the code in this file. Extract it to a types/ or schemas/ folder. See docs/next-codebase-guide/rules/types-and-schemas-rule.md`
3195
3242
  });
3196
3243
  }
3197
3244
  if (findings.length === 0) return {};
@@ -3207,7 +3254,7 @@ var typeExtractionRule = {
3207
3254
 
3208
3255
  // eslint/rules/locale-placement.ts
3209
3256
  import path32 from "path";
3210
- import { readFileSync as readFileSync3 } from "fs";
3257
+ import { readFileSync as readFileSync4 } from "fs";
3211
3258
  import ts5 from "typescript";
3212
3259
  var LOCALE_ACCESS = /\blocales\.(?<key>[A-Za-z_$][\w$]*)/g;
3213
3260
  var camelCase = (name) => name.replace(/-[a-z]/g, (match) => match.slice(1).toUpperCase());
@@ -3264,7 +3311,7 @@ var localePlacementRule = {
3264
3311
  return candidateSegments.length === 2 && candidateSegments[0] === "locales" && candidateSegments[1]?.startsWith("index.");
3265
3312
  });
3266
3313
  if (!localesFile || file !== localesFile) return {};
3267
- const placement = localePlacement(readFileSync3(localesFile, "utf8"));
3314
+ const placement = localePlacement(readFileSync4(localesFile, "utf8"));
3268
3315
  if (!placement) return {};
3269
3316
  const keyReaders = /* @__PURE__ */ new Map();
3270
3317
  const keyFeatures = /* @__PURE__ */ new Map();
@@ -3276,7 +3323,7 @@ var localePlacementRule = {
3276
3323
  );
3277
3324
  if (!importsLocales) continue;
3278
3325
  const candidateSegments = segmentsOf(candidateFile, sourceRoot);
3279
- for (const match of readFileSync3(candidateFile, "utf8").matchAll(LOCALE_ACCESS)) {
3326
+ for (const match of readFileSync4(candidateFile, "utf8").matchAll(LOCALE_ACCESS)) {
3280
3327
  const key = match.groups?.key;
3281
3328
  if (key === void 0) continue;
3282
3329
  const readers = keyReaders.get(key) ?? /* @__PURE__ */ new Set();
@@ -3300,7 +3347,7 @@ var localePlacementRule = {
3300
3347
  if (current?.kind === "nested") {
3301
3348
  findings.push({
3302
3349
  line: current.line,
3303
- message: `Locale "${key}" is read by ${describeConsumers([...readers], sourceRoot)} and must live at the top level of locales. See docs/code-organization-guide/rules/locales-rule.md`
3350
+ message: `Locale "${key}" is read by ${describeConsumers([...readers], sourceRoot)} and must live at the top level of locales. See docs/next-codebase-guide/rules/locales-rule.md`
3304
3351
  });
3305
3352
  }
3306
3353
  continue;
@@ -3311,12 +3358,12 @@ var localePlacementRule = {
3311
3358
  if (current?.kind === "top") {
3312
3359
  findings.push({
3313
3360
  line: current.line,
3314
- message: `Locale "${key}" is read only by the ${featureName} feature; it must live in an object named "${expected}". See docs/code-organization-guide/rules/locales-rule.md`
3361
+ message: `Locale "${key}" is read only by the ${featureName} feature; it must live in an object named "${expected}". See docs/next-codebase-guide/rules/locales-rule.md`
3315
3362
  });
3316
3363
  } else if (current?.kind === "nested" && key !== expected) {
3317
3364
  findings.push({
3318
3365
  line: current.line,
3319
- message: `Locale "${key}" is read only by the ${featureName} feature; it must live in an object named "${expected}", not "${key}". See docs/code-organization-guide/rules/locales-rule.md`
3366
+ message: `Locale "${key}" is read only by the ${featureName} feature; it must live in an object named "${expected}", not "${key}". See docs/next-codebase-guide/rules/locales-rule.md`
3320
3367
  });
3321
3368
  }
3322
3369
  }
@@ -3428,7 +3475,7 @@ var soleStateOwnerRule = {
3428
3475
  context.report({
3429
3476
  node,
3430
3477
  loc: { line: 1, column: 0 },
3431
- message: `Component "${component.name}" uses state "${hook.value}" in ${String(run)} contiguous top-level JSX part${run === 1 ? "" : "s"}; extract that part into a named component that owns useState instead of reading it in the parent. See docs/code-organization-guide/rules/sole-state-owner-rule.md`
3478
+ message: `Component "${component.name}" uses state "${hook.value}" in ${String(run)} contiguous top-level JSX part${run === 1 ? "" : "s"}; extract that part into a named component that owns useState instead of reading it in the parent. See docs/next-codebase-guide/rules/sole-state-owner-rule.md`
3432
3479
  });
3433
3480
  }
3434
3481
  }
@@ -3558,7 +3605,7 @@ function checkKey(context, node, name) {
3558
3605
  reportFor(
3559
3606
  context,
3560
3607
  node,
3561
- `Locale key "${name}" must be English; write it in the Latin alphabet. See docs/code-organization-guide/rules/locales-rule.md`
3608
+ `Locale key "${name}" must be English; write it in the Latin alphabet. See docs/next-codebase-guide/rules/locales-rule.md`
3562
3609
  );
3563
3610
  return;
3564
3611
  }
@@ -3566,7 +3613,7 @@ function checkKey(context, node, name) {
3566
3613
  reportFor(
3567
3614
  context,
3568
3615
  node,
3569
- `Locale key "${name}" must be camelCase English based on the text. See docs/code-organization-guide/rules/locales-rule.md`
3616
+ `Locale key "${name}" must be camelCase English based on the text. See docs/next-codebase-guide/rules/locales-rule.md`
3570
3617
  );
3571
3618
  return;
3572
3619
  }
@@ -3576,7 +3623,7 @@ function checkKey(context, node, name) {
3576
3623
  reportFor(
3577
3624
  context,
3578
3625
  node,
3579
- `Locale key "${name}" is longer than ${String(MAX_KEY_LENGTH)} characters, so it must describe the message's purpose instead of the text; end it with an element role such as "Button", "Link", or "Dialog" (see WAI-ARIA roles). See docs/code-organization-guide/rules/locales-rule.md`
3626
+ `Locale key "${name}" is longer than ${String(MAX_KEY_LENGTH)} characters, so it must describe the message's purpose instead of the text; end it with an element role such as "Button", "Link", or "Dialog" (see WAI-ARIA roles). See docs/next-codebase-guide/rules/locales-rule.md`
3580
3627
  );
3581
3628
  }
3582
3629
  var localeKeyShapeRule = {
@@ -3613,7 +3660,7 @@ var localeKeyShapeRule = {
3613
3660
 
3614
3661
  // eslint/rules/shared-style-dedup.ts
3615
3662
  import path35 from "path";
3616
- import { readFileSync as readFileSync4, statSync as statSync3 } from "fs";
3663
+ import { readFileSync as readFileSync5, statSync as statSync3 } from "fs";
3617
3664
  var CLASS_NAME = /className="(?<classes>[^"]+)"/g;
3618
3665
  var comboCache;
3619
3666
  function combosFor(index) {
@@ -3631,7 +3678,7 @@ function combosFor(index) {
3631
3678
  }
3632
3679
  const combos = /* @__PURE__ */ new Map();
3633
3680
  for (const file of files) {
3634
- const text = readFileSync4(file, "utf8");
3681
+ const text = readFileSync5(file, "utf8");
3635
3682
  for (const match of text.matchAll(CLASS_NAME)) {
3636
3683
  const classes = (match.groups?.classes ?? "").split(/\s+/).filter(Boolean);
3637
3684
  if (classes.length < 2) continue;
@@ -3668,7 +3715,7 @@ var sharedStyleDedupRule = {
3668
3715
  context.report({
3669
3716
  node,
3670
3717
  loc: { line: 1, column: 0 },
3671
- message: `Class combination "${combo}" is used by ${String(users.size)} components and should change together; create a named custom Tailwind utility for it. See docs/styling-guide/rules/theme-and-utility-definition-rule.md`
3718
+ message: `Class combination "${combo}" is used by ${String(users.size)} components and should change together; create a named custom Tailwind utility for it. See docs/next-tailwind-guide/rules/theme-and-utility-definition-rule.md`
3672
3719
  });
3673
3720
  }
3674
3721
  }
@@ -3777,7 +3824,7 @@ var repeatedStructureRule = {
3777
3824
  if (!first || !isSubstantial(first)) continue;
3778
3825
  context.report({
3779
3826
  node: first,
3780
- message: `The same arrangement of elements appears ${String(group.length)} times here; extract it as a named component. Different data or labels do not prevent extraction. See docs/code-organization-guide/rules/repeated-structure-rule.md`
3827
+ message: `The same arrangement of elements appears ${String(group.length)} times here; extract it as a named component. Different data or labels do not prevent extraction. See docs/next-codebase-guide/rules/repeated-structure-rule.md`
3781
3828
  });
3782
3829
  }
3783
3830
  }
@@ -4541,7 +4588,7 @@ var noTemplatePromptRule = {
4541
4588
  import path41 from "path";
4542
4589
 
4543
4590
  // eslint/rules/documentation/project-index.ts
4544
- import { readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
4591
+ import { readdirSync as readdirSync3, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
4545
4592
  import path40 from "path";
4546
4593
  var KIND_BY_SUFFIX = [
4547
4594
  ["-rule.md", "rule"],
@@ -4559,7 +4606,7 @@ function listMarkdownFiles(dir) {
4559
4606
  });
4560
4607
  }
4561
4608
  function extractTitle(filePath) {
4562
- const content = readFileSync5(filePath, "utf8");
4609
+ const content = readFileSync6(filePath, "utf8");
4563
4610
  const match = /^# (?<title>.+)$/m.exec(content);
4564
4611
  return match?.groups?.title?.trim() ?? "";
4565
4612
  }
@@ -4842,10 +4889,10 @@ var noNestedHowToRule = {
4842
4889
  };
4843
4890
 
4844
4891
  // eslint/rules/documentation/glossary-term-linking.ts
4845
- import { readFileSync as readFileSync6 } from "fs";
4892
+ import { readFileSync as readFileSync7 } from "fs";
4846
4893
  import path42 from "path";
4847
4894
  function extractGlossaryTerms(filePath) {
4848
- const content = readFileSync6(filePath, "utf8");
4895
+ const content = readFileSync7(filePath, "utf8");
4849
4896
  const terms = [];
4850
4897
  const headingPattern = /^## (?<term>.+)$/gm;
4851
4898
  let match;
@@ -5444,7 +5491,7 @@ import { statSync as statSync6 } from "fs";
5444
5491
  import path46 from "path";
5445
5492
 
5446
5493
  // eslint/rules/tailwind/source-files.ts
5447
- import { readdirSync as readdirSync4, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
5494
+ import { readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync5 } from "fs";
5448
5495
  import path44 from "path";
5449
5496
  var CSS_EXTENSIONS = [".css"];
5450
5497
  var MODULE_EXTENSIONS3 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
@@ -5475,7 +5522,7 @@ function cachedTextReader() {
5475
5522
  let text = texts.get(file);
5476
5523
  if (text === void 0) {
5477
5524
  try {
5478
- text = readFileSync7(file, "utf8");
5525
+ text = readFileSync8(file, "utf8");
5479
5526
  } catch {
5480
5527
  text = "";
5481
5528
  }
@@ -5843,7 +5890,7 @@ var nextjsPackageJsonRules = {
5843
5890
  };
5844
5891
 
5845
5892
  // eslint/rules/husky/husky-hook.ts
5846
- import { existsSync as existsSync2, readFileSync as readFileSync8 } from "fs";
5893
+ import { existsSync as existsSync2, readFileSync as readFileSync9 } from "fs";
5847
5894
  import path47 from "path";
5848
5895
  function memberName4(member) {
5849
5896
  return member.name.type === "String" ? member.name.value : member.name.name;
@@ -5871,7 +5918,7 @@ var huskyHookRule = {
5871
5918
  });
5872
5919
  return;
5873
5920
  }
5874
- const content = readFileSync8(hookPath, "utf8");
5921
+ const content = readFileSync9(hookPath, "utf8");
5875
5922
  if (!content.includes("lint-staged")) {
5876
5923
  context.report({ node, message: ".husky/pre-commit must run lint-staged." });
5877
5924
  }
@@ -5902,7 +5949,7 @@ var huskyRules = {
5902
5949
  };
5903
5950
 
5904
5951
  // eslint/rules/vulyk/vulyk-docs.ts
5905
- import { existsSync as existsSync3, readFileSync as readFileSync9 } from "fs";
5952
+ import { existsSync as existsSync3, readFileSync as readFileSync10 } from "fs";
5906
5953
  import path48 from "path";
5907
5954
  var PASIKA_REPO = "Bredansky/pasika";
5908
5955
  var BASE_REQUIRED_DOCS = [
@@ -5911,8 +5958,8 @@ var BASE_REQUIRED_DOCS = [
5911
5958
  { name: "repository-policy", path: "docs/repository-policy.md" }
5912
5959
  ];
5913
5960
  var NEXTJS_REQUIRED_DOCS = [
5914
- { name: "code-organization-guide", path: "docs/code-organization-guide" },
5915
- { name: "styling-guide", path: "docs/styling-guide" }
5961
+ { name: "next-codebase-guide", path: "docs/next-codebase-guide" },
5962
+ { name: "next-tailwind-guide", path: "docs/next-tailwind-guide" }
5916
5963
  ];
5917
5964
  function memberName5(member) {
5918
5965
  return member.name.type === "String" ? member.name.value : member.name.name;
@@ -5945,7 +5992,7 @@ var vulykDocsRule = {
5945
5992
  });
5946
5993
  return;
5947
5994
  }
5948
- const config = readFileSync9(configPath, "utf8");
5995
+ const config = readFileSync10(configPath, "utf8");
5949
5996
  if (!config.includes(PASIKA_REPO)) {
5950
5997
  context.report({
5951
5998
  node,
@@ -5980,7 +6027,7 @@ var vulykRules = {
5980
6027
  };
5981
6028
 
5982
6029
  // eslint/index.ts
5983
- var nextjsAppRules = {
6030
+ var pasikaNextjsAppRules = {
5984
6031
  // Framework-agnostic TypeScript rules.
5985
6032
  "filename-case": filenameCaseRule,
5986
6033
  "import-boundaries": importBoundariesRule,
@@ -6030,7 +6077,7 @@ var pasikaPlugin = {
6030
6077
  rules: {
6031
6078
  // The shared plugin must register every rule the preset blocks reference,
6032
6079
  // so all rule sets live here.
6033
- ...nextjsAppRules,
6080
+ ...pasikaNextjsAppRules,
6034
6081
  ...documentationRules,
6035
6082
  ...tailwindRules,
6036
6083
  ...repoPackageJsonRules,
@@ -6043,7 +6090,7 @@ var jsonLanguage = { languages: { json: jsonPlugin.languages.json } };
6043
6090
  function ruleIds(rules2) {
6044
6091
  return Object.keys(rules2).map((name) => `pasika/${name}`);
6045
6092
  }
6046
- var nextjsAppRuleIds = ruleIds(nextjsAppRules);
6093
+ var pasikaNextjsAppRuleIds = ruleIds(pasikaNextjsAppRules);
6047
6094
  var documentationRuleIds = ruleIds(documentationRules);
6048
6095
  var tailwindRuleIds = ruleIds(tailwindRules);
6049
6096
  var repoPackageJsonRuleIds = ruleIds(repoPackageJsonRules);
@@ -6051,7 +6098,7 @@ var nextjsPackageJsonRuleIds = ruleIds(nextjsPackageJsonRules);
6051
6098
  var huskyRuleIds = ruleIds(huskyRules);
6052
6099
  var vulykRuleIds = ruleIds(vulykRules);
6053
6100
  var allPasikaRuleIds = [
6054
- ...nextjsAppRuleIds,
6101
+ ...pasikaNextjsAppRuleIds,
6055
6102
  ...documentationRuleIds,
6056
6103
  ...tailwindRuleIds,
6057
6104
  ...repoPackageJsonRuleIds,
@@ -6059,7 +6106,7 @@ var allPasikaRuleIds = [
6059
6106
  ...huskyRuleIds,
6060
6107
  ...vulykRuleIds
6061
6108
  ];
6062
- var typescriptAppLanguageOptions = {
6109
+ var pasikaAppLanguageOptions = {
6063
6110
  parser: tsParser,
6064
6111
  parserOptions: {
6065
6112
  ecmaVersion: "latest",
@@ -6067,13 +6114,13 @@ var typescriptAppLanguageOptions = {
6067
6114
  ecmaFeatures: { jsx: true }
6068
6115
  }
6069
6116
  };
6070
- var nextjsAppConfig = {
6117
+ var pasikaNextjsAppConfig = {
6071
6118
  files: ["src/**/*.{cjs,cts,js,jsx,mjs,mts,ts,tsx}"],
6072
- languageOptions: typescriptAppLanguageOptions,
6119
+ languageOptions: pasikaAppLanguageOptions,
6073
6120
  plugins: {
6074
6121
  pasika: pasikaPlugin
6075
6122
  },
6076
- rules: Object.fromEntries(nextjsAppRuleIds.map((id) => [id, "error"]))
6123
+ rules: Object.fromEntries(pasikaNextjsAppRuleIds.map((id) => [id, "error"]))
6077
6124
  };
6078
6125
  var tailwindStructureRules = {
6079
6126
  files: ["src/**/globals.css"],
@@ -6097,7 +6144,7 @@ var tailwindImportGraph = {
6097
6144
  languageOptions: { tolerant: true },
6098
6145
  rules: { "pasika/css-entry-point": "error" }
6099
6146
  };
6100
- var typescriptAppPackageJsonConfig = {
6147
+ var pasikaAppPackageJsonConfig = {
6101
6148
  files: ["package.json"],
6102
6149
  plugins: {
6103
6150
  json: jsonLanguage,
@@ -6106,7 +6153,7 @@ var typescriptAppPackageJsonConfig = {
6106
6153
  language: "json/json",
6107
6154
  rules: Object.fromEntries([...repoPackageJsonRuleIds, ...huskyRuleIds, ...vulykRuleIds].map((id) => [id, "error"]))
6108
6155
  };
6109
- var nextjsAppPackageJsonConfig = {
6156
+ var pasikaNextjsAppPackageJsonConfig = {
6110
6157
  files: ["package.json"],
6111
6158
  plugins: {
6112
6159
  json: jsonLanguage,
@@ -6133,27 +6180,39 @@ var documentationConfig = {
6133
6180
  language: "markdown/gfm",
6134
6181
  rules: Object.fromEntries(documentationRuleIds.map((id) => [id, "error"]))
6135
6182
  };
6136
- var typescriptApp = [
6137
- typescriptAppPackageJsonConfig,
6183
+ var pasikaApp = [
6184
+ pasikaAppPackageJsonConfig,
6138
6185
  zirkaConfig,
6139
6186
  documentationConfig
6140
6187
  ];
6141
- var nextjsApp = [
6142
- ...typescriptApp,
6143
- nextjsAppPackageJsonConfig,
6144
- nextjsAppConfig,
6188
+ var pasikaNextjsAppWithDiagnostic = (preset) => {
6189
+ let checked = false;
6190
+ return new Proxy(preset, {
6191
+ get(target, property, receiver) {
6192
+ if (!checked && (property === Symbol.iterator || property === "length")) {
6193
+ checked = true;
6194
+ assertTypescriptAlignment();
6195
+ }
6196
+ return Reflect.get(target, property, receiver);
6197
+ }
6198
+ });
6199
+ };
6200
+ var pasikaNextjsApp = pasikaNextjsAppWithDiagnostic([
6201
+ ...pasikaApp,
6202
+ pasikaNextjsAppPackageJsonConfig,
6203
+ pasikaNextjsAppConfig,
6145
6204
  tailwindStructureRules,
6146
6205
  tailwindImportGraph
6147
- ];
6206
+ ]);
6148
6207
  export {
6149
6208
  allPasikaRuleIds,
6150
6209
  documentationRules,
6151
6210
  huskyRules,
6152
- nextjsApp,
6153
6211
  nextjsPackageJsonRules,
6212
+ pasikaApp,
6213
+ pasikaNextjsApp,
6154
6214
  pasikaPlugin,
6155
6215
  repoPackageJsonRules,
6156
6216
  tailwindRules,
6157
- typescriptApp,
6158
6217
  vulykRules
6159
6218
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.5.16",
3
+ "version": "0.5.18",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",