@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.
- package/.claude-template/hooks/capture-decisions.sh +355 -0
- package/.claude-template/hooks/lib/tooling-only.sh +77 -0
- package/.claude-template/hooks/normalize-decisions.sh +574 -0
- package/.claude-template/settings.template.json +26 -0
- package/.pi-template/extensions/n-rules-adr/docs/index.md +28 -0
- package/.pi-template/extensions/n-rules-adr/index.ts +105 -0
- package/.pi-template/extensions/n-rules-adr/tsconfig.json +17 -0
- package/AGENTS.template.md +53 -0
- package/CHANGELOG.md +4277 -0
- package/README.md +189 -0
- package/bin/docs/n-rules.md +612 -0
- package/bin/docs/rename-yaml-extensions.md +207 -0
- package/bin/n-rules.js +1709 -0
- package/bin/rename-yaml-extensions.mjs +42 -0
- package/docs/index.md +12 -0
- package/docs/stryker.config.md +31 -0
- package/docs/vitest.config.md +36 -0
- package/github-actions/release/action.yml +9 -0
- package/github-actions/setup-bun-deps/action.yml +27 -0
- package/package.json +87 -0
- package/rules/abie/base_deployment_preem/base_deployment_preem.mdc +22 -0
- package/rules/abie/base_deployment_preem/base_deployment_preem.rego +54 -0
- package/rules/abie/base_deployment_preem/concern.json +8 -0
- package/rules/abie/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
- package/rules/abie/clean_merged_ignore_branches/clean_merged_ignore_branches.rego +81 -0
- package/rules/abie/clean_merged_ignore_branches/concern.json +8 -0
- package/rules/abie/clean_merged_ignore_branches/template/clean-merged-branch.yml.snippet.yml +9 -0
- package/rules/abie/docs/index.md +11 -0
- package/rules/abie/env_dns/concern.json +4 -0
- package/rules/abie/env_dns/docs/main.md +32 -0
- package/rules/abie/env_dns/env_dns.mdc +33 -0
- package/rules/abie/env_dns/main.mjs +47 -0
- package/rules/abie/firebase_hosting/concern.json +4 -0
- package/rules/abie/firebase_hosting/docs/main.md +41 -0
- package/rules/abie/firebase_hosting/firebase_hosting.mdc +3 -0
- package/rules/abie/firebase_hosting/main.mjs +46 -0
- package/rules/abie/hc_pairing/concern.json +4 -0
- package/rules/abie/hc_pairing/docs/main.md +34 -0
- package/rules/abie/hc_pairing/hc_pairing.mdc +23 -0
- package/rules/abie/hc_pairing/main.mjs +52 -0
- package/rules/abie/health_check_policy/concern.json +8 -0
- package/rules/abie/health_check_policy/health_check_policy.mdc +19 -0
- package/rules/abie/health_check_policy/health_check_policy.rego +172 -0
- package/rules/abie/http_route_base/concern.json +8 -0
- package/rules/abie/http_route_base/http_route_base.mdc +9 -0
- package/rules/abie/http_route_base/http_route_base.rego +45 -0
- package/rules/abie/lib/docs/enabled.md +38 -0
- package/rules/abie/lib/docs/env-dns.md +31 -0
- package/rules/abie/lib/docs/hc-yaml.md +33 -0
- package/rules/abie/lib/docs/http-route.md +31 -0
- package/rules/abie/lib/docs/index.md +18 -0
- package/rules/abie/lib/docs/k8s-tree.md +44 -0
- package/rules/abie/lib/docs/kustomization-patches.md +37 -0
- package/rules/abie/lib/docs/overlay-paths.md +42 -0
- package/rules/abie/lib/docs/yaml.md +33 -0
- package/rules/abie/lib/enabled.mjs +37 -0
- package/rules/abie/lib/env-dns.mjs +81 -0
- package/rules/abie/lib/hc-yaml.mjs +27 -0
- package/rules/abie/lib/http-route.mjs +100 -0
- package/rules/abie/lib/k8s-tree.mjs +110 -0
- package/rules/abie/lib/kustomization-patches.mjs +211 -0
- package/rules/abie/lib/overlay-paths.mjs +97 -0
- package/rules/abie/lib/yaml.mjs +72 -0
- package/rules/abie/main.json +1 -0
- package/rules/abie/main.mdc +47 -0
- package/rules/abie/package_json_shared/concern.json +11 -0
- package/rules/abie/package_json_shared/package_json_shared.mdc +17 -0
- package/rules/abie/package_json_shared/package_json_shared.rego +16 -0
- package/rules/abie/ua_http_route/concern.json +4 -0
- package/rules/abie/ua_http_route/docs/main.md +44 -0
- package/rules/abie/ua_http_route/main.mjs +80 -0
- package/rules/abie/ua_http_route/ua_http_route.mdc +47 -0
- package/rules/abie/ua_node_selector/concern.json +4 -0
- package/rules/abie/ua_node_selector/docs/main.md +34 -0
- package/rules/abie/ua_node_selector/main.mjs +62 -0
- package/rules/abie/ua_node_selector/ua_node_selector.mdc +27 -0
- package/rules/adr/docs/index.md +11 -0
- package/rules/adr/hooks/concern.json +4 -0
- package/rules/adr/hooks/docs/main.md +38 -0
- package/rules/adr/hooks/hooks.mdc +32 -0
- package/rules/adr/hooks/main.mjs +367 -0
- package/rules/adr/main.json +1 -0
- package/rules/adr/main.mdc +93 -0
- package/rules/adr/settings_json/concern.json +9 -0
- package/rules/adr/settings_json/settings_json.mdc +7 -0
- package/rules/adr/settings_json/settings_json.rego +37 -0
- package/rules/adr/settings_local_json/concern.json +9 -0
- package/rules/adr/settings_local_json/settings_local_json.mdc +7 -0
- package/rules/adr/settings_local_json/settings_local_json.rego +40 -0
- package/rules/bun/bunfig/bunfig.mdc +12 -0
- package/rules/bun/bunfig/bunfig.rego +29 -0
- package/rules/bun/bunfig/concern.json +9 -0
- package/rules/bun/bunfig/template/bunfig.toml.snippet.toml +2 -0
- package/rules/bun/docs/index.md +11 -0
- package/rules/bun/layout/concern.json +16 -0
- package/rules/bun/layout/docs/fix-layout.md +29 -0
- package/rules/bun/layout/docs/main.md +34 -0
- package/rules/bun/layout/fix-layout.mjs +63 -0
- package/rules/bun/layout/layout.mdc +60 -0
- package/rules/bun/layout/main.mjs +53 -0
- package/rules/bun/licensee/concern.json +7 -0
- package/rules/bun/licensee/docs/fix-licensee.md +28 -0
- package/rules/bun/licensee/docs/index.md +12 -0
- package/rules/bun/licensee/docs/main.md +37 -0
- package/rules/bun/licensee/fix-licensee.mjs +32 -0
- package/rules/bun/licensee/main.mjs +44 -0
- package/rules/bun/main.json +1 -0
- package/rules/bun/main.mdc +11 -0
- package/rules/bun/package_json/concern.json +9 -0
- package/rules/bun/package_json/docs/fix-package_json.md +28 -0
- package/rules/bun/package_json/docs/index.md +9 -0
- package/rules/bun/package_json/fix-package_json.mjs +311 -0
- package/rules/bun/package_json/package_json.mdc +14 -0
- package/rules/bun/package_json/package_json.rego +64 -0
- package/rules/bun/package_json/template/package.json.deny.json +4 -0
- package/rules/capacitor/docs/index.md +11 -0
- package/rules/capacitor/main.json +1 -0
- package/rules/capacitor/main.mdc +12 -0
- package/rules/capacitor/package_json/concern.json +9 -0
- package/rules/capacitor/package_json/package_json.mdc +9 -0
- package/rules/capacitor/package_json/package_json.rego +45 -0
- package/rules/capacitor/platforms/concern.json +4 -0
- package/rules/capacitor/platforms/docs/main.md +41 -0
- package/rules/capacitor/platforms/main.mjs +486 -0
- package/rules/changelog/consistency/concern.json +4 -0
- package/rules/changelog/consistency/docs/fix-consistency.md +31 -0
- package/rules/changelog/consistency/docs/main.md +41 -0
- package/rules/changelog/consistency/fix-consistency.mjs +71 -0
- package/rules/changelog/consistency/main.mjs +820 -0
- package/rules/changelog/docs/index.md +11 -0
- package/rules/changelog/lib/docs/index.md +11 -0
- package/rules/changelog/lib/docs/package-manifest.md +214 -0
- package/rules/changelog/lib/package-manifest.mjs +158 -0
- package/rules/changelog/main.json +1 -0
- package/rules/changelog/main.mdc +7 -0
- package/rules/changelog/presence/concern.json +7 -0
- package/rules/changelog/presence/docs/main.md +44 -0
- package/rules/changelog/presence/main.mjs +87 -0
- package/rules/ci4/docs/index.md +11 -0
- package/rules/ci4/main.json +1 -0
- package/rules/ci4/main.mdc +375 -0
- package/rules/ci4/marksman_config/concern.json +5 -0
- package/rules/ci4/marksman_config/data/marksman_config/marksman.baseline.toml +27 -0
- package/rules/ci4/marksman_config/docs/fix-marksman_config.md +27 -0
- package/rules/ci4/marksman_config/docs/main.md +30 -0
- package/rules/ci4/marksman_config/fix-marksman_config.mjs +24 -0
- package/rules/ci4/marksman_config/main.mjs +38 -0
- package/rules/ci4/marksman_config/marksman_config.mdc +31 -0
- package/rules/ci4/vscode_extensions/concern.json +9 -0
- package/rules/ci4/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
- package/rules/ci4/vscode_extensions/docs/index.md +11 -0
- package/rules/ci4/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/ci4/vscode_extensions/template/extensions.json.snippet.json +3 -0
- package/rules/ci4/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/ci4/vscode_extensions/vscode_extensions.rego +12 -0
- package/rules/doc-files/check/concern.json +7 -0
- package/rules/doc-files/check/docs/fix-check.md +28 -0
- package/rules/doc-files/check/docs/fix-worker.md +28 -0
- package/rules/doc-files/check/docs/main.md +32 -0
- package/rules/doc-files/check/fix-check.mjs +45 -0
- package/rules/doc-files/check/fix-worker.mjs +56 -0
- package/rules/doc-files/check/main.mjs +99 -0
- package/rules/doc-files/docgen-crc/concern.json +3 -0
- package/rules/doc-files/docgen-crc/docs/main.md +46 -0
- package/rules/doc-files/docgen-crc/main.mjs +207 -0
- package/rules/doc-files/docgen-extract/concern.json +3 -0
- package/rules/doc-files/docgen-extract/docs/main.md +38 -0
- package/rules/doc-files/docgen-extract/main.mjs +471 -0
- package/rules/doc-files/docgen-extract-anchors/concern.json +3 -0
- package/rules/doc-files/docgen-extract-anchors/docs/main.md +49 -0
- package/rules/doc-files/docgen-extract-anchors/main.mjs +115 -0
- package/rules/doc-files/docgen-files-batch/concern.json +3 -0
- package/rules/doc-files/docgen-files-batch/docs/main.md +38 -0
- package/rules/doc-files/docgen-files-batch/main.mjs +517 -0
- package/rules/doc-files/docgen-fix-worker/concern.json +3 -0
- package/rules/doc-files/docgen-gen/concern.json +3 -0
- package/rules/doc-files/docgen-gen/docs/main.md +40 -0
- package/rules/doc-files/docgen-gen/main.mjs +582 -0
- package/rules/doc-files/docgen-ignore/concern.json +3 -0
- package/rules/doc-files/docgen-ignore/docs/main.md +33 -0
- package/rules/doc-files/docgen-ignore/main.mjs +54 -0
- package/rules/doc-files/docgen-judge/concern.json +3 -0
- package/rules/doc-files/docgen-judge/docs/main.md +43 -0
- package/rules/doc-files/docgen-judge/main.mjs +116 -0
- package/rules/doc-files/docgen-prompts/concern.json +3 -0
- package/rules/doc-files/docgen-prompts/docs/main.md +48 -0
- package/rules/doc-files/docgen-prompts/main.mjs +222 -0
- package/rules/doc-files/docgen-scan/concern.json +3 -0
- package/rules/doc-files/docgen-scan/docs/main.md +52 -0
- package/rules/doc-files/docgen-scan/main.mjs +231 -0
- package/rules/doc-files/docs/index.md +11 -0
- package/rules/doc-files/main.json +1 -0
- package/rules/doc-files/main.mdc +49 -0
- package/rules/doc-files/units/concern.json +3 -0
- package/rules/doc-files/units/docs/main.md +32 -0
- package/rules/doc-files/units/main.mjs +20 -0
- package/rules/doc-files/units-js/concern.json +3 -0
- package/rules/doc-files/units-js/docs/main.md +32 -0
- package/rules/doc-files/units-js/main.mjs +141 -0
- package/rules/doc-files/units-rs/concern.json +3 -0
- package/rules/doc-files/units-rs/docs/main.md +36 -0
- package/rules/doc-files/units-rs/main.mjs +311 -0
- package/rules/docker/docs/index.md +11 -0
- package/rules/docker/lib/docker-hadolint.mjs +60 -0
- package/rules/docker/lib/docker-mirror.mjs +148 -0
- package/rules/docker/lib/docker-native-addon.mjs +93 -0
- package/rules/docker/lib/docker-nginx-user.mjs +122 -0
- package/rules/docker/lib/docs/docker-hadolint.md +29 -0
- package/rules/docker/lib/docs/docker-mirror.md +251 -0
- package/rules/docker/lib/docs/docker-native-addon.md +174 -0
- package/rules/docker/lib/docs/docker-nginx-user.md +223 -0
- package/rules/docker/lib/docs/index.md +14 -0
- package/rules/docker/lint/concern.json +7 -0
- package/rules/docker/lint/docs/main.md +47 -0
- package/rules/docker/lint/main.mjs +360 -0
- package/rules/docker/lint_docker_yml/concern.json +9 -0
- package/rules/docker/lint_docker_yml/lint_docker_yml.mdc +14 -0
- package/rules/docker/lint_docker_yml/lint_docker_yml.rego +79 -0
- package/rules/docker/lint_docker_yml/template/lint-docker.yml.snippet.yml +41 -0
- package/rules/docker/main.json +1 -0
- package/rules/docker/main.mdc +14 -0
- package/rules/efes/docs/index.md +11 -0
- package/rules/efes/main.json +1 -0
- package/rules/efes/main.mdc +21 -0
- package/rules/efes/package_json_shared/concern.json +11 -0
- package/rules/efes/package_json_shared/package_json_shared.mdc +33 -0
- package/rules/efes/package_json_shared/package_json_shared.rego +16 -0
- package/rules/feedback/docs/index.md +11 -0
- package/rules/feedback/main.json +1 -0
- package/rules/feedback/main.mdc +63 -0
- package/rules/ga/clean_ga_workflows/clean_ga_workflows.mdc +20 -0
- package/rules/ga/clean_ga_workflows/clean_ga_workflows.rego +112 -0
- package/rules/ga/clean_ga_workflows/concern.json +10 -0
- package/rules/ga/clean_ga_workflows/template/clean-ga-workflows.yml.snippet.yml +26 -0
- package/rules/ga/clean_merged_branch/clean_merged_branch.mdc +24 -0
- package/rules/ga/clean_merged_branch/clean_merged_branch.rego +163 -0
- package/rules/ga/clean_merged_branch/concern.json +10 -0
- package/rules/ga/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml +37 -0
- package/rules/ga/docs/index.md +11 -0
- package/rules/ga/git_ai/concern.json +11 -0
- package/rules/ga/git_ai/git_ai.mdc +19 -0
- package/rules/ga/git_ai/git_ai.rego +76 -0
- package/rules/ga/git_ai/template/git-ai.yml.snippet.yml +30 -0
- package/rules/ga/lint_ga/concern.json +10 -0
- package/rules/ga/lint_ga/lint_ga.mdc +21 -0
- package/rules/ga/lint_ga/lint_ga.rego +132 -0
- package/rules/ga/lint_ga/template/lint-ga.yml.snippet.yml +41 -0
- package/rules/ga/main.json +1 -0
- package/rules/ga/main.mdc +17 -0
- package/rules/ga/vscode_extensions/concern.json +11 -0
- package/rules/ga/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
- package/rules/ga/vscode_extensions/docs/index.md +11 -0
- package/rules/ga/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/ga/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/ga/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/ga/vscode_extensions/vscode_extensions.rego +18 -0
- package/rules/ga/vscode_settings/concern.json +11 -0
- package/rules/ga/vscode_settings/template/settings.json.snippet.json +1 -0
- package/rules/ga/vscode_settings/vscode_settings.mdc +9 -0
- package/rules/ga/vscode_settings/vscode_settings.rego +22 -0
- package/rules/ga/workflow_common/concern.json +9 -0
- package/rules/ga/workflow_common/template/uses-min-versions.snippet.json +4 -0
- package/rules/ga/workflow_common/workflow_common.mdc +18 -0
- package/rules/ga/workflow_common/workflow_common.rego +288 -0
- package/rules/ga/workflows/concern.json +8 -0
- package/rules/ga/workflows/docs/fix-workflows.md +37 -0
- package/rules/ga/workflows/docs/main.md +38 -0
- package/rules/ga/workflows/fix-workflows.mjs +212 -0
- package/rules/ga/workflows/main.mjs +433 -0
- package/rules/ga/workflows/workflows.mdc +33 -0
- package/rules/ga/zizmor_yml/concern.json +11 -0
- package/rules/ga/zizmor_yml/template/zizmor.yml.snippet.yml +5 -0
- package/rules/ga/zizmor_yml/zizmor_yml.mdc +9 -0
- package/rules/ga/zizmor_yml/zizmor_yml.rego +27 -0
- package/rules/graphql/docs/index.md +11 -0
- package/rules/graphql/lib/docs/graphql-gql-scan.md +226 -0
- package/rules/graphql/lib/docs/index.md +11 -0
- package/rules/graphql/lib/graphql-gql-scan.mjs +146 -0
- package/rules/graphql/main.json +1 -0
- package/rules/graphql/main.mdc +8 -0
- package/rules/graphql/tooling/concern.json +8 -0
- package/rules/graphql/tooling/docs/main.md +36 -0
- package/rules/graphql/tooling/main.mjs +129 -0
- package/rules/graphql/tooling/tooling.mdc +13 -0
- package/rules/graphql/vscode_extensions/concern.json +9 -0
- package/rules/graphql/vscode_extensions/docs/fix-vscode_extensions.md +24 -0
- package/rules/graphql/vscode_extensions/docs/index.md +11 -0
- package/rules/graphql/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/graphql/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/graphql/vscode_extensions/vscode_extensions.rego +20 -0
- package/rules/hasura/docs/index.md +11 -0
- package/rules/hasura/internal_urls/concern.json +5 -0
- package/rules/hasura/internal_urls/docs/fix-internal_urls.md +26 -0
- package/rules/hasura/internal_urls/docs/index.md +12 -0
- package/rules/hasura/internal_urls/docs/main.md +36 -0
- package/rules/hasura/internal_urls/fix-internal_urls.mjs +66 -0
- package/rules/hasura/internal_urls/internal_urls.mdc +27 -0
- package/rules/hasura/internal_urls/main.mjs +233 -0
- package/rules/hasura/main.json +1 -0
- package/rules/hasura/main.mdc +8 -0
- package/rules/hasura/migrations/concern.json +4 -0
- package/rules/hasura/migrations/docs/fix-migrations.md +25 -0
- package/rules/hasura/migrations/docs/index.md +12 -0
- package/rules/hasura/migrations/docs/main.md +35 -0
- package/rules/hasura/migrations/fix-migrations.mjs +35 -0
- package/rules/hasura/migrations/main.mjs +53 -0
- package/rules/hasura/migrations/migrations.mdc +13 -0
- package/rules/hasura/svc_hl/concern.json +8 -0
- package/rules/hasura/svc_hl/svc_hl.mdc +15 -0
- package/rules/hasura/svc_hl/svc_hl.rego +50 -0
- package/rules/image-avif/avif_generation/avif_generation.mdc +26 -0
- package/rules/image-avif/avif_generation/concern.json +4 -0
- package/rules/image-avif/avif_generation/docs/fix-avif_generation.md +27 -0
- package/rules/image-avif/avif_generation/docs/main.md +36 -0
- package/rules/image-avif/avif_generation/fix-avif_generation.mjs +80 -0
- package/rules/image-avif/avif_generation/main.mjs +411 -0
- package/rules/image-avif/docs/index.md +11 -0
- package/rules/image-avif/main.json +1 -0
- package/rules/image-avif/main.mdc +8 -0
- package/rules/image-avif/package_json/concern.json +9 -0
- package/rules/image-avif/package_json/package_json.mdc +18 -0
- package/rules/image-avif/package_json/package_json.rego +47 -0
- package/rules/image-avif/package_json/template/package.json.deny.json +5 -0
- package/rules/image-compress/check/concern.json +7 -0
- package/rules/image-compress/check/docs/fix-check.md +34 -0
- package/rules/image-compress/check/docs/index.md +10 -0
- package/rules/image-compress/check/docs/main.md +31 -0
- package/rules/image-compress/check/fix-check.mjs +74 -0
- package/rules/image-compress/check/main.mjs +64 -0
- package/rules/image-compress/docs/index.md +11 -0
- package/rules/image-compress/main.json +1 -0
- package/rules/image-compress/main.mdc +10 -0
- package/rules/image-compress/package_json/concern.json +9 -0
- package/rules/image-compress/package_json/package_json.mdc +13 -0
- package/rules/image-compress/package_json/package_json.rego +21 -0
- package/rules/image-compress/package_json/template/package.json.deny.json +8 -0
- package/rules/image-compress/package_setup/concern.json +4 -0
- package/rules/image-compress/package_setup/docs/main.md +34 -0
- package/rules/image-compress/package_setup/main.mjs +98 -0
- package/rules/image-compress/package_setup/package_setup.mdc +13 -0
- package/rules/js/check/concern.json +19 -0
- package/rules/js/check/docs/eslint-config.md +56 -0
- package/rules/js/check/docs/fix-check.md +31 -0
- package/rules/js/check/docs/index.md +13 -0
- package/rules/js/check/docs/main.md +45 -0
- package/rules/js/check/eslint-config.mjs +262 -0
- package/rules/js/check/fix-check.mjs +39 -0
- package/rules/js/check/main.mjs +312 -0
- package/rules/js/dep-policy/concern.json +4 -0
- package/rules/js/dep-policy/dep-policy.mdc +36 -0
- package/rules/js/dep-policy/docs/main.md +35 -0
- package/rules/js/dep-policy/main.mjs +99 -0
- package/rules/js/docs/index.md +11 -0
- package/rules/js/eslint/concern.json +7 -0
- package/rules/js/eslint/docs/fix-eslint.md +32 -0
- package/rules/js/eslint/docs/main.md +33 -0
- package/rules/js/eslint/fix-eslint.mjs +77 -0
- package/rules/js/eslint/main.mjs +99 -0
- package/rules/js/jscpd_config/concern.json +11 -0
- package/rules/js/jscpd_config/jscpd_config.mdc +14 -0
- package/rules/js/jscpd_config/jscpd_config.rego +44 -0
- package/rules/js/jscpd_config/template/.jscpd.json.snippet.json +7 -0
- package/rules/js/jscpd_duplicates/concern.json +7 -0
- package/rules/js/jscpd_duplicates/docs/main.md +29 -0
- package/rules/js/jscpd_duplicates/main.mjs +70 -0
- package/rules/js/knip/concern.json +6 -0
- package/rules/js/knip/docs/main.md +32 -0
- package/rules/js/knip/main.mjs +68 -0
- package/rules/js/lint-findings/concern.json +3 -0
- package/rules/js/lint-findings/docs/main.md +41 -0
- package/rules/js/lint-findings/main.mjs +125 -0
- package/rules/js/lint_js_yml/concern.json +9 -0
- package/rules/js/lint_js_yml/lint_js_yml.mdc +14 -0
- package/rules/js/lint_js_yml/lint_js_yml.rego +117 -0
- package/rules/js/lint_js_yml/template/lint-js.yml.snippet.yml +40 -0
- package/rules/js/main.json +1 -0
- package/rules/js/main.mdc +19 -0
- package/rules/js/package_json/concern.json +9 -0
- package/rules/js/package_json/package_json.mdc +15 -0
- package/rules/js/package_json/package_json.rego +142 -0
- package/rules/js/package_json/template/package.json.snippet.json +6 -0
- package/rules/js/tooling/concern.json +3 -0
- package/rules/js/tooling/data/tooling/knip-canonical.json +29 -0
- package/rules/js/tooling/data/tooling/oxlint-canonical.json +400 -0
- package/rules/js/tooling/docs/main.md +31 -0
- package/rules/js/tooling/main.mjs +149 -0
- package/rules/js/utils_imports/concern.json +4 -0
- package/rules/js/utils_imports/docs/main.md +50 -0
- package/rules/js/utils_imports/main.mjs +185 -0
- package/rules/js/vscode_extensions/concern.json +11 -0
- package/rules/js/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
- package/rules/js/vscode_extensions/docs/index.md +11 -0
- package/rules/js/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/js/vscode_extensions/template/extensions.json.snippet.json +3 -0
- package/rules/js/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/js/vscode_extensions/vscode_extensions.rego +12 -0
- package/rules/js-bun-db/docs/index.md +11 -0
- package/rules/js-bun-db/lib/bun-sql-scan.mjs +1055 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +63 -0
- package/rules/js-bun-db/lib/docs/index.md +11 -0
- package/rules/js-bun-db/main.json +1 -0
- package/rules/js-bun-db/main.mdc +8 -0
- package/rules/js-bun-db/package_json/concern.json +9 -0
- package/rules/js-bun-db/package_json/package_json.mdc +17 -0
- package/rules/js-bun-db/package_json/package_json.rego +15 -0
- package/rules/js-bun-db/package_json/template/package.json.deny.json +6 -0
- package/rules/js-bun-db/safety/concern.json +4 -0
- package/rules/js-bun-db/safety/docs/main.md +34 -0
- package/rules/js-bun-db/safety/main.mjs +430 -0
- package/rules/js-bun-redis/docs/index.md +11 -0
- package/rules/js-bun-redis/imports/concern.json +4 -0
- package/rules/js-bun-redis/imports/docs/main.md +36 -0
- package/rules/js-bun-redis/imports/imports.mdc +47 -0
- package/rules/js-bun-redis/imports/main.mjs +88 -0
- package/rules/js-bun-redis/lib/docs/index.md +11 -0
- package/rules/js-bun-redis/lib/docs/redis-imports.md +227 -0
- package/rules/js-bun-redis/lib/redis-imports.mjs +130 -0
- package/rules/js-bun-redis/main.json +1 -0
- package/rules/js-bun-redis/main.mdc +8 -0
- package/rules/js-bun-redis/package_json/concern.json +9 -0
- package/rules/js-bun-redis/package_json/package_json.mdc +11 -0
- package/rules/js-bun-redis/package_json/package_json.rego +15 -0
- package/rules/js-bun-redis/package_json/template/package.json.deny.json +12 -0
- package/rules/js-mssql/deps/concern.json +4 -0
- package/rules/js-mssql/deps/docs/main.md +33 -0
- package/rules/js-mssql/deps/main.mjs +297 -0
- package/rules/js-mssql/docs/index.md +11 -0
- package/rules/js-mssql/lib/docs/index.md +11 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +380 -0
- package/rules/js-mssql/lib/mssql-pool-scan.mjs +610 -0
- package/rules/js-mssql/main.json +1 -0
- package/rules/js-mssql/main.mdc +14 -0
- package/rules/js-mssql/package_json/concern.json +9 -0
- package/rules/js-mssql/package_json/package_json.mdc +9 -0
- package/rules/js-mssql/package_json/package_json.rego +57 -0
- package/rules/js-run/configmap/concern.json +9 -0
- package/rules/js-run/configmap/configmap.mdc +31 -0
- package/rules/js-run/configmap/configmap.rego +21 -0
- package/rules/js-run/configmap/template/configmap.yaml.contains.yml +4 -0
- package/rules/js-run/docs/index.md +11 -0
- package/rules/js-run/jsconfig/concern.json +9 -0
- package/rules/js-run/jsconfig/docs/fix-jsconfig.md +29 -0
- package/rules/js-run/jsconfig/docs/index.md +9 -0
- package/rules/js-run/jsconfig/fix-jsconfig.mjs +119 -0
- package/rules/js-run/jsconfig/jsconfig.mdc +25 -0
- package/rules/js-run/jsconfig/jsconfig.rego +59 -0
- package/rules/js-run/jsconfig/template/jsconfig.json.snippet.json +10 -0
- package/rules/js-run/lib/bunyan-imports.mjs +98 -0
- package/rules/js-run/lib/check-env-scan.mjs +338 -0
- package/rules/js-run/lib/conn-file-rules.mjs +214 -0
- package/rules/js-run/lib/conn-imports-scan.mjs +154 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +121 -0
- package/rules/js-run/lib/docs/check-env-scan.md +438 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +304 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +208 -0
- package/rules/js-run/lib/docs/index.md +16 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +334 -0
- package/rules/js-run/lib/docs/temporal-scan.md +29 -0
- package/rules/js-run/lib/promise-settimeout-scan.mjs +128 -0
- package/rules/js-run/lib/temporal-scan.mjs +52 -0
- package/rules/js-run/main.json +1 -0
- package/rules/js-run/main.mdc +16 -0
- package/rules/js-run/package_json/concern.json +9 -0
- package/rules/js-run/package_json/package_json.mdc +38 -0
- package/rules/js-run/package_json/package_json.rego +37 -0
- package/rules/js-run/package_json/template/package.json.deny.json +22 -0
- package/rules/js-run/runtime/concern.json +12 -0
- package/rules/js-run/runtime/docs/fix-runtime.md +27 -0
- package/rules/js-run/runtime/docs/main.md +35 -0
- package/rules/js-run/runtime/fix-runtime.mjs +46 -0
- package/rules/js-run/runtime/main.mjs +494 -0
- package/rules/js-run/runtime/runtime.mdc +14 -0
- package/rules/k8s/base_kustomization/base_kustomization.mdc +12 -0
- package/rules/k8s/base_kustomization/base_kustomization.rego +77 -0
- package/rules/k8s/base_kustomization/concern.json +8 -0
- package/rules/k8s/base_manifest/base_manifest.mdc +14 -0
- package/rules/k8s/base_manifest/base_manifest.rego +154 -0
- package/rules/k8s/base_manifest/concern.json +8 -0
- package/rules/k8s/docs/index.md +11 -0
- package/rules/k8s/gateway/concern.json +8 -0
- package/rules/k8s/gateway/gateway.mdc +31 -0
- package/rules/k8s/gateway/gateway.rego +151 -0
- package/rules/k8s/hasura_configmap/concern.json +8 -0
- package/rules/k8s/hasura_configmap/hasura_configmap.mdc +20 -0
- package/rules/k8s/hasura_configmap/hasura_configmap.rego +129 -0
- package/rules/k8s/hasura_httproute/concern.json +8 -0
- package/rules/k8s/hasura_httproute/hasura_httproute.mdc +16 -0
- package/rules/k8s/hasura_httproute/hasura_httproute.rego +298 -0
- package/rules/k8s/hpa_pdb/concern.json +8 -0
- package/rules/k8s/hpa_pdb/hpa_pdb.mdc +25 -0
- package/rules/k8s/hpa_pdb/hpa_pdb.rego +139 -0
- package/rules/k8s/kubeconform/concern.json +7 -0
- package/rules/k8s/kubeconform/docs/main.md +32 -0
- package/rules/k8s/kubeconform/main.mjs +39 -0
- package/rules/k8s/kustomization/concern.json +8 -0
- package/rules/k8s/kustomization/kustomization.mdc +20 -0
- package/rules/k8s/kustomization/kustomization.rego +220 -0
- package/rules/k8s/lint_k8s_yml/concern.json +9 -0
- package/rules/k8s/lint_k8s_yml/lint_k8s_yml.rego +57 -0
- package/rules/k8s/lint_k8s_yml/template/lint-k8s.yml.snippet.yml +43 -0
- package/rules/k8s/main.json +1 -0
- package/rules/k8s/main.mdc +22 -0
- package/rules/k8s/manifest/concern.json +8 -0
- package/rules/k8s/manifest/manifest.mdc +17 -0
- package/rules/k8s/manifest/manifest.rego +328 -0
- package/rules/k8s/manifests/concern.json +6 -0
- package/rules/k8s/manifests/docs/fix-manifests.md +47 -0
- package/rules/k8s/manifests/fix-manifests.mjs +217 -0
- package/rules/k8s/manifests/main.mjs +6838 -0
- package/rules/k8s/network_policy/concern.json +8 -0
- package/rules/k8s/network_policy/network_policy.mdc +22 -0
- package/rules/k8s/network_policy/network_policy.rego +151 -0
- package/rules/k8s/network_policy/template/deployment.snippet.yaml +61 -0
- package/rules/k8s/network_policy/template/stateful-set.snippet.yaml +69 -0
- package/rules/k8s/svc_hl_yaml/concern.json +8 -0
- package/rules/k8s/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
- package/rules/k8s/svc_hl_yaml/svc_hl_yaml.rego +51 -0
- package/rules/k8s/svc_yaml/concern.json +8 -0
- package/rules/k8s/svc_yaml/svc_yaml.mdc +12 -0
- package/rules/k8s/svc_yaml/svc_yaml.rego +31 -0
- package/rules/nginx-default-tpl/docs/index.md +11 -0
- package/rules/nginx-default-tpl/main.json +1 -0
- package/rules/nginx-default-tpl/main.mdc +8 -0
- package/rules/nginx-default-tpl/template/concern.json +17 -0
- package/rules/nginx-default-tpl/template/docs/fix-template.md +26 -0
- package/rules/nginx-default-tpl/template/docs/main.md +42 -0
- package/rules/nginx-default-tpl/template/fix-template.mjs +67 -0
- package/rules/nginx-default-tpl/template/main.mjs +505 -0
- package/rules/nginx-default-tpl/vscode_extensions/concern.json +9 -0
- package/rules/nginx-default-tpl/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/nginx-default-tpl/vscode_extensions/vscode_extensions.rego +16 -0
- package/rules/nginx-default-tpl/vscode_settings/concern.json +9 -0
- package/rules/nginx-default-tpl/vscode_settings/vscode_settings.mdc +15 -0
- package/rules/nginx-default-tpl/vscode_settings/vscode_settings.rego +36 -0
- package/rules/npm-module/docs/index.md +11 -0
- package/rules/npm-module/emit_types_config/concern.json +9 -0
- package/rules/npm-module/emit_types_config/emit_types_config.mdc +43 -0
- package/rules/npm-module/emit_types_config/emit_types_config.rego +28 -0
- package/rules/npm-module/emit_types_config/template/tsconfig.emit-types.json.snippet.json +9 -0
- package/rules/npm-module/header_doc_pointer/concern.json +5 -0
- package/rules/npm-module/header_doc_pointer/docs/main.md +40 -0
- package/rules/npm-module/header_doc_pointer/header_doc_pointer.mdc +18 -0
- package/rules/npm-module/header_doc_pointer/main.mjs +131 -0
- package/rules/npm-module/main.json +1 -0
- package/rules/npm-module/main.mdc +38 -0
- package/rules/npm-module/npm_package_json/concern.json +9 -0
- package/rules/npm-module/npm_package_json/npm_package_json.mdc +57 -0
- package/rules/npm-module/npm_package_json/npm_package_json.rego +73 -0
- package/rules/npm-module/npm_package_json/template/package.json.snippet.json +1 -0
- package/rules/npm-module/npm_publish_yml/concern.json +10 -0
- package/rules/npm-module/npm_publish_yml/template/npm-publish.yml.snippet.yml +49 -0
- package/rules/npm-module/package_structure/concern.json +5 -0
- package/rules/npm-module/package_structure/docs/main.md +37 -0
- package/rules/npm-module/package_structure/main.mjs +515 -0
- package/rules/npm-module/package_structure/package_structure.mdc +63 -0
- package/rules/npm-module/root_package_json/concern.json +9 -0
- package/rules/npm-module/root_package_json/root_package_json.mdc +41 -0
- package/rules/npm-module/root_package_json/root_package_json.rego +28 -0
- package/rules/npm-module/root_package_json/template/package.json.snippet.json +1 -0
- package/rules/npm-module/rule_meta/concern.json +8 -0
- package/rules/npm-module/rule_meta/docs/main.md +35 -0
- package/rules/npm-module/rule_meta/main.mjs +119 -0
- package/rules/npm-module/rule_meta/rule_meta.mdc +11 -0
- package/rules/npm-module/skill_meta/concern.json +5 -0
- package/rules/npm-module/skill_meta/docs/main.md +149 -0
- package/rules/npm-module/skill_meta/main.mjs +91 -0
- package/rules/npm-module/skill_meta/skill_meta.mdc +11 -0
- package/rules/php/cs_fixer/concern.json +7 -0
- package/rules/php/cs_fixer/docs/main.md +34 -0
- package/rules/php/cs_fixer/main.mjs +52 -0
- package/rules/php/docs/index.md +11 -0
- package/rules/php/lint_php_yml/concern.json +9 -0
- package/rules/php/lint_php_yml/lint_php_yml.mdc +23 -0
- package/rules/php/lint_php_yml/lint_php_yml.rego +34 -0
- package/rules/php/lint_php_yml/template/lint-php.yml.snippet.yml +47 -0
- package/rules/php/main.json +1 -0
- package/rules/php/main.mdc +8 -0
- package/rules/php/phpcs/concern.json +7 -0
- package/rules/php/phpcs/docs/main.md +31 -0
- package/rules/php/phpcs/main.mjs +71 -0
- package/rules/php/project/concern.json +6 -0
- package/rules/php/project/docs/main.md +36 -0
- package/rules/php/project/main.mjs +88 -0
- package/rules/php/tooling/concern.json +5 -0
- package/rules/php/tooling/docs/main.md +33 -0
- package/rules/php/tooling/main.mjs +35 -0
- package/rules/php/tooling/tooling.mdc +66 -0
- package/rules/python/applies/concern.json +4 -0
- package/rules/python/applies/docs/main.md +29 -0
- package/rules/python/applies/main.mjs +24 -0
- package/rules/python/docs/index.md +11 -0
- package/rules/python/lib/docs/index.md +9 -0
- package/rules/python/lib/docs/uv-run.md +32 -0
- package/rules/python/lib/uv-run.mjs +48 -0
- package/rules/python/lint_python_yml/concern.json +9 -0
- package/rules/python/lint_python_yml/lint_python_yml.mdc +12 -0
- package/rules/python/lint_python_yml/lint_python_yml.rego +68 -0
- package/rules/python/lint_python_yml/template/lint-python.yml.snippet.yml +41 -0
- package/rules/python/main.json +1 -0
- package/rules/python/main.mdc +8 -0
- package/rules/python/mypy/concern.json +7 -0
- package/rules/python/mypy/docs/main.md +32 -0
- package/rules/python/mypy/main.mjs +36 -0
- package/rules/python/project/concern.json +6 -0
- package/rules/python/project/docs/main.md +43 -0
- package/rules/python/project/main.mjs +115 -0
- package/rules/python/pyproject_toml/concern.json +9 -0
- package/rules/python/pyproject_toml/pyproject_toml.mdc +13 -0
- package/rules/python/pyproject_toml/pyproject_toml.rego +53 -0
- package/rules/python/pyproject_toml/template/pyproject.toml.deny.toml +2 -0
- package/rules/python/pyproject_toml/template/pyproject.toml.snippet.toml +12 -0
- package/rules/python/ruff/concern.json +7 -0
- package/rules/python/ruff/docs/fix-ruff.md +34 -0
- package/rules/python/ruff/docs/main.md +35 -0
- package/rules/python/ruff/fix-ruff.mjs +63 -0
- package/rules/python/ruff/main.mjs +52 -0
- package/rules/python/tooling/concern.json +15 -0
- package/rules/python/tooling/docs/index.md +11 -0
- package/rules/python/tooling/docs/main.md +35 -0
- package/rules/python/tooling/main.mjs +50 -0
- package/rules/python/tooling/tooling.mdc +23 -0
- package/rules/rego/conftest_verify/concern.json +6 -0
- package/rules/rego/conftest_verify/docs/main.md +31 -0
- package/rules/rego/conftest_verify/main.mjs +55 -0
- package/rules/rego/docs/index.md +11 -0
- package/rules/rego/lib/docs/index.md +9 -0
- package/rules/rego/lib/docs/run-external-tool.md +36 -0
- package/rules/rego/lib/run-external-tool.mjs +53 -0
- package/rules/rego/main.json +1 -0
- package/rules/rego/main.mdc +20 -0
- package/rules/rego/opa_check/concern.json +7 -0
- package/rules/rego/opa_check/docs/main.md +32 -0
- package/rules/rego/opa_check/main.mjs +34 -0
- package/rules/rego/package_json/concern.json +10 -0
- package/rules/rego/package_json/package_json.mdc +12 -0
- package/rules/rego/package_json/package_json.rego +21 -0
- package/rules/rego/regal/concern.json +7 -0
- package/rules/rego/regal/docs/index.md +11 -0
- package/rules/rego/regal/docs/main.md +32 -0
- package/rules/rego/regal/main.mjs +34 -0
- package/rules/rego/tooling/concern.json +5 -0
- package/rules/rego/tooling/docs/index.md +11 -0
- package/rules/rego/tooling/docs/main.md +31 -0
- package/rules/rego/tooling/main.mjs +25 -0
- package/rules/rego/tooling/tooling.mdc +14 -0
- package/rules/rego/vscode_extensions/concern.json +11 -0
- package/rules/rego/vscode_extensions/docs/fix-vscode_extensions.md +24 -0
- package/rules/rego/vscode_extensions/docs/index.md +11 -0
- package/rules/rego/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/rego/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/rego/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/rego/vscode_extensions/vscode_extensions.rego +15 -0
- package/rules/rego/vscode_settings/concern.json +11 -0
- package/rules/rego/vscode_settings/template/settings.json.snippet.json +6 -0
- package/rules/rego/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/rego/vscode_settings/vscode_settings.rego +30 -0
- package/rules/release/change.mjs +88 -0
- package/rules/release/docs/change.md +189 -0
- package/rules/release/docs/index.md +13 -0
- package/rules/release/docs/release.md +25 -0
- package/rules/release/lib/aggregate.mjs +82 -0
- package/rules/release/lib/change-file.mjs +116 -0
- package/rules/release/lib/docs/aggregate.md +250 -0
- package/rules/release/lib/docs/change-file.md +206 -0
- package/rules/release/lib/docs/fallback.md +207 -0
- package/rules/release/lib/docs/index.md +13 -0
- package/rules/release/lib/fallback.mjs +48 -0
- package/rules/release/main.json +1 -0
- package/rules/release/main.mdc +10 -0
- package/rules/release/release.mjs +220 -0
- package/rules/rust/applies/concern.json +4 -0
- package/rules/rust/applies/docs/index.md +11 -0
- package/rules/rust/applies/docs/main.md +30 -0
- package/rules/rust/applies/main.mjs +28 -0
- package/rules/rust/check/concern.json +7 -0
- package/rules/rust/check/docs/fix-check.md +30 -0
- package/rules/rust/check/docs/index.md +11 -0
- package/rules/rust/check/docs/main.md +37 -0
- package/rules/rust/check/fix-check.mjs +79 -0
- package/rules/rust/check/main.mjs +81 -0
- package/rules/rust/coverage/coverage.mdc +28 -0
- package/rules/rust/docs/index.md +11 -0
- package/rules/rust/lib/docs/has-cargo-toml.md +134 -0
- package/rules/rust/lib/docs/index.md +11 -0
- package/rules/rust/lib/has-cargo-toml.mjs +37 -0
- package/rules/rust/lint_rust_yml/concern.json +11 -0
- package/rules/rust/lint_rust_yml/lint_rust_yml.mdc +17 -0
- package/rules/rust/lint_rust_yml/lint_rust_yml.rego +79 -0
- package/rules/rust/lint_rust_yml/template/lint-rust.yml.snippet.yml +44 -0
- package/rules/rust/main.json +1 -0
- package/rules/rust/main.mdc +8 -0
- package/rules/rust/package_json/concern.json +10 -0
- package/rules/rust/package_json/package_json.mdc +12 -0
- package/rules/rust/package_json/package_json.rego +20 -0
- package/rules/rust/toolchain_cache/concern.json +5 -0
- package/rules/rust/toolchain_cache/docs/fix-toolchain_cache.md +35 -0
- package/rules/rust/toolchain_cache/docs/index.md +12 -0
- package/rules/rust/toolchain_cache/docs/main.md +57 -0
- package/rules/rust/toolchain_cache/fix-toolchain_cache.mjs +117 -0
- package/rules/rust/toolchain_cache/main.mjs +177 -0
- package/rules/rust/toolchain_cache/toolchain_cache.mdc +23 -0
- package/rules/rust/vscode_extensions/concern.json +11 -0
- package/rules/rust/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
- package/rules/rust/vscode_extensions/docs/index.md +11 -0
- package/rules/rust/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/rust/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/rust/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/rust/vscode_extensions/vscode_extensions.rego +15 -0
- package/rules/security/docs/index.md +11 -0
- package/rules/security/lint_security_yml/concern.json +11 -0
- package/rules/security/lint_security_yml/lint_security_yml.mdc +7 -0
- package/rules/security/lint_security_yml/lint_security_yml.rego +33 -0
- package/rules/security/lint_security_yml/template/lint-security.yml.snippet.yml +31 -0
- package/rules/security/main.json +1 -0
- package/rules/security/main.mdc +15 -0
- package/rules/security/package_json/concern.json +9 -0
- package/rules/security/package_json/package_json.mdc +7 -0
- package/rules/security/package_json/package_json.rego +19 -0
- package/rules/security/package_json/template/package.json.deny.json +4 -0
- package/rules/security/sample_secret/concern.json +11 -0
- package/rules/security/sample_secret/docs/index.md +11 -0
- package/rules/security/sample_secret/docs/main.md +29 -0
- package/rules/security/sample_secret/main.mjs +80 -0
- package/rules/security/sample_secret/sample_secret.mdc +20 -0
- package/rules/security/scan/concern.json +6 -0
- package/rules/security/scan/docs/index.md +11 -0
- package/rules/security/scan/docs/main.md +32 -0
- package/rules/security/scan/main.mjs +48 -0
- package/rules/security/todo.MD +27 -0
- package/rules/security/trufflehog/concern.json +4 -0
- package/rules/security/trufflehog/docs/index.md +11 -0
- package/rules/security/trufflehog/docs/main.md +28 -0
- package/rules/security/trufflehog/main.mjs +45 -0
- package/rules/security/trufflehog/templates/trufflehog/.trufflehog-exclude.snippet.txt +6 -0
- package/rules/security/trufflehog/trufflehog.mdc +21 -0
- package/rules/style/docs/index.md +11 -0
- package/rules/style/lint/concern.json +7 -0
- package/rules/style/lint/docs/fix-lint.md +29 -0
- package/rules/style/lint/docs/index.md +11 -0
- package/rules/style/lint/docs/main.md +29 -0
- package/rules/style/lint/fix-lint.mjs +66 -0
- package/rules/style/lint/main.mjs +68 -0
- package/rules/style/lint_style_yml/concern.json +9 -0
- package/rules/style/lint_style_yml/lint_style_yml.mdc +13 -0
- package/rules/style/lint_style_yml/lint_style_yml.rego +38 -0
- package/rules/style/lint_style_yml/template/lint-style.yml.snippet.yml +39 -0
- package/rules/style/main.json +1 -0
- package/rules/style/main.mdc +13 -0
- package/rules/style/package_json/concern.json +9 -0
- package/rules/style/package_json/package_json.mdc +18 -0
- package/rules/style/package_json/package_json.rego +31 -0
- package/rules/style/package_json/template/package.json.snippet.json +5 -0
- package/rules/style/tooling/concern.json +14 -0
- package/rules/style/tooling/docs/fix-tooling.md +29 -0
- package/rules/style/tooling/docs/index.md +12 -0
- package/rules/style/tooling/docs/main.md +34 -0
- package/rules/style/tooling/fix-tooling.mjs +58 -0
- package/rules/style/tooling/main.mjs +78 -0
- package/rules/style/tooling/tooling.mdc +85 -0
- package/rules/style/vscode_extensions/concern.json +9 -0
- package/rules/style/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
- package/rules/style/vscode_extensions/docs/index.md +11 -0
- package/rules/style/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/style/vscode_extensions/template/extensions.json.snippet.json +1 -0
- package/rules/style/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/style/vscode_extensions/vscode_extensions.rego +13 -0
- package/rules/style/vscode_settings/concern.json +9 -0
- package/rules/style/vscode_settings/template/settings.json.snippet.json +5 -0
- package/rules/style/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/style/vscode_settings/vscode_settings.rego +15 -0
- package/rules/tauri/cargo_mutants_config/cargo_mutants_config.mdc +39 -0
- package/rules/tauri/cargo_mutants_config/concern.json +5 -0
- package/rules/tauri/cargo_mutants_config/docs/fix-cargo_mutants_config.md +30 -0
- package/rules/tauri/cargo_mutants_config/docs/index.md +12 -0
- package/rules/tauri/cargo_mutants_config/docs/main.md +30 -0
- package/rules/tauri/cargo_mutants_config/fix-cargo_mutants_config.mjs +53 -0
- package/rules/tauri/cargo_mutants_config/main.mjs +148 -0
- package/rules/tauri/core_test_isolation/concern.json +5 -0
- package/rules/tauri/core_test_isolation/core_test_isolation.mdc +43 -0
- package/rules/tauri/core_test_isolation/docs/index.md +9 -0
- package/rules/tauri/core_test_isolation/docs/main.md +36 -0
- package/rules/tauri/core_test_isolation/main.mjs +166 -0
- package/rules/tauri/docs/index.md +11 -0
- package/rules/tauri/linux_deps/concern.json +8 -0
- package/rules/tauri/linux_deps/docs/fix-linux_deps.md +29 -0
- package/rules/tauri/linux_deps/docs/index.md +10 -0
- package/rules/tauri/linux_deps/docs/main.md +36 -0
- package/rules/tauri/linux_deps/fix-linux_deps.mjs +89 -0
- package/rules/tauri/linux_deps/linux_deps.mdc +18 -0
- package/rules/tauri/linux_deps/main.mjs +100 -0
- package/rules/tauri/main.json +1 -0
- package/rules/tauri/main.mdc +86 -0
- package/rules/tauri/release/concern.json +8 -0
- package/rules/tauri/release/docs/fix-release.md +28 -0
- package/rules/tauri/release/docs/index.md +10 -0
- package/rules/tauri/release/docs/main.md +32 -0
- package/rules/tauri/release/fix-release.mjs +353 -0
- package/rules/tauri/release/main.mjs +315 -0
- package/rules/tauri/release/release.mdc +104 -0
- package/rules/tauri/tooling/concern.json +8 -0
- package/rules/tauri/tooling/docs/index.md +11 -0
- package/rules/tauri/tooling/docs/main.md +34 -0
- package/rules/tauri/tooling/main.mjs +94 -0
- package/rules/tauri/tooling/tooling.mdc +27 -0
- package/rules/tauri/updater/concern.json +14 -0
- package/rules/tauri/updater/docs/fix-updater.md +33 -0
- package/rules/tauri/updater/docs/index.md +10 -0
- package/rules/tauri/updater/docs/main.md +32 -0
- package/rules/tauri/updater/fix-updater.mjs +322 -0
- package/rules/tauri/updater/main.mjs +403 -0
- package/rules/tauri/updater/updater.mdc +90 -0
- package/rules/tauri/vscode_extensions/concern.json +9 -0
- package/rules/tauri/vscode_extensions/docs/fix-vscode_extensions.md +25 -0
- package/rules/tauri/vscode_extensions/docs/index.md +11 -0
- package/rules/tauri/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/tauri/vscode_extensions/vscode_extensions.mdc +23 -0
- package/rules/tauri/vscode_extensions/vscode_extensions.rego +26 -0
- package/rules/test/cargo_mutants_config/cargo_mutants_config.mdc +18 -0
- package/rules/test/cargo_mutants_config/concern.json +8 -0
- package/rules/test/cargo_mutants_config/data/cargo_mutants_config/mutants.toml.baseline +7 -0
- package/rules/test/cargo_mutants_config/docs/fix-cargo_mutants_config.md +31 -0
- package/rules/test/cargo_mutants_config/docs/index.md +12 -0
- package/rules/test/cargo_mutants_config/docs/main.md +36 -0
- package/rules/test/cargo_mutants_config/fix-cargo_mutants_config.mjs +49 -0
- package/rules/test/cargo_mutants_config/main.mjs +62 -0
- package/rules/test/docs/index.md +11 -0
- package/rules/test/location/concern.json +8 -0
- package/rules/test/location/docs/index.md +11 -0
- package/rules/test/location/docs/main.md +36 -0
- package/rules/test/location/location.mdc +52 -0
- package/rules/test/location/main.mjs +70 -0
- package/rules/test/main.json +1 -0
- package/rules/test/main.mdc +26 -0
- package/rules/test/no-bun-test-import/concern.json +7 -0
- package/rules/test/no-bun-test-import/docs/fix-no-bun-test-import.md +31 -0
- package/rules/test/no-bun-test-import/docs/index.md +10 -0
- package/rules/test/no-bun-test-import/docs/main.md +36 -0
- package/rules/test/no-bun-test-import/fix-no-bun-test-import.mjs +51 -0
- package/rules/test/no-bun-test-import/main.mjs +105 -0
- package/rules/test/no-bun-test-import/no-bun-test-import.mdc +9 -0
- package/rules/test/no-console-store-restore/concern.json +7 -0
- package/rules/test/no-console-store-restore/docs/index.md +11 -0
- package/rules/test/no-console-store-restore/docs/main.md +44 -0
- package/rules/test/no-console-store-restore/main.mjs +88 -0
- package/rules/test/no-console-store-restore/no-console-store-restore.mdc +11 -0
- package/rules/test/no-process-chdir/concern.json +7 -0
- package/rules/test/no-process-chdir/docs/index.md +11 -0
- package/rules/test/no-process-chdir/docs/main.md +32 -0
- package/rules/test/no-process-chdir/main.mjs +40 -0
- package/rules/test/no-process-chdir/no-process-chdir.mdc +15 -0
- package/rules/test/no-relative-fs-path/concern.json +7 -0
- package/rules/test/no-relative-fs-path/docs/index.md +11 -0
- package/rules/test/no-relative-fs-path/docs/main.md +34 -0
- package/rules/test/no-relative-fs-path/main.mjs +239 -0
- package/rules/test/no-relative-fs-path/no-relative-fs-path.mdc +22 -0
- package/rules/test/package_json/concern.json +11 -0
- package/rules/test/package_json/package_json.mdc +18 -0
- package/rules/test/package_json/package_json.rego +25 -0
- package/rules/test/package_json/template/package.json.contains.json +6 -0
- package/rules/test/sandbox-aware-test/concern.json +7 -0
- package/rules/test/sandbox-aware-test/docs/index.md +11 -0
- package/rules/test/sandbox-aware-test/docs/main.md +55 -0
- package/rules/test/sandbox-aware-test/main.mjs +89 -0
- package/rules/test/sandbox-aware-test/sandbox-aware-test.mdc +28 -0
- package/rules/test/stryker_config/concern.json +8 -0
- package/rules/test/stryker_config/data/stryker_config/docs/index.md +13 -0
- package/rules/test/stryker_config/data/stryker_config/docs/stryker-vue-macros-ignorer.md +31 -0
- package/rules/test/stryker_config/data/stryker_config/docs/stryker.config.baseline.md +31 -0
- package/rules/test/stryker_config/data/stryker_config/docs/stryker.config.vue.baseline.md +35 -0
- package/rules/test/stryker_config/data/stryker_config/stryker-vue-macros-ignorer.mjs +48 -0
- package/rules/test/stryker_config/data/stryker_config/stryker.config.baseline.mjs +18 -0
- package/rules/test/stryker_config/data/stryker_config/stryker.config.vue.baseline.mjs +23 -0
- package/rules/test/stryker_config/data/vitest_config/docs/index.md +11 -0
- package/rules/test/stryker_config/data/vitest_config/docs/vitest.config.baseline.md +35 -0
- package/rules/test/stryker_config/data/vitest_config/vitest.config.baseline.js +22 -0
- package/rules/test/stryker_config/docs/fix-stryker_config.md +42 -0
- package/rules/test/stryker_config/docs/index.md +12 -0
- package/rules/test/stryker_config/docs/main.md +38 -0
- package/rules/test/stryker_config/fix-stryker_config.mjs +76 -0
- package/rules/test/stryker_config/main.mjs +504 -0
- package/rules/test/stryker_config/stryker_config.mdc +26 -0
- package/rules/test/vitest-config-pool-forks/concern.json +7 -0
- package/rules/test/vitest-config-pool-forks/docs/index.md +11 -0
- package/rules/test/vitest-config-pool-forks/docs/main.md +42 -0
- package/rules/test/vitest-config-pool-forks/main.mjs +41 -0
- package/rules/test/vitest-config-pool-forks/vitest-config-pool-forks.mdc +34 -0
- package/rules/text/cspell/concern.json +9 -0
- package/rules/text/cspell/cspell.mdc +41 -0
- package/rules/text/cspell/cspell.rego +71 -0
- package/rules/text/cspell/docs/fix-cspell.md +36 -0
- package/rules/text/cspell/docs/index.md +11 -0
- package/rules/text/cspell/fix-cspell.mjs +115 -0
- package/rules/text/cspell/template/.cspell.json.contains.json +3 -0
- package/rules/text/cspell/template/.cspell.json.deny.json +5 -0
- package/rules/text/cspell/template/.cspell.json.snippet.json +15 -0
- package/rules/text/cspell-fix/concern.json +7 -0
- package/rules/text/cspell-fix/docs/fix-worker.md +38 -0
- package/rules/text/cspell-fix/docs/index.md +12 -0
- package/rules/text/cspell-fix/docs/main.md +32 -0
- package/rules/text/cspell-fix/fix-worker.mjs +73 -0
- package/rules/text/cspell-fix/main.mjs +185 -0
- package/rules/text/docs/index.md +11 -0
- package/rules/text/forbidden-prettier/concern.json +7 -0
- package/rules/text/forbidden-prettier/docs/index.md +11 -0
- package/rules/text/forbidden-prettier/docs/main.md +38 -0
- package/rules/text/forbidden-prettier/forbidden-prettier.mdc +14 -0
- package/rules/text/forbidden-prettier/main.mjs +56 -0
- package/rules/text/formatting/concern.json +17 -0
- package/rules/text/formatting/docs/index.md +11 -0
- package/rules/text/formatting/docs/main.md +39 -0
- package/rules/text/formatting/main.mjs +149 -0
- package/rules/text/lint_text/concern.json +8 -0
- package/rules/text/lint_text/lint_text.mdc +19 -0
- package/rules/text/lint_text/lint_text.rego +104 -0
- package/rules/text/lint_text/template/lint-text.yml.snippet.yml +61 -0
- package/rules/text/main.json +1 -0
- package/rules/text/main.mdc +23 -0
- package/rules/text/markdownlint/concern.json +12 -0
- package/rules/text/markdownlint/docs/fix-markdownlint.md +38 -0
- package/rules/text/markdownlint/docs/index.md +12 -0
- package/rules/text/markdownlint/docs/main.md +40 -0
- package/rules/text/markdownlint/fix-markdownlint.mjs +64 -0
- package/rules/text/markdownlint/main.mjs +55 -0
- package/rules/text/markdownlint/markdownlint.mdc +40 -0
- package/rules/text/markdownlint/markdownlint.rego +57 -0
- package/rules/text/markdownlint/template/.markdownlint-cli2.jsonc.snippet.jsonc +11 -0
- package/rules/text/oxfmt/concern.json +7 -0
- package/rules/text/oxfmt/docs/fix-oxfmt.md +28 -0
- package/rules/text/oxfmt/docs/main.md +27 -0
- package/rules/text/oxfmt/fix-oxfmt.mjs +52 -0
- package/rules/text/oxfmt/main.mjs +48 -0
- package/rules/text/oxfmt/oxfmt.mdc +11 -0
- package/rules/text/oxfmtrc/concern.json +9 -0
- package/rules/text/oxfmtrc/oxfmtrc.mdc +11 -0
- package/rules/text/oxfmtrc/oxfmtrc.rego +55 -0
- package/rules/text/oxfmtrc/template/.oxfmtrc.json.snippet.json +8 -0
- package/rules/text/package_json/concern.json +9 -0
- package/rules/text/package_json/package_json.mdc +35 -0
- package/rules/text/package_json/package_json.rego +66 -0
- package/rules/text/package_json/template/package.json.deny.json +15 -0
- package/rules/text/run-dotenv-linter/concern.json +7 -0
- package/rules/text/run-dotenv-linter/docs/fix-run-dotenv-linter.md +43 -0
- package/rules/text/run-dotenv-linter/docs/index.md +12 -0
- package/rules/text/run-dotenv-linter/docs/main.md +35 -0
- package/rules/text/run-dotenv-linter/fix-run-dotenv-linter.mjs +64 -0
- package/rules/text/run-dotenv-linter/main.mjs +122 -0
- package/rules/text/run-shellcheck/concern.json +7 -0
- package/rules/text/run-shellcheck/docs/fix-run-shellcheck.md +40 -0
- package/rules/text/run-shellcheck/docs/index.md +12 -0
- package/rules/text/run-shellcheck/docs/main.md +31 -0
- package/rules/text/run-shellcheck/fix-run-shellcheck.mjs +44 -0
- package/rules/text/run-shellcheck/main.mjs +245 -0
- package/rules/text/run-v8r/concern.json +7 -0
- package/rules/text/run-v8r/docs/index.md +11 -0
- package/rules/text/run-v8r/docs/main.md +40 -0
- package/rules/text/run-v8r/main.mjs +266 -0
- package/rules/text/vscode_extensions/concern.json +9 -0
- package/rules/text/vscode_extensions/docs/fix-vscode_extensions.md +36 -0
- package/rules/text/vscode_extensions/docs/index.md +11 -0
- package/rules/text/vscode_extensions/fix-vscode_extensions.mjs +1 -0
- package/rules/text/vscode_extensions/template/extensions.json.snippet.json +3 -0
- package/rules/text/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/text/vscode_extensions/vscode_extensions.rego +12 -0
- package/rules/text/vscode_settings/concern.json +9 -0
- package/rules/text/vscode_settings/template/settings.json.snippet.json +9 -0
- package/rules/text/vscode_settings/vscode_settings.mdc +13 -0
- package/rules/text/vscode_settings/vscode_settings.rego +34 -0
- package/rules/tool-surface/docs/index.md +11 -0
- package/rules/tool-surface/main.json +6 -0
- package/rules/tool-surface/main.mdc +72 -0
- package/rules/vue/docs/index.md +11 -0
- package/rules/vue/lib/docs/index.md +11 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +265 -0
- package/rules/vue/lib/vue-forbidden-imports.mjs +264 -0
- package/rules/vue/main.json +1 -0
- package/rules/vue/main.mdc +18 -0
- package/rules/vue/package_json/concern.json +9 -0
- package/rules/vue/package_json/package_json.mdc +30 -0
- package/rules/vue/package_json/package_json.rego +140 -0
- package/rules/vue/packages/concern.json +6 -0
- package/rules/vue/packages/docs/index.md +11 -0
- package/rules/vue/packages/docs/main.md +35 -0
- package/rules/vue/packages/main.mjs +575 -0
- package/rules/worktree/docs/index.md +11 -0
- package/rules/worktree/main.json +1 -0
- package/rules/worktree/main.mdc +100 -0
- package/rules/worktree/vscode_settings/concern.json +10 -0
- package/rules/worktree/vscode_settings/template/settings.json.snippet.json +8 -0
- package/rules/worktree/zed_settings/concern.json +10 -0
- package/rules/worktree/zed_settings/template/settings.json.snippet.json +12 -0
- package/schemas/any.json +4 -0
- package/schemas/concern.json +108 -0
- package/schemas/layers-config.json +38 -0
- package/schemas/n-rules.json +65 -0
- package/schemas/rule-meta.json +39 -0
- package/schemas/skill-meta.json +30 -0
- package/schemas/target.json +63 -0
- package/schemas/v8r-catalog.json +179 -0
- package/schemas/vendor/bunfig.json +616 -0
- package/schemas/vendor/cargo-mutants-config.json +158 -0
- package/schemas/vendor/cargo.json +9438 -0
- package/schemas/vendor/claude-code-settings.json +2742 -0
- package/schemas/vendor/codex-hooks.json +148 -0
- package/schemas/vendor/cspell.json +2427 -0
- package/schemas/vendor/github-action.json +695 -0
- package/schemas/vendor/github-workflow.json +2193 -0
- package/schemas/vendor/jsconfig.json +1252 -0
- package/schemas/vendor/jscpd.json +405 -0
- package/schemas/vendor/knip.json +915 -0
- package/schemas/vendor/mcp.json +26 -0
- package/schemas/vendor/mt-config.json +85 -0
- package/schemas/vendor/oxfmtrc.json +810 -0
- package/schemas/vendor/oxlintrc.json +18690 -0
- package/schemas/vendor/package.json +23798 -0
- package/schemas/vendor/prettierrc.json +433 -0
- package/schemas/vendor/quikrun.json +195 -0
- package/schemas/vendor/schema-catalog.json +62 -0
- package/schemas/vendor/tsconfig.json +1535 -0
- package/schemas/vendor/zizmor.json +489 -0
- package/scripts/auto-rules.mjs +444 -0
- package/scripts/auto-skills.mjs +95 -0
- package/scripts/build-agents-commands.mjs +91 -0
- package/scripts/cli-entry.mjs +34 -0
- package/scripts/dispatcher/docs/index.md +11 -0
- package/scripts/docs/auto-rules.md +34 -0
- package/scripts/docs/auto-skills.md +30 -0
- package/scripts/docs/build-agents-commands.md +37 -0
- package/scripts/docs/cli-entry.md +36 -0
- package/scripts/docs/ensure-n-rules-dev-dependencies.md +40 -0
- package/scripts/docs/hook.md +30 -0
- package/scripts/docs/index.md +22 -0
- package/scripts/docs/post-tool-use-check.md +27 -0
- package/scripts/docs/rename-yaml-extensions.md +40 -0
- package/scripts/docs/skills-cli.md +35 -0
- package/scripts/docs/smoke-check-imports.md +31 -0
- package/scripts/docs/sync-claude-config.md +84 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +28 -0
- package/scripts/docs/update-blue-oak.md +28 -0
- package/scripts/docs/upgrade-n-rules-and-install.md +36 -0
- package/scripts/ensure-n-rules-dev-dependencies.mjs +217 -0
- package/scripts/hook.mjs +100 -0
- package/scripts/lib/adr/docs/index.md +12 -0
- package/scripts/lib/adr/docs/normalize-cli.md +36 -0
- package/scripts/lib/adr/docs/normalize-pipeline.md +45 -0
- package/scripts/lib/adr/normalize-cli.mjs +74 -0
- package/scripts/lib/adr/normalize-pipeline.mjs +701 -0
- package/scripts/lib/assert-project-root.mjs +77 -0
- package/scripts/lib/blue-oak.mjs +41 -0
- package/scripts/lib/changed-files.mjs +83 -0
- package/scripts/lib/check-reporter.mjs +27 -0
- package/scripts/lib/collect-test-files.mjs +48 -0
- package/scripts/lib/concern-meta.mjs +140 -0
- package/scripts/lib/diff-added-lines.mjs +86 -0
- package/scripts/lib/discover-check-rules-from-cursor.mjs +40 -0
- package/scripts/lib/discover-checkable-rules.mjs +49 -0
- package/scripts/lib/docs/assert-project-root.md +30 -0
- package/scripts/lib/docs/blue-oak.md +29 -0
- package/scripts/lib/docs/changed-files.md +32 -0
- package/scripts/lib/docs/check-reporter.md +179 -0
- package/scripts/lib/docs/collect-test-files.md +32 -0
- package/scripts/lib/docs/concern-meta.md +34 -0
- package/scripts/lib/docs/diff-added-lines.md +38 -0
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +29 -0
- package/scripts/lib/docs/discover-checkable-rules.md +25 -0
- package/scripts/lib/docs/ensure-tool.md +258 -0
- package/scripts/lib/docs/generated-markdown.md +279 -0
- package/scripts/lib/docs/gha-workflow.md +38 -0
- package/scripts/lib/docs/index.md +40 -0
- package/scripts/lib/docs/inline-template-links.md +25 -0
- package/scripts/lib/docs/list-project-rules-mdc.md +27 -0
- package/scripts/lib/docs/list-rule-ids.md +25 -0
- package/scripts/lib/docs/load-cursor-config.md +154 -0
- package/scripts/lib/docs/mirror-parity.md +32 -0
- package/scripts/lib/docs/read-n-rules-config-lite.md +26 -0
- package/scripts/lib/docs/resolve-target-files.md +38 -0
- package/scripts/lib/docs/root-notice.md +29 -0
- package/scripts/lib/docs/rule-meta-helpers.md +38 -0
- package/scripts/lib/docs/rule-meta.md +29 -0
- package/scripts/lib/docs/rule-predicates.md +31 -0
- package/scripts/lib/docs/run-conftest-batch.md +30 -0
- package/scripts/lib/docs/run-lint-step.md +29 -0
- package/scripts/lib/docs/run-standard-lint.md +43 -0
- package/scripts/lib/docs/skill-meta.md +62 -0
- package/scripts/lib/docs/sync-gitignore-worktree.md +26 -0
- package/scripts/lib/docs/template.md +44 -0
- package/scripts/lib/docs/timing-summary.md +25 -0
- package/scripts/lib/docs/workspaces.md +34 -0
- package/scripts/lib/docs/worktree-notice.md +27 -0
- package/scripts/lib/ensure-tool.mjs +352 -0
- package/scripts/lib/fix/docs/index.md +11 -0
- package/scripts/lib/fix/docs/vscode-ext-add.md +33 -0
- package/scripts/lib/fix/vscode-ext-add.mjs +53 -0
- package/scripts/lib/generated-markdown.mjs +71 -0
- package/scripts/lib/gha-workflow.mjs +220 -0
- package/scripts/lib/inline-template-links.mjs +108 -0
- package/scripts/lib/lint-surface/codegen-opa-wrapper.mjs +30 -0
- package/scripts/lib/lint-surface/collateral-veto.mjs +55 -0
- package/scripts/lib/lint-surface/default-worker.mjs +67 -0
- package/scripts/lib/lint-surface/detect.mjs +169 -0
- package/scripts/lib/lint-surface/docs/codegen-opa-wrapper.md +30 -0
- package/scripts/lib/lint-surface/docs/collateral-veto.md +28 -0
- package/scripts/lib/lint-surface/docs/default-worker.md +32 -0
- package/scripts/lib/lint-surface/docs/detect.md +38 -0
- package/scripts/lib/lint-surface/docs/index.md +27 -0
- package/scripts/lib/lint-surface/docs/ladder.md +33 -0
- package/scripts/lib/lint-surface/docs/lint-lock.md +47 -0
- package/scripts/lib/lint-surface/docs/mt-run-node.md +37 -0
- package/scripts/lib/lint-surface/docs/mt-tail.md +41 -0
- package/scripts/lib/lint-surface/docs/policy-lint-adapter.md +44 -0
- package/scripts/lib/lint-surface/docs/policy-test-step.md +43 -0
- package/scripts/lib/lint-surface/docs/progress.md +28 -0
- package/scripts/lib/lint-surface/docs/render.md +29 -0
- package/scripts/lib/lint-surface/docs/run-detectors.md +32 -0
- package/scripts/lib/lint-surface/docs/run-fix.md +33 -0
- package/scripts/lib/lint-surface/docs/snapshot.md +30 -0
- package/scripts/lib/lint-surface/docs/tier-sampling-bench.md +40 -0
- package/scripts/lib/lint-surface/docs/tier-sampling-experiment.md +35 -0
- package/scripts/lib/lint-surface/docs/types.md +27 -0
- package/scripts/lib/lint-surface/docs/violation-reporter.md +32 -0
- package/scripts/lib/lint-surface/ladder.mjs +92 -0
- package/scripts/lib/lint-surface/lint-lock.mjs +247 -0
- package/scripts/lib/lint-surface/mt-run-node.mjs +206 -0
- package/scripts/lib/lint-surface/mt-tail.mjs +0 -0
- package/scripts/lib/lint-surface/policy-lint-adapter.mjs +101 -0
- package/scripts/lib/lint-surface/policy-test-step.mjs +149 -0
- package/scripts/lib/lint-surface/progress.mjs +198 -0
- package/scripts/lib/lint-surface/render.mjs +50 -0
- package/scripts/lib/lint-surface/run-detectors.mjs +314 -0
- package/scripts/lib/lint-surface/run-fix.mjs +732 -0
- package/scripts/lib/lint-surface/snapshot.mjs +83 -0
- package/scripts/lib/lint-surface/tier-sampling-bench.mjs +457 -0
- package/scripts/lib/lint-surface/tier-sampling-experiment.mjs +289 -0
- package/scripts/lib/lint-surface/types.mjs +150 -0
- package/scripts/lib/lint-surface/violation-reporter.mjs +46 -0
- package/scripts/lib/list-project-rules-mdc.mjs +22 -0
- package/scripts/lib/list-rule-ids.mjs +32 -0
- package/scripts/lib/load-cursor-config.mjs +58 -0
- package/scripts/lib/mirror-parity.mjs +62 -0
- package/scripts/lib/read-n-rules-config-lite.mjs +63 -0
- package/scripts/lib/resolve-target-files.mjs +103 -0
- package/scripts/lib/root-notice.mjs +67 -0
- package/scripts/lib/rule-meta-helpers.mjs +103 -0
- package/scripts/lib/rule-meta.mjs +66 -0
- package/scripts/lib/rule-predicates.mjs +114 -0
- package/scripts/lib/run-conftest-batch.mjs +124 -0
- package/scripts/lib/run-lint-step.mjs +38 -0
- package/scripts/lib/run-standard-lint.mjs +50 -0
- package/scripts/lib/skill-meta.mjs +90 -0
- package/scripts/lib/sync-gitignore-worktree.mjs +27 -0
- package/scripts/lib/template.mjs +315 -0
- package/scripts/lib/timing-summary.mjs +63 -0
- package/scripts/lib/workspaces.mjs +109 -0
- package/scripts/lib/worktree-notice.mjs +183 -0
- package/scripts/post-tool-use-check.mjs +82 -0
- package/scripts/rename-yaml-extensions.mjs +170 -0
- package/scripts/skills-cli.mjs +262 -0
- package/scripts/smoke-check-imports.mjs +66 -0
- package/scripts/sync-claude-config.mjs +692 -0
- package/scripts/sync-setup-bun-deps-action.mjs +36 -0
- package/scripts/update-blue-oak.mjs +50 -0
- package/scripts/upgrade-n-rules-and-install.mjs +264 -0
- package/scripts/utils/apply-to-files.mjs +36 -0
- package/scripts/utils/ast-extract.mjs +149 -0
- package/scripts/utils/ast-scan-utils.mjs +206 -0
- package/scripts/utils/docs/apply-to-files.md +38 -0
- package/scripts/utils/docs/ast-extract.md +30 -0
- package/scripts/utils/docs/ast-scan-utils.md +54 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +32 -0
- package/scripts/utils/docs/find-package-json-paths.md +30 -0
- package/scripts/utils/docs/index.md +23 -0
- package/scripts/utils/docs/lock-cache-dir.md +29 -0
- package/scripts/utils/docs/pass.md +29 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +27 -0
- package/scripts/utils/docs/resolve-cmd.md +33 -0
- package/scripts/utils/docs/resolve-js-root.md +26 -0
- package/scripts/utils/docs/test-helpers.md +30 -0
- package/scripts/utils/docs/walk-cache.md +31 -0
- package/scripts/utils/docs/walkDir.md +31 -0
- package/scripts/utils/docs/with-lock.md +30 -0
- package/scripts/utils/docs/worktree-fingerprint.md +31 -0
- package/scripts/utils/ensure-gitignore-entries.mjs +30 -0
- package/scripts/utils/find-package-json-paths.mjs +30 -0
- package/scripts/utils/lock-cache-dir.mjs +37 -0
- package/scripts/utils/pass.mjs +9 -0
- package/scripts/utils/resolve-cargo-manifest.mjs +62 -0
- package/scripts/utils/resolve-cmd.mjs +25 -0
- package/scripts/utils/resolve-js-root.mjs +61 -0
- package/scripts/utils/walk-cache.mjs +24 -0
- package/scripts/utils/walkDir.mjs +55 -0
- package/scripts/utils/with-lock.mjs +190 -0
- package/scripts/utils/worktree-fingerprint.mjs +33 -0
- package/skills/adr-normalize/SKILL.md +73 -0
- package/skills/adr-normalize/main.json +1 -0
- package/skills/brainstorming/SKILL.md +165 -0
- package/skills/brainstorming/main.json +1 -0
- package/skills/doc-aggregate/SKILL.md +121 -0
- package/skills/doc-aggregate/js/docs/index.md +11 -0
- package/skills/doc-aggregate/main.json +1 -0
- package/skills/doc-files/.changes/260612-0002.md +6 -0
- package/skills/doc-files/.changes/260612-0006.md +6 -0
- package/skills/doc-files/.changes/260612-0008.md +6 -0
- package/skills/doc-files/.changes/260612-0012.md +6 -0
- package/skills/doc-files/.changes/260612-0031.md +6 -0
- package/skills/doc-files/.changes/260612-0036.md +6 -0
- package/skills/doc-files/.changes/260612-0114.md +6 -0
- package/skills/doc-files/SKILL.md +86 -0
- package/skills/doc-files/main.json +1 -0
- package/skills/lint/SKILL.md +121 -0
- package/skills/lint/main.json +1 -0
- package/skills/llm-patch/SKILL.md +260 -0
- package/skills/llm-patch/main.json +1 -0
- package/skills/publish-telegram/SKILL.md +93 -0
- package/skills/publish-telegram/main.json +1 -0
- package/skills/taze/SKILL.md +114 -0
- package/skills/taze/js/diff.mjs +140 -0
- package/skills/taze/js/docs/diff.md +55 -0
- package/skills/taze/js/docs/index.md +11 -0
- package/skills/taze/main.json +1 -0
- package/types/bin/n-rules.d.ts +2 -0
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Синхронізує конфігурацію Claude Code (`.claude/settings.json`,
|
|
3
|
+
* slash-команди з `commands/` темплейту, ADR Stop-hook) і Cursor hooks
|
|
4
|
+
* (`.cursor/hooks.json`) у поточний проєкт із темплейтів пакету
|
|
5
|
+
* `npm/.claude-template/`.
|
|
6
|
+
*
|
|
7
|
+
* Архітектура:
|
|
8
|
+
* - `settings.json` — **merge**: користувацькі поля зберігаються; наші hooks
|
|
9
|
+
* ідентифікуються командою-маркером (`MANAGED_HOOK_COMMAND_MARKERS`) і
|
|
10
|
+
* перезаписуються; permissions.allow зливається через union (із дедублікацією).
|
|
11
|
+
* - `.claude/commands/*.md` — fully owned slash-команди з темплейту
|
|
12
|
+
* `.claude-template/commands/` (зараз порожньо; sync no-op).
|
|
13
|
+
* - `.claude/hooks/capture-decisions.sh` — fully owned bash-скрипт ADR capture Stop-hook;
|
|
14
|
+
* копіюється з `.claude-template/hooks/`, лише коли в `.n-rules.json` `rules`
|
|
15
|
+
* присутнє `adr` (правило увімкнене за замовчуванням; вимикається через
|
|
16
|
+
* `disable-rules: ["adr"]`). Якщо правила немає, керована ADR-група в hooks
|
|
17
|
+
* так само автоматично прибирається з settings.json.
|
|
18
|
+
* - `.claude/hooks/normalize-decisions.sh` — fully owned bash-скрипт ADR normalize
|
|
19
|
+
* Stop-hook (батч-нормалізація чернеток); умови — ті самі, що для `capture`.
|
|
20
|
+
* - `.cursor/hooks.json` — **merge**: користувацькі hooks зберігаються; ADR stop
|
|
21
|
+
* entries додаються, коли правило `adr` увімкнене, і видаляються, коли вимкнене.
|
|
22
|
+
* - `.gitignore` — **merge** (лише з `adr`): дописує відсутні рядки з канонічного
|
|
23
|
+
* фрагмента `rules/adr/js/hooks/template/.gitignore.snippet` (`node_modules/`, `dist/`,
|
|
24
|
+
* `*.secret`, логи capture/normalize, `.normalize-state`, `.normalize.lock`,
|
|
25
|
+
* `.claude/scheduled_tasks.lock`); існуючі рядки не перезаписуються.
|
|
26
|
+
*
|
|
27
|
+
* Опт-аут — `claude-config: false` у `.n-rules.json`.
|
|
28
|
+
*/
|
|
29
|
+
import { existsSync } from 'node:fs'
|
|
30
|
+
import { chmod, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises'
|
|
31
|
+
import { join } from 'node:path'
|
|
32
|
+
|
|
33
|
+
/** Маркер hook-ів пакета (`hook --post-tool-use`, `hook --stop`). */
|
|
34
|
+
export const MANAGED_HOOK_COMMAND_MARKER = '@7n/rules hook'
|
|
35
|
+
/** @deprecated — маркер hook-ів до перейменування пакету на `@7n/rules`; лишається для cleanup наявних конфігів при ресинку. */
|
|
36
|
+
export const LEGACY_PACKAGE_HOOK_COMMAND_MARKER = '@nitra/cursor hook'
|
|
37
|
+
/** @deprecated — замінено на `hook --post-tool-use`; маркер лишається для cleanup наявних конфігів при ресинку. */
|
|
38
|
+
export const LEGACY_POST_TOOL_USE_HOOK_COMMAND_MARKER = '@nitra/cursor post-tool-use-check'
|
|
39
|
+
/** @deprecated — ще старіша мутуюча PostToolUse-команда (`post-tool-use-fix`); маркер лишається для cleanup наявних конфігів при ресинку. */
|
|
40
|
+
export const LEGACY_POST_TOOL_USE_FIX_HOOK_COMMAND_MARKER = '@nitra/cursor post-tool-use-fix'
|
|
41
|
+
/** @deprecated — doc-files hook перенесено до `hook --post-tool-use`; маркер лишається для cleanup наявних конфігів при ресинку. */
|
|
42
|
+
export const DOC_FILES_HOOK_COMMAND_MARKER = '@nitra/cursor lint-doc-files'
|
|
43
|
+
/** @deprecated — ще старіший legacy-маркер doc-files hook'ів (`doc-files check`) — cleanup при ресинку. */
|
|
44
|
+
export const LEGACY_DOC_FILES_HOOK_COMMAND_MARKER = '@nitra/cursor doc-files check'
|
|
45
|
+
/** Legacy-маркер старого Stop-hook'а — лишаємо для cleanup-у при оновленні існуючих інсталяцій. */
|
|
46
|
+
export const LEGACY_STOP_HOOK_COMMAND_MARKER = '@nitra/cursor stop-hook'
|
|
47
|
+
/** Маркер ADR Stop-hook'а — підрядок шляху до bash-скрипта capture-decisions. */
|
|
48
|
+
export const ADR_HOOK_COMMAND_MARKER = '.claude/hooks/capture-decisions.sh'
|
|
49
|
+
/** Маркер ADR Stop-hook'а — підрядок шляху до bash-скрипта normalize-decisions. */
|
|
50
|
+
export const ADR_NORMALIZE_HOOK_COMMAND_MARKER = '.claude/hooks/normalize-decisions.sh'
|
|
51
|
+
/** Маркер Cursor ADR Stop-hook'а — той самий script path, але в `.cursor/hooks.json`. */
|
|
52
|
+
export const CURSOR_ADR_HOOK_COMMAND_MARKER = '.claude/hooks/capture-decisions.sh'
|
|
53
|
+
/** Маркер Cursor ADR Normalize Stop-hook'а — той самий script path, але в `.cursor/hooks.json`. */
|
|
54
|
+
export const CURSOR_ADR_NORMALIZE_HOOK_COMMAND_MARKER = '.claude/hooks/normalize-decisions.sh'
|
|
55
|
+
/**
|
|
56
|
+
* Усі маркери managed-hook'ів пакета — за ними відрізняємо свої записи від користувацьких.
|
|
57
|
+
* Legacy stop-hook включений сюди, щоб старі entries автоматично видалялись при наступному sync-у.
|
|
58
|
+
*/
|
|
59
|
+
export const MANAGED_HOOK_COMMAND_MARKERS = Object.freeze([
|
|
60
|
+
MANAGED_HOOK_COMMAND_MARKER,
|
|
61
|
+
LEGACY_PACKAGE_HOOK_COMMAND_MARKER,
|
|
62
|
+
LEGACY_POST_TOOL_USE_HOOK_COMMAND_MARKER,
|
|
63
|
+
LEGACY_POST_TOOL_USE_FIX_HOOK_COMMAND_MARKER,
|
|
64
|
+
DOC_FILES_HOOK_COMMAND_MARKER,
|
|
65
|
+
LEGACY_DOC_FILES_HOOK_COMMAND_MARKER,
|
|
66
|
+
LEGACY_STOP_HOOK_COMMAND_MARKER,
|
|
67
|
+
ADR_HOOK_COMMAND_MARKER,
|
|
68
|
+
ADR_NORMALIZE_HOOK_COMMAND_MARKER
|
|
69
|
+
])
|
|
70
|
+
|
|
71
|
+
const CLAUDE_DIR = '.claude'
|
|
72
|
+
const CLAUDE_SETTINGS_FILE = `${CLAUDE_DIR}/settings.json`
|
|
73
|
+
const CLAUDE_COMMANDS_DIR = `${CLAUDE_DIR}/commands`
|
|
74
|
+
const CLAUDE_HOOKS_DIR = `${CLAUDE_DIR}/hooks`
|
|
75
|
+
const CURSOR_DIR = '.cursor'
|
|
76
|
+
const CURSOR_HOOKS_FILE = `${CURSOR_DIR}/hooks.json`
|
|
77
|
+
const ADR_HOOK_SCRIPT_NAME = 'capture-decisions.sh'
|
|
78
|
+
const ADR_NORMALIZE_HOOK_SCRIPT_NAME = 'normalize-decisions.sh'
|
|
79
|
+
const ADR_HOOK_LIB_DIR = 'lib'
|
|
80
|
+
const TEMPLATE_DIR_NAME = '.claude-template'
|
|
81
|
+
|
|
82
|
+
/** Корінь pi.dev артефактів у проєкті-споживачі. */
|
|
83
|
+
export const PI_DIR = '.pi'
|
|
84
|
+
/** Директорія pi.dev TS-extensions у проєкті-споживачі. */
|
|
85
|
+
export const PI_EXTENSIONS_DIR = `${PI_DIR}/extensions`
|
|
86
|
+
/** Назва bundled-директорії pi-template у пакеті `@7n/rules`. */
|
|
87
|
+
export const PI_TEMPLATE_DIR_NAME = '.pi-template'
|
|
88
|
+
/** Імʼя bundled pi-extension'а для ADR capture/normalize. */
|
|
89
|
+
export const PI_EXTENSION_NAME = 'n-rules-adr'
|
|
90
|
+
/** @deprecated — ім'я extension-теки до перейменування пакету; лишається для cleanup при ресинку. */
|
|
91
|
+
export const LEGACY_PI_EXTENSION_NAME = 'n-cursor-adr'
|
|
92
|
+
/** Відносний шлях до канонічного фрагмента `.gitignore` для ADR Stop-hook'ів у tarball пакета. */
|
|
93
|
+
export const ADR_GITIGNORE_SNIPPET_REL = 'rules/adr/js/templates/hooks/.gitignore.snippet'
|
|
94
|
+
const GITIGNORE_FILE = '.gitignore'
|
|
95
|
+
const EOL_RE = /\r?\n/u
|
|
96
|
+
|
|
97
|
+
/** Канонічна група hooks для ADR capture Stop-hook'а — додається в settings, коли `adr` у `rules`. */
|
|
98
|
+
const ADR_STOP_HOOK_GROUP = Object.freeze({
|
|
99
|
+
matcher: '',
|
|
100
|
+
hooks: Object.freeze([
|
|
101
|
+
Object.freeze({
|
|
102
|
+
type: 'command',
|
|
103
|
+
command: `bash "$CLAUDE_PROJECT_DIR/${ADR_HOOK_COMMAND_MARKER}"`,
|
|
104
|
+
async: true,
|
|
105
|
+
timeout: 180
|
|
106
|
+
})
|
|
107
|
+
])
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
/** Канонічна група hooks для ADR normalize Stop-hook'а — батч-нормалізація чернеток у `docs/adr/`. */
|
|
111
|
+
const ADR_NORMALIZE_STOP_HOOK_GROUP = Object.freeze({
|
|
112
|
+
matcher: '',
|
|
113
|
+
hooks: Object.freeze([
|
|
114
|
+
Object.freeze({
|
|
115
|
+
type: 'command',
|
|
116
|
+
command: `bash "$CLAUDE_PROJECT_DIR/${ADR_NORMALIZE_HOOK_COMMAND_MARKER}"`,
|
|
117
|
+
async: true,
|
|
118
|
+
timeout: 600
|
|
119
|
+
})
|
|
120
|
+
])
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
/** Канонічний Cursor stop-hook для ADR capture. Cursor передає payload через stdin JSON. */
|
|
124
|
+
const CURSOR_ADR_STOP_HOOK = Object.freeze({
|
|
125
|
+
command: [
|
|
126
|
+
'bash -lc \'root="$PWD";',
|
|
127
|
+
`if [ ! -f "$root/${CURSOR_ADR_HOOK_COMMAND_MARKER}" ] && [ -f "$root/../${CURSOR_ADR_HOOK_COMMAND_MARKER}" ]; then root="$root/.."; fi;`,
|
|
128
|
+
`bash "$root/${CURSOR_ADR_HOOK_COMMAND_MARKER}"'`
|
|
129
|
+
].join(' '),
|
|
130
|
+
timeout: 180
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
/** Канонічний Cursor stop-hook для ADR normalize. */
|
|
134
|
+
const CURSOR_ADR_NORMALIZE_STOP_HOOK = Object.freeze({
|
|
135
|
+
command: [
|
|
136
|
+
'bash -lc \'root="$PWD";',
|
|
137
|
+
`if [ ! -f "$root/${CURSOR_ADR_NORMALIZE_HOOK_COMMAND_MARKER}" ] && [ -f "$root/../${CURSOR_ADR_NORMALIZE_HOOK_COMMAND_MARKER}" ]; then root="$root/.."; fi;`,
|
|
138
|
+
`bash "$root/${CURSOR_ADR_NORMALIZE_HOOK_COMMAND_MARKER}"'`
|
|
139
|
+
].join(' '),
|
|
140
|
+
timeout: 600
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @typedef {object} HookEntry
|
|
145
|
+
* @property {string} type тип hook'а у форматі Claude Code (зазвичай `'command'`)
|
|
146
|
+
* @property {string} command команда, яку виконує Claude Code (наш маркер живе саме тут)
|
|
147
|
+
* @property {number} [timeout] опційний таймаут у секундах
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @typedef {object} HookGroup
|
|
152
|
+
* @property {string} [matcher] патерн (наприклад, `'.*'`) для звуження hook'а
|
|
153
|
+
* @property {HookEntry[]} hooks впорядкований список команд hook-групи
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @typedef {object} ClaudeSettings
|
|
158
|
+
* @property {{ allow?: string[] }} [permissions] секція `permissions` із .claude/settings.json
|
|
159
|
+
* @property {Record<string, HookGroup[]>} [hooks] hooks за подіями (`Stop`, `PreToolUse`, ...)
|
|
160
|
+
*/
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @typedef {object} CursorHookEntry
|
|
164
|
+
* @property {string} command команда, яку виконує Cursor hook
|
|
165
|
+
* @property {number} [timeout] опційний таймаут у секундах
|
|
166
|
+
*/
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @typedef {object} CursorHooksConfig
|
|
170
|
+
* @property {number} [version] версія Cursor hooks config
|
|
171
|
+
* @property {Record<string, CursorHookEntry[]>} [hooks] hooks за подіями (`stop`, `afterFileEdit`, ...)
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Чи hook-група містить лише наші managed-команди (за будь-яким із маркерів пакета).
|
|
176
|
+
* @param {HookGroup} group hook-група з .claude/settings.json
|
|
177
|
+
* @returns {boolean} `true`, якщо всі hooks мають маркер з `MANAGED_HOOK_COMMAND_MARKERS`
|
|
178
|
+
*/
|
|
179
|
+
function isManagedHookGroup(group) {
|
|
180
|
+
if (!group?.hooks?.length) {
|
|
181
|
+
return false
|
|
182
|
+
}
|
|
183
|
+
return group.hooks.every(
|
|
184
|
+
h => typeof h?.command === 'string' && MANAGED_HOOK_COMMAND_MARKERS.some(marker => h.command.includes(marker))
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Чи Cursor hook entry належить пакету `@7n/rules`.
|
|
190
|
+
* @param {CursorHookEntry} entry один entry з `.cursor/hooks.json`
|
|
191
|
+
* @returns {boolean} `true`, якщо command містить managed ADR marker
|
|
192
|
+
*/
|
|
193
|
+
function isManagedCursorHookEntry(entry) {
|
|
194
|
+
return (
|
|
195
|
+
typeof entry?.command === 'string' &&
|
|
196
|
+
[CURSOR_ADR_HOOK_COMMAND_MARKER, CURSOR_ADR_NORMALIZE_HOOK_COMMAND_MARKER].some(marker =>
|
|
197
|
+
entry.command.includes(marker)
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Зливає список allow-permissions: union існуючого і темплейтного без дублікатів,
|
|
204
|
+
* порядок — спочатку існуючі (щоб не міняти користувацький порядок), потім нові.
|
|
205
|
+
* @param {string[] | undefined} existing існуючий список з `.claude/settings.json` користувача
|
|
206
|
+
* @param {string[] | undefined} fromTemplate список з темплейту пакета `@7n/rules`
|
|
207
|
+
* @returns {string[]} об'єднаний список без дублікатів (порядок: існуючі, потім нові)
|
|
208
|
+
*/
|
|
209
|
+
export function mergeAllowList(existing, fromTemplate) {
|
|
210
|
+
const out = []
|
|
211
|
+
const seen = new Set()
|
|
212
|
+
for (const arr of [existing ?? [], fromTemplate ?? []]) {
|
|
213
|
+
for (const item of arr) {
|
|
214
|
+
if (typeof item !== 'string' || seen.has(item)) {
|
|
215
|
+
continue
|
|
216
|
+
}
|
|
217
|
+
seen.add(item)
|
|
218
|
+
out.push(item)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return out
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Зливає hooks-секцію. Для **кожної події** з обох сторін:
|
|
226
|
+
* 1) видаляємо managed-групи з існуючої конфігурації (їх ідентифікують маркери з
|
|
227
|
+
* `MANAGED_HOOK_COMMAND_MARKERS`, включно з legacy-маркерами — це автоматично
|
|
228
|
+
* прибирає застарілі hook'и при переході на нову версію темплейту);
|
|
229
|
+
* 2) дописуємо managed-групи з темплейту.
|
|
230
|
+
* Перебір union-у подій важливий: коли пакет переносить hook між подіями (напр. `Stop`
|
|
231
|
+
* → `PostToolUse`), старі managed entries у вже-непотрібній події теж мають піти.
|
|
232
|
+
* @param {Record<string, HookGroup[]> | undefined} existing поточна `hooks`-секція з .claude/settings.json
|
|
233
|
+
* @param {Record<string, HookGroup[]> | undefined} fromTemplate цільова `hooks`-секція з темплейту
|
|
234
|
+
* @returns {Record<string, HookGroup[]>} результат злиття (порожні події видаляються)
|
|
235
|
+
*/
|
|
236
|
+
export function mergeHooks(existing, fromTemplate) {
|
|
237
|
+
/** @type {Record<string, HookGroup[]>} */
|
|
238
|
+
const out = {}
|
|
239
|
+
const allEvents = new Set([...Object.keys(existing ?? {}), ...Object.keys(fromTemplate ?? {})])
|
|
240
|
+
for (const event of allEvents) {
|
|
241
|
+
const existingClean = (existing?.[event] ?? []).filter(g => !isManagedHookGroup(g))
|
|
242
|
+
const templateGroups = fromTemplate?.[event] ?? []
|
|
243
|
+
const combined = [...existingClean, ...templateGroups]
|
|
244
|
+
if (combined.length > 0) {
|
|
245
|
+
out[event] = combined
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return out
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Будує копію темплейту із додатковою ADR Stop hook-групою у `Stop`.
|
|
253
|
+
* Темплейт залишається незмінним; повертається новий об'єкт з доданою групою.
|
|
254
|
+
* @param {ClaudeSettings} template вихідний темплейт із `.claude-template/settings.template.json`
|
|
255
|
+
* @returns {ClaudeSettings} копія з доданою ADR-групою у `hooks.Stop`
|
|
256
|
+
*/
|
|
257
|
+
function templateWithAdrHook(template) {
|
|
258
|
+
/** @type {Record<string, HookGroup[]>} */
|
|
259
|
+
const hooks = {}
|
|
260
|
+
for (const [event, groups] of Object.entries(template.hooks ?? {})) {
|
|
261
|
+
hooks[event] = Array.isArray(groups) ? [...groups] : []
|
|
262
|
+
}
|
|
263
|
+
hooks.Stop = [
|
|
264
|
+
...(hooks.Stop ?? []),
|
|
265
|
+
/** @type {HookGroup} */ (ADR_STOP_HOOK_GROUP),
|
|
266
|
+
/** @type {HookGroup} */ (ADR_NORMALIZE_STOP_HOOK_GROUP)
|
|
267
|
+
]
|
|
268
|
+
return { ...template, hooks }
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Повертає об'єднаний об'єкт settings.json.
|
|
273
|
+
* @param {ClaudeSettings | undefined} existing існуючий вміст `.claude/settings.json` користувача (або undefined, якщо файла нема)
|
|
274
|
+
* @param {ClaudeSettings} template settings із темплейту пакета `@7n/rules`
|
|
275
|
+
* @param {object} [options] опції merge-у
|
|
276
|
+
* @param {boolean} [options.includeAdrHook] чи додати ADR Stop-hook групу до managed-hooks (коли в `.n-rules.json` `rules` присутнє `adr`)
|
|
277
|
+
* @returns {ClaudeSettings} результат merge-у (користувацькі поля збережено, наші перевизначено)
|
|
278
|
+
*/
|
|
279
|
+
export function mergeSettings(existing, template, options = {}) {
|
|
280
|
+
const effectiveTemplate = options.includeAdrHook ? templateWithAdrHook(template) : template
|
|
281
|
+
/** @type {ClaudeSettings} */
|
|
282
|
+
const merged = { ...existing }
|
|
283
|
+
const mergedAllow = mergeAllowList(existing?.permissions?.allow, effectiveTemplate.permissions?.allow)
|
|
284
|
+
if (mergedAllow.length > 0) {
|
|
285
|
+
merged.permissions = { ...existing?.permissions, allow: mergedAllow }
|
|
286
|
+
}
|
|
287
|
+
const mergedHooks = mergeHooks(existing?.hooks, effectiveTemplate.hooks)
|
|
288
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
289
|
+
merged.hooks = mergedHooks
|
|
290
|
+
} else {
|
|
291
|
+
delete merged.hooks
|
|
292
|
+
}
|
|
293
|
+
return merged
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Зливає `.cursor/hooks.json`: користувацькі entries зберігаються, managed ADR
|
|
298
|
+
* entries у `hooks.stop` перезаписуються або видаляються залежно від `includeAdrHook`.
|
|
299
|
+
* @param {CursorHooksConfig | undefined} existing поточний Cursor hooks config
|
|
300
|
+
* @param {object} [options] опції merge-у
|
|
301
|
+
* @param {boolean} [options.includeAdrHook] чи додати ADR stop entries
|
|
302
|
+
* @returns {CursorHooksConfig} результат злиття
|
|
303
|
+
*/
|
|
304
|
+
export function mergeCursorHooksConfig(existing, options = {}) {
|
|
305
|
+
/** @type {CursorHooksConfig} */
|
|
306
|
+
const merged = { ...existing }
|
|
307
|
+
/** @type {Record<string, CursorHookEntry[]>} */
|
|
308
|
+
const hooks = {}
|
|
309
|
+
for (const [event, entries] of Object.entries(existing?.hooks ?? {})) {
|
|
310
|
+
hooks[event] = Array.isArray(entries) ? [...entries] : []
|
|
311
|
+
}
|
|
312
|
+
const stop = (hooks.stop ?? []).filter(entry => !isManagedCursorHookEntry(entry))
|
|
313
|
+
if (options.includeAdrHook) {
|
|
314
|
+
stop.push(
|
|
315
|
+
/** @type {CursorHookEntry} */ (CURSOR_ADR_STOP_HOOK),
|
|
316
|
+
/** @type {CursorHookEntry} */ (CURSOR_ADR_NORMALIZE_STOP_HOOK)
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
if (stop.length > 0) {
|
|
320
|
+
hooks.stop = stop
|
|
321
|
+
} else {
|
|
322
|
+
delete hooks.stop
|
|
323
|
+
}
|
|
324
|
+
merged.version = typeof merged.version === 'number' ? merged.version : 1
|
|
325
|
+
if (Object.keys(hooks).length > 0) {
|
|
326
|
+
merged.hooks = hooks
|
|
327
|
+
} else {
|
|
328
|
+
delete merged.hooks
|
|
329
|
+
}
|
|
330
|
+
return merged
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Читає JSON-файл; якщо файл відсутній або не валідний — повертає `undefined`.
|
|
335
|
+
* @param {string} path абсолютний шлях до JSON-файлу
|
|
336
|
+
* @returns {Promise<ClaudeSettings | undefined>} розпарсений об'єкт або `undefined` (файл відсутній / невалідний)
|
|
337
|
+
*/
|
|
338
|
+
async function readJsonOrUndefined(path) {
|
|
339
|
+
if (!existsSync(path)) {
|
|
340
|
+
return
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
return JSON.parse(await readFile(path, 'utf8'))
|
|
344
|
+
} catch {
|
|
345
|
+
return
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Синхронізує `.cursor/hooks.json` для Cursor Agent stop-hooks. Cursor читає
|
|
351
|
+
* project-level config з `.cursor/hooks.json`; hook scripts лишаються спільними
|
|
352
|
+
* з Claude Code у `.claude/hooks/`.
|
|
353
|
+
* @param {string} projectRoot корінь проєкту, куди писати
|
|
354
|
+
* @param {object} [options] опції merge-у
|
|
355
|
+
* @param {boolean} [options.includeAdrHook] чи додавати ADR stop-hook entries
|
|
356
|
+
* @returns {Promise<{ written: boolean, path: string }>} результат: чи писали файл, та його відносний шлях
|
|
357
|
+
*/
|
|
358
|
+
export async function syncCursorHooksConfig(projectRoot, options = {}) {
|
|
359
|
+
const hooksPath = join(projectRoot, CURSOR_HOOKS_FILE)
|
|
360
|
+
if (!options.includeAdrHook && !existsSync(hooksPath)) {
|
|
361
|
+
return { written: false, path: '' }
|
|
362
|
+
}
|
|
363
|
+
const existing = /** @type {CursorHooksConfig | undefined} */ (await readJsonOrUndefined(hooksPath))
|
|
364
|
+
const merged = mergeCursorHooksConfig(existing, options)
|
|
365
|
+
await mkdir(join(projectRoot, CURSOR_DIR), { recursive: true })
|
|
366
|
+
await writeFile(hooksPath, `${JSON.stringify(merged, null, 2)}\n`, 'utf8')
|
|
367
|
+
return { written: true, path: CURSOR_HOOKS_FILE }
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Синхронізує `.claude/settings.json` за темплейтом, зберігаючи решту
|
|
372
|
+
* користувацьких полів.
|
|
373
|
+
* @param {string} projectRoot корінь проєкту, куди писати
|
|
374
|
+
* @param {string} templateDir каталог `.claude-template/` усередині пакету
|
|
375
|
+
* @param {object} [options] опції merge-у
|
|
376
|
+
* @param {boolean} [options.includeAdrHook] чи додавати ADR Stop-hook (правило `adr` увімкнене у `rules`)
|
|
377
|
+
* @returns {Promise<{ written: boolean, path: string }>} результат: чи писали файл, та його відносний шлях
|
|
378
|
+
*/
|
|
379
|
+
export async function syncClaudeSettings(projectRoot, templateDir, options = {}) {
|
|
380
|
+
const templatePath = join(templateDir, 'settings.template.json')
|
|
381
|
+
if (!existsSync(templatePath)) {
|
|
382
|
+
return { written: false, path: '' }
|
|
383
|
+
}
|
|
384
|
+
const template = /** @type {ClaudeSettings} */ (JSON.parse(await readFile(templatePath, 'utf8')))
|
|
385
|
+
const settingsPath = join(projectRoot, CLAUDE_SETTINGS_FILE)
|
|
386
|
+
const existing = await readJsonOrUndefined(settingsPath)
|
|
387
|
+
const merged = mergeSettings(existing, template, options)
|
|
388
|
+
await mkdir(join(projectRoot, CLAUDE_DIR), { recursive: true })
|
|
389
|
+
await writeFile(settingsPath, `${JSON.stringify(merged, null, 2)}\n`, 'utf8')
|
|
390
|
+
return { written: true, path: CLAUDE_SETTINGS_FILE }
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Копіює один канонічний bash-скрипт hook'а з темплейту пакета у `.claude/hooks/`.
|
|
395
|
+
* Файл повністю керується пакетом — на кожен sync перезаписується (як setup-bun-deps).
|
|
396
|
+
* @param {string} projectRoot корінь проєкту, куди писати
|
|
397
|
+
* @param {string} templateDir каталог `.claude-template/` усередині пакету
|
|
398
|
+
* @param {string} scriptName базове ім'я скрипта (наприклад `capture-decisions.sh`)
|
|
399
|
+
* @returns {Promise<{ written: boolean, path: string }>} результат: чи писали файл, та його відносний шлях
|
|
400
|
+
*/
|
|
401
|
+
async function syncHookScript(projectRoot, templateDir, scriptName) {
|
|
402
|
+
const templatePath = join(templateDir, 'hooks', scriptName)
|
|
403
|
+
if (!existsSync(templatePath)) {
|
|
404
|
+
return { written: false, path: '' }
|
|
405
|
+
}
|
|
406
|
+
const content = await readFile(templatePath, 'utf8')
|
|
407
|
+
const hooksDir = join(projectRoot, CLAUDE_HOOKS_DIR)
|
|
408
|
+
await mkdir(hooksDir, { recursive: true })
|
|
409
|
+
const destPath = join(hooksDir, scriptName)
|
|
410
|
+
await writeFile(destPath, content, 'utf8')
|
|
411
|
+
await chmod(destPath, 0o755)
|
|
412
|
+
return { written: true, path: `${CLAUDE_HOOKS_DIR}/${scriptName}` }
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Копіює канонічний `.claude/hooks/capture-decisions.sh` з темплейту пакета.
|
|
417
|
+
* @param {string} projectRoot корінь проєкту, куди писати
|
|
418
|
+
* @param {string} templateDir каталог `.claude-template/` усередині пакету
|
|
419
|
+
* @returns {Promise<{ written: boolean, path: string }>} результат: чи писали файл, та його відносний шлях
|
|
420
|
+
*/
|
|
421
|
+
export function syncAdrHookScript(projectRoot, templateDir) {
|
|
422
|
+
return syncHookScript(projectRoot, templateDir, ADR_HOOK_SCRIPT_NAME)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Копіює канонічний `.claude/hooks/normalize-decisions.sh` з темплейту пакета.
|
|
427
|
+
* @param {string} projectRoot корінь проєкту, куди писати
|
|
428
|
+
* @param {string} templateDir каталог `.claude-template/` усередині пакету
|
|
429
|
+
* @returns {Promise<{ written: boolean, path: string }>} результат: чи писали файл, та його відносний шлях
|
|
430
|
+
*/
|
|
431
|
+
export function syncAdrNormalizeHookScript(projectRoot, templateDir) {
|
|
432
|
+
return syncHookScript(projectRoot, templateDir, ADR_NORMALIZE_HOOK_SCRIPT_NAME)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Копіює всі `.sh`-файли з `.claude-template/hooks/lib/` у `.claude/hooks/lib/` проєкту.
|
|
437
|
+
* Файли source-only (без exec bit) — їх `source`-ять capture/normalize-decisions.sh,
|
|
438
|
+
* щоб не дублювати спільну bash-логіку (`is_tooling_only_change`,
|
|
439
|
+
* `git_diff_only_version_field`).
|
|
440
|
+
* Тека fully-owned: при кожному sync-у перезаписується.
|
|
441
|
+
* @param {string} projectRoot корінь проєкту-споживача
|
|
442
|
+
* @param {string} templateDir каталог `.claude-template/` усередині пакету
|
|
443
|
+
* @returns {Promise<Array<{ written: boolean, path: string }>>} перелік записаних файлів (порожній, якщо темплейту нема)
|
|
444
|
+
*/
|
|
445
|
+
export async function syncAdrHookLibScripts(projectRoot, templateDir) {
|
|
446
|
+
const libTemplateDir = join(templateDir, 'hooks', ADR_HOOK_LIB_DIR)
|
|
447
|
+
if (!existsSync(libTemplateDir)) {
|
|
448
|
+
return []
|
|
449
|
+
}
|
|
450
|
+
const entries = await readdir(libTemplateDir, { withFileTypes: true })
|
|
451
|
+
const libDestDir = join(projectRoot, CLAUDE_HOOKS_DIR, ADR_HOOK_LIB_DIR)
|
|
452
|
+
await mkdir(libDestDir, { recursive: true })
|
|
453
|
+
const written = []
|
|
454
|
+
for (const entry of entries) {
|
|
455
|
+
if (!entry.isFile() || !entry.name.endsWith('.sh')) continue
|
|
456
|
+
const content = await readFile(join(libTemplateDir, entry.name), 'utf8')
|
|
457
|
+
// НЕ chmod 755 — source-файли не виконувані (їх лише `.`-ять caller-скрипти).
|
|
458
|
+
await writeFile(join(libDestDir, entry.name), content, 'utf8')
|
|
459
|
+
written.push({ written: true, path: `${CLAUDE_HOOKS_DIR}/${ADR_HOOK_LIB_DIR}/${entry.name}` })
|
|
460
|
+
}
|
|
461
|
+
return written
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Видаляє `.claude/hooks/lib/` директорію з проєкту-споживача.
|
|
466
|
+
* Викликається коли правило `adr` вимкнено — lib-файли не самостійні, без хуків,
|
|
467
|
+
* що їх source-ять, вони нікому не потрібні (симетрично до `removeOrphanPiExtension`).
|
|
468
|
+
* @param {string} projectRoot корінь проєкту-споживача
|
|
469
|
+
* @returns {Promise<{ removed: boolean, path: string }>} чи було щось видалено та відносний шлях
|
|
470
|
+
*/
|
|
471
|
+
export async function removeOrphanAdrHookLib(projectRoot) {
|
|
472
|
+
const libDir = join(projectRoot, CLAUDE_HOOKS_DIR, ADR_HOOK_LIB_DIR)
|
|
473
|
+
if (!existsSync(libDir)) {
|
|
474
|
+
return { removed: false, path: '' }
|
|
475
|
+
}
|
|
476
|
+
await rm(libDir, { recursive: true, force: true })
|
|
477
|
+
return { removed: true, path: `${CLAUDE_HOOKS_DIR}/${ADR_HOOK_LIB_DIR}` }
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Копіює bundled pi.dev TS-extension `npm/.pi-template/extensions/n-rules-adr/` (усі файли —
|
|
482
|
+
* `index.ts`, `tsconfig.json`, потенційні `package.json`/`.gitignore` тощо) у
|
|
483
|
+
* `.pi/extensions/n-rules-adr/` проєкту-споживача (legacy `n-cursor-adr/` видаляється). Тека fully-owned: при кожному sync-у
|
|
484
|
+
* перезаписується. Якщо bundled template відсутній (legacy-версії пакета без `.pi-template/`)
|
|
485
|
+
* або в ньому немає `index.ts` — повертаємо `{written: false}` без помилки.
|
|
486
|
+
*
|
|
487
|
+
* Розширення поверх `index.ts` (tsconfig тощо) потрібні, бо `.pi/extensions/` синхронізується як є
|
|
488
|
+
* у проєкти-споживачі, а IDE/TS-сервер мусить резолвити `node:*` модулі без додаткових
|
|
489
|
+
* project-wide конфігів.
|
|
490
|
+
* @param {string} projectRoot корінь проєкту-споживача
|
|
491
|
+
* @param {string} bundledPackageRoot корінь установленого `@7n/rules` (із `.pi-template/`)
|
|
492
|
+
* @returns {Promise<{ written: boolean, path: string, files: string[] }>} чи писали; відносний шлях до теки розширення; список скопійованих базових імен (відсортований)
|
|
493
|
+
*/
|
|
494
|
+
export async function syncPiExtensions(projectRoot, bundledPackageRoot) {
|
|
495
|
+
const srcDir = join(bundledPackageRoot, PI_TEMPLATE_DIR_NAME, 'extensions', PI_EXTENSION_NAME)
|
|
496
|
+
const indexPath = join(srcDir, 'index.ts')
|
|
497
|
+
if (!existsSync(indexPath)) {
|
|
498
|
+
return { written: false, path: '', files: [] }
|
|
499
|
+
}
|
|
500
|
+
const legacyDir = join(projectRoot, PI_EXTENSIONS_DIR, LEGACY_PI_EXTENSION_NAME)
|
|
501
|
+
if (existsSync(legacyDir)) {
|
|
502
|
+
await rm(legacyDir, { recursive: true, force: true })
|
|
503
|
+
}
|
|
504
|
+
const destDir = join(projectRoot, PI_EXTENSIONS_DIR, PI_EXTENSION_NAME)
|
|
505
|
+
await mkdir(destDir, { recursive: true })
|
|
506
|
+
const entries = await readdir(srcDir, { withFileTypes: true })
|
|
507
|
+
const copied = []
|
|
508
|
+
for (const entry of entries) {
|
|
509
|
+
if (!entry.isFile()) continue
|
|
510
|
+
const name = entry.name
|
|
511
|
+
const content = await readFile(join(srcDir, name), 'utf8')
|
|
512
|
+
await writeFile(join(destDir, name), content, 'utf8')
|
|
513
|
+
copied.push(name)
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
written: true,
|
|
517
|
+
path: `${PI_EXTENSIONS_DIR}/${PI_EXTENSION_NAME}`,
|
|
518
|
+
files: copied.toSorted((a, b) => a.localeCompare(b))
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Видаляє `.pi/extensions/n-rules-adr/` (і legacy `n-cursor-adr/`) директорію з проєкту-споживача.
|
|
524
|
+
* Викликається коли правило `adr` вимкнено у `.n-rules.json` (симетрично до
|
|
525
|
+
* cleanup-у `.claude/hooks/{capture,normalize}-decisions.sh`).
|
|
526
|
+
* @param {string} projectRoot корінь проєкту-споживача
|
|
527
|
+
* @returns {Promise<{ removed: boolean, path: string }>} чи було щось видалено та відносний шлях
|
|
528
|
+
*/
|
|
529
|
+
export async function removeOrphanPiExtension(projectRoot) {
|
|
530
|
+
const legacyDir = join(projectRoot, PI_EXTENSIONS_DIR, LEGACY_PI_EXTENSION_NAME)
|
|
531
|
+
if (existsSync(legacyDir)) {
|
|
532
|
+
await rm(legacyDir, { recursive: true, force: true })
|
|
533
|
+
}
|
|
534
|
+
const extDir = join(projectRoot, PI_EXTENSIONS_DIR, PI_EXTENSION_NAME)
|
|
535
|
+
if (!existsSync(extDir)) {
|
|
536
|
+
return { removed: false, path: '' }
|
|
537
|
+
}
|
|
538
|
+
await rm(extDir, { recursive: true, force: true })
|
|
539
|
+
return { removed: true, path: `${PI_EXTENSIONS_DIR}/${PI_EXTENSION_NAME}` }
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Повертає змістовні (не коментар, не порожній) рядки з text-фрагмента `.gitignore`.
|
|
544
|
+
* @param {string} raw вміст snippet-файлу
|
|
545
|
+
* @returns {string[]} нормалізовані рядки патернів
|
|
546
|
+
*/
|
|
547
|
+
function parseGitignoreFragmentLines(raw) {
|
|
548
|
+
return raw
|
|
549
|
+
.split(EOL_RE)
|
|
550
|
+
.map(l => l.trim())
|
|
551
|
+
.filter(l => l !== '' && !l.startsWith('#'))
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Дописує в кореневий `.gitignore` проєкту відсутні рядки з канонічного ADR-фрагмента.
|
|
556
|
+
* @param {string} projectRoot корінь проєкту-споживача
|
|
557
|
+
* @param {string} bundledPackageRoot корінь установленого `@7n/rules`
|
|
558
|
+
* @returns {Promise<{ written: boolean, path: string }>} чи змінено файл і відносний шлях
|
|
559
|
+
*/
|
|
560
|
+
export async function syncGitignoreAdrFragment(projectRoot, bundledPackageRoot) {
|
|
561
|
+
const snippetPath = join(bundledPackageRoot, ADR_GITIGNORE_SNIPPET_REL)
|
|
562
|
+
if (!existsSync(snippetPath)) {
|
|
563
|
+
return { written: false, path: '' }
|
|
564
|
+
}
|
|
565
|
+
const fragment = await readFile(snippetPath, 'utf8')
|
|
566
|
+
const required = parseGitignoreFragmentLines(fragment)
|
|
567
|
+
if (required.length === 0) {
|
|
568
|
+
return { written: false, path: '' }
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const destPath = join(projectRoot, GITIGNORE_FILE)
|
|
572
|
+
const existing = existsSync(destPath) ? await readFile(destPath, 'utf8') : ''
|
|
573
|
+
const existingLines = new Set(
|
|
574
|
+
existing
|
|
575
|
+
.split(EOL_RE)
|
|
576
|
+
.map(l => l.trim())
|
|
577
|
+
.filter(l => l !== '' && !l.startsWith('#'))
|
|
578
|
+
)
|
|
579
|
+
const missing = required.filter(l => !existingLines.has(l))
|
|
580
|
+
if (missing.length === 0) {
|
|
581
|
+
return { written: false, path: GITIGNORE_FILE }
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
const sectionHeader = '# @7n/rules (adr) — локальні артефакти Stop-hook, не коміти'
|
|
585
|
+
const hasHeader = existing.split(EOL_RE).some(l => l.trim() === sectionHeader)
|
|
586
|
+
const block = hasHeader ? missing.join('\n') : [sectionHeader, ...missing].join('\n')
|
|
587
|
+
let prefix = ''
|
|
588
|
+
if (existing.length > 0) {
|
|
589
|
+
prefix = existing.endsWith('\n') ? existing : `${existing}\n`
|
|
590
|
+
}
|
|
591
|
+
const next = `${prefix}${block}\n`
|
|
592
|
+
await writeFile(destPath, next, 'utf8')
|
|
593
|
+
return { written: true, path: GITIGNORE_FILE }
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Копіює всі slash-команди з `templateDir/commands/` у `.claude/commands/`.
|
|
598
|
+
* Команди ідентифікуються тим, що вони лежать у темплейті — не перетинаються
|
|
599
|
+
* з командами скілів (n-fix, n-lint, ...).
|
|
600
|
+
* @param {string} projectRoot корінь проєкту-споживача
|
|
601
|
+
* @param {string} templateDir каталог `.claude-template/` усередині пакету `@7n/rules`
|
|
602
|
+
* @returns {Promise<string[]>} масив відносних шляхів записаних файлів
|
|
603
|
+
*/
|
|
604
|
+
export async function syncClaudeCommands(projectRoot, templateDir) {
|
|
605
|
+
const commandsTemplateDir = join(templateDir, 'commands')
|
|
606
|
+
if (!existsSync(commandsTemplateDir)) {
|
|
607
|
+
return []
|
|
608
|
+
}
|
|
609
|
+
const targetDir = join(projectRoot, CLAUDE_COMMANDS_DIR)
|
|
610
|
+
await mkdir(targetDir, { recursive: true })
|
|
611
|
+
const written = []
|
|
612
|
+
for (const name of await readdir(commandsTemplateDir)) {
|
|
613
|
+
if (!name.endsWith('.md')) {
|
|
614
|
+
continue
|
|
615
|
+
}
|
|
616
|
+
const content = await readFile(join(commandsTemplateDir, name), 'utf8')
|
|
617
|
+
await writeFile(join(targetDir, name), content, 'utf8')
|
|
618
|
+
written.push(`${CLAUDE_COMMANDS_DIR}/${name}`)
|
|
619
|
+
}
|
|
620
|
+
return written
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Виконує повну синхронізацію Claude Code-конфігу з темплейту пакету в проєкт.
|
|
625
|
+
* Використовується з `bin/n-rules.js` після інших синків.
|
|
626
|
+
* @param {object} options опції синку
|
|
627
|
+
* @param {string} options.projectRoot корінь проєкту-споживача
|
|
628
|
+
* @param {string} options.bundledPackageRoot корінь установленого `@7n/rules`
|
|
629
|
+
* @param {boolean} options.enabled чи увімкнено sync (з `.n-rules.json` `claude-config`)
|
|
630
|
+
* @param {string[]} [options.rules] список увімкнених правил із `.n-rules.json` — впливає на ADR Stop-hook (`adr`)
|
|
631
|
+
* @returns {Promise<{ settings: boolean, cursorHooks: boolean, commands: string[], adrHook: boolean, adrNormalizeHook: boolean, adrHookLib: string[], gitignoreAdr: boolean, piExtension: boolean }>} прапорці записів settings/Cursor hooks/ADR-hook(s)/`.gitignore`/pi-extension, перелік lib-файлів і список slash-команд
|
|
632
|
+
*/
|
|
633
|
+
export async function syncClaudeConfig({ projectRoot, bundledPackageRoot, enabled, rules = [] }) {
|
|
634
|
+
if (!enabled) {
|
|
635
|
+
return {
|
|
636
|
+
settings: false,
|
|
637
|
+
cursorHooks: false,
|
|
638
|
+
commands: [],
|
|
639
|
+
adrHook: false,
|
|
640
|
+
adrNormalizeHook: false,
|
|
641
|
+
adrHookLib: [],
|
|
642
|
+
gitignoreAdr: false,
|
|
643
|
+
piExtension: false
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
const templateDir = join(bundledPackageRoot, TEMPLATE_DIR_NAME)
|
|
647
|
+
if (!existsSync(templateDir)) {
|
|
648
|
+
return {
|
|
649
|
+
settings: false,
|
|
650
|
+
cursorHooks: false,
|
|
651
|
+
commands: [],
|
|
652
|
+
adrHook: false,
|
|
653
|
+
adrNormalizeHook: false,
|
|
654
|
+
adrHookLib: [],
|
|
655
|
+
gitignoreAdr: false,
|
|
656
|
+
piExtension: false
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const includeAdrHook = Array.isArray(rules) && rules.includes('adr')
|
|
660
|
+
const adrHook = includeAdrHook ? await syncAdrHookScript(projectRoot, templateDir) : { written: false, path: '' }
|
|
661
|
+
const adrNormalizeHook = includeAdrHook
|
|
662
|
+
? await syncAdrNormalizeHookScript(projectRoot, templateDir)
|
|
663
|
+
: { written: false, path: '' }
|
|
664
|
+
// Lib-файли мають сенс лише з активним хоча б одним ADR-хуком — без caller'а
|
|
665
|
+
// нікому source-ити; при вимкненому правилі прибираємо осиротілу-теку.
|
|
666
|
+
const adrHookLibEntries = includeAdrHook
|
|
667
|
+
? await syncAdrHookLibScripts(projectRoot, templateDir)
|
|
668
|
+
: (await removeOrphanAdrHookLib(projectRoot), [])
|
|
669
|
+
const gitignoreAdr = includeAdrHook
|
|
670
|
+
? await syncGitignoreAdrFragment(projectRoot, bundledPackageRoot)
|
|
671
|
+
: { written: false, path: '' }
|
|
672
|
+
let piExtension
|
|
673
|
+
if (includeAdrHook) {
|
|
674
|
+
piExtension = await syncPiExtensions(projectRoot, bundledPackageRoot)
|
|
675
|
+
} else {
|
|
676
|
+
const removed = await removeOrphanPiExtension(projectRoot)
|
|
677
|
+
piExtension = { written: false, path: removed.path }
|
|
678
|
+
}
|
|
679
|
+
const settings = await syncClaudeSettings(projectRoot, templateDir, { includeAdrHook })
|
|
680
|
+
const cursorHooks = await syncCursorHooksConfig(projectRoot, { includeAdrHook })
|
|
681
|
+
const commands = await syncClaudeCommands(projectRoot, templateDir)
|
|
682
|
+
return {
|
|
683
|
+
settings: settings.written,
|
|
684
|
+
cursorHooks: cursorHooks.written,
|
|
685
|
+
commands,
|
|
686
|
+
adrHook: adrHook.written,
|
|
687
|
+
adrNormalizeHook: adrNormalizeHook.written,
|
|
688
|
+
adrHookLib: adrHookLibEntries.map(e => e.path),
|
|
689
|
+
gitignoreAdr: gitignoreAdr.written,
|
|
690
|
+
piExtension: piExtension.written
|
|
691
|
+
}
|
|
692
|
+
}
|