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,81 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ NotebookLM Skill Scripts Package
4
+ Provides automatic environment management for all scripts
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import subprocess
10
+ from pathlib import Path
11
+
12
+
13
+ def ensure_venv_and_run():
14
+ """
15
+ Ensure virtual environment exists and run the requested script.
16
+ This is called when any script is imported or run directly.
17
+ """
18
+ # Only do this if we're not already in the skill's venv
19
+ skill_dir = Path(__file__).parent.parent
20
+ venv_dir = skill_dir / ".venv"
21
+
22
+ # Check if we're in a venv
23
+ in_venv = hasattr(sys, 'real_prefix') or (
24
+ hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix
25
+ )
26
+
27
+ # Check if it's OUR venv
28
+ if in_venv:
29
+ venv_path = Path(sys.prefix)
30
+ if venv_path == venv_dir:
31
+ # We're already in the correct venv
32
+ return
33
+
34
+ # We need to set up or switch to our venv
35
+ if not venv_dir.exists():
36
+ print("šŸ”§ First-time setup detected...")
37
+ print(" Creating isolated environment for NotebookLM skill...")
38
+ print(" This ensures clean dependency management...")
39
+
40
+ # Create venv
41
+ import venv
42
+ venv.create(venv_dir, with_pip=True)
43
+
44
+ # Install requirements
45
+ requirements_file = skill_dir / "requirements.txt"
46
+ if requirements_file.exists():
47
+ if os.name == 'nt': # Windows
48
+ pip_exe = venv_dir / "Scripts" / "pip.exe"
49
+ else:
50
+ pip_exe = venv_dir / "bin" / "pip"
51
+
52
+ print(" Installing dependencies in isolated environment...")
53
+ subprocess.run(
54
+ [str(pip_exe), "install", "-q", "-r", str(requirements_file)],
55
+ check=True
56
+ )
57
+
58
+ # Also install patchright's chromium
59
+ print(" Setting up browser automation...")
60
+ if os.name == 'nt':
61
+ python_exe = venv_dir / "Scripts" / "python.exe"
62
+ else:
63
+ python_exe = venv_dir / "bin" / "python"
64
+
65
+ subprocess.run(
66
+ [str(python_exe), "-m", "patchright", "install", "chromium"],
67
+ check=True,
68
+ capture_output=True
69
+ )
70
+
71
+ print("āœ… Environment ready! All dependencies isolated in .venv/")
72
+
73
+ # If we're here and not in the venv, we should recommend using the venv
74
+ if not in_venv:
75
+ print("\nāš ļø Running outside virtual environment")
76
+ print(" Recommended: Use scripts/run.py to ensure clean execution")
77
+ print(" Or activate: source .venv/bin/activate")
78
+
79
+
80
+ # Check environment when module is imported
81
+ ensure_venv_and_run()
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Simple NotebookLM Question Interface
4
+ Based on MCP server implementation - simplified without sessions
5
+
6
+ Implements hybrid auth approach:
7
+ - Persistent browser profile (user_data_dir) for fingerprint consistency
8
+ - Manual cookie injection from state.json for session cookies (Playwright bug workaround)
9
+ See: https://github.com/microsoft/playwright/issues/36139
10
+ """
11
+
12
+ import argparse
13
+ import sys
14
+ import time
15
+ import re
16
+ from pathlib import Path
17
+
18
+ from patchright.sync_api import sync_playwright
19
+
20
+ # Add parent directory to path
21
+ sys.path.insert(0, str(Path(__file__).parent))
22
+
23
+ from auth_manager import AuthManager
24
+ from notebook_manager import NotebookLibrary
25
+ from config import QUERY_INPUT_SELECTORS, RESPONSE_SELECTORS
26
+ from browser_utils import BrowserFactory, StealthUtils
27
+
28
+
29
+ # Follow-up reminder (adapted from MCP server for stateless operation)
30
+ # Since we don't have persistent sessions, we encourage comprehensive questions
31
+ FOLLOW_UP_REMINDER = (
32
+ "\n\nEXTREMELY IMPORTANT: Is that ALL you need to know? "
33
+ "You can always ask another question! Think about it carefully: "
34
+ "before you reply to the user, review their original request and this answer. "
35
+ "If anything is still unclear or missing, ask me another comprehensive question "
36
+ "that includes all necessary context (since each question opens a new browser session)."
37
+ )
38
+
39
+
40
+ def ask_notebooklm(question: str, notebook_url: str, headless: bool = True) -> str:
41
+ """
42
+ Ask a question to NotebookLM
43
+
44
+ Args:
45
+ question: Question to ask
46
+ notebook_url: NotebookLM notebook URL
47
+ headless: Run browser in headless mode
48
+
49
+ Returns:
50
+ Answer text from NotebookLM
51
+ """
52
+ auth = AuthManager()
53
+
54
+ if not auth.is_authenticated():
55
+ print("āš ļø Not authenticated. Run: python auth_manager.py setup")
56
+ return None
57
+
58
+ print(f"šŸ’¬ Asking: {question}")
59
+ print(f"šŸ“š Notebook: {notebook_url}")
60
+
61
+ playwright = None
62
+ context = None
63
+
64
+ try:
65
+ # Start playwright
66
+ playwright = sync_playwright().start()
67
+
68
+ # Launch persistent browser context using factory
69
+ context = BrowserFactory.launch_persistent_context(
70
+ playwright,
71
+ headless=headless
72
+ )
73
+
74
+ # Navigate to notebook
75
+ page = context.new_page()
76
+ print(" 🌐 Opening notebook...")
77
+ page.goto(notebook_url, wait_until="domcontentloaded")
78
+
79
+ # Wait for NotebookLM
80
+ page.wait_for_url(re.compile(r"^https://notebooklm\.google\.com/"), timeout=10000)
81
+
82
+ # Wait for query input (MCP approach)
83
+ print(" ā³ Waiting for query input...")
84
+ query_element = None
85
+
86
+ for selector in QUERY_INPUT_SELECTORS:
87
+ try:
88
+ query_element = page.wait_for_selector(
89
+ selector,
90
+ timeout=10000,
91
+ state="visible" # Only check visibility, not disabled!
92
+ )
93
+ if query_element:
94
+ print(f" āœ“ Found input: {selector}")
95
+ break
96
+ except:
97
+ continue
98
+
99
+ if not query_element:
100
+ print(" āŒ Could not find query input")
101
+ return None
102
+
103
+ # Type question (human-like, fast)
104
+ print(" ā³ Typing question...")
105
+
106
+ # Use primary selector for typing
107
+ input_selector = QUERY_INPUT_SELECTORS[0]
108
+ StealthUtils.human_type(page, input_selector, question)
109
+
110
+ # Submit
111
+ print(" šŸ“¤ Submitting...")
112
+ page.keyboard.press("Enter")
113
+
114
+ # Small pause
115
+ StealthUtils.random_delay(500, 1500)
116
+
117
+ # Wait for response (MCP approach: poll for stable text)
118
+ print(" ā³ Waiting for answer...")
119
+
120
+ answer = None
121
+ stable_count = 0
122
+ last_text = None
123
+ deadline = time.time() + 120 # 2 minutes timeout
124
+
125
+ while time.time() < deadline:
126
+ # Check if NotebookLM is still thinking (most reliable indicator)
127
+ try:
128
+ thinking_element = page.query_selector('div.thinking-message')
129
+ if thinking_element and thinking_element.is_visible():
130
+ time.sleep(1)
131
+ continue
132
+ except:
133
+ pass
134
+
135
+ # Try to find response with MCP selectors
136
+ for selector in RESPONSE_SELECTORS:
137
+ try:
138
+ elements = page.query_selector_all(selector)
139
+ if elements:
140
+ # Get last (newest) response
141
+ latest = elements[-1]
142
+ text = latest.inner_text().strip()
143
+
144
+ if text:
145
+ if text == last_text:
146
+ stable_count += 1
147
+ if stable_count >= 3: # Stable for 3 polls
148
+ answer = text
149
+ break
150
+ else:
151
+ stable_count = 0
152
+ last_text = text
153
+ except:
154
+ continue
155
+
156
+ if answer:
157
+ break
158
+
159
+ time.sleep(1)
160
+
161
+ if not answer:
162
+ print(" āŒ Timeout waiting for answer")
163
+ return None
164
+
165
+ print(" āœ… Got answer!")
166
+ # Add follow-up reminder to encourage Claude to ask more questions
167
+ return answer + FOLLOW_UP_REMINDER
168
+
169
+ except Exception as e:
170
+ print(f" āŒ Error: {e}")
171
+ import traceback
172
+ traceback.print_exc()
173
+ return None
174
+
175
+ finally:
176
+ # Always clean up
177
+ if context:
178
+ try:
179
+ context.close()
180
+ except:
181
+ pass
182
+
183
+ if playwright:
184
+ try:
185
+ playwright.stop()
186
+ except:
187
+ pass
188
+
189
+
190
+ def main():
191
+ parser = argparse.ArgumentParser(description='Ask NotebookLM a question')
192
+
193
+ parser.add_argument('--question', required=True, help='Question to ask')
194
+ parser.add_argument('--notebook-url', help='NotebookLM notebook URL')
195
+ parser.add_argument('--notebook-id', help='Notebook ID from library')
196
+ parser.add_argument('--show-browser', action='store_true', help='Show browser')
197
+
198
+ args = parser.parse_args()
199
+
200
+ # Resolve notebook URL
201
+ notebook_url = args.notebook_url
202
+
203
+ if not notebook_url and args.notebook_id:
204
+ library = NotebookLibrary()
205
+ notebook = library.get_notebook(args.notebook_id)
206
+ if notebook:
207
+ notebook_url = notebook['url']
208
+ else:
209
+ print(f"āŒ Notebook '{args.notebook_id}' not found")
210
+ return 1
211
+
212
+ if not notebook_url:
213
+ # Check for active notebook first
214
+ library = NotebookLibrary()
215
+ active = library.get_active_notebook()
216
+ if active:
217
+ notebook_url = active['url']
218
+ print(f"šŸ“š Using active notebook: {active['name']}")
219
+ else:
220
+ # Show available notebooks
221
+ notebooks = library.list_notebooks()
222
+ if notebooks:
223
+ print("\nšŸ“š Available notebooks:")
224
+ for nb in notebooks:
225
+ mark = " [ACTIVE]" if nb.get('id') == library.active_notebook_id else ""
226
+ print(f" {nb['id']}: {nb['name']}{mark}")
227
+ print("\nSpecify with --notebook-id or set active:")
228
+ print("python scripts/run.py notebook_manager.py activate --id ID")
229
+ else:
230
+ print("āŒ No notebooks in library. Add one first:")
231
+ print("python scripts/run.py notebook_manager.py add --url URL --name NAME --description DESC --topics TOPICS")
232
+ return 1
233
+
234
+ # Ask the question
235
+ answer = ask_notebooklm(
236
+ question=args.question,
237
+ notebook_url=notebook_url,
238
+ headless=not args.show_browser
239
+ )
240
+
241
+ if answer:
242
+ print("\n" + "=" * 60)
243
+ print(f"Question: {args.question}")
244
+ print("=" * 60)
245
+ print()
246
+ print(answer)
247
+ print()
248
+ print("=" * 60)
249
+ return 0
250
+ else:
251
+ print("\nāŒ Failed to get answer")
252
+ return 1
253
+
254
+
255
+ if __name__ == "__main__":
256
+ sys.exit(main())
@@ -0,0 +1,358 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Authentication Manager for NotebookLM
4
+ Handles Google login and browser state persistence
5
+ Based on the MCP server implementation
6
+
7
+ Implements hybrid auth approach:
8
+ - Persistent browser profile (user_data_dir) for fingerprint consistency
9
+ - Manual cookie injection from state.json for session cookies (Playwright bug workaround)
10
+ See: https://github.com/microsoft/playwright/issues/36139
11
+ """
12
+
13
+ import json
14
+ import time
15
+ import argparse
16
+ import shutil
17
+ import re
18
+ import sys
19
+ from pathlib import Path
20
+ from typing import Optional, Dict, Any
21
+
22
+ from patchright.sync_api import sync_playwright, BrowserContext
23
+
24
+ # Add parent directory to path
25
+ sys.path.insert(0, str(Path(__file__).parent))
26
+
27
+ from config import BROWSER_STATE_DIR, STATE_FILE, AUTH_INFO_FILE, DATA_DIR
28
+ from browser_utils import BrowserFactory
29
+
30
+
31
+ class AuthManager:
32
+ """
33
+ Manages authentication and browser state for NotebookLM
34
+
35
+ Features:
36
+ - Interactive Google login
37
+ - Browser state persistence
38
+ - Session restoration
39
+ - Account switching
40
+ """
41
+
42
+ def __init__(self):
43
+ """Initialize the authentication manager"""
44
+ # Ensure directories exist
45
+ DATA_DIR.mkdir(parents=True, exist_ok=True)
46
+ BROWSER_STATE_DIR.mkdir(parents=True, exist_ok=True)
47
+
48
+ self.state_file = STATE_FILE
49
+ self.auth_info_file = AUTH_INFO_FILE
50
+ self.browser_state_dir = BROWSER_STATE_DIR
51
+
52
+ def is_authenticated(self) -> bool:
53
+ """Check if valid authentication exists"""
54
+ if not self.state_file.exists():
55
+ return False
56
+
57
+ # Check if state file is not too old (7 days)
58
+ age_days = (time.time() - self.state_file.stat().st_mtime) / 86400
59
+ if age_days > 7:
60
+ print(f"āš ļø Browser state is {age_days:.1f} days old, may need re-authentication")
61
+
62
+ return True
63
+
64
+ def get_auth_info(self) -> Dict[str, Any]:
65
+ """Get authentication information"""
66
+ info = {
67
+ 'authenticated': self.is_authenticated(),
68
+ 'state_file': str(self.state_file),
69
+ 'state_exists': self.state_file.exists()
70
+ }
71
+
72
+ if self.auth_info_file.exists():
73
+ try:
74
+ with open(self.auth_info_file, 'r') as f:
75
+ saved_info = json.load(f)
76
+ info.update(saved_info)
77
+ except Exception:
78
+ pass
79
+
80
+ if info['state_exists']:
81
+ age_hours = (time.time() - self.state_file.stat().st_mtime) / 3600
82
+ info['state_age_hours'] = age_hours
83
+
84
+ return info
85
+
86
+ def setup_auth(self, headless: bool = False, timeout_minutes: int = 10) -> bool:
87
+ """
88
+ Perform interactive authentication setup
89
+
90
+ Args:
91
+ headless: Run browser in headless mode (False for login)
92
+ timeout_minutes: Maximum time to wait for login
93
+
94
+ Returns:
95
+ True if authentication successful
96
+ """
97
+ print("šŸ” Starting authentication setup...")
98
+ print(f" Timeout: {timeout_minutes} minutes")
99
+
100
+ playwright = None
101
+ context = None
102
+
103
+ try:
104
+ playwright = sync_playwright().start()
105
+
106
+ # Launch using factory
107
+ context = BrowserFactory.launch_persistent_context(
108
+ playwright,
109
+ headless=headless
110
+ )
111
+
112
+ # Navigate to NotebookLM
113
+ page = context.new_page()
114
+ page.goto("https://notebooklm.google.com", wait_until="domcontentloaded")
115
+
116
+ # Check if already authenticated
117
+ if "notebooklm.google.com" in page.url and "accounts.google.com" not in page.url:
118
+ print(" āœ… Already authenticated!")
119
+ self._save_browser_state(context)
120
+ return True
121
+
122
+ # Wait for manual login
123
+ print("\n ā³ Please log in to your Google account...")
124
+ print(f" ā±ļø Waiting up to {timeout_minutes} minutes for login...")
125
+
126
+ try:
127
+ # Wait for URL to change to NotebookLM (regex ensures it's the actual domain, not a parameter)
128
+ timeout_ms = int(timeout_minutes * 60 * 1000)
129
+ page.wait_for_url(re.compile(r"^https://notebooklm\.google\.com/"), timeout=timeout_ms)
130
+
131
+ print(f" āœ… Login successful!")
132
+
133
+ # Save authentication state
134
+ self._save_browser_state(context)
135
+ self._save_auth_info()
136
+ return True
137
+
138
+ except Exception as e:
139
+ print(f" āŒ Authentication timeout: {e}")
140
+ return False
141
+
142
+ except Exception as e:
143
+ print(f" āŒ Error: {e}")
144
+ return False
145
+
146
+ finally:
147
+ # Clean up browser resources
148
+ if context:
149
+ try:
150
+ context.close()
151
+ except Exception:
152
+ pass
153
+
154
+ if playwright:
155
+ try:
156
+ playwright.stop()
157
+ except Exception:
158
+ pass
159
+
160
+ def _save_browser_state(self, context: BrowserContext):
161
+ """Save browser state to disk"""
162
+ try:
163
+ # Save storage state (cookies, localStorage)
164
+ context.storage_state(path=str(self.state_file))
165
+ print(f" šŸ’¾ Saved browser state to: {self.state_file}")
166
+ except Exception as e:
167
+ print(f" āŒ Failed to save browser state: {e}")
168
+ raise
169
+
170
+ def _save_auth_info(self):
171
+ """Save authentication metadata"""
172
+ try:
173
+ info = {
174
+ 'authenticated_at': time.time(),
175
+ 'authenticated_at_iso': time.strftime('%Y-%m-%d %H:%M:%S')
176
+ }
177
+ with open(self.auth_info_file, 'w') as f:
178
+ json.dump(info, f, indent=2)
179
+ except Exception:
180
+ pass # Non-critical
181
+
182
+ def clear_auth(self) -> bool:
183
+ """
184
+ Clear all authentication data
185
+
186
+ Returns:
187
+ True if cleared successfully
188
+ """
189
+ print("šŸ—‘ļø Clearing authentication data...")
190
+
191
+ try:
192
+ # Remove browser state
193
+ if self.state_file.exists():
194
+ self.state_file.unlink()
195
+ print(" āœ… Removed browser state")
196
+
197
+ # Remove auth info
198
+ if self.auth_info_file.exists():
199
+ self.auth_info_file.unlink()
200
+ print(" āœ… Removed auth info")
201
+
202
+ # Clear entire browser state directory
203
+ if self.browser_state_dir.exists():
204
+ shutil.rmtree(self.browser_state_dir)
205
+ self.browser_state_dir.mkdir(parents=True, exist_ok=True)
206
+ print(" āœ… Cleared browser data")
207
+
208
+ return True
209
+
210
+ except Exception as e:
211
+ print(f" āŒ Error clearing auth: {e}")
212
+ return False
213
+
214
+ def re_auth(self, headless: bool = False, timeout_minutes: int = 10) -> bool:
215
+ """
216
+ Perform re-authentication (clear and setup)
217
+
218
+ Args:
219
+ headless: Run browser in headless mode
220
+ timeout_minutes: Login timeout in minutes
221
+
222
+ Returns:
223
+ True if successful
224
+ """
225
+ print("šŸ”„ Starting re-authentication...")
226
+
227
+ # Clear existing auth
228
+ self.clear_auth()
229
+
230
+ # Setup new auth
231
+ return self.setup_auth(headless, timeout_minutes)
232
+
233
+ def validate_auth(self) -> bool:
234
+ """
235
+ Validate that stored authentication works
236
+ Uses persistent context to match actual usage pattern
237
+
238
+ Returns:
239
+ True if authentication is valid
240
+ """
241
+ if not self.is_authenticated():
242
+ return False
243
+
244
+ print("šŸ” Validating authentication...")
245
+
246
+ playwright = None
247
+ context = None
248
+
249
+ try:
250
+ playwright = sync_playwright().start()
251
+
252
+ # Launch using factory
253
+ context = BrowserFactory.launch_persistent_context(
254
+ playwright,
255
+ headless=True
256
+ )
257
+
258
+ # Try to access NotebookLM
259
+ page = context.new_page()
260
+ page.goto("https://notebooklm.google.com", wait_until="domcontentloaded", timeout=30000)
261
+
262
+ # Check if we can access NotebookLM
263
+ if "notebooklm.google.com" in page.url and "accounts.google.com" not in page.url:
264
+ print(" āœ… Authentication is valid")
265
+ return True
266
+ else:
267
+ print(" āŒ Authentication is invalid (redirected to login)")
268
+ return False
269
+
270
+ except Exception as e:
271
+ print(f" āŒ Validation failed: {e}")
272
+ return False
273
+
274
+ finally:
275
+ if context:
276
+ try:
277
+ context.close()
278
+ except Exception:
279
+ pass
280
+ if playwright:
281
+ try:
282
+ playwright.stop()
283
+ except Exception:
284
+ pass
285
+
286
+
287
+ def main():
288
+ """Command-line interface for authentication management"""
289
+ parser = argparse.ArgumentParser(description='Manage NotebookLM authentication')
290
+
291
+ subparsers = parser.add_subparsers(dest='command', help='Commands')
292
+
293
+ # Setup command
294
+ setup_parser = subparsers.add_parser('setup', help='Setup authentication')
295
+ setup_parser.add_argument('--headless', action='store_true', help='Run in headless mode')
296
+ setup_parser.add_argument('--timeout', type=float, default=10, help='Login timeout in minutes (default: 10)')
297
+
298
+ # Status command
299
+ subparsers.add_parser('status', help='Check authentication status')
300
+
301
+ # Validate command
302
+ subparsers.add_parser('validate', help='Validate authentication')
303
+
304
+ # Clear command
305
+ subparsers.add_parser('clear', help='Clear authentication')
306
+
307
+ # Re-auth command
308
+ reauth_parser = subparsers.add_parser('reauth', help='Re-authenticate (clear + setup)')
309
+ reauth_parser.add_argument('--timeout', type=float, default=10, help='Login timeout in minutes (default: 10)')
310
+
311
+ args = parser.parse_args()
312
+
313
+ # Initialize manager
314
+ auth = AuthManager()
315
+
316
+ # Execute command
317
+ if args.command == 'setup':
318
+ if auth.setup_auth(headless=args.headless, timeout_minutes=args.timeout):
319
+ print("\nāœ… Authentication setup complete!")
320
+ print("You can now use ask_question.py to query NotebookLM")
321
+ else:
322
+ print("\nāŒ Authentication setup failed")
323
+ exit(1)
324
+
325
+ elif args.command == 'status':
326
+ info = auth.get_auth_info()
327
+ print("\nšŸ” Authentication Status:")
328
+ print(f" Authenticated: {'Yes' if info['authenticated'] else 'No'}")
329
+ if info.get('state_age_hours'):
330
+ print(f" State age: {info['state_age_hours']:.1f} hours")
331
+ if info.get('authenticated_at_iso'):
332
+ print(f" Last auth: {info['authenticated_at_iso']}")
333
+ print(f" State file: {info['state_file']}")
334
+
335
+ elif args.command == 'validate':
336
+ if auth.validate_auth():
337
+ print("Authentication is valid and working")
338
+ else:
339
+ print("Authentication is invalid or expired")
340
+ print("Run: auth_manager.py setup")
341
+
342
+ elif args.command == 'clear':
343
+ if auth.clear_auth():
344
+ print("Authentication cleared")
345
+
346
+ elif args.command == 'reauth':
347
+ if auth.re_auth(timeout_minutes=args.timeout):
348
+ print("\nāœ… Re-authentication complete!")
349
+ else:
350
+ print("\nāŒ Re-authentication failed")
351
+ exit(1)
352
+
353
+ else:
354
+ parser.print_help()
355
+
356
+
357
+ if __name__ == "__main__":
358
+ main()