claude-code-pilot 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/install.js +267 -250
- package/manifest.json +5 -18
- package/package.json +5 -7
- package/src/agents/build-error-resolver.md +114 -0
- package/src/agents/ccp-advisor-researcher.md +104 -0
- package/src/agents/ccp-assumptions-analyzer.md +105 -0
- package/{gsd/agents/gsd-codebase-mapper.md → src/agents/ccp-codebase-mapper.md} +7 -7
- package/{gsd/agents/gsd-debugger.md → src/agents/ccp-debugger.md} +125 -8
- package/{gsd/agents/gsd-executor.md → src/agents/ccp-executor.md} +31 -20
- package/{gsd/agents/gsd-integration-checker.md → src/agents/ccp-integration-checker.md} +2 -2
- package/{gsd/agents/gsd-nyquist-auditor.md → src/agents/ccp-nyquist-auditor.md} +3 -3
- package/{gsd/agents/gsd-phase-researcher.md → src/agents/ccp-phase-researcher.md} +127 -13
- package/{gsd/agents/gsd-plan-checker.md → src/agents/ccp-plan-checker.md} +57 -21
- package/{gsd/agents/gsd-planner.md → src/agents/ccp-planner.md} +61 -23
- package/{gsd/agents/gsd-project-researcher.md → src/agents/ccp-project-researcher.md} +33 -6
- package/{gsd/agents/gsd-research-synthesizer.md → src/agents/ccp-research-synthesizer.md} +11 -11
- package/{gsd/agents/gsd-roadmapper.md → src/agents/ccp-roadmapper.md} +39 -10
- package/src/agents/ccp-ui-auditor.md +439 -0
- package/src/agents/ccp-ui-checker.md +300 -0
- package/src/agents/ccp-ui-researcher.md +357 -0
- package/{gsd/agents/gsd-verifier.md → src/agents/ccp-verifier.md} +81 -15
- package/src/agents/cpp-build-resolver.md +90 -0
- package/src/agents/cpp-reviewer.md +72 -0
- package/src/agents/database-reviewer.md +91 -0
- package/src/agents/docs-lookup.md +68 -0
- package/src/agents/flutter-reviewer.md +243 -0
- package/src/agents/go-build-resolver.md +94 -0
- package/src/agents/go-reviewer.md +76 -0
- package/src/agents/java-build-resolver.md +153 -0
- package/src/agents/java-reviewer.md +92 -0
- package/src/agents/kotlin-build-resolver.md +118 -0
- package/src/agents/kotlin-reviewer.md +159 -0
- package/src/agents/planner.md +212 -0
- package/src/agents/python-reviewer.md +98 -0
- package/src/agents/pytorch-build-resolver.md +120 -0
- package/src/agents/refactor-cleaner.md +85 -0
- package/src/agents/rust-build-resolver.md +148 -0
- package/src/agents/rust-reviewer.md +94 -0
- package/src/agents/typescript-reviewer.md +112 -0
- package/src/available-rules/README.md +80 -0
- package/src/available-rules/cpp/coding-style.md +44 -0
- package/src/available-rules/cpp/hooks.md +39 -0
- package/src/available-rules/cpp/patterns.md +51 -0
- package/src/available-rules/cpp/security.md +51 -0
- package/src/available-rules/cpp/testing.md +44 -0
- package/src/available-rules/csharp/coding-style.md +72 -0
- package/src/available-rules/csharp/hooks.md +25 -0
- package/src/available-rules/csharp/patterns.md +50 -0
- package/src/available-rules/csharp/security.md +58 -0
- package/src/available-rules/csharp/testing.md +46 -0
- package/src/available-rules/java/coding-style.md +114 -0
- package/src/available-rules/java/hooks.md +18 -0
- package/src/available-rules/java/patterns.md +146 -0
- package/src/available-rules/java/security.md +100 -0
- package/src/available-rules/java/testing.md +131 -0
- package/src/available-rules/kotlin/hooks.md +17 -0
- package/src/available-rules/rust/coding-style.md +151 -0
- package/src/available-rules/rust/hooks.md +16 -0
- package/src/available-rules/rust/patterns.md +168 -0
- package/src/available-rules/rust/security.md +141 -0
- package/src/available-rules/rust/testing.md +154 -0
- package/src/commands/aside.md +164 -0
- package/src/commands/build-fix.md +62 -0
- package/src/commands/ccp/add-backlog.md +76 -0
- package/{gsd/commands-gsd → src/commands/ccp}/add-phase.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/add-tests.md +5 -5
- package/{gsd/commands-gsd → src/commands/ccp}/add-todo.md +4 -4
- package/{gsd/commands-gsd → src/commands/ccp}/audit-milestone.md +3 -3
- package/src/commands/ccp/audit-uat.md +24 -0
- package/src/commands/ccp/autonomous.md +41 -0
- package/{gsd/commands-gsd → src/commands/ccp}/check-todos.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/cleanup.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/complete-milestone.md +9 -9
- package/{gsd/commands-gsd → src/commands/ccp}/debug.md +14 -9
- package/src/commands/ccp/discuss-phase.md +64 -0
- package/src/commands/ccp/do.md +30 -0
- package/src/commands/ccp/execute-phase.md +59 -0
- package/src/commands/ccp/fast.md +30 -0
- package/src/commands/ccp/forensics.md +56 -0
- package/{gsd/commands-gsd → src/commands/ccp}/health.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/help.md +5 -5
- package/{gsd/commands-gsd → src/commands/ccp}/insert-phase.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/list-phase-assumptions.md +2 -2
- package/src/commands/ccp/manager.md +39 -0
- package/{gsd/commands-gsd → src/commands/ccp}/map-codebase.md +7 -7
- package/src/commands/ccp/milestone-summary.md +51 -0
- package/{gsd/commands-gsd → src/commands/ccp}/new-milestone.md +8 -8
- package/{gsd/commands-gsd → src/commands/ccp}/new-project.md +8 -8
- package/src/commands/ccp/next.md +24 -0
- package/src/commands/ccp/note.md +34 -0
- package/{gsd/commands-gsd → src/commands/ccp}/pause-work.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/plan-milestone-gaps.md +5 -5
- package/{gsd/commands-gsd → src/commands/ccp}/plan-phase.md +9 -7
- package/src/commands/ccp/plant-seed.md +28 -0
- package/src/commands/ccp/pr-branch.md +25 -0
- package/{gsd/commands-gsd → src/commands/ccp}/progress.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/quick.md +10 -8
- package/{gsd/commands-gsd → src/commands/ccp}/remove-phase.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/research-phase.md +17 -12
- package/{gsd/commands-gsd → src/commands/ccp}/resume-work.md +3 -3
- package/src/commands/ccp/review-backlog.md +61 -0
- package/src/commands/ccp/session-report.md +19 -0
- package/src/commands/ccp/set-profile.md +12 -0
- package/{gsd/commands-gsd → src/commands/ccp}/settings.md +5 -5
- package/src/commands/ccp/ship.md +23 -0
- package/src/commands/ccp/stats.md +18 -0
- package/src/commands/ccp/thread.md +127 -0
- package/src/commands/ccp/ui-phase.md +34 -0
- package/src/commands/ccp/ui-review.md +32 -0
- package/{gsd/commands-gsd → src/commands/ccp}/update.md +5 -5
- package/{gsd/commands-gsd → src/commands/ccp}/validate-phase.md +3 -3
- package/{gsd/commands-gsd → src/commands/ccp}/verify-work.md +5 -5
- package/src/commands/code-review.md +40 -0
- package/src/commands/context-budget.md +29 -0
- package/src/commands/cpp-build.md +173 -0
- package/src/commands/cpp-review.md +132 -0
- package/src/commands/cpp-test.md +251 -0
- package/src/commands/docs.md +31 -0
- package/src/commands/e2e.md +364 -0
- package/src/commands/eval.md +120 -0
- package/{ecc → src}/commands/evolve.md +2 -2
- package/src/commands/go-build.md +183 -0
- package/src/commands/go-review.md +148 -0
- package/src/commands/go-test.md +268 -0
- package/src/commands/gradle-build.md +70 -0
- package/src/commands/harness-audit.md +71 -0
- package/src/commands/kotlin-build.md +174 -0
- package/src/commands/kotlin-review.md +140 -0
- package/src/commands/kotlin-test.md +312 -0
- package/src/commands/orchestrate.md +231 -0
- package/src/commands/plan.md +114 -0
- package/src/commands/prompt-optimize.md +38 -0
- package/src/commands/prune.md +25 -0
- package/src/commands/python-review.md +297 -0
- package/{ecc → src}/commands/quality-gate.md +1 -1
- package/src/commands/refactor-clean.md +80 -0
- package/src/commands/rules-distill.md +11 -0
- package/src/commands/rust-build.md +187 -0
- package/src/commands/rust-review.md +142 -0
- package/src/commands/rust-test.md +308 -0
- package/{ecc → src}/commands/sessions.md +10 -10
- package/src/commands/setup-pm.md +80 -0
- package/{kit → src}/commands/setup.md +45 -19
- package/src/commands/skill-create.md +172 -0
- package/src/commands/skill-health.md +51 -0
- package/src/commands/tdd.md +328 -0
- package/src/commands/test-coverage.md +69 -0
- package/src/commands/update-codemaps.md +72 -0
- package/src/commands/update-docs.md +84 -0
- package/{gsd/hooks/gsd-context-monitor.js → src/hooks/ccp-context-monitor.js} +3 -3
- package/src/hooks/ccp-prompt-guard.js +96 -0
- package/{gsd/hooks/gsd-statusline.js → src/hooks/ccp-statusline.js} +7 -7
- package/src/hooks/ccp-workflow-guard.js +94 -0
- package/src/hooks/config-protection.js +141 -0
- package/{kit → src}/hooks/kit-check-update.js +7 -4
- package/src/hooks/mcp-health-check.js +620 -0
- package/{ecc/scripts → src}/hooks/run-with-flags-shell.sh +1 -1
- package/{ecc/scripts → src}/hooks/run-with-flags.js +74 -13
- package/src/hooks/session-end-marker.js +29 -0
- package/{ecc/scripts → src}/hooks/session-end.js +83 -40
- package/{ecc/scripts → src}/hooks/session-start.js +75 -9
- package/{ecc/scripts → src}/lib/hook-flags.js +8 -4
- package/{ecc/scripts → src}/lib/project-detect.js +2 -1
- package/{ecc/scripts → src}/lib/session-manager.d.ts +5 -1
- package/{ecc/scripts → src}/lib/session-manager.js +202 -92
- package/{ecc/scripts → src}/lib/utils.d.ts +23 -1
- package/{ecc/scripts → src}/lib/utils.js +91 -3
- package/{gsd/get-shit-done/bin/gsd-tools.cjs → src/pilot/bin/ccp-tools.cjs} +257 -86
- package/{gsd/get-shit-done → src/pilot}/bin/lib/commands.cjs +1 -1
- package/src/pilot/bin/lib/config.cjs +444 -0
- package/src/pilot/bin/lib/core.cjs +1190 -0
- package/src/pilot/bin/lib/init.cjs +1281 -0
- package/src/pilot/bin/lib/model-profiles.cjs +67 -0
- package/{gsd/get-shit-done → src/pilot}/bin/lib/phase.cjs +2 -2
- package/src/pilot/bin/lib/security.cjs +382 -0
- package/{gsd/get-shit-done → src/pilot}/bin/lib/state.cjs +1 -1
- package/src/pilot/bin/lib/uat.cjs +282 -0
- package/{gsd/get-shit-done → src/pilot}/bin/lib/verify.cjs +10 -10
- package/{gsd/get-shit-done → src/pilot}/references/continuation-format.md +16 -16
- package/{gsd/get-shit-done → src/pilot}/references/decimal-phase-calculation.md +5 -5
- package/{gsd/get-shit-done → src/pilot}/references/git-integration.md +5 -5
- package/{gsd/get-shit-done → src/pilot}/references/git-planning-commit.md +4 -4
- package/src/pilot/references/mcp-servers.json +153 -0
- package/{gsd/get-shit-done → src/pilot}/references/model-profile-resolution.md +2 -2
- package/{gsd/get-shit-done → src/pilot}/references/model-profiles.md +20 -20
- package/{gsd/get-shit-done → src/pilot}/references/phase-argument-parsing.md +4 -4
- package/{gsd/get-shit-done → src/pilot}/references/planning-config.md +15 -15
- package/{gsd/get-shit-done → src/pilot}/references/ui-brand.md +5 -5
- package/{gsd/get-shit-done → src/pilot}/references/verification-patterns.md +1 -1
- package/{gsd/get-shit-done → src/pilot}/templates/DEBUG.md +1 -1
- package/{gsd/get-shit-done → src/pilot}/templates/UAT.md +3 -3
- package/src/pilot/templates/UI-SPEC.md +100 -0
- package/{gsd/get-shit-done → src/pilot}/templates/VALIDATION.md +1 -1
- package/src/pilot/templates/claude-md.md +122 -0
- package/{gsd/get-shit-done → src/pilot}/templates/codebase/architecture.md +2 -2
- package/{gsd/get-shit-done → src/pilot}/templates/codebase/structure.md +13 -13
- package/{gsd/get-shit-done → src/pilot}/templates/context.md +4 -4
- package/src/pilot/templates/copilot-instructions.md +7 -0
- package/{gsd/get-shit-done → src/pilot}/templates/debug-subagent-prompt.md +4 -4
- package/src/pilot/templates/dev-preferences.md +21 -0
- package/{gsd/get-shit-done → src/pilot}/templates/discovery.md +2 -2
- package/src/pilot/templates/discussion-log.md +63 -0
- package/{gsd/get-shit-done → src/pilot}/templates/phase-prompt.md +12 -12
- package/{gsd/get-shit-done → src/pilot}/templates/planner-subagent-prompt.md +7 -7
- package/{gsd/get-shit-done → src/pilot}/templates/project.md +1 -1
- package/{gsd/get-shit-done → src/pilot}/templates/research.md +2 -2
- package/{gsd/get-shit-done → src/pilot}/templates/state.md +2 -2
- package/{gsd/get-shit-done → src/pilot}/templates/summary-complex.md +1 -1
- package/{gsd/get-shit-done → src/pilot}/workflows/add-phase.md +11 -11
- package/{gsd/get-shit-done → src/pilot}/workflows/add-tests.md +15 -15
- package/{gsd/get-shit-done → src/pilot}/workflows/add-todo.md +7 -7
- package/{gsd/get-shit-done → src/pilot}/workflows/audit-milestone.md +24 -16
- package/src/pilot/workflows/audit-uat.md +109 -0
- package/src/pilot/workflows/autonomous.md +891 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/check-todos.md +10 -10
- package/{gsd/get-shit-done → src/pilot}/workflows/cleanup.md +3 -3
- package/{gsd/get-shit-done → src/pilot}/workflows/complete-milestone.md +19 -16
- package/{gsd/get-shit-done → src/pilot}/workflows/diagnose-issues.md +9 -4
- package/{gsd/get-shit-done → src/pilot}/workflows/discovery-phase.md +8 -8
- package/src/pilot/workflows/discuss-phase-assumptions.md +653 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/discuss-phase.md +407 -49
- package/src/pilot/workflows/do.md +104 -0
- package/src/pilot/workflows/execute-phase.md +821 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/execute-plan.md +79 -28
- package/src/pilot/workflows/fast.md +105 -0
- package/src/pilot/workflows/forensics.md +265 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/health.md +34 -11
- package/src/pilot/workflows/help.md +775 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/insert-phase.md +10 -10
- package/{gsd/get-shit-done → src/pilot}/workflows/list-phase-assumptions.md +4 -4
- package/src/pilot/workflows/manager.md +362 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/map-codebase.md +27 -17
- package/src/pilot/workflows/milestone-summary.md +223 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/new-milestone.md +135 -33
- package/{gsd/get-shit-done → src/pilot}/workflows/new-project.md +152 -79
- package/src/pilot/workflows/next.md +97 -0
- package/src/pilot/workflows/node-repair.md +92 -0
- package/src/pilot/workflows/note.md +156 -0
- package/src/pilot/workflows/pause-work.md +177 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/plan-milestone-gaps.md +10 -11
- package/src/pilot/workflows/plan-phase.md +859 -0
- package/src/pilot/workflows/plant-seed.md +169 -0
- package/src/pilot/workflows/pr-branch.md +129 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/progress.md +95 -34
- package/{gsd/get-shit-done → src/pilot}/workflows/quick.md +33 -21
- package/{gsd/get-shit-done → src/pilot}/workflows/remove-phase.md +14 -14
- package/{gsd/get-shit-done → src/pilot}/workflows/research-phase.md +18 -10
- package/{gsd/get-shit-done → src/pilot}/workflows/resume-project.md +37 -18
- package/src/pilot/workflows/session-report.md +146 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/set-profile.md +7 -7
- package/{gsd/get-shit-done → src/pilot}/workflows/settings.md +75 -22
- package/src/pilot/workflows/ship.md +228 -0
- package/src/pilot/workflows/stats.md +60 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/transition.md +57 -17
- package/src/pilot/workflows/ui-phase.md +302 -0
- package/src/pilot/workflows/ui-review.md +165 -0
- package/{gsd/get-shit-done → src/pilot}/workflows/update.md +88 -58
- package/{gsd/get-shit-done → src/pilot}/workflows/validate-phase.md +24 -17
- package/{gsd/get-shit-done → src/pilot}/workflows/verify-phase.md +26 -15
- package/{gsd/get-shit-done → src/pilot}/workflows/verify-work.md +89 -37
- package/{ecc → src}/rules/common/agents.md +1 -0
- package/{ecc → src}/rules/common/coding-style.md +21 -0
- package/src/skills/agentic-engineering/SKILL.md +63 -0
- package/src/skills/ai-first-engineering/SKILL.md +51 -0
- package/src/skills/ai-regression-testing/SKILL.md +385 -0
- package/src/skills/api-design/SKILL.md +523 -0
- package/src/skills/architecture-decision-records/SKILL.md +179 -0
- package/src/skills/backend-patterns/SKILL.md +598 -0
- package/src/skills/benchmark/SKILL.md +87 -0
- package/src/skills/blueprint/SKILL.md +90 -0
- package/src/skills/browser-qa/SKILL.md +81 -0
- package/src/skills/claude-api/SKILL.md +337 -0
- package/src/skills/codebase-onboarding/SKILL.md +233 -0
- package/src/skills/coding-standards/SKILL.md +530 -0
- package/src/skills/context-budget/SKILL.md +135 -0
- package/{ecc → src}/skills/continuous-learning-v2/SKILL.md +2 -2
- package/{ecc → src}/skills/continuous-learning-v2/agents/observer-loop.sh +1 -1
- package/src/skills/cpp-coding-standards/SKILL.md +723 -0
- package/src/skills/cpp-testing/SKILL.md +324 -0
- package/src/skills/database-migrations/SKILL.md +429 -0
- package/src/skills/deep-research/SKILL.md +155 -0
- package/src/skills/deployment-patterns/SKILL.md +427 -0
- package/src/skills/django-patterns/SKILL.md +734 -0
- package/src/skills/django-security/SKILL.md +593 -0
- package/src/skills/django-tdd/SKILL.md +729 -0
- package/src/skills/django-verification/SKILL.md +469 -0
- package/src/skills/docker-patterns/SKILL.md +364 -0
- package/src/skills/documentation-lookup/SKILL.md +90 -0
- package/src/skills/e2e-testing/SKILL.md +326 -0
- package/src/skills/exa-search/SKILL.md +103 -0
- package/src/skills/frontend-patterns/SKILL.md +642 -0
- package/src/skills/golang-patterns/SKILL.md +674 -0
- package/src/skills/golang-testing/SKILL.md +720 -0
- package/src/skills/java-coding-standards/SKILL.md +147 -0
- package/src/skills/jpa-patterns/SKILL.md +151 -0
- package/src/skills/kotlin-coroutines-flows/SKILL.md +284 -0
- package/src/skills/kotlin-exposed-patterns/SKILL.md +719 -0
- package/src/skills/kotlin-ktor-patterns/SKILL.md +689 -0
- package/src/skills/kotlin-patterns/SKILL.md +711 -0
- package/src/skills/kotlin-testing/SKILL.md +824 -0
- package/src/skills/laravel-patterns/SKILL.md +415 -0
- package/src/skills/laravel-security/SKILL.md +285 -0
- package/src/skills/laravel-tdd/SKILL.md +283 -0
- package/src/skills/laravel-verification/SKILL.md +179 -0
- package/src/skills/mcp-server-patterns/SKILL.md +67 -0
- package/src/skills/perl-patterns/SKILL.md +504 -0
- package/src/skills/perl-testing/SKILL.md +475 -0
- package/src/skills/postgres-patterns/SKILL.md +147 -0
- package/src/skills/prompt-optimizer/SKILL.md +397 -0
- package/src/skills/python-patterns/SKILL.md +750 -0
- package/src/skills/python-testing/SKILL.md +816 -0
- package/src/skills/rust-patterns/SKILL.md +499 -0
- package/src/skills/rust-testing/SKILL.md +500 -0
- package/src/skills/safety-guard/SKILL.md +69 -0
- package/src/skills/search-first/SKILL.md +161 -0
- package/src/skills/security-review/SKILL.md +495 -0
- package/src/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/src/skills/security-scan/SKILL.md +165 -0
- package/src/skills/springboot-patterns/SKILL.md +314 -0
- package/src/skills/springboot-security/SKILL.md +272 -0
- package/src/skills/springboot-tdd/SKILL.md +158 -0
- package/src/skills/springboot-verification/SKILL.md +231 -0
- package/src/skills/tdd-workflow/SKILL.md +410 -0
- package/ecc/scripts/hooks/session-end-marker.js +0 -15
- package/gsd/LICENSE +0 -21
- package/gsd/commands-gsd/discuss-phase.md +0 -90
- package/gsd/commands-gsd/execute-phase.md +0 -41
- package/gsd/commands-gsd/join-discord.md +0 -18
- package/gsd/commands-gsd/reapply-patches.md +0 -123
- package/gsd/commands-gsd/set-profile.md +0 -34
- package/gsd/get-shit-done/bin/lib/config.cjs +0 -169
- package/gsd/get-shit-done/bin/lib/core.cjs +0 -492
- package/gsd/get-shit-done/bin/lib/init.cjs +0 -710
- package/gsd/get-shit-done/workflows/execute-phase.md +0 -459
- package/gsd/get-shit-done/workflows/help.md +0 -489
- package/gsd/get-shit-done/workflows/pause-work.md +0 -122
- package/gsd/get-shit-done/workflows/plan-phase.md +0 -560
- package/gsd/hooks/gsd-check-update.js +0 -81
- package/kit/CLAUDE.md +0 -43
- package/kit/commands/kit/update.md +0 -46
- package/kit/mcp.json +0 -10
- package/kit/rules/code-style.md +0 -24
- /package/{ecc → src}/agents/architect.md +0 -0
- /package/{ecc → src}/agents/code-reviewer.md +0 -0
- /package/{ecc → src}/agents/doc-updater.md +0 -0
- /package/{ecc → src}/agents/e2e-runner.md +0 -0
- /package/{ecc → src}/agents/security-reviewer.md +0 -0
- /package/{ecc → src}/agents/tdd-guide.md +0 -0
- /package/{ecc/rules → src/available-rules}/golang/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/golang/hooks.md +0 -0
- /package/{ecc/rules → src/available-rules}/golang/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/golang/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/golang/testing.md +0 -0
- /package/{ecc/rules → src/available-rules}/kotlin/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/kotlin/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/kotlin/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/kotlin/testing.md +0 -0
- /package/{ecc/rules → src/available-rules}/perl/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/perl/hooks.md +0 -0
- /package/{ecc/rules → src/available-rules}/perl/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/perl/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/perl/testing.md +0 -0
- /package/{ecc/rules → src/available-rules}/php/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/php/hooks.md +0 -0
- /package/{ecc/rules → src/available-rules}/php/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/php/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/php/testing.md +0 -0
- /package/{ecc/rules → src/available-rules}/python/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/python/hooks.md +0 -0
- /package/{ecc/rules → src/available-rules}/python/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/python/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/python/testing.md +0 -0
- /package/{ecc/rules → src/available-rules}/swift/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/swift/hooks.md +0 -0
- /package/{ecc/rules → src/available-rules}/swift/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/swift/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/swift/testing.md +0 -0
- /package/{ecc/rules → src/available-rules}/typescript/coding-style.md +0 -0
- /package/{ecc/rules → src/available-rules}/typescript/hooks.md +0 -0
- /package/{ecc/rules → src/available-rules}/typescript/patterns.md +0 -0
- /package/{ecc/rules → src/available-rules}/typescript/security.md +0 -0
- /package/{ecc/rules → src/available-rules}/typescript/testing.md +0 -0
- /package/{ecc → src}/commands/checkpoint.md +0 -0
- /package/{ecc → src}/commands/learn.md +0 -0
- /package/{ecc → src}/commands/model-route.md +0 -0
- /package/{ecc → src}/commands/resume-session.md +0 -0
- /package/{ecc → src}/commands/save-session.md +0 -0
- /package/{kit → src}/commands/setup-refresh.md +0 -0
- /package/{kit → src}/commands/tool-guide.md +0 -0
- /package/{ecc → src}/commands/verify.md +0 -0
- /package/{ecc → src}/contexts/dev.md +0 -0
- /package/{ecc → src}/contexts/research.md +0 -0
- /package/{ecc → src}/contexts/review.md +0 -0
- /package/{ecc → src}/examples/CLAUDE.md +0 -0
- /package/{ecc → src}/examples/django-api-CLAUDE.md +0 -0
- /package/{ecc → src}/examples/go-microservice-CLAUDE.md +0 -0
- /package/{ecc → src}/examples/rust-api-CLAUDE.md +0 -0
- /package/{ecc → src}/examples/saas-nextjs-CLAUDE.md +0 -0
- /package/{ecc → src}/examples/user-CLAUDE.md +0 -0
- /package/{ecc/scripts → src}/hooks/check-hook-enabled.js +0 -0
- /package/{ecc/scripts → src}/hooks/evaluate-session.js +0 -0
- /package/{ecc/scripts → src}/hooks/pre-compact.js +0 -0
- /package/{ecc/scripts → src}/hooks/suggest-compact.js +0 -0
- /package/{ecc/scripts → src}/lib/package-manager.d.ts +0 -0
- /package/{ecc/scripts → src}/lib/package-manager.js +0 -0
- /package/{ecc/scripts → src}/lib/resolve-formatter.js +0 -0
- /package/{ecc/scripts → src}/lib/session-aliases.d.ts +0 -0
- /package/{ecc/scripts → src}/lib/session-aliases.js +0 -0
- /package/{ecc/scripts → src}/lib/shell-split.js +0 -0
- /package/{gsd/get-shit-done → src/pilot}/bin/lib/frontmatter.cjs +0 -0
- /package/{gsd/get-shit-done → src/pilot}/bin/lib/milestone.cjs +0 -0
- /package/{gsd/get-shit-done → src/pilot}/bin/lib/roadmap.cjs +0 -0
- /package/{gsd/get-shit-done → src/pilot}/bin/lib/template.cjs +0 -0
- /package/{gsd/get-shit-done → src/pilot}/references/checkpoints.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/references/questioning.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/references/tdd.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/codebase/concerns.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/codebase/conventions.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/codebase/integrations.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/codebase/stack.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/codebase/testing.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/config.json +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/continue-here.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/milestone-archive.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/milestone.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/requirements.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/research-project/ARCHITECTURE.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/research-project/FEATURES.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/research-project/PITFALLS.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/research-project/STACK.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/research-project/SUMMARY.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/retrospective.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/roadmap.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/summary-minimal.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/summary-standard.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/summary.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/user-setup.md +0 -0
- /package/{gsd/get-shit-done → src/pilot}/templates/verification-report.md +0 -0
- /package/{ecc → src}/rules/common/development-workflow.md +0 -0
- /package/{ecc → src}/rules/common/git-workflow.md +0 -0
- /package/{ecc → src}/rules/common/hooks.md +0 -0
- /package/{ecc → src}/rules/common/patterns.md +0 -0
- /package/{ecc → src}/rules/common/performance.md +0 -0
- /package/{ecc → src}/rules/common/security.md +0 -0
- /package/{ecc → src}/rules/common/testing.md +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/agents/observer.md +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/agents/start-observer.sh +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/config.json +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/hooks/observe.sh +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/scripts/detect-project.sh +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/scripts/instinct-cli.py +0 -0
- /package/{ecc → src}/skills/continuous-learning-v2/scripts/test_parse_instinct.py +0 -0
- /package/{ecc → src}/skills/strategic-compact/SKILL.md +0 -0
- /package/{ecc → src}/skills/strategic-compact/suggest-compact.sh +0 -0
- /package/{ecc/skills/verification-loop-SKILL.md → src/skills/verification-loop/SKILL.md} +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.java"
|
|
4
|
+
---
|
|
5
|
+
# Java Patterns
|
|
6
|
+
|
|
7
|
+
> This file extends [common/patterns.md](../common/patterns.md) with Java-specific content.
|
|
8
|
+
|
|
9
|
+
## Repository Pattern
|
|
10
|
+
|
|
11
|
+
Encapsulate data access behind an interface:
|
|
12
|
+
|
|
13
|
+
```java
|
|
14
|
+
public interface OrderRepository {
|
|
15
|
+
Optional<Order> findById(Long id);
|
|
16
|
+
List<Order> findAll();
|
|
17
|
+
Order save(Order order);
|
|
18
|
+
void deleteById(Long id);
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Concrete implementations handle storage details (JPA, JDBC, in-memory for tests).
|
|
23
|
+
|
|
24
|
+
## Service Layer
|
|
25
|
+
|
|
26
|
+
Business logic in service classes; keep controllers and repositories thin:
|
|
27
|
+
|
|
28
|
+
```java
|
|
29
|
+
public class OrderService {
|
|
30
|
+
private final OrderRepository orderRepository;
|
|
31
|
+
private final PaymentGateway paymentGateway;
|
|
32
|
+
|
|
33
|
+
public OrderService(OrderRepository orderRepository, PaymentGateway paymentGateway) {
|
|
34
|
+
this.orderRepository = orderRepository;
|
|
35
|
+
this.paymentGateway = paymentGateway;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public OrderSummary placeOrder(CreateOrderRequest request) {
|
|
39
|
+
var order = Order.from(request);
|
|
40
|
+
paymentGateway.charge(order.total());
|
|
41
|
+
var saved = orderRepository.save(order);
|
|
42
|
+
return OrderSummary.from(saved);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Constructor Injection
|
|
48
|
+
|
|
49
|
+
Always use constructor injection — never field injection:
|
|
50
|
+
|
|
51
|
+
```java
|
|
52
|
+
// GOOD — constructor injection (testable, immutable)
|
|
53
|
+
public class NotificationService {
|
|
54
|
+
private final EmailSender emailSender;
|
|
55
|
+
|
|
56
|
+
public NotificationService(EmailSender emailSender) {
|
|
57
|
+
this.emailSender = emailSender;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// BAD — field injection (untestable without reflection, requires framework magic)
|
|
62
|
+
public class NotificationService {
|
|
63
|
+
@Inject // or @Autowired
|
|
64
|
+
private EmailSender emailSender;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## DTO Mapping
|
|
69
|
+
|
|
70
|
+
Use records for DTOs. Map at service/controller boundaries:
|
|
71
|
+
|
|
72
|
+
```java
|
|
73
|
+
public record OrderResponse(Long id, String customer, BigDecimal total) {
|
|
74
|
+
public static OrderResponse from(Order order) {
|
|
75
|
+
return new OrderResponse(order.getId(), order.getCustomerName(), order.getTotal());
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Builder Pattern
|
|
81
|
+
|
|
82
|
+
Use for objects with many optional parameters:
|
|
83
|
+
|
|
84
|
+
```java
|
|
85
|
+
public class SearchCriteria {
|
|
86
|
+
private final String query;
|
|
87
|
+
private final int page;
|
|
88
|
+
private final int size;
|
|
89
|
+
private final String sortBy;
|
|
90
|
+
|
|
91
|
+
private SearchCriteria(Builder builder) {
|
|
92
|
+
this.query = builder.query;
|
|
93
|
+
this.page = builder.page;
|
|
94
|
+
this.size = builder.size;
|
|
95
|
+
this.sortBy = builder.sortBy;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public static class Builder {
|
|
99
|
+
private String query = "";
|
|
100
|
+
private int page = 0;
|
|
101
|
+
private int size = 20;
|
|
102
|
+
private String sortBy = "id";
|
|
103
|
+
|
|
104
|
+
public Builder query(String query) { this.query = query; return this; }
|
|
105
|
+
public Builder page(int page) { this.page = page; return this; }
|
|
106
|
+
public Builder size(int size) { this.size = size; return this; }
|
|
107
|
+
public Builder sortBy(String sortBy) { this.sortBy = sortBy; return this; }
|
|
108
|
+
public SearchCriteria build() { return new SearchCriteria(this); }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Sealed Types for Domain Models
|
|
114
|
+
|
|
115
|
+
```java
|
|
116
|
+
public sealed interface PaymentResult permits PaymentSuccess, PaymentFailure {
|
|
117
|
+
record PaymentSuccess(String transactionId, BigDecimal amount) implements PaymentResult {}
|
|
118
|
+
record PaymentFailure(String errorCode, String message) implements PaymentResult {}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Exhaustive handling (Java 21+)
|
|
122
|
+
String message = switch (result) {
|
|
123
|
+
case PaymentSuccess s -> "Paid: " + s.transactionId();
|
|
124
|
+
case PaymentFailure f -> "Failed: " + f.errorCode();
|
|
125
|
+
};
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## API Response Envelope
|
|
129
|
+
|
|
130
|
+
Consistent API responses:
|
|
131
|
+
|
|
132
|
+
```java
|
|
133
|
+
public record ApiResponse<T>(boolean success, T data, String error) {
|
|
134
|
+
public static <T> ApiResponse<T> ok(T data) {
|
|
135
|
+
return new ApiResponse<>(true, data, null);
|
|
136
|
+
}
|
|
137
|
+
public static <T> ApiResponse<T> error(String message) {
|
|
138
|
+
return new ApiResponse<>(false, null, message);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## References
|
|
144
|
+
|
|
145
|
+
See skill: `springboot-patterns` for Spring Boot architecture patterns.
|
|
146
|
+
See skill: `jpa-patterns` for entity design and query optimization.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.java"
|
|
4
|
+
---
|
|
5
|
+
# Java Security
|
|
6
|
+
|
|
7
|
+
> This file extends [common/security.md](../common/security.md) with Java-specific content.
|
|
8
|
+
|
|
9
|
+
## Secrets Management
|
|
10
|
+
|
|
11
|
+
- Never hardcode API keys, tokens, or credentials in source code
|
|
12
|
+
- Use environment variables: `System.getenv("API_KEY")`
|
|
13
|
+
- Use a secret manager (Vault, AWS Secrets Manager) for production secrets
|
|
14
|
+
- Keep local config files with secrets in `.gitignore`
|
|
15
|
+
|
|
16
|
+
```java
|
|
17
|
+
// BAD
|
|
18
|
+
private static final String API_KEY = "sk-abc123...";
|
|
19
|
+
|
|
20
|
+
// GOOD — environment variable
|
|
21
|
+
String apiKey = System.getenv("PAYMENT_API_KEY");
|
|
22
|
+
Objects.requireNonNull(apiKey, "PAYMENT_API_KEY must be set");
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## SQL Injection Prevention
|
|
26
|
+
|
|
27
|
+
- Always use parameterized queries — never concatenate user input into SQL
|
|
28
|
+
- Use `PreparedStatement` or your framework's parameterized query API
|
|
29
|
+
- Validate and sanitize any input used in native queries
|
|
30
|
+
|
|
31
|
+
```java
|
|
32
|
+
// BAD — SQL injection via string concatenation
|
|
33
|
+
Statement stmt = conn.createStatement();
|
|
34
|
+
String sql = "SELECT * FROM orders WHERE name = '" + name + "'";
|
|
35
|
+
stmt.executeQuery(sql);
|
|
36
|
+
|
|
37
|
+
// GOOD — PreparedStatement with parameterized query
|
|
38
|
+
PreparedStatement ps = conn.prepareStatement("SELECT * FROM orders WHERE name = ?");
|
|
39
|
+
ps.setString(1, name);
|
|
40
|
+
|
|
41
|
+
// GOOD — JDBC template
|
|
42
|
+
jdbcTemplate.query("SELECT * FROM orders WHERE name = ?", mapper, name);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Input Validation
|
|
46
|
+
|
|
47
|
+
- Validate all user input at system boundaries before processing
|
|
48
|
+
- Use Bean Validation (`@NotNull`, `@NotBlank`, `@Size`) on DTOs when using a validation framework
|
|
49
|
+
- Sanitize file paths and user-provided strings before use
|
|
50
|
+
- Reject input that fails validation with clear error messages
|
|
51
|
+
|
|
52
|
+
```java
|
|
53
|
+
// Validate manually in plain Java
|
|
54
|
+
public Order createOrder(String customerName, BigDecimal amount) {
|
|
55
|
+
if (customerName == null || customerName.isBlank()) {
|
|
56
|
+
throw new IllegalArgumentException("Customer name is required");
|
|
57
|
+
}
|
|
58
|
+
if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
|
|
59
|
+
throw new IllegalArgumentException("Amount must be positive");
|
|
60
|
+
}
|
|
61
|
+
return new Order(customerName, amount);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Authentication and Authorization
|
|
66
|
+
|
|
67
|
+
- Never implement custom auth crypto — use established libraries
|
|
68
|
+
- Store passwords with bcrypt or Argon2, never MD5/SHA1
|
|
69
|
+
- Enforce authorization checks at service boundaries
|
|
70
|
+
- Clear sensitive data from logs — never log passwords, tokens, or PII
|
|
71
|
+
|
|
72
|
+
## Dependency Security
|
|
73
|
+
|
|
74
|
+
- Run `mvn dependency:tree` or `./gradlew dependencies` to audit transitive dependencies
|
|
75
|
+
- Use OWASP Dependency-Check or Snyk to scan for known CVEs
|
|
76
|
+
- Keep dependencies updated — set up Dependabot or Renovate
|
|
77
|
+
|
|
78
|
+
## Error Messages
|
|
79
|
+
|
|
80
|
+
- Never expose stack traces, internal paths, or SQL errors in API responses
|
|
81
|
+
- Map exceptions to safe, generic client messages at handler boundaries
|
|
82
|
+
- Log detailed errors server-side; return generic messages to clients
|
|
83
|
+
|
|
84
|
+
```java
|
|
85
|
+
// Log the detail, return a generic message
|
|
86
|
+
try {
|
|
87
|
+
return orderService.findById(id);
|
|
88
|
+
} catch (OrderNotFoundException ex) {
|
|
89
|
+
log.warn("Order not found: id={}", id);
|
|
90
|
+
return ApiResponse.error("Resource not found"); // generic, no internals
|
|
91
|
+
} catch (Exception ex) {
|
|
92
|
+
log.error("Unexpected error processing order id={}", id, ex);
|
|
93
|
+
return ApiResponse.error("Internal server error"); // never expose ex.getMessage()
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## References
|
|
98
|
+
|
|
99
|
+
See skill: `springboot-security` for Spring Security authentication and authorization patterns.
|
|
100
|
+
See skill: `security-review` for general security checklists.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.java"
|
|
4
|
+
---
|
|
5
|
+
# Java Testing
|
|
6
|
+
|
|
7
|
+
> This file extends [common/testing.md](../common/testing.md) with Java-specific content.
|
|
8
|
+
|
|
9
|
+
## Test Framework
|
|
10
|
+
|
|
11
|
+
- **JUnit 5** (`@Test`, `@ParameterizedTest`, `@Nested`, `@DisplayName`)
|
|
12
|
+
- **AssertJ** for fluent assertions (`assertThat(result).isEqualTo(expected)`)
|
|
13
|
+
- **Mockito** for mocking dependencies
|
|
14
|
+
- **Testcontainers** for integration tests requiring databases or services
|
|
15
|
+
|
|
16
|
+
## Test Organization
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
src/test/java/com/example/app/
|
|
20
|
+
service/ # Unit tests for service layer
|
|
21
|
+
controller/ # Web layer / API tests
|
|
22
|
+
repository/ # Data access tests
|
|
23
|
+
integration/ # Cross-layer integration tests
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Mirror the `src/main/java` package structure in `src/test/java`.
|
|
27
|
+
|
|
28
|
+
## Unit Test Pattern
|
|
29
|
+
|
|
30
|
+
```java
|
|
31
|
+
@ExtendWith(MockitoExtension.class)
|
|
32
|
+
class OrderServiceTest {
|
|
33
|
+
|
|
34
|
+
@Mock
|
|
35
|
+
private OrderRepository orderRepository;
|
|
36
|
+
|
|
37
|
+
private OrderService orderService;
|
|
38
|
+
|
|
39
|
+
@BeforeEach
|
|
40
|
+
void setUp() {
|
|
41
|
+
orderService = new OrderService(orderRepository);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Test
|
|
45
|
+
@DisplayName("findById returns order when exists")
|
|
46
|
+
void findById_existingOrder_returnsOrder() {
|
|
47
|
+
var order = new Order(1L, "Alice", BigDecimal.TEN);
|
|
48
|
+
when(orderRepository.findById(1L)).thenReturn(Optional.of(order));
|
|
49
|
+
|
|
50
|
+
var result = orderService.findById(1L);
|
|
51
|
+
|
|
52
|
+
assertThat(result.customerName()).isEqualTo("Alice");
|
|
53
|
+
verify(orderRepository).findById(1L);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Test
|
|
57
|
+
@DisplayName("findById throws when order not found")
|
|
58
|
+
void findById_missingOrder_throws() {
|
|
59
|
+
when(orderRepository.findById(99L)).thenReturn(Optional.empty());
|
|
60
|
+
|
|
61
|
+
assertThatThrownBy(() -> orderService.findById(99L))
|
|
62
|
+
.isInstanceOf(OrderNotFoundException.class)
|
|
63
|
+
.hasMessageContaining("99");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Parameterized Tests
|
|
69
|
+
|
|
70
|
+
```java
|
|
71
|
+
@ParameterizedTest
|
|
72
|
+
@CsvSource({
|
|
73
|
+
"100.00, 10, 90.00",
|
|
74
|
+
"50.00, 0, 50.00",
|
|
75
|
+
"200.00, 25, 150.00"
|
|
76
|
+
})
|
|
77
|
+
@DisplayName("discount applied correctly")
|
|
78
|
+
void applyDiscount(BigDecimal price, int pct, BigDecimal expected) {
|
|
79
|
+
assertThat(PricingUtils.discount(price, pct)).isEqualByComparingTo(expected);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Integration Tests
|
|
84
|
+
|
|
85
|
+
Use Testcontainers for real database integration:
|
|
86
|
+
|
|
87
|
+
```java
|
|
88
|
+
@Testcontainers
|
|
89
|
+
class OrderRepositoryIT {
|
|
90
|
+
|
|
91
|
+
@Container
|
|
92
|
+
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");
|
|
93
|
+
|
|
94
|
+
private OrderRepository repository;
|
|
95
|
+
|
|
96
|
+
@BeforeEach
|
|
97
|
+
void setUp() {
|
|
98
|
+
var dataSource = new PGSimpleDataSource();
|
|
99
|
+
dataSource.setUrl(postgres.getJdbcUrl());
|
|
100
|
+
dataSource.setUser(postgres.getUsername());
|
|
101
|
+
dataSource.setPassword(postgres.getPassword());
|
|
102
|
+
repository = new JdbcOrderRepository(dataSource);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@Test
|
|
106
|
+
void save_and_findById() {
|
|
107
|
+
var saved = repository.save(new Order(null, "Bob", BigDecimal.ONE));
|
|
108
|
+
var found = repository.findById(saved.getId());
|
|
109
|
+
assertThat(found).isPresent();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For Spring Boot integration tests, see skill: `springboot-tdd`.
|
|
115
|
+
|
|
116
|
+
## Test Naming
|
|
117
|
+
|
|
118
|
+
Use descriptive names with `@DisplayName`:
|
|
119
|
+
- `methodName_scenario_expectedBehavior()` for method names
|
|
120
|
+
- `@DisplayName("human-readable description")` for reports
|
|
121
|
+
|
|
122
|
+
## Coverage
|
|
123
|
+
|
|
124
|
+
- Target 80%+ line coverage
|
|
125
|
+
- Use JaCoCo for coverage reporting
|
|
126
|
+
- Focus on service and domain logic — skip trivial getters/config classes
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
See skill: `springboot-tdd` for Spring Boot TDD patterns with MockMvc and Testcontainers.
|
|
131
|
+
See skill: `java-coding-standards` for testing expectations.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.kt"
|
|
4
|
+
- "**/*.kts"
|
|
5
|
+
- "**/build.gradle.kts"
|
|
6
|
+
---
|
|
7
|
+
# Kotlin Hooks
|
|
8
|
+
|
|
9
|
+
> This file extends [common/hooks.md](../common/hooks.md) with Kotlin-specific content.
|
|
10
|
+
|
|
11
|
+
## PostToolUse Hooks
|
|
12
|
+
|
|
13
|
+
Configure in `~/.claude/settings.json`:
|
|
14
|
+
|
|
15
|
+
- **ktfmt/ktlint**: Auto-format `.kt` and `.kts` files after edit
|
|
16
|
+
- **detekt**: Run static analysis after editing Kotlin files
|
|
17
|
+
- **./gradlew build**: Verify compilation after changes
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
---
|
|
5
|
+
# Rust Coding Style
|
|
6
|
+
|
|
7
|
+
> This file extends [common/coding-style.md](../common/coding-style.md) with Rust-specific content.
|
|
8
|
+
|
|
9
|
+
## Formatting
|
|
10
|
+
|
|
11
|
+
- **rustfmt** for enforcement — always run `cargo fmt` before committing
|
|
12
|
+
- **clippy** for lints — `cargo clippy -- -D warnings` (treat warnings as errors)
|
|
13
|
+
- 4-space indent (rustfmt default)
|
|
14
|
+
- Max line width: 100 characters (rustfmt default)
|
|
15
|
+
|
|
16
|
+
## Immutability
|
|
17
|
+
|
|
18
|
+
Rust variables are immutable by default — embrace this:
|
|
19
|
+
|
|
20
|
+
- Use `let` by default; only use `let mut` when mutation is required
|
|
21
|
+
- Prefer returning new values over mutating in place
|
|
22
|
+
- Use `Cow<'_, T>` when a function may or may not need to allocate
|
|
23
|
+
|
|
24
|
+
```rust
|
|
25
|
+
use std::borrow::Cow;
|
|
26
|
+
|
|
27
|
+
// GOOD — immutable by default, new value returned
|
|
28
|
+
fn normalize(input: &str) -> Cow<'_, str> {
|
|
29
|
+
if input.contains(' ') {
|
|
30
|
+
Cow::Owned(input.replace(' ', "_"))
|
|
31
|
+
} else {
|
|
32
|
+
Cow::Borrowed(input)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// BAD — unnecessary mutation
|
|
37
|
+
fn normalize_bad(input: &mut String) {
|
|
38
|
+
*input = input.replace(' ', "_");
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Naming
|
|
43
|
+
|
|
44
|
+
Follow standard Rust conventions:
|
|
45
|
+
- `snake_case` for functions, methods, variables, modules, crates
|
|
46
|
+
- `PascalCase` (UpperCamelCase) for types, traits, enums, type parameters
|
|
47
|
+
- `SCREAMING_SNAKE_CASE` for constants and statics
|
|
48
|
+
- Lifetimes: short lowercase (`'a`, `'de`) — descriptive names for complex cases (`'input`)
|
|
49
|
+
|
|
50
|
+
## Ownership and Borrowing
|
|
51
|
+
|
|
52
|
+
- Borrow (`&T`) by default; take ownership only when you need to store or consume
|
|
53
|
+
- Never clone to satisfy the borrow checker without understanding the root cause
|
|
54
|
+
- Accept `&str` over `String`, `&[T]` over `Vec<T>` in function parameters
|
|
55
|
+
- Use `impl Into<String>` for constructors that need to own a `String`
|
|
56
|
+
|
|
57
|
+
```rust
|
|
58
|
+
// GOOD — borrows when ownership isn't needed
|
|
59
|
+
fn word_count(text: &str) -> usize {
|
|
60
|
+
text.split_whitespace().count()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// GOOD — takes ownership in constructor via Into
|
|
64
|
+
fn new(name: impl Into<String>) -> Self {
|
|
65
|
+
Self { name: name.into() }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// BAD — takes String when &str suffices
|
|
69
|
+
fn word_count_bad(text: String) -> usize {
|
|
70
|
+
text.split_whitespace().count()
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Error Handling
|
|
75
|
+
|
|
76
|
+
- Use `Result<T, E>` and `?` for propagation — never `unwrap()` in production code
|
|
77
|
+
- **Libraries**: define typed errors with `thiserror`
|
|
78
|
+
- **Applications**: use `anyhow` for flexible error context
|
|
79
|
+
- Add context with `.with_context(|| format!("failed to ..."))?`
|
|
80
|
+
- Reserve `unwrap()` / `expect()` for tests and truly unreachable states
|
|
81
|
+
|
|
82
|
+
```rust
|
|
83
|
+
// GOOD — library error with thiserror
|
|
84
|
+
#[derive(Debug, thiserror::Error)]
|
|
85
|
+
pub enum ConfigError {
|
|
86
|
+
#[error("failed to read config: {0}")]
|
|
87
|
+
Io(#[from] std::io::Error),
|
|
88
|
+
#[error("invalid config format: {0}")]
|
|
89
|
+
Parse(String),
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// GOOD — application error with anyhow
|
|
93
|
+
use anyhow::Context;
|
|
94
|
+
|
|
95
|
+
fn load_config(path: &str) -> anyhow::Result<Config> {
|
|
96
|
+
let content = std::fs::read_to_string(path)
|
|
97
|
+
.with_context(|| format!("failed to read {path}"))?;
|
|
98
|
+
toml::from_str(&content)
|
|
99
|
+
.with_context(|| format!("failed to parse {path}"))
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Iterators Over Loops
|
|
104
|
+
|
|
105
|
+
Prefer iterator chains for transformations; use loops for complex control flow:
|
|
106
|
+
|
|
107
|
+
```rust
|
|
108
|
+
// GOOD — declarative and composable
|
|
109
|
+
let active_emails: Vec<&str> = users.iter()
|
|
110
|
+
.filter(|u| u.is_active)
|
|
111
|
+
.map(|u| u.email.as_str())
|
|
112
|
+
.collect();
|
|
113
|
+
|
|
114
|
+
// GOOD — loop for complex logic with early returns
|
|
115
|
+
for user in &users {
|
|
116
|
+
if let Some(verified) = verify_email(&user.email)? {
|
|
117
|
+
send_welcome(&verified)?;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Module Organization
|
|
123
|
+
|
|
124
|
+
Organize by domain, not by type:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
src/
|
|
128
|
+
├── main.rs
|
|
129
|
+
├── lib.rs
|
|
130
|
+
├── auth/ # Domain module
|
|
131
|
+
│ ├── mod.rs
|
|
132
|
+
│ ├── token.rs
|
|
133
|
+
│ └── middleware.rs
|
|
134
|
+
├── orders/ # Domain module
|
|
135
|
+
│ ├── mod.rs
|
|
136
|
+
│ ├── model.rs
|
|
137
|
+
│ └── service.rs
|
|
138
|
+
└── db/ # Infrastructure
|
|
139
|
+
├── mod.rs
|
|
140
|
+
└── pool.rs
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Visibility
|
|
144
|
+
|
|
145
|
+
- Default to private; use `pub(crate)` for internal sharing
|
|
146
|
+
- Only mark `pub` what is part of the crate's public API
|
|
147
|
+
- Re-export public API from `lib.rs`
|
|
148
|
+
|
|
149
|
+
## References
|
|
150
|
+
|
|
151
|
+
See skill: `rust-patterns` for comprehensive Rust idioms and patterns.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.rs"
|
|
4
|
+
- "**/Cargo.toml"
|
|
5
|
+
---
|
|
6
|
+
# Rust Hooks
|
|
7
|
+
|
|
8
|
+
> This file extends [common/hooks.md](../common/hooks.md) with Rust-specific content.
|
|
9
|
+
|
|
10
|
+
## PostToolUse Hooks
|
|
11
|
+
|
|
12
|
+
Configure in `~/.claude/settings.json`:
|
|
13
|
+
|
|
14
|
+
- **cargo fmt**: Auto-format `.rs` files after edit
|
|
15
|
+
- **cargo clippy**: Run lint checks after editing Rust files
|
|
16
|
+
- **cargo check**: Verify compilation after changes (faster than `cargo build`)
|