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.
- package/package.json +1 -1
- package/templates/.agents/agents/backend-specialist.md +263 -0
- package/templates/.agents/agents/code-archaeologist.md +106 -0
- package/templates/.agents/agents/database-architect.md +226 -0
- package/templates/.agents/agents/debugger.md +225 -0
- package/templates/.agents/agents/devops-engineer.md +242 -0
- package/templates/.agents/agents/documentation-writer.md +104 -0
- package/templates/.agents/agents/explorer-agent.md +73 -0
- package/templates/.agents/agents/frontend-specialist.md +593 -0
- package/templates/.agents/agents/game-developer.md +162 -0
- package/templates/.agents/agents/mobile-developer.md +377 -0
- package/templates/.agents/agents/orchestrator.md +416 -0
- package/templates/.agents/agents/penetration-tester.md +188 -0
- package/templates/.agents/agents/performance-optimizer.md +187 -0
- package/templates/.agents/agents/product-manager.md +112 -0
- package/templates/.agents/agents/product-owner.md +95 -0
- package/templates/.agents/agents/project-planner.md +406 -0
- package/templates/.agents/agents/qa-automation-engineer.md +103 -0
- package/templates/.agents/agents/security-auditor.md +170 -0
- package/templates/.agents/agents/seo-specialist.md +111 -0
- package/templates/.agents/agents/test-engineer.md +158 -0
- package/templates/.agents/rules/GEMINI.md +219 -0
- package/templates/.agents/scripts/auto_preview.py +148 -0
- package/templates/.agents/scripts/checklist.py +217 -0
- package/templates/.agents/scripts/session_manager.py +120 -0
- package/templates/.agents/scripts/verify_all.py +327 -0
- package/templates/.agents/workflows/brainstorm.md +113 -0
- package/templates/.agents/workflows/create.md +59 -0
- package/templates/.agents/workflows/debug.md +103 -0
- package/templates/.agents/workflows/deploy.md +176 -0
- package/templates/.agents/workflows/enhance.md +63 -0
- package/templates/.agents/workflows/orchestrate.md +237 -0
- package/templates/.agents/workflows/plan.md +89 -0
- package/templates/.agents/workflows/preview.md +81 -0
- package/templates/.agents/workflows/setup-brain.md +39 -0
- package/templates/.agents/workflows/status.md +86 -0
- package/templates/.agents/workflows/test.md +144 -0
- package/templates/.agents/workflows/ui-ux-pro-max.md +296 -0
- package/templates/skills_normal/api-patterns/scripts/api_validator.py +211 -0
- package/templates/skills_normal/database-design/scripts/schema_validator.py +172 -0
- package/templates/skills_normal/frontend-design/scripts/accessibility_checker.py +183 -0
- package/templates/skills_normal/frontend-design/scripts/ux_audit.py +722 -0
- package/templates/skills_normal/git-pushing/scripts/smart_commit.sh +19 -0
- package/templates/skills_normal/lint-and-validate/scripts/lint_runner.py +184 -0
- package/templates/skills_normal/lint-and-validate/scripts/type_coverage.py +173 -0
- package/templates/skills_normal/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/templates/skills_normal/senior-fullstack/scripts/code_quality_analyzer.py +114 -0
- package/templates/skills_normal/senior-fullstack/scripts/fullstack_scaffolder.py +114 -0
- package/templates/skills_normal/senior-fullstack/scripts/project_scaffolder.py +114 -0
- package/templates/skills_normal/seo-fundamentals/scripts/seo_checker.py +219 -0
- package/templates/skills_normal/testing-patterns/scripts/test_runner.py +219 -0
- package/templates/skills_normal/vulnerability-scanner/scripts/security_scan.py +458 -0
- package/templates/vault/007/scripts/config.py +472 -0
- package/templates/vault/007/scripts/full_audit.py +1306 -0
- package/templates/vault/007/scripts/quick_scan.py +481 -0
- package/templates/vault/007/scripts/requirements.txt +26 -0
- package/templates/vault/007/scripts/scanners/__init__.py +0 -0
- package/templates/vault/007/scripts/scanners/dependency_scanner.py +1305 -0
- package/templates/vault/007/scripts/scanners/injection_scanner.py +1104 -0
- package/templates/vault/007/scripts/scanners/secrets_scanner.py +1008 -0
- package/templates/vault/007/scripts/score_calculator.py +693 -0
- package/templates/vault/agent-orchestrator/scripts/match_skills.py +329 -0
- package/templates/vault/agent-orchestrator/scripts/orchestrate.py +304 -0
- package/templates/vault/agent-orchestrator/scripts/requirements.txt +1 -0
- package/templates/vault/agent-orchestrator/scripts/scan_registry.py +508 -0
- package/templates/vault/ai-studio-image/scripts/config.py +613 -0
- package/templates/vault/ai-studio-image/scripts/generate.py +630 -0
- package/templates/vault/ai-studio-image/scripts/prompt_engine.py +424 -0
- package/templates/vault/ai-studio-image/scripts/requirements.txt +4 -0
- package/templates/vault/ai-studio-image/scripts/templates.py +349 -0
- package/templates/vault/android_ui_verification/scripts/verify_ui.sh +32 -0
- package/templates/vault/apify-audience-analysis/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-brand-reputation-monitoring/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-competitor-intelligence/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-content-analytics/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-ecommerce/reference/scripts/package.json +3 -0
- package/templates/vault/apify-ecommerce/reference/scripts/run_actor.js +369 -0
- package/templates/vault/apify-influencer-discovery/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-lead-generation/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-market-research/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-trend-analysis/reference/scripts/run_actor.js +363 -0
- package/templates/vault/apify-ultimate-scraper/reference/scripts/run_actor.js +363 -0
- package/templates/vault/audio-transcriber/scripts/install-requirements.sh +190 -0
- package/templates/vault/audio-transcriber/scripts/transcribe.py +486 -0
- package/templates/vault/claude-monitor/scripts/api_bench.py +240 -0
- package/templates/vault/claude-monitor/scripts/config.py +69 -0
- package/templates/vault/claude-monitor/scripts/health_check.py +362 -0
- package/templates/vault/claude-monitor/scripts/monitor.py +296 -0
- package/templates/vault/content-creator/scripts/brand_voice_analyzer.py +185 -0
- package/templates/vault/content-creator/scripts/seo_optimizer.py +419 -0
- package/templates/vault/context-agent/scripts/active_context.py +227 -0
- package/templates/vault/context-agent/scripts/compressor.py +149 -0
- package/templates/vault/context-agent/scripts/config.py +69 -0
- package/templates/vault/context-agent/scripts/context_loader.py +155 -0
- package/templates/vault/context-agent/scripts/context_manager.py +302 -0
- package/templates/vault/context-agent/scripts/models.py +103 -0
- package/templates/vault/context-agent/scripts/project_registry.py +132 -0
- package/templates/vault/context-agent/scripts/requirements.txt +6 -0
- package/templates/vault/context-agent/scripts/search.py +115 -0
- package/templates/vault/context-agent/scripts/session_parser.py +206 -0
- package/templates/vault/context-agent/scripts/session_summary.py +319 -0
- package/templates/vault/context-guardian/scripts/context_snapshot.py +229 -0
- package/templates/vault/docx/ooxml/scripts/pack.py +159 -0
- package/templates/vault/docx/ooxml/scripts/unpack.py +29 -0
- package/templates/vault/docx/ooxml/scripts/validate.py +69 -0
- package/templates/vault/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/vault/docx/ooxml/scripts/validation/base.py +951 -0
- package/templates/vault/docx/ooxml/scripts/validation/docx.py +274 -0
- package/templates/vault/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/vault/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/vault/docx/scripts/__init__.py +1 -0
- package/templates/vault/docx/scripts/document.py +1276 -0
- package/templates/vault/docx/scripts/templates/comments.xml +3 -0
- package/templates/vault/docx/scripts/templates/commentsExtended.xml +3 -0
- package/templates/vault/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/templates/vault/docx/scripts/templates/commentsIds.xml +3 -0
- package/templates/vault/docx/scripts/templates/people.xml +3 -0
- package/templates/vault/docx/scripts/utilities.py +374 -0
- package/templates/vault/docx-official/ooxml/scripts/pack.py +159 -0
- package/templates/vault/docx-official/ooxml/scripts/unpack.py +29 -0
- package/templates/vault/docx-official/ooxml/scripts/validate.py +69 -0
- package/templates/vault/docx-official/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/vault/docx-official/ooxml/scripts/validation/base.py +951 -0
- package/templates/vault/docx-official/ooxml/scripts/validation/docx.py +274 -0
- package/templates/vault/docx-official/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/vault/docx-official/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/vault/docx-official/scripts/__init__.py +1 -0
- package/templates/vault/docx-official/scripts/document.py +1276 -0
- package/templates/vault/docx-official/scripts/templates/comments.xml +3 -0
- package/templates/vault/docx-official/scripts/templates/commentsExtended.xml +3 -0
- package/templates/vault/docx-official/scripts/templates/commentsExtensible.xml +3 -0
- package/templates/vault/docx-official/scripts/templates/commentsIds.xml +3 -0
- package/templates/vault/docx-official/scripts/templates/people.xml +3 -0
- package/templates/vault/docx-official/scripts/utilities.py +374 -0
- package/templates/vault/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/templates/vault/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
- package/templates/vault/i18n-localization/scripts/i18n_checker.py +241 -0
- package/templates/vault/instagram/scripts/account_setup.py +233 -0
- package/templates/vault/instagram/scripts/analyze.py +221 -0
- package/templates/vault/instagram/scripts/api_client.py +444 -0
- package/templates/vault/instagram/scripts/auth.py +411 -0
- package/templates/vault/instagram/scripts/comments.py +160 -0
- package/templates/vault/instagram/scripts/config.py +111 -0
- package/templates/vault/instagram/scripts/db.py +467 -0
- package/templates/vault/instagram/scripts/export.py +138 -0
- package/templates/vault/instagram/scripts/governance.py +233 -0
- package/templates/vault/instagram/scripts/hashtags.py +114 -0
- package/templates/vault/instagram/scripts/insights.py +170 -0
- package/templates/vault/instagram/scripts/media.py +65 -0
- package/templates/vault/instagram/scripts/messages.py +103 -0
- package/templates/vault/instagram/scripts/profile.py +58 -0
- package/templates/vault/instagram/scripts/publish.py +449 -0
- package/templates/vault/instagram/scripts/requirements.txt +5 -0
- package/templates/vault/instagram/scripts/run_all.py +189 -0
- package/templates/vault/instagram/scripts/schedule.py +189 -0
- package/templates/vault/instagram/scripts/serve_api.py +234 -0
- package/templates/vault/instagram/scripts/templates.py +155 -0
- package/templates/vault/junta-leiloeiros/scripts/db.py +216 -0
- package/templates/vault/junta-leiloeiros/scripts/export.py +137 -0
- package/templates/vault/junta-leiloeiros/scripts/requirements.txt +15 -0
- package/templates/vault/junta-leiloeiros/scripts/run_all.py +190 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/__init__.py +4 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/base_scraper.py +209 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/generic_scraper.py +110 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucap.py +110 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/juceac.py +72 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/juceal.py +72 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/juceb.py +68 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucec.py +63 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucema.py +211 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucemg.py +218 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucep.py +70 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucepa.py +74 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucepar.py +80 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucepe.py +78 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucepi.py +69 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucer.py +256 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucerja.py +170 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucern.py +71 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucesc.py +89 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucesp.py +233 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucetins.py +134 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucis_df.py +63 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/jucisrs.py +299 -0
- package/templates/vault/junta-leiloeiros/scripts/scraper/states.py +99 -0
- package/templates/vault/junta-leiloeiros/scripts/serve_api.py +164 -0
- package/templates/vault/junta-leiloeiros/scripts/web_scraper_fallback.py +233 -0
- package/templates/vault/last30days/scripts/last30days.py +521 -0
- package/templates/vault/last30days/scripts/lib/__init__.py +1 -0
- package/templates/vault/last30days/scripts/lib/cache.py +152 -0
- package/templates/vault/last30days/scripts/lib/dates.py +124 -0
- package/templates/vault/last30days/scripts/lib/dedupe.py +120 -0
- package/templates/vault/last30days/scripts/lib/env.py +149 -0
- package/templates/vault/last30days/scripts/lib/http.py +152 -0
- package/templates/vault/last30days/scripts/lib/models.py +175 -0
- package/templates/vault/last30days/scripts/lib/normalize.py +160 -0
- package/templates/vault/last30days/scripts/lib/openai_reddit.py +230 -0
- package/templates/vault/last30days/scripts/lib/reddit_enrich.py +232 -0
- package/templates/vault/last30days/scripts/lib/render.py +383 -0
- package/templates/vault/last30days/scripts/lib/schema.py +336 -0
- package/templates/vault/last30days/scripts/lib/score.py +311 -0
- package/templates/vault/last30days/scripts/lib/ui.py +324 -0
- package/templates/vault/last30days/scripts/lib/websearch.py +401 -0
- package/templates/vault/last30days/scripts/lib/xai_x.py +217 -0
- package/templates/vault/leiloeiro-avaliacao/scripts/governance.py +106 -0
- package/templates/vault/leiloeiro-avaliacao/scripts/requirements.txt +1 -0
- package/templates/vault/leiloeiro-edital/scripts/governance.py +106 -0
- package/templates/vault/leiloeiro-edital/scripts/requirements.txt +1 -0
- package/templates/vault/leiloeiro-ia/scripts/governance.py +106 -0
- package/templates/vault/leiloeiro-ia/scripts/requirements.txt +1 -0
- package/templates/vault/leiloeiro-juridico/scripts/governance.py +106 -0
- package/templates/vault/leiloeiro-juridico/scripts/requirements.txt +1 -0
- package/templates/vault/leiloeiro-mercado/scripts/governance.py +106 -0
- package/templates/vault/leiloeiro-mercado/scripts/requirements.txt +1 -0
- package/templates/vault/leiloeiro-risco/scripts/governance.py +106 -0
- package/templates/vault/leiloeiro-risco/scripts/requirements.txt +1 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/database.ts +24 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/db.ts +35 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/index.ts +2 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/migrations.ts +31 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/db/schema.sql +8 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/index.ts +44 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/routes/todos.ts +155 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/backend/src/types/index.ts +35 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/App.css +384 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/App.tsx +81 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/api/todos.ts +57 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/ConfirmDialog.tsx +26 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/EmptyState.tsx +8 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/TodoForm.tsx +43 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/TodoItem.tsx +36 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/components/TodoList.tsx +27 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/hooks/useTodos.ts +81 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/index.css +48 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/main.tsx +10 -0
- package/templates/vault/loki-mode/examples/todo-app-generated/frontend/src/vite-env.d.ts +1 -0
- package/templates/vault/loki-mode/scripts/export-to-vibe-kanban.sh +178 -0
- package/templates/vault/loki-mode/scripts/loki-wrapper.sh +281 -0
- package/templates/vault/loki-mode/scripts/take-screenshots.js +55 -0
- package/templates/vault/matematico-tao/scripts/complexity_analyzer.py +544 -0
- package/templates/vault/matematico-tao/scripts/dependency_graph.py +538 -0
- package/templates/vault/mcp-builder/scripts/connections.py +151 -0
- package/templates/vault/mcp-builder/scripts/evaluation.py +373 -0
- package/templates/vault/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/templates/vault/mcp-builder/scripts/requirements.txt +2 -0
- package/templates/vault/mobile-design/scripts/mobile_audit.py +670 -0
- package/templates/vault/notebooklm/scripts/__init__.py +81 -0
- package/templates/vault/notebooklm/scripts/ask_question.py +256 -0
- package/templates/vault/notebooklm/scripts/auth_manager.py +358 -0
- package/templates/vault/notebooklm/scripts/browser_session.py +255 -0
- package/templates/vault/notebooklm/scripts/browser_utils.py +107 -0
- package/templates/vault/notebooklm/scripts/cleanup_manager.py +302 -0
- package/templates/vault/notebooklm/scripts/config.py +44 -0
- package/templates/vault/notebooklm/scripts/notebook_manager.py +410 -0
- package/templates/vault/notebooklm/scripts/run.py +102 -0
- package/templates/vault/notebooklm/scripts/setup_environment.py +204 -0
- package/templates/vault/pdf/scripts/check_bounding_boxes.py +70 -0
- package/templates/vault/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/templates/vault/pdf/scripts/check_fillable_fields.py +12 -0
- package/templates/vault/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/templates/vault/pdf/scripts/create_validation_image.py +41 -0
- package/templates/vault/pdf/scripts/extract_form_field_info.py +152 -0
- package/templates/vault/pdf/scripts/fill_fillable_fields.py +114 -0
- package/templates/vault/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/templates/vault/pdf-official/scripts/check_bounding_boxes.py +70 -0
- package/templates/vault/pdf-official/scripts/check_bounding_boxes_test.py +226 -0
- package/templates/vault/pdf-official/scripts/check_fillable_fields.py +12 -0
- package/templates/vault/pdf-official/scripts/convert_pdf_to_images.py +35 -0
- package/templates/vault/pdf-official/scripts/create_validation_image.py +41 -0
- package/templates/vault/pdf-official/scripts/extract_form_field_info.py +152 -0
- package/templates/vault/pdf-official/scripts/fill_fillable_fields.py +114 -0
- package/templates/vault/pdf-official/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/templates/vault/planning-with-files/scripts/check-complete.sh +44 -0
- package/templates/vault/planning-with-files/scripts/init-session.sh +120 -0
- package/templates/vault/pptx/ooxml/scripts/pack.py +159 -0
- package/templates/vault/pptx/ooxml/scripts/unpack.py +29 -0
- package/templates/vault/pptx/ooxml/scripts/validate.py +69 -0
- package/templates/vault/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/vault/pptx/ooxml/scripts/validation/base.py +951 -0
- package/templates/vault/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/templates/vault/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/vault/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/vault/pptx/scripts/html2pptx.js +979 -0
- package/templates/vault/pptx/scripts/inventory.py +1020 -0
- package/templates/vault/pptx/scripts/rearrange.py +231 -0
- package/templates/vault/pptx/scripts/replace.py +385 -0
- package/templates/vault/pptx/scripts/thumbnail.py +450 -0
- package/templates/vault/pptx-official/ooxml/scripts/pack.py +159 -0
- package/templates/vault/pptx-official/ooxml/scripts/unpack.py +29 -0
- package/templates/vault/pptx-official/ooxml/scripts/validate.py +69 -0
- package/templates/vault/pptx-official/ooxml/scripts/validation/__init__.py +15 -0
- package/templates/vault/pptx-official/ooxml/scripts/validation/base.py +951 -0
- package/templates/vault/pptx-official/ooxml/scripts/validation/docx.py +274 -0
- package/templates/vault/pptx-official/ooxml/scripts/validation/pptx.py +315 -0
- package/templates/vault/pptx-official/ooxml/scripts/validation/redlining.py +279 -0
- package/templates/vault/pptx-official/scripts/html2pptx.js +979 -0
- package/templates/vault/pptx-official/scripts/inventory.py +1020 -0
- package/templates/vault/pptx-official/scripts/rearrange.py +231 -0
- package/templates/vault/pptx-official/scripts/replace.py +385 -0
- package/templates/vault/pptx-official/scripts/thumbnail.py +450 -0
- package/templates/vault/product-manager-toolkit/scripts/customer_interview_analyzer.py +441 -0
- package/templates/vault/product-manager-toolkit/scripts/rice_prioritizer.py +296 -0
- package/templates/vault/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
- package/templates/vault/scripts/.skill_cache.json +7538 -0
- package/templates/vault/scripts/skill_search.py +228 -0
- package/templates/vault/senior-architect/scripts/architecture_diagram_generator.py +114 -0
- package/templates/vault/senior-architect/scripts/dependency_analyzer.py +114 -0
- package/templates/vault/senior-architect/scripts/project_architect.py +114 -0
- package/templates/vault/shopify-development/scripts/requirements.txt +19 -0
- package/templates/vault/shopify-development/scripts/shopify_graphql.py +428 -0
- package/templates/vault/shopify-development/scripts/shopify_init.py +441 -0
- package/templates/vault/shopify-development/scripts/tests/test_shopify_init.py +379 -0
- package/templates/vault/skill-creator/scripts/init_skill.py +303 -0
- package/templates/vault/skill-creator/scripts/package_skill.py +110 -0
- package/templates/vault/skill-creator/scripts/quick_validate.py +95 -0
- package/templates/vault/skill-installer/scripts/detect_skills.py +318 -0
- package/templates/vault/skill-installer/scripts/install_skill.py +1708 -0
- package/templates/vault/skill-installer/scripts/package_skill.py +417 -0
- package/templates/vault/skill-installer/scripts/requirements.txt +1 -0
- package/templates/vault/skill-installer/scripts/validate_skill.py +430 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/__init__.py +13 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/code_quality.py +247 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/cross_skill.py +134 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/dependencies.py +121 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/documentation.py +189 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/governance_audit.py +153 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/performance.py +164 -0
- package/templates/vault/skill-sentinel/scripts/analyzers/security.py +189 -0
- package/templates/vault/skill-sentinel/scripts/config.py +158 -0
- package/templates/vault/skill-sentinel/scripts/cost_optimizer.py +146 -0
- package/templates/vault/skill-sentinel/scripts/db.py +354 -0
- package/templates/vault/skill-sentinel/scripts/governance.py +58 -0
- package/templates/vault/skill-sentinel/scripts/recommender.py +228 -0
- package/templates/vault/skill-sentinel/scripts/report_generator.py +224 -0
- package/templates/vault/skill-sentinel/scripts/requirements.txt +1 -0
- package/templates/vault/skill-sentinel/scripts/run_audit.py +290 -0
- package/templates/vault/skill-sentinel/scripts/scanner.py +271 -0
- package/templates/vault/stability-ai/scripts/config.py +266 -0
- package/templates/vault/stability-ai/scripts/generate.py +687 -0
- package/templates/vault/stability-ai/scripts/requirements.txt +4 -0
- package/templates/vault/stability-ai/scripts/styles.py +174 -0
- package/templates/vault/telegram/assets/boilerplate/nodejs/src/bot-client.ts +86 -0
- package/templates/vault/telegram/assets/boilerplate/nodejs/src/handlers.ts +79 -0
- package/templates/vault/telegram/assets/boilerplate/nodejs/src/index.ts +32 -0
- package/templates/vault/telegram/scripts/send_message.py +143 -0
- package/templates/vault/telegram/scripts/setup_project.py +103 -0
- package/templates/vault/telegram/scripts/test_bot.py +144 -0
- package/templates/vault/typescript-expert/scripts/ts_diagnostic.py +203 -0
- package/templates/vault/ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
- package/templates/vault/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
- package/templates/vault/ui-ux-pro-max/scripts/core.py +257 -0
- package/templates/vault/ui-ux-pro-max/scripts/design_system.py +487 -0
- package/templates/vault/ui-ux-pro-max/scripts/search.py +76 -0
- package/templates/vault/videodb/scripts/ws_listener.py +204 -0
- package/templates/vault/web-artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/templates/vault/web-artifacts-builder/scripts/init-artifact.sh +322 -0
- package/templates/vault/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/templates/vault/webapp-testing/scripts/with_server.py +106 -0
- package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/index.ts +125 -0
- package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/template-manager.ts +67 -0
- package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/types.ts +216 -0
- package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/webhook-handler.ts +173 -0
- package/templates/vault/whatsapp-cloud-api/assets/boilerplate/nodejs/src/whatsapp-client.ts +193 -0
- package/templates/vault/whatsapp-cloud-api/scripts/send_test_message.py +137 -0
- package/templates/vault/whatsapp-cloud-api/scripts/setup_project.py +118 -0
- package/templates/vault/whatsapp-cloud-api/scripts/validate_config.py +190 -0
- package/templates/vault/youtube-summarizer/scripts/extract-transcript.py +65 -0
- package/templates/vault/youtube-summarizer/scripts/install-dependencies.sh +28 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Camada de persistencia SQLite para a skill Sentinel.
|
|
3
|
+
|
|
4
|
+
Armazena auditorias, findings, snapshots de skills, recomendacoes
|
|
5
|
+
e historico de scores para analise de tendencias.
|
|
6
|
+
|
|
7
|
+
Uso:
|
|
8
|
+
from db import Database
|
|
9
|
+
db = Database()
|
|
10
|
+
db.init()
|
|
11
|
+
run_id = db.create_audit_run()
|
|
12
|
+
db.insert_skill_snapshot(run_id, {...})
|
|
13
|
+
db.insert_finding(run_id, {...})
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
import sqlite3
|
|
19
|
+
from datetime import datetime, timezone
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Any, Dict, List, Optional
|
|
22
|
+
|
|
23
|
+
from config import DB_PATH
|
|
24
|
+
|
|
25
|
+
DDL = """
|
|
26
|
+
-- Execucoes de auditoria
|
|
27
|
+
CREATE TABLE IF NOT EXISTS audit_runs (
|
|
28
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
29
|
+
started_at TEXT NOT NULL,
|
|
30
|
+
completed_at TEXT,
|
|
31
|
+
skills_scanned INTEGER DEFAULT 0,
|
|
32
|
+
total_findings INTEGER DEFAULT 0,
|
|
33
|
+
overall_score REAL,
|
|
34
|
+
report_path TEXT,
|
|
35
|
+
status TEXT DEFAULT 'running'
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
-- Snapshot de cada skill por auditoria
|
|
39
|
+
CREATE TABLE IF NOT EXISTS skill_snapshots (
|
|
40
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
|
+
audit_run_id INTEGER REFERENCES audit_runs(id),
|
|
42
|
+
skill_name TEXT NOT NULL,
|
|
43
|
+
skill_path TEXT NOT NULL,
|
|
44
|
+
version TEXT,
|
|
45
|
+
file_count INTEGER,
|
|
46
|
+
line_count INTEGER,
|
|
47
|
+
overall_score REAL,
|
|
48
|
+
code_quality REAL,
|
|
49
|
+
security REAL,
|
|
50
|
+
performance REAL,
|
|
51
|
+
governance REAL,
|
|
52
|
+
documentation REAL,
|
|
53
|
+
dependencies REAL,
|
|
54
|
+
raw_metrics TEXT,
|
|
55
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
-- Findings individuais (problemas e recomendacoes)
|
|
59
|
+
CREATE TABLE IF NOT EXISTS findings (
|
|
60
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
61
|
+
audit_run_id INTEGER REFERENCES audit_runs(id),
|
|
62
|
+
skill_name TEXT NOT NULL,
|
|
63
|
+
dimension TEXT NOT NULL,
|
|
64
|
+
severity TEXT NOT NULL,
|
|
65
|
+
category TEXT,
|
|
66
|
+
title TEXT NOT NULL,
|
|
67
|
+
description TEXT,
|
|
68
|
+
file_path TEXT,
|
|
69
|
+
line_number INTEGER,
|
|
70
|
+
recommendation TEXT,
|
|
71
|
+
effort TEXT,
|
|
72
|
+
impact TEXT,
|
|
73
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
-- Recomendacoes de novas skills
|
|
77
|
+
CREATE TABLE IF NOT EXISTS skill_recommendations (
|
|
78
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
79
|
+
audit_run_id INTEGER REFERENCES audit_runs(id),
|
|
80
|
+
suggested_name TEXT NOT NULL,
|
|
81
|
+
rationale TEXT,
|
|
82
|
+
capabilities TEXT,
|
|
83
|
+
priority TEXT,
|
|
84
|
+
skill_md_draft TEXT,
|
|
85
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
-- Historico de scores para tendencias
|
|
89
|
+
CREATE TABLE IF NOT EXISTS score_history (
|
|
90
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
91
|
+
audit_run_id INTEGER REFERENCES audit_runs(id),
|
|
92
|
+
skill_name TEXT NOT NULL,
|
|
93
|
+
dimension TEXT NOT NULL,
|
|
94
|
+
score REAL,
|
|
95
|
+
recorded_at TEXT DEFAULT (datetime('now'))
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
-- Action log (auto-governanca do sentinel)
|
|
99
|
+
CREATE TABLE IF NOT EXISTS action_log (
|
|
100
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
101
|
+
action TEXT NOT NULL,
|
|
102
|
+
params TEXT,
|
|
103
|
+
result TEXT,
|
|
104
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
-- Indices
|
|
108
|
+
CREATE INDEX IF NOT EXISTS idx_snapshots_run ON skill_snapshots (audit_run_id);
|
|
109
|
+
CREATE INDEX IF NOT EXISTS idx_snapshots_skill ON skill_snapshots (skill_name);
|
|
110
|
+
CREATE INDEX IF NOT EXISTS idx_findings_run ON findings (audit_run_id);
|
|
111
|
+
CREATE INDEX IF NOT EXISTS idx_findings_skill ON findings (skill_name);
|
|
112
|
+
CREATE INDEX IF NOT EXISTS idx_findings_severity ON findings (severity);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_findings_dim ON findings (dimension);
|
|
114
|
+
CREATE INDEX IF NOT EXISTS idx_history_skill ON score_history (skill_name);
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_history_time ON score_history (recorded_at);
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_action_log_time ON action_log (created_at);
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class Database:
|
|
121
|
+
def __init__(self, db_path: Path = DB_PATH):
|
|
122
|
+
self.db_path = Path(db_path)
|
|
123
|
+
self.db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
124
|
+
|
|
125
|
+
def _connect(self) -> sqlite3.Connection:
|
|
126
|
+
conn = sqlite3.connect(self.db_path)
|
|
127
|
+
conn.row_factory = sqlite3.Row
|
|
128
|
+
conn.execute("PRAGMA journal_mode=WAL")
|
|
129
|
+
conn.execute("PRAGMA synchronous=NORMAL")
|
|
130
|
+
conn.execute("PRAGMA foreign_keys=ON")
|
|
131
|
+
return conn
|
|
132
|
+
|
|
133
|
+
def init(self) -> None:
|
|
134
|
+
"""Cria tabelas e indices se nao existirem."""
|
|
135
|
+
with self._connect() as conn:
|
|
136
|
+
conn.executescript(DDL)
|
|
137
|
+
|
|
138
|
+
# -- Audit Runs ------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
def create_audit_run(self) -> int:
|
|
141
|
+
"""Cria uma nova execucao de auditoria. Retorna o id."""
|
|
142
|
+
now = datetime.now(timezone.utc).isoformat()
|
|
143
|
+
with self._connect() as conn:
|
|
144
|
+
cursor = conn.execute(
|
|
145
|
+
"INSERT INTO audit_runs (started_at) VALUES (?)", [now]
|
|
146
|
+
)
|
|
147
|
+
return cursor.lastrowid
|
|
148
|
+
|
|
149
|
+
def complete_audit_run(
|
|
150
|
+
self, run_id: int, skills_scanned: int, total_findings: int,
|
|
151
|
+
overall_score: float, report_path: str
|
|
152
|
+
) -> None:
|
|
153
|
+
"""Marca uma auditoria como completa."""
|
|
154
|
+
now = datetime.now(timezone.utc).isoformat()
|
|
155
|
+
with self._connect() as conn:
|
|
156
|
+
conn.execute(
|
|
157
|
+
"""UPDATE audit_runs SET
|
|
158
|
+
completed_at = ?, skills_scanned = ?, total_findings = ?,
|
|
159
|
+
overall_score = ?, report_path = ?, status = 'completed'
|
|
160
|
+
WHERE id = ?""",
|
|
161
|
+
[now, skills_scanned, total_findings, overall_score, report_path, run_id],
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def get_audit_runs(self, limit: int = 10) -> List[Dict[str, Any]]:
|
|
165
|
+
"""Retorna ultimas auditorias."""
|
|
166
|
+
with self._connect() as conn:
|
|
167
|
+
rows = conn.execute(
|
|
168
|
+
"SELECT * FROM audit_runs ORDER BY started_at DESC LIMIT ?", [limit]
|
|
169
|
+
).fetchall()
|
|
170
|
+
return [dict(r) for r in rows]
|
|
171
|
+
|
|
172
|
+
def get_latest_completed_run(self) -> Optional[Dict[str, Any]]:
|
|
173
|
+
"""Retorna a ultima auditoria completa."""
|
|
174
|
+
with self._connect() as conn:
|
|
175
|
+
row = conn.execute(
|
|
176
|
+
"SELECT * FROM audit_runs WHERE status = 'completed' "
|
|
177
|
+
"ORDER BY completed_at DESC LIMIT 1"
|
|
178
|
+
).fetchone()
|
|
179
|
+
return dict(row) if row else None
|
|
180
|
+
|
|
181
|
+
# -- Skill Snapshots -------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
def insert_skill_snapshot(self, run_id: int, data: Dict[str, Any]) -> int:
|
|
184
|
+
"""Insere snapshot de uma skill. Retorna o id."""
|
|
185
|
+
data["audit_run_id"] = run_id
|
|
186
|
+
if "raw_metrics" in data and isinstance(data["raw_metrics"], dict):
|
|
187
|
+
data["raw_metrics"] = json.dumps(data["raw_metrics"], ensure_ascii=False)
|
|
188
|
+
keys = list(data.keys())
|
|
189
|
+
placeholders = ", ".join(f":{k}" for k in keys)
|
|
190
|
+
columns = ", ".join(keys)
|
|
191
|
+
sql = f"INSERT INTO skill_snapshots ({columns}) VALUES ({placeholders})"
|
|
192
|
+
with self._connect() as conn:
|
|
193
|
+
cursor = conn.execute(sql, data)
|
|
194
|
+
return cursor.lastrowid
|
|
195
|
+
|
|
196
|
+
def get_snapshots_for_run(self, run_id: int) -> List[Dict[str, Any]]:
|
|
197
|
+
with self._connect() as conn:
|
|
198
|
+
rows = conn.execute(
|
|
199
|
+
"SELECT * FROM skill_snapshots WHERE audit_run_id = ? ORDER BY skill_name",
|
|
200
|
+
[run_id],
|
|
201
|
+
).fetchall()
|
|
202
|
+
return [dict(r) for r in rows]
|
|
203
|
+
|
|
204
|
+
def get_latest_snapshot(self, skill_name: str) -> Optional[Dict[str, Any]]:
|
|
205
|
+
"""Retorna o snapshot mais recente de uma skill."""
|
|
206
|
+
with self._connect() as conn:
|
|
207
|
+
row = conn.execute(
|
|
208
|
+
"SELECT * FROM skill_snapshots WHERE skill_name = ? "
|
|
209
|
+
"ORDER BY created_at DESC LIMIT 1",
|
|
210
|
+
[skill_name],
|
|
211
|
+
).fetchone()
|
|
212
|
+
return dict(row) if row else None
|
|
213
|
+
|
|
214
|
+
# -- Findings --------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
def insert_finding(self, run_id: int, data: Dict[str, Any]) -> int:
|
|
217
|
+
"""Insere um finding. Retorna o id."""
|
|
218
|
+
data["audit_run_id"] = run_id
|
|
219
|
+
keys = list(data.keys())
|
|
220
|
+
placeholders = ", ".join(f":{k}" for k in keys)
|
|
221
|
+
columns = ", ".join(keys)
|
|
222
|
+
sql = f"INSERT INTO findings ({columns}) VALUES ({placeholders})"
|
|
223
|
+
with self._connect() as conn:
|
|
224
|
+
cursor = conn.execute(sql, data)
|
|
225
|
+
return cursor.lastrowid
|
|
226
|
+
|
|
227
|
+
def insert_findings_batch(self, run_id: int, findings: List[Dict[str, Any]]) -> int:
|
|
228
|
+
"""Insere multiplos findings de uma vez."""
|
|
229
|
+
count = 0
|
|
230
|
+
for f in findings:
|
|
231
|
+
self.insert_finding(run_id, f)
|
|
232
|
+
count += 1
|
|
233
|
+
return count
|
|
234
|
+
|
|
235
|
+
def get_findings_for_run(
|
|
236
|
+
self, run_id: int, skill_name: Optional[str] = None,
|
|
237
|
+
severity: Optional[str] = None, dimension: Optional[str] = None
|
|
238
|
+
) -> List[Dict[str, Any]]:
|
|
239
|
+
conditions = ["audit_run_id = ?"]
|
|
240
|
+
params: list = [run_id]
|
|
241
|
+
if skill_name:
|
|
242
|
+
conditions.append("skill_name = ?")
|
|
243
|
+
params.append(skill_name)
|
|
244
|
+
if severity:
|
|
245
|
+
conditions.append("severity = ?")
|
|
246
|
+
params.append(severity)
|
|
247
|
+
if dimension:
|
|
248
|
+
conditions.append("dimension = ?")
|
|
249
|
+
params.append(dimension)
|
|
250
|
+
where = " AND ".join(conditions)
|
|
251
|
+
sql = f"SELECT * FROM findings WHERE {where} ORDER BY severity, dimension"
|
|
252
|
+
with self._connect() as conn:
|
|
253
|
+
rows = conn.execute(sql, params).fetchall()
|
|
254
|
+
return [dict(r) for r in rows]
|
|
255
|
+
|
|
256
|
+
def count_findings_by_severity(self, run_id: int) -> Dict[str, int]:
|
|
257
|
+
"""Conta findings por severidade."""
|
|
258
|
+
with self._connect() as conn:
|
|
259
|
+
rows = conn.execute(
|
|
260
|
+
"SELECT severity, COUNT(*) as cnt FROM findings "
|
|
261
|
+
"WHERE audit_run_id = ? GROUP BY severity",
|
|
262
|
+
[run_id],
|
|
263
|
+
).fetchall()
|
|
264
|
+
return {r["severity"]: r["cnt"] for r in rows}
|
|
265
|
+
|
|
266
|
+
# -- Skill Recommendations -------------------------------------------------
|
|
267
|
+
|
|
268
|
+
def insert_recommendation(self, run_id: int, data: Dict[str, Any]) -> int:
|
|
269
|
+
data["audit_run_id"] = run_id
|
|
270
|
+
if "capabilities" in data and isinstance(data["capabilities"], list):
|
|
271
|
+
data["capabilities"] = json.dumps(data["capabilities"], ensure_ascii=False)
|
|
272
|
+
keys = list(data.keys())
|
|
273
|
+
placeholders = ", ".join(f":{k}" for k in keys)
|
|
274
|
+
columns = ", ".join(keys)
|
|
275
|
+
sql = f"INSERT INTO skill_recommendations ({columns}) VALUES ({placeholders})"
|
|
276
|
+
with self._connect() as conn:
|
|
277
|
+
cursor = conn.execute(sql, data)
|
|
278
|
+
return cursor.lastrowid
|
|
279
|
+
|
|
280
|
+
def get_recommendations_for_run(self, run_id: int) -> List[Dict[str, Any]]:
|
|
281
|
+
with self._connect() as conn:
|
|
282
|
+
rows = conn.execute(
|
|
283
|
+
"SELECT * FROM skill_recommendations WHERE audit_run_id = ? ORDER BY priority",
|
|
284
|
+
[run_id],
|
|
285
|
+
).fetchall()
|
|
286
|
+
return [dict(r) for r in rows]
|
|
287
|
+
|
|
288
|
+
# -- Score History ---------------------------------------------------------
|
|
289
|
+
|
|
290
|
+
def insert_score_history(self, run_id: int, skill_name: str, dimension: str, score: float) -> None:
|
|
291
|
+
with self._connect() as conn:
|
|
292
|
+
conn.execute(
|
|
293
|
+
"INSERT INTO score_history (audit_run_id, skill_name, dimension, score) "
|
|
294
|
+
"VALUES (?, ?, ?, ?)",
|
|
295
|
+
[run_id, skill_name, dimension, score],
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
def get_score_trend(self, skill_name: str, dimension: str, limit: int = 10) -> List[Dict[str, Any]]:
|
|
299
|
+
"""Retorna historico de scores para uma skill/dimensao."""
|
|
300
|
+
with self._connect() as conn:
|
|
301
|
+
rows = conn.execute(
|
|
302
|
+
"SELECT * FROM score_history WHERE skill_name = ? AND dimension = ? "
|
|
303
|
+
"ORDER BY recorded_at DESC LIMIT ?",
|
|
304
|
+
[skill_name, dimension, limit],
|
|
305
|
+
).fetchall()
|
|
306
|
+
return [dict(r) for r in rows]
|
|
307
|
+
|
|
308
|
+
# -- Action Log (Auto-Governanca) ------------------------------------------
|
|
309
|
+
|
|
310
|
+
def log_action(self, action: str, params: Optional[Dict] = None, result: Optional[Dict] = None) -> None:
|
|
311
|
+
with self._connect() as conn:
|
|
312
|
+
conn.execute(
|
|
313
|
+
"INSERT INTO action_log (action, params, result) VALUES (?, ?, ?)",
|
|
314
|
+
[
|
|
315
|
+
action,
|
|
316
|
+
json.dumps(params, ensure_ascii=False) if params else None,
|
|
317
|
+
json.dumps(result, ensure_ascii=False) if result else None,
|
|
318
|
+
],
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
def get_recent_actions(self, limit: int = 20) -> List[Dict[str, Any]]:
|
|
322
|
+
with self._connect() as conn:
|
|
323
|
+
rows = conn.execute(
|
|
324
|
+
"SELECT * FROM action_log ORDER BY created_at DESC LIMIT ?", [limit]
|
|
325
|
+
).fetchall()
|
|
326
|
+
return [dict(r) for r in rows]
|
|
327
|
+
|
|
328
|
+
# -- Stats -----------------------------------------------------------------
|
|
329
|
+
|
|
330
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
331
|
+
"""Retorna estatisticas gerais do sentinel."""
|
|
332
|
+
with self._connect() as conn:
|
|
333
|
+
total_runs = conn.execute("SELECT COUNT(*) FROM audit_runs").fetchone()[0]
|
|
334
|
+
completed = conn.execute(
|
|
335
|
+
"SELECT COUNT(*) FROM audit_runs WHERE status = 'completed'"
|
|
336
|
+
).fetchone()[0]
|
|
337
|
+
total_findings = conn.execute("SELECT COUNT(*) FROM findings").fetchone()[0]
|
|
338
|
+
total_recs = conn.execute("SELECT COUNT(*) FROM skill_recommendations").fetchone()[0]
|
|
339
|
+
return {
|
|
340
|
+
"audit_runs": {"total": total_runs, "completed": completed},
|
|
341
|
+
"total_findings": total_findings,
|
|
342
|
+
"total_recommendations": total_recs,
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
# -- CLI rapido para verificacao -----------------------------------------------
|
|
347
|
+
if __name__ == "__main__":
|
|
348
|
+
db = Database()
|
|
349
|
+
db.init()
|
|
350
|
+
stats = db.get_stats()
|
|
351
|
+
print(json.dumps(stats, indent=2, ensure_ascii=False))
|
|
352
|
+
print("\nUltimas auditorias:")
|
|
353
|
+
for r in db.get_audit_runs(5):
|
|
354
|
+
print(f" [{r['started_at']}] {r['status']} - score: {r['overall_score']}")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auto-governanca do Sentinel.
|
|
3
|
+
|
|
4
|
+
Registra todas as acoes do sentinel em audit log proprio.
|
|
5
|
+
Padrao leve — sem rate limiting (operacoes locais apenas).
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from datetime import datetime, timezone
|
|
11
|
+
from typing import Any, Dict, Optional
|
|
12
|
+
|
|
13
|
+
from db import Database
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SentinelGovernance:
|
|
17
|
+
"""Registra acoes do sentinel para auditabilidade."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, db: Optional[Database] = None):
|
|
20
|
+
self.db = db or Database()
|
|
21
|
+
self.db.init()
|
|
22
|
+
|
|
23
|
+
def log_action(self, action: str, params: Optional[Dict] = None, result: Optional[Dict] = None) -> None:
|
|
24
|
+
"""Registra uma acao no audit log."""
|
|
25
|
+
self.db.log_action(action, params, result)
|
|
26
|
+
|
|
27
|
+
def log_audit_start(self, skills: list) -> None:
|
|
28
|
+
self.log_action("audit_start", {"skills": skills})
|
|
29
|
+
|
|
30
|
+
def log_audit_complete(self, run_id: int, score: float, findings_count: int) -> None:
|
|
31
|
+
self.log_action("audit_complete", {
|
|
32
|
+
"run_id": run_id,
|
|
33
|
+
"overall_score": score,
|
|
34
|
+
"findings_count": findings_count,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
def log_recommendation(self, suggested_name: str, priority: str) -> None:
|
|
38
|
+
self.log_action("recommendation", {
|
|
39
|
+
"suggested_name": suggested_name,
|
|
40
|
+
"priority": priority,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
def get_recent_actions(self, limit: int = 20) -> list:
|
|
44
|
+
return self.db.get_recent_actions(limit)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# -- CLI -----------------------------------------------------------------------
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
gov = SentinelGovernance()
|
|
50
|
+
actions = gov.get_recent_actions(10)
|
|
51
|
+
if not actions:
|
|
52
|
+
print("Nenhuma acao registrada.")
|
|
53
|
+
else:
|
|
54
|
+
print("Ultimas acoes do Sentinel:")
|
|
55
|
+
for a in actions:
|
|
56
|
+
print(f" [{a['created_at']}] {a['action']}")
|
|
57
|
+
if a.get("params"):
|
|
58
|
+
print(f" Params: {a['params']}")
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Recommender: gap analysis e sugestao de novas skills.
|
|
3
|
+
|
|
4
|
+
Analisa as capacidades existentes, identifica lacunas no ecossistema
|
|
5
|
+
e gera templates de SKILL.md para skills sugeridas.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any, Dict, List, Set
|
|
10
|
+
|
|
11
|
+
from config import CAPABILITY_TAXONOMY
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _map_capabilities(skills: List[Dict[str, Any]]) -> Dict[str, Set[str]]:
|
|
15
|
+
"""Mapeia cada skill para suas capacidades detectadas."""
|
|
16
|
+
capability_keywords = {
|
|
17
|
+
"data-extraction": ["scraper", "extract", "crawl", "parse", "scraping"],
|
|
18
|
+
"social-media": ["instagram", "facebook", "twitter", "tiktok", "social"],
|
|
19
|
+
"messaging": ["whatsapp", "message", "dm", "chat", "sms", "telegram"],
|
|
20
|
+
"government-data": ["junta", "governo", "government", "registro", "legal"],
|
|
21
|
+
"web-automation": ["browser", "playwright", "selenium", "automation"],
|
|
22
|
+
"api-integration": ["api_client", "graph_api", "oauth", "webhook"],
|
|
23
|
+
"analytics": ["insights", "analytics", "metrics", "dashboard"],
|
|
24
|
+
"content-management": ["publish", "template", "schedule", "content"],
|
|
25
|
+
"monitoring": ["monitor", "alert", "health", "sentinel"],
|
|
26
|
+
"security-audit": ["security", "audit", "governance", "compliance"],
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
skill_caps: Dict[str, Set[str]] = {}
|
|
30
|
+
for skill in skills:
|
|
31
|
+
caps: Set[str] = set()
|
|
32
|
+
desc = (skill.get("description", "") + " " + skill.get("name", "")).lower()
|
|
33
|
+
files = " ".join(skill.get("python_files", [])).lower()
|
|
34
|
+
combined = desc + " " + files
|
|
35
|
+
|
|
36
|
+
for cap, keywords in capability_keywords.items():
|
|
37
|
+
if any(kw in combined for kw in keywords):
|
|
38
|
+
caps.add(cap)
|
|
39
|
+
|
|
40
|
+
skill_caps[skill["name"]] = caps
|
|
41
|
+
return skill_caps
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _identify_gaps(covered: Set[str]) -> List[Dict[str, Any]]:
|
|
45
|
+
"""Identifica capacidades nao cobertas."""
|
|
46
|
+
gaps = []
|
|
47
|
+
for cap_id, cap_desc in CAPABILITY_TAXONOMY.items():
|
|
48
|
+
if cap_id not in covered:
|
|
49
|
+
gaps.append({
|
|
50
|
+
"capability": cap_id,
|
|
51
|
+
"description": cap_desc,
|
|
52
|
+
})
|
|
53
|
+
return gaps
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _generate_skill_template(name: str, description: str, capabilities: List[str]) -> str:
|
|
57
|
+
"""Gera um rascunho de SKILL.md para uma skill sugerida."""
|
|
58
|
+
cap_list = ", ".join(capabilities)
|
|
59
|
+
return f"""---
|
|
60
|
+
name: {name}
|
|
61
|
+
description: >-
|
|
62
|
+
{description}
|
|
63
|
+
Capacidades: {cap_list}.
|
|
64
|
+
version: 0.1.0
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
# Skill: {name.replace('-', ' ').title()}
|
|
68
|
+
|
|
69
|
+
## Resumo
|
|
70
|
+
|
|
71
|
+
{description}
|
|
72
|
+
|
|
73
|
+
## Estrutura Sugerida
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
{name}/
|
|
77
|
+
├── SKILL.md
|
|
78
|
+
├── scripts/
|
|
79
|
+
│ ├── requirements.txt
|
|
80
|
+
│ ├── config.py
|
|
81
|
+
│ ├── db.py
|
|
82
|
+
│ └── [modulos de features]
|
|
83
|
+
├── references/
|
|
84
|
+
│ └── [documentacao tecnica]
|
|
85
|
+
└── data/
|
|
86
|
+
└── {name}.db
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Proximos Passos
|
|
90
|
+
|
|
91
|
+
1. Definir escopo detalhado e APIs necessarias
|
|
92
|
+
2. Criar modulos core (config, db, governance)
|
|
93
|
+
3. Implementar features principais
|
|
94
|
+
4. Adicionar testes e documentacao
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _prioritize_gap(cap_id: str, all_skills: List[Dict[str, Any]]) -> str:
|
|
99
|
+
"""Define prioridade baseada na relevancia para o ecossistema atual."""
|
|
100
|
+
high_priority = {"testing", "monitoring", "data-pipeline", "notification"}
|
|
101
|
+
medium_priority = {"scheduling", "email-integration", "documentation-gen", "ci-cd"}
|
|
102
|
+
|
|
103
|
+
if cap_id in high_priority:
|
|
104
|
+
return "high"
|
|
105
|
+
elif cap_id in medium_priority:
|
|
106
|
+
return "medium"
|
|
107
|
+
return "low"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def recommend(all_skills: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
111
|
+
"""
|
|
112
|
+
Analisa ecossistema e retorna recomendacoes de novas skills.
|
|
113
|
+
"""
|
|
114
|
+
recommendations: List[Dict[str, Any]] = []
|
|
115
|
+
|
|
116
|
+
# Mapear capacidades existentes
|
|
117
|
+
skill_caps = _map_capabilities(all_skills)
|
|
118
|
+
all_covered = set()
|
|
119
|
+
for caps in skill_caps.values():
|
|
120
|
+
all_covered.update(caps)
|
|
121
|
+
|
|
122
|
+
# Gap analysis
|
|
123
|
+
gaps = _identify_gaps(all_covered)
|
|
124
|
+
|
|
125
|
+
# Gerar recomendacoes especificas por gap
|
|
126
|
+
skill_suggestions = {
|
|
127
|
+
"testing": {
|
|
128
|
+
"name": "skill-tester",
|
|
129
|
+
"rationale": "O ecossistema nao tem infraestrutura de testes automatizados. "
|
|
130
|
+
"Um skill-tester permitiria validar todas as skills automaticamente.",
|
|
131
|
+
"capabilities": ["testing", "ci-cd"],
|
|
132
|
+
},
|
|
133
|
+
"monitoring": {
|
|
134
|
+
"name": "skill-monitor",
|
|
135
|
+
"rationale": "Sem monitoramento ativo de saude das APIs e servicos externos. "
|
|
136
|
+
"Alertas proativos evitariam downtime.",
|
|
137
|
+
"capabilities": ["monitoring"],
|
|
138
|
+
},
|
|
139
|
+
"data-pipeline": {
|
|
140
|
+
"name": "data-pipeline",
|
|
141
|
+
"rationale": "Multiplas skills fazem ETL (extract, transform, export) de forma isolada. "
|
|
142
|
+
"Um pipeline unificado reduziria duplicacao.",
|
|
143
|
+
"capabilities": ["data-pipeline", "data-extraction"],
|
|
144
|
+
},
|
|
145
|
+
"notification": {
|
|
146
|
+
"name": "notification-hub",
|
|
147
|
+
"rationale": "Instagram e WhatsApp existem como canais isolados. "
|
|
148
|
+
"Um hub de notificacoes unificaria envio multi-canal.",
|
|
149
|
+
"capabilities": ["notification", "messaging"],
|
|
150
|
+
},
|
|
151
|
+
"scheduling": {
|
|
152
|
+
"name": "scheduler",
|
|
153
|
+
"rationale": "Agendamento implementado de forma ad-hoc em skills individuais. "
|
|
154
|
+
"Um scheduler centralizado com cron-like expressions.",
|
|
155
|
+
"capabilities": ["scheduling"],
|
|
156
|
+
},
|
|
157
|
+
"email-integration": {
|
|
158
|
+
"name": "email-integration",
|
|
159
|
+
"rationale": "Sem integracao com email. Util para relatorios automaticos, "
|
|
160
|
+
"alertas e comunicacao profissional.",
|
|
161
|
+
"capabilities": ["email-integration", "notification"],
|
|
162
|
+
},
|
|
163
|
+
"documentation-gen": {
|
|
164
|
+
"name": "doc-generator",
|
|
165
|
+
"rationale": "Geracao automatica de documentacao a partir do codigo. "
|
|
166
|
+
"Manteria SKILL.md e references/ sempre atualizados.",
|
|
167
|
+
"capabilities": ["documentation-gen"],
|
|
168
|
+
},
|
|
169
|
+
"database-management": {
|
|
170
|
+
"name": "db-manager",
|
|
171
|
+
"rationale": "Multiplas skills usam SQLite de forma independente. "
|
|
172
|
+
"Um gerenciador centralizado com migrations, backup e otimizacao.",
|
|
173
|
+
"capabilities": ["database-management"],
|
|
174
|
+
},
|
|
175
|
+
"file-management": {
|
|
176
|
+
"name": "file-manager",
|
|
177
|
+
"rationale": "Gestao de arquivos (upload, download, conversao, limpeza) "
|
|
178
|
+
"util para alimentar outras skills.",
|
|
179
|
+
"capabilities": ["file-management"],
|
|
180
|
+
},
|
|
181
|
+
"cost-optimization": {
|
|
182
|
+
"name": "cost-optimizer",
|
|
183
|
+
"rationale": "Analise e reducao de custos de API, tokens e recursos computacionais.",
|
|
184
|
+
"capabilities": ["cost-optimization", "monitoring"],
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
# Cross-skill recommendations baseadas em padroes detectados
|
|
189
|
+
db_skills = [s for s in all_skills if s.get("has_db")]
|
|
190
|
+
if len(db_skills) > 1:
|
|
191
|
+
recommendations.append({
|
|
192
|
+
"suggested_name": "shared-core",
|
|
193
|
+
"rationale": f"Os modulos db.py, config.py e export.py sao compartilhados entre "
|
|
194
|
+
f"{len(db_skills)} skills ({', '.join(s['name'] for s in db_skills)}). "
|
|
195
|
+
f"Extrair para modulo compartilhado reduziria duplicacao.",
|
|
196
|
+
"capabilities": ["database", "export", "configuration"],
|
|
197
|
+
"priority": "high",
|
|
198
|
+
"skill_md_draft": _generate_skill_template(
|
|
199
|
+
"shared-core",
|
|
200
|
+
"Modulos base compartilhados por todas as skills do ecossistema. "
|
|
201
|
+
"Database, config, export, governance.",
|
|
202
|
+
["database", "export", "configuration"],
|
|
203
|
+
),
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
# Adicionar gaps como recomendacoes
|
|
207
|
+
for gap in gaps:
|
|
208
|
+
cap_id = gap["capability"]
|
|
209
|
+
if cap_id in skill_suggestions:
|
|
210
|
+
sugg = skill_suggestions[cap_id]
|
|
211
|
+
priority = _prioritize_gap(cap_id, all_skills)
|
|
212
|
+
recommendations.append({
|
|
213
|
+
"suggested_name": sugg["name"],
|
|
214
|
+
"rationale": sugg["rationale"],
|
|
215
|
+
"capabilities": sugg["capabilities"],
|
|
216
|
+
"priority": priority,
|
|
217
|
+
"skill_md_draft": _generate_skill_template(
|
|
218
|
+
sugg["name"],
|
|
219
|
+
sugg["rationale"],
|
|
220
|
+
sugg["capabilities"],
|
|
221
|
+
),
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
# Ordenar por prioridade
|
|
225
|
+
priority_order = {"critical": 0, "high": 1, "medium": 2, "low": 3}
|
|
226
|
+
recommendations.sort(key=lambda r: priority_order.get(r.get("priority", "low"), 3))
|
|
227
|
+
|
|
228
|
+
return recommendations
|