@thedecipherist/claude-packs 0.0.0-stage → 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/CHANGELOG.md +680 -0
- package/LICENSE +21 -0
- package/README.md +316 -2
- package/bin/claude-packs.mjs +204 -0
- package/configurations/base/config.json +85 -0
- package/configurations/cpp/config.json +92 -0
- package/configurations/full-stack/config.json +152 -0
- package/configurations/go/config.json +96 -0
- package/configurations/node/config.json +100 -0
- package/configurations/python/config.json +97 -0
- package/configurations/synth-creator/config.json +148 -0
- package/global/hooks/gnu-shell.mjs +131 -0
- package/global/hooks/lib/program-read.mjs +196 -0
- package/global/hooks/lib/program-writes.mjs +177 -0
- package/global/hooks/lib/shell-writes.mjs +293 -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/claude-md.mjs +58 -0
- package/lib/config-cli.mjs +36 -0
- package/lib/configs.mjs +145 -0
- package/lib/coverage.mjs +86 -0
- package/lib/custom-packs.mjs +93 -0
- package/lib/doctor.mjs +115 -0
- package/lib/fix-plan.mjs +71 -0
- package/lib/git-tokens.mjs +64 -0
- package/lib/global.mjs +125 -0
- package/lib/hook-proof.mjs +28 -0
- package/lib/hook-timing.mjs +42 -0
- package/lib/hover-gate.mjs +29 -0
- package/lib/kit-lock.mjs +149 -0
- package/lib/layout.mjs +75 -0
- package/lib/logs.mjs +69 -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 +107 -0
- package/lib/planner.mjs +59 -0
- package/lib/repeats.mjs +65 -0
- package/lib/repo-weight.mjs +28 -0
- package/lib/rules.mjs +40 -0
- package/lib/scan-detect.mjs +94 -0
- package/lib/scan.mjs +168 -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 +18 -0
- package/lib/switches.mjs +44 -0
- package/lib/symmetry-doctor.mjs +26 -0
- package/lib/sync.mjs +130 -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 +129 -0
- package/packs/audio-core/hooks/realtime-guard.mjs +67 -0
- package/packs/audio-core/pack.json +187 -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 +26 -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 +21 -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 +21 -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 +23 -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 +95 -0
- package/packs/base/hooks/dispatch-once.mjs +87 -0
- package/packs/base/hooks/file-size-guard.mjs +61 -0
- package/packs/base/hooks/folder-law.mjs +74 -0
- package/packs/base/hooks/git-guard.mjs +289 -0
- package/packs/base/hooks/lesson-checks.mjs +174 -0
- package/packs/base/hooks/lib/apply-edit.mjs +20 -0
- package/packs/base/hooks/lib/code-shapes.mjs +137 -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/dup-index.mjs +199 -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 +67 -0
- package/packs/base/hooks/lib/function-shapes.mjs +90 -0
- package/packs/base/hooks/lib/git-adds.mjs +20 -0
- package/packs/base/hooks/lib/git-guard-selftest.mjs +99 -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 +66 -0
- package/packs/base/hooks/lib/layout.mjs +54 -0
- package/packs/base/hooks/lib/making-check-selftest.mjs +109 -0
- package/packs/base/hooks/lib/near-copies.mjs +76 -0
- package/packs/base/hooks/lib/program-read.mjs +196 -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/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.mjs +294 -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 +81 -0
- package/packs/base/hooks/lib/writes.mjs +71 -0
- package/packs/base/hooks/making-check.mjs +243 -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 +132 -0
- package/packs/base/hooks/secrets-guard.mjs +99 -0
- package/packs/base/hooks/shape-law.mjs +133 -0
- package/packs/base/hooks/suite-once.mjs +80 -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 +18 -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 +22 -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/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/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 +21 -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 +25 -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/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 +21 -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 +21 -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/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/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/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 +174 -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 +19 -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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TheDecipherist
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,317 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @thedecipherist/claude-packs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Rules, checks, hooks and skills that hold Claude Code to what a senior engineer would accept, installed per project. A rule tells Claude the law, a hook refuses the write before it reaches the disk, and a skill walks the fix. Everything lives in the project's own `.claude/`, so a team gets it from the repo.
|
|
4
|
+
|
|
5
|
+
## Start here
|
|
6
|
+
|
|
7
|
+
Install the package in the project (Node 22+):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
npm i -D @thedecipherist/claude-packs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then four commands:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
npx --no-install @thedecipherist/claude-packs suggest # which packs this project needs, and why
|
|
17
|
+
npx --no-install @thedecipherist/claude-packs init --auto # install exactly that
|
|
18
|
+
npx --no-install @thedecipherist/claude-packs scan # everything already wrong, on a copy of the project
|
|
19
|
+
npx --no-install @thedecipherist/claude-packs fix # the scan as a work order: .claude/fix-plan.md
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Then tell Claude to work through `.claude/fix-plan.md`. The `fix-from-scan` skill says how.
|
|
23
|
+
|
|
24
|
+
`scan` is safe to run before installing anything: it works on a copy in a temp folder and never writes to the project. `suggest` only reads file names and `package.json`.
|
|
25
|
+
|
|
26
|
+
## What happens when Claude writes code
|
|
27
|
+
|
|
28
|
+
1. **At the prompt.** `making` asks what is being made and what it reuses. `reuse-hint` shows functions the repo already has when the prompt names them, before a line is drafted.
|
|
29
|
+
2. **Before the first write.** The step's `making:` line goes in `build.md`: what, which concepts, what it reuses.
|
|
30
|
+
3. **At every write.** Hooks judge what the tool call would write, by any route: Write, Edit, a shell redirect, `sed -i`, `cp`, a heredoc, an inline script. A refusal is exit 2 with the reason, and the file never changes.
|
|
31
|
+
4. **At the end of the turn.** `making-check` compares what was written with what was said.
|
|
32
|
+
5. **Before landing.** The whole suite runs once, on committed work, and `land-branch` merges and pushes.
|
|
33
|
+
|
|
34
|
+
Four kinds of thing do the work:
|
|
35
|
+
|
|
36
|
+
| Kind | What it is | Lives in |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| Rule | A short law, loaded only for the files it applies to | `.claude/rules/` |
|
|
39
|
+
| Lesson check | A pattern with a `bad` and a `good` example. It refuses only an edit that adds a match, so old code can be fixed at its own pace | `.claude/checks/` |
|
|
40
|
+
| Hook | Code that judges a tool call and can refuse it | `.claude/hooks/` |
|
|
41
|
+
| Skill | One job's steps, loaded when the situation fits | `.claude/skills/` |
|
|
42
|
+
|
|
43
|
+
## Repetition is stopped before it is written
|
|
44
|
+
|
|
45
|
+
AI writes the same thing over and over, so the kit works on it at three points. `reuse-hint` puts what exists in front of Claude at the prompt. The `making:` line makes it say what it reuses. `template-law` refuses at the write, comparing code with names, numbers and strings stripped, so a copy with other names reads the same:
|
|
46
|
+
|
|
47
|
+
| What it catches | What the refusal says to make |
|
|
48
|
+
|---|---|
|
|
49
|
+
| Markup built by hand again (HTML, JSX, Vue, Svelte, template strings) | One component |
|
|
50
|
+
| An object filled in field by field again | One factory function |
|
|
51
|
+
| A run of statements with one shape, whole or in part | One function, with what differs as parameters |
|
|
52
|
+
| A near copy: most of a stretch matches another file, in order, with lines changed | One function |
|
|
53
|
+
| One call repeated with other arguments | One table and one loop |
|
|
54
|
+
| A function the repo already has, under the same compound name | Call it, or name it for its job |
|
|
55
|
+
|
|
56
|
+
A refusal names the copies and lists what differs between them, which are the template's parameters. `make-it-a-template` walks the change, with a skill per language for the forms it has. A real exception says so above it: `one-off: <reason>`.
|
|
57
|
+
|
|
58
|
+
One language table reads C, C++, Objective-C++, JS, TS, Python, shell, Go, Rust, Java, C#, Scala, Dart, Kotlin, Swift, Ruby, PHP and Lua. A new language is one row in `packs/base/hooks/lib/languages.mjs`. A folder of kind `copy`, or a glob in `guards.templates.exclude`, is left alone.
|
|
59
|
+
|
|
60
|
+
Anything used more than once is one template, and it is tested once. `test-the-template-once` says how: test the behaviour on one instance, and prove the rest are that template with a read of the table. `one-walk-per-template` refuses a test that presses every instance.
|
|
61
|
+
|
|
62
|
+
## Code stays small in every direction
|
|
63
|
+
|
|
64
|
+
`code-shape` refuses a write that adds a line over 120 columns of code, a line with more than two statements, a function over 50 statements or over 6 parameters. `file-size-guard` holds a file to 300 lines. Code that already stands is judged only if it gets worse. Limits are in `layout.json`: `"guards": { "codeShape": { "maxLineChars": 120, "maxStatementsPerLine": 2, "maxFunctionStatements": 50, "maxParameters": 6, "exclude": [] } }` and `"maxFileLines"`.
|
|
65
|
+
|
|
66
|
+
## Packs
|
|
67
|
+
|
|
68
|
+
`list` shows every pack and preset, with its version and author. `base`, `writing` and `hook-proof` come with every configuration.
|
|
69
|
+
|
|
70
|
+
| Pack | For | Rules | Checks | Hooks | Skills |
|
|
71
|
+
|---|---|---|---|---|---|
|
|
72
|
+
| `ai` | Code that calls a model: untrusted input, explicit keys, model ids | 2 | 4 | 0 | 0 |
|
|
73
|
+
| `audio-core` | Any JUCE synth or effect: realtime safety, DSP quality, state, parameters | 41 | 8 | 2 | 7 |
|
|
74
|
+
| `base` | Universal engineering, in every configuration | 21 | 7 | 18 | 8 |
|
|
75
|
+
| `ci` | CI workflows: every language run, tools pinned, permissions stated | 2 | 2 | 0 | 0 |
|
|
76
|
+
| `content-site` | Sites that publish: complete page heads, one source per page, defended forms, sized media | 4 | 3 | 0 | 1 |
|
|
77
|
+
| `cpp` | Any C++ project: templates, thread contracts, headers, casts, static analysis | 10 | 14 | 0 | 1 |
|
|
78
|
+
| `docker` | Dockerfiles, Compose and Swarm | 5 | 24 | 0 | 1 |
|
|
79
|
+
| `dynamic-data` | Definition-driven systems: a CMS, an admin generator, a low-code platform | 10 | 9 | 0 | 1 |
|
|
80
|
+
| `fastify` | Fastify servers | 6 | 15 | 0 | 0 |
|
|
81
|
+
| `full-stack` | The stack choice: Fastify and Next.js only | 1 | 1 | 1 | 0 |
|
|
82
|
+
| `go` | Go: errors handled, wrapped and never discarded | 1 | 2 | 0 | 0 |
|
|
83
|
+
| `gpu-painter` | GPU-drawn UI on Dawn, with no OpenGL | 15 | 6 | 1 | 6 |
|
|
84
|
+
| `hook-proof` | A hook that should refuse does refuse | 1 | 5 | 0 | 1 |
|
|
85
|
+
| `host-agent` | Software that runs as root on machines it does not own | 1 | 7 | 0 | 0 |
|
|
86
|
+
| `html-ui` | Server-rendered HTML: every value escaped | 2 | 5 | 0 | 0 |
|
|
87
|
+
| `http-api` | Any HTTP server, in any framework: records tied to their caller, guards that fail closed, versioned routes, three layers | 9 | 31 | 0 | 2 |
|
|
88
|
+
| `instrument-shell` | Instruments on a shared shell: sessions that still load, panels that keep every route | 5 | 1 | 0 | 2 |
|
|
89
|
+
| `js-ts` | JavaScript and TypeScript | 27 | 35 | 0 | 0 |
|
|
90
|
+
| `midi` | Clock, sync and sysex, right on the wire and in the audio | 5 | 9 | 0 | 2 |
|
|
91
|
+
| `mongo` | MongoDB with the native driver | 6 | 18 | 0 | 0 |
|
|
92
|
+
| `multi-tenant` | One system, many customers: no role crosses a tenant | 1 | 2 | 0 | 1 |
|
|
93
|
+
| `nginx` | NGINX in front of containers | 2 | 7 | 0 | 1 |
|
|
94
|
+
| `python` | Python: templates, errors, resources, safe subprocess calls | 2 | 11 | 0 | 1 |
|
|
95
|
+
| `react` | React: failed requests, effects, accessible controls | 2 | 6 | 0 | 0 |
|
|
96
|
+
| `reverse-engineering` | Rebuilding a machine from firmware, manuals and banks: the machine's own names first, two sources before naming, every law sourced | 9 | 4 | 1 | 6 |
|
|
97
|
+
| `shell` | Shell scripts: strict mode, quoting, shared functions | 2 | 9 | 0 | 1 |
|
|
98
|
+
| `shell-hooks` | Shell and Node hooks for Claude Code | 1 | 4 | 0 | 0 |
|
|
99
|
+
| `sound-design` | Sound proved by measuring audio: algorithms as data, neutral is exact, the meter first | 6 | 5 | 0 | 4 |
|
|
100
|
+
| `stellix` | Laws of one synth project | 5 | 5 | 1 | 0 |
|
|
101
|
+
| `stored-text` | Text from a database reaches the page through one renderer | 1 | 4 | 0 | 1 |
|
|
102
|
+
| `synth-creator` | The synth-creator configuration's own laws | 6 | 2 | 9 | 2 |
|
|
103
|
+
| `tui` | Terminal UIs | 1 | 5 | 0 | 1 |
|
|
104
|
+
| `ui-craft` | Application and page design in any web stack | 16 | 24 | 0 | 9 |
|
|
105
|
+
| `web` | Web UI: Next.js, HTML, CSS, Tailwind | 8 | 22 | 0 | 5 |
|
|
106
|
+
| `websocket` | WebSocket services: identity from the connection | 1 | 3 | 0 | 0 |
|
|
107
|
+
| `writing` | Text that goes public reads like a person wrote it | 9 | 11 | 0 | 10 |
|
|
108
|
+
| `zod` | Zod 4 schemas written once, in one folder | 2 | 0 | 1 | 0 |
|
|
109
|
+
|
|
110
|
+
## APIs are versioned, in any framework
|
|
111
|
+
|
|
112
|
+
`http-api` holds every route under `/api/v<N>/`: `api-path-versioned` reads mounts and routes in any framework, `next-api-route-versioned` reads Next.js route files, and `client-calls-a-version` reads the calls. `apis-are-versioned` says what a version promises: a published version only grows, and a breaking change is a new one with the old kept working behind `Deprecation` and `Sunset` headers. `change-an-api` walks a change. `/health`, auth callbacks and webhooks are left out, since the platform or the provider owns those paths.
|
|
113
|
+
|
|
114
|
+
## Configurations
|
|
115
|
+
|
|
116
|
+
A project is one configuration: a kind of project, as data in `configurations/<name>/config.json`. It holds the packs (`always`, `choose`, `default`), the folder template `init` creates, the order of its hooks, what doctor counts as source, and the house rules of its CLAUDE.md block. `.claude/layout.json` `"configuration"` names the project's. With none named, the install takes the configuration that has a chosen pack by default.
|
|
117
|
+
|
|
118
|
+
| Configuration | For | `init` adds by default |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `base` | Universal engineering only, for a project no other configuration fits | nothing |
|
|
121
|
+
| `cpp` | Any C++ project that is not a synth | `cpp` |
|
|
122
|
+
| `go` | Go projects | `go` |
|
|
123
|
+
| `node` | A Node.js or TypeScript service, web app, CLI, library or MCP server | `js-ts` |
|
|
124
|
+
| `python` | Python projects | `python` |
|
|
125
|
+
| `full-stack` | A Fastify API and a Next.js web app, with one schemas folder and one database gateway. It fixes a folder layout, so it is offered and never assumed. It always takes `full-stack`, `http-api`, `fastify`, `zod` and `docker` | `js-ts`, `stored-text`, `ui-craft` |
|
|
126
|
+
| `synth-creator` | JUCE synths and effects | `cpp`, `audio-core` |
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
npx --no-install @thedecipherist/claude-packs configs list them: packs, counts, folder template
|
|
130
|
+
npx --no-install @thedecipherist/claude-packs init --config <name> install one
|
|
131
|
+
npx --no-install @thedecipherist/claude-packs config <name> [--dry-run] switch; prints what changes first
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Presets
|
|
135
|
+
|
|
136
|
+
`init <preset>` installs the packs a stack needs.
|
|
137
|
+
|
|
138
|
+
| Preset | Packs |
|
|
139
|
+
|---|---|
|
|
140
|
+
| `node-api` | `js-ts`, `http-api`, `mongo`, `fastify`, `ai`, `docker` |
|
|
141
|
+
| `node-ui` | `js-ts`, `http-api`, `mongo`, `fastify`, `html-ui`, `stored-text`, `ui-craft`, `docker` |
|
|
142
|
+
| `next-app` | `js-ts`, `http-api`, `react`, `mongo`, `web`, `stored-text`, `ui-craft`, `ai`, `docker` |
|
|
143
|
+
| `mcp-server` | `js-ts`, `mongo`, `ai`, `shell-hooks` |
|
|
144
|
+
| `node-cli` | `js-ts`, `tui` |
|
|
145
|
+
| `node-lib` | `js-ts` |
|
|
146
|
+
| `edge` | `nginx`, `docker` |
|
|
147
|
+
| `synth` | `cpp`, `audio-core` |
|
|
148
|
+
| `synth-rebuild` | `cpp`, `audio-core`, `reverse-engineering`, `midi`, `sound-design`, `instrument-shell` |
|
|
149
|
+
| `python-app` | `python`, `shell`, `docker` |
|
|
150
|
+
| `shell-tools` | `shell` |
|
|
151
|
+
| `go-app` | `go`, `shell`, `docker`, `ci` |
|
|
152
|
+
|
|
153
|
+
## Commands
|
|
154
|
+
|
|
155
|
+
Each is `npx --no-install @thedecipherist/claude-packs <command>`, with `--dir <project>` for another folder.
|
|
156
|
+
|
|
157
|
+
| Command | What it does |
|
|
158
|
+
|---|---|
|
|
159
|
+
| `suggest` | The configuration and packs this project needs, with the evidence |
|
|
160
|
+
| `scan [--out <file>]` | On a copy: what to install and everything already wrong. `scan --prompt` prints the review brief for what checks cannot see |
|
|
161
|
+
| `fix [--from <scan.json>] [--out <file>]` | The last scan as a work order, `.claude/fix-plan.md`; scans first if there is none |
|
|
162
|
+
| `init [pack...] [--auto]` | Install packs or a preset. `--auto` takes what `suggest` finds; `--config`, `--profile` and `--layout` choose the start |
|
|
163
|
+
| `add <pack...> [--from <git-url>]` | Add packs, a team's own included |
|
|
164
|
+
| `remove <pack...>` | Remove packs; files you edited are kept |
|
|
165
|
+
| `update` | Re-sync installed packs from this version |
|
|
166
|
+
| `update-all <dir...>` | Update every listed project that has the kit |
|
|
167
|
+
| `logs` | Which hooks earn their place: calls, refusals and verdicts per hook. `logs refusals`, `logs mark <id> right\|wrong "<why>"` |
|
|
168
|
+
| `doctor [--strict] [--fresh]` | Verify the install: paths, hooks, selftests, checks' own examples, hook timing |
|
|
169
|
+
| `new <name>` | A new project: the house files, a git repo on a work branch, the kit installed |
|
|
170
|
+
| `new-pack <name> [--repo <git-url>]` | A new repository for a team's own pack |
|
|
171
|
+
| `list` | The packs and presets |
|
|
172
|
+
| `configs` | The configurations |
|
|
173
|
+
| `config <name> [--dry-run]` | Switch configuration |
|
|
174
|
+
| `planner-skills [--out <dir>]` | One project-layout skill body per configuration |
|
|
175
|
+
| `survey` | Print the prompt that makes Claude write `docs/project.md` for tailoring |
|
|
176
|
+
| `shape scan` | Every instance literal in the repo, against `design/shape.json` |
|
|
177
|
+
| `symmetry gen\|run` | The generated gate: every instance has the same members, and every pair swaps the same |
|
|
178
|
+
| `dup scan` | Every duplicated block, by file |
|
|
179
|
+
| `global add\|remove\|doctor` | The global part, below |
|
|
180
|
+
| `lock status\|take\|release` | This repo's own lock, for work on the kit |
|
|
181
|
+
|
|
182
|
+
## The hooks every project gets
|
|
183
|
+
|
|
184
|
+
| Hook | When | What it does |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| `making` | Prompt | Asks what is being made and what it reuses |
|
|
187
|
+
| `reuse-hint` | Prompt | Shows functions the repo already has when the prompt names them |
|
|
188
|
+
| `lesson-checks` | Write | Runs the installed lesson checks on what a write adds |
|
|
189
|
+
| `template-law` | Write | Refuses a copy, a near copy or a function made again |
|
|
190
|
+
| `once-only` | Write | Refuses a duplicate of code as written |
|
|
191
|
+
| `code-shape` | Write | Refuses wide lines, packed lines, long functions, long parameter lists |
|
|
192
|
+
| `file-size-guard` | Write | Refuses a source file past its line limit |
|
|
193
|
+
| `dispatch-once` | Write | Refuses a `switch` on a kind already switched on in another file |
|
|
194
|
+
| `folder-law` | Write | Refuses a new source file outside the layout |
|
|
195
|
+
| `placement-law` | Write | Refuses a kind of thing in the wrong folder |
|
|
196
|
+
| `shape-law` | Write | Refuses a literal instance of a many concept |
|
|
197
|
+
| `brief-guard` | Write | Refuses a brief that names a fixed instance |
|
|
198
|
+
| `secrets-guard` | Write | Refuses a secret in code, or a secret file in git |
|
|
199
|
+
| `untrusted-boundary` | Write | Refuses a model call with outside text and no per-call boundary |
|
|
200
|
+
| `git-guard` | Bash | Refuses a token in git config, and with `house: true` the git laws: stage by name, no rebase or force, branches from the fetched trunk |
|
|
201
|
+
| `suite-once` | Bash | Refuses the whole test suite on uncommitted work |
|
|
202
|
+
| `repo-litter` | Bash | Refuses `git add` of a big file, a working screenshot in the root, or a debug dump |
|
|
203
|
+
| `making-check` | Stop | Sends a turn back when what it wrote is not what it said |
|
|
204
|
+
|
|
205
|
+
Packs add their own: `realtime-guard` and `param-id-lock` (`audio-core`), `stack-guard` (`full-stack`), `schemas-only` (`zod`), `firmware-out-of-git` (`reverse-engineering`), `browser-guard` (`gpu-painter`), `no-shipped-images` (`stellix`), and the `synth-creator` set: `build-guard`, `time-guard`, `spec-lock`, `frozen-files`, `protect-vendor`, `stage-guard`, and the opt-in `build-sweep`, `idle-wake` and `user-asks`.
|
|
206
|
+
|
|
207
|
+
Every hook is timed to `.claude/hooks.log`, and `doctor` is red for a median over 500 ms. Nothing is ever cleared: a log past 1 MB moves to `.claude/logs/` under a dated name (`"guards": { "logs": { "maxKb": 1024 } }`). A hook that crashes lets a call through, so `doctor` is red for that too, and the `hook-proof` pack holds hooks to exit 2. Hooks of one entry run in one Node process, through `run-hooks.mjs`.
|
|
208
|
+
|
|
209
|
+
## Instruments, proved in the audio
|
|
210
|
+
|
|
211
|
+
Four packs carry what rebuilding classic machines from firmware taught, and most of it is about failures that pass every test: units deaf to the transport, presets silently on defaults, a list of algorithms behind one DSP path.
|
|
212
|
+
|
|
213
|
+
`reverse-engineering` starts from the machine's own names: `names-sweep` searches an image for what the manual prints, in the forms a display uses and through every wrapping met so far, and reports the record size, the order, the pools and the tables; `menu-map` joins every parameter to the page that reaches it. It needs two sources before anything is named, a source tag on every law and a debt ledger for what was tuned by ear, and it keeps firmware out of git. `midi` holds the law of clock and sync, and treats a program as records that round-trip byte for byte. `sound-design` proves sound by measuring audio. `instrument-shell` keeps sessions loadable and panels reachable. `init synth-rebuild` takes them all.
|
|
214
|
+
|
|
215
|
+
A project says what it is, in `"guards": { "instrument": { "kind": "reproduction" } }` or `"original"`, because the laws differ: on a reproduction the machine is the spec, aliasing and all.
|
|
216
|
+
|
|
217
|
+
## Published text is not code
|
|
218
|
+
|
|
219
|
+
A content folder (`articles/`, `blog/`, `posts/`, `content/`, `tutorials/`, `examples/`, `samples/`) holds text and samples. The writing laws read it. The code laws, `template-law`, `code-shape`, `once-only` and `file-size-guard` leave it alone, and `scan` lists what it finds there apart, so a tutorial's compose file is never a project fault and a sample key never heads the report. Under a code root the word means nothing: `src/app/blog/page.tsx` is code. `"guards": { "content": ["<glob>"] }` adds a project's own.
|
|
220
|
+
|
|
221
|
+
Dates are facts in an article. The `no-time-or-date` check is opt-in, for an author who wants none in posts, and even then it leaves articles alone.
|
|
222
|
+
|
|
223
|
+
## Knowing which hooks earn their place
|
|
224
|
+
|
|
225
|
+
A bug log only records the refusals somebody complained about, so it cannot say whether a hook works. The kit records them all. Every call is a line of `.claude/logs/events.jsonl`: the session, the tool, the file or command, and each hook's time, exit code and reason. Every refusal and crash is also a line of `refusals.jsonl`, with an id, the branch and commit, the kit's version and the hash of the hook that decided. Secrets are masked, and file contents are not kept.
|
|
226
|
+
|
|
227
|
+
`logs` adds it all up, over every rotated file. `logs mark <id> right|wrong "<why>"` records a verdict. The logs stay out of git by default.
|
|
228
|
+
|
|
229
|
+
## Where things apply
|
|
230
|
+
|
|
231
|
+
- **`.claude/layout.json` is the one source of truth.** It names every folder and concept, and what goes where. Move a folder there, run `update`, and every rule follows.
|
|
232
|
+
- **Rules** declare their concepts (`# concepts: dsp, world`); their `paths:` are generated from the layout.
|
|
233
|
+
- **Lesson checks** resolve their concepts from the same file. `whenDep` limits a check to a dependency's major version.
|
|
234
|
+
- **CLAUDE.md** gets a generated "Project layout" section between `<!-- claude-packs:start -->` markers.
|
|
235
|
+
- **Skills** for one area go into that folder's nested `.claude/skills/`, so they only appear once Claude works there.
|
|
236
|
+
- **Hooks judge only this project's files**, and a file in a git worktree by that worktree.
|
|
237
|
+
- **`doctor --strict`** fails on a rule that matches no file and a source file no rule covers.
|
|
238
|
+
|
|
239
|
+
## It never overwrites your work
|
|
240
|
+
|
|
241
|
+
- Your own files in `.claude/` are left alone. If a pack file has the same name, the pack's version goes beside it as `<file>.pack-new`.
|
|
242
|
+
- A pack file you edited is kept on every update, with the new version beside it. `--force` replaces edited pack files, never your own files.
|
|
243
|
+
- In `CLAUDE.md`, only the marked section is written. In `settings.json`, only this package's hooks change. A malformed `settings.json` stops the run before anything changes.
|
|
244
|
+
- `layout.json` keeps your edits, and the keys a project owns survive every update.
|
|
245
|
+
- `CLAUDE.md`, `settings.json`, `layout.json` and the lock are backed up to `.claude/.claude-packs-backup/` before every run.
|
|
246
|
+
- Files that leave a pack are removed only if you never edited them.
|
|
247
|
+
|
|
248
|
+
## Nothing new switches on unless you chose it
|
|
249
|
+
|
|
250
|
+
A hook or a check refuses work, so a new one never appears in a project by surprise.
|
|
251
|
+
|
|
252
|
+
- `init` and `add` bring every hook and check of the packs named, except the opt-in ones.
|
|
253
|
+
- `update` brings a hook or check new to the project only when `.claude/layout.json` `"enable"` names it, as in `"enable": ["hooks/template-law.mjs"]`.
|
|
254
|
+
- `update` prints both lists before it changes anything: what is switching on, and what is held back.
|
|
255
|
+
|
|
256
|
+
## Custom packs: share your own with your team
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
npx --no-install @thedecipherist/claude-packs new-pack acme-internal --repo git@git.acme.example:team/acme-internal.git
|
|
260
|
+
# edit packs/acme-internal/, push it, then in any project:
|
|
261
|
+
npx --no-install @thedecipherist/claude-packs add acme-internal --from git@git.acme.example:team/acme-internal.git
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
A pack is rules, checks, hooks and skills in a folder, in a repository of your own. `update` pulls the newest, and the lock records the commit, so teammates get the same pack. Hooks from a custom pack stay off until `"enable"` names them.
|
|
265
|
+
|
|
266
|
+
A `pack.json` is a manifest like a `package.json`. `name`, `version`, `description`, `type`, `author`, `license` and `repository.url` are required, and `type` is `stock` for the packs in this package and `custom` for anyone else's:
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"name": "acme-internal",
|
|
271
|
+
"version": "1.2.0",
|
|
272
|
+
"description": "What it is for.",
|
|
273
|
+
"type": "custom",
|
|
274
|
+
"author": "Acme Platform Team <platform@acme.example>",
|
|
275
|
+
"license": "UNLICENSED",
|
|
276
|
+
"repository": { "type": "git", "url": "git@git.acme.example:platform/claude-packs-acme.git" },
|
|
277
|
+
"engines": { "claude-packs": ">=0.19.0" }
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Fitting a real repo
|
|
282
|
+
|
|
283
|
+
Run `survey` and give the printed prompt to Claude Code. It writes `docs/project.md`: the real folder tree, where every concern lives, and how the code is built. The layout, concepts and rules are then tuned to it. A new project starts with `new <name>`.
|
|
284
|
+
|
|
285
|
+
## Working across projects
|
|
286
|
+
|
|
287
|
+
- This project's hooks judge only this project's files, so an edit in a sibling project is never refused.
|
|
288
|
+
- `layout.siblings` adds sibling folders to `permissions.additionalDirectories`.
|
|
289
|
+
- `update-all ~/projects/*` updates and doctors every project that has the kit, and skips the rest.
|
|
290
|
+
|
|
291
|
+
## The global part: exactly three pieces
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
npx --no-install @thedecipherist/claude-packs global add
|
|
295
|
+
npx --no-install @thedecipherist/claude-packs global doctor
|
|
296
|
+
npx --no-install @thedecipherist/claude-packs global remove # removes only what it installed and you did not edit
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Everything else in this package is per project. `global add` installs these into `~/.claude` and nothing else:
|
|
300
|
+
|
|
301
|
+
1. **latest-versions**, a skill and its `version-pin-guard` hook. Before Claude adds or pins a dependency, it looks up the current release, because that applies to every project. The hook refuses a pin whose row in `docs/versions.md` is over 14 days old.
|
|
302
|
+
2. **gnu-shell**: bash 5 and the GNU tools first on the Bash tool's PATH on macOS and Linux, with a warning in a zsh session.
|
|
303
|
+
3. **shell-traps**: refuses BSD flags, unsplit zsh words and `;`-chained destructive steps.
|
|
304
|
+
|
|
305
|
+
Global by design: they fix this machine's shell for Claude, not any project's rules.
|
|
306
|
+
|
|
307
|
+
## Working on the kit
|
|
308
|
+
|
|
309
|
+
`CLAUDE.md` is the guide. `CHANGELOG.md` has every release, and [docs/history.md](docs/history.md) keeps the notes from earlier versions, with upgrade notes for old installs. `npm test` runs the whole suite, and `test/readme.test.mjs` fails when this page falls behind the packs, the configurations or the commands.
|
|
310
|
+
|
|
311
|
+
## Credits
|
|
312
|
+
|
|
313
|
+
The kit learned from [superpowers](https://github.com/obra/superpowers) (MIT), mddkit and MDD, Vercel's Web Interface Guidelines (MIT), Anthropic's frontend-design (Apache 2.0), Impeccable (Apache 2.0), taste-skill and imagegen-skills (MIT). [docs/ui-craft-sources.md](docs/ui-craft-sources.md) says what came from each UI source.
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// claude-packs: per-project Claude Code rules, checks, hooks and skills for The Decipherist's synths.
|
|
3
|
+
// Everything installs into the project's own .claude/ (and nested skill folders).
|
|
4
|
+
// The one exception is `global`: latest-versions (skill and hook), gnu-shell and shell-traps.
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { doctor } from '../lib/doctor.mjs';
|
|
9
|
+
import { globalAdd, globalDoctor, globalRemove } from '../lib/global.mjs';
|
|
10
|
+
import { lockCommand } from '../lib/kit-lock.mjs';
|
|
11
|
+
import { readLock } from '../lib/manifest.mjs';
|
|
12
|
+
import { newProject } from '../lib/new.mjs';
|
|
13
|
+
import { dupScan } from '../lib/once-only-report.mjs';
|
|
14
|
+
import { PRESETS, availablePacks, readPack } from '../lib/packs.mjs';
|
|
15
|
+
import { describeConfigs, layoutConfiguration, readConfig, switchConfig } from '../lib/config-cli.mjs';
|
|
16
|
+
import { plannerSkills } from '../lib/planner.mjs';
|
|
17
|
+
import { addCustomPack, loadCustomPacks, newPack } from '../lib/custom-packs.mjs';
|
|
18
|
+
import { fixPlan } from '../lib/fix-plan.mjs';
|
|
19
|
+
import { logsCommand } from '../lib/logs.mjs';
|
|
20
|
+
import { scan } from '../lib/scan.mjs';
|
|
21
|
+
import { suggest, suggestionOf } from '../lib/suggest.mjs';
|
|
22
|
+
import { sync } from '../lib/sync.mjs';
|
|
23
|
+
import { ensureShape, isSynth, shapeCommand } from '../lib/shape-cli.mjs';
|
|
24
|
+
|
|
25
|
+
const HELP = `usage: npx --no-install @thedecipherist/claude-packs <command> [options]
|
|
26
|
+
|
|
27
|
+
new <name> a new project in <dir>/<name>: the house files (CLAUDE.md, build.md, bugs.md,
|
|
28
|
+
workflow-bugs.md, docs/versions.md), a git repo on a work/ branch, the kit installed
|
|
29
|
+
--packs <a,b> the packs (default audio-core); --profile <name>, --config <name> as for init
|
|
30
|
+
init [pack...] install packs or presets (e.g. init node-api; list shows them); base is always included
|
|
31
|
+
and create the layout folders
|
|
32
|
+
--config <name> the configuration (configs lists them; stored in layout.json
|
|
33
|
+
"configuration"); with no packs named, the ones it takes by default
|
|
34
|
+
--profile <name> start from a tailored layout shipped in the package (e.g. stellix)
|
|
35
|
+
--layout <file> start from your own layout.json
|
|
36
|
+
--auto the configuration and packs suggest finds, so nobody picks them by hand
|
|
37
|
+
add <pack...> add packs to an existing install
|
|
38
|
+
--from <git-url> a custom pack from a team's repository; its hooks stay off until "enable" names them
|
|
39
|
+
new-pack <name> [--repo <git-url>] a new repository for a team's own pack, ready to edit and push
|
|
40
|
+
remove <pack...> remove packs (files you edited are kept)
|
|
41
|
+
update re-sync installed packs from this package version, in the project's configuration
|
|
42
|
+
configs list the configurations: what each installs, its packs and its folder template
|
|
43
|
+
config <name> switch this project to another configuration; prints what changes first
|
|
44
|
+
--dry-run print what would change and stop
|
|
45
|
+
planner-skills [--out <dir>] one project-layout skill body per configuration, from its layout template
|
|
46
|
+
(printed, or written to <dir>/<configuration>/project-layout/SKILL.md)
|
|
47
|
+
update-all <dir...> update every listed project that already has claude-packs
|
|
48
|
+
(e.g. update-all ~/projects/*); folders without it are skipped
|
|
49
|
+
doctor [--strict] [--fresh] verify the install (paths, folders, hooks, checks' own examples); a hook's selftest that
|
|
50
|
+
passed is not run again until the hook changes (--fresh runs them all); --strict also fails
|
|
51
|
+
when a rule matches no file or a source file is covered by no rule
|
|
52
|
+
shape scan every instance literal in the repo (code, tests, docs, briefs), by file and concept,
|
|
53
|
+
with a count, against design/shape.json; exit 1 when any
|
|
54
|
+
scan [--out <file>] before installing anything: on a copy of the project, what to install and every issue the checks
|
|
55
|
+
find; the project is never touched. scan --prompt prints the review brief for what checks cannot see
|
|
56
|
+
suggest which configuration and packs this project needs, read from its own files, with the evidence
|
|
57
|
+
fix [--from <scan.json>] [--out <file>] the last scan as a work order for Claude, .claude/fix-plan.md; scans first if there is none
|
|
58
|
+
logs which hooks earn their place: calls, refusals and verdicts per hook, over all the history
|
|
59
|
+
logs refusals [--hook <h>] [--open]; logs mark <id> right|wrong "<why>"
|
|
60
|
+
survey print the prompt that makes Claude write docs/project.md for tailoring
|
|
61
|
+
list show available packs
|
|
62
|
+
symmetry gen --cmake <out.cmake> | --list the generated gate shape_symmetry: one test per many concept in
|
|
63
|
+
design/shape.json (add_test lines a CMakeLists includes at configure time, or plain lines)
|
|
64
|
+
symmetry run <concept> that gate for one concept: every instance the same members, every pair swaps the same
|
|
65
|
+
dup scan every duplicated block (jscpd, the once-only hook's detector), listed by file
|
|
66
|
+
lock status|take [--branch <b>]|release [--force]
|
|
67
|
+
the claude-packs repo's kit lock, a lease, in each checkout: who holds it, since when, last seen,
|
|
68
|
+
live or stale (30 min without renewal); take takes it for this session (a stale one is taken over
|
|
69
|
+
and logged); release takes away your own lock or a stale one, never a live lease without --force
|
|
70
|
+
global add|remove|doctor
|
|
71
|
+
the global part, exactly three pieces: latest-versions (skill and
|
|
72
|
+
version-pin-guard), gnu-shell, shell-traps, in ~/.claude (never
|
|
73
|
+
overwrites; --home <dir> to target another home)
|
|
74
|
+
|
|
75
|
+
options: --dir <project> (default: current folder) --force (replace files you edited)`;
|
|
76
|
+
|
|
77
|
+
function parse(argv) {
|
|
78
|
+
const opts = { dir: process.cwd(), force: false, strict: false, rest: [], seed: null, home: undefined, packs: null, config: null, dryRun: false };
|
|
79
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
80
|
+
if (argv[i] === '--dir') opts.dir = argv[++i];
|
|
81
|
+
else if (argv[i] === '--packs') opts.packs = argv[++i].split(',').map((p) => p.trim()).filter(Boolean);
|
|
82
|
+
else if (argv[i] === '--profile') opts.seed = fileURLToPath(new URL(`../profiles/${argv[++i]}.layout.json`, import.meta.url));
|
|
83
|
+
else if (argv[i] === '--layout') opts.seed = resolve(argv[++i]);
|
|
84
|
+
else if (argv[i] === '--config') opts.config = argv[++i];
|
|
85
|
+
else if (argv[i] === '--dry-run') opts.dryRun = true;
|
|
86
|
+
else if (argv[i] === '--force') opts.force = true;
|
|
87
|
+
else if (argv[i] === '--strict') opts.strict = true;
|
|
88
|
+
else if (argv[i] === '--fresh') opts.fresh = true;
|
|
89
|
+
else if (argv[i] === '--home') opts.home = resolve(argv[++i]);
|
|
90
|
+
else opts.rest.push(argv[i]);
|
|
91
|
+
}
|
|
92
|
+
opts.dir = resolve(opts.dir);
|
|
93
|
+
return opts;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function main() {
|
|
97
|
+
const [command, ...argv] = process.argv.slice(2);
|
|
98
|
+
const { dir, force, strict, fresh, rest, seed, home, packs, config, dryRun } = parse(argv);
|
|
99
|
+
const seedLayout = seed ? JSON.parse(readFileSync(seed, 'utf8')) : null;
|
|
100
|
+
const installed = readLock(resolve(dir, '.claude')).packs;
|
|
101
|
+
const fromUrl = rest.includes('--from') ? rest.splice(rest.indexOf('--from'), 2)[1] : null;
|
|
102
|
+
const fetched = ['new-pack', 'scan', 'suggest', 'fix', 'logs', 'global'].includes(command) ? {} : loadCustomPacks(dir, { latest: command === 'update' });
|
|
103
|
+
|
|
104
|
+
switch (command) {
|
|
105
|
+
case 'new':
|
|
106
|
+
return (await newProject(dir, rest[0], { packs: packs ?? (config ? readConfig(config).packs.default : ['audio-core']), seedLayout, config })).code;
|
|
107
|
+
case 'init': {
|
|
108
|
+
if (rest.includes('--auto')) {
|
|
109
|
+
const pick = suggestionOf(dir);
|
|
110
|
+
await sync(dir, pick.packs.map((p) => p.pack), { force, mkdirs: true, seedLayout, config: pick.config });
|
|
111
|
+
return doctor(dir);
|
|
112
|
+
}
|
|
113
|
+
if (rest.length === 0 && !config) throw new Error('name at least one pack or a configuration, e.g. `init audio-core` or `init --config base` (`configs` lists them)');
|
|
114
|
+
const chosen = rest.length ? rest : readConfig(config).packs.default;
|
|
115
|
+
await sync(dir, chosen, { force, mkdirs: true, seedLayout, config });
|
|
116
|
+
if (isSynth(chosen) && ensureShape(dir)) console.log(' design/shape.json: written empty; add a row per concept (one or many) before building it');
|
|
117
|
+
return doctor(dir);
|
|
118
|
+
}
|
|
119
|
+
case 'planner-skills':
|
|
120
|
+
return plannerSkills(rest.includes('--out') ? resolve(rest[rest.indexOf('--out') + 1]) : null);
|
|
121
|
+
case 'configs':
|
|
122
|
+
console.log(describeConfigs(layoutConfiguration(dir)));
|
|
123
|
+
return 0;
|
|
124
|
+
case 'config':
|
|
125
|
+
return switchConfig(dir, rest[0], installed, { force, dryRun });
|
|
126
|
+
case 'add': {
|
|
127
|
+
const sources = fromUrl ? { ...fetched, [rest[0]]: addCustomPack(rest[0], fromUrl) } : fetched;
|
|
128
|
+
await sync(dir, [...installed, ...rest], { force, mkdirs: true, sources });
|
|
129
|
+
return doctor(dir);
|
|
130
|
+
}
|
|
131
|
+
case 'remove':
|
|
132
|
+
await sync(dir, installed.filter((p) => p === 'base' || !rest.includes(p)), { force });
|
|
133
|
+
return doctor(dir);
|
|
134
|
+
case 'update':
|
|
135
|
+
if (installed.length === 0) throw new Error('nothing installed here; run init first');
|
|
136
|
+
await sync(dir, installed, { force, mkdirs: true, sources: fetched });
|
|
137
|
+
return doctor(dir);
|
|
138
|
+
case 'update-all': {
|
|
139
|
+
let failed = 0;
|
|
140
|
+
for (const d of rest.map((x) => resolve(x))) {
|
|
141
|
+
const lockPacks = readLock(resolve(d, '.claude')).packs;
|
|
142
|
+
if (lockPacks.length === 0) continue;
|
|
143
|
+
console.log(`\n== ${d}`);
|
|
144
|
+
try {
|
|
145
|
+
await sync(d, lockPacks, { force, mkdirs: true });
|
|
146
|
+
failed += await doctor(d);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
failed += 1;
|
|
149
|
+
console.log(` PROBLEM: ${e.message}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return failed ? 1 : 0;
|
|
153
|
+
}
|
|
154
|
+
case 'doctor':
|
|
155
|
+
return doctor(dir, console.log, { strict, fresh });
|
|
156
|
+
case 'shape':
|
|
157
|
+
return shapeCommand(rest[0], dir);
|
|
158
|
+
case 'scan':
|
|
159
|
+
if (rest.includes('--prompt')) { process.stdout.write(readFileSync(fileURLToPath(new URL('../prompts/scan-review.md', import.meta.url)), 'utf8')); return 0; }
|
|
160
|
+
await scan(dir, { out: rest.includes('--out') ? resolve(rest[rest.indexOf('--out') + 1]) : null });
|
|
161
|
+
return 0;
|
|
162
|
+
case 'logs':
|
|
163
|
+
return logsCommand(dir, rest);
|
|
164
|
+
case 'suggest':
|
|
165
|
+
suggest(dir);
|
|
166
|
+
break;
|
|
167
|
+
case 'fix':
|
|
168
|
+
await fixPlan(dir, { from: fromUrl ? resolve(fromUrl) : null, out: rest.includes('--out') ? resolve(rest[rest.indexOf('--out') + 1]) : null });
|
|
169
|
+
break;
|
|
170
|
+
case 'new-pack':
|
|
171
|
+
return newPack(dir, rest[0], { repo: rest.includes('--repo') ? rest[rest.indexOf('--repo') + 1] : null });
|
|
172
|
+
case 'survey':
|
|
173
|
+
process.stdout.write(readFileSync(fileURLToPath(new URL('../prompts/survey.md', import.meta.url)), 'utf8'));
|
|
174
|
+
return 0;
|
|
175
|
+
case 'global': {
|
|
176
|
+
const run = { add: globalAdd, remove: globalRemove, doctor: globalDoctor }[rest[0]];
|
|
177
|
+
if (!run) throw new Error('use `global add`, `global remove` or `global doctor`');
|
|
178
|
+
return run({ home, force });
|
|
179
|
+
}
|
|
180
|
+
case 'symmetry':
|
|
181
|
+
return (await import('../packs/base/tools/shape-symmetry.mjs')).main([...rest, '--dir', dir]);
|
|
182
|
+
case 'dup':
|
|
183
|
+
if (rest[0] !== 'scan') throw new Error('use `dup scan [--dir <project>]`');
|
|
184
|
+
return dupScan(dir);
|
|
185
|
+
case 'lock':
|
|
186
|
+
return lockCommand(rest[0], dir, { force, branch: rest.includes('--branch') ? rest[rest.indexOf('--branch') + 1] : undefined });
|
|
187
|
+
case 'list':
|
|
188
|
+
for (const name of availablePacks()) { const p = readPack(name); console.log(`${name.padEnd(14)}${p.version.padEnd(8)}${p.type.padEnd(7)}${p.author}: ${p.description}`); }
|
|
189
|
+
console.log('\npresets (init <preset> installs the packs that stack needs):');
|
|
190
|
+
for (const [name, packs] of Object.entries(PRESETS)) console.log(`${name.padEnd(12)} ${packs.join(', ')}`);
|
|
191
|
+
return 0;
|
|
192
|
+
default:
|
|
193
|
+
console.log(HELP);
|
|
194
|
+
return command ? 2 : 0;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
main().then(
|
|
199
|
+
(code) => process.exit(code ?? 0),
|
|
200
|
+
(err) => {
|
|
201
|
+
console.error(`claude-packs: ${err.message}`);
|
|
202
|
+
process.exit(2);
|
|
203
|
+
},
|
|
204
|
+
);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "base",
|
|
3
|
+
"description": "Universal engineering only: the git laws, the line limit, the folder and placement laws, the shape law, once-only, making, secrets and the untrusted-content boundary. For a project no other configuration fits.",
|
|
4
|
+
"packs": {
|
|
5
|
+
"always": [
|
|
6
|
+
"base",
|
|
7
|
+
"writing",
|
|
8
|
+
"hook-proof"
|
|
9
|
+
],
|
|
10
|
+
"choose": [
|
|
11
|
+
"shell",
|
|
12
|
+
"ci",
|
|
13
|
+
"docker",
|
|
14
|
+
"web",
|
|
15
|
+
"ui-craft",
|
|
16
|
+
"content-site", "reverse-engineering"
|
|
17
|
+
],
|
|
18
|
+
"default": []
|
|
19
|
+
},
|
|
20
|
+
"layout": {
|
|
21
|
+
"folders": {
|
|
22
|
+
"docs": {
|
|
23
|
+
"path": "docs",
|
|
24
|
+
"purpose": "spec, laws, licences, work orders, decisions"
|
|
25
|
+
},
|
|
26
|
+
"src": {
|
|
27
|
+
"path": "src",
|
|
28
|
+
"purpose": "all source code, only inside the subfolders below"
|
|
29
|
+
},
|
|
30
|
+
"tests": {
|
|
31
|
+
"path": "tests",
|
|
32
|
+
"purpose": "unit tests, gates with planted faults, golden files"
|
|
33
|
+
},
|
|
34
|
+
"tools": {
|
|
35
|
+
"path": "tools",
|
|
36
|
+
"purpose": "scripts and research tooling (not shipped)"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"kinds": {
|
|
40
|
+
"tests": {
|
|
41
|
+
"what": "tests, gates with planted faults, golden renders",
|
|
42
|
+
"in": "tests",
|
|
43
|
+
"concepts": [
|
|
44
|
+
"tests"
|
|
45
|
+
],
|
|
46
|
+
"files": [
|
|
47
|
+
"**/*_test.*",
|
|
48
|
+
"**/*Test.cpp",
|
|
49
|
+
"**/*Tests.cpp",
|
|
50
|
+
"**/test_*.*",
|
|
51
|
+
"**/*.test.*"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"docs": {
|
|
55
|
+
"what": "the spec, laws.md, decisions, research, work orders",
|
|
56
|
+
"in": "docs",
|
|
57
|
+
"concepts": [
|
|
58
|
+
"docs-folder"
|
|
59
|
+
],
|
|
60
|
+
"files": [
|
|
61
|
+
"**/laws.md",
|
|
62
|
+
"**/*-spec.md"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
"tools": {
|
|
66
|
+
"what": "scripts and research tools that never ship",
|
|
67
|
+
"in": "tools"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"preamble": {
|
|
72
|
+
"always": [
|
|
73
|
+
"Ask the user before inventing a new folder. A new folder goes into `.claude/layout.json` first.",
|
|
74
|
+
"When a hook, check or guard blocks work that is correct, stop and report its exact message. A blocking hook is a red check: fix the hook first, with a selftest, then continue.",
|
|
75
|
+
"When a command is refused or fails, the step fails loudly. Never report a refused write or a failed command as done.",
|
|
76
|
+
"claude-packs (`~/projects/claude-packs`) is the source of truth for every rule, check, hook and skill this project's configuration installs. A fix to one of them is made there with its test, committed, pushed and released as a new version, then taken in with `npx --no-install @thedecipherist/claude-packs update`. A project edits its installed copy only to try a fix before it goes into the kit."
|
|
77
|
+
],
|
|
78
|
+
"never": [
|
|
79
|
+
"Create source files outside these folders, or put a kind of thing anywhere but its place. The folder-law and placement-law hooks refuse both.",
|
|
80
|
+
"Edit files in `.claude/rules`, `.claude/checks` or `.claude/hooks` to get past a block. Fix the code, or ask the user to change the law.",
|
|
81
|
+
"Route around a block: no override variables, no writing through the shell after a refusal, no parking files in a scratchpad, no putting new code into an unrelated existing file.",
|
|
82
|
+
"Point at a document by line number. Cite a fixed anchor (`{#id}`) or a symbol name; lines move."
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
}
|