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,395 @@
|
|
|
1
|
+
# Sync Primitives
|
|
2
|
+
|
|
3
|
+
> Reference document for go-concurrency-reviewer. Loaded on demand via Read tool.
|
|
4
|
+
|
|
5
|
+
## sync.Mutex / sync.RWMutex
|
|
6
|
+
|
|
7
|
+
Protects shared mutable state. Use `RWMutex` when reads vastly outnumber writes.
|
|
8
|
+
|
|
9
|
+
```go
|
|
10
|
+
// Mutex — exclusive access
|
|
11
|
+
type UserCache struct {
|
|
12
|
+
mu sync.Mutex
|
|
13
|
+
users map[int64]*User
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func (c *UserCache) Set(id int64, u *User) {
|
|
17
|
+
c.mu.Lock()
|
|
18
|
+
defer c.mu.Unlock()
|
|
19
|
+
c.users[id] = u
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func (c *UserCache) Get(id int64) (*User, bool) {
|
|
23
|
+
c.mu.Lock()
|
|
24
|
+
defer c.mu.Unlock()
|
|
25
|
+
u, ok := c.users[id]
|
|
26
|
+
return u, ok
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// RWMutex — concurrent reads, exclusive writes
|
|
30
|
+
type ConfigStore struct {
|
|
31
|
+
mu sync.RWMutex
|
|
32
|
+
config Config
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func (s *ConfigStore) Get() Config {
|
|
36
|
+
s.mu.RLock()
|
|
37
|
+
defer s.mu.RUnlock()
|
|
38
|
+
return s.config // safe concurrent reads
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
func (s *ConfigStore) Update(cfg Config) {
|
|
42
|
+
s.mu.Lock()
|
|
43
|
+
defer s.mu.Unlock()
|
|
44
|
+
s.config = cfg // exclusive write
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Decision table — Mutex vs RWMutex:**
|
|
49
|
+
|
|
50
|
+
| Read:Write Ratio | Use | Why |
|
|
51
|
+
|-------------------|-----|-----|
|
|
52
|
+
| ~50:50 | `sync.Mutex` | RWMutex overhead not worth it |
|
|
53
|
+
| 90:10 or higher | `sync.RWMutex` | Concurrent reads improve throughput |
|
|
54
|
+
| Rarely contested | `sync.Mutex` | Simpler, less overhead |
|
|
55
|
+
|
|
56
|
+
**Anti-patterns:**
|
|
57
|
+
|
|
58
|
+
```go
|
|
59
|
+
// WRONG — copying a mutex
|
|
60
|
+
type Bad struct {
|
|
61
|
+
mu sync.Mutex
|
|
62
|
+
}
|
|
63
|
+
b1 := Bad{}
|
|
64
|
+
b2 := b1 // copies mutex! go vet warns
|
|
65
|
+
|
|
66
|
+
// WRONG — locking in wrong order (deadlock)
|
|
67
|
+
func transfer(a, b *Account) {
|
|
68
|
+
a.mu.Lock()
|
|
69
|
+
b.mu.Lock() // if another goroutine locks b then a → deadlock
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// CORRECT — consistent lock ordering
|
|
73
|
+
func transfer(a, b *Account) {
|
|
74
|
+
first, second := a, b
|
|
75
|
+
if a.ID > b.ID {
|
|
76
|
+
first, second = b, a
|
|
77
|
+
}
|
|
78
|
+
first.mu.Lock()
|
|
79
|
+
defer first.mu.Unlock()
|
|
80
|
+
second.mu.Lock()
|
|
81
|
+
defer second.mu.Unlock()
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## sync.Map
|
|
86
|
+
|
|
87
|
+
Specialized concurrent map. **Not** a general-purpose concurrent map.
|
|
88
|
+
|
|
89
|
+
**Use only when:**
|
|
90
|
+
- Keys are written once, read many times (append-only cache)
|
|
91
|
+
- Goroutines access disjoint key sets
|
|
92
|
+
- The key set is stable after initialization
|
|
93
|
+
|
|
94
|
+
**Do NOT use when:**
|
|
95
|
+
- Mixed read/write workload (use `Mutex` + `map`)
|
|
96
|
+
- Need to iterate consistently
|
|
97
|
+
- Need to check length efficiently
|
|
98
|
+
|
|
99
|
+
```go
|
|
100
|
+
var cache sync.Map
|
|
101
|
+
|
|
102
|
+
// Store
|
|
103
|
+
cache.Store("key", &User{Name: "Alice"})
|
|
104
|
+
|
|
105
|
+
// Load
|
|
106
|
+
if v, ok := cache.Load("key"); ok {
|
|
107
|
+
user := v.(*User) // type assertion required
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// LoadOrStore — atomic get-or-set
|
|
111
|
+
actual, loaded := cache.LoadOrStore("key", &User{Name: "Bob"})
|
|
112
|
+
// loaded=true: key existed, actual is existing value
|
|
113
|
+
// loaded=false: key was new, actual is the stored value
|
|
114
|
+
|
|
115
|
+
// LoadAndDelete — atomic get-and-remove
|
|
116
|
+
v, loaded := cache.LoadAndDelete("key")
|
|
117
|
+
|
|
118
|
+
// Range — iterate (not consistent snapshot)
|
|
119
|
+
cache.Range(func(key, value any) bool {
|
|
120
|
+
fmt.Printf("%v: %v\n", key, value)
|
|
121
|
+
return true // continue iteration
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## sync.Pool
|
|
126
|
+
|
|
127
|
+
Reuse temporary objects to reduce GC pressure. Objects may be reclaimed at any GC cycle.
|
|
128
|
+
|
|
129
|
+
**Use when:**
|
|
130
|
+
- Hot-path allocations (buffers, encoders, decoders)
|
|
131
|
+
- Object creation is expensive
|
|
132
|
+
- Objects are short-lived and reusable
|
|
133
|
+
|
|
134
|
+
**Always reset before Put:**
|
|
135
|
+
|
|
136
|
+
```go
|
|
137
|
+
var bufPool = sync.Pool{
|
|
138
|
+
New: func() any {
|
|
139
|
+
return new(bytes.Buffer)
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
func process(data []byte) string {
|
|
144
|
+
buf := bufPool.Get().(*bytes.Buffer)
|
|
145
|
+
defer func() {
|
|
146
|
+
buf.Reset() // CRITICAL: reset before returning to pool
|
|
147
|
+
bufPool.Put(buf)
|
|
148
|
+
}()
|
|
149
|
+
|
|
150
|
+
buf.Write(data)
|
|
151
|
+
buf.WriteString(" processed")
|
|
152
|
+
return buf.String()
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Pool for JSON encoders:**
|
|
157
|
+
|
|
158
|
+
```go
|
|
159
|
+
var encoderPool = sync.Pool{
|
|
160
|
+
New: func() any {
|
|
161
|
+
return json.NewEncoder(io.Discard) // placeholder, replaced on Get
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
func writeJSON(w http.ResponseWriter, v any) error {
|
|
166
|
+
enc := encoderPool.Get().(*json.Encoder)
|
|
167
|
+
defer encoderPool.Put(enc)
|
|
168
|
+
|
|
169
|
+
enc.Reset(w) // point to actual writer
|
|
170
|
+
return enc.Encode(v)
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Anti-patterns:**
|
|
175
|
+
|
|
176
|
+
```go
|
|
177
|
+
// WRONG — not resetting before Put (data leak between requests)
|
|
178
|
+
buf := bufPool.Get().(*bytes.Buffer)
|
|
179
|
+
buf.Write(sensitiveData)
|
|
180
|
+
bufPool.Put(buf) // next Get() sees leftover data!
|
|
181
|
+
|
|
182
|
+
// WRONG — storing pointers to pool objects (may be reclaimed)
|
|
183
|
+
obj := pool.Get().(*BigStruct)
|
|
184
|
+
cache[key] = obj // obj may be reclaimed by GC!
|
|
185
|
+
pool.Put(obj)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## sync.Once
|
|
189
|
+
|
|
190
|
+
Execute a function exactly once, regardless of how many goroutines call it. Thread-safe lazy initialization.
|
|
191
|
+
|
|
192
|
+
```go
|
|
193
|
+
type DBPool struct {
|
|
194
|
+
once sync.Once
|
|
195
|
+
pool *pgxpool.Pool
|
|
196
|
+
err error
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
func (d *DBPool) Get(ctx context.Context) (*pgxpool.Pool, error) {
|
|
200
|
+
d.once.Do(func() {
|
|
201
|
+
d.pool, d.err = pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
|
|
202
|
+
})
|
|
203
|
+
return d.pool, d.err
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**sync.OnceValue / sync.OnceValues (Go 1.21+):**
|
|
208
|
+
|
|
209
|
+
```go
|
|
210
|
+
// Returns a function that computes the value once
|
|
211
|
+
var getConfig = sync.OnceValue(func() *Config {
|
|
212
|
+
cfg, err := loadConfig()
|
|
213
|
+
if err != nil {
|
|
214
|
+
panic(err) // or handle differently
|
|
215
|
+
}
|
|
216
|
+
return cfg
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
// Returns a function that computes value + error once
|
|
220
|
+
var getDB = sync.OnceValues(func() (*pgxpool.Pool, error) {
|
|
221
|
+
return pgxpool.New(context.Background(), os.Getenv("DATABASE_URL"))
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
// Usage
|
|
225
|
+
cfg := getConfig() // computed on first call, cached after
|
|
226
|
+
db, err := getDB() // computed on first call, cached after
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## sync.WaitGroup
|
|
230
|
+
|
|
231
|
+
Wait for a fixed number of goroutines to complete.
|
|
232
|
+
|
|
233
|
+
### Go 1.25+: wg.Go
|
|
234
|
+
|
|
235
|
+
`wg.Go(f)` spawns `f` in a new goroutine and tracks it in one call — replacing the `Add(1)` / `go` / `defer Done()` triad and its easy-to-forget footguns (the classic Add-inside-goroutine race shown below).
|
|
236
|
+
|
|
237
|
+
```go
|
|
238
|
+
func processAll(ctx context.Context, items []Item) {
|
|
239
|
+
var wg sync.WaitGroup
|
|
240
|
+
|
|
241
|
+
for _, item := range items {
|
|
242
|
+
wg.Go(func() { process(ctx, item) }) // Add + goroutine + Done, atomically
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
wg.Wait()
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Rules:**
|
|
250
|
+
- Go 1.25+ only — keep the classic `Add`/`Done` form below as the fallback for older toolchains.
|
|
251
|
+
- `f` must not panic — `wg.Go` does not recover; a panic crashes the program. Recover inside `f` if it can fail.
|
|
252
|
+
- No error or cancellation propagation. When you need to collect the first error or cancel siblings, use `errgroup.WithContext` (see the errgroup section below), not `wg.Go`.
|
|
253
|
+
|
|
254
|
+
### Classic Add/Done (all versions)
|
|
255
|
+
|
|
256
|
+
```go
|
|
257
|
+
func processAll(ctx context.Context, items []Item) {
|
|
258
|
+
var wg sync.WaitGroup
|
|
259
|
+
|
|
260
|
+
for _, item := range items {
|
|
261
|
+
wg.Add(1)
|
|
262
|
+
go func() {
|
|
263
|
+
defer wg.Done()
|
|
264
|
+
process(ctx, item)
|
|
265
|
+
}()
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
wg.Wait() // blocks until all Done() calls
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Rules:**
|
|
273
|
+
- Call `Add` before spawning the goroutine (not inside it)
|
|
274
|
+
- Always `defer wg.Done()` to handle panics
|
|
275
|
+
- Never pass WaitGroup by value (use pointer)
|
|
276
|
+
|
|
277
|
+
```go
|
|
278
|
+
// WRONG — Add inside goroutine (race condition)
|
|
279
|
+
go func() {
|
|
280
|
+
wg.Add(1) // may run after Wait()!
|
|
281
|
+
defer wg.Done()
|
|
282
|
+
work()
|
|
283
|
+
}()
|
|
284
|
+
wg.Wait()
|
|
285
|
+
|
|
286
|
+
// WRONG — passing by value
|
|
287
|
+
func worker(wg sync.WaitGroup) { // copies WaitGroup!
|
|
288
|
+
defer wg.Done() // decrements the copy
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Atomic Operations
|
|
293
|
+
|
|
294
|
+
Lock-free operations for simple counters and flags. Faster than mutex for single-value access.
|
|
295
|
+
|
|
296
|
+
```go
|
|
297
|
+
import "sync/atomic"
|
|
298
|
+
|
|
299
|
+
// Counter
|
|
300
|
+
var requestCount atomic.Int64
|
|
301
|
+
|
|
302
|
+
func handleRequest() {
|
|
303
|
+
requestCount.Add(1)
|
|
304
|
+
// ...
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
func getMetrics() int64 {
|
|
308
|
+
return requestCount.Load()
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Bool flag
|
|
312
|
+
var isReady atomic.Bool
|
|
313
|
+
|
|
314
|
+
func init() {
|
|
315
|
+
go func() {
|
|
316
|
+
prepare()
|
|
317
|
+
isReady.Store(true)
|
|
318
|
+
}()
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Pointer swap (atomic config reload)
|
|
322
|
+
var currentConfig atomic.Pointer[Config]
|
|
323
|
+
|
|
324
|
+
func reloadConfig() {
|
|
325
|
+
newCfg := loadConfig()
|
|
326
|
+
currentConfig.Store(newCfg)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
func getConfig() *Config {
|
|
330
|
+
return currentConfig.Load()
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Decision table — atomic vs mutex:**
|
|
335
|
+
|
|
336
|
+
| Scenario | Use |
|
|
337
|
+
|----------|-----|
|
|
338
|
+
| Single counter/flag | `atomic` |
|
|
339
|
+
| Multiple related fields | `sync.Mutex` |
|
|
340
|
+
| Read-mostly single value | `atomic` |
|
|
341
|
+
| Complex state transitions | `sync.Mutex` |
|
|
342
|
+
| Pointer swap | `atomic.Pointer` |
|
|
343
|
+
|
|
344
|
+
## errgroup
|
|
345
|
+
|
|
346
|
+
Fan-out with error collection and automatic context cancellation.
|
|
347
|
+
|
|
348
|
+
```go
|
|
349
|
+
import "golang.org/x/sync/errgroup"
|
|
350
|
+
|
|
351
|
+
func fetchAll(ctx context.Context, urls []string) ([]Response, error) {
|
|
352
|
+
g, ctx := errgroup.WithContext(ctx)
|
|
353
|
+
results := make([]Response, len(urls))
|
|
354
|
+
|
|
355
|
+
for i, url := range urls {
|
|
356
|
+
g.Go(func() error {
|
|
357
|
+
resp, err := fetch(ctx, url)
|
|
358
|
+
if err != nil {
|
|
359
|
+
return fmt.Errorf("fetch %s: %w", url, err)
|
|
360
|
+
}
|
|
361
|
+
results[i] = resp
|
|
362
|
+
return nil
|
|
363
|
+
})
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if err := g.Wait(); err != nil {
|
|
367
|
+
return nil, err // first error, context was cancelled
|
|
368
|
+
}
|
|
369
|
+
return results, nil
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// With concurrency limit (Go 1.20+ errgroup)
|
|
373
|
+
g.SetLimit(10) // max 10 concurrent goroutines
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Decision Table: Which Primitive?
|
|
377
|
+
|
|
378
|
+
| Need | Primitive | Example |
|
|
379
|
+
|------|-----------|---------|
|
|
380
|
+
| Protect map/struct from concurrent access | `sync.Mutex` | Shared cache |
|
|
381
|
+
| Many concurrent readers, rare writes | `sync.RWMutex` | Config store |
|
|
382
|
+
| Append-only concurrent map | `sync.Map` | DNS cache |
|
|
383
|
+
| Reuse expensive temporary objects | `sync.Pool` | Byte buffers |
|
|
384
|
+
| One-time initialization | `sync.Once` | DB connection |
|
|
385
|
+
| Wait for N goroutines | `sync.WaitGroup` | Batch processing |
|
|
386
|
+
| Simple counter/flag | `atomic.Int64` / `atomic.Bool` | Metrics |
|
|
387
|
+
| Atomic pointer swap | `atomic.Pointer[T]` | Config reload |
|
|
388
|
+
| Fan-out with error handling | `errgroup.Group` | Parallel HTTP calls |
|
|
389
|
+
|
|
390
|
+
## When to Use
|
|
391
|
+
|
|
392
|
+
Apply when reviewing concurrent code for correct synchronization. Flag violations as:
|
|
393
|
+
- **CRITICAL**: Missing synchronization on shared mutable state, copying mutex/WaitGroup, sync.Pool without Reset
|
|
394
|
+
- **WARNING**: Using sync.Map for general concurrent access, mutex where atomic suffices, WaitGroup.Add inside goroutine
|
|
395
|
+
- **SUGGESTION**: Could use RWMutex for read-heavy workload, sync.OnceValue instead of sync.Once+field, errgroup.SetLimit
|