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,233 @@
1
+ """
2
+ Scraper JUCESP — Junta Comercial do Estado de São Paulo
3
+
4
+ MECANISMO REAL (descoberto em 2025-02-25):
5
+ A URL https://www.institucional.jucesp.sp.gov.br/tradutores-leiloeiros.html
6
+ é apenas uma página institucional com links para downloads e um accordeon.
7
+ O accordion "Localizar Leiloeiro e Tradutor" aponta para:
8
+ https://www.institucional.jucesp.sp.gov.br/consultaLeilao.html
9
+ Essa página contém um <iframe> carregando o sistema real:
10
+ https://www.institucional.jucesp.sp.gov.br/relatorio/ConsultasLeiloeiroTradutor
11
+
12
+ O sistema real é um app ASP.NET MVC com:
13
+ - GET /relatorio/ConsultasLeiloeiroTradutor
14
+ -> retorna formulário de busca com token CSRF anti-forgery
15
+ - POST /relatorio/ConsultasLeiloeiroTradutor/ListaLeiloeirosTradutores
16
+ -> retorna HTML com tabela id="example" contendo TODOS os registros
17
+ (sem paginação — 2.3 MB com 1152 leiloeiros na resposta completa)
18
+
19
+ Campos do POST:
20
+ __RequestVerificationToken (obrigatório, obtido no GET)
21
+ AgeTipo 1 = Leiloeiro | 2 = Tradutor
22
+ AgeMatricula filtro opcional
23
+ AgeNome filtro opcional
24
+ AgeSituacao -1 = todos | 1=Atuante | 14=Atuante Regular |
25
+ 13=Atuante Irregular | 2=Destituído | 3=Exonerado |
26
+ 4=Falecido | 9=Licenciado | 10=Matrícula Cancelada |
27
+ 12=Registro Cassado | 11=Registro Suspenso |
28
+ 8=Regular | 7=Suspenso | 6=Suspenso Por Ordem Judicial |
29
+ 5=Transferido
30
+ AgeDataPosseDe / AgeDataPosseAte filtro de data (dd/mm/aaaa)
31
+ AgeEndeComeLogradouro / AgeEndeComeBairro / AgeEndeComeMunicipio filtro de endereço
32
+ MatriculaCancelada true/false
33
+ MatriculaCancelada120 true/false
34
+
35
+ Colunas da tabela retornada (id="example"):
36
+ Nome | Matricula | PosseYMD | Posse | Logradouro | Bairro | Cidade |
37
+ CEP | Telefones | E-Mail | Web Site | Situação | Preposto |
38
+ Férias/Licença | Data do D.O.E. | Prazo para Publicação - 120 dias |
39
+ Data do Cancelamento | PDF
40
+
41
+ Total coletável: 1152 leiloeiros (todos os status)
42
+ Atuante Regular: 577 | Exonerado: 273 | Destituído: 214 | Falecido: 47 | ...
43
+
44
+ Método: httpx com sessão (GET para CSRF, POST para dados)
45
+ """
46
+ from __future__ import annotations
47
+
48
+ import re
49
+ from html import unescape
50
+ from typing import List, Optional
51
+
52
+ import httpx
53
+ from bs4 import BeautifulSoup
54
+
55
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
56
+
57
+
58
+ class JucespScraper(AbstractJuntaScraper):
59
+ estado = "SP"
60
+ junta = "JUCESP"
61
+ url = "https://www.institucional.jucesp.sp.gov.br/tradutores-leiloeiros.html"
62
+
63
+ # Endpoint real do sistema de consulta
64
+ _FORM_URL = "https://www.institucional.jucesp.sp.gov.br/relatorio/ConsultasLeiloeiroTradutor"
65
+ _POST_URL = (
66
+ "https://www.institucional.jucesp.sp.gov.br"
67
+ "/relatorio/ConsultasLeiloeiroTradutor/ListaLeiloeirosTradutores"
68
+ )
69
+
70
+ # Busca todos os status (-1). Para coletar apenas ativos use "14" (Atuante Regular).
71
+ _AGE_SITUACAO = "-1"
72
+
73
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
74
+ """
75
+ Fluxo:
76
+ 1. GET /relatorio/ConsultasLeiloeiroTradutor -> extrai token CSRF
77
+ (o servidor emite um cookie de sessão junto com o token)
78
+ 2. POST /relatorio/ConsultasLeiloeiroTradutor/ListaLeiloeirosTradutores
79
+ com AgeTipo=1 e AgeSituacao=-1 (todos)
80
+ IMPORTANTE: GET e POST devem usar o MESMO AsyncClient para que os
81
+ cookies de sessão sejam enviados. Sem isso o servidor retorna 500.
82
+ 3. Parseia a tabela id="example" do HTML retornado
83
+ """
84
+ import asyncio as _aio
85
+ import logging as _log
86
+ logger = _log.getLogger(__name__)
87
+
88
+ for attempt in range(1, self.max_retries + 1):
89
+ try:
90
+ soup = await self._fetch_with_session()
91
+ if soup:
92
+ return self._parse_table(soup)
93
+ except Exception as exc:
94
+ # Mask any CSRF tokens that might appear in error messages
95
+ safe_exc = str(exc)
96
+ if hasattr(self, '_last_csrf') and self._last_csrf and self._last_csrf in safe_exc:
97
+ safe_exc = safe_exc.replace(self._last_csrf, "***csrf-masked***")
98
+ logger.warning("[SP] Tentativa %d/%d falhou: %s", attempt, self.max_retries, safe_exc)
99
+ if attempt < self.max_retries:
100
+ await _aio.sleep(2 ** attempt)
101
+
102
+ return []
103
+
104
+ # ── helpers privados ─────────────────────────────────────────────────────
105
+
106
+ async def _fetch_with_session(self) -> Optional[BeautifulSoup]:
107
+ """
108
+ GET + POST dentro do mesmo AsyncClient.
109
+ O servidor ASP.NET emite um cookie de sessão no GET que deve ser
110
+ reenviado no POST — sem ele o servidor retorna HTTP 500.
111
+ """
112
+ import logging
113
+ logger = logging.getLogger(__name__)
114
+
115
+ async with httpx.AsyncClient(
116
+ headers=self.HEADERS,
117
+ verify=False,
118
+ http2=False, # servidor rejeita HTTP/2
119
+ follow_redirects=True,
120
+ timeout=120.0, # resposta do POST é ~2.3 MB
121
+ ) as client:
122
+ # 1. GET — obtém CSRF token e cookie de sessão
123
+ r_get = await client.get(self._FORM_URL)
124
+ r_get.raise_for_status()
125
+
126
+ csrf_match = re.search(
127
+ r'name="__RequestVerificationToken"[^>]*value="([^"]+)"',
128
+ r_get.text,
129
+ )
130
+ if not csrf_match:
131
+ logger.warning("[SP] CSRF token não encontrado")
132
+ return None
133
+ csrf = csrf_match.group(1)
134
+ self._last_csrf = csrf # Store for safe error masking
135
+
136
+ # 2. POST — mesmo client envia os cookies de sessão automaticamente
137
+ r_post = await client.post(
138
+ self._POST_URL,
139
+ data={
140
+ "__RequestVerificationToken": csrf,
141
+ "AgeTipo": "1", # Leiloeiro
142
+ "AgeMatricula": "",
143
+ "AgeNome": "",
144
+ "AgeSituacao": self._AGE_SITUACAO,
145
+ "AgeDataPosseDe": "",
146
+ "AgeDataPosseAte": "",
147
+ "AgeEndeComeLogradouro": "",
148
+ "AgeEndeComeBairro": "",
149
+ "AgeEndeComeMunicipio": "",
150
+ "MatriculaCancelada": "false",
151
+ "MatriculaCancelada120": "false",
152
+ },
153
+ headers={
154
+ "Content-Type": "application/x-www-form-urlencoded",
155
+ "Referer": self._FORM_URL,
156
+ "Origin": "https://www.institucional.jucesp.sp.gov.br",
157
+ },
158
+ )
159
+ r_post.raise_for_status()
160
+ return BeautifulSoup(r_post.text, "lxml")
161
+
162
+ def _parse_table(self, soup: BeautifulSoup) -> List[Leiloeiro]:
163
+ """
164
+ Parseia a tabela id="example" retornada pelo POST.
165
+
166
+ Colunas (índice 0-based):
167
+ 0 Nome
168
+ 1 Matricula
169
+ 2 PosseYMD (hidden, usado para ordenação)
170
+ 3 Posse (dd/mm/aaaa)
171
+ 4 Logradouro
172
+ 5 Bairro
173
+ 6 Cidade
174
+ 7 CEP
175
+ 8 Telefones
176
+ 9 E-Mail
177
+ 10 Web Site
178
+ 11 Situação
179
+ 12 Preposto
180
+ 13 Férias/Licença
181
+ 14 Data do D.O.E.
182
+ 15 Prazo para Publicação - 120 dias
183
+ 16 Data do Cancelamento
184
+ 17 PDF
185
+ """
186
+ results: List[Leiloeiro] = []
187
+
188
+ table = soup.find("table", {"id": "example"})
189
+ if not table:
190
+ # Fallback: procurar a maior tabela da página
191
+ tables = soup.find_all("table")
192
+ if not tables:
193
+ return []
194
+ table = max(tables, key=lambda t: len(t.find_all("tr")))
195
+
196
+ rows = table.find_all("tr")
197
+ if not rows:
198
+ return []
199
+
200
+ for row in rows[1:]: # pula o cabeçalho
201
+ cells = row.find_all("td")
202
+ if len(cells) < 12:
203
+ continue
204
+
205
+ def cell(idx: int) -> Optional[str]:
206
+ if idx < len(cells):
207
+ return self.clean(unescape(cells[idx].get_text()))
208
+ return None
209
+
210
+ nome = cell(0)
211
+ if not nome:
212
+ continue
213
+
214
+ # Monta endereço completo
215
+ logradouro = cell(4)
216
+ bairro = cell(5)
217
+ cidade = cell(6)
218
+ cep = cell(7)
219
+ partes = [p for p in [logradouro, bairro, cidade, cep] if p]
220
+ endereco = ", ".join(partes) if partes else None
221
+
222
+ results.append(self.make_leiloeiro(
223
+ nome=nome,
224
+ matricula=cell(1),
225
+ data_registro=cell(3), # data de posse
226
+ endereco=endereco,
227
+ municipio=cidade,
228
+ telefone=cell(8),
229
+ email=cell(9),
230
+ situacao=cell(11),
231
+ ))
232
+
233
+ return results
@@ -0,0 +1,134 @@
1
+ """
2
+ Scraper JUCETINS — Junta Comercial do Estado do Tocantins
3
+ URL: https://www.to.gov.br/jucetins/leiloeiros/152aezl6blm0
4
+ Metodo: httpx + BeautifulSoup com parser regex para texto numerado plano
5
+ Estrutura: Texto numerado plano sem tabela, padrao:
6
+ N. Nome Completo
7
+ Matricula no X, de DD/MM/AAAA
8
+ Endereco: ... CEP: XXXXX-XXX, Cidade/TO
9
+ Telefone: (XX) XXXXX-XXXX
10
+ E-mail: email@exemplo.com
11
+ Registros: ~55, todos em pagina unica. Ultima atualizacao: 24/02/2026.
12
+ """
13
+ from __future__ import annotations
14
+
15
+ import re
16
+ from typing import List, Optional
17
+
18
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
19
+
20
+ RE_ENTRY_START = re.compile(r"^\d+\.\s+(.+)$")
21
+ RE_MATRICULA = re.compile(r"[Mm]atr[íi]cula\s+n[oº]?\s*[\.\s]*(\d+).*?de\s+(\d{2}/\d{2}/\d{4})", re.IGNORECASE)
22
+ RE_ENDERECO = re.compile(r"[Ee]ndere[çc]o:\s+(.+)", re.IGNORECASE)
23
+ RE_TELEFONE = re.compile(r"[Tt]elefone:\s+(.+)", re.IGNORECASE)
24
+ RE_EMAIL = re.compile(r"[Ee]-?mail:\s+(.+)", re.IGNORECASE)
25
+ RE_CANCELADO = re.compile(r"CANCELAMENTO\s+DE\s+MATR[ÍI]CULA", re.IGNORECASE)
26
+
27
+
28
+ class JucetinsScraper(AbstractJuntaScraper):
29
+ estado = "TO"
30
+ junta = "JUCETINS"
31
+ url = "https://www.to.gov.br/jucetins/leiloeiros/152aezl6blm0"
32
+
33
+ def _parse_text_block(self, text: str) -> List[dict]:
34
+ records = []
35
+ current: Optional[dict] = None
36
+ for raw_line in text.split("\n"):
37
+ line = (raw_line or "").strip()
38
+ if not line:
39
+ continue
40
+ m_start = RE_ENTRY_START.match(line)
41
+ if m_start:
42
+ if current and current.get("nome"):
43
+ records.append(current)
44
+ nome_raw = m_start.group(1).strip()
45
+ is_cancelado = bool(RE_CANCELADO.search(nome_raw))
46
+ nome = RE_CANCELADO.sub("", nome_raw).strip(" -")
47
+ current = {"nome": nome, "municipio": "Palmas", "situacao": "CANCELADO" if is_cancelado else None}
48
+ continue
49
+ if current is None:
50
+ continue
51
+ m = RE_MATRICULA.search(line)
52
+ if m:
53
+ current["matricula"] = m.group(1)
54
+ current.setdefault("data_registro", m.group(2))
55
+ continue
56
+ m = RE_ENDERECO.search(line)
57
+ if m:
58
+ current["endereco"] = m.group(1).strip()
59
+ m_city = re.search(r"([A-Za-záéíóúàãõçÁÉÍÓÚÀÃÕÇ\s]+)/TO", m.group(1))
60
+ if m_city:
61
+ current["municipio"] = m_city.group(1).strip()
62
+ continue
63
+ m = RE_TELEFONE.search(line)
64
+ if m:
65
+ current["telefone"] = m.group(1).strip()
66
+ continue
67
+ m = RE_EMAIL.search(line)
68
+ if m:
69
+ current["email"] = m.group(1).strip()
70
+ continue
71
+ if current and current.get("nome"):
72
+ records.append(current)
73
+ return records
74
+
75
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
76
+ soup = await self.fetch_page()
77
+ if not soup:
78
+ soup = await self.fetch_page_js(url=self.url, wait_ms=4000)
79
+ if not soup:
80
+ return []
81
+
82
+ results: List[Leiloeiro] = []
83
+
84
+ # Encontra container principal do CMS
85
+ content = soup.select_one(
86
+ ".field--name-body, article .content, .node__content, main article, .conteudo, #content .field"
87
+ )
88
+ if not content:
89
+ candidates = sorted(soup.find_all(["div", "article", "section"]),
90
+ key=lambda el: len(el.get_text()), reverse=True)
91
+ content = candidates[0] if candidates else soup.body
92
+
93
+ if content:
94
+ records = self._parse_text_block(content.get_text("\n"))
95
+ if records:
96
+ for r in records:
97
+ results.append(self.make_leiloeiro(**r))
98
+ return results
99
+
100
+ # Fallback tabela
101
+ for table in soup.find_all("table"):
102
+ rows = table.find_all("tr")
103
+ if len(rows) < 2:
104
+ continue
105
+ headers = [self.clean(th.get_text()) for th in rows[0].find_all(["th", "td"])]
106
+ col = {(h or "").lower(): i for i, h in enumerate(headers)}
107
+
108
+ def gcol(cells, frags):
109
+ for k, i in col.items():
110
+ if any(f in k for f in frags) and i < len(cells):
111
+ return self.clean(cells[i].get_text())
112
+ return None
113
+
114
+ for row in rows[1:]:
115
+ cells = row.find_all(["td", "th"])
116
+ if not cells:
117
+ continue
118
+ nome = gcol(cells, ["nome", "leiloeiro"]) or self.clean(cells[0].get_text())
119
+ if not nome or len(nome) < 3:
120
+ continue
121
+ results.append(self.make_leiloeiro(
122
+ nome=nome,
123
+ matricula=gcol(cells, ["matr", "registro"]),
124
+ situacao=gcol(cells, ["situ", "status"]),
125
+ municipio=gcol(cells, ["munic", "cidade"]) or "Palmas",
126
+ telefone=gcol(cells, ["tel", "fone"]),
127
+ email=gcol(cells, ["email"]),
128
+ endereco=gcol(cells, ["ender", "logr"]),
129
+ data_registro=gcol(cells, ["data", "posse"]),
130
+ ))
131
+ if results:
132
+ break
133
+
134
+ return results
@@ -0,0 +1,63 @@
1
+ """
2
+ Scraper JUCIS-DF — Junta Comercial, Industrial e Serviços do Distrito Federal
3
+ URL: https://jucis.df.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 JucisDfScraper(AbstractJuntaScraper):
14
+ estado = "DF"
15
+ junta = "JUCIS-DF"
16
+ url = "https://jucis.df.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"]),
49
+ cpf_cnpj=gcol(cells, ["cpf", "cnpj"]),
50
+ situacao=gcol(cells, ["situ", "status"]),
51
+ municipio="Brasília",
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, .leiloeiro, article p"):
59
+ text = self.clean(el.get_text(" | "))
60
+ if text and len(text) > 5:
61
+ results.append(self.make_leiloeiro(nome=text, municipio="Brasília"))
62
+
63
+ return results