claude-code-superkit 0.0.0-stage → 1.5.3
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/LICENSE +21 -0
- package/README.md +374 -2
- package/bin/cli.js +153 -0
- package/bin/inject-tokens.js +224 -0
- package/bin/measure-tokens.js +17 -0
- package/bin/superkit-counts-verify.sh +30 -0
- package/lib/codex.js +246 -0
- package/lib/docs-scaffold.js +147 -0
- package/lib/installer.js +499 -0
- package/lib/prompts.js +51 -0
- package/lib/settings-builder.js +51 -0
- package/lib/superpowers.js +99 -0
- package/lib/utils.js +117 -0
- package/lib/validator.js +84 -0
- package/package.json +49 -4
- package/packages/codex/AGENTS.md +396 -0
- package/packages/codex/INSTALL.md +342 -0
- package/packages/codex/config.toml +22 -0
- package/packages/codex/hooks/superkit.mjs +203 -0
- package/packages/codex/hooks.json +30 -0
- package/packages/codex/legacy-baseline.json +88 -0
- package/packages/codex/native-skills.txt +65 -0
- package/packages/codex/rules/default.rules +565 -0
- package/packages/codex/skills/ai-slop-cleaner/SKILL.md +44 -0
- package/packages/codex/skills/api-contract-sync/SKILL.md +96 -0
- package/packages/codex/skills/architect/SKILL.md +49 -0
- package/packages/codex/skills/audit-backend/SKILL.md +80 -0
- package/packages/codex/skills/audit-frontend/SKILL.md +82 -0
- package/packages/codex/skills/audit-infra/SKILL.md +87 -0
- package/packages/codex/skills/audit-orchestrator/SKILL.md +114 -0
- package/packages/codex/skills/behavioral-nudge-engine/SKILL.md +110 -0
- package/packages/codex/skills/benchmark/SKILL.md +49 -0
- package/packages/codex/skills/bot-reviewer/SKILL.md +94 -0
- package/packages/codex/skills/code-reviewer/SKILL.md +67 -0
- package/packages/codex/skills/codebase-onboarding-engineer/SKILL.md +46 -0
- package/packages/codex/skills/comment-rot-analyzer/SKILL.md +75 -0
- package/packages/codex/skills/commit-helper/SKILL.md +101 -0
- package/packages/codex/skills/critic/SKILL.md +56 -0
- package/packages/codex/skills/database-reviewer/SKILL.md +79 -0
- package/packages/codex/skills/debug-observer/SKILL.md +107 -0
- package/packages/codex/skills/dependency-checker/SKILL.md +69 -0
- package/packages/codex/skills/design-system-reviewer/SKILL.md +121 -0
- package/packages/codex/skills/dev-orchestrator/SKILL.md +304 -0
- package/packages/codex/skills/docs-reviewer/SKILL.md +86 -0
- package/packages/codex/skills/drizzle-orm-expert/SKILL.md +246 -0
- package/packages/codex/skills/e2e-test-generator/SKILL.md +95 -0
- package/packages/codex/skills/evaluator/SKILL.md +63 -0
- package/packages/codex/skills/frontend-perf-reviewer/SKILL.md +95 -0
- package/packages/codex/skills/frontend-ui-color-reviewer/SKILL.md +68 -0
- package/packages/codex/skills/frontend-ui-design-critic/SKILL.md +99 -0
- package/packages/codex/skills/frontend-ui-interaction-reviewer/SKILL.md +102 -0
- package/packages/codex/skills/frontend-ui-motion-reviewer/SKILL.md +85 -0
- package/packages/codex/skills/frontend-ui-reviewer/SKILL.md +81 -0
- package/packages/codex/skills/frontend-ui-typography-reviewer/SKILL.md +62 -0
- package/packages/codex/skills/gltf-debugging/SKILL.md +128 -0
- package/packages/codex/skills/go-benchmark/SKILL.md +217 -0
- package/packages/codex/skills/go-concurrency-reviewer/SKILL.md +113 -0
- package/packages/codex/skills/go-error-reviewer/SKILL.md +107 -0
- package/packages/codex/skills/go-grpc-patterns/SKILL.md +285 -0
- package/packages/codex/skills/go-modernizer/SKILL.md +111 -0
- package/packages/codex/skills/go-observability-reviewer/SKILL.md +121 -0
- package/packages/codex/skills/go-performance-reviewer/SKILL.md +112 -0
- package/packages/codex/skills/go-reviewer/SKILL.md +109 -0
- package/packages/codex/skills/go-samber-do/SKILL.md +158 -0
- package/packages/codex/skills/go-samber-lo/SKILL.md +178 -0
- package/packages/codex/skills/go-samber-oops/SKILL.md +174 -0
- package/packages/codex/skills/goal-verifier/SKILL.md +53 -0
- package/packages/codex/skills/health-checker/SKILL.md +109 -0
- package/packages/codex/skills/html-to-3d-texture/SKILL.md +153 -0
- package/packages/codex/skills/impeccable-craft/SKILL.md +101 -0
- package/packages/codex/skills/lint-runner/SKILL.md +85 -0
- package/packages/codex/skills/migrate/SKILL.md +60 -0
- package/packages/codex/skills/migration-reviewer/SKILL.md +88 -0
- package/packages/codex/skills/minimal-change-engineer/SKILL.md +44 -0
- package/packages/codex/skills/new-migration/SKILL.md +59 -0
- package/packages/codex/skills/nextjs-supabase-auth/SKILL.md +227 -0
- package/packages/codex/skills/output-enforcement/SKILL.md +71 -0
- package/packages/codex/skills/plan-checker/SKILL.md +53 -0
- package/packages/codex/skills/postgresql-optimization/SKILL.md +159 -0
- package/packages/codex/skills/pre-deploy-validator/SKILL.md +111 -0
- package/packages/codex/skills/presentation-reviewer/SKILL.md +88 -0
- package/packages/codex/skills/product-3d-lighting/SKILL.md +137 -0
- package/packages/codex/skills/project-architecture/SKILL.md +52 -0
- package/packages/codex/skills/py-reviewer/SKILL.md +100 -0
- package/packages/codex/skills/r3f-scene-reviewer/SKILL.md +88 -0
- package/packages/codex/skills/r3f-scroll-driven-3d/SKILL.md +162 -0
- package/packages/codex/skills/reality-checker/SKILL.md +61 -0
- package/packages/codex/skills/redis-patterns/SKILL.md +260 -0
- package/packages/codex/skills/review-orchestrator/SKILL.md +151 -0
- package/packages/codex/skills/rs-reviewer/SKILL.md +98 -0
- package/packages/codex/skills/ru-text/SKILL.md +132 -0
- package/packages/codex/skills/scaffold-endpoint/SKILL.md +44 -0
- package/packages/codex/skills/security-scanner/SKILL.md +94 -0
- package/packages/codex/skills/silent-failure-hunter/SKILL.md +176 -0
- package/packages/codex/skills/telegram-bot-builder/SKILL.md +120 -0
- package/packages/codex/skills/test-generator/SKILL.md +79 -0
- package/packages/codex/skills/test-runner/SKILL.md +101 -0
- package/packages/codex/skills/threejs-color-management/SKILL.md +97 -0
- package/packages/codex/skills/tree-generator/SKILL.md +63 -0
- package/packages/codex/skills/ts-reviewer/SKILL.md +90 -0
- package/packages/codex/skills/ui-design-reviewer/SKILL.md +89 -0
- package/packages/codex/skills/ui-reviewer/SKILL.md +103 -0
- package/packages/codex/skills/visual-reviewer/SKILL.md +85 -0
- package/packages/codex/skills/writing-agents/SKILL.md +165 -0
- package/packages/codex/skills/writing-commands/SKILL.md +173 -0
- package/packages/core/CLAUDE.md +118 -0
- package/packages/core/INTERNAL-FILES +16 -0
- package/packages/core/agents/ai-slop-cleaner.md +187 -0
- package/packages/core/agents/api-contract-sync.md +127 -0
- package/packages/core/agents/architect.md +205 -0
- package/packages/core/agents/audit-backend.md +137 -0
- package/packages/core/agents/audit-frontend.md +129 -0
- package/packages/core/agents/audit-infra.md +182 -0
- package/packages/core/agents/behavioral-nudge-engine.md +170 -0
- package/packages/core/agents/code-reviewer.md +195 -0
- package/packages/core/agents/codebase-onboarding-engineer.md +172 -0
- package/packages/core/agents/comment-rot-analyzer.md +115 -0
- package/packages/core/agents/critic.md +172 -0
- package/packages/core/agents/database-reviewer.md +201 -0
- package/packages/core/agents/debug-observer.md +261 -0
- package/packages/core/agents/dependency-checker.md +199 -0
- package/packages/core/agents/docs-reviewer.md +206 -0
- package/packages/core/agents/e2e-test-generator.md +261 -0
- package/packages/core/agents/evaluator.md +141 -0
- package/packages/core/agents/goal-verifier.md +130 -0
- package/packages/core/agents/health-checker.md +194 -0
- package/packages/core/agents/migration-reviewer.md +161 -0
- package/packages/core/agents/minimal-change-engineer.md +219 -0
- package/packages/core/agents/plan-checker.md +139 -0
- package/packages/core/agents/pre-deploy-validator.md +189 -0
- package/packages/core/agents/reality-checker.md +175 -0
- package/packages/core/agents/scaffold-endpoint.md +162 -0
- package/packages/core/agents/security-scanner.md +236 -0
- package/packages/core/agents/silent-failure-hunter.md +276 -0
- package/packages/core/agents/test-generator.md +146 -0
- package/packages/core/agents/tree-generator.md +141 -0
- package/packages/core/agents/ui-reviewer.md +172 -0
- package/packages/core/agents/visual-reviewer.md +211 -0
- package/packages/core/commands/audit.md +166 -0
- package/packages/core/commands/benchmark.md +130 -0
- package/packages/core/commands/commit.md +148 -0
- package/packages/core/commands/dev.md +302 -0
- package/packages/core/commands/docs-init.md +75 -0
- package/packages/core/commands/lint.md +137 -0
- package/packages/core/commands/migrate.md +146 -0
- package/packages/core/commands/new-migration.md +182 -0
- package/packages/core/commands/pair.md +209 -0
- package/packages/core/commands/review.md +195 -0
- package/packages/core/commands/security-scan.md +142 -0
- package/packages/core/commands/superkit-evolve.md +231 -0
- package/packages/core/commands/superkit-init.md +274 -0
- package/packages/core/commands/test.md +108 -0
- package/packages/core/commands/workflow.md +150 -0
- package/packages/core/docs/guide/01-getting-started.md +41 -0
- package/packages/core/docs-templates/README.md +33 -0
- package/packages/core/docs-templates/adr-template.md +62 -0
- package/packages/core/docs-templates/architecture/api-contracts.md +26 -0
- package/packages/core/docs-templates/architecture/api-reference.md +48 -0
- package/packages/core/docs-templates/architecture/auth-and-sessions.md +38 -0
- package/packages/core/docs-templates/architecture/backend-layers.md +42 -0
- package/packages/core/docs-templates/architecture/data-flow.md +26 -0
- package/packages/core/docs-templates/architecture/database-schema.md +51 -0
- package/packages/core/docs-templates/architecture/deployment.md +41 -0
- package/packages/core/docs-templates/architecture/frontend-state.md +46 -0
- package/packages/core/helpers/statusline.cjs +370 -0
- package/packages/core/hooks/CHAIN-SEMANTICS.md +84 -0
- package/packages/core/hooks/audit-settings-source.sh +98 -0
- package/packages/core/hooks/audit-trail.sh +120 -0
- package/packages/core/hooks/block-dangerous-git.sh +189 -0
- package/packages/core/hooks/bundle-import-check.sh +64 -0
- package/packages/core/hooks/compact-state-inject.sh +84 -0
- package/packages/core/hooks/config-protection.sh +68 -0
- package/packages/core/hooks/console-log-warning.sh +28 -0
- package/packages/core/hooks/context-monitor.sh +35 -0
- package/packages/core/hooks/dev-edit-counter.sh +59 -0
- package/packages/core/hooks/dev-marker-set.sh +55 -0
- package/packages/core/hooks/dev-required-on-commit.sh +426 -0
- package/packages/core/hooks/doc-check-on-commit.sh +396 -0
- package/packages/core/hooks/edit-streak-check.sh +63 -0
- package/packages/core/hooks/evolve-check.sh +78 -0
- package/packages/core/hooks/gateguard-pre-edit.sh +154 -0
- package/packages/core/hooks/gateguard-record-facts.sh +37 -0
- package/packages/core/hooks/intake-classifier.py +449 -0
- package/packages/core/hooks/lib/profile.sh +141 -0
- package/packages/core/hooks/loop-guard.sh +75 -0
- package/packages/core/hooks/migration-safety.sh +56 -0
- package/packages/core/hooks/plan-completion-gate.sh +61 -0
- package/packages/core/hooks/pre-compact-save.sh +89 -0
- package/packages/core/hooks/security-patterns.sh +119 -0
- package/packages/core/hooks/session-context-restore.sh +76 -0
- package/packages/core/hooks/subagent-stop-validate.sh +73 -0
- package/packages/core/hooks/superkit-counts-verify.sh +346 -0
- package/packages/core/hooks/superkit-update.sh +367 -0
- package/packages/core/hooks/tests/README.md +42 -0
- package/packages/core/hooks/tests/audit-trail-chain_test.sh +62 -0
- package/packages/core/hooks/tests/block-dangerous-git_test.sh +144 -0
- package/packages/core/hooks/tests/chain-semantics/h1.sh +11 -0
- package/packages/core/hooks/tests/chain-semantics/h2.sh +9 -0
- package/packages/core/hooks/tests/chain-semantics/h3.sh +11 -0
- package/packages/core/hooks/tests/chain-semantics/run-experiment.sh +65 -0
- package/packages/core/hooks/tests/chain-semantics/settings-experiment.json +15 -0
- package/packages/core/hooks/tests/counts-verify_test.sh +118 -0
- package/packages/core/hooks/tests/dev-required-on-commit_test.sh +207 -0
- package/packages/core/hooks/tests/dev-required-wip-on-main_test.sh +20 -0
- package/packages/core/hooks/tests/doc-check-on-commit_test.sh +122 -0
- package/packages/core/hooks/tests/edit-streak-check_test.sh +106 -0
- package/packages/core/hooks/tests/internal-manifest_test.sh +130 -0
- package/packages/core/hooks/tests/json-path_test.sh +108 -0
- package/packages/core/hooks/tests/mirror-invariants_test.sh +139 -0
- package/packages/core/hooks/tests/nudge-throttle_test.sh +95 -0
- package/packages/core/hooks/tests/profile-helper_test.sh +21 -0
- package/packages/core/hooks/tests/run-all.sh +47 -0
- package/packages/core/hooks/tests/session-key-helper_test.sh +17 -0
- package/packages/core/hooks/tests/superkit-update_test.sh +311 -0
- package/packages/core/hooks/tests/warn-visibility_test.sh +59 -0
- package/packages/core/hooks/user-intent-detect.sh +44 -0
- package/packages/core/hooks/verify-hooks.sh +69 -0
- package/packages/core/rules/auto-commands.md +124 -0
- package/packages/core/rules/coding-style.md +68 -0
- package/packages/core/rules/dev-workflow.md +77 -0
- package/packages/core/rules/documentation.md +106 -0
- package/packages/core/rules/frontend-aesthetics.md +53 -0
- package/packages/core/rules/git-workflow.md +14 -0
- package/packages/core/rules/security.md +29 -0
- package/packages/core/rules/superkit-integrity.md +114 -0
- package/packages/core/settings.json +229 -0
- package/packages/core/skills/drizzle-orm-expert/SKILL.md +260 -0
- package/packages/core/skills/nextjs-supabase-auth/SKILL.md +259 -0
- package/packages/core/skills/postgresql-optimization/SKILL.md +150 -0
- package/packages/core/skills/project-architecture/SKILL.md +31 -0
- package/packages/core/skills/project-scanner/SKILL.md +132 -0
- package/packages/core/skills/redis-patterns/SKILL.md +261 -0
- package/packages/core/skills/ru-text/SKILL.md +156 -0
- package/packages/core/skills/telegram-bot-builder/SKILL.md +145 -0
- package/packages/core/skills/writing-agents/SKILL.md +220 -0
- package/packages/core/skills/writing-commands/SKILL.md +176 -0
- package/packages/core/skills/writing-hooks/SKILL.md +335 -0
- package/packages/extras/bot-reviewer.md +279 -0
- package/packages/extras/design-system-reviewer.md +234 -0
- package/packages/extras/red-blue-auditor/README.md +117 -0
- package/packages/extras/red-blue-auditor/agent.md +128 -0
- package/packages/extras/red-blue-auditor/patterns/agent-config.txt +4 -0
- package/packages/extras/red-blue-auditor/patterns/hook-injection.txt +8 -0
- package/packages/extras/red-blue-auditor/patterns/mcp-risk.txt +5 -0
- package/packages/extras/red-blue-auditor/patterns/permission-abuse.txt +6 -0
- package/packages/extras/red-blue-auditor/patterns/secrets.txt +17 -0
- package/packages/extras/red-blue-auditor/scan.sh +88 -0
- package/packages/extras/skillsmp-search/SKILL.md +134 -0
- package/packages/frontend-3d/README.md +62 -0
- package/packages/frontend-3d/agents/frontend-perf-reviewer.md +164 -0
- package/packages/frontend-3d/agents/presentation-reviewer.md +146 -0
- package/packages/frontend-3d/agents/r3f-scene-reviewer.md +128 -0
- package/packages/frontend-3d/agents/ui-design-reviewer.md +169 -0
- package/packages/frontend-3d/commands/capture-screen.md +166 -0
- package/packages/frontend-3d/hooks/bundle-size-warn.sh +93 -0
- package/packages/frontend-3d/hooks/gsap-pattern-check.sh +74 -0
- package/packages/frontend-3d/hooks/r3f-color-check.sh +76 -0
- package/packages/frontend-3d/hooks/tailwind-version-guard.sh +98 -0
- package/packages/frontend-3d/rules/frontend-aesthetics-3d.md +81 -0
- package/packages/frontend-3d/rules/gsap-conventions.md +129 -0
- package/packages/frontend-3d/rules/threejs-conventions.md +116 -0
- package/packages/frontend-3d/skills/gltf-debugging/SKILL.md +145 -0
- package/packages/frontend-3d/skills/html-to-3d-texture/SKILL.md +183 -0
- package/packages/frontend-3d/skills/output-enforcement/SKILL.md +79 -0
- package/packages/frontend-3d/skills/product-3d-lighting/SKILL.md +166 -0
- package/packages/frontend-3d/skills/r3f-scroll-driven-3d/SKILL.md +209 -0
- package/packages/frontend-3d/skills/threejs-color-management/SKILL.md +111 -0
- package/packages/frontend-ui/NOTICE.md +99 -0
- package/packages/frontend-ui/README.md +59 -0
- package/packages/frontend-ui/agents/ui-color-reviewer.md +174 -0
- package/packages/frontend-ui/agents/ui-design-critic.md +198 -0
- package/packages/frontend-ui/agents/ui-interaction-reviewer.md +259 -0
- package/packages/frontend-ui/agents/ui-motion-reviewer.md +266 -0
- package/packages/frontend-ui/agents/ui-reviewer.md +251 -0
- package/packages/frontend-ui/agents/ui-typography-reviewer.md +222 -0
- package/packages/frontend-ui/hooks/tests/ui-animation-easing-check_test.sh +78 -0
- package/packages/frontend-ui/hooks/tests/ui-banned-fonts-check_test.sh +77 -0
- package/packages/frontend-ui/hooks/tests/ui-color-check_test.sh +75 -0
- package/packages/frontend-ui/hooks/ui-animation-easing-check.sh +86 -0
- package/packages/frontend-ui/hooks/ui-banned-fonts-check.sh +90 -0
- package/packages/frontend-ui/hooks/ui-color-check.sh +102 -0
- package/packages/frontend-ui/rules/color-and-contrast.md +230 -0
- package/packages/frontend-ui/rules/frontend-design-aesthetics.md +124 -0
- package/packages/frontend-ui/rules/interaction-polish.md +335 -0
- package/packages/frontend-ui/rules/motion-and-animation.md +283 -0
- package/packages/frontend-ui/rules/spatial-and-layout.md +212 -0
- package/packages/frontend-ui/rules/typography-guidelines.md +185 -0
- package/packages/frontend-ui/rules/ui-anti-patterns.md +309 -0
- package/packages/frontend-ui/settings.json +24 -0
- package/packages/frontend-ui/skills/impeccable-craft/SKILL.md +187 -0
- package/packages/gan/README.md +232 -0
- package/packages/gan/agents/gan-evaluator.md +214 -0
- package/packages/gan/agents/gan-generator.md +171 -0
- package/packages/gan/agents/gan-planner.md +206 -0
- package/packages/gan/rubrics/functionality.md +66 -0
- package/packages/gan/rubrics/ui-quality.md +77 -0
- package/packages/gan/skills/gan-evaluator/SKILL.md +91 -0
- package/packages/gan/skills/gan-generator/SKILL.md +72 -0
- package/packages/gan/skills/gan-planner/SKILL.md +93 -0
- package/packages/stack-agents/go/go-concurrency-reviewer.md +210 -0
- package/packages/stack-agents/go/go-error-reviewer.md +187 -0
- package/packages/stack-agents/go/go-modernizer.md +160 -0
- package/packages/stack-agents/go/go-observability-reviewer.md +185 -0
- package/packages/stack-agents/go/go-performance-reviewer.md +160 -0
- package/packages/stack-agents/go/go-reviewer.md +277 -0
- package/packages/stack-agents/go/references/benchmark-methodology.md +280 -0
- package/packages/stack-agents/go/references/channel-patterns.md +384 -0
- package/packages/stack-agents/go/references/cli-cobra-viper.md +190 -0
- package/packages/stack-agents/go/references/code-style.md +262 -0
- package/packages/stack-agents/go/references/context-propagation.md +317 -0
- package/packages/stack-agents/go/references/data-structures.md +315 -0
- package/packages/stack-agents/go/references/database-patterns.md +334 -0
- package/packages/stack-agents/go/references/design-patterns.md +411 -0
- package/packages/stack-agents/go/references/di-frameworks.md +146 -0
- package/packages/stack-agents/go/references/error-creation.md +251 -0
- package/packages/stack-agents/go/references/error-inspection.md +348 -0
- package/packages/stack-agents/go/references/error-wrapping.md +230 -0
- package/packages/stack-agents/go/references/gopls-driving.md +62 -0
- package/packages/stack-agents/go/references/goroutine-lifecycle.md +351 -0
- package/packages/stack-agents/go/references/graphql-patterns.md +221 -0
- package/packages/stack-agents/go/references/grpc-patterns.md +373 -0
- package/packages/stack-agents/go/references/modernize-guide.md +522 -0
- package/packages/stack-agents/go/references/module-management.md +191 -0
- package/packages/stack-agents/go/references/naming-conventions.md +176 -0
- package/packages/stack-agents/go/references/observability-pipeline.md +352 -0
- package/packages/stack-agents/go/references/performance-profiling.md +250 -0
- package/packages/stack-agents/go/references/refactoring-mechanics.md +127 -0
- package/packages/stack-agents/go/references/rest-openapi-patterns.md +160 -0
- package/packages/stack-agents/go/references/samber-do.md +201 -0
- package/packages/stack-agents/go/references/samber-libraries.md +363 -0
- package/packages/stack-agents/go/references/samber-lo.md +260 -0
- package/packages/stack-agents/go/references/samber-oops.md +200 -0
- package/packages/stack-agents/go/references/security-checklist.md +441 -0
- package/packages/stack-agents/go/references/standard-stdlib-now.md +181 -0
- package/packages/stack-agents/go/references/stay-updated.md +147 -0
- package/packages/stack-agents/go/references/structs-interfaces.md +312 -0
- package/packages/stack-agents/go/references/sync-primitives.md +395 -0
- package/packages/stack-agents/go/references/testing-patterns.md +483 -0
- package/packages/stack-agents/go/references/troubleshooting.md +98 -0
- package/packages/stack-agents/python/py-reviewer.md +194 -0
- package/packages/stack-agents/rust/rs-reviewer.md +188 -0
- package/packages/stack-agents/typescript/ts-reviewer.md +135 -0
- package/packages/stack-hooks/go/go-context-check-on-edit.sh +56 -0
- package/packages/stack-hooks/go/go-error-check-on-edit.sh +54 -0
- package/packages/stack-hooks/go/go-format-on-edit.sh +32 -0
- package/packages/stack-hooks/go/go-safety-check-on-edit.sh +54 -0
- package/packages/stack-hooks/go/go-vet-on-edit.sh +61 -0
- package/packages/stack-hooks/go/golangci-lint-on-edit.sh +54 -0
- package/packages/stack-hooks/python/ruff-on-edit.sh +67 -0
- package/packages/stack-hooks/rust/cargo-check-on-edit.sh +64 -0
- package/packages/stack-hooks/typescript/typecheck-on-edit.sh +76 -0
- package/packages/stack-rules/go/go-conventions.md +44 -0
- package/packages/stack-rules/go/go-safety.md +35 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# internal-manifest_test.sh — guards the single-source-of-truth for repo-only
|
|
3
|
+
# files (packages/core/INTERNAL-FILES) and its two consumers.
|
|
4
|
+
#
|
|
5
|
+
# Three internal files must NEVER ship into a consumer's .claude/:
|
|
6
|
+
# hooks/superkit-counts-verify.sh, hooks/verify-hooks.sh, rules/superkit-integrity.md
|
|
7
|
+
# The skip-list used to be hand-duplicated in lib/installer.js and
|
|
8
|
+
# superkit-counts-verify.sh (and missing from superkit-update.sh). This suite
|
|
9
|
+
# fails the moment either consumer re-hard-codes a name instead of reading the
|
|
10
|
+
# manifest, or the manifest itself drifts from the three expected entries.
|
|
11
|
+
#
|
|
12
|
+
# Pure read-only: `grep`/file tests only. No writes, no network.
|
|
13
|
+
set -uo pipefail
|
|
14
|
+
|
|
15
|
+
# Resolve the repo root exactly like sibling suites (counts-verify_test.sh):
|
|
16
|
+
# tests → hooks → core → packages → repo root.
|
|
17
|
+
REPO_ROOT="$(cd "$(dirname "$0")/../../../.." && pwd)"
|
|
18
|
+
|
|
19
|
+
MANIFEST_REL="packages/core/INTERNAL-FILES"
|
|
20
|
+
MANIFEST="$REPO_ROOT/$MANIFEST_REL"
|
|
21
|
+
INSTALLER="lib/installer.js"
|
|
22
|
+
HOOK="packages/core/hooks/superkit-counts-verify.sh"
|
|
23
|
+
|
|
24
|
+
# Exactly these three, no more, no fewer (see PROMPT D2: "Do not expand").
|
|
25
|
+
EXPECTED_ENTRIES=(
|
|
26
|
+
"hooks/superkit-counts-verify.sh"
|
|
27
|
+
"hooks/verify-hooks.sh"
|
|
28
|
+
"rules/superkit-integrity.md"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
PASS_COUNT=0
|
|
32
|
+
FAIL_COUNT=0
|
|
33
|
+
pass() { echo "PASS: $1"; PASS_COUNT=$((PASS_COUNT + 1)); }
|
|
34
|
+
fail() { echo "FAIL: $1"; FAIL_COUNT=$((FAIL_COUNT + 1)); }
|
|
35
|
+
|
|
36
|
+
# ── Parse the manifest the same way its consumers do ────────────────────────
|
|
37
|
+
# Drop '#' comment lines and blanks; trim surrounding whitespace.
|
|
38
|
+
ENTRIES=()
|
|
39
|
+
if [ -f "$MANIFEST" ]; then
|
|
40
|
+
while IFS= read -r line || [ -n "$line" ]; do
|
|
41
|
+
line="${line#"${line%%[![:space:]]*}"}" # ltrim
|
|
42
|
+
line="${line%"${line##*[![:space:]]}"}" # rtrim
|
|
43
|
+
[ -z "$line" ] && continue
|
|
44
|
+
case "$line" in \#*) continue ;; esac
|
|
45
|
+
ENTRIES+=("$line")
|
|
46
|
+
done < "$MANIFEST"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# ── (a) manifest exists with exactly the 3 expected entries ─────────────────
|
|
50
|
+
echo "── (a): manifest exists with exactly the 3 expected entries"
|
|
51
|
+
if [ ! -f "$MANIFEST" ]; then
|
|
52
|
+
fail "(a) manifest not found: $MANIFEST_REL"
|
|
53
|
+
else
|
|
54
|
+
if [ "${#ENTRIES[@]}" -eq "${#EXPECTED_ENTRIES[@]}" ]; then
|
|
55
|
+
pass "(a) manifest has exactly ${#EXPECTED_ENTRIES[@]} entries"
|
|
56
|
+
else
|
|
57
|
+
fail "(a) manifest has ${#ENTRIES[@]} entries, expected ${#EXPECTED_ENTRIES[@]} (${ENTRIES[*]:-<none>})"
|
|
58
|
+
fi
|
|
59
|
+
# Every expected entry must be present.
|
|
60
|
+
for want in "${EXPECTED_ENTRIES[@]}"; do
|
|
61
|
+
found=0
|
|
62
|
+
for got in "${ENTRIES[@]:-}"; do [ "$got" = "$want" ] && found=1; done
|
|
63
|
+
if [ "$found" -eq 1 ]; then pass "(a) manifest lists '$want'"; else fail "(a) manifest MISSING '$want'"; fi
|
|
64
|
+
done
|
|
65
|
+
# No unexpected entry may sneak in.
|
|
66
|
+
for got in "${ENTRIES[@]:-}"; do
|
|
67
|
+
[ -z "$got" ] && continue
|
|
68
|
+
ok=0
|
|
69
|
+
for want in "${EXPECTED_ENTRIES[@]}"; do [ "$got" = "$want" ] && ok=1; done
|
|
70
|
+
[ "$ok" -eq 1 ] || fail "(a) manifest has UNEXPECTED entry '$got' (do not expand without evidence)"
|
|
71
|
+
done
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# ── (b) each entry resolves to an existing file under packages/core/ ────────
|
|
75
|
+
echo ""
|
|
76
|
+
echo "── (b): each entry resolves to an existing file under packages/core/"
|
|
77
|
+
for entry in "${ENTRIES[@]:-}"; do
|
|
78
|
+
[ -z "$entry" ] && continue
|
|
79
|
+
if [ -f "$REPO_ROOT/packages/core/$entry" ]; then
|
|
80
|
+
pass "(b) packages/core/$entry exists"
|
|
81
|
+
else
|
|
82
|
+
fail "(b) packages/core/$entry does NOT exist"
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
86
|
+
# ── (c) both consumers reference the manifest by name ───────────────────────
|
|
87
|
+
echo ""
|
|
88
|
+
echo "── (c): installer.js and superkit-counts-verify.sh reference INTERNAL-FILES"
|
|
89
|
+
for f in "$INSTALLER" "$HOOK"; do
|
|
90
|
+
if grep -qF -- "INTERNAL-FILES" "$REPO_ROOT/$f"; then
|
|
91
|
+
pass "(c) $f references INTERNAL-FILES"
|
|
92
|
+
else
|
|
93
|
+
fail "(c) $f does NOT reference INTERNAL-FILES (must read the manifest)"
|
|
94
|
+
fi
|
|
95
|
+
done
|
|
96
|
+
|
|
97
|
+
# ── (d) no internal file NAME hard-coded outside a FALLBACK-marked line ─────
|
|
98
|
+
# The only legitimate literal occurrences are the fallback constants that guard
|
|
99
|
+
# against a missing manifest — those lines are tagged FALLBACK. Any occurrence
|
|
100
|
+
# on a non-FALLBACK line means a consumer re-hard-coded the skip-list.
|
|
101
|
+
echo ""
|
|
102
|
+
echo "── (d): 'verify-hooks.sh' / 'superkit-integrity.md' appear only on FALLBACK lines"
|
|
103
|
+
assert_only_in_fallback() {
|
|
104
|
+
local file="$1" literal="$2" path="$REPO_ROOT/$1" offenders
|
|
105
|
+
# Lines that contain the literal but are NOT marked FALLBACK are offenders.
|
|
106
|
+
offenders="$(grep -nF -- "$literal" "$path" 2>/dev/null | grep -v 'FALLBACK' || true)"
|
|
107
|
+
if [ -n "$offenders" ]; then
|
|
108
|
+
fail "(d) $file hard-codes '$literal' outside a FALLBACK line:"
|
|
109
|
+
echo "$offenders" | sed 's/^/ /'
|
|
110
|
+
elif grep -qF -- "$literal" "$path"; then
|
|
111
|
+
pass "(d) $file: '$literal' only on FALLBACK line(s)"
|
|
112
|
+
else
|
|
113
|
+
# Absent entirely is also fine — nothing to hard-code — but flag it so a
|
|
114
|
+
# silently-deleted fallback is noticed.
|
|
115
|
+
fail "(d) $file: '$literal' not found at all (fallback removed?)"
|
|
116
|
+
fi
|
|
117
|
+
}
|
|
118
|
+
assert_only_in_fallback "$INSTALLER" "verify-hooks.sh"
|
|
119
|
+
assert_only_in_fallback "$INSTALLER" "superkit-integrity.md"
|
|
120
|
+
assert_only_in_fallback "$HOOK" "verify-hooks.sh"
|
|
121
|
+
assert_only_in_fallback "$HOOK" "superkit-integrity.md"
|
|
122
|
+
|
|
123
|
+
# ── Summary ─────────────────────────────────────────────────────────────────
|
|
124
|
+
echo ""
|
|
125
|
+
TOTAL=$((PASS_COUNT + FAIL_COUNT))
|
|
126
|
+
if [ "$FAIL_COUNT" -gt 0 ]; then
|
|
127
|
+
echo "INTERNAL-MANIFEST TESTS FAILED ($FAIL_COUNT/$TOTAL failed)"
|
|
128
|
+
exit 1
|
|
129
|
+
fi
|
|
130
|
+
echo "ALL INTERNAL-MANIFEST TESTS PASSED ($PASS_COUNT/$TOTAL)"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# json-path_test.sh — sanity tests that the 5 hooks read `.tool_input.*`
|
|
3
|
+
# correctly after the 2026-04-14 fix. Before the fix, these hooks read
|
|
4
|
+
# `.command` / `.file_path` at the top level and silently exited 0.
|
|
5
|
+
# Each case here asserts that the hook actually exercises its main
|
|
6
|
+
# branch when given a well-formed Claude Code payload.
|
|
7
|
+
#
|
|
8
|
+
# Usage: bash packages/core/hooks/tests/json-path_test.sh
|
|
9
|
+
# Exit codes: 0 if all cases pass, 1 on first failure.
|
|
10
|
+
|
|
11
|
+
set -u
|
|
12
|
+
|
|
13
|
+
HOOKS=$(cd "$(dirname "$0")/.." && pwd)
|
|
14
|
+
TMP=$(mktemp -d)
|
|
15
|
+
trap 'rm -rf "$TMP"' EXIT
|
|
16
|
+
|
|
17
|
+
PASS=0
|
|
18
|
+
FAIL=0
|
|
19
|
+
FAIL_DETAILS=""
|
|
20
|
+
|
|
21
|
+
# Prepare a repo with staged changes so doc-check + dev-required have something
|
|
22
|
+
# to diff against.
|
|
23
|
+
REPO="$TMP/repo"
|
|
24
|
+
mkdir -p "$REPO/backend/migrations"
|
|
25
|
+
(cd "$REPO" && git init -q && \
|
|
26
|
+
echo "init" > README.md && git add README.md && \
|
|
27
|
+
git -c user.email=t@t -c user.name=t commit -qm init && \
|
|
28
|
+
echo "CREATE TABLE foo();" > backend/migrations/001_foo.up.sql && \
|
|
29
|
+
git add backend/migrations/001_foo.up.sql)
|
|
30
|
+
|
|
31
|
+
assert_exit() {
|
|
32
|
+
local name="$1"
|
|
33
|
+
local expected="$2"
|
|
34
|
+
local actual="$3"
|
|
35
|
+
local allow_any="${4:-false}"
|
|
36
|
+
if [ "$allow_any" = "true" ] || [ "$actual" = "$expected" ]; then
|
|
37
|
+
echo " ✓ $name (exit=$actual)"
|
|
38
|
+
PASS=$((PASS + 1))
|
|
39
|
+
else
|
|
40
|
+
echo " ✗ $name — expected $expected, got $actual"
|
|
41
|
+
FAIL=$((FAIL + 1))
|
|
42
|
+
FAIL_DETAILS="${FAIL_DETAILS}\n - $name (expected=$expected actual=$actual)"
|
|
43
|
+
fi
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
echo "json-path_test.sh — verify all 5 hooks read .tool_input.* correctly"
|
|
47
|
+
echo ""
|
|
48
|
+
|
|
49
|
+
# 1) doc-check-on-commit — must BLOCK (code staged, no docs)
|
|
50
|
+
PAYLOAD=$(printf '{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git -C %s commit -m test"}}' "$REPO")
|
|
51
|
+
ACTUAL=$(echo "$PAYLOAD" | bash "$HOOKS/doc-check-on-commit.sh" >/dev/null 2>&1; echo $?)
|
|
52
|
+
assert_exit "doc-check-on-commit blocks missing docs" 2 "$ACTUAL"
|
|
53
|
+
|
|
54
|
+
# 2) superkit-counts-verify — exit 0 outside superkit repo (no packages/ layout)
|
|
55
|
+
PAYLOAD=$(printf '{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git -C %s commit -m test"}}' "$REPO")
|
|
56
|
+
ACTUAL=$(cd "$TMP" && echo "$PAYLOAD" | bash "$HOOKS/superkit-counts-verify.sh" >/dev/null 2>&1; echo $?)
|
|
57
|
+
assert_exit "superkit-counts-verify exits 0 outside superkit repo" 0 "$ACTUAL"
|
|
58
|
+
|
|
59
|
+
# 3) config-protection — warn on .eslintrc (exit 0 always, but must fire)
|
|
60
|
+
PAYLOAD='{"hook_event_name":"PostToolUse","tool_name":"Edit","tool_input":{"file_path":"/tmp/.eslintrc.json"}}'
|
|
61
|
+
OUTPUT=$(echo "$PAYLOAD" | bash "$HOOKS/config-protection.sh" 2>&1)
|
|
62
|
+
ACTUAL=$?
|
|
63
|
+
if echo "$OUTPUT" | grep -q "WARNING: Config file modified"; then
|
|
64
|
+
echo " ✓ config-protection warns on .eslintrc (exit=$ACTUAL)"
|
|
65
|
+
PASS=$((PASS + 1))
|
|
66
|
+
else
|
|
67
|
+
echo " ✗ config-protection did NOT warn on .eslintrc — output: $OUTPUT"
|
|
68
|
+
FAIL=$((FAIL + 1))
|
|
69
|
+
FAIL_DETAILS="${FAIL_DETAILS}\n - config-protection missed .eslintrc.json"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# 4) security-patterns — warn on eval() in a .js file (exit 0 always)
|
|
73
|
+
echo 'foo(eval(x));' > "$TMP/bad.js"
|
|
74
|
+
PAYLOAD=$(printf '{"hook_event_name":"PostToolUse","tool_name":"Edit","tool_input":{"file_path":"%s"}}' "$TMP/bad.js")
|
|
75
|
+
OUTPUT=$(echo "$PAYLOAD" | bash "$HOOKS/security-patterns.sh" 2>&1)
|
|
76
|
+
if echo "$OUTPUT" | grep -q "eval()"; then
|
|
77
|
+
echo " ✓ security-patterns flags eval()"
|
|
78
|
+
PASS=$((PASS + 1))
|
|
79
|
+
else
|
|
80
|
+
echo " ✗ security-patterns missed eval() — output: $OUTPUT"
|
|
81
|
+
FAIL=$((FAIL + 1))
|
|
82
|
+
FAIL_DETAILS="${FAIL_DETAILS}\n - security-patterns missed eval() in .js"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# 5) loop-guard — first call just records (exit 0, no block)
|
|
86
|
+
export TMPDIR="$TMP"
|
|
87
|
+
rm -f "$TMP/claude-loop-guard-"*
|
|
88
|
+
PAYLOAD='{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"ls -la"}}'
|
|
89
|
+
ACTUAL=$(echo "$PAYLOAD" | bash "$HOOKS/loop-guard.sh" >/dev/null 2>&1; echo $?)
|
|
90
|
+
assert_exit "loop-guard first call → allow" 0 "$ACTUAL"
|
|
91
|
+
# Verify a fingerprint file was actually written (proves COMMAND was read)
|
|
92
|
+
LOG=$(ls "$TMP/claude-loop-guard-"* 2>/dev/null | head -1)
|
|
93
|
+
if [ -n "$LOG" ] && [ -s "$LOG" ]; then
|
|
94
|
+
echo " ✓ loop-guard wrote fingerprint ($(wc -l < "$LOG") entries)"
|
|
95
|
+
PASS=$((PASS + 1))
|
|
96
|
+
else
|
|
97
|
+
echo " ✗ loop-guard did not write a fingerprint — command was not parsed"
|
|
98
|
+
FAIL=$((FAIL + 1))
|
|
99
|
+
FAIL_DETAILS="${FAIL_DETAILS}\n - loop-guard skipped (empty .tool_input.command parse)"
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
echo ""
|
|
103
|
+
echo "Results: $PASS passed, $FAIL failed"
|
|
104
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
105
|
+
echo -e "Failures:${FAIL_DETAILS}"
|
|
106
|
+
exit 1
|
|
107
|
+
fi
|
|
108
|
+
exit 0
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# mirror-invariants_test.sh — mirror-drift regression suite.
|
|
3
|
+
#
|
|
4
|
+
# Claude components and their Codex mirrors are hand-maintained copies. When a
|
|
5
|
+
# clause is edited on one side and not the other, the pair silently drifts.
|
|
6
|
+
# This suite pins invariant substrings on BOTH sides of each mirror pair, the
|
|
7
|
+
# same way ponytail's scripts/check-rule-copies.js pins its 9 substrings:
|
|
8
|
+
# drift on either side fails the suite.
|
|
9
|
+
#
|
|
10
|
+
# Pure read-only: `grep`/`find`/`ls` only. No writes, no network.
|
|
11
|
+
#
|
|
12
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
# MAINTENANCE CONTRACT
|
|
14
|
+
# Every string pinned in the tables below is expected to appear VERBATIM on
|
|
15
|
+
# BOTH sides of its mirror pair. If you edit a mirrored clause:
|
|
16
|
+
# • edit BOTH files (the Claude agent AND its Codex SKILL/AGENTS mirror), and
|
|
17
|
+
# • if the clause's wording legitimately changed, update the pin here too.
|
|
18
|
+
# Never "fix" a failure by touching only one side — that IS the drift this
|
|
19
|
+
# suite exists to catch.
|
|
20
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
set -uo pipefail
|
|
22
|
+
|
|
23
|
+
# Resolve the repo root exactly like sibling suites (counts-verify_test.sh):
|
|
24
|
+
# tests → hooks → core → packages → repo root.
|
|
25
|
+
REPO_ROOT="$(cd "$(dirname "$0")/../../../.." && pwd)"
|
|
26
|
+
|
|
27
|
+
PASS_COUNT=0
|
|
28
|
+
FAIL_COUNT=0
|
|
29
|
+
|
|
30
|
+
# assert_contains <label> <repo-relative-file> <fixed-substring>
|
|
31
|
+
# PASS when the file exists AND contains the literal substring; FAIL otherwise.
|
|
32
|
+
assert_contains() {
|
|
33
|
+
local label="$1" file="$2" substr="$3"
|
|
34
|
+
local path="$REPO_ROOT/$file"
|
|
35
|
+
if [ ! -f "$path" ]; then
|
|
36
|
+
echo "FAIL: $label — file not found: $file"
|
|
37
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
38
|
+
return
|
|
39
|
+
fi
|
|
40
|
+
if grep -qF -- "$substr" "$path"; then
|
|
41
|
+
echo "PASS: $label — [$substr] present in $file"
|
|
42
|
+
PASS_COUNT=$((PASS_COUNT + 1))
|
|
43
|
+
else
|
|
44
|
+
echo "FAIL: $label — [$substr] MISSING from $file"
|
|
45
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
46
|
+
fi
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# ─── INVARIANT TABLE (GROUP 1 + GROUP 2 share these 6 pairs) ─────────────────
|
|
50
|
+
# Row format: <claude_file>::<codex_mirror>::<sub1>|<sub2>|<sub3>
|
|
51
|
+
# The three subs per row are the external-symbol Evidence-Gate clause: the
|
|
52
|
+
# reviewer must consult real symbols (go doc / node_modules / inspect.signature
|
|
53
|
+
# / cargo) rather than reason "from memory", and label anything unverified
|
|
54
|
+
# "ASSUMED". Both sides of every pair must carry all three.
|
|
55
|
+
MIRROR_PAIRS=(
|
|
56
|
+
"packages/stack-agents/go/go-reviewer.md::packages/codex/skills/go-reviewer/SKILL.md::go doc|from memory|ASSUMED"
|
|
57
|
+
"packages/stack-agents/go/go-error-reviewer.md::packages/codex/skills/go-error-reviewer/SKILL.md::go doc|from memory|ASSUMED"
|
|
58
|
+
"packages/stack-agents/go/go-concurrency-reviewer.md::packages/codex/skills/go-concurrency-reviewer/SKILL.md::go doc|from memory|ASSUMED"
|
|
59
|
+
"packages/stack-agents/typescript/ts-reviewer.md::packages/codex/skills/ts-reviewer/SKILL.md::node_modules|from memory|ASSUMED"
|
|
60
|
+
"packages/stack-agents/python/py-reviewer.md::packages/codex/skills/py-reviewer/SKILL.md::inspect.signature|from memory|ASSUMED"
|
|
61
|
+
"packages/stack-agents/rust/rs-reviewer.md::packages/codex/skills/rs-reviewer/SKILL.md::cargo|from memory|ASSUMED"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# GROUP 2: severity enum — every reviewer (Claude + Codex) must offer all three.
|
|
65
|
+
SEVERITY_TOKENS=("CRITICAL" "WARNING" "SUGGESTION")
|
|
66
|
+
|
|
67
|
+
# GROUP 3: the Solution Ladder coding-style clause, mirrored Claude → Codex.
|
|
68
|
+
SOLUTION_LADDER_FILES=(
|
|
69
|
+
"packages/core/rules/coding-style.md"
|
|
70
|
+
"packages/codex/AGENTS.md"
|
|
71
|
+
)
|
|
72
|
+
SOLUTION_LADDER_SUBS="Solution Ladder|Minimal never means fragile|YAGNI"
|
|
73
|
+
|
|
74
|
+
# GROUP 4: Go reference-doc count reconciliation.
|
|
75
|
+
GO_REF_DIR="packages/stack-agents/go/references"
|
|
76
|
+
GO_COUNT_FILE="CLAUDE.md"
|
|
77
|
+
|
|
78
|
+
# ── GROUP 1 — external-symbol Evidence Gate pins on both sides of each pair ──
|
|
79
|
+
echo "── GROUP 1: Evidence-Gate mirror pairs (both sides carry all 3 pins)"
|
|
80
|
+
for row in "${MIRROR_PAIRS[@]}"; do
|
|
81
|
+
claude_file="${row%%::*}"
|
|
82
|
+
rest="${row#*::}"
|
|
83
|
+
codex_file="${rest%%::*}"
|
|
84
|
+
subs="${rest##*::}"
|
|
85
|
+
IFS='|' read -r -a sub_arr <<< "$subs"
|
|
86
|
+
for s in "${sub_arr[@]}"; do
|
|
87
|
+
assert_contains "G1 claude" "$claude_file" "$s"
|
|
88
|
+
assert_contains "G1 codex " "$codex_file" "$s"
|
|
89
|
+
done
|
|
90
|
+
done
|
|
91
|
+
|
|
92
|
+
# ── GROUP 2 — severity enum present in all 12 reviewers (6 Claude + 6 Codex) ─
|
|
93
|
+
echo ""
|
|
94
|
+
echo "── GROUP 2: severity enum (CRITICAL/WARNING/SUGGESTION) in all 12 reviewers"
|
|
95
|
+
for row in "${MIRROR_PAIRS[@]}"; do
|
|
96
|
+
claude_file="${row%%::*}"
|
|
97
|
+
rest="${row#*::}"
|
|
98
|
+
codex_file="${rest%%::*}"
|
|
99
|
+
for f in "$claude_file" "$codex_file"; do
|
|
100
|
+
for tok in "${SEVERITY_TOKENS[@]}"; do
|
|
101
|
+
assert_contains "G2" "$f" "$tok"
|
|
102
|
+
done
|
|
103
|
+
done
|
|
104
|
+
done
|
|
105
|
+
|
|
106
|
+
# ── GROUP 3 — Solution Ladder mirror ────────────────────────────────────────
|
|
107
|
+
echo ""
|
|
108
|
+
echo "── GROUP 3: Solution Ladder clause mirrored Claude ↔ Codex"
|
|
109
|
+
IFS='|' read -r -a sl_arr <<< "$SOLUTION_LADDER_SUBS"
|
|
110
|
+
for f in "${SOLUTION_LADDER_FILES[@]}"; do
|
|
111
|
+
for s in "${sl_arr[@]}"; do
|
|
112
|
+
assert_contains "G3" "$f" "$s"
|
|
113
|
+
done
|
|
114
|
+
done
|
|
115
|
+
|
|
116
|
+
# ── GROUP 4 — Go reference count reconciliation ─────────────────────────────
|
|
117
|
+
echo ""
|
|
118
|
+
echo "── GROUP 4: Go reference count reconciles with CLAUDE.md structure note"
|
|
119
|
+
N=$(find "$REPO_ROOT/$GO_REF_DIR" -maxdepth 1 -name '*.md' | wc -l | tr -d ' ')
|
|
120
|
+
LITERAL="# ${N} Go knowledge documents"
|
|
121
|
+
if grep -qF -- "$LITERAL" "$REPO_ROOT/$GO_COUNT_FILE"; then
|
|
122
|
+
echo "PASS: G4 — $GO_COUNT_FILE reconciles: '$LITERAL' (=$N *.md in $GO_REF_DIR)"
|
|
123
|
+
PASS_COUNT=$((PASS_COUNT + 1))
|
|
124
|
+
else
|
|
125
|
+
# Surface what CLAUDE.md actually claims, for a clear expected-vs-found error.
|
|
126
|
+
FOUND=$(grep -E 'Go knowledge documents' "$REPO_ROOT/$GO_COUNT_FILE" \
|
|
127
|
+
| head -1 | sed -nE 's/.*# *([0-9]+) Go knowledge documents.*/\1/p')
|
|
128
|
+
echo "FAIL: G4 — $GO_REF_DIR has $N *.md files, but $GO_COUNT_FILE says '${FOUND:-<none>} Go knowledge documents' (expected literal '$LITERAL')"
|
|
129
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# ── Summary ──────────────────────────────────────────────────────────────────
|
|
133
|
+
echo ""
|
|
134
|
+
TOTAL=$((PASS_COUNT + FAIL_COUNT))
|
|
135
|
+
if [ "$FAIL_COUNT" -gt 0 ]; then
|
|
136
|
+
echo "MIRROR-INVARIANTS TESTS FAILED ($FAIL_COUNT/$TOTAL failed)"
|
|
137
|
+
exit 1
|
|
138
|
+
fi
|
|
139
|
+
echo "ALL MIRROR-INVARIANTS TESTS PASSED ($PASS_COUNT/$TOTAL)"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# nudge-throttle_test.sh — regression test for advisory throttling (Task 18)
|
|
3
|
+
#
|
|
4
|
+
# Opus 4.8 self-flags, so repeated identical advisories are noise. The
|
|
5
|
+
# superkit_should_emit_advisory helper suppresses an identical advisory that
|
|
6
|
+
# recurs within CLAUDE_NUDGE_WINDOW_MIN (default 10). This test proves:
|
|
7
|
+
# 1. first identical advisory is emitted, second within the window is suppressed
|
|
8
|
+
# 2. CLAUDE_NUDGE_WINDOW_MIN=0 disables throttling
|
|
9
|
+
# 3. a different message is NOT suppressed by an unrelated one
|
|
10
|
+
# 4. edit-streak-check.sh suppresses its repeated streak nudge under one session
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
LIB="$(cd "$(dirname "$0")/.." && pwd)/lib/profile.sh"
|
|
14
|
+
[ -f "$LIB" ] || { echo "FAIL: lib not found at $LIB"; exit 1; }
|
|
15
|
+
# shellcheck source=/dev/null
|
|
16
|
+
source "$LIB"
|
|
17
|
+
|
|
18
|
+
command -v superkit_should_emit_advisory >/dev/null 2>&1 \
|
|
19
|
+
|| { echo "FAIL: superkit_should_emit_advisory not exported by profile.sh"; exit 1; }
|
|
20
|
+
|
|
21
|
+
TMPDIR="${TMPDIR:-/tmp}"
|
|
22
|
+
|
|
23
|
+
# ── Test 1: first emits, second within window suppressed ──────────────
|
|
24
|
+
export SUPERKIT_NUDGE_STATE="$TMPDIR/superkit-nudge-helper-test-$$"
|
|
25
|
+
rm -f "$SUPERKIT_NUDGE_STATE"
|
|
26
|
+
if superkit_should_emit_advisory "same nudge"; then
|
|
27
|
+
echo "PASS: first identical advisory emitted"
|
|
28
|
+
else
|
|
29
|
+
echo "FAIL: first advisory should be emitted"
|
|
30
|
+
rm -f "$SUPERKIT_NUDGE_STATE"; exit 1
|
|
31
|
+
fi
|
|
32
|
+
if superkit_should_emit_advisory "same nudge"; then
|
|
33
|
+
echo "FAIL: second identical advisory within window should be suppressed"
|
|
34
|
+
rm -f "$SUPERKIT_NUDGE_STATE"; exit 1
|
|
35
|
+
else
|
|
36
|
+
echo "PASS: second identical advisory suppressed within window"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# ── Test 2: a different message is not suppressed ─────────────────────
|
|
40
|
+
if superkit_should_emit_advisory "a different nudge"; then
|
|
41
|
+
echo "PASS: distinct advisory not suppressed by unrelated one"
|
|
42
|
+
else
|
|
43
|
+
echo "FAIL: distinct advisory should still emit"
|
|
44
|
+
rm -f "$SUPERKIT_NUDGE_STATE"; exit 1
|
|
45
|
+
fi
|
|
46
|
+
rm -f "$SUPERKIT_NUDGE_STATE"
|
|
47
|
+
|
|
48
|
+
# ── Test 3: CLAUDE_NUDGE_WINDOW_MIN=0 disables throttling ─────────────
|
|
49
|
+
export SUPERKIT_NUDGE_STATE="$TMPDIR/superkit-nudge-helper-test2-$$"
|
|
50
|
+
rm -f "$SUPERKIT_NUDGE_STATE"
|
|
51
|
+
CLAUDE_NUDGE_WINDOW_MIN=0 superkit_should_emit_advisory "x" || { echo "FAIL: window=0 should always emit (1st)"; rm -f "$SUPERKIT_NUDGE_STATE"; exit 1; }
|
|
52
|
+
CLAUDE_NUDGE_WINDOW_MIN=0 superkit_should_emit_advisory "x" || { echo "FAIL: window=0 should always emit (2nd)"; rm -f "$SUPERKIT_NUDGE_STATE"; exit 1; }
|
|
53
|
+
echo "PASS: CLAUDE_NUDGE_WINDOW_MIN=0 disables throttling"
|
|
54
|
+
rm -f "$SUPERKIT_NUDGE_STATE"
|
|
55
|
+
|
|
56
|
+
# ── Test 4: edit-streak-check.sh end-to-end throttling ────────────────
|
|
57
|
+
# Under a fixed SESSION_ID, drive the streak past the threshold so the
|
|
58
|
+
# advisory fires, then drive it again — the second nudge must be suppressed.
|
|
59
|
+
HOOK="$(cd "$(dirname "$0")/.." && pwd)/edit-streak-check.sh"
|
|
60
|
+
[ -x "$HOOK" ] || { echo "FAIL: edit-streak hook not executable at $HOOK"; exit 1; }
|
|
61
|
+
|
|
62
|
+
export SESSION_ID="nudge-throttle-sess-$$"
|
|
63
|
+
export SUPERKIT_NUDGE_STATE="$TMPDIR/superkit-nudge-${SESSION_ID}"
|
|
64
|
+
STREAK_FILE="$TMPDIR/claude-edit-streak-${SESSION_ID}"
|
|
65
|
+
rm -f "$SUPERKIT_NUDGE_STATE" "$STREAK_FILE"
|
|
66
|
+
unset CLAUDE_EDIT_STREAK_FILE 2>/dev/null || true
|
|
67
|
+
|
|
68
|
+
fire_edit() {
|
|
69
|
+
echo '{"tool_name":"Edit","tool_input":{"file_path":"/tmp/fake.txt"}}' | bash "$HOOK" 2>&1 >/dev/null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Edits 1-4 silent, 5th fires the advisory.
|
|
73
|
+
for i in 1 2 3 4; do fire_edit >/dev/null || true; done
|
|
74
|
+
OUT5=$(fire_edit || true)
|
|
75
|
+
if ! echo "$OUT5" | grep -q "edit streak — 5"; then
|
|
76
|
+
echo "FAIL: 5th edit should warn (first advisory)"
|
|
77
|
+
echo " stderr: $OUT5"
|
|
78
|
+
rm -f "$SUPERKIT_NUDGE_STATE" "$STREAK_FILE"; unset SESSION_ID SUPERKIT_NUDGE_STATE; exit 1
|
|
79
|
+
fi
|
|
80
|
+
echo "PASS: edit-streak first advisory emitted (edit 5)"
|
|
81
|
+
|
|
82
|
+
# 6th edit: streak >= 5 again, but identical advisory must be throttled.
|
|
83
|
+
OUT6=$(fire_edit || true)
|
|
84
|
+
if echo "$OUT6" | grep -q "edit streak"; then
|
|
85
|
+
echo "FAIL: 6th edit advisory should be suppressed within window"
|
|
86
|
+
echo " stderr: $OUT6"
|
|
87
|
+
rm -f "$SUPERKIT_NUDGE_STATE" "$STREAK_FILE"; unset SESSION_ID SUPERKIT_NUDGE_STATE; exit 1
|
|
88
|
+
fi
|
|
89
|
+
echo "PASS: edit-streak repeat advisory suppressed within window"
|
|
90
|
+
|
|
91
|
+
rm -f "$SUPERKIT_NUDGE_STATE" "$STREAK_FILE"
|
|
92
|
+
unset SESSION_ID SUPERKIT_NUDGE_STATE
|
|
93
|
+
|
|
94
|
+
echo ""
|
|
95
|
+
echo "ALL NUDGE-THROTTLE TESTS PASSED (6/6)"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
LIB="$(cd "$(dirname "$0")/.." && pwd)/lib/profile.sh"
|
|
5
|
+
[ -f "$LIB" ] || { echo "FAIL: lib not found at $LIB"; exit 1; }
|
|
6
|
+
# shellcheck source=/dev/null
|
|
7
|
+
source "$LIB"
|
|
8
|
+
|
|
9
|
+
# Test 1: CLAUDE_DISABLED_HOOKS matches
|
|
10
|
+
CLAUDE_DISABLED_HOOKS="loop-guard,security-patterns" should_skip_hook "loop-guard" && echo "PASS: loop-guard disabled" || { echo "FAIL"; exit 1; }
|
|
11
|
+
CLAUDE_DISABLED_HOOKS="loop-guard,security-patterns" should_skip_hook "audit-trail" && { echo "FAIL: should not skip"; exit 1; } || echo "PASS: audit-trail not disabled"
|
|
12
|
+
|
|
13
|
+
# Test 2: CLAUDE_HOOK_PROFILE=fast skips non-critical
|
|
14
|
+
CLAUDE_HOOK_PROFILE=fast should_skip_hook "loop-guard" && echo "PASS: fast skips loop-guard" || { echo "FAIL"; exit 1; }
|
|
15
|
+
CLAUDE_HOOK_PROFILE=fast should_skip_hook "block-dangerous-git" && { echo "FAIL: fast should not skip critical"; exit 1; } || echo "PASS: fast keeps block-dangerous-git"
|
|
16
|
+
|
|
17
|
+
# Test 3: Default profile keeps all hooks
|
|
18
|
+
unset CLAUDE_HOOK_PROFILE CLAUDE_DISABLED_HOOKS
|
|
19
|
+
should_skip_hook "loop-guard" && { echo "FAIL: default should not skip"; exit 1; } || echo "PASS: default keeps loop-guard"
|
|
20
|
+
|
|
21
|
+
echo "ALL PROFILE-HELPER TESTS PASSED"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# run-all.sh — invoke every regression-test suite and report a summary.
|
|
3
|
+
# Usage: bash packages/core/hooks/tests/run-all.sh
|
|
4
|
+
|
|
5
|
+
DIR=$(cd "$(dirname "$0")" && pwd)
|
|
6
|
+
SUITES=(
|
|
7
|
+
"doc-check-on-commit_test.sh"
|
|
8
|
+
"dev-required-on-commit_test.sh"
|
|
9
|
+
"dev-required-wip-on-main_test.sh"
|
|
10
|
+
"json-path_test.sh"
|
|
11
|
+
"profile-helper_test.sh"
|
|
12
|
+
"session-key-helper_test.sh"
|
|
13
|
+
"edit-streak-check_test.sh"
|
|
14
|
+
"audit-trail-chain_test.sh"
|
|
15
|
+
"warn-visibility_test.sh"
|
|
16
|
+
"nudge-throttle_test.sh"
|
|
17
|
+
"counts-verify_test.sh"
|
|
18
|
+
"block-dangerous-git_test.sh"
|
|
19
|
+
"mirror-invariants_test.sh"
|
|
20
|
+
"internal-manifest_test.sh"
|
|
21
|
+
"superkit-update_test.sh"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
TOTAL_PASS=0
|
|
25
|
+
TOTAL_FAIL=0
|
|
26
|
+
FAILED_SUITES=""
|
|
27
|
+
|
|
28
|
+
for suite in "${SUITES[@]}"; do
|
|
29
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
30
|
+
echo "▶ $suite"
|
|
31
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
32
|
+
if bash "$DIR/$suite"; then
|
|
33
|
+
TOTAL_PASS=$((TOTAL_PASS + 1))
|
|
34
|
+
else
|
|
35
|
+
TOTAL_FAIL=$((TOTAL_FAIL + 1))
|
|
36
|
+
FAILED_SUITES="${FAILED_SUITES}\n - $suite"
|
|
37
|
+
fi
|
|
38
|
+
echo ""
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
42
|
+
echo "Summary: $TOTAL_PASS suites passed, $TOTAL_FAIL failed"
|
|
43
|
+
if [ "$TOTAL_FAIL" -gt 0 ]; then
|
|
44
|
+
echo -e "Failed suites:${FAILED_SUITES}"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
exit 0
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -u
|
|
3
|
+
LIB="$(cd "$(dirname "$0")/.." && pwd)/lib/profile.sh"
|
|
4
|
+
. "$LIB"
|
|
5
|
+
|
|
6
|
+
fail=0
|
|
7
|
+
# SESSION_ID wins
|
|
8
|
+
SESSION_ID="sid123" CLAUDE_HOOK_PID="" ; k=$(superkit_session_key)
|
|
9
|
+
[ "$k" = "sid123" ] || { echo "FAIL: SESSION_ID precedence got '$k'"; fail=1; }
|
|
10
|
+
# falls back to CLAUDE_HOOK_PID
|
|
11
|
+
unset SESSION_ID; CLAUDE_HOOK_PID="pid456"; k=$(superkit_session_key)
|
|
12
|
+
[ "$k" = "pid456" ] || { echo "FAIL: CLAUDE_HOOK_PID fallback got '$k'"; fail=1; }
|
|
13
|
+
# falls back to PPID (non-empty)
|
|
14
|
+
unset SESSION_ID CLAUDE_HOOK_PID; k=$(superkit_session_key)
|
|
15
|
+
[ -n "$k" ] || { echo "FAIL: PPID fallback empty"; fail=1; }
|
|
16
|
+
|
|
17
|
+
[ "$fail" -eq 0 ] && echo "PASS: session-key helper" && exit 0 || exit 1
|