@heyai-rules/pilo-masterkit 2.1.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/agents/PILO_MASTER.md +77 -77
- package/.agent/agents/architect.md +211 -211
- package/.agent/agents/backend-specialist.md +263 -263
- package/.agent/agents/build-error-resolver.md +114 -114
- package/.agent/agents/chief-of-staff.md +151 -151
- package/.agent/agents/code-archaeologist.md +106 -106
- package/.agent/agents/code-reviewer.md +237 -237
- package/.agent/agents/cpp-build-resolver.md +90 -90
- package/.agent/agents/cpp-reviewer.md +72 -72
- package/.agent/agents/csharp-reviewer.md +101 -101
- package/.agent/agents/dart-build-resolver.md +201 -201
- package/.agent/agents/database-architect.md +226 -226
- package/.agent/agents/database-reviewer.md +91 -91
- package/.agent/agents/debugger.md +225 -225
- package/.agent/agents/devops-engineer.md +242 -242
- package/.agent/agents/doc-updater.md +107 -107
- package/.agent/agents/docs-lookup.md +68 -68
- package/.agent/agents/documentation-writer.md +104 -104
- package/.agent/agents/e2e-runner.md +107 -107
- package/.agent/agents/explorer-agent.md +73 -73
- package/.agent/agents/flutter-reviewer.md +243 -243
- package/.agent/agents/frontend-specialist.md +593 -593
- package/.agent/agents/game-developer.md +162 -162
- package/.agent/agents/gan-evaluator.md +209 -209
- package/.agent/agents/gan-generator.md +131 -131
- package/.agent/agents/gan-planner.md +99 -99
- package/.agent/agents/go-build-resolver.md +94 -94
- package/.agent/agents/go-reviewer.md +76 -76
- package/.agent/agents/harness-optimizer.md +35 -35
- package/.agent/agents/healthcare-reviewer.md +83 -83
- package/.agent/agents/java-build-resolver.md +153 -153
- package/.agent/agents/java-reviewer.md +92 -92
- package/.agent/agents/kotlin-build-resolver.md +118 -118
- package/.agent/agents/kotlin-reviewer.md +159 -159
- package/.agent/agents/loop-operator.md +36 -36
- package/.agent/agents/mobile-developer.md +377 -377
- package/.agent/agents/opensource-forker.md +198 -198
- package/.agent/agents/opensource-packager.md +249 -249
- package/.agent/agents/opensource-sanitizer.md +188 -188
- package/.agent/agents/orchestrator.md +416 -416
- package/.agent/agents/penetration-tester.md +188 -188
- package/.agent/agents/performance-optimizer.md +446 -446
- package/.agent/agents/personas/athena-agent/agent.json +10 -10
- package/.agent/agents/personas/athena-agent/athena-backend-logic-architecture-profile.md +3 -3
- package/.agent/agents/personas/athena-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/athena-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/athena-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/athena-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/athena-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/athena-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/da-vinci-agent/agent.json +10 -10
- package/.agent/agents/personas/da-vinci-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/da-vinci-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/da-vinci-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/da-vinci-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/da-vinci-agent/da-vinci-frontend-ui-ux-design-profile.md +3 -3
- package/.agent/agents/personas/da-vinci-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/da-vinci-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/duong-tang-agent/agent.json +10 -10
- package/.agent/agents/personas/duong-tang-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/duong-tang-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/duong-tang-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/duong-tang-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/duong-tang-agent/tang-monk-quality-testing-documentation-profile.md +3 -3
- package/.agent/agents/personas/duong-tang-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/duong-tang-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/gia-cat-luong-agent/agent.json +10 -10
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/gia-cat-luong-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/gia-cat-luong-agent/kongming-research-strategy-analysis-profile.md +3 -3
- package/.agent/agents/personas/gia-cat-luong-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/gia-cat-luong-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/mihata-agent/agent.json +10 -10
- package/.agent/agents/personas/mihata-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/mihata-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/mihata-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/mihata-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/mihata-agent/mihata-multi-agent-orchestration-profile.md +3 -3
- package/.agent/agents/personas/mihata-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/mihata-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/tesla-agent/agent.json +10 -10
- package/.agent/agents/personas/tesla-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/tesla-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/tesla-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/tesla-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/tesla-agent/tesla-fullstack-system-optimization-profile.md +3 -3
- package/.agent/agents/personas/tesla-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/tesla-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/tu-ma-y-agent/agent.json +10 -10
- package/.agent/agents/personas/tu-ma-y-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/tu-ma-y-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/tu-ma-y-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/tu-ma-y-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/tu-ma-y-agent/simayi-feasibility-risk-control-profile.md +3 -3
- package/.agent/agents/personas/tu-ma-y-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/tu-ma-y-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/venti-agent/agent.json +10 -10
- package/.agent/agents/personas/venti-agent/context-files/agents.md +1 -1
- package/.agent/agents/personas/venti-agent/context-files/identity.md +1 -1
- package/.agent/agents/personas/venti-agent/context-files/soul.md +1 -1
- package/.agent/agents/personas/venti-agent/context-files/user-predefined.md +1 -1
- package/.agent/agents/personas/venti-agent/user-context-files/system/bootstrap.md +1 -1
- package/.agent/agents/personas/venti-agent/user-context-files/system/user.md +1 -1
- package/.agent/agents/personas/venti-agent/venti-learning-communication-mentoring-profile.md +3 -3
- package/.agent/agents/planner.md +212 -212
- package/.agent/agents/product-manager.md +112 -112
- package/.agent/agents/product-owner.md +95 -95
- package/.agent/agents/project-planner.md +406 -406
- package/.agent/agents/python-reviewer.md +98 -98
- package/.agent/agents/pytorch-build-resolver.md +120 -120
- package/.agent/agents/qa-automation-engineer.md +103 -103
- package/.agent/agents/refactor-cleaner.md +85 -85
- package/.agent/agents/rust-build-resolver.md +148 -148
- package/.agent/agents/rust-reviewer.md +94 -94
- package/.agent/agents/security-auditor.md +170 -170
- package/.agent/agents/security-reviewer.md +108 -108
- package/.agent/agents/seo-specialist.md +111 -111
- package/.agent/agents/tdd-guide.md +91 -91
- package/.agent/agents/test-engineer.md +158 -158
- package/.agent/agents/typescript-reviewer.md +112 -112
- package/.agent/contexts/dev.md +20 -20
- package/.agent/contexts/research.md +26 -26
- package/.agent/contexts/review.md +22 -22
- package/.agent/hooks/hooks.json +395 -395
- package/.agent/hooks/readme.md +222 -222
- package/.agent/mcp-configs/mcp-servers.json +181 -181
- package/.agent/rules/ARCHITECTURAL_BLUEPRINTS.md +62 -62
- package/.agent/rules/CODE_CRAFTSMANSHIP.md +69 -69
- package/.agent/rules/CORE_RULES.md +72 -72
- package/.agent/rules/PROJECT_MAP.md +58 -58
- package/.agent/rules/QUALITY_ASSURANCE.md +54 -54
- package/.agent/rules/SECURITY_ARMOR.md +44 -44
- package/.agent/rules/VERSION_ORCHESTRATION.md +64 -64
- package/.agent/rules/WORKFLOW_ORCHESTRATION.md +55 -55
- package/.agent/rules/common/agents.md +50 -50
- package/.agent/rules/common/code-review.md +124 -124
- package/.agent/rules/common/coding-style.md +48 -48
- package/.agent/rules/common/development-workflow.md +44 -44
- package/.agent/rules/common/git-workflow.md +24 -24
- package/.agent/rules/common/hooks.md +30 -30
- package/.agent/rules/common/patterns.md +31 -31
- package/.agent/rules/common/performance.md +55 -55
- package/.agent/rules/common/security.md +29 -29
- package/.agent/rules/common/testing.md +29 -29
- package/.agent/rules/cpp/coding-style.md +44 -44
- package/.agent/rules/cpp/hooks.md +39 -39
- package/.agent/rules/cpp/patterns.md +51 -51
- package/.agent/rules/cpp/security.md +51 -51
- package/.agent/rules/cpp/testing.md +44 -44
- package/.agent/rules/csharp/coding-style.md +72 -72
- package/.agent/rules/csharp/hooks.md +25 -25
- package/.agent/rules/csharp/patterns.md +50 -50
- package/.agent/rules/csharp/security.md +58 -58
- package/.agent/rules/csharp/testing.md +46 -46
- package/.agent/rules/dart/coding-style.md +159 -159
- package/.agent/rules/dart/hooks.md +66 -66
- package/.agent/rules/dart/patterns.md +261 -261
- package/.agent/rules/dart/security.md +135 -135
- package/.agent/rules/dart/testing.md +215 -215
- package/.agent/rules/golang/coding-style.md +32 -32
- package/.agent/rules/golang/hooks.md +17 -17
- package/.agent/rules/golang/patterns.md +45 -45
- package/.agent/rules/golang/security.md +34 -34
- package/.agent/rules/golang/testing.md +31 -31
- package/.agent/rules/java/coding-style.md +114 -114
- package/.agent/rules/java/hooks.md +18 -18
- package/.agent/rules/java/patterns.md +146 -146
- package/.agent/rules/java/security.md +100 -100
- package/.agent/rules/java/testing.md +131 -131
- package/.agent/rules/kotlin/coding-style.md +86 -86
- package/.agent/rules/kotlin/hooks.md +17 -17
- package/.agent/rules/kotlin/patterns.md +146 -146
- package/.agent/rules/kotlin/security.md +82 -82
- package/.agent/rules/kotlin/testing.md +128 -128
- package/.agent/rules/perl/coding-style.md +46 -46
- package/.agent/rules/perl/hooks.md +22 -22
- package/.agent/rules/perl/patterns.md +76 -76
- package/.agent/rules/perl/security.md +69 -69
- package/.agent/rules/perl/testing.md +54 -54
- package/.agent/rules/php/coding-style.md +40 -40
- package/.agent/rules/php/hooks.md +24 -24
- package/.agent/rules/php/patterns.md +33 -33
- package/.agent/rules/php/security.md +37 -37
- package/.agent/rules/php/testing.md +39 -39
- package/.agent/rules/python/coding-style.md +42 -42
- package/.agent/rules/python/hooks.md +19 -19
- package/.agent/rules/python/patterns.md +39 -39
- package/.agent/rules/python/security.md +30 -30
- package/.agent/rules/python/testing.md +38 -38
- package/.agent/rules/readme.md +111 -111
- package/.agent/rules/rust/coding-style.md +151 -151
- package/.agent/rules/rust/hooks.md +16 -16
- package/.agent/rules/rust/patterns.md +168 -168
- package/.agent/rules/rust/security.md +141 -141
- package/.agent/rules/rust/testing.md +154 -154
- package/.agent/rules/swift/coding-style.md +47 -47
- package/.agent/rules/swift/hooks.md +20 -20
- package/.agent/rules/swift/patterns.md +66 -66
- package/.agent/rules/swift/security.md +33 -33
- package/.agent/rules/swift/testing.md +45 -45
- package/.agent/rules/typescript/coding-style.md +199 -199
- package/.agent/rules/typescript/hooks.md +22 -22
- package/.agent/rules/typescript/patterns.md +52 -52
- package/.agent/rules/typescript/security.md +28 -28
- package/.agent/rules/typescript/testing.md +18 -18
- package/.agent/rules/web/coding-style.md +96 -96
- package/.agent/rules/web/design-quality.md +63 -63
- package/.agent/rules/web/hooks.md +120 -120
- package/.agent/rules/web/patterns.md +79 -79
- package/.agent/rules/web/performance.md +64 -64
- package/.agent/rules/web/security.md +57 -57
- package/.agent/rules/web/testing.md +55 -55
- package/.agent/rules/zh/agents.md +50 -50
- package/.agent/rules/zh/code-review.md +124 -124
- package/.agent/rules/zh/coding-style.md +48 -48
- package/.agent/rules/zh/development-workflow.md +44 -44
- package/.agent/rules/zh/git-workflow.md +24 -24
- package/.agent/rules/zh/hooks.md +30 -30
- package/.agent/rules/zh/patterns.md +31 -31
- package/.agent/rules/zh/performance.md +55 -55
- package/.agent/rules/zh/readme.md +108 -108
- package/.agent/rules/zh/security.md +29 -29
- package/.agent/rules/zh/testing.md +29 -29
- package/.agent/scripts/auto_preview.py +148 -148
- package/.agent/scripts/checklist.py +217 -217
- package/.agent/scripts/session_manager.py +120 -120
- package/.agent/scripts/verify_all.py +327 -327
- package/.agent/skills/agent-eval/SKILL.md +145 -145
- package/.agent/skills/agent-harness-construction/SKILL.md +73 -73
- package/.agent/skills/agent-payment-x402/SKILL.md +178 -178
- package/.agent/skills/agentic-engineering/SKILL.md +63 -63
- package/.agent/skills/ai-first-engineering/SKILL.md +51 -51
- package/.agent/skills/ai-regression-testing/SKILL.md +385 -385
- package/.agent/skills/android-clean-architecture/SKILL.md +339 -339
- package/.agent/skills/api-design/SKILL.md +523 -523
- package/.agent/skills/api-patterns/SKILL.md +81 -81
- package/.agent/skills/api-patterns/api-style.md +42 -42
- package/.agent/skills/api-patterns/auth.md +24 -24
- package/.agent/skills/api-patterns/documentation.md +26 -26
- package/.agent/skills/api-patterns/graphql.md +41 -41
- package/.agent/skills/api-patterns/rate-limiting.md +31 -31
- package/.agent/skills/api-patterns/response.md +37 -37
- package/.agent/skills/api-patterns/rest.md +40 -40
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -211
- package/.agent/skills/api-patterns/security-testing.md +122 -122
- package/.agent/skills/api-patterns/trpc.md +41 -41
- package/.agent/skills/api-patterns/versioning.md +22 -22
- package/.agent/skills/app-builder/SKILL.md +75 -75
- package/.agent/skills/app-builder/agent-coordination.md +71 -71
- package/.agent/skills/app-builder/feature-building.md +53 -53
- package/.agent/skills/app-builder/project-detection.md +34 -34
- package/.agent/skills/app-builder/scaffolding.md +118 -118
- package/.agent/skills/app-builder/tech-stack.md +41 -41
- package/.agent/skills/app-builder/templates/SKILL.md +39 -39
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -76
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -92
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -88
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -88
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -83
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -90
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -90
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -122
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -122
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -169
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -134
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -83
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -119
- package/.agent/skills/architecture/SKILL.md +55 -55
- package/.agent/skills/architecture/context-discovery.md +43 -43
- package/.agent/skills/architecture/examples.md +94 -94
- package/.agent/skills/architecture/pattern-selection.md +68 -68
- package/.agent/skills/architecture/patterns-reference.md +50 -50
- package/.agent/skills/architecture/trade-off-analysis.md +77 -77
- package/.agent/skills/architecture-decision-records/SKILL.md +179 -179
- package/.agent/skills/article-writing/SKILL.md +79 -79
- package/.agent/skills/autonomous-agent-harness/SKILL.md +267 -267
- package/.agent/skills/autonomous-loops/SKILL.md +610 -610
- package/.agent/skills/backend-patterns/SKILL.md +598 -598
- package/.agent/skills/bash-linux/SKILL.md +199 -199
- package/.agent/skills/behavioral-modes/SKILL.md +242 -242
- package/.agent/skills/benchmark/SKILL.md +93 -93
- package/.agent/skills/blueprint/SKILL.md +105 -105
- package/.agent/skills/brainstorming/SKILL.md +163 -163
- package/.agent/skills/brainstorming/dynamic-questioning.md +350 -350
- package/.agent/skills/brand-voice/SKILL.md +97 -97
- package/.agent/skills/brand-voice/references/voice-profile-schema.md +55 -55
- package/.agent/skills/browser-qa/SKILL.md +87 -87
- package/.agent/skills/bun-runtime/SKILL.md +84 -84
- package/.agent/skills/canary-watch/SKILL.md +99 -99
- package/.agent/skills/carrier-relationship-management/SKILL.md +212 -212
- package/.agent/skills/ck/SKILL.md +147 -147
- package/.agent/skills/ck/commands/forget.mjs +44 -44
- package/.agent/skills/ck/commands/info.mjs +24 -24
- package/.agent/skills/ck/commands/init.mjs +143 -143
- package/.agent/skills/ck/commands/list.mjs +40 -40
- package/.agent/skills/ck/commands/migrate.mjs +202 -202
- package/.agent/skills/ck/commands/resume.mjs +36 -36
- package/.agent/skills/ck/commands/save.mjs +210 -210
- package/.agent/skills/ck/commands/shared.mjs +387 -387
- package/.agent/skills/ck/hooks/session-start.mjs +224 -224
- package/.agent/skills/claude-api/SKILL.md +337 -337
- package/.agent/skills/claude-devfleet/SKILL.md +103 -103
- package/.agent/skills/clean-code/SKILL.md +201 -201
- package/.agent/skills/click-path-audit/SKILL.md +244 -244
- package/.agent/skills/clickhouse-io/SKILL.md +439 -439
- package/.agent/skills/code-review-checklist/SKILL.md +109 -109
- package/.agent/skills/codebase-onboarding/SKILL.md +233 -233
- package/.agent/skills/coding-standards/SKILL.md +530 -530
- package/.agent/skills/compose-multiplatform-patterns/SKILL.md +299 -299
- package/.agent/skills/configure-ecc/SKILL.md +367 -367
- package/.agent/skills/connections-optimizer/SKILL.md +189 -189
- package/.agent/skills/content-engine/SKILL.md +131 -131
- package/.agent/skills/content-hash-cache-pattern/SKILL.md +161 -161
- package/.agent/skills/context-budget/SKILL.md +135 -135
- package/.agent/skills/continuous-agent-loop/SKILL.md +45 -45
- package/.agent/skills/continuous-learning/SKILL.md +119 -119
- package/.agent/skills/continuous-learning/config.json +18 -18
- package/.agent/skills/continuous-learning/evaluate-session.sh +69 -69
- package/.agent/skills/continuous-learning-v2/SKILL.md +365 -365
- package/.agent/skills/continuous-learning-v2/agents/observer-loop.sh +271 -271
- package/.agent/skills/continuous-learning-v2/agents/observer.md +198 -198
- package/.agent/skills/continuous-learning-v2/agents/session-guardian.sh +150 -150
- package/.agent/skills/continuous-learning-v2/agents/start-observer.sh +244 -244
- package/.agent/skills/continuous-learning-v2/config.json +8 -8
- package/.agent/skills/continuous-learning-v2/hooks/observe.sh +428 -428
- package/.agent/skills/continuous-learning-v2/scripts/detect-project.sh +228 -228
- package/.agent/skills/continuous-learning-v2/scripts/instinct-cli.py +1426 -1426
- package/.agent/skills/continuous-learning-v2/scripts/test-parse-instinct.py +984 -984
- package/.agent/skills/cost-aware-llm-pipeline/SKILL.md +183 -183
- package/.agent/skills/cpp-coding-standards/SKILL.md +723 -723
- package/.agent/skills/cpp-testing/SKILL.md +324 -324
- package/.agent/skills/crosspost/SKILL.md +111 -111
- package/.agent/skills/csharp-testing/SKILL.md +321 -321
- package/.agent/skills/customer-billing-ops/SKILL.md +140 -140
- package/.agent/skills/customs-trade-compliance/SKILL.md +263 -263
- package/.agent/skills/dart-flutter-patterns/SKILL.md +563 -563
- package/.agent/skills/data-scraper-agent/SKILL.md +764 -764
- package/.agent/skills/database-design/SKILL.md +52 -52
- package/.agent/skills/database-design/database-selection.md +43 -43
- package/.agent/skills/database-design/indexing.md +39 -39
- package/.agent/skills/database-design/migrations.md +48 -48
- package/.agent/skills/database-design/optimization.md +36 -36
- package/.agent/skills/database-design/orm-selection.md +30 -30
- package/.agent/skills/database-design/schema-design.md +56 -56
- package/.agent/skills/database-design/scripts/schema_validator.py +172 -172
- package/.agent/skills/database-migrations/SKILL.md +429 -429
- package/.agent/skills/deep-research/SKILL.md +155 -155
- package/.agent/skills/deployment-patterns/SKILL.md +427 -427
- package/.agent/skills/deployment-procedures/SKILL.md +241 -241
- package/.agent/skills/design-system/SKILL.md +82 -82
- package/.agent/skills/django-patterns/SKILL.md +734 -734
- package/.agent/skills/django-security/SKILL.md +593 -593
- package/.agent/skills/django-tdd/SKILL.md +729 -729
- package/.agent/skills/django-verification/SKILL.md +469 -469
- package/.agent/skills/dmux-workflows/SKILL.md +191 -191
- package/.agent/skills/doc.md +177 -177
- package/.agent/skills/docker-patterns/SKILL.md +364 -364
- package/.agent/skills/documentation-lookup/SKILL.md +90 -90
- package/.agent/skills/documentation-templates/SKILL.md +194 -194
- package/.agent/skills/dotnet-patterns/SKILL.md +321 -321
- package/.agent/skills/e2e-testing/SKILL.md +326 -326
- package/.agent/skills/energy-procurement/SKILL.md +228 -228
- package/.agent/skills/enterprise-agent-ops/SKILL.md +50 -50
- package/.agent/skills/eval-harness/SKILL.md +270 -270
- package/.agent/skills/exa-search/SKILL.md +103 -103
- package/.agent/skills/fal-ai-media/SKILL.md +284 -284
- package/.agent/skills/flutter-dart-code-review/SKILL.md +435 -435
- package/.agent/skills/foundation-models-on-device/SKILL.md +243 -243
- package/.agent/skills/frontend-design/SKILL.md +452 -452
- package/.agent/skills/frontend-design/animation-guide.md +331 -331
- package/.agent/skills/frontend-design/color-system.md +311 -311
- package/.agent/skills/frontend-design/decision-trees.md +418 -418
- package/.agent/skills/frontend-design/motion-graphics.md +306 -306
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -183
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -722
- package/.agent/skills/frontend-design/typography-system.md +345 -345
- package/.agent/skills/frontend-design/ux-psychology.md +1116 -1116
- package/.agent/skills/frontend-design/visual-effects.md +383 -383
- package/.agent/skills/frontend-patterns/SKILL.md +642 -642
- package/.agent/skills/frontend-slides/SKILL.md +184 -184
- package/.agent/skills/frontend-slides/style-presets.md +330 -330
- package/.agent/skills/game-development/2d-games/SKILL.md +119 -119
- package/.agent/skills/game-development/3d-games/SKILL.md +135 -135
- package/.agent/skills/game-development/SKILL.md +167 -167
- package/.agent/skills/game-development/game-art/SKILL.md +185 -185
- package/.agent/skills/game-development/game-audio/SKILL.md +190 -190
- package/.agent/skills/game-development/game-design/SKILL.md +129 -129
- package/.agent/skills/game-development/mobile-games/SKILL.md +108 -108
- package/.agent/skills/game-development/multiplayer/SKILL.md +132 -132
- package/.agent/skills/game-development/pc-games/SKILL.md +144 -144
- package/.agent/skills/game-development/vr-ar/SKILL.md +123 -123
- package/.agent/skills/game-development/web-games/SKILL.md +150 -150
- package/.agent/skills/gan-style-harness/SKILL.md +278 -278
- package/.agent/skills/geo-fundamentals/SKILL.md +156 -156
- package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -289
- package/.agent/skills/git-workflow/SKILL.md +715 -715
- package/.agent/skills/golang-patterns/SKILL.md +674 -674
- package/.agent/skills/golang-testing/SKILL.md +720 -720
- package/.agent/skills/google-workspace-ops/SKILL.md +95 -95
- package/.agent/skills/healthcare-cdss-patterns/SKILL.md +245 -245
- package/.agent/skills/healthcare-emr-patterns/SKILL.md +159 -159
- package/.agent/skills/healthcare-eval-harness/SKILL.md +207 -207
- package/.agent/skills/healthcare-phi-compliance/SKILL.md +145 -145
- package/.agent/skills/hexagonal-architecture/SKILL.md +276 -276
- package/.agent/skills/i18n-localization/SKILL.md +154 -154
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -241
- package/.agent/skills/intelligent-routing/SKILL.md +335 -335
- package/.agent/skills/inventory-demand-planning/SKILL.md +247 -247
- package/.agent/skills/investor-materials/SKILL.md +96 -96
- package/.agent/skills/investor-outreach/SKILL.md +91 -91
- package/.agent/skills/iterative-retrieval/SKILL.md +211 -211
- package/.agent/skills/java-coding-standards/SKILL.md +147 -147
- package/.agent/skills/jira-integration/SKILL.md +293 -293
- package/.agent/skills/jpa-patterns/SKILL.md +151 -151
- package/.agent/skills/kotlin-coroutines-flows/SKILL.md +284 -284
- package/.agent/skills/kotlin-exposed-patterns/SKILL.md +719 -719
- package/.agent/skills/kotlin-ktor-patterns/SKILL.md +689 -689
- package/.agent/skills/kotlin-patterns/SKILL.md +711 -711
- package/.agent/skills/kotlin-testing/SKILL.md +824 -824
- package/.agent/skills/laravel-patterns/SKILL.md +415 -415
- package/.agent/skills/laravel-plugin-discovery/SKILL.md +229 -229
- package/.agent/skills/laravel-security/SKILL.md +285 -285
- package/.agent/skills/laravel-tdd/SKILL.md +283 -283
- package/.agent/skills/laravel-verification/SKILL.md +179 -179
- package/.agent/skills/lead-intelligence/SKILL.md +321 -321
- package/.agent/skills/lead-intelligence/agents/enrichment-agent.md +85 -85
- package/.agent/skills/lead-intelligence/agents/mutual-mapper.md +75 -75
- package/.agent/skills/lead-intelligence/agents/outreach-drafter.md +98 -98
- package/.agent/skills/lead-intelligence/agents/signal-scorer.md +60 -60
- package/.agent/skills/lint-and-validate/SKILL.md +45 -45
- package/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -184
- package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -173
- package/.agent/skills/liquid-glass-design/SKILL.md +279 -279
- package/.agent/skills/logistics-exception-management/SKILL.md +222 -222
- package/.agent/skills/manim-video/SKILL.md +89 -89
- package/.agent/skills/manim-video/assets/network-graph-scene.py +52 -52
- package/.agent/skills/market-research/SKILL.md +75 -75
- package/.agent/skills/mcp-server-patterns/SKILL.md +67 -67
- package/.agent/skills/mobile-design/SKILL.md +394 -394
- package/.agent/skills/mobile-design/decision-trees.md +516 -516
- package/.agent/skills/mobile-design/mobile-backend.md +491 -491
- package/.agent/skills/mobile-design/mobile-color-system.md +420 -420
- package/.agent/skills/mobile-design/mobile-debugging.md +122 -122
- package/.agent/skills/mobile-design/mobile-design-thinking.md +357 -357
- package/.agent/skills/mobile-design/mobile-navigation.md +458 -458
- package/.agent/skills/mobile-design/mobile-performance.md +767 -767
- package/.agent/skills/mobile-design/mobile-testing.md +356 -356
- package/.agent/skills/mobile-design/mobile-typography.md +433 -433
- package/.agent/skills/mobile-design/platform-android.md +666 -666
- package/.agent/skills/mobile-design/platform-ios.md +561 -561
- package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -670
- package/.agent/skills/mobile-design/touch-psychology.md +537 -537
- package/.agent/skills/nanoclaw-repl/SKILL.md +33 -33
- package/.agent/skills/nestjs-patterns/SKILL.md +230 -230
- package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +351 -351
- package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +240 -240
- package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +490 -490
- package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +264 -264
- package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -581
- package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +432 -432
- package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +684 -684
- package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +150 -150
- package/.agent/skills/nextjs-react-expert/9-cache-components.md +103 -103
- package/.agent/skills/nextjs-react-expert/SKILL.md +293 -293
- package/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -222
- package/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -252
- package/.agent/skills/nextjs-turbopack/SKILL.md +44 -44
- package/.agent/skills/nodejs-best-practices/SKILL.md +333 -333
- package/.agent/skills/nutrient-document-processing/SKILL.md +167 -167
- package/.agent/skills/nuxt4-patterns/SKILL.md +100 -100
- package/.agent/skills/openclaw-persona-forge/SKILL.md +296 -296
- package/.agent/skills/openclaw-persona-forge/gacha.py +224 -224
- package/.agent/skills/openclaw-persona-forge/gacha.sh +5 -5
- package/.agent/skills/openclaw-persona-forge/references/avatar-style.md +124 -124
- package/.agent/skills/openclaw-persona-forge/references/boundary-rules.md +53 -53
- package/.agent/skills/openclaw-persona-forge/references/error-handling.md +53 -53
- package/.agent/skills/openclaw-persona-forge/references/identity-tension.md +48 -48
- package/.agent/skills/openclaw-persona-forge/references/naming-system.md +39 -39
- package/.agent/skills/openclaw-persona-forge/references/output-template.md +166 -166
- package/.agent/skills/opensource-pipeline/SKILL.md +255 -255
- package/.agent/skills/parallel-agents/SKILL.md +175 -175
- package/.agent/skills/performance-profiling/SKILL.md +143 -143
- package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -76
- package/.agent/skills/perl-patterns/SKILL.md +504 -504
- package/.agent/skills/perl-security/SKILL.md +503 -503
- package/.agent/skills/perl-testing/SKILL.md +475 -475
- package/.agent/skills/plan-writing/SKILL.md +152 -152
- package/.agent/skills/plankton-code-quality/SKILL.md +236 -236
- package/.agent/skills/postgres-patterns/SKILL.md +147 -147
- package/.agent/skills/powershell-windows/SKILL.md +167 -167
- package/.agent/skills/product-lens/SKILL.md +85 -85
- package/.agent/skills/production-scheduling/SKILL.md +238 -238
- package/.agent/skills/project-flow-ops/SKILL.md +111 -111
- package/.agent/skills/project-guidelines-example/SKILL.md +349 -349
- package/.agent/skills/prompt-optimizer/SKILL.md +397 -397
- package/.agent/skills/python-patterns/SKILL.md +750 -750
- package/.agent/skills/python-testing/SKILL.md +816 -816
- package/.agent/skills/pytorch-patterns/SKILL.md +396 -396
- package/.agent/skills/quality-nonconformance/SKILL.md +260 -260
- package/.agent/skills/ralphinho-rfc-pipeline/SKILL.md +67 -67
- package/.agent/skills/red-team-tactics/SKILL.md +199 -199
- package/.agent/skills/regex-vs-llm-structured-text/SKILL.md +220 -220
- package/.agent/skills/remotion-video-creation/SKILL.md +43 -43
- package/.agent/skills/remotion-video-creation/rules/3d.md +86 -86
- package/.agent/skills/remotion-video-creation/rules/animations.md +29 -29
- package/.agent/skills/remotion-video-creation/rules/assets/charts-bar-chart.tsx +173 -173
- package/.agent/skills/remotion-video-creation/rules/assets/text-animations-typewriter.tsx +100 -100
- package/.agent/skills/remotion-video-creation/rules/assets/text-animations-word-highlight.tsx +108 -108
- package/.agent/skills/remotion-video-creation/rules/assets.md +78 -78
- package/.agent/skills/remotion-video-creation/rules/audio.md +172 -172
- package/.agent/skills/remotion-video-creation/rules/calculate-metadata.md +104 -104
- package/.agent/skills/remotion-video-creation/rules/can-decode.md +75 -75
- package/.agent/skills/remotion-video-creation/rules/charts.md +58 -58
- package/.agent/skills/remotion-video-creation/rules/compositions.md +146 -146
- package/.agent/skills/remotion-video-creation/rules/display-captions.md +126 -126
- package/.agent/skills/remotion-video-creation/rules/extract-frames.md +229 -229
- package/.agent/skills/remotion-video-creation/rules/fonts.md +152 -152
- package/.agent/skills/remotion-video-creation/rules/get-audio-duration.md +58 -58
- package/.agent/skills/remotion-video-creation/rules/get-video-dimensions.md +68 -68
- package/.agent/skills/remotion-video-creation/rules/get-video-duration.md +58 -58
- package/.agent/skills/remotion-video-creation/rules/gifs.md +138 -138
- package/.agent/skills/remotion-video-creation/rules/images.md +130 -130
- package/.agent/skills/remotion-video-creation/rules/import-srt-captions.md +67 -67
- package/.agent/skills/remotion-video-creation/rules/lottie.md +67 -67
- package/.agent/skills/remotion-video-creation/rules/measuring-dom-nodes.md +34 -34
- package/.agent/skills/remotion-video-creation/rules/measuring-text.md +143 -143
- package/.agent/skills/remotion-video-creation/rules/sequencing.md +106 -106
- package/.agent/skills/remotion-video-creation/rules/tailwind.md +11 -11
- package/.agent/skills/remotion-video-creation/rules/text-animations.md +20 -20
- package/.agent/skills/remotion-video-creation/rules/timing.md +179 -179
- package/.agent/skills/remotion-video-creation/rules/transcribe-captions.md +19 -19
- package/.agent/skills/remotion-video-creation/rules/transitions.md +122 -122
- package/.agent/skills/remotion-video-creation/rules/trimming.md +52 -52
- package/.agent/skills/remotion-video-creation/rules/videos.md +171 -171
- package/.agent/skills/repo-scan/SKILL.md +63 -63
- package/.agent/skills/returns-reverse-logistics/SKILL.md +240 -240
- package/.agent/skills/rules-distill/SKILL.md +264 -264
- package/.agent/skills/rules-distill/scripts/scan-rules.sh +58 -58
- package/.agent/skills/rules-distill/scripts/scan-skills.sh +129 -129
- package/.agent/skills/rust-patterns/SKILL.md +499 -499
- package/.agent/skills/rust-pro/SKILL.md +175 -175
- package/.agent/skills/rust-testing/SKILL.md +500 -500
- package/.agent/skills/safety-guard/SKILL.md +75 -75
- package/.agent/skills/santa-method/SKILL.md +306 -306
- package/.agent/skills/search-first/SKILL.md +161 -161
- package/.agent/skills/security-review/SKILL.md +495 -495
- package/.agent/skills/security-review/cloud-infrastructure-security.md +361 -361
- package/.agent/skills/security-scan/SKILL.md +165 -165
- package/.agent/skills/seo-fundamentals/SKILL.md +129 -129
- package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -219
- package/.agent/skills/server-management/SKILL.md +161 -161
- package/.agent/skills/skill-comply/SKILL.md +58 -58
- package/.agent/skills/skill-comply/fixtures/compliant-trace.jsonl +5 -5
- package/.agent/skills/skill-comply/fixtures/noncompliant-trace.jsonl +3 -3
- package/.agent/skills/skill-comply/fixtures/tdd-spec.yaml +44 -44
- package/.agent/skills/skill-comply/prompts/classifier.md +24 -24
- package/.agent/skills/skill-comply/prompts/scenario-generator.md +62 -62
- package/.agent/skills/skill-comply/prompts/spec-generator.md +42 -42
- package/.agent/skills/skill-comply/pyproject.toml +15 -15
- package/.agent/skills/skill-comply/scripts/classifier.py +85 -85
- package/.agent/skills/skill-comply/scripts/grader.py +122 -122
- package/.agent/skills/skill-comply/scripts/parser.py +107 -107
- package/.agent/skills/skill-comply/scripts/report.py +170 -170
- package/.agent/skills/skill-comply/scripts/run.py +127 -127
- package/.agent/skills/skill-comply/scripts/runner.py +161 -161
- package/.agent/skills/skill-comply/scripts/scenario-generator.py +70 -70
- package/.agent/skills/skill-comply/scripts/spec-generator.py +72 -72
- package/.agent/skills/skill-comply/scripts/utils.py +13 -13
- package/.agent/skills/skill-comply/tests/test-grader.py +137 -137
- package/.agent/skills/skill-comply/tests/test-parser.py +90 -90
- package/.agent/skills/skill-stocktake/SKILL.md +193 -193
- package/.agent/skills/skill-stocktake/scripts/quick-diff.sh +87 -87
- package/.agent/skills/skill-stocktake/scripts/save-results.sh +56 -56
- package/.agent/skills/skill-stocktake/scripts/scan.sh +170 -170
- package/.agent/skills/social-graph-ranker/SKILL.md +154 -154
- package/.agent/skills/springboot-patterns/SKILL.md +314 -314
- package/.agent/skills/springboot-security/SKILL.md +272 -272
- package/.agent/skills/springboot-tdd/SKILL.md +158 -158
- package/.agent/skills/springboot-verification/SKILL.md +231 -231
- package/.agent/skills/strategic-compact/SKILL.md +131 -131
- package/.agent/skills/strategic-compact/suggest-compact.sh +54 -54
- package/.agent/skills/swift-actor-persistence/SKILL.md +143 -143
- package/.agent/skills/swift-concurrency-6-2/SKILL.md +216 -216
- package/.agent/skills/swift-protocol-di-testing/SKILL.md +190 -190
- package/.agent/skills/swiftui-patterns/SKILL.md +259 -259
- package/.agent/skills/systematic-debugging/SKILL.md +109 -109
- package/.agent/skills/tailwind-patterns/SKILL.md +269 -269
- package/.agent/skills/tdd-workflow/SKILL.md +463 -463
- package/.agent/skills/team-builder/SKILL.md +168 -168
- package/.agent/skills/testing-patterns/SKILL.md +178 -178
- package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -219
- package/.agent/skills/token-budget-advisor/SKILL.md +133 -133
- package/.agent/skills/ui-demo/SKILL.md +465 -465
- package/.agent/skills/ui-ux-pro-max/SKILL.md +292 -292
- package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -26
- package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -97
- package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -101
- package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -31
- package/.agent/skills/ui-ux-pro-max/data/products.csv +96 -96
- package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -45
- package/.agent/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/.agent/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/.agent/skills/ui-ux-pro-max/data/styles.csv +68 -68
- package/.agent/skills/ui-ux-pro-max/data/typography.csv +57 -57
- package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -101
- package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -31
- package/.agent/skills/ui-ux-pro-max/scripts/core.py +253 -253
- package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +1067 -1067
- package/.agent/skills/ui-ux-pro-max/scripts/search.py +114 -114
- package/.agent/skills/verification-loop/SKILL.md +126 -126
- package/.agent/skills/video-editing/SKILL.md +310 -310
- package/.agent/skills/videodb/SKILL.md +374 -374
- package/.agent/skills/videodb/reference/api-reference.md +550 -550
- package/.agent/skills/videodb/reference/capture-reference.md +407 -407
- package/.agent/skills/videodb/reference/capture.md +101 -101
- package/.agent/skills/videodb/reference/editor.md +443 -443
- package/.agent/skills/videodb/reference/generative.md +331 -331
- package/.agent/skills/videodb/reference/rtstream-reference.md +564 -564
- package/.agent/skills/videodb/reference/rtstream.md +65 -65
- package/.agent/skills/videodb/reference/search.md +230 -230
- package/.agent/skills/videodb/reference/streaming.md +406 -406
- package/.agent/skills/videodb/reference/use-cases.md +118 -118
- package/.agent/skills/videodb/scripts/ws-listener.py +282 -282
- package/.agent/skills/visa-doc-translate/SKILL.md +117 -117
- package/.agent/skills/visa-doc-translate/readme.md +86 -86
- package/.agent/skills/vulnerability-scanner/SKILL.md +276 -276
- package/.agent/skills/vulnerability-scanner/checklists.md +121 -121
- package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -458
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -57
- package/.agent/skills/webapp-testing/SKILL.md +187 -187
- package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -173
- package/.agent/skills/workspace-surface-audit/SKILL.md +125 -125
- package/.agent/skills/x-api/SKILL.md +230 -230
- package/.agent/tasks/lessons.md +40 -40
- package/.agent/tasks/todo.md +33 -33
- package/.agent/tasks/two-track-merge-contract.md +1 -1
- package/.agent/workflows/aside.md +164 -164
- package/.agent/workflows/brainstorm.md +113 -113
- package/.agent/workflows/build-fix.md +62 -62
- package/.agent/workflows/checkpoint.md +74 -74
- package/.agent/workflows/claw.md +23 -23
- package/.agent/workflows/clean-memory.md +34 -34
- package/.agent/workflows/code-review.md +289 -289
- package/.agent/workflows/context-budget.md +23 -23
- package/.agent/workflows/cpp-build.md +173 -173
- package/.agent/workflows/cpp-review.md +132 -132
- package/.agent/workflows/cpp-test.md +251 -251
- package/.agent/workflows/create.md +59 -59
- package/.agent/workflows/debug.md +103 -103
- package/.agent/workflows/deploy.md +176 -176
- package/.agent/workflows/devfleet.md +23 -23
- package/.agent/workflows/docs.md +23 -23
- package/.agent/workflows/e2e.md +268 -268
- package/.agent/workflows/enhance.md +63 -63
- package/.agent/workflows/eval.md +23 -23
- package/.agent/workflows/evolve.md +178 -178
- package/.agent/workflows/flutter-build.md +164 -164
- package/.agent/workflows/flutter-review.md +116 -116
- package/.agent/workflows/flutter-test.md +144 -144
- package/.agent/workflows/gan-build.md +99 -99
- package/.agent/workflows/gan-design.md +35 -35
- package/.agent/workflows/go-build.md +183 -183
- package/.agent/workflows/go-review.md +148 -148
- package/.agent/workflows/go-test.md +268 -268
- package/.agent/workflows/gradle-build.md +70 -70
- package/.agent/workflows/harness-audit.md +73 -73
- package/.agent/workflows/init-docs.md +46 -46
- package/.agent/workflows/instinct-export.md +66 -66
- package/.agent/workflows/instinct-import.md +114 -114
- package/.agent/workflows/instinct-status.md +59 -59
- package/.agent/workflows/jira.md +106 -106
- package/.agent/workflows/kotlin-build.md +174 -174
- package/.agent/workflows/kotlin-review.md +140 -140
- package/.agent/workflows/kotlin-test.md +312 -312
- package/.agent/workflows/learn-eval.md +116 -116
- package/.agent/workflows/learn.md +70 -70
- package/.agent/workflows/loop-start.md +32 -32
- package/.agent/workflows/loop-status.md +24 -24
- package/.agent/workflows/model-route.md +26 -26
- package/.agent/workflows/multi-backend.md +158 -158
- package/.agent/workflows/multi-execute.md +315 -315
- package/.agent/workflows/multi-frontend.md +158 -158
- package/.agent/workflows/multi-plan.md +268 -268
- package/.agent/workflows/multi-workflow.md +191 -191
- package/.agent/workflows/orchestrate.md +135 -135
- package/.agent/workflows/plan.md +117 -117
- package/.agent/workflows/pm2.md +272 -272
- package/.agent/workflows/preview.md +81 -81
- package/.agent/workflows/projects.md +39 -39
- package/.agent/workflows/promote.md +41 -41
- package/.agent/workflows/prompt-optimize.md +23 -23
- package/.agent/workflows/prp-commit.md +112 -112
- package/.agent/workflows/prp-implement.md +385 -385
- package/.agent/workflows/prp-plan.md +502 -502
- package/.agent/workflows/prp-pr.md +184 -184
- package/.agent/workflows/prp-prd.md +447 -447
- package/.agent/workflows/prune.md +31 -31
- package/.agent/workflows/python-review.md +297 -297
- package/.agent/workflows/quality-gate.md +29 -29
- package/.agent/workflows/refactor-clean.md +80 -80
- package/.agent/workflows/resume-session.md +156 -156
- package/.agent/workflows/rules-distill.md +20 -20
- package/.agent/workflows/rust-build.md +187 -187
- package/.agent/workflows/rust-review.md +142 -142
- package/.agent/workflows/rust-test.md +308 -308
- package/.agent/workflows/santa-loop.md +175 -175
- package/.agent/workflows/save-session.md +275 -275
- package/.agent/workflows/sessions.md +333 -333
- package/.agent/workflows/setup-pm.md +80 -80
- package/.agent/workflows/skill-create.md +174 -174
- package/.agent/workflows/skill-health.md +54 -54
- package/.agent/workflows/status.md +86 -86
- package/.agent/workflows/tdd.md +231 -231
- package/.agent/workflows/test-coverage.md +69 -69
- package/.agent/workflows/test.md +144 -144
- package/.agent/workflows/ui-ux-pro-max.md +295 -295
- package/.agent/workflows/update-codemaps.md +72 -72
- package/.agent/workflows/update-docs.md +84 -84
- package/.agent/workflows/verify.md +23 -23
- package/LICENSE +176 -176
- package/README.md +144 -144
- package/package.json +1 -1
- package/scripts/release-check.js +55 -55
- package/src/bin/cli.js +424 -354
- package/src/lib/installer.js +223 -11
|
@@ -1,674 +1,674 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: golang-patterns
|
|
3
|
-
description: Idiomatic Go patterns, best practices, and conventions for building robust, efficient, and maintainable Go applications.
|
|
4
|
-
origin: ECC
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Go Development Patterns
|
|
8
|
-
|
|
9
|
-
Idiomatic Go patterns and best practices for building robust, efficient, and maintainable applications.
|
|
10
|
-
|
|
11
|
-
## When to Activate
|
|
12
|
-
|
|
13
|
-
- Writing new Go code
|
|
14
|
-
- Reviewing Go code
|
|
15
|
-
- Refactoring existing Go code
|
|
16
|
-
- Designing Go packages/modules
|
|
17
|
-
|
|
18
|
-
## Core Principles
|
|
19
|
-
|
|
20
|
-
### 1. Simplicity and Clarity
|
|
21
|
-
|
|
22
|
-
Go favors simplicity over cleverness. Code should be obvious and easy to read.
|
|
23
|
-
|
|
24
|
-
```go
|
|
25
|
-
// Good: Clear and direct
|
|
26
|
-
func GetUser(id string) (*User, error) {
|
|
27
|
-
user, err := db.FindUser(id)
|
|
28
|
-
if err != nil {
|
|
29
|
-
return nil, fmt.Errorf("get user %s: %w", id, err)
|
|
30
|
-
}
|
|
31
|
-
return user, nil
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Bad: Overly clever
|
|
35
|
-
func GetUser(id string) (*User, error) {
|
|
36
|
-
return func() (*User, error) {
|
|
37
|
-
if u, e := db.FindUser(id); e == nil {
|
|
38
|
-
return u, nil
|
|
39
|
-
} else {
|
|
40
|
-
return nil, e
|
|
41
|
-
}
|
|
42
|
-
}()
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 2. Make the Zero Value Useful
|
|
47
|
-
|
|
48
|
-
Design types so their zero value is immediately usable without initialization.
|
|
49
|
-
|
|
50
|
-
```go
|
|
51
|
-
// Good: Zero value is useful
|
|
52
|
-
type Counter struct {
|
|
53
|
-
mu sync.Mutex
|
|
54
|
-
count int // zero value is 0, ready to use
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
func (c *Counter) Inc() {
|
|
58
|
-
c.mu.Lock()
|
|
59
|
-
c.count++
|
|
60
|
-
c.mu.Unlock()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Good: bytes.Buffer works with zero value
|
|
64
|
-
var buf bytes.Buffer
|
|
65
|
-
buf.WriteString("hello")
|
|
66
|
-
|
|
67
|
-
// Bad: Requires initialization
|
|
68
|
-
type BadCounter struct {
|
|
69
|
-
counts map[string]int // nil map will panic
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 3. Accept Interfaces, Return Structs
|
|
74
|
-
|
|
75
|
-
Functions should accept interface parameters and return concrete types.
|
|
76
|
-
|
|
77
|
-
```go
|
|
78
|
-
// Good: Accepts interface, returns concrete type
|
|
79
|
-
func ProcessData(r io.Reader) (*Result, error) {
|
|
80
|
-
data, err := io.ReadAll(r)
|
|
81
|
-
if err != nil {
|
|
82
|
-
return nil, err
|
|
83
|
-
}
|
|
84
|
-
return &Result{Data: data}, nil
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Bad: Returns interface (hides implementation details unnecessarily)
|
|
88
|
-
func ProcessData(r io.Reader) (io.Reader, error) {
|
|
89
|
-
// ...
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Error Handling Patterns
|
|
94
|
-
|
|
95
|
-
### Error Wrapping with Context
|
|
96
|
-
|
|
97
|
-
```go
|
|
98
|
-
// Good: Wrap errors with context
|
|
99
|
-
func LoadConfig(path string) (*Config, error) {
|
|
100
|
-
data, err := os.ReadFile(path)
|
|
101
|
-
if err != nil {
|
|
102
|
-
return nil, fmt.Errorf("load config %s: %w", path, err)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
var cfg Config
|
|
106
|
-
if err := json.Unmarshal(data, &cfg); err != nil {
|
|
107
|
-
return nil, fmt.Errorf("parse config %s: %w", path, err)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return &cfg, nil
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Custom Error Types
|
|
115
|
-
|
|
116
|
-
```go
|
|
117
|
-
// Define domain-specific errors
|
|
118
|
-
type ValidationError struct {
|
|
119
|
-
Field string
|
|
120
|
-
Message string
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
func (e *ValidationError) Error() string {
|
|
124
|
-
return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Sentinel errors for common cases
|
|
128
|
-
var (
|
|
129
|
-
ErrNotFound = errors.New("resource not found")
|
|
130
|
-
ErrUnauthorized = errors.New("unauthorized")
|
|
131
|
-
ErrInvalidInput = errors.New("invalid input")
|
|
132
|
-
)
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Error Checking with errors.Is and errors.As
|
|
136
|
-
|
|
137
|
-
```go
|
|
138
|
-
func HandleError(err error) {
|
|
139
|
-
// Check for specific error
|
|
140
|
-
if errors.Is(err, sql.ErrNoRows) {
|
|
141
|
-
log.Println("No records found")
|
|
142
|
-
return
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Check for error type
|
|
146
|
-
var validationErr *ValidationError
|
|
147
|
-
if errors.As(err, &validationErr) {
|
|
148
|
-
log.Printf("Validation error on field %s: %s",
|
|
149
|
-
validationErr.Field, validationErr.Message)
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Unknown error
|
|
154
|
-
log.Printf("Unexpected error: %v", err)
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Never Ignore Errors
|
|
159
|
-
|
|
160
|
-
```go
|
|
161
|
-
// Bad: Ignoring error with blank identifier
|
|
162
|
-
result, _ := doSomething()
|
|
163
|
-
|
|
164
|
-
// Good: Handle or explicitly document why it's safe to ignore
|
|
165
|
-
result, err := doSomething()
|
|
166
|
-
if err != nil {
|
|
167
|
-
return err
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Acceptable: When error truly doesn't matter (rare)
|
|
171
|
-
_ = writer.Close() // Best-effort cleanup, error logged elsewhere
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## Concurrency Patterns
|
|
175
|
-
|
|
176
|
-
### Worker Pool
|
|
177
|
-
|
|
178
|
-
```go
|
|
179
|
-
func WorkerPool(jobs <-chan Job, results chan<- Result, numWorkers int) {
|
|
180
|
-
var wg sync.WaitGroup
|
|
181
|
-
|
|
182
|
-
for i := 0; i < numWorkers; i++ {
|
|
183
|
-
wg.Add(1)
|
|
184
|
-
go func() {
|
|
185
|
-
defer wg.Done()
|
|
186
|
-
for job := range jobs {
|
|
187
|
-
results <- process(job)
|
|
188
|
-
}
|
|
189
|
-
}()
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
wg.Wait()
|
|
193
|
-
close(results)
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### Context for Cancellation and Timeouts
|
|
198
|
-
|
|
199
|
-
```go
|
|
200
|
-
func FetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
|
|
201
|
-
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
202
|
-
defer cancel()
|
|
203
|
-
|
|
204
|
-
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
|
205
|
-
if err != nil {
|
|
206
|
-
return nil, fmt.Errorf("create request: %w", err)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
resp, err := http.DefaultClient.Do(req)
|
|
210
|
-
if err != nil {
|
|
211
|
-
return nil, fmt.Errorf("fetch %s: %w", url, err)
|
|
212
|
-
}
|
|
213
|
-
defer resp.Body.Close()
|
|
214
|
-
|
|
215
|
-
return io.ReadAll(resp.Body)
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Graceful Shutdown
|
|
220
|
-
|
|
221
|
-
```go
|
|
222
|
-
func GracefulShutdown(server *http.Server) {
|
|
223
|
-
quit := make(chan os.Signal, 1)
|
|
224
|
-
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|
225
|
-
|
|
226
|
-
<-quit
|
|
227
|
-
log.Println("Shutting down server...")
|
|
228
|
-
|
|
229
|
-
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
230
|
-
defer cancel()
|
|
231
|
-
|
|
232
|
-
if err := server.Shutdown(ctx); err != nil {
|
|
233
|
-
log.Fatalf("Server forced to shutdown: %v", err)
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
log.Println("Server exited")
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### errgroup for Coordinated Goroutines
|
|
241
|
-
|
|
242
|
-
```go
|
|
243
|
-
import "golang.org/x/sync/errgroup"
|
|
244
|
-
|
|
245
|
-
func FetchAll(ctx context.Context, urls []string) ([][]byte, error) {
|
|
246
|
-
g, ctx := errgroup.WithContext(ctx)
|
|
247
|
-
results := make([][]byte, len(urls))
|
|
248
|
-
|
|
249
|
-
for i, url := range urls {
|
|
250
|
-
i, url := i, url // Capture loop variables
|
|
251
|
-
g.Go(func() error {
|
|
252
|
-
data, err := FetchWithTimeout(ctx, url)
|
|
253
|
-
if err != nil {
|
|
254
|
-
return err
|
|
255
|
-
}
|
|
256
|
-
results[i] = data
|
|
257
|
-
return nil
|
|
258
|
-
})
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if err := g.Wait(); err != nil {
|
|
262
|
-
return nil, err
|
|
263
|
-
}
|
|
264
|
-
return results, nil
|
|
265
|
-
}
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Avoiding Goroutine Leaks
|
|
269
|
-
|
|
270
|
-
```go
|
|
271
|
-
// Bad: Goroutine leak if context is cancelled
|
|
272
|
-
func leakyFetch(ctx context.Context, url string) <-chan []byte {
|
|
273
|
-
ch := make(chan []byte)
|
|
274
|
-
go func() {
|
|
275
|
-
data, _ := fetch(url)
|
|
276
|
-
ch <- data // Blocks forever if no receiver
|
|
277
|
-
}()
|
|
278
|
-
return ch
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Good: Properly handles cancellation
|
|
282
|
-
func safeFetch(ctx context.Context, url string) <-chan []byte {
|
|
283
|
-
ch := make(chan []byte, 1) // Buffered channel
|
|
284
|
-
go func() {
|
|
285
|
-
data, err := fetch(url)
|
|
286
|
-
if err != nil {
|
|
287
|
-
return
|
|
288
|
-
}
|
|
289
|
-
select {
|
|
290
|
-
case ch <- data:
|
|
291
|
-
case <-ctx.Done():
|
|
292
|
-
}
|
|
293
|
-
}()
|
|
294
|
-
return ch
|
|
295
|
-
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
## Interface Design
|
|
299
|
-
|
|
300
|
-
### Small, Focused Interfaces
|
|
301
|
-
|
|
302
|
-
```go
|
|
303
|
-
// Good: Single-method interfaces
|
|
304
|
-
type Reader interface {
|
|
305
|
-
Read(p []byte) (n int, err error)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
type Writer interface {
|
|
309
|
-
Write(p []byte) (n int, err error)
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
type Closer interface {
|
|
313
|
-
Close() error
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
// Compose interfaces as needed
|
|
317
|
-
type ReadWriteCloser interface {
|
|
318
|
-
Reader
|
|
319
|
-
Writer
|
|
320
|
-
Closer
|
|
321
|
-
}
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Define Interfaces Where They're Used
|
|
325
|
-
|
|
326
|
-
```go
|
|
327
|
-
// In the consumer package, not the provider
|
|
328
|
-
package service
|
|
329
|
-
|
|
330
|
-
// UserStore defines what this service needs
|
|
331
|
-
type UserStore interface {
|
|
332
|
-
GetUser(id string) (*User, error)
|
|
333
|
-
SaveUser(user *User) error
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
type Service struct {
|
|
337
|
-
store UserStore
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Concrete implementation can be in another package
|
|
341
|
-
// It doesn't need to know about this interface
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Optional Behavior with Type Assertions
|
|
345
|
-
|
|
346
|
-
```go
|
|
347
|
-
type Flusher interface {
|
|
348
|
-
Flush() error
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
func WriteAndFlush(w io.Writer, data []byte) error {
|
|
352
|
-
if _, err := w.Write(data); err != nil {
|
|
353
|
-
return err
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Flush if supported
|
|
357
|
-
if f, ok := w.(Flusher); ok {
|
|
358
|
-
return f.Flush()
|
|
359
|
-
}
|
|
360
|
-
return nil
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
## Package Organization
|
|
365
|
-
|
|
366
|
-
### Standard Project Layout
|
|
367
|
-
|
|
368
|
-
```text
|
|
369
|
-
myproject/
|
|
370
|
-
├── cmd/
|
|
371
|
-
│ └── myapp/
|
|
372
|
-
│ └── main.go # Entry point
|
|
373
|
-
├── internal/
|
|
374
|
-
│ ├── handler/ # HTTP handlers
|
|
375
|
-
│ ├── service/ # Business logic
|
|
376
|
-
│ ├── repository/ # Data access
|
|
377
|
-
│ └── config/ # Configuration
|
|
378
|
-
├── pkg/
|
|
379
|
-
│ └── client/ # Public API client
|
|
380
|
-
├── api/
|
|
381
|
-
│ └── v1/ # API definitions (proto, OpenAPI)
|
|
382
|
-
├── testdata/ # Test fixtures
|
|
383
|
-
├── go.mod
|
|
384
|
-
├── go.sum
|
|
385
|
-
└── Makefile
|
|
386
|
-
```
|
|
387
|
-
|
|
388
|
-
### Package Naming
|
|
389
|
-
|
|
390
|
-
```go
|
|
391
|
-
// Good: Short, lowercase, no underscores
|
|
392
|
-
package http
|
|
393
|
-
package json
|
|
394
|
-
package user
|
|
395
|
-
|
|
396
|
-
// Bad: Verbose, mixed case, or redundant
|
|
397
|
-
package httpHandler
|
|
398
|
-
package json_parser
|
|
399
|
-
package userService // Redundant 'Service' suffix
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### Avoid Package-Level State
|
|
403
|
-
|
|
404
|
-
```go
|
|
405
|
-
// Bad: Global mutable state
|
|
406
|
-
var db *sql.DB
|
|
407
|
-
|
|
408
|
-
func init() {
|
|
409
|
-
db, _ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// Good: Dependency injection
|
|
413
|
-
type Server struct {
|
|
414
|
-
db *sql.DB
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
func NewServer(db *sql.DB) *Server {
|
|
418
|
-
return &Server{db: db}
|
|
419
|
-
}
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
## Struct Design
|
|
423
|
-
|
|
424
|
-
### Functional Options Pattern
|
|
425
|
-
|
|
426
|
-
```go
|
|
427
|
-
type Server struct {
|
|
428
|
-
addr string
|
|
429
|
-
timeout time.Duration
|
|
430
|
-
logger *log.Logger
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
type Option func(*Server)
|
|
434
|
-
|
|
435
|
-
func WithTimeout(d time.Duration) Option {
|
|
436
|
-
return func(s *Server) {
|
|
437
|
-
s.timeout = d
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
func WithLogger(l *log.Logger) Option {
|
|
442
|
-
return func(s *Server) {
|
|
443
|
-
s.logger = l
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
func NewServer(addr string, opts ...Option) *Server {
|
|
448
|
-
s := &Server{
|
|
449
|
-
addr: addr,
|
|
450
|
-
timeout: 30 * time.Second, // default
|
|
451
|
-
logger: log.Default(), // default
|
|
452
|
-
}
|
|
453
|
-
for _, opt := range opts {
|
|
454
|
-
opt(s)
|
|
455
|
-
}
|
|
456
|
-
return s
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Usage
|
|
460
|
-
server := NewServer(":8080",
|
|
461
|
-
WithTimeout(60*time.Second),
|
|
462
|
-
WithLogger(customLogger),
|
|
463
|
-
)
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
### Embedding for Composition
|
|
467
|
-
|
|
468
|
-
```go
|
|
469
|
-
type Logger struct {
|
|
470
|
-
prefix string
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
func (l *Logger) Log(msg string) {
|
|
474
|
-
fmt.Printf("[%s] %s\n", l.prefix, msg)
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
type Server struct {
|
|
478
|
-
*Logger // Embedding - Server gets Log method
|
|
479
|
-
addr string
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
func NewServer(addr string) *Server {
|
|
483
|
-
return &Server{
|
|
484
|
-
Logger: &Logger{prefix: "SERVER"},
|
|
485
|
-
addr: addr,
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
// Usage
|
|
490
|
-
s := NewServer(":8080")
|
|
491
|
-
s.Log("Starting...") // Calls embedded Logger.Log
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
## Memory and Performance
|
|
495
|
-
|
|
496
|
-
### Preallocate Slices When Size is Known
|
|
497
|
-
|
|
498
|
-
```go
|
|
499
|
-
// Bad: Grows slice multiple times
|
|
500
|
-
func processItems(items []Item) []Result {
|
|
501
|
-
var results []Result
|
|
502
|
-
for _, item := range items {
|
|
503
|
-
results = append(results, process(item))
|
|
504
|
-
}
|
|
505
|
-
return results
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// Good: Single allocation
|
|
509
|
-
func processItems(items []Item) []Result {
|
|
510
|
-
results := make([]Result, 0, len(items))
|
|
511
|
-
for _, item := range items {
|
|
512
|
-
results = append(results, process(item))
|
|
513
|
-
}
|
|
514
|
-
return results
|
|
515
|
-
}
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
### Use sync.Pool for Frequent Allocations
|
|
519
|
-
|
|
520
|
-
```go
|
|
521
|
-
var bufferPool = sync.Pool{
|
|
522
|
-
New: func() interface{} {
|
|
523
|
-
return new(bytes.Buffer)
|
|
524
|
-
},
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
func ProcessRequest(data []byte) []byte {
|
|
528
|
-
buf := bufferPool.Get().(*bytes.Buffer)
|
|
529
|
-
defer func() {
|
|
530
|
-
buf.Reset()
|
|
531
|
-
bufferPool.Put(buf)
|
|
532
|
-
}()
|
|
533
|
-
|
|
534
|
-
buf.Write(data)
|
|
535
|
-
// Process...
|
|
536
|
-
return buf.Bytes()
|
|
537
|
-
}
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
### Avoid String Concatenation in Loops
|
|
541
|
-
|
|
542
|
-
```go
|
|
543
|
-
// Bad: Creates many string allocations
|
|
544
|
-
func join(parts []string) string {
|
|
545
|
-
var result string
|
|
546
|
-
for _, p := range parts {
|
|
547
|
-
result += p + ","
|
|
548
|
-
}
|
|
549
|
-
return result
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// Good: Single allocation with strings.Builder
|
|
553
|
-
func join(parts []string) string {
|
|
554
|
-
var sb strings.Builder
|
|
555
|
-
for i, p := range parts {
|
|
556
|
-
if i > 0 {
|
|
557
|
-
sb.WriteString(",")
|
|
558
|
-
}
|
|
559
|
-
sb.WriteString(p)
|
|
560
|
-
}
|
|
561
|
-
return sb.String()
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
// Best: Use standard library
|
|
565
|
-
func join(parts []string) string {
|
|
566
|
-
return strings.Join(parts, ",")
|
|
567
|
-
}
|
|
568
|
-
```
|
|
569
|
-
|
|
570
|
-
## Go Tooling Integration
|
|
571
|
-
|
|
572
|
-
### Essential Commands
|
|
573
|
-
|
|
574
|
-
```bash
|
|
575
|
-
# Build and run
|
|
576
|
-
go build ./...
|
|
577
|
-
go run ./cmd/myapp
|
|
578
|
-
|
|
579
|
-
# Testing
|
|
580
|
-
go test ./...
|
|
581
|
-
go test -race ./...
|
|
582
|
-
go test -cover ./...
|
|
583
|
-
|
|
584
|
-
# Static analysis
|
|
585
|
-
go vet ./...
|
|
586
|
-
staticcheck ./...
|
|
587
|
-
golangci-lint run
|
|
588
|
-
|
|
589
|
-
# Module management
|
|
590
|
-
go mod tidy
|
|
591
|
-
go mod verify
|
|
592
|
-
|
|
593
|
-
# Formatting
|
|
594
|
-
gofmt -w .
|
|
595
|
-
goimports -w .
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
### Recommended Linter Configuration (.golangci.yml)
|
|
599
|
-
|
|
600
|
-
```yaml
|
|
601
|
-
linters:
|
|
602
|
-
enable:
|
|
603
|
-
- errcheck
|
|
604
|
-
- gosimple
|
|
605
|
-
- govet
|
|
606
|
-
- ineffassign
|
|
607
|
-
- staticcheck
|
|
608
|
-
- unused
|
|
609
|
-
- gofmt
|
|
610
|
-
- goimports
|
|
611
|
-
- misspell
|
|
612
|
-
- unconvert
|
|
613
|
-
- unparam
|
|
614
|
-
|
|
615
|
-
linters-settings:
|
|
616
|
-
errcheck:
|
|
617
|
-
check-type-assertions: true
|
|
618
|
-
govet:
|
|
619
|
-
check-shadowing: true
|
|
620
|
-
|
|
621
|
-
issues:
|
|
622
|
-
exclude-use-default: false
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
## Quick Reference: Go Idioms
|
|
626
|
-
|
|
627
|
-
| Idiom | Description |
|
|
628
|
-
|-------|-------------|
|
|
629
|
-
| Accept interfaces, return structs | Functions accept interface params, return concrete types |
|
|
630
|
-
| Errors are values | Treat errors as first-class values, not exceptions |
|
|
631
|
-
| Don't communicate by sharing memory | Use channels for coordination between goroutines |
|
|
632
|
-
| Make the zero value useful | Types should work without explicit initialization |
|
|
633
|
-
| A little copying is better than a little dependency | Avoid unnecessary external dependencies |
|
|
634
|
-
| Clear is better than clever | Prioritize readability over cleverness |
|
|
635
|
-
| gofmt is no one's favorite but everyone's friend | Always format with gofmt/goimports |
|
|
636
|
-
| Return early | Handle errors first, keep happy path unindented |
|
|
637
|
-
|
|
638
|
-
## Anti-Patterns to Avoid
|
|
639
|
-
|
|
640
|
-
```go
|
|
641
|
-
// Bad: Naked returns in long functions
|
|
642
|
-
func process() (result int, err error) {
|
|
643
|
-
// ... 50 lines ...
|
|
644
|
-
return // What is being returned?
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
// Bad: Using panic for control flow
|
|
648
|
-
func GetUser(id string) *User {
|
|
649
|
-
user, err := db.Find(id)
|
|
650
|
-
if err != nil {
|
|
651
|
-
panic(err) // Don't do this
|
|
652
|
-
}
|
|
653
|
-
return user
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Bad: Passing context in struct
|
|
657
|
-
type Request struct {
|
|
658
|
-
ctx context.Context // Context should be first param
|
|
659
|
-
ID string
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// Good: Context as first parameter
|
|
663
|
-
func ProcessRequest(ctx context.Context, id string) error {
|
|
664
|
-
// ...
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Bad: Mixing value and pointer receivers
|
|
668
|
-
type Counter struct{ n int }
|
|
669
|
-
func (c Counter) Value() int { return c.n } // Value receiver
|
|
670
|
-
func (c *Counter) Increment() { c.n++ } // Pointer receiver
|
|
671
|
-
// Pick one style and be consistent
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
**Remember**: Go code should be boring in the best way - predictable, consistent, and easy to understand. When in doubt, keep it simple.
|
|
1
|
+
---
|
|
2
|
+
name: golang-patterns
|
|
3
|
+
description: Idiomatic Go patterns, best practices, and conventions for building robust, efficient, and maintainable Go applications.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Go Development Patterns
|
|
8
|
+
|
|
9
|
+
Idiomatic Go patterns and best practices for building robust, efficient, and maintainable applications.
|
|
10
|
+
|
|
11
|
+
## When to Activate
|
|
12
|
+
|
|
13
|
+
- Writing new Go code
|
|
14
|
+
- Reviewing Go code
|
|
15
|
+
- Refactoring existing Go code
|
|
16
|
+
- Designing Go packages/modules
|
|
17
|
+
|
|
18
|
+
## Core Principles
|
|
19
|
+
|
|
20
|
+
### 1. Simplicity and Clarity
|
|
21
|
+
|
|
22
|
+
Go favors simplicity over cleverness. Code should be obvious and easy to read.
|
|
23
|
+
|
|
24
|
+
```go
|
|
25
|
+
// Good: Clear and direct
|
|
26
|
+
func GetUser(id string) (*User, error) {
|
|
27
|
+
user, err := db.FindUser(id)
|
|
28
|
+
if err != nil {
|
|
29
|
+
return nil, fmt.Errorf("get user %s: %w", id, err)
|
|
30
|
+
}
|
|
31
|
+
return user, nil
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Bad: Overly clever
|
|
35
|
+
func GetUser(id string) (*User, error) {
|
|
36
|
+
return func() (*User, error) {
|
|
37
|
+
if u, e := db.FindUser(id); e == nil {
|
|
38
|
+
return u, nil
|
|
39
|
+
} else {
|
|
40
|
+
return nil, e
|
|
41
|
+
}
|
|
42
|
+
}()
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Make the Zero Value Useful
|
|
47
|
+
|
|
48
|
+
Design types so their zero value is immediately usable without initialization.
|
|
49
|
+
|
|
50
|
+
```go
|
|
51
|
+
// Good: Zero value is useful
|
|
52
|
+
type Counter struct {
|
|
53
|
+
mu sync.Mutex
|
|
54
|
+
count int // zero value is 0, ready to use
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func (c *Counter) Inc() {
|
|
58
|
+
c.mu.Lock()
|
|
59
|
+
c.count++
|
|
60
|
+
c.mu.Unlock()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Good: bytes.Buffer works with zero value
|
|
64
|
+
var buf bytes.Buffer
|
|
65
|
+
buf.WriteString("hello")
|
|
66
|
+
|
|
67
|
+
// Bad: Requires initialization
|
|
68
|
+
type BadCounter struct {
|
|
69
|
+
counts map[string]int // nil map will panic
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3. Accept Interfaces, Return Structs
|
|
74
|
+
|
|
75
|
+
Functions should accept interface parameters and return concrete types.
|
|
76
|
+
|
|
77
|
+
```go
|
|
78
|
+
// Good: Accepts interface, returns concrete type
|
|
79
|
+
func ProcessData(r io.Reader) (*Result, error) {
|
|
80
|
+
data, err := io.ReadAll(r)
|
|
81
|
+
if err != nil {
|
|
82
|
+
return nil, err
|
|
83
|
+
}
|
|
84
|
+
return &Result{Data: data}, nil
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Bad: Returns interface (hides implementation details unnecessarily)
|
|
88
|
+
func ProcessData(r io.Reader) (io.Reader, error) {
|
|
89
|
+
// ...
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Error Handling Patterns
|
|
94
|
+
|
|
95
|
+
### Error Wrapping with Context
|
|
96
|
+
|
|
97
|
+
```go
|
|
98
|
+
// Good: Wrap errors with context
|
|
99
|
+
func LoadConfig(path string) (*Config, error) {
|
|
100
|
+
data, err := os.ReadFile(path)
|
|
101
|
+
if err != nil {
|
|
102
|
+
return nil, fmt.Errorf("load config %s: %w", path, err)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
var cfg Config
|
|
106
|
+
if err := json.Unmarshal(data, &cfg); err != nil {
|
|
107
|
+
return nil, fmt.Errorf("parse config %s: %w", path, err)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return &cfg, nil
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Custom Error Types
|
|
115
|
+
|
|
116
|
+
```go
|
|
117
|
+
// Define domain-specific errors
|
|
118
|
+
type ValidationError struct {
|
|
119
|
+
Field string
|
|
120
|
+
Message string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
func (e *ValidationError) Error() string {
|
|
124
|
+
return fmt.Sprintf("validation failed on %s: %s", e.Field, e.Message)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Sentinel errors for common cases
|
|
128
|
+
var (
|
|
129
|
+
ErrNotFound = errors.New("resource not found")
|
|
130
|
+
ErrUnauthorized = errors.New("unauthorized")
|
|
131
|
+
ErrInvalidInput = errors.New("invalid input")
|
|
132
|
+
)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Error Checking with errors.Is and errors.As
|
|
136
|
+
|
|
137
|
+
```go
|
|
138
|
+
func HandleError(err error) {
|
|
139
|
+
// Check for specific error
|
|
140
|
+
if errors.Is(err, sql.ErrNoRows) {
|
|
141
|
+
log.Println("No records found")
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Check for error type
|
|
146
|
+
var validationErr *ValidationError
|
|
147
|
+
if errors.As(err, &validationErr) {
|
|
148
|
+
log.Printf("Validation error on field %s: %s",
|
|
149
|
+
validationErr.Field, validationErr.Message)
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Unknown error
|
|
154
|
+
log.Printf("Unexpected error: %v", err)
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Never Ignore Errors
|
|
159
|
+
|
|
160
|
+
```go
|
|
161
|
+
// Bad: Ignoring error with blank identifier
|
|
162
|
+
result, _ := doSomething()
|
|
163
|
+
|
|
164
|
+
// Good: Handle or explicitly document why it's safe to ignore
|
|
165
|
+
result, err := doSomething()
|
|
166
|
+
if err != nil {
|
|
167
|
+
return err
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Acceptable: When error truly doesn't matter (rare)
|
|
171
|
+
_ = writer.Close() // Best-effort cleanup, error logged elsewhere
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Concurrency Patterns
|
|
175
|
+
|
|
176
|
+
### Worker Pool
|
|
177
|
+
|
|
178
|
+
```go
|
|
179
|
+
func WorkerPool(jobs <-chan Job, results chan<- Result, numWorkers int) {
|
|
180
|
+
var wg sync.WaitGroup
|
|
181
|
+
|
|
182
|
+
for i := 0; i < numWorkers; i++ {
|
|
183
|
+
wg.Add(1)
|
|
184
|
+
go func() {
|
|
185
|
+
defer wg.Done()
|
|
186
|
+
for job := range jobs {
|
|
187
|
+
results <- process(job)
|
|
188
|
+
}
|
|
189
|
+
}()
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
wg.Wait()
|
|
193
|
+
close(results)
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Context for Cancellation and Timeouts
|
|
198
|
+
|
|
199
|
+
```go
|
|
200
|
+
func FetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
|
|
201
|
+
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
202
|
+
defer cancel()
|
|
203
|
+
|
|
204
|
+
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
|
205
|
+
if err != nil {
|
|
206
|
+
return nil, fmt.Errorf("create request: %w", err)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
resp, err := http.DefaultClient.Do(req)
|
|
210
|
+
if err != nil {
|
|
211
|
+
return nil, fmt.Errorf("fetch %s: %w", url, err)
|
|
212
|
+
}
|
|
213
|
+
defer resp.Body.Close()
|
|
214
|
+
|
|
215
|
+
return io.ReadAll(resp.Body)
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Graceful Shutdown
|
|
220
|
+
|
|
221
|
+
```go
|
|
222
|
+
func GracefulShutdown(server *http.Server) {
|
|
223
|
+
quit := make(chan os.Signal, 1)
|
|
224
|
+
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|
225
|
+
|
|
226
|
+
<-quit
|
|
227
|
+
log.Println("Shutting down server...")
|
|
228
|
+
|
|
229
|
+
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
230
|
+
defer cancel()
|
|
231
|
+
|
|
232
|
+
if err := server.Shutdown(ctx); err != nil {
|
|
233
|
+
log.Fatalf("Server forced to shutdown: %v", err)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
log.Println("Server exited")
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### errgroup for Coordinated Goroutines
|
|
241
|
+
|
|
242
|
+
```go
|
|
243
|
+
import "golang.org/x/sync/errgroup"
|
|
244
|
+
|
|
245
|
+
func FetchAll(ctx context.Context, urls []string) ([][]byte, error) {
|
|
246
|
+
g, ctx := errgroup.WithContext(ctx)
|
|
247
|
+
results := make([][]byte, len(urls))
|
|
248
|
+
|
|
249
|
+
for i, url := range urls {
|
|
250
|
+
i, url := i, url // Capture loop variables
|
|
251
|
+
g.Go(func() error {
|
|
252
|
+
data, err := FetchWithTimeout(ctx, url)
|
|
253
|
+
if err != nil {
|
|
254
|
+
return err
|
|
255
|
+
}
|
|
256
|
+
results[i] = data
|
|
257
|
+
return nil
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if err := g.Wait(); err != nil {
|
|
262
|
+
return nil, err
|
|
263
|
+
}
|
|
264
|
+
return results, nil
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Avoiding Goroutine Leaks
|
|
269
|
+
|
|
270
|
+
```go
|
|
271
|
+
// Bad: Goroutine leak if context is cancelled
|
|
272
|
+
func leakyFetch(ctx context.Context, url string) <-chan []byte {
|
|
273
|
+
ch := make(chan []byte)
|
|
274
|
+
go func() {
|
|
275
|
+
data, _ := fetch(url)
|
|
276
|
+
ch <- data // Blocks forever if no receiver
|
|
277
|
+
}()
|
|
278
|
+
return ch
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Good: Properly handles cancellation
|
|
282
|
+
func safeFetch(ctx context.Context, url string) <-chan []byte {
|
|
283
|
+
ch := make(chan []byte, 1) // Buffered channel
|
|
284
|
+
go func() {
|
|
285
|
+
data, err := fetch(url)
|
|
286
|
+
if err != nil {
|
|
287
|
+
return
|
|
288
|
+
}
|
|
289
|
+
select {
|
|
290
|
+
case ch <- data:
|
|
291
|
+
case <-ctx.Done():
|
|
292
|
+
}
|
|
293
|
+
}()
|
|
294
|
+
return ch
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Interface Design
|
|
299
|
+
|
|
300
|
+
### Small, Focused Interfaces
|
|
301
|
+
|
|
302
|
+
```go
|
|
303
|
+
// Good: Single-method interfaces
|
|
304
|
+
type Reader interface {
|
|
305
|
+
Read(p []byte) (n int, err error)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
type Writer interface {
|
|
309
|
+
Write(p []byte) (n int, err error)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
type Closer interface {
|
|
313
|
+
Close() error
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Compose interfaces as needed
|
|
317
|
+
type ReadWriteCloser interface {
|
|
318
|
+
Reader
|
|
319
|
+
Writer
|
|
320
|
+
Closer
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Define Interfaces Where They're Used
|
|
325
|
+
|
|
326
|
+
```go
|
|
327
|
+
// In the consumer package, not the provider
|
|
328
|
+
package service
|
|
329
|
+
|
|
330
|
+
// UserStore defines what this service needs
|
|
331
|
+
type UserStore interface {
|
|
332
|
+
GetUser(id string) (*User, error)
|
|
333
|
+
SaveUser(user *User) error
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
type Service struct {
|
|
337
|
+
store UserStore
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Concrete implementation can be in another package
|
|
341
|
+
// It doesn't need to know about this interface
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Optional Behavior with Type Assertions
|
|
345
|
+
|
|
346
|
+
```go
|
|
347
|
+
type Flusher interface {
|
|
348
|
+
Flush() error
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
func WriteAndFlush(w io.Writer, data []byte) error {
|
|
352
|
+
if _, err := w.Write(data); err != nil {
|
|
353
|
+
return err
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Flush if supported
|
|
357
|
+
if f, ok := w.(Flusher); ok {
|
|
358
|
+
return f.Flush()
|
|
359
|
+
}
|
|
360
|
+
return nil
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Package Organization
|
|
365
|
+
|
|
366
|
+
### Standard Project Layout
|
|
367
|
+
|
|
368
|
+
```text
|
|
369
|
+
myproject/
|
|
370
|
+
├── cmd/
|
|
371
|
+
│ └── myapp/
|
|
372
|
+
│ └── main.go # Entry point
|
|
373
|
+
├── internal/
|
|
374
|
+
│ ├── handler/ # HTTP handlers
|
|
375
|
+
│ ├── service/ # Business logic
|
|
376
|
+
│ ├── repository/ # Data access
|
|
377
|
+
│ └── config/ # Configuration
|
|
378
|
+
├── pkg/
|
|
379
|
+
│ └── client/ # Public API client
|
|
380
|
+
├── api/
|
|
381
|
+
│ └── v1/ # API definitions (proto, OpenAPI)
|
|
382
|
+
├── testdata/ # Test fixtures
|
|
383
|
+
├── go.mod
|
|
384
|
+
├── go.sum
|
|
385
|
+
└── Makefile
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Package Naming
|
|
389
|
+
|
|
390
|
+
```go
|
|
391
|
+
// Good: Short, lowercase, no underscores
|
|
392
|
+
package http
|
|
393
|
+
package json
|
|
394
|
+
package user
|
|
395
|
+
|
|
396
|
+
// Bad: Verbose, mixed case, or redundant
|
|
397
|
+
package httpHandler
|
|
398
|
+
package json_parser
|
|
399
|
+
package userService // Redundant 'Service' suffix
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Avoid Package-Level State
|
|
403
|
+
|
|
404
|
+
```go
|
|
405
|
+
// Bad: Global mutable state
|
|
406
|
+
var db *sql.DB
|
|
407
|
+
|
|
408
|
+
func init() {
|
|
409
|
+
db, _ = sql.Open("postgres", os.Getenv("DATABASE_URL"))
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Good: Dependency injection
|
|
413
|
+
type Server struct {
|
|
414
|
+
db *sql.DB
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
func NewServer(db *sql.DB) *Server {
|
|
418
|
+
return &Server{db: db}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## Struct Design
|
|
423
|
+
|
|
424
|
+
### Functional Options Pattern
|
|
425
|
+
|
|
426
|
+
```go
|
|
427
|
+
type Server struct {
|
|
428
|
+
addr string
|
|
429
|
+
timeout time.Duration
|
|
430
|
+
logger *log.Logger
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
type Option func(*Server)
|
|
434
|
+
|
|
435
|
+
func WithTimeout(d time.Duration) Option {
|
|
436
|
+
return func(s *Server) {
|
|
437
|
+
s.timeout = d
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
func WithLogger(l *log.Logger) Option {
|
|
442
|
+
return func(s *Server) {
|
|
443
|
+
s.logger = l
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
func NewServer(addr string, opts ...Option) *Server {
|
|
448
|
+
s := &Server{
|
|
449
|
+
addr: addr,
|
|
450
|
+
timeout: 30 * time.Second, // default
|
|
451
|
+
logger: log.Default(), // default
|
|
452
|
+
}
|
|
453
|
+
for _, opt := range opts {
|
|
454
|
+
opt(s)
|
|
455
|
+
}
|
|
456
|
+
return s
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Usage
|
|
460
|
+
server := NewServer(":8080",
|
|
461
|
+
WithTimeout(60*time.Second),
|
|
462
|
+
WithLogger(customLogger),
|
|
463
|
+
)
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### Embedding for Composition
|
|
467
|
+
|
|
468
|
+
```go
|
|
469
|
+
type Logger struct {
|
|
470
|
+
prefix string
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
func (l *Logger) Log(msg string) {
|
|
474
|
+
fmt.Printf("[%s] %s\n", l.prefix, msg)
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
type Server struct {
|
|
478
|
+
*Logger // Embedding - Server gets Log method
|
|
479
|
+
addr string
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
func NewServer(addr string) *Server {
|
|
483
|
+
return &Server{
|
|
484
|
+
Logger: &Logger{prefix: "SERVER"},
|
|
485
|
+
addr: addr,
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Usage
|
|
490
|
+
s := NewServer(":8080")
|
|
491
|
+
s.Log("Starting...") // Calls embedded Logger.Log
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
## Memory and Performance
|
|
495
|
+
|
|
496
|
+
### Preallocate Slices When Size is Known
|
|
497
|
+
|
|
498
|
+
```go
|
|
499
|
+
// Bad: Grows slice multiple times
|
|
500
|
+
func processItems(items []Item) []Result {
|
|
501
|
+
var results []Result
|
|
502
|
+
for _, item := range items {
|
|
503
|
+
results = append(results, process(item))
|
|
504
|
+
}
|
|
505
|
+
return results
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// Good: Single allocation
|
|
509
|
+
func processItems(items []Item) []Result {
|
|
510
|
+
results := make([]Result, 0, len(items))
|
|
511
|
+
for _, item := range items {
|
|
512
|
+
results = append(results, process(item))
|
|
513
|
+
}
|
|
514
|
+
return results
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Use sync.Pool for Frequent Allocations
|
|
519
|
+
|
|
520
|
+
```go
|
|
521
|
+
var bufferPool = sync.Pool{
|
|
522
|
+
New: func() interface{} {
|
|
523
|
+
return new(bytes.Buffer)
|
|
524
|
+
},
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
func ProcessRequest(data []byte) []byte {
|
|
528
|
+
buf := bufferPool.Get().(*bytes.Buffer)
|
|
529
|
+
defer func() {
|
|
530
|
+
buf.Reset()
|
|
531
|
+
bufferPool.Put(buf)
|
|
532
|
+
}()
|
|
533
|
+
|
|
534
|
+
buf.Write(data)
|
|
535
|
+
// Process...
|
|
536
|
+
return buf.Bytes()
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
### Avoid String Concatenation in Loops
|
|
541
|
+
|
|
542
|
+
```go
|
|
543
|
+
// Bad: Creates many string allocations
|
|
544
|
+
func join(parts []string) string {
|
|
545
|
+
var result string
|
|
546
|
+
for _, p := range parts {
|
|
547
|
+
result += p + ","
|
|
548
|
+
}
|
|
549
|
+
return result
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Good: Single allocation with strings.Builder
|
|
553
|
+
func join(parts []string) string {
|
|
554
|
+
var sb strings.Builder
|
|
555
|
+
for i, p := range parts {
|
|
556
|
+
if i > 0 {
|
|
557
|
+
sb.WriteString(",")
|
|
558
|
+
}
|
|
559
|
+
sb.WriteString(p)
|
|
560
|
+
}
|
|
561
|
+
return sb.String()
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Best: Use standard library
|
|
565
|
+
func join(parts []string) string {
|
|
566
|
+
return strings.Join(parts, ",")
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
## Go Tooling Integration
|
|
571
|
+
|
|
572
|
+
### Essential Commands
|
|
573
|
+
|
|
574
|
+
```bash
|
|
575
|
+
# Build and run
|
|
576
|
+
go build ./...
|
|
577
|
+
go run ./cmd/myapp
|
|
578
|
+
|
|
579
|
+
# Testing
|
|
580
|
+
go test ./...
|
|
581
|
+
go test -race ./...
|
|
582
|
+
go test -cover ./...
|
|
583
|
+
|
|
584
|
+
# Static analysis
|
|
585
|
+
go vet ./...
|
|
586
|
+
staticcheck ./...
|
|
587
|
+
golangci-lint run
|
|
588
|
+
|
|
589
|
+
# Module management
|
|
590
|
+
go mod tidy
|
|
591
|
+
go mod verify
|
|
592
|
+
|
|
593
|
+
# Formatting
|
|
594
|
+
gofmt -w .
|
|
595
|
+
goimports -w .
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### Recommended Linter Configuration (.golangci.yml)
|
|
599
|
+
|
|
600
|
+
```yaml
|
|
601
|
+
linters:
|
|
602
|
+
enable:
|
|
603
|
+
- errcheck
|
|
604
|
+
- gosimple
|
|
605
|
+
- govet
|
|
606
|
+
- ineffassign
|
|
607
|
+
- staticcheck
|
|
608
|
+
- unused
|
|
609
|
+
- gofmt
|
|
610
|
+
- goimports
|
|
611
|
+
- misspell
|
|
612
|
+
- unconvert
|
|
613
|
+
- unparam
|
|
614
|
+
|
|
615
|
+
linters-settings:
|
|
616
|
+
errcheck:
|
|
617
|
+
check-type-assertions: true
|
|
618
|
+
govet:
|
|
619
|
+
check-shadowing: true
|
|
620
|
+
|
|
621
|
+
issues:
|
|
622
|
+
exclude-use-default: false
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
## Quick Reference: Go Idioms
|
|
626
|
+
|
|
627
|
+
| Idiom | Description |
|
|
628
|
+
|-------|-------------|
|
|
629
|
+
| Accept interfaces, return structs | Functions accept interface params, return concrete types |
|
|
630
|
+
| Errors are values | Treat errors as first-class values, not exceptions |
|
|
631
|
+
| Don't communicate by sharing memory | Use channels for coordination between goroutines |
|
|
632
|
+
| Make the zero value useful | Types should work without explicit initialization |
|
|
633
|
+
| A little copying is better than a little dependency | Avoid unnecessary external dependencies |
|
|
634
|
+
| Clear is better than clever | Prioritize readability over cleverness |
|
|
635
|
+
| gofmt is no one's favorite but everyone's friend | Always format with gofmt/goimports |
|
|
636
|
+
| Return early | Handle errors first, keep happy path unindented |
|
|
637
|
+
|
|
638
|
+
## Anti-Patterns to Avoid
|
|
639
|
+
|
|
640
|
+
```go
|
|
641
|
+
// Bad: Naked returns in long functions
|
|
642
|
+
func process() (result int, err error) {
|
|
643
|
+
// ... 50 lines ...
|
|
644
|
+
return // What is being returned?
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Bad: Using panic for control flow
|
|
648
|
+
func GetUser(id string) *User {
|
|
649
|
+
user, err := db.Find(id)
|
|
650
|
+
if err != nil {
|
|
651
|
+
panic(err) // Don't do this
|
|
652
|
+
}
|
|
653
|
+
return user
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Bad: Passing context in struct
|
|
657
|
+
type Request struct {
|
|
658
|
+
ctx context.Context // Context should be first param
|
|
659
|
+
ID string
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Good: Context as first parameter
|
|
663
|
+
func ProcessRequest(ctx context.Context, id string) error {
|
|
664
|
+
// ...
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Bad: Mixing value and pointer receivers
|
|
668
|
+
type Counter struct{ n int }
|
|
669
|
+
func (c Counter) Value() int { return c.n } // Value receiver
|
|
670
|
+
func (c *Counter) Increment() { c.n++ } // Pointer receiver
|
|
671
|
+
// Pick one style and be consistent
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Remember**: Go code should be boring in the best way - predictable, consistent, and easy to understand. When in doubt, keep it simple.
|