bps-kit 1.0.1 → 1.0.2

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 (368) hide show
  1. package/package.json +1 -1
  2. package/templates/.agents/agents/backend-specialist.md +263 -0
  3. package/templates/.agents/agents/code-archaeologist.md +106 -0
  4. package/templates/.agents/agents/database-architect.md +226 -0
  5. package/templates/.agents/agents/debugger.md +225 -0
  6. package/templates/.agents/agents/devops-engineer.md +242 -0
  7. package/templates/.agents/agents/documentation-writer.md +104 -0
  8. package/templates/.agents/agents/explorer-agent.md +73 -0
  9. package/templates/.agents/agents/frontend-specialist.md +593 -0
  10. package/templates/.agents/agents/game-developer.md +162 -0
  11. package/templates/.agents/agents/mobile-developer.md +377 -0
  12. package/templates/.agents/agents/orchestrator.md +416 -0
  13. package/templates/.agents/agents/penetration-tester.md +188 -0
  14. package/templates/.agents/agents/performance-optimizer.md +187 -0
  15. package/templates/.agents/agents/product-manager.md +112 -0
  16. package/templates/.agents/agents/product-owner.md +95 -0
  17. package/templates/.agents/agents/project-planner.md +406 -0
  18. package/templates/.agents/agents/qa-automation-engineer.md +103 -0
  19. package/templates/.agents/agents/security-auditor.md +170 -0
  20. package/templates/.agents/agents/seo-specialist.md +111 -0
  21. package/templates/.agents/agents/test-engineer.md +158 -0
  22. package/templates/.agents/rules/GEMINI.md +219 -0
  23. package/templates/.agents/scripts/auto_preview.py +148 -0
  24. package/templates/.agents/scripts/checklist.py +217 -0
  25. package/templates/.agents/scripts/session_manager.py +120 -0
  26. package/templates/.agents/scripts/verify_all.py +327 -0
  27. package/templates/.agents/workflows/brainstorm.md +113 -0
  28. package/templates/.agents/workflows/create.md +59 -0
  29. package/templates/.agents/workflows/debug.md +103 -0
  30. package/templates/.agents/workflows/deploy.md +176 -0
  31. package/templates/.agents/workflows/enhance.md +63 -0
  32. package/templates/.agents/workflows/orchestrate.md +237 -0
  33. package/templates/.agents/workflows/plan.md +89 -0
  34. package/templates/.agents/workflows/preview.md +81 -0
  35. package/templates/.agents/workflows/setup-brain.md +39 -0
  36. package/templates/.agents/workflows/status.md +86 -0
  37. package/templates/.agents/workflows/test.md +144 -0
  38. package/templates/.agents/workflows/ui-ux-pro-max.md +296 -0
  39. package/templates/skills_normal/api-patterns/scripts/api_validator.py +211 -0
  40. package/templates/skills_normal/database-design/scripts/schema_validator.py +172 -0
  41. package/templates/skills_normal/frontend-design/scripts/accessibility_checker.py +183 -0
  42. package/templates/skills_normal/frontend-design/scripts/ux_audit.py +722 -0
  43. package/templates/skills_normal/git-pushing/scripts/smart_commit.sh +19 -0
  44. package/templates/skills_normal/lint-and-validate/scripts/lint_runner.py +184 -0
  45. package/templates/skills_normal/lint-and-validate/scripts/type_coverage.py +173 -0
  46. package/templates/skills_normal/performance-profiling/scripts/lighthouse_audit.py +76 -0
  47. package/templates/skills_normal/senior-fullstack/scripts/code_quality_analyzer.py +114 -0
  48. package/templates/skills_normal/senior-fullstack/scripts/fullstack_scaffolder.py +114 -0
  49. package/templates/skills_normal/senior-fullstack/scripts/project_scaffolder.py +114 -0
  50. package/templates/skills_normal/seo-fundamentals/scripts/seo_checker.py +219 -0
  51. package/templates/skills_normal/testing-patterns/scripts/test_runner.py +219 -0
  52. package/templates/skills_normal/vulnerability-scanner/scripts/security_scan.py +458 -0
  53. package/templates/vault/007/scripts/config.py +472 -0
  54. package/templates/vault/007/scripts/full_audit.py +1306 -0
  55. package/templates/vault/007/scripts/quick_scan.py +481 -0
  56. package/templates/vault/007/scripts/requirements.txt +26 -0
  57. package/templates/vault/007/scripts/scanners/__init__.py +0 -0
  58. package/templates/vault/007/scripts/scanners/dependency_scanner.py +1305 -0
  59. package/templates/vault/007/scripts/scanners/injection_scanner.py +1104 -0
  60. package/templates/vault/007/scripts/scanners/secrets_scanner.py +1008 -0
  61. package/templates/vault/007/scripts/score_calculator.py +693 -0
  62. package/templates/vault/agent-orchestrator/scripts/match_skills.py +329 -0
  63. package/templates/vault/agent-orchestrator/scripts/orchestrate.py +304 -0
  64. package/templates/vault/agent-orchestrator/scripts/requirements.txt +1 -0
  65. package/templates/vault/agent-orchestrator/scripts/scan_registry.py +508 -0
  66. package/templates/vault/ai-studio-image/scripts/config.py +613 -0
  67. package/templates/vault/ai-studio-image/scripts/generate.py +630 -0
  68. package/templates/vault/ai-studio-image/scripts/prompt_engine.py +424 -0
  69. package/templates/vault/ai-studio-image/scripts/requirements.txt +4 -0
  70. package/templates/vault/ai-studio-image/scripts/templates.py +349 -0
  71. package/templates/vault/android_ui_verification/scripts/verify_ui.sh +32 -0
  72. package/templates/vault/apify-audience-analysis/reference/scripts/run_actor.js +363 -0
  73. package/templates/vault/apify-brand-reputation-monitoring/reference/scripts/run_actor.js +363 -0
  74. package/templates/vault/apify-competitor-intelligence/reference/scripts/run_actor.js +363 -0
  75. package/templates/vault/apify-content-analytics/reference/scripts/run_actor.js +363 -0
  76. package/templates/vault/apify-ecommerce/reference/scripts/package.json +3 -0
  77. package/templates/vault/apify-ecommerce/reference/scripts/run_actor.js +369 -0
  78. package/templates/vault/apify-influencer-discovery/reference/scripts/run_actor.js +363 -0
  79. package/templates/vault/apify-lead-generation/reference/scripts/run_actor.js +363 -0
  80. package/templates/vault/apify-market-research/reference/scripts/run_actor.js +363 -0
  81. package/templates/vault/apify-trend-analysis/reference/scripts/run_actor.js +363 -0
  82. package/templates/vault/apify-ultimate-scraper/reference/scripts/run_actor.js +363 -0
  83. package/templates/vault/audio-transcriber/scripts/install-requirements.sh +190 -0
  84. package/templates/vault/audio-transcriber/scripts/transcribe.py +486 -0
  85. package/templates/vault/claude-monitor/scripts/api_bench.py +240 -0
  86. package/templates/vault/claude-monitor/scripts/config.py +69 -0
  87. package/templates/vault/claude-monitor/scripts/health_check.py +362 -0
  88. package/templates/vault/claude-monitor/scripts/monitor.py +296 -0
  89. package/templates/vault/content-creator/scripts/brand_voice_analyzer.py +185 -0
  90. package/templates/vault/content-creator/scripts/seo_optimizer.py +419 -0
  91. package/templates/vault/context-agent/scripts/active_context.py +227 -0
  92. package/templates/vault/context-agent/scripts/compressor.py +149 -0
  93. package/templates/vault/context-agent/scripts/config.py +69 -0
  94. package/templates/vault/context-agent/scripts/context_loader.py +155 -0
  95. package/templates/vault/context-agent/scripts/context_manager.py +302 -0
  96. package/templates/vault/context-agent/scripts/models.py +103 -0
  97. package/templates/vault/context-agent/scripts/project_registry.py +132 -0
  98. package/templates/vault/context-agent/scripts/requirements.txt +6 -0
  99. package/templates/vault/context-agent/scripts/search.py +115 -0
  100. package/templates/vault/context-agent/scripts/session_parser.py +206 -0
  101. package/templates/vault/context-agent/scripts/session_summary.py +319 -0
  102. package/templates/vault/context-guardian/scripts/context_snapshot.py +229 -0
  103. package/templates/vault/docx/ooxml/scripts/pack.py +159 -0
  104. package/templates/vault/docx/ooxml/scripts/unpack.py +29 -0
  105. package/templates/vault/docx/ooxml/scripts/validate.py +69 -0
  106. package/templates/vault/docx/ooxml/scripts/validation/__init__.py +15 -0
  107. package/templates/vault/docx/ooxml/scripts/validation/base.py +951 -0
  108. package/templates/vault/docx/ooxml/scripts/validation/docx.py +274 -0
  109. package/templates/vault/docx/ooxml/scripts/validation/pptx.py +315 -0
  110. package/templates/vault/docx/ooxml/scripts/validation/redlining.py +279 -0
  111. package/templates/vault/docx/scripts/__init__.py +1 -0
  112. package/templates/vault/docx/scripts/document.py +1276 -0
  113. package/templates/vault/docx/scripts/templates/comments.xml +3 -0
  114. package/templates/vault/docx/scripts/templates/commentsExtended.xml +3 -0
  115. package/templates/vault/docx/scripts/templates/commentsExtensible.xml +3 -0
  116. package/templates/vault/docx/scripts/templates/commentsIds.xml +3 -0
  117. package/templates/vault/docx/scripts/templates/people.xml +3 -0
  118. package/templates/vault/docx/scripts/utilities.py +374 -0
  119. package/templates/vault/docx-official/ooxml/scripts/pack.py +159 -0
  120. package/templates/vault/docx-official/ooxml/scripts/unpack.py +29 -0
  121. package/templates/vault/docx-official/ooxml/scripts/validate.py +69 -0
  122. package/templates/vault/docx-official/ooxml/scripts/validation/__init__.py +15 -0
  123. package/templates/vault/docx-official/ooxml/scripts/validation/base.py +951 -0
  124. package/templates/vault/docx-official/ooxml/scripts/validation/docx.py +274 -0
  125. package/templates/vault/docx-official/ooxml/scripts/validation/pptx.py +315 -0
  126. package/templates/vault/docx-official/ooxml/scripts/validation/redlining.py +279 -0
  127. package/templates/vault/docx-official/scripts/__init__.py +1 -0
  128. package/templates/vault/docx-official/scripts/document.py +1276 -0
  129. package/templates/vault/docx-official/scripts/templates/comments.xml +3 -0
  130. package/templates/vault/docx-official/scripts/templates/commentsExtended.xml +3 -0
  131. package/templates/vault/docx-official/scripts/templates/commentsExtensible.xml +3 -0
  132. package/templates/vault/docx-official/scripts/templates/commentsIds.xml +3 -0
  133. package/templates/vault/docx-official/scripts/templates/people.xml +3 -0
  134. package/templates/vault/docx-official/scripts/utilities.py +374 -0
  135. package/templates/vault/geo-fundamentals/scripts/geo_checker.py +289 -0
  136. package/templates/vault/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
  137. package/templates/vault/i18n-localization/scripts/i18n_checker.py +241 -0
  138. package/templates/vault/instagram/scripts/account_setup.py +233 -0
  139. package/templates/vault/instagram/scripts/analyze.py +221 -0
  140. package/templates/vault/instagram/scripts/api_client.py +444 -0
  141. package/templates/vault/instagram/scripts/auth.py +411 -0
  142. package/templates/vault/instagram/scripts/comments.py +160 -0
  143. package/templates/vault/instagram/scripts/config.py +111 -0
  144. package/templates/vault/instagram/scripts/db.py +467 -0
  145. package/templates/vault/instagram/scripts/export.py +138 -0
  146. package/templates/vault/instagram/scripts/governance.py +233 -0
  147. package/templates/vault/instagram/scripts/hashtags.py +114 -0
  148. package/templates/vault/instagram/scripts/insights.py +170 -0
  149. package/templates/vault/instagram/scripts/media.py +65 -0
  150. package/templates/vault/instagram/scripts/messages.py +103 -0
  151. package/templates/vault/instagram/scripts/profile.py +58 -0
  152. package/templates/vault/instagram/scripts/publish.py +449 -0
  153. package/templates/vault/instagram/scripts/requirements.txt +5 -0
  154. package/templates/vault/instagram/scripts/run_all.py +189 -0
  155. package/templates/vault/instagram/scripts/schedule.py +189 -0
  156. package/templates/vault/instagram/scripts/serve_api.py +234 -0
  157. package/templates/vault/instagram/scripts/templates.py +155 -0
  158. package/templates/vault/junta-leiloeiros/scripts/db.py +216 -0
  159. package/templates/vault/junta-leiloeiros/scripts/export.py +137 -0
  160. package/templates/vault/junta-leiloeiros/scripts/requirements.txt +15 -0
  161. package/templates/vault/junta-leiloeiros/scripts/run_all.py +190 -0
  162. package/templates/vault/junta-leiloeiros/scripts/scraper/__init__.py +4 -0
  163. package/templates/vault/junta-leiloeiros/scripts/scraper/base_scraper.py +209 -0
  164. package/templates/vault/junta-leiloeiros/scripts/scraper/generic_scraper.py +110 -0
  165. package/templates/vault/junta-leiloeiros/scripts/scraper/jucap.py +110 -0
  166. package/templates/vault/junta-leiloeiros/scripts/scraper/juceac.py +72 -0
  167. package/templates/vault/junta-leiloeiros/scripts/scraper/juceal.py +72 -0
  168. package/templates/vault/junta-leiloeiros/scripts/scraper/juceb.py +68 -0
  169. package/templates/vault/junta-leiloeiros/scripts/scraper/jucec.py +63 -0
  170. package/templates/vault/junta-leiloeiros/scripts/scraper/jucema.py +211 -0
  171. package/templates/vault/junta-leiloeiros/scripts/scraper/jucemg.py +218 -0
  172. package/templates/vault/junta-leiloeiros/scripts/scraper/jucep.py +70 -0
  173. package/templates/vault/junta-leiloeiros/scripts/scraper/jucepa.py +74 -0
  174. package/templates/vault/junta-leiloeiros/scripts/scraper/jucepar.py +80 -0
  175. package/templates/vault/junta-leiloeiros/scripts/scraper/jucepe.py +78 -0
  176. package/templates/vault/junta-leiloeiros/scripts/scraper/jucepi.py +69 -0
  177. package/templates/vault/junta-leiloeiros/scripts/scraper/jucer.py +256 -0
  178. package/templates/vault/junta-leiloeiros/scripts/scraper/jucerja.py +170 -0
  179. package/templates/vault/junta-leiloeiros/scripts/scraper/jucern.py +71 -0
  180. package/templates/vault/junta-leiloeiros/scripts/scraper/jucesc.py +89 -0
  181. package/templates/vault/junta-leiloeiros/scripts/scraper/jucesp.py +233 -0
  182. package/templates/vault/junta-leiloeiros/scripts/scraper/jucetins.py +134 -0
  183. package/templates/vault/junta-leiloeiros/scripts/scraper/jucis_df.py +63 -0
  184. package/templates/vault/junta-leiloeiros/scripts/scraper/jucisrs.py +299 -0
  185. package/templates/vault/junta-leiloeiros/scripts/scraper/states.py +99 -0
  186. package/templates/vault/junta-leiloeiros/scripts/serve_api.py +164 -0
  187. package/templates/vault/junta-leiloeiros/scripts/web_scraper_fallback.py +233 -0
  188. package/templates/vault/last30days/scripts/last30days.py +521 -0
  189. package/templates/vault/last30days/scripts/lib/__init__.py +1 -0
  190. package/templates/vault/last30days/scripts/lib/cache.py +152 -0
  191. package/templates/vault/last30days/scripts/lib/dates.py +124 -0
  192. package/templates/vault/last30days/scripts/lib/dedupe.py +120 -0
  193. package/templates/vault/last30days/scripts/lib/env.py +149 -0
  194. package/templates/vault/last30days/scripts/lib/http.py +152 -0
  195. package/templates/vault/last30days/scripts/lib/models.py +175 -0
  196. package/templates/vault/last30days/scripts/lib/normalize.py +160 -0
  197. package/templates/vault/last30days/scripts/lib/openai_reddit.py +230 -0
  198. package/templates/vault/last30days/scripts/lib/reddit_enrich.py +232 -0
  199. package/templates/vault/last30days/scripts/lib/render.py +383 -0
  200. package/templates/vault/last30days/scripts/lib/schema.py +336 -0
  201. package/templates/vault/last30days/scripts/lib/score.py +311 -0
  202. package/templates/vault/last30days/scripts/lib/ui.py +324 -0
  203. package/templates/vault/last30days/scripts/lib/websearch.py +401 -0
  204. package/templates/vault/last30days/scripts/lib/xai_x.py +217 -0
  205. package/templates/vault/leiloeiro-avaliacao/scripts/governance.py +106 -0
  206. package/templates/vault/leiloeiro-avaliacao/scripts/requirements.txt +1 -0
  207. package/templates/vault/leiloeiro-edital/scripts/governance.py +106 -0
  208. package/templates/vault/leiloeiro-edital/scripts/requirements.txt +1 -0
  209. package/templates/vault/leiloeiro-ia/scripts/governance.py +106 -0
  210. package/templates/vault/leiloeiro-ia/scripts/requirements.txt +1 -0
  211. package/templates/vault/leiloeiro-juridico/scripts/governance.py +106 -0
  212. package/templates/vault/leiloeiro-juridico/scripts/requirements.txt +1 -0
  213. package/templates/vault/leiloeiro-mercado/scripts/governance.py +106 -0
  214. package/templates/vault/leiloeiro-mercado/scripts/requirements.txt +1 -0
  215. package/templates/vault/leiloeiro-risco/scripts/governance.py +106 -0
  216. package/templates/vault/leiloeiro-risco/scripts/requirements.txt +1 -0
  217. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/database.ts +24 -0
  218. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/db.ts +35 -0
  219. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/index.ts +2 -0
  220. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/migrations.ts +31 -0
  221. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/schema.sql +8 -0
  222. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/index.ts +44 -0
  223. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/routes/todos.ts +155 -0
  224. package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/types/index.ts +35 -0
  225. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/App.css +384 -0
  226. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/App.tsx +81 -0
  227. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/api/todos.ts +57 -0
  228. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/ConfirmDialog.tsx +26 -0
  229. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/EmptyState.tsx +8 -0
  230. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/TodoForm.tsx +43 -0
  231. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/TodoItem.tsx +36 -0
  232. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/TodoList.tsx +27 -0
  233. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/hooks/useTodos.ts +81 -0
  234. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/index.css +48 -0
  235. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/main.tsx +10 -0
  236. package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/vite-env.d.ts +1 -0
  237. package/templates/vault/loki-mode/scripts/export-to-vibe-kanban.sh +178 -0
  238. package/templates/vault/loki-mode/scripts/loki-wrapper.sh +281 -0
  239. package/templates/vault/loki-mode/scripts/take-screenshots.js +55 -0
  240. package/templates/vault/matematico-tao/scripts/complexity_analyzer.py +544 -0
  241. package/templates/vault/matematico-tao/scripts/dependency_graph.py +538 -0
  242. package/templates/vault/mcp-builder/scripts/connections.py +151 -0
  243. package/templates/vault/mcp-builder/scripts/evaluation.py +373 -0
  244. package/templates/vault/mcp-builder/scripts/example_evaluation.xml +22 -0
  245. package/templates/vault/mcp-builder/scripts/requirements.txt +2 -0
  246. package/templates/vault/mobile-design/scripts/mobile_audit.py +670 -0
  247. package/templates/vault/notebooklm/scripts/__init__.py +81 -0
  248. package/templates/vault/notebooklm/scripts/ask_question.py +256 -0
  249. package/templates/vault/notebooklm/scripts/auth_manager.py +358 -0
  250. package/templates/vault/notebooklm/scripts/browser_session.py +255 -0
  251. package/templates/vault/notebooklm/scripts/browser_utils.py +107 -0
  252. package/templates/vault/notebooklm/scripts/cleanup_manager.py +302 -0
  253. package/templates/vault/notebooklm/scripts/config.py +44 -0
  254. package/templates/vault/notebooklm/scripts/notebook_manager.py +410 -0
  255. package/templates/vault/notebooklm/scripts/run.py +102 -0
  256. package/templates/vault/notebooklm/scripts/setup_environment.py +204 -0
  257. package/templates/vault/pdf/scripts/check_bounding_boxes.py +70 -0
  258. package/templates/vault/pdf/scripts/check_bounding_boxes_test.py +226 -0
  259. package/templates/vault/pdf/scripts/check_fillable_fields.py +12 -0
  260. package/templates/vault/pdf/scripts/convert_pdf_to_images.py +35 -0
  261. package/templates/vault/pdf/scripts/create_validation_image.py +41 -0
  262. package/templates/vault/pdf/scripts/extract_form_field_info.py +152 -0
  263. package/templates/vault/pdf/scripts/fill_fillable_fields.py +114 -0
  264. package/templates/vault/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  265. package/templates/vault/pdf-official/scripts/check_bounding_boxes.py +70 -0
  266. package/templates/vault/pdf-official/scripts/check_bounding_boxes_test.py +226 -0
  267. package/templates/vault/pdf-official/scripts/check_fillable_fields.py +12 -0
  268. package/templates/vault/pdf-official/scripts/convert_pdf_to_images.py +35 -0
  269. package/templates/vault/pdf-official/scripts/create_validation_image.py +41 -0
  270. package/templates/vault/pdf-official/scripts/extract_form_field_info.py +152 -0
  271. package/templates/vault/pdf-official/scripts/fill_fillable_fields.py +114 -0
  272. package/templates/vault/pdf-official/scripts/fill_pdf_form_with_annotations.py +108 -0
  273. package/templates/vault/planning-with-files/scripts/check-complete.sh +44 -0
  274. package/templates/vault/planning-with-files/scripts/init-session.sh +120 -0
  275. package/templates/vault/pptx/ooxml/scripts/pack.py +159 -0
  276. package/templates/vault/pptx/ooxml/scripts/unpack.py +29 -0
  277. package/templates/vault/pptx/ooxml/scripts/validate.py +69 -0
  278. package/templates/vault/pptx/ooxml/scripts/validation/__init__.py +15 -0
  279. package/templates/vault/pptx/ooxml/scripts/validation/base.py +951 -0
  280. package/templates/vault/pptx/ooxml/scripts/validation/docx.py +274 -0
  281. package/templates/vault/pptx/ooxml/scripts/validation/pptx.py +315 -0
  282. package/templates/vault/pptx/ooxml/scripts/validation/redlining.py +279 -0
  283. package/templates/vault/pptx/scripts/html2pptx.js +979 -0
  284. package/templates/vault/pptx/scripts/inventory.py +1020 -0
  285. package/templates/vault/pptx/scripts/rearrange.py +231 -0
  286. package/templates/vault/pptx/scripts/replace.py +385 -0
  287. package/templates/vault/pptx/scripts/thumbnail.py +450 -0
  288. package/templates/vault/pptx-official/ooxml/scripts/pack.py +159 -0
  289. package/templates/vault/pptx-official/ooxml/scripts/unpack.py +29 -0
  290. package/templates/vault/pptx-official/ooxml/scripts/validate.py +69 -0
  291. package/templates/vault/pptx-official/ooxml/scripts/validation/__init__.py +15 -0
  292. package/templates/vault/pptx-official/ooxml/scripts/validation/base.py +951 -0
  293. package/templates/vault/pptx-official/ooxml/scripts/validation/docx.py +274 -0
  294. package/templates/vault/pptx-official/ooxml/scripts/validation/pptx.py +315 -0
  295. package/templates/vault/pptx-official/ooxml/scripts/validation/redlining.py +279 -0
  296. package/templates/vault/pptx-official/scripts/html2pptx.js +979 -0
  297. package/templates/vault/pptx-official/scripts/inventory.py +1020 -0
  298. package/templates/vault/pptx-official/scripts/rearrange.py +231 -0
  299. package/templates/vault/pptx-official/scripts/replace.py +385 -0
  300. package/templates/vault/pptx-official/scripts/thumbnail.py +450 -0
  301. package/templates/vault/product-manager-toolkit/scripts/customer_interview_analyzer.py +441 -0
  302. package/templates/vault/product-manager-toolkit/scripts/rice_prioritizer.py +296 -0
  303. package/templates/vault/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
  304. package/templates/vault/scripts/.skill_cache.json +7538 -0
  305. package/templates/vault/scripts/skill_search.py +228 -0
  306. package/templates/vault/senior-architect/scripts/architecture_diagram_generator.py +114 -0
  307. package/templates/vault/senior-architect/scripts/dependency_analyzer.py +114 -0
  308. package/templates/vault/senior-architect/scripts/project_architect.py +114 -0
  309. package/templates/vault/shopify-development/scripts/requirements.txt +19 -0
  310. package/templates/vault/shopify-development/scripts/shopify_graphql.py +428 -0
  311. package/templates/vault/shopify-development/scripts/shopify_init.py +441 -0
  312. package/templates/vault/shopify-development/scripts/tests/test_shopify_init.py +379 -0
  313. package/templates/vault/skill-creator/scripts/init_skill.py +303 -0
  314. package/templates/vault/skill-creator/scripts/package_skill.py +110 -0
  315. package/templates/vault/skill-creator/scripts/quick_validate.py +95 -0
  316. package/templates/vault/skill-installer/scripts/detect_skills.py +318 -0
  317. package/templates/vault/skill-installer/scripts/install_skill.py +1708 -0
  318. package/templates/vault/skill-installer/scripts/package_skill.py +417 -0
  319. package/templates/vault/skill-installer/scripts/requirements.txt +1 -0
  320. package/templates/vault/skill-installer/scripts/validate_skill.py +430 -0
  321. package/templates/vault/skill-sentinel/scripts/analyzers/__init__.py +13 -0
  322. package/templates/vault/skill-sentinel/scripts/analyzers/code_quality.py +247 -0
  323. package/templates/vault/skill-sentinel/scripts/analyzers/cross_skill.py +134 -0
  324. package/templates/vault/skill-sentinel/scripts/analyzers/dependencies.py +121 -0
  325. package/templates/vault/skill-sentinel/scripts/analyzers/documentation.py +189 -0
  326. package/templates/vault/skill-sentinel/scripts/analyzers/governance_audit.py +153 -0
  327. package/templates/vault/skill-sentinel/scripts/analyzers/performance.py +164 -0
  328. package/templates/vault/skill-sentinel/scripts/analyzers/security.py +189 -0
  329. package/templates/vault/skill-sentinel/scripts/config.py +158 -0
  330. package/templates/vault/skill-sentinel/scripts/cost_optimizer.py +146 -0
  331. package/templates/vault/skill-sentinel/scripts/db.py +354 -0
  332. package/templates/vault/skill-sentinel/scripts/governance.py +58 -0
  333. package/templates/vault/skill-sentinel/scripts/recommender.py +228 -0
  334. package/templates/vault/skill-sentinel/scripts/report_generator.py +224 -0
  335. package/templates/vault/skill-sentinel/scripts/requirements.txt +1 -0
  336. package/templates/vault/skill-sentinel/scripts/run_audit.py +290 -0
  337. package/templates/vault/skill-sentinel/scripts/scanner.py +271 -0
  338. package/templates/vault/stability-ai/scripts/config.py +266 -0
  339. package/templates/vault/stability-ai/scripts/generate.py +687 -0
  340. package/templates/vault/stability-ai/scripts/requirements.txt +4 -0
  341. package/templates/vault/stability-ai/scripts/styles.py +174 -0
  342. package/templates/vault/telegram/assets/boilerplate/nodejs/src/bot-client.ts +86 -0
  343. package/templates/vault/telegram/assets/boilerplate/nodejs/src/handlers.ts +79 -0
  344. package/templates/vault/telegram/assets/boilerplate/nodejs/src/index.ts +32 -0
  345. package/templates/vault/telegram/scripts/send_message.py +143 -0
  346. package/templates/vault/telegram/scripts/setup_project.py +103 -0
  347. package/templates/vault/telegram/scripts/test_bot.py +144 -0
  348. package/templates/vault/typescript-expert/scripts/ts_diagnostic.py +203 -0
  349. package/templates/vault/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
  350. package/templates/vault/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
  351. package/templates/vault/ui-ux-pro-max/scripts/core.py +257 -0
  352. package/templates/vault/ui-ux-pro-max/scripts/design_system.py +487 -0
  353. package/templates/vault/ui-ux-pro-max/scripts/search.py +76 -0
  354. package/templates/vault/videodb/scripts/ws_listener.py +204 -0
  355. package/templates/vault/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
  356. package/templates/vault/web-artifacts-builder/scripts/init-artifact.sh +322 -0
  357. package/templates/vault/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  358. package/templates/vault/webapp-testing/scripts/with_server.py +106 -0
  359. package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/index.ts +125 -0
  360. package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/template-manager.ts +67 -0
  361. package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/types.ts +216 -0
  362. package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/webhook-handler.ts +173 -0
  363. package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/whatsapp-client.ts +193 -0
  364. package/templates/vault/whatsapp-cloud-api/scripts/send_test_message.py +137 -0
  365. package/templates/vault/whatsapp-cloud-api/scripts/setup_project.py +118 -0
  366. package/templates/vault/whatsapp-cloud-api/scripts/validate_config.py +190 -0
  367. package/templates/vault/youtube-summarizer/scripts/extract-transcript.py +65 -0
  368. package/templates/vault/youtube-summarizer/scripts/install-dependencies.sh +28 -0
@@ -0,0 +1,164 @@
1
+ """
2
+ Analyzer de performance.
3
+
4
+ Verifica: chamadas API sequenciais, caching, N+1 queries,
5
+ connection reuse, retry/backoff, timeouts.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ from pathlib import Path
11
+ from typing import Any, Dict, List, Tuple
12
+
13
+
14
+ def analyze(skill_data: Dict[str, Any]) -> Tuple[float, List[Dict[str, Any]]]:
15
+ """Analisa performance de uma skill. Retorna (score, findings)."""
16
+ score = 100.0
17
+ findings: List[Dict[str, Any]] = []
18
+ skill_name = skill_data["name"]
19
+ skill_path = Path(skill_data["path"])
20
+
21
+ has_retry = False
22
+ has_timeout = False
23
+ has_caching = False
24
+ has_connection_pool = False
25
+ has_async = False
26
+ has_concurrency = False
27
+
28
+ api_call_files = []
29
+
30
+ for rel_path in skill_data.get("python_files", []):
31
+ filepath = skill_path / rel_path
32
+ if not filepath.exists():
33
+ continue
34
+ try:
35
+ source = filepath.read_text(encoding="utf-8", errors="replace")
36
+ except OSError:
37
+ continue
38
+
39
+ # Detectar patterns de performance
40
+ if re.search(r'(?:retry|backoff|MAX_RETRIES|RETRY_BACKOFF)', source, re.I):
41
+ has_retry = True
42
+ if re.search(r'(?:timeout|REQUEST_TIMEOUT)', source, re.I):
43
+ has_timeout = True
44
+ if re.search(r'(?:cache|lru_cache|functools\.cache|_cache)', source, re.I):
45
+ has_caching = True
46
+ if re.search(r'(?:session|Session\(\)|httpx\.Client)', source, re.I):
47
+ has_connection_pool = True
48
+ if re.search(r'(?:async\s+def|asyncio|aiohttp|httpx\.AsyncClient)', source):
49
+ has_async = True
50
+ if re.search(r'(?:concurrent|ThreadPool|ProcessPool|asyncio\.gather|--concurrency)', source, re.I):
51
+ has_concurrency = True
52
+
53
+ # Contar chamadas API (requests.get/post, httpx, etc)
54
+ api_calls = len(re.findall(
55
+ r'(?:requests\.\w+|httpx\.\w+|self\.\w*(?:get|post|put|delete|patch))\s*\(',
56
+ source
57
+ ))
58
+ if api_calls > 0:
59
+ api_call_files.append((rel_path, api_calls))
60
+
61
+ # Detectar N+1 patterns (loop com query SQL dentro)
62
+ # Analise linha-a-linha para evitar backtracking em regex DOTALL
63
+ lines = source.splitlines()
64
+ in_for_loop = False
65
+ for line_text in lines:
66
+ stripped = line_text.strip()
67
+ if stripped.startswith("for ") and stripped.endswith(":"):
68
+ in_for_loop = True
69
+ elif in_for_loop and stripped and not stripped[0].isspace() and not line_text[0].isspace():
70
+ in_for_loop = False
71
+ elif in_for_loop and re.search(r'(?:SELECT|\.execute)\s*\(', stripped):
72
+ findings.append({
73
+ "skill_name": skill_name,
74
+ "dimension": "performance",
75
+ "severity": "medium",
76
+ "category": "n_plus_1",
77
+ "title": f"Possivel N+1 query em {rel_path}",
78
+ "description": "Loop com query SQL pode causar muitas chamadas ao banco",
79
+ "file_path": rel_path,
80
+ "recommendation": "Carregar dados em batch antes do loop",
81
+ "effort": "medium",
82
+ "impact": "high",
83
+ })
84
+ score -= 8
85
+ break
86
+
87
+ # Criar conexao dentro de loop (analise simples)
88
+ has_connect_in_loop = False
89
+ in_for_loop = False
90
+ for line_text in lines:
91
+ stripped = line_text.strip()
92
+ if stripped.startswith("for ") and stripped.endswith(":"):
93
+ in_for_loop = True
94
+ elif in_for_loop and stripped and not line_text[0].isspace():
95
+ in_for_loop = False
96
+ elif in_for_loop and "_connect()" in stripped:
97
+ has_connect_in_loop = True
98
+ break
99
+
100
+ if has_connect_in_loop:
101
+ findings.append({
102
+ "skill_name": skill_name,
103
+ "dimension": "performance",
104
+ "severity": "medium",
105
+ "category": "connection_per_iteration",
106
+ "title": f"Conexao criada dentro de loop em {rel_path}",
107
+ "file_path": rel_path,
108
+ "recommendation": "Mover _connect() para fora do loop, reutilizar conexao",
109
+ "effort": "low",
110
+ "impact": "high",
111
+ })
112
+ score -= 5
113
+
114
+ # Verificar ausencia de boas praticas
115
+ if not has_retry and api_call_files:
116
+ findings.append({
117
+ "skill_name": skill_name,
118
+ "dimension": "performance",
119
+ "severity": "medium",
120
+ "category": "no_retry",
121
+ "title": "Sem retry/backoff para chamadas API",
122
+ "description": f"Encontradas chamadas API em {len(api_call_files)} arquivo(s) sem mecanismo de retry",
123
+ "recommendation": "Implementar retry com exponential backoff (ex: tenacity, ou manual)",
124
+ "effort": "medium",
125
+ "impact": "high",
126
+ })
127
+ score -= 10
128
+
129
+ if not has_timeout and api_call_files:
130
+ findings.append({
131
+ "skill_name": skill_name,
132
+ "dimension": "performance",
133
+ "severity": "medium",
134
+ "category": "no_timeout",
135
+ "title": "Sem timeout configurado para chamadas HTTP",
136
+ "recommendation": "Adicionar timeout= em todas as chamadas requests/httpx",
137
+ "effort": "low",
138
+ "impact": "medium",
139
+ })
140
+ score -= 5
141
+
142
+ if not has_connection_pool and len(api_call_files) > 2:
143
+ findings.append({
144
+ "skill_name": skill_name,
145
+ "dimension": "performance",
146
+ "severity": "low",
147
+ "category": "no_connection_reuse",
148
+ "title": "Sem reuso de conexoes HTTP",
149
+ "description": "Multiplos arquivos fazem chamadas HTTP sem Session/Client compartilhado",
150
+ "recommendation": "Usar requests.Session() ou httpx.Client() para reutilizar conexoes",
151
+ "effort": "low",
152
+ "impact": "medium",
153
+ })
154
+ score -= 3
155
+
156
+ # Bonus
157
+ if has_retry:
158
+ score = min(100.0, score + 5)
159
+ if has_async or has_concurrency:
160
+ score = min(100.0, score + 5)
161
+ if has_caching:
162
+ score = min(100.0, score + 3)
163
+
164
+ return max(0.0, min(100.0, score)), findings
@@ -0,0 +1,189 @@
1
+ """
2
+ Analyzer de seguranca.
3
+
4
+ Verifica: secrets hardcoded, SQL injection, validacao de input,
5
+ HTTPS enforcement, tokens em logs, padroes de autenticacao.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ from pathlib import Path
11
+ from typing import Any, Dict, List, Tuple
12
+
13
+ from config import SECRET_EXCEPTIONS, SECRET_PATTERNS, SQL_INJECTION_PATTERNS
14
+
15
+
16
+ def _check_secrets(source: str, rel_path: str, skill_name: str) -> List[Dict[str, Any]]:
17
+ """Verifica patterns de secrets hardcoded."""
18
+ findings = []
19
+ for i, line in enumerate(source.splitlines(), 1):
20
+ for pattern in SECRET_PATTERNS:
21
+ if pattern.search(line):
22
+ # Checar se eh excecao conhecida
23
+ is_exception = any(exc in line for exc in SECRET_EXCEPTIONS)
24
+ if is_exception:
25
+ continue
26
+ findings.append({
27
+ "skill_name": skill_name,
28
+ "dimension": "security",
29
+ "severity": "critical",
30
+ "category": "hardcoded_secret",
31
+ "title": f"Possivel secret hardcoded em {rel_path}:{i}",
32
+ "description": "Credencial ou token encontrado no codigo-fonte. "
33
+ "Mover para variavel de ambiente.",
34
+ "file_path": rel_path,
35
+ "line_number": i,
36
+ "recommendation": "Usar os.environ.get() ou arquivo .env (nao versionado)",
37
+ "effort": "low",
38
+ "impact": "high",
39
+ })
40
+ return findings
41
+
42
+
43
+ def _check_sql_injection(source: str, rel_path: str, skill_name: str) -> List[Dict[str, Any]]:
44
+ """Verifica uso de f-strings/format em queries SQL."""
45
+ findings = []
46
+ for i, line in enumerate(source.splitlines(), 1):
47
+ for pattern in SQL_INJECTION_PATTERNS:
48
+ if pattern.search(line):
49
+ findings.append({
50
+ "skill_name": skill_name,
51
+ "dimension": "security",
52
+ "severity": "high",
53
+ "category": "sql_injection",
54
+ "title": f"Possivel SQL injection em {rel_path}:{i}",
55
+ "description": "Interpolacao de string em query SQL. Usar queries parametrizadas (?)",
56
+ "file_path": rel_path,
57
+ "line_number": i,
58
+ "recommendation": "Substituir f-string/format por query parametrizada: cursor.execute(sql, [param])",
59
+ "effort": "low",
60
+ "impact": "high",
61
+ })
62
+ return findings
63
+
64
+
65
+ def _check_https(source: str, rel_path: str, skill_name: str) -> List[Dict[str, Any]]:
66
+ """Verifica se URLs usam HTTP em vez de HTTPS."""
67
+ findings = []
68
+ http_pattern = re.compile(r'["\']http://(?!localhost|127\.0\.0\.1|0\.0\.0\.0)')
69
+ for i, line in enumerate(source.splitlines(), 1):
70
+ if http_pattern.search(line):
71
+ findings.append({
72
+ "skill_name": skill_name,
73
+ "dimension": "security",
74
+ "severity": "medium",
75
+ "category": "insecure_http",
76
+ "title": f"URL HTTP insegura em {rel_path}:{i}",
77
+ "description": "Uso de HTTP em vez de HTTPS para comunicacao externa.",
78
+ "file_path": rel_path,
79
+ "line_number": i,
80
+ "recommendation": "Trocar http:// por https://",
81
+ "effort": "low",
82
+ "impact": "medium",
83
+ })
84
+ return findings
85
+
86
+
87
+ def _check_token_in_logs(source: str, rel_path: str, skill_name: str) -> List[Dict[str, Any]]:
88
+ """Verifica se tokens/secrets aparecem em print/logging."""
89
+ findings = []
90
+ log_pattern = re.compile(
91
+ r'(?:print|logging\.\w+|logger\.\w+)\s*\(.*(?:token|secret|password|key|credential)',
92
+ re.I
93
+ )
94
+ for i, line in enumerate(source.splitlines(), 1):
95
+ if log_pattern.search(line):
96
+ findings.append({
97
+ "skill_name": skill_name,
98
+ "dimension": "security",
99
+ "severity": "high",
100
+ "category": "token_in_log",
101
+ "title": f"Possivel token em log em {rel_path}:{i}",
102
+ "description": "Dados sensiveis podem estar sendo logados.",
103
+ "file_path": rel_path,
104
+ "line_number": i,
105
+ "recommendation": "Nao logar tokens/secrets. Usar mascaramento ou remover do log.",
106
+ "effort": "low",
107
+ "impact": "high",
108
+ })
109
+ return findings
110
+
111
+
112
+ def _check_input_validation(source: str, rel_path: str, skill_name: str) -> List[Dict[str, Any]]:
113
+ """Verifica se argumentos CLI sao validados."""
114
+ findings = []
115
+ # Se usa argparse mas nao tem choices/type/nargs restritivos, e warning leve
116
+ if "argparse" in source and "add_argument" in source:
117
+ # Verificar se ao menos alguns args tem type= ou choices=
118
+ args_count = source.count("add_argument")
119
+ typed_count = len(re.findall(r'add_argument\([^)]*(?:type=|choices=)', source))
120
+ if args_count > 3 and typed_count == 0:
121
+ findings.append({
122
+ "skill_name": skill_name,
123
+ "dimension": "security",
124
+ "severity": "low",
125
+ "category": "weak_input_validation",
126
+ "title": f"Validacao fraca de argumentos CLI em {rel_path}",
127
+ "description": f"{args_count} argumentos sem type= ou choices=",
128
+ "file_path": rel_path,
129
+ "recommendation": "Adicionar type= e choices= nos argumentos do argparse",
130
+ "effort": "low",
131
+ "impact": "low",
132
+ })
133
+ return findings
134
+
135
+
136
+ def analyze(skill_data: Dict[str, Any]) -> Tuple[float, List[Dict[str, Any]]]:
137
+ """Analisa seguranca de uma skill. Retorna (score, findings)."""
138
+ score = 100.0
139
+ findings: List[Dict[str, Any]] = []
140
+ skill_name = skill_data["name"]
141
+ skill_path = Path(skill_data["path"])
142
+
143
+ has_auth_module = False
144
+ uses_env_vars = False
145
+
146
+ for rel_path in skill_data.get("python_files", []):
147
+ filepath = skill_path / rel_path
148
+ if not filepath.exists():
149
+ continue
150
+
151
+ try:
152
+ source = filepath.read_text(encoding="utf-8", errors="replace")
153
+ except OSError:
154
+ continue
155
+
156
+ if "auth" in rel_path.lower():
157
+ has_auth_module = True
158
+ if "os.environ" in source or "os.getenv" in source or "dotenv" in source:
159
+ uses_env_vars = True
160
+
161
+ # Checks
162
+ secret_findings = _check_secrets(source, rel_path, skill_name)
163
+ findings.extend(secret_findings)
164
+ score -= len([f for f in secret_findings if f["severity"] == "critical"]) * 20
165
+ score -= len([f for f in secret_findings if f["severity"] == "high"]) * 10
166
+
167
+ sql_findings = _check_sql_injection(source, rel_path, skill_name)
168
+ findings.extend(sql_findings)
169
+ score -= len(sql_findings) * 15
170
+
171
+ https_findings = _check_https(source, rel_path, skill_name)
172
+ findings.extend(https_findings)
173
+ score -= len(https_findings) * 5
174
+
175
+ token_findings = _check_token_in_logs(source, rel_path, skill_name)
176
+ findings.extend(token_findings)
177
+ score -= len(token_findings) * 10
178
+
179
+ input_findings = _check_input_validation(source, rel_path, skill_name)
180
+ findings.extend(input_findings)
181
+ score -= len(input_findings) * 2
182
+
183
+ # Bonus por boas praticas
184
+ if has_auth_module:
185
+ score = min(100.0, score + 5)
186
+ if uses_env_vars:
187
+ score = min(100.0, score + 5)
188
+
189
+ return max(0.0, min(100.0, score)), findings
@@ -0,0 +1,158 @@
1
+ """
2
+ Configuracao central da skill Sentinel.
3
+
4
+ Paths, thresholds de analise, pesos de scoring e padroes de seguranca.
5
+ Importado por todos os outros scripts.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import re
10
+ from pathlib import Path
11
+ from typing import Any, Dict, List, Tuple
12
+
13
+ # -- Paths --------------------------------------------------------------------
14
+ ROOT_DIR = Path(__file__).resolve().parent.parent
15
+ SCRIPTS_DIR = ROOT_DIR / "scripts"
16
+ DATA_DIR = ROOT_DIR / "data"
17
+ REPORTS_DIR = DATA_DIR / "reports"
18
+ DB_PATH = DATA_DIR / "sentinel.db"
19
+
20
+ # Raiz do ecossistema de skills
21
+ SKILLS_ROOT = ROOT_DIR.parent
22
+
23
+ # Garante que diretorios existem
24
+ DATA_DIR.mkdir(parents=True, exist_ok=True)
25
+ REPORTS_DIR.mkdir(parents=True, exist_ok=True)
26
+
27
+ # -- Skill Discovery ----------------------------------------------------------
28
+ # Locais onde skills podem estar (relativo a SKILLS_ROOT)
29
+ SKILL_SEARCH_PATHS: List[Path] = [
30
+ SKILLS_ROOT, # skills de primeiro nivel
31
+ SKILLS_ROOT / ".claude" / "skills", # skills built-in do Claude
32
+ ]
33
+
34
+ # Subdiretorios a escanear recursivamente (para skills aninhadas)
35
+ SKILL_MAX_DEPTH = 3
36
+
37
+ # Diretorios a ignorar durante o scan
38
+ IGNORE_DIRS = {
39
+ "__pycache__", ".git", "node_modules", ".venv", "venv",
40
+ "data", "exports", "static", ".claude",
41
+ "skill-sentinel", # nao auditar a si mesmo
42
+ }
43
+
44
+ # -- Scoring Weights (devem somar 1.0) ----------------------------------------
45
+ DIMENSION_WEIGHTS: Dict[str, float] = {
46
+ "code_quality": 0.20,
47
+ "security": 0.20,
48
+ "performance": 0.15,
49
+ "governance": 0.15,
50
+ "documentation": 0.15,
51
+ "dependencies": 0.15,
52
+ }
53
+
54
+ # -- Score Labels --------------------------------------------------------------
55
+ SCORE_LABELS: List[Tuple[int, int, str]] = [
56
+ (90, 100, "Excelente"),
57
+ (75, 89, "Bom"),
58
+ (50, 74, "Adequado"),
59
+ (25, 49, "Precisa melhorar"),
60
+ (0, 24, "Critico"),
61
+ ]
62
+
63
+ def get_score_label(score: float) -> str:
64
+ """Retorna label textual para um score numerico."""
65
+ for low, high, label in SCORE_LABELS:
66
+ if low <= score <= high:
67
+ return label
68
+ return "Desconhecido"
69
+
70
+ # -- Code Quality Thresholds ---------------------------------------------------
71
+ MAX_FUNCTION_LINES = 50
72
+ MAX_CYCLOMATIC_COMPLEXITY = 10
73
+ MAX_FILE_LINES = 500
74
+ MIN_DOCSTRING_COVERAGE = 0.5
75
+
76
+ # Penalidades (pontos subtraidos de 100)
77
+ PENALTY_HIGH_COMPLEXITY = 5 # por funcao acima do limite
78
+ PENALTY_LONG_FUNCTION = 3 # por funcao acima do limite
79
+ PENALTY_LONG_FILE = 5 # por arquivo acima do limite
80
+ PENALTY_NO_DOCSTRING = 1 # por funcao/classe sem docstring
81
+ PENALTY_BARE_EXCEPT = 8 # por bare except
82
+ PENALTY_BROAD_EXCEPT = 3 # por except Exception sem log
83
+
84
+ # -- Security Patterns ---------------------------------------------------------
85
+ SECRET_PATTERNS: List[re.Pattern] = [
86
+ re.compile(r'(?:password|passwd|pwd)\s*=\s*["\'][^"\']{8,}["\']', re.I),
87
+ re.compile(r'(?:secret|secret_key)\s*=\s*["\'][^"\']{8,}["\']', re.I),
88
+ re.compile(r'(?:api_key|apikey|api_secret)\s*=\s*["\'][^"\']{8,}["\']', re.I),
89
+ re.compile(r'(?:access_token|auth_token)\s*=\s*["\'][^"\']{8,}["\']', re.I),
90
+ re.compile(r'(?:private_key|ssh_key)\s*=\s*["\']', re.I),
91
+ re.compile(r'(?:aws_access_key_id|aws_secret)\s*=\s*["\']', re.I),
92
+ ]
93
+
94
+ # Padroes que sao excepcoes conhecidas (nao sao secrets reais)
95
+ SECRET_EXCEPTIONS: List[str] = [
96
+ "546c25a59c58ad7", # Imgur public anonymous upload key
97
+ ]
98
+
99
+ SQL_INJECTION_PATTERNS: List[re.Pattern] = [
100
+ re.compile(r'f["\'].*(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE).*\{', re.I),
101
+ re.compile(r'\.format\(.*(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE)', re.I),
102
+ re.compile(r'%\s*\(.*(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE)', re.I),
103
+ ]
104
+
105
+ # -- Performance Thresholds ----------------------------------------------------
106
+ MAX_SEQUENTIAL_API_CALLS = 5 # sugerir batching se > este numero
107
+ WARN_NO_RETRY = True # avisar se nao tem retry/backoff
108
+ WARN_NO_TIMEOUT = True # avisar se requests sem timeout
109
+
110
+ # -- Governance Maturity Levels ------------------------------------------------
111
+ GOVERNANCE_LEVELS: Dict[int, str] = {
112
+ 0: "Nenhuma",
113
+ 1: "Basica (action logging)",
114
+ 2: "Padrao (logging + rate limiting)",
115
+ 3: "Completa (logging + rate limit + confirmacoes)",
116
+ 4: "Avancada (completa + alertas + trends)",
117
+ }
118
+
119
+ # -- Documentation Required Sections -------------------------------------------
120
+ SKILL_MD_REQUIRED_SECTIONS: List[str] = [
121
+ "name", # frontmatter
122
+ "description", # frontmatter
123
+ ]
124
+
125
+ SKILL_MD_RECOMMENDED_SECTIONS: List[str] = [
126
+ "version", # frontmatter
127
+ "instalacao", # ou "installation"
128
+ "comandos", # ou "commands", "uso", "usage"
129
+ "governanca", # ou "governance"
130
+ "referencias", # ou "references"
131
+ ]
132
+
133
+ # -- Severity Ordering ---------------------------------------------------------
134
+ SEVERITY_ORDER = {"critical": 0, "high": 1, "medium": 2, "low": 3, "info": 4}
135
+
136
+ # -- Gap Analysis Taxonomy -----------------------------------------------------
137
+ CAPABILITY_TAXONOMY: Dict[str, str] = {
138
+ "data-extraction": "Extracao de dados de fontes externas",
139
+ "social-media": "Integracao com redes sociais",
140
+ "messaging": "Sistemas de mensageria",
141
+ "government-data": "Dados governamentais e registros publicos",
142
+ "web-automation": "Automacao de browser e interacoes web",
143
+ "api-integration": "Integracao com APIs externas",
144
+ "analytics": "Analise de dados e metricas",
145
+ "content-management": "Gestao e criacao de conteudo",
146
+ "testing": "Testes automatizados e QA",
147
+ "monitoring": "Monitoramento e alertas",
148
+ "ci-cd": "Integracao e deploy continuo",
149
+ "documentation-gen": "Geracao automatica de documentacao",
150
+ "data-pipeline": "ETL e pipelines de dados",
151
+ "scheduling": "Agendamento e cron jobs",
152
+ "notification": "Notificacoes multi-canal",
153
+ "email-integration": "Integracao com email",
154
+ "database-management": "Gestao de bancos de dados",
155
+ "file-management": "Gestao de arquivos e storage",
156
+ "security-audit": "Auditoria de seguranca",
157
+ "cost-optimization": "Otimizacao de custos e recursos",
158
+ }
@@ -0,0 +1,146 @@
1
+ """
2
+ Cost Optimizer: analisa padroes que impactam consumo de tokens e custos de API.
3
+
4
+ Identifica SKILL.md muito grandes (impacto direto em tokens consumidos pelo Claude),
5
+ output verboso, oportunidades de cache, e padrao de chamadas API.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+ from typing import Any, Dict, List, Tuple
11
+
12
+
13
+ def analyze(skill_data: Dict[str, Any]) -> Tuple[float, List[Dict[str, Any]]]:
14
+ """
15
+ Analisa custos de uma skill. Retorna (score, findings).
16
+ Score alto = skill eficiente em custo.
17
+ """
18
+ score = 100.0
19
+ findings: List[Dict[str, Any]] = []
20
+ skill_name = skill_data["name"]
21
+ skill_path = Path(skill_data["path"])
22
+
23
+ # -- 1. Tamanho do SKILL.md (impacto direto em context window) ---------------
24
+ skill_md_lines = skill_data.get("skill_md_lines", 0)
25
+
26
+ if skill_md_lines > 500:
27
+ cost_impact = "alto"
28
+ severity = "high"
29
+ score -= 20
30
+ elif skill_md_lines > 300:
31
+ cost_impact = "medio"
32
+ severity = "medium"
33
+ score -= 10
34
+ elif skill_md_lines > 150:
35
+ cost_impact = "baixo"
36
+ severity = "low"
37
+ score -= 3
38
+ else:
39
+ cost_impact = None
40
+
41
+ if cost_impact:
42
+ # Estimar tokens: ~1.3 tokens por palavra, ~10 palavras por linha
43
+ est_tokens = int(skill_md_lines * 10 * 1.3)
44
+ findings.append({
45
+ "skill_name": skill_name,
46
+ "dimension": "cost",
47
+ "severity": severity,
48
+ "category": "large_skill_md",
49
+ "title": f"SKILL.md com {skill_md_lines} linhas (~{est_tokens:,} tokens estimados)",
50
+ "description": f"Impacto de custo {cost_impact}. Cada ativacao desta skill "
51
+ f"consome ~{est_tokens:,} tokens do context window.",
52
+ "recommendation": "Mover detalhes para references/ e manter SKILL.md < 200 linhas. "
53
+ "Usar progressive disclosure: SKILL.md = overview, "
54
+ "references/ = detalhes lidos sob demanda.",
55
+ "effort": "medium",
56
+ "impact": "high",
57
+ })
58
+
59
+ # -- 2. References muito grandes ----------------------------------------------
60
+ ref_dir = skill_path / "references"
61
+ if ref_dir.exists():
62
+ for ref_file in ref_dir.glob("*.md"):
63
+ try:
64
+ lines = len(ref_file.read_text(encoding="utf-8", errors="replace").splitlines())
65
+ except OSError:
66
+ continue
67
+ if lines > 300:
68
+ est_tokens = int(lines * 10 * 1.3)
69
+ findings.append({
70
+ "skill_name": skill_name,
71
+ "dimension": "cost",
72
+ "severity": "low",
73
+ "category": "large_reference",
74
+ "title": f"Reference grande: {ref_file.name} ({lines} linhas, ~{est_tokens:,} tokens)",
75
+ "description": "Se carregado inteiro no contexto, consome muitos tokens.",
76
+ "file_path": f"references/{ref_file.name}",
77
+ "recommendation": "Adicionar indice/TOC no inicio. Instruir no SKILL.md "
78
+ "para ler apenas secoes relevantes.",
79
+ "effort": "low",
80
+ "impact": "medium",
81
+ })
82
+ score -= 3
83
+
84
+ # -- 3. Output verboso dos scripts --------------------------------------------
85
+ for rel_path in skill_data.get("python_files", []):
86
+ filepath = skill_path / rel_path
87
+ if not filepath.exists():
88
+ continue
89
+ try:
90
+ source = filepath.read_text(encoding="utf-8", errors="replace")
91
+ except OSError:
92
+ continue
93
+
94
+ # Contar prints verbosos
95
+ import re
96
+ print_count = len(re.findall(r'\bprint\s*\(', source))
97
+ lines = len(source.splitlines())
98
+
99
+ # Se >10% das linhas sao prints, eh verboso
100
+ if lines > 20 and print_count > 0 and (print_count / lines) > 0.08:
101
+ findings.append({
102
+ "skill_name": skill_name,
103
+ "dimension": "cost",
104
+ "severity": "low",
105
+ "category": "verbose_output",
106
+ "title": f"Output verboso em {rel_path} ({print_count} prints em {lines} linhas)",
107
+ "description": "Output excessivo consome tokens do context window quando "
108
+ "Claude le a saida do script.",
109
+ "file_path": rel_path,
110
+ "recommendation": "Usar --verbose flag ou logging levels em vez de prints fixos. "
111
+ "Retornar JSON conciso por padrao.",
112
+ "effort": "low",
113
+ "impact": "medium",
114
+ })
115
+ score -= 3
116
+
117
+ # -- 4. Verificar se scripts retornam JSON estruturado vs texto livre -----------
118
+ has_json_output = False
119
+ for rel_path in skill_data.get("python_files", []):
120
+ filepath = skill_path / rel_path
121
+ if not filepath.exists():
122
+ continue
123
+ try:
124
+ source = filepath.read_text(encoding="utf-8", errors="replace")
125
+ except OSError:
126
+ continue
127
+ if "json.dumps" in source or "json.dump" in source:
128
+ has_json_output = True
129
+ break
130
+
131
+ if not has_json_output and skill_data.get("file_count", 0) > 3:
132
+ findings.append({
133
+ "skill_name": skill_name,
134
+ "dimension": "cost",
135
+ "severity": "low",
136
+ "category": "no_structured_output",
137
+ "title": "Sem output JSON estruturado",
138
+ "description": "Scripts que retornam JSON sao mais eficientes para o Claude processar "
139
+ "do que texto livre.",
140
+ "recommendation": "Adicionar opcao --json para output estruturado em scripts principais",
141
+ "effort": "low",
142
+ "impact": "medium",
143
+ })
144
+ score -= 5
145
+
146
+ return max(0.0, min(100.0, score)), findings