rsc-universal 0.1.1
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/LICENSE +21 -0
- package/README.md +279 -0
- package/manifest.json +4761 -0
- package/package.json +59 -0
- package/schema/frontmatter.schema.json +12 -0
- package/scripts/build-manifest.js +72 -0
- package/scripts/consult.js +106 -0
- package/scripts/detect-repo.js +118 -0
- package/scripts/doctor.js +21 -0
- package/scripts/eval-lint.sh +179 -0
- package/scripts/install-apply.js +52 -0
- package/scripts/install-plan.js +13 -0
- package/scripts/lib/behavior-score.js +103 -0
- package/scripts/lib/frontmatter.js +47 -0
- package/scripts/lib/harden-policy.js +41 -0
- package/scripts/lib/manifest.js +18 -0
- package/scripts/lib/recommend.js +36 -0
- package/scripts/lib/registry.js +110 -0
- package/scripts/lib/result-envelope.js +35 -0
- package/scripts/lib/state.js +12 -0
- package/scripts/lib/ui.js +17 -0
- package/scripts/reviewer-guard.sh +67 -0
- package/scripts/rsc.js +108 -0
- package/scripts/skill-behavior-eval.js +33 -0
- package/scripts/skill-behavior-eval.workflow.js +136 -0
- package/scripts/skill-behavior-rubric.md +63 -0
- package/scripts/skill-harden-rubric.md +40 -0
- package/scripts/skill-harden.workflow.js +161 -0
- package/scripts/skill-rubric.md +39 -0
- package/scripts/skill-scoreboard.workflow.js +35 -0
- package/skills/ab-testing/SKILL.md +191 -0
- package/skills/ab-testing/evals/README.md +8 -0
- package/skills/ab-testing/evals/cases.yaml +49 -0
- package/skills/ab-testing/references/pitfalls.md +74 -0
- package/skills/ab-testing/references/sample-size-and-cuped.md +128 -0
- package/skills/ab-testing/scripts/verify.sh +89 -0
- package/skills/accessibility/SKILL.md +218 -0
- package/skills/accessibility/evals/README.md +3 -0
- package/skills/accessibility/evals/cases.yaml +47 -0
- package/skills/accessibility/references/aria-patterns.md +113 -0
- package/skills/accessibility/references/wcag22-checklist.md +83 -0
- package/skills/accessibility/scripts/verify.sh +103 -0
- package/skills/ads/SKILL.md +175 -0
- package/skills/ads/evals/README.md +15 -0
- package/skills/ads/evals/cases.yaml +58 -0
- package/skills/ads/references/platform-specs.md +73 -0
- package/skills/ads/references/roas-model.md +77 -0
- package/skills/ads/scripts/verify.sh +210 -0
- package/skills/agent-eval/SKILL.md +213 -0
- package/skills/agent-eval/evals/README.md +12 -0
- package/skills/agent-eval/evals/cases.yaml +45 -0
- package/skills/agent-eval/references/judge-design.md +118 -0
- package/skills/agent-eval/references/runner-and-gate.md +183 -0
- package/skills/agent-eval/scripts/verify.sh +161 -0
- package/skills/agent-safety/SKILL.md +176 -0
- package/skills/agent-safety/evals/README.md +12 -0
- package/skills/agent-safety/evals/cases.yaml +46 -0
- package/skills/agent-safety/references/threat-model.md +51 -0
- package/skills/ai-media/SKILL.md +196 -0
- package/skills/ai-media/evals/README.md +3 -0
- package/skills/ai-media/evals/cases.yaml +45 -0
- package/skills/ai-media/references/ffmpeg-assembly.md +117 -0
- package/skills/ai-media/references/models-and-params.md +78 -0
- package/skills/ai-media/scripts/verify.sh +103 -0
- package/skills/analytics/SKILL.md +219 -0
- package/skills/analytics/evals/README.md +9 -0
- package/skills/analytics/evals/cases.yaml +53 -0
- package/skills/analytics/references/event-taxonomy.md +75 -0
- package/skills/analytics/references/ga4-setup.md +122 -0
- package/skills/analytics/references/posthog-setup.md +100 -0
- package/skills/analytics/scripts/verify.sh +95 -0
- package/skills/analyze/SKILL.md +136 -0
- package/skills/analyze/evals/README.md +72 -0
- package/skills/analyze/evals/cases.yaml +74 -0
- package/skills/angular/SKILL.md +288 -0
- package/skills/angular/evals/README.md +3 -0
- package/skills/angular/evals/cases.yaml +38 -0
- package/skills/angular/references/migration.md +81 -0
- package/skills/angular/references/signals-rxjs.md +92 -0
- package/skills/angular/scripts/verify.sh +122 -0
- package/skills/api-connector-builder/SKILL.md +285 -0
- package/skills/api-connector-builder/evals/README.md +11 -0
- package/skills/api-connector-builder/evals/cases.yaml +47 -0
- package/skills/api-connector-builder/references/auth-flows.md +132 -0
- package/skills/api-connector-builder/references/pagination.md +144 -0
- package/skills/api-connector-builder/scripts/verify.sh +172 -0
- package/skills/api-design/SKILL.md +189 -0
- package/skills/api-design/evals/README.md +3 -0
- package/skills/api-design/evals/cases.yaml +45 -0
- package/skills/api-design/references/graphql-design.md +70 -0
- package/skills/api-design/references/openapi-contract.md +86 -0
- package/skills/api-design/references/rest-conventions.md +63 -0
- package/skills/api-design/references/versioning-and-evolution.md +49 -0
- package/skills/api-design/scripts/verify.sh +138 -0
- package/skills/article-writing/SKILL.md +175 -0
- package/skills/article-writing/evals/README.md +3 -0
- package/skills/article-writing/evals/cases.yaml +47 -0
- package/skills/article-writing/references/ai-tell-banlist.md +114 -0
- package/skills/article-writing/references/on-page-seo.md +133 -0
- package/skills/article-writing/scripts/verify.sh +165 -0
- package/skills/astro/SKILL.md +275 -0
- package/skills/astro/evals/README.md +3 -0
- package/skills/astro/evals/cases.yaml +41 -0
- package/skills/astro/references/content-layer.md +118 -0
- package/skills/astro/references/deploy-and-integrations.md +163 -0
- package/skills/astro/scripts/verify.sh +137 -0
- package/skills/author-skill/SKILL.md +206 -0
- package/skills/author-skill/evals/README.md +66 -0
- package/skills/author-skill/evals/cases.yaml +75 -0
- package/skills/author-skill/references/description-recipe.md +84 -0
- package/skills/author-skill/references/eval-authoring.md +74 -0
- package/skills/author-skill/references/rsc-conventions.md +91 -0
- package/skills/automation-flows/SKILL.md +132 -0
- package/skills/automation-flows/evals/README.md +5 -0
- package/skills/automation-flows/evals/cases.yaml +44 -0
- package/skills/automation-flows/references/error-handling.md +58 -0
- package/skills/automation-flows/references/n8n-workflow-json.md +63 -0
- package/skills/automation-flows/scripts/verify.sh +78 -0
- package/skills/aws-essentials/SKILL.md +223 -0
- package/skills/aws-essentials/evals/README.md +10 -0
- package/skills/aws-essentials/evals/cases.yaml +44 -0
- package/skills/aws-essentials/references/iam-least-privilege.md +134 -0
- package/skills/aws-essentials/references/rds-cloudfront-recipes.md +127 -0
- package/skills/aws-essentials/scripts/verify.sh +99 -0
- package/skills/backups/SKILL.md +137 -0
- package/skills/backups/evals/README.md +3 -0
- package/skills/backups/evals/cases.yaml +42 -0
- package/skills/backups/references/engine-recipes.md +121 -0
- package/skills/backups/references/restore-runbook.md +65 -0
- package/skills/backups/scripts/verify.sh +80 -0
- package/skills/bash-scripting/SKILL.md +231 -0
- package/skills/bash-scripting/evals/README.md +3 -0
- package/skills/bash-scripting/evals/cases.yaml +45 -0
- package/skills/bash-scripting/references/portability.md +97 -0
- package/skills/bash-scripting/scripts/verify.sh +140 -0
- package/skills/bookkeeping/SKILL.md +184 -0
- package/skills/bookkeeping/evals/README.md +5 -0
- package/skills/bookkeeping/evals/cases.yaml +52 -0
- package/skills/bookkeeping/references/chart-of-accounts.md +87 -0
- package/skills/bookkeeping/references/reconciliation-playbook.md +54 -0
- package/skills/bookkeeping/references/tricky-transactions.md +192 -0
- package/skills/brand-identity/SKILL.md +161 -0
- package/skills/brand-identity/evals/README.md +14 -0
- package/skills/brand-identity/evals/cases.yaml +43 -0
- package/skills/brand-identity/references/color-and-tokens.md +129 -0
- package/skills/brand-identity/references/logo-and-assets.md +117 -0
- package/skills/brand-identity/scripts/verify.sh +224 -0
- package/skills/brand-voice/SKILL.md +183 -0
- package/skills/brand-voice/evals/README.md +3 -0
- package/skills/brand-voice/evals/cases.yaml +57 -0
- package/skills/brand-voice/references/voice-guide-template.md +150 -0
- package/skills/brand-voice/references/word-bank.md +61 -0
- package/skills/brand-voice/scripts/verify.sh +190 -0
- package/skills/building-agents/SKILL.md +469 -0
- package/skills/building-agents/evals/README.md +68 -0
- package/skills/building-agents/evals/cases.yaml +60 -0
- package/skills/building-agents/references/agent-loops-and-harness.md +371 -0
- package/skills/building-agents/references/evals-and-observability.md +420 -0
- package/skills/building-agents/references/mcp-servers.md +294 -0
- package/skills/building-agents/references/provider-abstraction.md +489 -0
- package/skills/building-agents/references/tools-and-rag.md +417 -0
- package/skills/building-agents/scripts/verify.sh +121 -0
- package/skills/business-intelligence/SKILL.md +176 -0
- package/skills/business-intelligence/evals/README.md +3 -0
- package/skills/business-intelligence/evals/cases.yaml +43 -0
- package/skills/business-intelligence/references/authoring-semantic-models.md +120 -0
- package/skills/business-intelligence/references/wiring-agents-and-apis.md +79 -0
- package/skills/business-intelligence/scripts/verify.sh +143 -0
- package/skills/calendar-scheduling/SKILL.md +196 -0
- package/skills/calendar-scheduling/evals/README.md +14 -0
- package/skills/calendar-scheduling/evals/cases.yaml +45 -0
- package/skills/calendar-scheduling/references/google-calendar-sync.md +78 -0
- package/skills/calendar-scheduling/references/provider-matrix.md +71 -0
- package/skills/calendar-scheduling/scripts/verify.sh +117 -0
- package/skills/case-studies/SKILL.md +147 -0
- package/skills/case-studies/evals/README.md +3 -0
- package/skills/case-studies/evals/cases.yaml +63 -0
- package/skills/case-studies/references/case-study-skeleton.md +90 -0
- package/skills/case-studies/references/consent-and-substantiation.md +80 -0
- package/skills/case-studies/scripts/verify.sh +161 -0
- package/skills/chatbot/SKILL.md +168 -0
- package/skills/chatbot/evals/README.md +13 -0
- package/skills/chatbot/evals/cases.yaml +43 -0
- package/skills/chatbot/references/handoff-and-sales.md +71 -0
- package/skills/chatbot/references/system-prompt-and-guardrails.md +78 -0
- package/skills/chatbot/scripts/verify.sh +162 -0
- package/skills/chrome-extension/SKILL.md +169 -0
- package/skills/chrome-extension/evals/README.md +12 -0
- package/skills/chrome-extension/evals/cases.yaml +40 -0
- package/skills/chrome-extension/references/store-and-migration.md +84 -0
- package/skills/chrome-extension/scripts/verify.sh +62 -0
- package/skills/clarify/SKILL.md +159 -0
- package/skills/clarify/evals/README.md +70 -0
- package/skills/clarify/evals/cases.yaml +71 -0
- package/skills/clickhouse-analytics/SKILL.md +165 -0
- package/skills/clickhouse-analytics/evals/README.md +3 -0
- package/skills/clickhouse-analytics/evals/cases.yaml +45 -0
- package/skills/clickhouse-analytics/references/ingestion-and-mvs.md +109 -0
- package/skills/clickhouse-analytics/references/query-optimization.md +76 -0
- package/skills/clickhouse-analytics/references/schema-and-engines.md +63 -0
- package/skills/clickhouse-analytics/scripts/verify.sh +109 -0
- package/skills/client-onboarding/SKILL.md +254 -0
- package/skills/client-onboarding/evals/README.md +14 -0
- package/skills/client-onboarding/evals/cases.yaml +40 -0
- package/skills/client-onboarding/references/onboarding-playbook.md +126 -0
- package/skills/cloudflare/SKILL.md +191 -0
- package/skills/cloudflare/evals/README.md +15 -0
- package/skills/cloudflare/evals/cases.yaml +46 -0
- package/skills/cloudflare/references/storage-primitives.md +104 -0
- package/skills/cloudflare/references/wrangler-config.md +91 -0
- package/skills/cloudflare/scripts/verify.sh +133 -0
- package/skills/code-review/SKILL.md +143 -0
- package/skills/code-review/evals/README.md +3 -0
- package/skills/code-review/evals/cases.yaml +55 -0
- package/skills/code-review/references/pr-workflow.md +67 -0
- package/skills/codebase-onboarding/SKILL.md +133 -0
- package/skills/codebase-onboarding/evals/README.md +3 -0
- package/skills/codebase-onboarding/evals/cases.yaml +69 -0
- package/skills/codebase-onboarding/references/recon-playbook.md +57 -0
- package/skills/codebase-onboarding/scripts/verify.sh +54 -0
- package/skills/cold-outreach/SKILL.md +206 -0
- package/skills/cold-outreach/evals/README.md +3 -0
- package/skills/cold-outreach/evals/cases.yaml +60 -0
- package/skills/cold-outreach/references/compliance-footer.md +50 -0
- package/skills/cold-outreach/references/hook-derivation.md +73 -0
- package/skills/cold-outreach/references/templates.md +88 -0
- package/skills/cold-outreach/scripts/verify.sh +170 -0
- package/skills/community/SKILL.md +225 -0
- package/skills/community/evals/README.md +3 -0
- package/skills/community/evals/cases.yaml +40 -0
- package/skills/community/references/metrics-and-rituals.md +58 -0
- package/skills/community/references/platform-playbooks.md +64 -0
- package/skills/community/scripts/verify.sh +83 -0
- package/skills/competitor-watch/SKILL.md +193 -0
- package/skills/competitor-watch/evals/README.md +19 -0
- package/skills/competitor-watch/evals/cases.yaml +54 -0
- package/skills/competitor-watch/references/monitoring-config.md +124 -0
- package/skills/competitor-watch/references/tracker-schema.md +79 -0
- package/skills/competitor-watch/scripts/verify.sh +253 -0
- package/skills/compliance/SKILL.md +184 -0
- package/skills/compliance/evals/README.md +14 -0
- package/skills/compliance/evals/cases.yaml +46 -0
- package/skills/compliance/references/frameworks.md +108 -0
- package/skills/compliance/references/operating-rhythm.md +79 -0
- package/skills/compliance/scripts/verify.sh +168 -0
- package/skills/compose-multiplatform/SKILL.md +198 -0
- package/skills/compose-multiplatform/evals/README.md +3 -0
- package/skills/compose-multiplatform/evals/cases.yaml +40 -0
- package/skills/compose-multiplatform/references/ios-interop.md +91 -0
- package/skills/compose-multiplatform/references/project-setup.md +96 -0
- package/skills/compose-multiplatform/scripts/verify.sh +123 -0
- package/skills/constitution/SKILL.md +160 -0
- package/skills/constitution/evals/README.md +68 -0
- package/skills/constitution/evals/cases.yaml +72 -0
- package/skills/constitution/references/constitution-template.md +90 -0
- package/skills/content-engine/SKILL.md +164 -0
- package/skills/content-engine/evals/README.md +17 -0
- package/skills/content-engine/evals/cases.yaml +62 -0
- package/skills/content-engine/references/atomization.md +81 -0
- package/skills/content-engine/references/brief-and-pipeline.md +90 -0
- package/skills/content-engine/scripts/verify.sh +146 -0
- package/skills/context-budget/SKILL.md +132 -0
- package/skills/context-budget/evals/README.md +11 -0
- package/skills/context-budget/evals/cases.yaml +40 -0
- package/skills/context-budget/references/handoff-and-compaction.md +96 -0
- package/skills/continuous-learning/SKILL.md +136 -0
- package/skills/continuous-learning/evals/README.md +16 -0
- package/skills/continuous-learning/evals/cases.yaml +39 -0
- package/skills/continuous-learning/references/lesson-routing.md +106 -0
- package/skills/contracts/SKILL.md +124 -0
- package/skills/contracts/evals/README.md +3 -0
- package/skills/contracts/evals/cases.yaml +42 -0
- package/skills/contracts/references/clause-library.md +129 -0
- package/skills/contracts/references/review-playbook.md +49 -0
- package/skills/contracts/scripts/verify.sh +53 -0
- package/skills/coolify/SKILL.md +201 -0
- package/skills/coolify/evals/README.md +21 -0
- package/skills/coolify/evals/cases.yaml +46 -0
- package/skills/coolify/references/databases-and-backups.md +99 -0
- package/skills/coolify/references/deploy-recipes.md +105 -0
- package/skills/coolify/references/install-and-proxy.md +80 -0
- package/skills/coolify/scripts/verify.sh +123 -0
- package/skills/cost-tracking/SKILL.md +183 -0
- package/skills/cost-tracking/evals/README.md +3 -0
- package/skills/cost-tracking/evals/cases.yaml +45 -0
- package/skills/cost-tracking/references/cloud-caps.md +52 -0
- package/skills/cost-tracking/references/pricing-tables.md +51 -0
- package/skills/cost-tracking/scripts/verify.sh +135 -0
- package/skills/course-builder/SKILL.md +186 -0
- package/skills/course-builder/evals/README.md +16 -0
- package/skills/course-builder/evals/cases.yaml +49 -0
- package/skills/course-builder/references/assessment-design.md +74 -0
- package/skills/course-builder/references/grounding-and-scoping.md +69 -0
- package/skills/course-builder/references/outcomes-and-blooms.md +82 -0
- package/skills/course-builder/scripts/verify.sh +247 -0
- package/skills/course-storytelling/SKILL.md +205 -0
- package/skills/course-storytelling/evals/README.md +54 -0
- package/skills/course-storytelling/evals/cases.yaml +50 -0
- package/skills/course-storytelling/references/brunson-frameworks.md +190 -0
- package/skills/course-storytelling/references/concept-landing-recipe.md +136 -0
- package/skills/course-storytelling/references/course-analysis.md +124 -0
- package/skills/course-storytelling/references/learner-grounding.md +183 -0
- package/skills/course-storytelling/references/mental-models.md +115 -0
- package/skills/course-storytelling/scripts/verify.sh +223 -0
- package/skills/cpp/SKILL.md +349 -0
- package/skills/cpp/evals/README.md +14 -0
- package/skills/cpp/evals/cases.yaml +44 -0
- package/skills/cpp/references/cmake.md +167 -0
- package/skills/cpp/references/move-and-templates.md +130 -0
- package/skills/cpp/references/undefined-behavior.md +86 -0
- package/skills/cpp/scripts/verify.sh +165 -0
- package/skills/csharp-dotnet/SKILL.md +291 -0
- package/skills/csharp-dotnet/evals/README.md +3 -0
- package/skills/csharp-dotnet/evals/cases.yaml +48 -0
- package/skills/csharp-dotnet/references/aspnetcore.md +99 -0
- package/skills/csharp-dotnet/references/async.md +82 -0
- package/skills/csharp-dotnet/references/efcore.md +96 -0
- package/skills/csharp-dotnet/scripts/verify.sh +90 -0
- package/skills/customer-support/SKILL.md +193 -0
- package/skills/customer-support/evals/README.md +13 -0
- package/skills/customer-support/evals/cases.yaml +61 -0
- package/skills/customer-support/references/macros-and-sla.md +142 -0
- package/skills/dashboard/SKILL.md +205 -0
- package/skills/dashboard/evals/README.md +3 -0
- package/skills/dashboard/evals/cases.yaml +50 -0
- package/skills/dashboard/references/chart-selection.md +34 -0
- package/skills/dashboard/references/tile-schema.md +164 -0
- package/skills/dashboard/scripts/verify.sh +130 -0
- package/skills/data-cleaning/SKILL.md +285 -0
- package/skills/data-cleaning/evals/README.md +16 -0
- package/skills/data-cleaning/evals/cases.yaml +57 -0
- package/skills/data-cleaning/references/normalization-recipes.md +136 -0
- package/skills/data-cleaning/references/validation-patterns.md +134 -0
- package/skills/data-cleaning/scripts/verify.sh +115 -0
- package/skills/data-policy/SKILL.md +163 -0
- package/skills/data-policy/evals/README.md +15 -0
- package/skills/data-policy/evals/cases.yaml +44 -0
- package/skills/data-policy/references/consent-and-ropa.md +97 -0
- package/skills/data-policy/references/retention-schedule.md +83 -0
- package/skills/data-policy/scripts/verify.sh +143 -0
- package/skills/data-scraper/SKILL.md +134 -0
- package/skills/data-scraper/evals/README.md +3 -0
- package/skills/data-scraper/evals/cases.yaml +46 -0
- package/skills/data-scraper/references/anti-bot.md +85 -0
- package/skills/data-scraper/references/frameworks.md +116 -0
- package/skills/data-scraper/references/legal-compliance.md +59 -0
- package/skills/data-scraper/scripts/verify.sh +166 -0
- package/skills/db-migrations/SKILL.md +254 -0
- package/skills/db-migrations/evals/README.md +10 -0
- package/skills/db-migrations/evals/cases.yaml +46 -0
- package/skills/db-migrations/references/backfill-and-batching.md +105 -0
- package/skills/db-migrations/references/expand-contract-playbook.md +152 -0
- package/skills/db-migrations/references/tools-and-runners.md +88 -0
- package/skills/db-migrations/scripts/verify.sh +112 -0
- package/skills/debug/SKILL.md +227 -0
- package/skills/debug/evals/README.md +88 -0
- package/skills/debug/evals/cases.yaml +74 -0
- package/skills/decision-records/SKILL.md +189 -0
- package/skills/decision-records/evals/README.md +3 -0
- package/skills/decision-records/evals/cases.yaml +43 -0
- package/skills/decision-records/references/templates.md +232 -0
- package/skills/decision-records/scripts/verify.sh +105 -0
- package/skills/deployment/SKILL.md +439 -0
- package/skills/deployment/evals/README.md +50 -0
- package/skills/deployment/evals/cases.yaml +53 -0
- package/skills/deployment/references/coolify.md +216 -0
- package/skills/deployment/references/dockerfiles-by-stack.md +319 -0
- package/skills/deployment/references/github-actions.md +295 -0
- package/skills/deployment/references/hosting-targets.md +272 -0
- package/skills/deployment/scripts/verify.sh +134 -0
- package/skills/design/SKILL.md +399 -0
- package/skills/design/evals/README.md +53 -0
- package/skills/design/evals/cases.yaml +56 -0
- package/skills/design/references/brand-grounding.md +187 -0
- package/skills/design/references/copywriting-frameworks.md +138 -0
- package/skills/design/references/landing-anatomy-and-cro.md +202 -0
- package/skills/design/references/motion-and-interaction.md +182 -0
- package/skills/design/references/research-method.md +147 -0
- package/skills/design/references/signature-and-craft.md +148 -0
- package/skills/design/references/trends-2026.md +80 -0
- package/skills/design/references/visual-system.md +236 -0
- package/skills/design/scripts/verify.sh +248 -0
- package/skills/digitalocean/SKILL.md +251 -0
- package/skills/digitalocean/evals/README.md +10 -0
- package/skills/digitalocean/evals/cases.yaml +37 -0
- package/skills/digitalocean/references/app-spec.md +126 -0
- package/skills/digitalocean/references/droplet-ops.md +95 -0
- package/skills/digitalocean/scripts/verify.sh +102 -0
- package/skills/django/SKILL.md +268 -0
- package/skills/django/evals/README.md +11 -0
- package/skills/django/evals/cases.yaml +47 -0
- package/skills/django/references/drf.md +109 -0
- package/skills/django/references/orm-performance.md +91 -0
- package/skills/django/references/security.md +81 -0
- package/skills/django/references/testing.md +86 -0
- package/skills/django/scripts/verify.sh +115 -0
- package/skills/docker/SKILL.md +283 -0
- package/skills/docker/evals/README.md +10 -0
- package/skills/docker/evals/cases.yaml +44 -0
- package/skills/docker/references/base-images-and-stages.md +104 -0
- package/skills/docker/references/compose-recipes.md +109 -0
- package/skills/docker/scripts/verify.sh +149 -0
- package/skills/document-processing/SKILL.md +214 -0
- package/skills/document-processing/evals/README.md +3 -0
- package/skills/document-processing/evals/cases.yaml +65 -0
- package/skills/document-processing/references/engines.md +67 -0
- package/skills/document-processing/scripts/verify.sh +172 -0
- package/skills/domains-dns/SKILL.md +146 -0
- package/skills/domains-dns/evals/README.md +16 -0
- package/skills/domains-dns/evals/cases.yaml +47 -0
- package/skills/domains-dns/references/record-cookbook.md +94 -0
- package/skills/domains-dns/references/tls-and-acme.md +90 -0
- package/skills/domains-dns/references/verify-and-debug.md +64 -0
- package/skills/domains-dns/scripts/verify.sh +163 -0
- package/skills/drizzle-orm/SKILL.md +234 -0
- package/skills/drizzle-orm/evals/README.md +12 -0
- package/skills/drizzle-orm/evals/cases.yaml +47 -0
- package/skills/drizzle-orm/references/relations-and-drivers.md +118 -0
- package/skills/drizzle-orm/scripts/verify.sh +155 -0
- package/skills/duckdb/SKILL.md +207 -0
- package/skills/duckdb/evals/README.md +31 -0
- package/skills/duckdb/evals/cases.yaml +41 -0
- package/skills/duckdb/references/python-and-interop.md +105 -0
- package/skills/duckdb/references/remote-and-lakehouse.md +101 -0
- package/skills/duckdb/scripts/verify.sh +71 -0
- package/skills/dynamodb/SKILL.md +217 -0
- package/skills/dynamodb/evals/README.md +8 -0
- package/skills/dynamodb/evals/cases.yaml +46 -0
- package/skills/dynamodb/references/access-patterns.md +127 -0
- package/skills/dynamodb/references/capacity-and-limits.md +78 -0
- package/skills/dynamodb/scripts/verify.sh +108 -0
- package/skills/e-signature/SKILL.md +185 -0
- package/skills/e-signature/evals/README.md +3 -0
- package/skills/e-signature/evals/cases.yaml +44 -0
- package/skills/e-signature/references/docusign.md +83 -0
- package/skills/e-signature/references/dropbox-sign.md +73 -0
- package/skills/e-signature/references/legal-tiers.md +37 -0
- package/skills/e-signature/scripts/verify.sh +81 -0
- package/skills/e2e-testing/SKILL.md +243 -0
- package/skills/e2e-testing/evals/README.md +10 -0
- package/skills/e2e-testing/evals/cases.yaml +64 -0
- package/skills/e2e-testing/references/config-and-ci.md +156 -0
- package/skills/e2e-testing/references/flakiness-playbook.md +124 -0
- package/skills/e2e-testing/scripts/verify.sh +117 -0
- package/skills/electron/SKILL.md +221 -0
- package/skills/electron/evals/README.md +13 -0
- package/skills/electron/evals/cases.yaml +38 -0
- package/skills/electron/references/packaging-and-updates.md +122 -0
- package/skills/electron/references/security-and-ipc.md +158 -0
- package/skills/electron/scripts/verify.sh +143 -0
- package/skills/elixir/SKILL.md +217 -0
- package/skills/elixir/evals/README.md +3 -0
- package/skills/elixir/evals/cases.yaml +41 -0
- package/skills/elixir/references/mix-and-releases.md +91 -0
- package/skills/elixir/references/otp-patterns.md +96 -0
- package/skills/elixir/scripts/verify.sh +76 -0
- package/skills/email-connector/SKILL.md +294 -0
- package/skills/email-connector/evals/README.md +19 -0
- package/skills/email-connector/evals/cases.yaml +39 -0
- package/skills/email-connector/references/providers.md +107 -0
- package/skills/email-connector/scripts/verify.sh +72 -0
- package/skills/email-deliverability/SKILL.md +168 -0
- package/skills/email-deliverability/evals/README.md +21 -0
- package/skills/email-deliverability/evals/cases.yaml +45 -0
- package/skills/email-deliverability/scripts/verify.sh +98 -0
- package/skills/embeddings-search/SKILL.md +193 -0
- package/skills/embeddings-search/evals/README.md +10 -0
- package/skills/embeddings-search/evals/cases.yaml +44 -0
- package/skills/embeddings-search/references/evaluation.md +86 -0
- package/skills/embeddings-search/references/models.md +73 -0
- package/skills/embeddings-search/scripts/verify.sh +103 -0
- package/skills/error-handling/SKILL.md +307 -0
- package/skills/error-handling/evals/README.md +12 -0
- package/skills/error-handling/evals/cases.yaml +46 -0
- package/skills/error-handling/references/boundaries-and-messaging.md +120 -0
- package/skills/error-handling/references/retry-and-resilience.md +154 -0
- package/skills/error-handling/scripts/verify.sh +110 -0
- package/skills/expo/SKILL.md +253 -0
- package/skills/expo/evals/README.md +13 -0
- package/skills/expo/evals/cases.yaml +44 -0
- package/skills/expo/references/config-plugins.md +117 -0
- package/skills/expo/references/eas-update.md +118 -0
- package/skills/expo/scripts/verify.sh +132 -0
- package/skills/fal/SKILL.md +210 -0
- package/skills/fal/evals/README.md +3 -0
- package/skills/fal/evals/cases.yaml +42 -0
- package/skills/fal/references/models-and-cost.md +53 -0
- package/skills/fal/references/queue-and-webhooks.md +153 -0
- package/skills/fal/scripts/verify.sh +72 -0
- package/skills/fastapi/SKILL.md +499 -0
- package/skills/fastapi/evals/README.md +50 -0
- package/skills/fastapi/evals/cases.yaml +55 -0
- package/skills/fastapi/references/database.md +347 -0
- package/skills/fastapi/references/production.md +338 -0
- package/skills/fastapi/references/security.md +330 -0
- package/skills/fastapi/references/testing.md +349 -0
- package/skills/fastapi/scripts/verify.sh +116 -0
- package/skills/finance-ops/SKILL.md +149 -0
- package/skills/finance-ops/evals/README.md +3 -0
- package/skills/finance-ops/evals/cases.yaml +39 -0
- package/skills/finance-ops/references/cash-flow-forecast.md +57 -0
- package/skills/finance-ops/references/month-close.md +59 -0
- package/skills/finance-ops/references/reconciliation.md +65 -0
- package/skills/finance-ops/scripts/verify.sh +166 -0
- package/skills/financial-model/SKILL.md +170 -0
- package/skills/financial-model/evals/README.md +3 -0
- package/skills/financial-model/evals/cases.yaml +53 -0
- package/skills/financial-model/references/benchmarks-and-scenarios.md +55 -0
- package/skills/financial-model/references/model-structure.md +67 -0
- package/skills/financial-model/references/revenue-build.md +68 -0
- package/skills/financial-model/scripts/verify.sh +232 -0
- package/skills/firebase/SKILL.md +251 -0
- package/skills/firebase/evals/README.md +12 -0
- package/skills/firebase/evals/cases.yaml +45 -0
- package/skills/firebase/references/cloud-functions.md +102 -0
- package/skills/firebase/references/data-modeling.md +108 -0
- package/skills/firebase/references/security-rules.md +137 -0
- package/skills/firebase/scripts/verify.sh +98 -0
- package/skills/flutter/SKILL.md +448 -0
- package/skills/flutter/evals/README.md +54 -0
- package/skills/flutter/evals/cases.yaml +69 -0
- package/skills/flutter/references/architecture-and-state.md +499 -0
- package/skills/flutter/references/i18n-and-dependencies.md +197 -0
- package/skills/flutter/references/performance.md +299 -0
- package/skills/flutter/references/testing.md +385 -0
- package/skills/flutter/references/ui-and-navigation.md +378 -0
- package/skills/flutter/scripts/verify.sh +104 -0
- package/skills/fly-io/SKILL.md +206 -0
- package/skills/fly-io/evals/README.md +3 -0
- package/skills/fly-io/evals/cases.yaml +42 -0
- package/skills/fly-io/references/fly-toml.md +155 -0
- package/skills/fly-io/references/multi-region.md +66 -0
- package/skills/fly-io/scripts/verify.sh +90 -0
- package/skills/forecasting/SKILL.md +139 -0
- package/skills/forecasting/evals/README.md +13 -0
- package/skills/forecasting/evals/cases.yaml +47 -0
- package/skills/forecasting/references/accuracy-and-backtesting.md +104 -0
- package/skills/forecasting/references/methods-cheatsheet.md +94 -0
- package/skills/forecasting/scripts/verify.sh +99 -0
- package/skills/fundraising/SKILL.md +162 -0
- package/skills/fundraising/evals/README.md +18 -0
- package/skills/fundraising/evals/cases.yaml +76 -0
- package/skills/fundraising/references/funnel-math.md +90 -0
- package/skills/fundraising/references/process-playbook.md +97 -0
- package/skills/gcp-essentials/SKILL.md +327 -0
- package/skills/gcp-essentials/evals/README.md +12 -0
- package/skills/gcp-essentials/evals/cases.yaml +38 -0
- package/skills/gcp-essentials/references/deploy-recipes.md +81 -0
- package/skills/gcp-essentials/references/iam-and-auth.md +94 -0
- package/skills/gcp-essentials/references/networking-and-sql.md +74 -0
- package/skills/gcp-essentials/scripts/verify.sh +158 -0
- package/skills/gdpr-privacy/SKILL.md +167 -0
- package/skills/gdpr-privacy/evals/README.md +3 -0
- package/skills/gdpr-privacy/evals/cases.yaml +47 -0
- package/skills/gdpr-privacy/references/dpa-and-transfers.md +63 -0
- package/skills/gdpr-privacy/references/dsar-and-consent.md +83 -0
- package/skills/gdpr-privacy/references/privacy-policy-blueprint.md +99 -0
- package/skills/gdpr-privacy/scripts/verify.sh +84 -0
- package/skills/git-workflow/SKILL.md +190 -0
- package/skills/git-workflow/evals/README.md +10 -0
- package/skills/git-workflow/evals/cases.yaml +47 -0
- package/skills/git-workflow/references/interactive-rebase.md +89 -0
- package/skills/github-actions/SKILL.md +256 -0
- package/skills/github-actions/evals/README.md +3 -0
- package/skills/github-actions/evals/cases.yaml +45 -0
- package/skills/github-actions/references/caching-and-matrix.md +92 -0
- package/skills/github-actions/references/oidc-deploys.md +130 -0
- package/skills/github-actions/scripts/verify.sh +105 -0
- package/skills/go/SKILL.md +438 -0
- package/skills/go/evals/README.md +56 -0
- package/skills/go/evals/cases.yaml +55 -0
- package/skills/go/references/concurrency.md +557 -0
- package/skills/go/references/http-services.md +529 -0
- package/skills/go/references/testing.md +338 -0
- package/skills/go/scripts/verify.sh +109 -0
- package/skills/google-workspace/SKILL.md +287 -0
- package/skills/google-workspace/evals/README.md +16 -0
- package/skills/google-workspace/evals/cases.yaml +44 -0
- package/skills/google-workspace/references/api-recipes.md +148 -0
- package/skills/google-workspace/references/auth-setup.md +100 -0
- package/skills/google-workspace/scripts/verify.sh +128 -0
- package/skills/grants/SKILL.md +171 -0
- package/skills/grants/evals/README.md +3 -0
- package/skills/grants/evals/cases.yaml +69 -0
- package/skills/grants/references/budget-justification.md +71 -0
- package/skills/grants/references/jurisdictions.md +35 -0
- package/skills/grants/references/logic-model.md +66 -0
- package/skills/grants/scripts/verify.sh +193 -0
- package/skills/harness/SKILL.md +329 -0
- package/skills/harness/assets/_TEMPLATE/.env.example +8 -0
- package/skills/harness/assets/_TEMPLATE/CREDENTIALS.md +25 -0
- package/skills/harness/assets/_TEMPLATE/README.md +25 -0
- package/skills/harness/assets/_TEMPLATE/test_connection.sh +30 -0
- package/skills/harness/evals/README.md +54 -0
- package/skills/harness/evals/cases.yaml +72 -0
- package/skills/harness/examples/audit-example.md +120 -0
- package/skills/harness/references/agents-md-template.md +41 -0
- package/skills/harness/references/audit-report-template.html +140 -0
- package/skills/harness/references/audit-report-template.md +116 -0
- package/skills/harness/references/claude-md-template.md +98 -0
- package/skills/harness/references/inbox-readme-template.md +51 -0
- package/skills/harness/references/ingest-formats.md +185 -0
- package/skills/harness/references/providers.yaml +3410 -0
- package/skills/harness/references/tools-readme-template.md +88 -0
- package/skills/harness/references/wiki-archive-template.html +81 -0
- package/skills/harness/references/wiki-article-template.md +20 -0
- package/skills/harness/references/wiki-dashboard-template.html +136 -0
- package/skills/harness/references/wiki-deep-improve-report-template.html +126 -0
- package/skills/harness/references/wiki-gaps-template.md +18 -0
- package/skills/harness/references/wiki-index-template.md +23 -0
- package/skills/harness/references/wiki-protocol.md +699 -0
- package/skills/harness/references/wiki-raw-template.md +7 -0
- package/skills/hetzner/SKILL.md +221 -0
- package/skills/hetzner/evals/README.md +35 -0
- package/skills/hetzner/evals/cases.yaml +46 -0
- package/skills/hetzner/references/cloud-init.md +120 -0
- package/skills/hetzner/references/plans-and-locations.md +56 -0
- package/skills/hetzner/scripts/verify.sh +122 -0
- package/skills/hiring/SKILL.md +248 -0
- package/skills/hiring/evals/README.md +13 -0
- package/skills/hiring/evals/cases.yaml +41 -0
- package/skills/hiring/references/templates.md +118 -0
- package/skills/htmx/SKILL.md +261 -0
- package/skills/htmx/evals/README.md +3 -0
- package/skills/htmx/evals/cases.yaml +38 -0
- package/skills/htmx/references/patterns.md +113 -0
- package/skills/htmx/references/server-contract.md +91 -0
- package/skills/htmx/scripts/verify.sh +93 -0
- package/skills/huggingface/SKILL.md +190 -0
- package/skills/huggingface/evals/README.md +11 -0
- package/skills/huggingface/evals/cases.yaml +41 -0
- package/skills/huggingface/references/endpoints-and-spaces.md +99 -0
- package/skills/huggingface/references/hub-and-cli.md +85 -0
- package/skills/huggingface/references/inference-providers.md +115 -0
- package/skills/huggingface/scripts/verify.sh +123 -0
- package/skills/implement/SKILL.md +283 -0
- package/skills/implement/evals/README.md +56 -0
- package/skills/implement/evals/cases.yaml +43 -0
- package/skills/init/SKILL.md +184 -0
- package/skills/init/evals/README.md +49 -0
- package/skills/init/evals/cases.yaml +74 -0
- package/skills/init/references/accompaniment-and-profile.md +140 -0
- package/skills/init/references/discovery.md +90 -0
- package/skills/init/references/recommend-skills.md +115 -0
- package/skills/init/scripts/verify.sh +122 -0
- package/skills/instagram-api/SKILL.md +241 -0
- package/skills/instagram-api/evals/README.md +3 -0
- package/skills/instagram-api/evals/cases.yaml +43 -0
- package/skills/instagram-api/references/insights-metrics.md +88 -0
- package/skills/instagram-api/references/publish-reel.md +98 -0
- package/skills/instagram-api/scripts/verify.sh +137 -0
- package/skills/inventory/SKILL.md +131 -0
- package/skills/inventory/evals/README.md +3 -0
- package/skills/inventory/evals/cases.yaml +43 -0
- package/skills/inventory/references/abc-xyz.md +52 -0
- package/skills/inventory/references/ddmrp.md +32 -0
- package/skills/inventory/references/reorder-policies.md +85 -0
- package/skills/inventory/references/safety-stock.md +63 -0
- package/skills/inventory/scripts/verify.sh +155 -0
- package/skills/investor-materials/SKILL.md +175 -0
- package/skills/investor-materials/evals/README.md +15 -0
- package/skills/investor-materials/evals/cases.yaml +60 -0
- package/skills/investor-materials/references/dataroom-checklist.md +134 -0
- package/skills/investor-materials/references/update-and-onepager-templates.md +152 -0
- package/skills/investor-materials/scripts/verify.sh +148 -0
- package/skills/invoicing/SKILL.md +154 -0
- package/skills/invoicing/evals/README.md +5 -0
- package/skills/invoicing/evals/cases.yaml +49 -0
- package/skills/invoicing/references/dunning-ladder.md +53 -0
- package/skills/invoicing/references/e-invoicing-mandates.md +43 -0
- package/skills/invoicing/scripts/fixtures/broken-invoice.json +13 -0
- package/skills/invoicing/scripts/fixtures/valid-invoice.json +15 -0
- package/skills/invoicing/scripts/verify.sh +133 -0
- package/skills/ip-trademark/SKILL.md +186 -0
- package/skills/ip-trademark/evals/README.md +10 -0
- package/skills/ip-trademark/evals/cases.yaml +47 -0
- package/skills/ip-trademark/references/jurisdictions.md +63 -0
- package/skills/ip-trademark/references/ownership-and-licensing.md +90 -0
- package/skills/java/SKILL.md +341 -0
- package/skills/java/evals/README.md +23 -0
- package/skills/java/evals/cases.yaml +43 -0
- package/skills/java/references/builds.md +133 -0
- package/skills/java/references/concurrency.md +108 -0
- package/skills/java/references/streams.md +102 -0
- package/skills/java/scripts/verify.sh +107 -0
- package/skills/knowledge-ops/SKILL.md +125 -0
- package/skills/knowledge-ops/evals/README.md +16 -0
- package/skills/knowledge-ops/evals/cases.yaml +50 -0
- package/skills/knowledge-ops/references/gardening-playbook.md +116 -0
- package/skills/kotlin-android/SKILL.md +245 -0
- package/skills/kotlin-android/evals/README.md +13 -0
- package/skills/kotlin-android/evals/cases.yaml +56 -0
- package/skills/kotlin-android/references/architecture.md +200 -0
- package/skills/kotlin-android/references/gradle-setup.md +125 -0
- package/skills/kotlin-android/scripts/verify.sh +109 -0
- package/skills/kpi-framework/SKILL.md +199 -0
- package/skills/kpi-framework/evals/README.md +11 -0
- package/skills/kpi-framework/evals/cases.yaml +42 -0
- package/skills/kpi-framework/references/definition-and-targets.md +64 -0
- package/skills/kpi-framework/references/metric-catalog.md +84 -0
- package/skills/landing-copy/SKILL.md +153 -0
- package/skills/landing-copy/evals/README.md +18 -0
- package/skills/landing-copy/evals/cases.yaml +63 -0
- package/skills/landing-copy/references/frameworks.md +61 -0
- package/skills/landing-copy/references/page-skeleton.md +92 -0
- package/skills/landing-copy/scripts/verify.sh +164 -0
- package/skills/laravel/SKILL.md +301 -0
- package/skills/laravel/evals/README.md +10 -0
- package/skills/laravel/evals/cases.yaml +45 -0
- package/skills/laravel/references/eloquent-patterns.md +126 -0
- package/skills/laravel/references/queues-and-scheduling.md +153 -0
- package/skills/laravel/scripts/verify.sh +128 -0
- package/skills/lead-gen/SKILL.md +155 -0
- package/skills/lead-gen/evals/README.md +3 -0
- package/skills/lead-gen/evals/cases.yaml +43 -0
- package/skills/lead-gen/references/data-sources.md +87 -0
- package/skills/lead-gen/references/scoring-model.md +93 -0
- package/skills/lead-gen/scripts/verify.sh +179 -0
- package/skills/linkedin-api/SKILL.md +211 -0
- package/skills/linkedin-api/evals/README.md +3 -0
- package/skills/linkedin-api/evals/cases.yaml +41 -0
- package/skills/linkedin-api/references/api-reference.md +168 -0
- package/skills/linkedin-api/scripts/verify.sh +98 -0
- package/skills/linkedin-carousels/SKILL.md +239 -0
- package/skills/linkedin-carousels/evals/README.md +13 -0
- package/skills/linkedin-carousels/evals/cases.yaml +62 -0
- package/skills/linkedin-carousels/references/carousel-patterns.md +200 -0
- package/skills/linkedin-carousels/scripts/verify.sh +160 -0
- package/skills/linkedin-content/SKILL.md +162 -0
- package/skills/linkedin-content/evals/README.md +13 -0
- package/skills/linkedin-content/evals/cases.yaml +62 -0
- package/skills/linkedin-content/references/hooks-and-formats.md +114 -0
- package/skills/linkedin-content/scripts/verify.sh +154 -0
- package/skills/linkedin-outreach/SKILL.md +174 -0
- package/skills/linkedin-outreach/evals/README.md +3 -0
- package/skills/linkedin-outreach/evals/cases.yaml +43 -0
- package/skills/linkedin-outreach/references/ledger-schema.md +48 -0
- package/skills/linkedin-outreach/references/sales-navigator-playbook.md +61 -0
- package/skills/linkedin-outreach/scripts/verify.sh +120 -0
- package/skills/linkedin-strategy/SKILL.md +167 -0
- package/skills/linkedin-strategy/evals/README.md +3 -0
- package/skills/linkedin-strategy/evals/cases.yaml +49 -0
- package/skills/linkedin-strategy/references/ssi-and-pillars.md +59 -0
- package/skills/linkedin-strategy/references/wiki-records.md +62 -0
- package/skills/linkedin-strategy/scripts/verify.sh +120 -0
- package/skills/llm-pipeline/SKILL.md +155 -0
- package/skills/llm-pipeline/evals/README.md +3 -0
- package/skills/llm-pipeline/evals/cases.yaml +44 -0
- package/skills/llm-pipeline/references/caching-layers.md +60 -0
- package/skills/llm-pipeline/references/litellm-router.md +101 -0
- package/skills/llm-pipeline/scripts/verify.sh +169 -0
- package/skills/logistics-ops/SKILL.md +219 -0
- package/skills/logistics-ops/evals/README.md +20 -0
- package/skills/logistics-ops/evals/cases.yaml +48 -0
- package/skills/logistics-ops/references/carriers-and-claims.md +105 -0
- package/skills/market-research/SKILL.md +145 -0
- package/skills/market-research/evals/README.md +3 -0
- package/skills/market-research/evals/cases.yaml +48 -0
- package/skills/market-research/references/demand-signals.md +63 -0
- package/skills/market-research/references/sizing-playbook.md +121 -0
- package/skills/market-research/scripts/verify.sh +215 -0
- package/skills/marketing/SKILL.md +233 -0
- package/skills/marketing/evals/README.md +61 -0
- package/skills/marketing/evals/cases.yaml +84 -0
- package/skills/marketing/references/brand-grounding.md +197 -0
- package/skills/marketing/references/campaigns-and-channels.md +151 -0
- package/skills/marketing/references/copy-frameworks.md +166 -0
- package/skills/marketing/references/landing-copy.md +191 -0
- package/skills/marketing/references/seo-geo.md +391 -0
- package/skills/marketing/scripts/seo_audit.py +166 -0
- package/skills/marketing/scripts/verify.sh +233 -0
- package/skills/medium-publishing/SKILL.md +152 -0
- package/skills/medium-publishing/evals/README.md +3 -0
- package/skills/medium-publishing/evals/cases.yaml +42 -0
- package/skills/medium-publishing/references/cross-post-and-canonical.md +65 -0
- package/skills/medium-publishing/references/legacy-api.md +100 -0
- package/skills/medium-strategy/SKILL.md +161 -0
- package/skills/medium-strategy/evals/README.md +3 -0
- package/skills/medium-strategy/evals/cases.yaml +50 -0
- package/skills/medium-strategy/references/distribution-and-boost.md +65 -0
- package/skills/medium-strategy/references/wiki-records.md +60 -0
- package/skills/medium-strategy/scripts/verify.sh +118 -0
- package/skills/medium-writing/SKILL.md +140 -0
- package/skills/medium-writing/evals/README.md +5 -0
- package/skills/medium-writing/evals/cases.yaml +39 -0
- package/skills/medium-writing/references/title-patterns.md +79 -0
- package/skills/meeting-notes/SKILL.md +168 -0
- package/skills/meeting-notes/evals/README.md +14 -0
- package/skills/meeting-notes/evals/cases.yaml +46 -0
- package/skills/meeting-notes/references/templates.md +140 -0
- package/skills/modal/SKILL.md +307 -0
- package/skills/modal/evals/README.md +29 -0
- package/skills/modal/evals/cases.yaml +50 -0
- package/skills/modal/references/images-gpu-cookbook.md +160 -0
- package/skills/modal/references/web-and-scaling.md +138 -0
- package/skills/modal/scripts/verify.sh +127 -0
- package/skills/mongodb/SKILL.md +342 -0
- package/skills/mongodb/evals/README.md +29 -0
- package/skills/mongodb/evals/cases.yaml +41 -0
- package/skills/mongodb/references/aggregation.md +115 -0
- package/skills/mongodb/references/data-modeling.md +135 -0
- package/skills/mongodb/references/transactions-and-ops.md +128 -0
- package/skills/mongodb/scripts/verify.sh +151 -0
- package/skills/monitoring/SKILL.md +155 -0
- package/skills/monitoring/evals/README.md +3 -0
- package/skills/monitoring/evals/cases.yaml +47 -0
- package/skills/monitoring/references/burn-rate-and-oncall.md +128 -0
- package/skills/monitoring/references/tool-setup.md +154 -0
- package/skills/monitoring/scripts/verify.sh +145 -0
- package/skills/mysql/SKILL.md +249 -0
- package/skills/mysql/evals/README.md +12 -0
- package/skills/mysql/evals/cases.yaml +49 -0
- package/skills/mysql/references/indexing-and-explain.md +161 -0
- package/skills/mysql/references/mysql-vs-mariadb.md +78 -0
- package/skills/mysql/references/online-ddl-and-migrations.md +120 -0
- package/skills/mysql/references/replication-and-ha.md +115 -0
- package/skills/mysql/scripts/verify.sh +141 -0
- package/skills/neon/SKILL.md +218 -0
- package/skills/neon/evals/README.md +11 -0
- package/skills/neon/evals/cases.yaml +45 -0
- package/skills/neon/references/branching-ci.md +86 -0
- package/skills/neon/scripts/verify.sh +78 -0
- package/skills/nestjs/SKILL.md +225 -0
- package/skills/nestjs/evals/README.md +3 -0
- package/skills/nestjs/evals/cases.yaml +38 -0
- package/skills/nestjs/references/cross-cutting.md +135 -0
- package/skills/nestjs/references/testing-recipes.md +105 -0
- package/skills/nestjs/scripts/verify.sh +98 -0
- package/skills/netlify/SKILL.md +208 -0
- package/skills/netlify/evals/README.md +13 -0
- package/skills/netlify/evals/cases.yaml +43 -0
- package/skills/netlify/references/functions.md +97 -0
- package/skills/netlify/references/netlify-toml.md +115 -0
- package/skills/netlify/scripts/verify.sh +95 -0
- package/skills/newsletter/SKILL.md +162 -0
- package/skills/newsletter/evals/README.md +12 -0
- package/skills/newsletter/evals/cases.yaml +42 -0
- package/skills/newsletter/references/growth-loops.md +73 -0
- package/skills/newsletter/references/welcome-sequence.md +62 -0
- package/skills/newsletter/scripts/verify.sh +173 -0
- package/skills/nextjs/SKILL.md +472 -0
- package/skills/nextjs/evals/README.md +59 -0
- package/skills/nextjs/evals/cases.yaml +56 -0
- package/skills/nextjs/references/data-and-caching.md +309 -0
- package/skills/nextjs/references/metadata.md +208 -0
- package/skills/nextjs/references/performance.md +325 -0
- package/skills/nextjs/references/react.md +383 -0
- package/skills/nextjs/references/security.md +239 -0
- package/skills/nextjs/references/testing.md +290 -0
- package/skills/nextjs/scripts/verify.sh +141 -0
- package/skills/no-code-app/SKILL.md +153 -0
- package/skills/no-code-app/evals/README.md +3 -0
- package/skills/no-code-app/evals/cases.yaml +43 -0
- package/skills/no-code-app/references/platform-limits.md +100 -0
- package/skills/nodejs/SKILL.md +242 -0
- package/skills/nodejs/evals/README.md +3 -0
- package/skills/nodejs/evals/cases.yaml +39 -0
- package/skills/nodejs/references/express5-migration.md +53 -0
- package/skills/nodejs/references/graceful-shutdown.md +73 -0
- package/skills/nodejs/scripts/verify.sh +122 -0
- package/skills/notion-connector/SKILL.md +234 -0
- package/skills/notion-connector/evals/README.md +15 -0
- package/skills/notion-connector/evals/cases.yaml +45 -0
- package/skills/notion-connector/references/api-versions.md +63 -0
- package/skills/notion-connector/references/property-shapes.md +110 -0
- package/skills/notion-connector/references/sync-patterns.md +95 -0
- package/skills/notion-connector/scripts/verify.sh +162 -0
- package/skills/observability/SKILL.md +231 -0
- package/skills/observability/evals/README.md +3 -0
- package/skills/observability/evals/cases.yaml +49 -0
- package/skills/observability/references/collector-config.md +98 -0
- package/skills/observability/references/instrumentation-recipes.md +115 -0
- package/skills/observability/scripts/verify.sh +156 -0
- package/skills/ollama/SKILL.md +213 -0
- package/skills/ollama/evals/README.md +9 -0
- package/skills/ollama/evals/cases.yaml +43 -0
- package/skills/ollama/references/api.md +148 -0
- package/skills/ollama/references/hardware-sizing.md +87 -0
- package/skills/ollama/scripts/verify.sh +116 -0
- package/skills/orient/SKILL.md +54 -0
- package/skills/orient/evals/README.md +16 -0
- package/skills/orient/evals/cases.yaml +57 -0
- package/skills/orient/references/orientation-contract.md +34 -0
- package/skills/parallel/SKILL.md +198 -0
- package/skills/parallel/evals/README.md +62 -0
- package/skills/parallel/evals/cases.yaml +44 -0
- package/skills/people-ops/SKILL.md +122 -0
- package/skills/people-ops/evals/README.md +14 -0
- package/skills/people-ops/evals/cases.yaml +43 -0
- package/skills/people-ops/references/templates.md +129 -0
- package/skills/performance/SKILL.md +221 -0
- package/skills/performance/evals/README.md +3 -0
- package/skills/performance/evals/cases.yaml +47 -0
- package/skills/performance/references/profiling-playbook.md +54 -0
- package/skills/performance/scripts/verify.sh +94 -0
- package/skills/phoenix/SKILL.md +169 -0
- package/skills/phoenix/evals/README.md +3 -0
- package/skills/phoenix/evals/cases.yaml +40 -0
- package/skills/phoenix/references/auth-and-scopes.md +82 -0
- package/skills/phoenix/references/ecto-patterns.md +93 -0
- package/skills/phoenix/references/liveview.md +134 -0
- package/skills/phoenix/scripts/verify.sh +73 -0
- package/skills/php/SKILL.md +397 -0
- package/skills/php/evals/README.md +12 -0
- package/skills/php/evals/cases.yaml +45 -0
- package/skills/php/references/tooling.md +170 -0
- package/skills/php/references/type-system.md +220 -0
- package/skills/php/scripts/verify.sh +155 -0
- package/skills/pitch-deck/SKILL.md +209 -0
- package/skills/pitch-deck/evals/README.md +15 -0
- package/skills/pitch-deck/evals/cases.yaml +55 -0
- package/skills/pitch-deck/references/numbers-that-matter.md +78 -0
- package/skills/pitch-deck/references/slide-spine.md +149 -0
- package/skills/pitch-deck/scripts/verify.sh +186 -0
- package/skills/plan/SKILL.md +204 -0
- package/skills/plan/evals/README.md +62 -0
- package/skills/plan/evals/cases.yaml +49 -0
- package/skills/plan/references/plan-template.md +124 -0
- package/skills/planetscale/SKILL.md +223 -0
- package/skills/planetscale/evals/README.md +11 -0
- package/skills/planetscale/evals/cases.yaml +46 -0
- package/skills/planetscale/references/deploy-requests.md +75 -0
- package/skills/planetscale/references/no-foreign-keys.md +88 -0
- package/skills/planetscale/scripts/verify.sh +115 -0
- package/skills/podcast/SKILL.md +166 -0
- package/skills/podcast/evals/README.md +17 -0
- package/skills/podcast/evals/cases.yaml +61 -0
- package/skills/podcast/references/rss-and-namespace.md +136 -0
- package/skills/podcast/scripts/verify.sh +246 -0
- package/skills/postgresdb/SKILL.md +372 -0
- package/skills/postgresdb/evals/README.md +55 -0
- package/skills/postgresdb/evals/cases.yaml +57 -0
- package/skills/postgresdb/references/migrations.md +279 -0
- package/skills/postgresdb/references/operations-and-security.md +267 -0
- package/skills/postgresdb/references/query-optimization.md +374 -0
- package/skills/postgresdb/references/schema-and-indexing.md +379 -0
- package/skills/postgresdb/scripts/verify.sh +191 -0
- package/skills/presentations/SKILL.md +296 -0
- package/skills/presentations/evals/README.md +61 -0
- package/skills/presentations/evals/cases.yaml +56 -0
- package/skills/presentations/references/brand-grounding.md +160 -0
- package/skills/presentations/references/markdown-decks.md +290 -0
- package/skills/presentations/references/pptx-python.md +242 -0
- package/skills/presentations/references/slide-design.md +261 -0
- package/skills/presentations/references/storytelling-and-decks.md +150 -0
- package/skills/presentations/scripts/verify.sh +252 -0
- package/skills/press-kit/SKILL.md +243 -0
- package/skills/press-kit/evals/README.md +15 -0
- package/skills/press-kit/evals/cases.yaml +55 -0
- package/skills/press-kit/references/release-types.md +102 -0
- package/skills/press-kit/references/templates.md +132 -0
- package/skills/press-kit/scripts/verify.sh +161 -0
- package/skills/pricing/SKILL.md +160 -0
- package/skills/pricing/evals/README.md +5 -0
- package/skills/pricing/evals/cases.yaml +44 -0
- package/skills/pricing/references/localization.md +56 -0
- package/skills/pricing/references/pricing-models.md +55 -0
- package/skills/pricing/scripts/verify.sh +91 -0
- package/skills/prisma-orm/SKILL.md +320 -0
- package/skills/prisma-orm/evals/README.md +12 -0
- package/skills/prisma-orm/evals/cases.yaml +56 -0
- package/skills/prisma-orm/references/migrations-and-v7-upgrade.md +197 -0
- package/skills/prisma-orm/references/queries-and-performance.md +169 -0
- package/skills/prisma-orm/scripts/verify.sh +137 -0
- package/skills/procurement/SKILL.md +179 -0
- package/skills/procurement/evals/README.md +20 -0
- package/skills/procurement/evals/cases.yaml +49 -0
- package/skills/procurement/references/scorecard-and-tco.md +100 -0
- package/skills/procurement/references/sourcing-requests.md +116 -0
- package/skills/procurement/scripts/verify.sh +280 -0
- package/skills/project-ops/SKILL.md +130 -0
- package/skills/project-ops/evals/README.md +3 -0
- package/skills/project-ops/evals/cases.yaml +71 -0
- package/skills/project-ops/references/raid-and-rag.md +58 -0
- package/skills/project-ops/references/status-report-template.md +68 -0
- package/skills/project-ops/scripts/verify.sh +257 -0
- package/skills/prompt-engineering/SKILL.md +138 -0
- package/skills/prompt-engineering/evals/README.md +11 -0
- package/skills/prompt-engineering/evals/cases.yaml +46 -0
- package/skills/prompt-engineering/references/eval-templates.md +94 -0
- package/skills/prompt-engineering/references/output-contracts.md +120 -0
- package/skills/prompt-engineering/scripts/verify.sh +84 -0
- package/skills/proposals/SKILL.md +159 -0
- package/skills/proposals/evals/README.md +3 -0
- package/skills/proposals/evals/cases.yaml +53 -0
- package/skills/proposals/references/proposal-skeleton.md +110 -0
- package/skills/proposals/references/sow-skeleton.md +79 -0
- package/skills/proposals/scripts/verify.sh +201 -0
- package/skills/python/SKILL.md +369 -0
- package/skills/python/evals/README.md +19 -0
- package/skills/python/evals/cases.yaml +46 -0
- package/skills/python/references/async.md +136 -0
- package/skills/python/references/stdlib.md +162 -0
- package/skills/python/references/typing.md +160 -0
- package/skills/python/scripts/verify.sh +125 -0
- package/skills/rag/SKILL.md +226 -0
- package/skills/rag/evals/README.md +13 -0
- package/skills/rag/evals/cases.yaml +45 -0
- package/skills/rag/references/evaluation.md +99 -0
- package/skills/rag/references/pipeline.md +151 -0
- package/skills/rag/scripts/verify.sh +99 -0
- package/skills/rails/SKILL.md +264 -0
- package/skills/rails/evals/README.md +12 -0
- package/skills/rails/evals/cases.yaml +47 -0
- package/skills/rails/references/activerecord.md +148 -0
- package/skills/rails/references/hotwire.md +139 -0
- package/skills/rails/references/testing.md +110 -0
- package/skills/rails/scripts/verify.sh +128 -0
- package/skills/railway/SKILL.md +245 -0
- package/skills/railway/evals/README.md +14 -0
- package/skills/railway/evals/cases.yaml +44 -0
- package/skills/railway/references/cli-cookbook.md +137 -0
- package/skills/railway/references/config-as-code.md +120 -0
- package/skills/railway/scripts/verify.sh +162 -0
- package/skills/react/SKILL.md +222 -0
- package/skills/react/evals/README.md +3 -0
- package/skills/react/evals/cases.yaml +43 -0
- package/skills/react/references/data-and-state.md +152 -0
- package/skills/react/references/performance.md +75 -0
- package/skills/react/references/routing.md +99 -0
- package/skills/react/scripts/verify.sh +123 -0
- package/skills/react-native/SKILL.md +220 -0
- package/skills/react-native/evals/README.md +3 -0
- package/skills/react-native/evals/cases.yaml +42 -0
- package/skills/react-native/references/native-modules.md +123 -0
- package/skills/react-native/references/performance-debugging.md +46 -0
- package/skills/react-native/scripts/verify.sh +117 -0
- package/skills/redis/SKILL.md +298 -0
- package/skills/redis/evals/README.md +10 -0
- package/skills/redis/evals/cases.yaml +43 -0
- package/skills/redis/references/caching.md +116 -0
- package/skills/redis/references/locks-and-rate-limiting.md +140 -0
- package/skills/redis/references/queues.md +102 -0
- package/skills/redis/scripts/verify.sh +164 -0
- package/skills/remotion-video/SKILL.md +218 -0
- package/skills/remotion-video/evals/README.md +23 -0
- package/skills/remotion-video/evals/cases.yaml +64 -0
- package/skills/remotion-video/references/captions-pipeline.md +163 -0
- package/skills/remotion-video/references/render-and-pipeline.md +131 -0
- package/skills/remotion-video/scripts/verify.sh +169 -0
- package/skills/render/SKILL.md +256 -0
- package/skills/render/evals/README.md +12 -0
- package/skills/render/evals/cases.yaml +45 -0
- package/skills/render/references/blueprint-reference.md +203 -0
- package/skills/render/scripts/verify.sh +167 -0
- package/skills/replicate/SKILL.md +210 -0
- package/skills/replicate/evals/README.md +9 -0
- package/skills/replicate/evals/cases.yaml +45 -0
- package/skills/replicate/references/cog-packaging.md +89 -0
- package/skills/replicate/references/deployments-api.md +87 -0
- package/skills/replicate/references/webhooks-and-async.md +110 -0
- package/skills/replicate/scripts/verify.sh +162 -0
- package/skills/replicate-images/SKILL.md +241 -0
- package/skills/replicate-images/evals/README.md +13 -0
- package/skills/replicate-images/evals/cases.yaml +41 -0
- package/skills/replicate-images/references/editing-recipes.md +129 -0
- package/skills/replicate-images/references/models.md +131 -0
- package/skills/replicate-images/scripts/verify.sh +178 -0
- package/skills/reporting/SKILL.md +178 -0
- package/skills/reporting/evals/README.md +12 -0
- package/skills/reporting/evals/cases.yaml +46 -0
- package/skills/reporting/references/pipeline.md +213 -0
- package/skills/reporting/scripts/verify.sh +149 -0
- package/skills/research-ops/SKILL.md +200 -0
- package/skills/research-ops/evals/README.md +13 -0
- package/skills/research-ops/evals/cases.yaml +38 -0
- package/skills/research-ops/references/credibility-rubric.md +78 -0
- package/skills/research-ops/references/memo-template.md +63 -0
- package/skills/research-ops/scripts/verify.sh +181 -0
- package/skills/retention/SKILL.md +206 -0
- package/skills/retention/evals/README.md +13 -0
- package/skills/retention/evals/cases.yaml +42 -0
- package/skills/retention/references/health-score-and-metrics.md +97 -0
- package/skills/retention/references/save-and-winback-plays.md +65 -0
- package/skills/review/SKILL.md +222 -0
- package/skills/review/evals/README.md +84 -0
- package/skills/review/evals/cases.yaml +55 -0
- package/skills/review-management/SKILL.md +204 -0
- package/skills/review-management/evals/README.md +13 -0
- package/skills/review-management/evals/cases.yaml +60 -0
- package/skills/review-management/references/platform-apis.md +86 -0
- package/skills/review-management/scripts/verify.sh +128 -0
- package/skills/ruby/SKILL.md +316 -0
- package/skills/ruby/evals/README.md +12 -0
- package/skills/ruby/evals/cases.yaml +41 -0
- package/skills/ruby/references/gems-and-testing.md +208 -0
- package/skills/ruby/references/metaprogramming.md +161 -0
- package/skills/ruby/scripts/verify.sh +83 -0
- package/skills/runpod/SKILL.md +238 -0
- package/skills/runpod/evals/README.md +11 -0
- package/skills/runpod/evals/cases.yaml +47 -0
- package/skills/runpod/references/cost-and-scaling.md +85 -0
- package/skills/runpod/references/serverless-workers.md +101 -0
- package/skills/runpod/scripts/verify.sh +126 -0
- package/skills/rust/SKILL.md +395 -0
- package/skills/rust/evals/README.md +12 -0
- package/skills/rust/evals/cases.yaml +42 -0
- package/skills/rust/references/async-tokio.md +141 -0
- package/skills/rust/references/axum-service.md +132 -0
- package/skills/rust/references/ownership.md +86 -0
- package/skills/rust/references/testing.md +108 -0
- package/skills/rust/scripts/verify.sh +91 -0
- package/skills/sales-pipeline/SKILL.md +162 -0
- package/skills/sales-pipeline/evals/README.md +13 -0
- package/skills/sales-pipeline/evals/cases.yaml +60 -0
- package/skills/sales-pipeline/references/forecasting-math.md +82 -0
- package/skills/sales-pipeline/references/stage-playbook.md +84 -0
- package/skills/sales-pipeline/scripts/verify.sh +210 -0
- package/skills/scaling/SKILL.md +137 -0
- package/skills/scaling/evals/README.md +3 -0
- package/skills/scaling/evals/cases.yaml +42 -0
- package/skills/scaling/references/load-testing-k6.md +127 -0
- package/skills/scaling/scripts/example.load.js +24 -0
- package/skills/scaling/scripts/verify.sh +70 -0
- package/skills/sdd/SKILL.md +203 -0
- package/skills/sdd/evals/README.md +60 -0
- package/skills/sdd/evals/cases.yaml +78 -0
- package/skills/sdd-init/SKILL.md +148 -0
- package/skills/sdd-init/evals/README.md +3 -0
- package/skills/sdd-init/evals/cases.yaml +43 -0
- package/skills/secure-coding/SKILL.md +365 -0
- package/skills/secure-coding/evals/README.md +68 -0
- package/skills/secure-coding/evals/cases.yaml +55 -0
- package/skills/secure-coding/references/authn-authz.md +249 -0
- package/skills/secure-coding/references/owasp-by-stack.md +574 -0
- package/skills/secure-coding/references/secrets-and-supply-chain.md +205 -0
- package/skills/secure-coding/references/threat-modeling.md +213 -0
- package/skills/secure-coding/scripts/verify.sh +208 -0
- package/skills/security-scan/SKILL.md +239 -0
- package/skills/security-scan/evals/README.md +14 -0
- package/skills/security-scan/evals/cases.yaml +50 -0
- package/skills/security-scan/references/tools.md +98 -0
- package/skills/security-scan/references/triage.md +93 -0
- package/skills/security-scan/scripts/verify.sh +108 -0
- package/skills/seo-geo/SKILL.md +192 -0
- package/skills/seo-geo/evals/README.md +14 -0
- package/skills/seo-geo/evals/cases.yaml +45 -0
- package/skills/seo-geo/references/ai-crawler-control.md +104 -0
- package/skills/seo-geo/references/schema-recipes.md +130 -0
- package/skills/seo-geo/scripts/verify.sh +236 -0
- package/skills/ship/SKILL.md +258 -0
- package/skills/ship/evals/README.md +89 -0
- package/skills/ship/evals/cases.yaml +44 -0
- package/skills/shopify/SKILL.md +229 -0
- package/skills/shopify/evals/README.md +14 -0
- package/skills/shopify/evals/cases.yaml +41 -0
- package/skills/shopify/references/apps-graphql.md +103 -0
- package/skills/shopify/references/checkout-extensibility.md +71 -0
- package/skills/shopify/references/liquid-themes.md +89 -0
- package/skills/shopify/scripts/verify.sh +120 -0
- package/skills/shortform-editing/SKILL.md +161 -0
- package/skills/shortform-editing/evals/README.md +16 -0
- package/skills/shortform-editing/evals/cases.yaml +61 -0
- package/skills/shortform-editing/references/captions.md +85 -0
- package/skills/shortform-editing/references/ffmpeg-pipeline.md +126 -0
- package/skills/shortform-editing/scripts/verify.sh +148 -0
- package/skills/shortform-ideation/SKILL.md +153 -0
- package/skills/shortform-ideation/evals/README.md +20 -0
- package/skills/shortform-ideation/evals/cases.yaml +58 -0
- package/skills/shortform-ideation/references/experiment-ledger.md +85 -0
- package/skills/shortform-ideation/references/trend-sources.md +69 -0
- package/skills/shortform-ideation/scripts/verify.sh +172 -0
- package/skills/shortform-packaging/SKILL.md +247 -0
- package/skills/shortform-packaging/evals/README.md +10 -0
- package/skills/shortform-packaging/evals/cases.yaml +48 -0
- package/skills/shortform-packaging/references/package-templates.md +117 -0
- package/skills/shortform-packaging/scripts/verify.sh +210 -0
- package/skills/shortform-strategy/SKILL.md +149 -0
- package/skills/shortform-strategy/evals/README.md +3 -0
- package/skills/shortform-strategy/evals/cases.yaml +52 -0
- package/skills/shortform-strategy/references/learning-loop-template.md +49 -0
- package/skills/shortform-strategy/references/platform-signals-2026.md +46 -0
- package/skills/shortform-strategy/scripts/verify.sh +176 -0
- package/skills/skill-scout/SKILL.md +133 -0
- package/skills/skill-scout/evals/README.md +12 -0
- package/skills/skill-scout/evals/cases.yaml +56 -0
- package/skills/skill-scout/references/install-commands.md +76 -0
- package/skills/skill-scout/scripts/verify.sh +154 -0
- package/skills/social-publisher/SKILL.md +179 -0
- package/skills/social-publisher/evals/README.md +14 -0
- package/skills/social-publisher/evals/cases.yaml +55 -0
- package/skills/social-publisher/references/calendar-schema.md +97 -0
- package/skills/social-publisher/references/platform-limits.md +56 -0
- package/skills/social-publisher/scripts/verify.sh +232 -0
- package/skills/solid-js/SKILL.md +260 -0
- package/skills/solid-js/evals/README.md +3 -0
- package/skills/solid-js/evals/cases.yaml +38 -0
- package/skills/solid-js/references/reactivity-deep-dive.md +89 -0
- package/skills/solid-js/references/router-and-start.md +93 -0
- package/skills/solid-js/scripts/verify.sh +130 -0
- package/skills/sop-builder/SKILL.md +233 -0
- package/skills/sop-builder/evals/README.md +14 -0
- package/skills/sop-builder/evals/cases.yaml +48 -0
- package/skills/sop-builder/references/sop-skeleton.md +170 -0
- package/skills/specify/SKILL.md +214 -0
- package/skills/specify/evals/README.md +73 -0
- package/skills/specify/evals/cases.yaml +80 -0
- package/skills/specify/references/eliciting-requirements.md +77 -0
- package/skills/specify/references/spec-template.md +60 -0
- package/skills/spreadsheet-ops/SKILL.md +180 -0
- package/skills/spreadsheet-ops/evals/README.md +33 -0
- package/skills/spreadsheet-ops/evals/cases.yaml +42 -0
- package/skills/spreadsheet-ops/references/formula-cookbook.md +70 -0
- package/skills/spreadsheet-ops/references/python-excel.md +87 -0
- package/skills/spreadsheet-ops/references/sheets-api-appsscript.md +118 -0
- package/skills/spreadsheet-ops/scripts/verify.sh +152 -0
- package/skills/spring-boot/SKILL.md +375 -0
- package/skills/spring-boot/evals/README.md +11 -0
- package/skills/spring-boot/evals/cases.yaml +49 -0
- package/skills/spring-boot/references/jpa.md +94 -0
- package/skills/spring-boot/references/security.md +92 -0
- package/skills/spring-boot/references/testing.md +95 -0
- package/skills/spring-boot/scripts/verify.sh +115 -0
- package/skills/sql/SKILL.md +286 -0
- package/skills/sql/evals/README.md +9 -0
- package/skills/sql/evals/cases.yaml +49 -0
- package/skills/sql/references/ctes-and-recursion.md +63 -0
- package/skills/sql/references/joins-and-sets.md +71 -0
- package/skills/sql/references/portability.md +38 -0
- package/skills/sql/references/window-functions.md +72 -0
- package/skills/sql/scripts/verify.sh +139 -0
- package/skills/sqlite-turso/SKILL.md +214 -0
- package/skills/sqlite-turso/evals/README.md +24 -0
- package/skills/sqlite-turso/evals/cases.yaml +45 -0
- package/skills/sqlite-turso/references/embedded-replicas.md +96 -0
- package/skills/sqlite-turso/scripts/verify.sh +95 -0
- package/skills/stripe/SKILL.md +269 -0
- package/skills/stripe/evals/README.md +11 -0
- package/skills/stripe/evals/cases.yaml +45 -0
- package/skills/stripe/references/going-live.md +64 -0
- package/skills/stripe/references/webhook-events.md +79 -0
- package/skills/stripe/scripts/verify.sh +130 -0
- package/skills/structured-extraction/SKILL.md +230 -0
- package/skills/structured-extraction/evals/README.md +13 -0
- package/skills/structured-extraction/evals/cases.yaml +70 -0
- package/skills/structured-extraction/references/providers.md +152 -0
- package/skills/structured-extraction/scripts/verify.sh +160 -0
- package/skills/suggest/SKILL.md +30 -0
- package/skills/suggest/evals/README.md +14 -0
- package/skills/suggest/evals/cases.yaml +51 -0
- package/skills/supabase/SKILL.md +268 -0
- package/skills/supabase/evals/README.md +12 -0
- package/skills/supabase/evals/cases.yaml +42 -0
- package/skills/supabase/references/auth-ssr.md +173 -0
- package/skills/supabase/references/rls-cookbook.md +122 -0
- package/skills/supabase/scripts/verify.sh +149 -0
- package/skills/svelte/SKILL.md +238 -0
- package/skills/svelte/evals/README.md +3 -0
- package/skills/svelte/evals/cases.yaml +41 -0
- package/skills/svelte/references/runes.md +97 -0
- package/skills/svelte/references/sveltekit-data.md +156 -0
- package/skills/svelte/scripts/verify.sh +128 -0
- package/skills/swift-ios/SKILL.md +217 -0
- package/skills/swift-ios/evals/README.md +3 -0
- package/skills/swift-ios/evals/cases.yaml +46 -0
- package/skills/swift-ios/references/concurrency.md +132 -0
- package/skills/swift-ios/references/testing.md +112 -0
- package/skills/swift-ios/scripts/verify.sh +98 -0
- package/skills/tasks/SKILL.md +260 -0
- package/skills/tasks/evals/README.md +70 -0
- package/skills/tasks/evals/cases.yaml +75 -0
- package/skills/tauri/SKILL.md +224 -0
- package/skills/tauri/evals/README.md +12 -0
- package/skills/tauri/evals/cases.yaml +46 -0
- package/skills/tauri/references/bundling-distribution.md +129 -0
- package/skills/tauri/references/security.md +143 -0
- package/skills/tauri/scripts/verify.sh +178 -0
- package/skills/technical-writing/SKILL.md +230 -0
- package/skills/technical-writing/evals/README.md +12 -0
- package/skills/technical-writing/evals/cases.yaml +53 -0
- package/skills/technical-writing/references/diataxis-modes.md +131 -0
- package/skills/technical-writing/references/vale-starter.md +90 -0
- package/skills/technical-writing/scripts/verify.sh +83 -0
- package/skills/terms-conditions/SKILL.md +147 -0
- package/skills/terms-conditions/evals/README.md +14 -0
- package/skills/terms-conditions/evals/cases.yaml +48 -0
- package/skills/terms-conditions/references/clause-library.md +158 -0
- package/skills/terms-conditions/references/notices-and-aup.md +125 -0
- package/skills/terms-conditions/scripts/verify.sh +92 -0
- package/skills/testing-go/SKILL.md +246 -0
- package/skills/testing-go/evals/README.md +3 -0
- package/skills/testing-go/evals/cases.yaml +44 -0
- package/skills/testing-go/references/coverage-and-benchmarks.md +85 -0
- package/skills/testing-go/references/mocks-and-fakes.md +140 -0
- package/skills/testing-go/references/synctest-and-concurrency.md +82 -0
- package/skills/testing-go/scripts/verify.sh +72 -0
- package/skills/testing-py/SKILL.md +179 -0
- package/skills/testing-py/evals/README.md +5 -0
- package/skills/testing-py/evals/cases.yaml +44 -0
- package/skills/testing-py/references/mocking.md +141 -0
- package/skills/testing-py/references/property-testing.md +99 -0
- package/skills/testing-py/scripts/verify.sh +117 -0
- package/skills/testing-web/SKILL.md +224 -0
- package/skills/testing-web/evals/README.md +11 -0
- package/skills/testing-web/evals/cases.yaml +52 -0
- package/skills/testing-web/references/jest-setup.md +88 -0
- package/skills/testing-web/references/recipes.md +116 -0
- package/skills/testing-web/scripts/verify.sh +111 -0
- package/skills/tiktok-api/SKILL.md +315 -0
- package/skills/tiktok-api/evals/README.md +17 -0
- package/skills/tiktok-api/evals/cases.yaml +51 -0
- package/skills/tiktok-api/references/metrics-and-publish.md +127 -0
- package/skills/tiktok-api/references/oauth-setup.md +105 -0
- package/skills/tiktok-api/references/wiki-schema.md +85 -0
- package/skills/tiktok-api/scripts/verify.sh +96 -0
- package/skills/together-fireworks/SKILL.md +181 -0
- package/skills/together-fireworks/evals/README.md +3 -0
- package/skills/together-fireworks/evals/cases.yaml +50 -0
- package/skills/together-fireworks/references/batch-and-tuning.md +59 -0
- package/skills/together-fireworks/references/models-and-pricing.md +79 -0
- package/skills/together-fireworks/scripts/verify.sh +165 -0
- package/skills/translation-l10n/SKILL.md +229 -0
- package/skills/translation-l10n/evals/README.md +3 -0
- package/skills/translation-l10n/evals/cases.yaml +39 -0
- package/skills/translation-l10n/references/icu-cookbook.md +82 -0
- package/skills/translation-l10n/references/rtl-and-bidi.md +60 -0
- package/skills/typescript/SKILL.md +258 -0
- package/skills/typescript/evals/README.md +15 -0
- package/skills/typescript/evals/cases.yaml +46 -0
- package/skills/typescript/references/build-and-monorepo.md +141 -0
- package/skills/typescript/references/type-system.md +162 -0
- package/skills/typescript/scripts/verify.sh +52 -0
- package/skills/unit-economics/SKILL.md +180 -0
- package/skills/unit-economics/evals/README.md +5 -0
- package/skills/unit-economics/evals/cases.yaml +43 -0
- package/skills/unit-economics/references/formulas.md +144 -0
- package/skills/unit-economics/scripts/verify.sh +179 -0
- package/skills/vector-db/SKILL.md +189 -0
- package/skills/vector-db/evals/README.md +10 -0
- package/skills/vector-db/evals/cases.yaml +45 -0
- package/skills/vector-db/references/engines.md +175 -0
- package/skills/vector-db/references/tuning.md +62 -0
- package/skills/vector-db/scripts/verify.sh +110 -0
- package/skills/vercel/SKILL.md +242 -0
- package/skills/vercel/evals/README.md +23 -0
- package/skills/vercel/evals/cases.yaml +45 -0
- package/skills/vercel/references/cli-cookbook.md +98 -0
- package/skills/vercel/references/vercel-json.md +120 -0
- package/skills/vercel/scripts/verify.sh +168 -0
- package/skills/verify/SKILL.md +188 -0
- package/skills/verify/evals/README.md +78 -0
- package/skills/verify/evals/cases.yaml +74 -0
- package/skills/video-shorts/SKILL.md +163 -0
- package/skills/video-shorts/evals/README.md +15 -0
- package/skills/video-shorts/evals/cases.yaml +56 -0
- package/skills/video-shorts/references/hook-and-script-patterns.md +95 -0
- package/skills/video-shorts/references/specs-and-safe-zones.md +74 -0
- package/skills/video-shorts/scripts/verify.sh +172 -0
- package/skills/vue-nuxt/SKILL.md +384 -0
- package/skills/vue-nuxt/evals/README.md +11 -0
- package/skills/vue-nuxt/evals/cases.yaml +49 -0
- package/skills/vue-nuxt/references/data-and-state.md +127 -0
- package/skills/vue-nuxt/references/migration-nuxt4.md +79 -0
- package/skills/vue-nuxt/references/nitro-and-rendering.md +117 -0
- package/skills/vue-nuxt/references/reactivity.md +135 -0
- package/skills/vue-nuxt/scripts/verify.sh +148 -0
- package/skills/webhooks/SKILL.md +246 -0
- package/skills/webhooks/evals/README.md +15 -0
- package/skills/webhooks/evals/cases.yaml +46 -0
- package/skills/webhooks/references/framework-raw-body.md +97 -0
- package/skills/webhooks/references/signature-schemes.md +66 -0
- package/skills/webhooks/scripts/verify.sh +142 -0
- package/skills/webinar/SKILL.md +196 -0
- package/skills/webinar/evals/README.md +14 -0
- package/skills/webinar/evals/cases.yaml +44 -0
- package/skills/webinar/references/email-cadence.md +75 -0
- package/skills/webinar/references/run-of-show.md +83 -0
- package/skills/whatsapp-telegram/SKILL.md +235 -0
- package/skills/whatsapp-telegram/evals/README.md +11 -0
- package/skills/whatsapp-telegram/evals/cases.yaml +44 -0
- package/skills/whatsapp-telegram/references/telegram-bot-api.md +91 -0
- package/skills/whatsapp-telegram/references/whatsapp-cloud-api.md +103 -0
- package/skills/whatsapp-telegram/scripts/verify.sh +90 -0
- package/skills/wordpress/SKILL.md +224 -0
- package/skills/wordpress/evals/README.md +3 -0
- package/skills/wordpress/evals/cases.yaml +50 -0
- package/skills/wordpress/references/hardening.md +108 -0
- package/skills/wordpress/references/performance.md +80 -0
- package/skills/wordpress/references/woocommerce.md +65 -0
- package/skills/wordpress/scripts/verify.sh +96 -0
- package/skills/worktrees/SKILL.md +199 -0
- package/skills/worktrees/evals/README.md +78 -0
- package/skills/worktrees/evals/cases.yaml +47 -0
- package/skills/youtube-api/SKILL.md +286 -0
- package/skills/youtube-api/evals/README.md +3 -0
- package/skills/youtube-api/evals/cases.yaml +50 -0
- package/skills/youtube-api/references/analytics-queries.md +89 -0
- package/skills/youtube-api/references/oauth-setup.md +55 -0
- package/skills/youtube-api/references/wiki-schema.md +70 -0
- package/skills/youtube-api/scripts/verify.sh +84 -0
- package/skills/youtube-ideation/SKILL.md +234 -0
- package/skills/youtube-ideation/evals/README.md +14 -0
- package/skills/youtube-ideation/evals/cases.yaml +52 -0
- package/skills/youtube-ideation/references/idea-ledger-and-loop.md +89 -0
- package/skills/youtube-ideation/references/research-and-signals.md +92 -0
- package/skills/youtube-ideation/scripts/verify.sh +237 -0
- package/skills/youtube-packaging/SKILL.md +220 -0
- package/skills/youtube-packaging/evals/README.md +16 -0
- package/skills/youtube-packaging/evals/cases.yaml +48 -0
- package/skills/youtube-packaging/references/description-and-chapters.md +135 -0
- package/skills/youtube-packaging/scripts/verify.sh +250 -0
- package/skills/youtube-strategy/SKILL.md +157 -0
- package/skills/youtube-strategy/evals/README.md +5 -0
- package/skills/youtube-strategy/evals/cases.yaml +61 -0
- package/skills/youtube-strategy/references/channel-architecture.md +46 -0
- package/skills/youtube-strategy/references/wiki-records.md +86 -0
- package/skills/youtube-strategy/scripts/verify.sh +118 -0
- package/skills/youtube-thumbnails/SKILL.md +180 -0
- package/skills/youtube-thumbnails/evals/README.md +11 -0
- package/skills/youtube-thumbnails/evals/cases.yaml +48 -0
- package/skills/youtube-thumbnails/references/composition-and-specs.md +69 -0
- package/skills/youtube-thumbnails/references/experiment-log-format.md +65 -0
- package/skills/youtube-thumbnails/scripts/verify.sh +123 -0
- package/targets/claude.js +23 -0
- package/targets/codex.js +29 -0
- package/targets/cursor.js +20 -0
- package/targets/gemini.js +29 -0
- package/targets/index.js +55 -0
|
@@ -0,0 +1,3410 @@
|
|
|
1
|
+
# Provider catalog for harness.
|
|
2
|
+
#
|
|
3
|
+
# Each entry defines how to DETECT a provider in a workspace and what to SHIP
|
|
4
|
+
# inside 01-TOOLS/<ID>/ when it is detected. Adding a new provider = add a new
|
|
5
|
+
# entry here. The SKILL.md never needs to change.
|
|
6
|
+
#
|
|
7
|
+
# Schema:
|
|
8
|
+
# id: uppercase folder name under 01-TOOLS/
|
|
9
|
+
# category: grouping for 01-TOOLS/README.md
|
|
10
|
+
# detectors:
|
|
11
|
+
# imports: list of grep patterns for SDK imports (any match)
|
|
12
|
+
# env_vars: list of env var names to grep
|
|
13
|
+
# deps: list of dependency names in manifests
|
|
14
|
+
# env_example: literal body of .env.example
|
|
15
|
+
# dashboard_url: provider dashboard for credentials
|
|
16
|
+
# files: map of relative path -> file body
|
|
17
|
+
# Variables: {{TODAY}}
|
|
18
|
+
# manual_only: true if provider has no automated test_connection
|
|
19
|
+
# (e.g. credentials kept for human dashboard use)
|
|
20
|
+
|
|
21
|
+
providers:
|
|
22
|
+
|
|
23
|
+
- id: STRIPE
|
|
24
|
+
category: pagos
|
|
25
|
+
detectors:
|
|
26
|
+
imports:
|
|
27
|
+
- "import stripe"
|
|
28
|
+
- "from stripe"
|
|
29
|
+
- "require('stripe')"
|
|
30
|
+
- "require(\"stripe\")"
|
|
31
|
+
- "@stripe/stripe-js"
|
|
32
|
+
- "@stripe/stripe-node"
|
|
33
|
+
env_vars:
|
|
34
|
+
- "STRIPE_SECRET_KEY"
|
|
35
|
+
- "STRIPE_PUBLISHABLE_KEY"
|
|
36
|
+
- "STRIPE_WEBHOOK_SECRET"
|
|
37
|
+
deps:
|
|
38
|
+
- "stripe"
|
|
39
|
+
- "@stripe/stripe-js"
|
|
40
|
+
- "@stripe/stripe-node"
|
|
41
|
+
dashboard_url: "https://dashboard.stripe.com/apikeys"
|
|
42
|
+
env_example: |
|
|
43
|
+
# STRIPE — operational credentials
|
|
44
|
+
# Generate at: https://dashboard.stripe.com/apikeys
|
|
45
|
+
#
|
|
46
|
+
# Copy this file to `.env`, fill in real values, and `chmod 600 .env`.
|
|
47
|
+
|
|
48
|
+
STRIPE_SECRET_KEY=
|
|
49
|
+
STRIPE_PUBLISHABLE_KEY=
|
|
50
|
+
STRIPE_WEBHOOK_SECRET=
|
|
51
|
+
files:
|
|
52
|
+
test_connection.sh: |
|
|
53
|
+
#!/usr/bin/env bash
|
|
54
|
+
# Smoke-test against Stripe API: GET /v1/account.
|
|
55
|
+
set -euo pipefail
|
|
56
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
57
|
+
ENV_PATH="$SCRIPT_DIR/.env"
|
|
58
|
+
[ -f "$ENV_PATH" ] || { echo "ERROR: missing $ENV_PATH" >&2; exit 1; }
|
|
59
|
+
set -a; source "$ENV_PATH"; set +a
|
|
60
|
+
: "${STRIPE_SECRET_KEY:?STRIPE_SECRET_KEY not set in $ENV_PATH}"
|
|
61
|
+
RESP=$(curl -fsS -u "$STRIPE_SECRET_KEY:" https://api.stripe.com/v1/account)
|
|
62
|
+
echo "$RESP" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(f"OK — account: {d[\"id\"]} ({d.get(\"business_profile\",{}).get(\"name\",\"-\")})")'
|
|
63
|
+
README.md: |
|
|
64
|
+
# STRIPE
|
|
65
|
+
|
|
66
|
+
Operations against the project Stripe account: pricing, customers,
|
|
67
|
+
subscriptions, webhook events.
|
|
68
|
+
|
|
69
|
+
## Setup
|
|
70
|
+
|
|
71
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
72
|
+
2. Set `STRIPE_SECRET_KEY` from https://dashboard.stripe.com/apikeys
|
|
73
|
+
3. `./test_connection.sh` — should print `OK — account: acct_…`
|
|
74
|
+
|
|
75
|
+
## Scripts
|
|
76
|
+
|
|
77
|
+
| Script | What it does |
|
|
78
|
+
|--------|--------------|
|
|
79
|
+
| `test_connection.sh` | Smoke-test against `/v1/account`. |
|
|
80
|
+
|
|
81
|
+
## Notes
|
|
82
|
+
|
|
83
|
+
- The product backend consumes Stripe via its own runtime SDK.
|
|
84
|
+
This tool is for manual terminal-driven operations only.
|
|
85
|
+
CREDENTIALS.md: |
|
|
86
|
+
# Credentials — STRIPE
|
|
87
|
+
|
|
88
|
+
## Dashboard
|
|
89
|
+
|
|
90
|
+
- URL: https://dashboard.stripe.com/apikeys
|
|
91
|
+
- 2FA mandatory.
|
|
92
|
+
|
|
93
|
+
## Variables
|
|
94
|
+
|
|
95
|
+
| Variable | Type | Where to generate | Rotation |
|
|
96
|
+
|----------|------|-------------------|----------|
|
|
97
|
+
| `STRIPE_SECRET_KEY` | secret | Dashboard → Developers → API keys | on suspected leak |
|
|
98
|
+
| `STRIPE_PUBLISHABLE_KEY` | public | Dashboard → Developers → API keys | n/a |
|
|
99
|
+
| `STRIPE_WEBHOOK_SECRET` | secret | Dashboard → Developers → Webhooks → endpoint | whenever the endpoint changes |
|
|
100
|
+
|
|
101
|
+
## If a credential leaks
|
|
102
|
+
|
|
103
|
+
1. Revocar inmediatamente en el dashboard (rolling key).
|
|
104
|
+
2. Generar una nueva y actualizar `.env` local.
|
|
105
|
+
3. Si el backend la consume en runtime: actualizar env vars del despliegue.
|
|
106
|
+
|
|
107
|
+
- id: MAILJET
|
|
108
|
+
category: pagos_email
|
|
109
|
+
detectors:
|
|
110
|
+
imports:
|
|
111
|
+
- "import mailjet_rest"
|
|
112
|
+
- "from mailjet_rest"
|
|
113
|
+
- "node-mailjet"
|
|
114
|
+
- "require('node-mailjet')"
|
|
115
|
+
env_vars:
|
|
116
|
+
- "MAILJET_API_KEY"
|
|
117
|
+
- "MAILJET_API_SECRET"
|
|
118
|
+
- "MJ_APIKEY_PUBLIC"
|
|
119
|
+
- "MJ_APIKEY_PRIVATE"
|
|
120
|
+
deps:
|
|
121
|
+
- "mailjet-rest"
|
|
122
|
+
- "node-mailjet"
|
|
123
|
+
- "mailjet"
|
|
124
|
+
dashboard_url: "https://app.mailjet.com/account/apikeys"
|
|
125
|
+
env_example: |
|
|
126
|
+
# MAILJET — operational credentials
|
|
127
|
+
# Generate at: https://app.mailjet.com/account/apikeys
|
|
128
|
+
MAILJET_API_KEY=
|
|
129
|
+
MAILJET_API_SECRET=
|
|
130
|
+
MAILJET_FROM_EMAIL=
|
|
131
|
+
MAILJET_FROM_NAME=
|
|
132
|
+
files:
|
|
133
|
+
test_connection.sh: |
|
|
134
|
+
#!/usr/bin/env bash
|
|
135
|
+
# Smoke-test against Mailjet API: GET /v3/REST/sender.
|
|
136
|
+
set -euo pipefail
|
|
137
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
138
|
+
ENV_PATH="$SCRIPT_DIR/.env"
|
|
139
|
+
[ -f "$ENV_PATH" ] || { echo "ERROR: missing $ENV_PATH" >&2; exit 1; }
|
|
140
|
+
set -a; source "$ENV_PATH"; set +a
|
|
141
|
+
: "${MAILJET_API_KEY:?MAILJET_API_KEY not set}"
|
|
142
|
+
: "${MAILJET_API_SECRET:?MAILJET_API_SECRET not set}"
|
|
143
|
+
RESP=$(curl -fsS -u "$MAILJET_API_KEY:$MAILJET_API_SECRET" https://api.mailjet.com/v3/REST/sender)
|
|
144
|
+
echo "$RESP" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(f"OK — registered senders: {d[\"Count\"]}")'
|
|
145
|
+
README.md: |
|
|
146
|
+
# MAILJET
|
|
147
|
+
|
|
148
|
+
Transactional email (verification, invites, password reset).
|
|
149
|
+
|
|
150
|
+
## Setup
|
|
151
|
+
|
|
152
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
153
|
+
2. Fill in `MAILJET_API_KEY` and `MAILJET_API_SECRET` from https://app.mailjet.com/account/apikeys
|
|
154
|
+
3. `./test_connection.sh`
|
|
155
|
+
|
|
156
|
+
## Scripts
|
|
157
|
+
|
|
158
|
+
| Script | What it does |
|
|
159
|
+
|--------|--------------|
|
|
160
|
+
| `test_connection.sh` | Lists registered senders — confirms auth. |
|
|
161
|
+
CREDENTIALS.md: |
|
|
162
|
+
# Credentials — MAILJET
|
|
163
|
+
|
|
164
|
+
Dashboard: https://app.mailjet.com/account/apikeys
|
|
165
|
+
|
|
166
|
+
| Variable | Type | Where to generate |
|
|
167
|
+
|----------|------|-------------------|
|
|
168
|
+
| `MAILJET_API_KEY` | public | Dashboard → API Keys |
|
|
169
|
+
| `MAILJET_API_SECRET` | secret | Dashboard → API Keys |
|
|
170
|
+
| `MAILJET_FROM_EMAIL` | config | Address verified as sender |
|
|
171
|
+
| `MAILJET_FROM_NAME` | config | Display name shown to recipients |
|
|
172
|
+
|
|
173
|
+
- id: HETZNER
|
|
174
|
+
category: infra
|
|
175
|
+
detectors:
|
|
176
|
+
imports:
|
|
177
|
+
- "hcloud"
|
|
178
|
+
- "from hcloud"
|
|
179
|
+
env_vars:
|
|
180
|
+
- "HCLOUD_TOKEN"
|
|
181
|
+
- "HETZNER_TOKEN"
|
|
182
|
+
- "HETZNER_API_TOKEN"
|
|
183
|
+
deps:
|
|
184
|
+
- "hcloud"
|
|
185
|
+
- "hetznercloud"
|
|
186
|
+
dashboard_url: "https://console.hetzner.cloud/projects"
|
|
187
|
+
env_example: |
|
|
188
|
+
# HETZNER Cloud — operational credentials
|
|
189
|
+
# Generate at: https://console.hetzner.cloud (proyecto → Security → API tokens)
|
|
190
|
+
HCLOUD_TOKEN=
|
|
191
|
+
files:
|
|
192
|
+
test_connection.py: |
|
|
193
|
+
#!/usr/bin/env python3
|
|
194
|
+
"""Smoke-test against Hetzner Cloud API: GET /v1/servers."""
|
|
195
|
+
import os, sys, urllib.request, urllib.error, json
|
|
196
|
+
from pathlib import Path
|
|
197
|
+
|
|
198
|
+
env_path = Path(__file__).parent / ".env"
|
|
199
|
+
if not env_path.exists():
|
|
200
|
+
print(f"ERROR: missing {env_path}", file=sys.stderr); sys.exit(1)
|
|
201
|
+
for line in env_path.read_text().splitlines():
|
|
202
|
+
line = line.strip()
|
|
203
|
+
if not line or line.startswith("#") or "=" not in line: continue
|
|
204
|
+
k, v = line.split("=", 1); os.environ.setdefault(k, v)
|
|
205
|
+
|
|
206
|
+
token = os.environ.get("HCLOUD_TOKEN")
|
|
207
|
+
if not token:
|
|
208
|
+
print("ERROR: HCLOUD_TOKEN not set", file=sys.stderr); sys.exit(1)
|
|
209
|
+
|
|
210
|
+
req = urllib.request.Request(
|
|
211
|
+
"https://api.hetzner.cloud/v1/servers",
|
|
212
|
+
headers={"Authorization": f"Bearer {token}"},
|
|
213
|
+
)
|
|
214
|
+
try:
|
|
215
|
+
with urllib.request.urlopen(req, timeout=10) as r:
|
|
216
|
+
data = json.load(r)
|
|
217
|
+
n = len(data.get("servers", []))
|
|
218
|
+
print(f"OK — servers in the project: {n}")
|
|
219
|
+
except urllib.error.HTTPError as e:
|
|
220
|
+
print(f"FAIL: {e.code} {e.reason}", file=sys.stderr); sys.exit(1)
|
|
221
|
+
README.md: |
|
|
222
|
+
# HETZNER
|
|
223
|
+
|
|
224
|
+
Provisioning and operation of Hetzner Cloud servers.
|
|
225
|
+
|
|
226
|
+
## Setup
|
|
227
|
+
|
|
228
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
229
|
+
2. Create an API token for the project: https://console.hetzner.cloud
|
|
230
|
+
3. `python3 test_connection.py`
|
|
231
|
+
|
|
232
|
+
## Scripts
|
|
233
|
+
|
|
234
|
+
| Script | What it does |
|
|
235
|
+
|--------|--------------|
|
|
236
|
+
| `test_connection.py` | Lists servers in the project — confirms auth. |
|
|
237
|
+
CREDENTIALS.md: |
|
|
238
|
+
# Credentials — HETZNER
|
|
239
|
+
|
|
240
|
+
Dashboard: https://console.hetzner.cloud
|
|
241
|
+
|
|
242
|
+
| Variable | Type | Where to generate | Rotation |
|
|
243
|
+
|----------|------|-------------------|----------|
|
|
244
|
+
| `HCLOUD_TOKEN` | secret | Project → Security → API tokens | revoke + regenerate on leak |
|
|
245
|
+
|
|
246
|
+
- id: REPLICATE
|
|
247
|
+
category: ia
|
|
248
|
+
detectors:
|
|
249
|
+
imports:
|
|
250
|
+
- "import replicate"
|
|
251
|
+
- "from replicate"
|
|
252
|
+
- "require('replicate')"
|
|
253
|
+
env_vars:
|
|
254
|
+
- "REPLICATE_API_TOKEN"
|
|
255
|
+
deps:
|
|
256
|
+
- "replicate"
|
|
257
|
+
dashboard_url: "https://replicate.com/account/api-tokens"
|
|
258
|
+
env_example: |
|
|
259
|
+
# REPLICATE — operational credentials
|
|
260
|
+
# Generate at: https://replicate.com/account/api-tokens
|
|
261
|
+
REPLICATE_API_TOKEN=
|
|
262
|
+
files:
|
|
263
|
+
test_connection.py: |
|
|
264
|
+
#!/usr/bin/env python3
|
|
265
|
+
"""Smoke-test against Replicate API: GET /v1/account."""
|
|
266
|
+
import os, sys, urllib.request, urllib.error, json
|
|
267
|
+
from pathlib import Path
|
|
268
|
+
|
|
269
|
+
env_path = Path(__file__).parent / ".env"
|
|
270
|
+
if not env_path.exists():
|
|
271
|
+
print(f"ERROR: missing {env_path}", file=sys.stderr); sys.exit(1)
|
|
272
|
+
for line in env_path.read_text().splitlines():
|
|
273
|
+
line = line.strip()
|
|
274
|
+
if not line or line.startswith("#") or "=" not in line: continue
|
|
275
|
+
k, v = line.split("=", 1); os.environ.setdefault(k, v)
|
|
276
|
+
|
|
277
|
+
token = os.environ.get("REPLICATE_API_TOKEN")
|
|
278
|
+
if not token:
|
|
279
|
+
print("ERROR: REPLICATE_API_TOKEN not set", file=sys.stderr); sys.exit(1)
|
|
280
|
+
|
|
281
|
+
req = urllib.request.Request(
|
|
282
|
+
"https://api.replicate.com/v1/account",
|
|
283
|
+
headers={"Authorization": f"Bearer {token}"},
|
|
284
|
+
)
|
|
285
|
+
try:
|
|
286
|
+
with urllib.request.urlopen(req, timeout=10) as r:
|
|
287
|
+
data = json.load(r)
|
|
288
|
+
print(f"OK — username: {data.get('username','?')} type: {data.get('type','?')}")
|
|
289
|
+
except urllib.error.HTTPError as e:
|
|
290
|
+
print(f"FAIL: {e.code} {e.reason}", file=sys.stderr); sys.exit(1)
|
|
291
|
+
README.md: |
|
|
292
|
+
# REPLICATE
|
|
293
|
+
|
|
294
|
+
Image and model generation via Replicate.
|
|
295
|
+
|
|
296
|
+
## Setup
|
|
297
|
+
|
|
298
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
299
|
+
2. Token from https://replicate.com/account/api-tokens
|
|
300
|
+
3. `python3 test_connection.py`
|
|
301
|
+
CREDENTIALS.md: |
|
|
302
|
+
# Credentials — REPLICATE
|
|
303
|
+
|
|
304
|
+
Dashboard: https://replicate.com/account/api-tokens
|
|
305
|
+
|
|
306
|
+
| Variable | Type | Rotation |
|
|
307
|
+
|----------|------|----------|
|
|
308
|
+
| `REPLICATE_API_TOKEN` | secret | revoke + regenerate on leak |
|
|
309
|
+
|
|
310
|
+
- id: FIREBASE
|
|
311
|
+
category: mobile_auth
|
|
312
|
+
detectors:
|
|
313
|
+
imports:
|
|
314
|
+
- "firebase-admin"
|
|
315
|
+
- "from firebase_admin"
|
|
316
|
+
- "import firebase_admin"
|
|
317
|
+
- "firebase/app"
|
|
318
|
+
- "firebase/messaging"
|
|
319
|
+
- "@react-native-firebase"
|
|
320
|
+
env_vars:
|
|
321
|
+
- "FIREBASE_PROJECT_ID"
|
|
322
|
+
- "FCM_SERVER_KEY"
|
|
323
|
+
- "GOOGLE_APPLICATION_CREDENTIALS"
|
|
324
|
+
deps:
|
|
325
|
+
- "firebase-admin"
|
|
326
|
+
- "firebase"
|
|
327
|
+
- "@react-native-firebase/app"
|
|
328
|
+
dashboard_url: "https://console.firebase.google.com"
|
|
329
|
+
env_example: |
|
|
330
|
+
# FIREBASE / FCM — operational credentials
|
|
331
|
+
# Required: service account JSON downloaded from the Firebase project.
|
|
332
|
+
# Console → Project settings → Service accounts → Generate new private key
|
|
333
|
+
FIREBASE_PROJECT_ID=
|
|
334
|
+
GOOGLE_APPLICATION_CREDENTIALS=./service-account.json
|
|
335
|
+
files:
|
|
336
|
+
test_connection.py: |
|
|
337
|
+
#!/usr/bin/env python3
|
|
338
|
+
"""Smoke-test FCM: firma un JWT y pide un access token a Google."""
|
|
339
|
+
import os, sys, json, time, base64, hmac, hashlib, urllib.request, urllib.parse
|
|
340
|
+
from pathlib import Path
|
|
341
|
+
|
|
342
|
+
env_path = Path(__file__).parent / ".env"
|
|
343
|
+
if not env_path.exists():
|
|
344
|
+
print(f"ERROR: missing {env_path}", file=sys.stderr); sys.exit(1)
|
|
345
|
+
for line in env_path.read_text().splitlines():
|
|
346
|
+
line = line.strip()
|
|
347
|
+
if not line or line.startswith("#") or "=" not in line: continue
|
|
348
|
+
k, v = line.split("=", 1); os.environ.setdefault(k, v)
|
|
349
|
+
|
|
350
|
+
sa_path = os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", "./service-account.json")
|
|
351
|
+
sa_path = (Path(__file__).parent / sa_path).resolve()
|
|
352
|
+
if not sa_path.exists():
|
|
353
|
+
print(f"ERROR: service account not found at {sa_path}", file=sys.stderr); sys.exit(1)
|
|
354
|
+
|
|
355
|
+
try:
|
|
356
|
+
from google.oauth2 import service_account
|
|
357
|
+
from google.auth.transport.requests import Request
|
|
358
|
+
except ImportError:
|
|
359
|
+
print("ERROR: pip install google-auth", file=sys.stderr); sys.exit(1)
|
|
360
|
+
|
|
361
|
+
creds = service_account.Credentials.from_service_account_file(
|
|
362
|
+
str(sa_path),
|
|
363
|
+
scopes=["https://www.googleapis.com/auth/firebase.messaging"],
|
|
364
|
+
)
|
|
365
|
+
creds.refresh(Request())
|
|
366
|
+
if creds.token:
|
|
367
|
+
print(f"OK — FCM access token obtained (project: {os.environ.get('FIREBASE_PROJECT_ID','?')})")
|
|
368
|
+
else:
|
|
369
|
+
print("FAIL: no token obtained", file=sys.stderr); sys.exit(1)
|
|
370
|
+
requirements.txt: |
|
|
371
|
+
google-auth>=2.0
|
|
372
|
+
README.md: |
|
|
373
|
+
# FIREBASE / FCM
|
|
374
|
+
|
|
375
|
+
Push notifications for Android / iOS / Web via Firebase Cloud Messaging.
|
|
376
|
+
|
|
377
|
+
## Setup
|
|
378
|
+
|
|
379
|
+
1. Download the service account JSON from Console → Project settings → Service accounts.
|
|
380
|
+
2. Save it as `service-account.json` in this folder (gitignored).
|
|
381
|
+
3. `cp .env.example .env && chmod 600 .env` and fill in `FIREBASE_PROJECT_ID`.
|
|
382
|
+
4. `pip install -r requirements.txt`
|
|
383
|
+
5. `python3 test_connection.py`
|
|
384
|
+
CREDENTIALS.md: |
|
|
385
|
+
# Credentials — FIREBASE
|
|
386
|
+
|
|
387
|
+
Dashboard: https://console.firebase.google.com
|
|
388
|
+
|
|
389
|
+
| Artifact | Where to generate | Notes |
|
|
390
|
+
|----------|-------------------|-------|
|
|
391
|
+
| service-account.json | Project settings → Service accounts → Generate new private key | DO NOT commit; gitignored |
|
|
392
|
+
| `FIREBASE_PROJECT_ID` | Project settings → General | Identifies the project |
|
|
393
|
+
|
|
394
|
+
## Manual FCM setup per platform
|
|
395
|
+
|
|
396
|
+
- Android: `google-services.json` in `android/app/`.
|
|
397
|
+
- iOS: `GoogleService-Info.plist` in the app bundle.
|
|
398
|
+
- Web: client config with `apiKey`, `messagingSenderId`, `appId`.
|
|
399
|
+
|
|
400
|
+
- id: GOOGLE_OAUTH
|
|
401
|
+
category: mobile_auth
|
|
402
|
+
detectors:
|
|
403
|
+
imports:
|
|
404
|
+
- "google-auth-oauthlib"
|
|
405
|
+
- "from google.oauth2"
|
|
406
|
+
- "next-auth/providers/google"
|
|
407
|
+
- "@react-oauth/google"
|
|
408
|
+
env_vars:
|
|
409
|
+
- "GOOGLE_CLIENT_ID"
|
|
410
|
+
- "GOOGLE_CLIENT_SECRET"
|
|
411
|
+
- "GOOGLE_OAUTH_CLIENT_ID"
|
|
412
|
+
deps:
|
|
413
|
+
- "google-auth-oauthlib"
|
|
414
|
+
- "@react-oauth/google"
|
|
415
|
+
- "next-auth"
|
|
416
|
+
dashboard_url: "https://console.cloud.google.com/apis/credentials"
|
|
417
|
+
env_example: |
|
|
418
|
+
# GOOGLE OAuth 2.0 — operational credentials
|
|
419
|
+
# Generate at: https://console.cloud.google.com/apis/credentials
|
|
420
|
+
# Need a Client ID + Secret per platform (Web/Android/iOS).
|
|
421
|
+
GOOGLE_CLIENT_ID=
|
|
422
|
+
GOOGLE_CLIENT_SECRET=
|
|
423
|
+
GOOGLE_REDIRECT_URI=
|
|
424
|
+
files:
|
|
425
|
+
test_connection.sh: |
|
|
426
|
+
#!/usr/bin/env bash
|
|
427
|
+
# Smoke-test: validate that Google's discovery endpoint responds
|
|
428
|
+
# and that GOOGLE_CLIENT_ID has a reasonable shape.
|
|
429
|
+
set -euo pipefail
|
|
430
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
431
|
+
ENV_PATH="$SCRIPT_DIR/.env"
|
|
432
|
+
[ -f "$ENV_PATH" ] || { echo "ERROR: missing $ENV_PATH" >&2; exit 1; }
|
|
433
|
+
set -a; source "$ENV_PATH"; set +a
|
|
434
|
+
: "${GOOGLE_CLIENT_ID:?GOOGLE_CLIENT_ID not set}"
|
|
435
|
+
[[ "$GOOGLE_CLIENT_ID" == *".apps.googleusercontent.com" ]] || {
|
|
436
|
+
echo "FAIL: GOOGLE_CLIENT_ID does not end with .apps.googleusercontent.com" >&2; exit 1; }
|
|
437
|
+
curl -fsS https://accounts.google.com/.well-known/openid-configuration > /dev/null
|
|
438
|
+
echo "OK — discovery endpoint reachable and client_id shape is valid."
|
|
439
|
+
README.md: |
|
|
440
|
+
# GOOGLE_OAUTH
|
|
441
|
+
|
|
442
|
+
Login with Google. Per-platform Client IDs (Web, Android, iOS).
|
|
443
|
+
|
|
444
|
+
## Setup
|
|
445
|
+
|
|
446
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
447
|
+
2. Client IDs from https://console.cloud.google.com/apis/credentials
|
|
448
|
+
3. `./test_connection.sh`
|
|
449
|
+
|
|
450
|
+
## Notes
|
|
451
|
+
|
|
452
|
+
- For Android/iOS: the client_id is shipped in the app (not a secret).
|
|
453
|
+
- For Web: you need client_secret and a registered redirect_uri.
|
|
454
|
+
CREDENTIALS.md: |
|
|
455
|
+
# Credentials — GOOGLE OAuth
|
|
456
|
+
|
|
457
|
+
Dashboard: https://console.cloud.google.com/apis/credentials
|
|
458
|
+
|
|
459
|
+
| Variable | Type | Notes |
|
|
460
|
+
|----------|------|-------|
|
|
461
|
+
| `GOOGLE_CLIENT_ID` | public-ish | OAuth client identifier |
|
|
462
|
+
| `GOOGLE_CLIENT_SECRET` | secret | Web only. NEVER in mobile apps. |
|
|
463
|
+
| `GOOGLE_REDIRECT_URI` | config | Must match exactly a registered URI |
|
|
464
|
+
|
|
465
|
+
- id: DB_CLI
|
|
466
|
+
category: datos
|
|
467
|
+
detectors:
|
|
468
|
+
imports:
|
|
469
|
+
- "from sqlalchemy"
|
|
470
|
+
- "import sqlalchemy"
|
|
471
|
+
- "psycopg"
|
|
472
|
+
- "asyncpg"
|
|
473
|
+
- "from pg"
|
|
474
|
+
- "require('pg')"
|
|
475
|
+
env_vars:
|
|
476
|
+
- "DATABASE_URL"
|
|
477
|
+
- "POSTGRES_USER"
|
|
478
|
+
- "POSTGRES_PASSWORD"
|
|
479
|
+
- "POSTGRES_HOST"
|
|
480
|
+
- "POSTGRES_DB"
|
|
481
|
+
deps:
|
|
482
|
+
- "sqlalchemy"
|
|
483
|
+
- "psycopg"
|
|
484
|
+
- "psycopg2-binary"
|
|
485
|
+
- "asyncpg"
|
|
486
|
+
- "pg"
|
|
487
|
+
- "drizzle-orm"
|
|
488
|
+
dashboard_url: ""
|
|
489
|
+
env_example: |
|
|
490
|
+
# DB_CLI — access to the project's Postgres database
|
|
491
|
+
# If the DB is on a remote server via SSH, set SSH_HOST + SSH_USER.
|
|
492
|
+
# If local, only POSTGRES_* is needed.
|
|
493
|
+
DATABASE_URL=postgresql://user:pass@host:5432/dbname
|
|
494
|
+
# Alternative: individual vars
|
|
495
|
+
POSTGRES_HOST=localhost
|
|
496
|
+
POSTGRES_PORT=5432
|
|
497
|
+
POSTGRES_USER=
|
|
498
|
+
POSTGRES_PASSWORD=
|
|
499
|
+
POSTGRES_DB=
|
|
500
|
+
# Optional — for a DB behind an SSH bastion
|
|
501
|
+
SSH_HOST=
|
|
502
|
+
SSH_USER=
|
|
503
|
+
files:
|
|
504
|
+
test_connection.sh: |
|
|
505
|
+
#!/usr/bin/env bash
|
|
506
|
+
# Smoke-test against Postgres: pg_isready (local or via SSH).
|
|
507
|
+
set -euo pipefail
|
|
508
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
509
|
+
ENV_PATH="$SCRIPT_DIR/.env"
|
|
510
|
+
[ -f "$ENV_PATH" ] || { echo "ERROR: missing $ENV_PATH" >&2; exit 1; }
|
|
511
|
+
set -a; source "$ENV_PATH"; set +a
|
|
512
|
+
|
|
513
|
+
if [ -n "${SSH_HOST:-}" ] && [ -n "${SSH_USER:-}" ]; then
|
|
514
|
+
ssh "${SSH_USER}@${SSH_HOST}" "pg_isready -h ${POSTGRES_HOST:-localhost} -p ${POSTGRES_PORT:-5432}"
|
|
515
|
+
echo "OK — Postgres reachable via ${SSH_USER}@${SSH_HOST}."
|
|
516
|
+
else
|
|
517
|
+
: "${POSTGRES_HOST:?POSTGRES_HOST or DATABASE_URL not set}"
|
|
518
|
+
pg_isready -h "${POSTGRES_HOST}" -p "${POSTGRES_PORT:-5432}" -U "${POSTGRES_USER:-postgres}"
|
|
519
|
+
echo "OK — Local Postgres reachable."
|
|
520
|
+
fi
|
|
521
|
+
abrir_psql.sh: |
|
|
522
|
+
#!/usr/bin/env bash
|
|
523
|
+
# Opens an interactive psql session against the DB in .env.
|
|
524
|
+
set -euo pipefail
|
|
525
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
526
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
527
|
+
if [ -n "${DATABASE_URL:-}" ]; then
|
|
528
|
+
psql "$DATABASE_URL"
|
|
529
|
+
else
|
|
530
|
+
PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_HOST" -p "${POSTGRES_PORT:-5432}" -U "$POSTGRES_USER" -d "$POSTGRES_DB"
|
|
531
|
+
fi
|
|
532
|
+
README.md: |
|
|
533
|
+
# DB_CLI
|
|
534
|
+
|
|
535
|
+
Terminal access to the project's Postgres database.
|
|
536
|
+
|
|
537
|
+
## Setup
|
|
538
|
+
|
|
539
|
+
1. `cp .env.example .env && chmod 600 .env` and fill in.
|
|
540
|
+
2. `./test_connection.sh`
|
|
541
|
+
3. `./abrir_psql.sh` for an interactive session.
|
|
542
|
+
|
|
543
|
+
## Notes
|
|
544
|
+
|
|
545
|
+
- If the production DB does not expose a public port, set
|
|
546
|
+
`SSH_HOST`/`SSH_USER` and the script will tunnel via SSH.
|
|
547
|
+
CREDENTIALS.md: |
|
|
548
|
+
# Credentials — DB_CLI
|
|
549
|
+
|
|
550
|
+
| Variable | Type | Notes |
|
|
551
|
+
|----------|------|-------|
|
|
552
|
+
| `DATABASE_URL` | secret | Full DSN, alternative to the individual vars |
|
|
553
|
+
| `POSTGRES_PASSWORD` | secret | Rotate on exposure |
|
|
554
|
+
|
|
555
|
+
- id: COOLIFY
|
|
556
|
+
category: infra
|
|
557
|
+
detectors:
|
|
558
|
+
imports: []
|
|
559
|
+
env_vars:
|
|
560
|
+
- "COOLIFY_TOKEN"
|
|
561
|
+
- "COOLIFY_URL"
|
|
562
|
+
deps: []
|
|
563
|
+
dashboard_url: ""
|
|
564
|
+
manual_only: false
|
|
565
|
+
env_example: |
|
|
566
|
+
# COOLIFY — self-hosted PaaS panel
|
|
567
|
+
COOLIFY_URL=
|
|
568
|
+
COOLIFY_TOKEN=
|
|
569
|
+
files:
|
|
570
|
+
test_connection.sh: |
|
|
571
|
+
#!/usr/bin/env bash
|
|
572
|
+
# Smoke-test against Coolify API: GET /api/v1/version.
|
|
573
|
+
set -euo pipefail
|
|
574
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
575
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
576
|
+
: "${COOLIFY_URL:?COOLIFY_URL not set}"
|
|
577
|
+
: "${COOLIFY_TOKEN:?COOLIFY_TOKEN not set}"
|
|
578
|
+
RESP=$(curl -fsS -H "Authorization: Bearer $COOLIFY_TOKEN" "${COOLIFY_URL%/}/api/v1/version")
|
|
579
|
+
echo "OK — Coolify version: $RESP"
|
|
580
|
+
README.md: |
|
|
581
|
+
# COOLIFY
|
|
582
|
+
|
|
583
|
+
Access to the self-hosted PaaS panel that orchestrates deployments.
|
|
584
|
+
|
|
585
|
+
## Setup
|
|
586
|
+
|
|
587
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
588
|
+
2. Token from Coolify → Profile → API tokens.
|
|
589
|
+
3. `./test_connection.sh`
|
|
590
|
+
CREDENTIALS.md: |
|
|
591
|
+
# Credentials — COOLIFY
|
|
592
|
+
|
|
593
|
+
| Variable | Type | Notes |
|
|
594
|
+
|----------|------|-------|
|
|
595
|
+
| `COOLIFY_URL` | config | Panel base URL (no trailing slash) |
|
|
596
|
+
| `COOLIFY_TOKEN` | secret | Generated from Profile → API tokens |
|
|
597
|
+
|
|
598
|
+
- id: TAILSCALE
|
|
599
|
+
category: infra
|
|
600
|
+
detectors:
|
|
601
|
+
imports: []
|
|
602
|
+
env_vars:
|
|
603
|
+
- "TAILSCALE_AUTHKEY"
|
|
604
|
+
- "TS_AUTHKEY"
|
|
605
|
+
deps: []
|
|
606
|
+
dashboard_url: "https://login.tailscale.com/admin/settings/keys"
|
|
607
|
+
manual_only: true
|
|
608
|
+
env_example: |
|
|
609
|
+
# TAILSCALE — auth keys (only if we automate provisioning)
|
|
610
|
+
# For normal human use the `tailscale` CLI manages the session without .env.
|
|
611
|
+
TAILSCALE_AUTHKEY=
|
|
612
|
+
files:
|
|
613
|
+
README.md: |
|
|
614
|
+
# TAILSCALE
|
|
615
|
+
|
|
616
|
+
Mesh VPN over WireGuard. Access to internal services without exposing ports.
|
|
617
|
+
|
|
618
|
+
## Manual setup
|
|
619
|
+
|
|
620
|
+
- Client: install from https://tailscale.com/download
|
|
621
|
+
- `tailscale up` from the device; auth happens in the browser.
|
|
622
|
+
- Auth keys (for automated server provisioning) from:
|
|
623
|
+
https://login.tailscale.com/admin/settings/keys
|
|
624
|
+
|
|
625
|
+
## No automated smoke-test
|
|
626
|
+
|
|
627
|
+
State is verified with `tailscale status` from the official CLI.
|
|
628
|
+
CREDENTIALS.md: |
|
|
629
|
+
# Credentials — TAILSCALE
|
|
630
|
+
|
|
631
|
+
Dashboard: https://login.tailscale.com/admin
|
|
632
|
+
|
|
633
|
+
- Auth keys: single-use, expire. Only for provisioning new nodes
|
|
634
|
+
without interactive login.
|
|
635
|
+
- Human usage relies on the client's OAuth session — no `.env` secrets.
|
|
636
|
+
|
|
637
|
+
- id: GITHUB_RUNNER
|
|
638
|
+
category: infra
|
|
639
|
+
detectors:
|
|
640
|
+
imports: []
|
|
641
|
+
env_vars:
|
|
642
|
+
- "RUNNER_TOKEN"
|
|
643
|
+
- "GH_RUNNER_TOKEN"
|
|
644
|
+
deps: []
|
|
645
|
+
dashboard_url: ""
|
|
646
|
+
manual_only: true
|
|
647
|
+
env_example: |
|
|
648
|
+
# GITHUB self-hosted runner — registration
|
|
649
|
+
# Registration token: GitHub → Settings → Actions → Runners → New self-hosted runner
|
|
650
|
+
# (Org-level: org Settings, not a single repo.)
|
|
651
|
+
GH_OWNER=
|
|
652
|
+
GH_RUNNER_TOKEN=
|
|
653
|
+
RUNNER_NAME=
|
|
654
|
+
RUNNER_LABELS=self-hosted,linux,x64
|
|
655
|
+
files:
|
|
656
|
+
README.md: |
|
|
657
|
+
# GITHUB_RUNNER
|
|
658
|
+
|
|
659
|
+
Self-hosted GitHub Actions runner.
|
|
660
|
+
|
|
661
|
+
## Setup
|
|
662
|
+
|
|
663
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
664
|
+
2. Token from Settings → Actions → Runners → New self-hosted runner.
|
|
665
|
+
3. Run the runner following GitHub's instructions for your OS.
|
|
666
|
+
|
|
667
|
+
The token expires in ~1h; only used at registration time.
|
|
668
|
+
|
|
669
|
+
## Operations
|
|
670
|
+
|
|
671
|
+
- Runner status: `sudo systemctl status actions.runner.*`
|
|
672
|
+
- Logs: `journalctl -u actions.runner.*`
|
|
673
|
+
CREDENTIALS.md: |
|
|
674
|
+
# Credentials — GITHUB_RUNNER
|
|
675
|
+
|
|
676
|
+
| Variable | Type | Notes |
|
|
677
|
+
|----------|------|-------|
|
|
678
|
+
| `GH_OWNER` | config | Org or user the runner is registered against |
|
|
679
|
+
| `GH_RUNNER_TOKEN` | secret | Ephemeral (~1h). Regenerate per registration. |
|
|
680
|
+
|
|
681
|
+
- id: APPLE
|
|
682
|
+
category: mobile_auth
|
|
683
|
+
detectors:
|
|
684
|
+
imports: []
|
|
685
|
+
env_vars:
|
|
686
|
+
- "APP_STORE_CONNECT_API_KEY"
|
|
687
|
+
- "FASTLANE_USER"
|
|
688
|
+
- "MATCH_PASSWORD"
|
|
689
|
+
deps: []
|
|
690
|
+
dashboard_url: "https://appstoreconnect.apple.com"
|
|
691
|
+
manual_only: true
|
|
692
|
+
env_example: |
|
|
693
|
+
# APPLE — App Store Connect + Fastlane Match
|
|
694
|
+
# API key JSON: appstoreconnect.apple.com → Users and Access → Keys
|
|
695
|
+
ASC_KEY_ID=
|
|
696
|
+
ASC_ISSUER_ID=
|
|
697
|
+
ASC_KEY_PATH=./AuthKey_XXXXXXXXXX.p8
|
|
698
|
+
# Fastlane Match (keep names EXACT: the SDK requires them)
|
|
699
|
+
MATCH_PASSWORD=
|
|
700
|
+
MATCH_GIT_URL=
|
|
701
|
+
files:
|
|
702
|
+
README.md: |
|
|
703
|
+
# APPLE
|
|
704
|
+
|
|
705
|
+
App Store Connect: API key, Fastlane Match (certs/profiles), Team ID.
|
|
706
|
+
|
|
707
|
+
## Manual setup
|
|
708
|
+
|
|
709
|
+
1. Download the API key (`.p8`) from App Store Connect → Users and Access → Keys.
|
|
710
|
+
2. Save it in this folder as `AuthKey_<KEY_ID>.p8` (gitignored).
|
|
711
|
+
3. Configure `MATCH_PASSWORD` and `MATCH_GIT_URL` for the certs repo.
|
|
712
|
+
|
|
713
|
+
## No automated smoke-test
|
|
714
|
+
|
|
715
|
+
Verify via Fastlane: `fastlane match development --readonly`.
|
|
716
|
+
CREDENTIALS.md: |
|
|
717
|
+
# Credentials — APPLE
|
|
718
|
+
|
|
719
|
+
Dashboard: https://appstoreconnect.apple.com
|
|
720
|
+
|
|
721
|
+
| Artifact | Notes |
|
|
722
|
+
|----------|-------|
|
|
723
|
+
| `AuthKey_*.p8` | API key downloaded ONCE. Keep it safe. |
|
|
724
|
+
| `ASC_KEY_ID` | Visible next to the key in the dashboard |
|
|
725
|
+
| `ASC_ISSUER_ID` | Visible in Users and Access → Keys |
|
|
726
|
+
| `MATCH_PASSWORD` | Name required by Fastlane (not `APPLE_*`) |
|
|
727
|
+
| `MATCH_GIT_URL` | Private repo with encrypted certs |
|
|
728
|
+
|
|
729
|
+
- id: GOOGLE_PLAY
|
|
730
|
+
category: mobile_auth
|
|
731
|
+
detectors:
|
|
732
|
+
imports: []
|
|
733
|
+
env_vars:
|
|
734
|
+
- "GOOGLE_PLAY_SERVICE_ACCOUNT"
|
|
735
|
+
- "SUPPLY_JSON_KEY"
|
|
736
|
+
deps: []
|
|
737
|
+
dashboard_url: "https://play.google.com/console"
|
|
738
|
+
manual_only: true
|
|
739
|
+
env_example: |
|
|
740
|
+
# GOOGLE PLAY Console
|
|
741
|
+
# Service account JSON: Play Console → Setup → API access → Service accounts
|
|
742
|
+
GOOGLE_PLAY_SERVICE_ACCOUNT=./play-service-account.json
|
|
743
|
+
PACKAGE_NAME=
|
|
744
|
+
files:
|
|
745
|
+
README.md: |
|
|
746
|
+
# GOOGLE_PLAY
|
|
747
|
+
|
|
748
|
+
Play Console: service account JSON, upload keystore, package name.
|
|
749
|
+
|
|
750
|
+
## Manual setup
|
|
751
|
+
|
|
752
|
+
1. Create a GCP service account and link it in Play Console → Setup → API access.
|
|
753
|
+
2. Download the JSON and save it here as `play-service-account.json` (gitignored).
|
|
754
|
+
3. `PACKAGE_NAME` must match `applicationId` from the Android build.
|
|
755
|
+
|
|
756
|
+
## No automated smoke-test
|
|
757
|
+
|
|
758
|
+
Verify via Fastlane: `fastlane supply --track internal --skip_upload_apk --skip_upload_aab`.
|
|
759
|
+
CREDENTIALS.md: |
|
|
760
|
+
# Credentials — GOOGLE_PLAY
|
|
761
|
+
|
|
762
|
+
Dashboard: https://play.google.com/console
|
|
763
|
+
|
|
764
|
+
| Artifact | Notes |
|
|
765
|
+
|----------|-------|
|
|
766
|
+
| `play-service-account.json` | DO NOT commit; gitignored |
|
|
767
|
+
| `PACKAGE_NAME` | applicationId of the Android project |
|
|
768
|
+
|
|
769
|
+
# ------------------------------------------------------------------
|
|
770
|
+
# IA / LLMs (texto)
|
|
771
|
+
# ------------------------------------------------------------------
|
|
772
|
+
|
|
773
|
+
- id: OPENAI
|
|
774
|
+
category: ia_texto
|
|
775
|
+
detectors:
|
|
776
|
+
imports: ["import openai", "from openai", "require('openai')", "@ai-sdk/openai", "from langchain_openai"]
|
|
777
|
+
env_vars: ["OPENAI_API_KEY", "OPENAI_ORG_ID"]
|
|
778
|
+
deps: ["openai", "@ai-sdk/openai", "langchain-openai"]
|
|
779
|
+
dashboard_url: "https://platform.openai.com/api-keys"
|
|
780
|
+
env_example: |
|
|
781
|
+
# OPENAI — generate at https://platform.openai.com/api-keys
|
|
782
|
+
OPENAI_API_KEY=
|
|
783
|
+
files:
|
|
784
|
+
test_connection.sh: |
|
|
785
|
+
#!/usr/bin/env bash
|
|
786
|
+
set -euo pipefail
|
|
787
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
788
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
789
|
+
: "${OPENAI_API_KEY:?OPENAI_API_KEY not set}"
|
|
790
|
+
N=$(curl -fsS https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
791
|
+
echo "OK — $N models available."
|
|
792
|
+
README.md: |
|
|
793
|
+
# OPENAI
|
|
794
|
+
OpenAI API (GPT, embeddings, DALL·E, Whisper).
|
|
795
|
+
## Setup
|
|
796
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
797
|
+
2. Key from https://platform.openai.com/api-keys
|
|
798
|
+
3. `./test_connection.sh`
|
|
799
|
+
CREDENTIALS.md: |
|
|
800
|
+
# Credentials — OPENAI
|
|
801
|
+
Dashboard: https://platform.openai.com/api-keys
|
|
802
|
+
| Variable | Type |
|
|
803
|
+
|----------|------|
|
|
804
|
+
| `OPENAI_API_KEY` | secret |
|
|
805
|
+
|
|
806
|
+
- id: ANTHROPIC
|
|
807
|
+
category: ia_texto
|
|
808
|
+
detectors:
|
|
809
|
+
imports: ["import anthropic", "from anthropic", "@anthropic-ai/sdk", "@ai-sdk/anthropic", "from langchain_anthropic"]
|
|
810
|
+
env_vars: ["ANTHROPIC_API_KEY"]
|
|
811
|
+
deps: ["anthropic", "@anthropic-ai/sdk", "@ai-sdk/anthropic", "langchain-anthropic"]
|
|
812
|
+
dashboard_url: "https://console.anthropic.com/settings/keys"
|
|
813
|
+
env_example: |
|
|
814
|
+
# ANTHROPIC — generate at https://console.anthropic.com/settings/keys
|
|
815
|
+
ANTHROPIC_API_KEY=
|
|
816
|
+
files:
|
|
817
|
+
test_connection.sh: |
|
|
818
|
+
#!/usr/bin/env bash
|
|
819
|
+
set -euo pipefail
|
|
820
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
821
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
822
|
+
: "${ANTHROPIC_API_KEY:?ANTHROPIC_API_KEY not set}"
|
|
823
|
+
N=$(curl -fsS https://api.anthropic.com/v1/models -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
824
|
+
echo "OK — $N Claude models available."
|
|
825
|
+
README.md: |
|
|
826
|
+
# ANTHROPIC
|
|
827
|
+
Claude API (Opus, Sonnet, Haiku).
|
|
828
|
+
## Setup
|
|
829
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
830
|
+
2. Key from https://console.anthropic.com/settings/keys
|
|
831
|
+
3. `./test_connection.sh`
|
|
832
|
+
CREDENTIALS.md: |
|
|
833
|
+
# Credentials — ANTHROPIC
|
|
834
|
+
Dashboard: https://console.anthropic.com/settings/keys
|
|
835
|
+
`ANTHROPIC_API_KEY` — secret. Rotate on leak.
|
|
836
|
+
|
|
837
|
+
- id: GOOGLE_AI
|
|
838
|
+
category: ia_texto
|
|
839
|
+
detectors:
|
|
840
|
+
imports: ["import google.generativeai", "from google import genai", "@google/generative-ai", "@ai-sdk/google"]
|
|
841
|
+
env_vars: ["GOOGLE_API_KEY", "GEMINI_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"]
|
|
842
|
+
deps: ["google-generativeai", "@google/generative-ai", "@ai-sdk/google"]
|
|
843
|
+
dashboard_url: "https://aistudio.google.com/apikey"
|
|
844
|
+
env_example: |
|
|
845
|
+
# GOOGLE AI (Gemini) — generate at https://aistudio.google.com/apikey
|
|
846
|
+
GEMINI_API_KEY=
|
|
847
|
+
files:
|
|
848
|
+
test_connection.sh: |
|
|
849
|
+
#!/usr/bin/env bash
|
|
850
|
+
set -euo pipefail
|
|
851
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
852
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
853
|
+
KEY="${GEMINI_API_KEY:-${GOOGLE_API_KEY:-}}"
|
|
854
|
+
[ -n "$KEY" ] || { echo "ERROR: GEMINI_API_KEY not set" >&2; exit 1; }
|
|
855
|
+
N=$(curl -fsS "https://generativelanguage.googleapis.com/v1beta/models?key=$KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["models"]))')
|
|
856
|
+
echo "OK — $N Gemini models available."
|
|
857
|
+
README.md: |
|
|
858
|
+
# GOOGLE_AI
|
|
859
|
+
Google Gemini API (text + multimodal).
|
|
860
|
+
## Setup
|
|
861
|
+
1. `cp .env.example .env && chmod 600 .env`
|
|
862
|
+
2. Key from https://aistudio.google.com/apikey
|
|
863
|
+
3. `./test_connection.sh`
|
|
864
|
+
CREDENTIALS.md: |
|
|
865
|
+
# Credentials — GOOGLE_AI
|
|
866
|
+
Dashboard: https://aistudio.google.com/apikey
|
|
867
|
+
`GEMINI_API_KEY` — secret. Shares AI Studio quotas.
|
|
868
|
+
|
|
869
|
+
- id: COHERE
|
|
870
|
+
category: ia_texto
|
|
871
|
+
detectors:
|
|
872
|
+
imports: ["import cohere", "from cohere"]
|
|
873
|
+
env_vars: ["COHERE_API_KEY", "CO_API_KEY"]
|
|
874
|
+
deps: ["cohere", "cohere-ai"]
|
|
875
|
+
dashboard_url: "https://dashboard.cohere.com/api-keys"
|
|
876
|
+
env_example: |
|
|
877
|
+
COHERE_API_KEY=
|
|
878
|
+
files:
|
|
879
|
+
test_connection.sh: |
|
|
880
|
+
#!/usr/bin/env bash
|
|
881
|
+
set -euo pipefail
|
|
882
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
883
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
884
|
+
: "${COHERE_API_KEY:?COHERE_API_KEY not set}"
|
|
885
|
+
curl -fsS https://api.cohere.com/v1/check-api-key -X POST -H "Authorization: Bearer $COHERE_API_KEY" >/dev/null
|
|
886
|
+
echo "OK — Cohere API key valid."
|
|
887
|
+
README.md: |
|
|
888
|
+
# COHERE
|
|
889
|
+
Cohere API (embed, rerank, command).
|
|
890
|
+
CREDENTIALS.md: |
|
|
891
|
+
Dashboard: https://dashboard.cohere.com/api-keys
|
|
892
|
+
`COHERE_API_KEY` — secret.
|
|
893
|
+
|
|
894
|
+
- id: MISTRAL
|
|
895
|
+
category: ia_texto
|
|
896
|
+
detectors:
|
|
897
|
+
imports: ["import mistralai", "from mistralai", "@mistralai/mistralai", "@ai-sdk/mistral"]
|
|
898
|
+
env_vars: ["MISTRAL_API_KEY"]
|
|
899
|
+
deps: ["mistralai", "@mistralai/mistralai", "@ai-sdk/mistral"]
|
|
900
|
+
dashboard_url: "https://console.mistral.ai/api-keys"
|
|
901
|
+
env_example: |
|
|
902
|
+
MISTRAL_API_KEY=
|
|
903
|
+
files:
|
|
904
|
+
test_connection.sh: |
|
|
905
|
+
#!/usr/bin/env bash
|
|
906
|
+
set -euo pipefail
|
|
907
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
908
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
909
|
+
: "${MISTRAL_API_KEY:?MISTRAL_API_KEY not set}"
|
|
910
|
+
N=$(curl -fsS https://api.mistral.ai/v1/models -H "Authorization: Bearer $MISTRAL_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
911
|
+
echo "OK — $N Mistral models."
|
|
912
|
+
README.md: |
|
|
913
|
+
# MISTRAL
|
|
914
|
+
Mistral AI API (Mistral, Codestral, Pixtral).
|
|
915
|
+
CREDENTIALS.md: |
|
|
916
|
+
Dashboard: https://console.mistral.ai/api-keys
|
|
917
|
+
`MISTRAL_API_KEY` — secret.
|
|
918
|
+
|
|
919
|
+
- id: TOGETHER_AI
|
|
920
|
+
category: ia_texto
|
|
921
|
+
detectors:
|
|
922
|
+
imports: ["import together", "from together", "@ai-sdk/togetherai"]
|
|
923
|
+
env_vars: ["TOGETHER_API_KEY", "TOGETHERAI_API_KEY"]
|
|
924
|
+
deps: ["together", "@ai-sdk/togetherai"]
|
|
925
|
+
dashboard_url: "https://api.together.ai/settings/api-keys"
|
|
926
|
+
env_example: |
|
|
927
|
+
TOGETHER_API_KEY=
|
|
928
|
+
files:
|
|
929
|
+
test_connection.sh: |
|
|
930
|
+
#!/usr/bin/env bash
|
|
931
|
+
set -euo pipefail
|
|
932
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
933
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
934
|
+
: "${TOGETHER_API_KEY:?TOGETHER_API_KEY not set}"
|
|
935
|
+
N=$(curl -fsS https://api.together.xyz/v1/models -H "Authorization: Bearer $TOGETHER_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')
|
|
936
|
+
echo "OK — $N open-source models via Together."
|
|
937
|
+
README.md: |
|
|
938
|
+
# TOGETHER_AI
|
|
939
|
+
Cheap inference for open-source models (Llama, Mixtral, etc.).
|
|
940
|
+
CREDENTIALS.md: |
|
|
941
|
+
Dashboard: https://api.together.ai/settings/api-keys
|
|
942
|
+
`TOGETHER_API_KEY` — secret.
|
|
943
|
+
|
|
944
|
+
- id: HUGGINGFACE
|
|
945
|
+
category: ia_texto
|
|
946
|
+
detectors:
|
|
947
|
+
imports: ["from huggingface_hub", "import huggingface_hub", "@huggingface/inference"]
|
|
948
|
+
env_vars: ["HF_TOKEN", "HUGGINGFACE_API_KEY", "HUGGINGFACEHUB_API_TOKEN"]
|
|
949
|
+
deps: ["huggingface_hub", "@huggingface/inference"]
|
|
950
|
+
dashboard_url: "https://huggingface.co/settings/tokens"
|
|
951
|
+
env_example: |
|
|
952
|
+
HF_TOKEN=
|
|
953
|
+
files:
|
|
954
|
+
test_connection.sh: |
|
|
955
|
+
#!/usr/bin/env bash
|
|
956
|
+
set -euo pipefail
|
|
957
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
958
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
959
|
+
TOKEN="${HF_TOKEN:-${HUGGINGFACE_API_KEY:-${HUGGINGFACEHUB_API_TOKEN:-}}}"
|
|
960
|
+
[ -n "$TOKEN" ] || { echo "ERROR: HF_TOKEN not set" >&2; exit 1; }
|
|
961
|
+
USER=$(curl -fsS https://huggingface.co/api/whoami-v2 -H "Authorization: Bearer $TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["name"])')
|
|
962
|
+
echo "OK — authed as $USER."
|
|
963
|
+
README.md: |
|
|
964
|
+
# HUGGINGFACE
|
|
965
|
+
Hub + Inference API + Spaces.
|
|
966
|
+
CREDENTIALS.md: |
|
|
967
|
+
Dashboard: https://huggingface.co/settings/tokens
|
|
968
|
+
`HF_TOKEN` — secret. Minimal scopes for the Inference API.
|
|
969
|
+
|
|
970
|
+
- id: PERPLEXITY
|
|
971
|
+
category: ia_texto
|
|
972
|
+
detectors:
|
|
973
|
+
imports: ["@ai-sdk/perplexity"]
|
|
974
|
+
env_vars: ["PERPLEXITY_API_KEY", "PPLX_API_KEY"]
|
|
975
|
+
deps: ["@ai-sdk/perplexity"]
|
|
976
|
+
dashboard_url: "https://www.perplexity.ai/settings/api"
|
|
977
|
+
env_example: |
|
|
978
|
+
PERPLEXITY_API_KEY=
|
|
979
|
+
files:
|
|
980
|
+
test_connection.sh: |
|
|
981
|
+
#!/usr/bin/env bash
|
|
982
|
+
# Perplexity has no /models endpoint; validate via a tiny POST.
|
|
983
|
+
set -euo pipefail
|
|
984
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
985
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
986
|
+
: "${PERPLEXITY_API_KEY:?PERPLEXITY_API_KEY not set}"
|
|
987
|
+
RESP=$(curl -fsS https://api.perplexity.ai/chat/completions \
|
|
988
|
+
-H "Authorization: Bearer $PERPLEXITY_API_KEY" \
|
|
989
|
+
-H "Content-Type: application/json" \
|
|
990
|
+
-d '{"model":"sonar","messages":[{"role":"user","content":"ping"}],"max_tokens":1}')
|
|
991
|
+
echo "OK — Perplexity API key valid."
|
|
992
|
+
README.md: |
|
|
993
|
+
# PERPLEXITY
|
|
994
|
+
Perplexity Sonar API (search-grounded LLM).
|
|
995
|
+
> The smoke-test sends 1 token. Cost is negligible.
|
|
996
|
+
CREDENTIALS.md: |
|
|
997
|
+
Dashboard: https://www.perplexity.ai/settings/api
|
|
998
|
+
`PERPLEXITY_API_KEY` — secret.
|
|
999
|
+
|
|
1000
|
+
# ------------------------------------------------------------------
|
|
1001
|
+
# IA / multimedia (audio, imagen, vídeo)
|
|
1002
|
+
# ------------------------------------------------------------------
|
|
1003
|
+
|
|
1004
|
+
- id: ELEVENLABS
|
|
1005
|
+
category: ia_media
|
|
1006
|
+
detectors:
|
|
1007
|
+
imports: ["from elevenlabs", "import elevenlabs", "@elevenlabs/elevenlabs-js"]
|
|
1008
|
+
env_vars: ["ELEVENLABS_API_KEY", "ELEVEN_API_KEY"]
|
|
1009
|
+
deps: ["elevenlabs", "@elevenlabs/elevenlabs-js"]
|
|
1010
|
+
dashboard_url: "https://elevenlabs.io/app/settings/api-keys"
|
|
1011
|
+
env_example: |
|
|
1012
|
+
ELEVENLABS_API_KEY=
|
|
1013
|
+
files:
|
|
1014
|
+
test_connection.sh: |
|
|
1015
|
+
#!/usr/bin/env bash
|
|
1016
|
+
set -euo pipefail
|
|
1017
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1018
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1019
|
+
KEY="${ELEVENLABS_API_KEY:-${ELEVEN_API_KEY:-}}"
|
|
1020
|
+
[ -n "$KEY" ] || { echo "ERROR: ELEVENLABS_API_KEY not set" >&2; exit 1; }
|
|
1021
|
+
TIER=$(curl -fsS https://api.elevenlabs.io/v1/user -H "xi-api-key: $KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("subscription",{}).get("tier","?"))')
|
|
1022
|
+
echo "OK — ElevenLabs tier: $TIER."
|
|
1023
|
+
README.md: |
|
|
1024
|
+
# ELEVENLABS
|
|
1025
|
+
Text-to-speech, voice cloning, dubbing.
|
|
1026
|
+
CREDENTIALS.md: |
|
|
1027
|
+
Dashboard: https://elevenlabs.io/app/settings/api-keys
|
|
1028
|
+
`ELEVENLABS_API_KEY` — secret.
|
|
1029
|
+
|
|
1030
|
+
- id: FAL_AI
|
|
1031
|
+
category: ia_media
|
|
1032
|
+
detectors:
|
|
1033
|
+
imports: ["import fal_client", "from fal_client", "@fal-ai/client"]
|
|
1034
|
+
env_vars: ["FAL_KEY", "FAL_API_KEY"]
|
|
1035
|
+
deps: ["fal-client", "@fal-ai/client"]
|
|
1036
|
+
dashboard_url: "https://fal.ai/dashboard/keys"
|
|
1037
|
+
env_example: |
|
|
1038
|
+
FAL_KEY=
|
|
1039
|
+
files:
|
|
1040
|
+
test_connection.sh: |
|
|
1041
|
+
#!/usr/bin/env bash
|
|
1042
|
+
# Lightweight validation: GET on the queue API with auth Key.
|
|
1043
|
+
set -euo pipefail
|
|
1044
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1045
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1046
|
+
: "${FAL_KEY:?FAL_KEY not set}"
|
|
1047
|
+
curl -fsS https://queue.fal.run/health -H "Authorization: Key $FAL_KEY" >/dev/null
|
|
1048
|
+
echo "OK — fal.ai queue reachable."
|
|
1049
|
+
README.md: |
|
|
1050
|
+
# FAL_AI
|
|
1051
|
+
Fast inference of image/video models (Flux, etc.).
|
|
1052
|
+
CREDENTIALS.md: |
|
|
1053
|
+
Dashboard: https://fal.ai/dashboard/keys
|
|
1054
|
+
`FAL_KEY` — secret.
|
|
1055
|
+
|
|
1056
|
+
- id: DEEPGRAM
|
|
1057
|
+
category: ia_media
|
|
1058
|
+
detectors:
|
|
1059
|
+
imports: ["from deepgram", "import deepgram", "@deepgram/sdk"]
|
|
1060
|
+
env_vars: ["DEEPGRAM_API_KEY"]
|
|
1061
|
+
deps: ["deepgram-sdk", "@deepgram/sdk"]
|
|
1062
|
+
dashboard_url: "https://console.deepgram.com/project/_/keys"
|
|
1063
|
+
env_example: |
|
|
1064
|
+
DEEPGRAM_API_KEY=
|
|
1065
|
+
files:
|
|
1066
|
+
test_connection.sh: |
|
|
1067
|
+
#!/usr/bin/env bash
|
|
1068
|
+
set -euo pipefail
|
|
1069
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1070
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1071
|
+
: "${DEEPGRAM_API_KEY:?DEEPGRAM_API_KEY not set}"
|
|
1072
|
+
N=$(curl -fsS https://api.deepgram.com/v1/projects -H "Authorization: Token $DEEPGRAM_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["projects"]))')
|
|
1073
|
+
echo "OK — $N Deepgram projects."
|
|
1074
|
+
README.md: |
|
|
1075
|
+
# DEEPGRAM
|
|
1076
|
+
Speech-to-text + audio intelligence.
|
|
1077
|
+
CREDENTIALS.md: |
|
|
1078
|
+
Dashboard: https://console.deepgram.com
|
|
1079
|
+
`DEEPGRAM_API_KEY` — secret.
|
|
1080
|
+
|
|
1081
|
+
- id: ASSEMBLYAI
|
|
1082
|
+
category: ia_media
|
|
1083
|
+
detectors:
|
|
1084
|
+
imports: ["import assemblyai", "from assemblyai", "assemblyai"]
|
|
1085
|
+
env_vars: ["ASSEMBLYAI_API_KEY"]
|
|
1086
|
+
deps: ["assemblyai"]
|
|
1087
|
+
dashboard_url: "https://www.assemblyai.com/app/account"
|
|
1088
|
+
env_example: |
|
|
1089
|
+
ASSEMBLYAI_API_KEY=
|
|
1090
|
+
files:
|
|
1091
|
+
test_connection.sh: |
|
|
1092
|
+
#!/usr/bin/env bash
|
|
1093
|
+
set -euo pipefail
|
|
1094
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1095
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1096
|
+
: "${ASSEMBLYAI_API_KEY:?ASSEMBLYAI_API_KEY not set}"
|
|
1097
|
+
curl -fsS https://api.assemblyai.com/v2/transcript -H "Authorization: $ASSEMBLYAI_API_KEY" -G --data-urlencode "limit=1" >/dev/null
|
|
1098
|
+
echo "OK — AssemblyAI API key valid."
|
|
1099
|
+
README.md: |
|
|
1100
|
+
# ASSEMBLYAI
|
|
1101
|
+
Speech-to-text + LeMUR (LLM sobre audio).
|
|
1102
|
+
CREDENTIALS.md: |
|
|
1103
|
+
Dashboard: https://www.assemblyai.com/app/account
|
|
1104
|
+
`ASSEMBLYAI_API_KEY` — secret.
|
|
1105
|
+
|
|
1106
|
+
# ------------------------------------------------------------------
|
|
1107
|
+
# Email (transaccional)
|
|
1108
|
+
# ------------------------------------------------------------------
|
|
1109
|
+
|
|
1110
|
+
- id: SENDGRID
|
|
1111
|
+
category: email
|
|
1112
|
+
detectors:
|
|
1113
|
+
imports: ["from sendgrid", "import sendgrid", "@sendgrid/mail"]
|
|
1114
|
+
env_vars: ["SENDGRID_API_KEY"]
|
|
1115
|
+
deps: ["sendgrid", "@sendgrid/mail"]
|
|
1116
|
+
dashboard_url: "https://app.sendgrid.com/settings/api_keys"
|
|
1117
|
+
env_example: |
|
|
1118
|
+
SENDGRID_API_KEY=
|
|
1119
|
+
files:
|
|
1120
|
+
test_connection.sh: |
|
|
1121
|
+
#!/usr/bin/env bash
|
|
1122
|
+
set -euo pipefail
|
|
1123
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1124
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1125
|
+
: "${SENDGRID_API_KEY:?SENDGRID_API_KEY not set}"
|
|
1126
|
+
TYPE=$(curl -fsS https://api.sendgrid.com/v3/scopes -H "Authorization: Bearer $SENDGRID_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["scopes"]))')
|
|
1127
|
+
echo "OK — SendGrid API key con $TYPE scopes."
|
|
1128
|
+
README.md: |
|
|
1129
|
+
# SENDGRID
|
|
1130
|
+
Email transaccional (Twilio SendGrid).
|
|
1131
|
+
CREDENTIALS.md: |
|
|
1132
|
+
Dashboard: https://app.sendgrid.com/settings/api_keys
|
|
1133
|
+
`SENDGRID_API_KEY` — secret.
|
|
1134
|
+
|
|
1135
|
+
- id: POSTMARK
|
|
1136
|
+
category: email
|
|
1137
|
+
detectors:
|
|
1138
|
+
imports: ["from postmarker", "import postmarker", "postmark"]
|
|
1139
|
+
env_vars: ["POSTMARK_SERVER_TOKEN", "POSTMARK_API_TOKEN"]
|
|
1140
|
+
deps: ["postmark", "postmarker"]
|
|
1141
|
+
dashboard_url: "https://account.postmarkapp.com/servers"
|
|
1142
|
+
env_example: |
|
|
1143
|
+
POSTMARK_SERVER_TOKEN=
|
|
1144
|
+
files:
|
|
1145
|
+
test_connection.sh: |
|
|
1146
|
+
#!/usr/bin/env bash
|
|
1147
|
+
set -euo pipefail
|
|
1148
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1149
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1150
|
+
: "${POSTMARK_SERVER_TOKEN:?POSTMARK_SERVER_TOKEN not set}"
|
|
1151
|
+
NAME=$(curl -fsS https://api.postmarkapp.com/server -H "Accept: application/json" -H "X-Postmark-Server-Token: $POSTMARK_SERVER_TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["Name"])')
|
|
1152
|
+
echo "OK — Postmark server: $NAME."
|
|
1153
|
+
README.md: |
|
|
1154
|
+
# POSTMARK
|
|
1155
|
+
Email transaccional rápido y simple.
|
|
1156
|
+
CREDENTIALS.md: |
|
|
1157
|
+
Dashboard: https://account.postmarkapp.com/servers
|
|
1158
|
+
`POSTMARK_SERVER_TOKEN` — uno por server, scoped.
|
|
1159
|
+
|
|
1160
|
+
- id: RESEND
|
|
1161
|
+
category: email
|
|
1162
|
+
detectors:
|
|
1163
|
+
imports: ["from resend", "import resend", "resend"]
|
|
1164
|
+
env_vars: ["RESEND_API_KEY"]
|
|
1165
|
+
deps: ["resend"]
|
|
1166
|
+
dashboard_url: "https://resend.com/api-keys"
|
|
1167
|
+
env_example: |
|
|
1168
|
+
RESEND_API_KEY=
|
|
1169
|
+
files:
|
|
1170
|
+
test_connection.sh: |
|
|
1171
|
+
#!/usr/bin/env bash
|
|
1172
|
+
set -euo pipefail
|
|
1173
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1174
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1175
|
+
: "${RESEND_API_KEY:?RESEND_API_KEY not set}"
|
|
1176
|
+
N=$(curl -fsS https://api.resend.com/domains -H "Authorization: Bearer $RESEND_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
1177
|
+
echo "OK — Resend dominios: $N."
|
|
1178
|
+
README.md: |
|
|
1179
|
+
# RESEND
|
|
1180
|
+
Email transaccional para developers (React Email-friendly).
|
|
1181
|
+
CREDENTIALS.md: |
|
|
1182
|
+
Dashboard: https://resend.com/api-keys
|
|
1183
|
+
`RESEND_API_KEY` — secret.
|
|
1184
|
+
|
|
1185
|
+
- id: MAILGUN
|
|
1186
|
+
category: email
|
|
1187
|
+
detectors:
|
|
1188
|
+
imports: ["import mailgun", "from mailgun", "mailgun.js"]
|
|
1189
|
+
env_vars: ["MAILGUN_API_KEY", "MAILGUN_DOMAIN"]
|
|
1190
|
+
deps: ["mailgun", "mailgun.js"]
|
|
1191
|
+
dashboard_url: "https://app.mailgun.com/settings/api_security"
|
|
1192
|
+
env_example: |
|
|
1193
|
+
MAILGUN_API_KEY=
|
|
1194
|
+
MAILGUN_DOMAIN=
|
|
1195
|
+
MAILGUN_REGION=api
|
|
1196
|
+
files:
|
|
1197
|
+
test_connection.sh: |
|
|
1198
|
+
#!/usr/bin/env bash
|
|
1199
|
+
set -euo pipefail
|
|
1200
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1201
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1202
|
+
: "${MAILGUN_API_KEY:?MAILGUN_API_KEY not set}"
|
|
1203
|
+
REGION="${MAILGUN_REGION:-api}"
|
|
1204
|
+
N=$(curl -fsS "https://${REGION}.mailgun.net/v4/domains" -u "api:$MAILGUN_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["total_count"])')
|
|
1205
|
+
echo "OK — Mailgun dominios: $N."
|
|
1206
|
+
README.md: |
|
|
1207
|
+
# MAILGUN
|
|
1208
|
+
Email transaccional + email parsing.
|
|
1209
|
+
CREDENTIALS.md: |
|
|
1210
|
+
Dashboard: https://app.mailgun.com/settings/api_security
|
|
1211
|
+
Region: `api` (US) o `api.eu`.
|
|
1212
|
+
|
|
1213
|
+
- id: AWS_SES
|
|
1214
|
+
category: email
|
|
1215
|
+
detectors:
|
|
1216
|
+
imports: ["from boto3", "import boto3", "@aws-sdk/client-ses"]
|
|
1217
|
+
env_vars: ["AWS_SES_ACCESS_KEY_ID", "SES_REGION"]
|
|
1218
|
+
deps: ["@aws-sdk/client-ses"]
|
|
1219
|
+
dashboard_url: "https://console.aws.amazon.com/ses"
|
|
1220
|
+
manual_only: true
|
|
1221
|
+
env_example: |
|
|
1222
|
+
# AWS SES — usa el CLI oficial de AWS para verificar.
|
|
1223
|
+
AWS_ACCESS_KEY_ID=
|
|
1224
|
+
AWS_SECRET_ACCESS_KEY=
|
|
1225
|
+
AWS_REGION=eu-west-1
|
|
1226
|
+
files:
|
|
1227
|
+
README.md: |
|
|
1228
|
+
# AWS_SES
|
|
1229
|
+
Amazon SES para email transaccional. La auth SigV4 es compleja —
|
|
1230
|
+
verifica con el AWS CLI:
|
|
1231
|
+
|
|
1232
|
+
aws ses get-account-sending-enabled --region $AWS_REGION
|
|
1233
|
+
|
|
1234
|
+
## No hay smoke-test bash automatizado
|
|
1235
|
+
SigV4 requiere firma HMAC compleja; usa boto3 o el AWS CLI.
|
|
1236
|
+
CREDENTIALS.md: |
|
|
1237
|
+
Dashboard: https://console.aws.amazon.com/ses
|
|
1238
|
+
Credentials: IAM access key with the `ses:SendEmail` policy.
|
|
1239
|
+
|
|
1240
|
+
# ------------------------------------------------------------------
|
|
1241
|
+
# Payments & billing
|
|
1242
|
+
# ------------------------------------------------------------------
|
|
1243
|
+
|
|
1244
|
+
- id: PADDLE
|
|
1245
|
+
category: pagos
|
|
1246
|
+
detectors:
|
|
1247
|
+
imports: ["@paddle/paddle-node-sdk", "@paddle/paddle-js"]
|
|
1248
|
+
env_vars: ["PADDLE_API_KEY", "PADDLE_VENDOR_ID", "PADDLE_NOTIFICATION_SECRET"]
|
|
1249
|
+
deps: ["@paddle/paddle-node-sdk", "@paddle/paddle-js"]
|
|
1250
|
+
dashboard_url: "https://vendors.paddle.com/authentication"
|
|
1251
|
+
env_example: |
|
|
1252
|
+
# PADDLE — generate at https://vendors.paddle.com/authentication
|
|
1253
|
+
PADDLE_API_KEY=
|
|
1254
|
+
PADDLE_ENV=sandbox
|
|
1255
|
+
files:
|
|
1256
|
+
test_connection.sh: |
|
|
1257
|
+
#!/usr/bin/env bash
|
|
1258
|
+
set -euo pipefail
|
|
1259
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1260
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1261
|
+
: "${PADDLE_API_KEY:?PADDLE_API_KEY not set}"
|
|
1262
|
+
HOST="https://api.paddle.com"
|
|
1263
|
+
[ "${PADDLE_ENV:-}" = "sandbox" ] && HOST="https://sandbox-api.paddle.com"
|
|
1264
|
+
N=$(curl -fsS "$HOST/products" -H "Authorization: Bearer $PADDLE_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
1265
|
+
echo "OK — Paddle ($PADDLE_ENV) products: $N."
|
|
1266
|
+
README.md: |
|
|
1267
|
+
# PADDLE
|
|
1268
|
+
Merchant-of-record billing (subscriptions, taxes handled).
|
|
1269
|
+
CREDENTIALS.md: |
|
|
1270
|
+
Dashboard: https://vendors.paddle.com/authentication
|
|
1271
|
+
`PADDLE_API_KEY` — secret. Set `PADDLE_ENV=sandbox` for the sandbox.
|
|
1272
|
+
|
|
1273
|
+
- id: LEMONSQUEEZY
|
|
1274
|
+
category: pagos
|
|
1275
|
+
detectors:
|
|
1276
|
+
imports: ["@lemonsqueezy/lemonsqueezy.js"]
|
|
1277
|
+
env_vars: ["LEMONSQUEEZY_API_KEY", "LEMONSQUEEZY_STORE_ID", "LEMONSQUEEZY_WEBHOOK_SECRET"]
|
|
1278
|
+
deps: ["@lemonsqueezy/lemonsqueezy.js"]
|
|
1279
|
+
dashboard_url: "https://app.lemonsqueezy.com/settings/api"
|
|
1280
|
+
env_example: |
|
|
1281
|
+
LEMONSQUEEZY_API_KEY=
|
|
1282
|
+
LEMONSQUEEZY_STORE_ID=
|
|
1283
|
+
LEMONSQUEEZY_WEBHOOK_SECRET=
|
|
1284
|
+
files:
|
|
1285
|
+
test_connection.sh: |
|
|
1286
|
+
#!/usr/bin/env bash
|
|
1287
|
+
set -euo pipefail
|
|
1288
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1289
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1290
|
+
: "${LEMONSQUEEZY_API_KEY:?LEMONSQUEEZY_API_KEY not set}"
|
|
1291
|
+
NAME=$(curl -fsS https://api.lemonsqueezy.com/v1/users/me \
|
|
1292
|
+
-H "Accept: application/vnd.api+json" \
|
|
1293
|
+
-H "Authorization: Bearer $LEMONSQUEEZY_API_KEY" \
|
|
1294
|
+
| python3 -c 'import json,sys; print(json.load(sys.stdin)["data"]["attributes"]["name"])')
|
|
1295
|
+
echo "OK — Lemon Squeezy authed as $NAME."
|
|
1296
|
+
README.md: |
|
|
1297
|
+
# LEMONSQUEEZY
|
|
1298
|
+
Merchant-of-record SaaS billing (alternative to Paddle).
|
|
1299
|
+
CREDENTIALS.md: |
|
|
1300
|
+
Dashboard: https://app.lemonsqueezy.com/settings/api
|
|
1301
|
+
`LEMONSQUEEZY_API_KEY` — secret. `LEMONSQUEEZY_STORE_ID` from the URL of the store page.
|
|
1302
|
+
|
|
1303
|
+
- id: REVENUECAT
|
|
1304
|
+
category: pagos
|
|
1305
|
+
detectors:
|
|
1306
|
+
imports: ["import Purchases", "from purchases", "@revenuecat/purchases-js", "react-native-purchases", "purchases_flutter"]
|
|
1307
|
+
env_vars: ["REVENUECAT_API_KEY", "REVENUECAT_SECRET_API_KEY"]
|
|
1308
|
+
deps: ["@revenuecat/purchases-js", "react-native-purchases", "purchases-flutter"]
|
|
1309
|
+
dashboard_url: "https://app.revenuecat.com/projects"
|
|
1310
|
+
env_example: |
|
|
1311
|
+
# Secret API key for server-side ops (mobile clients use public SDK keys).
|
|
1312
|
+
REVENUECAT_SECRET_API_KEY=
|
|
1313
|
+
files:
|
|
1314
|
+
test_connection.sh: |
|
|
1315
|
+
#!/usr/bin/env bash
|
|
1316
|
+
set -euo pipefail
|
|
1317
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1318
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1319
|
+
: "${REVENUECAT_SECRET_API_KEY:?REVENUECAT_SECRET_API_KEY not set}"
|
|
1320
|
+
# v2 API: list projects under the current account.
|
|
1321
|
+
N=$(curl -fsS https://api.revenuecat.com/v2/projects -H "Authorization: Bearer $REVENUECAT_SECRET_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin).get("items",[])))')
|
|
1322
|
+
echo "OK — RevenueCat projects: $N."
|
|
1323
|
+
README.md: |
|
|
1324
|
+
# REVENUECAT
|
|
1325
|
+
Cross-platform subscription management (iOS + Android + web).
|
|
1326
|
+
CREDENTIALS.md: |
|
|
1327
|
+
Dashboard: https://app.revenuecat.com/projects
|
|
1328
|
+
`REVENUECAT_SECRET_API_KEY` — secret, for server-side calls only.
|
|
1329
|
+
Public SDK keys (iOS/Android/web) go directly in the client.
|
|
1330
|
+
|
|
1331
|
+
# ------------------------------------------------------------------
|
|
1332
|
+
# Auth & identity
|
|
1333
|
+
# ------------------------------------------------------------------
|
|
1334
|
+
|
|
1335
|
+
- id: CLERK
|
|
1336
|
+
category: auth
|
|
1337
|
+
detectors:
|
|
1338
|
+
imports: ["@clerk/clerk-sdk-node", "@clerk/nextjs", "@clerk/clerk-react", "@clerk/backend", "from clerk_backend_api"]
|
|
1339
|
+
env_vars: ["CLERK_SECRET_KEY", "CLERK_PUBLISHABLE_KEY", "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY"]
|
|
1340
|
+
deps: ["@clerk/nextjs", "@clerk/clerk-sdk-node", "@clerk/backend", "clerk-backend-api"]
|
|
1341
|
+
dashboard_url: "https://dashboard.clerk.com"
|
|
1342
|
+
env_example: |
|
|
1343
|
+
CLERK_SECRET_KEY=
|
|
1344
|
+
CLERK_PUBLISHABLE_KEY=
|
|
1345
|
+
files:
|
|
1346
|
+
test_connection.sh: |
|
|
1347
|
+
#!/usr/bin/env bash
|
|
1348
|
+
set -euo pipefail
|
|
1349
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1350
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1351
|
+
: "${CLERK_SECRET_KEY:?CLERK_SECRET_KEY not set}"
|
|
1352
|
+
N=$(curl -fsS https://api.clerk.com/v1/users?limit=1 -H "Authorization: Bearer $CLERK_SECRET_KEY" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(len(d) if isinstance(d,list) else "?")')
|
|
1353
|
+
echo "OK — Clerk users endpoint accessible (sample: $N)."
|
|
1354
|
+
README.md: |
|
|
1355
|
+
# CLERK
|
|
1356
|
+
Drop-in auth + user management for Next.js, React, Expo.
|
|
1357
|
+
CREDENTIALS.md: |
|
|
1358
|
+
Dashboard: https://dashboard.clerk.com
|
|
1359
|
+
`CLERK_SECRET_KEY` — backend secret. `CLERK_PUBLISHABLE_KEY` — public.
|
|
1360
|
+
|
|
1361
|
+
- id: WORKOS
|
|
1362
|
+
category: auth
|
|
1363
|
+
detectors:
|
|
1364
|
+
imports: ["@workos-inc/node", "@workos-inc/authkit-nextjs", "import workos"]
|
|
1365
|
+
env_vars: ["WORKOS_API_KEY", "WORKOS_CLIENT_ID"]
|
|
1366
|
+
deps: ["@workos-inc/node", "@workos-inc/authkit-nextjs", "workos"]
|
|
1367
|
+
dashboard_url: "https://dashboard.workos.com/api-keys"
|
|
1368
|
+
env_example: |
|
|
1369
|
+
WORKOS_API_KEY=
|
|
1370
|
+
WORKOS_CLIENT_ID=
|
|
1371
|
+
files:
|
|
1372
|
+
test_connection.sh: |
|
|
1373
|
+
#!/usr/bin/env bash
|
|
1374
|
+
set -euo pipefail
|
|
1375
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1376
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1377
|
+
: "${WORKOS_API_KEY:?WORKOS_API_KEY not set}"
|
|
1378
|
+
N=$(curl -fsS "https://api.workos.com/organizations?limit=1" -H "Authorization: Bearer $WORKOS_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
1379
|
+
echo "OK — WorkOS organizations sample: $N."
|
|
1380
|
+
README.md: |
|
|
1381
|
+
# WORKOS
|
|
1382
|
+
Enterprise SSO (SAML, OIDC), SCIM, Directory Sync, AuthKit.
|
|
1383
|
+
CREDENTIALS.md: |
|
|
1384
|
+
Dashboard: https://dashboard.workos.com/api-keys
|
|
1385
|
+
`WORKOS_API_KEY` — secret. `WORKOS_CLIENT_ID` — public.
|
|
1386
|
+
|
|
1387
|
+
- id: AUTH0
|
|
1388
|
+
category: auth
|
|
1389
|
+
detectors:
|
|
1390
|
+
imports: ["@auth0/nextjs-auth0", "@auth0/auth0-react", "@auth0/auth0-spa-js", "from auth0"]
|
|
1391
|
+
env_vars: ["AUTH0_DOMAIN", "AUTH0_CLIENT_ID", "AUTH0_CLIENT_SECRET", "AUTH0_MGMT_API_TOKEN"]
|
|
1392
|
+
deps: ["@auth0/nextjs-auth0", "@auth0/auth0-react", "auth0"]
|
|
1393
|
+
dashboard_url: "https://manage.auth0.com"
|
|
1394
|
+
env_example: |
|
|
1395
|
+
AUTH0_DOMAIN=
|
|
1396
|
+
AUTH0_CLIENT_ID=
|
|
1397
|
+
AUTH0_CLIENT_SECRET=
|
|
1398
|
+
files:
|
|
1399
|
+
test_connection.sh: |
|
|
1400
|
+
#!/usr/bin/env bash
|
|
1401
|
+
# Auth0: validate that the tenant domain serves OIDC discovery.
|
|
1402
|
+
set -euo pipefail
|
|
1403
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1404
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1405
|
+
: "${AUTH0_DOMAIN:?AUTH0_DOMAIN not set}"
|
|
1406
|
+
ISSUER=$(curl -fsS "https://${AUTH0_DOMAIN}/.well-known/openid-configuration" | python3 -c 'import json,sys; print(json.load(sys.stdin)["issuer"])')
|
|
1407
|
+
echo "OK — Auth0 tenant reachable: $ISSUER."
|
|
1408
|
+
README.md: |
|
|
1409
|
+
# AUTH0
|
|
1410
|
+
Identity platform (login, MFA, social, enterprise SSO).
|
|
1411
|
+
> Management API checks need a separate M2M token — see CREDENTIALS.md.
|
|
1412
|
+
CREDENTIALS.md: |
|
|
1413
|
+
Dashboard: https://manage.auth0.com
|
|
1414
|
+
- `AUTH0_DOMAIN` — `<tenant>.auth0.com` or custom domain.
|
|
1415
|
+
- `AUTH0_CLIENT_ID` / `AUTH0_CLIENT_SECRET` — per Application.
|
|
1416
|
+
- `AUTH0_MGMT_API_TOKEN` — only needed for Management API calls.
|
|
1417
|
+
|
|
1418
|
+
- id: STYTCH
|
|
1419
|
+
category: auth
|
|
1420
|
+
detectors:
|
|
1421
|
+
imports: ["import stytch", "from stytch", "@stytch/nextjs", "stytch"]
|
|
1422
|
+
env_vars: ["STYTCH_PROJECT_ID", "STYTCH_SECRET"]
|
|
1423
|
+
deps: ["stytch", "@stytch/nextjs"]
|
|
1424
|
+
dashboard_url: "https://stytch.com/dashboard/api-keys"
|
|
1425
|
+
env_example: |
|
|
1426
|
+
STYTCH_PROJECT_ID=
|
|
1427
|
+
STYTCH_SECRET=
|
|
1428
|
+
STYTCH_ENV=test
|
|
1429
|
+
files:
|
|
1430
|
+
test_connection.sh: |
|
|
1431
|
+
#!/usr/bin/env bash
|
|
1432
|
+
set -euo pipefail
|
|
1433
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1434
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1435
|
+
: "${STYTCH_PROJECT_ID:?STYTCH_PROJECT_ID not set}"
|
|
1436
|
+
: "${STYTCH_SECRET:?STYTCH_SECRET not set}"
|
|
1437
|
+
HOST="https://test.stytch.com"
|
|
1438
|
+
[ "${STYTCH_ENV:-test}" = "live" ] && HOST="https://api.stytch.com"
|
|
1439
|
+
# Lists trusted metadata — read-only, safe smoke test.
|
|
1440
|
+
curl -fsS "$HOST/v1/projects" -u "$STYTCH_PROJECT_ID:$STYTCH_SECRET" >/dev/null
|
|
1441
|
+
echo "OK — Stytch ($STYTCH_ENV) auth valid."
|
|
1442
|
+
README.md: |
|
|
1443
|
+
# STYTCH
|
|
1444
|
+
Passwordless + passkeys + B2B SaaS auth APIs.
|
|
1445
|
+
CREDENTIALS.md: |
|
|
1446
|
+
Dashboard: https://stytch.com/dashboard/api-keys
|
|
1447
|
+
`STYTCH_PROJECT_ID` + `STYTCH_SECRET`. Set `STYTCH_ENV=live` for prod.
|
|
1448
|
+
|
|
1449
|
+
- id: KINDE
|
|
1450
|
+
category: auth
|
|
1451
|
+
detectors:
|
|
1452
|
+
imports: ["@kinde-oss/kinde-auth-nextjs", "@kinde-oss/kinde-typescript-sdk", "@kinde-oss/kinde-auth-react"]
|
|
1453
|
+
env_vars: ["KINDE_CLIENT_ID", "KINDE_CLIENT_SECRET", "KINDE_ISSUER_URL", "KINDE_M2M_CLIENT_ID", "KINDE_M2M_CLIENT_SECRET"]
|
|
1454
|
+
deps: ["@kinde-oss/kinde-auth-nextjs", "@kinde-oss/kinde-typescript-sdk"]
|
|
1455
|
+
dashboard_url: "https://app.kinde.com"
|
|
1456
|
+
env_example: |
|
|
1457
|
+
KINDE_ISSUER_URL=
|
|
1458
|
+
KINDE_CLIENT_ID=
|
|
1459
|
+
KINDE_CLIENT_SECRET=
|
|
1460
|
+
files:
|
|
1461
|
+
test_connection.sh: |
|
|
1462
|
+
#!/usr/bin/env bash
|
|
1463
|
+
set -euo pipefail
|
|
1464
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1465
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1466
|
+
: "${KINDE_ISSUER_URL:?KINDE_ISSUER_URL not set}"
|
|
1467
|
+
ISSUER=$(curl -fsS "${KINDE_ISSUER_URL%/}/.well-known/openid-configuration" | python3 -c 'import json,sys; print(json.load(sys.stdin)["issuer"])')
|
|
1468
|
+
echo "OK — Kinde tenant reachable: $ISSUER."
|
|
1469
|
+
README.md: |
|
|
1470
|
+
# KINDE
|
|
1471
|
+
Auth + user management with feature flags built in.
|
|
1472
|
+
CREDENTIALS.md: |
|
|
1473
|
+
Dashboard: https://app.kinde.com
|
|
1474
|
+
`KINDE_ISSUER_URL` is `https://<subdomain>.kinde.com`.
|
|
1475
|
+
Management API needs M2M client (see KINDE_M2M_*).
|
|
1476
|
+
|
|
1477
|
+
# ------------------------------------------------------------------
|
|
1478
|
+
# Databases & backend-as-a-service
|
|
1479
|
+
# ------------------------------------------------------------------
|
|
1480
|
+
|
|
1481
|
+
- id: SUPABASE
|
|
1482
|
+
category: datos
|
|
1483
|
+
detectors:
|
|
1484
|
+
imports: ["@supabase/supabase-js", "@supabase/ssr", "from supabase", "import supabase"]
|
|
1485
|
+
env_vars: ["SUPABASE_URL", "SUPABASE_ANON_KEY", "SUPABASE_SERVICE_ROLE_KEY", "NEXT_PUBLIC_SUPABASE_URL"]
|
|
1486
|
+
deps: ["@supabase/supabase-js", "@supabase/ssr", "supabase"]
|
|
1487
|
+
dashboard_url: "https://supabase.com/dashboard"
|
|
1488
|
+
env_example: |
|
|
1489
|
+
SUPABASE_URL=
|
|
1490
|
+
SUPABASE_ANON_KEY=
|
|
1491
|
+
SUPABASE_SERVICE_ROLE_KEY=
|
|
1492
|
+
files:
|
|
1493
|
+
test_connection.sh: |
|
|
1494
|
+
#!/usr/bin/env bash
|
|
1495
|
+
set -euo pipefail
|
|
1496
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1497
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1498
|
+
: "${SUPABASE_URL:?SUPABASE_URL not set}"
|
|
1499
|
+
: "${SUPABASE_ANON_KEY:?SUPABASE_ANON_KEY not set}"
|
|
1500
|
+
curl -fsS "${SUPABASE_URL%/}/auth/v1/health" -H "apikey: $SUPABASE_ANON_KEY" >/dev/null
|
|
1501
|
+
echo "OK — Supabase auth service reachable."
|
|
1502
|
+
README.md: |
|
|
1503
|
+
# SUPABASE
|
|
1504
|
+
Postgres + Auth + Storage + Realtime + Edge Functions.
|
|
1505
|
+
CREDENTIALS.md: |
|
|
1506
|
+
Dashboard: https://supabase.com/dashboard
|
|
1507
|
+
`SUPABASE_ANON_KEY` — public.
|
|
1508
|
+
`SUPABASE_SERVICE_ROLE_KEY` — secret, bypasses RLS. Server-only.
|
|
1509
|
+
|
|
1510
|
+
- id: NEON
|
|
1511
|
+
category: datos
|
|
1512
|
+
detectors:
|
|
1513
|
+
imports: ["@neondatabase/serverless", "from neon"]
|
|
1514
|
+
env_vars: ["NEON_API_KEY", "NEON_PROJECT_ID", "DATABASE_URL"]
|
|
1515
|
+
deps: ["@neondatabase/serverless"]
|
|
1516
|
+
dashboard_url: "https://console.neon.tech/app/settings/api-keys"
|
|
1517
|
+
env_example: |
|
|
1518
|
+
NEON_API_KEY=
|
|
1519
|
+
files:
|
|
1520
|
+
test_connection.sh: |
|
|
1521
|
+
#!/usr/bin/env bash
|
|
1522
|
+
set -euo pipefail
|
|
1523
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1524
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1525
|
+
: "${NEON_API_KEY:?NEON_API_KEY not set}"
|
|
1526
|
+
N=$(curl -fsS https://console.neon.tech/api/v2/projects -H "Authorization: Bearer $NEON_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["projects"]))')
|
|
1527
|
+
echo "OK — Neon projects: $N."
|
|
1528
|
+
README.md: |
|
|
1529
|
+
# NEON
|
|
1530
|
+
Serverless Postgres with branching.
|
|
1531
|
+
CREDENTIALS.md: |
|
|
1532
|
+
Dashboard: https://console.neon.tech/app/settings/api-keys
|
|
1533
|
+
`NEON_API_KEY` — secret.
|
|
1534
|
+
|
|
1535
|
+
- id: PLANETSCALE
|
|
1536
|
+
category: datos
|
|
1537
|
+
detectors:
|
|
1538
|
+
imports: ["@planetscale/database", "from planetscale"]
|
|
1539
|
+
env_vars: ["PLANETSCALE_TOKEN", "PLANETSCALE_SERVICE_TOKEN", "PLANETSCALE_SERVICE_TOKEN_NAME", "DATABASE_URL"]
|
|
1540
|
+
deps: ["@planetscale/database"]
|
|
1541
|
+
dashboard_url: "https://app.planetscale.com/settings/service-tokens"
|
|
1542
|
+
env_example: |
|
|
1543
|
+
PLANETSCALE_SERVICE_TOKEN_NAME=
|
|
1544
|
+
PLANETSCALE_SERVICE_TOKEN=
|
|
1545
|
+
PLANETSCALE_ORG=
|
|
1546
|
+
files:
|
|
1547
|
+
test_connection.sh: |
|
|
1548
|
+
#!/usr/bin/env bash
|
|
1549
|
+
set -euo pipefail
|
|
1550
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1551
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1552
|
+
: "${PLANETSCALE_SERVICE_TOKEN_NAME:?not set}"
|
|
1553
|
+
: "${PLANETSCALE_SERVICE_TOKEN:?not set}"
|
|
1554
|
+
: "${PLANETSCALE_ORG:?not set}"
|
|
1555
|
+
N=$(curl -fsS "https://api.planetscale.com/v1/organizations/$PLANETSCALE_ORG/databases" \
|
|
1556
|
+
-H "Authorization: ${PLANETSCALE_SERVICE_TOKEN_NAME}:${PLANETSCALE_SERVICE_TOKEN}" \
|
|
1557
|
+
| python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
1558
|
+
echo "OK — PlanetScale databases: $N."
|
|
1559
|
+
README.md: |
|
|
1560
|
+
# PLANETSCALE
|
|
1561
|
+
Serverless MySQL with branching.
|
|
1562
|
+
CREDENTIALS.md: |
|
|
1563
|
+
Dashboard: https://app.planetscale.com/settings/service-tokens
|
|
1564
|
+
Service tokens use `NAME:TOKEN` in the Authorization header.
|
|
1565
|
+
|
|
1566
|
+
- id: TURSO
|
|
1567
|
+
category: datos
|
|
1568
|
+
detectors:
|
|
1569
|
+
imports: ["@libsql/client", "libsql_client", "import libsql"]
|
|
1570
|
+
env_vars: ["TURSO_AUTH_TOKEN", "TURSO_DATABASE_URL", "TURSO_API_TOKEN", "TURSO_ORG"]
|
|
1571
|
+
deps: ["@libsql/client", "libsql"]
|
|
1572
|
+
dashboard_url: "https://turso.tech/app"
|
|
1573
|
+
env_example: |
|
|
1574
|
+
TURSO_API_TOKEN=
|
|
1575
|
+
TURSO_ORG=
|
|
1576
|
+
files:
|
|
1577
|
+
test_connection.sh: |
|
|
1578
|
+
#!/usr/bin/env bash
|
|
1579
|
+
set -euo pipefail
|
|
1580
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1581
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1582
|
+
: "${TURSO_API_TOKEN:?TURSO_API_TOKEN not set}"
|
|
1583
|
+
: "${TURSO_ORG:?TURSO_ORG not set}"
|
|
1584
|
+
N=$(curl -fsS "https://api.turso.tech/v1/organizations/$TURSO_ORG/databases" -H "Authorization: Bearer $TURSO_API_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["databases"]))')
|
|
1585
|
+
echo "OK — Turso databases: $N."
|
|
1586
|
+
README.md: |
|
|
1587
|
+
# TURSO
|
|
1588
|
+
SQLite at the edge (libSQL).
|
|
1589
|
+
CREDENTIALS.md: |
|
|
1590
|
+
Dashboard: https://turso.tech/app
|
|
1591
|
+
`TURSO_API_TOKEN` — for platform API.
|
|
1592
|
+
`TURSO_AUTH_TOKEN` — per-database, for client connections.
|
|
1593
|
+
|
|
1594
|
+
- id: MONGODB_ATLAS
|
|
1595
|
+
category: datos
|
|
1596
|
+
detectors:
|
|
1597
|
+
imports: ["pymongo", "from motor", "mongoose", "mongodb"]
|
|
1598
|
+
env_vars: ["MONGODB_URI", "MONGO_URL", "ATLAS_PUBLIC_KEY", "ATLAS_PRIVATE_KEY"]
|
|
1599
|
+
deps: ["pymongo", "motor", "mongoose", "mongodb"]
|
|
1600
|
+
dashboard_url: "https://cloud.mongodb.com"
|
|
1601
|
+
manual_only: true
|
|
1602
|
+
env_example: |
|
|
1603
|
+
# MongoDB Atlas — connection string for runtime + Atlas API key for ops.
|
|
1604
|
+
MONGODB_URI=
|
|
1605
|
+
ATLAS_PUBLIC_KEY=
|
|
1606
|
+
ATLAS_PRIVATE_KEY=
|
|
1607
|
+
files:
|
|
1608
|
+
README.md: |
|
|
1609
|
+
# MONGODB_ATLAS
|
|
1610
|
+
Managed MongoDB. The Atlas Admin API uses HTTP digest auth which is
|
|
1611
|
+
non-trivial in plain bash. Verify with:
|
|
1612
|
+
|
|
1613
|
+
mongosh "$MONGODB_URI" --eval "db.runCommand({ ping: 1 })"
|
|
1614
|
+
|
|
1615
|
+
or use the Atlas CLI: `atlas projects list`.
|
|
1616
|
+
CREDENTIALS.md: |
|
|
1617
|
+
Dashboard: https://cloud.mongodb.com
|
|
1618
|
+
- `MONGODB_URI` — full SRV connection string for runtime.
|
|
1619
|
+
- `ATLAS_PUBLIC_KEY` / `ATLAS_PRIVATE_KEY` — for Admin API (HTTP digest).
|
|
1620
|
+
|
|
1621
|
+
- id: UPSTASH_REDIS
|
|
1622
|
+
category: datos
|
|
1623
|
+
detectors:
|
|
1624
|
+
imports: ["@upstash/redis", "@upstash/ratelimit"]
|
|
1625
|
+
env_vars: ["UPSTASH_REDIS_REST_URL", "UPSTASH_REDIS_REST_TOKEN", "KV_REST_API_URL", "KV_REST_API_TOKEN"]
|
|
1626
|
+
deps: ["@upstash/redis", "@upstash/ratelimit"]
|
|
1627
|
+
dashboard_url: "https://console.upstash.com"
|
|
1628
|
+
env_example: |
|
|
1629
|
+
UPSTASH_REDIS_REST_URL=
|
|
1630
|
+
UPSTASH_REDIS_REST_TOKEN=
|
|
1631
|
+
files:
|
|
1632
|
+
test_connection.sh: |
|
|
1633
|
+
#!/usr/bin/env bash
|
|
1634
|
+
set -euo pipefail
|
|
1635
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1636
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1637
|
+
URL="${UPSTASH_REDIS_REST_URL:-${KV_REST_API_URL:-}}"
|
|
1638
|
+
TOKEN="${UPSTASH_REDIS_REST_TOKEN:-${KV_REST_API_TOKEN:-}}"
|
|
1639
|
+
[ -n "$URL" ] && [ -n "$TOKEN" ] || { echo "ERROR: missing URL/token" >&2; exit 1; }
|
|
1640
|
+
# PING via REST API.
|
|
1641
|
+
curl -fsS "${URL%/}/ping" -H "Authorization: Bearer $TOKEN" | grep -q PONG
|
|
1642
|
+
echo "OK — Upstash Redis REST responds PONG."
|
|
1643
|
+
README.md: |
|
|
1644
|
+
# UPSTASH_REDIS
|
|
1645
|
+
Serverless Redis (REST API friendly for edge runtimes).
|
|
1646
|
+
CREDENTIALS.md: |
|
|
1647
|
+
Dashboard: https://console.upstash.com
|
|
1648
|
+
Both URL + token are needed; the URL embeds the DB region.
|
|
1649
|
+
|
|
1650
|
+
- id: CONVEX
|
|
1651
|
+
category: datos
|
|
1652
|
+
detectors:
|
|
1653
|
+
imports: ["convex/server", "convex/react", "from convex"]
|
|
1654
|
+
env_vars: ["CONVEX_URL", "CONVEX_DEPLOY_KEY", "CONVEX_DEPLOYMENT", "NEXT_PUBLIC_CONVEX_URL"]
|
|
1655
|
+
deps: ["convex"]
|
|
1656
|
+
dashboard_url: "https://dashboard.convex.dev"
|
|
1657
|
+
manual_only: true
|
|
1658
|
+
env_example: |
|
|
1659
|
+
CONVEX_URL=
|
|
1660
|
+
CONVEX_DEPLOY_KEY=
|
|
1661
|
+
files:
|
|
1662
|
+
README.md: |
|
|
1663
|
+
# CONVEX
|
|
1664
|
+
Reactive backend (TS functions + realtime DB). The deploy-key is
|
|
1665
|
+
validated implicitly by `npx convex deploy`; there is no public
|
|
1666
|
+
read-only smoke endpoint. Verify with:
|
|
1667
|
+
|
|
1668
|
+
npx convex run system:listFunctions
|
|
1669
|
+
|
|
1670
|
+
## No automated smoke-test in bash
|
|
1671
|
+
CREDENTIALS.md: |
|
|
1672
|
+
Dashboard: https://dashboard.convex.dev
|
|
1673
|
+
`CONVEX_URL` — public deployment URL.
|
|
1674
|
+
`CONVEX_DEPLOY_KEY` — secret, only needed for CI/CD deploys.
|
|
1675
|
+
|
|
1676
|
+
# ------------------------------------------------------------------
|
|
1677
|
+
# Search & vector databases
|
|
1678
|
+
# ------------------------------------------------------------------
|
|
1679
|
+
|
|
1680
|
+
- id: PINECONE
|
|
1681
|
+
category: busqueda
|
|
1682
|
+
detectors:
|
|
1683
|
+
imports: ["import pinecone", "from pinecone", "@pinecone-database/pinecone"]
|
|
1684
|
+
env_vars: ["PINECONE_API_KEY", "PINECONE_ENVIRONMENT"]
|
|
1685
|
+
deps: ["pinecone", "pinecone-client", "@pinecone-database/pinecone"]
|
|
1686
|
+
dashboard_url: "https://app.pinecone.io"
|
|
1687
|
+
env_example: |
|
|
1688
|
+
PINECONE_API_KEY=
|
|
1689
|
+
files:
|
|
1690
|
+
test_connection.sh: |
|
|
1691
|
+
#!/usr/bin/env bash
|
|
1692
|
+
set -euo pipefail
|
|
1693
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1694
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1695
|
+
: "${PINECONE_API_KEY:?PINECONE_API_KEY not set}"
|
|
1696
|
+
N=$(curl -fsS https://api.pinecone.io/indexes -H "Api-Key: $PINECONE_API_KEY" -H "X-Pinecone-API-Version: 2025-10" | python3 -c 'import json,sys; print(len(json.load(sys.stdin).get("indexes",[])))')
|
|
1697
|
+
echo "OK — Pinecone indexes: $N."
|
|
1698
|
+
README.md: |
|
|
1699
|
+
# PINECONE
|
|
1700
|
+
Managed vector database for RAG and similarity search.
|
|
1701
|
+
CREDENTIALS.md: |
|
|
1702
|
+
Dashboard: https://app.pinecone.io
|
|
1703
|
+
`PINECONE_API_KEY` — secret, scoped per project.
|
|
1704
|
+
|
|
1705
|
+
- id: WEAVIATE
|
|
1706
|
+
category: busqueda
|
|
1707
|
+
detectors:
|
|
1708
|
+
imports: ["import weaviate", "from weaviate", "weaviate-ts-client", "weaviate-client"]
|
|
1709
|
+
env_vars: ["WEAVIATE_URL", "WEAVIATE_API_KEY"]
|
|
1710
|
+
deps: ["weaviate-client", "weaviate-ts-client"]
|
|
1711
|
+
dashboard_url: "https://console.weaviate.cloud"
|
|
1712
|
+
env_example: |
|
|
1713
|
+
WEAVIATE_URL=
|
|
1714
|
+
WEAVIATE_API_KEY=
|
|
1715
|
+
files:
|
|
1716
|
+
test_connection.sh: |
|
|
1717
|
+
#!/usr/bin/env bash
|
|
1718
|
+
set -euo pipefail
|
|
1719
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1720
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1721
|
+
: "${WEAVIATE_URL:?WEAVIATE_URL not set}"
|
|
1722
|
+
AUTH=()
|
|
1723
|
+
[ -n "${WEAVIATE_API_KEY:-}" ] && AUTH=(-H "Authorization: Bearer ${WEAVIATE_API_KEY}")
|
|
1724
|
+
VER=$(curl -fsS "${WEAVIATE_URL%/}/v1/meta" "${AUTH[@]+"${AUTH[@]}"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["version"])')
|
|
1725
|
+
echo "OK — Weaviate version: $VER."
|
|
1726
|
+
README.md: |
|
|
1727
|
+
# WEAVIATE
|
|
1728
|
+
Open-source vector DB with modules (text2vec, generative, etc.).
|
|
1729
|
+
CREDENTIALS.md: |
|
|
1730
|
+
Dashboard: https://console.weaviate.cloud (managed) or self-hosted.
|
|
1731
|
+
`WEAVIATE_URL` — full base URL including scheme.
|
|
1732
|
+
|
|
1733
|
+
- id: QDRANT
|
|
1734
|
+
category: busqueda
|
|
1735
|
+
detectors:
|
|
1736
|
+
imports: ["from qdrant_client", "import qdrant_client", "@qdrant/js-client-rest"]
|
|
1737
|
+
env_vars: ["QDRANT_URL", "QDRANT_API_KEY"]
|
|
1738
|
+
deps: ["qdrant-client", "@qdrant/js-client-rest"]
|
|
1739
|
+
dashboard_url: "https://cloud.qdrant.io"
|
|
1740
|
+
env_example: |
|
|
1741
|
+
QDRANT_URL=
|
|
1742
|
+
QDRANT_API_KEY=
|
|
1743
|
+
files:
|
|
1744
|
+
test_connection.sh: |
|
|
1745
|
+
#!/usr/bin/env bash
|
|
1746
|
+
set -euo pipefail
|
|
1747
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1748
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1749
|
+
: "${QDRANT_URL:?QDRANT_URL not set}"
|
|
1750
|
+
AUTH=()
|
|
1751
|
+
[ -n "${QDRANT_API_KEY:-}" ] && AUTH=(-H "api-key: ${QDRANT_API_KEY}")
|
|
1752
|
+
N=$(curl -fsS "${QDRANT_URL%/}/collections" "${AUTH[@]+"${AUTH[@]}"}" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["result"]["collections"]))')
|
|
1753
|
+
echo "OK — Qdrant collections: $N."
|
|
1754
|
+
README.md: |
|
|
1755
|
+
# QDRANT
|
|
1756
|
+
Vector DB written in Rust. Managed (Qdrant Cloud) or self-hosted.
|
|
1757
|
+
CREDENTIALS.md: |
|
|
1758
|
+
Dashboard: https://cloud.qdrant.io
|
|
1759
|
+
`QDRANT_URL` includes the port (6333 by default for self-hosted).
|
|
1760
|
+
|
|
1761
|
+
- id: ALGOLIA
|
|
1762
|
+
category: busqueda
|
|
1763
|
+
detectors:
|
|
1764
|
+
imports: ["algoliasearch", "from algoliasearch", "import algoliasearch", "react-instantsearch"]
|
|
1765
|
+
env_vars: ["ALGOLIA_APP_ID", "ALGOLIA_ADMIN_API_KEY", "ALGOLIA_SEARCH_API_KEY", "NEXT_PUBLIC_ALGOLIA_APP_ID"]
|
|
1766
|
+
deps: ["algoliasearch", "react-instantsearch", "algoliasearch-helper"]
|
|
1767
|
+
dashboard_url: "https://dashboard.algolia.com/account/api-keys"
|
|
1768
|
+
env_example: |
|
|
1769
|
+
ALGOLIA_APP_ID=
|
|
1770
|
+
ALGOLIA_ADMIN_API_KEY=
|
|
1771
|
+
ALGOLIA_SEARCH_API_KEY=
|
|
1772
|
+
files:
|
|
1773
|
+
test_connection.sh: |
|
|
1774
|
+
#!/usr/bin/env bash
|
|
1775
|
+
set -euo pipefail
|
|
1776
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1777
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1778
|
+
: "${ALGOLIA_APP_ID:?ALGOLIA_APP_ID not set}"
|
|
1779
|
+
: "${ALGOLIA_ADMIN_API_KEY:?ALGOLIA_ADMIN_API_KEY not set}"
|
|
1780
|
+
N=$(curl -fsS "https://${ALGOLIA_APP_ID}.algolia.net/1/indexes" \
|
|
1781
|
+
-H "X-Algolia-Application-Id: $ALGOLIA_APP_ID" \
|
|
1782
|
+
-H "X-Algolia-API-Key: $ALGOLIA_ADMIN_API_KEY" \
|
|
1783
|
+
| python3 -c 'import json,sys; print(json.load(sys.stdin)["nbHits"])')
|
|
1784
|
+
echo "OK — Algolia indices: $N."
|
|
1785
|
+
README.md: |
|
|
1786
|
+
# ALGOLIA
|
|
1787
|
+
Hosted search-as-a-service. Admin key for ops, search key for clients.
|
|
1788
|
+
CREDENTIALS.md: |
|
|
1789
|
+
Dashboard: https://dashboard.algolia.com/account/api-keys
|
|
1790
|
+
`ALGOLIA_ADMIN_API_KEY` — secret, server-only.
|
|
1791
|
+
`ALGOLIA_SEARCH_API_KEY` — public, safe for clients.
|
|
1792
|
+
|
|
1793
|
+
- id: TYPESENSE
|
|
1794
|
+
category: busqueda
|
|
1795
|
+
detectors:
|
|
1796
|
+
imports: ["import typesense", "from typesense", "typesense"]
|
|
1797
|
+
env_vars: ["TYPESENSE_API_KEY", "TYPESENSE_HOST", "TYPESENSE_PORT"]
|
|
1798
|
+
deps: ["typesense"]
|
|
1799
|
+
dashboard_url: "https://cloud.typesense.org/clusters"
|
|
1800
|
+
env_example: |
|
|
1801
|
+
TYPESENSE_HOST=
|
|
1802
|
+
TYPESENSE_PORT=443
|
|
1803
|
+
TYPESENSE_PROTOCOL=https
|
|
1804
|
+
TYPESENSE_API_KEY=
|
|
1805
|
+
files:
|
|
1806
|
+
test_connection.sh: |
|
|
1807
|
+
#!/usr/bin/env bash
|
|
1808
|
+
set -euo pipefail
|
|
1809
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1810
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1811
|
+
: "${TYPESENSE_HOST:?TYPESENSE_HOST not set}"
|
|
1812
|
+
: "${TYPESENSE_API_KEY:?TYPESENSE_API_KEY not set}"
|
|
1813
|
+
PROTO="${TYPESENSE_PROTOCOL:-https}"
|
|
1814
|
+
PORT="${TYPESENSE_PORT:-443}"
|
|
1815
|
+
curl -fsS "${PROTO}://${TYPESENSE_HOST}:${PORT}/health" -H "X-TYPESENSE-API-KEY: $TYPESENSE_API_KEY" | grep -q '"ok":true'
|
|
1816
|
+
echo "OK — Typesense health: ok."
|
|
1817
|
+
README.md: |
|
|
1818
|
+
# TYPESENSE
|
|
1819
|
+
Open-source typo-tolerant search engine. Managed cloud available.
|
|
1820
|
+
CREDENTIALS.md: |
|
|
1821
|
+
Dashboard: https://cloud.typesense.org/clusters
|
|
1822
|
+
`TYPESENSE_API_KEY` — generate per cluster.
|
|
1823
|
+
|
|
1824
|
+
- id: MEILISEARCH
|
|
1825
|
+
category: busqueda
|
|
1826
|
+
detectors:
|
|
1827
|
+
imports: ["meilisearch", "import meilisearch", "from meilisearch"]
|
|
1828
|
+
env_vars: ["MEILI_MASTER_KEY", "MEILI_URL", "MEILISEARCH_HOST"]
|
|
1829
|
+
deps: ["meilisearch"]
|
|
1830
|
+
dashboard_url: "https://cloud.meilisearch.com"
|
|
1831
|
+
env_example: |
|
|
1832
|
+
MEILI_URL=
|
|
1833
|
+
MEILI_MASTER_KEY=
|
|
1834
|
+
files:
|
|
1835
|
+
test_connection.sh: |
|
|
1836
|
+
#!/usr/bin/env bash
|
|
1837
|
+
set -euo pipefail
|
|
1838
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1839
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1840
|
+
URL="${MEILI_URL:-${MEILISEARCH_HOST:-}}"
|
|
1841
|
+
[ -n "$URL" ] || { echo "ERROR: MEILI_URL not set" >&2; exit 1; }
|
|
1842
|
+
: "${MEILI_MASTER_KEY:?MEILI_MASTER_KEY not set}"
|
|
1843
|
+
curl -fsS "${URL%/}/health" -H "Authorization: Bearer $MEILI_MASTER_KEY" | grep -q available
|
|
1844
|
+
echo "OK — Meilisearch available."
|
|
1845
|
+
README.md: |
|
|
1846
|
+
# MEILISEARCH
|
|
1847
|
+
Open-source instant search. Managed cloud or self-hosted.
|
|
1848
|
+
CREDENTIALS.md: |
|
|
1849
|
+
Dashboard: https://cloud.meilisearch.com
|
|
1850
|
+
`MEILI_MASTER_KEY` — secret. Use scoped API keys for clients.
|
|
1851
|
+
|
|
1852
|
+
# ------------------------------------------------------------------
|
|
1853
|
+
# Observability (logs, errors, tracing, product analytics)
|
|
1854
|
+
# ------------------------------------------------------------------
|
|
1855
|
+
|
|
1856
|
+
- id: SENTRY
|
|
1857
|
+
category: observabilidad
|
|
1858
|
+
detectors:
|
|
1859
|
+
imports: ["@sentry/nextjs", "@sentry/node", "@sentry/react", "import sentry_sdk", "from sentry_sdk"]
|
|
1860
|
+
env_vars: ["SENTRY_DSN", "SENTRY_AUTH_TOKEN", "SENTRY_ORG", "SENTRY_PROJECT", "NEXT_PUBLIC_SENTRY_DSN"]
|
|
1861
|
+
deps: ["@sentry/nextjs", "@sentry/node", "@sentry/react", "sentry-sdk", "sentry-cli"]
|
|
1862
|
+
dashboard_url: "https://sentry.io/settings/auth-tokens/"
|
|
1863
|
+
env_example: |
|
|
1864
|
+
SENTRY_DSN=
|
|
1865
|
+
SENTRY_AUTH_TOKEN=
|
|
1866
|
+
SENTRY_ORG=
|
|
1867
|
+
SENTRY_PROJECT=
|
|
1868
|
+
files:
|
|
1869
|
+
test_connection.sh: |
|
|
1870
|
+
#!/usr/bin/env bash
|
|
1871
|
+
set -euo pipefail
|
|
1872
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1873
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1874
|
+
: "${SENTRY_AUTH_TOKEN:?SENTRY_AUTH_TOKEN not set}"
|
|
1875
|
+
: "${SENTRY_ORG:?SENTRY_ORG not set}"
|
|
1876
|
+
N=$(curl -fsS "https://sentry.io/api/0/organizations/$SENTRY_ORG/projects/" -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')
|
|
1877
|
+
echo "OK — Sentry projects: $N."
|
|
1878
|
+
README.md: |
|
|
1879
|
+
# SENTRY
|
|
1880
|
+
Error tracking + performance + session replay.
|
|
1881
|
+
CREDENTIALS.md: |
|
|
1882
|
+
Dashboard: https://sentry.io/settings/auth-tokens/
|
|
1883
|
+
`SENTRY_DSN` — public, for SDK init.
|
|
1884
|
+
`SENTRY_AUTH_TOKEN` — secret, for sourcemaps upload + API.
|
|
1885
|
+
|
|
1886
|
+
- id: DATADOG
|
|
1887
|
+
category: observabilidad
|
|
1888
|
+
detectors:
|
|
1889
|
+
imports: ["from datadog", "import datadog", "datadog-api-client", "dd-trace"]
|
|
1890
|
+
env_vars: ["DD_API_KEY", "DD_APP_KEY", "DATADOG_API_KEY", "DD_SITE"]
|
|
1891
|
+
deps: ["datadog", "datadog-api-client", "dd-trace"]
|
|
1892
|
+
dashboard_url: "https://app.datadoghq.com/organization-settings/api-keys"
|
|
1893
|
+
env_example: |
|
|
1894
|
+
DD_API_KEY=
|
|
1895
|
+
DD_APP_KEY=
|
|
1896
|
+
DD_SITE=datadoghq.eu
|
|
1897
|
+
files:
|
|
1898
|
+
test_connection.sh: |
|
|
1899
|
+
#!/usr/bin/env bash
|
|
1900
|
+
set -euo pipefail
|
|
1901
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1902
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1903
|
+
: "${DD_API_KEY:?DD_API_KEY not set}"
|
|
1904
|
+
SITE="${DD_SITE:-datadoghq.com}"
|
|
1905
|
+
curl -fsS "https://api.${SITE}/api/v1/validate" -H "DD-API-KEY: $DD_API_KEY" | grep -q '"valid":true'
|
|
1906
|
+
echo "OK — Datadog API key valid ($SITE)."
|
|
1907
|
+
README.md: |
|
|
1908
|
+
# DATADOG
|
|
1909
|
+
Logs + APM + metrics + RUM. Pick `DD_SITE` for your region.
|
|
1910
|
+
CREDENTIALS.md: |
|
|
1911
|
+
Dashboard: https://app.datadoghq.com/organization-settings/api-keys
|
|
1912
|
+
`DD_API_KEY` — for ingest. `DD_APP_KEY` — for API queries.
|
|
1913
|
+
|
|
1914
|
+
- id: NEW_RELIC
|
|
1915
|
+
category: observabilidad
|
|
1916
|
+
detectors:
|
|
1917
|
+
imports: ["import newrelic", "newrelic"]
|
|
1918
|
+
env_vars: ["NEW_RELIC_LICENSE_KEY", "NEW_RELIC_API_KEY", "NEW_RELIC_ACCOUNT_ID"]
|
|
1919
|
+
deps: ["newrelic"]
|
|
1920
|
+
dashboard_url: "https://one.newrelic.com/admin-portal/api-keys/home"
|
|
1921
|
+
env_example: |
|
|
1922
|
+
NEW_RELIC_API_KEY=
|
|
1923
|
+
NEW_RELIC_ACCOUNT_ID=
|
|
1924
|
+
files:
|
|
1925
|
+
test_connection.sh: |
|
|
1926
|
+
#!/usr/bin/env bash
|
|
1927
|
+
set -euo pipefail
|
|
1928
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1929
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1930
|
+
: "${NEW_RELIC_API_KEY:?NEW_RELIC_API_KEY not set}"
|
|
1931
|
+
: "${NEW_RELIC_ACCOUNT_ID:?NEW_RELIC_ACCOUNT_ID not set}"
|
|
1932
|
+
# NerdGraph query for account name (smallest valid request).
|
|
1933
|
+
curl -fsS https://api.newrelic.com/graphql \
|
|
1934
|
+
-H "API-Key: $NEW_RELIC_API_KEY" \
|
|
1935
|
+
-H "Content-Type: application/json" \
|
|
1936
|
+
-d "{\"query\":\"{ actor { account(id: $NEW_RELIC_ACCOUNT_ID) { name } } }\"}" >/dev/null
|
|
1937
|
+
echo "OK — New Relic API key valid."
|
|
1938
|
+
README.md: |
|
|
1939
|
+
# NEW_RELIC
|
|
1940
|
+
APM + logs + metrics + browser/mobile.
|
|
1941
|
+
CREDENTIALS.md: |
|
|
1942
|
+
Dashboard: https://one.newrelic.com/admin-portal/api-keys/home
|
|
1943
|
+
`NEW_RELIC_LICENSE_KEY` — for agents (ingest).
|
|
1944
|
+
`NEW_RELIC_API_KEY` — for NerdGraph queries.
|
|
1945
|
+
|
|
1946
|
+
- id: BETTER_STACK
|
|
1947
|
+
category: observabilidad
|
|
1948
|
+
detectors:
|
|
1949
|
+
imports: ["@logtail/node", "@logtail/next", "import logtail", "from logtail"]
|
|
1950
|
+
env_vars: ["LOGTAIL_SOURCE_TOKEN", "BETTERSTACK_API_TOKEN"]
|
|
1951
|
+
deps: ["@logtail/node", "@logtail/next", "logtail"]
|
|
1952
|
+
dashboard_url: "https://logs.betterstack.com"
|
|
1953
|
+
env_example: |
|
|
1954
|
+
LOGTAIL_SOURCE_TOKEN=
|
|
1955
|
+
BETTERSTACK_API_TOKEN=
|
|
1956
|
+
files:
|
|
1957
|
+
test_connection.sh: |
|
|
1958
|
+
#!/usr/bin/env bash
|
|
1959
|
+
set -euo pipefail
|
|
1960
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1961
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1962
|
+
: "${BETTERSTACK_API_TOKEN:?BETTERSTACK_API_TOKEN not set}"
|
|
1963
|
+
N=$(curl -fsS https://logs.betterstack.com/api/v1/sources -H "Authorization: Bearer $BETTERSTACK_API_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
1964
|
+
echo "OK — Better Stack sources: $N."
|
|
1965
|
+
README.md: |
|
|
1966
|
+
# BETTER_STACK
|
|
1967
|
+
Logs (Logtail) + uptime + incident management (formerly Better Uptime).
|
|
1968
|
+
CREDENTIALS.md: |
|
|
1969
|
+
Dashboard: https://logs.betterstack.com
|
|
1970
|
+
`LOGTAIL_SOURCE_TOKEN` — for log ingest.
|
|
1971
|
+
`BETTERSTACK_API_TOKEN` — for API/management.
|
|
1972
|
+
|
|
1973
|
+
- id: AXIOM
|
|
1974
|
+
category: observabilidad
|
|
1975
|
+
detectors:
|
|
1976
|
+
imports: ["@axiomhq/js", "@axiomhq/nextjs", "import axiom"]
|
|
1977
|
+
env_vars: ["AXIOM_TOKEN", "AXIOM_DATASET", "AXIOM_ORG_ID"]
|
|
1978
|
+
deps: ["@axiomhq/js", "@axiomhq/nextjs"]
|
|
1979
|
+
dashboard_url: "https://app.axiom.co/settings/api-tokens"
|
|
1980
|
+
env_example: |
|
|
1981
|
+
AXIOM_TOKEN=
|
|
1982
|
+
AXIOM_DATASET=
|
|
1983
|
+
files:
|
|
1984
|
+
test_connection.sh: |
|
|
1985
|
+
#!/usr/bin/env bash
|
|
1986
|
+
set -euo pipefail
|
|
1987
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
1988
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
1989
|
+
: "${AXIOM_TOKEN:?AXIOM_TOKEN not set}"
|
|
1990
|
+
N=$(curl -fsS https://api.axiom.co/v1/datasets -H "Authorization: Bearer $AXIOM_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')
|
|
1991
|
+
echo "OK — Axiom datasets: $N."
|
|
1992
|
+
README.md: |
|
|
1993
|
+
# AXIOM
|
|
1994
|
+
Time-series + logs platform with SQL/APL queries.
|
|
1995
|
+
CREDENTIALS.md: |
|
|
1996
|
+
Dashboard: https://app.axiom.co/settings/api-tokens
|
|
1997
|
+
`AXIOM_TOKEN` — API token (per-dataset or org-wide).
|
|
1998
|
+
|
|
1999
|
+
- id: HONEYCOMB
|
|
2000
|
+
category: observabilidad
|
|
2001
|
+
detectors:
|
|
2002
|
+
imports: ["@honeycombio/opentelemetry-node", "from honeycomb_beeline"]
|
|
2003
|
+
env_vars: ["HONEYCOMB_API_KEY", "HONEYCOMB_DATASET"]
|
|
2004
|
+
deps: ["@honeycombio/opentelemetry-node", "honeycomb-beeline"]
|
|
2005
|
+
dashboard_url: "https://ui.honeycomb.io/account/api_keys"
|
|
2006
|
+
env_example: |
|
|
2007
|
+
HONEYCOMB_API_KEY=
|
|
2008
|
+
HONEYCOMB_DATASET=
|
|
2009
|
+
files:
|
|
2010
|
+
test_connection.sh: |
|
|
2011
|
+
#!/usr/bin/env bash
|
|
2012
|
+
set -euo pipefail
|
|
2013
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2014
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2015
|
+
: "${HONEYCOMB_API_KEY:?HONEYCOMB_API_KEY not set}"
|
|
2016
|
+
TEAM=$(curl -fsS https://api.honeycomb.io/1/auth -H "X-Honeycomb-Team: $HONEYCOMB_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["team"]["slug"])')
|
|
2017
|
+
echo "OK — Honeycomb team: $TEAM."
|
|
2018
|
+
README.md: |
|
|
2019
|
+
# HONEYCOMB
|
|
2020
|
+
Observability for tracing-heavy distributed systems.
|
|
2021
|
+
CREDENTIALS.md: |
|
|
2022
|
+
Dashboard: https://ui.honeycomb.io/account/api_keys
|
|
2023
|
+
`HONEYCOMB_API_KEY` — secret, scoped per environment.
|
|
2024
|
+
|
|
2025
|
+
- id: POSTHOG
|
|
2026
|
+
category: observabilidad
|
|
2027
|
+
detectors:
|
|
2028
|
+
imports: ["posthog-js", "posthog-node", "posthog-python", "import posthog", "from posthog"]
|
|
2029
|
+
env_vars: ["POSTHOG_API_KEY", "POSTHOG_PROJECT_API_KEY", "POSTHOG_PERSONAL_API_KEY", "NEXT_PUBLIC_POSTHOG_KEY"]
|
|
2030
|
+
deps: ["posthog-js", "posthog-node", "posthog"]
|
|
2031
|
+
dashboard_url: "https://app.posthog.com/project/settings"
|
|
2032
|
+
env_example: |
|
|
2033
|
+
POSTHOG_PROJECT_API_KEY=
|
|
2034
|
+
POSTHOG_PERSONAL_API_KEY=
|
|
2035
|
+
POSTHOG_HOST=https://us.i.posthog.com
|
|
2036
|
+
files:
|
|
2037
|
+
test_connection.sh: |
|
|
2038
|
+
#!/usr/bin/env bash
|
|
2039
|
+
set -euo pipefail
|
|
2040
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2041
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2042
|
+
: "${POSTHOG_PERSONAL_API_KEY:?POSTHOG_PERSONAL_API_KEY not set}"
|
|
2043
|
+
HOST="${POSTHOG_HOST:-https://us.i.posthog.com}"
|
|
2044
|
+
NAME=$(curl -fsS "${HOST%/}/api/users/@me/" -H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("email","?"))')
|
|
2045
|
+
echo "OK — PostHog authed as $NAME."
|
|
2046
|
+
README.md: |
|
|
2047
|
+
# POSTHOG
|
|
2048
|
+
Product analytics + session replay + feature flags + A/B + LLM observability.
|
|
2049
|
+
CREDENTIALS.md: |
|
|
2050
|
+
Dashboard: https://app.posthog.com/project/settings
|
|
2051
|
+
`POSTHOG_PROJECT_API_KEY` — public, for SDK init.
|
|
2052
|
+
`POSTHOG_PERSONAL_API_KEY` — secret, for API queries.
|
|
2053
|
+
|
|
2054
|
+
- id: LANGFUSE
|
|
2055
|
+
category: observabilidad
|
|
2056
|
+
detectors:
|
|
2057
|
+
imports: ["langfuse", "import langfuse", "from langfuse"]
|
|
2058
|
+
env_vars: ["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY", "LANGFUSE_HOST"]
|
|
2059
|
+
deps: ["langfuse"]
|
|
2060
|
+
dashboard_url: "https://cloud.langfuse.com"
|
|
2061
|
+
env_example: |
|
|
2062
|
+
LANGFUSE_PUBLIC_KEY=
|
|
2063
|
+
LANGFUSE_SECRET_KEY=
|
|
2064
|
+
LANGFUSE_HOST=https://cloud.langfuse.com
|
|
2065
|
+
files:
|
|
2066
|
+
test_connection.sh: |
|
|
2067
|
+
#!/usr/bin/env bash
|
|
2068
|
+
set -euo pipefail
|
|
2069
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2070
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2071
|
+
: "${LANGFUSE_PUBLIC_KEY:?LANGFUSE_PUBLIC_KEY not set}"
|
|
2072
|
+
: "${LANGFUSE_SECRET_KEY:?LANGFUSE_SECRET_KEY not set}"
|
|
2073
|
+
HOST="${LANGFUSE_HOST:-https://cloud.langfuse.com}"
|
|
2074
|
+
curl -fsS "${HOST%/}/api/public/projects" -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" >/dev/null
|
|
2075
|
+
echo "OK — Langfuse credentials valid."
|
|
2076
|
+
README.md: |
|
|
2077
|
+
# LANGFUSE
|
|
2078
|
+
LLM observability: tracing, evals, prompts, datasets.
|
|
2079
|
+
CREDENTIALS.md: |
|
|
2080
|
+
Dashboard: https://cloud.langfuse.com
|
|
2081
|
+
Both keys are needed; the public key is used as the username.
|
|
2082
|
+
|
|
2083
|
+
- id: LOGFIRE
|
|
2084
|
+
category: observabilidad
|
|
2085
|
+
detectors:
|
|
2086
|
+
imports: ["import logfire", "from logfire"]
|
|
2087
|
+
env_vars: ["LOGFIRE_TOKEN"]
|
|
2088
|
+
deps: ["logfire"]
|
|
2089
|
+
dashboard_url: "https://logfire.pydantic.dev"
|
|
2090
|
+
env_example: |
|
|
2091
|
+
LOGFIRE_TOKEN=
|
|
2092
|
+
files:
|
|
2093
|
+
test_connection.sh: |
|
|
2094
|
+
#!/usr/bin/env bash
|
|
2095
|
+
# Logfire ingests via OTLP; there's no read-only auth endpoint.
|
|
2096
|
+
# We validate the token format and probe the public OTLP endpoint.
|
|
2097
|
+
set -euo pipefail
|
|
2098
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2099
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2100
|
+
: "${LOGFIRE_TOKEN:?LOGFIRE_TOKEN not set}"
|
|
2101
|
+
curl -fsS -o /dev/null -w "%{http_code}\n" https://logfire-api.pydantic.dev/health | grep -q 200
|
|
2102
|
+
echo "OK — Logfire ingest endpoint reachable."
|
|
2103
|
+
README.md: |
|
|
2104
|
+
# LOGFIRE
|
|
2105
|
+
Observability built on OpenTelemetry by the Pydantic team.
|
|
2106
|
+
CREDENTIALS.md: |
|
|
2107
|
+
Dashboard: https://logfire.pydantic.dev
|
|
2108
|
+
`LOGFIRE_TOKEN` — secret, scoped per project.
|
|
2109
|
+
|
|
2110
|
+
# ------------------------------------------------------------------
|
|
2111
|
+
# Product analytics
|
|
2112
|
+
# ------------------------------------------------------------------
|
|
2113
|
+
|
|
2114
|
+
- id: MIXPANEL
|
|
2115
|
+
category: analitica
|
|
2116
|
+
detectors:
|
|
2117
|
+
imports: ["import mixpanel", "from mixpanel", "mixpanel-browser", "mixpanel"]
|
|
2118
|
+
env_vars: ["MIXPANEL_TOKEN", "MIXPANEL_API_SECRET", "MIXPANEL_PROJECT_ID", "MIXPANEL_SA_USER", "MIXPANEL_SA_SECRET"]
|
|
2119
|
+
deps: ["mixpanel", "mixpanel-browser"]
|
|
2120
|
+
dashboard_url: "https://mixpanel.com/settings/project"
|
|
2121
|
+
env_example: |
|
|
2122
|
+
MIXPANEL_TOKEN=
|
|
2123
|
+
MIXPANEL_SA_USER=
|
|
2124
|
+
MIXPANEL_SA_SECRET=
|
|
2125
|
+
MIXPANEL_PROJECT_ID=
|
|
2126
|
+
files:
|
|
2127
|
+
test_connection.sh: |
|
|
2128
|
+
#!/usr/bin/env bash
|
|
2129
|
+
set -euo pipefail
|
|
2130
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2131
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2132
|
+
: "${MIXPANEL_SA_USER:?MIXPANEL_SA_USER not set}"
|
|
2133
|
+
: "${MIXPANEL_SA_SECRET:?MIXPANEL_SA_SECRET not set}"
|
|
2134
|
+
: "${MIXPANEL_PROJECT_ID:?MIXPANEL_PROJECT_ID not set}"
|
|
2135
|
+
curl -fsS "https://mixpanel.com/api/app/projects/$MIXPANEL_PROJECT_ID" -u "$MIXPANEL_SA_USER:$MIXPANEL_SA_SECRET" >/dev/null
|
|
2136
|
+
echo "OK — Mixpanel service account valid."
|
|
2137
|
+
README.md: |
|
|
2138
|
+
# MIXPANEL
|
|
2139
|
+
Event-based product analytics.
|
|
2140
|
+
CREDENTIALS.md: |
|
|
2141
|
+
Dashboard: https://mixpanel.com/settings/project
|
|
2142
|
+
`MIXPANEL_TOKEN` — public, for SDK init.
|
|
2143
|
+
`MIXPANEL_SA_USER` / `MIXPANEL_SA_SECRET` — Service Account credentials for API queries.
|
|
2144
|
+
|
|
2145
|
+
- id: AMPLITUDE
|
|
2146
|
+
category: analitica
|
|
2147
|
+
detectors:
|
|
2148
|
+
imports: ["@amplitude/analytics-browser", "@amplitude/analytics-node", "amplitude-js", "import amplitude"]
|
|
2149
|
+
env_vars: ["AMPLITUDE_API_KEY", "AMPLITUDE_SECRET_KEY"]
|
|
2150
|
+
deps: ["@amplitude/analytics-browser", "@amplitude/analytics-node", "amplitude"]
|
|
2151
|
+
dashboard_url: "https://amplitude.com/settings"
|
|
2152
|
+
env_example: |
|
|
2153
|
+
AMPLITUDE_API_KEY=
|
|
2154
|
+
AMPLITUDE_SECRET_KEY=
|
|
2155
|
+
files:
|
|
2156
|
+
test_connection.sh: |
|
|
2157
|
+
#!/usr/bin/env bash
|
|
2158
|
+
# Amplitude API uses HTTP Basic with api_key:secret_key.
|
|
2159
|
+
set -euo pipefail
|
|
2160
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2161
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2162
|
+
: "${AMPLITUDE_API_KEY:?AMPLITUDE_API_KEY not set}"
|
|
2163
|
+
: "${AMPLITUDE_SECRET_KEY:?AMPLITUDE_SECRET_KEY not set}"
|
|
2164
|
+
curl -fsS https://amplitude.com/api/2/usersearch?user=test -u "$AMPLITUDE_API_KEY:$AMPLITUDE_SECRET_KEY" >/dev/null
|
|
2165
|
+
echo "OK — Amplitude credentials valid."
|
|
2166
|
+
README.md: |
|
|
2167
|
+
# AMPLITUDE
|
|
2168
|
+
Product analytics + experimentation.
|
|
2169
|
+
CREDENTIALS.md: |
|
|
2170
|
+
Dashboard: https://amplitude.com/settings
|
|
2171
|
+
Both keys are needed for the API (Basic auth: api_key:secret_key).
|
|
2172
|
+
|
|
2173
|
+
- id: PLAUSIBLE
|
|
2174
|
+
category: analitica
|
|
2175
|
+
detectors:
|
|
2176
|
+
imports: ["next-plausible", "plausible-tracker"]
|
|
2177
|
+
env_vars: ["PLAUSIBLE_API_KEY", "PLAUSIBLE_SITE_ID", "PLAUSIBLE_HOST"]
|
|
2178
|
+
deps: ["next-plausible", "plausible-tracker"]
|
|
2179
|
+
dashboard_url: "https://plausible.io/settings/api-keys"
|
|
2180
|
+
env_example: |
|
|
2181
|
+
PLAUSIBLE_API_KEY=
|
|
2182
|
+
PLAUSIBLE_SITE_ID=
|
|
2183
|
+
PLAUSIBLE_HOST=https://plausible.io
|
|
2184
|
+
files:
|
|
2185
|
+
test_connection.sh: |
|
|
2186
|
+
#!/usr/bin/env bash
|
|
2187
|
+
set -euo pipefail
|
|
2188
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2189
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2190
|
+
: "${PLAUSIBLE_API_KEY:?PLAUSIBLE_API_KEY not set}"
|
|
2191
|
+
: "${PLAUSIBLE_SITE_ID:?PLAUSIBLE_SITE_ID not set}"
|
|
2192
|
+
HOST="${PLAUSIBLE_HOST:-https://plausible.io}"
|
|
2193
|
+
N=$(curl -fsS "${HOST%/}/api/v1/stats/realtime/visitors?site_id=$PLAUSIBLE_SITE_ID" -H "Authorization: Bearer $PLAUSIBLE_API_KEY")
|
|
2194
|
+
echo "OK — Plausible realtime visitors: $N."
|
|
2195
|
+
README.md: |
|
|
2196
|
+
# PLAUSIBLE
|
|
2197
|
+
Privacy-friendly, GDPR-compliant analytics.
|
|
2198
|
+
CREDENTIALS.md: |
|
|
2199
|
+
Dashboard: https://plausible.io/settings/api-keys
|
|
2200
|
+
`PLAUSIBLE_SITE_ID` is the domain (e.g. `example.com`).
|
|
2201
|
+
|
|
2202
|
+
- id: FATHOM
|
|
2203
|
+
category: analitica
|
|
2204
|
+
detectors:
|
|
2205
|
+
imports: ["fathom-client"]
|
|
2206
|
+
env_vars: ["FATHOM_API_TOKEN", "FATHOM_SITE_ID"]
|
|
2207
|
+
deps: ["fathom-client"]
|
|
2208
|
+
dashboard_url: "https://app.usefathom.com/api"
|
|
2209
|
+
env_example: |
|
|
2210
|
+
FATHOM_API_TOKEN=
|
|
2211
|
+
FATHOM_SITE_ID=
|
|
2212
|
+
files:
|
|
2213
|
+
test_connection.sh: |
|
|
2214
|
+
#!/usr/bin/env bash
|
|
2215
|
+
set -euo pipefail
|
|
2216
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2217
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2218
|
+
: "${FATHOM_API_TOKEN:?FATHOM_API_TOKEN not set}"
|
|
2219
|
+
N=$(curl -fsS https://api.usefathom.com/v1/sites -H "Authorization: Bearer $FATHOM_API_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
2220
|
+
echo "OK — Fathom sites: $N."
|
|
2221
|
+
README.md: |
|
|
2222
|
+
# FATHOM
|
|
2223
|
+
Simple, privacy-focused web analytics.
|
|
2224
|
+
CREDENTIALS.md: |
|
|
2225
|
+
Dashboard: https://app.usefathom.com/api
|
|
2226
|
+
`FATHOM_API_TOKEN` — secret.
|
|
2227
|
+
|
|
2228
|
+
- id: UMAMI
|
|
2229
|
+
category: analitica
|
|
2230
|
+
detectors:
|
|
2231
|
+
imports: ["@umami/node"]
|
|
2232
|
+
env_vars: ["UMAMI_API_KEY", "UMAMI_HOST", "UMAMI_WEBSITE_ID"]
|
|
2233
|
+
deps: ["@umami/node"]
|
|
2234
|
+
dashboard_url: "https://cloud.umami.is/settings/api"
|
|
2235
|
+
env_example: |
|
|
2236
|
+
UMAMI_HOST=https://api.umami.is
|
|
2237
|
+
UMAMI_API_KEY=
|
|
2238
|
+
UMAMI_WEBSITE_ID=
|
|
2239
|
+
files:
|
|
2240
|
+
test_connection.sh: |
|
|
2241
|
+
#!/usr/bin/env bash
|
|
2242
|
+
set -euo pipefail
|
|
2243
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2244
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2245
|
+
: "${UMAMI_API_KEY:?UMAMI_API_KEY not set}"
|
|
2246
|
+
HOST="${UMAMI_HOST:-https://api.umami.is}"
|
|
2247
|
+
curl -fsS "${HOST%/}/v1/me" -H "x-umami-api-key: $UMAMI_API_KEY" >/dev/null
|
|
2248
|
+
echo "OK — Umami API key valid."
|
|
2249
|
+
README.md: |
|
|
2250
|
+
# UMAMI
|
|
2251
|
+
Open-source, privacy-focused analytics. Cloud or self-hosted.
|
|
2252
|
+
CREDENTIALS.md: |
|
|
2253
|
+
Dashboard: https://cloud.umami.is/settings/api
|
|
2254
|
+
`UMAMI_API_KEY` — secret.
|
|
2255
|
+
|
|
2256
|
+
- id: SEGMENT
|
|
2257
|
+
category: analitica
|
|
2258
|
+
detectors:
|
|
2259
|
+
imports: ["@segment/analytics-node", "@segment/analytics-next", "from segment"]
|
|
2260
|
+
env_vars: ["SEGMENT_WRITE_KEY", "SEGMENT_API_TOKEN"]
|
|
2261
|
+
deps: ["@segment/analytics-node", "@segment/analytics-next"]
|
|
2262
|
+
dashboard_url: "https://app.segment.com/goto-my-workspace/settings/access-management"
|
|
2263
|
+
env_example: |
|
|
2264
|
+
SEGMENT_WRITE_KEY=
|
|
2265
|
+
SEGMENT_API_TOKEN=
|
|
2266
|
+
files:
|
|
2267
|
+
test_connection.sh: |
|
|
2268
|
+
#!/usr/bin/env bash
|
|
2269
|
+
set -euo pipefail
|
|
2270
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2271
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2272
|
+
: "${SEGMENT_API_TOKEN:?SEGMENT_API_TOKEN not set}"
|
|
2273
|
+
N=$(curl -fsS https://api.segmentapis.com/sources -H "Authorization: Bearer $SEGMENT_API_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]["sources"]))')
|
|
2274
|
+
echo "OK — Segment sources: $N."
|
|
2275
|
+
README.md: |
|
|
2276
|
+
# SEGMENT
|
|
2277
|
+
CDP (Customer Data Platform). Pipes events to other tools.
|
|
2278
|
+
CREDENTIALS.md: |
|
|
2279
|
+
Dashboard: https://app.segment.com/goto-my-workspace/settings/access-management
|
|
2280
|
+
`SEGMENT_WRITE_KEY` — per source, for SDKs.
|
|
2281
|
+
`SEGMENT_API_TOKEN` — workspace, for Config API.
|
|
2282
|
+
|
|
2283
|
+
# ------------------------------------------------------------------
|
|
2284
|
+
# Deploy & PaaS
|
|
2285
|
+
# ------------------------------------------------------------------
|
|
2286
|
+
|
|
2287
|
+
- id: VERCEL
|
|
2288
|
+
category: infra
|
|
2289
|
+
detectors:
|
|
2290
|
+
imports: ["@vercel/sdk", "@vercel/analytics", "@vercel/blob", "@vercel/kv", "@vercel/postgres"]
|
|
2291
|
+
env_vars: ["VERCEL_TOKEN", "VERCEL_TEAM_ID", "VERCEL_PROJECT_ID"]
|
|
2292
|
+
deps: ["@vercel/sdk", "vercel"]
|
|
2293
|
+
dashboard_url: "https://vercel.com/account/tokens"
|
|
2294
|
+
env_example: |
|
|
2295
|
+
VERCEL_TOKEN=
|
|
2296
|
+
VERCEL_TEAM_ID=
|
|
2297
|
+
files:
|
|
2298
|
+
test_connection.sh: |
|
|
2299
|
+
#!/usr/bin/env bash
|
|
2300
|
+
set -euo pipefail
|
|
2301
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2302
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2303
|
+
: "${VERCEL_TOKEN:?VERCEL_TOKEN not set}"
|
|
2304
|
+
USER=$(curl -fsS https://api.vercel.com/v2/user -H "Authorization: Bearer $VERCEL_TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["user"]["username"])')
|
|
2305
|
+
echo "OK — Vercel authed as $USER."
|
|
2306
|
+
README.md: |
|
|
2307
|
+
# VERCEL
|
|
2308
|
+
Frontend + serverless deploy. Tokens scoped per-team.
|
|
2309
|
+
CREDENTIALS.md: |
|
|
2310
|
+
Dashboard: https://vercel.com/account/tokens
|
|
2311
|
+
`VERCEL_TOKEN` — secret. `VERCEL_TEAM_ID` needed for team-scoped calls.
|
|
2312
|
+
|
|
2313
|
+
- id: NETLIFY
|
|
2314
|
+
category: infra
|
|
2315
|
+
detectors:
|
|
2316
|
+
imports: ["@netlify/functions", "@netlify/blobs"]
|
|
2317
|
+
env_vars: ["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]
|
|
2318
|
+
deps: ["netlify", "netlify-cli", "@netlify/functions"]
|
|
2319
|
+
dashboard_url: "https://app.netlify.com/user/applications#personal-access-tokens"
|
|
2320
|
+
env_example: |
|
|
2321
|
+
NETLIFY_AUTH_TOKEN=
|
|
2322
|
+
NETLIFY_SITE_ID=
|
|
2323
|
+
files:
|
|
2324
|
+
test_connection.sh: |
|
|
2325
|
+
#!/usr/bin/env bash
|
|
2326
|
+
set -euo pipefail
|
|
2327
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2328
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2329
|
+
: "${NETLIFY_AUTH_TOKEN:?NETLIFY_AUTH_TOKEN not set}"
|
|
2330
|
+
N=$(curl -fsS https://api.netlify.com/api/v1/sites -H "Authorization: Bearer $NETLIFY_AUTH_TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')
|
|
2331
|
+
echo "OK — Netlify sites: $N."
|
|
2332
|
+
README.md: |
|
|
2333
|
+
# NETLIFY
|
|
2334
|
+
Static + serverless hosting.
|
|
2335
|
+
CREDENTIALS.md: |
|
|
2336
|
+
Dashboard: https://app.netlify.com/user/applications#personal-access-tokens
|
|
2337
|
+
`NETLIFY_AUTH_TOKEN` — secret.
|
|
2338
|
+
|
|
2339
|
+
- id: RAILWAY
|
|
2340
|
+
category: infra
|
|
2341
|
+
detectors:
|
|
2342
|
+
imports: []
|
|
2343
|
+
env_vars: ["RAILWAY_TOKEN", "RAILWAY_API_TOKEN", "RAILWAY_PROJECT_ID"]
|
|
2344
|
+
deps: ["@railway/cli"]
|
|
2345
|
+
dashboard_url: "https://railway.app/account/tokens"
|
|
2346
|
+
env_example: |
|
|
2347
|
+
RAILWAY_API_TOKEN=
|
|
2348
|
+
files:
|
|
2349
|
+
test_connection.sh: |
|
|
2350
|
+
#!/usr/bin/env bash
|
|
2351
|
+
# Railway uses GraphQL exclusively.
|
|
2352
|
+
set -euo pipefail
|
|
2353
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2354
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2355
|
+
: "${RAILWAY_API_TOKEN:?RAILWAY_API_TOKEN not set}"
|
|
2356
|
+
curl -fsS https://backboard.railway.app/graphql/v2 \
|
|
2357
|
+
-H "Authorization: Bearer $RAILWAY_API_TOKEN" \
|
|
2358
|
+
-H "Content-Type: application/json" \
|
|
2359
|
+
-d '{"query":"{ me { name } }"}' \
|
|
2360
|
+
| python3 -c 'import json,sys; d=json.load(sys.stdin); print("OK — Railway authed as", d["data"]["me"]["name"])'
|
|
2361
|
+
README.md: |
|
|
2362
|
+
# RAILWAY
|
|
2363
|
+
Hetzner-style PaaS with templates and Postgres add-ons.
|
|
2364
|
+
CREDENTIALS.md: |
|
|
2365
|
+
Dashboard: https://railway.app/account/tokens
|
|
2366
|
+
`RAILWAY_API_TOKEN` — secret, account-scoped.
|
|
2367
|
+
|
|
2368
|
+
- id: FLY_IO
|
|
2369
|
+
category: infra
|
|
2370
|
+
detectors:
|
|
2371
|
+
imports: []
|
|
2372
|
+
env_vars: ["FLY_API_TOKEN", "FLY_ACCESS_TOKEN", "FLY_ORG"]
|
|
2373
|
+
deps: []
|
|
2374
|
+
dashboard_url: "https://fly.io/user/personal_access_tokens"
|
|
2375
|
+
env_example: |
|
|
2376
|
+
FLY_API_TOKEN=
|
|
2377
|
+
FLY_ORG=personal
|
|
2378
|
+
files:
|
|
2379
|
+
test_connection.sh: |
|
|
2380
|
+
#!/usr/bin/env bash
|
|
2381
|
+
set -euo pipefail
|
|
2382
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2383
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2384
|
+
TOKEN="${FLY_API_TOKEN:-${FLY_ACCESS_TOKEN:-}}"
|
|
2385
|
+
[ -n "$TOKEN" ] || { echo "ERROR: FLY_API_TOKEN not set" >&2; exit 1; }
|
|
2386
|
+
# Fly Machines REST API.
|
|
2387
|
+
ORG="${FLY_ORG:-personal}"
|
|
2388
|
+
N=$(curl -fsS "https://api.machines.dev/v1/apps?org_slug=$ORG" -H "Authorization: Bearer $TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin).get("apps",[])))')
|
|
2389
|
+
echo "OK — Fly.io apps in '$ORG': $N."
|
|
2390
|
+
README.md: |
|
|
2391
|
+
# FLY_IO
|
|
2392
|
+
Run apps as Firecracker microVMs in regions worldwide.
|
|
2393
|
+
CREDENTIALS.md: |
|
|
2394
|
+
Dashboard: https://fly.io/user/personal_access_tokens
|
|
2395
|
+
`FLY_API_TOKEN` — secret. `FLY_ORG` is the org slug (default `personal`).
|
|
2396
|
+
|
|
2397
|
+
- id: RENDER
|
|
2398
|
+
category: infra
|
|
2399
|
+
detectors:
|
|
2400
|
+
imports: []
|
|
2401
|
+
env_vars: ["RENDER_API_KEY"]
|
|
2402
|
+
deps: []
|
|
2403
|
+
dashboard_url: "https://dashboard.render.com/u/settings#api-keys"
|
|
2404
|
+
env_example: |
|
|
2405
|
+
RENDER_API_KEY=
|
|
2406
|
+
files:
|
|
2407
|
+
test_connection.sh: |
|
|
2408
|
+
#!/usr/bin/env bash
|
|
2409
|
+
set -euo pipefail
|
|
2410
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2411
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2412
|
+
: "${RENDER_API_KEY:?RENDER_API_KEY not set}"
|
|
2413
|
+
N=$(curl -fsS https://api.render.com/v1/services -H "Authorization: Bearer $RENDER_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')
|
|
2414
|
+
echo "OK — Render services: $N."
|
|
2415
|
+
README.md: |
|
|
2416
|
+
# RENDER
|
|
2417
|
+
PaaS for web services, cron jobs, static sites, databases.
|
|
2418
|
+
CREDENTIALS.md: |
|
|
2419
|
+
Dashboard: https://dashboard.render.com/u/settings#api-keys
|
|
2420
|
+
`RENDER_API_KEY` — secret.
|
|
2421
|
+
|
|
2422
|
+
- id: DIGITALOCEAN
|
|
2423
|
+
category: infra
|
|
2424
|
+
detectors:
|
|
2425
|
+
imports: ["pydo", "from digitalocean", "@digitalocean/godo"]
|
|
2426
|
+
env_vars: ["DIGITALOCEAN_TOKEN", "DO_API_TOKEN", "DIGITALOCEAN_ACCESS_TOKEN"]
|
|
2427
|
+
deps: ["pydo", "digitalocean"]
|
|
2428
|
+
dashboard_url: "https://cloud.digitalocean.com/account/api/tokens"
|
|
2429
|
+
env_example: |
|
|
2430
|
+
DIGITALOCEAN_TOKEN=
|
|
2431
|
+
files:
|
|
2432
|
+
test_connection.sh: |
|
|
2433
|
+
#!/usr/bin/env bash
|
|
2434
|
+
set -euo pipefail
|
|
2435
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2436
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2437
|
+
TOKEN="${DIGITALOCEAN_TOKEN:-${DO_API_TOKEN:-${DIGITALOCEAN_ACCESS_TOKEN:-}}}"
|
|
2438
|
+
[ -n "$TOKEN" ] || { echo "ERROR: DIGITALOCEAN_TOKEN not set" >&2; exit 1; }
|
|
2439
|
+
EMAIL=$(curl -fsS https://api.digitalocean.com/v2/account -H "Authorization: Bearer $TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["account"]["email"])')
|
|
2440
|
+
echo "OK — DigitalOcean account: $EMAIL."
|
|
2441
|
+
README.md: |
|
|
2442
|
+
# DIGITALOCEAN
|
|
2443
|
+
Droplets, Spaces, App Platform, Managed Databases.
|
|
2444
|
+
CREDENTIALS.md: |
|
|
2445
|
+
Dashboard: https://cloud.digitalocean.com/account/api/tokens
|
|
2446
|
+
`DIGITALOCEAN_TOKEN` — secret. Read + write scope.
|
|
2447
|
+
|
|
2448
|
+
- id: CLOUDFLARE
|
|
2449
|
+
category: infra
|
|
2450
|
+
detectors:
|
|
2451
|
+
imports: ["cloudflare", "import cloudflare", "from cloudflare", "@cloudflare/workers-types", "wrangler"]
|
|
2452
|
+
env_vars: ["CLOUDFLARE_API_TOKEN", "CLOUDFLARE_ACCOUNT_ID", "CF_API_TOKEN"]
|
|
2453
|
+
deps: ["cloudflare", "wrangler", "@cloudflare/workers-types"]
|
|
2454
|
+
dashboard_url: "https://dash.cloudflare.com/profile/api-tokens"
|
|
2455
|
+
env_example: |
|
|
2456
|
+
CLOUDFLARE_API_TOKEN=
|
|
2457
|
+
CLOUDFLARE_ACCOUNT_ID=
|
|
2458
|
+
files:
|
|
2459
|
+
test_connection.sh: |
|
|
2460
|
+
#!/usr/bin/env bash
|
|
2461
|
+
set -euo pipefail
|
|
2462
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2463
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2464
|
+
TOKEN="${CLOUDFLARE_API_TOKEN:-${CF_API_TOKEN:-}}"
|
|
2465
|
+
[ -n "$TOKEN" ] || { echo "ERROR: CLOUDFLARE_API_TOKEN not set" >&2; exit 1; }
|
|
2466
|
+
curl -fsS https://api.cloudflare.com/client/v4/user/tokens/verify -H "Authorization: Bearer $TOKEN" | grep -q '"success":true'
|
|
2467
|
+
echo "OK — Cloudflare token verified."
|
|
2468
|
+
README.md: |
|
|
2469
|
+
# CLOUDFLARE
|
|
2470
|
+
DNS + CDN + Workers + R2 + D1 + Pages + Tunnels.
|
|
2471
|
+
CREDENTIALS.md: |
|
|
2472
|
+
Dashboard: https://dash.cloudflare.com/profile/api-tokens
|
|
2473
|
+
`CLOUDFLARE_API_TOKEN` — scoped, prefer over global API key.
|
|
2474
|
+
|
|
2475
|
+
- id: HEROKU
|
|
2476
|
+
category: infra
|
|
2477
|
+
detectors:
|
|
2478
|
+
imports: []
|
|
2479
|
+
env_vars: ["HEROKU_API_KEY"]
|
|
2480
|
+
deps: ["heroku"]
|
|
2481
|
+
dashboard_url: "https://dashboard.heroku.com/account"
|
|
2482
|
+
env_example: |
|
|
2483
|
+
HEROKU_API_KEY=
|
|
2484
|
+
files:
|
|
2485
|
+
test_connection.sh: |
|
|
2486
|
+
#!/usr/bin/env bash
|
|
2487
|
+
set -euo pipefail
|
|
2488
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2489
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2490
|
+
: "${HEROKU_API_KEY:?HEROKU_API_KEY not set}"
|
|
2491
|
+
EMAIL=$(curl -fsS https://api.heroku.com/account -H "Accept: application/vnd.heroku+json; version=3" -H "Authorization: Bearer $HEROKU_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["email"])')
|
|
2492
|
+
echo "OK — Heroku account: $EMAIL."
|
|
2493
|
+
README.md: |
|
|
2494
|
+
# HEROKU
|
|
2495
|
+
Classic PaaS for buildpack-based apps.
|
|
2496
|
+
CREDENTIALS.md: |
|
|
2497
|
+
Dashboard: https://dashboard.heroku.com/account
|
|
2498
|
+
`HEROKU_API_KEY` — secret.
|
|
2499
|
+
|
|
2500
|
+
- id: VULTR
|
|
2501
|
+
category: infra
|
|
2502
|
+
detectors:
|
|
2503
|
+
imports: []
|
|
2504
|
+
env_vars: ["VULTR_API_KEY"]
|
|
2505
|
+
deps: []
|
|
2506
|
+
dashboard_url: "https://my.vultr.com/settings/#settingsapi"
|
|
2507
|
+
env_example: |
|
|
2508
|
+
VULTR_API_KEY=
|
|
2509
|
+
files:
|
|
2510
|
+
test_connection.sh: |
|
|
2511
|
+
#!/usr/bin/env bash
|
|
2512
|
+
set -euo pipefail
|
|
2513
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2514
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2515
|
+
: "${VULTR_API_KEY:?VULTR_API_KEY not set}"
|
|
2516
|
+
BAL=$(curl -fsS https://api.vultr.com/v2/account -H "Authorization: Bearer $VULTR_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["account"]["balance"])')
|
|
2517
|
+
echo "OK — Vultr account balance: $BAL."
|
|
2518
|
+
README.md: |
|
|
2519
|
+
# VULTR
|
|
2520
|
+
Cloud servers, block/object storage, bare metal.
|
|
2521
|
+
CREDENTIALS.md: |
|
|
2522
|
+
Dashboard: https://my.vultr.com/settings/#settingsapi
|
|
2523
|
+
`VULTR_API_KEY` — secret. IP allowlist may apply.
|
|
2524
|
+
|
|
2525
|
+
# ------------------------------------------------------------------
|
|
2526
|
+
# Object storage
|
|
2527
|
+
# ------------------------------------------------------------------
|
|
2528
|
+
|
|
2529
|
+
- id: AWS_S3
|
|
2530
|
+
category: almacenamiento
|
|
2531
|
+
detectors:
|
|
2532
|
+
imports: ["@aws-sdk/client-s3", "from boto3", "import boto3"]
|
|
2533
|
+
env_vars: ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION", "S3_BUCKET"]
|
|
2534
|
+
deps: ["@aws-sdk/client-s3", "boto3"]
|
|
2535
|
+
dashboard_url: "https://console.aws.amazon.com/iam/home"
|
|
2536
|
+
manual_only: true
|
|
2537
|
+
env_example: |
|
|
2538
|
+
AWS_ACCESS_KEY_ID=
|
|
2539
|
+
AWS_SECRET_ACCESS_KEY=
|
|
2540
|
+
AWS_REGION=eu-west-1
|
|
2541
|
+
S3_BUCKET=
|
|
2542
|
+
files:
|
|
2543
|
+
README.md: |
|
|
2544
|
+
# AWS_S3
|
|
2545
|
+
S3 uses SigV4 signing which is not trivial to implement in plain bash.
|
|
2546
|
+
Verify with the AWS CLI:
|
|
2547
|
+
|
|
2548
|
+
aws s3 ls s3://$S3_BUCKET --region $AWS_REGION
|
|
2549
|
+
|
|
2550
|
+
or with boto3:
|
|
2551
|
+
|
|
2552
|
+
python -c "import boto3; print(boto3.client('s3').list_buckets()['Buckets'])"
|
|
2553
|
+
CREDENTIALS.md: |
|
|
2554
|
+
Dashboard: https://console.aws.amazon.com/iam/home
|
|
2555
|
+
IAM access key with at minimum `s3:ListBucket`, `s3:GetObject`, `s3:PutObject` on the target bucket.
|
|
2556
|
+
|
|
2557
|
+
- id: CLOUDFLARE_R2
|
|
2558
|
+
category: almacenamiento
|
|
2559
|
+
detectors:
|
|
2560
|
+
imports: ["@aws-sdk/client-s3"]
|
|
2561
|
+
env_vars: ["R2_ACCOUNT_ID", "R2_ACCESS_KEY_ID", "R2_SECRET_ACCESS_KEY", "R2_BUCKET", "R2_ENDPOINT"]
|
|
2562
|
+
deps: ["@aws-sdk/client-s3"]
|
|
2563
|
+
dashboard_url: "https://dash.cloudflare.com/?to=/:account/r2/api-tokens"
|
|
2564
|
+
manual_only: true
|
|
2565
|
+
env_example: |
|
|
2566
|
+
R2_ACCOUNT_ID=
|
|
2567
|
+
R2_ACCESS_KEY_ID=
|
|
2568
|
+
R2_SECRET_ACCESS_KEY=
|
|
2569
|
+
R2_BUCKET=
|
|
2570
|
+
R2_ENDPOINT=https://<account_id>.r2.cloudflarestorage.com
|
|
2571
|
+
files:
|
|
2572
|
+
README.md: |
|
|
2573
|
+
# CLOUDFLARE_R2
|
|
2574
|
+
S3-compatible object storage. Same SigV4 caveat as AWS_S3 — verify with:
|
|
2575
|
+
|
|
2576
|
+
aws --endpoint-url=$R2_ENDPOINT s3 ls s3://$R2_BUCKET
|
|
2577
|
+
|
|
2578
|
+
or `wrangler r2 bucket list`.
|
|
2579
|
+
CREDENTIALS.md: |
|
|
2580
|
+
Dashboard: https://dash.cloudflare.com/?to=/:account/r2/api-tokens
|
|
2581
|
+
R2 keys are S3-compatible. Endpoint is per account.
|
|
2582
|
+
|
|
2583
|
+
- id: BACKBLAZE_B2
|
|
2584
|
+
category: almacenamiento
|
|
2585
|
+
detectors:
|
|
2586
|
+
imports: ["b2sdk", "from b2sdk"]
|
|
2587
|
+
env_vars: ["B2_APPLICATION_KEY_ID", "B2_APPLICATION_KEY", "B2_BUCKET"]
|
|
2588
|
+
deps: ["b2sdk"]
|
|
2589
|
+
dashboard_url: "https://secure.backblaze.com/app_keys.htm"
|
|
2590
|
+
env_example: |
|
|
2591
|
+
B2_APPLICATION_KEY_ID=
|
|
2592
|
+
B2_APPLICATION_KEY=
|
|
2593
|
+
B2_BUCKET=
|
|
2594
|
+
files:
|
|
2595
|
+
test_connection.sh: |
|
|
2596
|
+
#!/usr/bin/env bash
|
|
2597
|
+
# b2_authorize_account is the canonical auth handshake.
|
|
2598
|
+
set -euo pipefail
|
|
2599
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2600
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2601
|
+
: "${B2_APPLICATION_KEY_ID:?not set}"
|
|
2602
|
+
: "${B2_APPLICATION_KEY:?not set}"
|
|
2603
|
+
ACC=$(curl -fsS https://api.backblazeb2.com/b2api/v3/b2_authorize_account -u "$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["accountId"])')
|
|
2604
|
+
echo "OK — Backblaze B2 account: $ACC."
|
|
2605
|
+
README.md: |
|
|
2606
|
+
# BACKBLAZE_B2
|
|
2607
|
+
Cheap S3-compatible (and native) object storage.
|
|
2608
|
+
CREDENTIALS.md: |
|
|
2609
|
+
Dashboard: https://secure.backblaze.com/app_keys.htm
|
|
2610
|
+
`B2_APPLICATION_KEY_ID` + `B2_APPLICATION_KEY`. Restrict to specific bucket.
|
|
2611
|
+
|
|
2612
|
+
# ------------------------------------------------------------------
|
|
2613
|
+
# Realtime, video, WebRTC
|
|
2614
|
+
# ------------------------------------------------------------------
|
|
2615
|
+
|
|
2616
|
+
- id: MUX
|
|
2617
|
+
category: realtime
|
|
2618
|
+
detectors:
|
|
2619
|
+
imports: ["@mux/mux-node", "@mux/mux-player-react"]
|
|
2620
|
+
env_vars: ["MUX_TOKEN_ID", "MUX_TOKEN_SECRET", "MUX_WEBHOOK_SECRET"]
|
|
2621
|
+
deps: ["@mux/mux-node", "@mux/mux-player-react"]
|
|
2622
|
+
dashboard_url: "https://dashboard.mux.com/settings/access-tokens"
|
|
2623
|
+
env_example: |
|
|
2624
|
+
MUX_TOKEN_ID=
|
|
2625
|
+
MUX_TOKEN_SECRET=
|
|
2626
|
+
files:
|
|
2627
|
+
test_connection.sh: |
|
|
2628
|
+
#!/usr/bin/env bash
|
|
2629
|
+
set -euo pipefail
|
|
2630
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2631
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2632
|
+
: "${MUX_TOKEN_ID:?MUX_TOKEN_ID not set}"
|
|
2633
|
+
: "${MUX_TOKEN_SECRET:?MUX_TOKEN_SECRET not set}"
|
|
2634
|
+
N=$(curl -fsS "https://api.mux.com/video/v1/assets?limit=1" -u "$MUX_TOKEN_ID:$MUX_TOKEN_SECRET" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
2635
|
+
echo "OK — Mux access token valid (sample assets: $N)."
|
|
2636
|
+
README.md: |
|
|
2637
|
+
# MUX
|
|
2638
|
+
Video infrastructure for product teams (upload, transcode, deliver).
|
|
2639
|
+
CREDENTIALS.md: |
|
|
2640
|
+
Dashboard: https://dashboard.mux.com/settings/access-tokens
|
|
2641
|
+
Token id + secret, scoped per env (dev/prod).
|
|
2642
|
+
|
|
2643
|
+
- id: LIVEKIT
|
|
2644
|
+
category: realtime
|
|
2645
|
+
detectors:
|
|
2646
|
+
imports: ["livekit-server-sdk", "livekit-client", "from livekit"]
|
|
2647
|
+
env_vars: ["LIVEKIT_API_KEY", "LIVEKIT_API_SECRET", "LIVEKIT_URL"]
|
|
2648
|
+
deps: ["livekit-server-sdk", "livekit-client", "livekit"]
|
|
2649
|
+
dashboard_url: "https://cloud.livekit.io"
|
|
2650
|
+
manual_only: true
|
|
2651
|
+
env_example: |
|
|
2652
|
+
LIVEKIT_URL=
|
|
2653
|
+
LIVEKIT_API_KEY=
|
|
2654
|
+
LIVEKIT_API_SECRET=
|
|
2655
|
+
files:
|
|
2656
|
+
README.md: |
|
|
2657
|
+
# LIVEKIT
|
|
2658
|
+
WebRTC infra (rooms, recording, ingress). The API requires JWTs
|
|
2659
|
+
signed with the API secret — verify with the official CLI:
|
|
2660
|
+
|
|
2661
|
+
livekit-cli list-rooms --url $LIVEKIT_URL --api-key $LIVEKIT_API_KEY --api-secret $LIVEKIT_API_SECRET
|
|
2662
|
+
CREDENTIALS.md: |
|
|
2663
|
+
Dashboard: https://cloud.livekit.io
|
|
2664
|
+
Project URL + API key/secret. Self-hosted is the same env vars.
|
|
2665
|
+
|
|
2666
|
+
- id: DAILY_CO
|
|
2667
|
+
category: realtime
|
|
2668
|
+
detectors:
|
|
2669
|
+
imports: ["@daily-co/daily-js", "@daily-co/daily-react"]
|
|
2670
|
+
env_vars: ["DAILY_API_KEY", "DAILY_DOMAIN"]
|
|
2671
|
+
deps: ["@daily-co/daily-js", "@daily-co/daily-react"]
|
|
2672
|
+
dashboard_url: "https://dashboard.daily.co/developers"
|
|
2673
|
+
env_example: |
|
|
2674
|
+
DAILY_API_KEY=
|
|
2675
|
+
files:
|
|
2676
|
+
test_connection.sh: |
|
|
2677
|
+
#!/usr/bin/env bash
|
|
2678
|
+
set -euo pipefail
|
|
2679
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2680
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2681
|
+
: "${DAILY_API_KEY:?DAILY_API_KEY not set}"
|
|
2682
|
+
DOMAIN=$(curl -fsS https://api.daily.co/v1/ -H "Authorization: Bearer $DAILY_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("domain_name","?"))')
|
|
2683
|
+
echo "OK — Daily.co domain: $DOMAIN."
|
|
2684
|
+
README.md: |
|
|
2685
|
+
# DAILY_CO
|
|
2686
|
+
Embeddable video calls + meeting infra.
|
|
2687
|
+
CREDENTIALS.md: |
|
|
2688
|
+
Dashboard: https://dashboard.daily.co/developers
|
|
2689
|
+
`DAILY_API_KEY` — secret.
|
|
2690
|
+
|
|
2691
|
+
- id: PUSHER
|
|
2692
|
+
category: realtime
|
|
2693
|
+
detectors:
|
|
2694
|
+
imports: ["pusher", "pusher-js", "import pusher"]
|
|
2695
|
+
env_vars: ["PUSHER_APP_ID", "PUSHER_KEY", "PUSHER_SECRET", "PUSHER_CLUSTER"]
|
|
2696
|
+
deps: ["pusher", "pusher-js"]
|
|
2697
|
+
dashboard_url: "https://dashboard.pusher.com"
|
|
2698
|
+
manual_only: true
|
|
2699
|
+
env_example: |
|
|
2700
|
+
PUSHER_APP_ID=
|
|
2701
|
+
PUSHER_KEY=
|
|
2702
|
+
PUSHER_SECRET=
|
|
2703
|
+
PUSHER_CLUSTER=eu
|
|
2704
|
+
files:
|
|
2705
|
+
README.md: |
|
|
2706
|
+
# PUSHER
|
|
2707
|
+
Channels (pub/sub) + Beams (push). The REST API requires per-request
|
|
2708
|
+
HMAC-SHA256 signing — easiest to verify with the official SDK:
|
|
2709
|
+
|
|
2710
|
+
node -e "const Pusher = require('pusher'); new Pusher({appId: process.env.PUSHER_APP_ID, key: process.env.PUSHER_KEY, secret: process.env.PUSHER_SECRET, cluster: process.env.PUSHER_CLUSTER}).get({path: '/channels'}, console.log)"
|
|
2711
|
+
CREDENTIALS.md: |
|
|
2712
|
+
Dashboard: https://dashboard.pusher.com
|
|
2713
|
+
4 vars: app_id, key, secret, cluster.
|
|
2714
|
+
|
|
2715
|
+
- id: ABLY
|
|
2716
|
+
category: realtime
|
|
2717
|
+
detectors:
|
|
2718
|
+
imports: ["ably", "import ably", "from ably"]
|
|
2719
|
+
env_vars: ["ABLY_API_KEY"]
|
|
2720
|
+
deps: ["ably"]
|
|
2721
|
+
dashboard_url: "https://ably.com/accounts/any/apps"
|
|
2722
|
+
env_example: |
|
|
2723
|
+
ABLY_API_KEY=
|
|
2724
|
+
files:
|
|
2725
|
+
test_connection.sh: |
|
|
2726
|
+
#!/usr/bin/env bash
|
|
2727
|
+
set -euo pipefail
|
|
2728
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2729
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2730
|
+
: "${ABLY_API_KEY:?ABLY_API_KEY not set}"
|
|
2731
|
+
# Time endpoint requires auth and is read-only/cheap.
|
|
2732
|
+
TS=$(curl -fsS https://rest.ably.io/time -u "$ABLY_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)[0])')
|
|
2733
|
+
echo "OK — Ably server timestamp: $TS."
|
|
2734
|
+
README.md: |
|
|
2735
|
+
# ABLY
|
|
2736
|
+
Realtime messaging / pub-sub at scale.
|
|
2737
|
+
CREDENTIALS.md: |
|
|
2738
|
+
Dashboard: https://ably.com/accounts/any/apps
|
|
2739
|
+
`ABLY_API_KEY` has the form `appKeyId:appKeySecret`.
|
|
2740
|
+
|
|
2741
|
+
# ------------------------------------------------------------------
|
|
2742
|
+
# Communications (SMS, voice, push, in-app notifications)
|
|
2743
|
+
# ------------------------------------------------------------------
|
|
2744
|
+
|
|
2745
|
+
- id: TWILIO
|
|
2746
|
+
category: comunicacion
|
|
2747
|
+
detectors:
|
|
2748
|
+
imports: ["twilio", "from twilio", "import twilio"]
|
|
2749
|
+
env_vars: ["TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN", "TWILIO_API_KEY", "TWILIO_API_SECRET"]
|
|
2750
|
+
deps: ["twilio"]
|
|
2751
|
+
dashboard_url: "https://console.twilio.com"
|
|
2752
|
+
env_example: |
|
|
2753
|
+
TWILIO_ACCOUNT_SID=
|
|
2754
|
+
TWILIO_AUTH_TOKEN=
|
|
2755
|
+
files:
|
|
2756
|
+
test_connection.sh: |
|
|
2757
|
+
#!/usr/bin/env bash
|
|
2758
|
+
set -euo pipefail
|
|
2759
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2760
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2761
|
+
: "${TWILIO_ACCOUNT_SID:?TWILIO_ACCOUNT_SID not set}"
|
|
2762
|
+
: "${TWILIO_AUTH_TOKEN:?TWILIO_AUTH_TOKEN not set}"
|
|
2763
|
+
STATUS=$(curl -fsS "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID.json" -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
|
|
2764
|
+
echo "OK — Twilio account status: $STATUS."
|
|
2765
|
+
README.md: |
|
|
2766
|
+
# TWILIO
|
|
2767
|
+
SMS, voice, WhatsApp, Verify, Video.
|
|
2768
|
+
CREDENTIALS.md: |
|
|
2769
|
+
Dashboard: https://console.twilio.com
|
|
2770
|
+
Account SID + Auth Token from the main account page.
|
|
2771
|
+
|
|
2772
|
+
- id: VONAGE
|
|
2773
|
+
category: comunicacion
|
|
2774
|
+
detectors:
|
|
2775
|
+
imports: ["@vonage/server-sdk", "vonage"]
|
|
2776
|
+
env_vars: ["VONAGE_API_KEY", "VONAGE_API_SECRET"]
|
|
2777
|
+
deps: ["@vonage/server-sdk", "vonage"]
|
|
2778
|
+
dashboard_url: "https://dashboard.nexmo.com/settings"
|
|
2779
|
+
env_example: |
|
|
2780
|
+
VONAGE_API_KEY=
|
|
2781
|
+
VONAGE_API_SECRET=
|
|
2782
|
+
files:
|
|
2783
|
+
test_connection.sh: |
|
|
2784
|
+
#!/usr/bin/env bash
|
|
2785
|
+
set -euo pipefail
|
|
2786
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2787
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2788
|
+
: "${VONAGE_API_KEY:?VONAGE_API_KEY not set}"
|
|
2789
|
+
: "${VONAGE_API_SECRET:?VONAGE_API_SECRET not set}"
|
|
2790
|
+
BAL=$(curl -fsS "https://rest.nexmo.com/account/get-balance?api_key=$VONAGE_API_KEY&api_secret=$VONAGE_API_SECRET" | python3 -c 'import json,sys; print(json.load(sys.stdin)["value"])')
|
|
2791
|
+
echo "OK — Vonage balance: $BAL."
|
|
2792
|
+
README.md: |
|
|
2793
|
+
# VONAGE
|
|
2794
|
+
SMS, voice, verify (formerly Nexmo).
|
|
2795
|
+
CREDENTIALS.md: |
|
|
2796
|
+
Dashboard: https://dashboard.nexmo.com/settings
|
|
2797
|
+
API key + secret. Some APIs (Conversations) need an Application ID.
|
|
2798
|
+
|
|
2799
|
+
- id: ONESIGNAL
|
|
2800
|
+
category: comunicacion
|
|
2801
|
+
detectors:
|
|
2802
|
+
imports: ["react-onesignal", "onesignal-node", "@onesignal/onesignal-react-native"]
|
|
2803
|
+
env_vars: ["ONESIGNAL_APP_ID", "ONESIGNAL_REST_API_KEY", "ONESIGNAL_USER_AUTH_KEY"]
|
|
2804
|
+
deps: ["onesignal-node", "react-onesignal", "@onesignal/onesignal-react-native"]
|
|
2805
|
+
dashboard_url: "https://dashboard.onesignal.com/apps"
|
|
2806
|
+
env_example: |
|
|
2807
|
+
ONESIGNAL_APP_ID=
|
|
2808
|
+
ONESIGNAL_REST_API_KEY=
|
|
2809
|
+
files:
|
|
2810
|
+
test_connection.sh: |
|
|
2811
|
+
#!/usr/bin/env bash
|
|
2812
|
+
set -euo pipefail
|
|
2813
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2814
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2815
|
+
: "${ONESIGNAL_APP_ID:?ONESIGNAL_APP_ID not set}"
|
|
2816
|
+
: "${ONESIGNAL_REST_API_KEY:?ONESIGNAL_REST_API_KEY not set}"
|
|
2817
|
+
N=$(curl -fsS "https://api.onesignal.com/apps/$ONESIGNAL_APP_ID" -H "Authorization: Key $ONESIGNAL_REST_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["players"])')
|
|
2818
|
+
echo "OK — OneSignal app players: $N."
|
|
2819
|
+
README.md: |
|
|
2820
|
+
# ONESIGNAL
|
|
2821
|
+
Multi-channel push (mobile, web, email).
|
|
2822
|
+
CREDENTIALS.md: |
|
|
2823
|
+
Dashboard: https://dashboard.onesignal.com/apps
|
|
2824
|
+
REST API key is per-app, scoped.
|
|
2825
|
+
|
|
2826
|
+
- id: EXPO_PUSH
|
|
2827
|
+
category: comunicacion
|
|
2828
|
+
detectors:
|
|
2829
|
+
imports: ["expo-server-sdk", "expo-notifications"]
|
|
2830
|
+
env_vars: ["EXPO_ACCESS_TOKEN"]
|
|
2831
|
+
deps: ["expo-server-sdk", "expo-notifications"]
|
|
2832
|
+
dashboard_url: "https://expo.dev/accounts/[account]/settings/access-tokens"
|
|
2833
|
+
manual_only: true
|
|
2834
|
+
env_example: |
|
|
2835
|
+
EXPO_ACCESS_TOKEN=
|
|
2836
|
+
files:
|
|
2837
|
+
README.md: |
|
|
2838
|
+
# EXPO_PUSH
|
|
2839
|
+
Push notifications for Expo apps. The push endpoint requires a real
|
|
2840
|
+
ExponentPushToken from a device — there is no read-only health endpoint.
|
|
2841
|
+
Verify by calling `expo whoami` after `export EXPO_TOKEN=$EXPO_ACCESS_TOKEN`.
|
|
2842
|
+
CREDENTIALS.md: |
|
|
2843
|
+
Dashboard: https://expo.dev/accounts/[account]/settings/access-tokens
|
|
2844
|
+
`EXPO_ACCESS_TOKEN` — secret, account-scoped.
|
|
2845
|
+
|
|
2846
|
+
- id: KNOCK
|
|
2847
|
+
category: comunicacion
|
|
2848
|
+
detectors:
|
|
2849
|
+
imports: ["@knocklabs/node", "@knocklabs/react", "@knocklabs/client"]
|
|
2850
|
+
env_vars: ["KNOCK_API_KEY", "KNOCK_PUBLIC_API_KEY", "KNOCK_SIGNING_KEY"]
|
|
2851
|
+
deps: ["@knocklabs/node", "@knocklabs/react"]
|
|
2852
|
+
dashboard_url: "https://dashboard.knock.app"
|
|
2853
|
+
env_example: |
|
|
2854
|
+
KNOCK_API_KEY=
|
|
2855
|
+
KNOCK_PUBLIC_API_KEY=
|
|
2856
|
+
files:
|
|
2857
|
+
test_connection.sh: |
|
|
2858
|
+
#!/usr/bin/env bash
|
|
2859
|
+
set -euo pipefail
|
|
2860
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2861
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2862
|
+
: "${KNOCK_API_KEY:?KNOCK_API_KEY not set}"
|
|
2863
|
+
# List users with a tiny limit; cheap auth check.
|
|
2864
|
+
curl -fsS "https://api.knock.app/v1/users?page_size=1" -H "Authorization: Bearer $KNOCK_API_KEY" >/dev/null
|
|
2865
|
+
echo "OK — Knock API key valid."
|
|
2866
|
+
README.md: |
|
|
2867
|
+
# KNOCK
|
|
2868
|
+
Notifications-as-a-service: orchestrate email, push, in-app, SMS.
|
|
2869
|
+
CREDENTIALS.md: |
|
|
2870
|
+
Dashboard: https://dashboard.knock.app
|
|
2871
|
+
Secret key for backend, public key for client SDKs.
|
|
2872
|
+
|
|
2873
|
+
# ------------------------------------------------------------------
|
|
2874
|
+
# Maps / geo
|
|
2875
|
+
# ------------------------------------------------------------------
|
|
2876
|
+
|
|
2877
|
+
- id: GOOGLE_MAPS
|
|
2878
|
+
category: mapas_geo
|
|
2879
|
+
detectors:
|
|
2880
|
+
imports: ["@googlemaps/js-api-loader", "@googlemaps/google-maps-services-js", "@react-google-maps/api"]
|
|
2881
|
+
env_vars: ["GOOGLE_MAPS_API_KEY", "NEXT_PUBLIC_GOOGLE_MAPS_API_KEY"]
|
|
2882
|
+
deps: ["@googlemaps/js-api-loader", "@googlemaps/google-maps-services-js", "@react-google-maps/api"]
|
|
2883
|
+
dashboard_url: "https://console.cloud.google.com/google/maps-apis/credentials"
|
|
2884
|
+
env_example: |
|
|
2885
|
+
GOOGLE_MAPS_API_KEY=
|
|
2886
|
+
files:
|
|
2887
|
+
test_connection.sh: |
|
|
2888
|
+
#!/usr/bin/env bash
|
|
2889
|
+
# Geocoding a known landmark is cheap (~$0.005) and validates the key.
|
|
2890
|
+
set -euo pipefail
|
|
2891
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2892
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2893
|
+
: "${GOOGLE_MAPS_API_KEY:?GOOGLE_MAPS_API_KEY not set}"
|
|
2894
|
+
STATUS=$(curl -fsS "https://maps.googleapis.com/maps/api/geocode/json?address=Madrid&key=$GOOGLE_MAPS_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
|
|
2895
|
+
[ "$STATUS" = "OK" ] || { echo "FAIL: status=$STATUS" >&2; exit 1; }
|
|
2896
|
+
echo "OK — Google Maps geocoding accessible."
|
|
2897
|
+
README.md: |
|
|
2898
|
+
# GOOGLE_MAPS
|
|
2899
|
+
Maps, Places, Geocoding, Directions, Distance Matrix.
|
|
2900
|
+
> The smoke-test costs ~$0.005 (1 geocode).
|
|
2901
|
+
CREDENTIALS.md: |
|
|
2902
|
+
Dashboard: https://console.cloud.google.com/google/maps-apis/credentials
|
|
2903
|
+
Restrict the key by HTTP referrer (web) or app bundle (mobile).
|
|
2904
|
+
|
|
2905
|
+
- id: MAPBOX
|
|
2906
|
+
category: mapas_geo
|
|
2907
|
+
detectors:
|
|
2908
|
+
imports: ["mapbox-gl", "react-map-gl", "@mapbox/mapbox-sdk"]
|
|
2909
|
+
env_vars: ["MAPBOX_ACCESS_TOKEN", "NEXT_PUBLIC_MAPBOX_TOKEN", "MAPBOX_SECRET_TOKEN"]
|
|
2910
|
+
deps: ["mapbox-gl", "react-map-gl", "@mapbox/mapbox-sdk"]
|
|
2911
|
+
dashboard_url: "https://account.mapbox.com/access-tokens"
|
|
2912
|
+
env_example: |
|
|
2913
|
+
MAPBOX_ACCESS_TOKEN=
|
|
2914
|
+
files:
|
|
2915
|
+
test_connection.sh: |
|
|
2916
|
+
#!/usr/bin/env bash
|
|
2917
|
+
set -euo pipefail
|
|
2918
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2919
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2920
|
+
: "${MAPBOX_ACCESS_TOKEN:?MAPBOX_ACCESS_TOKEN not set}"
|
|
2921
|
+
# Geocoding API: 1 free request.
|
|
2922
|
+
FEATURES=$(curl -fsS "https://api.mapbox.com/geocoding/v5/mapbox.places/Madrid.json?access_token=$MAPBOX_ACCESS_TOKEN&limit=1" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["features"]))')
|
|
2923
|
+
echo "OK — Mapbox geocoding returned $FEATURES feature(s)."
|
|
2924
|
+
README.md: |
|
|
2925
|
+
# MAPBOX
|
|
2926
|
+
Vector maps, geocoding, navigation, search.
|
|
2927
|
+
CREDENTIALS.md: |
|
|
2928
|
+
Dashboard: https://account.mapbox.com/access-tokens
|
|
2929
|
+
Public tokens (`pk.*`) for clients, secret tokens (`sk.*`) for server.
|
|
2930
|
+
|
|
2931
|
+
# ------------------------------------------------------------------
|
|
2932
|
+
# Calendar / scheduling
|
|
2933
|
+
# ------------------------------------------------------------------
|
|
2934
|
+
|
|
2935
|
+
- id: CAL_COM
|
|
2936
|
+
category: productividad
|
|
2937
|
+
detectors:
|
|
2938
|
+
imports: ["@calcom/embed-react"]
|
|
2939
|
+
env_vars: ["CAL_API_KEY", "CALCOM_API_KEY"]
|
|
2940
|
+
deps: ["@calcom/embed-react"]
|
|
2941
|
+
dashboard_url: "https://app.cal.com/settings/developer/api-keys"
|
|
2942
|
+
env_example: |
|
|
2943
|
+
CALCOM_API_KEY=
|
|
2944
|
+
files:
|
|
2945
|
+
test_connection.sh: |
|
|
2946
|
+
#!/usr/bin/env bash
|
|
2947
|
+
set -euo pipefail
|
|
2948
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2949
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2950
|
+
KEY="${CALCOM_API_KEY:-${CAL_API_KEY:-}}"
|
|
2951
|
+
[ -n "$KEY" ] || { echo "ERROR: CALCOM_API_KEY not set" >&2; exit 1; }
|
|
2952
|
+
# v1: GET /me?apiKey=
|
|
2953
|
+
EMAIL=$(curl -fsS "https://api.cal.com/v1/me?apiKey=$KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["user"]["email"])')
|
|
2954
|
+
echo "OK — Cal.com user: $EMAIL."
|
|
2955
|
+
README.md: |
|
|
2956
|
+
# CAL_COM
|
|
2957
|
+
Open-source scheduling (Calendly alternative).
|
|
2958
|
+
CREDENTIALS.md: |
|
|
2959
|
+
Dashboard: https://app.cal.com/settings/developer/api-keys
|
|
2960
|
+
`CALCOM_API_KEY` — secret.
|
|
2961
|
+
|
|
2962
|
+
- id: CALENDLY
|
|
2963
|
+
category: productividad
|
|
2964
|
+
detectors:
|
|
2965
|
+
imports: []
|
|
2966
|
+
env_vars: ["CALENDLY_API_KEY", "CALENDLY_ACCESS_TOKEN"]
|
|
2967
|
+
deps: []
|
|
2968
|
+
dashboard_url: "https://calendly.com/integrations/api_webhooks"
|
|
2969
|
+
env_example: |
|
|
2970
|
+
CALENDLY_ACCESS_TOKEN=
|
|
2971
|
+
files:
|
|
2972
|
+
test_connection.sh: |
|
|
2973
|
+
#!/usr/bin/env bash
|
|
2974
|
+
set -euo pipefail
|
|
2975
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
2976
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
2977
|
+
TOKEN="${CALENDLY_ACCESS_TOKEN:-${CALENDLY_API_KEY:-}}"
|
|
2978
|
+
[ -n "$TOKEN" ] || { echo "ERROR: CALENDLY_ACCESS_TOKEN not set" >&2; exit 1; }
|
|
2979
|
+
EMAIL=$(curl -fsS https://api.calendly.com/users/me -H "Authorization: Bearer $TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["resource"]["email"])')
|
|
2980
|
+
echo "OK — Calendly user: $EMAIL."
|
|
2981
|
+
README.md: |
|
|
2982
|
+
# CALENDLY
|
|
2983
|
+
Scheduling SaaS. API access requires a paid plan.
|
|
2984
|
+
CREDENTIALS.md: |
|
|
2985
|
+
Dashboard: https://calendly.com/integrations/api_webhooks
|
|
2986
|
+
`CALENDLY_ACCESS_TOKEN` — secret. Personal access tokens for individuals.
|
|
2987
|
+
|
|
2988
|
+
# ------------------------------------------------------------------
|
|
2989
|
+
# Productivity / project management / CRM / dev tools APIs
|
|
2990
|
+
# ------------------------------------------------------------------
|
|
2991
|
+
|
|
2992
|
+
- id: LINEAR
|
|
2993
|
+
category: productividad
|
|
2994
|
+
detectors:
|
|
2995
|
+
imports: ["@linear/sdk"]
|
|
2996
|
+
env_vars: ["LINEAR_API_KEY"]
|
|
2997
|
+
deps: ["@linear/sdk"]
|
|
2998
|
+
dashboard_url: "https://linear.app/settings/api"
|
|
2999
|
+
env_example: |
|
|
3000
|
+
LINEAR_API_KEY=
|
|
3001
|
+
files:
|
|
3002
|
+
test_connection.sh: |
|
|
3003
|
+
#!/usr/bin/env bash
|
|
3004
|
+
# Linear is GraphQL-only.
|
|
3005
|
+
set -euo pipefail
|
|
3006
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3007
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3008
|
+
: "${LINEAR_API_KEY:?LINEAR_API_KEY not set}"
|
|
3009
|
+
NAME=$(curl -fsS https://api.linear.app/graphql \
|
|
3010
|
+
-H "Authorization: $LINEAR_API_KEY" \
|
|
3011
|
+
-H "Content-Type: application/json" \
|
|
3012
|
+
-d '{"query":"{ viewer { name } }"}' \
|
|
3013
|
+
| python3 -c 'import json,sys; print(json.load(sys.stdin)["data"]["viewer"]["name"])')
|
|
3014
|
+
echo "OK — Linear authed as $NAME."
|
|
3015
|
+
README.md: |
|
|
3016
|
+
# LINEAR
|
|
3017
|
+
Issue tracking and project management. GraphQL API.
|
|
3018
|
+
CREDENTIALS.md: |
|
|
3019
|
+
Dashboard: https://linear.app/settings/api
|
|
3020
|
+
`LINEAR_API_KEY` — secret, personal API key.
|
|
3021
|
+
|
|
3022
|
+
- id: NOTION
|
|
3023
|
+
category: productividad
|
|
3024
|
+
detectors:
|
|
3025
|
+
imports: ["@notionhq/client", "notion-client"]
|
|
3026
|
+
env_vars: ["NOTION_API_KEY", "NOTION_TOKEN", "NOTION_DATABASE_ID"]
|
|
3027
|
+
deps: ["@notionhq/client"]
|
|
3028
|
+
dashboard_url: "https://www.notion.so/my-integrations"
|
|
3029
|
+
env_example: |
|
|
3030
|
+
NOTION_API_KEY=
|
|
3031
|
+
files:
|
|
3032
|
+
test_connection.sh: |
|
|
3033
|
+
#!/usr/bin/env bash
|
|
3034
|
+
set -euo pipefail
|
|
3035
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3036
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3037
|
+
TOKEN="${NOTION_API_KEY:-${NOTION_TOKEN:-}}"
|
|
3038
|
+
[ -n "$TOKEN" ] || { echo "ERROR: NOTION_API_KEY not set" >&2; exit 1; }
|
|
3039
|
+
NAME=$(curl -fsS https://api.notion.com/v1/users/me \
|
|
3040
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
3041
|
+
-H "Notion-Version: 2022-06-28" \
|
|
3042
|
+
| python3 -c 'import json,sys; print(json.load(sys.stdin).get("name","?"))')
|
|
3043
|
+
echo "OK — Notion integration: $NAME."
|
|
3044
|
+
README.md: |
|
|
3045
|
+
# NOTION
|
|
3046
|
+
Internal integration token gives access to pages explicitly shared with it.
|
|
3047
|
+
CREDENTIALS.md: |
|
|
3048
|
+
Dashboard: https://www.notion.so/my-integrations
|
|
3049
|
+
Internal integration secret. Share each page/db with the integration.
|
|
3050
|
+
|
|
3051
|
+
- id: HUBSPOT
|
|
3052
|
+
category: productividad
|
|
3053
|
+
detectors:
|
|
3054
|
+
imports: ["@hubspot/api-client"]
|
|
3055
|
+
env_vars: ["HUBSPOT_ACCESS_TOKEN", "HUBSPOT_PRIVATE_APP_TOKEN"]
|
|
3056
|
+
deps: ["@hubspot/api-client", "hubspot-api-client"]
|
|
3057
|
+
dashboard_url: "https://app.hubspot.com/private-apps"
|
|
3058
|
+
env_example: |
|
|
3059
|
+
HUBSPOT_ACCESS_TOKEN=
|
|
3060
|
+
files:
|
|
3061
|
+
test_connection.sh: |
|
|
3062
|
+
#!/usr/bin/env bash
|
|
3063
|
+
set -euo pipefail
|
|
3064
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3065
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3066
|
+
TOKEN="${HUBSPOT_ACCESS_TOKEN:-${HUBSPOT_PRIVATE_APP_TOKEN:-}}"
|
|
3067
|
+
[ -n "$TOKEN" ] || { echo "ERROR: HUBSPOT_ACCESS_TOKEN not set" >&2; exit 1; }
|
|
3068
|
+
N=$(curl -fsS "https://api.hubapi.com/crm/v3/objects/contacts?limit=1" -H "Authorization: Bearer $TOKEN" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["results"]))')
|
|
3069
|
+
echo "OK — HubSpot contacts endpoint accessible (sample: $N)."
|
|
3070
|
+
README.md: |
|
|
3071
|
+
# HUBSPOT
|
|
3072
|
+
CRM + marketing automation + service hub.
|
|
3073
|
+
CREDENTIALS.md: |
|
|
3074
|
+
Dashboard: https://app.hubspot.com/private-apps
|
|
3075
|
+
Private apps use a single bearer token with selectable scopes.
|
|
3076
|
+
|
|
3077
|
+
- id: GITHUB_API
|
|
3078
|
+
category: productividad
|
|
3079
|
+
detectors:
|
|
3080
|
+
imports: ["@octokit/rest", "@octokit/core", "from github", "import github"]
|
|
3081
|
+
env_vars: ["GH_TOKEN", "GITHUB_TOKEN", "GH_PAT", "GITHUB_PAT"]
|
|
3082
|
+
deps: ["@octokit/rest", "@octokit/core", "pygithub", "octokit"]
|
|
3083
|
+
dashboard_url: "https://github.com/settings/tokens"
|
|
3084
|
+
env_example: |
|
|
3085
|
+
GITHUB_TOKEN=
|
|
3086
|
+
files:
|
|
3087
|
+
test_connection.sh: |
|
|
3088
|
+
#!/usr/bin/env bash
|
|
3089
|
+
set -euo pipefail
|
|
3090
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3091
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3092
|
+
TOKEN="${GITHUB_TOKEN:-${GH_TOKEN:-${GH_PAT:-${GITHUB_PAT:-}}}}"
|
|
3093
|
+
[ -n "$TOKEN" ] || { echo "ERROR: GITHUB_TOKEN not set" >&2; exit 1; }
|
|
3094
|
+
LOGIN=$(curl -fsS https://api.github.com/user -H "Authorization: Bearer $TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["login"])')
|
|
3095
|
+
echo "OK — GitHub authed as $LOGIN."
|
|
3096
|
+
README.md: |
|
|
3097
|
+
# GITHUB_API
|
|
3098
|
+
Programmatic access to GitHub (repos, PRs, issues, releases, Actions).
|
|
3099
|
+
CREDENTIALS.md: |
|
|
3100
|
+
Dashboard: https://github.com/settings/tokens (or fine-grained tokens).
|
|
3101
|
+
Use a fine-grained token scoped to the minimal repos/permissions.
|
|
3102
|
+
|
|
3103
|
+
- id: GITLAB_API
|
|
3104
|
+
category: productividad
|
|
3105
|
+
detectors:
|
|
3106
|
+
imports: ["@gitbeaker/rest", "from gitlab", "import gitlab"]
|
|
3107
|
+
env_vars: ["GITLAB_TOKEN", "GITLAB_PRIVATE_TOKEN"]
|
|
3108
|
+
deps: ["@gitbeaker/rest", "python-gitlab"]
|
|
3109
|
+
dashboard_url: "https://gitlab.com/-/user_settings/personal_access_tokens"
|
|
3110
|
+
env_example: |
|
|
3111
|
+
GITLAB_TOKEN=
|
|
3112
|
+
GITLAB_URL=https://gitlab.com
|
|
3113
|
+
files:
|
|
3114
|
+
test_connection.sh: |
|
|
3115
|
+
#!/usr/bin/env bash
|
|
3116
|
+
set -euo pipefail
|
|
3117
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3118
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3119
|
+
: "${GITLAB_TOKEN:?GITLAB_TOKEN not set}"
|
|
3120
|
+
URL="${GITLAB_URL:-https://gitlab.com}"
|
|
3121
|
+
NAME=$(curl -fsS "${URL%/}/api/v4/user" -H "PRIVATE-TOKEN: $GITLAB_TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["username"])')
|
|
3122
|
+
echo "OK — GitLab authed as $NAME."
|
|
3123
|
+
README.md: |
|
|
3124
|
+
# GITLAB_API
|
|
3125
|
+
Programmatic access to GitLab. Works for SaaS and self-hosted.
|
|
3126
|
+
CREDENTIALS.md: |
|
|
3127
|
+
Dashboard: https://gitlab.com/-/user_settings/personal_access_tokens
|
|
3128
|
+
`GITLAB_URL` defaults to gitlab.com; override for self-hosted instances.
|
|
3129
|
+
|
|
3130
|
+
# ------------------------------------------------------------------
|
|
3131
|
+
# Customer support
|
|
3132
|
+
# ------------------------------------------------------------------
|
|
3133
|
+
|
|
3134
|
+
- id: INTERCOM
|
|
3135
|
+
category: productividad
|
|
3136
|
+
detectors:
|
|
3137
|
+
imports: ["@intercom/messenger-js-sdk", "intercom-client"]
|
|
3138
|
+
env_vars: ["INTERCOM_ACCESS_TOKEN", "INTERCOM_APP_ID"]
|
|
3139
|
+
deps: ["intercom-client", "@intercom/messenger-js-sdk"]
|
|
3140
|
+
dashboard_url: "https://app.intercom.com/a/apps/_/developer-hub"
|
|
3141
|
+
env_example: |
|
|
3142
|
+
INTERCOM_ACCESS_TOKEN=
|
|
3143
|
+
INTERCOM_APP_ID=
|
|
3144
|
+
files:
|
|
3145
|
+
test_connection.sh: |
|
|
3146
|
+
#!/usr/bin/env bash
|
|
3147
|
+
set -euo pipefail
|
|
3148
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3149
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3150
|
+
: "${INTERCOM_ACCESS_TOKEN:?INTERCOM_ACCESS_TOKEN not set}"
|
|
3151
|
+
NAME=$(curl -fsS https://api.intercom.io/me \
|
|
3152
|
+
-H "Authorization: Bearer $INTERCOM_ACCESS_TOKEN" \
|
|
3153
|
+
-H "Accept: application/json" \
|
|
3154
|
+
| python3 -c 'import json,sys; print(json.load(sys.stdin).get("app",{}).get("name","?"))')
|
|
3155
|
+
echo "OK — Intercom workspace: $NAME."
|
|
3156
|
+
README.md: |
|
|
3157
|
+
# INTERCOM
|
|
3158
|
+
Customer messaging + help center + product tours.
|
|
3159
|
+
CREDENTIALS.md: |
|
|
3160
|
+
Dashboard: https://app.intercom.com/a/apps/_/developer-hub
|
|
3161
|
+
Personal access token (developer hub).
|
|
3162
|
+
|
|
3163
|
+
- id: CRISP
|
|
3164
|
+
category: productividad
|
|
3165
|
+
detectors:
|
|
3166
|
+
imports: ["crisp-api"]
|
|
3167
|
+
env_vars: ["CRISP_IDENTIFIER", "CRISP_KEY", "CRISP_WEBSITE_ID"]
|
|
3168
|
+
deps: ["crisp-api"]
|
|
3169
|
+
dashboard_url: "https://app.crisp.chat/initiate/plugin/"
|
|
3170
|
+
manual_only: true
|
|
3171
|
+
env_example: |
|
|
3172
|
+
CRISP_IDENTIFIER=
|
|
3173
|
+
CRISP_KEY=
|
|
3174
|
+
CRISP_WEBSITE_ID=
|
|
3175
|
+
files:
|
|
3176
|
+
README.md: |
|
|
3177
|
+
# CRISP
|
|
3178
|
+
Customer chat + helpdesk. The REST API uses Basic auth with
|
|
3179
|
+
`identifier:key` plus a Website ID — verify via the official SDK:
|
|
3180
|
+
|
|
3181
|
+
node -e "require('crisp-api').authenticateTier('plugin', process.env.CRISP_IDENTIFIER, process.env.CRISP_KEY)"
|
|
3182
|
+
CREDENTIALS.md: |
|
|
3183
|
+
Dashboard: https://app.crisp.chat/initiate/plugin/
|
|
3184
|
+
Plugin tokens scoped to a specific Website ID.
|
|
3185
|
+
|
|
3186
|
+
# ------------------------------------------------------------------
|
|
3187
|
+
# Feature flags / experimentation
|
|
3188
|
+
# ------------------------------------------------------------------
|
|
3189
|
+
|
|
3190
|
+
- id: GROWTHBOOK
|
|
3191
|
+
category: feature_flags
|
|
3192
|
+
detectors:
|
|
3193
|
+
imports: ["@growthbook/growthbook", "@growthbook/growthbook-react", "growthbook"]
|
|
3194
|
+
env_vars: ["GROWTHBOOK_API_KEY", "GROWTHBOOK_CLIENT_KEY", "GROWTHBOOK_HOST"]
|
|
3195
|
+
deps: ["@growthbook/growthbook", "@growthbook/growthbook-react", "growthbook"]
|
|
3196
|
+
dashboard_url: "https://app.growthbook.io/settings/keys"
|
|
3197
|
+
env_example: |
|
|
3198
|
+
GROWTHBOOK_HOST=https://api.growthbook.io
|
|
3199
|
+
GROWTHBOOK_API_KEY=
|
|
3200
|
+
GROWTHBOOK_CLIENT_KEY=
|
|
3201
|
+
files:
|
|
3202
|
+
test_connection.sh: |
|
|
3203
|
+
#!/usr/bin/env bash
|
|
3204
|
+
set -euo pipefail
|
|
3205
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3206
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3207
|
+
: "${GROWTHBOOK_API_KEY:?GROWTHBOOK_API_KEY not set}"
|
|
3208
|
+
HOST="${GROWTHBOOK_HOST:-https://api.growthbook.io}"
|
|
3209
|
+
N=$(curl -fsS "${HOST%/}/api/v1/features?limit=1" -H "Authorization: Bearer $GROWTHBOOK_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("limit","?"))')
|
|
3210
|
+
echo "OK — GrowthBook API key valid."
|
|
3211
|
+
README.md: |
|
|
3212
|
+
# GROWTHBOOK
|
|
3213
|
+
Open-source feature flags + experimentation. Cloud or self-hosted.
|
|
3214
|
+
CREDENTIALS.md: |
|
|
3215
|
+
Dashboard: https://app.growthbook.io/settings/keys
|
|
3216
|
+
`GROWTHBOOK_API_KEY` — secret, for the management API.
|
|
3217
|
+
`GROWTHBOOK_CLIENT_KEY` — public, for SDK init.
|
|
3218
|
+
|
|
3219
|
+
- id: LAUNCHDARKLY
|
|
3220
|
+
category: feature_flags
|
|
3221
|
+
detectors:
|
|
3222
|
+
imports: ["launchdarkly-node-server-sdk", "launchdarkly-react-client-sdk", "launchdarkly-js-client-sdk"]
|
|
3223
|
+
env_vars: ["LAUNCHDARKLY_SDK_KEY", "LAUNCHDARKLY_API_KEY", "LD_SDK_KEY", "LD_API_KEY"]
|
|
3224
|
+
deps: ["launchdarkly-node-server-sdk", "launchdarkly-react-client-sdk"]
|
|
3225
|
+
dashboard_url: "https://app.launchdarkly.com/settings/authorization"
|
|
3226
|
+
env_example: |
|
|
3227
|
+
LAUNCHDARKLY_API_KEY=
|
|
3228
|
+
LAUNCHDARKLY_SDK_KEY=
|
|
3229
|
+
files:
|
|
3230
|
+
test_connection.sh: |
|
|
3231
|
+
#!/usr/bin/env bash
|
|
3232
|
+
set -euo pipefail
|
|
3233
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3234
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3235
|
+
TOKEN="${LAUNCHDARKLY_API_KEY:-${LD_API_KEY:-}}"
|
|
3236
|
+
[ -n "$TOKEN" ] || { echo "ERROR: LAUNCHDARKLY_API_KEY not set" >&2; exit 1; }
|
|
3237
|
+
N=$(curl -fsS https://app.launchdarkly.com/api/v2/projects -H "Authorization: $TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["totalCount"])')
|
|
3238
|
+
echo "OK — LaunchDarkly projects: $N."
|
|
3239
|
+
README.md: |
|
|
3240
|
+
# LAUNCHDARKLY
|
|
3241
|
+
Enterprise feature flagging + experimentation.
|
|
3242
|
+
CREDENTIALS.md: |
|
|
3243
|
+
Dashboard: https://app.launchdarkly.com/settings/authorization
|
|
3244
|
+
`LAUNCHDARKLY_API_KEY` — for REST API.
|
|
3245
|
+
`LAUNCHDARKLY_SDK_KEY` — per-environment, for runtime SDKs.
|
|
3246
|
+
|
|
3247
|
+
- id: FLAGSMITH
|
|
3248
|
+
category: feature_flags
|
|
3249
|
+
detectors:
|
|
3250
|
+
imports: ["flagsmith", "flagsmith-nodejs"]
|
|
3251
|
+
env_vars: ["FLAGSMITH_ENVIRONMENT_KEY", "FLAGSMITH_API_URL", "FLAGSMITH_API_TOKEN"]
|
|
3252
|
+
deps: ["flagsmith", "flagsmith-nodejs"]
|
|
3253
|
+
dashboard_url: "https://app.flagsmith.com"
|
|
3254
|
+
env_example: |
|
|
3255
|
+
FLAGSMITH_API_URL=https://edge.api.flagsmith.com/api/v1
|
|
3256
|
+
FLAGSMITH_ENVIRONMENT_KEY=
|
|
3257
|
+
files:
|
|
3258
|
+
test_connection.sh: |
|
|
3259
|
+
#!/usr/bin/env bash
|
|
3260
|
+
set -euo pipefail
|
|
3261
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3262
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3263
|
+
: "${FLAGSMITH_ENVIRONMENT_KEY:?FLAGSMITH_ENVIRONMENT_KEY not set}"
|
|
3264
|
+
URL="${FLAGSMITH_API_URL:-https://edge.api.flagsmith.com/api/v1}"
|
|
3265
|
+
# Fetch flags for the env (anonymous identity).
|
|
3266
|
+
curl -fsS "${URL%/}/flags/" -H "X-Environment-Key: $FLAGSMITH_ENVIRONMENT_KEY" >/dev/null
|
|
3267
|
+
echo "OK — Flagsmith environment key valid."
|
|
3268
|
+
README.md: |
|
|
3269
|
+
# FLAGSMITH
|
|
3270
|
+
Open-source feature flagging + remote config. Cloud or self-hosted.
|
|
3271
|
+
CREDENTIALS.md: |
|
|
3272
|
+
Dashboard: https://app.flagsmith.com
|
|
3273
|
+
Environment key per env (dev/staging/prod). Admin tokens for management API.
|
|
3274
|
+
|
|
3275
|
+
# ------------------------------------------------------------------
|
|
3276
|
+
# Chatops & automation
|
|
3277
|
+
# ------------------------------------------------------------------
|
|
3278
|
+
|
|
3279
|
+
- id: SLACK_WEBHOOK
|
|
3280
|
+
category: chat_webhooks
|
|
3281
|
+
detectors:
|
|
3282
|
+
imports: ["@slack/webhook", "@slack/web-api", "slack_sdk"]
|
|
3283
|
+
env_vars: ["SLACK_WEBHOOK_URL", "SLACK_BOT_TOKEN"]
|
|
3284
|
+
deps: ["@slack/webhook", "@slack/web-api", "slack-sdk"]
|
|
3285
|
+
dashboard_url: "https://api.slack.com/apps"
|
|
3286
|
+
env_example: |
|
|
3287
|
+
SLACK_WEBHOOK_URL=
|
|
3288
|
+
SLACK_BOT_TOKEN=
|
|
3289
|
+
files:
|
|
3290
|
+
test_connection.sh: |
|
|
3291
|
+
#!/usr/bin/env bash
|
|
3292
|
+
# Posts a test message — visible in the target channel.
|
|
3293
|
+
set -euo pipefail
|
|
3294
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3295
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3296
|
+
: "${SLACK_WEBHOOK_URL:?SLACK_WEBHOOK_URL not set}"
|
|
3297
|
+
curl -fsS -X POST -H "Content-Type: application/json" \
|
|
3298
|
+
--data '{"text":"harness smoke-test — ignore."}' \
|
|
3299
|
+
"$SLACK_WEBHOOK_URL" | grep -q ok
|
|
3300
|
+
echo "OK — Slack webhook posted a test message."
|
|
3301
|
+
README.md: |
|
|
3302
|
+
# SLACK_WEBHOOK
|
|
3303
|
+
Incoming webhooks + bot token for richer flows (chat.postMessage).
|
|
3304
|
+
> The smoke-test posts a visible message to the target channel.
|
|
3305
|
+
CREDENTIALS.md: |
|
|
3306
|
+
Dashboard: https://api.slack.com/apps
|
|
3307
|
+
Incoming webhook URL is per-channel. Bot tokens (xoxb-…) for Web API.
|
|
3308
|
+
|
|
3309
|
+
- id: DISCORD_WEBHOOK
|
|
3310
|
+
category: chat_webhooks
|
|
3311
|
+
detectors:
|
|
3312
|
+
imports: ["discord.js", "from discord", "import discord"]
|
|
3313
|
+
env_vars: ["DISCORD_WEBHOOK_URL", "DISCORD_BOT_TOKEN"]
|
|
3314
|
+
deps: ["discord.js", "discord.py"]
|
|
3315
|
+
dashboard_url: "https://discord.com/developers/applications"
|
|
3316
|
+
env_example: |
|
|
3317
|
+
DISCORD_WEBHOOK_URL=
|
|
3318
|
+
files:
|
|
3319
|
+
test_connection.sh: |
|
|
3320
|
+
#!/usr/bin/env bash
|
|
3321
|
+
# GET on the webhook URL returns its metadata without sending a message.
|
|
3322
|
+
set -euo pipefail
|
|
3323
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3324
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3325
|
+
: "${DISCORD_WEBHOOK_URL:?DISCORD_WEBHOOK_URL not set}"
|
|
3326
|
+
NAME=$(curl -fsS "$DISCORD_WEBHOOK_URL" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("name","?"))')
|
|
3327
|
+
echo "OK — Discord webhook: $NAME."
|
|
3328
|
+
README.md: |
|
|
3329
|
+
# DISCORD_WEBHOOK
|
|
3330
|
+
Incoming webhook for posting messages to a channel.
|
|
3331
|
+
CREDENTIALS.md: |
|
|
3332
|
+
Dashboard: https://discord.com/developers/applications
|
|
3333
|
+
Webhook URL contains an embedded token — treat as secret.
|
|
3334
|
+
|
|
3335
|
+
- id: TELEGRAM_BOT
|
|
3336
|
+
category: chat_webhooks
|
|
3337
|
+
detectors:
|
|
3338
|
+
imports: ["python-telegram-bot", "telegraf", "node-telegram-bot-api"]
|
|
3339
|
+
env_vars: ["TELEGRAM_BOT_TOKEN", "TELEGRAM_CHAT_ID"]
|
|
3340
|
+
deps: ["python-telegram-bot", "telegraf", "node-telegram-bot-api"]
|
|
3341
|
+
dashboard_url: "https://t.me/BotFather"
|
|
3342
|
+
env_example: |
|
|
3343
|
+
TELEGRAM_BOT_TOKEN=
|
|
3344
|
+
TELEGRAM_CHAT_ID=
|
|
3345
|
+
files:
|
|
3346
|
+
test_connection.sh: |
|
|
3347
|
+
#!/usr/bin/env bash
|
|
3348
|
+
set -euo pipefail
|
|
3349
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3350
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3351
|
+
: "${TELEGRAM_BOT_TOKEN:?TELEGRAM_BOT_TOKEN not set}"
|
|
3352
|
+
NAME=$(curl -fsS "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe" | python3 -c 'import json,sys; print(json.load(sys.stdin)["result"]["username"])')
|
|
3353
|
+
echo "OK — Telegram bot: @$NAME."
|
|
3354
|
+
README.md: |
|
|
3355
|
+
# TELEGRAM_BOT
|
|
3356
|
+
Create a bot with @BotFather, then drive it via the Bot API.
|
|
3357
|
+
CREDENTIALS.md: |
|
|
3358
|
+
Dashboard: https://t.me/BotFather (chat with @BotFather to create/manage bots)
|
|
3359
|
+
`TELEGRAM_BOT_TOKEN` — secret. Chat ID is the user/group to message.
|
|
3360
|
+
|
|
3361
|
+
- id: N8N
|
|
3362
|
+
category: automatizacion
|
|
3363
|
+
detectors:
|
|
3364
|
+
imports: []
|
|
3365
|
+
env_vars: ["N8N_API_KEY", "N8N_HOST"]
|
|
3366
|
+
deps: []
|
|
3367
|
+
dashboard_url: "https://app.n8n.cloud/settings/api"
|
|
3368
|
+
env_example: |
|
|
3369
|
+
N8N_HOST=
|
|
3370
|
+
N8N_API_KEY=
|
|
3371
|
+
files:
|
|
3372
|
+
test_connection.sh: |
|
|
3373
|
+
#!/usr/bin/env bash
|
|
3374
|
+
set -euo pipefail
|
|
3375
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
3376
|
+
set -a; source "$SCRIPT_DIR/.env"; set +a
|
|
3377
|
+
: "${N8N_HOST:?N8N_HOST not set}"
|
|
3378
|
+
: "${N8N_API_KEY:?N8N_API_KEY not set}"
|
|
3379
|
+
N=$(curl -fsS "${N8N_HOST%/}/api/v1/workflows?limit=1" -H "X-N8N-API-KEY: $N8N_API_KEY" | python3 -c 'import json,sys; print(len(json.load(sys.stdin)["data"]))')
|
|
3380
|
+
echo "OK — n8n workflows endpoint accessible (sample: $N)."
|
|
3381
|
+
README.md: |
|
|
3382
|
+
# N8N
|
|
3383
|
+
Open-source workflow automation. Self-hosted or n8n Cloud.
|
|
3384
|
+
CREDENTIALS.md: |
|
|
3385
|
+
Dashboard: https://app.n8n.cloud/settings/api (or self-hosted equivalent).
|
|
3386
|
+
`N8N_API_KEY` — secret. Required for all REST API calls.
|
|
3387
|
+
|
|
3388
|
+
# Categories used to group tools in 01-TOOLS/README.md.
|
|
3389
|
+
categories:
|
|
3390
|
+
infra: "Infra & deploy"
|
|
3391
|
+
datos: "Databases & BaaS"
|
|
3392
|
+
almacenamiento: "Object storage"
|
|
3393
|
+
pagos: "Payments & billing"
|
|
3394
|
+
email: "Email (transactional)"
|
|
3395
|
+
pagos_email: "Email (transactional, legacy bucket)"
|
|
3396
|
+
mobile_auth: "Mobile / auth"
|
|
3397
|
+
auth: "Auth & identity"
|
|
3398
|
+
ia: "AI / generation (legacy bucket)"
|
|
3399
|
+
ia_texto: "AI / LLMs"
|
|
3400
|
+
ia_media: "AI / audio, image, video"
|
|
3401
|
+
busqueda: "Search & vector databases"
|
|
3402
|
+
observabilidad: "Observability"
|
|
3403
|
+
analitica: "Product analytics"
|
|
3404
|
+
comunicacion: "Communications (SMS, push, voice)"
|
|
3405
|
+
realtime: "Realtime & video"
|
|
3406
|
+
mapas_geo: "Maps & geolocation"
|
|
3407
|
+
productividad: "Productivity / PM / CRM"
|
|
3408
|
+
feature_flags: "Feature flags"
|
|
3409
|
+
chat_webhooks: "Chatops webhooks"
|
|
3410
|
+
automatizacion: "Automation"
|