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,144 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Test Telegram Bot connection and token validity.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python test_bot.py --token "YOUR_BOT_TOKEN"
|
|
7
|
+
python test_bot.py # Uses TELEGRAM_BOT_TOKEN env var
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import json
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
from urllib.request import urlopen, Request
|
|
15
|
+
from urllib.error import URLError, HTTPError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _mask_token(token: str) -> str:
|
|
19
|
+
"""Return a masked version of the token for safe logging."""
|
|
20
|
+
if not token or len(token) < 12:
|
|
21
|
+
return "***masked***"
|
|
22
|
+
return f"{token[:8]}...masked"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_bot(token: str) -> dict:
|
|
26
|
+
"""Test bot token and return bot info."""
|
|
27
|
+
base_url = f"https://api.telegram.org/bot{token}"
|
|
28
|
+
masked_token = _mask_token(token)
|
|
29
|
+
results = {
|
|
30
|
+
"token_valid": False,
|
|
31
|
+
"bot_info": None,
|
|
32
|
+
"webhook_info": None,
|
|
33
|
+
"errors": []
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Test 1: getMe
|
|
37
|
+
print(f"[1/3] Testing token ({masked_token}) with getMe...")
|
|
38
|
+
try:
|
|
39
|
+
req = Request(f"{base_url}/getMe")
|
|
40
|
+
with urlopen(req, timeout=10) as resp:
|
|
41
|
+
data = json.loads(resp.read().decode())
|
|
42
|
+
if data.get("ok"):
|
|
43
|
+
results["token_valid"] = True
|
|
44
|
+
results["bot_info"] = data["result"]
|
|
45
|
+
bot = data["result"]
|
|
46
|
+
print(f" OK - Bot: @{bot.get('username', 'N/A')}")
|
|
47
|
+
print(f" Name: {bot.get('first_name', 'N/A')}")
|
|
48
|
+
print(f" ID: {bot.get('id', 'N/A')}")
|
|
49
|
+
print(f" Can join groups: {bot.get('can_join_groups', 'N/A')}")
|
|
50
|
+
print(f" Can read group messages: {bot.get('can_read_all_group_messages', 'N/A')}")
|
|
51
|
+
print(f" Supports inline: {bot.get('supports_inline_queries', 'N/A')}")
|
|
52
|
+
else:
|
|
53
|
+
results["errors"].append(f"getMe returned ok=false: {data}")
|
|
54
|
+
print(f" FAIL - {data.get('description', 'Unknown error')}")
|
|
55
|
+
except HTTPError as e:
|
|
56
|
+
error_body = e.read().decode()
|
|
57
|
+
# Mask token in error body to prevent credential leakage
|
|
58
|
+
safe_error = error_body.replace(token, masked_token) if token in error_body else error_body
|
|
59
|
+
results["errors"].append(f"HTTP {e.code}: {safe_error}")
|
|
60
|
+
print(f" FAIL - HTTP {e.code}: {safe_error}")
|
|
61
|
+
if e.code == 401:
|
|
62
|
+
print(" Token is INVALID. Get a new one from @BotFather")
|
|
63
|
+
return results
|
|
64
|
+
except URLError as e:
|
|
65
|
+
results["errors"].append(f"Network error: {e.reason}")
|
|
66
|
+
print(f" FAIL - Network error: {e.reason}")
|
|
67
|
+
return results
|
|
68
|
+
|
|
69
|
+
# Test 2: getWebhookInfo
|
|
70
|
+
print("\n[2/3] Checking webhook status...")
|
|
71
|
+
try:
|
|
72
|
+
req = Request(f"{base_url}/getWebhookInfo")
|
|
73
|
+
with urlopen(req, timeout=10) as resp:
|
|
74
|
+
data = json.loads(resp.read().decode())
|
|
75
|
+
if data.get("ok"):
|
|
76
|
+
wh = data["result"]
|
|
77
|
+
results["webhook_info"] = wh
|
|
78
|
+
if wh.get("url"):
|
|
79
|
+
print(f" Webhook active: {wh['url']}")
|
|
80
|
+
print(f" Pending updates: {wh.get('pending_update_count', 0)}")
|
|
81
|
+
if wh.get("last_error_message"):
|
|
82
|
+
print(f" Last error: {wh['last_error_message']}")
|
|
83
|
+
print(f" Error date: {wh.get('last_error_date', 'N/A')}")
|
|
84
|
+
else:
|
|
85
|
+
print(" No webhook set (using long polling or inactive)")
|
|
86
|
+
except Exception as e:
|
|
87
|
+
safe_err = str(e).replace(token, masked_token)
|
|
88
|
+
results["errors"].append(f"getWebhookInfo error: {safe_err}")
|
|
89
|
+
print(f" WARN - Could not check webhook: {safe_err}")
|
|
90
|
+
|
|
91
|
+
# Test 3: getUpdates (only if no webhook)
|
|
92
|
+
print("\n[3/3] Testing getUpdates...")
|
|
93
|
+
if results.get("webhook_info", {}).get("url"):
|
|
94
|
+
print(" SKIP - Webhook is active (getUpdates disabled)")
|
|
95
|
+
else:
|
|
96
|
+
try:
|
|
97
|
+
req = Request(f"{base_url}/getUpdates?limit=1&timeout=1")
|
|
98
|
+
with urlopen(req, timeout=15) as resp:
|
|
99
|
+
data = json.loads(resp.read().decode())
|
|
100
|
+
if data.get("ok"):
|
|
101
|
+
updates = data.get("result", [])
|
|
102
|
+
print(f" OK - {len(updates)} pending update(s)")
|
|
103
|
+
if updates:
|
|
104
|
+
last = updates[-1]
|
|
105
|
+
print(f" Last update ID: {last.get('update_id')}")
|
|
106
|
+
except Exception as e:
|
|
107
|
+
safe_err = str(e).replace(token, masked_token)
|
|
108
|
+
results["errors"].append(f"getUpdates error: {safe_err}")
|
|
109
|
+
print(f" WARN - {safe_err}")
|
|
110
|
+
|
|
111
|
+
# Summary
|
|
112
|
+
print("\n" + "=" * 50)
|
|
113
|
+
if results["token_valid"] and not results["errors"]:
|
|
114
|
+
print("RESULT: All tests PASSED. Bot is ready!")
|
|
115
|
+
elif results["token_valid"]:
|
|
116
|
+
print(f"RESULT: Token valid but {len(results['errors'])} warning(s)")
|
|
117
|
+
else:
|
|
118
|
+
print("RESULT: Token INVALID. Check with @BotFather")
|
|
119
|
+
print("=" * 50)
|
|
120
|
+
|
|
121
|
+
return results
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def main():
|
|
125
|
+
parser = argparse.ArgumentParser(description="Test Telegram Bot token")
|
|
126
|
+
parser.add_argument("--token", type=str, help="Bot token (or set TELEGRAM_BOT_TOKEN env var)")
|
|
127
|
+
parser.add_argument("--json", action="store_true", help="Output results as JSON")
|
|
128
|
+
args = parser.parse_args()
|
|
129
|
+
|
|
130
|
+
token = args.token or os.environ.get("TELEGRAM_BOT_TOKEN")
|
|
131
|
+
if not token:
|
|
132
|
+
print("ERROR: Provide --token or set TELEGRAM_BOT_TOKEN environment variable")
|
|
133
|
+
sys.exit(1)
|
|
134
|
+
|
|
135
|
+
results = test_bot(token)
|
|
136
|
+
|
|
137
|
+
if args.json:
|
|
138
|
+
print("\n" + json.dumps(results, indent=2, ensure_ascii=False))
|
|
139
|
+
|
|
140
|
+
sys.exit(0 if results["token_valid"] else 1)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
if __name__ == "__main__":
|
|
144
|
+
main()
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
TypeScript Project Diagnostic Script
|
|
4
|
+
Analyzes TypeScript projects for configuration, performance, and common issues.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
import os
|
|
10
|
+
import json
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
def run_cmd(cmd: str) -> str:
|
|
14
|
+
"""Run shell command and return output."""
|
|
15
|
+
try:
|
|
16
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
17
|
+
return result.stdout + result.stderr
|
|
18
|
+
except Exception as e:
|
|
19
|
+
return str(e)
|
|
20
|
+
|
|
21
|
+
def check_versions():
|
|
22
|
+
"""Check TypeScript and Node versions."""
|
|
23
|
+
print("\n📦 Versions:")
|
|
24
|
+
print("-" * 40)
|
|
25
|
+
|
|
26
|
+
ts_version = run_cmd("npx tsc --version 2>/dev/null").strip()
|
|
27
|
+
node_version = run_cmd("node -v 2>/dev/null").strip()
|
|
28
|
+
|
|
29
|
+
print(f" TypeScript: {ts_version or 'Not found'}")
|
|
30
|
+
print(f" Node.js: {node_version or 'Not found'}")
|
|
31
|
+
|
|
32
|
+
def check_tsconfig():
|
|
33
|
+
"""Analyze tsconfig.json settings."""
|
|
34
|
+
print("\n⚙️ TSConfig Analysis:")
|
|
35
|
+
print("-" * 40)
|
|
36
|
+
|
|
37
|
+
tsconfig_path = Path("tsconfig.json")
|
|
38
|
+
if not tsconfig_path.exists():
|
|
39
|
+
print("⚠️ tsconfig.json not found")
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
with open(tsconfig_path) as f:
|
|
44
|
+
config = json.load(f)
|
|
45
|
+
|
|
46
|
+
compiler_opts = config.get("compilerOptions", {})
|
|
47
|
+
|
|
48
|
+
# Check strict mode
|
|
49
|
+
if compiler_opts.get("strict"):
|
|
50
|
+
print("✅ Strict mode enabled")
|
|
51
|
+
else:
|
|
52
|
+
print("⚠️ Strict mode NOT enabled")
|
|
53
|
+
|
|
54
|
+
# Check important flags
|
|
55
|
+
flags = {
|
|
56
|
+
"noUncheckedIndexedAccess": "Unchecked index access protection",
|
|
57
|
+
"noImplicitOverride": "Implicit override protection",
|
|
58
|
+
"skipLibCheck": "Skip lib check (performance)",
|
|
59
|
+
"incremental": "Incremental compilation"
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for flag, desc in flags.items():
|
|
63
|
+
status = "✅" if compiler_opts.get(flag) else "⚪"
|
|
64
|
+
print(f" {status} {desc}: {compiler_opts.get(flag, 'not set')}")
|
|
65
|
+
|
|
66
|
+
# Check module settings
|
|
67
|
+
print(f"\n Module: {compiler_opts.get('module', 'not set')}")
|
|
68
|
+
print(f" Module Resolution: {compiler_opts.get('moduleResolution', 'not set')}")
|
|
69
|
+
print(f" Target: {compiler_opts.get('target', 'not set')}")
|
|
70
|
+
|
|
71
|
+
except json.JSONDecodeError:
|
|
72
|
+
print("❌ Invalid JSON in tsconfig.json")
|
|
73
|
+
|
|
74
|
+
def check_tooling():
|
|
75
|
+
"""Detect TypeScript tooling ecosystem."""
|
|
76
|
+
print("\n🛠️ Tooling Detection:")
|
|
77
|
+
print("-" * 40)
|
|
78
|
+
|
|
79
|
+
pkg_path = Path("package.json")
|
|
80
|
+
if not pkg_path.exists():
|
|
81
|
+
print("⚠️ package.json not found")
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
with open(pkg_path) as f:
|
|
86
|
+
pkg = json.load(f)
|
|
87
|
+
|
|
88
|
+
all_deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
|
|
89
|
+
|
|
90
|
+
tools = {
|
|
91
|
+
"biome": "Biome (linter/formatter)",
|
|
92
|
+
"eslint": "ESLint",
|
|
93
|
+
"prettier": "Prettier",
|
|
94
|
+
"vitest": "Vitest (testing)",
|
|
95
|
+
"jest": "Jest (testing)",
|
|
96
|
+
"turborepo": "Turborepo (monorepo)",
|
|
97
|
+
"turbo": "Turbo (monorepo)",
|
|
98
|
+
"nx": "Nx (monorepo)",
|
|
99
|
+
"lerna": "Lerna (monorepo)"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for tool, desc in tools.items():
|
|
103
|
+
for dep in all_deps:
|
|
104
|
+
if tool in dep.lower():
|
|
105
|
+
print(f" ✅ {desc}")
|
|
106
|
+
break
|
|
107
|
+
|
|
108
|
+
except json.JSONDecodeError:
|
|
109
|
+
print("❌ Invalid JSON in package.json")
|
|
110
|
+
|
|
111
|
+
def check_monorepo():
|
|
112
|
+
"""Check for monorepo configuration."""
|
|
113
|
+
print("\n📦 Monorepo Check:")
|
|
114
|
+
print("-" * 40)
|
|
115
|
+
|
|
116
|
+
indicators = [
|
|
117
|
+
("pnpm-workspace.yaml", "PNPM Workspace"),
|
|
118
|
+
("lerna.json", "Lerna"),
|
|
119
|
+
("nx.json", "Nx"),
|
|
120
|
+
("turbo.json", "Turborepo")
|
|
121
|
+
]
|
|
122
|
+
|
|
123
|
+
found = False
|
|
124
|
+
for file, name in indicators:
|
|
125
|
+
if Path(file).exists():
|
|
126
|
+
print(f" ✅ {name} detected")
|
|
127
|
+
found = True
|
|
128
|
+
|
|
129
|
+
if not found:
|
|
130
|
+
print(" ⚪ No monorepo configuration detected")
|
|
131
|
+
|
|
132
|
+
def check_type_errors():
|
|
133
|
+
"""Run quick type check."""
|
|
134
|
+
print("\n🔍 Type Check:")
|
|
135
|
+
print("-" * 40)
|
|
136
|
+
|
|
137
|
+
result = run_cmd("npx tsc --noEmit 2>&1 | head -20")
|
|
138
|
+
if "error TS" in result:
|
|
139
|
+
errors = result.count("error TS")
|
|
140
|
+
print(f" ❌ {errors}+ type errors found")
|
|
141
|
+
print(result[:500])
|
|
142
|
+
else:
|
|
143
|
+
print(" ✅ No type errors")
|
|
144
|
+
|
|
145
|
+
def check_any_usage():
|
|
146
|
+
"""Check for any type usage."""
|
|
147
|
+
print("\n⚠️ 'any' Type Usage:")
|
|
148
|
+
print("-" * 40)
|
|
149
|
+
|
|
150
|
+
result = run_cmd("grep -r ': any' --include='*.ts' --include='*.tsx' src/ 2>/dev/null | wc -l")
|
|
151
|
+
count = result.strip()
|
|
152
|
+
if count and count != "0":
|
|
153
|
+
print(f" ⚠️ Found {count} occurrences of ': any'")
|
|
154
|
+
sample = run_cmd("grep -rn ': any' --include='*.ts' --include='*.tsx' src/ 2>/dev/null | head -5")
|
|
155
|
+
if sample:
|
|
156
|
+
print(sample)
|
|
157
|
+
else:
|
|
158
|
+
print(" ✅ No explicit 'any' types found")
|
|
159
|
+
|
|
160
|
+
def check_type_assertions():
|
|
161
|
+
"""Check for type assertions."""
|
|
162
|
+
print("\n⚠️ Type Assertions (as):")
|
|
163
|
+
print("-" * 40)
|
|
164
|
+
|
|
165
|
+
result = run_cmd("grep -r ' as ' --include='*.ts' --include='*.tsx' src/ 2>/dev/null | grep -v 'import' | wc -l")
|
|
166
|
+
count = result.strip()
|
|
167
|
+
if count and count != "0":
|
|
168
|
+
print(f" ⚠️ Found {count} type assertions")
|
|
169
|
+
else:
|
|
170
|
+
print(" ✅ No type assertions found")
|
|
171
|
+
|
|
172
|
+
def check_performance():
|
|
173
|
+
"""Check type checking performance."""
|
|
174
|
+
print("\n⏱️ Type Check Performance:")
|
|
175
|
+
print("-" * 40)
|
|
176
|
+
|
|
177
|
+
result = run_cmd("npx tsc --extendedDiagnostics --noEmit 2>&1 | grep -E 'Check time|Files:|Lines:|Nodes:'")
|
|
178
|
+
if result.strip():
|
|
179
|
+
for line in result.strip().split('\n'):
|
|
180
|
+
print(f" {line}")
|
|
181
|
+
else:
|
|
182
|
+
print(" ⚠️ Could not measure performance")
|
|
183
|
+
|
|
184
|
+
def main():
|
|
185
|
+
print("=" * 50)
|
|
186
|
+
print("🔍 TypeScript Project Diagnostic Report")
|
|
187
|
+
print("=" * 50)
|
|
188
|
+
|
|
189
|
+
check_versions()
|
|
190
|
+
check_tsconfig()
|
|
191
|
+
check_tooling()
|
|
192
|
+
check_monorepo()
|
|
193
|
+
check_any_usage()
|
|
194
|
+
check_type_assertions()
|
|
195
|
+
check_type_errors()
|
|
196
|
+
check_performance()
|
|
197
|
+
|
|
198
|
+
print("\n" + "=" * 50)
|
|
199
|
+
print("✅ Diagnostic Complete")
|
|
200
|
+
print("=" * 50)
|
|
201
|
+
|
|
202
|
+
if __name__ == "__main__":
|
|
203
|
+
main()
|
|
Binary file
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
UI/UX Pro Max Core - BM25 search engine for UI/UX style guides
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import csv
|
|
8
|
+
import re
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from math import log
|
|
11
|
+
from collections import defaultdict
|
|
12
|
+
|
|
13
|
+
# ============ CONFIGURATION ============
|
|
14
|
+
DATA_DIR = Path(__file__).parent.parent / "data"
|
|
15
|
+
MAX_RESULTS = 3
|
|
16
|
+
|
|
17
|
+
CSV_CONFIG = {
|
|
18
|
+
"style": {
|
|
19
|
+
"file": "styles.csv",
|
|
20
|
+
"search_cols": ["Style Category", "Keywords", "Best For", "Type"],
|
|
21
|
+
"output_cols": ["Style Category", "Type", "Keywords", "Primary Colors", "Effects & Animation", "Best For", "Performance", "Accessibility", "Framework Compatibility", "Complexity"]
|
|
22
|
+
},
|
|
23
|
+
"prompt": {
|
|
24
|
+
"file": "prompts.csv",
|
|
25
|
+
"search_cols": ["Style Category", "AI Prompt Keywords (Copy-Paste Ready)", "CSS/Technical Keywords"],
|
|
26
|
+
"output_cols": ["Style Category", "AI Prompt Keywords (Copy-Paste Ready)", "CSS/Technical Keywords", "Implementation Checklist"]
|
|
27
|
+
},
|
|
28
|
+
"color": {
|
|
29
|
+
"file": "colors.csv",
|
|
30
|
+
"search_cols": ["Product Type", "Keywords", "Notes"],
|
|
31
|
+
"output_cols": ["Product Type", "Keywords", "Primary (Hex)", "Secondary (Hex)", "CTA (Hex)", "Background (Hex)", "Text (Hex)", "Border (Hex)", "Notes"]
|
|
32
|
+
},
|
|
33
|
+
"chart": {
|
|
34
|
+
"file": "charts.csv",
|
|
35
|
+
"search_cols": ["Data Type", "Keywords", "Best Chart Type", "Accessibility Notes"],
|
|
36
|
+
"output_cols": ["Data Type", "Keywords", "Best Chart Type", "Secondary Options", "Color Guidance", "Accessibility Notes", "Library Recommendation", "Interactive Level"]
|
|
37
|
+
},
|
|
38
|
+
"landing": {
|
|
39
|
+
"file": "landing.csv",
|
|
40
|
+
"search_cols": ["Pattern Name", "Keywords", "Conversion Optimization", "Section Order"],
|
|
41
|
+
"output_cols": ["Pattern Name", "Keywords", "Section Order", "Primary CTA Placement", "Color Strategy", "Conversion Optimization"]
|
|
42
|
+
},
|
|
43
|
+
"product": {
|
|
44
|
+
"file": "products.csv",
|
|
45
|
+
"search_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Key Considerations"],
|
|
46
|
+
"output_cols": ["Product Type", "Keywords", "Primary Style Recommendation", "Secondary Styles", "Landing Page Pattern", "Dashboard Style (if applicable)", "Color Palette Focus"]
|
|
47
|
+
},
|
|
48
|
+
"ux": {
|
|
49
|
+
"file": "ux-guidelines.csv",
|
|
50
|
+
"search_cols": ["Category", "Issue", "Description", "Platform"],
|
|
51
|
+
"output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
|
|
52
|
+
},
|
|
53
|
+
"typography": {
|
|
54
|
+
"file": "typography.csv",
|
|
55
|
+
"search_cols": ["Font Pairing Name", "Category", "Mood/Style Keywords", "Best For", "Heading Font", "Body Font"],
|
|
56
|
+
"output_cols": ["Font Pairing Name", "Category", "Heading Font", "Body Font", "Mood/Style Keywords", "Best For", "Google Fonts URL", "CSS Import", "Tailwind Config", "Notes"]
|
|
57
|
+
},
|
|
58
|
+
"icons": {
|
|
59
|
+
"file": "icons.csv",
|
|
60
|
+
"search_cols": ["Category", "Icon Name", "Keywords", "Best For"],
|
|
61
|
+
"output_cols": ["Category", "Icon Name", "Keywords", "Library", "Import Code", "Usage", "Best For", "Style"]
|
|
62
|
+
},
|
|
63
|
+
"react": {
|
|
64
|
+
"file": "react-performance.csv",
|
|
65
|
+
"search_cols": ["Category", "Issue", "Keywords", "Description"],
|
|
66
|
+
"output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
|
|
67
|
+
},
|
|
68
|
+
"web": {
|
|
69
|
+
"file": "web-interface.csv",
|
|
70
|
+
"search_cols": ["Category", "Issue", "Keywords", "Description"],
|
|
71
|
+
"output_cols": ["Category", "Issue", "Platform", "Description", "Do", "Don't", "Code Example Good", "Code Example Bad", "Severity"]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
STACK_CONFIG = {
|
|
76
|
+
"html-tailwind": {"file": "stacks/html-tailwind.csv"},
|
|
77
|
+
"react": {"file": "stacks/react.csv"},
|
|
78
|
+
"nextjs": {"file": "stacks/nextjs.csv"},
|
|
79
|
+
"vue": {"file": "stacks/vue.csv"},
|
|
80
|
+
"nuxtjs": {"file": "stacks/nuxtjs.csv"},
|
|
81
|
+
"nuxt-ui": {"file": "stacks/nuxt-ui.csv"},
|
|
82
|
+
"svelte": {"file": "stacks/svelte.csv"},
|
|
83
|
+
"swiftui": {"file": "stacks/swiftui.csv"},
|
|
84
|
+
"react-native": {"file": "stacks/react-native.csv"},
|
|
85
|
+
"flutter": {"file": "stacks/flutter.csv"},
|
|
86
|
+
"shadcn": {"file": "stacks/shadcn.csv"}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Common columns for all stacks
|
|
90
|
+
_STACK_COLS = {
|
|
91
|
+
"search_cols": ["Category", "Guideline", "Description", "Do", "Don't"],
|
|
92
|
+
"output_cols": ["Category", "Guideline", "Description", "Do", "Don't", "Code Good", "Code Bad", "Severity", "Docs URL"]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
AVAILABLE_STACKS = list(STACK_CONFIG.keys())
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# ============ BM25 IMPLEMENTATION ============
|
|
99
|
+
class BM25:
|
|
100
|
+
"""BM25 ranking algorithm for text search"""
|
|
101
|
+
|
|
102
|
+
def __init__(self, k1=1.5, b=0.75):
|
|
103
|
+
self.k1 = k1
|
|
104
|
+
self.b = b
|
|
105
|
+
self.corpus = []
|
|
106
|
+
self.doc_lengths = []
|
|
107
|
+
self.avgdl = 0
|
|
108
|
+
self.idf = {}
|
|
109
|
+
self.doc_freqs = defaultdict(int)
|
|
110
|
+
self.N = 0
|
|
111
|
+
|
|
112
|
+
def tokenize(self, text):
|
|
113
|
+
"""Lowercase, split, remove punctuation, filter short words"""
|
|
114
|
+
text = re.sub(r'[^\w\s]', ' ', str(text).lower())
|
|
115
|
+
return [w for w in text.split() if len(w) > 2]
|
|
116
|
+
|
|
117
|
+
def fit(self, documents):
|
|
118
|
+
"""Build BM25 index from documents"""
|
|
119
|
+
self.corpus = [self.tokenize(doc) for doc in documents]
|
|
120
|
+
self.N = len(self.corpus)
|
|
121
|
+
if self.N == 0:
|
|
122
|
+
return
|
|
123
|
+
self.doc_lengths = [len(doc) for doc in self.corpus]
|
|
124
|
+
self.avgdl = sum(self.doc_lengths) / self.N
|
|
125
|
+
|
|
126
|
+
for doc in self.corpus:
|
|
127
|
+
seen = set()
|
|
128
|
+
for word in doc:
|
|
129
|
+
if word not in seen:
|
|
130
|
+
self.doc_freqs[word] += 1
|
|
131
|
+
seen.add(word)
|
|
132
|
+
|
|
133
|
+
for word, freq in self.doc_freqs.items():
|
|
134
|
+
self.idf[word] = log((self.N - freq + 0.5) / (freq + 0.5) + 1)
|
|
135
|
+
|
|
136
|
+
def score(self, query):
|
|
137
|
+
"""Score all documents against query"""
|
|
138
|
+
query_tokens = self.tokenize(query)
|
|
139
|
+
scores = []
|
|
140
|
+
|
|
141
|
+
for idx, doc in enumerate(self.corpus):
|
|
142
|
+
score = 0
|
|
143
|
+
doc_len = self.doc_lengths[idx]
|
|
144
|
+
term_freqs = defaultdict(int)
|
|
145
|
+
for word in doc:
|
|
146
|
+
term_freqs[word] += 1
|
|
147
|
+
|
|
148
|
+
for token in query_tokens:
|
|
149
|
+
if token in self.idf:
|
|
150
|
+
tf = term_freqs[token]
|
|
151
|
+
idf = self.idf[token]
|
|
152
|
+
numerator = tf * (self.k1 + 1)
|
|
153
|
+
denominator = tf + self.k1 * (1 - self.b + self.b * doc_len / self.avgdl)
|
|
154
|
+
score += idf * numerator / denominator
|
|
155
|
+
|
|
156
|
+
scores.append((idx, score))
|
|
157
|
+
|
|
158
|
+
return sorted(scores, key=lambda x: x[1], reverse=True)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# ============ SEARCH FUNCTIONS ============
|
|
162
|
+
def _load_csv(filepath):
|
|
163
|
+
"""Load CSV and return list of dicts"""
|
|
164
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
165
|
+
return list(csv.DictReader(f))
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _search_csv(filepath, search_cols, output_cols, query, max_results):
|
|
169
|
+
"""Core search function using BM25"""
|
|
170
|
+
if not filepath.exists():
|
|
171
|
+
return []
|
|
172
|
+
|
|
173
|
+
data = _load_csv(filepath)
|
|
174
|
+
|
|
175
|
+
# Build documents from search columns
|
|
176
|
+
documents = [" ".join(str(row.get(col, "")) for col in search_cols) for row in data]
|
|
177
|
+
|
|
178
|
+
# BM25 search
|
|
179
|
+
bm25 = BM25()
|
|
180
|
+
bm25.fit(documents)
|
|
181
|
+
ranked = bm25.score(query)
|
|
182
|
+
|
|
183
|
+
# Get top results with score > 0
|
|
184
|
+
results = []
|
|
185
|
+
for idx, score in ranked[:max_results]:
|
|
186
|
+
if score > 0:
|
|
187
|
+
row = data[idx]
|
|
188
|
+
results.append({col: row.get(col, "") for col in output_cols if col in row})
|
|
189
|
+
|
|
190
|
+
return results
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def detect_domain(query):
|
|
194
|
+
"""Auto-detect the most relevant domain from query"""
|
|
195
|
+
query_lower = query.lower()
|
|
196
|
+
|
|
197
|
+
domain_keywords = {
|
|
198
|
+
"color": ["color", "palette", "hex", "#", "rgb"],
|
|
199
|
+
"chart": ["chart", "graph", "visualization", "trend", "bar", "pie", "scatter", "heatmap", "funnel"],
|
|
200
|
+
"landing": ["landing", "page", "cta", "conversion", "hero", "testimonial", "pricing", "section"],
|
|
201
|
+
"product": ["saas", "ecommerce", "e-commerce", "fintech", "healthcare", "gaming", "portfolio", "crypto", "dashboard"],
|
|
202
|
+
"prompt": ["prompt", "css", "implementation", "variable", "checklist", "tailwind"],
|
|
203
|
+
"style": ["style", "design", "ui", "minimalism", "glassmorphism", "neumorphism", "brutalism", "dark mode", "flat", "aurora"],
|
|
204
|
+
"ux": ["ux", "usability", "accessibility", "wcag", "touch", "scroll", "animation", "keyboard", "navigation", "mobile"],
|
|
205
|
+
"typography": ["font", "typography", "heading", "serif", "sans"],
|
|
206
|
+
"icons": ["icon", "icons", "lucide", "heroicons", "symbol", "glyph", "pictogram", "svg icon"],
|
|
207
|
+
"react": ["react", "next.js", "nextjs", "suspense", "memo", "usecallback", "useeffect", "rerender", "bundle", "waterfall", "barrel", "dynamic import", "rsc", "server component"],
|
|
208
|
+
"web": ["aria", "focus", "outline", "semantic", "virtualize", "autocomplete", "form", "input type", "preconnect"]
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
scores = {domain: sum(1 for kw in keywords if kw in query_lower) for domain, keywords in domain_keywords.items()}
|
|
212
|
+
best = max(scores, key=scores.get)
|
|
213
|
+
return best if scores[best] > 0 else "style"
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def search(query, domain=None, max_results=MAX_RESULTS):
|
|
217
|
+
"""Main search function with auto-domain detection"""
|
|
218
|
+
if domain is None:
|
|
219
|
+
domain = detect_domain(query)
|
|
220
|
+
|
|
221
|
+
config = CSV_CONFIG.get(domain, CSV_CONFIG["style"])
|
|
222
|
+
filepath = DATA_DIR / config["file"]
|
|
223
|
+
|
|
224
|
+
if not filepath.exists():
|
|
225
|
+
return {"error": f"File not found: {filepath}", "domain": domain}
|
|
226
|
+
|
|
227
|
+
results = _search_csv(filepath, config["search_cols"], config["output_cols"], query, max_results)
|
|
228
|
+
|
|
229
|
+
return {
|
|
230
|
+
"domain": domain,
|
|
231
|
+
"query": query,
|
|
232
|
+
"file": config["file"],
|
|
233
|
+
"count": len(results),
|
|
234
|
+
"results": results
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def search_stack(query, stack, max_results=MAX_RESULTS):
|
|
239
|
+
"""Search stack-specific guidelines"""
|
|
240
|
+
if stack not in STACK_CONFIG:
|
|
241
|
+
return {"error": f"Unknown stack: {stack}. Available: {', '.join(AVAILABLE_STACKS)}"}
|
|
242
|
+
|
|
243
|
+
filepath = DATA_DIR / STACK_CONFIG[stack]["file"]
|
|
244
|
+
|
|
245
|
+
if not filepath.exists():
|
|
246
|
+
return {"error": f"Stack file not found: {filepath}", "stack": stack}
|
|
247
|
+
|
|
248
|
+
results = _search_csv(filepath, _STACK_COLS["search_cols"], _STACK_COLS["output_cols"], query, max_results)
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
"domain": "stack",
|
|
252
|
+
"stack": stack,
|
|
253
|
+
"query": query,
|
|
254
|
+
"file": STACK_CONFIG[stack]["file"],
|
|
255
|
+
"count": len(results),
|
|
256
|
+
"results": results
|
|
257
|
+
}
|