pasika 0.7.3 → 0.7.5

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
@@ -198,14 +198,14 @@ Applied to `src/**/globals.css` (and other stylesheets) through `@eslint/css` wi
198
198
 
199
199
  ### Package.json rules
200
200
 
201
- 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, and `vulyk-docs` to a repository adopting the framework.
202
-
203
- | Rule | Enforces |
204
- | ---------------------------- | ----------------------------------------------------------------------------------- |
205
- | `pasika/no-vulyk-dependency` | `vulyk` is not in `dependencies` |
206
- | `pasika/exact-version` | Dependency and devDependency versions are pinned exactly, never ranges |
207
- | `pasika/nextjs-stack` | All Tech Stack Reference packages are listed in `package.json` (Next.js/React apps) |
208
- | `pasika/vulyk-docs` | `vulyk.config.ts` tracks the framework's docs from pasika and `AGENTS.md` exists |
201
+ Applied to `package.json` through `@eslint/json`. The framework-agnostic `exact-version` rule applies to any repository, including pasika itself; `nextjs-stack` applies to a Next.js/React application, and the Vulyk rules apply to a repository adopting the framework.
202
+
203
+ | Rule | Enforces |
204
+ | ------------------------- | ----------------------------------------------------------------------------------- |
205
+ | `pasika/exact-version` | Dependency and devDependency versions are pinned exactly, never ranges |
206
+ | `pasika/nextjs-stack` | All Tech Stack Reference packages are listed in `package.json` (Next.js/React apps) |
207
+ | `pasika/vulyk-dependency` | `vulyk` is listed in `devDependencies`, not `dependencies` |
208
+ | `pasika/vulyk-docs` | `vulyk.config.ts` tracks the framework's docs from pasika and `AGENTS.md` exists |
209
209
 
210
210
  ### Documentation rules
211
211
 
@@ -118,7 +118,6 @@ declare const tailwindRules: {
118
118
 
119
119
  /** Framework-agnostic package.json rules any repository should follow. */
120
120
  declare const repoPackageJsonRules: {
121
- "no-vulyk-dependency": _eslint_json.JSONRuleDefinition;
122
121
  "exact-version": _eslint_json.JSONRuleDefinition;
123
122
  "lint-setup": _eslint_json.JSONRuleDefinition;
124
123
  "vitest-coverage": _eslint_json.JSONRuleDefinition;
@@ -133,6 +132,7 @@ declare const huskyRules: {
133
132
  };
134
133
 
135
134
  declare const vulykRules: {
135
+ "vulyk-dependency": _eslint_json.JSONRuleDefinition;
136
136
  "vulyk-docs": _eslint_json.JSONRuleDefinition;
137
137
  };
138
138
 
@@ -145,10 +145,10 @@ declare const vulykRules: {
145
145
  */
146
146
  declare const pasikaPlugin: {
147
147
  rules: {
148
+ "vulyk-dependency": _eslint_json.JSONRuleDefinition;
148
149
  "vulyk-docs": _eslint_json.JSONRuleDefinition;
149
150
  "husky-hook": _eslint_json.JSONRuleDefinition;
150
151
  "nextjs-stack": _eslint_json.JSONRuleDefinition;
151
- "no-vulyk-dependency": _eslint_json.JSONRuleDefinition;
152
152
  "exact-version": _eslint_json.JSONRuleDefinition;
153
153
  "lint-setup": _eslint_json.JSONRuleDefinition;
154
154
  "vitest-coverage": _eslint_json.JSONRuleDefinition;
@@ -6100,39 +6100,6 @@ var lintSetupRule = {
6100
6100
  }
6101
6101
  };
6102
6102
 
6103
- // eslint/rules/package-json/no-vulyk-dependency.ts
6104
- function memberName3(member) {
6105
- return member.name.type === "String" ? member.name.value : member.name.name;
6106
- }
6107
- var noVulykDependencyRule = {
6108
- meta: {
6109
- schema: [],
6110
- type: "problem",
6111
- docs: {
6112
- description: "Require vulyk to run as an ephemeral command, not a package.json dependency."
6113
- }
6114
- },
6115
- create(context) {
6116
- return {
6117
- Document(node) {
6118
- const root = node.body;
6119
- if (root.type !== "Object") return;
6120
- for (const key of ["dependencies", "devDependencies"]) {
6121
- const section = root.members.find((member) => memberName3(member) === key);
6122
- if (section?.value.type !== "Object") continue;
6123
- const vulyk = section.value.members.find((member) => memberName3(member) === "vulyk");
6124
- if (vulyk) {
6125
- context.report({
6126
- node: vulyk,
6127
- message: 'Vulyk must not be a package.json dependency. Run it as "npx vulyk@latest" instead.'
6128
- });
6129
- }
6130
- }
6131
- }
6132
- };
6133
- }
6134
- };
6135
-
6136
6103
  // eslint/rules/package-json/nextjs-stack.ts
6137
6104
  var NEXTJS_STACK_DEPENDENCIES = [
6138
6105
  "next",
@@ -6156,13 +6123,13 @@ var NEXTJS_STACK_DEV_DEPENDENCIES = [
6156
6123
  "@testing-library/react",
6157
6124
  "@testing-library/dom"
6158
6125
  ];
6159
- function memberName4(member) {
6126
+ function memberName3(member) {
6160
6127
  return member.name.type === "String" ? member.name.value : member.name.name;
6161
6128
  }
6162
6129
  function sectionPackages(root, section) {
6163
- const member = root.type === "Object" ? root.members.find((entry) => memberName4(entry) === section) : void 0;
6130
+ const member = root.type === "Object" ? root.members.find((entry) => memberName3(entry) === section) : void 0;
6164
6131
  if (member?.value.type !== "Object") return /* @__PURE__ */ new Set();
6165
- return new Set(member.value.members.map(memberName4));
6132
+ return new Set(member.value.members.map(memberName3));
6166
6133
  }
6167
6134
  var nextjsStackRule = {
6168
6135
  meta: {
@@ -6201,7 +6168,7 @@ var nextjsStackRule = {
6201
6168
  // eslint/rules/package-json/vitest-coverage.ts
6202
6169
  import { existsSync as existsSync4, readFileSync as readFileSync9 } from "fs";
6203
6170
  import path47 from "path";
6204
- function memberName5(member) {
6171
+ function memberName4(member) {
6205
6172
  return member.name.type === "String" ? member.name.value : member.name.name;
6206
6173
  }
6207
6174
  function memberValue3(member) {
@@ -6238,9 +6205,9 @@ var vitestCoverageRule = {
6238
6205
  Document(node) {
6239
6206
  const root = node.body;
6240
6207
  if (root.type !== "Object") return;
6241
- const devDependencies = root.members.find((member) => memberName5(member) === "devDependencies");
6208
+ const devDependencies = root.members.find((member) => memberName4(member) === "devDependencies");
6242
6209
  const devDependencyNames = new Set(
6243
- devDependencies?.value.type === "Object" ? devDependencies.value.members.map(memberName5) : []
6210
+ devDependencies?.value.type === "Object" ? devDependencies.value.members.map(memberName4) : []
6244
6211
  );
6245
6212
  if (!devDependencyNames.has("vitest")) {
6246
6213
  context.report({ node, message: "vitest must be listed in package.json as a devDependency." });
@@ -6251,9 +6218,9 @@ var vitestCoverageRule = {
6251
6218
  message: "@vitest/coverage-v8 must be listed in package.json as a devDependency."
6252
6219
  });
6253
6220
  }
6254
- const scripts = root.members.find((member) => memberName5(member) === "scripts");
6221
+ const scripts = root.members.find((member) => memberName4(member) === "scripts");
6255
6222
  const scriptMembers = scripts?.value.type === "Object" ? scripts.value.members : [];
6256
- const unit = scriptMembers.find((member) => memberName5(member) === "test:unit");
6223
+ const unit = scriptMembers.find((member) => memberName4(member) === "test:unit");
6257
6224
  const unitCommand = memberValue3(unit);
6258
6225
  if (unitCommand === void 0 || !/\bvitest\b/.test(unitCommand) || COVERAGE_FLAG_PATTERN.test(unitCommand)) {
6259
6226
  context.report({
@@ -6261,7 +6228,7 @@ var vitestCoverageRule = {
6261
6228
  message: 'package.json must declare a "test:unit" script that runs Vitest without coverage.'
6262
6229
  });
6263
6230
  }
6264
- const coverage = scriptMembers.find((member) => memberName5(member) === "test:unit:coverage");
6231
+ const coverage = scriptMembers.find((member) => memberName4(member) === "test:unit:coverage");
6265
6232
  const coverageCommand = memberValue3(coverage);
6266
6233
  if (coverageCommand === void 0 || !/\bvitest\b/.test(coverageCommand) || !COVERAGE_FLAG_PATTERN.test(coverageCommand)) {
6267
6234
  context.report({
@@ -6289,7 +6256,7 @@ var vitestCoverageRule = {
6289
6256
  message: `${configName} must set coverage.thresholds.autoUpdate to true.`
6290
6257
  });
6291
6258
  }
6292
- const stagedTests = scriptMembers.find((member) => memberName5(member) === "test:unit:staged");
6259
+ const stagedTests = scriptMembers.find((member) => memberName4(member) === "test:unit:staged");
6293
6260
  const stagedTestsCommand = memberValue3(stagedTests);
6294
6261
  if (stagedTestsCommand === void 0 || !/\bvitest\b/.test(stagedTestsCommand) || !RELATED_PATTERN.test(stagedTestsCommand) || COVERAGE_FLAG_PATTERN.test(stagedTestsCommand)) {
6295
6262
  context.report({
@@ -6297,9 +6264,9 @@ var vitestCoverageRule = {
6297
6264
  message: 'package.json must declare a "test:unit:staged" script that runs vitest related without coverage.'
6298
6265
  });
6299
6266
  }
6300
- const lintStaged = root.members.find((member) => memberName5(member) === "lint-staged");
6267
+ const lintStaged = root.members.find((member) => memberName4(member) === "lint-staged");
6301
6268
  const hasStagedTests = lintStaged?.value.type === "Object" && lintStaged.value.members.some(
6302
- (member) => SOURCE_GLOB_PATTERN2.test(memberName5(member)) && stringValues2(member.value).some((command) => command.includes("npm run test:unit:staged"))
6269
+ (member) => SOURCE_GLOB_PATTERN2.test(memberName4(member)) && stringValues2(member.value).some((command) => command.includes("npm run test:unit:staged"))
6303
6270
  );
6304
6271
  if (!hasStagedTests) {
6305
6272
  context.report({
@@ -6314,7 +6281,6 @@ var vitestCoverageRule = {
6314
6281
 
6315
6282
  // eslint/rules/package-json/index.ts
6316
6283
  var repoPackageJsonRules = {
6317
- "no-vulyk-dependency": noVulykDependencyRule,
6318
6284
  "exact-version": exactVersionRule,
6319
6285
  "lint-setup": lintSetupRule,
6320
6286
  "vitest-coverage": vitestCoverageRule
@@ -6326,7 +6292,15 @@ var nextjsPackageJsonRules = {
6326
6292
  // eslint/rules/husky/husky-hook.ts
6327
6293
  import { existsSync as existsSync5, readFileSync as readFileSync10 } from "fs";
6328
6294
  import path48 from "path";
6329
- function memberName6(member) {
6295
+ var VITEST_CONFIG_NAMES2 = [
6296
+ "vitest.config.ts",
6297
+ "vitest.config.mts",
6298
+ "vitest.config.cts",
6299
+ "vitest.config.js",
6300
+ "vitest.config.mjs",
6301
+ "vitest.config.cjs"
6302
+ ];
6303
+ function memberName5(member) {
6330
6304
  return member.name.type === "String" ? member.name.value : member.name.name;
6331
6305
  }
6332
6306
  var huskyHookRule = {
@@ -6334,7 +6308,7 @@ var huskyHookRule = {
6334
6308
  schema: [],
6335
6309
  type: "problem",
6336
6310
  docs: {
6337
- description: "Require a pre-commit hook that runs lint-staged and the libyear drift check directly, and the typecheck and suppression-file ratchet through named package.json scripts."
6311
+ description: "Require a pre-commit hook that runs lint-staged, typecheck, coverage with local threshold staging, suppression pruning when applicable, and the libyear drift check."
6338
6312
  }
6339
6313
  },
6340
6314
  create(context) {
@@ -6352,8 +6326,8 @@ var huskyHookRule = {
6352
6326
  return;
6353
6327
  }
6354
6328
  const content = readFileSync10(hookPath, "utf8");
6355
- const scripts = root.members.find((member) => memberName6(member) === "scripts");
6356
- const scriptNames = new Set(scripts?.value.type === "Object" ? scripts.value.members.map(memberName6) : []);
6329
+ const scripts = root.members.find((member) => memberName5(member) === "scripts");
6330
+ const scriptNames = new Set(scripts?.value.type === "Object" ? scripts.value.members.map(memberName5) : []);
6357
6331
  const requireNamedScript = (name) => {
6358
6332
  if (!scriptNames.has(name)) {
6359
6333
  context.report({ node, message: `package.json must declare a "${name}" script.` });
@@ -6366,6 +6340,18 @@ var huskyHookRule = {
6366
6340
  context.report({ node, message: ".husky/pre-commit must run lint-staged." });
6367
6341
  }
6368
6342
  requireNamedScript("typecheck");
6343
+ requireNamedScript("test:unit:coverage");
6344
+ const vitestConfigName = VITEST_CONFIG_NAMES2.find((name) => existsSync5(path48.join(context.cwd, name)));
6345
+ if (vitestConfigName !== void 0) {
6346
+ const coverageIndex = content.indexOf("npm run test:unit:coverage");
6347
+ const localAddIndex = content.indexOf(`git add ${vitestConfigName}`);
6348
+ if (localAddIndex <= coverageIndex) {
6349
+ context.report({
6350
+ node,
6351
+ message: `.husky/pre-commit must stage an auto-updated ${vitestConfigName} after coverage.`
6352
+ });
6353
+ }
6354
+ }
6369
6355
  if (!content.includes("libyear --limit-major-individual=1")) {
6370
6356
  context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
6371
6357
  }
@@ -6374,7 +6360,7 @@ var huskyHookRule = {
6374
6360
  requireNamedScript("lint:prune");
6375
6361
  }
6376
6362
  if (scripts?.value.type === "Object") {
6377
- const prepare = scripts.value.members.find((member) => memberName6(member) === "prepare");
6363
+ const prepare = scripts.value.members.find((member) => memberName5(member) === "prepare");
6378
6364
  if (prepare?.value.type === "String" && !prepare.value.value.includes("husky")) {
6379
6365
  context.report({
6380
6366
  node: prepare,
@@ -6392,6 +6378,46 @@ var huskyRules = {
6392
6378
  "husky-hook": huskyHookRule
6393
6379
  };
6394
6380
 
6381
+ // eslint/rules/vulyk/vulyk-dependency.ts
6382
+ function memberName6(member) {
6383
+ return member.name.type === "String" ? member.name.value : member.name.name;
6384
+ }
6385
+ function dependency(root, sectionName) {
6386
+ if (root.type !== "Object") return void 0;
6387
+ const section = root.members.find((member) => memberName6(member) === sectionName);
6388
+ if (section?.value.type !== "Object") return void 0;
6389
+ return section.value.members.find((member) => memberName6(member) === "vulyk");
6390
+ }
6391
+ var vulykDependencyRule = {
6392
+ meta: {
6393
+ schema: [],
6394
+ type: "problem",
6395
+ docs: {
6396
+ description: "Require vulyk in devDependencies so its typed config and CLI use the pinned package."
6397
+ }
6398
+ },
6399
+ create(context) {
6400
+ return {
6401
+ Document(node) {
6402
+ const runtimeDependency = dependency(node.body, "dependencies");
6403
+ const developmentDependency = dependency(node.body, "devDependencies");
6404
+ if (runtimeDependency) {
6405
+ context.report({
6406
+ node: runtimeDependency,
6407
+ message: "vulyk must be listed in devDependencies, not dependencies."
6408
+ });
6409
+ }
6410
+ if (!developmentDependency && !runtimeDependency) {
6411
+ context.report({
6412
+ node,
6413
+ message: "vulyk must be listed in package.json as a devDependency."
6414
+ });
6415
+ }
6416
+ }
6417
+ };
6418
+ }
6419
+ };
6420
+
6395
6421
  // eslint/rules/vulyk/vulyk-docs.ts
6396
6422
  import { existsSync as existsSync6, readFileSync as readFileSync11 } from "fs";
6397
6423
  import path49 from "path";
@@ -6432,7 +6458,7 @@ var vulykDocsRule = {
6432
6458
  if (!existsSync6(configPath)) {
6433
6459
  context.report({
6434
6460
  node,
6435
- message: "No vulyk.config.ts found. Run npx vulyk@latest init to create one that tracks the framework's docs."
6461
+ message: "No vulyk.config.ts found. Run npx vulyk init to create one that tracks the framework's docs."
6436
6462
  });
6437
6463
  return;
6438
6464
  }
@@ -6457,7 +6483,7 @@ var vulykDocsRule = {
6457
6483
  if (!existsSync6(agentsPath)) {
6458
6484
  context.report({
6459
6485
  node,
6460
- message: "No AGENTS.md found. Run npx vulyk@latest agents to generate the agent file that routes to the tracked docs."
6486
+ message: "No AGENTS.md found. Run npx vulyk agents to generate the agent file that routes to the tracked docs."
6461
6487
  });
6462
6488
  }
6463
6489
  }
@@ -6467,6 +6493,7 @@ var vulykDocsRule = {
6467
6493
 
6468
6494
  // eslint/rules/vulyk/index.ts
6469
6495
  var vulykRules = {
6496
+ "vulyk-dependency": vulykDependencyRule,
6470
6497
  "vulyk-docs": vulykDocsRule
6471
6498
  };
6472
6499
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",