pasika 0.7.4 → 0.7.6

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
@@ -6334,7 +6300,7 @@ var VITEST_CONFIG_NAMES2 = [
6334
6300
  "vitest.config.mjs",
6335
6301
  "vitest.config.cjs"
6336
6302
  ];
6337
- function memberName6(member) {
6303
+ function memberName5(member) {
6338
6304
  return member.name.type === "String" ? member.name.value : member.name.name;
6339
6305
  }
6340
6306
  var huskyHookRule = {
@@ -6342,7 +6308,7 @@ var huskyHookRule = {
6342
6308
  schema: [],
6343
6309
  type: "problem",
6344
6310
  docs: {
6345
- 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."
6311
+ description: "Require a pre-commit hook that runs lint-staged, typecheck, coverage and suppression pruning with local staging, and the libyear drift check."
6346
6312
  }
6347
6313
  },
6348
6314
  create(context) {
@@ -6360,8 +6326,8 @@ var huskyHookRule = {
6360
6326
  return;
6361
6327
  }
6362
6328
  const content = readFileSync10(hookPath, "utf8");
6363
- const scripts = root.members.find((member) => memberName6(member) === "scripts");
6364
- 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) : []);
6365
6331
  const requireNamedScript = (name) => {
6366
6332
  if (!scriptNames.has(name)) {
6367
6333
  context.report({ node, message: `package.json must declare a "${name}" script.` });
@@ -6392,9 +6358,17 @@ var huskyHookRule = {
6392
6358
  const suppressionsPath = path48.join(context.cwd, "eslint-suppressions.json");
6393
6359
  if (existsSync5(suppressionsPath)) {
6394
6360
  requireNamedScript("lint:prune");
6361
+ const pruneIndex = content.indexOf("npm run lint:prune");
6362
+ const localAddIndex = content.indexOf("git add eslint-suppressions.json");
6363
+ if (localAddIndex <= pruneIndex) {
6364
+ context.report({
6365
+ node,
6366
+ message: ".husky/pre-commit must stage eslint-suppressions.json after pruning suppressions."
6367
+ });
6368
+ }
6395
6369
  }
6396
6370
  if (scripts?.value.type === "Object") {
6397
- const prepare = scripts.value.members.find((member) => memberName6(member) === "prepare");
6371
+ const prepare = scripts.value.members.find((member) => memberName5(member) === "prepare");
6398
6372
  if (prepare?.value.type === "String" && !prepare.value.value.includes("husky")) {
6399
6373
  context.report({
6400
6374
  node: prepare,
@@ -6412,6 +6386,46 @@ var huskyRules = {
6412
6386
  "husky-hook": huskyHookRule
6413
6387
  };
6414
6388
 
6389
+ // eslint/rules/vulyk/vulyk-dependency.ts
6390
+ function memberName6(member) {
6391
+ return member.name.type === "String" ? member.name.value : member.name.name;
6392
+ }
6393
+ function dependency(root, sectionName) {
6394
+ if (root.type !== "Object") return void 0;
6395
+ const section = root.members.find((member) => memberName6(member) === sectionName);
6396
+ if (section?.value.type !== "Object") return void 0;
6397
+ return section.value.members.find((member) => memberName6(member) === "vulyk");
6398
+ }
6399
+ var vulykDependencyRule = {
6400
+ meta: {
6401
+ schema: [],
6402
+ type: "problem",
6403
+ docs: {
6404
+ description: "Require vulyk in devDependencies so its typed config and CLI use the pinned package."
6405
+ }
6406
+ },
6407
+ create(context) {
6408
+ return {
6409
+ Document(node) {
6410
+ const runtimeDependency = dependency(node.body, "dependencies");
6411
+ const developmentDependency = dependency(node.body, "devDependencies");
6412
+ if (runtimeDependency) {
6413
+ context.report({
6414
+ node: runtimeDependency,
6415
+ message: "vulyk must be listed in devDependencies, not dependencies."
6416
+ });
6417
+ }
6418
+ if (!developmentDependency && !runtimeDependency) {
6419
+ context.report({
6420
+ node,
6421
+ message: "vulyk must be listed in package.json as a devDependency."
6422
+ });
6423
+ }
6424
+ }
6425
+ };
6426
+ }
6427
+ };
6428
+
6415
6429
  // eslint/rules/vulyk/vulyk-docs.ts
6416
6430
  import { existsSync as existsSync6, readFileSync as readFileSync11 } from "fs";
6417
6431
  import path49 from "path";
@@ -6452,7 +6466,7 @@ var vulykDocsRule = {
6452
6466
  if (!existsSync6(configPath)) {
6453
6467
  context.report({
6454
6468
  node,
6455
- message: "No vulyk.config.ts found. Run npx vulyk@latest init to create one that tracks the framework's docs."
6469
+ message: "No vulyk.config.ts found. Run npx vulyk init to create one that tracks the framework's docs."
6456
6470
  });
6457
6471
  return;
6458
6472
  }
@@ -6477,7 +6491,7 @@ var vulykDocsRule = {
6477
6491
  if (!existsSync6(agentsPath)) {
6478
6492
  context.report({
6479
6493
  node,
6480
- message: "No AGENTS.md found. Run npx vulyk@latest agents to generate the agent file that routes to the tracked docs."
6494
+ message: "No AGENTS.md found. Run npx vulyk agents to generate the agent file that routes to the tracked docs."
6481
6495
  });
6482
6496
  }
6483
6497
  }
@@ -6487,6 +6501,7 @@ var vulykDocsRule = {
6487
6501
 
6488
6502
  // eslint/rules/vulyk/index.ts
6489
6503
  var vulykRules = {
6504
+ "vulyk-dependency": vulykDependencyRule,
6490
6505
  "vulyk-docs": vulykDocsRule
6491
6506
  };
6492
6507
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",