dev-booster 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/README.md +203 -0
  2. package/bin/dev-booster.js +4 -0
  3. package/package.json +41 -0
  4. package/src/index.js +78 -0
  5. package/src/sync-template.js +55 -0
  6. package/template/.devbooster/MANIFEST.md +177 -0
  7. package/template/.devbooster/boosters/accessibility.md +63 -0
  8. package/template/.devbooster/boosters/advisor.md +68 -0
  9. package/template/.devbooster/boosters/atomic.md +58 -0
  10. package/template/.devbooster/boosters/backend.md +75 -0
  11. package/template/.devbooster/boosters/changelog.md +126 -0
  12. package/template/.devbooster/boosters/create.md +85 -0
  13. package/template/.devbooster/boosters/debug.md +55 -0
  14. package/template/.devbooster/boosters/deploy.md +11 -0
  15. package/template/.devbooster/boosters/design.md +56 -0
  16. package/template/.devbooster/boosters/discovery.md +75 -0
  17. package/template/.devbooster/boosters/documentation.md +106 -0
  18. package/template/.devbooster/boosters/frontend.md +82 -0
  19. package/template/.devbooster/boosters/i18n.md +63 -0
  20. package/template/.devbooster/boosters/implementation.md +82 -0
  21. package/template/.devbooster/boosters/investigation.md +96 -0
  22. package/template/.devbooster/boosters/mobile.md +56 -0
  23. package/template/.devbooster/boosters/performance.md +70 -0
  24. package/template/.devbooster/boosters/planning.md +92 -0
  25. package/template/.devbooster/boosters/refactor.md +17 -0
  26. package/template/.devbooster/boosters/review.md +88 -0
  27. package/template/.devbooster/boosters/security.md +60 -0
  28. package/template/.devbooster/boosters/seo.md +59 -0
  29. package/template/.devbooster/boosters/templates/implementation_heavy.md +130 -0
  30. package/template/.devbooster/boosters/templates/implementation_simple.md +109 -0
  31. package/template/.devbooster/boosters/templates/implementation_standard.md +134 -0
  32. package/template/.devbooster/boosters/testing.md +76 -0
  33. package/template/.devbooster/hub/personas/agent_backend-specialist.md +263 -0
  34. package/template/.devbooster/hub/personas/agent_code-archaeologist.md +106 -0
  35. package/template/.devbooster/hub/personas/agent_database-architect.md +226 -0
  36. package/template/.devbooster/hub/personas/agent_debugger.md +225 -0
  37. package/template/.devbooster/hub/personas/agent_devops-engineer.md +242 -0
  38. package/template/.devbooster/hub/personas/agent_documentation-writer.md +104 -0
  39. package/template/.devbooster/hub/personas/agent_explorer-agent.md +73 -0
  40. package/template/.devbooster/hub/personas/agent_frontend-specialist.md +593 -0
  41. package/template/.devbooster/hub/personas/agent_game-developer.md +162 -0
  42. package/template/.devbooster/hub/personas/agent_mobile-developer.md +377 -0
  43. package/template/.devbooster/hub/personas/agent_orchestrator.md +416 -0
  44. package/template/.devbooster/hub/personas/agent_penetration-tester.md +188 -0
  45. package/template/.devbooster/hub/personas/agent_performance-optimizer.md +187 -0
  46. package/template/.devbooster/hub/personas/agent_product-manager.md +112 -0
  47. package/template/.devbooster/hub/personas/agent_product-owner.md +95 -0
  48. package/template/.devbooster/hub/personas/agent_project-planner.md +406 -0
  49. package/template/.devbooster/hub/personas/agent_qa-automation-engineer.md +103 -0
  50. package/template/.devbooster/hub/personas/agent_security-auditor.md +170 -0
  51. package/template/.devbooster/hub/personas/agent_seo-specialist.md +111 -0
  52. package/template/.devbooster/hub/personas/agent_test-engineer.md +158 -0
  53. package/template/.devbooster/hub/personas/backend-specialist.md +263 -0
  54. package/template/.devbooster/hub/personas/brainstorm.md +113 -0
  55. package/template/.devbooster/hub/personas/code-archaeologist.md +106 -0
  56. package/template/.devbooster/hub/personas/create.md +59 -0
  57. package/template/.devbooster/hub/personas/database-architect.md +226 -0
  58. package/template/.devbooster/hub/personas/debug.md +103 -0
  59. package/template/.devbooster/hub/personas/debugger.md +225 -0
  60. package/template/.devbooster/hub/personas/deploy.md +176 -0
  61. package/template/.devbooster/hub/personas/devops-engineer.md +242 -0
  62. package/template/.devbooster/hub/personas/documentation-writer.md +104 -0
  63. package/template/.devbooster/hub/personas/enhance.md +63 -0
  64. package/template/.devbooster/hub/personas/explorer-agent.md +73 -0
  65. package/template/.devbooster/hub/personas/frontend-specialist.md +593 -0
  66. package/template/.devbooster/hub/personas/game-developer.md +162 -0
  67. package/template/.devbooster/hub/personas/mobile-developer.md +377 -0
  68. package/template/.devbooster/hub/personas/orchestrate.md +237 -0
  69. package/template/.devbooster/hub/personas/orchestrator.md +416 -0
  70. package/template/.devbooster/hub/personas/penetration-tester.md +188 -0
  71. package/template/.devbooster/hub/personas/performance-optimizer.md +187 -0
  72. package/template/.devbooster/hub/personas/plan.md +89 -0
  73. package/template/.devbooster/hub/personas/preview.md +81 -0
  74. package/template/.devbooster/hub/personas/product-manager.md +112 -0
  75. package/template/.devbooster/hub/personas/product-owner.md +95 -0
  76. package/template/.devbooster/hub/personas/project-planner.md +406 -0
  77. package/template/.devbooster/hub/personas/qa-automation-engineer.md +103 -0
  78. package/template/.devbooster/hub/personas/security-auditor.md +170 -0
  79. package/template/.devbooster/hub/personas/seo-specialist.md +111 -0
  80. package/template/.devbooster/hub/personas/skill_api-patterns.md +567 -0
  81. package/template/.devbooster/hub/personas/skill_app-builder.md +1855 -0
  82. package/template/.devbooster/hub/personas/skill_architecture.md +417 -0
  83. package/template/.devbooster/hub/personas/skill_bash-linux.md +199 -0
  84. package/template/.devbooster/hub/personas/skill_behavioral-modes.md +242 -0
  85. package/template/.devbooster/hub/personas/skill_brainstorming.md +519 -0
  86. package/template/.devbooster/hub/personas/skill_clean-code.md +201 -0
  87. package/template/.devbooster/hub/personas/skill_code-review-checklist.md +109 -0
  88. package/template/.devbooster/hub/personas/skill_database-design.md +340 -0
  89. package/template/.devbooster/hub/personas/skill_deployment-procedures.md +241 -0
  90. package/template/.devbooster/hub/personas/skill_doc.md +177 -0
  91. package/template/.devbooster/hub/personas/skill_documentation-templates.md +194 -0
  92. package/template/.devbooster/hub/personas/skill_frontend-design.md +3670 -0
  93. package/template/.devbooster/hub/personas/skill_game-development.md +167 -0
  94. package/template/.devbooster/hub/personas/skill_geo-fundamentals.md +156 -0
  95. package/template/.devbooster/hub/personas/skill_i18n-localization.md +154 -0
  96. package/template/.devbooster/hub/personas/skill_intelligent-routing.md +335 -0
  97. package/template/.devbooster/hub/personas/skill_lint-and-validate.md +45 -0
  98. package/template/.devbooster/hub/personas/skill_mcp-builder.md +176 -0
  99. package/template/.devbooster/hub/personas/skill_mobile-design.md +6150 -0
  100. package/template/.devbooster/hub/personas/skill_nextjs-react-expert.md +3487 -0
  101. package/template/.devbooster/hub/personas/skill_nodejs-best-practices.md +333 -0
  102. package/template/.devbooster/hub/personas/skill_parallel-agents.md +175 -0
  103. package/template/.devbooster/hub/personas/skill_performance-profiling.md +143 -0
  104. package/template/.devbooster/hub/personas/skill_plan-writing.md +152 -0
  105. package/template/.devbooster/hub/personas/skill_powershell-windows.md +167 -0
  106. package/template/.devbooster/hub/personas/skill_python-patterns.md +441 -0
  107. package/template/.devbooster/hub/personas/skill_red-team-tactics.md +199 -0
  108. package/template/.devbooster/hub/personas/skill_rust-pro.md +176 -0
  109. package/template/.devbooster/hub/personas/skill_seo-fundamentals.md +129 -0
  110. package/template/.devbooster/hub/personas/skill_server-management.md +161 -0
  111. package/template/.devbooster/hub/personas/skill_systematic-debugging.md +109 -0
  112. package/template/.devbooster/hub/personas/skill_tailwind-patterns.md +269 -0
  113. package/template/.devbooster/hub/personas/skill_tdd-workflow.md +149 -0
  114. package/template/.devbooster/hub/personas/skill_testing-patterns.md +178 -0
  115. package/template/.devbooster/hub/personas/skill_vulnerability-scanner.md +403 -0
  116. package/template/.devbooster/hub/personas/skill_web-design-guidelines.md +57 -0
  117. package/template/.devbooster/hub/personas/skill_webapp-testing.md +187 -0
  118. package/template/.devbooster/hub/personas/status.md +86 -0
  119. package/template/.devbooster/hub/personas/test-engineer.md +158 -0
  120. package/template/.devbooster/hub/personas/test.md +144 -0
  121. package/template/.devbooster/hub/personas/ui-ux-pro-max.md +296 -0
  122. package/template/.devbooster/hub/scripts/accessibility_checker.py +183 -0
  123. package/template/.devbooster/hub/scripts/api_validator.py +211 -0
  124. package/template/.devbooster/hub/scripts/auto_preview.py +148 -0
  125. package/template/.devbooster/hub/scripts/checklist.py +217 -0
  126. package/template/.devbooster/hub/scripts/convert_rules.py +222 -0
  127. package/template/.devbooster/hub/scripts/geo_checker.py +289 -0
  128. package/template/.devbooster/hub/scripts/i18n_checker.py +241 -0
  129. package/template/.devbooster/hub/scripts/lighthouse_audit.py +76 -0
  130. package/template/.devbooster/hub/scripts/lint_runner.py +184 -0
  131. package/template/.devbooster/hub/scripts/mobile_audit.py +670 -0
  132. package/template/.devbooster/hub/scripts/playwright_runner.py +173 -0
  133. package/template/.devbooster/hub/scripts/react_performance_checker.py +252 -0
  134. package/template/.devbooster/hub/scripts/schema_validator.py +172 -0
  135. package/template/.devbooster/hub/scripts/security_scan.py +458 -0
  136. package/template/.devbooster/hub/scripts/seo_checker.py +219 -0
  137. package/template/.devbooster/hub/scripts/session_manager.py +120 -0
  138. package/template/.devbooster/hub/scripts/test_runner.py +219 -0
  139. package/template/.devbooster/hub/scripts/type_coverage.py +173 -0
  140. package/template/.devbooster/hub/scripts/ux_audit.py +722 -0
  141. package/template/.devbooster/hub/scripts/verify_all.py +327 -0
  142. package/template/.devbooster/hub/skills/api-patterns/SKILL.md +81 -0
  143. package/template/.devbooster/hub/skills/api-patterns/api-style.md +42 -0
  144. package/template/.devbooster/hub/skills/api-patterns/auth.md +24 -0
  145. package/template/.devbooster/hub/skills/api-patterns/documentation.md +26 -0
  146. package/template/.devbooster/hub/skills/api-patterns/graphql.md +41 -0
  147. package/template/.devbooster/hub/skills/api-patterns/rate-limiting.md +31 -0
  148. package/template/.devbooster/hub/skills/api-patterns/response.md +37 -0
  149. package/template/.devbooster/hub/skills/api-patterns/rest.md +40 -0
  150. package/template/.devbooster/hub/skills/api-patterns/scripts/api_validator.py +211 -0
  151. package/template/.devbooster/hub/skills/api-patterns/security-testing.md +122 -0
  152. package/template/.devbooster/hub/skills/api-patterns/trpc.md +41 -0
  153. package/template/.devbooster/hub/skills/api-patterns/versioning.md +22 -0
  154. package/template/.devbooster/hub/skills/app-builder/SKILL.md +75 -0
  155. package/template/.devbooster/hub/skills/app-builder/agent-coordination.md +71 -0
  156. package/template/.devbooster/hub/skills/app-builder/feature-building.md +53 -0
  157. package/template/.devbooster/hub/skills/app-builder/project-detection.md +34 -0
  158. package/template/.devbooster/hub/skills/app-builder/scaffolding.md +118 -0
  159. package/template/.devbooster/hub/skills/app-builder/tech-stack.md +40 -0
  160. package/template/.devbooster/hub/skills/app-builder/templates/SKILL.md +39 -0
  161. package/template/.devbooster/hub/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  162. package/template/.devbooster/hub/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  163. package/template/.devbooster/hub/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  164. package/template/.devbooster/hub/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  165. package/template/.devbooster/hub/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  166. package/template/.devbooster/hub/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  167. package/template/.devbooster/hub/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  168. package/template/.devbooster/hub/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
  169. package/template/.devbooster/hub/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
  170. package/template/.devbooster/hub/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
  171. package/template/.devbooster/hub/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
  172. package/template/.devbooster/hub/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  173. package/template/.devbooster/hub/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
  174. package/template/.devbooster/hub/skills/architecture/SKILL.md +55 -0
  175. package/template/.devbooster/hub/skills/architecture/context-discovery.md +43 -0
  176. package/template/.devbooster/hub/skills/architecture/examples.md +94 -0
  177. package/template/.devbooster/hub/skills/architecture/pattern-selection.md +68 -0
  178. package/template/.devbooster/hub/skills/architecture/patterns-reference.md +50 -0
  179. package/template/.devbooster/hub/skills/architecture/trade-off-analysis.md +77 -0
  180. package/template/.devbooster/hub/skills/bash-linux/SKILL.md +199 -0
  181. package/template/.devbooster/hub/skills/behavioral-modes/SKILL.md +242 -0
  182. package/template/.devbooster/hub/skills/brainstorming/SKILL.md +163 -0
  183. package/template/.devbooster/hub/skills/brainstorming/dynamic-questioning.md +350 -0
  184. package/template/.devbooster/hub/skills/clean-code/SKILL.md +201 -0
  185. package/template/.devbooster/hub/skills/code-review-checklist/SKILL.md +109 -0
  186. package/template/.devbooster/hub/skills/database-design/SKILL.md +52 -0
  187. package/template/.devbooster/hub/skills/database-design/database-selection.md +43 -0
  188. package/template/.devbooster/hub/skills/database-design/indexing.md +39 -0
  189. package/template/.devbooster/hub/skills/database-design/migrations.md +48 -0
  190. package/template/.devbooster/hub/skills/database-design/optimization.md +36 -0
  191. package/template/.devbooster/hub/skills/database-design/orm-selection.md +30 -0
  192. package/template/.devbooster/hub/skills/database-design/schema-design.md +56 -0
  193. package/template/.devbooster/hub/skills/database-design/scripts/schema_validator.py +172 -0
  194. package/template/.devbooster/hub/skills/deployment-procedures/SKILL.md +241 -0
  195. package/template/.devbooster/hub/skills/doc.md +177 -0
  196. package/template/.devbooster/hub/skills/documentation-templates/SKILL.md +194 -0
  197. package/template/.devbooster/hub/skills/frontend-design/SKILL.md +418 -0
  198. package/template/.devbooster/hub/skills/frontend-design/animation-guide.md +331 -0
  199. package/template/.devbooster/hub/skills/frontend-design/anti-generic-guide.md +252 -0
  200. package/template/.devbooster/hub/skills/frontend-design/color-system.md +311 -0
  201. package/template/.devbooster/hub/skills/frontend-design/decision-trees.md +418 -0
  202. package/template/.devbooster/hub/skills/frontend-design/motion-graphics.md +306 -0
  203. package/template/.devbooster/hub/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  204. package/template/.devbooster/hub/skills/frontend-design/scripts/ux_audit.py +722 -0
  205. package/template/.devbooster/hub/skills/frontend-design/typography-system.md +345 -0
  206. package/template/.devbooster/hub/skills/frontend-design/ux-psychology.md +1116 -0
  207. package/template/.devbooster/hub/skills/frontend-design/visual-effects.md +383 -0
  208. package/template/.devbooster/hub/skills/game-development/2d-games/SKILL.md +119 -0
  209. package/template/.devbooster/hub/skills/game-development/3d-games/SKILL.md +135 -0
  210. package/template/.devbooster/hub/skills/game-development/SKILL.md +167 -0
  211. package/template/.devbooster/hub/skills/game-development/game-art/SKILL.md +185 -0
  212. package/template/.devbooster/hub/skills/game-development/game-audio/SKILL.md +190 -0
  213. package/template/.devbooster/hub/skills/game-development/game-design/SKILL.md +129 -0
  214. package/template/.devbooster/hub/skills/game-development/mobile-games/SKILL.md +108 -0
  215. package/template/.devbooster/hub/skills/game-development/multiplayer/SKILL.md +132 -0
  216. package/template/.devbooster/hub/skills/game-development/pc-games/SKILL.md +144 -0
  217. package/template/.devbooster/hub/skills/game-development/vr-ar/SKILL.md +123 -0
  218. package/template/.devbooster/hub/skills/game-development/web-games/SKILL.md +150 -0
  219. package/template/.devbooster/hub/skills/geo-fundamentals/SKILL.md +156 -0
  220. package/template/.devbooster/hub/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  221. package/template/.devbooster/hub/skills/i18n-localization/SKILL.md +154 -0
  222. package/template/.devbooster/hub/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  223. package/template/.devbooster/hub/skills/intelligent-routing/SKILL.md +335 -0
  224. package/template/.devbooster/hub/skills/lint-and-validate/SKILL.md +45 -0
  225. package/template/.devbooster/hub/skills/lint-and-validate/scripts/lint_runner.py +184 -0
  226. package/template/.devbooster/hub/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  227. package/template/.devbooster/hub/skills/mcp-builder/SKILL.md +176 -0
  228. package/template/.devbooster/hub/skills/mobile-design/SKILL.md +394 -0
  229. package/template/.devbooster/hub/skills/mobile-design/decision-trees.md +516 -0
  230. package/template/.devbooster/hub/skills/mobile-design/mobile-backend.md +491 -0
  231. package/template/.devbooster/hub/skills/mobile-design/mobile-color-system.md +420 -0
  232. package/template/.devbooster/hub/skills/mobile-design/mobile-debugging.md +122 -0
  233. package/template/.devbooster/hub/skills/mobile-design/mobile-design-thinking.md +357 -0
  234. package/template/.devbooster/hub/skills/mobile-design/mobile-navigation.md +458 -0
  235. package/template/.devbooster/hub/skills/mobile-design/mobile-performance.md +767 -0
  236. package/template/.devbooster/hub/skills/mobile-design/mobile-testing.md +356 -0
  237. package/template/.devbooster/hub/skills/mobile-design/mobile-typography.md +433 -0
  238. package/template/.devbooster/hub/skills/mobile-design/platform-android.md +666 -0
  239. package/template/.devbooster/hub/skills/mobile-design/platform-ios.md +561 -0
  240. package/template/.devbooster/hub/skills/mobile-design/scripts/mobile_audit.py +670 -0
  241. package/template/.devbooster/hub/skills/mobile-design/touch-psychology.md +537 -0
  242. package/template/.devbooster/hub/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +312 -0
  243. package/template/.devbooster/hub/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +240 -0
  244. package/template/.devbooster/hub/skills/nextjs-react-expert/3-server-server-side-performance.md +490 -0
  245. package/template/.devbooster/hub/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +264 -0
  246. package/template/.devbooster/hub/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
  247. package/template/.devbooster/hub/skills/nextjs-react-expert/6-rendering-rendering-performance.md +432 -0
  248. package/template/.devbooster/hub/skills/nextjs-react-expert/7-js-javascript-performance.md +684 -0
  249. package/template/.devbooster/hub/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +150 -0
  250. package/template/.devbooster/hub/skills/nextjs-react-expert/SKILL.md +286 -0
  251. package/template/.devbooster/hub/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
  252. package/template/.devbooster/hub/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
  253. package/template/.devbooster/hub/skills/nodejs-best-practices/SKILL.md +333 -0
  254. package/template/.devbooster/hub/skills/parallel-agents/SKILL.md +175 -0
  255. package/template/.devbooster/hub/skills/performance-profiling/SKILL.md +143 -0
  256. package/template/.devbooster/hub/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  257. package/template/.devbooster/hub/skills/plan-writing/SKILL.md +152 -0
  258. package/template/.devbooster/hub/skills/powershell-windows/SKILL.md +167 -0
  259. package/template/.devbooster/hub/skills/python-patterns/SKILL.md +441 -0
  260. package/template/.devbooster/hub/skills/red-team-tactics/SKILL.md +199 -0
  261. package/template/.devbooster/hub/skills/rust-pro/SKILL.md +176 -0
  262. package/template/.devbooster/hub/skills/seo-fundamentals/SKILL.md +129 -0
  263. package/template/.devbooster/hub/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
  264. package/template/.devbooster/hub/skills/server-management/SKILL.md +161 -0
  265. package/template/.devbooster/hub/skills/systematic-debugging/SKILL.md +109 -0
  266. package/template/.devbooster/hub/skills/tailwind-patterns/SKILL.md +269 -0
  267. package/template/.devbooster/hub/skills/tdd-workflow/SKILL.md +149 -0
  268. package/template/.devbooster/hub/skills/testing-patterns/SKILL.md +178 -0
  269. package/template/.devbooster/hub/skills/testing-patterns/scripts/test_runner.py +219 -0
  270. package/template/.devbooster/hub/skills/vulnerability-scanner/SKILL.md +276 -0
  271. package/template/.devbooster/hub/skills/vulnerability-scanner/checklists.md +121 -0
  272. package/template/.devbooster/hub/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  273. package/template/.devbooster/hub/skills/web-design-guidelines/SKILL.md +57 -0
  274. package/template/.devbooster/hub/skills/webapp-testing/SKILL.md +187 -0
  275. package/template/.devbooster/hub/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  276. package/template/.devbooster/hub/workflows/brainstorm.md +113 -0
  277. package/template/.devbooster/hub/workflows/create.md +59 -0
  278. package/template/.devbooster/hub/workflows/debug.md +103 -0
  279. package/template/.devbooster/hub/workflows/deploy.md +176 -0
  280. package/template/.devbooster/hub/workflows/enhance.md +63 -0
  281. package/template/.devbooster/hub/workflows/orchestrate.md +237 -0
  282. package/template/.devbooster/hub/workflows/plan.md +89 -0
  283. package/template/.devbooster/hub/workflows/preview.md +81 -0
  284. package/template/.devbooster/hub/workflows/status.md +86 -0
  285. package/template/.devbooster/hub/workflows/test.md +144 -0
  286. package/template/.devbooster/hub/workflows/ui-ux-pro-max.md +296 -0
  287. package/template/.devbooster/rules/BACKEND.md +72 -0
  288. package/template/.devbooster/rules/COMERCIAL.md +69 -0
  289. package/template/.devbooster/rules/FRONTEND.md +76 -0
  290. package/template/.devbooster/rules/GUIDE.md +111 -0
  291. package/template/.devbooster/rules/PROJECT.md +83 -0
  292. package/template/.devbooster/rules/PROTOCOL.md +42 -0
  293. package/template/.devbooster/rules/USER_PREFERENCES.md +33 -0
  294. package/template/DEVBOOSTER_INIT.md +42 -0
@@ -0,0 +1,458 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Skill: vulnerability-scanner
4
+ Script: security_scan.py
5
+ Purpose: Validate that security principles from SKILL.md are applied correctly
6
+ Usage: python security_scan.py <project_path> [--scan-type all|deps|secrets|patterns|config]
7
+ Output: JSON with validation findings
8
+
9
+ This script verifies:
10
+ 1. Dependencies - Supply chain security (OWASP A03)
11
+ 2. Secrets - No hardcoded credentials (OWASP A04)
12
+ 3. Code Patterns - Dangerous patterns identified (OWASP A05)
13
+ 4. Configuration - Security settings validated (OWASP A02)
14
+ """
15
+ import subprocess
16
+ import json
17
+ import os
18
+ import sys
19
+ import re
20
+ import argparse
21
+ from pathlib import Path
22
+ from typing import Dict, List, Any
23
+ from datetime import datetime
24
+
25
+ # Fix Windows console encoding for Unicode output
26
+ try:
27
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
28
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
29
+ except AttributeError:
30
+ pass # Python < 3.7
31
+
32
+
33
+ # ============================================================================
34
+ # CONFIGURATION
35
+ # ============================================================================
36
+
37
+ SECRET_PATTERNS = [
38
+ # API Keys & Tokens
39
+ (r'api[_-]?key\s*[=:]\s*["\'][^"\']{10,}["\']', "API Key", "high"),
40
+ (r'token\s*[=:]\s*["\'][^"\']{10,}["\']', "Token", "high"),
41
+ (r'bearer\s+[a-zA-Z0-9\-_.]+', "Bearer Token", "critical"),
42
+
43
+ # Cloud Credentials
44
+ (r'AKIA[0-9A-Z]{16}', "AWS Access Key", "critical"),
45
+ (r'aws[_-]?secret[_-]?access[_-]?key\s*[=:]\s*["\'][^"\']+["\']', "AWS Secret", "critical"),
46
+ (r'AZURE[_-]?[A-Z_]+\s*[=:]\s*["\'][^"\']+["\']', "Azure Credential", "critical"),
47
+ (r'GOOGLE[_-]?[A-Z_]+\s*[=:]\s*["\'][^"\']+["\']', "GCP Credential", "critical"),
48
+
49
+ # Database & Connections
50
+ (r'password\s*[=:]\s*["\'][^"\']{4,}["\']', "Password", "high"),
51
+ (r'(mongodb|postgres|mysql|redis):\/\/[^\s"\']+', "Database Connection String", "critical"),
52
+
53
+ # Private Keys
54
+ (r'-----BEGIN\s+(RSA|PRIVATE|EC)\s+KEY-----', "Private Key", "critical"),
55
+ (r'ssh-rsa\s+[A-Za-z0-9+/]+', "SSH Key", "critical"),
56
+
57
+ # JWT
58
+ (r'eyJ[A-Za-z0-9-_]+\.eyJ[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+', "JWT Token", "high"),
59
+ ]
60
+
61
+ DANGEROUS_PATTERNS = [
62
+ # Injection risks
63
+ (r'eval\s*\(', "eval() usage", "critical", "Code Injection risk"),
64
+ (r'exec\s*\(', "exec() usage", "critical", "Code Injection risk"),
65
+ (r'new\s+Function\s*\(', "Function constructor", "high", "Code Injection risk"),
66
+ (r'child_process\.exec\s*\(', "child_process.exec", "high", "Command Injection risk"),
67
+ (r'subprocess\.call\s*\([^)]*shell\s*=\s*True', "subprocess with shell=True", "high", "Command Injection risk"),
68
+
69
+ # XSS risks
70
+ (r'dangerouslySetInnerHTML', "dangerouslySetInnerHTML", "high", "XSS risk"),
71
+ (r'\.innerHTML\s*=', "innerHTML assignment", "medium", "XSS risk"),
72
+ (r'document\.write\s*\(', "document.write", "medium", "XSS risk"),
73
+
74
+ # SQL Injection indicators
75
+ (r'["\'][^"\']*\+\s*[a-zA-Z_]+\s*\+\s*["\'].*(?:SELECT|INSERT|UPDATE|DELETE)', "SQL String Concat", "critical", "SQL Injection risk"),
76
+ (r'f"[^"]*(?:SELECT|INSERT|UPDATE|DELETE)[^"]*\{', "SQL f-string", "critical", "SQL Injection risk"),
77
+
78
+ # Insecure configurations
79
+ (r'verify\s*=\s*False', "SSL Verify Disabled", "high", "MITM risk"),
80
+ (r'--insecure', "Insecure flag", "medium", "Security disabled"),
81
+ (r'disable[_-]?ssl', "SSL Disabled", "high", "MITM risk"),
82
+
83
+ # Unsafe deserialization
84
+ (r'pickle\.loads?\s*\(', "pickle usage", "high", "Deserialization risk"),
85
+ (r'yaml\.load\s*\([^)]*\)(?!\s*,\s*Loader)', "Unsafe YAML load", "high", "Deserialization risk"),
86
+ ]
87
+
88
+ SKIP_DIRS = {'node_modules', '.git', 'dist', 'build', '__pycache__', '.venv', 'venv', '.next'}
89
+ CODE_EXTENSIONS = {'.js', '.ts', '.jsx', '.tsx', '.py', '.go', '.java', '.rb', '.php'}
90
+ CONFIG_EXTENSIONS = {'.json', '.yaml', '.yml', '.toml', '.env', '.env.local', '.env.development'}
91
+
92
+
93
+ # ============================================================================
94
+ # SCANNING FUNCTIONS
95
+ # ============================================================================
96
+
97
+ def scan_dependencies(project_path: str) -> Dict[str, Any]:
98
+ """
99
+ Validate supply chain security (OWASP A03).
100
+ Checks: npm audit, lock file presence, dependency age.
101
+ """
102
+ results = {"tool": "dependency_scanner", "findings": [], "status": "[OK] Secure"}
103
+
104
+ # Check for lock files
105
+ lock_files = {
106
+ "npm": ["package-lock.json", "npm-shrinkwrap.json"],
107
+ "yarn": ["yarn.lock"],
108
+ "pnpm": ["pnpm-lock.yaml"],
109
+ "pip": ["requirements.txt", "Pipfile.lock", "poetry.lock"],
110
+ }
111
+
112
+ found_locks = []
113
+ missing_locks = []
114
+
115
+ for manager, files in lock_files.items():
116
+ pkg_file = "package.json" if manager in ["npm", "yarn", "pnpm"] else "setup.py"
117
+ pkg_path = Path(project_path) / pkg_file
118
+
119
+ if pkg_path.exists() or (manager == "pip" and (Path(project_path) / "requirements.txt").exists()):
120
+ has_lock = any((Path(project_path) / f).exists() for f in files)
121
+ if has_lock:
122
+ found_locks.append(manager)
123
+ else:
124
+ missing_locks.append(manager)
125
+ results["findings"].append({
126
+ "type": "Missing Lock File",
127
+ "severity": "high",
128
+ "message": f"{manager}: No lock file found. Supply chain integrity at risk."
129
+ })
130
+
131
+ # Run npm audit if applicable
132
+ if (Path(project_path) / "package.json").exists():
133
+ try:
134
+ result = subprocess.run(
135
+ ["npm", "audit", "--json"],
136
+ cwd=project_path,
137
+ capture_output=True,
138
+ text=True,
139
+ timeout=60
140
+ )
141
+
142
+ try:
143
+ audit_data = json.loads(result.stdout)
144
+ vulnerabilities = audit_data.get("vulnerabilities", {})
145
+
146
+ severity_count = {"critical": 0, "high": 0, "moderate": 0, "low": 0}
147
+ for vuln in vulnerabilities.values():
148
+ sev = vuln.get("severity", "low").lower()
149
+ if sev in severity_count:
150
+ severity_count[sev] += 1
151
+
152
+ if severity_count["critical"] > 0:
153
+ results["status"] = "[!!] Critical vulnerabilities"
154
+ results["findings"].append({
155
+ "type": "npm audit",
156
+ "severity": "critical",
157
+ "message": f"{severity_count['critical']} critical vulnerabilities in dependencies"
158
+ })
159
+ elif severity_count["high"] > 0:
160
+ results["status"] = "[!] High vulnerabilities"
161
+ results["findings"].append({
162
+ "type": "npm audit",
163
+ "severity": "high",
164
+ "message": f"{severity_count['high']} high severity vulnerabilities"
165
+ })
166
+
167
+ results["npm_audit"] = severity_count
168
+
169
+ except json.JSONDecodeError:
170
+ pass
171
+
172
+ except (FileNotFoundError, subprocess.TimeoutExpired):
173
+ pass
174
+
175
+ if not results["findings"]:
176
+ results["status"] = "[OK] Supply chain checks passed"
177
+
178
+ return results
179
+
180
+
181
+ def scan_secrets(project_path: str) -> Dict[str, Any]:
182
+ """
183
+ Validate no hardcoded secrets (OWASP A04).
184
+ Checks: API keys, tokens, passwords, cloud credentials.
185
+ """
186
+ results = {
187
+ "tool": "secret_scanner",
188
+ "findings": [],
189
+ "status": "[OK] No secrets detected",
190
+ "scanned_files": 0,
191
+ "by_severity": {"critical": 0, "high": 0, "medium": 0}
192
+ }
193
+
194
+ for root, dirs, files in os.walk(project_path):
195
+ dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
196
+
197
+ for file in files:
198
+ ext = Path(file).suffix.lower()
199
+ if ext not in CODE_EXTENSIONS and ext not in CONFIG_EXTENSIONS:
200
+ continue
201
+
202
+ filepath = Path(root) / file
203
+ results["scanned_files"] += 1
204
+
205
+ try:
206
+ with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
207
+ content = f.read()
208
+
209
+ for pattern, secret_type, severity in SECRET_PATTERNS:
210
+ matches = re.findall(pattern, content, re.IGNORECASE)
211
+ if matches:
212
+ results["findings"].append({
213
+ "file": str(filepath.relative_to(project_path)),
214
+ "type": secret_type,
215
+ "severity": severity,
216
+ "count": len(matches)
217
+ })
218
+ results["by_severity"][severity] += len(matches)
219
+
220
+ except Exception:
221
+ pass
222
+
223
+ if results["by_severity"]["critical"] > 0:
224
+ results["status"] = "[!!] CRITICAL: Secrets exposed!"
225
+ elif results["by_severity"]["high"] > 0:
226
+ results["status"] = "[!] HIGH: Secrets found"
227
+ elif sum(results["by_severity"].values()) > 0:
228
+ results["status"] = "[?] Potential secrets detected"
229
+
230
+ # Limit findings for output
231
+ results["findings"] = results["findings"][:15]
232
+
233
+ return results
234
+
235
+
236
+ def scan_code_patterns(project_path: str) -> Dict[str, Any]:
237
+ """
238
+ Validate dangerous code patterns (OWASP A05).
239
+ Checks: Injection risks, XSS, unsafe deserialization.
240
+ """
241
+ results = {
242
+ "tool": "pattern_scanner",
243
+ "findings": [],
244
+ "status": "[OK] No dangerous patterns",
245
+ "scanned_files": 0,
246
+ "by_category": {}
247
+ }
248
+
249
+ for root, dirs, files in os.walk(project_path):
250
+ dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
251
+
252
+ for file in files:
253
+ ext = Path(file).suffix.lower()
254
+ if ext not in CODE_EXTENSIONS:
255
+ continue
256
+
257
+ filepath = Path(root) / file
258
+ results["scanned_files"] += 1
259
+
260
+ try:
261
+ with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
262
+ lines = f.readlines()
263
+
264
+ for line_num, line in enumerate(lines, 1):
265
+ for pattern, name, severity, category in DANGEROUS_PATTERNS:
266
+ if re.search(pattern, line, re.IGNORECASE):
267
+ results["findings"].append({
268
+ "file": str(filepath.relative_to(project_path)),
269
+ "line": line_num,
270
+ "pattern": name,
271
+ "severity": severity,
272
+ "category": category,
273
+ "snippet": line.strip()[:80]
274
+ })
275
+ results["by_category"][category] = results["by_category"].get(category, 0) + 1
276
+
277
+ except Exception:
278
+ pass
279
+
280
+ critical_count = sum(1 for f in results["findings"] if f["severity"] == "critical")
281
+ high_count = sum(1 for f in results["findings"] if f["severity"] == "high")
282
+
283
+ if critical_count > 0:
284
+ results["status"] = f"[!!] CRITICAL: {critical_count} dangerous patterns"
285
+ elif high_count > 0:
286
+ results["status"] = f"[!] HIGH: {high_count} risky patterns"
287
+ elif results["findings"]:
288
+ results["status"] = "[?] Some patterns need review"
289
+
290
+ # Limit findings
291
+ results["findings"] = results["findings"][:20]
292
+
293
+ return results
294
+
295
+
296
+ def scan_configuration(project_path: str) -> Dict[str, Any]:
297
+ """
298
+ Validate security configuration (OWASP A02).
299
+ Checks: Security headers, CORS, debug modes.
300
+ """
301
+ results = {
302
+ "tool": "config_scanner",
303
+ "findings": [],
304
+ "status": "[OK] Configuration secure",
305
+ "checks": {}
306
+ }
307
+
308
+ # Check common config files for issues
309
+ config_issues = [
310
+ (r'"DEBUG"\s*:\s*true', "Debug mode enabled", "high"),
311
+ (r'debug\s*=\s*True', "Debug mode enabled", "high"),
312
+ (r'NODE_ENV.*development', "Development mode in config", "medium"),
313
+ (r'"CORS_ALLOW_ALL".*true', "CORS allow all origins", "high"),
314
+ (r'"Access-Control-Allow-Origin".*\*', "CORS wildcard", "high"),
315
+ (r'allowCredentials.*true.*origin.*\*', "Dangerous CORS combo", "critical"),
316
+ ]
317
+
318
+ for root, dirs, files in os.walk(project_path):
319
+ dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
320
+
321
+ for file in files:
322
+ ext = Path(file).suffix.lower()
323
+ if ext not in CONFIG_EXTENSIONS and file not in ['next.config.js', 'webpack.config.js', '.eslintrc.js']:
324
+ continue
325
+
326
+ filepath = Path(root) / file
327
+
328
+ try:
329
+ with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
330
+ content = f.read()
331
+
332
+ for pattern, issue, severity in config_issues:
333
+ if re.search(pattern, content, re.IGNORECASE):
334
+ results["findings"].append({
335
+ "file": str(filepath.relative_to(project_path)),
336
+ "issue": issue,
337
+ "severity": severity
338
+ })
339
+
340
+ except Exception:
341
+ pass
342
+
343
+ # Check for security header configurations
344
+ header_files = ["next.config.js", "next.config.mjs", "middleware.ts", "nginx.conf"]
345
+ for hf in header_files:
346
+ hf_path = Path(project_path) / hf
347
+ if hf_path.exists():
348
+ results["checks"]["security_headers_config"] = True
349
+ break
350
+ else:
351
+ results["checks"]["security_headers_config"] = False
352
+ results["findings"].append({
353
+ "issue": "No security headers configuration found",
354
+ "severity": "medium",
355
+ "recommendation": "Configure CSP, HSTS, X-Frame-Options headers"
356
+ })
357
+
358
+ if any(f["severity"] == "critical" for f in results["findings"]):
359
+ results["status"] = "[!!] CRITICAL: Configuration issues"
360
+ elif any(f["severity"] == "high" for f in results["findings"]):
361
+ results["status"] = "[!] HIGH: Configuration review needed"
362
+ elif results["findings"]:
363
+ results["status"] = "[?] Minor configuration issues"
364
+
365
+ return results
366
+
367
+
368
+ # ============================================================================
369
+ # MAIN
370
+ # ============================================================================
371
+
372
+ def run_full_scan(project_path: str, scan_type: str = "all") -> Dict[str, Any]:
373
+ """Execute security validation scans."""
374
+
375
+ report = {
376
+ "project": project_path,
377
+ "timestamp": datetime.now().isoformat(),
378
+ "scan_type": scan_type,
379
+ "scans": {},
380
+ "summary": {
381
+ "total_findings": 0,
382
+ "critical": 0,
383
+ "high": 0,
384
+ "overall_status": "[OK] SECURE"
385
+ }
386
+ }
387
+
388
+ scanners = {
389
+ "deps": ("dependencies", scan_dependencies),
390
+ "secrets": ("secrets", scan_secrets),
391
+ "patterns": ("code_patterns", scan_code_patterns),
392
+ "config": ("configuration", scan_configuration),
393
+ }
394
+
395
+ for key, (name, scanner) in scanners.items():
396
+ if scan_type == "all" or scan_type == key:
397
+ result = scanner(project_path)
398
+ report["scans"][name] = result
399
+
400
+ findings_count = len(result.get("findings", []))
401
+ report["summary"]["total_findings"] += findings_count
402
+
403
+ for finding in result.get("findings", []):
404
+ sev = finding.get("severity", "low")
405
+ if sev == "critical":
406
+ report["summary"]["critical"] += 1
407
+ elif sev == "high":
408
+ report["summary"]["high"] += 1
409
+
410
+ # Determine overall status
411
+ if report["summary"]["critical"] > 0:
412
+ report["summary"]["overall_status"] = "[!!] CRITICAL ISSUES FOUND"
413
+ elif report["summary"]["high"] > 0:
414
+ report["summary"]["overall_status"] = "[!] HIGH RISK ISSUES"
415
+ elif report["summary"]["total_findings"] > 0:
416
+ report["summary"]["overall_status"] = "[?] REVIEW RECOMMENDED"
417
+
418
+ return report
419
+
420
+
421
+ def main():
422
+ parser = argparse.ArgumentParser(
423
+ description="Validate security principles from vulnerability-scanner skill"
424
+ )
425
+ parser.add_argument("project_path", nargs="?", default=".", help="Project directory to scan")
426
+ parser.add_argument("--scan-type", choices=["all", "deps", "secrets", "patterns", "config"],
427
+ default="all", help="Type of scan to run")
428
+ parser.add_argument("--output", choices=["json", "summary"], default="json",
429
+ help="Output format")
430
+
431
+ args = parser.parse_args()
432
+
433
+ if not os.path.isdir(args.project_path):
434
+ print(json.dumps({"error": f"Directory not found: {args.project_path}"}))
435
+ sys.exit(1)
436
+
437
+ result = run_full_scan(args.project_path, args.scan_type)
438
+
439
+ if args.output == "summary":
440
+ print(f"\n{'='*60}")
441
+ print(f"Security Scan: {result['project']}")
442
+ print(f"{'='*60}")
443
+ print(f"Status: {result['summary']['overall_status']}")
444
+ print(f"Total Findings: {result['summary']['total_findings']}")
445
+ print(f" Critical: {result['summary']['critical']}")
446
+ print(f" High: {result['summary']['high']}")
447
+ print(f"{'='*60}\n")
448
+
449
+ for scan_name, scan_result in result['scans'].items():
450
+ print(f"\n{scan_name.upper()}: {scan_result['status']}")
451
+ for finding in scan_result.get('findings', [])[:5]:
452
+ print(f" - {finding}")
453
+ else:
454
+ print(json.dumps(result, indent=2))
455
+
456
+
457
+ if __name__ == "__main__":
458
+ main()
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ SEO Checker - Search Engine Optimization Audit
4
+ Checks HTML/JSX/TSX pages for SEO best practices.
5
+
6
+ PURPOSE:
7
+ - Verify meta tags, titles, descriptions
8
+ - Check Open Graph tags for social sharing
9
+ - Validate heading hierarchy
10
+ - Check image accessibility (alt attributes)
11
+
12
+ WHAT IT CHECKS:
13
+ - HTML files (actual web pages)
14
+ - JSX/TSX files (React page components)
15
+ - Only files that are likely PUBLIC pages
16
+
17
+ Usage:
18
+ python seo_checker.py <project_path>
19
+ """
20
+ import sys
21
+ import json
22
+ import re
23
+ from pathlib import Path
24
+ from datetime import datetime
25
+
26
+ # Fix Windows console encoding
27
+ try:
28
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
29
+ except:
30
+ pass
31
+
32
+
33
+ # Directories to skip
34
+ SKIP_DIRS = {
35
+ 'node_modules', '.next', 'dist', 'build', '.git', '.github',
36
+ '__pycache__', '.vscode', '.idea', 'coverage', 'test', 'tests',
37
+ '__tests__', 'spec', 'docs', 'documentation', 'examples'
38
+ }
39
+
40
+ # Files to skip (not pages)
41
+ SKIP_PATTERNS = [
42
+ 'config', 'setup', 'util', 'helper', 'hook', 'context', 'store',
43
+ 'service', 'api', 'lib', 'constant', 'type', 'interface', 'mock',
44
+ '.test.', '.spec.', '_test.', '_spec.'
45
+ ]
46
+
47
+
48
+ def is_page_file(file_path: Path) -> bool:
49
+ """Check if this file is likely a public-facing page."""
50
+ name = file_path.name.lower()
51
+ stem = file_path.stem.lower()
52
+
53
+ # Skip utility/config files
54
+ if any(skip in name for skip in SKIP_PATTERNS):
55
+ return False
56
+
57
+ # Check path - pages in specific directories are likely pages
58
+ parts = [p.lower() for p in file_path.parts]
59
+ page_dirs = ['pages', 'app', 'routes', 'views', 'screens']
60
+
61
+ if any(d in parts for d in page_dirs):
62
+ return True
63
+
64
+ # Filename indicators for pages
65
+ page_names = ['page', 'index', 'home', 'about', 'contact', 'blog',
66
+ 'post', 'article', 'product', 'landing', 'layout']
67
+
68
+ if any(p in stem for p in page_names):
69
+ return True
70
+
71
+ # HTML files are usually pages
72
+ if file_path.suffix.lower() in ['.html', '.htm']:
73
+ return True
74
+
75
+ return False
76
+
77
+
78
+ def find_pages(project_path: Path) -> list:
79
+ """Find page files to check."""
80
+ patterns = ['**/*.html', '**/*.htm', '**/*.jsx', '**/*.tsx']
81
+
82
+ files = []
83
+ for pattern in patterns:
84
+ for f in project_path.glob(pattern):
85
+ # Skip excluded directories
86
+ if any(skip in f.parts for skip in SKIP_DIRS):
87
+ continue
88
+
89
+ # Check if it's likely a page
90
+ if is_page_file(f):
91
+ files.append(f)
92
+
93
+ return files[:50] # Limit to 50 files
94
+
95
+
96
+ def check_page(file_path: Path) -> dict:
97
+ """Check a single page for SEO issues."""
98
+ issues = []
99
+
100
+ try:
101
+ content = file_path.read_text(encoding='utf-8', errors='ignore')
102
+ except Exception as e:
103
+ return {"file": str(file_path.name), "issues": [f"Error: {e}"]}
104
+
105
+ # Detect if this is a layout/template file (has Head component)
106
+ is_layout = 'Head>' in content or '<head' in content.lower()
107
+
108
+ # 1. Title tag
109
+ has_title = '<title' in content.lower() or 'title=' in content or 'Head>' in content
110
+ if not has_title and is_layout:
111
+ issues.append("Missing <title> tag")
112
+
113
+ # 2. Meta description
114
+ has_description = 'name="description"' in content.lower() or 'name=\'description\'' in content.lower()
115
+ if not has_description and is_layout:
116
+ issues.append("Missing meta description")
117
+
118
+ # 3. Open Graph tags
119
+ has_og = 'og:' in content or 'property="og:' in content.lower()
120
+ if not has_og and is_layout:
121
+ issues.append("Missing Open Graph tags")
122
+
123
+ # 4. Heading hierarchy - multiple H1s
124
+ h1_matches = re.findall(r'<h1[^>]*>', content, re.I)
125
+ if len(h1_matches) > 1:
126
+ issues.append(f"Multiple H1 tags ({len(h1_matches)})")
127
+
128
+ # 5. Images without alt
129
+ img_pattern = r'<img[^>]+>'
130
+ imgs = re.findall(img_pattern, content, re.I)
131
+ for img in imgs:
132
+ if 'alt=' not in img.lower():
133
+ issues.append("Image missing alt attribute")
134
+ break
135
+ if 'alt=""' in img or "alt=''" in img:
136
+ issues.append("Image has empty alt attribute")
137
+ break
138
+
139
+ # 6. Check for canonical link (nice to have)
140
+ # has_canonical = 'rel="canonical"' in content.lower()
141
+
142
+ return {
143
+ "file": str(file_path.name),
144
+ "issues": issues
145
+ }
146
+
147
+
148
+ def main():
149
+ project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
150
+
151
+ print(f"\n{'='*60}")
152
+ print(f" SEO CHECKER - Search Engine Optimization Audit")
153
+ print(f"{'='*60}")
154
+ print(f"Project: {project_path}")
155
+ print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
156
+ print("-"*60)
157
+
158
+ # Find pages
159
+ pages = find_pages(project_path)
160
+
161
+ if not pages:
162
+ print("\n[!] No page files found.")
163
+ print(" Looking for: HTML, JSX, TSX in pages/app/routes directories")
164
+ output = {"script": "seo_checker", "files_checked": 0, "passed": True}
165
+ print("\n" + json.dumps(output, indent=2))
166
+ sys.exit(0)
167
+
168
+ print(f"Found {len(pages)} page files to analyze\n")
169
+
170
+ # Check each page
171
+ all_issues = []
172
+ for f in pages:
173
+ result = check_page(f)
174
+ if result["issues"]:
175
+ all_issues.append(result)
176
+
177
+ # Summary
178
+ print("=" * 60)
179
+ print("SEO ANALYSIS RESULTS")
180
+ print("=" * 60)
181
+
182
+ if all_issues:
183
+ # Group by issue type
184
+ issue_counts = {}
185
+ for item in all_issues:
186
+ for issue in item["issues"]:
187
+ issue_counts[issue] = issue_counts.get(issue, 0) + 1
188
+
189
+ print("\nIssue Summary:")
190
+ for issue, count in sorted(issue_counts.items(), key=lambda x: -x[1]):
191
+ print(f" [{count}] {issue}")
192
+
193
+ print(f"\nAffected files ({len(all_issues)}):")
194
+ for item in all_issues[:5]:
195
+ print(f" - {item['file']}")
196
+ if len(all_issues) > 5:
197
+ print(f" ... and {len(all_issues) - 5} more")
198
+ else:
199
+ print("\n[OK] No SEO issues found!")
200
+
201
+ total_issues = sum(len(item["issues"]) for item in all_issues)
202
+ passed = total_issues == 0
203
+
204
+ output = {
205
+ "script": "seo_checker",
206
+ "project": str(project_path),
207
+ "files_checked": len(pages),
208
+ "files_with_issues": len(all_issues),
209
+ "issues_found": total_issues,
210
+ "passed": passed
211
+ }
212
+
213
+ print("\n" + json.dumps(output, indent=2))
214
+
215
+ sys.exit(0 if passed else 1)
216
+
217
+
218
+ if __name__ == "__main__":
219
+ main()