devflow-kit 0.9.0 → 1.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/CHANGELOG.md +197 -29
- package/LICENSE +1 -1
- package/README.md +185 -309
- package/dist/cli.js +7 -1
- package/dist/commands/ambient.d.ts +18 -0
- package/dist/commands/ambient.js +136 -0
- package/dist/commands/init.d.ts +23 -0
- package/dist/commands/init.js +393 -571
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.js +20 -0
- package/dist/commands/memory.d.ts +22 -0
- package/dist/commands/memory.js +175 -0
- package/dist/commands/uninstall.d.ts +10 -0
- package/dist/commands/uninstall.js +418 -78
- package/dist/plugins.d.ts +46 -0
- package/dist/plugins.js +169 -0
- package/dist/utils/cli.d.ts +5 -0
- package/dist/utils/cli.js +14 -0
- package/dist/utils/installer.d.ts +41 -0
- package/dist/utils/installer.js +177 -0
- package/dist/utils/paths.d.ts +10 -0
- package/dist/utils/paths.js +23 -3
- package/dist/utils/post-install.d.ts +80 -0
- package/dist/utils/post-install.js +508 -0
- package/dist/utils/safe-delete-install.d.ts +29 -0
- package/dist/utils/safe-delete-install.js +191 -0
- package/dist/utils/safe-delete.d.ts +12 -0
- package/dist/utils/safe-delete.js +83 -0
- package/package.json +18 -8
- package/plugins/devflow-ambient/.claude-plugin/plugin.json +7 -0
- package/plugins/devflow-ambient/README.md +49 -0
- package/plugins/devflow-ambient/commands/ambient.md +110 -0
- package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +89 -0
- package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +64 -0
- package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +7 -0
- package/plugins/devflow-audit-claude/README.md +46 -0
- package/plugins/devflow-audit-claude/agents/claude-md-auditor.md +134 -0
- package/plugins/devflow-audit-claude/commands/audit-claude.md +85 -0
- package/plugins/devflow-code-review/.claude-plugin/plugin.json +31 -0
- package/plugins/devflow-code-review/README.md +73 -0
- package/plugins/devflow-code-review/agents/git.md +272 -0
- package/plugins/devflow-code-review/agents/reviewer.md +119 -0
- package/plugins/devflow-code-review/agents/synthesizer.md +204 -0
- package/plugins/devflow-code-review/commands/code-review-teams.md +262 -0
- package/plugins/devflow-code-review/commands/code-review.md +141 -0
- package/plugins/devflow-code-review/skills/accessibility/SKILL.md +229 -0
- package/plugins/devflow-code-review/skills/accessibility/references/detection.md +171 -0
- package/plugins/devflow-code-review/skills/accessibility/references/patterns.md +670 -0
- package/plugins/devflow-code-review/skills/accessibility/references/violations.md +419 -0
- package/plugins/devflow-code-review/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-code-review/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-code-review/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-code-review/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +153 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/references/detection.md +337 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/references/patterns.md +873 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/references/violations.md +575 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +143 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/references/detection.md +264 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/references/patterns.md +487 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/references/violations.md +361 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +140 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/references/detection.md +207 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/references/patterns.md +202 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/references/violations.md +213 -0
- package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +134 -0
- package/plugins/devflow-code-review/skills/database-patterns/references/detection.md +208 -0
- package/plugins/devflow-code-review/skills/database-patterns/references/patterns.md +394 -0
- package/plugins/devflow-code-review/skills/database-patterns/references/violations.md +332 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +141 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/references/detection.md +181 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/references/patterns.md +225 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/references/violations.md +247 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +125 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/references/detection.md +190 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/references/patterns.md +189 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/references/violations.md +163 -0
- package/plugins/devflow-code-review/skills/frontend-design/SKILL.md +254 -0
- package/plugins/devflow-code-review/skills/frontend-design/references/detection.md +184 -0
- package/plugins/devflow-code-review/skills/frontend-design/references/patterns.md +511 -0
- package/plugins/devflow-code-review/skills/frontend-design/references/violations.md +453 -0
- package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +154 -0
- package/plugins/devflow-code-review/skills/performance-patterns/references/detection.md +351 -0
- package/plugins/devflow-code-review/skills/performance-patterns/references/patterns.md +503 -0
- package/plugins/devflow-code-review/skills/performance-patterns/references/violations.md +354 -0
- package/plugins/devflow-code-review/skills/react/SKILL.md +276 -0
- package/plugins/devflow-code-review/skills/react/references/patterns.md +1331 -0
- package/plugins/devflow-code-review/skills/react/references/violations.md +565 -0
- package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +146 -0
- package/plugins/devflow-code-review/skills/regression-patterns/references/detection.md +237 -0
- package/plugins/devflow-code-review/skills/regression-patterns/references/patterns.md +226 -0
- package/plugins/devflow-code-review/skills/regression-patterns/references/violations.md +225 -0
- package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +119 -0
- package/plugins/devflow-code-review/skills/review-methodology/references/patterns.md +186 -0
- package/plugins/devflow-code-review/skills/review-methodology/references/report-template.md +142 -0
- package/plugins/devflow-code-review/skills/review-methodology/references/violations.md +125 -0
- package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +156 -0
- package/plugins/devflow-code-review/skills/security-patterns/references/detection.md +287 -0
- package/plugins/devflow-code-review/skills/security-patterns/references/patterns.md +507 -0
- package/plugins/devflow-code-review/skills/security-patterns/references/violations.md +237 -0
- package/plugins/devflow-code-review/skills/test-patterns/SKILL.md +183 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/detection.md +149 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/patterns.md +220 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/report-template.md +108 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/violations.md +221 -0
- package/plugins/devflow-core-skills/.claude-plugin/plugin.json +28 -0
- package/plugins/devflow-core-skills/README.md +50 -0
- package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +229 -0
- package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +171 -0
- package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +670 -0
- package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +419 -0
- package/plugins/devflow-core-skills/skills/core-patterns/SKILL.md +162 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/checklist.md +276 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/code-smell-violations.md +144 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/detection.md +303 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/patterns.md +576 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/violations.md +369 -0
- package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +138 -0
- package/plugins/devflow-core-skills/skills/docs-framework/references/patterns.md +346 -0
- package/plugins/devflow-core-skills/skills/docs-framework/references/violations.md +221 -0
- package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +254 -0
- package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +184 -0
- package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +511 -0
- package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +453 -0
- package/plugins/devflow-core-skills/skills/git-safety/SKILL.md +122 -0
- package/plugins/devflow-core-skills/skills/git-safety/references/detection.md +290 -0
- package/plugins/devflow-core-skills/skills/git-safety/references/patterns.md +289 -0
- package/plugins/devflow-core-skills/skills/git-safety/references/violations.md +18 -0
- package/plugins/devflow-core-skills/skills/git-workflow/SKILL.md +158 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/commit-patterns.md +115 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/commit-violations.md +77 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/pr-patterns.md +127 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/pr-violations.md +96 -0
- package/plugins/devflow-core-skills/skills/github-patterns/SKILL.md +153 -0
- package/plugins/devflow-core-skills/skills/github-patterns/references/patterns.md +572 -0
- package/plugins/devflow-core-skills/skills/github-patterns/references/violations.md +298 -0
- package/plugins/devflow-core-skills/skills/input-validation/SKILL.md +148 -0
- package/plugins/devflow-core-skills/skills/input-validation/references/detection.md +283 -0
- package/plugins/devflow-core-skills/skills/input-validation/references/patterns.md +361 -0
- package/plugins/devflow-core-skills/skills/input-validation/references/violations.md +224 -0
- package/plugins/devflow-core-skills/skills/react/SKILL.md +276 -0
- package/plugins/devflow-core-skills/skills/react/references/patterns.md +1331 -0
- package/plugins/devflow-core-skills/skills/react/references/violations.md +565 -0
- package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +139 -0
- package/plugins/devflow-core-skills/skills/test-driven-development/references/rationalization-prevention.md +111 -0
- package/plugins/devflow-core-skills/skills/test-patterns/SKILL.md +183 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/detection.md +149 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/patterns.md +220 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/report-template.md +108 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/violations.md +221 -0
- package/plugins/devflow-core-skills/skills/typescript/SKILL.md +176 -0
- package/plugins/devflow-core-skills/skills/typescript/references/patterns.md +1105 -0
- package/plugins/devflow-core-skills/skills/typescript/references/violations.md +433 -0
- package/plugins/devflow-debug/.claude-plugin/plugin.json +18 -0
- package/plugins/devflow-debug/README.md +65 -0
- package/plugins/devflow-debug/agents/git.md +272 -0
- package/plugins/devflow-debug/commands/debug-teams.md +231 -0
- package/plugins/devflow-debug/commands/debug.md +160 -0
- package/plugins/devflow-debug/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-debug/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-debug/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-debug/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-debug/skills/git-safety/SKILL.md +122 -0
- package/plugins/devflow-debug/skills/git-safety/references/detection.md +290 -0
- package/plugins/devflow-debug/skills/git-safety/references/patterns.md +289 -0
- package/plugins/devflow-debug/skills/git-safety/references/violations.md +18 -0
- package/plugins/devflow-implement/.claude-plugin/plugin.json +21 -0
- package/plugins/devflow-implement/README.md +71 -0
- package/plugins/devflow-implement/agents/coder.md +122 -0
- package/plugins/devflow-implement/agents/git.md +272 -0
- package/plugins/devflow-implement/agents/scrutinizer.md +80 -0
- package/plugins/devflow-implement/agents/shepherd.md +94 -0
- package/plugins/devflow-implement/agents/simplifier.md +62 -0
- package/plugins/devflow-implement/agents/skimmer.md +88 -0
- package/plugins/devflow-implement/agents/synthesizer.md +204 -0
- package/plugins/devflow-implement/agents/validator.md +86 -0
- package/plugins/devflow-implement/commands/implement-teams.md +608 -0
- package/plugins/devflow-implement/commands/implement.md +426 -0
- package/plugins/devflow-implement/skills/accessibility/SKILL.md +229 -0
- package/plugins/devflow-implement/skills/accessibility/references/detection.md +171 -0
- package/plugins/devflow-implement/skills/accessibility/references/patterns.md +670 -0
- package/plugins/devflow-implement/skills/accessibility/references/violations.md +419 -0
- package/plugins/devflow-implement/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-implement/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-implement/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-implement/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-implement/skills/frontend-design/SKILL.md +254 -0
- package/plugins/devflow-implement/skills/frontend-design/references/detection.md +184 -0
- package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +511 -0
- package/plugins/devflow-implement/skills/frontend-design/references/violations.md +453 -0
- package/plugins/devflow-implement/skills/implementation-patterns/SKILL.md +162 -0
- package/plugins/devflow-implement/skills/implementation-patterns/references/patterns.md +1063 -0
- package/plugins/devflow-implement/skills/implementation-patterns/references/violations.md +483 -0
- package/plugins/devflow-implement/skills/self-review/SKILL.md +149 -0
- package/plugins/devflow-implement/skills/self-review/references/patterns.md +405 -0
- package/plugins/devflow-implement/skills/self-review/references/report-template.md +253 -0
- package/plugins/devflow-implement/skills/self-review/references/violations.md +308 -0
- package/plugins/devflow-resolve/.claude-plugin/plugin.json +19 -0
- package/plugins/devflow-resolve/README.md +65 -0
- package/plugins/devflow-resolve/agents/git.md +272 -0
- package/plugins/devflow-resolve/agents/resolver.md +131 -0
- package/plugins/devflow-resolve/agents/simplifier.md +62 -0
- package/plugins/devflow-resolve/commands/resolve-teams.md +298 -0
- package/plugins/devflow-resolve/commands/resolve.md +237 -0
- package/plugins/devflow-resolve/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-resolve/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-resolve/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-resolve/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-resolve/skills/implementation-patterns/SKILL.md +162 -0
- package/plugins/devflow-resolve/skills/implementation-patterns/references/patterns.md +1063 -0
- package/plugins/devflow-resolve/skills/implementation-patterns/references/violations.md +483 -0
- package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +156 -0
- package/plugins/devflow-resolve/skills/security-patterns/references/detection.md +287 -0
- package/plugins/devflow-resolve/skills/security-patterns/references/patterns.md +507 -0
- package/plugins/devflow-resolve/skills/security-patterns/references/violations.md +237 -0
- package/plugins/devflow-self-review/.claude-plugin/plugin.json +7 -0
- package/plugins/devflow-self-review/README.md +38 -0
- package/plugins/devflow-self-review/agents/scrutinizer.md +80 -0
- package/plugins/devflow-self-review/agents/simplifier.md +62 -0
- package/plugins/devflow-self-review/agents/validator.md +86 -0
- package/plugins/devflow-self-review/commands/self-review.md +126 -0
- package/plugins/devflow-self-review/skills/core-patterns/SKILL.md +162 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/checklist.md +276 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/code-smell-violations.md +144 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/detection.md +303 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/patterns.md +576 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/violations.md +369 -0
- package/plugins/devflow-self-review/skills/self-review/SKILL.md +149 -0
- package/plugins/devflow-self-review/skills/self-review/references/patterns.md +405 -0
- package/plugins/devflow-self-review/skills/self-review/references/report-template.md +253 -0
- package/plugins/devflow-self-review/skills/self-review/references/violations.md +308 -0
- package/plugins/devflow-specify/.claude-plugin/plugin.json +15 -0
- package/plugins/devflow-specify/README.md +46 -0
- package/plugins/devflow-specify/agents/skimmer.md +88 -0
- package/plugins/devflow-specify/agents/synthesizer.md +204 -0
- package/plugins/devflow-specify/commands/specify-teams.md +314 -0
- package/plugins/devflow-specify/commands/specify.md +179 -0
- package/plugins/devflow-specify/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-specify/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-specify/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-specify/skills/agent-teams/references/team-patterns.md +217 -0
- package/scripts/hooks/ambient-prompt.sh +48 -0
- package/scripts/hooks/background-memory-update.sh +208 -0
- package/scripts/hooks/ensure-memory-gitignore.sh +17 -0
- package/scripts/hooks/pre-compact-memory.sh +87 -0
- package/scripts/hooks/session-start-memory.sh +126 -0
- package/scripts/hooks/stop-update-memory.sh +85 -0
- package/shared/agents/coder.md +122 -0
- package/shared/agents/git.md +272 -0
- package/shared/agents/resolver.md +131 -0
- package/shared/agents/reviewer.md +119 -0
- package/shared/agents/scrutinizer.md +80 -0
- package/shared/agents/shepherd.md +94 -0
- package/shared/agents/simplifier.md +62 -0
- package/shared/agents/skimmer.md +88 -0
- package/shared/agents/synthesizer.md +204 -0
- package/shared/agents/validator.md +86 -0
- package/shared/skills/accessibility/SKILL.md +229 -0
- package/shared/skills/accessibility/references/detection.md +171 -0
- package/shared/skills/accessibility/references/patterns.md +670 -0
- package/shared/skills/accessibility/references/violations.md +419 -0
- package/shared/skills/agent-teams/SKILL.md +124 -0
- package/shared/skills/agent-teams/references/cleanup.md +104 -0
- package/shared/skills/agent-teams/references/communication.md +122 -0
- package/shared/skills/agent-teams/references/team-patterns.md +217 -0
- package/shared/skills/ambient-router/SKILL.md +89 -0
- package/shared/skills/ambient-router/references/skill-catalog.md +64 -0
- package/shared/skills/architecture-patterns/SKILL.md +153 -0
- package/shared/skills/architecture-patterns/references/detection.md +337 -0
- package/shared/skills/architecture-patterns/references/patterns.md +873 -0
- package/shared/skills/architecture-patterns/references/violations.md +575 -0
- package/shared/skills/complexity-patterns/SKILL.md +143 -0
- package/shared/skills/complexity-patterns/references/detection.md +264 -0
- package/shared/skills/complexity-patterns/references/patterns.md +487 -0
- package/shared/skills/complexity-patterns/references/violations.md +361 -0
- package/shared/skills/consistency-patterns/SKILL.md +140 -0
- package/shared/skills/consistency-patterns/references/detection.md +207 -0
- package/shared/skills/consistency-patterns/references/patterns.md +202 -0
- package/shared/skills/consistency-patterns/references/violations.md +213 -0
- package/shared/skills/core-patterns/SKILL.md +162 -0
- package/shared/skills/core-patterns/references/checklist.md +276 -0
- package/shared/skills/core-patterns/references/code-smell-violations.md +144 -0
- package/shared/skills/core-patterns/references/detection.md +303 -0
- package/shared/skills/core-patterns/references/patterns.md +576 -0
- package/shared/skills/core-patterns/references/violations.md +369 -0
- package/shared/skills/database-patterns/SKILL.md +134 -0
- package/shared/skills/database-patterns/references/detection.md +208 -0
- package/shared/skills/database-patterns/references/patterns.md +394 -0
- package/shared/skills/database-patterns/references/violations.md +332 -0
- package/shared/skills/dependencies-patterns/SKILL.md +141 -0
- package/shared/skills/dependencies-patterns/references/detection.md +181 -0
- package/shared/skills/dependencies-patterns/references/patterns.md +225 -0
- package/shared/skills/dependencies-patterns/references/violations.md +247 -0
- package/shared/skills/docs-framework/SKILL.md +138 -0
- package/shared/skills/docs-framework/references/patterns.md +346 -0
- package/shared/skills/docs-framework/references/violations.md +221 -0
- package/shared/skills/documentation-patterns/SKILL.md +125 -0
- package/shared/skills/documentation-patterns/references/detection.md +190 -0
- package/shared/skills/documentation-patterns/references/patterns.md +189 -0
- package/shared/skills/documentation-patterns/references/violations.md +163 -0
- package/shared/skills/frontend-design/SKILL.md +254 -0
- package/shared/skills/frontend-design/references/detection.md +184 -0
- package/shared/skills/frontend-design/references/patterns.md +511 -0
- package/shared/skills/frontend-design/references/violations.md +453 -0
- package/shared/skills/git-safety/SKILL.md +122 -0
- package/shared/skills/git-safety/references/detection.md +290 -0
- package/shared/skills/git-safety/references/patterns.md +289 -0
- package/shared/skills/git-safety/references/violations.md +18 -0
- package/shared/skills/git-workflow/SKILL.md +158 -0
- package/shared/skills/git-workflow/references/commit-patterns.md +115 -0
- package/shared/skills/git-workflow/references/commit-violations.md +77 -0
- package/shared/skills/git-workflow/references/pr-patterns.md +127 -0
- package/shared/skills/git-workflow/references/pr-violations.md +96 -0
- package/shared/skills/github-patterns/SKILL.md +153 -0
- package/shared/skills/github-patterns/references/patterns.md +572 -0
- package/shared/skills/github-patterns/references/violations.md +298 -0
- package/shared/skills/implementation-patterns/SKILL.md +162 -0
- package/shared/skills/implementation-patterns/references/patterns.md +1063 -0
- package/shared/skills/implementation-patterns/references/violations.md +483 -0
- package/shared/skills/input-validation/SKILL.md +148 -0
- package/shared/skills/input-validation/references/detection.md +283 -0
- package/shared/skills/input-validation/references/patterns.md +361 -0
- package/shared/skills/input-validation/references/violations.md +224 -0
- package/shared/skills/performance-patterns/SKILL.md +154 -0
- package/shared/skills/performance-patterns/references/detection.md +351 -0
- package/shared/skills/performance-patterns/references/patterns.md +503 -0
- package/shared/skills/performance-patterns/references/violations.md +354 -0
- package/shared/skills/react/SKILL.md +276 -0
- package/shared/skills/react/references/patterns.md +1331 -0
- package/shared/skills/react/references/violations.md +565 -0
- package/shared/skills/regression-patterns/SKILL.md +146 -0
- package/shared/skills/regression-patterns/references/detection.md +237 -0
- package/shared/skills/regression-patterns/references/patterns.md +226 -0
- package/shared/skills/regression-patterns/references/violations.md +225 -0
- package/shared/skills/review-methodology/SKILL.md +119 -0
- package/shared/skills/review-methodology/references/patterns.md +186 -0
- package/shared/skills/review-methodology/references/report-template.md +142 -0
- package/shared/skills/review-methodology/references/violations.md +125 -0
- package/shared/skills/security-patterns/SKILL.md +156 -0
- package/shared/skills/security-patterns/references/detection.md +287 -0
- package/shared/skills/security-patterns/references/patterns.md +507 -0
- package/shared/skills/security-patterns/references/violations.md +237 -0
- package/shared/skills/self-review/SKILL.md +149 -0
- package/shared/skills/self-review/references/patterns.md +405 -0
- package/shared/skills/self-review/references/report-template.md +253 -0
- package/shared/skills/self-review/references/violations.md +308 -0
- package/shared/skills/test-driven-development/SKILL.md +139 -0
- package/shared/skills/test-driven-development/references/rationalization-prevention.md +111 -0
- package/shared/skills/test-patterns/SKILL.md +183 -0
- package/shared/skills/test-patterns/references/detection.md +149 -0
- package/shared/skills/test-patterns/references/patterns.md +220 -0
- package/shared/skills/test-patterns/references/report-template.md +108 -0
- package/shared/skills/test-patterns/references/violations.md +221 -0
- package/shared/skills/typescript/SKILL.md +176 -0
- package/shared/skills/typescript/references/patterns.md +1105 -0
- package/shared/skills/typescript/references/violations.md +433 -0
- package/src/templates/claudeignore.template +188 -0
- package/src/templates/managed-settings.json +160 -0
- package/src/templates/settings.json +59 -0
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/uninstall.d.ts.map +0 -1
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/paths.d.ts.map +0 -1
- package/dist/utils/paths.js.map +0 -1
- package/src/claude/CLAUDE.md +0 -400
- package/src/claude/agents/devflow/audit-architecture.md +0 -132
- package/src/claude/agents/devflow/audit-complexity.md +0 -132
- package/src/claude/agents/devflow/audit-database.md +0 -132
- package/src/claude/agents/devflow/audit-dependencies.md +0 -132
- package/src/claude/agents/devflow/audit-documentation.md +0 -132
- package/src/claude/agents/devflow/audit-performance.md +0 -256
- package/src/claude/agents/devflow/audit-security.md +0 -259
- package/src/claude/agents/devflow/audit-tests.md +0 -132
- package/src/claude/agents/devflow/audit-typescript.md +0 -132
- package/src/claude/agents/devflow/brainstorm.md +0 -279
- package/src/claude/agents/devflow/catch-up.md +0 -345
- package/src/claude/agents/devflow/code-review.md +0 -307
- package/src/claude/agents/devflow/commit.md +0 -380
- package/src/claude/agents/devflow/debug.md +0 -476
- package/src/claude/agents/devflow/design.md +0 -491
- package/src/claude/agents/devflow/get-issue.md +0 -286
- package/src/claude/agents/devflow/pr-comments.md +0 -285
- package/src/claude/agents/devflow/project-state.md +0 -419
- package/src/claude/agents/devflow/pull-request.md +0 -493
- package/src/claude/agents/devflow/release.md +0 -1137
- package/src/claude/agents/devflow/tech-debt.md +0 -338
- package/src/claude/commands/devflow/brainstorm.md +0 -68
- package/src/claude/commands/devflow/breakdown.md +0 -125
- package/src/claude/commands/devflow/catch-up.md +0 -29
- package/src/claude/commands/devflow/code-review.md +0 -237
- package/src/claude/commands/devflow/commit.md +0 -17
- package/src/claude/commands/devflow/debug.md +0 -56
- package/src/claude/commands/devflow/design.md +0 -82
- package/src/claude/commands/devflow/devlog.md +0 -408
- package/src/claude/commands/devflow/get-issue.md +0 -16
- package/src/claude/commands/devflow/implement.md +0 -100
- package/src/claude/commands/devflow/plan.md +0 -223
- package/src/claude/commands/devflow/pull-request.md +0 -20
- package/src/claude/commands/devflow/release.md +0 -251
- package/src/claude/commands/devflow/resolve-comments.md +0 -583
- package/src/claude/scripts/statusline.sh +0 -47
- package/src/claude/settings.json +0 -6
- package/src/claude/skills/devflow/code-smell/SKILL.md +0 -428
- package/src/claude/skills/devflow/debug/SKILL.md +0 -119
- package/src/claude/skills/devflow/error-handling/SKILL.md +0 -597
- package/src/claude/skills/devflow/input-validation/SKILL.md +0 -514
- package/src/claude/skills/devflow/pattern-check/SKILL.md +0 -238
- package/src/claude/skills/devflow/research/SKILL.md +0 -138
- package/src/claude/skills/devflow/test-design/SKILL.md +0 -384
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# Validation Issue Detection
|
|
2
|
+
|
|
3
|
+
Grep patterns and report templates for finding validation issues.
|
|
4
|
+
|
|
5
|
+
## Quick Detection Commands
|
|
6
|
+
|
|
7
|
+
### Find Unvalidated Request Body Usage
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Express/Node.js
|
|
11
|
+
grep -rn "req\.body" --include="*.ts" --include="*.js" | grep -v "safeParse\|validate\|schema"
|
|
12
|
+
|
|
13
|
+
# Look for direct property access without validation
|
|
14
|
+
grep -rn "req\.body\.\w" --include="*.ts" --include="*.js"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Find Unvalidated Parameters
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Path parameters
|
|
21
|
+
grep -rn "req\.params\.\w" --include="*.ts" --include="*.js" | grep -v "safeParse\|validate"
|
|
22
|
+
|
|
23
|
+
# Query parameters
|
|
24
|
+
grep -rn "req\.query\.\w" --include="*.ts" --include="*.js" | grep -v "safeParse\|validate"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Find SQL Injection Risks
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Template literals with SQL
|
|
31
|
+
grep -rn '`.*SELECT.*\${' --include="*.ts" --include="*.js"
|
|
32
|
+
grep -rn '`.*INSERT.*\${' --include="*.ts" --include="*.js"
|
|
33
|
+
grep -rn '`.*UPDATE.*\${' --include="*.ts" --include="*.js"
|
|
34
|
+
grep -rn '`.*DELETE.*\${' --include="*.ts" --include="*.js"
|
|
35
|
+
|
|
36
|
+
# String concatenation in queries
|
|
37
|
+
grep -rn "'\s*\+\s*.*\+\s*'" --include="*.ts" --include="*.js" | grep -i "select\|insert\|update\|delete"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Find Unvalidated External Data
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# JSON.parse without validation
|
|
44
|
+
grep -rn "JSON\.parse" --include="*.ts" --include="*.js" | grep -v "safeParse\|try"
|
|
45
|
+
|
|
46
|
+
# fetch responses used directly
|
|
47
|
+
grep -rn "\.json()" --include="*.ts" --include="*.js" | grep -v "safeParse\|schema\|validate"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Find Unvalidated Environment Variables
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Direct process.env usage
|
|
54
|
+
grep -rn "process\.env\.\w" --include="*.ts" --include="*.js" | grep -v "safeParse\|validate\|ConfigSchema"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Find Dangerous Functions
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# eval and Function constructor
|
|
61
|
+
grep -rn "eval\s*(" --include="*.ts" --include="*.js"
|
|
62
|
+
grep -rn "new\s*Function\s*(" --include="*.ts" --include="*.js"
|
|
63
|
+
|
|
64
|
+
# JWT decode without verify
|
|
65
|
+
grep -rn "jwt\.decode" --include="*.ts" --include="*.js" | grep -v "jwt\.verify"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Validation Report Format
|
|
71
|
+
|
|
72
|
+
When validation issues detected:
|
|
73
|
+
|
|
74
|
+
```markdown
|
|
75
|
+
# INPUT VALIDATION ISSUES DETECTED
|
|
76
|
+
|
|
77
|
+
## CRITICAL - Missing Boundary Validation
|
|
78
|
+
**File**: src/api/routes/users.ts:45
|
|
79
|
+
**Issue**: API endpoint accepts unvalidated user input
|
|
80
|
+
**Security Risk**: HIGH - Injection attacks, data corruption possible
|
|
81
|
+
|
|
82
|
+
**Current Code**:
|
|
83
|
+
```typescript
|
|
84
|
+
app.post('/api/users', async (req, res) => {
|
|
85
|
+
const user = await createUser(req.body); // NO VALIDATION
|
|
86
|
+
res.json(user);
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Required Fix**:
|
|
91
|
+
```typescript
|
|
92
|
+
const UserRequestSchema = z.object({
|
|
93
|
+
body: z.object({
|
|
94
|
+
email: z.string().email().max(255),
|
|
95
|
+
name: z.string().min(1).max(100),
|
|
96
|
+
age: z.number().int().min(0).max(150)
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
app.post('/api/users', async (req, res) => {
|
|
101
|
+
const validation = UserRequestSchema.safeParse(req);
|
|
102
|
+
|
|
103
|
+
if (!validation.success) {
|
|
104
|
+
return res.status(400).json({ error: validation.error });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const result = await createUser(validation.data.body);
|
|
108
|
+
// ... handle result
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Impact**: Prevents malicious input, ensures data integrity
|
|
113
|
+
|
|
114
|
+
## CRITICAL - Manual Validation Instead of Schema
|
|
115
|
+
**File**: src/services/validation.ts:23
|
|
116
|
+
**Issue**: Manual type checking instead of schema validation
|
|
117
|
+
**Problem**: Scattered validation logic, incomplete checks
|
|
118
|
+
|
|
119
|
+
**Current Code**:
|
|
120
|
+
```typescript
|
|
121
|
+
if (!data.email || typeof data.email !== 'string') {
|
|
122
|
+
throw new Error('Invalid email');
|
|
123
|
+
}
|
|
124
|
+
if (!data.age || typeof data.age !== 'number') {
|
|
125
|
+
throw new Error('Invalid age');
|
|
126
|
+
}
|
|
127
|
+
// ... 15 more manual checks
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Required Fix**:
|
|
131
|
+
```typescript
|
|
132
|
+
const UserSchema = z.object({
|
|
133
|
+
email: z.string().email().max(255),
|
|
134
|
+
age: z.number().int().min(0).max(150),
|
|
135
|
+
name: z.string().min(1).max(100),
|
|
136
|
+
// All validation rules in one place
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const validation = UserSchema.safeParse(data);
|
|
140
|
+
if (!validation.success) {
|
|
141
|
+
return { ok: false, error: validation.error };
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Impact**: Centralized validation, type safety, better error messages
|
|
146
|
+
|
|
147
|
+
## CRITICAL - SQL Injection Risk
|
|
148
|
+
**File**: src/database/queries.ts:67
|
|
149
|
+
**Issue**: String interpolation in SQL query
|
|
150
|
+
**Security Risk**: CRITICAL - SQL injection possible
|
|
151
|
+
|
|
152
|
+
**Current Code**:
|
|
153
|
+
```typescript
|
|
154
|
+
const query = `SELECT * FROM users WHERE email = '${email}'`;
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Required Fix**:
|
|
158
|
+
```typescript
|
|
159
|
+
// 1. Validate input
|
|
160
|
+
const validation = EmailSchema.safeParse(email);
|
|
161
|
+
if (!validation.success) {
|
|
162
|
+
return { ok: false, error: new Error('Invalid email') };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 2. Use parameterized query
|
|
166
|
+
const query = 'SELECT * FROM users WHERE email = $1';
|
|
167
|
+
const result = await db.query(query, [validation.data]);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Impact**: Prevents SQL injection attacks (critical security issue)
|
|
171
|
+
|
|
172
|
+
## HIGH - External API Response Not Validated
|
|
173
|
+
**File**: src/integrations/payment.ts:89
|
|
174
|
+
**Issue**: Trusting external API response without validation
|
|
175
|
+
**Risk**: Application crash if API changes structure
|
|
176
|
+
|
|
177
|
+
**Current Code**:
|
|
178
|
+
```typescript
|
|
179
|
+
const data = await response.json();
|
|
180
|
+
return data.amount; // No validation
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Required Fix**:
|
|
184
|
+
```typescript
|
|
185
|
+
const PaymentResponseSchema = z.object({
|
|
186
|
+
amount: z.number().positive(),
|
|
187
|
+
currency: z.string().length(3),
|
|
188
|
+
status: z.enum(['success', 'failed', 'pending'])
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const validation = PaymentResponseSchema.safeParse(await response.json());
|
|
192
|
+
if (!validation.success) {
|
|
193
|
+
return { ok: false, error: new Error('Invalid payment response') };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return { ok: true, value: validation.data.amount };
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Summary
|
|
200
|
+
- **Critical**: X validation issues (Y missing, Z SQL injection risks)
|
|
201
|
+
- **High**: X external data issues
|
|
202
|
+
- **Security Risk**: CRITICAL/HIGH/MEDIUM
|
|
203
|
+
- **Files affected**: X
|
|
204
|
+
|
|
205
|
+
## SECURITY GATE FAILED
|
|
206
|
+
|
|
207
|
+
These validation gaps create serious security vulnerabilities:
|
|
208
|
+
1. SQL injection possible in X locations
|
|
209
|
+
2. Unvalidated user input in Y API endpoints
|
|
210
|
+
3. External data trusted without validation
|
|
211
|
+
|
|
212
|
+
**DO NOT deploy until these are fixed.**
|
|
213
|
+
|
|
214
|
+
## Required Actions
|
|
215
|
+
|
|
216
|
+
1. **Immediate** (Security Critical):
|
|
217
|
+
- Fix SQL injection risks
|
|
218
|
+
- Add validation to all API endpoints
|
|
219
|
+
|
|
220
|
+
2. **High Priority**:
|
|
221
|
+
- Validate all external API responses
|
|
222
|
+
- Validate environment variables on startup
|
|
223
|
+
|
|
224
|
+
3. **Standard**:
|
|
225
|
+
- Replace manual validation with schemas
|
|
226
|
+
- Add validation tests
|
|
227
|
+
|
|
228
|
+
## Implementation Guide
|
|
229
|
+
|
|
230
|
+
**Step 1**: Install validation library
|
|
231
|
+
```bash
|
|
232
|
+
npm install zod # or appropriate library
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Step 2**: Define schemas for all boundaries
|
|
236
|
+
```typescript
|
|
237
|
+
// src/validation/schemas.ts
|
|
238
|
+
export const schemas = {
|
|
239
|
+
createUser: UserSchema,
|
|
240
|
+
updateUser: UpdateUserSchema,
|
|
241
|
+
searchQuery: SearchQuerySchema,
|
|
242
|
+
// ... all input shapes
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Step 3**: Apply at boundaries
|
|
247
|
+
```typescript
|
|
248
|
+
// Validate at entry point
|
|
249
|
+
const validation = schema.safeParse(input);
|
|
250
|
+
// Check result and proceed
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Step 4**: Add tests
|
|
254
|
+
```typescript
|
|
255
|
+
// Verify validation catches invalid input
|
|
256
|
+
```
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Risk Classification
|
|
262
|
+
|
|
263
|
+
| Issue Type | Risk Level | Fix Priority |
|
|
264
|
+
|------------|------------|--------------|
|
|
265
|
+
| SQL injection | CRITICAL | Immediate |
|
|
266
|
+
| Command injection | CRITICAL | Immediate |
|
|
267
|
+
| Path traversal | CRITICAL | Immediate |
|
|
268
|
+
| Missing auth validation | CRITICAL | Immediate |
|
|
269
|
+
| Unvalidated API input | HIGH | Same day |
|
|
270
|
+
| Unvalidated external data | HIGH | Same day |
|
|
271
|
+
| Manual validation | MEDIUM | This sprint |
|
|
272
|
+
| Missing env validation | MEDIUM | This sprint |
|
|
273
|
+
| Incomplete schemas | LOW | Next sprint |
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Integration Points
|
|
278
|
+
|
|
279
|
+
This skill works with:
|
|
280
|
+
|
|
281
|
+
- **core-patterns**: Ensures validation uses Result types, catches fake/incomplete validation
|
|
282
|
+
- **test-patterns**: Validates boundary tests exist
|
|
283
|
+
- **security-patterns**: Broader security review context
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Input Validation Correct Patterns
|
|
2
|
+
|
|
3
|
+
Extended examples of proper validation patterns.
|
|
4
|
+
|
|
5
|
+
## Schema Validation at Boundary
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
|
|
10
|
+
const UserSchema = z.object({
|
|
11
|
+
email: z.string().email().max(255),
|
|
12
|
+
age: z.number().int().min(0).max(150),
|
|
13
|
+
name: z.string().min(1).max(100)
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
type User = z.infer<typeof UserSchema>;
|
|
17
|
+
|
|
18
|
+
function createUser(data: unknown): Result<User, ValidationError> {
|
|
19
|
+
const validation = UserSchema.safeParse(data);
|
|
20
|
+
|
|
21
|
+
if (!validation.success) {
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
error: new ValidationError('Invalid user data', validation.error)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// After this point, data is guaranteed valid User type
|
|
29
|
+
return { ok: true, value: validation.data };
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## API Endpoint Validation
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const CreateUserRequestSchema = z.object({
|
|
39
|
+
body: UserSchema
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
app.post('/api/users', async (req, res) => {
|
|
43
|
+
const validation = CreateUserRequestSchema.safeParse(req);
|
|
44
|
+
|
|
45
|
+
if (!validation.success) {
|
|
46
|
+
return res.status(400).json({
|
|
47
|
+
error: 'Validation failed',
|
|
48
|
+
details: validation.error.issues
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Now req.body is safely typed as User
|
|
53
|
+
const result = await createUser(validation.data.body);
|
|
54
|
+
|
|
55
|
+
if (!result.ok) {
|
|
56
|
+
return res.status(500).json({ error: result.error.message });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
res.json(result.value);
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## External API Response Validation
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const ExternalUserSchema = z.object({
|
|
69
|
+
id: z.string().uuid(),
|
|
70
|
+
name: z.string(),
|
|
71
|
+
email: z.string().email(),
|
|
72
|
+
// Define exact structure we expect
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
async function fetchUserData(userId: string): Promise<Result<UserData, Error>> {
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(`https://api.example.com/users/${userId}`);
|
|
78
|
+
const rawData = await response.json();
|
|
79
|
+
|
|
80
|
+
const validation = ExternalUserSchema.safeParse(rawData);
|
|
81
|
+
|
|
82
|
+
if (!validation.success) {
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
error: new Error('External API returned invalid data')
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { ok: true, value: validation.data };
|
|
90
|
+
} catch (error) {
|
|
91
|
+
return { ok: false, error: error as Error };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Environment Variable Validation
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const ConfigSchema = z.object({
|
|
102
|
+
port: z.string().regex(/^\d+$/).transform(Number).pipe(z.number().min(1).max(65535)),
|
|
103
|
+
dbUrl: z.string().url().startsWith('postgresql://'),
|
|
104
|
+
apiKey: z.string().min(32).max(128)
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
function loadConfig(): Result<Config, Error> {
|
|
108
|
+
const validation = ConfigSchema.safeParse({
|
|
109
|
+
port: process.env.PORT,
|
|
110
|
+
dbUrl: process.env.DATABASE_URL,
|
|
111
|
+
apiKey: process.env.API_KEY
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!validation.success) {
|
|
115
|
+
return {
|
|
116
|
+
ok: false,
|
|
117
|
+
error: new Error(`Invalid configuration: ${validation.error.message}`)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return { ok: true, value: validation.data };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Application initialization
|
|
125
|
+
const configResult = loadConfig();
|
|
126
|
+
if (!configResult.ok) {
|
|
127
|
+
console.error('Failed to load configuration:', configResult.error);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const config = configResult.value; // Type-safe, validated config
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Database Query with Validation
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const EmailSchema = z.string().email().max(255);
|
|
140
|
+
const SearchTermSchema = z.string().min(1).max(100).regex(/^[a-zA-Z0-9\s-]+$/);
|
|
141
|
+
|
|
142
|
+
async function getUserByEmail(email: unknown): Promise<Result<User, Error>> {
|
|
143
|
+
const validation = EmailSchema.safeParse(email);
|
|
144
|
+
|
|
145
|
+
if (!validation.success) {
|
|
146
|
+
return { ok: false, error: new Error('Invalid email format') };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
// Parameterized query prevents SQL injection
|
|
151
|
+
const user = await db.query('SELECT * FROM users WHERE email = $1', [validation.data]);
|
|
152
|
+
return { ok: true, value: user };
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return { ok: false, error: error as Error };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function searchUsers(searchTerm: unknown): Promise<Result<User[], Error>> {
|
|
159
|
+
const validation = SearchTermSchema.safeParse(searchTerm);
|
|
160
|
+
|
|
161
|
+
if (!validation.success) {
|
|
162
|
+
return { ok: false, error: new Error('Invalid search term') };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const users = await db.query(
|
|
167
|
+
'SELECT * FROM users WHERE name ILIKE $1',
|
|
168
|
+
[`%${validation.data}%`]
|
|
169
|
+
);
|
|
170
|
+
return { ok: true, value: users };
|
|
171
|
+
} catch (error) {
|
|
172
|
+
return { ok: false, error: error as Error };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## File Upload Validation
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const FileUploadSchema = z.object({
|
|
183
|
+
name: z.string().max(255).regex(/^[a-zA-Z0-9._-]+$/),
|
|
184
|
+
size: z.number().max(10 * 1024 * 1024), // 10MB max
|
|
185
|
+
mimetype: z.enum(['image/jpeg', 'image/png', 'application/pdf']),
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
async function handleUpload(file: unknown): Promise<Result<string, Error>> {
|
|
189
|
+
const validation = FileUploadSchema.safeParse(file);
|
|
190
|
+
|
|
191
|
+
if (!validation.success) {
|
|
192
|
+
return { ok: false, error: new Error('Invalid file') };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const { name, size, mimetype } = validation.data;
|
|
196
|
+
|
|
197
|
+
// Additional content validation
|
|
198
|
+
const buffer = await readFileBuffer(file);
|
|
199
|
+
const detectedType = await fileType.fromBuffer(buffer);
|
|
200
|
+
|
|
201
|
+
if (detectedType?.mime !== mimetype) {
|
|
202
|
+
return { ok: false, error: new Error('File type mismatch') };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Safe filename generation
|
|
206
|
+
const safeFilename = `${uuid()}_${name}`;
|
|
207
|
+
const safePath = path.join(UPLOAD_DIR, safeFilename);
|
|
208
|
+
|
|
209
|
+
await fs.writeFile(safePath, buffer);
|
|
210
|
+
return { ok: true, value: safeFilename };
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## URL Parameter Validation
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const UserIdSchema = z.string().uuid();
|
|
220
|
+
|
|
221
|
+
app.get('/users/:id', async (req, res) => {
|
|
222
|
+
const validation = UserIdSchema.safeParse(req.params.id);
|
|
223
|
+
|
|
224
|
+
if (!validation.success) {
|
|
225
|
+
return res.status(400).json({ error: 'Invalid user ID format' });
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const result = await getUserById(validation.data);
|
|
229
|
+
|
|
230
|
+
if (!result.ok) {
|
|
231
|
+
return res.status(404).json({ error: 'User not found' });
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
res.json(result.value);
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Query String Validation
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const SearchQuerySchema = z.object({
|
|
244
|
+
q: z.string().min(1).max(100),
|
|
245
|
+
page: z.coerce.number().int().min(1).default(1),
|
|
246
|
+
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
247
|
+
sort: z.enum(['name', 'date', 'relevance']).default('relevance'),
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
app.get('/search', async (req, res) => {
|
|
251
|
+
const validation = SearchQuerySchema.safeParse(req.query);
|
|
252
|
+
|
|
253
|
+
if (!validation.success) {
|
|
254
|
+
return res.status(400).json({
|
|
255
|
+
error: 'Invalid query parameters',
|
|
256
|
+
details: validation.error.issues
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const { q, page, limit, sort } = validation.data;
|
|
261
|
+
const results = await searchService.search(q, { page, limit, sort });
|
|
262
|
+
|
|
263
|
+
res.json(results);
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Webhook Signature Verification
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
const WebhookPayloadSchema = z.object({
|
|
273
|
+
event: z.enum(['payment.completed', 'payment.failed', 'subscription.created']),
|
|
274
|
+
data: z.object({
|
|
275
|
+
id: z.string(),
|
|
276
|
+
amount: z.number().optional(),
|
|
277
|
+
status: z.string(),
|
|
278
|
+
}),
|
|
279
|
+
timestamp: z.number(),
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
app.post('/webhook', async (req, res) => {
|
|
283
|
+
// 1. Verify signature first
|
|
284
|
+
const signature = req.headers['x-webhook-signature'];
|
|
285
|
+
const expectedSignature = crypto
|
|
286
|
+
.createHmac('sha256', WEBHOOK_SECRET)
|
|
287
|
+
.update(JSON.stringify(req.body))
|
|
288
|
+
.digest('hex');
|
|
289
|
+
|
|
290
|
+
if (signature !== expectedSignature) {
|
|
291
|
+
return res.status(401).json({ error: 'Invalid signature' });
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// 2. Then validate payload structure
|
|
295
|
+
const validation = WebhookPayloadSchema.safeParse(req.body);
|
|
296
|
+
|
|
297
|
+
if (!validation.success) {
|
|
298
|
+
return res.status(400).json({ error: 'Invalid payload' });
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 3. Process verified and validated event
|
|
302
|
+
await processWebhookEvent(validation.data);
|
|
303
|
+
res.sendStatus(200);
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## GraphQL Input Validation
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
const UserFilterSchema = z.object({
|
|
313
|
+
name: z.string().max(100).optional(),
|
|
314
|
+
email: z.string().email().optional(),
|
|
315
|
+
status: z.enum(['active', 'inactive']).optional(),
|
|
316
|
+
limit: z.number().int().min(1).max(100).default(20),
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const resolvers = {
|
|
320
|
+
Query: {
|
|
321
|
+
users: async (_, { filter }) => {
|
|
322
|
+
const validation = UserFilterSchema.safeParse(filter);
|
|
323
|
+
|
|
324
|
+
if (!validation.success) {
|
|
325
|
+
throw new GraphQLError('Invalid filter', {
|
|
326
|
+
extensions: { code: 'BAD_USER_INPUT' }
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return userService.findUsers(validation.data);
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Form Data Sanitization
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
import DOMPurify from 'isomorphic-dompurify';
|
|
342
|
+
|
|
343
|
+
const ProfileUpdateSchema = z.object({
|
|
344
|
+
bio: z.string().max(500).transform(s => DOMPurify.sanitize(s)),
|
|
345
|
+
website: z.string().url().optional(),
|
|
346
|
+
displayName: z.string().min(1).max(50),
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
app.post('/profile', async (req, res) => {
|
|
350
|
+
const validation = ProfileUpdateSchema.safeParse(req.body);
|
|
351
|
+
|
|
352
|
+
if (!validation.success) {
|
|
353
|
+
return res.status(400).json({ error: validation.error });
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// bio is already sanitized by the schema transform
|
|
357
|
+
await db.users.update(req.userId, validation.data);
|
|
358
|
+
|
|
359
|
+
res.json({ success: true });
|
|
360
|
+
});
|
|
361
|
+
```
|