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,411 @@
|
|
|
1
|
+
# Design Patterns
|
|
2
|
+
|
|
3
|
+
> Reference document for go-reviewer. Loaded on demand via Read tool.
|
|
4
|
+
|
|
5
|
+
## 1. Functional Options
|
|
6
|
+
|
|
7
|
+
The most idiomatic Go pattern for configurable constructors. Allows extensibility without breaking API.
|
|
8
|
+
|
|
9
|
+
```go
|
|
10
|
+
type Option func(*Server)
|
|
11
|
+
|
|
12
|
+
func WithPort(port int) Option {
|
|
13
|
+
return func(s *Server) {
|
|
14
|
+
s.port = port
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func WithTimeout(d time.Duration) Option {
|
|
19
|
+
return func(s *Server) {
|
|
20
|
+
s.timeout = d
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
func WithLogger(l *slog.Logger) Option {
|
|
25
|
+
return func(s *Server) {
|
|
26
|
+
s.logger = l
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func NewServer(addr string, opts ...Option) *Server {
|
|
31
|
+
s := &Server{
|
|
32
|
+
addr: addr,
|
|
33
|
+
port: 8080, // sensible default
|
|
34
|
+
timeout: 30 * time.Second, // sensible default
|
|
35
|
+
logger: slog.Default(), // sensible default
|
|
36
|
+
}
|
|
37
|
+
for _, opt := range opts {
|
|
38
|
+
opt(s)
|
|
39
|
+
}
|
|
40
|
+
return s
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Usage
|
|
44
|
+
srv := NewServer("localhost",
|
|
45
|
+
WithPort(9090),
|
|
46
|
+
WithTimeout(10*time.Second),
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 2. Constructor Pattern
|
|
51
|
+
|
|
52
|
+
Always provide `NewX` functions. Return pointer for structs with internal state.
|
|
53
|
+
|
|
54
|
+
```go
|
|
55
|
+
func NewUserService(repo UserRepository, cache Cache) *UserService {
|
|
56
|
+
return &UserService{
|
|
57
|
+
repo: repo,
|
|
58
|
+
cache: cache,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Decision table — return type:**
|
|
64
|
+
|
|
65
|
+
| Condition | Return | Example |
|
|
66
|
+
|-----------|--------|---------|
|
|
67
|
+
| Has internal state / methods | `*T` | `NewServer() *Server` |
|
|
68
|
+
| Small, immutable value | `T` | `NewPoint(x, y int) Point` |
|
|
69
|
+
| May fail to construct | `(*T, error)` | `NewClient(cfg Config) (*Client, error)` |
|
|
70
|
+
| Interface implementation | Interface type | `NewLogger() Logger` |
|
|
71
|
+
|
|
72
|
+
## 3. Enums with iota
|
|
73
|
+
|
|
74
|
+
Always start with an Unknown/Invalid zero value to catch uninitialized fields.
|
|
75
|
+
|
|
76
|
+
```go
|
|
77
|
+
type Status int
|
|
78
|
+
|
|
79
|
+
const (
|
|
80
|
+
StatusUnknown Status = iota // 0 — zero value catches bugs
|
|
81
|
+
StatusActive // 1
|
|
82
|
+
StatusInactive // 2
|
|
83
|
+
StatusBanned // 3
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
func (s Status) String() string {
|
|
87
|
+
switch s {
|
|
88
|
+
case StatusActive:
|
|
89
|
+
return "active"
|
|
90
|
+
case StatusInactive:
|
|
91
|
+
return "inactive"
|
|
92
|
+
case StatusBanned:
|
|
93
|
+
return "banned"
|
|
94
|
+
default:
|
|
95
|
+
return "unknown"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
func (s Status) IsValid() bool {
|
|
100
|
+
return s >= StatusActive && s <= StatusBanned
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 4. Builder Pattern
|
|
105
|
+
|
|
106
|
+
For constructing complex objects step by step. Less common in Go than functional options, but useful for immutable value objects.
|
|
107
|
+
|
|
108
|
+
```go
|
|
109
|
+
type QueryBuilder struct {
|
|
110
|
+
table string
|
|
111
|
+
conditions []string
|
|
112
|
+
args []any
|
|
113
|
+
limit int
|
|
114
|
+
offset int
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
func NewQueryBuilder(table string) *QueryBuilder {
|
|
118
|
+
return &QueryBuilder{table: table}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
func (b *QueryBuilder) Where(cond string, args ...any) *QueryBuilder {
|
|
122
|
+
b.conditions = append(b.conditions, cond)
|
|
123
|
+
b.args = append(b.args, args...)
|
|
124
|
+
return b
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
func (b *QueryBuilder) Limit(n int) *QueryBuilder {
|
|
128
|
+
b.limit = n
|
|
129
|
+
return b
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func (b *QueryBuilder) Build() (string, []any) {
|
|
133
|
+
q := "SELECT * FROM " + b.table
|
|
134
|
+
if len(b.conditions) > 0 {
|
|
135
|
+
q += " WHERE " + strings.Join(b.conditions, " AND ")
|
|
136
|
+
}
|
|
137
|
+
if b.limit > 0 {
|
|
138
|
+
q += fmt.Sprintf(" LIMIT %d", b.limit)
|
|
139
|
+
}
|
|
140
|
+
return q, b.args
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## 5. Dependency Injection (Interface-Based)
|
|
145
|
+
|
|
146
|
+
Define small interfaces at the consumer side. Inject concrete implementations via constructors.
|
|
147
|
+
|
|
148
|
+
```go
|
|
149
|
+
// Consumer defines what it needs (not the provider)
|
|
150
|
+
type UserFinder interface {
|
|
151
|
+
FindByID(ctx context.Context, id int64) (*User, error)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type NotificationSender interface {
|
|
155
|
+
Send(ctx context.Context, userID int64, msg string) error
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
type OrderService struct {
|
|
159
|
+
users UserFinder
|
|
160
|
+
notify NotificationSender
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
func NewOrderService(users UserFinder, notify NotificationSender) *OrderService {
|
|
164
|
+
return &OrderService{users: users, notify: notify}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## 6. Factory Functions
|
|
169
|
+
|
|
170
|
+
Return different implementations behind an interface based on configuration.
|
|
171
|
+
|
|
172
|
+
```go
|
|
173
|
+
func NewCache(cfg Config) (Cache, error) {
|
|
174
|
+
switch cfg.Type {
|
|
175
|
+
case "redis":
|
|
176
|
+
return NewRedisCache(cfg.RedisURL)
|
|
177
|
+
case "memory":
|
|
178
|
+
return NewMemoryCache(cfg.MaxSize)
|
|
179
|
+
case "noop":
|
|
180
|
+
return NoopCache{}, nil
|
|
181
|
+
default:
|
|
182
|
+
return nil, fmt.Errorf("unknown cache type: %s", cfg.Type)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## 7. Singleton (sync.Once)
|
|
188
|
+
|
|
189
|
+
Thread-safe lazy initialization. Use sparingly — prefer dependency injection.
|
|
190
|
+
|
|
191
|
+
```go
|
|
192
|
+
var (
|
|
193
|
+
defaultClient *Client
|
|
194
|
+
clientOnce sync.Once
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
func DefaultClient() *Client {
|
|
198
|
+
clientOnce.Do(func() {
|
|
199
|
+
defaultClient = &Client{
|
|
200
|
+
http: &http.Client{Timeout: 30 * time.Second},
|
|
201
|
+
baseURL: "https://api.example.com",
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
return defaultClient
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## 8. Composition Over Inheritance
|
|
209
|
+
|
|
210
|
+
Go has no inheritance. Use struct embedding for code reuse and interface embedding for contract composition.
|
|
211
|
+
|
|
212
|
+
```go
|
|
213
|
+
// Struct embedding — reuse behavior
|
|
214
|
+
type BaseRepository struct {
|
|
215
|
+
db *pgxpool.Pool
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
func (r *BaseRepository) Health(ctx context.Context) error {
|
|
219
|
+
return r.db.Ping(ctx)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
type UserRepository struct {
|
|
223
|
+
BaseRepository // embeds Health() and db field
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Interface embedding — compose contracts
|
|
227
|
+
type ReadWriter interface {
|
|
228
|
+
Reader
|
|
229
|
+
Writer
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 9. Accept Interfaces, Return Structs
|
|
234
|
+
|
|
235
|
+
Functions should accept interfaces (flexibility) and return concrete types (clarity).
|
|
236
|
+
|
|
237
|
+
```go
|
|
238
|
+
// CORRECT
|
|
239
|
+
func NewService(repo UserRepository) *Service { // accepts interface, returns struct
|
|
240
|
+
return &Service{repo: repo}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// WRONG
|
|
244
|
+
func NewService(repo *PostgresRepo) ServiceInterface { // accepts struct, returns interface
|
|
245
|
+
return &Service{repo: repo}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## 10. Table-Driven Logic
|
|
250
|
+
|
|
251
|
+
Replace complex switch/if chains with a lookup table.
|
|
252
|
+
|
|
253
|
+
```go
|
|
254
|
+
var statusTransitions = map[Status][]Status{
|
|
255
|
+
StatusDraft: {StatusPending},
|
|
256
|
+
StatusPending: {StatusApproved, StatusRejected},
|
|
257
|
+
StatusApproved: {StatusPublished},
|
|
258
|
+
StatusRejected: {StatusDraft},
|
|
259
|
+
StatusPublished: {StatusArchived},
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
func (s Status) CanTransitionTo(target Status) bool {
|
|
263
|
+
allowed, ok := statusTransitions[s]
|
|
264
|
+
if !ok {
|
|
265
|
+
return false
|
|
266
|
+
}
|
|
267
|
+
return slices.Contains(allowed, target)
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 11. Errors as Values
|
|
272
|
+
|
|
273
|
+
Errors are values that can be inspected, wrapped, and composed. Never use panics for control flow.
|
|
274
|
+
|
|
275
|
+
```go
|
|
276
|
+
type ValidationError struct {
|
|
277
|
+
Fields map[string]string
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
func (e *ValidationError) Error() string {
|
|
281
|
+
return fmt.Sprintf("validation failed: %d fields", len(e.Fields))
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
func (e *ValidationError) HasField(name string) bool {
|
|
285
|
+
_, ok := e.Fields[name]
|
|
286
|
+
return ok
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## 12. Nil-Safe Methods
|
|
291
|
+
|
|
292
|
+
Design methods that handle nil receivers gracefully.
|
|
293
|
+
|
|
294
|
+
```go
|
|
295
|
+
type User struct {
|
|
296
|
+
Name string
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
func (u *User) DisplayName() string {
|
|
300
|
+
if u == nil {
|
|
301
|
+
return "anonymous"
|
|
302
|
+
}
|
|
303
|
+
if u.Name == "" {
|
|
304
|
+
return "unnamed"
|
|
305
|
+
}
|
|
306
|
+
return u.Name
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## 13. Sentinel Values
|
|
311
|
+
|
|
312
|
+
Package-level values used as signals. Always check with `errors.Is`.
|
|
313
|
+
|
|
314
|
+
```go
|
|
315
|
+
var (
|
|
316
|
+
ErrNotFound = errors.New("not found")
|
|
317
|
+
ErrConflict = errors.New("conflict")
|
|
318
|
+
ErrForbidden = errors.New("forbidden")
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
// Check
|
|
322
|
+
if errors.Is(err, ErrNotFound) {
|
|
323
|
+
// handle not found
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## 14. Guard Clauses
|
|
328
|
+
|
|
329
|
+
Validate preconditions at function entry before proceeding to logic.
|
|
330
|
+
|
|
331
|
+
```go
|
|
332
|
+
func Transfer(ctx context.Context, from, to *Account, amount decimal.Decimal) error {
|
|
333
|
+
if from == nil || to == nil {
|
|
334
|
+
return ErrInvalidInput
|
|
335
|
+
}
|
|
336
|
+
if amount.IsNegative() || amount.IsZero() {
|
|
337
|
+
return ErrInvalidAmount
|
|
338
|
+
}
|
|
339
|
+
if from.ID == to.ID {
|
|
340
|
+
return ErrSameAccount
|
|
341
|
+
}
|
|
342
|
+
if from.Balance.LessThan(amount) {
|
|
343
|
+
return ErrInsufficientFunds
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// proceed with transfer logic
|
|
347
|
+
from.Balance = from.Balance.Sub(amount)
|
|
348
|
+
to.Balance = to.Balance.Add(amount)
|
|
349
|
+
return nil
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## 15. Configuration with Defaults
|
|
354
|
+
|
|
355
|
+
Provide usable defaults, allow override. Combine with functional options or config structs.
|
|
356
|
+
|
|
357
|
+
```go
|
|
358
|
+
type Config struct {
|
|
359
|
+
Host string `env:"HOST" default:"localhost"`
|
|
360
|
+
Port int `env:"PORT" default:"8080"`
|
|
361
|
+
ReadTimeout time.Duration `env:"READ_TIMEOUT" default:"5s"`
|
|
362
|
+
WriteTimeout time.Duration `env:"WRITE_TIMEOUT" default:"10s"`
|
|
363
|
+
MaxBodySize int64 `env:"MAX_BODY_SIZE" default:"1048576"` // 1MB
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
func DefaultConfig() Config {
|
|
367
|
+
return Config{
|
|
368
|
+
Host: "localhost",
|
|
369
|
+
Port: 8080,
|
|
370
|
+
ReadTimeout: 5 * time.Second,
|
|
371
|
+
WriteTimeout: 10 * time.Second,
|
|
372
|
+
MaxBodySize: 1 << 20, // 1MB
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## 16. Middleware Pattern
|
|
378
|
+
|
|
379
|
+
Wrap handlers with cross-cutting concerns. Chain middlewares in order.
|
|
380
|
+
|
|
381
|
+
```go
|
|
382
|
+
type Middleware func(http.Handler) http.Handler
|
|
383
|
+
|
|
384
|
+
func WithLogging(logger *slog.Logger) Middleware {
|
|
385
|
+
return func(next http.Handler) http.Handler {
|
|
386
|
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
387
|
+
start := time.Now()
|
|
388
|
+
next.ServeHTTP(w, r)
|
|
389
|
+
logger.Info("request",
|
|
390
|
+
"method", r.Method,
|
|
391
|
+
"path", r.URL.Path,
|
|
392
|
+
"duration", time.Since(start),
|
|
393
|
+
)
|
|
394
|
+
})
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
func Chain(h http.Handler, mws ...Middleware) http.Handler {
|
|
399
|
+
for i := len(mws) - 1; i >= 0; i-- {
|
|
400
|
+
h = mws[i](h)
|
|
401
|
+
}
|
|
402
|
+
return h
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## When to Use
|
|
407
|
+
|
|
408
|
+
Apply when reviewing Go code architecture and API design. Flag violations as:
|
|
409
|
+
- **CRITICAL**: Panic for control flow, global mutable state without sync, inheritance simulation
|
|
410
|
+
- **WARNING**: Missing functional options for 5+ config params, large interfaces, deeply nested logic
|
|
411
|
+
- **SUGGESTION**: Could use table-driven logic, nil-unsafe methods, missing guard clauses
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Dependency Injection Frameworks (uber-fx, uber-dig, google-wire)
|
|
2
|
+
|
|
3
|
+
Standalone DI frameworks for Go applications. Different from `samber/do` (which is in `samber-do.md`).
|
|
4
|
+
|
|
5
|
+
## When to use a DI framework
|
|
6
|
+
|
|
7
|
+
- Application has 10+ services with shared dependencies (db, logger, config, cache)
|
|
8
|
+
- Manual `main.go` wiring becomes hard to read (200+ lines of construction)
|
|
9
|
+
- Multiple environments (prod, test, dev) need different concrete implementations
|
|
10
|
+
- Lifecycle management (start / stop / health-check) needs to be orderly
|
|
11
|
+
|
|
12
|
+
## When NOT to use a DI framework
|
|
13
|
+
|
|
14
|
+
- Small CLI or single-service app — manual wiring is clearer
|
|
15
|
+
- Hot-path code where reflection-based DI adds startup latency
|
|
16
|
+
- Team is unfamiliar with the pattern — added complexity outweighs benefit
|
|
17
|
+
|
|
18
|
+
## uber-fx — Highest-level, most opinionated
|
|
19
|
+
|
|
20
|
+
Use when: you want a full application lifecycle framework (start, stop, signal handling, structured logs).
|
|
21
|
+
|
|
22
|
+
```go
|
|
23
|
+
import "go.uber.org/fx"
|
|
24
|
+
|
|
25
|
+
type Server struct {
|
|
26
|
+
db *sql.DB
|
|
27
|
+
cfg *Config
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func NewServer(lc fx.Lifecycle, db *sql.DB, cfg *Config) *Server {
|
|
31
|
+
s := &Server{db: db, cfg: cfg}
|
|
32
|
+
lc.Append(fx.Hook{
|
|
33
|
+
// OnStart MUST return quickly. Run blocking work (Serve/accept loops) in a
|
|
34
|
+
// goroutine so dependent hooks can start; do teardown in OnStop honoring ctx.
|
|
35
|
+
OnStart: func(ctx context.Context) error {
|
|
36
|
+
ln, err := net.Listen("tcp", cfg.Addr)
|
|
37
|
+
if err != nil {
|
|
38
|
+
return err
|
|
39
|
+
}
|
|
40
|
+
go s.Serve(ln) // blocking accept loop off the startup path
|
|
41
|
+
return nil
|
|
42
|
+
},
|
|
43
|
+
OnStop: func(ctx context.Context) error {
|
|
44
|
+
return s.Shutdown(ctx) // honor ctx deadline (StopTimeout, default 15s)
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
return s
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func main() {
|
|
51
|
+
fx.New(
|
|
52
|
+
fx.Provide(
|
|
53
|
+
NewConfig,
|
|
54
|
+
NewDB,
|
|
55
|
+
NewServer,
|
|
56
|
+
),
|
|
57
|
+
fx.Invoke(func(*Server) {}),
|
|
58
|
+
).Run()
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Pros:** Lifecycle hooks, parameter/result objects, fx.Module for grouping, built-in signal handling.
|
|
63
|
+
**Cons:** Reflection-based — startup is slower. Errors at startup, not at compile time.
|
|
64
|
+
|
|
65
|
+
**Review notes.**
|
|
66
|
+
- `fx.Module` decorators are descendant-scoped: an `fx.Decorate` inside a module only rewrites providers for that module and its children, but a top-level `fx.Decorate` leaks globally to every provider. Keep decorators inside the module that owns them.
|
|
67
|
+
- `StartTimeout` / `StopTimeout` default to **15s**. A hook that runs longer (slow migration, drain) fails the lifecycle — raise the bound via `fx.StartTimeout` / `fx.StopTimeout`, don't let a hook silently rely on more.
|
|
68
|
+
- Validate the DI graph in CI without starting the app: `fx.New(...).Err()` builds and type-checks the whole graph (missing or ambiguous providers surface here) but never runs `OnStart`.
|
|
69
|
+
|
|
70
|
+
## uber-dig — Just the DI container
|
|
71
|
+
|
|
72
|
+
Use when: you want fx's container without the lifecycle/run machinery.
|
|
73
|
+
|
|
74
|
+
```go
|
|
75
|
+
container := dig.New()
|
|
76
|
+
container.Provide(NewConfig)
|
|
77
|
+
container.Provide(NewDB)
|
|
78
|
+
container.Provide(NewServer)
|
|
79
|
+
|
|
80
|
+
err := container.Invoke(func(s *Server) {
|
|
81
|
+
s.Listen()
|
|
82
|
+
})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Pros:** Smaller than fx, same reflection model.
|
|
86
|
+
**Cons:** No lifecycle hooks — you manage start/stop yourself.
|
|
87
|
+
|
|
88
|
+
## google-wire — Compile-time DI via codegen
|
|
89
|
+
|
|
90
|
+
Use when: you want zero runtime cost and compile-time guarantees.
|
|
91
|
+
|
|
92
|
+
```go
|
|
93
|
+
//go:build wireinject
|
|
94
|
+
|
|
95
|
+
package main
|
|
96
|
+
|
|
97
|
+
import "github.com/google/wire"
|
|
98
|
+
|
|
99
|
+
func InitializeServer() (*Server, error) {
|
|
100
|
+
wire.Build(NewConfig, NewDB, NewServer)
|
|
101
|
+
return nil, nil
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then run `wire ./...` to generate `wire_gen.go` containing the actual constructor calls.
|
|
106
|
+
|
|
107
|
+
**Pros:** Zero reflection, zero runtime cost, errors are compile-time. Generated code is readable.
|
|
108
|
+
**Cons:** Extra build step (`wire gen`). Errors require understanding the codegen output.
|
|
109
|
+
|
|
110
|
+
**Review notes.**
|
|
111
|
+
- **Cleanup functions.** A provider returning `(T, func(), error)` registers a cleanup. wire chains cleanups in **reverse** provider order and handles partial failure: if a later provider errors, the already-built providers' cleanups still run. In generated call sites always nil-guard before deferring — `if cleanup != nil { defer cleanup() }` — since a provider may return a nil cleanup.
|
|
112
|
+
- **Interface binding.** wire forbids implicit interface satisfaction: a concrete type is not substituted for an interface automatically. A missing `wire.Bind(new(Iface), new(*Impl))` is a **compile-time break** in the generated code, not a runtime surprise.
|
|
113
|
+
- **Currency caution.** google/wire was **archived by its owner on Aug 25, 2025** and is no longer maintained (feature-complete, read-only). It still builds and works, but expect no fixes or new features — weigh this before adopting it for a new project.
|
|
114
|
+
|
|
115
|
+
## Comparison
|
|
116
|
+
|
|
117
|
+
| Aspect | uber-fx | uber-dig | google-wire | samber/do |
|
|
118
|
+
|--------|---------|----------|-------------|-----------|
|
|
119
|
+
| Resolution | Runtime (reflection) | Runtime (reflection) | Compile-time (codegen) | Runtime (generics) |
|
|
120
|
+
| Startup cost | Medium | Low | Zero | Low |
|
|
121
|
+
| Lifecycle hooks | Yes | No | No | Yes (via shutdown) |
|
|
122
|
+
| Type safety | Runtime | Runtime | Compile | Compile (generics) |
|
|
123
|
+
| Codegen | No | No | Yes | No |
|
|
124
|
+
| Learning curve | Medium | Low | High initially | Low |
|
|
125
|
+
|
|
126
|
+
## Anti-patterns
|
|
127
|
+
|
|
128
|
+
- **Service locator hidden in DI**: passing the container itself into services. Defeats the point — services should only see their dependencies.
|
|
129
|
+
- **DI for everything**: simple cases (a `*sql.DB` and a config) don't need a framework.
|
|
130
|
+
- **No teardown**: starting things without stopping them. Leaks connections, goroutines, files.
|
|
131
|
+
- **Mixing two frameworks**: pick one. Mixing fx with wire (or with samber/do) creates two parallel object graphs.
|
|
132
|
+
|
|
133
|
+
## Choosing one
|
|
134
|
+
|
|
135
|
+
| Situation | Pick |
|
|
136
|
+
|-----------|------|
|
|
137
|
+
| Full microservice with HTTP + workers + signal handling | **uber-fx** |
|
|
138
|
+
| Library that needs an injection container, not an app framework | **uber-dig** |
|
|
139
|
+
| Compile-time guarantees mandated, codegen acceptable | **google-wire** (archived Aug 2025 — feature-complete but unmaintained) |
|
|
140
|
+
| Lightweight, generics-first, no codegen | **samber/do** (see samber-do.md) |
|
|
141
|
+
| Small CLI / single-process tool | Manual wiring (no framework) |
|
|
142
|
+
|
|
143
|
+
## See also
|
|
144
|
+
|
|
145
|
+
- `samber-do.md` — generics-based alternative
|
|
146
|
+
- `samber-libraries.md` — overview of samber's Go libs
|