@thedecipherist/claude-packs 0.0.0-stage → 1.1.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/CHANGELOG.md +754 -0
- package/LICENSE +21 -0
- package/README.md +573 -2
- package/bin/claude-packs.mjs +212 -0
- package/configurations/base/config.json +85 -0
- package/configurations/cpp/config.json +93 -0
- package/configurations/full-stack/config.json +153 -0
- package/configurations/go/config.json +98 -0
- package/configurations/node/config.json +102 -0
- package/configurations/python/config.json +99 -0
- package/configurations/rust/config.json +106 -0
- package/configurations/synth-creator/config.json +148 -0
- package/global/hooks/gnu-shell.mjs +131 -0
- package/global/hooks/lib/shell-writes.mjs +2 -0
- package/global/hooks/shell-traps.mjs +79 -0
- package/global/hooks/version-pin-guard.mjs +280 -0
- package/global/skills/latest-versions/SKILL.md +49 -0
- package/lib/backup.mjs +34 -0
- package/lib/build-queue.mjs +22 -0
- package/lib/claude-md.mjs +60 -0
- package/lib/config-cli.mjs +36 -0
- package/lib/configs.mjs +145 -0
- package/lib/coverage.mjs +94 -0
- package/lib/custom-packs.mjs +93 -0
- package/lib/doctor.mjs +126 -0
- package/lib/fix-plan.mjs +72 -0
- package/lib/found-folders.mjs +25 -0
- package/lib/git-tokens.mjs +64 -0
- package/lib/global.mjs +125 -0
- package/lib/hook-proof.mjs +45 -0
- package/lib/hook-timing.mjs +42 -0
- package/lib/hover-gate.mjs +29 -0
- package/lib/kit-command.mjs +14 -0
- package/lib/kit-lock.mjs +149 -0
- package/lib/layout.mjs +99 -0
- package/lib/logs.mjs +109 -0
- package/lib/manifest.mjs +24 -0
- package/lib/new.mjs +49 -0
- package/lib/once-only-report.mjs +54 -0
- package/lib/pack-manifest.mjs +20 -0
- package/lib/packs.mjs +109 -0
- package/lib/planner.mjs +59 -0
- package/lib/repeats.mjs +65 -0
- package/lib/repo-weight.mjs +28 -0
- package/lib/rule-tests.mjs +42 -0
- package/lib/rules.mjs +40 -0
- package/lib/scan-detect.mjs +130 -0
- package/lib/scan.mjs +171 -0
- package/lib/selftest-cache.mjs +39 -0
- package/lib/settings.mjs +138 -0
- package/lib/shape-cli.mjs +76 -0
- package/lib/shape.mjs +4 -0
- package/lib/suggest.mjs +31 -0
- package/lib/switches.mjs +44 -0
- package/lib/symmetry-doctor.mjs +26 -0
- package/lib/sync.mjs +133 -0
- package/lib/workorder.mjs +26 -0
- package/package.json +34 -4
- package/packs/ai/checks/boundary-computes-its-own-hash.json +30 -0
- package/packs/ai/checks/model-call-needs-boundary.json +29 -0
- package/packs/ai/checks/model-id-from-config.json +28 -0
- package/packs/ai/checks/model-output-validated.json +26 -0
- package/packs/ai/pack.json +38 -0
- package/packs/ai/rules/ai-input-sha-boundary.md +31 -0
- package/packs/ai/rules/llm-pipeline-security.md +26 -0
- package/packs/audio-core/checks/denormals-not-in-prepare.json +12 -0
- package/packs/audio-core/checks/dsp-without-apvts.json +12 -0
- package/packs/audio-core/checks/float-phase-or-rate.json +12 -0
- package/packs/audio-core/checks/juce-snap-to-zero-off.json +12 -0
- package/packs/audio-core/checks/keep-werror.json +12 -0
- package/packs/audio-core/checks/no-fast-math.json +14 -0
- package/packs/audio-core/checks/no-locale-change.json +12 -0
- package/packs/audio-core/checks/no-march-native.json +14 -0
- package/packs/audio-core/clang-tidy +28 -0
- package/packs/audio-core/hooks/lib/realtime-checks.mjs +56 -0
- package/packs/audio-core/hooks/param-id-lock.mjs +172 -0
- package/packs/audio-core/hooks/realtime-guard.mjs +67 -0
- package/packs/audio-core/pack.json +192 -0
- package/packs/audio-core/rules/a-control-is-proved-through-its-input.md +26 -0
- package/packs/audio-core/rules/audio-thread-realtime-safe.md +27 -0
- package/packs/audio-core/rules/audio-ui-thread-handoff.md +21 -0
- package/packs/audio-core/rules/boundary-tests-cross-the-boundary.md +16 -0
- package/packs/audio-core/rules/build-flags-safe.md +20 -0
- package/packs/audio-core/rules/cached-parameter-pointers.md +28 -0
- package/packs/audio-core/rules/clang-tidy-core-guidelines.md +21 -0
- package/packs/audio-core/rules/control-reaches-every-surface.md +23 -0
- package/packs/audio-core/rules/cpu-worst-case-per-block.md +28 -0
- package/packs/audio-core/rules/dc-block-after-asymmetry.md +22 -0
- package/packs/audio-core/rules/discrete-params-snap.md +19 -0
- package/packs/audio-core/rules/double-where-precision-matters.md +20 -0
- package/packs/audio-core/rules/filters-stable-under-modulation.md +29 -0
- package/packs/audio-core/rules/host-parameters-at-scale.md +24 -0
- package/packs/audio-core/rules/house-control-behaviours.md +34 -0
- package/packs/audio-core/rules/math-domain-guards.md +19 -0
- package/packs/audio-core/rules/modulated-delay-interpolation.md +22 -0
- package/packs/audio-core/rules/multiband-phase-coherent.md +22 -0
- package/packs/audio-core/rules/nonlinear-stages-antialiased.md +28 -0
- package/packs/audio-core/rules/note-ledger-and-pedals.md +22 -0
- package/packs/audio-core/rules/one-formula-per-value.md +20 -0
- package/packs/audio-core/rules/optimisations-are-null-tested.md +23 -0
- package/packs/audio-core/rules/oscillators-bandlimited.md +23 -0
- package/packs/audio-core/rules/output-limiter.md +23 -0
- package/packs/audio-core/rules/parameter-ids-never-change.md +20 -0
- package/packs/audio-core/rules/params-and-state-thread-safe.md +19 -0
- package/packs/audio-core/rules/params-snapshot-per-block.md +21 -0
- package/packs/audio-core/rules/patch-excludes-performance-controls.md +18 -0
- package/packs/audio-core/rules/per-sample-code-inlinable.md +22 -0
- package/packs/audio-core/rules/prepare-is-repeatable.md +23 -0
- package/packs/audio-core/rules/recursive-state-nan-guard.md +20 -0
- package/packs/audio-core/rules/reverb-loop-gain-bounded.md +24 -0
- package/packs/audio-core/rules/sample-accurate-midi.md +22 -0
- package/packs/audio-core/rules/sample-rate-and-block-size-from-host.md +23 -0
- package/packs/audio-core/rules/scoped-no-denormals.md +26 -0
- package/packs/audio-core/rules/smooth-continuous-parameters.md +22 -0
- package/packs/audio-core/rules/state-load-versioned-and-safe.md +22 -0
- package/packs/audio-core/rules/straight-on-and-aligned.md +21 -0
- package/packs/audio-core/rules/ui-matches-reference-look.md +23 -0
- package/packs/audio-core/rules/undo-one-gesture-one-step.md +21 -0
- package/packs/audio-core/rules/voice-steal-fades.md +21 -0
- package/packs/audio-core/rules/voice-sum-headroom.md +20 -0
- package/packs/audio-core/skills/analyse-reference-look/SKILL.md +35 -0
- package/packs/audio-core/skills/copy-and-prove/SKILL.md +98 -0
- package/packs/audio-core/skills/juce-realtime-audit/SKILL.md +22 -0
- package/packs/audio-core/skills/measure-tone/SKILL.md +20 -0
- package/packs/audio-core/skills/new-panel-control/SKILL.md +15 -0
- package/packs/audio-core/skills/prove-control/SKILL.md +25 -0
- package/packs/audio-core/skills/trace-parameter/SKILL.md +29 -0
- package/packs/audio-core/tools/lib/spectrum.mjs +112 -0
- package/packs/audio-core/tools/lib/wav.mjs +41 -0
- package/packs/audio-core/tools/tone-report.mjs +47 -0
- package/packs/base/checks/field-map-over-if-runs.json +25 -0
- package/packs/base/checks/lookup-over-if-chains.json +25 -0
- package/packs/base/checks/lookup-over-ternary-chains.json +20 -0
- package/packs/base/checks/no-code-after-midline-comment.json +12 -0
- package/packs/base/checks/one-walk-per-template.json +23 -0
- package/packs/base/checks/stub-reports-success.json +31 -0
- package/packs/base/checks/test-skip-on-failed-setup.json +17 -0
- package/packs/base/hooks/brief-guard.mjs +96 -0
- package/packs/base/hooks/code-shape.mjs +99 -0
- package/packs/base/hooks/dispatch-once.mjs +124 -0
- package/packs/base/hooks/file-size-guard.mjs +61 -0
- package/packs/base/hooks/folder-law.mjs +77 -0
- package/packs/base/hooks/git-guard.mjs +202 -0
- package/packs/base/hooks/lesson-checks.mjs +182 -0
- package/packs/base/hooks/lib/apply-edit.mjs +20 -0
- package/packs/base/hooks/lib/code-shapes.mjs +142 -0
- package/packs/base/hooks/lib/content.mjs +14 -0
- package/packs/base/hooks/lib/cpp-scan.mjs +94 -0
- package/packs/base/hooks/lib/crash-policy.mjs +47 -0
- package/packs/base/hooks/lib/dup-index.mjs +204 -0
- package/packs/base/hooks/lib/dup.mjs +127 -0
- package/packs/base/hooks/lib/elements.mjs +87 -0
- package/packs/base/hooks/lib/event-log.mjs +68 -0
- package/packs/base/hooks/lib/function-shapes.mjs +90 -0
- package/packs/base/hooks/lib/git-adds.mjs +21 -0
- package/packs/base/hooks/lib/git-auth.mjs +44 -0
- package/packs/base/hooks/lib/git-guard-selftest.mjs +192 -0
- package/packs/base/hooks/lib/glob.mjs +33 -0
- package/packs/base/hooks/lib/hook-log.mjs +100 -0
- package/packs/base/hooks/lib/house.py +77 -0
- package/packs/base/hooks/lib/languages.mjs +69 -0
- package/packs/base/hooks/lib/layout.mjs +58 -0
- package/packs/base/hooks/lib/making-check-selftest.mjs +112 -0
- package/packs/base/hooks/lib/near-copies.mjs +76 -0
- package/packs/base/hooks/lib/program-read.mjs +199 -0
- package/packs/base/hooks/lib/program-writes.mjs +177 -0
- package/packs/base/hooks/lib/project.mjs +81 -0
- package/packs/base/hooks/lib/prose.mjs +11 -0
- package/packs/base/hooks/lib/pushed.mjs +201 -0
- package/packs/base/hooks/lib/repo-index.mjs +52 -0
- package/packs/base/hooks/lib/rust-scan.mjs +139 -0
- package/packs/base/hooks/lib/secret-patterns.mjs +18 -0
- package/packs/base/hooks/lib/selftest.mjs +45 -0
- package/packs/base/hooks/lib/shape-code.mjs +126 -0
- package/packs/base/hooks/lib/shape-lists.mjs +31 -0
- package/packs/base/hooks/lib/shape-prose.mjs +78 -0
- package/packs/base/hooks/lib/shape.mjs +273 -0
- package/packs/base/hooks/lib/shell-writes-selftest.mjs +65 -0
- package/packs/base/hooks/lib/shell-writes.mjs +293 -0
- package/packs/base/hooks/lib/turn.mjs +86 -0
- package/packs/base/hooks/lib/unread-writes.mjs +24 -0
- package/packs/base/hooks/lib/writes.mjs +71 -0
- package/packs/base/hooks/making-check.mjs +248 -0
- package/packs/base/hooks/making.mjs +106 -0
- package/packs/base/hooks/once-only.mjs +150 -0
- package/packs/base/hooks/placement-law.mjs +84 -0
- package/packs/base/hooks/repo-litter.mjs +75 -0
- package/packs/base/hooks/reuse-hint.mjs +75 -0
- package/packs/base/hooks/run-hooks.mjs +140 -0
- package/packs/base/hooks/secrets-guard.mjs +99 -0
- package/packs/base/hooks/shape-law.mjs +140 -0
- package/packs/base/hooks/suite-once.mjs +96 -0
- package/packs/base/hooks/template-law.mjs +148 -0
- package/packs/base/hooks/untrusted-boundary.mjs +53 -0
- package/packs/base/pack.json +214 -0
- package/packs/base/rules/a-control-is-seen-to-fire.md +27 -0
- package/packs/base/rules/behaviour-lives-with-its-kind.md +51 -0
- package/packs/base/rules/bug-fix-starts-red.md +25 -0
- package/packs/base/rules/field-map-over-if-runs.md +47 -0
- package/packs/base/rules/finished-work-lands.md +17 -0
- package/packs/base/rules/git-right-first-time.md +19 -0
- package/packs/base/rules/instances-by-index-identities-by-id.md +54 -0
- package/packs/base/rules/lookup-over-if-chains.md +49 -0
- package/packs/base/rules/making-line-first.md +14 -0
- package/packs/base/rules/open-items-tagged.md +17 -0
- package/packs/base/rules/plan-and-logs.md +22 -0
- package/packs/base/rules/references-use-anchors.md +19 -0
- package/packs/base/rules/refusals-are-judged.md +19 -0
- package/packs/base/rules/reuse-before-writing.md +15 -0
- package/packs/base/rules/secrets-never-committed.md +16 -0
- package/packs/base/rules/skill-writing.md +23 -0
- package/packs/base/rules/split-before-the-limit.md +14 -0
- package/packs/base/rules/subagent-dispatch.md +26 -0
- package/packs/base/rules/test-only-what-changed.md +17 -0
- package/packs/base/rules/test-the-template-once.md +23 -0
- package/packs/base/rules/unattended-runs.md +15 -0
- package/packs/base/rules/untrusted-content-boundary.md +15 -0
- package/packs/base/skills/add-lesson-check/SKILL.md +26 -0
- package/packs/base/skills/fix-from-scan/SKILL.md +25 -0
- package/packs/base/skills/land-branch/SKILL.md +24 -0
- package/packs/base/skills/make-it-a-template/SKILL.md +23 -0
- package/packs/base/skills/new-project/SKILL.md +23 -0
- package/packs/base/skills/pdf-to-md/SKILL.md +25 -0
- package/packs/base/skills/pick-tests/SKILL.md +20 -0
- package/packs/base/skills/pressure-test-skill/SKILL.md +23 -0
- package/packs/base/skills/prove-instances-identical/SKILL.md +37 -0
- package/packs/base/skills/write-a-workorder/SKILL.md +41 -0
- package/packs/base/tools/shape-symmetry-selftest.mjs +66 -0
- package/packs/base/tools/shape-symmetry.mjs +178 -0
- package/packs/base/tools/test-verdict.mjs +75 -0
- package/packs/ci/checks/ci-permissions-stated.json +18 -0
- package/packs/ci/checks/ci-tools-pinned.json +14 -0
- package/packs/ci/pack.json +21 -0
- package/packs/ci/rules/ci-covers-what-ships.md +20 -0
- package/packs/ci/rules/generated-files-have-no-diff.md +15 -0
- package/packs/content-site/checks/captcha-is-not-constant.json +27 -0
- package/packs/content-site/checks/img-has-size.json +20 -0
- package/packs/content-site/checks/page-head-complete.json +26 -0
- package/packs/content-site/pack.json +22 -0
- package/packs/content-site/rules/content-has-one-source.md +23 -0
- package/packs/content-site/rules/media-is-sized.md +24 -0
- package/packs/content-site/rules/page-head-is-complete.md +26 -0
- package/packs/content-site/rules/public-forms-are-defended.md +27 -0
- package/packs/content-site/skills/publish-a-page/SKILL.md +21 -0
- package/packs/cpp/checks/cpp-clamp-before-cast.json +16 -0
- package/packs/cpp/checks/cpp-find-with-the-library.json +12 -0
- package/packs/cpp/checks/cpp-hardened-test-build.json +18 -0
- package/packs/cpp/checks/cpp-m-pi-not-standard.json +23 -0
- package/packs/cpp/checks/cpp-no-atoi.json +16 -0
- package/packs/cpp/checks/cpp-no-const-cast.json +16 -0
- package/packs/cpp/checks/cpp-no-float-loop-counter.json +16 -0
- package/packs/cpp/checks/cpp-no-getenv-in-product.json +22 -0
- package/packs/cpp/checks/cpp-no-mutable-global.json +20 -0
- package/packs/cpp/checks/cpp-no-mutable-local-static.json +23 -0
- package/packs/cpp/checks/cpp-no-unchecked-fwrite.json +17 -0
- package/packs/cpp/checks/cpp-no-using-namespace-in-header.json +19 -0
- package/packs/cpp/checks/cpp-no-zero-size-array.json +23 -0
- package/packs/cpp/checks/cpp-numbers-pi.json +16 -0
- package/packs/cpp/pack.json +22 -0
- package/packs/cpp/rules/cpp-absent-and-failed-are-types.md +24 -0
- package/packs/cpp/rules/cpp-builds-everywhere.md +26 -0
- package/packs/cpp/rules/cpp-faults-only-in-the-test-build.md +21 -0
- package/packs/cpp/rules/cpp-find-with-the-library.md +19 -0
- package/packs/cpp/rules/cpp-gates-share-one-reader.md +22 -0
- package/packs/cpp/rules/cpp-headers-declare.md +22 -0
- package/packs/cpp/rules/cpp-numbers-and-casts.md +22 -0
- package/packs/cpp/rules/cpp-repeats-become-templates.md +33 -0
- package/packs/cpp/rules/cpp-static-analysis-runs.md +22 -0
- package/packs/cpp/rules/cpp-thread-contracts-are-code.md +23 -0
- package/packs/cpp/skills/cpp-extract-template/SKILL.md +38 -0
- package/packs/docker/checks/alpine-with-native-build.json +13 -0
- package/packs/docker/checks/compose-db-needs-auth.json +14 -0
- package/packs/docker/checks/compose-image-pinned.json +14 -0
- package/packs/docker/checks/compose-no-hardcoded-ip.json +12 -0
- package/packs/docker/checks/compose-no-host-bind-for-data.json +18 -0
- package/packs/docker/checks/compose-no-plaintext-secret.json +13 -0
- package/packs/docker/checks/compose-no-swarm-ignored-keys.json +13 -0
- package/packs/docker/checks/compose-overlay-not-bridge.json +13 -0
- package/packs/docker/checks/compose-service-needs-healthcheck.json +11 -0
- package/packs/docker/checks/compose-service-needs-init.json +11 -0
- package/packs/docker/checks/copy-needs-chown-with-user.json +17 -0
- package/packs/docker/checks/copy-source-before-deps.json +13 -0
- package/packs/docker/checks/docker-exec-form.json +16 -0
- package/packs/docker/checks/dockerfile-needs-healthcheck.json +17 -0
- package/packs/docker/checks/dockerfile-needs-user.json +21 -0
- package/packs/docker/checks/dockerignore-has-the-basics.json +21 -0
- package/packs/docker/checks/gitattributes-forces-lf.json +17 -0
- package/packs/docker/checks/health-checks-nothing.json +25 -0
- package/packs/docker/checks/no-crlf-in-scripts.json +15 -0
- package/packs/docker/checks/no-latest-base.json +13 -0
- package/packs/docker/checks/no-secret-in-image.json +13 -0
- package/packs/docker/checks/no-sensitive-file-copy.json +13 -0
- package/packs/docker/checks/node-env-before-install.json +13 -0
- package/packs/docker/checks/npm-ci-not-install.json +13 -0
- package/packs/docker/pack.json +46 -0
- package/packs/docker/rules/compose-pinned-and-closed.md +21 -0
- package/packs/docker/rules/compose-swarm-safe.md +26 -0
- package/packs/docker/rules/docker-exec-form.md +19 -0
- package/packs/docker/rules/dockerfile-multistage.md +13 -0
- package/packs/docker/rules/dockerfile-production.md +25 -0
- package/packs/docker/skills/docker-diagnose/SKILL.md +23 -0
- package/packs/dynamic-data/checks/draft-on-the-server.json +27 -0
- package/packs/dynamic-data/checks/guard-does-its-job.json +28 -0
- package/packs/dynamic-data/checks/key-is-not-a-display-name.json +28 -0
- package/packs/dynamic-data/checks/no-code-from-data.json +29 -0
- package/packs/dynamic-data/checks/no-collection-from-request.json +27 -0
- package/packs/dynamic-data/checks/no-pipeline-from-stored-text.json +27 -0
- package/packs/dynamic-data/checks/no-regexp-from-stored-config.json +27 -0
- package/packs/dynamic-data/checks/no-template-from-stored-text.json +27 -0
- package/packs/dynamic-data/checks/save-takes-named-paths.json +27 -0
- package/packs/dynamic-data/pack.json +23 -0
- package/packs/dynamic-data/rules/a-list-is-a-saved-query.md +23 -0
- package/packs/dynamic-data/rules/definitions-are-validated-data.md +24 -0
- package/packs/dynamic-data/rules/every-dynamic-surface-has-a-boundary.md +29 -0
- package/packs/dynamic-data/rules/fields-have-owners.md +22 -0
- package/packs/dynamic-data/rules/imports-drop-nothing.md +26 -0
- package/packs/dynamic-data/rules/one-definition-many-surfaces.md +24 -0
- package/packs/dynamic-data/rules/one-fact-one-place.md +28 -0
- package/packs/dynamic-data/rules/rules-live-in-the-engine.md +29 -0
- package/packs/dynamic-data/rules/saves-are-patches.md +28 -0
- package/packs/dynamic-data/rules/tenant-costs-one-document.md +22 -0
- package/packs/dynamic-data/skills/design-a-definition/SKILL.md +24 -0
- package/packs/fastify/checks/api-routes-versioned.json +28 -0
- package/packs/fastify/checks/cookie-host-prefix.json +24 -0
- package/packs/fastify/checks/hijack-needs-try.json +28 -0
- package/packs/fastify/checks/no-cast-at-route-boundary.json +24 -0
- package/packs/fastify/checks/no-db-in-route-file.json +28 -0
- package/packs/fastify/checks/no-err-message-to-client.json +24 -0
- package/packs/fastify/checks/no-regexp-from-input.json +24 -0
- package/packs/fastify/checks/no-trust-proxy-true.json +25 -0
- package/packs/fastify/checks/one-error-body.json +26 -0
- package/packs/fastify/checks/origin-from-config-not-host.json +31 -0
- package/packs/fastify/checks/password-needs-slow-hash.json +30 -0
- package/packs/fastify/checks/sec-headers-present.json +28 -0
- package/packs/fastify/checks/secrets-compared-constant-time.json +24 -0
- package/packs/fastify/checks/sse-needs-error-listener.json +28 -0
- package/packs/fastify/checks/user-bytes-need-disposition.json +29 -0
- package/packs/fastify/pack.json +41 -0
- package/packs/fastify/rules/credentials-and-input.md +23 -0
- package/packs/fastify/rules/security-one-switch.md +28 -0
- package/packs/fastify/rules/streams-and-hijacks.md +22 -0
- package/packs/fastify/rules/tests-use-inject.md +13 -0
- package/packs/fastify/rules/three-layers.md +20 -0
- package/packs/fastify/rules/trust-config-not-headers.md +24 -0
- package/packs/full-stack/checks/no-express-no-vite.json +23 -0
- package/packs/full-stack/hooks/stack-guard.mjs +90 -0
- package/packs/full-stack/pack.json +76 -0
- package/packs/full-stack/rules/stack-is-fastify-and-nextjs.md +20 -0
- package/packs/go/checks/go-exec-result-ignored.json +15 -0
- package/packs/go/checks/go-unmarshal-error-ignored.json +15 -0
- package/packs/go/pack.json +26 -0
- package/packs/go/rules/go-errors-are-handled.md +22 -0
- package/packs/gpu-painter/checks/dawn-backends-and-validation.json +9 -0
- package/packs/gpu-painter/checks/dawn-no-spontaneous.json +10 -0
- package/packs/gpu-painter/checks/dawn-present-on-render-thread.json +17 -0
- package/packs/gpu-painter/checks/gpu-no-frame-stalls.json +12 -0
- package/packs/gpu-painter/checks/no-opengl-link.json +11 -0
- package/packs/gpu-painter/checks/no-opengl.json +13 -0
- package/packs/gpu-painter/hooks/browser-guard.py +196 -0
- package/packs/gpu-painter/pack.json +91 -0
- package/packs/gpu-painter/rules/dawn-build-and-shaders.md +27 -0
- package/packs/gpu-painter/rules/dawn-device-and-render-thread.md +26 -0
- package/packs/gpu-painter/rules/gpu-antialiasing.md +20 -0
- package/packs/gpu-painter/rules/gpu-blend-order.md +22 -0
- package/packs/gpu-painter/rules/gpu-bloom.md +20 -0
- package/packs/gpu-painter/rules/gpu-frame-budget.md +25 -0
- package/packs/gpu-painter/rules/gpu-frame-pacing-and-power.md +27 -0
- package/packs/gpu-painter/rules/gpu-frame-work.md +30 -0
- package/packs/gpu-painter/rules/gpu-golden-images.md +21 -0
- package/packs/gpu-painter/rules/gpu-hdr-and-tonemap.md +23 -0
- package/packs/gpu-painter/rules/gpu-picking-on-cpu.md +19 -0
- package/packs/gpu-painter/rules/gpu-render-lifecycle.md +25 -0
- package/packs/gpu-painter/rules/gpu-text-atlas.md +24 -0
- package/packs/gpu-painter/rules/gpu-travellers-from-snapshot.md +24 -0
- package/packs/gpu-painter/rules/hover-every-pressable.md +25 -0
- package/packs/gpu-painter/skills/gpu-capture/SKILL.md +15 -0
- package/packs/gpu-painter/skills/gpu-frame-bench/SKILL.md +14 -0
- package/packs/gpu-painter/skills/gpu-golden-check/SKILL.md +13 -0
- package/packs/gpu-painter/skills/gpu-golden-update/SKILL.md +16 -0
- package/packs/gpu-painter/skills/gpu-lifecycle-stress/SKILL.md +15 -0
- package/packs/gpu-painter/skills/hover-state/SKILL.md +33 -0
- package/packs/hook-proof/checks/hook-catch-must-not-allow.json +16 -0
- package/packs/hook-proof/checks/hook-command-no-pipe.json +16 -0
- package/packs/hook-proof/checks/hook-exit-1-does-not-block.json +17 -0
- package/packs/hook-proof/checks/hook-no-or-true.json +18 -0
- package/packs/hook-proof/checks/hook-refusal-on-stderr.json +17 -0
- package/packs/hook-proof/pack.json +38 -0
- package/packs/hook-proof/rules/a-refusal-is-exit-2.md +28 -0
- package/packs/hook-proof/skills/prove-a-hook/SKILL.md +21 -0
- package/packs/host-agent/checks/file-path-from-param.json +27 -0
- package/packs/host-agent/checks/integrity-check-optional.json +27 -0
- package/packs/host-agent/checks/quoted-value-into-config.json +24 -0
- package/packs/host-agent/checks/secret-on-argv.json +28 -0
- package/packs/host-agent/checks/ssh-verifies-host-key.json +27 -0
- package/packs/host-agent/checks/system-file-written-in-place.json +26 -0
- package/packs/host-agent/checks/tmp-path-predictable.json +27 -0
- package/packs/host-agent/pack.json +22 -0
- package/packs/host-agent/rules/root-on-other-machines.md +27 -0
- package/packs/html-ui/checks/email-html-escapes.json +25 -0
- package/packs/html-ui/checks/external-link-rel.json +21 -0
- package/packs/html-ui/checks/no-duplicate-escape.json +26 -0
- package/packs/html-ui/checks/no-inline-client-script.json +21 -0
- package/packs/html-ui/checks/no-inline-style.json +23 -0
- package/packs/html-ui/pack.json +33 -0
- package/packs/html-ui/rules/email-html-escapes.md +19 -0
- package/packs/html-ui/rules/server-html-escapes-everything.md +22 -0
- package/packs/http-api/checks/api-path-versioned.json +31 -0
- package/packs/http-api/checks/authz-from-request-body.json +26 -0
- package/packs/http-api/checks/client-calls-a-version.json +28 -0
- package/packs/http-api/checks/client-ip-not-leftmost-xff.json +28 -0
- package/packs/http-api/checks/cors-needs-origin.json +26 -0
- package/packs/http-api/checks/csp-not-switched-off.json +28 -0
- package/packs/http-api/checks/debug-route-not-shipped.json +26 -0
- package/packs/http-api/checks/encrypted-name-plaintext-value.json +26 -0
- package/packs/http-api/checks/err-text-stays-server-side.json +27 -0
- package/packs/http-api/checks/failure-is-not-empty.json +28 -0
- package/packs/http-api/checks/gate-is-not-a-todo.json +27 -0
- package/packs/http-api/checks/guard-fails-open.json +28 -0
- package/packs/http-api/checks/hmac-over-reserialised-body.json +26 -0
- package/packs/http-api/checks/jwt-verify-pins-algorithm.json +26 -0
- package/packs/http-api/checks/middleware-skips-without-user.json +26 -0
- package/packs/http-api/checks/next-api-route-versioned.json +47 -0
- package/packs/http-api/checks/no-security-off-switch.json +28 -0
- package/packs/http-api/checks/oauth-state-signed.json +26 -0
- package/packs/http-api/checks/one-time-code-compared-raw.json +26 -0
- package/packs/http-api/checks/query-cast-is-not-validation.json +28 -0
- package/packs/http-api/checks/queue-action-from-client.json +26 -0
- package/packs/http-api/checks/rate-limit-one-module.json +28 -0
- package/packs/http-api/checks/role-checked-in-one-guard.json +27 -0
- package/packs/http-api/checks/route-body-needs-schema.json +31 -0
- package/packs/http-api/checks/route-scopes-to-the-caller.json +31 -0
- package/packs/http-api/checks/secret-compared-constant-time-any.json +28 -0
- package/packs/http-api/checks/secret-in-job-record.json +27 -0
- package/packs/http-api/checks/server-fetches-tenant-url.json +30 -0
- package/packs/http-api/checks/short-code-needs-limit.json +26 -0
- package/packs/http-api/checks/user-url-through-safe-fetch.json +28 -0
- package/packs/http-api/checks/webhook-dedupes-event-id.json +30 -0
- package/packs/http-api/pack.json +45 -0
- package/packs/http-api/rules/adapters-one-db-gateway.md +18 -0
- package/packs/http-api/rules/apis-are-versioned.md +27 -0
- package/packs/http-api/rules/credentials-handled-safely.md +22 -0
- package/packs/http-api/rules/handlers-own-the-work.md +17 -0
- package/packs/http-api/rules/health-and-correlation.md +17 -0
- package/packs/http-api/rules/one-error-contract.md +17 -0
- package/packs/http-api/rules/routes-are-thin.md +17 -0
- package/packs/http-api/rules/routes-scope-to-the-caller.md +26 -0
- package/packs/http-api/rules/routes-validate-and-answer.md +25 -0
- package/packs/http-api/skills/change-an-api/SKILL.md +20 -0
- package/packs/http-api/skills/secure-a-route/SKILL.md +21 -0
- package/packs/instrument-shell/checks/no-raw-struct-blob.json +23 -0
- package/packs/instrument-shell/pack.json +22 -0
- package/packs/instrument-shell/rules/fold-keeps-every-route.md +24 -0
- package/packs/instrument-shell/rules/quiet-announces-itself.md +22 -0
- package/packs/instrument-shell/rules/render-the-extremes.md +25 -0
- package/packs/instrument-shell/rules/seams-are-declared.md +27 -0
- package/packs/instrument-shell/rules/session-blob-append-only.md +25 -0
- package/packs/instrument-shell/skills/gates-from-commit-one/SKILL.md +20 -0
- package/packs/instrument-shell/skills/hit-the-painted-control/SKILL.md +18 -0
- package/packs/js-ts/checks/async-callback-unguarded.json +26 -0
- package/packs/js-ts/checks/background-loop-needs-stop.json +28 -0
- package/packs/js-ts/checks/child-process-error-handler.json +28 -0
- package/packs/js-ts/checks/entry-registers-shutdown.json +31 -0
- package/packs/js-ts/checks/fetch-needs-timeout.json +30 -0
- package/packs/js-ts/checks/job-only-in-memory.json +28 -0
- package/packs/js-ts/checks/json-only-through-helper.json +29 -0
- package/packs/js-ts/checks/line-under-200-chars.json +34 -0
- package/packs/js-ts/checks/localhost-default-in-server.json +29 -0
- package/packs/js-ts/checks/no-any.json +27 -0
- package/packs/js-ts/checks/no-cast-escape-hatches.json +24 -0
- package/packs/js-ts/checks/no-console-in-app.json +31 -0
- package/packs/js-ts/checks/no-dynamic-import-node-builtin.json +25 -0
- package/packs/js-ts/checks/no-inline-binary.json +20 -0
- package/packs/js-ts/checks/no-inline-zod-outside-schemas.json +27 -0
- package/packs/js-ts/checks/no-local-sleep.json +25 -0
- package/packs/js-ts/checks/no-nested-ternary.json +20 -0
- package/packs/js-ts/checks/no-secret-in-log.json +24 -0
- package/packs/js-ts/checks/no-shell-string-interpolation.json +24 -0
- package/packs/js-ts/checks/no-swallowed-errors.json +25 -0
- package/packs/js-ts/checks/no-ts-enum.json +20 -0
- package/packs/js-ts/checks/process-env-only-in-config.json +31 -0
- package/packs/js-ts/checks/race-leaves-work-running.json +23 -0
- package/packs/js-ts/checks/reject-as-catch-all-exists.json +24 -0
- package/packs/js-ts/checks/secret-has-no-fallback.json +24 -0
- package/packs/js-ts/checks/secret-needs-crypto-random.json +24 -0
- package/packs/js-ts/checks/server-close-awaited.json +27 -0
- package/packs/js-ts/checks/session-user-typed-once.json +24 -0
- package/packs/js-ts/checks/switch-is-a-table.json +24 -0
- package/packs/js-ts/checks/test-imports-the-source.json +19 -0
- package/packs/js-ts/checks/test-name-says-behaviour.json +16 -0
- package/packs/js-ts/checks/tsconfig-flags.json +21 -0
- package/packs/js-ts/checks/void-needs-catch.json +24 -0
- package/packs/js-ts/checks/zod-string-needs-max.json +25 -0
- package/packs/js-ts/checks/zod-v4-formats.json +23 -0
- package/packs/js-ts/pack.json +84 -0
- package/packs/js-ts/rules/await-handled-at-a-boundary.md +66 -0
- package/packs/js-ts/rules/env-through-config.md +36 -0
- package/packs/js-ts/rules/errors-never-swallowed.md +33 -0
- package/packs/js-ts/rules/files-under-300-lines.md +18 -0
- package/packs/js-ts/rules/guard-clauses-over-nesting.md +34 -0
- package/packs/js-ts/rules/js-repeats-become-templates.md +26 -0
- package/packs/js-ts/rules/json-only-through-one-helper.md +62 -0
- package/packs/js-ts/rules/named-constants-not-magic-numbers.md +34 -0
- package/packs/js-ts/rules/no-any.md +34 -0
- package/packs/js-ts/rules/no-console.md +30 -0
- package/packs/js-ts/rules/no-floating-promises.md +31 -0
- package/packs/js-ts/rules/no-param-mutation.md +28 -0
- package/packs/js-ts/rules/no-unsafe-assertions.md +30 -0
- package/packs/js-ts/rules/one-logger.md +24 -0
- package/packs/js-ts/rules/outbound-calls-have-a-limit.md +20 -0
- package/packs/js-ts/rules/parallel-independent-awaits.md +29 -0
- package/packs/js-ts/rules/process-lifecycle.md +47 -0
- package/packs/js-ts/rules/schema-single-source-of-truth.md +36 -0
- package/packs/js-ts/rules/secrets-stay-secret.md +22 -0
- package/packs/js-ts/rules/small-functions.md +20 -0
- package/packs/js-ts/rules/test-names-describe-behavior.md +28 -0
- package/packs/js-ts/rules/tests-can-fail.md +19 -0
- package/packs/js-ts/rules/tsconfig-strict.md +32 -0
- package/packs/js-ts/rules/typed-exports.md +27 -0
- package/packs/js-ts/rules/types-once-at-the-edge.md +18 -0
- package/packs/js-ts/rules/unions-over-enums.md +29 -0
- package/packs/js-ts/rules/zod-at-route-boundaries.md +40 -0
- package/packs/midi/checks/active-sensing-no-pulse.json +24 -0
- package/packs/midi/checks/clock-not-at-sample-zero.json +23 -0
- package/packs/midi/checks/midi-realtime-first.json +27 -0
- package/packs/midi/checks/no-tempo-writeback.json +23 -0
- package/packs/midi/checks/position-not-integrated.json +29 -0
- package/packs/midi/checks/stub-playhead-advances.json +27 -0
- package/packs/midi/checks/sysex-length-literal.json +23 -0
- package/packs/midi/checks/sysex-not-on-audio.json +24 -0
- package/packs/midi/checks/sysex-survives-realtime.json +27 -0
- package/packs/midi/pack.json +22 -0
- package/packs/midi/rules/clock-is-a-pulse-stream.md +30 -0
- package/packs/midi/rules/imports-count-every-loss.md +25 -0
- package/packs/midi/rules/measure-the-clock-in-audio.md +30 -0
- package/packs/midi/rules/sync-is-a-mode.md +29 -0
- package/packs/midi/rules/sysex-is-a-record.md +29 -0
- package/packs/midi/skills/clock-probe/SKILL.md +23 -0
- package/packs/midi/skills/clock-probe/clock-law.md +417 -0
- package/packs/midi/skills/does-it-sync/SKILL.md +19 -0
- package/packs/mongo/checks/bulk-over-many.json +28 -0
- package/packs/mongo/checks/created-at-immutable.json +25 -0
- package/packs/mongo/checks/driver-outside-gateway.json +24 -0
- package/packs/mongo/checks/key-lookup-is-hashed.json +24 -0
- package/packs/mongo/checks/mongoclient-cached-and-named.json +34 -0
- package/packs/mongo/checks/mongoclient-outside-gateway.json +24 -0
- package/packs/mongo/checks/no-count-plus-one-ids.json +25 -0
- package/packs/mongo/checks/no-db-write-in-loop.json +25 -0
- package/packs/mongo/checks/no-drop-in-code.json +27 -0
- package/packs/mongo/checks/no-empty-deletemany.json +26 -0
- package/packs/mongo/checks/no-find-reads.json +26 -0
- package/packs/mongo/checks/no-input-spread-into-write.json +24 -0
- package/packs/mongo/checks/no-mongoose.json +23 -0
- package/packs/mongo/checks/no-negation-delete.json +26 -0
- package/packs/mongo/checks/no-non-null-after-findone.json +25 -0
- package/packs/mongo/checks/objectid-equals.json +26 -0
- package/packs/mongo/checks/update-then-reread.json +24 -0
- package/packs/mongo/checks/watch-not-poll.json +25 -0
- package/packs/mongo/pack.json +52 -0
- package/packs/mongo/rules/deletes-name-what-dies.md +21 -0
- package/packs/mongo/rules/driver-only-in-gateway.md +26 -0
- package/packs/mongo/rules/keys-hashed-input-picked.md +21 -0
- package/packs/mongo/rules/one-client-one-pool.md +32 -0
- package/packs/mongo/rules/reads-aggregate-writes-bulk.md +25 -0
- package/packs/mongo/rules/writes-are-atomic.md +27 -0
- package/packs/multi-tenant/checks/role-sees-all-tenants.json +26 -0
- package/packs/multi-tenant/checks/tenant-filter-from-url.json +25 -0
- package/packs/multi-tenant/pack.json +22 -0
- package/packs/multi-tenant/rules/no-role-crosses-a-tenant.md +21 -0
- package/packs/multi-tenant/skills/prove-tenant-isolation/SKILL.md +19 -0
- package/packs/nginx/checks/modsec-no-blanket-off.json +16 -0
- package/packs/nginx/checks/nginx-csp-no-unsafe.json +15 -0
- package/packs/nginx/checks/nginx-headers-always.json +15 -0
- package/packs/nginx/checks/nginx-keepalive-http11.json +20 -0
- package/packs/nginx/checks/nginx-logs-to-stdout.json +15 -0
- package/packs/nginx/checks/nginx-no-crlf.json +17 -0
- package/packs/nginx/checks/nginx-resolver-ttl.json +19 -0
- package/packs/nginx/pack.json +43 -0
- package/packs/nginx/rules/modsecurity-tuning.md +22 -0
- package/packs/nginx/rules/nginx-production.md +26 -0
- package/packs/nginx/skills/waf-rollout/SKILL.md +20 -0
- package/packs/postgres/checks/pg-bind-values.json +33 -0
- package/packs/postgres/checks/pg-concurrently-in-txn.json +18 -0
- package/packs/postgres/checks/pg-fk-not-valid.json +18 -0
- package/packs/postgres/checks/pg-index-concurrently.json +18 -0
- package/packs/postgres/checks/pg-no-float-money.json +19 -0
- package/packs/postgres/checks/pg-no-money.json +18 -0
- package/packs/postgres/checks/pg-no-required-column.json +18 -0
- package/packs/postgres/checks/pg-no-volatile-default.json +18 -0
- package/packs/postgres/checks/pg-not-exists.json +18 -0
- package/packs/postgres/checks/pg-timestamptz.json +18 -0
- package/packs/postgres/hooks/db-wipe-guard.mjs +95 -0
- package/packs/postgres/pack.json +48 -0
- package/packs/postgres/rules/postgres-migrations-never-stop-traffic.md +28 -0
- package/packs/postgres/rules/postgres-one-pool-per-process.md +21 -0
- package/packs/postgres/rules/postgres-queries-are-null-safe-and-bounded.md +26 -0
- package/packs/postgres/rules/postgres-types-say-what-they-hold.md +22 -0
- package/packs/postgres/rules/postgres-values-are-bound.md +130 -0
- package/packs/postgres/skills/postgres-safe-migration/SKILL.md +45 -0
- package/packs/python/checks/py-no-bare-except.json +18 -0
- package/packs/python/checks/py-no-eval.json +18 -0
- package/packs/python/checks/py-no-mutable-default.json +18 -0
- package/packs/python/checks/py-no-shell-true.json +18 -0
- package/packs/python/checks/py-no-star-import.json +18 -0
- package/packs/python/checks/py-no-swallowed-exception.json +18 -0
- package/packs/python/checks/py-none-by-is.json +18 -0
- package/packs/python/checks/py-open-with-with.json +18 -0
- package/packs/python/checks/py-requests-timeout.json +18 -0
- package/packs/python/checks/py-subprocess-output-checked.json +18 -0
- package/packs/python/checks/py-yaml-safe-load.json +18 -0
- package/packs/python/pack.json +26 -0
- package/packs/python/rules/python-errors-and-resources.md +26 -0
- package/packs/python/rules/python-repeats-become-templates.md +27 -0
- package/packs/python/skills/python-extract-template/SKILL.md +35 -0
- package/packs/react/checks/dialog-needs-role.json +28 -0
- package/packs/react/checks/effect-not-for-derived-state.json +24 -0
- package/packs/react/checks/icon-button-needs-name.json +24 -0
- package/packs/react/checks/label-needs-a-field.json +24 -0
- package/packs/react/checks/ui-failed-fetch-says-so.json +23 -0
- package/packs/react/checks/ui-ok-branch-has-an-else.json +23 -0
- package/packs/react/pack.json +20 -0
- package/packs/react/rules/react-accessible-controls.md +20 -0
- package/packs/react/rules/react-state-and-effects.md +23 -0
- package/packs/reverse-engineering/checks/ear-constant-tagged.json +23 -0
- package/packs/reverse-engineering/checks/no-default-on-distrust.json +24 -0
- package/packs/reverse-engineering/checks/no-rom-table-literal.json +29 -0
- package/packs/reverse-engineering/checks/prose-never-decides.json +22 -0
- package/packs/reverse-engineering/hooks/firmware-out-of-git.mjs +49 -0
- package/packs/reverse-engineering/pack.json +35 -0
- package/packs/reverse-engineering/rules/a-negative-names-what-was-scanned.md +19 -0
- package/packs/reverse-engineering/rules/account-every-term.md +20 -0
- package/packs/reverse-engineering/rules/addresses-name-their-space.md +22 -0
- package/packs/reverse-engineering/rules/every-law-has-a-source.md +18 -0
- package/packs/reverse-engineering/rules/findings-are-withdrawn-in-place.md +17 -0
- package/packs/reverse-engineering/rules/firmware-stays-out.md +18 -0
- package/packs/reverse-engineering/rules/names-before-code.md +19 -0
- package/packs/reverse-engineering/rules/reproduction-or-original.md +18 -0
- package/packs/reverse-engineering/rules/two-sources-before-naming.md +21 -0
- package/packs/reverse-engineering/skills/bank-census/SKILL.md +18 -0
- package/packs/reverse-engineering/skills/gather-sources/SKILL.md +22 -0
- package/packs/reverse-engineering/skills/menu-map/SKILL.md +28 -0
- package/packs/reverse-engineering/skills/names-first/SKILL.md +41 -0
- package/packs/reverse-engineering/skills/re-deliverables/SKILL.md +21 -0
- package/packs/reverse-engineering/skills/tripwire-the-law/SKILL.md +19 -0
- package/packs/reverse-engineering/tools/lib/unwrap.mjs +115 -0
- package/packs/reverse-engineering/tools/names-sweep.mjs +264 -0
- package/packs/rust/checks/rust-allow-needs-reason.json +16 -0
- package/packs/rust/checks/rust-blocking-in-async.json +32 -0
- package/packs/rust/checks/rust-if-chain-is-a-match.json +32 -0
- package/packs/rust/checks/rust-static-mut.json +32 -0
- package/packs/rust/checks/rust-string-as-error.json +34 -0
- package/packs/rust/checks/rust-stub-left-in.json +32 -0
- package/packs/rust/checks/rust-unsafe-needs-safety.json +31 -0
- package/packs/rust/checks/rust-unwrap-in-library.json +34 -0
- package/packs/rust/checks/rust-wildcard-dependency.json +16 -0
- package/packs/rust/clippy.toml +5 -0
- package/packs/rust/pack.json +27 -0
- package/packs/rust/rules/rust-async-never-blocks.md +20 -0
- package/packs/rust/rules/rust-borrow-before-you-clone.md +19 -0
- package/packs/rust/rules/rust-errors-are-returned.md +22 -0
- package/packs/rust/rules/rust-lints-are-the-gate.md +23 -0
- package/packs/rust/rules/rust-repeats-become-templates.md +28 -0
- package/packs/rust/rules/rust-unsafe-is-proved.md +21 -0
- package/packs/rust/skills/rust-extract-template/SKILL.md +50 -0
- package/packs/rust/skills/rust-port/SKILL.md +22 -0
- package/packs/rust/skills/rust-review/SKILL.md +24 -0
- package/packs/rust/tools/rust-lints.toml +19 -0
- package/packs/shell/checks/sh-mktemp.json +18 -0
- package/packs/shell/checks/sh-no-backticks.json +18 -0
- package/packs/shell/checks/sh-no-eval.json +18 -0
- package/packs/shell/checks/sh-no-parse-ls.json +18 -0
- package/packs/shell/checks/sh-no-pipe-to-shell.json +18 -0
- package/packs/shell/checks/sh-no-program-in-heredoc.json +18 -0
- package/packs/shell/checks/sh-quote-arguments.json +18 -0
- package/packs/shell/checks/sh-rm-guarded.json +18 -0
- package/packs/shell/checks/sh-strict-mode.json +20 -0
- package/packs/shell/pack.json +28 -0
- package/packs/shell/rules/shell-repeats-become-templates.md +23 -0
- package/packs/shell/rules/shell-strict-and-quoted.md +27 -0
- package/packs/shell/skills/shell-extract-template/SKILL.md +32 -0
- package/packs/shell-hooks/checks/gnu-only-in-shell.json +18 -0
- package/packs/shell-hooks/checks/hook-command-anchored.json +12 -0
- package/packs/shell-hooks/checks/hook-json-by-tool.json +18 -0
- package/packs/shell-hooks/checks/no-bash-c-with-variable.json +20 -0
- package/packs/shell-hooks/pack.json +36 -0
- package/packs/shell-hooks/rules/hooks-portable-anchored-quoted.md +26 -0
- package/packs/sound-design/checks/audio-seed-fixed.json +23 -0
- package/packs/sound-design/checks/mix-is-a-crossfade.json +30 -0
- package/packs/sound-design/checks/no-hash-in-the-signal.json +30 -0
- package/packs/sound-design/checks/no-literal-key-anchor.json +30 -0
- package/packs/sound-design/checks/test-compares-a-function-with-itself.json +22 -0
- package/packs/sound-design/pack.json +22 -0
- package/packs/sound-design/rules/algorithms-are-data.md +26 -0
- package/packs/sound-design/rules/meter-before-engine.md +27 -0
- package/packs/sound-design/rules/neutral-is-exact.md +26 -0
- package/packs/sound-design/rules/test-off-the-easy-point.md +28 -0
- package/packs/sound-design/rules/unreachable-is-said.md +25 -0
- package/packs/sound-design/rules/waveforms-and-octaves.md +24 -0
- package/packs/sound-design/skills/bounce-a-plugin/SKILL.md +40 -0
- package/packs/sound-design/skills/choose-observable/SKILL.md +18 -0
- package/packs/sound-design/skills/measure-a-law/SKILL.md +18 -0
- package/packs/sound-design/skills/measure-reverb/SKILL.md +19 -0
- package/packs/sound-design/skills/spread-probe/SKILL.md +18 -0
- package/packs/sound-design/tools/vst3host/build.sh +73 -0
- package/packs/sound-design/tools/vst3host/host_events.h +101 -0
- package/packs/sound-design/tools/vst3host/options.h +172 -0
- package/packs/sound-design/tools/vst3host/render.cpp +245 -0
- package/packs/sound-design/tools/vst3host/session.h +241 -0
- package/packs/stellix/checks/no-keyboard-focus.json +12 -0
- package/packs/stellix/checks/one-seeded-random.json +16 -0
- package/packs/stellix/checks/world-never-includes-painter.json +12 -0
- package/packs/stellix/checks/world-no-libm.json +15 -0
- package/packs/stellix/checks/world-no-unordered.json +10 -0
- package/packs/stellix/hooks/no-shipped-images.mjs +88 -0
- package/packs/stellix/pack.json +61 -0
- package/packs/stellix/rules/stellix-deterministic-world.md +29 -0
- package/packs/stellix/rules/stellix-reset-generated.md +24 -0
- package/packs/stellix/rules/stellix-world-snapshot.md +27 -0
- package/packs/stellix/rules/world-continuous-collision.md +26 -0
- package/packs/stellix/rules/world-fp-determinism.md +28 -0
- package/packs/stored-text/checks/no-raw-html-from-data.json +31 -0
- package/packs/stored-text/checks/stored-text-libs-only-in-renderer.json +31 -0
- package/packs/stored-text/checks/stored-text-renderer-complete.json +24 -0
- package/packs/stored-text/checks/stored-text-through-renderer.json +25 -0
- package/packs/stored-text/pack.json +41 -0
- package/packs/stored-text/rules/stored-text-renders-once.md +26 -0
- package/packs/stored-text/skills/render-stored-text/SKILL.md +24 -0
- package/packs/synth-creator/checks/timing-from-synthcore.json +24 -0
- package/packs/synth-creator/checks/ui-drawn-in-code.json +23 -0
- package/packs/synth-creator/hooks/build-guard.mjs +232 -0
- package/packs/synth-creator/hooks/build-sweep.mjs +166 -0
- package/packs/synth-creator/hooks/frozen-files.mjs +63 -0
- package/packs/synth-creator/hooks/idle-wake.mjs +90 -0
- package/packs/synth-creator/hooks/protect-vendor.mjs +175 -0
- package/packs/synth-creator/hooks/spec-lock.mjs +117 -0
- package/packs/synth-creator/hooks/stage-guard.mjs +50 -0
- package/packs/synth-creator/hooks/time-guard.mjs +292 -0
- package/packs/synth-creator/hooks/user-asks.mjs +165 -0
- package/packs/synth-creator/pack.json +136 -0
- package/packs/synth-creator/rules/copy-trees-read-only.md +25 -0
- package/packs/synth-creator/rules/debug-by-measurement.md +20 -0
- package/packs/synth-creator/rules/done-means-fresh-evidence.md +18 -0
- package/packs/synth-creator/rules/hooks-and-gates.md +21 -0
- package/packs/synth-creator/rules/long-work-in-the-background.md +16 -0
- package/packs/synth-creator/rules/timing-from-synthcore.md +16 -0
- package/packs/synth-creator/skills/build-step/SKILL.md +125 -0
- package/packs/synth-creator/skills/build-through-the-queue/SKILL.md +21 -0
- package/packs/synth-creator/tools/buildq.mjs +74 -0
- package/packs/synth-creator/tools/freeze.mjs +36 -0
- package/packs/tui/checks/tui-entry-restores-terminal.json +27 -0
- package/packs/tui/checks/tui-gates-on-tty.json +25 -0
- package/packs/tui/checks/tui-no-ris-reset.json +22 -0
- package/packs/tui/checks/tui-resize-listener-removed.json +26 -0
- package/packs/tui/checks/tui-width-is-state.json +33 -0
- package/packs/tui/pack.json +44 -0
- package/packs/tui/rules/tui-resize-and-screen.md +25 -0
- package/packs/tui/skills/build-tui/SKILL.md +21 -0
- package/packs/ui-craft/checks/ui-input-needs-autocomplete.json +23 -0
- package/packs/ui-craft/checks/ui-intl-for-dates.json +21 -0
- package/packs/ui-craft/checks/ui-no-ai-palette.json +22 -0
- package/packs/ui-craft/checks/ui-no-animate-layout.json +22 -0
- package/packs/ui-craft/checks/ui-no-assistant-palette.json +23 -0
- package/packs/ui-craft/checks/ui-no-bounce-easing.json +22 -0
- package/packs/ui-craft/checks/ui-no-custom-cursor.json +22 -0
- package/packs/ui-craft/checks/ui-no-emoji-as-ui.json +22 -0
- package/packs/ui-craft/checks/ui-no-empty-image.json +21 -0
- package/packs/ui-craft/checks/ui-no-eyebrow.json +21 -0
- package/packs/ui-craft/checks/ui-no-furniture-text.json +22 -0
- package/packs/ui-craft/checks/ui-no-gradient-text.json +22 -0
- package/packs/ui-craft/checks/ui-no-index-numbering.json +21 -0
- package/packs/ui-craft/checks/ui-no-lorem.json +22 -0
- package/packs/ui-craft/checks/ui-no-marketing-buzzword.json +22 -0
- package/packs/ui-craft/checks/ui-no-paste-block.json +21 -0
- package/packs/ui-craft/checks/ui-no-placeholder-names.json +21 -0
- package/packs/ui-craft/checks/ui-no-scroll-hijack.json +21 -0
- package/packs/ui-craft/checks/ui-no-side-tab.json +21 -0
- package/packs/ui-craft/checks/ui-no-stock-labels.json +22 -0
- package/packs/ui-craft/checks/ui-no-transition-all.json +22 -0
- package/packs/ui-craft/checks/ui-no-uppercase-table-header.json +21 -0
- package/packs/ui-craft/checks/ui-no-zebra-rows.json +22 -0
- package/packs/ui-craft/checks/ui-no-zoom-lock.json +21 -0
- package/packs/ui-craft/pack.json +43 -0
- package/packs/ui-craft/rules/apps-are-not-pages.md +26 -0
- package/packs/ui-craft/rules/data-tells-the-truth.md +26 -0
- package/packs/ui-craft/rules/dates-and-numbers.md +18 -0
- package/packs/ui-craft/rules/forms-never-fight.md +22 -0
- package/packs/ui-craft/rules/interface-copy.md +26 -0
- package/packs/ui-craft/rules/motion-is-rare.md +31 -0
- package/packs/ui-craft/rules/no-generated-look.md +37 -0
- package/packs/ui-craft/rules/page-holds-its-frame.md +28 -0
- package/packs/ui-craft/rules/page-proved-rendered.md +19 -0
- package/packs/ui-craft/rules/pictures-do-a-job.md +25 -0
- package/packs/ui-craft/rules/pointer-feedback.md +28 -0
- package/packs/ui-craft/rules/screen-answers-one-question.md +24 -0
- package/packs/ui-craft/rules/survives-real-data.md +23 -0
- package/packs/ui-craft/rules/touch-and-small-screens.md +19 -0
- package/packs/ui-craft/rules/type-space-colour.md +26 -0
- package/packs/ui-craft/rules/url-holds-the-state.md +19 -0
- package/packs/ui-craft/skills/app-screen/SKILL.md +33 -0
- package/packs/ui-craft/skills/build-from-reference/SKILL.md +28 -0
- package/packs/ui-craft/skills/chart-choice/SKILL.md +34 -0
- package/packs/ui-craft/skills/hover-state/SKILL.md +28 -0
- package/packs/ui-craft/skills/page-critique/SKILL.md +33 -0
- package/packs/ui-craft/skills/prove-page/SKILL.md +23 -0
- package/packs/ui-craft/skills/redesign-page/SKILL.md +19 -0
- package/packs/ui-craft/skills/ui-code-review/SKILL.md +22 -0
- package/packs/ui-craft/skills/write-the-page/SKILL.md +21 -0
- package/packs/ui-craft/tools/page-measure.mjs +41 -0
- package/packs/web/checks/a11y-img-needs-alt.json +26 -0
- package/packs/web/checks/a11y-no-bare-outline-none.json +21 -0
- package/packs/web/checks/a11y-no-clickable-div.json +26 -0
- package/packs/web/checks/a11y-no-positive-tabindex.json +26 -0
- package/packs/web/checks/client-no-api-key.json +29 -0
- package/packs/web/checks/client-no-browser-global-at-module-scope.json +28 -0
- package/packs/web/checks/client-no-server-import.json +31 -0
- package/packs/web/checks/client-no-window-location-nav.json +28 -0
- package/packs/web/checks/css-no-inline-style.json +30 -0
- package/packs/web/checks/ds-pages-compose-primitives.json +28 -0
- package/packs/web/checks/key-from-index.json +23 -0
- package/packs/web/checks/prodbuild-no-cdn-runtime-deps.json +21 -0
- package/packs/web/checks/prodbuild-no-dev-flags.json +21 -0
- package/packs/web/checks/prodbuild-no-remote-fonts.json +22 -0
- package/packs/web/checks/rcss-button-cursor.json +30 -0
- package/packs/web/checks/rcss-no-100vw.json +21 -0
- package/packs/web/checks/rcss-no-fixed-wide-width.json +21 -0
- package/packs/web/checks/rcss-viewport-meta.json +28 -0
- package/packs/web/checks/secret-not-in-web-storage.json +25 -0
- package/packs/web/checks/tw-no-raw-hex-in-markup.json +34 -0
- package/packs/web/checks/wp-hero-not-lazy.json +27 -0
- package/packs/web/checks/wp-img-needs-dimensions.json +26 -0
- package/packs/web/pack.json +73 -0
- package/packs/web/rules/accessibility.md +26 -0
- package/packs/web/rules/client-boundaries.md +23 -0
- package/packs/web/rules/production-build.md +22 -0
- package/packs/web/rules/secrets-not-in-the-browser.md +18 -0
- package/packs/web/rules/styles-live-in-stylesheets.md +23 -0
- package/packs/web/rules/tailwind-v4.md +23 -0
- package/packs/web/rules/ui-primitives-one-module.md +30 -0
- package/packs/web/rules/web-performance.md +21 -0
- package/packs/web/skills/design-direction/SKILL.md +30 -0
- package/packs/web/skills/design-review/SKILL.md +28 -0
- package/packs/web/skills/pick-rendering-mode/SKILL.md +21 -0
- package/packs/web/skills/preflight-build/SKILL.md +23 -0
- package/packs/web/skills/seo-audit/SKILL.md +22 -0
- package/packs/websocket/checks/no-token-in-query.json +26 -0
- package/packs/websocket/checks/stale-socket-deletes-new-entry.json +25 -0
- package/packs/websocket/checks/ws-identity-from-message.json +26 -0
- package/packs/websocket/pack.json +21 -0
- package/packs/websocket/rules/identity-comes-from-the-connection.md +24 -0
- package/packs/writing/checks/ascii-no-em-dash.json +17 -0
- package/packs/writing/checks/no-copula-dodging.json +18 -0
- package/packs/writing/checks/no-dramatic-colon.json +18 -0
- package/packs/writing/checks/no-not-x-but-y.json +18 -0
- package/packs/writing/checks/no-participial-opener.json +18 -0
- package/packs/writing/checks/no-pseudo-wisdom.json +18 -0
- package/packs/writing/checks/no-slop-words.json +18 -0
- package/packs/writing/checks/no-stock-connectors.json +18 -0
- package/packs/writing/checks/no-time-or-date.json +27 -0
- package/packs/writing/checks/no-trailing-ing.json +18 -0
- package/packs/writing/checks/no-vague-attribution.json +18 -0
- package/packs/writing/pack.json +43 -0
- package/packs/writing/rules/ascii-no-em-dash.md +21 -0
- package/packs/writing/rules/cut-the-padding.md +20 -0
- package/packs/writing/rules/direct-voice.md +22 -0
- package/packs/writing/rules/no-cargo-cult.md +16 -0
- package/packs/writing/rules/no-scaffolding.md +19 -0
- package/packs/writing/rules/no-stock-language.md +27 -0
- package/packs/writing/rules/no-time-or-date.md +18 -0
- package/packs/writing/rules/rhythm-like-talk.md +20 -0
- package/packs/writing/rules/write-from-your-own-corner.md +20 -0
- package/packs/writing/skills/argument-post/SKILL.md +28 -0
- package/packs/writing/skills/humanize/SKILL.md +28 -0
- package/packs/writing/skills/launch-post/SKILL.md +38 -0
- package/packs/writing/skills/pick-subreddit/SKILL.md +69 -0
- package/packs/writing/skills/post-voice/SKILL.md +22 -0
- package/packs/writing/skills/reddit-post/SKILL.md +63 -0
- package/packs/writing/skills/reddit-title/SKILL.md +23 -0
- package/packs/writing/skills/reply-moves/SKILL.md +40 -0
- package/packs/writing/skills/reply-stance/SKILL.md +23 -0
- package/packs/writing/skills/should-i-reply/SKILL.md +21 -0
- package/packs/zod/hooks/schemas-only.mjs +53 -0
- package/packs/zod/pack.json +44 -0
- package/packs/zod/rules/env-shapes-only.md +14 -0
- package/packs/zod/rules/zod-4-schemas.md +14 -0
- package/profiles/stellix.layout.json +315 -0
- package/profiles/sub37.layout.json +247 -0
- package/prompts/scan-review.md +40 -0
- package/prompts/survey.md +82 -0
- package/prompts/workorder/PROMPT.md +53 -0
- package/prompts/workorder/run.sh +36 -0
- package/prompts/workorder/workorder.md +59 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "rust-stub-left-in",
|
|
3
|
+
"why": "A stub or a debug print compiles, so it ships. `unimplemented!` stays allowed: it is a decision, not a leftover.",
|
|
4
|
+
"rule": ".claude/rules/rust-lints-are-the-gate.md",
|
|
5
|
+
"globs": [
|
|
6
|
+
"**/*.rs"
|
|
7
|
+
],
|
|
8
|
+
"exclude": [
|
|
9
|
+
"**/tests/**",
|
|
10
|
+
"**/test/**",
|
|
11
|
+
"**/benches/**",
|
|
12
|
+
"**/examples/**",
|
|
13
|
+
"**/fixtures/**",
|
|
14
|
+
"**/test_data/**",
|
|
15
|
+
"**/testdata/**",
|
|
16
|
+
"**/fuzz/**",
|
|
17
|
+
"**/xtask/**",
|
|
18
|
+
"**/target/**",
|
|
19
|
+
"**/vendor/**",
|
|
20
|
+
"**/build.rs",
|
|
21
|
+
"**/tests.rs",
|
|
22
|
+
"**/test.rs",
|
|
23
|
+
"**/*_test.rs",
|
|
24
|
+
"**/*_tests.rs",
|
|
25
|
+
"**/test_*.rs"
|
|
26
|
+
],
|
|
27
|
+
"language": "rust",
|
|
28
|
+
"notInTests": true,
|
|
29
|
+
"pattern": "\\b(?:todo|dbg)!\\s*[(\\[{]",
|
|
30
|
+
"bad": "fn load() -> Config { todo!() }",
|
|
31
|
+
"good": "fn load() -> Result<Config> { read_config() }"
|
|
32
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "rust-unsafe-needs-safety",
|
|
3
|
+
"why": "An unsafe block with no stated reason cannot be reviewed.",
|
|
4
|
+
"rule": ".claude/rules/rust-unsafe-is-proved.md",
|
|
5
|
+
"globs": [
|
|
6
|
+
"**/*.rs"
|
|
7
|
+
],
|
|
8
|
+
"exclude": [
|
|
9
|
+
"**/tests/**",
|
|
10
|
+
"**/test/**",
|
|
11
|
+
"**/benches/**",
|
|
12
|
+
"**/examples/**",
|
|
13
|
+
"**/fixtures/**",
|
|
14
|
+
"**/test_data/**",
|
|
15
|
+
"**/testdata/**",
|
|
16
|
+
"**/fuzz/**",
|
|
17
|
+
"**/xtask/**",
|
|
18
|
+
"**/target/**",
|
|
19
|
+
"**/vendor/**",
|
|
20
|
+
"**/build.rs",
|
|
21
|
+
"**/tests.rs",
|
|
22
|
+
"**/test.rs",
|
|
23
|
+
"**/*_test.rs",
|
|
24
|
+
"**/*_tests.rs",
|
|
25
|
+
"**/test_*.rs"
|
|
26
|
+
],
|
|
27
|
+
"pattern": "^(?<!(?:^|\\n)[ \\t]*//[^\\n]*[Ss][Aa][Ff][Ee][Tt][Yy][^\\n]*\\n(?:[ \\t]*//[^\\n]*\\n)*)(?![ \\t]*//)(?![^\\n]*//[^\\n]*SAFETY)[^\\n]*\\bunsafe\\s*\\{",
|
|
28
|
+
"flags": "m",
|
|
29
|
+
"bad": "fn f(p: *const u8) -> u8 {\n unsafe { *p }\n}",
|
|
30
|
+
"good": "fn f(p: *const u8) -> u8 {\n // SAFETY: the caller passes a live pointer, checked in new().\n unsafe { *p }\n}"
|
|
31
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "rust-unwrap-in-library",
|
|
3
|
+
"why": "A failure the caller could handle becomes a panic with no reason. Return it with `?`, or say why it cannot happen with `.expect(\"...\")`.",
|
|
4
|
+
"rule": ".claude/rules/rust-errors-are-returned.md",
|
|
5
|
+
"globs": [
|
|
6
|
+
"**/*.rs"
|
|
7
|
+
],
|
|
8
|
+
"exclude": [
|
|
9
|
+
"**/tests/**",
|
|
10
|
+
"**/test/**",
|
|
11
|
+
"**/benches/**",
|
|
12
|
+
"**/examples/**",
|
|
13
|
+
"**/fixtures/**",
|
|
14
|
+
"**/test_data/**",
|
|
15
|
+
"**/testdata/**",
|
|
16
|
+
"**/fuzz/**",
|
|
17
|
+
"**/xtask/**",
|
|
18
|
+
"**/target/**",
|
|
19
|
+
"**/vendor/**",
|
|
20
|
+
"**/build.rs",
|
|
21
|
+
"**/tests.rs",
|
|
22
|
+
"**/test.rs",
|
|
23
|
+
"**/*_test.rs",
|
|
24
|
+
"**/*_tests.rs",
|
|
25
|
+
"**/test_*.rs",
|
|
26
|
+
"**/main.rs",
|
|
27
|
+
"**/bin/**"
|
|
28
|
+
],
|
|
29
|
+
"language": "rust",
|
|
30
|
+
"notInTests": true,
|
|
31
|
+
"pattern": "(?<!\\.lock\\(\\)|\\.read\\(\\)|\\.write\\(\\))\\.unwrap\\(\\)",
|
|
32
|
+
"bad": "let n = text.parse::<u32>().unwrap();",
|
|
33
|
+
"good": "let n = text.parse::<u32>()?;"
|
|
34
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "rust-wildcard-dependency",
|
|
3
|
+
"why": "A * version takes whatever is newest, and crates.io refuses it.",
|
|
4
|
+
"rule": ".claude/rules/rust-lints-are-the-gate.md",
|
|
5
|
+
"globs": [
|
|
6
|
+
"**/Cargo.toml"
|
|
7
|
+
],
|
|
8
|
+
"exclude": [
|
|
9
|
+
"**/target/**",
|
|
10
|
+
"**/vendor/**"
|
|
11
|
+
],
|
|
12
|
+
"pattern": "(?:^[ \\t]*[\\w-]+\\s*=\\s*|\\bversion\\s*=\\s*)\"\\*\"",
|
|
13
|
+
"flags": "m",
|
|
14
|
+
"bad": "serde = \"*\"",
|
|
15
|
+
"good": "serde = \"1.0\""
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rust",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Rust: errors returned, unsafe proved, async never blocks, clippy as the gate. What clippy reads better stays with clippy.",
|
|
5
|
+
"type": "stock",
|
|
6
|
+
"author": "claude-packs",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/TheDecipherist/claude-packs",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/TheDecipherist/claude-packs.git",
|
|
12
|
+
"directory": "packs/rust"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"rust",
|
|
16
|
+
"cargo",
|
|
17
|
+
"clippy"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"claude-packs": ">=1.1.0"
|
|
21
|
+
},
|
|
22
|
+
"concepts": {
|
|
23
|
+
"rust": [
|
|
24
|
+
"**/*.rs"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# An async function never blocks its thread
|
|
7
|
+
|
|
8
|
+
<constraints>
|
|
9
|
+
Always do:
|
|
10
|
+
- Hand blocking work to `spawn_blocking`, or use the runtime's own `fs`, `process` and `time`.
|
|
11
|
+
- Drop a `std::sync` guard before an `.await`. Use the runtime's own mutex when the lock must span one.
|
|
12
|
+
- Give every spawned task a way to stop, and a place its error lands.
|
|
13
|
+
|
|
14
|
+
Never do:
|
|
15
|
+
- Call `std::thread::sleep`, `std::fs` or `std::process::Command` in an `async fn`.
|
|
16
|
+
- Hold a lock across `.await`: clippy's `await_holding_lock` reads this, and the gate holds it.
|
|
17
|
+
</constraints>
|
|
18
|
+
|
|
19
|
+
## Check
|
|
20
|
+
`rust-blocking-in-async`.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Borrow first: a clone is a decision, never a way past the borrow checker
|
|
7
|
+
|
|
8
|
+
<constraints>
|
|
9
|
+
Always do:
|
|
10
|
+
- Take `&str`, `&[T]` and `&Path` in a parameter, and own only what is kept.
|
|
11
|
+
- When the borrow checker refuses, change who owns the value, or shorten the borrow.
|
|
12
|
+
- Use `impl Trait` or a generic before `Box<dyn Trait>`, unless the types differ at run time.
|
|
13
|
+
- Walk with iterators. Let lifetimes be elided where the compiler allows it.
|
|
14
|
+
- Give a value its own type (a newtype, an enum) in place of a bare `String` or a `bool` flag.
|
|
15
|
+
|
|
16
|
+
Never do:
|
|
17
|
+
- Add `.clone()`, `Rc` or `RefCell` only to make an error go away.
|
|
18
|
+
- Write a function again in another crate: `template-law` reads Rust. The `rust-extract-template` skill has the forms.
|
|
19
|
+
</constraints>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# An error is returned; a panic states why it cannot happen
|
|
7
|
+
|
|
8
|
+
<constraints>
|
|
9
|
+
Always do:
|
|
10
|
+
- Return `Result` from anything that can fail, and pass it up with `?`.
|
|
11
|
+
- Give a library its own error type, by hand or with `thiserror`, so a caller can match on it.
|
|
12
|
+
- In an application, use `anyhow` with `.context(...)` saying what was being attempted.
|
|
13
|
+
- Write `.expect("why this cannot fail")` for a true invariant. The message is the proof.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- `.unwrap()` in library code. Tests, `main.rs` and `src/bin/` may.
|
|
17
|
+
- Return `Result<T, String>` or `Box<dyn Error>` from a public function.
|
|
18
|
+
- Drop a `Result` with `let _ =` on a state change.
|
|
19
|
+
</constraints>
|
|
20
|
+
|
|
21
|
+
## Check
|
|
22
|
+
`rust-unwrap-in-library`, `rust-string-as-error`.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `cargo clippy -D warnings` and `cargo fmt --check` are the gate
|
|
7
|
+
|
|
8
|
+
Clippy reads types, so what it can judge stays with it. The lesson checks stop only what is cheaper to stop at the write.
|
|
9
|
+
|
|
10
|
+
<constraints>
|
|
11
|
+
Always do:
|
|
12
|
+
- Take the lint set in `.claude/tools/rust-lints.toml` into `Cargo.toml`, and keep the installed `clippy.toml` at the root.
|
|
13
|
+
- Run `cargo fmt --check`, then `cargo clippy --all-targets --all-features -- -D warnings`, before landing.
|
|
14
|
+
- Turn a lint off with `#[expect(lint, reason = "...")]`, on the smallest item. `reason` needs Rust 1.81; on an older toolchain, disable `checks/rust-allow-needs-reason.json` in `layout.json`.
|
|
15
|
+
- Commit `Cargo.lock` for an application.
|
|
16
|
+
|
|
17
|
+
Never do:
|
|
18
|
+
- Leave `todo!()` or `dbg!()` in code that lands. `unimplemented!()` is a decision, and may stay.
|
|
19
|
+
- Depend on a `*` version.
|
|
20
|
+
</constraints>
|
|
21
|
+
|
|
22
|
+
## Check
|
|
23
|
+
`rust-allow-needs-reason`, `rust-stub-left-in`, `rust-wildcard-dependency`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Anything repeated in Rust becomes one template: pick the form that fits the repeat
|
|
7
|
+
|
|
8
|
+
<constraints>
|
|
9
|
+
Always do:
|
|
10
|
+
- Match the repeat to its form. The `rust-extract-template` skill has each with an example:
|
|
11
|
+
- A block with other names: one function, with what differs as parameters.
|
|
12
|
+
- The same code over several types: a generic with a trait bound.
|
|
13
|
+
- The same method on many types: a trait with a default method.
|
|
14
|
+
- The same `impl` for many types, where a generic cannot do it: one `macro_rules!`.
|
|
15
|
+
- One call repeated with other arguments: a `const` table and one loop.
|
|
16
|
+
- The same code in two crates: the crate both depend on.
|
|
17
|
+
- Give an enum its own methods for what varies by variant: `state.label()`, in the enum's impl. A table of values on an enum belongs with the enum.
|
|
18
|
+
- Match every variant by name, so a new variant is a compile error in each place that must decide. `clippy::wildcard_enum_match_arm` holds this.
|
|
19
|
+
- Use `#[derive(...)]` and `thiserror`'s `#[from]` in place of hand-written impls.
|
|
20
|
+
|
|
21
|
+
Never do:
|
|
22
|
+
- Write `_ =>` on your own enum: it hides the next variant from the compiler.
|
|
23
|
+
- Write a macro where a function or a generic does the job, or a trait with one implementor.
|
|
24
|
+
- Treat a trait method as a copy: `from_str` on two types is the trait doing its job.
|
|
25
|
+
</constraints>
|
|
26
|
+
|
|
27
|
+
## Check
|
|
28
|
+
`template-law` refuses a copy, a near copy, a table written as calls and a function made again. `dispatch-once` refuses a second lookup table on one enum outside the enum's own file. `once-only` refuses a copy as written. `rust-if-chain-is-a-match` refuses three `==` branches on one value.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Every unsafe block says why it is sound
|
|
7
|
+
|
|
8
|
+
<constraints>
|
|
9
|
+
Always do:
|
|
10
|
+
- Put a `// SAFETY:` comment directly above each `unsafe` block, naming the invariant and what upholds it.
|
|
11
|
+
- Keep a block to one unsafe operation, and wrap it in a safe function that checks what it needs.
|
|
12
|
+
- Give every `unsafe fn` a `# Safety` section in its docs.
|
|
13
|
+
- Run `cargo miri test` on code with `unsafe`, where it can run.
|
|
14
|
+
|
|
15
|
+
Never do:
|
|
16
|
+
- Use `static mut`: use an atomic, `OnceLock` or a `Mutex`.
|
|
17
|
+
- Use `unsafe` for speed with no measurement showing the safe form is too slow.
|
|
18
|
+
</constraints>
|
|
19
|
+
|
|
20
|
+
## Check
|
|
21
|
+
`rust-unsafe-needs-safety`, `rust-static-mut`.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-extract-template
|
|
3
|
+
description: Use when template-law refuses Rust code, when scan lists repeated Rust, or when copying a Rust function, impl or module to change it.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Extract a Rust repeat into one template (one job: pick the Rust form, and move every copy to it)
|
|
7
|
+
|
|
8
|
+
Follow `make-it-a-template`. This skill is its Rust forms.
|
|
9
|
+
|
|
10
|
+
<constraints>
|
|
11
|
+
Always do:
|
|
12
|
+
1. A repeated block: one function, with what differs as parameters. A difference in behaviour is a closure parameter.
|
|
13
|
+
2. The same code over several types: a generic with a trait bound.
|
|
14
|
+
```rust
|
|
15
|
+
fn total<T: Priced>(items: &[T]) -> u64 {
|
|
16
|
+
items.iter().map(Priced::price).sum()
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
3. The same method on many types: a trait with a default method.
|
|
20
|
+
4. The same `impl` written for many types: one `macro_rules!`, and only when a generic cannot do it.
|
|
21
|
+
```rust
|
|
22
|
+
macro_rules! impl_id { ($($t:ident),*) => { $(impl Id for $t { fn raw(&self) -> u64 { self.0 } })* } }
|
|
23
|
+
impl_id!(UserId, OrderId);
|
|
24
|
+
```
|
|
25
|
+
5. One call with other arguments: a `const` table and one loop.
|
|
26
|
+
```rust
|
|
27
|
+
const ROUTES: &[(&str, Handler)] = &[("/users", users), ("/orders", orders)];
|
|
28
|
+
for (path, handler) in ROUTES {
|
|
29
|
+
app.route(path, *handler);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
6. A table of values on an enum: a method on the enum, in its own impl, with every variant named. `dispatch-once` refuses a second table outside it.
|
|
33
|
+
```rust
|
|
34
|
+
impl State {
|
|
35
|
+
pub fn colour(&self) -> u32 {
|
|
36
|
+
match self {
|
|
37
|
+
State::Open => 1,
|
|
38
|
+
State::Closed => 4,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
7. Fields that travel together: a struct, with `#[derive(...)]` in place of hand-written impls. A run of `impl From<X> for MyError`: `thiserror`'s `#[from]`.
|
|
44
|
+
8. The same code in two crates: move it to the crate both depend on.
|
|
45
|
+
9. Run what the change reaches: `cargo test -p <crate>`. Then search for the old names: none is left.
|
|
46
|
+
|
|
47
|
+
Never do:
|
|
48
|
+
- Write a macro where a function or a generic does the job.
|
|
49
|
+
- Add a trait with one implementor.
|
|
50
|
+
</constraints>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-port
|
|
3
|
+
description: Use when porting code to Rust from another language, or rewriting a module in Rust.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Port to Rust (one job: the same behaviour, in Rust's own shapes)
|
|
7
|
+
|
|
8
|
+
<constraints>
|
|
9
|
+
Always do:
|
|
10
|
+
1. Pin the behaviour first: tests or recorded input and output from the old code, kept as the proof.
|
|
11
|
+
2. Write down who owns each piece of state. A shared mutable object becomes one owner that lends, or a message to the task that owns it.
|
|
12
|
+
3. Map each failure the old code can have to a variant of an error type. An exception becomes a `Result`; a null becomes an `Option`.
|
|
13
|
+
4. Map an inheritance tree to an enum when the set of kinds is closed, and to a trait when it is open.
|
|
14
|
+
5. Port one module at a time behind the same interface, and run the pinned tests after each.
|
|
15
|
+
6. Keep a behaviour the old code has even if it looks wrong, and list it. Change it in its own step.
|
|
16
|
+
7. Compare speed only after it is correct, on a release build.
|
|
17
|
+
|
|
18
|
+
Never do:
|
|
19
|
+
- Translate line by line: a class with getters and shared pointers everywhere is the old language in Rust's syntax.
|
|
20
|
+
- Reach for `Rc<RefCell<T>>` or `unsafe` to keep the old shape.
|
|
21
|
+
- Change behaviour and language in the same step.
|
|
22
|
+
</constraints>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rust-review
|
|
3
|
+
description: Use when reviewing Rust code, a Rust diff or a crate before it lands, or when asked whether Rust code is sound or idiomatic.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Review Rust (one job: find what the compiler and clippy cannot)
|
|
7
|
+
|
|
8
|
+
Run the gate first, so the review spends nothing on what tools already say: `cargo fmt --check`, `cargo clippy --all-targets --all-features -- -D warnings`, `cargo test`.
|
|
9
|
+
|
|
10
|
+
<constraints>
|
|
11
|
+
Always do:
|
|
12
|
+
1. Ownership: is each `.clone()`, `Rc`, `Arc` and `RefCell` needed, or was it a way past a borrow error? Could the caller keep the value and lend it?
|
|
13
|
+
2. Errors: can a caller tell the failures apart? Is every `.expect` message a true invariant? Does a `?` lose what was being attempted?
|
|
14
|
+
3. `unsafe`: does each `SAFETY` comment name a real invariant, and does the code around it uphold that? Read the callers. Check aliasing, alignment, initialization, and that a panic in the block leaves nothing half done.
|
|
15
|
+
4. Concurrency: what happens when a future is dropped at each `.await`? Is state left half written? Is a channel unbounded? Is `Ordering::Relaxed` proved enough?
|
|
16
|
+
5. Public API: would a new field or variant break a caller (`#[non_exhaustive]`)? Is an internal type exposed? Are `Send` and `Sync` what the caller needs?
|
|
17
|
+
6. Numbers and text: an `as` cast that truncates, an overflow in release builds, a byte index into a `&str`.
|
|
18
|
+
7. Tests: does a test fail without the change? Is an error path covered, not only the happy one?
|
|
19
|
+
8. Report each finding with the file, the symbol and the input that breaks it. A finding you cannot give an input for is a question.
|
|
20
|
+
|
|
21
|
+
Never do:
|
|
22
|
+
- Report what clippy or `rustfmt` already says.
|
|
23
|
+
- Ask for a lifetime, a trait or a generic the code does not need.
|
|
24
|
+
</constraints>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# The gate's lint set: paste it into Cargo.toml. In a workspace, write [workspace.lints.rust] and [workspace.lints.clippy]
|
|
2
|
+
# at the root, and `[lints] workspace = true` in each crate. An application can drop unwrap_used from main.rs with an
|
|
3
|
+
# `#[expect(clippy::unwrap_used, reason = "...")]`. `reason` needs Rust 1.81.
|
|
4
|
+
[lints.rust]
|
|
5
|
+
unsafe_op_in_unsafe_fn = "deny"
|
|
6
|
+
|
|
7
|
+
[lints.clippy]
|
|
8
|
+
all = { level = "deny", priority = -1 }
|
|
9
|
+
unwrap_used = "deny"
|
|
10
|
+
todo = "deny"
|
|
11
|
+
dbg_macro = "deny"
|
|
12
|
+
allow_attributes_without_reason = "deny"
|
|
13
|
+
undocumented_unsafe_blocks = "deny"
|
|
14
|
+
multiple_unsafe_ops_per_block = "deny"
|
|
15
|
+
panic_in_result_fn = "deny"
|
|
16
|
+
redundant_clone = "deny"
|
|
17
|
+
clone_on_ref_ptr = "deny"
|
|
18
|
+
fn_params_excessive_bools = "deny"
|
|
19
|
+
wildcard_enum_match_arm = "deny"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-mktemp",
|
|
3
|
+
"why": "A fixed path in /tmp collides with another run, and another user can plant it.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": ">>?\\s*\\\"?/tmp/\\w",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "echo x > /tmp/out.txt",
|
|
17
|
+
"good": "out=$(mktemp)\necho x > \"$out\""
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-no-backticks",
|
|
3
|
+
"why": "Backticks do not nest and hide in quoted text. $(...) does the same thing, and reads.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "^[^#'\\n]*`[^`\\n]+`",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "now=`date`",
|
|
17
|
+
"good": "now=$(date)"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-no-eval",
|
|
3
|
+
"why": "eval runs whatever a variable holds, with the script's rights.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "^[^#\\n]*(?:^|[;&|\\s])eval\\s",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "eval \"$cmd\"",
|
|
17
|
+
"good": "\"$@\""
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-no-parse-ls",
|
|
3
|
+
"why": "ls output breaks on spaces and newlines. A glob does not.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "\\bfor\\s+\\w+\\s+in\\s+\\$\\(\\s*ls\\b|\\bls\\b[^|\\n]*\\|\\s*(?:while|xargs)\\b",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "for f in $(ls *.txt); do echo \"$f\"; done",
|
|
17
|
+
"good": "for f in *.txt; do echo \"$f\"; done"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-no-pipe-to-shell",
|
|
3
|
+
"why": "A download piped into a shell runs whatever the server sends, unread.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "\\b(?:curl|wget)\\b[^\\n|]*\\|\\s*(?:sudo\\s+)?(?:ba|z|da)?sh\\b",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "curl -fsSL https://example.com/i.sh | sh",
|
|
17
|
+
"good": "curl -fsSL -o i.sh https://example.com/i.sh"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-no-program-in-heredoc",
|
|
3
|
+
"why": "A program in a heredoc cannot be linted, tested or reused. Give it its own file and call it.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "\\b(?:python3?|node|ruby|perl)\\s+(?:-\\w+\\s+)*-(?:\\s[^\\n]*)?<<",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "python3 - \"$out\" <<'EOF'\nprint(1)\nEOF",
|
|
17
|
+
"good": "python3 tools/read_out.py \"$out\""
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-quote-arguments",
|
|
3
|
+
"why": "An unquoted variable splits on spaces and expands globs, so a path with a space becomes two arguments.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "^[^#\\\"'\\n]*\\b(?:cp|mv|rm|cat|cd|mkdir|touch|chmod|chown|source)\\s+[^\\\"'\\n#]*\\$[A-Za-z_{]",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "cp $src $dst",
|
|
17
|
+
"good": "cp \"$src\" \"$dst\""
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-rm-guarded",
|
|
3
|
+
"why": "An empty variable turns `rm -rf \"$dir/\"` into a delete from the root. `${dir:?}` stops the script instead.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/.venv/**",
|
|
12
|
+
"**/venv/**"
|
|
13
|
+
],
|
|
14
|
+
"pattern": "\\brm\\s+-[a-zA-Z]*[rR][a-zA-Z]*\\s+\\\"?\\$\\{?\\w+(?!\\w*:\\?)\\}?",
|
|
15
|
+
"flags": "m",
|
|
16
|
+
"bad": "rm -rf \"$dir/build\"",
|
|
17
|
+
"good": "rm -rf \"${dir:?}/build\""
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sh-strict-mode",
|
|
3
|
+
"why": "Without strict mode a failed step is ignored and the script carries on with bad state. A file only sourced is left out.",
|
|
4
|
+
"rule": ".claude/rules/shell-strict-and-quoted.md",
|
|
5
|
+
"concepts": [
|
|
6
|
+
"shell"
|
|
7
|
+
],
|
|
8
|
+
"globs": [],
|
|
9
|
+
"exclude": [
|
|
10
|
+
"**/node_modules/**"
|
|
11
|
+
],
|
|
12
|
+
"pattern": "^#![^\\n]*\\b(?:ba|z|da)?sh\\b",
|
|
13
|
+
"flags": "m",
|
|
14
|
+
"bad": "#!/usr/bin/env bash\nset -u\necho done",
|
|
15
|
+
"good": "#!/usr/bin/env bash\nset -euo pipefail\necho done\n",
|
|
16
|
+
"mode": "needs",
|
|
17
|
+
"needs": [
|
|
18
|
+
"^\\s*set\\s+-\\w*e\\w*(?:\\s+-o\\s+pipefail|\\w*o\\s+pipefail)"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "shell",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shell scripts: strict mode, quoted arguments, shared functions in one sourced file, tables and loops, and programs kept out of heredocs.",
|
|
5
|
+
"type": "stock",
|
|
6
|
+
"author": "claude-packs",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/TheDecipherist/claude-packs",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/TheDecipherist/claude-packs.git",
|
|
12
|
+
"directory": "packs/shell"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"shell",
|
|
16
|
+
"bash"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"claude-packs": ">=0.25.0"
|
|
20
|
+
},
|
|
21
|
+
"concepts": {
|
|
22
|
+
"shell": [
|
|
23
|
+
"**/*.sh",
|
|
24
|
+
"**/*.bash",
|
|
25
|
+
"**/*.zsh"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
# concepts: shell
|
|
3
|
+
paths:
|
|
4
|
+
- "placeholder"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Anything repeated in shell becomes a template: a function in one sourced file, or a table and a loop
|
|
8
|
+
|
|
9
|
+
Measured on real repos: the same wait-and-check block in five gate scripts, the same retry and logging at the top of every hook, and one command written out dozens of times with other arguments.
|
|
10
|
+
|
|
11
|
+
<constraints>
|
|
12
|
+
Always do:
|
|
13
|
+
- Put what scripts share in one file they source: logging, waiting, cleanup, argument checks. `. "$(dirname "$0")/lib.sh"`.
|
|
14
|
+
- Turn one command repeated with other arguments into an array of rows and one loop, or a function called from a table.
|
|
15
|
+
- Start a new script from the shared file: it holds only what this script does.
|
|
16
|
+
|
|
17
|
+
Never do:
|
|
18
|
+
- Copy a script to start the next one.
|
|
19
|
+
- Paste the same `if` or `trap` block at the top of each script.
|
|
20
|
+
</constraints>
|
|
21
|
+
|
|
22
|
+
## Check
|
|
23
|
+
`template-law` refuses a new copy, a near copy or a function the repo already has. The `shell-extract-template` skill walks the change.
|