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,103 @@
1
+ """
2
+ Modelos de dados do Context Agent.
3
+ Dataclasses puras sem dependências externas.
4
+ """
5
+
6
+ from dataclasses import dataclass, field
7
+ from datetime import datetime
8
+ from typing import Optional
9
+
10
+
11
+ @dataclass
12
+ class SessionEntry:
13
+ """Uma entrada individual do log JSONL do Claude Code."""
14
+ type: str # "user" | "assistant" | "queue-operation"
15
+ timestamp: str # ISO 8601
16
+ session_id: str
17
+ slug: str = ""
18
+ role: str = "" # "user" | "assistant"
19
+ content: str = "" # Texto da mensagem
20
+ tool_calls: list = field(default_factory=list) # [{name, input}]
21
+ token_usage: dict = field(default_factory=dict) # {input, output, cache_read}
22
+ model: str = ""
23
+ files_modified: list = field(default_factory=list)
24
+
25
+
26
+ @dataclass
27
+ class PendingTask:
28
+ """Tarefa pendente identificada em uma sessão."""
29
+ description: str
30
+ priority: str = "medium" # "high" | "medium" | "low"
31
+ source_session: int = 0 # Número da sessão onde foi criada
32
+ created_date: str = ""
33
+ context: str = "" # Contexto adicional sobre a tarefa
34
+ completed: bool = False
35
+
36
+
37
+ @dataclass
38
+ class ProjectInfo:
39
+ """Informações de um projeto/skill rastreado."""
40
+ name: str
41
+ path: str = ""
42
+ status: str = "active" # "active" | "paused" | "completed"
43
+ last_touched: str = "" # Data da última interação
44
+ last_session: int = 0 # Número da última sessão
45
+ next_actions: list = field(default_factory=list)
46
+ dependencies: list = field(default_factory=list)
47
+
48
+
49
+ @dataclass
50
+ class SessionSummary:
51
+ """Resumo estruturado de uma sessão do Claude Code."""
52
+ session_number: int
53
+ session_id: str = ""
54
+ slug: str = ""
55
+ date: str = "" # YYYY-MM-DD
56
+ start_time: str = "" # HH:MM
57
+ end_time: str = "" # HH:MM
58
+ duration_minutes: int = 0
59
+ model: str = ""
60
+
61
+ # Conteúdo
62
+ topics: list = field(default_factory=list)
63
+ decisions: list = field(default_factory=list)
64
+ tasks_completed: list = field(default_factory=list)
65
+ tasks_pending: list = field(default_factory=list) # list[PendingTask]
66
+ files_modified: list = field(default_factory=list) # list[{path, action}]
67
+ key_findings: list = field(default_factory=list)
68
+ errors_resolved: list = field(default_factory=list) # list[{error, solution}]
69
+ open_questions: list = field(default_factory=list)
70
+ technical_debt: list = field(default_factory=list)
71
+
72
+ # Métricas
73
+ total_input_tokens: int = 0
74
+ total_output_tokens: int = 0
75
+ total_cache_tokens: int = 0
76
+ message_count: int = 0
77
+ tool_call_count: int = 0
78
+
79
+ # Projetos tocados nesta sessão
80
+ projects_touched: list = field(default_factory=list)
81
+
82
+
83
+ @dataclass
84
+ class ActiveContext:
85
+ """Contexto ativo consolidado de todas as sessões."""
86
+ last_updated: str = ""
87
+ projects: list = field(default_factory=list) # list[ProjectInfo]
88
+ pending_tasks: list = field(default_factory=list) # list[PendingTask]
89
+ recent_decisions: list = field(default_factory=list) # list[{session, text}]
90
+ active_blockers: list = field(default_factory=list)
91
+ conventions: list = field(default_factory=list)
92
+ recent_sessions: list = field(default_factory=list) # list[{number, summary}]
93
+ total_sessions: int = 0
94
+
95
+
96
+ @dataclass
97
+ class SearchResult:
98
+ """Resultado de busca no histórico de sessões."""
99
+ session_number: int
100
+ date: str
101
+ snippet: str
102
+ section: str # Em qual seção foi encontrado
103
+ relevance: float = 0.0
@@ -0,0 +1,132 @@
1
+ """
2
+ Registro e tracking de projetos/skills.
3
+ Mantém PROJECT_REGISTRY.md atualizado.
4
+ """
5
+
6
+ import re
7
+ from datetime import datetime
8
+ from pathlib import Path
9
+
10
+ from config import (
11
+ PROJECT_REGISTRY_PATH,
12
+ SKILLS_ROOT,
13
+ KNOWN_PROJECTS,
14
+ )
15
+ from models import ProjectInfo
16
+
17
+
18
+ def load_registry() -> list[ProjectInfo]:
19
+ """Carrega projetos do PROJECT_REGISTRY.md."""
20
+ if not PROJECT_REGISTRY_PATH.exists():
21
+ return _discover_projects()
22
+
23
+ text = PROJECT_REGISTRY_PATH.read_text(encoding="utf-8")
24
+ projects = []
25
+ in_table = False
26
+
27
+ for line in text.splitlines():
28
+ if line.startswith("|") and "Projeto" in line:
29
+ in_table = True
30
+ continue
31
+ if in_table and line.startswith("|---"):
32
+ continue
33
+ if in_table and line.startswith("|"):
34
+ cells = [c.strip() for c in line.split("|")[1:-1]]
35
+ if len(cells) >= 4:
36
+ projects.append(ProjectInfo(
37
+ name=cells[0],
38
+ path=cells[1] if len(cells) > 4 else "",
39
+ status=cells[2] if len(cells) > 4 else cells[1],
40
+ last_touched=cells[3] if len(cells) > 4 else cells[2],
41
+ last_session=_extract_session_number(cells[-1]) if cells[-1] else 0,
42
+ next_actions=[a.strip() for a in (cells[4] if len(cells) > 4 else cells[3]).split(";") if a.strip()],
43
+ ))
44
+ elif in_table and not line.strip():
45
+ in_table = False
46
+
47
+ return projects if projects else _discover_projects()
48
+
49
+
50
+ def _extract_session_number(text: str) -> int:
51
+ """Extrai número de sessão de texto como 'session-005'."""
52
+ m = re.search(r"session-(\d+)", text)
53
+ return int(m.group(1)) if m else 0
54
+
55
+
56
+ def _discover_projects() -> list[ProjectInfo]:
57
+ """Auto-detecta projetos a partir da estrutura de diretórios."""
58
+ projects = []
59
+ for name, display_name in KNOWN_PROJECTS.items():
60
+ project_path = SKILLS_ROOT / name
61
+ if project_path.exists() and project_path.is_dir():
62
+ projects.append(ProjectInfo(
63
+ name=display_name,
64
+ path=str(project_path),
65
+ status="active",
66
+ last_touched=datetime.now().strftime("%Y-%m-%d"),
67
+ ))
68
+ return projects
69
+
70
+
71
+ def detect_projects_from_session(files_modified: list[dict], tool_calls: list[dict]) -> list[str]:
72
+ """Detecta quais projetos foram tocados numa sessão via paths."""
73
+ touched = set()
74
+
75
+ # Verificar arquivos modificados
76
+ all_paths = [f.get("path", "") for f in files_modified]
77
+
78
+ # Verificar tool_calls com file_path
79
+ for tc in tool_calls:
80
+ inp = tc.get("input", {})
81
+ if isinstance(inp, dict):
82
+ fp = inp.get("file_path", "") or inp.get("path", "")
83
+ if fp:
84
+ all_paths.append(fp)
85
+
86
+ skills_root_str = str(SKILLS_ROOT).replace("\\", "/").lower()
87
+ for p in all_paths:
88
+ p_norm = p.replace("\\", "/").lower()
89
+ if skills_root_str in p_norm:
90
+ relative = p_norm.split(skills_root_str)[-1].lstrip("/")
91
+ top_dir = relative.split("/")[0] if "/" in relative else relative
92
+ if top_dir in KNOWN_PROJECTS:
93
+ touched.add(KNOWN_PROJECTS[top_dir])
94
+
95
+ return list(touched)
96
+
97
+
98
+ def update_project(projects: list[ProjectInfo], name: str, **fields) -> list[ProjectInfo]:
99
+ """Atualiza campos de um projeto existente ou cria novo."""
100
+ for p in projects:
101
+ if p.name == name:
102
+ for k, v in fields.items():
103
+ if hasattr(p, k):
104
+ setattr(p, k, v)
105
+ return projects
106
+
107
+ # Projeto novo
108
+ new_project = ProjectInfo(name=name, **fields)
109
+ projects.append(new_project)
110
+ return projects
111
+
112
+
113
+ def save_registry(projects: list[ProjectInfo]):
114
+ """Salva PROJECT_REGISTRY.md."""
115
+ PROJECT_REGISTRY_PATH.parent.mkdir(parents=True, exist_ok=True)
116
+ now = datetime.now().strftime("%Y-%m-%d %H:%M")
117
+
118
+ lines = [
119
+ f"# Registro de Projetos — Atualizado em {now}",
120
+ "",
121
+ "| Projeto | Status | Última Interação | Próximas Ações |",
122
+ "|---------|--------|------------------|----------------|",
123
+ ]
124
+ for p in projects:
125
+ actions = "; ".join(p.next_actions) if p.next_actions else "—"
126
+ session_ref = f"session-{p.last_session:03d}" if p.last_session else "—"
127
+ lines.append(
128
+ f"| {p.name} | {p.status} | {p.last_touched} ({session_ref}) | {actions} |"
129
+ )
130
+
131
+ lines.append("")
132
+ PROJECT_REGISTRY_PATH.write_text("\n".join(lines), encoding="utf-8")
@@ -0,0 +1,6 @@
1
+ # Context Agent — Zero dependências externas
2
+ # Usa apenas stdlib Python:
3
+ # - json, sqlite3, pathlib, dataclasses
4
+ # - argparse, datetime, re, shutil, sys
5
+ #
6
+ # Nenhum pip install necessário.
@@ -0,0 +1,115 @@
1
+ """
2
+ Busca full-text via SQLite FTS5 no histórico de sessões.
3
+ """
4
+
5
+ import sqlite3
6
+ from pathlib import Path
7
+
8
+ from config import DB_PATH, MAX_SEARCH_RESULTS
9
+ from models import SearchResult
10
+
11
+
12
+ def _get_connection() -> sqlite3.Connection:
13
+ """Retorna conexão SQLite com FTS5."""
14
+ DB_PATH.parent.mkdir(parents=True, exist_ok=True)
15
+ conn = sqlite3.connect(str(DB_PATH))
16
+ conn.execute("PRAGMA journal_mode=WAL")
17
+ return conn
18
+
19
+
20
+ def init_search_db():
21
+ """Cria tabela FTS5 se não existir."""
22
+ conn = _get_connection()
23
+ conn.execute("""
24
+ CREATE VIRTUAL TABLE IF NOT EXISTS session_search USING fts5(
25
+ session_number,
26
+ date,
27
+ section,
28
+ content,
29
+ tokenize='unicode61'
30
+ )
31
+ """)
32
+ conn.commit()
33
+ conn.close()
34
+
35
+
36
+ def index_session(session_number: int, date: str, sections: dict[str, str]):
37
+ """
38
+ Indexa conteúdo de uma sessão.
39
+ sections: {"topics": "texto", "decisions": "texto", ...}
40
+ """
41
+ conn = _get_connection()
42
+ # Remove entradas antigas da mesma sessão
43
+ conn.execute(
44
+ "DELETE FROM session_search WHERE session_number = ?",
45
+ (str(session_number),),
46
+ )
47
+ for section_name, content in sections.items():
48
+ if content.strip():
49
+ conn.execute(
50
+ "INSERT INTO session_search (session_number, date, section, content) VALUES (?, ?, ?, ?)",
51
+ (str(session_number), date, section_name, content),
52
+ )
53
+ conn.commit()
54
+ conn.close()
55
+
56
+
57
+ def search(query: str, limit: int = MAX_SEARCH_RESULTS) -> list[SearchResult]:
58
+ """Busca full-text no histórico."""
59
+ conn = _get_connection()
60
+ try:
61
+ rows = conn.execute(
62
+ """
63
+ SELECT session_number, date, section, snippet(session_search, 3, '>>>', '<<<', '...', 40)
64
+ FROM session_search
65
+ WHERE session_search MATCH ?
66
+ ORDER BY rank
67
+ LIMIT ?
68
+ """,
69
+ (query, limit),
70
+ ).fetchall()
71
+ except sqlite3.OperationalError:
72
+ # Tabela não existe ou query inválida
73
+ return []
74
+ finally:
75
+ conn.close()
76
+
77
+ results = []
78
+ for row in rows:
79
+ results.append(SearchResult(
80
+ session_number=int(row[0]),
81
+ date=row[1],
82
+ section=row[2],
83
+ snippet=row[3],
84
+ ))
85
+ return results
86
+
87
+
88
+ def reindex_all(sessions_dir: Path):
89
+ """Reconstrói índice a partir dos arquivos de sessão."""
90
+ conn = _get_connection()
91
+ conn.execute("DELETE FROM session_search")
92
+ conn.commit()
93
+ conn.close()
94
+
95
+ for session_file in sorted(sessions_dir.glob("session-*.md")):
96
+ try:
97
+ num = int(session_file.stem.split("-")[1])
98
+ except (IndexError, ValueError):
99
+ continue
100
+
101
+ text = session_file.read_text(encoding="utf-8")
102
+ date = ""
103
+ sections = {}
104
+ current_section = "general"
105
+
106
+ for line in text.splitlines():
107
+ if line.startswith("# Sessão") and "—" in line:
108
+ date = line.split("—")[-1].strip()
109
+ elif line.startswith("## "):
110
+ current_section = line[3:].strip().lower()
111
+ else:
112
+ sections.setdefault(current_section, "")
113
+ sections[current_section] += line + "\n"
114
+
115
+ index_session(num, date, sections)
@@ -0,0 +1,206 @@
1
+ """
2
+ Parser dos logs JSONL do Claude Code.
3
+ Lê arquivos de sessão e extrai informações estruturadas.
4
+ """
5
+
6
+ import json
7
+ from pathlib import Path
8
+ from datetime import datetime
9
+ from typing import Optional
10
+
11
+ from config import CLAUDE_SESSION_DIR, FILE_MODIFYING_TOOLS
12
+ from models import SessionEntry
13
+
14
+
15
+ def parse_session_file(path: Path) -> list[SessionEntry]:
16
+ """Lê um arquivo JSONL e retorna lista de SessionEntry."""
17
+ entries = []
18
+ with open(path, "r", encoding="utf-8") as f:
19
+ for line in f:
20
+ line = line.strip()
21
+ if not line:
22
+ continue
23
+ try:
24
+ raw = json.loads(line)
25
+ entry = _parse_raw_entry(raw)
26
+ if entry:
27
+ entries.append(entry)
28
+ except json.JSONDecodeError:
29
+ continue
30
+ return entries
31
+
32
+
33
+ def _parse_raw_entry(raw: dict) -> Optional[SessionEntry]:
34
+ """Converte um dict JSON bruto em SessionEntry."""
35
+ entry_type = raw.get("type", "")
36
+
37
+ if entry_type == "queue-operation":
38
+ return SessionEntry(
39
+ type="queue",
40
+ timestamp=raw.get("timestamp", ""),
41
+ session_id=raw.get("sessionId", ""),
42
+ content=raw.get("content", ""),
43
+ )
44
+
45
+ if entry_type not in ("user", "assistant"):
46
+ return None
47
+
48
+ msg = raw.get("message", {})
49
+ role = msg.get("role", "")
50
+ slug = raw.get("slug", "")
51
+ session_id = raw.get("sessionId", "")
52
+ timestamp = raw.get("timestamp", "")
53
+
54
+ # Extrair texto e tool_calls do content
55
+ text_parts = []
56
+ tool_calls = []
57
+ files_modified = []
58
+ model = msg.get("model", "")
59
+
60
+ content = msg.get("content", "")
61
+ if isinstance(content, str):
62
+ text_parts.append(content)
63
+ elif isinstance(content, list):
64
+ for block in content:
65
+ if not isinstance(block, dict):
66
+ continue
67
+ block_type = block.get("type", "")
68
+ if block_type == "text":
69
+ text_parts.append(block.get("text", ""))
70
+ elif block_type == "tool_use":
71
+ tool_name = block.get("name", "")
72
+ tool_input = block.get("input", {})
73
+ tool_calls.append({"name": tool_name, "input": tool_input})
74
+ # Detectar arquivos modificados
75
+ if tool_name in FILE_MODIFYING_TOOLS:
76
+ fp = tool_input.get("file_path", "")
77
+ if fp:
78
+ files_modified.append({"path": fp, "action": tool_name.lower()})
79
+ elif block_type == "tool_result":
80
+ # Resultados de ferramentas (em mensagens do user)
81
+ result_content = block.get("content", "")
82
+ if isinstance(result_content, list):
83
+ for rc in result_content:
84
+ if isinstance(rc, dict) and rc.get("type") == "text":
85
+ text_parts.append(rc.get("text", ""))
86
+ elif isinstance(result_content, str):
87
+ text_parts.append(result_content)
88
+
89
+ # Token usage
90
+ usage = msg.get("usage", {})
91
+ token_usage = {}
92
+ if usage:
93
+ token_usage = {
94
+ "input": usage.get("input_tokens", 0),
95
+ "output": usage.get("output_tokens", 0),
96
+ "cache_read": usage.get("cache_read_input_tokens", 0),
97
+ "cache_creation": usage.get("cache_creation_input_tokens", 0),
98
+ }
99
+
100
+ return SessionEntry(
101
+ type=entry_type,
102
+ timestamp=timestamp,
103
+ session_id=session_id,
104
+ slug=slug,
105
+ role=role,
106
+ content="\n".join(text_parts),
107
+ tool_calls=tool_calls,
108
+ token_usage=token_usage,
109
+ model=model,
110
+ files_modified=files_modified,
111
+ )
112
+
113
+
114
+ def extract_user_messages(entries: list[SessionEntry]) -> list[str]:
115
+ """Extrai apenas o texto das mensagens do usuário."""
116
+ return [e.content for e in entries if e.role == "user" and e.content.strip()]
117
+
118
+
119
+ def extract_assistant_messages(entries: list[SessionEntry]) -> list[str]:
120
+ """Extrai apenas o texto das respostas do assistente."""
121
+ return [e.content for e in entries if e.role == "assistant" and e.content.strip()]
122
+
123
+
124
+ def extract_tool_calls(entries: list[SessionEntry]) -> list[dict]:
125
+ """Extrai todas as chamadas de ferramentas."""
126
+ calls = []
127
+ for e in entries:
128
+ calls.extend(e.tool_calls)
129
+ return calls
130
+
131
+
132
+ def extract_files_modified(entries: list[SessionEntry]) -> list[dict]:
133
+ """Extrai lista de arquivos modificados (sem duplicatas)."""
134
+ seen = set()
135
+ files = []
136
+ for e in entries:
137
+ for f in e.files_modified:
138
+ key = f["path"]
139
+ if key not in seen:
140
+ seen.add(key)
141
+ files.append(f)
142
+ return files
143
+
144
+
145
+ def get_session_metadata(entries: list[SessionEntry]) -> dict:
146
+ """Extrai metadados da sessão: slug, timestamps, modelo, tokens."""
147
+ if not entries:
148
+ return {}
149
+
150
+ timestamps = [e.timestamp for e in entries if e.timestamp]
151
+ slugs = [e.slug for e in entries if e.slug]
152
+ models = [e.model for e in entries if e.model]
153
+
154
+ total_input = sum(e.token_usage.get("input", 0) for e in entries)
155
+ total_output = sum(e.token_usage.get("output", 0) for e in entries)
156
+ total_cache = sum(e.token_usage.get("cache_read", 0) for e in entries)
157
+
158
+ user_msgs = [e for e in entries if e.role == "user"]
159
+ assistant_msgs = [e for e in entries if e.role == "assistant"]
160
+
161
+ # Calcular duração
162
+ duration_minutes = 0
163
+ if len(timestamps) >= 2:
164
+ try:
165
+ t_start = datetime.fromisoformat(timestamps[0].replace("Z", "+00:00"))
166
+ t_end = datetime.fromisoformat(timestamps[-1].replace("Z", "+00:00"))
167
+ duration_minutes = int((t_end - t_start).total_seconds() / 60)
168
+ except (ValueError, IndexError):
169
+ pass
170
+
171
+ return {
172
+ "slug": slugs[0] if slugs else "",
173
+ "session_id": entries[0].session_id if entries else "",
174
+ "start_time": timestamps[0] if timestamps else "",
175
+ "end_time": timestamps[-1] if timestamps else "",
176
+ "duration_minutes": duration_minutes,
177
+ "model": models[0] if models else "",
178
+ "total_input_tokens": total_input,
179
+ "total_output_tokens": total_output,
180
+ "total_cache_tokens": total_cache,
181
+ "message_count": len(user_msgs) + len(assistant_msgs),
182
+ "tool_call_count": sum(len(e.tool_calls) for e in entries),
183
+ }
184
+
185
+
186
+ def get_latest_session_file() -> Optional[Path]:
187
+ """Encontra o arquivo JSONL mais recente."""
188
+ if not CLAUDE_SESSION_DIR.exists():
189
+ return None
190
+ jsonl_files = sorted(
191
+ CLAUDE_SESSION_DIR.glob("*.jsonl"),
192
+ key=lambda p: p.stat().st_mtime,
193
+ reverse=True,
194
+ )
195
+ return jsonl_files[0] if jsonl_files else None
196
+
197
+
198
+ def get_all_session_files() -> list[Path]:
199
+ """Retorna todos os arquivos JSONL ordenados por data de modificação."""
200
+ if not CLAUDE_SESSION_DIR.exists():
201
+ return []
202
+ return sorted(
203
+ CLAUDE_SESSION_DIR.glob("*.jsonl"),
204
+ key=lambda p: p.stat().st_mtime,
205
+ reverse=True,
206
+ )