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,72 @@
1
+ """
2
+ Scraper JUCEAC — Junta Comercial do Estado do Acre
3
+ URL: https://juceac.ac.gov.br/leiloeiro/
4
+ Método: httpx + BeautifulSoup
5
+ Nota: URL correta é /leiloeiro/ (singular), não /leiloeiros/.
6
+ Lista ~30 leiloeiros com situação (CANCELADO, SUSPENSO, ativo),
7
+ data de posse, endereço e contatos. Lista atualizada.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ from typing import List
12
+
13
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
14
+
15
+
16
+ class JuceacScraper(AbstractJuntaScraper):
17
+ estado = "AC"
18
+ junta = "JUCEAC"
19
+ url = "https://juceac.ac.gov.br/leiloeiro/"
20
+
21
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
22
+ soup = await self.fetch_page()
23
+ if not soup:
24
+ # Tenta sem trailing slash e com www
25
+ soup = await self.fetch_page(url="https://www.juceac.ac.gov.br/leiloeiro/")
26
+ if not soup:
27
+ soup = await self.fetch_page_js(wait_ms=3000)
28
+ if not soup:
29
+ return []
30
+
31
+ results: List[Leiloeiro] = []
32
+
33
+ for table in soup.find_all("table"):
34
+ rows = table.find_all("tr")
35
+ if len(rows) < 2:
36
+ continue
37
+ headers = [self.clean(th.get_text()) for th in rows[0].find_all(["th", "td"])]
38
+ col = {(h or "").lower(): i for i, h in enumerate(headers)}
39
+
40
+ def gcol(cells, frags):
41
+ for k, i in col.items():
42
+ if any(f in k for f in frags) and i < len(cells):
43
+ return self.clean(cells[i].get_text())
44
+ return None
45
+
46
+ for row in rows[1:]:
47
+ cells = row.find_all(["td", "th"])
48
+ if not cells:
49
+ continue
50
+ nome = gcol(cells, ["nome", "leiloeiro"]) or self.clean(cells[0].get_text())
51
+ if not nome or len(nome) < 3:
52
+ continue
53
+ results.append(self.make_leiloeiro(
54
+ nome=nome,
55
+ matricula=gcol(cells, ["matr", "registro", "nº"]),
56
+ situacao=gcol(cells, ["situ", "status", "cancel", "suspen"]),
57
+ municipio=gcol(cells, ["munic", "cidade"]) or "Rio Branco",
58
+ telefone=gcol(cells, ["tel", "fone"]),
59
+ email=gcol(cells, ["email"]),
60
+ endereco=gcol(cells, ["ender", "logr"]),
61
+ data_registro=gcol(cells, ["data", "posse"]),
62
+ ))
63
+ if results:
64
+ break
65
+
66
+ if not results:
67
+ for el in soup.select("li, p, .leiloeiro, article"):
68
+ text = self.clean(el.get_text(" | "))
69
+ if text and len(text) > 10:
70
+ results.append(self.make_leiloeiro(nome=text, municipio="Rio Branco"))
71
+
72
+ return results
@@ -0,0 +1,72 @@
1
+ """
2
+ Scraper JUCEAL — Junta Comercial do Estado de Alagoas
3
+ URL: http://www.juceal.al.gov.br/servicos/leiloeiros
4
+ Método: httpx + BeautifulSoup
5
+ Nota: URL /leiloeiros retornava 404 — URL correta é /servicos/leiloeiros.
6
+ Lista 28 leiloeiros com matrícula, data de posse, situação, contatos e redes sociais.
7
+ Registros atualizados até 2025.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ from typing import List
12
+
13
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
14
+
15
+
16
+ class JucealScraper(AbstractJuntaScraper):
17
+ estado = "AL"
18
+ junta = "JUCEAL"
19
+ url = "http://www.juceal.al.gov.br/servicos/leiloeiros"
20
+
21
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
22
+ soup = await self.fetch_page()
23
+ if not soup:
24
+ # Tenta HTTPS também
25
+ soup = await self.fetch_page(url="https://www.juceal.al.gov.br/servicos/leiloeiros")
26
+ if not soup:
27
+ soup = await self.fetch_page_js(wait_ms=3000)
28
+ if not soup:
29
+ return []
30
+
31
+ results: List[Leiloeiro] = []
32
+
33
+ for table in soup.find_all("table"):
34
+ rows = table.find_all("tr")
35
+ if len(rows) < 2:
36
+ continue
37
+ headers = [self.clean(th.get_text()) for th in rows[0].find_all(["th", "td"])]
38
+ col = {(h or "").lower(): i for i, h in enumerate(headers)}
39
+
40
+ def gcol(cells, frags):
41
+ for k, i in col.items():
42
+ if any(f in k for f in frags) and i < len(cells):
43
+ return self.clean(cells[i].get_text())
44
+ return None
45
+
46
+ for row in rows[1:]:
47
+ cells = row.find_all(["td", "th"])
48
+ if not cells:
49
+ continue
50
+ nome = gcol(cells, ["nome", "leiloeiro"]) or self.clean(cells[0].get_text())
51
+ if not nome or len(nome) < 3:
52
+ continue
53
+ results.append(self.make_leiloeiro(
54
+ nome=nome,
55
+ matricula=gcol(cells, ["matr", "registro", "nº"]),
56
+ situacao=gcol(cells, ["situ", "status"]),
57
+ municipio=gcol(cells, ["munic", "cidade"]) or "Maceió",
58
+ telefone=gcol(cells, ["tel", "fone"]),
59
+ email=gcol(cells, ["email"]),
60
+ endereco=gcol(cells, ["ender", "logr"]),
61
+ data_registro=gcol(cells, ["data", "posse"]),
62
+ ))
63
+ if results:
64
+ break
65
+
66
+ if not results:
67
+ for el in soup.select("li, p, .leiloeiro, article"):
68
+ text = self.clean(el.get_text(" | "))
69
+ if text and len(text) > 10:
70
+ results.append(self.make_leiloeiro(nome=text, municipio="Maceió"))
71
+
72
+ return results
@@ -0,0 +1,68 @@
1
+ """
2
+ Scraper JUCEB — Junta Comercial do Estado da Bahia
3
+ URL: https://www.ba.gov.br/juceb/home/matriculas-e-carteira-profissional/leiloeiros
4
+ Método: httpx + BeautifulSoup
5
+ Nota: Site migrou de juceb.ba.gov.br para ba.gov.br/juceb
6
+ Lista inclui: nome, matrícula, portaria, nomeação, contatos, situação (Regular/Irregular)
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from typing import List
11
+
12
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
13
+
14
+
15
+ class JucebScraper(AbstractJuntaScraper):
16
+ estado = "BA"
17
+ junta = "JUCEB"
18
+ url = "https://www.ba.gov.br/juceb/home/matriculas-e-carteira-profissional/leiloeiros"
19
+
20
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
21
+ soup = await self.fetch_page()
22
+ if not soup:
23
+ soup = await self.fetch_page_js(wait_ms=3000)
24
+ if not soup:
25
+ return []
26
+
27
+ results: List[Leiloeiro] = []
28
+
29
+ for table in soup.find_all("table"):
30
+ rows = table.find_all("tr")
31
+ if len(rows) < 2:
32
+ continue
33
+ headers = [self.clean(th.get_text()) for th in rows[0].find_all(["th", "td"])]
34
+ col = {(h or "").lower(): i for i, h in enumerate(headers)}
35
+
36
+ def gcol(cells, frags):
37
+ for k, i in col.items():
38
+ if any(f in k for f in frags) and i < len(cells):
39
+ return self.clean(cells[i].get_text())
40
+ return None
41
+
42
+ for row in rows[1:]:
43
+ cells = row.find_all(["td", "th"])
44
+ if not cells:
45
+ continue
46
+ nome = gcol(cells, ["nome", "leiloeiro"]) or self.clean(cells[0].get_text())
47
+ if not nome or len(nome) < 3:
48
+ continue
49
+ results.append(self.make_leiloeiro(
50
+ nome=nome,
51
+ matricula=gcol(cells, ["matr", "registro", "nº"]),
52
+ situacao=gcol(cells, ["situ", "status", "regular", "irregular"]),
53
+ municipio=gcol(cells, ["munic", "cidade"]) or "Salvador",
54
+ telefone=gcol(cells, ["tel", "fone", "contato"]),
55
+ email=gcol(cells, ["email"]),
56
+ endereco=gcol(cells, ["ender", "logr"]),
57
+ data_registro=gcol(cells, ["portaria", "nomea", "data", "posse"]),
58
+ ))
59
+ if results:
60
+ break
61
+
62
+ if not results:
63
+ for li in soup.select("li, p, .item-leiloeiro, article"):
64
+ text = self.clean(li.get_text(" | "))
65
+ if text and len(text) > 10:
66
+ results.append(self.make_leiloeiro(nome=text, municipio="Salvador"))
67
+
68
+ return results
@@ -0,0 +1,63 @@
1
+ """
2
+ Scraper JUCEC — Junta Comercial do Estado do Ceará
3
+ URL: https://www.jucec.ce.gov.br/leiloeiros/
4
+ Método: httpx + BeautifulSoup
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import List
9
+
10
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
11
+
12
+
13
+ class JucecScraper(AbstractJuntaScraper):
14
+ estado = "CE"
15
+ junta = "JUCEC"
16
+ url = "https://www.jucec.ce.gov.br/leiloeiros/"
17
+
18
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
19
+ soup = await self.fetch_page()
20
+ if not soup:
21
+ return []
22
+
23
+ results: List[Leiloeiro] = []
24
+
25
+ tables = soup.find_all("table")
26
+ for table in tables:
27
+ rows = table.find_all("tr")
28
+ if len(rows) < 2:
29
+ continue
30
+ headers = [self.clean(th.get_text()) for th in rows[0].find_all(["th", "td"])]
31
+ col = {(h or "").lower(): i for i, h in enumerate(headers)}
32
+
33
+ def gcol(cells, frags):
34
+ for k, i in col.items():
35
+ if any(f in k for f in frags) and i < len(cells):
36
+ return self.clean(cells[i].get_text())
37
+ return None
38
+
39
+ for row in rows[1:]:
40
+ cells = row.find_all(["td", "th"])
41
+ if not cells:
42
+ continue
43
+ nome = gcol(cells, ["nome"]) or self.clean(cells[0].get_text())
44
+ if not nome or len(nome) < 3:
45
+ continue
46
+ results.append(self.make_leiloeiro(
47
+ nome=nome,
48
+ matricula=gcol(cells, ["matr", "registro", "núm"]),
49
+ cpf_cnpj=gcol(cells, ["cpf", "cnpj"]),
50
+ situacao=gcol(cells, ["situ", "status"]),
51
+ municipio=gcol(cells, ["munic", "cidade", "fortaleza"]),
52
+ telefone=gcol(cells, ["tel", "fone"]),
53
+ email=gcol(cells, ["email"]),
54
+ endereco=gcol(cells, ["ender", "logr"]),
55
+ ))
56
+
57
+ if not results:
58
+ for el in soup.select("ul li, ol li, .leiloeiro"):
59
+ text = self.clean(el.get_text(" | "))
60
+ if text and len(text) > 5:
61
+ results.append(self.make_leiloeiro(nome=text))
62
+
63
+ return results
@@ -0,0 +1,211 @@
1
+ """
2
+ Scraper JUCEMA — Junta Comercial do Estado do Maranhao
3
+ URL: https://portal.jucema.ma.gov.br/ (React SPA - dados via REST API)
4
+ Metodo: httpx GET para API REST do CMS
5
+ Mecanismo real descoberto em 2026-02-25:
6
+ - Portal e React SPA (Create React App), sem conteudo server-side
7
+ - API base: https://api.jucema.ma.gov.br/api/public/
8
+ - Leiloeiros estao em: GET /api/public/posts/11
9
+ (post_id 11 = "Leiloeiro" no menu /api/public/menus?with=menus.menus)
10
+ - Conteudo e HTML dentro do campo data.content
11
+ - Ultima atualizacao: 2025-10-20 18:29:59
12
+ Total: 53 leiloeiros (39 Regular + 12 Irregular + 2 Cancelada)
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import logging
17
+ import re
18
+ from typing import List
19
+
20
+ import httpx
21
+ from bs4 import BeautifulSoup
22
+
23
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ RE_MATRICULA = re.compile(r"[Mm]atr[íi]cula\s+N[º°o]?\s*(\d+(?:/\d+)?)\s*[–\-]\s*[Ee]m:\s*(\d{2}/\d{2}/\d{4})")
28
+ RE_SITUACAO = re.compile(r"SITUA[ÇC][ÃA]O:\s*(.+)", re.IGNORECASE)
29
+ RE_CONTATO = re.compile(r"[Cc]ontato:\s*(.+)")
30
+ RE_EMAIL = re.compile(r"[Ee]-?[Mm]ail:\s*(.+)")
31
+ RE_ENDERECO = re.compile(r"[Ee]ndere[çc]o:\s*(.+)")
32
+
33
+
34
+ class JucemaScraper(AbstractJuntaScraper):
35
+ estado = "MA"
36
+ junta = "JUCEMA"
37
+ url = "https://portal.jucema.ma.gov.br/"
38
+ _API_URL = "https://api.jucema.ma.gov.br/api/public/posts/11"
39
+
40
+ async def _fetch_api(self) -> List[dict]:
41
+ """
42
+ Busca dados do post de leiloeiros via API REST do CMS.
43
+ GET /api/public/posts/11 retorna JSON com campo 'content' em HTML.
44
+ """
45
+ try:
46
+ async with httpx.AsyncClient(
47
+ headers={**self.HEADERS, "Accept": "application/json"},
48
+ verify=True,
49
+ follow_redirects=True,
50
+ timeout=30.0,
51
+ ) as client:
52
+ resp = await client.get(self._API_URL)
53
+ if resp.status_code >= 400:
54
+ logger.warning("[MA] API post/11 retornou HTTP %d", resp.status_code)
55
+ return []
56
+
57
+ data = resp.json()
58
+ # O campo pode estar em data.content ou diretamente em content
59
+ # API retorna { success: true, data: { content: "..." }, message: "..." }
60
+ inner = data.get("data") or {}
61
+ content_html = (
62
+ inner.get("content") or
63
+ data.get("content") or
64
+ ""
65
+ )
66
+ if not content_html:
67
+ logger.warning("[MA] Campo 'content' vazio na API")
68
+ return []
69
+
70
+ logger.info("[MA] API retornou %d bytes de HTML", len(content_html))
71
+ soup = BeautifulSoup(content_html, "lxml")
72
+ return self._parse_cms_content(soup)
73
+
74
+ except Exception as exc:
75
+ logger.error("[MA] Erro na API: %s", exc)
76
+ return []
77
+
78
+ def _parse_cms_content(self, soup) -> List[dict]:
79
+ """
80
+ Parseia conteudo HTML do CMS da JUCEMA.
81
+ Formato dos paragrafos:
82
+ <p>NOME COMPLETO</p>
83
+ <p>SITUACAO: REGULAR</p>
84
+ <p>Matricula No 010/1993 - Em: 29/04/1993</p>
85
+ <p>Endereco: ...</p>
86
+ <p>Contato: ...</p>
87
+ <p>E-mail: ...</p>
88
+ """
89
+ records = []
90
+ paragraphs = [self.clean(p.get_text()) for p in soup.find_all("p") if self.clean(p.get_text())]
91
+
92
+ # Tambem tentar com outros elementos se nao houver <p>
93
+ if len(paragraphs) < 3:
94
+ paragraphs = [
95
+ self.clean(el.get_text())
96
+ for el in soup.find_all(["p", "li", "div", "span"])
97
+ if self.clean(el.get_text()) and len(self.clean(el.get_text())) > 3
98
+ ]
99
+
100
+ current: dict | None = None
101
+
102
+ for text in paragraphs:
103
+ if not text:
104
+ continue
105
+
106
+ m_matr = RE_MATRICULA.search(text)
107
+ m_sit = RE_SITUACAO.search(text)
108
+ m_cont = RE_CONTATO.search(text)
109
+ m_email = RE_EMAIL.search(text)
110
+ m_end = RE_ENDERECO.search(text)
111
+
112
+ if m_matr:
113
+ if current:
114
+ current["matricula"] = m_matr.group(1)
115
+ current["data_registro"] = m_matr.group(2)
116
+ continue
117
+ if m_sit:
118
+ if current:
119
+ current["situacao"] = self.clean(m_sit.group(1))
120
+ continue
121
+ if m_cont:
122
+ if current:
123
+ current.setdefault("telefone", self.clean(m_cont.group(1)))
124
+ continue
125
+ if m_email:
126
+ if current:
127
+ current["email"] = self.clean(m_email.group(1))
128
+ continue
129
+ if m_end:
130
+ if current:
131
+ current["endereco"] = self.clean(m_end.group(1))
132
+ m_cidade = re.search(r"([A-ZÁÉÍÓÚÀÃÕÇ][A-Za-záéíóúàãõç\s]+)/MA", text)
133
+ if m_cidade:
134
+ current["municipio"] = m_cidade.group(1).strip()
135
+ continue
136
+
137
+ # Detectar inicio de nova entrada: nome em maiusculas
138
+ # Excluir titulos de secao como "RELACAO DOS LEILOEIROS", "CEP:", linhas curtas
139
+ is_nome = (
140
+ len(text) > 8 and
141
+ not re.match(r"(SITUA|Matr|MATR|[Ee]ndere|[Cc]ontato|[Ee]-?mail|www\.|http|^\d|Site:|CEP:|RELA[ÇC])", text) and
142
+ not re.search(r"^(RELA[ÇC][ÃA]O|LISTA|CADASTRO|JUNTA|COMERCIAL|LEILOEIROS\s*$)", text, re.IGNORECASE) and
143
+ sum(1 for c in text if c.isupper()) > len(text) * 0.3 and
144
+ " " in text and
145
+ len(text.split()) >= 2 and
146
+ len(text) < 120
147
+ )
148
+
149
+ if is_nome:
150
+ if current and current.get("nome"):
151
+ records.append(current)
152
+ current = {"nome": text, "municipio": "Sao Luis"}
153
+ elif current and text and re.search(r"\(\d{2}\)", text):
154
+ current.setdefault("telefone", text)
155
+
156
+ if current and current.get("nome"):
157
+ records.append(current)
158
+
159
+ return records
160
+
161
+ async def fetch_insecure(self, url: str):
162
+ """Fetch com verify=False para sites com SSL problematico."""
163
+ try:
164
+ async with httpx.AsyncClient(
165
+ headers=self.HEADERS,
166
+ timeout=30.0,
167
+ follow_redirects=True,
168
+ verify=False,
169
+ ) as client:
170
+ resp = await client.get(url)
171
+ if resp.status_code < 400:
172
+ return BeautifulSoup(resp.text, "lxml")
173
+ except Exception:
174
+ pass
175
+ return None
176
+
177
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
178
+ # Estrategia 1: API REST (direto ao dado, sem renderizacao JS)
179
+ records = await self._fetch_api()
180
+
181
+ if not records:
182
+ # Estrategia 2: Playwright para renderizar o SPA React
183
+ logger.info("[MA] API falhou, tentando Playwright no SPA")
184
+ for spa_url in [
185
+ "https://portal.jucema.ma.gov.br/leiloeiro",
186
+ "https://portal.jucema.ma.gov.br/leiloeiros",
187
+ ]:
188
+ soup = await self.fetch_page_js(url=spa_url, wait_ms=5000)
189
+ if soup:
190
+ records = self._parse_cms_content(soup)
191
+ if records:
192
+ break
193
+
194
+ if not records:
195
+ # Estrategia 3: URLs alternativas com httpx
196
+ logger.info("[MA] Tentando URLs alternativas")
197
+ for url in [
198
+ "http://www.jucema.ma.gov.br/leiloeiros",
199
+ "https://www.jucema.ma.gov.br/leiloeiros",
200
+ "http://portal.jucema.ma.gov.br/pagina/11",
201
+ ]:
202
+ soup = await self.fetch_insecure(url)
203
+ if soup:
204
+ text = soup.get_text()
205
+ if any(kw in text.lower() for kw in ["leiloeiro", "matr", "nome"]):
206
+ records = self._parse_cms_content(soup)
207
+ if records:
208
+ break
209
+
210
+ logger.info("[MA] Total de registros encontrados: %d", len(records))
211
+ return [self.make_leiloeiro(**r) for r in records if r.get("nome")]