@nerdev/skillset 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +351 -0
- package/bin/skillset.mjs +205 -0
- package/curations/README.md +53 -0
- package/curations/TEMPLATE/WHY.md +23 -0
- package/curations/TEMPLATE/overlay/SKILL.md +6 -0
- package/curations/impeccable/WHY.md +34 -0
- package/curations/impeccable/overlay/SKILL.md +116 -0
- package/package.json +43 -0
- package/scripts/ste-gate.mjs +39 -0
- package/scripts/ste-lint.py +201 -0
- package/scripts/sync.mjs +174 -0
- package/skills/ai-agent/agent-docs-writer/SKILL.md +105 -0
- package/skills/ai-agent/agent-docs-writer/references/principles.md +73 -0
- package/skills/ai-agent/agent-docs-writer/templates/AGENTS.template.md +44 -0
- package/skills/ai-agent/agent-docs-writer/templates/README.template.md +19 -0
- package/skills/ai-agent/ultra-context-engine/SKILL.md +941 -0
- package/skills/architecture/blueprint/SKILL.md +191 -0
- package/skills/architecture/code-tour/SKILL.md +204 -0
- package/skills/architecture/progress-guard/SKILL.md +148 -0
- package/skills/architecture/search-first/SKILL.md +97 -0
- package/skills/backend/api-design/SKILL.md +456 -0
- package/skills/backend/auth/SKILL.md +596 -0
- package/skills/backend/database/SKILL.md +431 -0
- package/skills/backend/realtime/SKILL.md +670 -0
- package/skills/backend/security/SKILL.md +590 -0
- package/skills/business/brag/SKILL.md +177 -0
- package/skills/business/brag/assets/music/README.md +20 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-1-by-ende-dot-app.music-cues.json +3846 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-1-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-10-by-ende-dot-app.music-cues.json +1826 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-10-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-11-by-ende-dot-app.music-cues.json +2266 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-11-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-12-by-ende-dot-app.music-cues.json +2806 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-12-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-9-by-ende-dot-app.music-cues.json +2796 -0
- package/skills/business/brag/assets/music/cues/happy-beats-business-moves-vol-9-by-ende-dot-app.music-cues.md +35 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-1-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-10-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-11-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-12-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/music/happy-beats-business-moves-vol-9-by-ende-dot-app.mp3 +0 -0
- package/skills/business/brag/assets/sfx/casino/card-fan-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-fan-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-place-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shove-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-shuffle.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-5.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-6.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-7.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/card-slide-8.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/cards-pack-open-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/cards-pack-open-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chip-lay-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chip-lay-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chip-lay-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-collide-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-handle-6.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-5.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/chips-stack-6.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-grab-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-grab-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-shake-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-shake-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-shake-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-throw-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-throw-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/dice-throw-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-1.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-2.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-3.ogg +0 -0
- package/skills/business/brag/assets/sfx/casino/die-throw-4.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_carpet_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_carpet_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_carpet_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_concrete_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_grass_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_snow_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/footstep_wood_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactBell_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactBell_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactBell_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGeneric_light_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactGlass_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMetal_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactMining_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlank_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_light_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPlate_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactPunch_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactSoft_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactTin_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_heavy_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_light_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_000.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/impact/impactWood_medium_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/bong_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/click_005.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/drop_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/drop_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/drop_003.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/error_005.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/error_006.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/glitch_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/glitch_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/select_008.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_001.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_002.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_004.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_005.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_006.ogg +0 -0
- package/skills/business/brag/assets/sfx/interface/switch_007.ogg +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-001.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-002.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-003.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-004.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-005.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-006.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-007.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-008.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-009.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-010.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-011.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-012.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-013.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-014.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-015.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-016.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-017.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-018.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-019.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-020.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-021.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-022.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-023.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-024.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-025.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-026.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-027.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-028.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-029.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-030.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-031.wav +0 -0
- package/skills/business/brag/assets/sfx/keyboard/keypress-032.wav +0 -0
- package/skills/business/brag/assets/sfx/sfx-analysis.json +15584 -0
- package/skills/business/brag/assets/sfx/sfx-analysis.md +75 -0
- package/skills/business/brag/assets/sfx/ui/click1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click2.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click3.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click4.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/click5.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/mouseclick1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover2.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover4.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/rollover5.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch1.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch10.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch11.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch12.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch13.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch14.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch15.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch16.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch17.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch18.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch19.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch2.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch20.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch21.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch22.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch23.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch24.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch25.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch26.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch27.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch28.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch29.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch3.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch30.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch31.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch32.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch33.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch34.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch35.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch36.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch37.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch38.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch4.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch5.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch6.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch7.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch8.ogg +0 -0
- package/skills/business/brag/assets/sfx/ui/switch9.ogg +0 -0
- package/skills/business/brag/references/audio.md +307 -0
- package/skills/business/brag/references/step-1-inspect.md +133 -0
- package/skills/business/brag/references/step-2-plan.md +234 -0
- package/skills/business/brag/references/step-3-compose.md +210 -0
- package/skills/business/brag/references/step-4-deliver.md +168 -0
- package/skills/business/brag/references/tones.md +231 -0
- package/skills/business/brag/scripts/analyze_music_cues.py +309 -0
- package/skills/business/brag/scripts/pyproject.toml +14 -0
- package/skills/business/brag/scripts/uv.lock +819 -0
- package/skills/business/copywriting/SKILL.md +178 -0
- package/skills/business/customer-research/SKILL.md +259 -0
- package/skills/business/freelancing/SKILL.md +679 -0
- package/skills/business/launch/SKILL.md +273 -0
- package/skills/business/marketing-psychology/SKILL.md +364 -0
- package/skills/business/pricing/SKILL.md +233 -0
- package/skills/business/resume-revamp-jake-ats/SKILL.md +64 -0
- package/skills/business/startup-founder/SKILL.md +400 -0
- package/skills/business/startup-founder/references/funding.md +48 -0
- package/skills/business/startup-founder/references/further-reading.md +132 -0
- package/skills/business/startup-founder/references/gtm-tools.md +57 -0
- package/skills/business/startup-founder/references/legal-india.md +36 -0
- package/skills/business/startup-founder/references/marketing/README.md +16 -0
- package/skills/business/startup-founder/references/marketing/cold-email.md +172 -0
- package/skills/business/startup-founder/references/marketing/competitors.md +245 -0
- package/skills/business/startup-founder/references/marketing/customer-research.md +276 -0
- package/skills/business/startup-founder/references/marketing/free-tools.md +168 -0
- package/skills/business/startup-founder/references/marketing/launch.md +343 -0
- package/skills/business/startup-founder/references/marketing/marketing-plan.md +270 -0
- package/skills/business/startup-founder/references/marketing/pricing.md +237 -0
- package/skills/business/startup-founder/references/marketing/product-marketing.md +250 -0
- package/skills/business/startup-founder/references/validation.md +267 -0
- package/skills/devops/deployments/SKILL.md +339 -0
- package/skills/devops/git-ci/SKILL.md +372 -0
- package/skills/devops/performance/SKILL.md +523 -0
- package/skills/devops/testing/SKILL.md +558 -0
- package/skills/engineering/code-review/SKILL.md +149 -0
- package/skills/engineering/coding-standards/SKILL.md +229 -0
- package/skills/engineering/product-engineering/SKILL.md +219 -0
- package/skills/engineering/senior-engineer-prompts/SKILL.md +145 -0
- package/skills/engineering/tdd-workflow/SKILL.md +178 -0
- package/skills/engineering/verification-loop/SKILL.md +199 -0
- package/skills/nerdev/nerdev-abstraction/SKILL.md +412 -0
- package/skills/nerdev/nerdev-docs/SKILL.md +527 -0
- package/skills/nerdev/nerdev-docs/templates/adr-template.md +39 -0
- package/skills/nerdev/nerdev-docs/templates/contributing-template.md +140 -0
- package/skills/nerdev/nerdev-docs/templates/deploy-template.md +426 -0
- package/skills/nerdev/nerdev-docs/templates/design-template.md +105 -0
- package/skills/nerdev/nerdev-docs/templates/incident-template.md +66 -0
- package/skills/nerdev/nerdev-monorepo/SKILL.md +522 -0
- package/skills/quality/output-skill/SKILL.md +49 -0
- package/skills/quality/unslop/SKILL.md +67 -0
- package/skills/ui/animaxxing/SKILL.md +58 -0
- package/skills/ui/animaxxing/agents/openai.yaml +7 -0
- package/skills/ui/animaxxing/references/effect-restoration.md +26 -0
- package/skills/ui/animaxxing/references/motion-vocabulary.md +142 -0
- package/skills/ui/animaxxing/references/recipes/blast-off.md +119 -0
- package/skills/ui/animaxxing/references/recipes/particle-effects.md +718 -0
- package/skills/ui/animaxxing/references/recipes/particle-field.md +428 -0
- package/skills/ui/animaxxing/references/recipes/route-letters.md +205 -0
- package/skills/ui/animaxxing/references/recipes/speak-in.md +181 -0
- package/skills/ui/animaxxing/references/recipes/split-entrances.md +345 -0
- package/skills/ui/animaxxing/references/recipes/wave.md +144 -0
- package/skills/ui/animaxxing/references/text-stability.md +68 -0
- package/skills/ui/animaxxing/references/verification.md +44 -0
- package/skills/ui/ask-animation/SKILL.md +178 -0
- package/skills/ui/ask-base-ui/SKILL.md +400 -0
- package/skills/ui/ask-cmdk/SKILL.md +315 -0
- package/skills/ui/ask-command-menu/SKILL.md +262 -0
- package/skills/ui/ask-drawer/SKILL.md +235 -0
- package/skills/ui/ask-form/SKILL.md +229 -0
- package/skills/ui/ask-gsap/SKILL.md +435 -0
- package/skills/ui/ask-modal/SKILL.md +145 -0
- package/skills/ui/ask-motion/SKILL.md +339 -0
- package/skills/ui/ask-rhf/SKILL.md +388 -0
- package/skills/ui/ask-sonner/API.md +64 -0
- package/skills/ui/ask-sonner/SKILL.md +88 -0
- package/skills/ui/ask-table/SKILL.md +253 -0
- package/skills/ui/ask-tanstack-table/SKILL.md +490 -0
- package/skills/ui/ask-toast/SKILL.md +163 -0
- package/skills/ui/ask-vaul/SKILL.md +291 -0
- package/skills/ui/ask-virtual-list/SKILL.md +304 -0
- package/skills/ui/ask-virtuoso/SKILL.md +332 -0
- package/skills/ui/email-craft/SKILL.md +258 -0
- package/skills/ui/frontend-craftsmanship/SKILL.md +462 -0
- package/skills/ui/gsap-astro/SKILL.md +56 -0
- package/skills/ui/gsap-astro/agents/openai.yaml +7 -0
- package/skills/ui/gsap-astro/references/client-router-navigation.md +139 -0
- package/skills/ui/gsap-astro/references/initialization.md +87 -0
- package/skills/ui/gsap-astro/references/motion-system.md +152 -0
- package/skills/ui/gsap-astro/references/scripts-and-islands.md +65 -0
- package/skills/ui/gsap-astro/references/verification.md +44 -0
- package/skills/ui/gsap-core/SKILL.md +254 -0
- package/skills/ui/gsap-frameworks/SKILL.md +266 -0
- package/skills/ui/gsap-nextjs/SKILL.md +51 -0
- package/skills/ui/gsap-nextjs/agents/openai.yaml +7 -0
- package/skills/ui/gsap-nextjs/references/app-router-navigation.md +189 -0
- package/skills/ui/gsap-nextjs/references/initialization.md +87 -0
- package/skills/ui/gsap-nextjs/references/motion-system.md +158 -0
- package/skills/ui/gsap-nextjs/references/verification.md +40 -0
- package/skills/ui/gsap-nuxt/SKILL.md +56 -0
- package/skills/ui/gsap-nuxt/agents/openai.yaml +7 -0
- package/skills/ui/gsap-nuxt/references/initialization.md +87 -0
- package/skills/ui/gsap-nuxt/references/motion-system.md +161 -0
- package/skills/ui/gsap-nuxt/references/navigation.md +145 -0
- package/skills/ui/gsap-nuxt/references/page-transitions.md +107 -0
- package/skills/ui/gsap-nuxt/references/verification.md +42 -0
- package/skills/ui/gsap-performance/SKILL.md +79 -0
- package/skills/ui/gsap-plugins/SKILL.md +433 -0
- package/skills/ui/gsap-react/SKILL.md +136 -0
- package/skills/ui/gsap-react-router/SKILL.md +55 -0
- package/skills/ui/gsap-react-router/agents/openai.yaml +7 -0
- package/skills/ui/gsap-react-router/references/initialization.md +87 -0
- package/skills/ui/gsap-react-router/references/motion-system.md +158 -0
- package/skills/ui/gsap-react-router/references/react-router-navigation.md +165 -0
- package/skills/ui/gsap-react-router/references/route-lifetime.md +74 -0
- package/skills/ui/gsap-react-router/references/verification.md +42 -0
- package/skills/ui/gsap-scrolltrigger/SKILL.md +296 -0
- package/skills/ui/gsap-sveltekit/SKILL.md +54 -0
- package/skills/ui/gsap-sveltekit/agents/openai.yaml +7 -0
- package/skills/ui/gsap-sveltekit/references/initialization.md +87 -0
- package/skills/ui/gsap-sveltekit/references/motion-system.md +156 -0
- package/skills/ui/gsap-sveltekit/references/page-lifetime.md +63 -0
- package/skills/ui/gsap-sveltekit/references/sveltekit-navigation.md +160 -0
- package/skills/ui/gsap-sveltekit/references/verification.md +41 -0
- package/skills/ui/gsap-tanstack-router/SKILL.md +56 -0
- package/skills/ui/gsap-tanstack-router/agents/openai.yaml +7 -0
- package/skills/ui/gsap-tanstack-router/references/initialization.md +87 -0
- package/skills/ui/gsap-tanstack-router/references/motion-system.md +160 -0
- package/skills/ui/gsap-tanstack-router/references/route-lifetime.md +66 -0
- package/skills/ui/gsap-tanstack-router/references/tanstack-navigation.md +156 -0
- package/skills/ui/gsap-tanstack-router/references/verification.md +41 -0
- package/skills/ui/gsap-timeline/SKILL.md +107 -0
- package/skills/ui/gsap-utils/SKILL.md +284 -0
- package/skills/ui/gsap-vanilla/SKILL.md +63 -0
- package/skills/ui/gsap-vanilla/agents/openai.yaml +7 -0
- package/skills/ui/gsap-vanilla/references/cross-document-navigation.md +54 -0
- package/skills/ui/gsap-vanilla/references/initialization.md +87 -0
- package/skills/ui/gsap-vanilla/references/motion-system.md +150 -0
- package/skills/ui/gsap-vanilla/references/page-load.md +96 -0
- package/skills/ui/gsap-vanilla/references/spa-navigation.md +70 -0
- package/skills/ui/gsap-vanilla/references/verification.md +41 -0
- package/skills/ui/house-style/SKILL.md +366 -0
- package/skills/ui/imagegen/SKILL.md +49 -0
- package/skills/ui/imagegen/references/brandkit.md +48 -0
- package/skills/ui/imagegen/references/image-to-code.md +56 -0
- package/skills/ui/imagegen/references/mobile.md +58 -0
- package/skills/ui/imagegen/references/web.md +63 -0
- package/skills/ui/impeccable/SKILL.md +116 -0
- package/skills/ui/impeccable/reference/adapt.md +318 -0
- package/skills/ui/impeccable/reference/adapt.native.md +58 -0
- package/skills/ui/impeccable/reference/android.md +46 -0
- package/skills/ui/impeccable/reference/animate.md +89 -0
- package/skills/ui/impeccable/reference/audit.md +137 -0
- package/skills/ui/impeccable/reference/audit.native.md +139 -0
- package/skills/ui/impeccable/reference/bolder.md +33 -0
- package/skills/ui/impeccable/reference/clarify.md +94 -0
- package/skills/ui/impeccable/reference/colorize.md +86 -0
- package/skills/ui/impeccable/reference/craft-floor.md +44 -0
- package/skills/ui/impeccable/reference/craft.md +5 -0
- package/skills/ui/impeccable/reference/critique.md +806 -0
- package/skills/ui/impeccable/reference/degraded/asset-producer.md +37 -0
- package/skills/ui/impeccable/reference/degraded/documenter.md +24 -0
- package/skills/ui/impeccable/reference/degraded/finish-reviewer.md +38 -0
- package/skills/ui/impeccable/reference/degraded/manual-edit-applier.md +92 -0
- package/skills/ui/impeccable/reference/delight.md +70 -0
- package/skills/ui/impeccable/reference/distill.md +111 -0
- package/skills/ui/impeccable/reference/doctor.md +54 -0
- package/skills/ui/impeccable/reference/document.md +416 -0
- package/skills/ui/impeccable/reference/extract.md +69 -0
- package/skills/ui/impeccable/reference/generate.md +101 -0
- package/skills/ui/impeccable/reference/harden.md +345 -0
- package/skills/ui/impeccable/reference/hooks.md +111 -0
- package/skills/ui/impeccable/reference/init.md +131 -0
- package/skills/ui/impeccable/reference/ios.md +51 -0
- package/skills/ui/impeccable/reference/layout.md +84 -0
- package/skills/ui/impeccable/reference/live-setup.md +104 -0
- package/skills/ui/impeccable/reference/live.md +325 -0
- package/skills/ui/impeccable/reference/new-work.md +145 -0
- package/skills/ui/impeccable/reference/onboard.md +234 -0
- package/skills/ui/impeccable/reference/operate.md +61 -0
- package/skills/ui/impeccable/reference/optimize.md +258 -0
- package/skills/ui/impeccable/reference/overdrive.md +127 -0
- package/skills/ui/impeccable/reference/polish.md +105 -0
- package/skills/ui/impeccable/reference/quieter.md +99 -0
- package/skills/ui/impeccable/reference/routing.md +24 -0
- package/skills/ui/impeccable/reference/shape.md +59 -0
- package/skills/ui/impeccable/reference/typeset.md +80 -0
- package/skills/ui/impeccable/reference/visualize.md +46 -0
- package/skills/ui/impeccable/scripts/VERSION +1 -0
- package/skills/ui/impeccable/scripts/command-metadata.json +98 -0
- package/skills/ui/impeccable/scripts/data/font-index-failures.json +121 -0
- package/skills/ui/impeccable/scripts/data/font-index.json +1 -0
- package/skills/ui/impeccable/scripts/impeccable +206 -0
- package/skills/ui/impeccable/scripts/impeccable.cmd +214 -0
- package/skills/ui/impeccable/scripts/live-browser-dom.js +167 -0
- package/skills/ui/impeccable/scripts/live-browser-ignores.js +242 -0
- package/skills/ui/impeccable/scripts/live-browser-session.js +144 -0
- package/skills/ui/impeccable/scripts/live-browser.js +13510 -0
- package/skills/ui/impeccable/scripts/modern-screenshot.umd.js +14 -0
- package/skills/ui/motion/SKILL.md +207 -0
- package/skills/ui/pick-ui-library/SKILL.md +85 -0
- package/skills/ui/product-messaging/SKILL.md +163 -0
- package/skills/ui/product-site/SKILL.md +465 -0
- package/skills/ui/prototype/PICKER.md +197 -0
- package/skills/ui/prototype/SKILL.md +98 -0
- package/skills/ui/refero-design/SKILL.md +534 -0
- package/skills/ui/refero-design/agents/openai.yaml +4 -0
- package/skills/ui/refero-design/references/anti-ai-slop.md +292 -0
- package/skills/ui/refero-design/references/color.md +563 -0
- package/skills/ui/refero-design/references/copywriting.md +222 -0
- package/skills/ui/refero-design/references/craft-details.md +525 -0
- package/skills/ui/refero-design/references/example-workflow.md +264 -0
- package/skills/ui/refero-design/references/icons.md +166 -0
- package/skills/ui/refero-design/references/mcp-tools.md +258 -0
- package/skills/ui/refero-design/references/motion.md +504 -0
- package/skills/ui/refero-design/references/typography.md +737 -0
- package/skills/ui/refero-design/references/visual-workflow.md +105 -0
- package/skills/ui/style-animaxxing/SKILL.md +48 -0
- package/skills/ui/style-animaxxing/agents/openai.yaml +7 -0
- package/skills/ui/style-animaxxing/references/motion-vocabulary.md +51 -0
- package/skills/ui/style-animaxxing/references/tokens.md +288 -0
- package/skills/ui/style-animaxxing/references/typography-and-layout.md +149 -0
- package/skills/ui/style-animaxxing/references/verification.md +38 -0
- package/skills/ui/typography-picker/SKILL.md +305 -0
- package/skills/ui/ui-core/SKILL.md +345 -0
- package/skills/ui/ui-core/references/accessibility.md +85 -0
- package/skills/ui/ui-core/references/build.md +666 -0
- package/skills/ui/ui-core/references/copy.md +70 -0
- package/skills/ui/ui-core/references/dark-mode.md +76 -0
- package/skills/ui/ui-core/references/direction.md +99 -0
- package/skills/ui/ui-core/references/redesign.md +74 -0
- package/skills/ui/ui-core/references/responsive.md +77 -0
- package/skills/ui/ui-core/references/styles.md +42 -0
- package/skills/ui/ui-core/references/system.md +190 -0
- package/skills/ui/ui-core/references/verify.md +37 -0
- package/skills/ui/ui-engineering/SKILL.md +436 -0
- package/skills/ui/ui-engineering/references/avatars.md +74 -0
- package/skills/ui/ui-engineering/references/card-patterns.md +66 -0
- package/skills/ui/ui-engineering/references/floating-actions.md +65 -0
- package/skills/ui/ui-engineering/references/navigation.md +81 -0
- package/skills/ui/ui-engineering/references/overlays.md +74 -0
- package/skills/ui/ui-engineering/references/pagination.md +71 -0
- package/skills/ui/ui-engineering/references/progress-indicators.md +77 -0
- package/skills/ui/ui-engineering/references/quality-bar.md +293 -0
- package/skills/ui/ui-engineering/references/search.md +68 -0
- package/skills/ui/ui-engineering/references/tailwind-architecture.md +81 -0
- package/skills/ui/ui-theme-picker/SKILL.md +522 -0
- package/skills/ui/ui-theme-picker/references/component-sources.md +223 -0
- package/skills/ui/ui-theme-picker/references/styles.md +298 -0
- package/skills/ui/vitepress-docs/SKILL.md +439 -0
- package/skills/ui/vitepress-docs/references/components.md +333 -0
- package/skills/ui/vitepress-docs/references/layout.md +128 -0
- package/skills/ui/vitepress-docs/references/tokens.md +87 -0
- package/skills/ui/vitepress-docs/references/typography.md +76 -0
- package/skills/workflow/careful/SKILL.md +48 -0
- package/skills/workflow/context-restore/SKILL.md +69 -0
- package/skills/workflow/context-save/SKILL.md +96 -0
- package/skills/workflow/health/SKILL.md +99 -0
- package/skills/workflow/learn/SKILL.md +95 -0
- package/skills/workflow/office-hours/SKILL.md +136 -0
- package/skills/workflow/ship/SKILL.md +95 -0
- package/vendor.json +80 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security
|
|
3
|
+
description: Application security , CSP, security headers, input validation, rate limiting, secrets management, authentication hardening, CORS, CSRF, XSS prevention, dependency scanning. Load when securing an app or reviewing security posture.
|
|
4
|
+
---
|
|
5
|
+
# Security , Hardening Applications
|
|
6
|
+
|
|
7
|
+
**When to use:** New project security setup, security review, hardening existing app, compliance prep.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Security Headers (Mandatory)
|
|
11
|
+
|
|
12
|
+
### Content Security Policy (CSP)
|
|
13
|
+
```typescript
|
|
14
|
+
// middleware.ts or nginx.conf
|
|
15
|
+
const csp = [
|
|
16
|
+
"default-src 'self'",
|
|
17
|
+
"script-src 'self' 'unsafe-inline' 'unsafe-eval'", // Tighten in prod
|
|
18
|
+
"style-src 'self' 'unsafe-inline'",
|
|
19
|
+
"img-src 'self' data: https:",
|
|
20
|
+
"font-src 'self' data:",
|
|
21
|
+
"connect-src 'self' https://api.example.com wss://ws.example.com",
|
|
22
|
+
"frame-ancestors 'none'",
|
|
23
|
+
"base-uri 'self'",
|
|
24
|
+
"form-action 'self'",
|
|
25
|
+
"frame-src 'none'",
|
|
26
|
+
"object-src 'none'",
|
|
27
|
+
].join('; ')
|
|
28
|
+
|
|
29
|
+
// With nonce for inline scripts (recommended)
|
|
30
|
+
const nonce = crypto.randomUUID()
|
|
31
|
+
const cspWithNonce = csp.replace(
|
|
32
|
+
"script-src 'self' 'unsafe-inline'",
|
|
33
|
+
`script-src 'self' 'nonce-${nonce}'`
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
### Security Headers Checklist
|
|
37
|
+
| Header | Value | Purpose |
|
|
38
|
+
|--------|-------|---------|
|
|
39
|
+
| `Content-Security-Policy` | Strict policy above | XSS prevention |
|
|
40
|
+
| `X-Frame-Options` | `DENY` | Clickjacking |
|
|
41
|
+
| `X-Content-Type-Options` | `nosniff` | MIME sniffing |
|
|
42
|
+
| `Referrer-Policy` | `strict-origin-when-cross-origin` | Referrer leakage |
|
|
43
|
+
| `Permissions-Policy` | `camera=(), microphone=(), geolocation=()` | Feature policy |
|
|
44
|
+
| `Strict-Transport-Security` | `max-age=31536000. includeSubDomains. preload` | HTTPS enforcement |
|
|
45
|
+
| `Cross-Origin-Opener-Policy` | `same-origin` | COOP |
|
|
46
|
+
| `Cross-Origin-Resource-Policy` | `same-origin` | CORP |
|
|
47
|
+
| `Cross-Origin-Embedder-Policy` | `require-corp` | COEP |
|
|
48
|
+
|
|
49
|
+
### Implementation (Bun/Elysia)
|
|
50
|
+
```typescript
|
|
51
|
+
// middleware/security.ts
|
|
52
|
+
export function securityHeaders() {
|
|
53
|
+
return (req: Request, next: () => Response) => {
|
|
54
|
+
const res = next()
|
|
55
|
+
const headers = new Headers(res.headers)
|
|
56
|
+
|
|
57
|
+
headers.set('Content-Security-Policy', csp)
|
|
58
|
+
headers.set('X-Frame-Options', 'DENY')
|
|
59
|
+
headers.set('X-Content-Type-Options', 'nosniff')
|
|
60
|
+
headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
|
|
61
|
+
headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
|
|
62
|
+
headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload')
|
|
63
|
+
headers.set('Cross-Origin-Opener-Policy', 'same-origin')
|
|
64
|
+
headers.set('Cross-Origin-Resource-Policy', 'same-origin')
|
|
65
|
+
headers.set('Cross-Origin-Embedder-Policy', 'require-corp')
|
|
66
|
+
|
|
67
|
+
return new Response(res.body, { status: res.status, headers })
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## CORS Configuration
|
|
73
|
+
```typescript
|
|
74
|
+
// Strict CORS - only allow your domains
|
|
75
|
+
const cors = {
|
|
76
|
+
origin: [
|
|
77
|
+
'https://app.example.com',
|
|
78
|
+
'https://admin.example.com',
|
|
79
|
+
'http://localhost:5173', // Dev only
|
|
80
|
+
],
|
|
81
|
+
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
|
82
|
+
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
|
|
83
|
+
exposedHeaders: ['X-Request-Id'],
|
|
84
|
+
credentials: true, // Only if using cookies
|
|
85
|
+
maxAge: 86400, // 24 hours
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Never use: origin: '*' with credentials: true
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Rate Limiting
|
|
92
|
+
|
|
93
|
+
### Sliding Window (Redis)
|
|
94
|
+
```typescript
|
|
95
|
+
// lib/rate-limit.ts
|
|
96
|
+
import { Redis } from '@upstash/redis'
|
|
97
|
+
|
|
98
|
+
const redis = new Redis({ url: process.env.REDIS_URL!, token: process.env.REDIS_TOKEN! })
|
|
99
|
+
|
|
100
|
+
export async function rateLimit(
|
|
101
|
+
key: string,
|
|
102
|
+
limit: number,
|
|
103
|
+
windowMs: number
|
|
104
|
+
): Promise<{ success: boolean; remaining: number; reset: number }> {
|
|
105
|
+
const now = Date.now()
|
|
106
|
+
const windowStart = now - windowMs
|
|
107
|
+
|
|
108
|
+
const pipeline = redis.pipeline()
|
|
109
|
+
pipeline.zremrangebyscore(key, 0, windowStart)
|
|
110
|
+
pipeline.zcard(key)
|
|
111
|
+
pipeline.zadd(key, { score: now, member: `${now}-${Math.random()}` })
|
|
112
|
+
pipeline.expire(key, Math.ceil(windowMs / 1000))
|
|
113
|
+
|
|
114
|
+
const results = await pipeline.exec()
|
|
115
|
+
const current = results[1] as number
|
|
116
|
+
|
|
117
|
+
if (current >= limit) {
|
|
118
|
+
const oldest = await redis.zrange(key, 0, 0, { withScores: true })
|
|
119
|
+
const reset = oldest[0] ? oldest[0].score + windowMs : now + windowMs
|
|
120
|
+
return { success: false, remaining: 0, reset }
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return { success: true, remaining: limit - current - 1, reset: now + windowMs }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Usage
|
|
127
|
+
export function rateLimitMiddleware(limit = 100, windowMs = 60000) {
|
|
128
|
+
return async (req: Request, next: () => Response) => {
|
|
129
|
+
const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || 'unknown'
|
|
130
|
+
const key = `ratelimit:${ip}`
|
|
131
|
+
|
|
132
|
+
const { success, remaining, reset } = await rateLimit(key, limit, windowMs)
|
|
133
|
+
|
|
134
|
+
if (!success) {
|
|
135
|
+
return new Response('Too Many Requests', {
|
|
136
|
+
status: 429,
|
|
137
|
+
headers: {
|
|
138
|
+
'Retry-After': String(Math.ceil((reset - Date.now()) / 1000)),
|
|
139
|
+
'X-RateLimit-Limit': String(limit),
|
|
140
|
+
'X-RateLimit-Remaining': '0',
|
|
141
|
+
'X-RateLimit-Reset': String(Math.ceil(reset / 1000)),
|
|
142
|
+
},
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const res = next()
|
|
147
|
+
res.headers.set('X-RateLimit-Limit', String(limit))
|
|
148
|
+
res.headers.set('X-RateLimit-Remaining', String(remaining))
|
|
149
|
+
res.headers.set('X-RateLimit-Reset', String(Math.ceil(reset / 1000)))
|
|
150
|
+
return res
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
### Per-Route Limits
|
|
155
|
+
| Route | Limit | Window |
|
|
156
|
+
|-------|-------|--------|
|
|
157
|
+
| `/auth/signin` | 5 | 15 min |
|
|
158
|
+
| `/auth/signup` | 3 | 15 min |
|
|
159
|
+
| `/auth/forgot-password` | 2 | 1 hour |
|
|
160
|
+
| `/api/*` | 100 | 1 min |
|
|
161
|
+
| `/ws` | 30 | 1 min (connections) |
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
## Input Validation (Zod)
|
|
165
|
+
```typescript
|
|
166
|
+
// schemas/common.ts
|
|
167
|
+
import { z } from 'zod'
|
|
168
|
+
|
|
169
|
+
// Sanitize strings
|
|
170
|
+
export const sanitizedString = (max = 1000) =>
|
|
171
|
+
z.string().max(max).transform(s => s.trim().replace(/[\x00-\x1F\x7F]/g, ''))
|
|
172
|
+
|
|
173
|
+
// Email
|
|
174
|
+
export const emailSchema = z.string().email().max(254).toLowerCase()
|
|
175
|
+
|
|
176
|
+
// Password (OWASP recommended)
|
|
177
|
+
export const passwordSchema = z
|
|
178
|
+
.string()
|
|
179
|
+
.min(12)
|
|
180
|
+
.max(128)
|
|
181
|
+
.regex(/[A-Z]/, 'Must contain uppercase')
|
|
182
|
+
.regex(/[a-z]/, 'Must contain lowercase')
|
|
183
|
+
.regex(/[0-9]/, 'Must contain number')
|
|
184
|
+
.regex(/[^A-Za-z0-9]/, 'Must contain special char')
|
|
185
|
+
|
|
186
|
+
// UUID
|
|
187
|
+
export const uuidSchema = z.string().uuid()
|
|
188
|
+
|
|
189
|
+
// Pagination
|
|
190
|
+
export const paginationSchema = z.object({
|
|
191
|
+
page: z.coerce.number().int().min(1).default(1),
|
|
192
|
+
limit: z.coerce.number().int().min(1).max(100).default(25),
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
// File upload
|
|
196
|
+
export const fileUploadSchema = z.object({
|
|
197
|
+
filename: z.string().max(255),
|
|
198
|
+
mimetype: z.enum(['image/jpeg', 'image/png', 'image/webp', 'application/pdf']),
|
|
199
|
+
size: z.number().max(10 * 1024 * 1024), // 10MB
|
|
200
|
+
})
|
|
201
|
+
```
|
|
202
|
+
### Validation Middleware
|
|
203
|
+
```typescript
|
|
204
|
+
export function validateBody<T>(schema: z.ZodSchema<T>) {
|
|
205
|
+
return async (req: Request, next: (body: T) => Response) => {
|
|
206
|
+
const body = await req.json()
|
|
207
|
+
const result = schema.safeParse(body)
|
|
208
|
+
|
|
209
|
+
if (!result.success) {
|
|
210
|
+
return Response.json(
|
|
211
|
+
{ error: 'Validation failed', details: result.error.flatten() },
|
|
212
|
+
{ status: 400 }
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return next(result.data)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Authentication Hardening
|
|
222
|
+
|
|
223
|
+
### Password Hashing
|
|
224
|
+
```typescript
|
|
225
|
+
// lib/auth/password.ts
|
|
226
|
+
import { hash, verify } from '@node-rs/argon2'
|
|
227
|
+
|
|
228
|
+
export async function hashPassword(password: string): Promise<string> {
|
|
229
|
+
return hash(password, {
|
|
230
|
+
memoryCost: 19456, // ~19 MB
|
|
231
|
+
timeCost: 2,
|
|
232
|
+
parallelism: 1,
|
|
233
|
+
outputLen: 32,
|
|
234
|
+
type: 'Argon2id',
|
|
235
|
+
})
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export async function verifyPassword(password: string, hash: string): Promise<boolean> {
|
|
239
|
+
return verify(hash, password)
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
### JWT Security
|
|
243
|
+
```typescript
|
|
244
|
+
// lib/auth/jwt.ts
|
|
245
|
+
import { SignJWT, jwtVerify } from 'jose'
|
|
246
|
+
|
|
247
|
+
const secret = new TextEncoder().encode(process.env.JWT_SECRET!)
|
|
248
|
+
const issuer = 'my-app'
|
|
249
|
+
const audience = 'my-app-users'
|
|
250
|
+
|
|
251
|
+
export async function createToken(payload: object, expiresIn = '15m') {
|
|
252
|
+
return new SignJWT(payload)
|
|
253
|
+
.setProtectedHeader({ alg: 'HS256' })
|
|
254
|
+
.setIssuedAt()
|
|
255
|
+
.setIssuer(issuer)
|
|
256
|
+
.setAudience(audience)
|
|
257
|
+
.setExpirationTime(expiresIn)
|
|
258
|
+
.sign(secret)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export async function verifyToken(token: string) {
|
|
262
|
+
const { payload } = await jwtVerify(token, secret, { issuer, audience })
|
|
263
|
+
return payload
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Short-lived access token (15min) + refresh token (7 days, httpOnly cookie)
|
|
267
|
+
// Rotate refresh tokens on use
|
|
268
|
+
```
|
|
269
|
+
### Session Security
|
|
270
|
+
```typescript
|
|
271
|
+
// lib/auth/session.ts
|
|
272
|
+
import { createClient } from 'redis'
|
|
273
|
+
|
|
274
|
+
const redis = createClient({ url: process.env.REDIS_URL! })
|
|
275
|
+
|
|
276
|
+
export async function createSession(userId: string, metadata: object) {
|
|
277
|
+
const sessionId = crypto.randomUUID()
|
|
278
|
+
const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000 // 7 days
|
|
279
|
+
|
|
280
|
+
await redis.hSet(`session:${sessionId}`, {
|
|
281
|
+
userId,
|
|
282
|
+
metadata: JSON.stringify(metadata),
|
|
283
|
+
createdAt: Date.now().toString(),
|
|
284
|
+
expiresAt: expiresAt.toString(),
|
|
285
|
+
})
|
|
286
|
+
await redis.expire(`session:${sessionId}`, 7 * 24 * 60 * 60)
|
|
287
|
+
|
|
288
|
+
return sessionId
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export async function validateSession(sessionId: string) {
|
|
292
|
+
const session = await redis.hGetAll(`session:${sessionId}`)
|
|
293
|
+
if (!session || Date.now() > parseInt(session.expiresAt)) {
|
|
294
|
+
await redis.del(`session:${sessionId}`)
|
|
295
|
+
return null
|
|
296
|
+
}
|
|
297
|
+
return { userId: session.userId, metadata: JSON.parse(session.metadata) }
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export async function revokeSession(sessionId: string) {
|
|
301
|
+
await redis.del(`session:${sessionId}`)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export async function revokeAllUserSessions(userId: string) {
|
|
305
|
+
const keys = await redis.keys(`session:*`)
|
|
306
|
+
for (const key of keys) {
|
|
307
|
+
const session = await redis.hGetAll(key)
|
|
308
|
+
if (session.userId === userId) await redis.del(key)
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Secrets Management
|
|
314
|
+
|
|
315
|
+
### Environment Variables
|
|
316
|
+
```bash
|
|
317
|
+
# .env.example (tracked)
|
|
318
|
+
DATABASE_URL=
|
|
319
|
+
JWT_SECRET=
|
|
320
|
+
ENCRYPTION_KEY=
|
|
321
|
+
REDIS_URL=
|
|
322
|
+
REDIS_TOKEN=
|
|
323
|
+
SENTRY_DSN=
|
|
324
|
+
|
|
325
|
+
# .env.production (NOT tracked - use secrets manager)
|
|
326
|
+
# AWS Secrets Manager / Vercel Env / Railway Variables / Doppler
|
|
327
|
+
```
|
|
328
|
+
### Secrets in CI
|
|
329
|
+
```yaml
|
|
330
|
+
# GitHub Actions - use environments with protection rules
|
|
331
|
+
jobs:
|
|
332
|
+
deploy:
|
|
333
|
+
environment: production
|
|
334
|
+
# Requires approval, secrets only available here
|
|
335
|
+
steps:
|
|
336
|
+
- run: echo ${{ secrets.DATABASE_URL }}
|
|
337
|
+
```
|
|
338
|
+
### Encryption at Rest
|
|
339
|
+
```typescript
|
|
340
|
+
// lib/crypto.ts
|
|
341
|
+
import { encrypt, decrypt } from '@node-rs/aes-gcm'
|
|
342
|
+
|
|
343
|
+
const key = new TextEncoder().encode(process.env.ENCRYPTION_KEY!.padEnd(32, '0').slice(0, 32))
|
|
344
|
+
|
|
345
|
+
export function encryptData(data: string): string {
|
|
346
|
+
const iv = crypto.getRandomValues(new Uint8Array(12))
|
|
347
|
+
const ciphertext = encrypt(key, new TextEncoder().encode(data), iv)
|
|
348
|
+
return Buffer.from(iv).toString('base64') + ':' + Buffer.from(ciphertext).toString('base64')
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export function decryptData(encrypted: string): string {
|
|
352
|
+
const [ivB64, ctB64] = encrypted.split(':')
|
|
353
|
+
const iv = Buffer.from(ivB64, 'base64')
|
|
354
|
+
const ciphertext = Buffer.from(ctB64, 'base64')
|
|
355
|
+
const plaintext = decrypt(key, ciphertext, iv)
|
|
356
|
+
return new TextDecoder().decode(plaintext)
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Dependency Security
|
|
361
|
+
```bash
|
|
362
|
+
# Audit
|
|
363
|
+
bun audit # or npm audit
|
|
364
|
+
bun audit --json # CI parsing
|
|
365
|
+
|
|
366
|
+
# Fix
|
|
367
|
+
bun audit --fix
|
|
368
|
+
|
|
369
|
+
# SBOM
|
|
370
|
+
bun x @cyclonedx/bom --format json > sbom.json
|
|
371
|
+
|
|
372
|
+
# Block vulnerable deps in CI
|
|
373
|
+
# .github/workflows/security.yml
|
|
374
|
+
- name: Audit
|
|
375
|
+
run: |
|
|
376
|
+
bun audit --audit-level=high
|
|
377
|
+
# Fail on high/critical
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Security Checklist (Per Deploy)
|
|
381
|
+
|
|
382
|
+
- [ ] CSP implemented and tested (report-only first)
|
|
383
|
+
- [ ] All security headers present
|
|
384
|
+
- [ ] CORS restricted to known origins
|
|
385
|
+
- [ ] Rate limiting on all auth endpoints
|
|
386
|
+
- [ ] Input validation on all endpoints (Zod)
|
|
387
|
+
- [ ] Passwords: Argon2id, cost calibrated
|
|
388
|
+
- [ ] JWT: HS256/RS256, short expiry, rotation
|
|
389
|
+
- [ ] Sessions: httpOnly, secure, sameSite=lax, Redis-backed
|
|
390
|
+
- [ ] Secrets: Never in code, rotated quarterly
|
|
391
|
+
- [ ] Dependencies: `bun audit` passes, Dependabot enabled
|
|
392
|
+
- [ ] HTTPS: HSTS, cert monitoring
|
|
393
|
+
- [ ] Error messages: No stack traces in production
|
|
394
|
+
- [ ] Logging: No PII/secrets in logs
|
|
395
|
+
- [ ] File uploads: Type/size validation, virus scan
|
|
396
|
+
- [ ] SQL injection: Parameterized queries only (Prisma)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
## NASA Safety-Critical Coding Rules
|
|
400
|
+
|
|
401
|
+
**When to use:** Safety-critical systems, high-reliability software, avionics, medical devices, automotive systems, or any code where failure could cause harm.
|
|
402
|
+
|
|
403
|
+
### The 10 Rules
|
|
404
|
+
|
|
405
|
+
1. **Restrict all code to very simple control flow constructs**
|
|
406
|
+
- Do not use `goto` statements, `setjmp` or `longjmp` constructs, or direct/indirect recursion
|
|
407
|
+
- Use structured control flow only: `if/else`, `for`, `while`, `switch`
|
|
408
|
+
|
|
409
|
+
2. **Give all loops a fixed upper bound**
|
|
410
|
+
- Prevent infinite loops with explicit iteration limits
|
|
411
|
+
- All loops must have provable termination conditions
|
|
412
|
+
|
|
413
|
+
3. **Do not use dynamic memory allocation after initialization**
|
|
414
|
+
- No `malloc`, `calloc`, `realloc`, `new`, or `delete` after program start
|
|
415
|
+
- Allocate all memory at compile-time or during initialization phase
|
|
416
|
+
- Prevents memory leaks, fragmentation, and non-deterministic behavior
|
|
417
|
+
|
|
418
|
+
4. **No function should be longer than what can be printed on a single sheet of paper**
|
|
419
|
+
- One line per statement, one line per declaration
|
|
420
|
+
- Typically 50-60 lines maximum
|
|
421
|
+
- Forces modular, testable design
|
|
422
|
+
|
|
423
|
+
5. **The code's assertion density should average to minimally two assertions per function**
|
|
424
|
+
- Verify all assumptions about data and state
|
|
425
|
+
- Check preconditions, postconditions, and invariants
|
|
426
|
+
- Assertions should never have side effects
|
|
427
|
+
|
|
428
|
+
6. **Declare all data objects at the smallest possible level of scope**
|
|
429
|
+
- Minimize variable lifetime and visibility
|
|
430
|
+
- Reduces state-related bugs and naming conflicts
|
|
431
|
+
- Use block scoping wherever possible
|
|
432
|
+
|
|
433
|
+
7. **Each calling function must check the return value of nonvoid functions, and each called function must check the validity of all parameters provided by the caller**
|
|
434
|
+
- No ignored return values
|
|
435
|
+
- Validate all inputs at function entry
|
|
436
|
+
- Defensive programming throughout the call stack
|
|
437
|
+
|
|
438
|
+
8. **The use of the preprocessor must be limited to the inclusion of header files and simple macro definitions**
|
|
439
|
+
- No complex macros with logic, loops, or conditional compilation
|
|
440
|
+
- Avoid token-pasting, stringification beyond simple use
|
|
441
|
+
- Keep preprocessor usage predictable and auditable
|
|
442
|
+
|
|
443
|
+
9. **Limit pointer use to a single dereference, and do not use function pointers**
|
|
444
|
+
- No pointer-to-pointer dereferencing
|
|
445
|
+
- No function pointers or callbacks via function pointers
|
|
446
|
+
- Simplifies memory access patterns and static analysis
|
|
447
|
+
|
|
448
|
+
10. **Compile with all possible warnings active; all warnings should then be addressed before release**
|
|
449
|
+
- Enable strict compiler warnings (`-Wall -Wextra -Werror`)
|
|
450
|
+
- Treat all warnings as errors
|
|
451
|
+
- Zero-warning policy before any release
|
|
452
|
+
|
|
453
|
+
### Implementation Checklist
|
|
454
|
+
|
|
455
|
+
- [ ] No recursion (direct or indirect) in codebase
|
|
456
|
+
- [ ] All loops have fixed upper bounds
|
|
457
|
+
- [ ] No dynamic allocation after initialization
|
|
458
|
+
- [ ] Functions under 60 lines
|
|
459
|
+
- [ ] Average 2+ assertions per function
|
|
460
|
+
- [ ] Variables declared at smallest scope
|
|
461
|
+
- [ ] All function return values checked
|
|
462
|
+
- [ ] All function parameters validated
|
|
463
|
+
- [ ] Preprocessor limited to includes and simple macros
|
|
464
|
+
- [ ] Single-level pointer dereferences only
|
|
465
|
+
- [ ] No function pointers
|
|
466
|
+
- [ ] All compiler warnings enabled and resolved
|
|
467
|
+
|
|
468
|
+
### TypeScript/JavaScript Adaptations
|
|
469
|
+
|
|
470
|
+
```typescript
|
|
471
|
+
// ✅ Rule 1: Simple control flow only
|
|
472
|
+
// No recursion - use iteration instead
|
|
473
|
+
function traverseTree(root: TreeNode): void {
|
|
474
|
+
const stack: TreeNode[] = [root]
|
|
475
|
+
while (stack.length > 0) {
|
|
476
|
+
const node = stack.pop()!
|
|
477
|
+
process(node)
|
|
478
|
+
if (node.right) stack.push(node.right)
|
|
479
|
+
if (node.left) stack.push(node.left)
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// ✅ Rule 2: Fixed upper bound on loops
|
|
484
|
+
function processData(items: unknown[]): void {
|
|
485
|
+
const MAX_ITERATIONS = 10000
|
|
486
|
+
let i = 0
|
|
487
|
+
while (i < items.length && i < MAX_ITERATIONS) {
|
|
488
|
+
process(items[i])
|
|
489
|
+
i++
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// ✅ Rule 3: No dynamic allocation after init
|
|
494
|
+
const BUFFER_SIZE = 1024
|
|
495
|
+
const buffer = new ArrayBuffer(BUFFER_SIZE) // Allocated at init
|
|
496
|
+
|
|
497
|
+
// ✅ Rule 4: Short functions
|
|
498
|
+
function validateInput(input: unknown): boolean {
|
|
499
|
+
if (typeof input !== 'string') return false
|
|
500
|
+
if (input.length === 0) return false
|
|
501
|
+
if (input.length > 255) return false
|
|
502
|
+
return true
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// ✅ Rule 5: Assertions
|
|
506
|
+
function divide(a: number, b: number): number {
|
|
507
|
+
assert(a !== 0, 'Dividend cannot be zero')
|
|
508
|
+
assert(b !== 0, 'Divisor cannot be zero')
|
|
509
|
+
assert(Number.isFinite(a), 'Dividend must be finite')
|
|
510
|
+
assert(Number.isFinite(b), 'Divisor must be finite')
|
|
511
|
+
return a / b
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// ✅ Rule 6: Smallest scope
|
|
515
|
+
function processOrder(order: Order): void {
|
|
516
|
+
const total = calculateTotal(order.items)
|
|
517
|
+
if (total > 0) {
|
|
518
|
+
const discount = applyDiscount(total)
|
|
519
|
+
const final = total - discount
|
|
520
|
+
assert(final >= 0, 'Final price cannot be negative')
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// ✅ Rule 7: Check return values and validate params
|
|
525
|
+
function getUser(id: string): User | null {
|
|
526
|
+
assert(typeof id === 'string', 'ID must be string')
|
|
527
|
+
assert(id.length > 0, 'ID cannot be empty')
|
|
528
|
+
|
|
529
|
+
const result = db.findUser(id)
|
|
530
|
+
if (result.error) {
|
|
531
|
+
logError(result.error)
|
|
532
|
+
return null
|
|
533
|
+
}
|
|
534
|
+
return result.data
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// ✅ Rule 8: Simple macros/includes only (TypeScript has no preprocessor)
|
|
538
|
+
// Just use imports and const values
|
|
539
|
+
const MAX_RETRIES = 3 as const
|
|
540
|
+
import { validate } from './validators'
|
|
541
|
+
|
|
542
|
+
// ✅ Rule 9: Single dereference (no function pointers)
|
|
543
|
+
// Use strategy pattern or dependency injection instead
|
|
544
|
+
type Processor = (data: Data) => Result
|
|
545
|
+
function execute(processor: Processor, data: Data): Result {
|
|
546
|
+
return processor(data)
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// ✅ Rule 10: Strict TypeScript config
|
|
550
|
+
// tsconfig.json
|
|
551
|
+
{
|
|
552
|
+
"compilerOptions": {
|
|
553
|
+
"strict": true,
|
|
554
|
+
"noUncheckedIndexedAccess": true,
|
|
555
|
+
"noImplicitReturns": true,
|
|
556
|
+
"noFallthroughCasesInSwitch": true,
|
|
557
|
+
"noImplicitOverride": true
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Static Analysis Tools
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
# ESLint with strict rules
|
|
566
|
+
bun add -d eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
|
|
567
|
+
|
|
568
|
+
# Recommended .eslintrc
|
|
569
|
+
{
|
|
570
|
+
"extends": [
|
|
571
|
+
"eslint:recommended",
|
|
572
|
+
"plugin:@typescript-eslint/strict-type-checked"
|
|
573
|
+
],
|
|
574
|
+
"rules": {
|
|
575
|
+
"@typescript-eslint/no-unused-vars": "error",
|
|
576
|
+
"@typescript-eslint/no-floating-promises": "error",
|
|
577
|
+
"@typescript-eslint/no-misused-promises": "error",
|
|
578
|
+
"no-constant-condition": "error",
|
|
579
|
+
"no-constant-binary-expression": "error",
|
|
580
|
+
"no-constructor-return": "error"
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
## Related Skills
|
|
586
|
+
- `backend/auth` - Authentication patterns
|
|
587
|
+
- `backend/api-design` - Secure API conventions
|
|
588
|
+
- `backend/database` - Prisma security
|
|
589
|
+
- `devops/deployments` - Production hardening
|
|
590
|
+
- `engineering/code-review` - Security review process
|