@7n/rules 1.0.0

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.
Files changed (1219) hide show
  1. package/.claude-template/hooks/capture-decisions.sh +355 -0
  2. package/.claude-template/hooks/lib/tooling-only.sh +77 -0
  3. package/.claude-template/hooks/normalize-decisions.sh +574 -0
  4. package/.claude-template/settings.template.json +26 -0
  5. package/.pi-template/extensions/n-rules-adr/docs/index.md +28 -0
  6. package/.pi-template/extensions/n-rules-adr/index.ts +105 -0
  7. package/.pi-template/extensions/n-rules-adr/tsconfig.json +17 -0
  8. package/AGENTS.template.md +53 -0
  9. package/CHANGELOG.md +4277 -0
  10. package/README.md +189 -0
  11. package/bin/docs/n-rules.md +612 -0
  12. package/bin/docs/rename-yaml-extensions.md +207 -0
  13. package/bin/n-rules.js +1709 -0
  14. package/bin/rename-yaml-extensions.mjs +42 -0
  15. package/docs/index.md +12 -0
  16. package/docs/stryker.config.md +31 -0
  17. package/docs/vitest.config.md +36 -0
  18. package/github-actions/release/action.yml +9 -0
  19. package/github-actions/setup-bun-deps/action.yml +27 -0
  20. package/package.json +87 -0
  21. package/rules/abie/base_deployment_preem/base_deployment_preem.mdc +22 -0
  22. package/rules/abie/base_deployment_preem/base_deployment_preem.rego +54 -0
  23. package/rules/abie/base_deployment_preem/concern.json +8 -0
  24. package/rules/abie/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
  25. package/rules/abie/clean_merged_ignore_branches/clean_merged_ignore_branches.rego +81 -0
  26. package/rules/abie/clean_merged_ignore_branches/concern.json +8 -0
  27. package/rules/abie/clean_merged_ignore_branches/template/clean-merged-branch.yml.snippet.yml +9 -0
  28. package/rules/abie/docs/index.md +11 -0
  29. package/rules/abie/env_dns/concern.json +4 -0
  30. package/rules/abie/env_dns/docs/main.md +32 -0
  31. package/rules/abie/env_dns/env_dns.mdc +33 -0
  32. package/rules/abie/env_dns/main.mjs +47 -0
  33. package/rules/abie/firebase_hosting/concern.json +4 -0
  34. package/rules/abie/firebase_hosting/docs/main.md +41 -0
  35. package/rules/abie/firebase_hosting/firebase_hosting.mdc +3 -0
  36. package/rules/abie/firebase_hosting/main.mjs +46 -0
  37. package/rules/abie/hc_pairing/concern.json +4 -0
  38. package/rules/abie/hc_pairing/docs/main.md +34 -0
  39. package/rules/abie/hc_pairing/hc_pairing.mdc +23 -0
  40. package/rules/abie/hc_pairing/main.mjs +52 -0
  41. package/rules/abie/health_check_policy/concern.json +8 -0
  42. package/rules/abie/health_check_policy/health_check_policy.mdc +19 -0
  43. package/rules/abie/health_check_policy/health_check_policy.rego +172 -0
  44. package/rules/abie/http_route_base/concern.json +8 -0
  45. package/rules/abie/http_route_base/http_route_base.mdc +9 -0
  46. package/rules/abie/http_route_base/http_route_base.rego +45 -0
  47. package/rules/abie/lib/docs/enabled.md +38 -0
  48. package/rules/abie/lib/docs/env-dns.md +31 -0
  49. package/rules/abie/lib/docs/hc-yaml.md +33 -0
  50. package/rules/abie/lib/docs/http-route.md +31 -0
  51. package/rules/abie/lib/docs/index.md +18 -0
  52. package/rules/abie/lib/docs/k8s-tree.md +44 -0
  53. package/rules/abie/lib/docs/kustomization-patches.md +37 -0
  54. package/rules/abie/lib/docs/overlay-paths.md +42 -0
  55. package/rules/abie/lib/docs/yaml.md +33 -0
  56. package/rules/abie/lib/enabled.mjs +37 -0
  57. package/rules/abie/lib/env-dns.mjs +81 -0
  58. package/rules/abie/lib/hc-yaml.mjs +27 -0
  59. package/rules/abie/lib/http-route.mjs +100 -0
  60. package/rules/abie/lib/k8s-tree.mjs +110 -0
  61. package/rules/abie/lib/kustomization-patches.mjs +211 -0
  62. package/rules/abie/lib/overlay-paths.mjs +97 -0
  63. package/rules/abie/lib/yaml.mjs +72 -0
  64. package/rules/abie/main.json +1 -0
  65. package/rules/abie/main.mdc +47 -0
  66. package/rules/abie/package_json_shared/concern.json +11 -0
  67. package/rules/abie/package_json_shared/package_json_shared.mdc +17 -0
  68. package/rules/abie/package_json_shared/package_json_shared.rego +16 -0
  69. package/rules/abie/ua_http_route/concern.json +4 -0
  70. package/rules/abie/ua_http_route/docs/main.md +44 -0
  71. package/rules/abie/ua_http_route/main.mjs +80 -0
  72. package/rules/abie/ua_http_route/ua_http_route.mdc +47 -0
  73. package/rules/abie/ua_node_selector/concern.json +4 -0
  74. package/rules/abie/ua_node_selector/docs/main.md +34 -0
  75. package/rules/abie/ua_node_selector/main.mjs +62 -0
  76. package/rules/abie/ua_node_selector/ua_node_selector.mdc +27 -0
  77. package/rules/adr/docs/index.md +11 -0
  78. package/rules/adr/hooks/concern.json +4 -0
  79. package/rules/adr/hooks/docs/main.md +38 -0
  80. package/rules/adr/hooks/hooks.mdc +32 -0
  81. package/rules/adr/hooks/main.mjs +367 -0
  82. package/rules/adr/main.json +1 -0
  83. package/rules/adr/main.mdc +93 -0
  84. package/rules/adr/settings_json/concern.json +9 -0
  85. package/rules/adr/settings_json/settings_json.mdc +7 -0
  86. package/rules/adr/settings_json/settings_json.rego +37 -0
  87. package/rules/adr/settings_local_json/concern.json +9 -0
  88. package/rules/adr/settings_local_json/settings_local_json.mdc +7 -0
  89. package/rules/adr/settings_local_json/settings_local_json.rego +40 -0
  90. package/rules/bun/bunfig/bunfig.mdc +12 -0
  91. package/rules/bun/bunfig/bunfig.rego +29 -0
  92. package/rules/bun/bunfig/concern.json +9 -0
  93. package/rules/bun/bunfig/template/bunfig.toml.snippet.toml +2 -0
  94. package/rules/bun/docs/index.md +11 -0
  95. package/rules/bun/layout/concern.json +16 -0
  96. package/rules/bun/layout/docs/fix-layout.md +29 -0
  97. package/rules/bun/layout/docs/main.md +34 -0
  98. package/rules/bun/layout/fix-layout.mjs +63 -0
  99. package/rules/bun/layout/layout.mdc +60 -0
  100. package/rules/bun/layout/main.mjs +53 -0
  101. package/rules/bun/licensee/concern.json +7 -0
  102. package/rules/bun/licensee/docs/fix-licensee.md +28 -0
  103. package/rules/bun/licensee/docs/index.md +12 -0
  104. package/rules/bun/licensee/docs/main.md +37 -0
  105. package/rules/bun/licensee/fix-licensee.mjs +32 -0
  106. package/rules/bun/licensee/main.mjs +44 -0
  107. package/rules/bun/main.json +1 -0
  108. package/rules/bun/main.mdc +11 -0
  109. package/rules/bun/package_json/concern.json +9 -0
  110. package/rules/bun/package_json/docs/fix-package_json.md +28 -0
  111. package/rules/bun/package_json/docs/index.md +9 -0
  112. package/rules/bun/package_json/fix-package_json.mjs +311 -0
  113. package/rules/bun/package_json/package_json.mdc +14 -0
  114. package/rules/bun/package_json/package_json.rego +64 -0
  115. package/rules/bun/package_json/template/package.json.deny.json +4 -0
  116. package/rules/capacitor/docs/index.md +11 -0
  117. package/rules/capacitor/main.json +1 -0
  118. package/rules/capacitor/main.mdc +12 -0
  119. package/rules/capacitor/package_json/concern.json +9 -0
  120. package/rules/capacitor/package_json/package_json.mdc +9 -0
  121. package/rules/capacitor/package_json/package_json.rego +45 -0
  122. package/rules/capacitor/platforms/concern.json +4 -0
  123. package/rules/capacitor/platforms/docs/main.md +41 -0
  124. package/rules/capacitor/platforms/main.mjs +486 -0
  125. package/rules/changelog/consistency/concern.json +4 -0
  126. package/rules/changelog/consistency/docs/fix-consistency.md +31 -0
  127. package/rules/changelog/consistency/docs/main.md +41 -0
  128. package/rules/changelog/consistency/fix-consistency.mjs +71 -0
  129. package/rules/changelog/consistency/main.mjs +820 -0
  130. package/rules/changelog/docs/index.md +11 -0
  131. package/rules/changelog/lib/docs/index.md +11 -0
  132. package/rules/changelog/lib/docs/package-manifest.md +214 -0
  133. package/rules/changelog/lib/package-manifest.mjs +158 -0
  134. package/rules/changelog/main.json +1 -0
  135. package/rules/changelog/main.mdc +7 -0
  136. package/rules/changelog/presence/concern.json +7 -0
  137. package/rules/changelog/presence/docs/main.md +44 -0
  138. package/rules/changelog/presence/main.mjs +87 -0
  139. package/rules/ci4/docs/index.md +11 -0
  140. package/rules/ci4/main.json +1 -0
  141. package/rules/ci4/main.mdc +375 -0
  142. package/rules/ci4/marksman_config/concern.json +5 -0
  143. package/rules/ci4/marksman_config/data/marksman_config/marksman.baseline.toml +27 -0
  144. package/rules/ci4/marksman_config/docs/fix-marksman_config.md +27 -0
  145. package/rules/ci4/marksman_config/docs/main.md +30 -0
  146. package/rules/ci4/marksman_config/fix-marksman_config.mjs +24 -0
  147. package/rules/ci4/marksman_config/main.mjs +38 -0
  148. package/rules/ci4/marksman_config/marksman_config.mdc +31 -0
  149. package/rules/ci4/vscode_extensions/concern.json +9 -0
  150. package/rules/ci4/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
  151. package/rules/ci4/vscode_extensions/docs/index.md +11 -0
  152. package/rules/ci4/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  153. package/rules/ci4/vscode_extensions/template/extensions.json.snippet.json +3 -0
  154. package/rules/ci4/vscode_extensions/vscode_extensions.mdc +9 -0
  155. package/rules/ci4/vscode_extensions/vscode_extensions.rego +12 -0
  156. package/rules/doc-files/check/concern.json +7 -0
  157. package/rules/doc-files/check/docs/fix-check.md +28 -0
  158. package/rules/doc-files/check/docs/fix-worker.md +28 -0
  159. package/rules/doc-files/check/docs/main.md +32 -0
  160. package/rules/doc-files/check/fix-check.mjs +45 -0
  161. package/rules/doc-files/check/fix-worker.mjs +56 -0
  162. package/rules/doc-files/check/main.mjs +99 -0
  163. package/rules/doc-files/docgen-crc/concern.json +3 -0
  164. package/rules/doc-files/docgen-crc/docs/main.md +46 -0
  165. package/rules/doc-files/docgen-crc/main.mjs +207 -0
  166. package/rules/doc-files/docgen-extract/concern.json +3 -0
  167. package/rules/doc-files/docgen-extract/docs/main.md +38 -0
  168. package/rules/doc-files/docgen-extract/main.mjs +471 -0
  169. package/rules/doc-files/docgen-extract-anchors/concern.json +3 -0
  170. package/rules/doc-files/docgen-extract-anchors/docs/main.md +49 -0
  171. package/rules/doc-files/docgen-extract-anchors/main.mjs +115 -0
  172. package/rules/doc-files/docgen-files-batch/concern.json +3 -0
  173. package/rules/doc-files/docgen-files-batch/docs/main.md +38 -0
  174. package/rules/doc-files/docgen-files-batch/main.mjs +517 -0
  175. package/rules/doc-files/docgen-fix-worker/concern.json +3 -0
  176. package/rules/doc-files/docgen-gen/concern.json +3 -0
  177. package/rules/doc-files/docgen-gen/docs/main.md +40 -0
  178. package/rules/doc-files/docgen-gen/main.mjs +582 -0
  179. package/rules/doc-files/docgen-ignore/concern.json +3 -0
  180. package/rules/doc-files/docgen-ignore/docs/main.md +33 -0
  181. package/rules/doc-files/docgen-ignore/main.mjs +54 -0
  182. package/rules/doc-files/docgen-judge/concern.json +3 -0
  183. package/rules/doc-files/docgen-judge/docs/main.md +43 -0
  184. package/rules/doc-files/docgen-judge/main.mjs +116 -0
  185. package/rules/doc-files/docgen-prompts/concern.json +3 -0
  186. package/rules/doc-files/docgen-prompts/docs/main.md +48 -0
  187. package/rules/doc-files/docgen-prompts/main.mjs +222 -0
  188. package/rules/doc-files/docgen-scan/concern.json +3 -0
  189. package/rules/doc-files/docgen-scan/docs/main.md +52 -0
  190. package/rules/doc-files/docgen-scan/main.mjs +231 -0
  191. package/rules/doc-files/docs/index.md +11 -0
  192. package/rules/doc-files/main.json +1 -0
  193. package/rules/doc-files/main.mdc +49 -0
  194. package/rules/doc-files/units/concern.json +3 -0
  195. package/rules/doc-files/units/docs/main.md +32 -0
  196. package/rules/doc-files/units/main.mjs +20 -0
  197. package/rules/doc-files/units-js/concern.json +3 -0
  198. package/rules/doc-files/units-js/docs/main.md +32 -0
  199. package/rules/doc-files/units-js/main.mjs +141 -0
  200. package/rules/doc-files/units-rs/concern.json +3 -0
  201. package/rules/doc-files/units-rs/docs/main.md +36 -0
  202. package/rules/doc-files/units-rs/main.mjs +311 -0
  203. package/rules/docker/docs/index.md +11 -0
  204. package/rules/docker/lib/docker-hadolint.mjs +60 -0
  205. package/rules/docker/lib/docker-mirror.mjs +148 -0
  206. package/rules/docker/lib/docker-native-addon.mjs +93 -0
  207. package/rules/docker/lib/docker-nginx-user.mjs +122 -0
  208. package/rules/docker/lib/docs/docker-hadolint.md +29 -0
  209. package/rules/docker/lib/docs/docker-mirror.md +251 -0
  210. package/rules/docker/lib/docs/docker-native-addon.md +174 -0
  211. package/rules/docker/lib/docs/docker-nginx-user.md +223 -0
  212. package/rules/docker/lib/docs/index.md +14 -0
  213. package/rules/docker/lint/concern.json +7 -0
  214. package/rules/docker/lint/docs/main.md +47 -0
  215. package/rules/docker/lint/main.mjs +360 -0
  216. package/rules/docker/lint_docker_yml/concern.json +9 -0
  217. package/rules/docker/lint_docker_yml/lint_docker_yml.mdc +14 -0
  218. package/rules/docker/lint_docker_yml/lint_docker_yml.rego +79 -0
  219. package/rules/docker/lint_docker_yml/template/lint-docker.yml.snippet.yml +41 -0
  220. package/rules/docker/main.json +1 -0
  221. package/rules/docker/main.mdc +14 -0
  222. package/rules/efes/docs/index.md +11 -0
  223. package/rules/efes/main.json +1 -0
  224. package/rules/efes/main.mdc +21 -0
  225. package/rules/efes/package_json_shared/concern.json +11 -0
  226. package/rules/efes/package_json_shared/package_json_shared.mdc +33 -0
  227. package/rules/efes/package_json_shared/package_json_shared.rego +16 -0
  228. package/rules/feedback/docs/index.md +11 -0
  229. package/rules/feedback/main.json +1 -0
  230. package/rules/feedback/main.mdc +63 -0
  231. package/rules/ga/clean_ga_workflows/clean_ga_workflows.mdc +20 -0
  232. package/rules/ga/clean_ga_workflows/clean_ga_workflows.rego +112 -0
  233. package/rules/ga/clean_ga_workflows/concern.json +10 -0
  234. package/rules/ga/clean_ga_workflows/template/clean-ga-workflows.yml.snippet.yml +26 -0
  235. package/rules/ga/clean_merged_branch/clean_merged_branch.mdc +24 -0
  236. package/rules/ga/clean_merged_branch/clean_merged_branch.rego +163 -0
  237. package/rules/ga/clean_merged_branch/concern.json +10 -0
  238. package/rules/ga/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml +37 -0
  239. package/rules/ga/docs/index.md +11 -0
  240. package/rules/ga/git_ai/concern.json +11 -0
  241. package/rules/ga/git_ai/git_ai.mdc +19 -0
  242. package/rules/ga/git_ai/git_ai.rego +76 -0
  243. package/rules/ga/git_ai/template/git-ai.yml.snippet.yml +30 -0
  244. package/rules/ga/lint_ga/concern.json +10 -0
  245. package/rules/ga/lint_ga/lint_ga.mdc +21 -0
  246. package/rules/ga/lint_ga/lint_ga.rego +132 -0
  247. package/rules/ga/lint_ga/template/lint-ga.yml.snippet.yml +41 -0
  248. package/rules/ga/main.json +1 -0
  249. package/rules/ga/main.mdc +17 -0
  250. package/rules/ga/vscode_extensions/concern.json +11 -0
  251. package/rules/ga/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
  252. package/rules/ga/vscode_extensions/docs/index.md +11 -0
  253. package/rules/ga/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  254. package/rules/ga/vscode_extensions/template/extensions.json.snippet.json +1 -0
  255. package/rules/ga/vscode_extensions/vscode_extensions.mdc +9 -0
  256. package/rules/ga/vscode_extensions/vscode_extensions.rego +18 -0
  257. package/rules/ga/vscode_settings/concern.json +11 -0
  258. package/rules/ga/vscode_settings/template/settings.json.snippet.json +1 -0
  259. package/rules/ga/vscode_settings/vscode_settings.mdc +9 -0
  260. package/rules/ga/vscode_settings/vscode_settings.rego +22 -0
  261. package/rules/ga/workflow_common/concern.json +9 -0
  262. package/rules/ga/workflow_common/template/uses-min-versions.snippet.json +4 -0
  263. package/rules/ga/workflow_common/workflow_common.mdc +18 -0
  264. package/rules/ga/workflow_common/workflow_common.rego +288 -0
  265. package/rules/ga/workflows/concern.json +8 -0
  266. package/rules/ga/workflows/docs/fix-workflows.md +37 -0
  267. package/rules/ga/workflows/docs/main.md +38 -0
  268. package/rules/ga/workflows/fix-workflows.mjs +212 -0
  269. package/rules/ga/workflows/main.mjs +433 -0
  270. package/rules/ga/workflows/workflows.mdc +33 -0
  271. package/rules/ga/zizmor_yml/concern.json +11 -0
  272. package/rules/ga/zizmor_yml/template/zizmor.yml.snippet.yml +5 -0
  273. package/rules/ga/zizmor_yml/zizmor_yml.mdc +9 -0
  274. package/rules/ga/zizmor_yml/zizmor_yml.rego +27 -0
  275. package/rules/graphql/docs/index.md +11 -0
  276. package/rules/graphql/lib/docs/graphql-gql-scan.md +226 -0
  277. package/rules/graphql/lib/docs/index.md +11 -0
  278. package/rules/graphql/lib/graphql-gql-scan.mjs +146 -0
  279. package/rules/graphql/main.json +1 -0
  280. package/rules/graphql/main.mdc +8 -0
  281. package/rules/graphql/tooling/concern.json +8 -0
  282. package/rules/graphql/tooling/docs/main.md +36 -0
  283. package/rules/graphql/tooling/main.mjs +129 -0
  284. package/rules/graphql/tooling/tooling.mdc +13 -0
  285. package/rules/graphql/vscode_extensions/concern.json +9 -0
  286. package/rules/graphql/vscode_extensions/docs/fix-vscode_extensions.md +24 -0
  287. package/rules/graphql/vscode_extensions/docs/index.md +11 -0
  288. package/rules/graphql/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  289. package/rules/graphql/vscode_extensions/vscode_extensions.mdc +9 -0
  290. package/rules/graphql/vscode_extensions/vscode_extensions.rego +20 -0
  291. package/rules/hasura/docs/index.md +11 -0
  292. package/rules/hasura/internal_urls/concern.json +5 -0
  293. package/rules/hasura/internal_urls/docs/fix-internal_urls.md +26 -0
  294. package/rules/hasura/internal_urls/docs/index.md +12 -0
  295. package/rules/hasura/internal_urls/docs/main.md +36 -0
  296. package/rules/hasura/internal_urls/fix-internal_urls.mjs +66 -0
  297. package/rules/hasura/internal_urls/internal_urls.mdc +27 -0
  298. package/rules/hasura/internal_urls/main.mjs +233 -0
  299. package/rules/hasura/main.json +1 -0
  300. package/rules/hasura/main.mdc +8 -0
  301. package/rules/hasura/migrations/concern.json +4 -0
  302. package/rules/hasura/migrations/docs/fix-migrations.md +25 -0
  303. package/rules/hasura/migrations/docs/index.md +12 -0
  304. package/rules/hasura/migrations/docs/main.md +35 -0
  305. package/rules/hasura/migrations/fix-migrations.mjs +35 -0
  306. package/rules/hasura/migrations/main.mjs +53 -0
  307. package/rules/hasura/migrations/migrations.mdc +13 -0
  308. package/rules/hasura/svc_hl/concern.json +8 -0
  309. package/rules/hasura/svc_hl/svc_hl.mdc +15 -0
  310. package/rules/hasura/svc_hl/svc_hl.rego +50 -0
  311. package/rules/image-avif/avif_generation/avif_generation.mdc +26 -0
  312. package/rules/image-avif/avif_generation/concern.json +4 -0
  313. package/rules/image-avif/avif_generation/docs/fix-avif_generation.md +27 -0
  314. package/rules/image-avif/avif_generation/docs/main.md +36 -0
  315. package/rules/image-avif/avif_generation/fix-avif_generation.mjs +80 -0
  316. package/rules/image-avif/avif_generation/main.mjs +411 -0
  317. package/rules/image-avif/docs/index.md +11 -0
  318. package/rules/image-avif/main.json +1 -0
  319. package/rules/image-avif/main.mdc +8 -0
  320. package/rules/image-avif/package_json/concern.json +9 -0
  321. package/rules/image-avif/package_json/package_json.mdc +18 -0
  322. package/rules/image-avif/package_json/package_json.rego +47 -0
  323. package/rules/image-avif/package_json/template/package.json.deny.json +5 -0
  324. package/rules/image-compress/check/concern.json +7 -0
  325. package/rules/image-compress/check/docs/fix-check.md +34 -0
  326. package/rules/image-compress/check/docs/index.md +10 -0
  327. package/rules/image-compress/check/docs/main.md +31 -0
  328. package/rules/image-compress/check/fix-check.mjs +74 -0
  329. package/rules/image-compress/check/main.mjs +64 -0
  330. package/rules/image-compress/docs/index.md +11 -0
  331. package/rules/image-compress/main.json +1 -0
  332. package/rules/image-compress/main.mdc +10 -0
  333. package/rules/image-compress/package_json/concern.json +9 -0
  334. package/rules/image-compress/package_json/package_json.mdc +13 -0
  335. package/rules/image-compress/package_json/package_json.rego +21 -0
  336. package/rules/image-compress/package_json/template/package.json.deny.json +8 -0
  337. package/rules/image-compress/package_setup/concern.json +4 -0
  338. package/rules/image-compress/package_setup/docs/main.md +34 -0
  339. package/rules/image-compress/package_setup/main.mjs +98 -0
  340. package/rules/image-compress/package_setup/package_setup.mdc +13 -0
  341. package/rules/js/check/concern.json +19 -0
  342. package/rules/js/check/docs/eslint-config.md +56 -0
  343. package/rules/js/check/docs/fix-check.md +31 -0
  344. package/rules/js/check/docs/index.md +13 -0
  345. package/rules/js/check/docs/main.md +45 -0
  346. package/rules/js/check/eslint-config.mjs +262 -0
  347. package/rules/js/check/fix-check.mjs +39 -0
  348. package/rules/js/check/main.mjs +312 -0
  349. package/rules/js/dep-policy/concern.json +4 -0
  350. package/rules/js/dep-policy/dep-policy.mdc +36 -0
  351. package/rules/js/dep-policy/docs/main.md +35 -0
  352. package/rules/js/dep-policy/main.mjs +99 -0
  353. package/rules/js/docs/index.md +11 -0
  354. package/rules/js/eslint/concern.json +7 -0
  355. package/rules/js/eslint/docs/fix-eslint.md +32 -0
  356. package/rules/js/eslint/docs/main.md +33 -0
  357. package/rules/js/eslint/fix-eslint.mjs +77 -0
  358. package/rules/js/eslint/main.mjs +99 -0
  359. package/rules/js/jscpd_config/concern.json +11 -0
  360. package/rules/js/jscpd_config/jscpd_config.mdc +14 -0
  361. package/rules/js/jscpd_config/jscpd_config.rego +44 -0
  362. package/rules/js/jscpd_config/template/.jscpd.json.snippet.json +7 -0
  363. package/rules/js/jscpd_duplicates/concern.json +7 -0
  364. package/rules/js/jscpd_duplicates/docs/main.md +29 -0
  365. package/rules/js/jscpd_duplicates/main.mjs +70 -0
  366. package/rules/js/knip/concern.json +6 -0
  367. package/rules/js/knip/docs/main.md +32 -0
  368. package/rules/js/knip/main.mjs +68 -0
  369. package/rules/js/lint-findings/concern.json +3 -0
  370. package/rules/js/lint-findings/docs/main.md +41 -0
  371. package/rules/js/lint-findings/main.mjs +125 -0
  372. package/rules/js/lint_js_yml/concern.json +9 -0
  373. package/rules/js/lint_js_yml/lint_js_yml.mdc +14 -0
  374. package/rules/js/lint_js_yml/lint_js_yml.rego +117 -0
  375. package/rules/js/lint_js_yml/template/lint-js.yml.snippet.yml +40 -0
  376. package/rules/js/main.json +1 -0
  377. package/rules/js/main.mdc +19 -0
  378. package/rules/js/package_json/concern.json +9 -0
  379. package/rules/js/package_json/package_json.mdc +15 -0
  380. package/rules/js/package_json/package_json.rego +142 -0
  381. package/rules/js/package_json/template/package.json.snippet.json +6 -0
  382. package/rules/js/tooling/concern.json +3 -0
  383. package/rules/js/tooling/data/tooling/knip-canonical.json +29 -0
  384. package/rules/js/tooling/data/tooling/oxlint-canonical.json +400 -0
  385. package/rules/js/tooling/docs/main.md +31 -0
  386. package/rules/js/tooling/main.mjs +149 -0
  387. package/rules/js/utils_imports/concern.json +4 -0
  388. package/rules/js/utils_imports/docs/main.md +50 -0
  389. package/rules/js/utils_imports/main.mjs +185 -0
  390. package/rules/js/vscode_extensions/concern.json +11 -0
  391. package/rules/js/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
  392. package/rules/js/vscode_extensions/docs/index.md +11 -0
  393. package/rules/js/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  394. package/rules/js/vscode_extensions/template/extensions.json.snippet.json +3 -0
  395. package/rules/js/vscode_extensions/vscode_extensions.mdc +11 -0
  396. package/rules/js/vscode_extensions/vscode_extensions.rego +12 -0
  397. package/rules/js-bun-db/docs/index.md +11 -0
  398. package/rules/js-bun-db/lib/bun-sql-scan.mjs +1055 -0
  399. package/rules/js-bun-db/lib/docs/bun-sql-scan.md +63 -0
  400. package/rules/js-bun-db/lib/docs/index.md +11 -0
  401. package/rules/js-bun-db/main.json +1 -0
  402. package/rules/js-bun-db/main.mdc +8 -0
  403. package/rules/js-bun-db/package_json/concern.json +9 -0
  404. package/rules/js-bun-db/package_json/package_json.mdc +17 -0
  405. package/rules/js-bun-db/package_json/package_json.rego +15 -0
  406. package/rules/js-bun-db/package_json/template/package.json.deny.json +6 -0
  407. package/rules/js-bun-db/safety/concern.json +4 -0
  408. package/rules/js-bun-db/safety/docs/main.md +34 -0
  409. package/rules/js-bun-db/safety/main.mjs +430 -0
  410. package/rules/js-bun-redis/docs/index.md +11 -0
  411. package/rules/js-bun-redis/imports/concern.json +4 -0
  412. package/rules/js-bun-redis/imports/docs/main.md +36 -0
  413. package/rules/js-bun-redis/imports/imports.mdc +47 -0
  414. package/rules/js-bun-redis/imports/main.mjs +88 -0
  415. package/rules/js-bun-redis/lib/docs/index.md +11 -0
  416. package/rules/js-bun-redis/lib/docs/redis-imports.md +227 -0
  417. package/rules/js-bun-redis/lib/redis-imports.mjs +130 -0
  418. package/rules/js-bun-redis/main.json +1 -0
  419. package/rules/js-bun-redis/main.mdc +8 -0
  420. package/rules/js-bun-redis/package_json/concern.json +9 -0
  421. package/rules/js-bun-redis/package_json/package_json.mdc +11 -0
  422. package/rules/js-bun-redis/package_json/package_json.rego +15 -0
  423. package/rules/js-bun-redis/package_json/template/package.json.deny.json +12 -0
  424. package/rules/js-mssql/deps/concern.json +4 -0
  425. package/rules/js-mssql/deps/docs/main.md +33 -0
  426. package/rules/js-mssql/deps/main.mjs +297 -0
  427. package/rules/js-mssql/docs/index.md +11 -0
  428. package/rules/js-mssql/lib/docs/index.md +11 -0
  429. package/rules/js-mssql/lib/docs/mssql-pool-scan.md +380 -0
  430. package/rules/js-mssql/lib/mssql-pool-scan.mjs +610 -0
  431. package/rules/js-mssql/main.json +1 -0
  432. package/rules/js-mssql/main.mdc +14 -0
  433. package/rules/js-mssql/package_json/concern.json +9 -0
  434. package/rules/js-mssql/package_json/package_json.mdc +9 -0
  435. package/rules/js-mssql/package_json/package_json.rego +57 -0
  436. package/rules/js-run/configmap/concern.json +9 -0
  437. package/rules/js-run/configmap/configmap.mdc +31 -0
  438. package/rules/js-run/configmap/configmap.rego +21 -0
  439. package/rules/js-run/configmap/template/configmap.yaml.contains.yml +4 -0
  440. package/rules/js-run/docs/index.md +11 -0
  441. package/rules/js-run/jsconfig/concern.json +9 -0
  442. package/rules/js-run/jsconfig/docs/fix-jsconfig.md +29 -0
  443. package/rules/js-run/jsconfig/docs/index.md +9 -0
  444. package/rules/js-run/jsconfig/fix-jsconfig.mjs +119 -0
  445. package/rules/js-run/jsconfig/jsconfig.mdc +25 -0
  446. package/rules/js-run/jsconfig/jsconfig.rego +59 -0
  447. package/rules/js-run/jsconfig/template/jsconfig.json.snippet.json +10 -0
  448. package/rules/js-run/lib/bunyan-imports.mjs +98 -0
  449. package/rules/js-run/lib/check-env-scan.mjs +338 -0
  450. package/rules/js-run/lib/conn-file-rules.mjs +214 -0
  451. package/rules/js-run/lib/conn-imports-scan.mjs +154 -0
  452. package/rules/js-run/lib/docs/bunyan-imports.md +121 -0
  453. package/rules/js-run/lib/docs/check-env-scan.md +438 -0
  454. package/rules/js-run/lib/docs/conn-file-rules.md +304 -0
  455. package/rules/js-run/lib/docs/conn-imports-scan.md +208 -0
  456. package/rules/js-run/lib/docs/index.md +16 -0
  457. package/rules/js-run/lib/docs/promise-settimeout-scan.md +334 -0
  458. package/rules/js-run/lib/docs/temporal-scan.md +29 -0
  459. package/rules/js-run/lib/promise-settimeout-scan.mjs +128 -0
  460. package/rules/js-run/lib/temporal-scan.mjs +52 -0
  461. package/rules/js-run/main.json +1 -0
  462. package/rules/js-run/main.mdc +16 -0
  463. package/rules/js-run/package_json/concern.json +9 -0
  464. package/rules/js-run/package_json/package_json.mdc +38 -0
  465. package/rules/js-run/package_json/package_json.rego +37 -0
  466. package/rules/js-run/package_json/template/package.json.deny.json +22 -0
  467. package/rules/js-run/runtime/concern.json +12 -0
  468. package/rules/js-run/runtime/docs/fix-runtime.md +27 -0
  469. package/rules/js-run/runtime/docs/main.md +35 -0
  470. package/rules/js-run/runtime/fix-runtime.mjs +46 -0
  471. package/rules/js-run/runtime/main.mjs +494 -0
  472. package/rules/js-run/runtime/runtime.mdc +14 -0
  473. package/rules/k8s/base_kustomization/base_kustomization.mdc +12 -0
  474. package/rules/k8s/base_kustomization/base_kustomization.rego +77 -0
  475. package/rules/k8s/base_kustomization/concern.json +8 -0
  476. package/rules/k8s/base_manifest/base_manifest.mdc +14 -0
  477. package/rules/k8s/base_manifest/base_manifest.rego +154 -0
  478. package/rules/k8s/base_manifest/concern.json +8 -0
  479. package/rules/k8s/docs/index.md +11 -0
  480. package/rules/k8s/gateway/concern.json +8 -0
  481. package/rules/k8s/gateway/gateway.mdc +31 -0
  482. package/rules/k8s/gateway/gateway.rego +151 -0
  483. package/rules/k8s/hasura_configmap/concern.json +8 -0
  484. package/rules/k8s/hasura_configmap/hasura_configmap.mdc +20 -0
  485. package/rules/k8s/hasura_configmap/hasura_configmap.rego +129 -0
  486. package/rules/k8s/hasura_httproute/concern.json +8 -0
  487. package/rules/k8s/hasura_httproute/hasura_httproute.mdc +16 -0
  488. package/rules/k8s/hasura_httproute/hasura_httproute.rego +298 -0
  489. package/rules/k8s/hpa_pdb/concern.json +8 -0
  490. package/rules/k8s/hpa_pdb/hpa_pdb.mdc +25 -0
  491. package/rules/k8s/hpa_pdb/hpa_pdb.rego +139 -0
  492. package/rules/k8s/kubeconform/concern.json +7 -0
  493. package/rules/k8s/kubeconform/docs/main.md +32 -0
  494. package/rules/k8s/kubeconform/main.mjs +39 -0
  495. package/rules/k8s/kustomization/concern.json +8 -0
  496. package/rules/k8s/kustomization/kustomization.mdc +20 -0
  497. package/rules/k8s/kustomization/kustomization.rego +220 -0
  498. package/rules/k8s/lint_k8s_yml/concern.json +9 -0
  499. package/rules/k8s/lint_k8s_yml/lint_k8s_yml.rego +57 -0
  500. package/rules/k8s/lint_k8s_yml/template/lint-k8s.yml.snippet.yml +43 -0
  501. package/rules/k8s/main.json +1 -0
  502. package/rules/k8s/main.mdc +22 -0
  503. package/rules/k8s/manifest/concern.json +8 -0
  504. package/rules/k8s/manifest/manifest.mdc +17 -0
  505. package/rules/k8s/manifest/manifest.rego +328 -0
  506. package/rules/k8s/manifests/concern.json +6 -0
  507. package/rules/k8s/manifests/docs/fix-manifests.md +47 -0
  508. package/rules/k8s/manifests/fix-manifests.mjs +217 -0
  509. package/rules/k8s/manifests/main.mjs +6838 -0
  510. package/rules/k8s/network_policy/concern.json +8 -0
  511. package/rules/k8s/network_policy/network_policy.mdc +22 -0
  512. package/rules/k8s/network_policy/network_policy.rego +151 -0
  513. package/rules/k8s/network_policy/template/deployment.snippet.yaml +61 -0
  514. package/rules/k8s/network_policy/template/stateful-set.snippet.yaml +69 -0
  515. package/rules/k8s/svc_hl_yaml/concern.json +8 -0
  516. package/rules/k8s/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
  517. package/rules/k8s/svc_hl_yaml/svc_hl_yaml.rego +51 -0
  518. package/rules/k8s/svc_yaml/concern.json +8 -0
  519. package/rules/k8s/svc_yaml/svc_yaml.mdc +12 -0
  520. package/rules/k8s/svc_yaml/svc_yaml.rego +31 -0
  521. package/rules/nginx-default-tpl/docs/index.md +11 -0
  522. package/rules/nginx-default-tpl/main.json +1 -0
  523. package/rules/nginx-default-tpl/main.mdc +8 -0
  524. package/rules/nginx-default-tpl/template/concern.json +17 -0
  525. package/rules/nginx-default-tpl/template/docs/fix-template.md +26 -0
  526. package/rules/nginx-default-tpl/template/docs/main.md +42 -0
  527. package/rules/nginx-default-tpl/template/fix-template.mjs +67 -0
  528. package/rules/nginx-default-tpl/template/main.mjs +505 -0
  529. package/rules/nginx-default-tpl/vscode_extensions/concern.json +9 -0
  530. package/rules/nginx-default-tpl/vscode_extensions/vscode_extensions.mdc +11 -0
  531. package/rules/nginx-default-tpl/vscode_extensions/vscode_extensions.rego +16 -0
  532. package/rules/nginx-default-tpl/vscode_settings/concern.json +9 -0
  533. package/rules/nginx-default-tpl/vscode_settings/vscode_settings.mdc +15 -0
  534. package/rules/nginx-default-tpl/vscode_settings/vscode_settings.rego +36 -0
  535. package/rules/npm-module/docs/index.md +11 -0
  536. package/rules/npm-module/emit_types_config/concern.json +9 -0
  537. package/rules/npm-module/emit_types_config/emit_types_config.mdc +43 -0
  538. package/rules/npm-module/emit_types_config/emit_types_config.rego +28 -0
  539. package/rules/npm-module/emit_types_config/template/tsconfig.emit-types.json.snippet.json +9 -0
  540. package/rules/npm-module/header_doc_pointer/concern.json +5 -0
  541. package/rules/npm-module/header_doc_pointer/docs/main.md +40 -0
  542. package/rules/npm-module/header_doc_pointer/header_doc_pointer.mdc +18 -0
  543. package/rules/npm-module/header_doc_pointer/main.mjs +131 -0
  544. package/rules/npm-module/main.json +1 -0
  545. package/rules/npm-module/main.mdc +38 -0
  546. package/rules/npm-module/npm_package_json/concern.json +9 -0
  547. package/rules/npm-module/npm_package_json/npm_package_json.mdc +57 -0
  548. package/rules/npm-module/npm_package_json/npm_package_json.rego +73 -0
  549. package/rules/npm-module/npm_package_json/template/package.json.snippet.json +1 -0
  550. package/rules/npm-module/npm_publish_yml/concern.json +10 -0
  551. package/rules/npm-module/npm_publish_yml/template/npm-publish.yml.snippet.yml +49 -0
  552. package/rules/npm-module/package_structure/concern.json +5 -0
  553. package/rules/npm-module/package_structure/docs/main.md +37 -0
  554. package/rules/npm-module/package_structure/main.mjs +515 -0
  555. package/rules/npm-module/package_structure/package_structure.mdc +63 -0
  556. package/rules/npm-module/root_package_json/concern.json +9 -0
  557. package/rules/npm-module/root_package_json/root_package_json.mdc +41 -0
  558. package/rules/npm-module/root_package_json/root_package_json.rego +28 -0
  559. package/rules/npm-module/root_package_json/template/package.json.snippet.json +1 -0
  560. package/rules/npm-module/rule_meta/concern.json +8 -0
  561. package/rules/npm-module/rule_meta/docs/main.md +35 -0
  562. package/rules/npm-module/rule_meta/main.mjs +119 -0
  563. package/rules/npm-module/rule_meta/rule_meta.mdc +11 -0
  564. package/rules/npm-module/skill_meta/concern.json +5 -0
  565. package/rules/npm-module/skill_meta/docs/main.md +149 -0
  566. package/rules/npm-module/skill_meta/main.mjs +91 -0
  567. package/rules/npm-module/skill_meta/skill_meta.mdc +11 -0
  568. package/rules/php/cs_fixer/concern.json +7 -0
  569. package/rules/php/cs_fixer/docs/main.md +34 -0
  570. package/rules/php/cs_fixer/main.mjs +52 -0
  571. package/rules/php/docs/index.md +11 -0
  572. package/rules/php/lint_php_yml/concern.json +9 -0
  573. package/rules/php/lint_php_yml/lint_php_yml.mdc +23 -0
  574. package/rules/php/lint_php_yml/lint_php_yml.rego +34 -0
  575. package/rules/php/lint_php_yml/template/lint-php.yml.snippet.yml +47 -0
  576. package/rules/php/main.json +1 -0
  577. package/rules/php/main.mdc +8 -0
  578. package/rules/php/phpcs/concern.json +7 -0
  579. package/rules/php/phpcs/docs/main.md +31 -0
  580. package/rules/php/phpcs/main.mjs +71 -0
  581. package/rules/php/project/concern.json +6 -0
  582. package/rules/php/project/docs/main.md +36 -0
  583. package/rules/php/project/main.mjs +88 -0
  584. package/rules/php/tooling/concern.json +5 -0
  585. package/rules/php/tooling/docs/main.md +33 -0
  586. package/rules/php/tooling/main.mjs +35 -0
  587. package/rules/php/tooling/tooling.mdc +66 -0
  588. package/rules/python/applies/concern.json +4 -0
  589. package/rules/python/applies/docs/main.md +29 -0
  590. package/rules/python/applies/main.mjs +24 -0
  591. package/rules/python/docs/index.md +11 -0
  592. package/rules/python/lib/docs/index.md +9 -0
  593. package/rules/python/lib/docs/uv-run.md +32 -0
  594. package/rules/python/lib/uv-run.mjs +48 -0
  595. package/rules/python/lint_python_yml/concern.json +9 -0
  596. package/rules/python/lint_python_yml/lint_python_yml.mdc +12 -0
  597. package/rules/python/lint_python_yml/lint_python_yml.rego +68 -0
  598. package/rules/python/lint_python_yml/template/lint-python.yml.snippet.yml +41 -0
  599. package/rules/python/main.json +1 -0
  600. package/rules/python/main.mdc +8 -0
  601. package/rules/python/mypy/concern.json +7 -0
  602. package/rules/python/mypy/docs/main.md +32 -0
  603. package/rules/python/mypy/main.mjs +36 -0
  604. package/rules/python/project/concern.json +6 -0
  605. package/rules/python/project/docs/main.md +43 -0
  606. package/rules/python/project/main.mjs +115 -0
  607. package/rules/python/pyproject_toml/concern.json +9 -0
  608. package/rules/python/pyproject_toml/pyproject_toml.mdc +13 -0
  609. package/rules/python/pyproject_toml/pyproject_toml.rego +53 -0
  610. package/rules/python/pyproject_toml/template/pyproject.toml.deny.toml +2 -0
  611. package/rules/python/pyproject_toml/template/pyproject.toml.snippet.toml +12 -0
  612. package/rules/python/ruff/concern.json +7 -0
  613. package/rules/python/ruff/docs/fix-ruff.md +34 -0
  614. package/rules/python/ruff/docs/main.md +35 -0
  615. package/rules/python/ruff/fix-ruff.mjs +63 -0
  616. package/rules/python/ruff/main.mjs +52 -0
  617. package/rules/python/tooling/concern.json +15 -0
  618. package/rules/python/tooling/docs/index.md +11 -0
  619. package/rules/python/tooling/docs/main.md +35 -0
  620. package/rules/python/tooling/main.mjs +50 -0
  621. package/rules/python/tooling/tooling.mdc +23 -0
  622. package/rules/rego/conftest_verify/concern.json +6 -0
  623. package/rules/rego/conftest_verify/docs/main.md +31 -0
  624. package/rules/rego/conftest_verify/main.mjs +55 -0
  625. package/rules/rego/docs/index.md +11 -0
  626. package/rules/rego/lib/docs/index.md +9 -0
  627. package/rules/rego/lib/docs/run-external-tool.md +36 -0
  628. package/rules/rego/lib/run-external-tool.mjs +53 -0
  629. package/rules/rego/main.json +1 -0
  630. package/rules/rego/main.mdc +20 -0
  631. package/rules/rego/opa_check/concern.json +7 -0
  632. package/rules/rego/opa_check/docs/main.md +32 -0
  633. package/rules/rego/opa_check/main.mjs +34 -0
  634. package/rules/rego/package_json/concern.json +10 -0
  635. package/rules/rego/package_json/package_json.mdc +12 -0
  636. package/rules/rego/package_json/package_json.rego +21 -0
  637. package/rules/rego/regal/concern.json +7 -0
  638. package/rules/rego/regal/docs/index.md +11 -0
  639. package/rules/rego/regal/docs/main.md +32 -0
  640. package/rules/rego/regal/main.mjs +34 -0
  641. package/rules/rego/tooling/concern.json +5 -0
  642. package/rules/rego/tooling/docs/index.md +11 -0
  643. package/rules/rego/tooling/docs/main.md +31 -0
  644. package/rules/rego/tooling/main.mjs +25 -0
  645. package/rules/rego/tooling/tooling.mdc +14 -0
  646. package/rules/rego/vscode_extensions/concern.json +11 -0
  647. package/rules/rego/vscode_extensions/docs/fix-vscode_extensions.md +24 -0
  648. package/rules/rego/vscode_extensions/docs/index.md +11 -0
  649. package/rules/rego/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  650. package/rules/rego/vscode_extensions/template/extensions.json.snippet.json +1 -0
  651. package/rules/rego/vscode_extensions/vscode_extensions.mdc +11 -0
  652. package/rules/rego/vscode_extensions/vscode_extensions.rego +15 -0
  653. package/rules/rego/vscode_settings/concern.json +11 -0
  654. package/rules/rego/vscode_settings/template/settings.json.snippet.json +6 -0
  655. package/rules/rego/vscode_settings/vscode_settings.mdc +19 -0
  656. package/rules/rego/vscode_settings/vscode_settings.rego +30 -0
  657. package/rules/release/change.mjs +88 -0
  658. package/rules/release/docs/change.md +189 -0
  659. package/rules/release/docs/index.md +13 -0
  660. package/rules/release/docs/release.md +25 -0
  661. package/rules/release/lib/aggregate.mjs +82 -0
  662. package/rules/release/lib/change-file.mjs +116 -0
  663. package/rules/release/lib/docs/aggregate.md +250 -0
  664. package/rules/release/lib/docs/change-file.md +206 -0
  665. package/rules/release/lib/docs/fallback.md +207 -0
  666. package/rules/release/lib/docs/index.md +13 -0
  667. package/rules/release/lib/fallback.mjs +48 -0
  668. package/rules/release/main.json +1 -0
  669. package/rules/release/main.mdc +10 -0
  670. package/rules/release/release.mjs +220 -0
  671. package/rules/rust/applies/concern.json +4 -0
  672. package/rules/rust/applies/docs/index.md +11 -0
  673. package/rules/rust/applies/docs/main.md +30 -0
  674. package/rules/rust/applies/main.mjs +28 -0
  675. package/rules/rust/check/concern.json +7 -0
  676. package/rules/rust/check/docs/fix-check.md +30 -0
  677. package/rules/rust/check/docs/index.md +11 -0
  678. package/rules/rust/check/docs/main.md +37 -0
  679. package/rules/rust/check/fix-check.mjs +79 -0
  680. package/rules/rust/check/main.mjs +81 -0
  681. package/rules/rust/coverage/coverage.mdc +28 -0
  682. package/rules/rust/docs/index.md +11 -0
  683. package/rules/rust/lib/docs/has-cargo-toml.md +134 -0
  684. package/rules/rust/lib/docs/index.md +11 -0
  685. package/rules/rust/lib/has-cargo-toml.mjs +37 -0
  686. package/rules/rust/lint_rust_yml/concern.json +11 -0
  687. package/rules/rust/lint_rust_yml/lint_rust_yml.mdc +17 -0
  688. package/rules/rust/lint_rust_yml/lint_rust_yml.rego +79 -0
  689. package/rules/rust/lint_rust_yml/template/lint-rust.yml.snippet.yml +44 -0
  690. package/rules/rust/main.json +1 -0
  691. package/rules/rust/main.mdc +8 -0
  692. package/rules/rust/package_json/concern.json +10 -0
  693. package/rules/rust/package_json/package_json.mdc +12 -0
  694. package/rules/rust/package_json/package_json.rego +20 -0
  695. package/rules/rust/toolchain_cache/concern.json +5 -0
  696. package/rules/rust/toolchain_cache/docs/fix-toolchain_cache.md +35 -0
  697. package/rules/rust/toolchain_cache/docs/index.md +12 -0
  698. package/rules/rust/toolchain_cache/docs/main.md +57 -0
  699. package/rules/rust/toolchain_cache/fix-toolchain_cache.mjs +117 -0
  700. package/rules/rust/toolchain_cache/main.mjs +177 -0
  701. package/rules/rust/toolchain_cache/toolchain_cache.mdc +23 -0
  702. package/rules/rust/vscode_extensions/concern.json +11 -0
  703. package/rules/rust/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
  704. package/rules/rust/vscode_extensions/docs/index.md +11 -0
  705. package/rules/rust/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  706. package/rules/rust/vscode_extensions/template/extensions.json.snippet.json +1 -0
  707. package/rules/rust/vscode_extensions/vscode_extensions.mdc +9 -0
  708. package/rules/rust/vscode_extensions/vscode_extensions.rego +15 -0
  709. package/rules/security/docs/index.md +11 -0
  710. package/rules/security/lint_security_yml/concern.json +11 -0
  711. package/rules/security/lint_security_yml/lint_security_yml.mdc +7 -0
  712. package/rules/security/lint_security_yml/lint_security_yml.rego +33 -0
  713. package/rules/security/lint_security_yml/template/lint-security.yml.snippet.yml +31 -0
  714. package/rules/security/main.json +1 -0
  715. package/rules/security/main.mdc +15 -0
  716. package/rules/security/package_json/concern.json +9 -0
  717. package/rules/security/package_json/package_json.mdc +7 -0
  718. package/rules/security/package_json/package_json.rego +19 -0
  719. package/rules/security/package_json/template/package.json.deny.json +4 -0
  720. package/rules/security/sample_secret/concern.json +11 -0
  721. package/rules/security/sample_secret/docs/index.md +11 -0
  722. package/rules/security/sample_secret/docs/main.md +29 -0
  723. package/rules/security/sample_secret/main.mjs +80 -0
  724. package/rules/security/sample_secret/sample_secret.mdc +20 -0
  725. package/rules/security/scan/concern.json +6 -0
  726. package/rules/security/scan/docs/index.md +11 -0
  727. package/rules/security/scan/docs/main.md +32 -0
  728. package/rules/security/scan/main.mjs +48 -0
  729. package/rules/security/todo.MD +27 -0
  730. package/rules/security/trufflehog/concern.json +4 -0
  731. package/rules/security/trufflehog/docs/index.md +11 -0
  732. package/rules/security/trufflehog/docs/main.md +28 -0
  733. package/rules/security/trufflehog/main.mjs +45 -0
  734. package/rules/security/trufflehog/templates/trufflehog/.trufflehog-exclude.snippet.txt +6 -0
  735. package/rules/security/trufflehog/trufflehog.mdc +21 -0
  736. package/rules/style/docs/index.md +11 -0
  737. package/rules/style/lint/concern.json +7 -0
  738. package/rules/style/lint/docs/fix-lint.md +29 -0
  739. package/rules/style/lint/docs/index.md +11 -0
  740. package/rules/style/lint/docs/main.md +29 -0
  741. package/rules/style/lint/fix-lint.mjs +66 -0
  742. package/rules/style/lint/main.mjs +68 -0
  743. package/rules/style/lint_style_yml/concern.json +9 -0
  744. package/rules/style/lint_style_yml/lint_style_yml.mdc +13 -0
  745. package/rules/style/lint_style_yml/lint_style_yml.rego +38 -0
  746. package/rules/style/lint_style_yml/template/lint-style.yml.snippet.yml +39 -0
  747. package/rules/style/main.json +1 -0
  748. package/rules/style/main.mdc +13 -0
  749. package/rules/style/package_json/concern.json +9 -0
  750. package/rules/style/package_json/package_json.mdc +18 -0
  751. package/rules/style/package_json/package_json.rego +31 -0
  752. package/rules/style/package_json/template/package.json.snippet.json +5 -0
  753. package/rules/style/tooling/concern.json +14 -0
  754. package/rules/style/tooling/docs/fix-tooling.md +29 -0
  755. package/rules/style/tooling/docs/index.md +12 -0
  756. package/rules/style/tooling/docs/main.md +34 -0
  757. package/rules/style/tooling/fix-tooling.mjs +58 -0
  758. package/rules/style/tooling/main.mjs +78 -0
  759. package/rules/style/tooling/tooling.mdc +85 -0
  760. package/rules/style/vscode_extensions/concern.json +9 -0
  761. package/rules/style/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
  762. package/rules/style/vscode_extensions/docs/index.md +11 -0
  763. package/rules/style/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  764. package/rules/style/vscode_extensions/template/extensions.json.snippet.json +1 -0
  765. package/rules/style/vscode_extensions/vscode_extensions.mdc +13 -0
  766. package/rules/style/vscode_extensions/vscode_extensions.rego +13 -0
  767. package/rules/style/vscode_settings/concern.json +9 -0
  768. package/rules/style/vscode_settings/template/settings.json.snippet.json +5 -0
  769. package/rules/style/vscode_settings/vscode_settings.mdc +19 -0
  770. package/rules/style/vscode_settings/vscode_settings.rego +15 -0
  771. package/rules/tauri/cargo_mutants_config/cargo_mutants_config.mdc +39 -0
  772. package/rules/tauri/cargo_mutants_config/concern.json +5 -0
  773. package/rules/tauri/cargo_mutants_config/docs/fix-cargo_mutants_config.md +30 -0
  774. package/rules/tauri/cargo_mutants_config/docs/index.md +12 -0
  775. package/rules/tauri/cargo_mutants_config/docs/main.md +30 -0
  776. package/rules/tauri/cargo_mutants_config/fix-cargo_mutants_config.mjs +53 -0
  777. package/rules/tauri/cargo_mutants_config/main.mjs +148 -0
  778. package/rules/tauri/core_test_isolation/concern.json +5 -0
  779. package/rules/tauri/core_test_isolation/core_test_isolation.mdc +43 -0
  780. package/rules/tauri/core_test_isolation/docs/index.md +9 -0
  781. package/rules/tauri/core_test_isolation/docs/main.md +36 -0
  782. package/rules/tauri/core_test_isolation/main.mjs +166 -0
  783. package/rules/tauri/docs/index.md +11 -0
  784. package/rules/tauri/linux_deps/concern.json +8 -0
  785. package/rules/tauri/linux_deps/docs/fix-linux_deps.md +29 -0
  786. package/rules/tauri/linux_deps/docs/index.md +10 -0
  787. package/rules/tauri/linux_deps/docs/main.md +36 -0
  788. package/rules/tauri/linux_deps/fix-linux_deps.mjs +89 -0
  789. package/rules/tauri/linux_deps/linux_deps.mdc +18 -0
  790. package/rules/tauri/linux_deps/main.mjs +100 -0
  791. package/rules/tauri/main.json +1 -0
  792. package/rules/tauri/main.mdc +86 -0
  793. package/rules/tauri/release/concern.json +8 -0
  794. package/rules/tauri/release/docs/fix-release.md +28 -0
  795. package/rules/tauri/release/docs/index.md +10 -0
  796. package/rules/tauri/release/docs/main.md +32 -0
  797. package/rules/tauri/release/fix-release.mjs +353 -0
  798. package/rules/tauri/release/main.mjs +315 -0
  799. package/rules/tauri/release/release.mdc +104 -0
  800. package/rules/tauri/tooling/concern.json +8 -0
  801. package/rules/tauri/tooling/docs/index.md +11 -0
  802. package/rules/tauri/tooling/docs/main.md +34 -0
  803. package/rules/tauri/tooling/main.mjs +94 -0
  804. package/rules/tauri/tooling/tooling.mdc +27 -0
  805. package/rules/tauri/updater/concern.json +14 -0
  806. package/rules/tauri/updater/docs/fix-updater.md +33 -0
  807. package/rules/tauri/updater/docs/index.md +10 -0
  808. package/rules/tauri/updater/docs/main.md +32 -0
  809. package/rules/tauri/updater/fix-updater.mjs +322 -0
  810. package/rules/tauri/updater/main.mjs +403 -0
  811. package/rules/tauri/updater/updater.mdc +90 -0
  812. package/rules/tauri/vscode_extensions/concern.json +9 -0
  813. package/rules/tauri/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
  814. package/rules/tauri/vscode_extensions/docs/index.md +11 -0
  815. package/rules/tauri/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  816. package/rules/tauri/vscode_extensions/vscode_extensions.mdc +23 -0
  817. package/rules/tauri/vscode_extensions/vscode_extensions.rego +26 -0
  818. package/rules/test/cargo_mutants_config/cargo_mutants_config.mdc +18 -0
  819. package/rules/test/cargo_mutants_config/concern.json +8 -0
  820. package/rules/test/cargo_mutants_config/data/cargo_mutants_config/mutants.toml.baseline +7 -0
  821. package/rules/test/cargo_mutants_config/docs/fix-cargo_mutants_config.md +31 -0
  822. package/rules/test/cargo_mutants_config/docs/index.md +12 -0
  823. package/rules/test/cargo_mutants_config/docs/main.md +36 -0
  824. package/rules/test/cargo_mutants_config/fix-cargo_mutants_config.mjs +49 -0
  825. package/rules/test/cargo_mutants_config/main.mjs +62 -0
  826. package/rules/test/docs/index.md +11 -0
  827. package/rules/test/location/concern.json +8 -0
  828. package/rules/test/location/docs/index.md +11 -0
  829. package/rules/test/location/docs/main.md +36 -0
  830. package/rules/test/location/location.mdc +52 -0
  831. package/rules/test/location/main.mjs +70 -0
  832. package/rules/test/main.json +1 -0
  833. package/rules/test/main.mdc +26 -0
  834. package/rules/test/no-bun-test-import/concern.json +7 -0
  835. package/rules/test/no-bun-test-import/docs/fix-no-bun-test-import.md +31 -0
  836. package/rules/test/no-bun-test-import/docs/index.md +10 -0
  837. package/rules/test/no-bun-test-import/docs/main.md +36 -0
  838. package/rules/test/no-bun-test-import/fix-no-bun-test-import.mjs +51 -0
  839. package/rules/test/no-bun-test-import/main.mjs +105 -0
  840. package/rules/test/no-bun-test-import/no-bun-test-import.mdc +9 -0
  841. package/rules/test/no-console-store-restore/concern.json +7 -0
  842. package/rules/test/no-console-store-restore/docs/index.md +11 -0
  843. package/rules/test/no-console-store-restore/docs/main.md +44 -0
  844. package/rules/test/no-console-store-restore/main.mjs +88 -0
  845. package/rules/test/no-console-store-restore/no-console-store-restore.mdc +11 -0
  846. package/rules/test/no-process-chdir/concern.json +7 -0
  847. package/rules/test/no-process-chdir/docs/index.md +11 -0
  848. package/rules/test/no-process-chdir/docs/main.md +32 -0
  849. package/rules/test/no-process-chdir/main.mjs +40 -0
  850. package/rules/test/no-process-chdir/no-process-chdir.mdc +15 -0
  851. package/rules/test/no-relative-fs-path/concern.json +7 -0
  852. package/rules/test/no-relative-fs-path/docs/index.md +11 -0
  853. package/rules/test/no-relative-fs-path/docs/main.md +34 -0
  854. package/rules/test/no-relative-fs-path/main.mjs +239 -0
  855. package/rules/test/no-relative-fs-path/no-relative-fs-path.mdc +22 -0
  856. package/rules/test/package_json/concern.json +11 -0
  857. package/rules/test/package_json/package_json.mdc +18 -0
  858. package/rules/test/package_json/package_json.rego +25 -0
  859. package/rules/test/package_json/template/package.json.contains.json +6 -0
  860. package/rules/test/sandbox-aware-test/concern.json +7 -0
  861. package/rules/test/sandbox-aware-test/docs/index.md +11 -0
  862. package/rules/test/sandbox-aware-test/docs/main.md +55 -0
  863. package/rules/test/sandbox-aware-test/main.mjs +89 -0
  864. package/rules/test/sandbox-aware-test/sandbox-aware-test.mdc +28 -0
  865. package/rules/test/stryker_config/concern.json +8 -0
  866. package/rules/test/stryker_config/data/stryker_config/docs/index.md +13 -0
  867. package/rules/test/stryker_config/data/stryker_config/docs/stryker-vue-macros-ignorer.md +31 -0
  868. package/rules/test/stryker_config/data/stryker_config/docs/stryker.config.baseline.md +31 -0
  869. package/rules/test/stryker_config/data/stryker_config/docs/stryker.config.vue.baseline.md +35 -0
  870. package/rules/test/stryker_config/data/stryker_config/stryker-vue-macros-ignorer.mjs +48 -0
  871. package/rules/test/stryker_config/data/stryker_config/stryker.config.baseline.mjs +18 -0
  872. package/rules/test/stryker_config/data/stryker_config/stryker.config.vue.baseline.mjs +23 -0
  873. package/rules/test/stryker_config/data/vitest_config/docs/index.md +11 -0
  874. package/rules/test/stryker_config/data/vitest_config/docs/vitest.config.baseline.md +35 -0
  875. package/rules/test/stryker_config/data/vitest_config/vitest.config.baseline.js +22 -0
  876. package/rules/test/stryker_config/docs/fix-stryker_config.md +42 -0
  877. package/rules/test/stryker_config/docs/index.md +12 -0
  878. package/rules/test/stryker_config/docs/main.md +38 -0
  879. package/rules/test/stryker_config/fix-stryker_config.mjs +76 -0
  880. package/rules/test/stryker_config/main.mjs +504 -0
  881. package/rules/test/stryker_config/stryker_config.mdc +26 -0
  882. package/rules/test/vitest-config-pool-forks/concern.json +7 -0
  883. package/rules/test/vitest-config-pool-forks/docs/index.md +11 -0
  884. package/rules/test/vitest-config-pool-forks/docs/main.md +42 -0
  885. package/rules/test/vitest-config-pool-forks/main.mjs +41 -0
  886. package/rules/test/vitest-config-pool-forks/vitest-config-pool-forks.mdc +34 -0
  887. package/rules/text/cspell/concern.json +9 -0
  888. package/rules/text/cspell/cspell.mdc +41 -0
  889. package/rules/text/cspell/cspell.rego +71 -0
  890. package/rules/text/cspell/docs/fix-cspell.md +36 -0
  891. package/rules/text/cspell/docs/index.md +11 -0
  892. package/rules/text/cspell/fix-cspell.mjs +115 -0
  893. package/rules/text/cspell/template/.cspell.json.contains.json +3 -0
  894. package/rules/text/cspell/template/.cspell.json.deny.json +5 -0
  895. package/rules/text/cspell/template/.cspell.json.snippet.json +15 -0
  896. package/rules/text/cspell-fix/concern.json +7 -0
  897. package/rules/text/cspell-fix/docs/fix-worker.md +38 -0
  898. package/rules/text/cspell-fix/docs/index.md +12 -0
  899. package/rules/text/cspell-fix/docs/main.md +32 -0
  900. package/rules/text/cspell-fix/fix-worker.mjs +73 -0
  901. package/rules/text/cspell-fix/main.mjs +185 -0
  902. package/rules/text/docs/index.md +11 -0
  903. package/rules/text/forbidden-prettier/concern.json +7 -0
  904. package/rules/text/forbidden-prettier/docs/index.md +11 -0
  905. package/rules/text/forbidden-prettier/docs/main.md +38 -0
  906. package/rules/text/forbidden-prettier/forbidden-prettier.mdc +14 -0
  907. package/rules/text/forbidden-prettier/main.mjs +56 -0
  908. package/rules/text/formatting/concern.json +17 -0
  909. package/rules/text/formatting/docs/index.md +11 -0
  910. package/rules/text/formatting/docs/main.md +39 -0
  911. package/rules/text/formatting/main.mjs +149 -0
  912. package/rules/text/lint_text/concern.json +8 -0
  913. package/rules/text/lint_text/lint_text.mdc +19 -0
  914. package/rules/text/lint_text/lint_text.rego +104 -0
  915. package/rules/text/lint_text/template/lint-text.yml.snippet.yml +61 -0
  916. package/rules/text/main.json +1 -0
  917. package/rules/text/main.mdc +23 -0
  918. package/rules/text/markdownlint/concern.json +12 -0
  919. package/rules/text/markdownlint/docs/fix-markdownlint.md +38 -0
  920. package/rules/text/markdownlint/docs/index.md +12 -0
  921. package/rules/text/markdownlint/docs/main.md +40 -0
  922. package/rules/text/markdownlint/fix-markdownlint.mjs +64 -0
  923. package/rules/text/markdownlint/main.mjs +55 -0
  924. package/rules/text/markdownlint/markdownlint.mdc +40 -0
  925. package/rules/text/markdownlint/markdownlint.rego +57 -0
  926. package/rules/text/markdownlint/template/.markdownlint-cli2.jsonc.snippet.jsonc +11 -0
  927. package/rules/text/oxfmt/concern.json +7 -0
  928. package/rules/text/oxfmt/docs/fix-oxfmt.md +28 -0
  929. package/rules/text/oxfmt/docs/main.md +27 -0
  930. package/rules/text/oxfmt/fix-oxfmt.mjs +52 -0
  931. package/rules/text/oxfmt/main.mjs +48 -0
  932. package/rules/text/oxfmt/oxfmt.mdc +11 -0
  933. package/rules/text/oxfmtrc/concern.json +9 -0
  934. package/rules/text/oxfmtrc/oxfmtrc.mdc +11 -0
  935. package/rules/text/oxfmtrc/oxfmtrc.rego +55 -0
  936. package/rules/text/oxfmtrc/template/.oxfmtrc.json.snippet.json +8 -0
  937. package/rules/text/package_json/concern.json +9 -0
  938. package/rules/text/package_json/package_json.mdc +35 -0
  939. package/rules/text/package_json/package_json.rego +66 -0
  940. package/rules/text/package_json/template/package.json.deny.json +15 -0
  941. package/rules/text/run-dotenv-linter/concern.json +7 -0
  942. package/rules/text/run-dotenv-linter/docs/fix-run-dotenv-linter.md +43 -0
  943. package/rules/text/run-dotenv-linter/docs/index.md +12 -0
  944. package/rules/text/run-dotenv-linter/docs/main.md +35 -0
  945. package/rules/text/run-dotenv-linter/fix-run-dotenv-linter.mjs +64 -0
  946. package/rules/text/run-dotenv-linter/main.mjs +122 -0
  947. package/rules/text/run-shellcheck/concern.json +7 -0
  948. package/rules/text/run-shellcheck/docs/fix-run-shellcheck.md +40 -0
  949. package/rules/text/run-shellcheck/docs/index.md +12 -0
  950. package/rules/text/run-shellcheck/docs/main.md +31 -0
  951. package/rules/text/run-shellcheck/fix-run-shellcheck.mjs +44 -0
  952. package/rules/text/run-shellcheck/main.mjs +245 -0
  953. package/rules/text/run-v8r/concern.json +7 -0
  954. package/rules/text/run-v8r/docs/index.md +11 -0
  955. package/rules/text/run-v8r/docs/main.md +40 -0
  956. package/rules/text/run-v8r/main.mjs +266 -0
  957. package/rules/text/vscode_extensions/concern.json +9 -0
  958. package/rules/text/vscode_extensions/docs/fix-vscode_extensions.md +36 -0
  959. package/rules/text/vscode_extensions/docs/index.md +11 -0
  960. package/rules/text/vscode_extensions/fix-vscode_extensions.mjs +1 -0
  961. package/rules/text/vscode_extensions/template/extensions.json.snippet.json +3 -0
  962. package/rules/text/vscode_extensions/vscode_extensions.mdc +13 -0
  963. package/rules/text/vscode_extensions/vscode_extensions.rego +12 -0
  964. package/rules/text/vscode_settings/concern.json +9 -0
  965. package/rules/text/vscode_settings/template/settings.json.snippet.json +9 -0
  966. package/rules/text/vscode_settings/vscode_settings.mdc +13 -0
  967. package/rules/text/vscode_settings/vscode_settings.rego +34 -0
  968. package/rules/tool-surface/docs/index.md +11 -0
  969. package/rules/tool-surface/main.json +6 -0
  970. package/rules/tool-surface/main.mdc +72 -0
  971. package/rules/vue/docs/index.md +11 -0
  972. package/rules/vue/lib/docs/index.md +11 -0
  973. package/rules/vue/lib/docs/vue-forbidden-imports.md +265 -0
  974. package/rules/vue/lib/vue-forbidden-imports.mjs +264 -0
  975. package/rules/vue/main.json +1 -0
  976. package/rules/vue/main.mdc +18 -0
  977. package/rules/vue/package_json/concern.json +9 -0
  978. package/rules/vue/package_json/package_json.mdc +30 -0
  979. package/rules/vue/package_json/package_json.rego +140 -0
  980. package/rules/vue/packages/concern.json +6 -0
  981. package/rules/vue/packages/docs/index.md +11 -0
  982. package/rules/vue/packages/docs/main.md +35 -0
  983. package/rules/vue/packages/main.mjs +575 -0
  984. package/rules/worktree/docs/index.md +11 -0
  985. package/rules/worktree/main.json +1 -0
  986. package/rules/worktree/main.mdc +100 -0
  987. package/rules/worktree/vscode_settings/concern.json +10 -0
  988. package/rules/worktree/vscode_settings/template/settings.json.snippet.json +8 -0
  989. package/rules/worktree/zed_settings/concern.json +10 -0
  990. package/rules/worktree/zed_settings/template/settings.json.snippet.json +12 -0
  991. package/schemas/any.json +4 -0
  992. package/schemas/concern.json +108 -0
  993. package/schemas/layers-config.json +38 -0
  994. package/schemas/n-rules.json +65 -0
  995. package/schemas/rule-meta.json +39 -0
  996. package/schemas/skill-meta.json +30 -0
  997. package/schemas/target.json +63 -0
  998. package/schemas/v8r-catalog.json +179 -0
  999. package/schemas/vendor/bunfig.json +616 -0
  1000. package/schemas/vendor/cargo-mutants-config.json +158 -0
  1001. package/schemas/vendor/cargo.json +9438 -0
  1002. package/schemas/vendor/claude-code-settings.json +2742 -0
  1003. package/schemas/vendor/codex-hooks.json +148 -0
  1004. package/schemas/vendor/cspell.json +2427 -0
  1005. package/schemas/vendor/github-action.json +695 -0
  1006. package/schemas/vendor/github-workflow.json +2193 -0
  1007. package/schemas/vendor/jsconfig.json +1252 -0
  1008. package/schemas/vendor/jscpd.json +405 -0
  1009. package/schemas/vendor/knip.json +915 -0
  1010. package/schemas/vendor/mcp.json +26 -0
  1011. package/schemas/vendor/mt-config.json +85 -0
  1012. package/schemas/vendor/oxfmtrc.json +810 -0
  1013. package/schemas/vendor/oxlintrc.json +18690 -0
  1014. package/schemas/vendor/package.json +23798 -0
  1015. package/schemas/vendor/prettierrc.json +433 -0
  1016. package/schemas/vendor/quikrun.json +195 -0
  1017. package/schemas/vendor/schema-catalog.json +62 -0
  1018. package/schemas/vendor/tsconfig.json +1535 -0
  1019. package/schemas/vendor/zizmor.json +489 -0
  1020. package/scripts/auto-rules.mjs +444 -0
  1021. package/scripts/auto-skills.mjs +95 -0
  1022. package/scripts/build-agents-commands.mjs +91 -0
  1023. package/scripts/cli-entry.mjs +34 -0
  1024. package/scripts/dispatcher/docs/index.md +11 -0
  1025. package/scripts/docs/auto-rules.md +34 -0
  1026. package/scripts/docs/auto-skills.md +30 -0
  1027. package/scripts/docs/build-agents-commands.md +37 -0
  1028. package/scripts/docs/cli-entry.md +36 -0
  1029. package/scripts/docs/ensure-n-rules-dev-dependencies.md +40 -0
  1030. package/scripts/docs/hook.md +30 -0
  1031. package/scripts/docs/index.md +22 -0
  1032. package/scripts/docs/post-tool-use-check.md +27 -0
  1033. package/scripts/docs/rename-yaml-extensions.md +40 -0
  1034. package/scripts/docs/skills-cli.md +35 -0
  1035. package/scripts/docs/smoke-check-imports.md +31 -0
  1036. package/scripts/docs/sync-claude-config.md +84 -0
  1037. package/scripts/docs/sync-setup-bun-deps-action.md +28 -0
  1038. package/scripts/docs/update-blue-oak.md +28 -0
  1039. package/scripts/docs/upgrade-n-rules-and-install.md +36 -0
  1040. package/scripts/ensure-n-rules-dev-dependencies.mjs +217 -0
  1041. package/scripts/hook.mjs +100 -0
  1042. package/scripts/lib/adr/docs/index.md +12 -0
  1043. package/scripts/lib/adr/docs/normalize-cli.md +36 -0
  1044. package/scripts/lib/adr/docs/normalize-pipeline.md +45 -0
  1045. package/scripts/lib/adr/normalize-cli.mjs +74 -0
  1046. package/scripts/lib/adr/normalize-pipeline.mjs +701 -0
  1047. package/scripts/lib/assert-project-root.mjs +77 -0
  1048. package/scripts/lib/blue-oak.mjs +41 -0
  1049. package/scripts/lib/changed-files.mjs +83 -0
  1050. package/scripts/lib/check-reporter.mjs +27 -0
  1051. package/scripts/lib/collect-test-files.mjs +48 -0
  1052. package/scripts/lib/concern-meta.mjs +140 -0
  1053. package/scripts/lib/diff-added-lines.mjs +86 -0
  1054. package/scripts/lib/discover-check-rules-from-cursor.mjs +40 -0
  1055. package/scripts/lib/discover-checkable-rules.mjs +49 -0
  1056. package/scripts/lib/docs/assert-project-root.md +30 -0
  1057. package/scripts/lib/docs/blue-oak.md +29 -0
  1058. package/scripts/lib/docs/changed-files.md +32 -0
  1059. package/scripts/lib/docs/check-reporter.md +179 -0
  1060. package/scripts/lib/docs/collect-test-files.md +32 -0
  1061. package/scripts/lib/docs/concern-meta.md +34 -0
  1062. package/scripts/lib/docs/diff-added-lines.md +38 -0
  1063. package/scripts/lib/docs/discover-check-rules-from-cursor.md +29 -0
  1064. package/scripts/lib/docs/discover-checkable-rules.md +25 -0
  1065. package/scripts/lib/docs/ensure-tool.md +258 -0
  1066. package/scripts/lib/docs/generated-markdown.md +279 -0
  1067. package/scripts/lib/docs/gha-workflow.md +38 -0
  1068. package/scripts/lib/docs/index.md +40 -0
  1069. package/scripts/lib/docs/inline-template-links.md +25 -0
  1070. package/scripts/lib/docs/list-project-rules-mdc.md +27 -0
  1071. package/scripts/lib/docs/list-rule-ids.md +25 -0
  1072. package/scripts/lib/docs/load-cursor-config.md +154 -0
  1073. package/scripts/lib/docs/mirror-parity.md +32 -0
  1074. package/scripts/lib/docs/read-n-rules-config-lite.md +26 -0
  1075. package/scripts/lib/docs/resolve-target-files.md +38 -0
  1076. package/scripts/lib/docs/root-notice.md +29 -0
  1077. package/scripts/lib/docs/rule-meta-helpers.md +38 -0
  1078. package/scripts/lib/docs/rule-meta.md +29 -0
  1079. package/scripts/lib/docs/rule-predicates.md +31 -0
  1080. package/scripts/lib/docs/run-conftest-batch.md +30 -0
  1081. package/scripts/lib/docs/run-lint-step.md +29 -0
  1082. package/scripts/lib/docs/run-standard-lint.md +43 -0
  1083. package/scripts/lib/docs/skill-meta.md +62 -0
  1084. package/scripts/lib/docs/sync-gitignore-worktree.md +26 -0
  1085. package/scripts/lib/docs/template.md +44 -0
  1086. package/scripts/lib/docs/timing-summary.md +25 -0
  1087. package/scripts/lib/docs/workspaces.md +34 -0
  1088. package/scripts/lib/docs/worktree-notice.md +27 -0
  1089. package/scripts/lib/ensure-tool.mjs +352 -0
  1090. package/scripts/lib/fix/docs/index.md +11 -0
  1091. package/scripts/lib/fix/docs/vscode-ext-add.md +33 -0
  1092. package/scripts/lib/fix/vscode-ext-add.mjs +53 -0
  1093. package/scripts/lib/generated-markdown.mjs +71 -0
  1094. package/scripts/lib/gha-workflow.mjs +220 -0
  1095. package/scripts/lib/inline-template-links.mjs +108 -0
  1096. package/scripts/lib/lint-surface/codegen-opa-wrapper.mjs +30 -0
  1097. package/scripts/lib/lint-surface/collateral-veto.mjs +55 -0
  1098. package/scripts/lib/lint-surface/default-worker.mjs +67 -0
  1099. package/scripts/lib/lint-surface/detect.mjs +169 -0
  1100. package/scripts/lib/lint-surface/docs/codegen-opa-wrapper.md +30 -0
  1101. package/scripts/lib/lint-surface/docs/collateral-veto.md +28 -0
  1102. package/scripts/lib/lint-surface/docs/default-worker.md +32 -0
  1103. package/scripts/lib/lint-surface/docs/detect.md +38 -0
  1104. package/scripts/lib/lint-surface/docs/index.md +27 -0
  1105. package/scripts/lib/lint-surface/docs/ladder.md +33 -0
  1106. package/scripts/lib/lint-surface/docs/lint-lock.md +47 -0
  1107. package/scripts/lib/lint-surface/docs/mt-run-node.md +37 -0
  1108. package/scripts/lib/lint-surface/docs/mt-tail.md +41 -0
  1109. package/scripts/lib/lint-surface/docs/policy-lint-adapter.md +44 -0
  1110. package/scripts/lib/lint-surface/docs/policy-test-step.md +43 -0
  1111. package/scripts/lib/lint-surface/docs/progress.md +28 -0
  1112. package/scripts/lib/lint-surface/docs/render.md +29 -0
  1113. package/scripts/lib/lint-surface/docs/run-detectors.md +32 -0
  1114. package/scripts/lib/lint-surface/docs/run-fix.md +33 -0
  1115. package/scripts/lib/lint-surface/docs/snapshot.md +30 -0
  1116. package/scripts/lib/lint-surface/docs/tier-sampling-bench.md +40 -0
  1117. package/scripts/lib/lint-surface/docs/tier-sampling-experiment.md +35 -0
  1118. package/scripts/lib/lint-surface/docs/types.md +27 -0
  1119. package/scripts/lib/lint-surface/docs/violation-reporter.md +32 -0
  1120. package/scripts/lib/lint-surface/ladder.mjs +92 -0
  1121. package/scripts/lib/lint-surface/lint-lock.mjs +247 -0
  1122. package/scripts/lib/lint-surface/mt-run-node.mjs +206 -0
  1123. package/scripts/lib/lint-surface/mt-tail.mjs +0 -0
  1124. package/scripts/lib/lint-surface/policy-lint-adapter.mjs +101 -0
  1125. package/scripts/lib/lint-surface/policy-test-step.mjs +149 -0
  1126. package/scripts/lib/lint-surface/progress.mjs +198 -0
  1127. package/scripts/lib/lint-surface/render.mjs +50 -0
  1128. package/scripts/lib/lint-surface/run-detectors.mjs +314 -0
  1129. package/scripts/lib/lint-surface/run-fix.mjs +732 -0
  1130. package/scripts/lib/lint-surface/snapshot.mjs +83 -0
  1131. package/scripts/lib/lint-surface/tier-sampling-bench.mjs +457 -0
  1132. package/scripts/lib/lint-surface/tier-sampling-experiment.mjs +289 -0
  1133. package/scripts/lib/lint-surface/types.mjs +150 -0
  1134. package/scripts/lib/lint-surface/violation-reporter.mjs +46 -0
  1135. package/scripts/lib/list-project-rules-mdc.mjs +22 -0
  1136. package/scripts/lib/list-rule-ids.mjs +32 -0
  1137. package/scripts/lib/load-cursor-config.mjs +58 -0
  1138. package/scripts/lib/mirror-parity.mjs +62 -0
  1139. package/scripts/lib/read-n-rules-config-lite.mjs +63 -0
  1140. package/scripts/lib/resolve-target-files.mjs +103 -0
  1141. package/scripts/lib/root-notice.mjs +67 -0
  1142. package/scripts/lib/rule-meta-helpers.mjs +103 -0
  1143. package/scripts/lib/rule-meta.mjs +66 -0
  1144. package/scripts/lib/rule-predicates.mjs +114 -0
  1145. package/scripts/lib/run-conftest-batch.mjs +124 -0
  1146. package/scripts/lib/run-lint-step.mjs +38 -0
  1147. package/scripts/lib/run-standard-lint.mjs +50 -0
  1148. package/scripts/lib/skill-meta.mjs +90 -0
  1149. package/scripts/lib/sync-gitignore-worktree.mjs +27 -0
  1150. package/scripts/lib/template.mjs +315 -0
  1151. package/scripts/lib/timing-summary.mjs +63 -0
  1152. package/scripts/lib/workspaces.mjs +109 -0
  1153. package/scripts/lib/worktree-notice.mjs +183 -0
  1154. package/scripts/post-tool-use-check.mjs +82 -0
  1155. package/scripts/rename-yaml-extensions.mjs +170 -0
  1156. package/scripts/skills-cli.mjs +262 -0
  1157. package/scripts/smoke-check-imports.mjs +66 -0
  1158. package/scripts/sync-claude-config.mjs +692 -0
  1159. package/scripts/sync-setup-bun-deps-action.mjs +36 -0
  1160. package/scripts/update-blue-oak.mjs +50 -0
  1161. package/scripts/upgrade-n-rules-and-install.mjs +264 -0
  1162. package/scripts/utils/apply-to-files.mjs +36 -0
  1163. package/scripts/utils/ast-extract.mjs +149 -0
  1164. package/scripts/utils/ast-scan-utils.mjs +206 -0
  1165. package/scripts/utils/docs/apply-to-files.md +38 -0
  1166. package/scripts/utils/docs/ast-extract.md +30 -0
  1167. package/scripts/utils/docs/ast-scan-utils.md +54 -0
  1168. package/scripts/utils/docs/ensure-gitignore-entries.md +32 -0
  1169. package/scripts/utils/docs/find-package-json-paths.md +30 -0
  1170. package/scripts/utils/docs/index.md +23 -0
  1171. package/scripts/utils/docs/lock-cache-dir.md +29 -0
  1172. package/scripts/utils/docs/pass.md +29 -0
  1173. package/scripts/utils/docs/resolve-cargo-manifest.md +27 -0
  1174. package/scripts/utils/docs/resolve-cmd.md +33 -0
  1175. package/scripts/utils/docs/resolve-js-root.md +26 -0
  1176. package/scripts/utils/docs/test-helpers.md +30 -0
  1177. package/scripts/utils/docs/walk-cache.md +31 -0
  1178. package/scripts/utils/docs/walkDir.md +31 -0
  1179. package/scripts/utils/docs/with-lock.md +30 -0
  1180. package/scripts/utils/docs/worktree-fingerprint.md +31 -0
  1181. package/scripts/utils/ensure-gitignore-entries.mjs +30 -0
  1182. package/scripts/utils/find-package-json-paths.mjs +30 -0
  1183. package/scripts/utils/lock-cache-dir.mjs +37 -0
  1184. package/scripts/utils/pass.mjs +9 -0
  1185. package/scripts/utils/resolve-cargo-manifest.mjs +62 -0
  1186. package/scripts/utils/resolve-cmd.mjs +25 -0
  1187. package/scripts/utils/resolve-js-root.mjs +61 -0
  1188. package/scripts/utils/walk-cache.mjs +24 -0
  1189. package/scripts/utils/walkDir.mjs +55 -0
  1190. package/scripts/utils/with-lock.mjs +190 -0
  1191. package/scripts/utils/worktree-fingerprint.mjs +33 -0
  1192. package/skills/adr-normalize/SKILL.md +73 -0
  1193. package/skills/adr-normalize/main.json +1 -0
  1194. package/skills/brainstorming/SKILL.md +165 -0
  1195. package/skills/brainstorming/main.json +1 -0
  1196. package/skills/doc-aggregate/SKILL.md +121 -0
  1197. package/skills/doc-aggregate/js/docs/index.md +11 -0
  1198. package/skills/doc-aggregate/main.json +1 -0
  1199. package/skills/doc-files/.changes/260612-0002.md +6 -0
  1200. package/skills/doc-files/.changes/260612-0006.md +6 -0
  1201. package/skills/doc-files/.changes/260612-0008.md +6 -0
  1202. package/skills/doc-files/.changes/260612-0012.md +6 -0
  1203. package/skills/doc-files/.changes/260612-0031.md +6 -0
  1204. package/skills/doc-files/.changes/260612-0036.md +6 -0
  1205. package/skills/doc-files/.changes/260612-0114.md +6 -0
  1206. package/skills/doc-files/SKILL.md +86 -0
  1207. package/skills/doc-files/main.json +1 -0
  1208. package/skills/lint/SKILL.md +121 -0
  1209. package/skills/lint/main.json +1 -0
  1210. package/skills/llm-patch/SKILL.md +260 -0
  1211. package/skills/llm-patch/main.json +1 -0
  1212. package/skills/publish-telegram/SKILL.md +93 -0
  1213. package/skills/publish-telegram/main.json +1 -0
  1214. package/skills/taze/SKILL.md +114 -0
  1215. package/skills/taze/js/diff.mjs +140 -0
  1216. package/skills/taze/js/docs/diff.md +55 -0
  1217. package/skills/taze/js/docs/index.md +11 -0
  1218. package/skills/taze/main.json +1 -0
  1219. package/types/bin/n-rules.d.ts +2 -0
@@ -0,0 +1,820 @@
1
+ /** @see ./docs/consistency.md */
2
+ import { execFile } from 'node:child_process'
3
+ import { existsSync } from 'node:fs'
4
+ import { readFile } from 'node:fs/promises'
5
+ import { join } from 'node:path'
6
+ import { promisify } from 'node:util'
7
+
8
+ import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
9
+ import {
10
+ getMonorepoProjectRootDirs,
11
+ manifestFilePath,
12
+ parsePyprojectFields,
13
+ readPackageManifest
14
+ } from '../lib/package-manifest.mjs'
15
+ import { writeChange } from '../../release/change.mjs'
16
+ import { readChangeFiles } from '../../release/lib/change-file.mjs'
17
+
18
+ const execFileAsync = promisify(execFile)
19
+
20
+ /**
21
+ * Env-прапорець, що вмикає autofix. Виставляється кроком `npm-changelog` у `hk.pkl`
22
+ * (канонічний fix-only snippet із `stage` не потребує — див. npm-module.mdc);
23
+ * наявність самого кроку валідує `npm-module`/`package_structure`.
24
+ */
25
+ const AUTOFIX_ENV_VAR = 'N_RULES_CHANGELOG_AUTOFIX'
26
+ /** @deprecated legacy-назва env до перейменування пакету — читається як fallback */
27
+ const LEGACY_AUTOFIX_ENV_VAR = 'N_CURSOR_CHANGELOG_AUTOFIX'
28
+
29
+ /** Дефолтний `bump` для autofix-створеного change-файлу (вищий bump редагуєш вручну). */
30
+ const AUTOFIX_BUMP = 'patch'
31
+
32
+ /** Дефолтна секція для autofix-створеного change-файлу. */
33
+ const AUTOFIX_SECTION = 'Changed'
34
+
35
+ /** Fallback-опис, коли subject останнього коміту порожній (напр. порожній репозиторій). */
36
+ const AUTOFIX_FALLBACK_MESSAGE = 'оновлення'
37
+
38
+ /** Кандидати інтеграційними тести гілки для feature-гілок (перша наявна; див. n-changelog.mdc). */
39
+ const FEATURE_BASE_BRANCH_CANDIDATES = Object.freeze(['dev', 'main'])
40
+
41
+ /** Гілка `dev`: local-only не активний (крім незакомічених registry-published). */
42
+ const LOCAL_ONLY_SKIP_BRANCH = 'dev'
43
+
44
+ /**
45
+ * Префікси шляхів (posix), які не вважаються релізними змінами — інверсія glob (n-changelog.mdc):
46
+ * документація (`docs/`, `doc/`) та синхронізований із `@7n/rules` інструментарій
47
+ * (`.cursor/` — канонічні правила й скіли, `.claude/` — ADR-хуки). Останнє — дзеркало tooling-пакета,
48
+ * не логіка самого воркспейсу, тож bump CHANGELOG не потрібен. Джерело правил у репо `@7n/rules`
49
+ * лежить під `npm/`, тож на нього ця інверсія не поширюється.
50
+ */
51
+ const CHANGELOG_IGNORE_PATH_PREFIXES = Object.freeze(['docs/', 'doc/', '.cursor/', '.claude/'])
52
+
53
+ /** Таймаут на `npm view` / PyPI (мс) */
54
+ const REGISTRY_TIMEOUT_MS = 10_000
55
+
56
+ const LEADING_DOTSLASH_RE = /^\.\//
57
+
58
+ /**
59
+ * Тихо запускає `git` у заданому `cwd` і повертає stdout або `null` при будь-якій помилці.
60
+ * @param {string[]} args аргументи `git`
61
+ * @param {string} cwd робочий каталог процесу
62
+ * @returns {Promise<string | null>} результат
63
+ */
64
+ async function gitOrNull(args, cwd) {
65
+ try {
66
+ const { stdout } = await execFileAsync('git', args, { cwd })
67
+ return stdout
68
+ } catch {
69
+ return null
70
+ }
71
+ }
72
+
73
+ /**
74
+ * @param {string} cwd робочий каталог
75
+ * @returns {Promise<boolean>} результат
76
+ */
77
+ async function isInsideGitRepo(cwd) {
78
+ const out = await gitOrNull(['rev-parse', '--is-inside-work-tree'], cwd)
79
+ return typeof out === 'string' && out.trim() === 'true'
80
+ }
81
+
82
+ /**
83
+ * @param {string} cwd робочий каталог
84
+ * @returns {Promise<string | null>} результат
85
+ */
86
+ async function currentBranchName(cwd) {
87
+ const out = await gitOrNull(['rev-parse', '--abbrev-ref', 'HEAD'], cwd)
88
+ return typeof out === 'string' ? out.trim() : null
89
+ }
90
+
91
+ /**
92
+ * Чи HEAD — merge-коміт (має 2-го предка) АБО merge зараз у процесі (`MERGE_HEAD`).
93
+ * Merge інтегрує вже задокументовану роботу (changeset створено в feature-комітах),
94
+ * тож власного changeset не потребує — інакше autofix створив би шумний «Merge…»
95
+ * changeset, який CI commit-back каскадить у patch-реліз.
96
+ *
97
+ * `MERGE_HEAD` критичний для pre-commit: під час `git commit` незавершеного merge
98
+ * коміт ще НЕ створено, `HEAD^2` не існує — без цієї гілки перевірка хибно валила
99
+ * merge-коміт легітимним вмістом бази (обхід через `HK=0`).
100
+ * @param {string} cwd робочий каталог
101
+ * @returns {Promise<boolean>} true — HEAD merge-коміт або merge у процесі.
102
+ */
103
+ async function isMergeCommit(cwd) {
104
+ const out = await gitOrNull(['rev-parse', '--verify', '--quiet', 'HEAD^2'], cwd)
105
+ if (typeof out === 'string' && out.trim().length > 0) return true
106
+ const mergeHead = await gitOrNull(['rev-parse', '--verify', '--quiet', 'MERGE_HEAD'], cwd)
107
+ return typeof mergeHead === 'string' && mergeHead.trim().length > 0
108
+ }
109
+
110
+ /**
111
+ * Чи `ancestor` — предок `descendant`. `git merge-base --is-ancestor` нічого не друкує:
112
+ * вердикт несе exit-код (0 → так), тож успіх = будь-який string від gitOrNull.
113
+ * @param {string} ancestor предок
114
+ * @param {string} descendant нащадок
115
+ * @param {string} cwd робочий каталог
116
+ * @returns {Promise<boolean>} результат
117
+ */
118
+ async function isGitAncestor(ancestor, descendant, cwd) {
119
+ const out = await gitOrNull(['merge-base', '--is-ancestor', ancestor, descendant], cwd)
120
+ return typeof out === 'string'
121
+ }
122
+
123
+ /**
124
+ * Merge-base найновішої з локальної та origin-версії базової гілки проти HEAD.
125
+ *
126
+ * Порядок «локальна виграє» тут не працює: застарілий локальний `main` (позаду
127
+ * `origin/main`) давав старіший merge-base — реліз-коміти, що вже інтегровані в
128
+ * origin і влиті у feature-гілку, виглядали як «ручний bump поза CI». Симетрично
129
+ * валідний і локальний `main` попереду origin — тому беремо НОВІШУ з двох баз
130
+ * (та, чиїм предком є інша), а репо без remote природно лишається на локальній.
131
+ * @param {string} branchName ім'я базової гілки (`dev`/`main`)
132
+ * @param {string} cwd робочий каталог
133
+ * @returns {Promise<string | null>} SHA новішого merge-base або null (жоден ref не існує)
134
+ */
135
+ async function resolveNewestMergeBase(branchName, cwd) {
136
+ /** @type {string[]} */
137
+ const bases = []
138
+ for (const ref of [branchName, `origin/${branchName}`]) {
139
+ const exists = await gitOrNull(['rev-parse', '--verify', '--quiet', ref], cwd)
140
+ if (typeof exists !== 'string' || exists.trim().length === 0) continue
141
+ const mergeBase = await resolveMergeBase(ref, cwd)
142
+ if (mergeBase) bases.push(mergeBase)
143
+ }
144
+ if (bases.length === 0) return null
145
+ let newest = bases[0]
146
+ for (const candidate of bases.slice(1)) {
147
+ if (candidate !== newest && (await isGitAncestor(newest, candidate, cwd))) newest = candidate
148
+ }
149
+ return newest
150
+ }
151
+
152
+ /**
153
+ * @param {string} relPath параметр
154
+ * @returns {boolean} результат
155
+ */
156
+ function isChangelogIgnoredPath(relPath) {
157
+ const p = relPath.replaceAll('\\', '/').replace(LEADING_DOTSLASH_RE, '')
158
+ return CHANGELOG_IGNORE_PATH_PREFIXES.some(prefix => p.startsWith(prefix))
159
+ }
160
+
161
+ /**
162
+ * @param {string} relPath параметр
163
+ * @param {string} cwd робочий каталог
164
+ * @returns {Promise<boolean>} результат
165
+ */
166
+ async function isPathGitIgnored(relPath, cwd) {
167
+ try {
168
+ await execFileAsync('git', ['check-ignore', '-q', '--', relPath], { cwd })
169
+ return true
170
+ } catch {
171
+ return false
172
+ }
173
+ }
174
+
175
+ /**
176
+ * @param {string} baseRef параметр
177
+ * @param {string} cwd робочий каталог
178
+ * @returns {Promise<string | null>} результат
179
+ */
180
+ async function resolveMergeBase(baseRef, cwd) {
181
+ const out = await gitOrNull(['merge-base', baseRef, 'HEAD'], cwd)
182
+ if (typeof out !== 'string') return null
183
+ const sha = out.trim()
184
+ return sha.length > 0 ? sha : null
185
+ }
186
+
187
+ /**
188
+ * Точка порівняння git для changelog (ref або SHA для `git diff` / `git show`).
189
+ * @param {string | null} branch поточна гілка
190
+ * @param {string} cwd робочий каталог
191
+ * @returns {Promise<{ ref: string, label: string } | null>} результат
192
+ */
193
+ async function resolveChangelogComparisonPoint(branch, cwd) {
194
+ if (branch === LOCAL_ONLY_SKIP_BRANCH) {
195
+ return null
196
+ }
197
+
198
+ if (branch === 'main') {
199
+ const originMainRaw = await gitOrNull(['rev-parse', '--verify', '--quiet', 'origin/main'], cwd)
200
+ const originMainSha = originMainRaw?.trim()
201
+ const headRaw = await gitOrNull(['rev-parse', 'HEAD'], cwd)
202
+ const headSha = headRaw?.trim()
203
+ if (originMainSha && headSha && (originMainSha === headSha || (await isGitAncestor('origin/main', 'HEAD', cwd)))) {
204
+ return { ref: 'origin/main', label: 'main' }
205
+ }
206
+ const parent = await gitOrNull(['rev-parse', '--verify', '--quiet', 'HEAD~1'], cwd)
207
+ if (typeof parent === 'string' && parent.trim().length > 0) {
208
+ return { ref: parent.trim(), label: 'main~1' }
209
+ }
210
+ return null
211
+ }
212
+
213
+ // Feature-гілка: база — новіший merge-base серед локальної та origin-версії кандидата
214
+ // (див. resolveNewestMergeBase; застарілий локальний main не має перекривати origin).
215
+ for (const name of FEATURE_BASE_BRANCH_CANDIDATES) {
216
+ const mergeBase = await resolveNewestMergeBase(name, cwd)
217
+ if (!mergeBase) {
218
+ continue
219
+ }
220
+ return { ref: mergeBase, label: name }
221
+ }
222
+ return null
223
+ }
224
+
225
+ /**
226
+ * @param {string} ws параметр
227
+ * @param {string[]} subWorkspaces параметр
228
+ * @returns {string[]} результат
229
+ */
230
+ function pathspecForWorkspace(ws, subWorkspaces) {
231
+ if (ws !== '.') return [`${ws}/`]
232
+ return ['.', ...subWorkspaces.filter(s => s !== '.').map(s => `:(exclude)${s}/`)]
233
+ }
234
+
235
+ /**
236
+ * Шляхи з `NUL`-розділеного виводу git (прапорець `-z`).
237
+ *
238
+ * `-z` критичний: без нього git застосовує `core.quotePath` і повертає не-ASCII імена файлів
239
+ * (кирилиця тощо) у C-quoted формі `"docs/\320\262..."`. Такий рядок не збігається з
240
+ * префіксами інверсії (`docs/`, `.cursor/`, ...), тож файл хибно вважався б зміною, що потребує bump.
241
+ * @param {string | null} nulSeparated сирий вивід git або `null`
242
+ * @returns {string[]} шляхи без обгортки/escape
243
+ */
244
+ function splitNulPaths(nulSeparated) {
245
+ if (typeof nulSeparated !== 'string') {
246
+ return []
247
+ }
248
+ return nulSeparated.split('\0').filter(p => p.length > 0)
249
+ }
250
+
251
+ /**
252
+ * @param {string} baseRef параметр
253
+ * @param {string[]} pathspec параметр
254
+ * @param {string} cwd робочий каталог
255
+ * @returns {Promise<string[]>} результат
256
+ */
257
+ async function listChangedPathsAgainstBase(baseRef, pathspec, cwd) {
258
+ const diffOut = await gitOrNull(['diff', '--name-only', '-z', baseRef, '--', ...pathspec], cwd)
259
+ const untrackedOut = await gitOrNull(['ls-files', '--others', '--exclude-standard', '-z', '--', ...pathspec], cwd)
260
+ return [...new Set([...splitNulPaths(diffOut), ...splitNulPaths(untrackedOut)])]
261
+ }
262
+
263
+ /**
264
+ * @param {string} baseRef параметр
265
+ * @param {string} ws параметр
266
+ * @param {string[]} subWorkspaces параметр
267
+ * @param {string} cwd робочий каталог
268
+ * @returns {Promise<boolean>} результат
269
+ */
270
+ async function workspaceHasRelevantChangesAgainstBase(baseRef, ws, subWorkspaces, cwd) {
271
+ const pathspec = pathspecForWorkspace(ws, subWorkspaces)
272
+ const paths = await listChangedPathsAgainstBase(baseRef, pathspec, cwd)
273
+ for (const p of paths) {
274
+ if (isChangelogIgnoredPath(p)) {
275
+ continue
276
+ }
277
+ if (await isPathGitIgnored(p, cwd)) {
278
+ continue
279
+ }
280
+ return true
281
+ }
282
+ return false
283
+ }
284
+
285
+ /**
286
+ * Версія з маніфесту на `baseRef`.
287
+ * @param {string} baseRef параметр
288
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
289
+ * @param {string} cwd робочий каталог
290
+ * @returns {Promise<string | null>} результат
291
+ */
292
+ async function readBaseVersion(baseRef, manifest, cwd) {
293
+ const wsPath = manifest.ws === '.' ? manifest.manifestRel : `${manifest.ws}/${manifest.manifestRel}`
294
+ const out = await gitOrNull(['show', `${baseRef}:${wsPath}`], cwd)
295
+ if (out === null) return null
296
+ if (manifest.kind === 'npm') {
297
+ try {
298
+ const parsed = JSON.parse(out)
299
+ return typeof parsed?.version === 'string' ? parsed.version : null
300
+ } catch {
301
+ return null
302
+ }
303
+ }
304
+ return parsePyprojectFields(out).version
305
+ }
306
+
307
+ /**
308
+ * @param {string} name параметр
309
+ * @returns {Promise<string | null>} результат
310
+ */
311
+ async function defaultGetPublishedNpmVersion(name) {
312
+ try {
313
+ const { stdout } = await execFileAsync('npm', ['view', name, 'version'], { timeout: REGISTRY_TIMEOUT_MS })
314
+ const v = stdout.trim()
315
+ return v.length > 0 ? v : null
316
+ } catch {
317
+ return null
318
+ }
319
+ }
320
+
321
+ /**
322
+ * @param {string} name параметр
323
+ * @returns {Promise<string | null>} результат
324
+ */
325
+ async function defaultGetPublishedPyPiVersion(name) {
326
+ try {
327
+ const res = await fetch(`https://pypi.org/pypi/${encodeURIComponent(name)}/json`, {
328
+ signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS)
329
+ })
330
+ if (!res.ok) return null
331
+ const data = await res.json()
332
+ const v = data?.info?.version
333
+ return typeof v === 'string' && v.length > 0 ? v : null
334
+ } catch {
335
+ return null
336
+ }
337
+ }
338
+
339
+ /**
340
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
341
+ * @param {(name: string, kind?: import('../lib/package-manifest.mjs').PackageKind) => Promise<string | null>} getPublishedVersion параметр
342
+ * @returns {Promise<string | null>} результат
343
+ */
344
+ function resolvePublishedVersion(manifest, getPublishedVersion) {
345
+ if (!manifest.name) return Promise.resolve(null)
346
+ return getPublishedVersion(manifest.name, manifest.kind)
347
+ }
348
+
349
+ /** Числове ядро semver (`x.y.z`); хвіст (prerelease/build) ігнорується. */
350
+ const SEMVER_CORE_RE = /^(\d+)\.(\d+)\.(\d+)/
351
+
352
+ /**
353
+ * Парсить числове ядро semver-рядка.
354
+ * @param {unknown} v версія
355
+ * @returns {{ major: number, minor: number, patch: number } | null} ядро або null
356
+ */
357
+ function parseSemverCore(v) {
358
+ const m = typeof v === 'string' ? v.match(SEMVER_CORE_RE) : null
359
+ if (!m) return null
360
+ return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]) }
361
+ }
362
+
363
+ /**
364
+ * Порівнює semver-ядра двох версій.
365
+ * @param {unknown} a перша версія
366
+ * @param {unknown} b друга версія
367
+ * @returns {-1 | 0 | 1 | null} a<b → -1, a==b → 0, a>b → 1; null — нерозпізнано
368
+ */
369
+ function compareSemverCore(a, b) {
370
+ const pa = parseSemverCore(a)
371
+ const pb = parseSemverCore(b)
372
+ if (!pa || !pb) return null
373
+ if (pa.major !== pb.major) return pa.major > pb.major ? 1 : -1
374
+ if (pa.minor !== pb.minor) return pa.minor > pb.minor ? 1 : -1
375
+ if (pa.patch !== pb.patch) return pa.patch > pb.patch ? 1 : -1
376
+ return 0
377
+ }
378
+
379
+ /**
380
+ * Чи `current` випереджає `base` (ручний bump поза CI). Якщо semver нерозпізнаний
381
+ * (null) — fail-closed на будь-яку нерівність (консервативно, як до directional-фікса).
382
+ * @param {unknown} current версія в дереві
383
+ * @param {unknown} base база (опублікована / git-база)
384
+ * @returns {boolean} true — current попереду base (або нерозпізнано й не рівні)
385
+ */
386
+ function versionIsAhead(current, base) {
387
+ const cmp = compareSemverCore(current, base)
388
+ return cmp === null ? current !== base : cmp > 0
389
+ }
390
+
391
+ /**
392
+ * @param {string} name пакет
393
+ * @param {import('../lib/package-manifest.mjs').PackageKind} [kind] тип пакета
394
+ * @returns {Promise<string | null>} опублікована версія або null
395
+ */
396
+ function defaultGetPublishedVersion(name, kind = 'npm') {
397
+ if (kind === 'python') {
398
+ return defaultGetPublishedPyPiVersion(name)
399
+ }
400
+ return defaultGetPublishedNpmVersion(name)
401
+ }
402
+
403
+ /**
404
+ * @returns {(name: string, kind?: import('../lib/package-manifest.mjs').PackageKind) => Promise<string | null>} стандартний резолвер
405
+ */
406
+ function createDefaultGetPublishedVersion() {
407
+ return defaultGetPublishedVersion
408
+ }
409
+
410
+ /**
411
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
412
+ * @param {(msg: string) => void} pass параметр
413
+ * @param {(msg: string) => void} fail параметр
414
+ */
415
+ /**
416
+ * Перевіряє наявність `CHANGELOG.md` у воркспейсі.
417
+ * @param {string} ws відносний шлях воркспейсу від кореня репо
418
+ * @param {string} label мітка для повідомлень
419
+ * @param {string} cwd корінь репозиторію
420
+ * @param {(msg: string) => void} pass колбек успішної перевірки.
421
+ * @param {(msg: string) => void} fail колбек провалу перевірки.
422
+ * @returns {boolean} true — файл існує
423
+ */
424
+ function checkChangelogFileExists(ws, label, cwd, pass, fail) {
425
+ const path = join(cwd, ws, 'CHANGELOG.md')
426
+ if (existsSync(path)) {
427
+ pass(`${label}: CHANGELOG.md існує`)
428
+ return true
429
+ }
430
+ fail(`${label}: CHANGELOG.md відсутній — створи файл за форматом Keep a Changelog (n-changelog.mdc)`)
431
+ return false
432
+ }
433
+
434
+ /**
435
+ * Перевіряє базовий формат `CHANGELOG.md`: наявність H1 `# Changelog`.
436
+ * Версійні секції `## [x.y.z]` не вимагаються для нових workspace-ів без релізів.
437
+ * @param {string} ws відносний шлях воркспейсу від кореня репо
438
+ * @param {string} label мітка для повідомлень
439
+ * @param {string} cwd корінь репозиторію
440
+ * @param {(msg: string) => void} pass колбек успішної перевірки.
441
+ * @param {(msg: string) => void} fail колбек провалу перевірки.
442
+ * @returns {Promise<void>}
443
+ */
444
+ async function checkChangelogFormat(ws, label, cwd, pass, fail) {
445
+ const path = join(cwd, ws, 'CHANGELOG.md')
446
+ const content = await readFile(path, 'utf8')
447
+ const hasH1 = content.split('\n').some(l => l.trimEnd() === '# Changelog')
448
+ if (hasH1) {
449
+ pass(`${label}: CHANGELOG.md має рядок "# Changelog"`)
450
+ } else {
451
+ fail(`${label}: CHANGELOG.md не має рядка "# Changelog" — перший рядок має бути H1-заголовком (n-changelog.mdc)`)
452
+ }
453
+ }
454
+
455
+ /**
456
+ * Перевіряє, що масив `files` npm-маніфесту містить `CHANGELOG.md`.
457
+ * @param {object} manifest дескриптор воркспейсу (з kind/npmFiles).
458
+ * @param {(msg: string) => void} pass колбек успішної перевірки.
459
+ * @param {(msg: string) => void} fail колбек провалу перевірки.
460
+ * @returns {void}
461
+ */
462
+ function checkNpmFilesArrayContainsChangelog(manifest, pass, fail) {
463
+ if (manifest.kind !== 'npm' || !manifest.npmFiles) return
464
+ const pkgPath = manifestFilePath(manifest.ws, manifest)
465
+ if (manifest.npmFiles.includes('CHANGELOG.md')) {
466
+ pass(`${pkgPath}: files містить "CHANGELOG.md"`)
467
+ } else {
468
+ fail(`${pkgPath}: масив files має містити "CHANGELOG.md", щоб публікувати changelog із пакетом`)
469
+ }
470
+ }
471
+
472
+ /**
473
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
474
+ * @returns {string} результат
475
+ */
476
+ function workspaceLabel(manifest) {
477
+ return manifest.ws === '.' ? '<root>' : manifest.ws
478
+ }
479
+
480
+ /**
481
+ * Повідомлення «поклади change-файл» для workspace з релевантними змінами без change-файлу.
482
+ * @param {string} label мітка воркспейсу
483
+ * @param {string} mf шлях до маніфесту
484
+ * @returns {string} текст fail
485
+ */
486
+ function missingChangeFileMessage(label, mf) {
487
+ return (
488
+ `${label}: є релевантні зміни, але немає change-файлу (version у ${mf} не чіпай вручну). ` +
489
+ `Поклади change-файл: npx @7n/n ch [--bump <major|minor|patch>] [--section <Added|Changed|Fixed|Removed>] [--message "<…>"]; ` +
490
+ `bump зробить CI на main (n-changelog.mdc)`
491
+ )
492
+ }
493
+
494
+ /**
495
+ * Чи має workspace незрелізні change-файли (намір зафіксовано — bump зробить CI).
496
+ * @param {string} ws workspace
497
+ * @param {string} cwd корінь
498
+ * @returns {Promise<boolean>} результат
499
+ */
500
+ async function hasPendingChangeFiles(ws, cwd) {
501
+ const files = await readChangeFiles(ws, cwd)
502
+ return files.length > 0
503
+ }
504
+
505
+ /**
506
+ * Опис для autofix-change-файлу: subject останнього коміту (HEAD), а якщо порожній
507
+ * (порожній репозиторій / detached без імені) — назва гілки, інакше fallback-літерал.
508
+ * Опис мусить бути непорожнім — `writeChange`/`parseChangeFile` кидають на порожньому.
509
+ * @param {string} cwd корінь репозиторію
510
+ * @returns {Promise<string>} непорожній опис зміни
511
+ */
512
+ async function resolveAutoChangeMessage(cwd) {
513
+ const lastSubject = await gitOrNull(['log', '-1', '--format=%s'], cwd)
514
+ const subject = lastSubject?.trim()
515
+ if (subject) return subject
516
+ const branch = await currentBranchName(cwd)
517
+ return branch && branch !== 'HEAD' ? branch : AUTOFIX_FALLBACK_MESSAGE
518
+ }
519
+
520
+ /**
521
+ * Реакція на відсутній change-файл: у autofix-режимі — створити його з дефолтами й
522
+ * поставити у git-індекс (щоб коміт не падав); інакше — fail із підказкою.
523
+ * @param {string} ws workspace (`.` — корінь)
524
+ * @param {string} label мітка воркспейсу для повідомлень
525
+ * @param {string} mf шлях до маніфесту (для fail-підказки)
526
+ * @param {boolean} autofix чи створювати файл автоматично
527
+ * @param {(msg: string) => void} pass репортер pass
528
+ * @param {(msg: string) => void} fail репортер fail
529
+ * @param {string} cwd корінь репозиторію
530
+ * @returns {Promise<boolean>} `true` — change-файл створено (autofix); `false` — зафейлено
531
+ */
532
+ async function reportOrFixMissingChangeFile(ws, label, mf, autofix, pass, fail, cwd) {
533
+ if (!autofix) {
534
+ fail(missingChangeFileMessage(label, mf))
535
+ return false
536
+ }
537
+ const message = await resolveAutoChangeMessage(cwd)
538
+ const relFromWs = await writeChange({ bump: AUTOFIX_BUMP, section: AUTOFIX_SECTION, message, ws, cwd })
539
+ const created = ws === '.' ? relFromWs : join(ws, relFromWs)
540
+ // Ставимо новий файл у індекс одразу: pre-commit-хук комітить уже застейджені зміни,
541
+ // а свіжостворений untracked-файл інакше лишився б поза комітом.
542
+ await gitOrNull(['add', '--', created], cwd)
543
+ pass(
544
+ `${label}: автоматично створено change-файл ${created} ` +
545
+ `(${AUTOFIX_BUMP}/${AUTOFIX_SECTION}: "${message}") — відредагуй за потреби; bump зробить CI (n-changelog.mdc)`
546
+ )
547
+ return true
548
+ }
549
+
550
+ /**
551
+ * Published-варіант реакції на відсутній change-файл: створити/зафейлити через
552
+ * `reportOrFixMissingChangeFile`, а коли autofix створив файл — додатково перевірити,
553
+ * що `files` містить `CHANGELOG.md` (реліз наближається — CHANGELOG публікується з пакетом).
554
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest маніфест воркспейсу
555
+ * @param {string} label мітка воркспейсу
556
+ * @param {string} mf шлях до маніфесту
557
+ * @param {boolean} autofix autofix-режим
558
+ * @param {(msg: string) => void} pass репортер pass
559
+ * @param {(msg: string) => void} fail репортер fail
560
+ * @param {string} cwd корінь репозиторію
561
+ * @returns {Promise<void>} результат
562
+ */
563
+ async function fixOrFailPublishedWorkspace(manifest, label, mf, autofix, pass, fail, cwd) {
564
+ if (await reportOrFixMissingChangeFile(manifest.ws, label, mf, autofix, pass, fail, cwd)) {
565
+ checkNpmFilesArrayContainsChangelog(manifest, pass, fail)
566
+ }
567
+ }
568
+
569
+ /**
570
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
571
+ * @param {string} _Vcurrent параметр (для сумісності сигнатури; bump робить CI)
572
+ * @param {string[]} subWorkspaces параметр
573
+ * @param {boolean} autofix autofix-режим (створити change-файл замість fail)
574
+ * @param {(msg: string) => void} pass параметр
575
+ * @param {(msg: string) => void} fail параметр
576
+ * @param {string} cwd робочий каталог
577
+ * @returns {Promise<void>} результат
578
+ */
579
+ async function checkPublishedWorkspacePendingGitChanges(manifest, _Vcurrent, subWorkspaces, autofix, pass, fail, cwd) {
580
+ const label = workspaceLabel(manifest)
581
+ const mf = manifestFilePath(manifest.ws, manifest)
582
+ if (await hasPendingChangeFiles(manifest.ws, cwd)) {
583
+ pass(`${label}: є change-файл(и) у .changes/ — bump зробить CI (n-changelog.mdc)`)
584
+ // Реліз наближається → CHANGELOG має публікуватися разом із пакетом.
585
+ checkNpmFilesArrayContainsChangelog(manifest, pass, fail)
586
+ return
587
+ }
588
+ if (!(await isInsideGitRepo(cwd))) {
589
+ return
590
+ }
591
+
592
+ const branch = await currentBranchName(cwd)
593
+
594
+ if (branch === LOCAL_ONLY_SKIP_BRANCH) {
595
+ if (await workspaceHasRelevantChangesAgainstBase('HEAD', manifest.ws, subWorkspaces, cwd)) {
596
+ await fixOrFailPublishedWorkspace(manifest, label, mf, autofix, pass, fail, cwd)
597
+ }
598
+ return
599
+ }
600
+
601
+ const comparison = await resolveChangelogComparisonPoint(branch, cwd)
602
+ if (comparison && (await workspaceHasRelevantChangesAgainstBase(comparison.ref, manifest.ws, subWorkspaces, cwd))) {
603
+ await fixOrFailPublishedWorkspace(manifest, label, mf, autofix, pass, fail, cwd)
604
+ return
605
+ }
606
+
607
+ if (branch === 'main' && (await workspaceHasRelevantChangesAgainstBase('HEAD', manifest.ws, subWorkspaces, cwd))) {
608
+ await fixOrFailPublishedWorkspace(manifest, label, mf, autofix, pass, fail, cwd)
609
+ }
610
+ }
611
+
612
+ /**
613
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
614
+ * @param {string[]} subWorkspaces параметр
615
+ * @param {(name: string, kind?: import('../lib/package-manifest.mjs').PackageKind) => Promise<string | null>} getPublishedVersion параметр
616
+ * @param {boolean} autofix autofix-режим (створити change-файл замість fail)
617
+ * @param {(msg: string) => void} pass параметр
618
+ * @param {(msg: string) => void} fail параметр
619
+ * @param {string} cwd робочий каталог
620
+ * @returns {Promise<void>} результат
621
+ */
622
+ async function checkPublishedWorkspace(manifest, subWorkspaces, getPublishedVersion, autofix, pass, fail, cwd) {
623
+ const label = workspaceLabel(manifest)
624
+ const mf = manifestFilePath(manifest.ws, manifest)
625
+ const changelogExists = checkChangelogFileExists(manifest.ws, label, cwd, pass, fail)
626
+ if (changelogExists) {
627
+ await checkChangelogFormat(manifest.ws, label, cwd, pass, fail)
628
+ }
629
+ const Vcurrent = manifest.version
630
+ if (!Vcurrent) {
631
+ fail(`${label}: у ${mf} відсутнє поле version (registry-published воркспейс)`)
632
+ return
633
+ }
634
+ const name = manifest.name
635
+ if (!name) {
636
+ fail(`${label}: у ${mf} відсутнє ім'я пакета (registry-published воркспейс)`)
637
+ return
638
+ }
639
+ // Autofix/hook-режим: жодної мережі. Реєстровий резолв (`npm view` / PyPI fetch) і
640
+ // drift-перевірка vs опублікована версія пропускаються — лишається лише наявність
641
+ // change-файлу (+ autofix) і git-diff. Ручний bump version у хуці не ловиться; його
642
+ // далі ловить CI та ручний `fix changelog` (без env). Запит користувача: «прибери
643
+ // npm view з хуку».
644
+ if (autofix) {
645
+ pass(`${label}: ${name} — autofix-режим, реєстрову перевірку version пропущено (без npm view)`)
646
+ await checkPublishedWorkspacePendingGitChanges(manifest, Vcurrent, subWorkspaces, autofix, pass, fail, cwd)
647
+ return
648
+ }
649
+ const Vpublished = await resolvePublishedVersion(manifest, getPublishedVersion)
650
+ if (Vpublished === null) {
651
+ pass(`${label}: ${name} — опублікована версія недоступна (мережа/реєстр), перевірку пропущено`)
652
+ return
653
+ }
654
+ // Лише drift УПЕРЕД (version > опублікованої) — ручний bump поза CI; має пріоритет
655
+ // над change-файлом (симетрично з local-only-шляхом). Версія ПОЗАДУ реєстру — локаль
656
+ // відстала від уже опублікованого релізу, не порушення (нижче).
657
+ if (versionIsAhead(Vcurrent, Vpublished)) {
658
+ fail(
659
+ `${label}: version у ${mf} (${Vcurrent}) випереджає опубліковану (${Vpublished}) — ` +
660
+ `ручний bump поза CI заборонено. Відкоти version і поклади change-файл ` +
661
+ `(npx @7n/n ch); bump зробить CI на main (n-changelog.mdc)`
662
+ )
663
+ return
664
+ }
665
+ if (compareSemverCore(Vcurrent, Vpublished) < 0) {
666
+ // Локаль ПОЗАДУ реєстру: CI вже опублікував новішу версію й закомітив bump назад,
667
+ // а ти ще не зробив `git pull`. Це не ручний bump (git не дасть запушити
668
+ // non-fast-forward), тож коміт не блокуємо — лише вимагаємо change-файл на наявні зміни.
669
+ pass(
670
+ `${label}: version у ${mf} (${Vcurrent}) позаду опублікованої (${Vpublished}) — ` +
671
+ `локаль відстала від реєстру (зроби git pull); це не ручний bump`
672
+ )
673
+ await checkPublishedWorkspacePendingGitChanges(manifest, Vcurrent, subWorkspaces, autofix, pass, fail, cwd)
674
+ return
675
+ }
676
+ pass(`${label}: ${name}@${Vcurrent} збігається з реєстром — перевіряємо git на незрелізні зміни`)
677
+ await checkPublishedWorkspacePendingGitChanges(manifest, Vcurrent, subWorkspaces, autofix, pass, fail, cwd)
678
+ }
679
+
680
+ /**
681
+ * @param {string} comparisonRef ref/SHA для `git diff` / `git show`
682
+ * @param {import('../lib/package-manifest.mjs').PackageManifest} manifest параметр
683
+ * @param {string} baseLabel параметр
684
+ * @param {boolean} autofix autofix-режим (створити change-файл замість fail)
685
+ * @param {(msg: string) => void} pass параметр
686
+ * @param {(msg: string) => void} fail параметр
687
+ * @param {string} cwd робочий каталог
688
+ */
689
+ async function checkLocalOnlyChangedWorkspace(comparisonRef, manifest, baseLabel, autofix, pass, fail, cwd) {
690
+ const label = workspaceLabel(manifest)
691
+ const mf = manifestFilePath(manifest.ws, manifest)
692
+ const Vcurrent = manifest.version
693
+ // Лише drift УПЕРЕД (version > бази) має пріоритет над change-файлом: ручний bump
694
+ // заборонено навіть із change-файлом (симетрично з published-шляхом). Version позаду
695
+ // бази (гілка відстала від base-ref) — не порушення, не блокуємо.
696
+ const Vbase = await readBaseVersion(comparisonRef, manifest, cwd)
697
+ if (Vbase !== null && Vcurrent !== null && versionIsAhead(Vcurrent, Vbase)) {
698
+ fail(
699
+ `${label}: version у ${mf} змінено поза CI (${Vbase} → ${Vcurrent}) — ручний bump заборонено (на ${baseLabel} — ${Vbase}). ` +
700
+ `Відкоти version і поклади change-файл (npx @7n/n ch); bump зробить CI (n-changelog.mdc)`
701
+ )
702
+ return
703
+ }
704
+ if (await hasPendingChangeFiles(manifest.ws, cwd)) {
705
+ pass(`${label}: є change-файл(и) у .changes/ — bump зробить CI (n-changelog.mdc)`)
706
+ return
707
+ }
708
+ await reportOrFixMissingChangeFile(manifest.ws, label, mf, autofix, pass, fail, cwd)
709
+ }
710
+
711
+ /**
712
+ * @param {import('../lib/package-manifest.mjs').PackageManifest[]} localOnly параметр
713
+ * @param {string[]} subWorkspaces параметр
714
+ * @param {boolean} autofix autofix-режим (створити change-файл замість fail)
715
+ * @param {(msg: string) => void} pass параметр
716
+ * @param {(msg: string) => void} fail параметр
717
+ * @param {string} cwd робочий каталог
718
+ */
719
+ async function runLocalOnlyChecks(localOnly, subWorkspaces, autofix, pass, fail, cwd) {
720
+ if (localOnly.length === 0) return
721
+
722
+ for (const manifest of localOnly) {
723
+ const label = workspaceLabel(manifest)
724
+ const exists = checkChangelogFileExists(manifest.ws, label, cwd, pass, fail)
725
+ if (exists) {
726
+ await checkChangelogFormat(manifest.ws, label, cwd, pass, fail)
727
+ }
728
+ }
729
+
730
+ if (!(await isInsideGitRepo(cwd))) {
731
+ pass('changelog: не git-репозиторій — local-only перевірку пропущено')
732
+ return
733
+ }
734
+ const branch = await currentBranchName(cwd)
735
+ if (branch === LOCAL_ONLY_SKIP_BRANCH) {
736
+ pass('changelog: поточна гілка = dev — local-only перевірку пропущено')
737
+ return
738
+ }
739
+ const comparison = await resolveChangelogComparisonPoint(branch, cwd)
740
+ if (!comparison) {
741
+ pass('changelog: ref dev/main (та origin/*) не знайдено — local-only перевірку пропущено')
742
+ return
743
+ }
744
+
745
+ let checkedAny = false
746
+ for (const manifest of localOnly) {
747
+ if (!(await workspaceHasRelevantChangesAgainstBase(comparison.ref, manifest.ws, subWorkspaces, cwd))) continue
748
+ checkedAny = true
749
+ await checkLocalOnlyChangedWorkspace(comparison.ref, manifest, comparison.label, autofix, pass, fail, cwd)
750
+ }
751
+ if (!checkedAny) {
752
+ pass(`changelog: local-only воркспейси без змін відносно ${comparison.label}`)
753
+ }
754
+ }
755
+
756
+ /**
757
+ * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст лінт-прогону.
758
+ * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат перевірки consistency changelog.
759
+ */
760
+ export async function lint(ctx) {
761
+ const reporter = createViolationReporter(ctx)
762
+ const { pass, fail } = reporter
763
+ const getPublishedVersion = createDefaultGetPublishedVersion()
764
+ const cwd = ctx.cwd
765
+
766
+ // Merge-коміт інтегрує вже задокументовану роботу — changeset не потрібен (інакше
767
+ // autofix створює шумний «Merge…» changeset → CI commit-back каскадить patch-реліз).
768
+ if (await isMergeCommit(cwd)) {
769
+ pass('HEAD — merge-коміт: changelog-перевірку пропущено (changeset документують feature-коміти)')
770
+ return reporter.result()
771
+ }
772
+
773
+ const autofix = process.env[AUTOFIX_ENV_VAR] === '1' || process.env[LEGACY_AUTOFIX_ENV_VAR] === '1'
774
+
775
+ const workspaces = await getMonorepoProjectRootDirs(cwd)
776
+ const subWorkspaces = workspaces.filter(w => w !== '.')
777
+ // Корінь монорепо (`.` за наявності підпакетів) — це glue/конфіг/tooling, а не логіка
778
+ // продукту: власного CHANGELOG він не веде, помітні зміни документують підпакети.
779
+ const isMonorepoRoot = subWorkspaces.length > 0
780
+
781
+ /**
782
+ @type {import('../lib/package-manifest.mjs').PackageManifest[]}
783
+ */
784
+ const published = []
785
+ /**
786
+ @type {import('../lib/package-manifest.mjs').PackageManifest[]}
787
+ */
788
+ const localOnly = []
789
+
790
+ for (const ws of workspaces) {
791
+ if (ws === '.' && isMonorepoRoot) {
792
+ pass(
793
+ '<root>: корінь монорепо (glue/конфіг/tooling) — перевірку CHANGELOG пропущено; помітні зміни документують підпакети'
794
+ )
795
+ continue
796
+ }
797
+ const manifest = await readPackageManifest(ws, cwd)
798
+ if (!manifest) {
799
+ continue
800
+ }
801
+ if (manifest.registryPublishable) {
802
+ published.push(manifest)
803
+ } else {
804
+ localOnly.push(manifest)
805
+ }
806
+ }
807
+
808
+ // Promise.all, не послідовний for (spec docs/specs/2026-07-02-text-check-per-file-split-design.md
809
+ // §7): кожен виклик — незалежний мережевий запит (npm view/PyPI), послідовність тут не давала
810
+ // жодної переваги, лише сумувала worst-case timeout на кожен published workspace.
811
+ await Promise.all(
812
+ published.map(manifest =>
813
+ checkPublishedWorkspace(manifest, subWorkspaces, getPublishedVersion, autofix, pass, fail, cwd)
814
+ )
815
+ )
816
+
817
+ await runLocalOnlyChecks(localOnly, subWorkspaces, autofix, pass, fail, cwd)
818
+
819
+ return reporter.result()
820
+ }