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,538 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Prof. Euler — Dependency Graph Analyzer
4
+ Gera grafo de dependências de projetos Kotlin/Android com análise matemática
5
+ de grafos: componentes, ciclos, centralidade, instabilidade.
6
+
7
+ Uso:
8
+ python dependency_graph.py [path] [--format dot|json|text] [--output FILE]
9
+ python dependency_graph.py C:/Users/renat/earbudllm
10
+ python dependency_graph.py C:/Users/renat/earbudllm --format dot --output deps.dot
11
+ """
12
+
13
+ import os
14
+ import re
15
+ import sys
16
+ import json
17
+ import argparse
18
+ from pathlib import Path
19
+ from dataclasses import dataclass, field
20
+ from typing import Dict, List, Set, Optional, Tuple
21
+
22
+ # Fix Windows terminal encoding (cp1252 doesn't support emojis/unicode)
23
+ if sys.platform == 'win32':
24
+ try:
25
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
26
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
27
+ except AttributeError:
28
+ pass # Python < 3.7 fallback
29
+ from collections import defaultdict, deque
30
+
31
+
32
+ @dataclass
33
+ class Node:
34
+ id: str
35
+ module: str
36
+ package: str
37
+ kind: str # 'class', 'interface', 'object', 'enum', 'data class'
38
+ is_abstract: bool = False
39
+ is_open: bool = False
40
+
41
+
42
+ @dataclass
43
+ class Edge:
44
+ src: str # node id
45
+ dst: str # node id
46
+ kind: str # 'implements', 'extends', 'uses', 'imports', 'delegates_to'
47
+ weight: float = 1.0
48
+
49
+
50
+ class DependencyGraph:
51
+ """Grafo de dependências com análise matemática completa."""
52
+
53
+ def __init__(self):
54
+ self.nodes: Dict[str, Node] = {}
55
+ self.edges: List[Edge] = []
56
+ self._adj: Dict[str, Set[str]] = defaultdict(set) # adjacência direta
57
+ self._radj: Dict[str, Set[str]] = defaultdict(set) # adjacência reversa
58
+
59
+ def add_node(self, node: Node) -> None:
60
+ self.nodes[node.id] = node
61
+
62
+ def add_edge(self, edge: Edge) -> None:
63
+ if edge.src != edge.dst: # sem self-loops
64
+ self.edges.append(edge)
65
+ self._adj[edge.src].add(edge.dst)
66
+ self._radj[edge.dst].add(edge.src)
67
+
68
+ def successors(self, node_id: str) -> Set[str]:
69
+ return self._adj.get(node_id, set())
70
+
71
+ def predecessors(self, node_id: str) -> Set[str]:
72
+ return self._radj.get(node_id, set())
73
+
74
+ # ─── Algoritmos de Grafos ────────────────────────────────────────────────
75
+
76
+ def find_cycles(self) -> List[List[str]]:
77
+ """Detecta ciclos usando DFS com coloração (branco/cinza/preto)."""
78
+ WHITE, GRAY, BLACK = 0, 1, 2
79
+ color = {n: WHITE for n in self.nodes}
80
+ cycles = []
81
+ path = []
82
+
83
+ def dfs(node: str) -> None:
84
+ color[node] = GRAY
85
+ path.append(node)
86
+
87
+ for neighbor in self._adj.get(node, set()):
88
+ if neighbor not in self.nodes:
89
+ continue
90
+ if color[neighbor] == GRAY:
91
+ # Ciclo encontrado! Extrair o ciclo do path
92
+ cycle_start = path.index(neighbor)
93
+ cycle = path[cycle_start:] + [neighbor]
94
+ cycles.append(cycle)
95
+ elif color[neighbor] == WHITE:
96
+ dfs(neighbor)
97
+
98
+ path.pop()
99
+ color[node] = BLACK
100
+
101
+ for node in list(self.nodes.keys()):
102
+ if color[node] == WHITE:
103
+ dfs(node)
104
+
105
+ # Deduplicar ciclos
106
+ unique = []
107
+ seen = set()
108
+ for cycle in cycles:
109
+ key = frozenset(cycle)
110
+ if key not in seen:
111
+ seen.add(key)
112
+ unique.append(cycle)
113
+
114
+ return unique
115
+
116
+ def strongly_connected_components(self) -> List[List[str]]:
117
+ """Algoritmo de Kosaraju para SCCs."""
118
+ visited = set()
119
+ finish_order = []
120
+
121
+ def dfs1(node: str) -> None:
122
+ visited.add(node)
123
+ for neighbor in self._adj.get(node, set()):
124
+ if neighbor in self.nodes and neighbor not in visited:
125
+ dfs1(neighbor)
126
+ finish_order.append(node)
127
+
128
+ def dfs2(node: str, component: List[str]) -> None:
129
+ visited.add(node)
130
+ component.append(node)
131
+ for neighbor in self._radj.get(node, set()):
132
+ if neighbor in self.nodes and neighbor not in visited:
133
+ dfs2(neighbor, component)
134
+
135
+ # Fase 1: DFS no grafo original
136
+ for node in self.nodes:
137
+ if node not in visited:
138
+ dfs1(node)
139
+
140
+ # Fase 2: DFS no grafo transposto na ordem inversa de finalização
141
+ visited.clear()
142
+ sccs = []
143
+ for node in reversed(finish_order):
144
+ if node not in visited:
145
+ component = []
146
+ dfs2(node, component)
147
+ sccs.append(component)
148
+
149
+ return sccs
150
+
151
+ def topological_sort(self) -> Optional[List[str]]:
152
+ """Ordenação topológica (só válida se DAG)."""
153
+ in_degree = defaultdict(int)
154
+ for edge in self.edges:
155
+ if edge.src in self.nodes and edge.dst in self.nodes:
156
+ in_degree[edge.dst] += 1
157
+
158
+ queue = deque([n for n in self.nodes if in_degree[n] == 0])
159
+ result = []
160
+
161
+ while queue:
162
+ node = queue.popleft()
163
+ result.append(node)
164
+ for neighbor in self._adj.get(node, set()):
165
+ if neighbor in self.nodes:
166
+ in_degree[neighbor] -= 1
167
+ if in_degree[neighbor] == 0:
168
+ queue.append(neighbor)
169
+
170
+ if len(result) == len(self.nodes):
171
+ return result
172
+ return None # Há ciclos → não é DAG
173
+
174
+ def betweenness_centrality(self) -> Dict[str, float]:
175
+ """
176
+ Centralidade de betweenness: nós que fazem "ponte" entre outros.
177
+ Alto betweenness = single point of failure.
178
+
179
+ Algoritmo de Brandes: O(V·E)
180
+ """
181
+ betweenness = defaultdict(float)
182
+ nodes = list(self.nodes.keys())
183
+
184
+ for s in nodes:
185
+ # BFS para encontrar caminhos mais curtos de s para todos
186
+ stack = []
187
+ pred = defaultdict(list)
188
+ sigma = defaultdict(int)
189
+ sigma[s] = 1
190
+ dist = defaultdict(lambda: -1)
191
+ dist[s] = 0
192
+ queue = deque([s])
193
+
194
+ while queue:
195
+ v = queue.popleft()
196
+ stack.append(v)
197
+ for w in self._adj.get(v, set()):
198
+ if w not in self.nodes:
199
+ continue
200
+ if dist[w] < 0:
201
+ queue.append(w)
202
+ dist[w] = dist[v] + 1
203
+ if dist[w] == dist[v] + 1:
204
+ sigma[w] += sigma[v]
205
+ pred[w].append(v)
206
+
207
+ # Acumulação
208
+ delta = defaultdict(float)
209
+ while stack:
210
+ w = stack.pop()
211
+ for v in pred[w]:
212
+ if sigma[w] > 0:
213
+ delta[v] += (sigma[v] / sigma[w]) * (1 + delta[w])
214
+ if w != s:
215
+ betweenness[w] += delta[w]
216
+
217
+ # Normalizar
218
+ n = len(nodes)
219
+ if n > 2:
220
+ factor = 2 / ((n - 1) * (n - 2))
221
+ for node in betweenness:
222
+ betweenness[node] *= factor
223
+
224
+ return dict(betweenness)
225
+
226
+ def page_rank(self, damping: float = 0.85, iterations: int = 100) -> Dict[str, float]:
227
+ """
228
+ PageRank para identificar classes/módulos mais "importantes".
229
+ Nodes com alto PageRank são frequentemente usados por outros.
230
+ """
231
+ n = len(self.nodes)
232
+ if n == 0:
233
+ return {}
234
+
235
+ rank = {node: 1.0 / n for node in self.nodes}
236
+
237
+ for _ in range(iterations):
238
+ new_rank = {}
239
+ for node in self.nodes:
240
+ incoming_sum = sum(
241
+ rank.get(pred, 0) / max(len(self._adj.get(pred, set())), 1)
242
+ for pred in self._radj.get(node, set())
243
+ if pred in self.nodes
244
+ )
245
+ new_rank[node] = (1 - damping) / n + damping * incoming_sum
246
+ rank = new_rank
247
+
248
+ return rank
249
+
250
+ def coupling_metrics(self) -> Dict[str, Dict]:
251
+ """Calcula Ca, Ce, instabilidade e abstração por módulo."""
252
+ module_nodes: Dict[str, Set[str]] = defaultdict(set)
253
+ for node_id, node in self.nodes.items():
254
+ module_nodes[node.module].add(node_id)
255
+
256
+ metrics = {}
257
+ for module, nodes in module_nodes.items():
258
+ # Ce: dependências efetivas (de fora do módulo)
259
+ efferent = set()
260
+ for n in nodes:
261
+ for dep in self._adj.get(n, set()):
262
+ if dep in self.nodes and self.nodes[dep].module != module:
263
+ efferent.add(self.nodes[dep].module)
264
+
265
+ # Ca: acoplamentos aferentes
266
+ afferent = set()
267
+ for n in nodes:
268
+ for dep in self._radj.get(n, set()):
269
+ if dep in self.nodes and self.nodes[dep].module != module:
270
+ afferent.add(self.nodes[dep].module)
271
+
272
+ ca = len(afferent)
273
+ ce = len(efferent)
274
+ instability = ce / (ca + ce) if (ca + ce) > 0 else 0.0
275
+
276
+ # Abstração: razão de interfaces/abstratas para total
277
+ abstracts = sum(1 for n in nodes if
278
+ n in self.nodes and
279
+ (self.nodes[n].is_abstract or self.nodes[n].kind == 'interface'))
280
+ abstraction = abstracts / max(len(nodes), 1)
281
+
282
+ # Distância da sequência principal: D = |A + I - 1|
283
+ # Sequência principal: A + I = 1 (ideal)
284
+ distance = abs(abstraction + instability - 1)
285
+
286
+ metrics[module] = {
287
+ 'Ca': ca,
288
+ 'Ce': ce,
289
+ 'instability': round(instability, 3),
290
+ 'abstraction': round(abstraction, 3),
291
+ 'distance_from_main_sequence': round(distance, 3),
292
+ 'total_classes': len(nodes),
293
+ 'abstract_classes': abstracts,
294
+ 'depends_on_modules': list(efferent),
295
+ 'used_by_modules': list(afferent),
296
+ }
297
+
298
+ return metrics
299
+
300
+
301
+ class ProjectAnalyzer:
302
+ """Analisa um projeto Kotlin/Android completo."""
303
+
304
+ def __init__(self, project_root: str):
305
+ self.project_root = Path(project_root)
306
+ self.graph = DependencyGraph()
307
+ self.module_files: Dict[str, List[Path]] = defaultdict(list)
308
+
309
+ def analyze(self) -> None:
310
+ """Analisa todos os arquivos Kotlin."""
311
+ kt_files = list(self.project_root.glob("**/*.kt"))
312
+
313
+ for kt_file in kt_files:
314
+ module = self._detect_module(kt_file)
315
+ self.module_files[module].append(kt_file)
316
+ self._analyze_file(kt_file, module)
317
+
318
+ def _detect_module(self, file_path: Path) -> str:
319
+ known = ['app', 'bluetooth', 'audio', 'voice', 'llm', 'integrations', 'core-logging']
320
+ for part in file_path.parts:
321
+ if part in known:
322
+ return part
323
+ return 'unknown'
324
+
325
+ def _analyze_file(self, file_path: Path, module: str) -> None:
326
+ try:
327
+ content = file_path.read_text(encoding='utf-8', errors='ignore')
328
+ except Exception:
329
+ return
330
+
331
+ # Extrair package
332
+ pkg_match = re.search(r'^package\s+(.+)$', content, re.MULTILINE)
333
+ package = pkg_match.group(1).strip() if pkg_match else 'unknown'
334
+
335
+ # Extrair declarações de classe/interface/object
336
+ class_patterns = [
337
+ (r'(?:abstract\s+)?(?:open\s+)?(?:data\s+)?class\s+(\w+)', 'class'),
338
+ (r'interface\s+(\w+)', 'interface'),
339
+ (r'object\s+(\w+)', 'object'),
340
+ (r'enum\s+class\s+(\w+)', 'enum'),
341
+ ]
342
+
343
+ for pattern, kind in class_patterns:
344
+ for match in re.finditer(pattern, content):
345
+ class_name = match.group(1)
346
+ node_id = f"{package}.{class_name}"
347
+ is_abstract = 'abstract' in content[max(0, match.start()-20):match.start()]
348
+ is_open = 'open' in content[max(0, match.start()-10):match.start()]
349
+
350
+ node = Node(
351
+ id=node_id,
352
+ module=module,
353
+ package=package,
354
+ kind=kind,
355
+ is_abstract=is_abstract,
356
+ is_open=is_open
357
+ )
358
+ self.graph.add_node(node)
359
+
360
+ # Extrair dependências via imports
361
+ imports = re.findall(r'^import\s+(.+)$', content, re.MULTILINE)
362
+ for imp in imports:
363
+ imp = imp.strip()
364
+ if imp.startswith('com.earllm'):
365
+ dep_id = imp
366
+ if dep_id != node_id:
367
+ edge = Edge(src=node_id, dst=dep_id, kind='imports')
368
+ self.graph.add_edge(edge)
369
+
370
+ def generate_full_report(self) -> Dict:
371
+ """Gera relatório matemático completo do grafo."""
372
+ cycles = self.graph.find_cycles()
373
+ sccs = self.graph.strongly_connected_components()
374
+ topo = self.graph.topological_sort()
375
+ betweenness = self.graph.betweenness_centrality()
376
+ pagerank = self.graph.page_rank()
377
+ coupling = self.graph.coupling_metrics()
378
+
379
+ # Top nodes por betweenness (single points of failure)
380
+ top_betweenness = sorted(
381
+ betweenness.items(), key=lambda x: x[1], reverse=True
382
+ )[:10]
383
+
384
+ # Top nodes por pagerank (mais influentes)
385
+ top_pagerank = sorted(
386
+ pagerank.items(), key=lambda x: x[1], reverse=True
387
+ )[:10]
388
+
389
+ # SCCs com mais de 1 nó (ciclos reais)
390
+ real_sccs = [scc for scc in sccs if len(scc) > 1]
391
+
392
+ return {
393
+ 'graph_summary': {
394
+ 'nodes': len(self.graph.nodes),
395
+ 'edges': len(self.graph.edges),
396
+ 'is_dag': topo is not None,
397
+ 'cycles_found': len(cycles),
398
+ 'strongly_connected_components': len(real_sccs),
399
+ },
400
+ 'cycles': cycles[:10], # primeiros 10 ciclos
401
+ 'real_sccs': real_sccs[:5],
402
+ 'topological_order': topo[:20] if topo else None,
403
+ 'top_betweenness_centrality': [
404
+ {'node': n, 'betweenness': round(b, 4)} for n, b in top_betweenness
405
+ ],
406
+ 'top_pagerank': [
407
+ {'node': n, 'pagerank': round(pr, 4)} for n, pr in top_pagerank
408
+ ],
409
+ 'module_coupling': coupling,
410
+ 'modules': {mod: len(files) for mod, files in self.module_files.items()},
411
+ }
412
+
413
+ def to_dot(self) -> str:
414
+ """Exporta grafo em formato DOT para visualização (Graphviz)."""
415
+ lines = ['digraph AuriDependencies {']
416
+ lines.append(' rankdir=LR;')
417
+ lines.append(' node [shape=box, fontname="Arial"];')
418
+
419
+ # Cores por módulo
420
+ module_colors = {
421
+ 'app': '#4CAF50',
422
+ 'bluetooth': '#2196F3',
423
+ 'audio': '#FF9800',
424
+ 'voice': '#9C27B0',
425
+ 'llm': '#F44336',
426
+ 'integrations': '#00BCD4',
427
+ 'core-logging': '#607D8B',
428
+ }
429
+
430
+ # Adicionar nós por módulo
431
+ modules_seen = defaultdict(list)
432
+ for node_id, node in self.graph.nodes.items():
433
+ modules_seen[node.module].append((node_id, node))
434
+
435
+ for module, nodes in modules_seen.items():
436
+ color = module_colors.get(module, '#9E9E9E')
437
+ lines.append(f' subgraph cluster_{module.replace("-", "_")} {{')
438
+ lines.append(f' label="{module}";')
439
+ lines.append(f' style=filled;')
440
+ lines.append(f' fillcolor="{color}20";') # 20 = ~12% opacity
441
+ for node_id, node in nodes[:20]: # limitar para visualização
442
+ short_name = node_id.split('.')[-1]
443
+ shape = 'diamond' if node.kind == 'interface' else 'box'
444
+ lines.append(f' "{node_id}" [label="{short_name}", shape={shape}];')
445
+ lines.append(' }')
446
+
447
+ # Adicionar arestas (amostra)
448
+ for edge in self.edges[:100]: # limitar para visualização
449
+ lines.append(f' "{edge.src}" -> "{edge.dst}" [label="{edge.kind}"];')
450
+
451
+ lines.append('}')
452
+ return '\n'.join(lines)
453
+
454
+ @property
455
+ def edges(self):
456
+ return self.graph.edges
457
+
458
+ def print_report(self, report: Dict) -> None:
459
+ print("\n" + "="*70)
460
+ print(" PROF. EULER — ANÁLISE DE GRAFOS DE DEPENDÊNCIAS")
461
+ print("="*70)
462
+
463
+ gs = report['graph_summary']
464
+ print(f"\n📊 RESUMO DO GRAFO G = (V={gs['nodes']}, E={gs['edges']}):")
465
+ print(f" É DAG (sem ciclos): {'✅ SIM' if gs['is_dag'] else '❌ NÃO'}")
466
+ print(f" Ciclos detectados: {gs['cycles_found']}")
467
+ print(f" SCCs com mais de 1 nó: {gs['strongly_connected_components']}")
468
+
469
+ if report['cycles']:
470
+ print(f"\n❌ CICLOS DE DEPENDÊNCIA (devem ser eliminados):")
471
+ for i, cycle in enumerate(report['cycles'][:5], 1):
472
+ print(f" {i}. {' → '.join(c.split('.')[-1] for c in cycle)}")
473
+
474
+ if report['top_betweenness_centrality']:
475
+ print(f"\n⚠️ TOP NÓDULOS CRÍTICOS (single points of failure — alto betweenness):")
476
+ for item in report['top_betweenness_centrality'][:5]:
477
+ short = item['node'].split('.')[-1]
478
+ print(f" {short:<35} betweenness={item['betweenness']:.4f}")
479
+
480
+ print(f"\n📦 ACOPLAMENTO DE MÓDULOS (Princípio de Martin):")
481
+ print(f" {'Módulo':<20} {'Ca':>5} {'Ce':>5} {'I':>8} {'A':>8} {'D':>8} Status")
482
+ print(f" {'-'*20} {'-'*5} {'-'*5} {'-'*8} {'-'*8} {'-'*8} {'-'*20}")
483
+ for mod, data in sorted(report['module_coupling'].items()):
484
+ i = data['instability']
485
+ a = data['abstraction']
486
+ d = data['distance_from_main_sequence']
487
+ status = "✅ OK" if d < 0.3 else ("⚠️ ZONA DE PROBLEMA" if d < 0.5 else "❌ FORA DA SEQ.")
488
+ print(f" {mod:<20} {data['Ca']:>5} {data['Ce']:>5} {i:>8.3f} {a:>8.3f} {d:>8.3f} {status}")
489
+
490
+ print("\n I=instabilidade, A=abstração, D=distância da sequência principal")
491
+ print(" D ideal < 0.3 (zona de exclusão = zona de dor/inutilidade)")
492
+ print("\n" + "="*70 + "\n")
493
+
494
+
495
+ def main():
496
+ parser = argparse.ArgumentParser(
497
+ description='Prof. Euler — Análise de Grafos de Dependências'
498
+ )
499
+ parser.add_argument('path', nargs='?',
500
+ default=r'C:\Users\renat\earbudllm',
501
+ help='Caminho raiz do projeto')
502
+ parser.add_argument('--format', '-f', choices=['text', 'json', 'dot'],
503
+ default='text', help='Formato de saída')
504
+ parser.add_argument('--output', '-o', help='Arquivo de saída')
505
+
506
+ args = parser.parse_args()
507
+
508
+ print(f"🔬 Prof. Euler analisando grafos: {args.path}")
509
+
510
+ analyzer = ProjectAnalyzer(args.path)
511
+ analyzer.analyze()
512
+ report = analyzer.generate_full_report()
513
+
514
+ if args.format == 'json':
515
+ output = json.dumps(report, indent=2, ensure_ascii=False)
516
+ print(output)
517
+ elif args.format == 'dot':
518
+ output = analyzer.to_dot()
519
+ print(output)
520
+ if args.output:
521
+ Path(args.output).write_text(output)
522
+ print(f"\n✅ Arquivo DOT salvo: {args.output}")
523
+ print(" Para visualizar: dot -Tpng deps.dot -o deps.png")
524
+ else:
525
+ analyzer.print_report(report)
526
+
527
+ if args.output and args.format != 'dot':
528
+ Path(args.output).write_text(
529
+ json.dumps(report, indent=2, ensure_ascii=False),
530
+ encoding='utf-8'
531
+ )
532
+ print(f"✅ Relatório salvo: {args.output}")
533
+
534
+ return report
535
+
536
+
537
+ if __name__ == '__main__':
538
+ main()
@@ -0,0 +1,151 @@
1
+ """Lightweight connection handling for MCP servers."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from contextlib import AsyncExitStack
5
+ from typing import Any
6
+
7
+ from mcp import ClientSession, StdioServerParameters
8
+ from mcp.client.sse import sse_client
9
+ from mcp.client.stdio import stdio_client
10
+ from mcp.client.streamable_http import streamablehttp_client
11
+
12
+
13
+ class MCPConnection(ABC):
14
+ """Base class for MCP server connections."""
15
+
16
+ def __init__(self):
17
+ self.session = None
18
+ self._stack = None
19
+
20
+ @abstractmethod
21
+ def _create_context(self):
22
+ """Create the connection context based on connection type."""
23
+
24
+ async def __aenter__(self):
25
+ """Initialize MCP server connection."""
26
+ self._stack = AsyncExitStack()
27
+ await self._stack.__aenter__()
28
+
29
+ try:
30
+ ctx = self._create_context()
31
+ result = await self._stack.enter_async_context(ctx)
32
+
33
+ if len(result) == 2:
34
+ read, write = result
35
+ elif len(result) == 3:
36
+ read, write, _ = result
37
+ else:
38
+ raise ValueError(f"Unexpected context result: {result}")
39
+
40
+ session_ctx = ClientSession(read, write)
41
+ self.session = await self._stack.enter_async_context(session_ctx)
42
+ await self.session.initialize()
43
+ return self
44
+ except BaseException:
45
+ await self._stack.__aexit__(None, None, None)
46
+ raise
47
+
48
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
49
+ """Clean up MCP server connection resources."""
50
+ if self._stack:
51
+ await self._stack.__aexit__(exc_type, exc_val, exc_tb)
52
+ self.session = None
53
+ self._stack = None
54
+
55
+ async def list_tools(self) -> list[dict[str, Any]]:
56
+ """Retrieve available tools from the MCP server."""
57
+ response = await self.session.list_tools()
58
+ return [
59
+ {
60
+ "name": tool.name,
61
+ "description": tool.description,
62
+ "input_schema": tool.inputSchema,
63
+ }
64
+ for tool in response.tools
65
+ ]
66
+
67
+ async def call_tool(self, tool_name: str, arguments: dict[str, Any]) -> Any:
68
+ """Call a tool on the MCP server with provided arguments."""
69
+ result = await self.session.call_tool(tool_name, arguments=arguments)
70
+ return result.content
71
+
72
+
73
+ class MCPConnectionStdio(MCPConnection):
74
+ """MCP connection using standard input/output."""
75
+
76
+ def __init__(self, command: str, args: list[str] = None, env: dict[str, str] = None):
77
+ super().__init__()
78
+ self.command = command
79
+ self.args = args or []
80
+ self.env = env
81
+
82
+ def _create_context(self):
83
+ return stdio_client(
84
+ StdioServerParameters(command=self.command, args=self.args, env=self.env)
85
+ )
86
+
87
+
88
+ class MCPConnectionSSE(MCPConnection):
89
+ """MCP connection using Server-Sent Events."""
90
+
91
+ def __init__(self, url: str, headers: dict[str, str] = None):
92
+ super().__init__()
93
+ self.url = url
94
+ self.headers = headers or {}
95
+
96
+ def _create_context(self):
97
+ return sse_client(url=self.url, headers=self.headers)
98
+
99
+
100
+ class MCPConnectionHTTP(MCPConnection):
101
+ """MCP connection using Streamable HTTP."""
102
+
103
+ def __init__(self, url: str, headers: dict[str, str] = None):
104
+ super().__init__()
105
+ self.url = url
106
+ self.headers = headers or {}
107
+
108
+ def _create_context(self):
109
+ return streamablehttp_client(url=self.url, headers=self.headers)
110
+
111
+
112
+ def create_connection(
113
+ transport: str,
114
+ command: str = None,
115
+ args: list[str] = None,
116
+ env: dict[str, str] = None,
117
+ url: str = None,
118
+ headers: dict[str, str] = None,
119
+ ) -> MCPConnection:
120
+ """Factory function to create the appropriate MCP connection.
121
+
122
+ Args:
123
+ transport: Connection type ("stdio", "sse", or "http")
124
+ command: Command to run (stdio only)
125
+ args: Command arguments (stdio only)
126
+ env: Environment variables (stdio only)
127
+ url: Server URL (sse and http only)
128
+ headers: HTTP headers (sse and http only)
129
+
130
+ Returns:
131
+ MCPConnection instance
132
+ """
133
+ transport = transport.lower()
134
+
135
+ if transport == "stdio":
136
+ if not command:
137
+ raise ValueError("Command is required for stdio transport")
138
+ return MCPConnectionStdio(command=command, args=args, env=env)
139
+
140
+ elif transport == "sse":
141
+ if not url:
142
+ raise ValueError("URL is required for sse transport")
143
+ return MCPConnectionSSE(url=url, headers=headers)
144
+
145
+ elif transport in ["http", "streamable_http", "streamable-http"]:
146
+ if not url:
147
+ raise ValueError("URL is required for http transport")
148
+ return MCPConnectionHTTP(url=url, headers=headers)
149
+
150
+ else:
151
+ raise ValueError(f"Unsupported transport type: {transport}. Use 'stdio', 'sse', or 'http'")