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,299 @@
1
+ """
2
+ Scraper JUCISRS — Junta Comercial, Industrial e Servicos do Rio Grande do Sul
3
+ URL: https://sistemas.jucisrs.rs.gov.br/leiloeiros/
4
+ Metodo: httpx POST com verify=False (SSL invalido mas conteudo OK)
5
+ Mecanismo real descoberto em 2026-02-25:
6
+ - GET https://sistemas.jucisrs.rs.gov.br/leiloeiros/
7
+ -> retorna formulario de busca PHP/Bootstrap
8
+ - POST https://sistemas.jucisrs.rs.gov.br/leiloeiros/busca/listar
9
+ com Nome=Todos (retorna todos os 376 registros)
10
+ Estrutura HTML: <b><font color="#A01A14">MATRICULA</font> - NOME<br>
11
+ separados por <hr> entre entradas
12
+ Total: 376 leiloeiros (261 ativos + 111 cancelados)
13
+ Nota: Antigo dominio jucers.rs.gov.br foi aposentado. Junta renomeada para JUCISRS.
14
+ """
15
+ from __future__ import annotations
16
+
17
+ import logging
18
+ import re
19
+ from typing import List
20
+
21
+ from .base_scraper import AbstractJuntaScraper, Leiloeiro
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ # Regex para extrair dados do formato plano JUCISRS
26
+ RE_MATRICULA_NOME = re.compile(r"(\d+)\s*-\s*(.+)")
27
+ RE_POSSE = re.compile(r"[Pp]osse\s*:\s*(\d{2}/\d{2}/\d{4})")
28
+ RE_TELEFONE = re.compile(r"[Tt]elefone\s*:\s*(.+)")
29
+ RE_EMAIL = re.compile(r"[Ee]-[Mm]ail\s*:\s*(.+)")
30
+ RE_PREPOSTO = re.compile(r"[Pp]reposto\s*:\s*(.+)")
31
+ RE_CEP = re.compile(r"CEP\s+([\d.]+)")
32
+ RE_CANCELADO = re.compile(r"CANCELAD|CANCELAMENTO|canc\.", re.IGNORECASE)
33
+ RE_CIDADE_UF = re.compile(r"^([A-ZÁÉÍÓÚÀÃÕÇ][A-ZÁÉÍÓÚÀÃÕÇ\s]+)\s+-\s+RS$")
34
+
35
+
36
+ class JucisrsScraper(AbstractJuntaScraper):
37
+ estado = "RS"
38
+ junta = "JUCISRS"
39
+ url = "https://sistemas.jucisrs.rs.gov.br/leiloeiros/"
40
+ url_fallback = "https://jucisrs.rs.gov.br/leiloeiro"
41
+
42
+ _POST_URL = "https://sistemas.jucisrs.rs.gov.br/leiloeiros/busca/listar"
43
+
44
+ def _parse_plain_html(self, html: str) -> List[dict]:
45
+ """
46
+ Parseia o formato plano HTML da JUCISRS.
47
+ Toda a lista esta dentro de um unico grande <b> com <hr> como separadores.
48
+ Estrutura por entrada (separada por <hr/>):
49
+ <font color="#A01A14">173</font> - NOME<br/>
50
+ [www.site.com.br<br/>]
51
+ <b>Posse : </b>DD/MM/AAAA<br/>
52
+ ENDERECO<br/>
53
+ CIDADE - RS<br/>
54
+ CEP XXXXX-XXX<br/>
55
+ Telefone : XXXXX<br/>
56
+ e-Mail : xxx@yyy<br/>
57
+ Preposto : NOME<hr/>
58
+ """
59
+ from bs4 import BeautifulSoup
60
+
61
+ records = []
62
+
63
+ # Dividir o HTML bruto pelo separador <hr> ou <hr/>
64
+ # Isso e mais confiavel que navegar o DOM pois o <b> gigante contem tudo
65
+ blocks = re.split(r"<hr\s*/?>", html, flags=re.IGNORECASE)
66
+ logger.debug("[RS] Total de blocos (separados por <hr>): %d", len(blocks))
67
+
68
+ for block in blocks:
69
+ if not block.strip():
70
+ continue
71
+
72
+ # Parsear o bloco como HTML para extrair texto estruturado
73
+ block_soup = BeautifulSoup(block, "lxml")
74
+ lines_raw = block_soup.get_text("\n").splitlines()
75
+ lines = [l.strip() for l in lines_raw if l.strip()]
76
+
77
+ if not lines:
78
+ continue
79
+
80
+ # Primeira linha com matricula e nome: "NNN - NOME SOBRENOME"
81
+ # NOTA: O <font> de cor separa matricula e nome em linhas distintas:
82
+ # lines[0] = "365" (matricula dentro do <font>)
83
+ # lines[1] = "- ADAIR ABRAAO..." (nome apos o <font>)
84
+ # Precisamos reconhecer e juntar esses dois fragmentos.
85
+ nome = None
86
+ matricula = None
87
+ situacao = None
88
+ remaining = []
89
+
90
+ for i, line in enumerate(lines):
91
+ # Padrao 1: matricula e nome na mesma linha "365 - NOME"
92
+ m = RE_MATRICULA_NOME.match(line)
93
+ if m:
94
+ matricula = m.group(1)
95
+ nome_raw = m.group(2).strip()
96
+ if RE_CANCELADO.search(nome_raw):
97
+ situacao = "CANCELADO"
98
+ nome_raw = RE_CANCELADO.sub("", nome_raw).strip(" ")
99
+ nome = self.clean(nome_raw)
100
+ remaining = lines[i+1:]
101
+ break
102
+ # Padrao 2: so matricula (numero puro), proximo e "- NOME"
103
+ if line.isdigit() and i + 1 < len(lines):
104
+ next_line = lines[i+1]
105
+ if next_line.startswith("- ") or next_line.startswith("– "):
106
+ matricula = line
107
+ nome_raw = next_line[2:].strip()
108
+ if RE_CANCELADO.search(nome_raw):
109
+ situacao = "CANCELADO"
110
+ nome_raw = RE_CANCELADO.sub("", nome_raw).strip(" ")
111
+ nome = self.clean(nome_raw)
112
+ remaining = lines[i+2:]
113
+ break
114
+
115
+ if not nome or len(nome) < 3:
116
+ continue
117
+
118
+ record = {
119
+ "nome": nome,
120
+ "matricula": matricula,
121
+ "situacao": situacao,
122
+ "municipio": "Porto Alegre",
123
+ "data_registro": None,
124
+ "telefone": None,
125
+ "email": None,
126
+ "endereco": None,
127
+ }
128
+
129
+ for line in remaining:
130
+ if not line:
131
+ continue
132
+ # Cancelado inline (linha separada como "(Cancelado)")
133
+ if RE_CANCELADO.search(line) and not record["situacao"]:
134
+ record["situacao"] = "CANCELADO"
135
+ continue
136
+ m = RE_POSSE.search(line)
137
+ if m:
138
+ record["data_registro"] = m.group(1)
139
+ continue
140
+ m = RE_TELEFONE.search(line)
141
+ if m:
142
+ record["telefone"] = self.clean(m.group(1))
143
+ continue
144
+ m = RE_EMAIL.search(line)
145
+ if m:
146
+ record["email"] = self.clean(m.group(1))
147
+ continue
148
+ m = RE_PREPOSTO.match(line)
149
+ if m:
150
+ continue # ignorar preposto
151
+ # Cidade/UF: "CANELA - RS" ou "PORTO ALEGRE - RS"
152
+ m = RE_CIDADE_UF.search(line)
153
+ if m:
154
+ record["municipio"] = m.group(1).strip()
155
+ continue
156
+ if RE_CEP.search(line):
157
+ continue # linha de CEP
158
+ # Linha de url (site)
159
+ if line.startswith("www.") or line.startswith("http"):
160
+ continue
161
+ # Linha de endereco
162
+ if (not record["endereco"] and len(line) > 5 and
163
+ re.search(r"[A-ZÁÉÍÓÚÀÃÕÇ]", line)):
164
+ record["endereco"] = line
165
+
166
+ records.append(record)
167
+
168
+ return records
169
+
170
+ async def _fetch_post(self) -> List[dict]:
171
+ """
172
+ POST para /leiloeiros/busca/listar com Nome=Todos.
173
+ Retorna todos os 376 registros em resposta unica.
174
+ """
175
+ import httpx
176
+
177
+ try:
178
+ async with httpx.AsyncClient(
179
+ headers=self.HEADERS,
180
+ verify=False, # Cert autoassinado/invalido
181
+ follow_redirects=True,
182
+ timeout=60.0,
183
+ ) as client:
184
+ # GET primeiro para obter cookies/CSRF se necessario
185
+ try:
186
+ await client.get(self.url)
187
+ except Exception:
188
+ pass
189
+
190
+ resp = await client.post(
191
+ self._POST_URL,
192
+ data={
193
+ "Nome": "",
194
+ "CodMunicipio": "0", # 0 = Todas as cidades
195
+ "Situacao": "TODOS",
196
+ "Funcao": "LEILOEIRO",
197
+ },
198
+ headers={
199
+ "Content-Type": "application/x-www-form-urlencoded",
200
+ "Referer": self.url,
201
+ "Origin": "https://sistemas.jucisrs.rs.gov.br",
202
+ },
203
+ )
204
+ if resp.status_code >= 400:
205
+ logger.warning("[RS] POST retornou HTTP %d", resp.status_code)
206
+ return []
207
+
208
+ logger.info("[RS] POST OK - tamanho resposta: %d bytes", len(resp.content))
209
+ return self._parse_plain_html(resp.text)
210
+
211
+ except Exception as exc:
212
+ logger.error("[RS] Erro no POST: %s", exc)
213
+ return []
214
+
215
+ async def _fetch_get_all(self) -> List[dict]:
216
+ """
217
+ Fallback: GET simples na URL principal com verify=False.
218
+ Pode retornar formulario ou lista parcial.
219
+ """
220
+ import httpx
221
+ from bs4 import BeautifulSoup
222
+
223
+ try:
224
+ async with httpx.AsyncClient(
225
+ headers=self.HEADERS,
226
+ verify=False,
227
+ follow_redirects=True,
228
+ timeout=30.0,
229
+ ) as client:
230
+ resp = await client.get(self.url)
231
+ if resp.status_code >= 400:
232
+ return []
233
+ soup = BeautifulSoup(resp.text, "lxml")
234
+ return self._parse_plain_html(resp.text)
235
+ except Exception as exc:
236
+ logger.error("[RS] Erro no GET: %s", exc)
237
+ return []
238
+
239
+ async def _playwright_ssl_bypass(self, url: str):
240
+ """Playwright com SSL completamente desabilitado para cert autoassinado."""
241
+ try:
242
+ from playwright.async_api import async_playwright
243
+ from bs4 import BeautifulSoup
244
+ async with async_playwright() as pw:
245
+ browser = await pw.chromium.launch(
246
+ headless=True,
247
+ args=[
248
+ "--ignore-certificate-errors",
249
+ "--ignore-ssl-errors",
250
+ "--disable-web-security",
251
+ "--allow-insecure-localhost",
252
+ ],
253
+ )
254
+ ctx = await browser.new_context(
255
+ user_agent=self.HEADERS["User-Agent"],
256
+ ignore_https_errors=True,
257
+ )
258
+ page = await ctx.new_page()
259
+ try:
260
+ await page.goto(url, timeout=60000, wait_until="networkidle")
261
+ # Submeter o formulario com "Todos"
262
+ try:
263
+ await page.fill("input[name='Nome']", "Todos")
264
+ await page.click("button[type='submit'], input[type='submit']")
265
+ await page.wait_for_load_state("networkidle", timeout=30000)
266
+ except Exception:
267
+ pass
268
+ except Exception:
269
+ pass
270
+ html = await page.content()
271
+ await browser.close()
272
+ return self._parse_plain_html(html)
273
+ except Exception as exc:
274
+ logger.error("[RS] Playwright SSL bypass falhou: %s", exc)
275
+ return []
276
+
277
+ async def parse_leiloeiros(self) -> List[Leiloeiro]:
278
+ # Estrategia 1: POST direto (mais eficiente, retorna todos de uma vez)
279
+ records = await self._fetch_post()
280
+
281
+ if not records:
282
+ # Estrategia 2: GET simples
283
+ logger.info("[RS] POST falhou, tentando GET simples")
284
+ records = await self._fetch_get_all()
285
+
286
+ if not records:
287
+ # Estrategia 3: Playwright com SSL bypass e submissao de formulario
288
+ logger.info("[RS] GET falhou, tentando Playwright com SSL bypass")
289
+ records = await self._playwright_ssl_bypass(self.url)
290
+
291
+ if not records:
292
+ # Estrategia 4: Pagina informativa (pode ter lista estatica)
293
+ logger.info("[RS] Tentando pagina informativa: %s", self.url_fallback)
294
+ soup = await self.fetch_page(url=self.url_fallback)
295
+ if soup:
296
+ records = self._parse_plain_html(str(soup))
297
+
298
+ logger.info("[RS] Total de registros encontrados: %d", len(records))
299
+ return [self.make_leiloeiro(**r) for r in records if r.get("nome")]
@@ -0,0 +1,99 @@
1
+ """
2
+ Registro de todos os 27 scrapers das Juntas Comerciais do Brasil.
3
+ Cada entrada define estado, junta, URL e scraper a ser usado.
4
+
5
+ URLs verificadas e atualizadas em 2026-02-25.
6
+ Scrapers customizados têm lógica específica para cada site.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from typing import Type
11
+
12
+ from .base_scraper import AbstractJuntaScraper
13
+ from .generic_scraper import GenericJuntaScraper
14
+
15
+ # Scrapers customizados — lógica específica por estado
16
+ from .jucesp import JucespScraper # SP
17
+ from .jucerja import JucerjaScraper # RJ (Playwright)
18
+ from .jucemg import JucemgScraper # MG
19
+ from .jucec import JucecScraper # CE
20
+ from .jucis_df import JucisDfScraper # DF
21
+ from .jucisrs import JucisrsScraper # RS (Playwright - JUCISRS, domínio antigo aposentado)
22
+ from .jucepar import JuceparScraper # PR (URL migrou para juntacomercial.pr.gov.br)
23
+ from .jucesc import JucescScraper # SC (sistema dedicado leiloeiros.jucesc.sc.gov.br)
24
+ from .juceb import JucebScraper # BA (URL migrou para ba.gov.br/juceb)
25
+ from .jucepe import JucepeScraper # PE (Playwright - portal.jucepe.pe.gov.br)
26
+ from .jucepa import JucepaScraper # PA (Drupal node/171)
27
+ from .jucema import JucemaScraper # MA (múltiplas tentativas de URL)
28
+ from .jucepi import JucepiScraper # PI (URL migrou para portal.pi.gov.br/jucepi)
29
+ from .jucern import JucernScraper # RN (HTTP com query string)
30
+ from .jucep import JucepScraper # PB (JUCEP - domínio migrou para jucep.pb.gov.br)
31
+ from .juceal import JucealScraper # AL (URL correta: /servicos/leiloeiros)
32
+ from .jucer import JucerScraper # RO (URL migrou para rondonia.ro.gov.br/jucer)
33
+ from .jucap import JucapScraper # AP (HTTP - cert TLS inválido)
34
+ from .juceac import JuceacScraper # AC (URL correta: /leiloeiro/ singular)
35
+ from .jucetins import JucetinsScraper # TO (JUCETINS - URL migrou para to.gov.br/jucetins)
36
+
37
+
38
+ def _make(estado: str, junta: str, url: str, municipio_default: str = None) -> Type[AbstractJuntaScraper]:
39
+ """Cria dinamicamente uma classe de scraper genérico para o estado."""
40
+ attrs = {
41
+ "estado": estado,
42
+ "junta": junta,
43
+ "url": url,
44
+ "municipio_default": municipio_default,
45
+ }
46
+ return type(f"{junta}Scraper", (GenericJuntaScraper,), attrs)
47
+
48
+
49
+ # Mapeamento completo: UF -> Classe de Scraper
50
+ # Todos os 27 estados com URLs verificadas e atualizadas em 2026-02-25
51
+ SCRAPERS: dict[str, Type[AbstractJuntaScraper]] = {
52
+ # Região Sudeste
53
+ "SP": JucespScraper, # JUCESP - https://www.institucional.jucesp.sp.gov.br/tradutores-leiloeiros.html
54
+ "RJ": JucerjaScraper, # JUCERJA - https://www.jucerja.rj.gov.br/AuxiliaresComercio/Leiloeiros (JS)
55
+ "MG": JucemgScraper, # JUCEMG - https://jucemg.mg.gov.br/pagina/139/leiloeiros-oficiais
56
+ "ES": _make("ES", "JUCEES", "https://jucees.es.gov.br/leiloeiros", "Vitória"),
57
+
58
+ # Região Sul
59
+ "RS": JucisrsScraper, # JUCISRS - https://sistemas.jucisrs.rs.gov.br/leiloeiros/ (JS)
60
+ "PR": JuceparScraper, # JUCEPAR - https://www.juntacomercial.pr.gov.br/Pagina/LEILOEIROS-OFICIAIS
61
+ "SC": JucescScraper, # JUCESC - https://leiloeiros.jucesc.sc.gov.br/site/
62
+
63
+ # Região Nordeste
64
+ "BA": JucebScraper, # JUCEB - https://www.ba.gov.br/juceb/home/matriculas-e-carteira-profissional/leiloeiros
65
+ "PE": JucepeScraper, # JUCEPE - https://portal.jucepe.pe.gov.br/leiloeiros (JS)
66
+ "CE": JucecScraper, # JUCEC - https://www.jucec.ce.gov.br/leiloeiros/
67
+ "MA": JucemaScraper, # JUCEMA - múltiplas URLs tentadas
68
+ "PI": JucepiScraper, # JUCEPI - https://portal.pi.gov.br/jucepi/leiloeiro-oficial/
69
+ "RN": JucernScraper, # JUCERN - http://www.jucern.rn.gov.br/Conteudo.asp?TRAN=ITEM&TARG=8695...
70
+ "PB": JucepScraper, # JUCEP - https://jucep.pb.gov.br/contatos/leiloeiros
71
+ "AL": JucealScraper, # JUCEAL - http://www.juceal.al.gov.br/servicos/leiloeiros
72
+ "SE": _make("SE", "JUCESE", "https://jucese.se.gov.br/leiloeiros/", "Aracaju"),
73
+
74
+ # Região Centro-Oeste
75
+ "DF": JucisDfScraper, # JUCIS-DF - https://jucis.df.gov.br/leiloeiros/
76
+ "GO": _make("GO", "JUCEG", "https://goias.gov.br/juceg/", "Goiânia"),
77
+ "MT": _make("MT", "JUCEMAT", "https://www.jucemat.mt.gov.br/leiloeiros", "Cuiabá"),
78
+ "MS": _make("MS", "JUCEMS", "https://www.jucems.ms.gov.br/empresas/controles-especiais/agentes-auxiliares/leiloeiros/", "Campo Grande"),
79
+
80
+ # Região Norte
81
+ "PA": JucepaScraper, # JUCEPA - https://www.jucepa.pa.gov.br/node/171
82
+ "AM": _make("AM", "JUCEA", "https://www.jucea.am.gov.br/leiloeiros/", "Manaus"),
83
+ "RO": JucerScraper, # JUCER - https://rondonia.ro.gov.br/jucer/lista-de-leiloeiros-oficiais/
84
+ "RR": _make("RR", "JUCERR", "https://jucerr.rr.gov.br/leiloeiros/", "Boa Vista"),
85
+ "AP": JucapScraper, # JUCAP - http://www.jucap.ap.gov.br/leiloeiros (HTTP - TLS inválido)
86
+ "AC": JuceacScraper, # JUCEAC - https://juceac.ac.gov.br/leiloeiro/
87
+ "TO": JucetinsScraper, # JUCETINS - https://www.to.gov.br/jucetins/leiloeiros/152aezl6blm0
88
+ }
89
+
90
+
91
+ def get_all_scrapers() -> list[AbstractJuntaScraper]:
92
+ """Retorna instâncias de todos os scrapers."""
93
+ return [cls() for cls in SCRAPERS.values()]
94
+
95
+
96
+ def get_scraper(estado: str) -> AbstractJuntaScraper | None:
97
+ """Retorna o scraper para um estado específico (UF)."""
98
+ cls = SCRAPERS.get(estado.upper())
99
+ return cls() if cls else None
@@ -0,0 +1,164 @@
1
+ """
2
+ API REST para consulta de leiloeiros das Juntas Comerciais do Brasil.
3
+
4
+ Uso:
5
+ python scripts/serve_api.py
6
+ python scripts/serve_api.py --port 8080 --host 0.0.0.0
7
+
8
+ Endpoints:
9
+ GET / → info da API
10
+ GET /leiloeiros → lista todos (filtros: estado, situacao, nome, limit, offset)
11
+ GET /leiloeiros/{estado} → por UF
12
+ GET /busca?q=texto → busca por nome/matrícula/município
13
+ GET /stats → contagem por estado
14
+ GET /export/json → dump completo em JSON
15
+ GET /export/csv → dump completo em CSV
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import argparse
20
+ import csv
21
+ import io
22
+ import json
23
+ import sys
24
+ from pathlib import Path
25
+ from typing import List, Optional
26
+
27
+ sys.path.insert(0, str(Path(__file__).parent))
28
+
29
+ from db import Database
30
+
31
+ try:
32
+ from fastapi import FastAPI, HTTPException, Query
33
+ from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse
34
+ import uvicorn
35
+ except ImportError:
36
+ print("FastAPI não instalado. Execute: pip install fastapi uvicorn")
37
+ sys.exit(1)
38
+
39
+ app = FastAPI(
40
+ title="Leiloeiros Juntas Comerciais Brasil",
41
+ description="API de dados de leiloeiros oficiais de todas as 27 Juntas Comerciais do Brasil",
42
+ version="1.0.0",
43
+ )
44
+
45
+ db = Database()
46
+ db.init()
47
+
48
+
49
+ @app.get("/", summary="Informações da API")
50
+ def root():
51
+ total = db.get_total()
52
+ return {
53
+ "name": "Leiloeiros Juntas Comerciais Brasil",
54
+ "version": "1.0.0",
55
+ "total_registros": total,
56
+ "endpoints": {
57
+ "lista": "/leiloeiros",
58
+ "por_estado": "/leiloeiros/{estado}",
59
+ "busca": "/busca?q=texto",
60
+ "stats": "/stats",
61
+ "export_json": "/export/json",
62
+ "export_csv": "/export/csv",
63
+ },
64
+ }
65
+
66
+
67
+ @app.get("/leiloeiros", summary="Lista leiloeiros com filtros")
68
+ def list_leiloeiros(
69
+ estado: Optional[str] = Query(None, description="UF ex: SP, RJ, MG"),
70
+ situacao: Optional[str] = Query(None, description="ATIVO, CANCELADO, SUSPENSO"),
71
+ nome: Optional[str] = Query(None, description="Busca parcial por nome"),
72
+ limit: int = Query(100, ge=1, le=5000),
73
+ offset: int = Query(0, ge=0),
74
+ ):
75
+ records = db.get_all(
76
+ estado=estado,
77
+ situacao=situacao,
78
+ nome_like=nome,
79
+ limit=limit,
80
+ offset=offset,
81
+ )
82
+ return {"total": len(records), "offset": offset, "data": records}
83
+
84
+
85
+ @app.get("/leiloeiros/{estado}", summary="Leiloeiros de um estado específico")
86
+ def leiloeiros_por_estado(estado: str):
87
+ estado = estado.upper()
88
+ if len(estado) != 2:
89
+ raise HTTPException(status_code=400, detail="Estado deve ser a UF com 2 letras (ex: SP)")
90
+ records = db.get_by_estado(estado)
91
+ return {"estado": estado, "total": len(records), "data": records}
92
+
93
+
94
+ @app.get("/busca", summary="Busca por nome, matrícula ou município")
95
+ def busca(
96
+ q: str = Query(..., description="Texto para buscar"),
97
+ limit: int = Query(50, ge=1, le=500),
98
+ ):
99
+ if len(q) < 2:
100
+ raise HTTPException(status_code=400, detail="Query deve ter pelo menos 2 caracteres")
101
+ records = db.search(q, limit=limit)
102
+ return {"query": q, "total": len(records), "data": records}
103
+
104
+
105
+ @app.get("/stats", summary="Estatísticas por estado")
106
+ def stats():
107
+ data = db.get_stats()
108
+ total = sum(r["total"] for r in data)
109
+ return {"total_geral": total, "por_estado": data}
110
+
111
+
112
+ @app.get("/export/json", summary="Exporta todos os dados em JSON")
113
+ def export_json():
114
+ records = db.get_all()
115
+ return JSONResponse(
116
+ content={"total": len(records), "data": records},
117
+ headers={"Content-Disposition": "attachment; filename=leiloeiros.json"},
118
+ )
119
+
120
+
121
+ @app.get("/export/csv", summary="Exporta todos os dados em CSV")
122
+ def export_csv():
123
+ records = db.get_all()
124
+ if not records:
125
+ return PlainTextResponse("Nenhum dado encontrado.")
126
+
127
+ output = io.StringIO()
128
+ writer = csv.DictWriter(
129
+ output,
130
+ fieldnames=list(records[0].keys()),
131
+ extrasaction="ignore",
132
+ )
133
+ writer.writeheader()
134
+ writer.writerows(records)
135
+ output.seek(0)
136
+
137
+ return StreamingResponse(
138
+ iter([output.getvalue()]),
139
+ media_type="text/csv",
140
+ headers={"Content-Disposition": "attachment; filename=leiloeiros.csv"},
141
+ )
142
+
143
+
144
+ def main():
145
+ parser = argparse.ArgumentParser(description="Servidor API de leiloeiros")
146
+ parser.add_argument("--host", default="127.0.0.1")
147
+ parser.add_argument("--port", type=int, default=8000)
148
+ parser.add_argument("--reload", action="store_true")
149
+ args = parser.parse_args()
150
+
151
+ print(f"\nAPI disponível em: http://{args.host}:{args.port}")
152
+ print(f"Docs interativos: http://{args.host}:{args.port}/docs\n")
153
+
154
+ uvicorn.run(
155
+ "serve_api:app",
156
+ host=args.host,
157
+ port=args.port,
158
+ reload=args.reload,
159
+ app_dir=str(Path(__file__).parent),
160
+ )
161
+
162
+
163
+ if __name__ == "__main__":
164
+ main()