@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,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Експериментальний harness для перевірки sampling/consensus поверх lint fix ladder.
|
|
3
|
+
*
|
|
4
|
+
* Модуль не підключений до production `runFixPipeline`: він моделює isolated candidates
|
|
5
|
+
* для заданого tier-а, кожен раз відкочує робоче дерево до S1, вибирає тільки candidate,
|
|
6
|
+
* який пройшов canonical detect, і лишає judge/consensus лише джерелом feedback.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
9
|
+
import { dirname } from 'node:path'
|
|
10
|
+
|
|
11
|
+
import { createSnapshot } from './snapshot.mjs'
|
|
12
|
+
|
|
13
|
+
export const EXPERIMENT_TIER_ORDER = Object.freeze(['local-min', 'cloud-min', 'cloud-avg', 'cloud-max'])
|
|
14
|
+
|
|
15
|
+
const DEFAULT_LOCAL_TIMEOUT_MS = 300_000
|
|
16
|
+
const DEFAULT_CLOUD_TIMEOUT_MS = 300_000
|
|
17
|
+
|
|
18
|
+
const DEFAULT_PROFILES_BY_TIER = Object.freeze({
|
|
19
|
+
'local-min': ['conservative'],
|
|
20
|
+
'cloud-min': ['conservative', 'exploratory'],
|
|
21
|
+
'cloud-avg': ['conservative', 'exploratory'],
|
|
22
|
+
'cloud-max': ['conservative']
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {object} ExperimentRung
|
|
27
|
+
* @property {'local-min'|'cloud-min'|'cloud-avg'|'cloud-max'} tier Ідентифікатор tier-а в експериментальному ladder.
|
|
28
|
+
* @property {string} model Назва моделі, що виконує fix на цьому rung-і.
|
|
29
|
+
* @property {boolean} feedback Чи передавати judge-feedback у контекст fix-у.
|
|
30
|
+
* @property {boolean} local Чи виконується rung локальною моделлю.
|
|
31
|
+
* @property {boolean} isAvg Чи це rung рівня cloud-avg.
|
|
32
|
+
* @property {boolean} isMax Чи це rung рівня cloud-max.
|
|
33
|
+
* @property {boolean} experimentOnly Позначка, що rung існує лише в експерименті, не в production ladder.
|
|
34
|
+
* @property {number} timeoutMs Стеля часу виконання одного кандидата, мс.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @typedef {object} SamplingCandidate
|
|
39
|
+
* @property {string} id Унікальний ідентифікатор кандидата в межах прогону.
|
|
40
|
+
* @property {'conservative'|'exploratory'|'judge'|string} samplingProfile Sampling-профіль, з яким запускається кандидат.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {object} CandidateAttempt
|
|
45
|
+
* @property {number} index Порядковий номер кандидата у списку.
|
|
46
|
+
* @property {string} id Ідентифікатор кандидата.
|
|
47
|
+
* @property {string} samplingProfile Sampling-профіль кандидата.
|
|
48
|
+
* @property {string} tier Tier rung-а, на якому виконувався кандидат.
|
|
49
|
+
* @property {string} model Модель, що виконувала fix.
|
|
50
|
+
* @property {boolean} clean Чи пройшов кандидат canonical detect без залишкових порушень.
|
|
51
|
+
* @property {string[]} touchedFiles Абсолютні шляхи файлів, які кандидат змінив.
|
|
52
|
+
* @property {number} changedBytes Сумарний розмір captured patch у байтах.
|
|
53
|
+
* @property {number} wallMs Тривалість спроби, мс.
|
|
54
|
+
* @property {string|null} error Повідомлення помилки worker-а або null.
|
|
55
|
+
* @property {import('./types.mjs').LintViolation[]} violations Порушення, що лишилися після спроби.
|
|
56
|
+
* @property {object|undefined} telemetry Телеметрія worker-а, якщо він її повернув.
|
|
57
|
+
* @property {Array<{ absPath: string, exists: boolean, content: string }>} patch Знімок змінених файлів чистого кандидата.
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Будує experiment-only ladder із `cloud-max`. Production ladder це не змінює.
|
|
62
|
+
* @param {{ localMin?: string, cloudMin?: string, cloudAvg?: string, cloudMax?: string }} models - Об'єкт, що містить імена моделей для кожного tier.
|
|
63
|
+
* @param {{ localTimeoutMs?: number, cloudTimeoutMs?: number }} [opts] - Опції для встановлення timeout для локального та хмарного етапу.
|
|
64
|
+
* @returns {ExperimentRung[]} Масив експериментальних rung'ів (етапів).
|
|
65
|
+
*/
|
|
66
|
+
export function buildExperimentLadder(models, opts = {}) {
|
|
67
|
+
const localTimeoutMs = opts.localTimeoutMs ?? DEFAULT_LOCAL_TIMEOUT_MS
|
|
68
|
+
const cloudTimeoutMs = opts.cloudTimeoutMs ?? DEFAULT_CLOUD_TIMEOUT_MS
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
tier: 'local-min',
|
|
72
|
+
model: models.localMin ?? '',
|
|
73
|
+
feedback: false,
|
|
74
|
+
local: true,
|
|
75
|
+
isAvg: false,
|
|
76
|
+
isMax: false,
|
|
77
|
+
experimentOnly: true,
|
|
78
|
+
timeoutMs: localTimeoutMs
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
tier: 'cloud-min',
|
|
82
|
+
model: models.cloudMin ?? '',
|
|
83
|
+
feedback: true,
|
|
84
|
+
local: false,
|
|
85
|
+
isAvg: false,
|
|
86
|
+
isMax: false,
|
|
87
|
+
experimentOnly: true,
|
|
88
|
+
timeoutMs: cloudTimeoutMs
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
tier: 'cloud-avg',
|
|
92
|
+
model: models.cloudAvg ?? '',
|
|
93
|
+
feedback: true,
|
|
94
|
+
local: false,
|
|
95
|
+
isAvg: true,
|
|
96
|
+
isMax: false,
|
|
97
|
+
experimentOnly: true,
|
|
98
|
+
timeoutMs: cloudTimeoutMs
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
tier: 'cloud-max',
|
|
102
|
+
model: models.cloudMax ?? '',
|
|
103
|
+
feedback: true,
|
|
104
|
+
local: false,
|
|
105
|
+
isAvg: false,
|
|
106
|
+
isMax: true,
|
|
107
|
+
experimentOnly: true,
|
|
108
|
+
timeoutMs: cloudTimeoutMs
|
|
109
|
+
}
|
|
110
|
+
].filter(r => r.model)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Повертає можливі sampling profiles для заданого tier-а.
|
|
115
|
+
* @param {string} tier - Назва tier (наприклад, 'local-min').
|
|
116
|
+
* @param {Record<string, Array<string|SamplingCandidate>>} [overrides] - Об'єкт з перевизначеними profiles для конкретного tier.
|
|
117
|
+
* @returns {SamplingCandidate[]} Масив об'єктів SamplingCandidate для даного tier.
|
|
118
|
+
*/
|
|
119
|
+
export function samplingProfilesForTier(tier, overrides = {}) {
|
|
120
|
+
const raw = overrides[tier] ?? DEFAULT_PROFILES_BY_TIER[tier] ?? ['conservative']
|
|
121
|
+
return raw.map((p, index) => {
|
|
122
|
+
if (typeof p === 'string') return { id: `${tier}:${p}:${index}`, samplingProfile: p }
|
|
123
|
+
return { id: p.id ?? `${tier}:${p.samplingProfile}:${index}`, samplingProfile: p.samplingProfile }
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Дефолтний вибір найкращого (clean) кандидата серед усіх спроб.
|
|
129
|
+
* Вибір відбувається за критеріями: менша кількість змінених файлів, менший розмір patch, менша латентність.
|
|
130
|
+
* @param {CandidateAttempt[]} attempts - Масив усіх спроб (candidates).
|
|
131
|
+
* @returns {CandidateAttempt|null} Найкращий чистий кандидат, або null, якщо жоден не знайдено.
|
|
132
|
+
*/
|
|
133
|
+
export function chooseCleanCandidate(attempts) {
|
|
134
|
+
const clean = attempts.filter(a => a.clean)
|
|
135
|
+
if (clean.length === 0) return null
|
|
136
|
+
return clean.toSorted((a, b) => {
|
|
137
|
+
const byTouched = a.touchedFiles.length - b.touchedFiles.length
|
|
138
|
+
if (byTouched !== 0) return byTouched
|
|
139
|
+
const byBytes = a.changedBytes - b.changedBytes
|
|
140
|
+
if (byBytes !== 0) return byBytes
|
|
141
|
+
const byTime = a.wallMs - b.wallMs
|
|
142
|
+
if (byTime !== 0) return byTime
|
|
143
|
+
return a.index - b.index
|
|
144
|
+
})[0]
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Виконує послідовність випробувань (sampling) для одного tier.
|
|
149
|
+
* Для кожного кандидата виконується rollback до S1, запускається worker,
|
|
150
|
+
* оцінюється чистота, і якщо кандидат обраний, застосовується його patch.
|
|
151
|
+
* @param {object} args - Аргументи для експерименту.
|
|
152
|
+
* @param {import('./types.mjs').LintViolation[]} args.violations - Початкові порушення для перевірки.
|
|
153
|
+
* @param {object} args.ctx - Базовий контекст для фіксації.
|
|
154
|
+
* @param {ExperimentRung} args.rung - Конфігурація поточного експерименту.
|
|
155
|
+
* @param {SamplingCandidate[]} args.candidates - Список кандидатів для тестування.
|
|
156
|
+
* @param {(violations: import('./types.mjs').LintViolation[], ctx: object) => Promise<{ touchedFiles?: string[], telemetry?: object }|void>} args.worker - Функція для виконання фіксу.
|
|
157
|
+
* @param {(ctx: object) => Promise<import('./types.mjs').LintViolation[]> | import('./types.mjs').LintViolation[]} args.detect - Функція для перевірки порушень після застосування/умовами.
|
|
158
|
+
* @param {(attempts: CandidateAttempt[]) => CandidateAttempt|null} [args.choose] - Стратегія вибору найкращого кандидата.
|
|
159
|
+
* @param {(ctx: object) => Promise<object|null> | object | null} [args.judge] - Функція для відгуку судді (judge).
|
|
160
|
+
* @param {() => number} [args.clock] - Функція для отримання часу.
|
|
161
|
+
* @returns {Promise<{ clean: boolean, selected: CandidateAttempt|null, attempts: CandidateAttempt[], finalViolations: import('./types.mjs').LintViolation[], judgeFeedback: object|null }>} Результат виконання експерименту.
|
|
162
|
+
*/
|
|
163
|
+
export async function runTierSamplingExperiment(args) {
|
|
164
|
+
const choose = args.choose ?? chooseCleanCandidate
|
|
165
|
+
const clock = args.clock ?? (() => Date.now())
|
|
166
|
+
const snapshot = createSnapshot()
|
|
167
|
+
/** @type {CandidateAttempt[]} */
|
|
168
|
+
const attempts = []
|
|
169
|
+
|
|
170
|
+
for (const [index, candidate] of args.candidates.entries()) {
|
|
171
|
+
snapshot.rollback()
|
|
172
|
+
const recordedThisCandidate = new Set()
|
|
173
|
+
const startedAt = clock()
|
|
174
|
+
let error = null
|
|
175
|
+
let telemetry
|
|
176
|
+
/** @type {string[]} */
|
|
177
|
+
let touchedFiles
|
|
178
|
+
|
|
179
|
+
const candidateCtx = {
|
|
180
|
+
...args.ctx,
|
|
181
|
+
tier: args.rung.tier,
|
|
182
|
+
model: args.rung.model,
|
|
183
|
+
feedback: args.rung.feedback ? args.ctx.feedback : undefined,
|
|
184
|
+
samplingProfile: candidate.samplingProfile,
|
|
185
|
+
candidateId: candidate.id,
|
|
186
|
+
recordWrite(absPath) {
|
|
187
|
+
recordedThisCandidate.add(absPath)
|
|
188
|
+
snapshot.record(absPath)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
const res = await args.worker(args.violations, candidateCtx)
|
|
194
|
+
touchedFiles = uniqueStrings(res?.touchedFiles?.length ? res.touchedFiles : [...recordedThisCandidate])
|
|
195
|
+
telemetry = res?.telemetry
|
|
196
|
+
} catch (workerError) {
|
|
197
|
+
error = workerError.message
|
|
198
|
+
touchedFiles = uniqueStrings([...recordedThisCandidate])
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const detected = await args.detect({ ...candidateCtx, phase: 'candidate-detect' })
|
|
202
|
+
const patch = detected.length === 0 && !error ? captureFiles(touchedFiles) : []
|
|
203
|
+
attempts.push({
|
|
204
|
+
index,
|
|
205
|
+
id: candidate.id,
|
|
206
|
+
samplingProfile: candidate.samplingProfile,
|
|
207
|
+
tier: args.rung.tier,
|
|
208
|
+
model: args.rung.model,
|
|
209
|
+
clean: detected.length === 0 && !error,
|
|
210
|
+
touchedFiles,
|
|
211
|
+
changedBytes: patchSize(patch),
|
|
212
|
+
wallMs: clock() - startedAt,
|
|
213
|
+
error,
|
|
214
|
+
violations: detected,
|
|
215
|
+
telemetry,
|
|
216
|
+
patch
|
|
217
|
+
})
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
snapshot.rollback()
|
|
221
|
+
const selected = choose(attempts)
|
|
222
|
+
if (!selected) {
|
|
223
|
+
const judgeFeedback = args.judge ? await args.judge({ ...args.ctx, rung: args.rung, attempts }) : null
|
|
224
|
+
return { clean: false, selected: null, attempts, finalViolations: attempts.at(-1)?.violations ?? [], judgeFeedback }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
applyCapturedFiles(selected.patch, snapshot)
|
|
228
|
+
const finalViolations = await args.detect({
|
|
229
|
+
...args.ctx,
|
|
230
|
+
tier: args.rung.tier,
|
|
231
|
+
model: args.rung.model,
|
|
232
|
+
samplingProfile: selected.samplingProfile,
|
|
233
|
+
candidateId: selected.id,
|
|
234
|
+
phase: 'final-detect'
|
|
235
|
+
})
|
|
236
|
+
if (finalViolations.length > 0) {
|
|
237
|
+
snapshot.rollback()
|
|
238
|
+
return { clean: false, selected: null, attempts, finalViolations, judgeFeedback: null }
|
|
239
|
+
}
|
|
240
|
+
return { clean: true, selected, attempts, finalViolations, judgeFeedback: null }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Видаляє дублікати з масиву рядків.
|
|
245
|
+
* @param {string[]} values - Вхідний масив рядків.
|
|
246
|
+
* @returns {string[]} Масив унікальних рядків.
|
|
247
|
+
*/
|
|
248
|
+
function uniqueStrings(values) {
|
|
249
|
+
return [...new Set(values.filter(v => typeof v === 'string' && v.length > 0))]
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Збирає вміст файлів, зазначених у шляхах.
|
|
254
|
+
* @param {string[]} paths - Масив абсолютних шляхів до файлів.
|
|
255
|
+
* @returns {Array<{ absPath: string, exists: boolean, content: string }>} Масив об'єктів з інформацією про файли.
|
|
256
|
+
*/
|
|
257
|
+
function captureFiles(paths) {
|
|
258
|
+
return paths.map(absPath => ({
|
|
259
|
+
absPath,
|
|
260
|
+
exists: existsSync(absPath),
|
|
261
|
+
content: existsSync(absPath) ? readFileSync(absPath, 'utf8') : ''
|
|
262
|
+
}))
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Застосовує зміни (patch) до робочого дерева через snapshot.
|
|
267
|
+
* @param {Array<{ absPath: string, exists: boolean, content: string }>} patch - Патч для застосування.
|
|
268
|
+
* @param {object} snapshot - Об'єкт з функцією для запису змін.
|
|
269
|
+
*/
|
|
270
|
+
function applyCapturedFiles(patch, snapshot) {
|
|
271
|
+
for (const file of patch) {
|
|
272
|
+
snapshot.record(file.absPath)
|
|
273
|
+
if (!file.exists) {
|
|
274
|
+
rmSync(file.absPath, { force: true })
|
|
275
|
+
continue
|
|
276
|
+
}
|
|
277
|
+
mkdirSync(dirname(file.absPath), { recursive: true })
|
|
278
|
+
writeFileSync(file.absPath, file.content, 'utf8')
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Обчислює загальний розмір патчу.
|
|
284
|
+
* @param {Array<{ absPath: string, exists: boolean, content: string }>} patch - Масив файлів патчу.
|
|
285
|
+
* @returns {number} Загальна кількість байтів.
|
|
286
|
+
*/
|
|
287
|
+
function patchSize(patch) {
|
|
288
|
+
return patch.reduce((sum, file) => sum + file.content.length, 0)
|
|
289
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Контракти unified lint surface (spec: docs/specs/2026-06-29-unified-lint-surface.md).
|
|
3
|
+
*
|
|
4
|
+
* Один detector API, один result type, дві чесні ролі:
|
|
5
|
+
* - `lint(ctx) -> LintResult` тільки виявляє порушення (read-only, без LLM, без side effects);
|
|
6
|
+
* - central fix pipeline (T0 + tier ladder) виправляє і перевіряє результат.
|
|
7
|
+
*
|
|
8
|
+
* Цей модуль не містить runtime-логіки — лише JSDoc typedefs, спільні для runner-а,
|
|
9
|
+
* detector-ів, T0-патернів і fix-worker-ів. Імпортуй через `@typedef {import(...)}`.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Вхід detector-а. Runner будує `ctx` per concern.
|
|
14
|
+
* @typedef {object} LintContext
|
|
15
|
+
* @property {string} cwd абсолютний корінь consumer-репо
|
|
16
|
+
* @property {string} ruleId id правила (`rules/<rule>`)
|
|
17
|
+
* @property {string} concernId id concern-а (`rules/<rule>/<concern>`)
|
|
18
|
+
* @property {string} [concernDir] абсолютний шлях до каталогу concern-а (для T0, що читають
|
|
19
|
+
* власний `template/`); runner заповнює, detector зазвичай не потребує
|
|
20
|
+
* @property {string[]} [files] posix-relative файли від `cwd` для per-file запуску;
|
|
21
|
+
* `undefined` означає whole-repo
|
|
22
|
+
* @property {boolean} [verbose] `--verbose` CLI-прапорець; concern-и із зовнішніми
|
|
23
|
+
* інструментами (напр. `ga/workflows`) звіряються з ним, щоб не засмічувати прогрес-бар `lint --full`
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Одне порушення. Namespace стабільного коду — `(ruleId, concernId, reason)`,
|
|
28
|
+
* тому різні concerns можуть мати однакові `reason` (`missing`, `crc-mismatch`, ...).
|
|
29
|
+
* @typedef {object} LintViolation
|
|
30
|
+
* @property {string} ruleId заповнюється detector-ом із ctx або normalizer-ом runner-а
|
|
31
|
+
* @property {string} concernId id concern-а, до якого належить порушення
|
|
32
|
+
* @property {string} reason стабільний machine code (`crc-mismatch`, `no-unused-vars`)
|
|
33
|
+
* @property {string} message людиночитний опис (єдине джерело для runner-render)
|
|
34
|
+
* @property {string} [file] posix-relative шлях від cwd; absolute і `..` заборонені
|
|
35
|
+
* @property {'error'|'warn'} [severity] default `error`
|
|
36
|
+
* @property {Record<string, unknown>} [data] concern-specific payload для T0/worker;
|
|
37
|
+
* runner не розгалужується за його формою
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Технічна діагностика (не основний violation-report). Runner показує у verbose/debug.
|
|
42
|
+
* @typedef {object} LintDiagnostic
|
|
43
|
+
* @property {'info'|'warn'} level рівень діагностики
|
|
44
|
+
* @property {string} message текст діагностики
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Результат detector-а. Не містить exit code — exit це похідна CLI-семантика
|
|
49
|
+
* (0 = немає violations, 1 = є, 2 = exception/invalid result/tool crash).
|
|
50
|
+
* @typedef {object} LintResult
|
|
51
|
+
* @property {LintViolation[]} violations перелік виявлених порушень
|
|
52
|
+
* @property {LintDiagnostic[]} [diagnostics] технічні діагностики для verbose/debug
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Detector-контракт concern-а (`main.mjs`).
|
|
57
|
+
* @callback LintFn
|
|
58
|
+
* @param {LintContext} ctx
|
|
59
|
+
* @returns {Promise<LintResult> | LintResult}
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Детермінований T0-патерн (`fix-<concern>.mjs` експортує `patterns: T0Pattern[]`).
|
|
64
|
+
* Отримує ТІЛЬКИ violations свого concern-а (runner scope-ить за ruleId/concernId).
|
|
65
|
+
* @typedef {object} T0Pattern
|
|
66
|
+
* @property {string} id унікальний id патерну (дедуп за ним при re-export)
|
|
67
|
+
* @property {(violations: LintViolation[]) => boolean} test чи застосовний патерн
|
|
68
|
+
* @property {(violations: LintViolation[], ctx: LintContext) => Promise<T0Result> | T0Result} apply застосовує детерміноване виправлення й повертає результат
|
|
69
|
+
* @property {boolean} [standalone] true — патерн сам ідемпотентний і самоаналізуючий (напр.
|
|
70
|
+
* `oxfmt --write`, `ruff --fix`): не потребує per-violation даних, щоб вирішити, чи
|
|
71
|
+
* запускати `apply()` — runner обходить `test()` і, якщо ВСІ патерни concern-а standalone,
|
|
72
|
+
* пропускає початковий detect у fix-режимі (spec
|
|
73
|
+
* docs/specs/2026-07-02-text-check-per-file-split-design.md §8, Phase 2). Не стосується
|
|
74
|
+
* `--no-fix` (detect-only) шляху.
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @typedef {object} T0Result
|
|
79
|
+
* @property {string[]} touchedFiles абсолютні шляхи змінених файлів
|
|
80
|
+
* @property {string} [message] опис дії для debug/telemetry
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Контекст одного rung-а fix-worker-а. Описує single attempt, НЕ всю ladder.
|
|
85
|
+
* Worker знає поточний tier/model і feedback попереднього rung-а, але не вирішує,
|
|
86
|
+
* який tier буде наступним, не володіє rollback і не визначає success.
|
|
87
|
+
* @typedef {object} FixContext
|
|
88
|
+
* @property {string} cwd абсолютний корінь consumer-репо
|
|
89
|
+
* @property {string} ruleId id правила поточного concern-а
|
|
90
|
+
* @property {string} concernId id concern-а, який виправляється
|
|
91
|
+
* @property {string[]} [files] posix-relative файли для per-file виправлення; `undefined` — whole-repo
|
|
92
|
+
* @property {'local-min'|'local-min-retry'|'cloud-min'|'cloud-avg'} tier поточний rung ladder-а
|
|
93
|
+
* @property {string} [model] "provider/model-id"
|
|
94
|
+
* @property {number} [timeoutMs] per-tier таймаут rung-а (ADR 260620-0556) — worker
|
|
95
|
+
* ЗОБОВ'ЯЗАНИЙ прокинути його у свій LLM-виклик (напр. `runAgentFix`/`runOneShot`
|
|
96
|
+
* opts.timeoutMs), щоб зависла сесія переривалась зсередини (abort); runner додатково тримає
|
|
97
|
+
* backstop ×1.25 навколо всього worker-виклику
|
|
98
|
+
* @property {AbortSignal} [signal] сигнал скасування rung-а
|
|
99
|
+
* @property {object} [feedback] structured diagnosis попереднього rung-а
|
|
100
|
+
* @property {(absPath: string) => void} recordWrite worker ЗОБОВ'ЯЗАНИЙ викликати
|
|
101
|
+
* перед будь-яким записом у файл — runner так знімає pre-image для central rollback.
|
|
102
|
+
* Це обов'язок реєстрації, НЕ володіння rollback-ом (rollback лишається в runner).
|
|
103
|
+
* @property {(absPath: string) => void} [recordDurableWrite] durable-реєстрація для
|
|
104
|
+
* worker-ів, чиї записи — самодостатні кінцеві стани (файл або записаний повністю й
|
|
105
|
+
* валідний, або не записаний; напр. doc-files: кожна дока зі свіжим CRC, degraded теж
|
|
106
|
+
* валідна). Durable-файли переживають rollback провального rung-а — прогрес великого
|
|
107
|
+
* батчу не стирається, canonical re-detect рахує лише те, що реально лишилось; у
|
|
108
|
+
* semantic-collateral veto вони не входять. Для правок наявного стороннього коду —
|
|
109
|
+
* ЗАВЖДИ recordWrite (rollback-контракт незмінний).
|
|
110
|
+
* @property {object} [chain] chain handle concern-а (@7n/llm-lib/chain) — worker
|
|
111
|
+
* прокидає його у runAgentFix/runOneShot, щоб рунг став кроком ланцюжка.
|
|
112
|
+
* @property {(args: { touchedFiles: string[] }) => Promise<{ ok: boolean, output?: string }>} [verify]
|
|
113
|
+
* evidence-гейт рунга (дизайн 2026-07-11 Фаза A1): item-scoped canonical re-detect.
|
|
114
|
+
* Worker прокидає у `runAgentFix` opts.verify — провал інʼєктиться фідбеком у ту саму
|
|
115
|
+
* pi-сесію (до `verifyMax` ітерацій). Це НЕ заміна зовнішнього canonical re-detect
|
|
116
|
+
* runner-а (він лишається вердиктом) — лише рання петля всередині рунга.
|
|
117
|
+
* @property {number} [verifyMax] додаткові verify-ітерації рунга (local — менше, cloud — більше).
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Контракт fix-worker-а (`fix-worker.mjs` експортує `fixWorker`).
|
|
122
|
+
* Повертає лише застосовані зміни — success визначає canonical re-check runner-а.
|
|
123
|
+
* @callback FixWorkerFn
|
|
124
|
+
* @param {LintViolation[]} violations violations свого concern-а
|
|
125
|
+
* @param {FixContext} ctx
|
|
126
|
+
* @returns {Promise<FixWorkerResult>}
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @typedef {object} FixWorkerResult
|
|
131
|
+
* @property {string[]} touchedFiles абсолютні шляхи змінених файлів
|
|
132
|
+
* @property {object} [telemetry] опційні метрики rung-а
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Поверхня policy-concern-а у concern.json (target-семантика для generated detector-а).
|
|
137
|
+
* @typedef {object} PolicySurface
|
|
138
|
+
* @property {'rego'|'template'} engine рушій перевірки policy-concern-а
|
|
139
|
+
* @property {{ single?: string, walkGlob?: string|string[], required?: boolean }} files цільові файли concern-а (одиничний, glob-обхід, обовʼязковість)
|
|
140
|
+
* @property {string} [missingMessage] override fail-повідомлення для required:single
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Lint-поверхня concern-а (коли concern запускається).
|
|
145
|
+
* @typedef {object} LintSurface
|
|
146
|
+
* @property {'per-file'|'full'} scope режим запуску concern-а (пофайлово чи по всьому дереву)
|
|
147
|
+
* @property {string[]} glob нормалізований масив; порожній якщо не задано
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
export {}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drop-in заміна `createCheckReporter` для міграції check-concern-ів у detector-и.
|
|
3
|
+
*
|
|
4
|
+
* Старий reporter друкував pass/fail і накопичував exit code. Detector НЕ друкує —
|
|
5
|
+
* цей reporter накопичує `LintViolation[]`. Тіло concern-а майже не змінюється:
|
|
6
|
+
* - `createCheckReporter()` → `createViolationReporter(ctx)`
|
|
7
|
+
* - `return reporter.getExitCode()` → `return reporter.result()`
|
|
8
|
+
*
|
|
9
|
+
* `fail(msg)` за замовчуванням дає `reason = ctx.concernId`. Для кількох типів порушень
|
|
10
|
+
* у одному concern-і — `fail(msg, 'specific-reason')` або `fail(msg, { reason, file, data })`.
|
|
11
|
+
* @typedef {import('./types.mjs').LintContext} LintContext
|
|
12
|
+
* @typedef {import('./types.mjs').LintViolation} LintViolation
|
|
13
|
+
* @typedef {import('./types.mjs').LintResult} LintResult
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {LintContext} ctx контекст concern-а (джерело дефолтного reason).
|
|
18
|
+
* @returns {{
|
|
19
|
+
* pass: (...args: unknown[]) => void,
|
|
20
|
+
* fail: (msg: string, opts?: string | { reason?: string, file?: string, severity?: 'error'|'warn', data?: object }) => void,
|
|
21
|
+
* result: () => LintResult
|
|
22
|
+
* }} reporter, що накопичує порушення й повертає LintResult.
|
|
23
|
+
*/
|
|
24
|
+
export function createViolationReporter(ctx) {
|
|
25
|
+
/** @type {LintViolation[]} */
|
|
26
|
+
const violations = []
|
|
27
|
+
const defaultReason = ctx?.concernId ?? 'violation'
|
|
28
|
+
return {
|
|
29
|
+
// detector не друкує — pass стає no-op (успіхи рендерить runner відсутністю violations)
|
|
30
|
+
pass() {
|
|
31
|
+
// навмисний no-op: успіх не накопичує violation
|
|
32
|
+
},
|
|
33
|
+
fail(msg, opts) {
|
|
34
|
+
const o = typeof opts === 'string' ? { reason: opts } : (opts ?? {})
|
|
35
|
+
/** @type {Record<string, unknown>} */
|
|
36
|
+
const v = { reason: o.reason ?? defaultReason, message: msg }
|
|
37
|
+
if (o.file) v.file = o.file
|
|
38
|
+
if (o.severity) v.severity = o.severity
|
|
39
|
+
if (o.data) v.data = o.data
|
|
40
|
+
violations.push(/** @type {LintViolation} */ (v))
|
|
41
|
+
},
|
|
42
|
+
result() {
|
|
43
|
+
return { violations }
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Список `.mdc`-файлів правил у `.cursor/rules/` проєкту-споживача (відсортований).
|
|
3
|
+
* Винесено зі `bin/n-rules.js`, щоб ділити між CLI-dispatch і `run-conformance-check` (конформність-детект).
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from 'node:fs'
|
|
6
|
+
import { join } from 'node:path'
|
|
7
|
+
import { cwd as processCwd } from 'node:process'
|
|
8
|
+
import { globby } from 'globby'
|
|
9
|
+
|
|
10
|
+
/** Каталог правил у проєкті-споживачі (відносно кореня). */
|
|
11
|
+
export const CURSOR_RULES_DIR = '.cursor/rules'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string} [cwd] корінь проєкту
|
|
15
|
+
* @returns {Promise<string[]>} імена `*.mdc` (відсортовані), або `[]` якщо каталогу немає
|
|
16
|
+
*/
|
|
17
|
+
export async function listProjectRulesMdcFiles(cwd = processCwd()) {
|
|
18
|
+
const dir = join(cwd, CURSOR_RULES_DIR)
|
|
19
|
+
if (!existsSync(dir)) return []
|
|
20
|
+
const names = await globby('*.mdc', { cwd: dir, onlyFiles: true, gitignore: false })
|
|
21
|
+
return names.toSorted((a, b) => a.localeCompare(b))
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Перебір `rules/<id>/` директорій з фільтром на наявність entrypoint-а.
|
|
3
|
+
* Канон (ADR 2026-06-21): єдиний entrypoint `rules/<id>/main.mjs`. Каталог без нього —
|
|
4
|
+
* пропускається (це not-a-rule або заглушка).
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync } from 'node:fs'
|
|
7
|
+
import { readdir } from 'node:fs/promises'
|
|
8
|
+
import { join } from 'node:path'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Чи має каталог правила entrypoint `main.mjs`.
|
|
12
|
+
* @param {string} ruleDir абсолютний шлях `rules/<id>/`
|
|
13
|
+
* @returns {boolean} true, якщо `main.mjs` існує
|
|
14
|
+
*/
|
|
15
|
+
function hasEntrypoint(ruleDir) {
|
|
16
|
+
return existsSync(join(ruleDir, 'main.mjs'))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} bundledRulesDir абсолютний шлях до `npm/rules/`
|
|
21
|
+
* @param {string} [filter] id одного правила (через `--rule abie`)
|
|
22
|
+
* @returns {Promise<string[]>} відсортовані алфавітно id
|
|
23
|
+
*/
|
|
24
|
+
export async function listRuleIds(bundledRulesDir, filter) {
|
|
25
|
+
const entries = await readdir(bundledRulesDir, { withFileTypes: true })
|
|
26
|
+
const ids = entries
|
|
27
|
+
.filter(e => e.isDirectory() && !e.name.startsWith('.'))
|
|
28
|
+
.map(e => e.name)
|
|
29
|
+
.filter(id => hasEntrypoint(join(bundledRulesDir, id)))
|
|
30
|
+
.filter(id => filter === undefined || id === filter)
|
|
31
|
+
return ids.toSorted((a, b) => a.localeCompare(b))
|
|
32
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Утиліта читання `.n-rules.json` у корені репозиторію (fallback — legacy `.n-cursor.json`
|
|
3
|
+
* до першого синку, який мігрує ім'я файлу).
|
|
4
|
+
*
|
|
5
|
+
* Зараз експортує `loadCursorIgnorePaths(root)` — список абсолютних posix-шляхів каталогів,
|
|
6
|
+
* які check-скрипти повністю виключають з обходу (поле `ignore` у конфізі).
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync } from 'node:fs'
|
|
9
|
+
import { readFile } from 'node:fs/promises'
|
|
10
|
+
import { isAbsolute, join, resolve, sep } from 'node:path'
|
|
11
|
+
|
|
12
|
+
const CONFIG_FILE = '.n-rules.json'
|
|
13
|
+
const LEGACY_CONFIG_FILE = '.n-cursor.json'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Нормалізує шлях до абсолютного posix-формату без trailing-slash.
|
|
17
|
+
* Відносні шляхи розв'язуються від `root`.
|
|
18
|
+
* @param {string} root абсолютний корінь репозиторію
|
|
19
|
+
* @param {string} p шлях з конфігу (відносний або абсолютний)
|
|
20
|
+
* @returns {string} абсолютний posix-шлях
|
|
21
|
+
*/
|
|
22
|
+
function toAbsPosix(root, p) {
|
|
23
|
+
const trimmed = String(p).trim()
|
|
24
|
+
const abs = isAbsolute(trimmed) ? trimmed : resolve(root, trimmed)
|
|
25
|
+
let posix = abs.split(sep).join('/')
|
|
26
|
+
while (posix.endsWith('/')) posix = posix.slice(0, -1)
|
|
27
|
+
return posix
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Читає `.n-rules.json` з кореня та повертає нормалізовані ignore-шляхи.
|
|
32
|
+
* Якщо файлу нема, поле `ignore` відсутнє чи має невалідний формат — повертає порожній масив.
|
|
33
|
+
* Сам конфіг не валідується (це робить v8r/окрема перевірка) — лише поле `ignore`.
|
|
34
|
+
* @param {string} root абсолютний корінь репозиторію
|
|
35
|
+
* @returns {Promise<string[]>} абсолютні posix-шляхи без trailing-slash
|
|
36
|
+
*/
|
|
37
|
+
export async function loadCursorIgnorePaths(root) {
|
|
38
|
+
let file = join(root, CONFIG_FILE)
|
|
39
|
+
if (!existsSync(file)) file = join(root, LEGACY_CONFIG_FILE)
|
|
40
|
+
if (!existsSync(file)) return []
|
|
41
|
+
let raw
|
|
42
|
+
try {
|
|
43
|
+
raw = JSON.parse(await readFile(file, 'utf8'))
|
|
44
|
+
} catch {
|
|
45
|
+
return []
|
|
46
|
+
}
|
|
47
|
+
const list = raw?.ignore
|
|
48
|
+
if (!Array.isArray(list)) return []
|
|
49
|
+
/** @type {string[]} */
|
|
50
|
+
const out = []
|
|
51
|
+
for (const item of list) {
|
|
52
|
+
if (typeof item !== 'string') continue
|
|
53
|
+
const v = item.trim()
|
|
54
|
+
if (v.length === 0) continue
|
|
55
|
+
out.push(toAbsPosix(root, v))
|
|
56
|
+
}
|
|
57
|
+
return out
|
|
58
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parity дзеркала правил: `.cursor/rules/n-<id>.mdc` має дорівнювати канонічному
|
|
3
|
+
* `npm/rules/<id>/<id>.mdc` з inlined-шаблонами — тим самим трансформом, що його
|
|
4
|
+
* застосовує синк (`readBundledRuleContent` → `inlineTemplateLinks`). Дрейф виникає,
|
|
5
|
+
* коли канонічний `.mdc` змінюють, не регенерувавши дзеркало (беклог адаптації flow #10).
|
|
6
|
+
*
|
|
7
|
+
* Використовується і тестом-гардом (drift === []), і разовою регенерацією.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs'
|
|
10
|
+
import { dirname, join } from 'node:path'
|
|
11
|
+
|
|
12
|
+
import { appendDiscoveredMdcFiles, inlineTemplateLinks } from './inline-template-links.mjs'
|
|
13
|
+
|
|
14
|
+
const MIRROR_PREFIX = 'n-'
|
|
15
|
+
const MDC_EXT = '.mdc'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Керовані дзеркала `.cursor/rules/n-<id>.mdc`, що мають канонічне джерело
|
|
19
|
+
* `npm/rules/<id>/<id>.mdc`. Дзеркала без канону (зовнішні) пропускаються.
|
|
20
|
+
* @param {string} repoRoot корінь репо
|
|
21
|
+
* @returns {{ id: string, mirrorPath: string, canonicalPath: string }[]} список
|
|
22
|
+
*/
|
|
23
|
+
export function listManagedMirrors(repoRoot) {
|
|
24
|
+
const rulesDir = join(repoRoot, '.cursor/rules')
|
|
25
|
+
if (!existsSync(rulesDir)) return []
|
|
26
|
+
return readdirSync(rulesDir)
|
|
27
|
+
.filter(f => f.startsWith(MIRROR_PREFIX) && f.endsWith(MDC_EXT))
|
|
28
|
+
.map(f => {
|
|
29
|
+
const id = f.slice(MIRROR_PREFIX.length, -MDC_EXT.length)
|
|
30
|
+
return {
|
|
31
|
+
id,
|
|
32
|
+
mirrorPath: join(rulesDir, f),
|
|
33
|
+
canonicalPath: join(repoRoot, 'npm/rules', id, `main${MDC_EXT}`)
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
.filter(m => existsSync(m.canonicalPath))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Очікуваний вміст дзеркала = канон з inlined-шаблонами (трансформ синку).
|
|
41
|
+
* @param {string} canonicalPath абсолютний шлях `npm/rules/<id>/<id>.mdc`
|
|
42
|
+
* @returns {Promise<string>} очікуваний текст дзеркала
|
|
43
|
+
*/
|
|
44
|
+
export async function expectedMirrorContent(canonicalPath) {
|
|
45
|
+
const dir = dirname(canonicalPath)
|
|
46
|
+
const withTemplates = await inlineTemplateLinks(readFileSync(canonicalPath, 'utf8'), dir)
|
|
47
|
+
return appendDiscoveredMdcFiles(withTemplates, dir)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Id дзеркал, що розійшлися з каноном (actual ≠ expected).
|
|
52
|
+
* @param {string} repoRoot корінь репо
|
|
53
|
+
* @returns {Promise<string[]>} відсортовані id дрейфу
|
|
54
|
+
*/
|
|
55
|
+
export async function findMirrorDrift(repoRoot) {
|
|
56
|
+
const drift = []
|
|
57
|
+
for (const m of listManagedMirrors(repoRoot)) {
|
|
58
|
+
const expected = await expectedMirrorContent(m.canonicalPath)
|
|
59
|
+
if (readFileSync(m.mirrorPath, 'utf8') !== expected) drift.push(m.id)
|
|
60
|
+
}
|
|
61
|
+
return drift.toSorted()
|
|
62
|
+
}
|