@dsalazardev/ai-hub-cli 0.0.0-stage → 0.2.0
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/NOTICE.md +34 -0
- package/README.md +64 -2
- package/agents/cpp-build-resolver.md +25 -0
- package/agents/cpp-reviewer.md +28 -0
- package/agents/csharp-reviewer.md +28 -0
- package/agents/django-build-resolver.md +25 -0
- package/agents/django-reviewer.md +28 -0
- package/agents/explorer-domain.md +28 -0
- package/agents/fastapi-reviewer.md +28 -0
- package/agents/flutter-build-resolver.md +25 -0
- package/agents/flutter-reviewer.md +28 -0
- package/agents/go-build-resolver.md +25 -0
- package/agents/go-reviewer.md +28 -0
- package/agents/implementer-backend.md +30 -0
- package/agents/implementer-frontend.md +30 -0
- package/agents/java-build-resolver.md +26 -0
- package/agents/java-reviewer.md +29 -0
- package/agents/kotlin-build-resolver.md +25 -0
- package/agents/kotlin-reviewer.md +28 -0
- package/agents/mle-reviewer.md +28 -0
- package/agents/php-reviewer.md +29 -0
- package/agents/postgres-reviewer.md +28 -0
- package/agents/python-reviewer.md +28 -0
- package/agents/pytorch-build-resolver.md +25 -0
- package/agents/rag-reviewer.md +28 -0
- package/agents/react-build-resolver.md +26 -0
- package/agents/react-reviewer.md +29 -0
- package/agents/reviewer-architecture.md +32 -0
- package/agents/reviewer-tests.md +31 -0
- package/agents/rust-build-resolver.md +25 -0
- package/agents/rust-reviewer.md +28 -0
- package/agents/spec-author.md +36 -0
- package/agents/spec-miner.md +14 -0
- package/agents/swift-build-resolver.md +25 -0
- package/agents/swift-reviewer.md +28 -0
- package/agents/typescript-reviewer.md +28 -0
- package/agents/vue-reviewer.md +28 -0
- package/dist/backup/snapshots.d.ts +24 -0
- package/dist/backup/snapshots.js +171 -0
- package/dist/bin/ai-hub.d.ts +2 -0
- package/dist/bin/ai-hub.js +11 -0
- package/dist/catalog.d.ts +76 -0
- package/dist/catalog.js +321 -0
- package/dist/cli/args.d.ts +4 -0
- package/dist/cli/args.js +63 -0
- package/dist/cli/context.d.ts +7 -0
- package/dist/cli/context.js +79 -0
- package/dist/cli/doctor.d.ts +14 -0
- package/dist/cli/doctor.js +282 -0
- package/dist/cli/drift.d.ts +2 -0
- package/dist/cli/drift.js +34 -0
- package/dist/cli/items.d.ts +5 -0
- package/dist/cli/items.js +10 -0
- package/dist/cli/legacy.d.ts +3 -0
- package/dist/cli/legacy.js +18 -0
- package/dist/cli/maintenance.d.ts +8 -0
- package/dist/cli/maintenance.js +334 -0
- package/dist/cli/memory.d.ts +2 -0
- package/dist/cli/memory.js +89 -0
- package/dist/cli/onboarding.d.ts +36 -0
- package/dist/cli/onboarding.js +516 -0
- package/dist/cli/run.d.ts +15 -0
- package/dist/cli/run.js +185 -0
- package/dist/cli/source.d.ts +5 -0
- package/dist/cli/source.js +22 -0
- package/dist/cli/trunk.d.ts +8 -0
- package/dist/cli/trunk.js +54 -0
- package/dist/cli/types.d.ts +17 -0
- package/dist/cli/types.js +4 -0
- package/dist/cli/worktrees.d.ts +11 -0
- package/dist/cli/worktrees.js +141 -0
- package/dist/concurrency.d.ts +5 -0
- package/dist/concurrency.js +23 -0
- package/dist/engine/engine.d.ts +48 -0
- package/dist/engine/engine.js +114 -0
- package/dist/engine/gates.d.ts +2 -0
- package/dist/engine/gates.js +131 -0
- package/dist/frontmatter.d.ts +11 -0
- package/dist/frontmatter.js +30 -0
- package/dist/harness/guards/adapters/context.d.ts +19 -0
- package/dist/harness/guards/adapters/context.js +153 -0
- package/dist/harness/guards/adapters/hermes.d.ts +13 -0
- package/dist/harness/guards/adapters/hermes.js +18 -0
- package/dist/harness/guards/adapters/hooks.d.ts +25 -0
- package/dist/harness/guards/adapters/hooks.js +52 -0
- package/dist/harness/guards/branch.d.ts +5 -0
- package/dist/harness/guards/branch.js +43 -0
- package/dist/harness/guards/danger.d.ts +13 -0
- package/dist/harness/guards/danger.js +157 -0
- package/dist/harness/guards/index.d.ts +6 -0
- package/dist/harness/guards/index.js +6 -0
- package/dist/harness/guards/preflight.d.ts +14 -0
- package/dist/harness/guards/preflight.js +37 -0
- package/dist/harness/guards/ship.d.ts +2 -0
- package/dist/harness/guards/ship.js +35 -0
- package/dist/harness/guards/trunk.d.ts +5 -0
- package/dist/harness/guards/trunk.js +41 -0
- package/dist/harness/guards/types.d.ts +50 -0
- package/dist/harness/guards/types.js +1 -0
- package/dist/harness/memory/ledger.d.ts +53 -0
- package/dist/harness/memory/ledger.js +136 -0
- package/dist/harness/memory/state.d.ts +35 -0
- package/dist/harness/memory/state.js +121 -0
- package/dist/harness/worktree/reaper.d.ts +32 -0
- package/dist/harness/worktree/reaper.js +54 -0
- package/dist/manifest/build.d.ts +1 -0
- package/dist/manifest/build.js +1 -0
- package/dist/manifest/cli.d.ts +2 -0
- package/dist/manifest/cli.js +44 -0
- package/dist/manifest/dispatch.d.ts +13 -0
- package/dist/manifest/dispatch.js +36 -0
- package/dist/manifest/labels.d.ts +15 -0
- package/dist/manifest/labels.js +70 -0
- package/dist/manifest/manifest.d.ts +130 -0
- package/dist/manifest/manifest.js +220 -0
- package/dist/package-info.d.ts +4 -0
- package/dist/package-info.js +7 -0
- package/dist/paths.d.ts +33 -0
- package/dist/paths.js +123 -0
- package/dist/presets/detect.d.ts +24 -0
- package/dist/presets/detect.js +116 -0
- package/dist/presets/materialize.d.ts +26 -0
- package/dist/presets/materialize.js +192 -0
- package/dist/presets/resolve.d.ts +37 -0
- package/dist/presets/resolve.js +83 -0
- package/dist/presets/schema.d.ts +57 -0
- package/dist/presets/schema.js +68 -0
- package/dist/source-checkout.d.ts +8 -0
- package/dist/source-checkout.js +19 -0
- package/dist/sync/config.d.ts +47 -0
- package/dist/sync/config.js +85 -0
- package/dist/sync/lock.d.ts +16 -0
- package/dist/sync/lock.js +43 -0
- package/dist/sync/render.d.ts +18 -0
- package/dist/sync/render.js +259 -0
- package/dist/sync/sync.d.ts +38 -0
- package/dist/sync/sync.js +288 -0
- package/dist/sync/targets.d.ts +24 -0
- package/dist/sync/targets.js +78 -0
- package/engine/coupling.json +4 -0
- package/engine/engine.yaml +250 -0
- package/engine/legacy-paths.json +4 -0
- package/engine/preflight.md +11 -0
- package/manifest.json +402 -0
- package/package.json +62 -4
- package/presets/angular-express/harness/rules/01-zero-any.sh +25 -0
- package/presets/angular-express/harness/rules/02-no-ng-module.sh +21 -0
- package/presets/angular-express/harness/rules/03-no-constructor-injection.sh +21 -0
- package/presets/angular-express/harness/rules/04-no-legacy-directives.sh +21 -0
- package/presets/angular-express/harness/rules/05-no-dolibarrdal-inheritance.sh +25 -0
- package/presets/angular-express/harness/rules/06-no-todos.sh +22 -0
- package/presets/angular-express/harness/run-all.sh +13 -0
- package/presets/angular-express/preset.yaml +53 -0
- package/presets/angular-express/references/common-imports-catalog.md +146 -0
- package/presets/angular-express/references/fichajes-migration-notes.md +57 -0
- package/presets/angular-express/references/module-implementation-flow.md +260 -0
- package/presets/angular-express/references/products-coding-standard.md +143 -0
- package/presets/angular-express/references/products-module-blueprint.md +860 -0
- package/presets/angular-express/references/replicate-module-checklist.md +72 -0
- package/presets/angular-express/references/users-migration-notes.md +172 -0
- package/presets/angular-express/rules/architecture.md +8 -0
- package/presets/angular-express/rules/backend.md +4 -0
- package/presets/angular-express/rules/frontend.md +53 -0
- package/presets/angular-express/skills/angular-developer/SKILL.md +130 -0
- package/presets/angular-express/skills/angular-developer/references/angular-animations.md +160 -0
- package/presets/angular-express/skills/angular-developer/references/angular-aria.md +410 -0
- package/presets/angular-express/skills/angular-developer/references/cli.md +86 -0
- package/presets/angular-express/skills/angular-developer/references/component-harnesses.md +59 -0
- package/presets/angular-express/skills/angular-developer/references/component-styling.md +91 -0
- package/presets/angular-express/skills/angular-developer/references/components.md +117 -0
- package/presets/angular-express/skills/angular-developer/references/creating-services.md +97 -0
- package/presets/angular-express/skills/angular-developer/references/data-resolvers.md +69 -0
- package/presets/angular-express/skills/angular-developer/references/define-routes.md +67 -0
- package/presets/angular-express/skills/angular-developer/references/defining-providers.md +72 -0
- package/presets/angular-express/skills/angular-developer/references/di-fundamentals.md +120 -0
- package/presets/angular-express/skills/angular-developer/references/e2e-testing.md +66 -0
- package/presets/angular-express/skills/angular-developer/references/effects.md +83 -0
- package/presets/angular-express/skills/angular-developer/references/hierarchical-injectors.md +43 -0
- package/presets/angular-express/skills/angular-developer/references/host-elements.md +80 -0
- package/presets/angular-express/skills/angular-developer/references/injection-context.md +63 -0
- package/presets/angular-express/skills/angular-developer/references/inputs.md +101 -0
- package/presets/angular-express/skills/angular-developer/references/linked-signal.md +59 -0
- package/presets/angular-express/skills/angular-developer/references/loading-strategies.md +61 -0
- package/presets/angular-express/skills/angular-developer/references/mcp.md +106 -0
- package/presets/angular-express/skills/angular-developer/references/migrations.md +30 -0
- package/presets/angular-express/skills/angular-developer/references/navigate-to-routes.md +69 -0
- package/presets/angular-express/skills/angular-developer/references/outputs.md +86 -0
- package/presets/angular-express/skills/angular-developer/references/reactive-forms.md +122 -0
- package/presets/angular-express/skills/angular-developer/references/rendering-strategies.md +44 -0
- package/presets/angular-express/skills/angular-developer/references/resource.md +74 -0
- package/presets/angular-express/skills/angular-developer/references/route-animations.md +56 -0
- package/presets/angular-express/skills/angular-developer/references/route-guards.md +52 -0
- package/presets/angular-express/skills/angular-developer/references/router-lifecycle.md +45 -0
- package/presets/angular-express/skills/angular-developer/references/router-testing.md +87 -0
- package/presets/angular-express/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
- package/presets/angular-express/skills/angular-developer/references/signal-forms.md +897 -0
- package/presets/angular-express/skills/angular-developer/references/signals-overview.md +94 -0
- package/presets/angular-express/skills/angular-developer/references/tailwind-css.md +69 -0
- package/presets/angular-express/skills/angular-developer/references/template-driven-forms.md +114 -0
- package/presets/angular-express/skills/angular-developer/references/testing-fundamentals.md +66 -0
- package/presets/angular-express/skills/angular-new-app/SKILL.md +62 -0
- package/presets/angular-express/skills/frontend-design/LICENSE.txt +177 -0
- package/presets/angular-express/skills/frontend-design/SKILL.md +55 -0
- package/presets/angular-express/skills/onna-architecture-angular/SKILL.md +229 -0
- package/presets/angular-express/skills/onna-architecture-bff/SKILL.md +446 -0
- package/presets/angular-express/skills/onna-architecture-common/SKILL.md +313 -0
- package/presets/angular-express/skills/onna-design-system/SKILL.md +615 -0
- package/presets/base/preset.yaml +25 -0
- package/presets/base/rules/core.md +35 -0
- package/presets/generic-ts/preset.yaml +44 -0
- package/presets/python/preset.yaml +45 -0
- package/presets/python/rules/python.md +10 -0
- package/rules/skill-quality/skill-behavior-rubric.md +63 -0
- package/rules/skill-quality/skill-harden-rubric.md +102 -0
- package/rules/skill-quality/skill-migration-brief.md +200 -0
- package/rules/skill-quality/skill-rubric.md +40 -0
- package/schema/engine.schema.json +73 -0
- package/schema/manifest.schema.json +152 -0
- package/schema/preset.schema.json +98 -0
- package/schema/state.schema.json +27 -0
- package/skills/shared/ab-testing/SKILL.md +159 -0
- package/skills/shared/ab-testing/evals/README.md +8 -0
- package/skills/shared/ab-testing/evals/cases.yaml +49 -0
- package/skills/shared/ab-testing/references/pitfalls.md +74 -0
- package/skills/shared/ab-testing/references/sample-size-and-cuped.md +128 -0
- package/skills/shared/ab-testing/scripts/verify.sh +89 -0
- package/skills/shared/accessibility/SKILL.md +216 -0
- package/skills/shared/accessibility/evals/README.md +3 -0
- package/skills/shared/accessibility/evals/cases.yaml +47 -0
- package/skills/shared/accessibility/references/aria-patterns.md +113 -0
- package/skills/shared/accessibility/references/wcag22-checklist.md +83 -0
- package/skills/shared/accessibility/scripts/verify.sh +103 -0
- package/skills/shared/agent-eval/SKILL.md +187 -0
- package/skills/shared/agent-eval/evals/README.md +12 -0
- package/skills/shared/agent-eval/evals/cases.yaml +45 -0
- package/skills/shared/agent-eval/references/judge-design.md +118 -0
- package/skills/shared/agent-eval/references/runner-and-gate.md +183 -0
- package/skills/shared/agent-eval/scripts/verify.sh +161 -0
- package/skills/shared/agent-safety/SKILL.md +169 -0
- package/skills/shared/agent-safety/evals/README.md +12 -0
- package/skills/shared/agent-safety/evals/cases.yaml +46 -0
- package/skills/shared/agent-safety/references/threat-model.md +51 -0
- package/skills/shared/analyze/SKILL.md +123 -0
- package/skills/shared/analyze/evals/README.md +72 -0
- package/skills/shared/analyze/evals/cases.yaml +74 -0
- package/skills/shared/angular/SKILL.md +275 -0
- package/skills/shared/angular/evals/README.md +3 -0
- package/skills/shared/angular/evals/cases.yaml +38 -0
- package/skills/shared/angular/references/migration.md +81 -0
- package/skills/shared/angular/references/signals-rxjs.md +92 -0
- package/skills/shared/angular/scripts/verify.sh +122 -0
- package/skills/shared/api-connector-builder/SKILL.md +268 -0
- package/skills/shared/api-connector-builder/evals/README.md +11 -0
- package/skills/shared/api-connector-builder/evals/cases.yaml +47 -0
- package/skills/shared/api-connector-builder/references/auth-flows.md +132 -0
- package/skills/shared/api-connector-builder/references/pagination.md +144 -0
- package/skills/shared/api-connector-builder/scripts/verify.sh +172 -0
- package/skills/shared/api-design/SKILL.md +182 -0
- package/skills/shared/api-design/evals/README.md +3 -0
- package/skills/shared/api-design/evals/cases.yaml +45 -0
- package/skills/shared/api-design/references/graphql-design.md +70 -0
- package/skills/shared/api-design/references/openapi-contract.md +86 -0
- package/skills/shared/api-design/references/rest-conventions.md +63 -0
- package/skills/shared/api-design/references/versioning-and-evolution.md +49 -0
- package/skills/shared/api-design/scripts/verify.sh +138 -0
- package/skills/shared/astro/SKILL.md +257 -0
- package/skills/shared/astro/evals/README.md +3 -0
- package/skills/shared/astro/evals/cases.yaml +41 -0
- package/skills/shared/astro/references/content-layer.md +118 -0
- package/skills/shared/astro/references/deploy-and-integrations.md +163 -0
- package/skills/shared/astro/scripts/verify.sh +137 -0
- package/skills/shared/author-skill/SKILL.md +194 -0
- package/skills/shared/author-skill/evals/README.md +66 -0
- package/skills/shared/author-skill/evals/cases.yaml +75 -0
- package/skills/shared/author-skill/references/description-recipe.md +85 -0
- package/skills/shared/author-skill/references/eval-authoring.md +108 -0
- package/skills/shared/author-skill/references/skill-conventions.md +95 -0
- package/skills/shared/automation-flows/SKILL.md +122 -0
- package/skills/shared/automation-flows/evals/README.md +5 -0
- package/skills/shared/automation-flows/evals/cases.yaml +44 -0
- package/skills/shared/automation-flows/references/error-handling.md +58 -0
- package/skills/shared/automation-flows/references/n8n-workflow-json.md +63 -0
- package/skills/shared/automation-flows/scripts/verify.sh +78 -0
- package/skills/shared/aws-essentials/SKILL.md +206 -0
- package/skills/shared/aws-essentials/evals/README.md +10 -0
- package/skills/shared/aws-essentials/evals/cases.yaml +44 -0
- package/skills/shared/aws-essentials/references/iam-least-privilege.md +134 -0
- package/skills/shared/aws-essentials/references/rds-cloudfront-recipes.md +127 -0
- package/skills/shared/aws-essentials/scripts/verify.sh +99 -0
- package/skills/shared/backups/SKILL.md +131 -0
- package/skills/shared/backups/evals/README.md +3 -0
- package/skills/shared/backups/evals/cases.yaml +42 -0
- package/skills/shared/backups/references/engine-recipes.md +121 -0
- package/skills/shared/backups/references/restore-runbook.md +65 -0
- package/skills/shared/backups/scripts/verify.sh +80 -0
- package/skills/shared/bash-scripting/SKILL.md +227 -0
- package/skills/shared/bash-scripting/evals/README.md +3 -0
- package/skills/shared/bash-scripting/evals/cases.yaml +45 -0
- package/skills/shared/bash-scripting/references/portability.md +97 -0
- package/skills/shared/bash-scripting/scripts/verify.sh +140 -0
- package/skills/shared/building-agents/SKILL.md +386 -0
- package/skills/shared/building-agents/evals/README.md +68 -0
- package/skills/shared/building-agents/evals/cases.yaml +60 -0
- package/skills/shared/building-agents/references/agent-loops-and-harness.md +371 -0
- package/skills/shared/building-agents/references/evals-and-observability.md +420 -0
- package/skills/shared/building-agents/references/mcp-servers.md +294 -0
- package/skills/shared/building-agents/references/provider-abstraction.md +489 -0
- package/skills/shared/building-agents/references/tools-and-rag.md +417 -0
- package/skills/shared/building-agents/scripts/verify.sh +121 -0
- package/skills/shared/chatbot/SKILL.md +151 -0
- package/skills/shared/chatbot/evals/README.md +13 -0
- package/skills/shared/chatbot/evals/cases.yaml +43 -0
- package/skills/shared/chatbot/references/handoff-and-sales.md +71 -0
- package/skills/shared/chatbot/references/system-prompt-and-guardrails.md +78 -0
- package/skills/shared/chatbot/scripts/verify.sh +162 -0
- package/skills/shared/chrome-extension/SKILL.md +169 -0
- package/skills/shared/chrome-extension/evals/README.md +12 -0
- package/skills/shared/chrome-extension/evals/cases.yaml +40 -0
- package/skills/shared/chrome-extension/references/store-and-migration.md +84 -0
- package/skills/shared/chrome-extension/scripts/verify.sh +62 -0
- package/skills/shared/clarify/SKILL.md +161 -0
- package/skills/shared/clarify/evals/README.md +70 -0
- package/skills/shared/clarify/evals/cases.yaml +71 -0
- package/skills/shared/clickhouse-analytics/SKILL.md +159 -0
- package/skills/shared/clickhouse-analytics/evals/README.md +3 -0
- package/skills/shared/clickhouse-analytics/evals/cases.yaml +45 -0
- package/skills/shared/clickhouse-analytics/references/ingestion-and-mvs.md +109 -0
- package/skills/shared/clickhouse-analytics/references/query-optimization.md +76 -0
- package/skills/shared/clickhouse-analytics/references/schema-and-engines.md +63 -0
- package/skills/shared/clickhouse-analytics/scripts/verify.sh +109 -0
- package/skills/shared/cloudflare/SKILL.md +186 -0
- package/skills/shared/cloudflare/evals/README.md +15 -0
- package/skills/shared/cloudflare/evals/cases.yaml +46 -0
- package/skills/shared/cloudflare/references/storage-primitives.md +104 -0
- package/skills/shared/cloudflare/references/wrangler-config.md +91 -0
- package/skills/shared/cloudflare/scripts/verify.sh +133 -0
- package/skills/shared/code-review/SKILL.md +132 -0
- package/skills/shared/code-review/evals/README.md +3 -0
- package/skills/shared/code-review/evals/cases.yaml +55 -0
- package/skills/shared/code-review/references/pr-workflow.md +67 -0
- package/skills/shared/codebase-onboarding/SKILL.md +128 -0
- package/skills/shared/codebase-onboarding/evals/README.md +3 -0
- package/skills/shared/codebase-onboarding/evals/cases.yaml +69 -0
- package/skills/shared/codebase-onboarding/references/recon-playbook.md +57 -0
- package/skills/shared/codebase-onboarding/scripts/verify.sh +54 -0
- package/skills/shared/compose-multiplatform/SKILL.md +198 -0
- package/skills/shared/compose-multiplatform/evals/README.md +3 -0
- package/skills/shared/compose-multiplatform/evals/cases.yaml +40 -0
- package/skills/shared/compose-multiplatform/references/ios-interop.md +91 -0
- package/skills/shared/compose-multiplatform/references/project-setup.md +96 -0
- package/skills/shared/compose-multiplatform/scripts/verify.sh +123 -0
- package/skills/shared/connect-tool/SKILL.md +163 -0
- package/skills/shared/connect-tool/evals/cases.yaml +58 -0
- package/skills/shared/constitution/SKILL.md +158 -0
- package/skills/shared/constitution/evals/README.md +68 -0
- package/skills/shared/constitution/evals/cases.yaml +72 -0
- package/skills/shared/constitution/references/constitution-template.md +100 -0
- package/skills/shared/context-budget/SKILL.md +114 -0
- package/skills/shared/context-budget/evals/README.md +11 -0
- package/skills/shared/context-budget/evals/cases.yaml +40 -0
- package/skills/shared/context-budget/references/handoff-and-compaction.md +96 -0
- package/skills/shared/continuous-learning/SKILL.md +106 -0
- package/skills/shared/continuous-learning/evals/README.md +16 -0
- package/skills/shared/continuous-learning/evals/cases.yaml +39 -0
- package/skills/shared/continuous-learning/references/lesson-routing.md +106 -0
- package/skills/shared/coolify/SKILL.md +194 -0
- package/skills/shared/coolify/evals/README.md +21 -0
- package/skills/shared/coolify/evals/cases.yaml +46 -0
- package/skills/shared/coolify/references/databases-and-backups.md +99 -0
- package/skills/shared/coolify/references/deploy-recipes.md +105 -0
- package/skills/shared/coolify/references/install-and-proxy.md +80 -0
- package/skills/shared/coolify/scripts/verify.sh +123 -0
- package/skills/shared/cost-tracking/SKILL.md +176 -0
- package/skills/shared/cost-tracking/evals/README.md +3 -0
- package/skills/shared/cost-tracking/evals/cases.yaml +45 -0
- package/skills/shared/cost-tracking/references/cloud-caps.md +52 -0
- package/skills/shared/cost-tracking/references/pricing-tables.md +51 -0
- package/skills/shared/cost-tracking/scripts/verify.sh +135 -0
- package/skills/shared/cpp/SKILL.md +302 -0
- package/skills/shared/cpp/evals/README.md +14 -0
- package/skills/shared/cpp/evals/cases.yaml +44 -0
- package/skills/shared/cpp/references/cmake.md +167 -0
- package/skills/shared/cpp/references/move-and-templates.md +130 -0
- package/skills/shared/cpp/references/undefined-behavior.md +86 -0
- package/skills/shared/cpp/scripts/verify.sh +165 -0
- package/skills/shared/csharp-dotnet/SKILL.md +272 -0
- package/skills/shared/csharp-dotnet/evals/README.md +3 -0
- package/skills/shared/csharp-dotnet/evals/cases.yaml +48 -0
- package/skills/shared/csharp-dotnet/references/aspnetcore.md +99 -0
- package/skills/shared/csharp-dotnet/references/async.md +82 -0
- package/skills/shared/csharp-dotnet/references/efcore.md +96 -0
- package/skills/shared/csharp-dotnet/scripts/verify.sh +90 -0
- package/skills/shared/data-cleaning/SKILL.md +259 -0
- package/skills/shared/data-cleaning/evals/README.md +16 -0
- package/skills/shared/data-cleaning/evals/cases.yaml +57 -0
- package/skills/shared/data-cleaning/references/normalization-recipes.md +136 -0
- package/skills/shared/data-cleaning/references/validation-patterns.md +134 -0
- package/skills/shared/data-cleaning/scripts/verify.sh +115 -0
- package/skills/shared/data-scraper/SKILL.md +130 -0
- package/skills/shared/data-scraper/evals/README.md +3 -0
- package/skills/shared/data-scraper/evals/cases.yaml +46 -0
- package/skills/shared/data-scraper/references/anti-bot.md +85 -0
- package/skills/shared/data-scraper/references/frameworks.md +116 -0
- package/skills/shared/data-scraper/references/legal-compliance.md +64 -0
- package/skills/shared/data-scraper/scripts/verify.sh +166 -0
- package/skills/shared/db-migrations/SKILL.md +237 -0
- package/skills/shared/db-migrations/evals/README.md +10 -0
- package/skills/shared/db-migrations/evals/cases.yaml +46 -0
- package/skills/shared/db-migrations/references/backfill-and-batching.md +105 -0
- package/skills/shared/db-migrations/references/expand-contract-playbook.md +152 -0
- package/skills/shared/db-migrations/references/tools-and-runners.md +88 -0
- package/skills/shared/db-migrations/scripts/verify.sh +112 -0
- package/skills/shared/debug/SKILL.md +188 -0
- package/skills/shared/debug/evals/README.md +88 -0
- package/skills/shared/debug/evals/cases.yaml +74 -0
- package/skills/shared/decision-challenge/SKILL.md +113 -0
- package/skills/shared/decision-challenge/evals/README.md +3 -0
- package/skills/shared/decision-challenge/evals/cases.yaml +42 -0
- package/skills/shared/decision-records/SKILL.md +202 -0
- package/skills/shared/decision-records/evals/README.md +3 -0
- package/skills/shared/decision-records/evals/cases.yaml +43 -0
- package/skills/shared/decision-records/references/templates.md +252 -0
- package/skills/shared/decision-records/scripts/verify.sh +105 -0
- package/skills/shared/deep-learning/SKILL.md +226 -0
- package/skills/shared/deep-learning/evals/README.md +11 -0
- package/skills/shared/deep-learning/evals/cases.yaml +48 -0
- package/skills/shared/deep-learning/references/distributed.md +105 -0
- package/skills/shared/deep-learning/references/training-recipes.md +135 -0
- package/skills/shared/deployment/SKILL.md +374 -0
- package/skills/shared/deployment/evals/README.md +50 -0
- package/skills/shared/deployment/evals/cases.yaml +53 -0
- package/skills/shared/deployment/references/coolify.md +216 -0
- package/skills/shared/deployment/references/dockerfiles-by-stack.md +319 -0
- package/skills/shared/deployment/references/github-actions.md +295 -0
- package/skills/shared/deployment/references/hosting-targets.md +272 -0
- package/skills/shared/deployment/scripts/verify.sh +134 -0
- package/skills/shared/deprecation/SKILL.md +123 -0
- package/skills/shared/deprecation/evals/README.md +3 -0
- package/skills/shared/deprecation/evals/cases.yaml +42 -0
- package/skills/shared/design/IMPECCABLE-LICENSE.txt +191 -0
- package/skills/shared/design/SKILL.md +111 -0
- package/skills/shared/design/THIRD_PARTY.md +26 -0
- package/skills/shared/design/engine/LICENSE +21 -0
- package/skills/shared/design/engine/RUN.md +515 -0
- package/skills/shared/design/engine/UPSTREAM.json +4 -0
- package/skills/shared/design/engine/assets/app.css +216 -0
- package/skills/shared/design/engine/assets/base.css +105 -0
- package/skills/shared/design/engine/assets/base.js +37 -0
- package/skills/shared/design/engine/assets/charts.js +617 -0
- package/skills/shared/design/engine/assets/scenes/stage.css +28 -0
- package/skills/shared/design/engine/assets/scenes/stage.js +133 -0
- package/skills/shared/design/engine/library/app.json +1327 -0
- package/skills/shared/design/engine/library/directions.json +1078 -0
- package/skills/shared/design/engine/library/heroes.json +1086 -0
- package/skills/shared/design/engine/library/motions.json +92 -0
- package/skills/shared/design/engine/library/palettes.json +1485 -0
- package/skills/shared/design/engine/library/photos.json +7240 -0
- package/skills/shared/design/engine/library/sections.json +4429 -0
- package/skills/shared/design/engine/library/sites.json +8350 -0
- package/skills/shared/design/engine/library/type.json +2024 -0
- package/skills/shared/design/engine/references/app-screens.md +1199 -0
- package/skills/shared/design/engine/references/colour.md +141 -0
- package/skills/shared/design/engine/references/copy.md +177 -0
- package/skills/shared/design/engine/references/critique.md +182 -0
- package/skills/shared/design/engine/references/imagery.md +791 -0
- package/skills/shared/design/engine/references/layout.md +292 -0
- package/skills/shared/design/engine/references/motion.md +980 -0
- package/skills/shared/design/engine/references/research.md +356 -0
- package/skills/shared/design/engine/references/scenes.md +174 -0
- package/skills/shared/design/engine/references/tells.md +115 -0
- package/skills/shared/design/engine/references/type.md +170 -0
- package/skills/shared/design/engine/scripts/assets.mjs +865 -0
- package/skills/shared/design/engine/scripts/draw.mjs +584 -0
- package/skills/shared/design/engine/scripts/inspect.mjs +303 -0
- package/skills/shared/design/engine/scripts/lib/app-draw.mjs +203 -0
- package/skills/shared/design/engine/scripts/lib/cdp.mjs +248 -0
- package/skills/shared/design/engine/scripts/lib/probe.mjs +909 -0
- package/skills/shared/design/engine/scripts/lib/rules.mjs +243 -0
- package/skills/shared/design/engine/scripts/lint.mjs +119 -0
- package/skills/shared/design/engine/scripts/scenes.mjs +124 -0
- package/skills/shared/design/evals/cases.yaml +45 -0
- package/skills/shared/design/references/design-md.md +49 -0
- package/skills/shared/design/references/finish-review.md +46 -0
- package/skills/shared/design/references/modes.md +51 -0
- package/skills/shared/digitalocean/SKILL.md +227 -0
- package/skills/shared/digitalocean/evals/README.md +10 -0
- package/skills/shared/digitalocean/evals/cases.yaml +37 -0
- package/skills/shared/digitalocean/references/app-spec.md +126 -0
- package/skills/shared/digitalocean/references/droplet-ops.md +95 -0
- package/skills/shared/digitalocean/scripts/verify.sh +102 -0
- package/skills/shared/django/SKILL.md +263 -0
- package/skills/shared/django/evals/README.md +11 -0
- package/skills/shared/django/evals/cases.yaml +47 -0
- package/skills/shared/django/references/drf.md +109 -0
- package/skills/shared/django/references/orm-performance.md +91 -0
- package/skills/shared/django/references/security.md +81 -0
- package/skills/shared/django/references/testing.md +86 -0
- package/skills/shared/django/scripts/verify.sh +115 -0
- package/skills/shared/docker/SKILL.md +251 -0
- package/skills/shared/docker/evals/README.md +10 -0
- package/skills/shared/docker/evals/cases.yaml +44 -0
- package/skills/shared/docker/references/base-images-and-stages.md +104 -0
- package/skills/shared/docker/references/compose-recipes.md +109 -0
- package/skills/shared/docker/scripts/verify.sh +149 -0
- package/skills/shared/domains-dns/SKILL.md +131 -0
- package/skills/shared/domains-dns/evals/README.md +16 -0
- package/skills/shared/domains-dns/evals/cases.yaml +47 -0
- package/skills/shared/domains-dns/references/record-cookbook.md +94 -0
- package/skills/shared/domains-dns/references/tls-and-acme.md +90 -0
- package/skills/shared/domains-dns/references/verify-and-debug.md +64 -0
- package/skills/shared/domains-dns/scripts/verify.sh +163 -0
- package/skills/shared/drizzle-orm/SKILL.md +231 -0
- package/skills/shared/drizzle-orm/evals/README.md +12 -0
- package/skills/shared/drizzle-orm/evals/cases.yaml +47 -0
- package/skills/shared/drizzle-orm/references/relations-and-drivers.md +118 -0
- package/skills/shared/drizzle-orm/scripts/verify.sh +155 -0
- package/skills/shared/duckdb/SKILL.md +202 -0
- package/skills/shared/duckdb/evals/README.md +31 -0
- package/skills/shared/duckdb/evals/cases.yaml +41 -0
- package/skills/shared/duckdb/references/python-and-interop.md +105 -0
- package/skills/shared/duckdb/references/remote-and-lakehouse.md +101 -0
- package/skills/shared/duckdb/scripts/verify.sh +71 -0
- package/skills/shared/dynamodb/SKILL.md +204 -0
- package/skills/shared/dynamodb/evals/README.md +8 -0
- package/skills/shared/dynamodb/evals/cases.yaml +46 -0
- package/skills/shared/dynamodb/references/access-patterns.md +127 -0
- package/skills/shared/dynamodb/references/capacity-and-limits.md +78 -0
- package/skills/shared/dynamodb/scripts/verify.sh +108 -0
- package/skills/shared/e2e-testing/SKILL.md +233 -0
- package/skills/shared/e2e-testing/evals/README.md +10 -0
- package/skills/shared/e2e-testing/evals/cases.yaml +64 -0
- package/skills/shared/e2e-testing/references/config-and-ci.md +156 -0
- package/skills/shared/e2e-testing/references/flakiness-playbook.md +124 -0
- package/skills/shared/e2e-testing/scripts/verify.sh +117 -0
- package/skills/shared/electron/SKILL.md +209 -0
- package/skills/shared/electron/evals/README.md +13 -0
- package/skills/shared/electron/evals/cases.yaml +38 -0
- package/skills/shared/electron/references/packaging-and-updates.md +122 -0
- package/skills/shared/electron/references/security-and-ipc.md +158 -0
- package/skills/shared/electron/scripts/verify.sh +143 -0
- package/skills/shared/elixir/SKILL.md +209 -0
- package/skills/shared/elixir/evals/README.md +3 -0
- package/skills/shared/elixir/evals/cases.yaml +41 -0
- package/skills/shared/elixir/references/mix-and-releases.md +91 -0
- package/skills/shared/elixir/references/otp-patterns.md +96 -0
- package/skills/shared/elixir/scripts/verify.sh +76 -0
- package/skills/shared/email-deliverability/SKILL.md +148 -0
- package/skills/shared/email-deliverability/evals/README.md +21 -0
- package/skills/shared/email-deliverability/evals/cases.yaml +45 -0
- package/skills/shared/email-deliverability/scripts/verify.sh +98 -0
- package/skills/shared/embeddings-search/SKILL.md +184 -0
- package/skills/shared/embeddings-search/evals/README.md +10 -0
- package/skills/shared/embeddings-search/evals/cases.yaml +44 -0
- package/skills/shared/embeddings-search/references/evaluation.md +86 -0
- package/skills/shared/embeddings-search/references/models.md +73 -0
- package/skills/shared/embeddings-search/scripts/verify.sh +103 -0
- package/skills/shared/error-handling/SKILL.md +273 -0
- package/skills/shared/error-handling/evals/README.md +12 -0
- package/skills/shared/error-handling/evals/cases.yaml +46 -0
- package/skills/shared/error-handling/references/boundaries-and-messaging.md +120 -0
- package/skills/shared/error-handling/references/retry-and-resilience.md +154 -0
- package/skills/shared/error-handling/scripts/verify.sh +110 -0
- package/skills/shared/expo/SKILL.md +243 -0
- package/skills/shared/expo/evals/README.md +13 -0
- package/skills/shared/expo/evals/cases.yaml +44 -0
- package/skills/shared/expo/references/config-plugins.md +117 -0
- package/skills/shared/expo/references/eas-update.md +118 -0
- package/skills/shared/expo/scripts/verify.sh +132 -0
- package/skills/shared/fal/SKILL.md +196 -0
- package/skills/shared/fal/evals/README.md +3 -0
- package/skills/shared/fal/evals/cases.yaml +42 -0
- package/skills/shared/fal/references/models-and-cost.md +53 -0
- package/skills/shared/fal/references/queue-and-webhooks.md +153 -0
- package/skills/shared/fal/scripts/verify.sh +72 -0
- package/skills/shared/fastapi/SKILL.md +469 -0
- package/skills/shared/fastapi/evals/README.md +50 -0
- package/skills/shared/fastapi/evals/cases.yaml +55 -0
- package/skills/shared/fastapi/references/database.md +347 -0
- package/skills/shared/fastapi/references/production.md +338 -0
- package/skills/shared/fastapi/references/security.md +330 -0
- package/skills/shared/fastapi/references/testing.md +349 -0
- package/skills/shared/fastapi/scripts/verify.sh +157 -0
- package/skills/shared/finetuning/SKILL.md +232 -0
- package/skills/shared/finetuning/evals/README.md +13 -0
- package/skills/shared/finetuning/evals/cases.yaml +50 -0
- package/skills/shared/finetuning/references/hyperparameters-and-eval.md +74 -0
- package/skills/shared/finetuning/references/methods.md +189 -0
- package/skills/shared/firebase/SKILL.md +237 -0
- package/skills/shared/firebase/evals/README.md +12 -0
- package/skills/shared/firebase/evals/cases.yaml +45 -0
- package/skills/shared/firebase/references/cloud-functions.md +102 -0
- package/skills/shared/firebase/references/data-modeling.md +108 -0
- package/skills/shared/firebase/references/security-rules.md +137 -0
- package/skills/shared/firebase/scripts/verify.sh +98 -0
- package/skills/shared/flutter/SKILL.md +400 -0
- package/skills/shared/flutter/evals/README.md +54 -0
- package/skills/shared/flutter/evals/cases.yaml +69 -0
- package/skills/shared/flutter/references/architecture-and-state.md +499 -0
- package/skills/shared/flutter/references/i18n-and-dependencies.md +197 -0
- package/skills/shared/flutter/references/performance.md +299 -0
- package/skills/shared/flutter/references/testing.md +385 -0
- package/skills/shared/flutter/references/ui-and-navigation.md +378 -0
- package/skills/shared/flutter/scripts/verify.sh +104 -0
- package/skills/shared/fly-io/SKILL.md +197 -0
- package/skills/shared/fly-io/evals/README.md +3 -0
- package/skills/shared/fly-io/evals/cases.yaml +42 -0
- package/skills/shared/fly-io/references/fly-toml.md +155 -0
- package/skills/shared/fly-io/references/multi-region.md +66 -0
- package/skills/shared/fly-io/scripts/verify.sh +90 -0
- package/skills/shared/ftd/SKILL.md +111 -0
- package/skills/shared/ftd/evals/cases.yaml +66 -0
- package/skills/shared/ftd/evals/routing.json +24 -0
- package/skills/shared/game-design/SKILL.md +146 -0
- package/skills/shared/game-design/evals/README.md +13 -0
- package/skills/shared/game-design/evals/cases.yaml +47 -0
- package/skills/shared/game-design/references/mechanics-and-loops.md +78 -0
- package/skills/shared/game-design/references/playtesting-and-scope.md +58 -0
- package/skills/shared/game-design/references/progression-and-economy.md +70 -0
- package/skills/shared/game-storytelling/SKILL.md +134 -0
- package/skills/shared/game-storytelling/evals/README.md +28 -0
- package/skills/shared/game-storytelling/evals/cases.yaml +51 -0
- package/skills/shared/game-storytelling/references/branching-and-state.md +134 -0
- package/skills/shared/game-storytelling/references/dialogue-tools.md +117 -0
- package/skills/shared/game-storytelling/references/environmental-storytelling.md +71 -0
- package/skills/shared/gamedev-multiplayer/SKILL.md +237 -0
- package/skills/shared/gamedev-multiplayer/evals/README.md +12 -0
- package/skills/shared/gamedev-multiplayer/evals/cases.yaml +44 -0
- package/skills/shared/gamedev-multiplayer/references/godot-high-level-multiplayer.md +133 -0
- package/skills/shared/gamedev-multiplayer/references/prediction-and-latency.md +104 -0
- package/skills/shared/gamedev-multiplayer/references/unity-and-unreal-netcode.md +166 -0
- package/skills/shared/gamedev-pathing/SKILL.md +233 -0
- package/skills/shared/gamedev-pathing/evals/README.md +14 -0
- package/skills/shared/gamedev-pathing/evals/cases.yaml +49 -0
- package/skills/shared/gamedev-pathing/references/navmesh-workflow.md +110 -0
- package/skills/shared/gamedev-pathing/references/search-algorithms.md +135 -0
- package/skills/shared/gamedev-pathing/references/steering-and-avoidance.md +120 -0
- package/skills/shared/gamedev-physics/SKILL.md +225 -0
- package/skills/shared/gamedev-physics/evals/README.md +12 -0
- package/skills/shared/gamedev-physics/evals/cases.yaml +54 -0
- package/skills/shared/gamedev-physics/references/character-controllers.md +120 -0
- package/skills/shared/gamedev-physics/references/determinism-and-queries.md +124 -0
- package/skills/shared/gamedev-physics/references/layers-and-masks.md +115 -0
- package/skills/shared/gamedev-shaders/SKILL.md +232 -0
- package/skills/shared/gamedev-shaders/evals/README.md +14 -0
- package/skills/shared/gamedev-shaders/evals/cases.yaml +45 -0
- package/skills/shared/gamedev-shaders/references/effect-recipes.md +205 -0
- package/skills/shared/gamedev-shaders/references/godot-shading-language.md +133 -0
- package/skills/shared/gamedev-shaders/references/unity-and-unreal-shaders.md +169 -0
- package/skills/shared/gamedev-shipping/SKILL.md +220 -0
- package/skills/shared/gamedev-shipping/evals/README.md +9 -0
- package/skills/shared/gamedev-shipping/evals/cases.yaml +55 -0
- package/skills/shared/gamedev-shipping/references/mobile-and-desktop.md +127 -0
- package/skills/shared/gamedev-shipping/references/stores-and-ci.md +162 -0
- package/skills/shared/gamedev-shipping/references/web-export-headers.md +140 -0
- package/skills/shared/gcp-essentials/SKILL.md +324 -0
- package/skills/shared/gcp-essentials/evals/README.md +12 -0
- package/skills/shared/gcp-essentials/evals/cases.yaml +38 -0
- package/skills/shared/gcp-essentials/references/deploy-recipes.md +81 -0
- package/skills/shared/gcp-essentials/references/iam-and-auth.md +94 -0
- package/skills/shared/gcp-essentials/references/networking-and-sql.md +74 -0
- package/skills/shared/gcp-essentials/scripts/verify.sh +158 -0
- package/skills/shared/git-workflow/SKILL.md +214 -0
- package/skills/shared/git-workflow/evals/README.md +10 -0
- package/skills/shared/git-workflow/evals/cases.yaml +52 -0
- package/skills/shared/git-workflow/references/gitmoji.md +157 -0
- package/skills/shared/git-workflow/references/interactive-rebase.md +89 -0
- package/skills/shared/github-actions/SKILL.md +244 -0
- package/skills/shared/github-actions/evals/README.md +3 -0
- package/skills/shared/github-actions/evals/cases.yaml +45 -0
- package/skills/shared/github-actions/references/caching-and-matrix.md +92 -0
- package/skills/shared/github-actions/references/oidc-deploys.md +130 -0
- package/skills/shared/github-actions/scripts/verify.sh +105 -0
- package/skills/shared/gitlab-auth/SKILL.md +99 -0
- package/skills/shared/gitlab-workflow/SKILL.md +138 -0
- package/skills/shared/go/SKILL.md +390 -0
- package/skills/shared/go/evals/README.md +56 -0
- package/skills/shared/go/evals/cases.yaml +55 -0
- package/skills/shared/go/references/concurrency.md +557 -0
- package/skills/shared/go/references/http-services.md +529 -0
- package/skills/shared/go/references/testing.md +338 -0
- package/skills/shared/go/scripts/verify.sh +134 -0
- package/skills/shared/godot/SKILL.md +300 -0
- package/skills/shared/godot/evals/README.md +13 -0
- package/skills/shared/godot/evals/cases.yaml +50 -0
- package/skills/shared/godot/references/export-and-testing.md +102 -0
- package/skills/shared/godot/references/gdscript-style.md +84 -0
- package/skills/shared/godot/references/godot3-to-4-traps.md +89 -0
- package/skills/shared/godot/references/nodes-scenes-resources.md +109 -0
- package/skills/shared/harness/SKILL.md +316 -0
- package/skills/shared/harness/assets/_TEMPLATE/.env.example +8 -0
- package/skills/shared/harness/assets/_TEMPLATE/CREDENTIALS.md +25 -0
- package/skills/shared/harness/assets/_TEMPLATE/README.md +25 -0
- package/skills/shared/harness/assets/_TEMPLATE/gitignore +10 -0
- package/skills/shared/harness/assets/_TEMPLATE/test_connection.sh +30 -0
- package/skills/shared/harness/evals/README.md +54 -0
- package/skills/shared/harness/evals/cases.yaml +72 -0
- package/skills/shared/harness/examples/audit-example.md +120 -0
- package/skills/shared/harness/references/agents-md-template.md +41 -0
- package/skills/shared/harness/references/audit-report-template.html +140 -0
- package/skills/shared/harness/references/audit-report-template.md +116 -0
- package/skills/shared/harness/references/claude-md-template.md +85 -0
- package/skills/shared/harness/references/daily-curation-automation.md +68 -0
- package/skills/shared/harness/references/inbox-readme-template.md +51 -0
- package/skills/shared/harness/references/ingest-formats.md +185 -0
- package/skills/shared/harness/references/ingest-ignore-defaults.md +48 -0
- package/skills/shared/harness/references/obsidian-scaffolding.md +103 -0
- package/skills/shared/harness/references/providers.yaml +3546 -0
- package/skills/shared/harness/references/tools-readme-template.md +88 -0
- package/skills/shared/harness/references/wiki-archive-template.html +81 -0
- package/skills/shared/harness/references/wiki-article-template.md +60 -0
- package/skills/shared/harness/references/wiki-dashboard-template.html +136 -0
- package/skills/shared/harness/references/wiki-deep-improve-report-template.html +126 -0
- package/skills/shared/harness/references/wiki-gaps-template.md +22 -0
- package/skills/shared/harness/references/wiki-index-template.md +32 -0
- package/skills/shared/harness/references/wiki-protocol.md +926 -0
- package/skills/shared/harness/references/wiki-raw-template.md +7 -0
- package/skills/shared/harness/references/wiki-worklog-template.md +60 -0
- package/skills/shared/hetzner/SKILL.md +203 -0
- package/skills/shared/hetzner/evals/README.md +35 -0
- package/skills/shared/hetzner/evals/cases.yaml +46 -0
- package/skills/shared/hetzner/references/cloud-init.md +120 -0
- package/skills/shared/hetzner/references/plans-and-locations.md +56 -0
- package/skills/shared/hetzner/scripts/verify.sh +122 -0
- package/skills/shared/htmx/SKILL.md +261 -0
- package/skills/shared/htmx/evals/README.md +3 -0
- package/skills/shared/htmx/evals/cases.yaml +38 -0
- package/skills/shared/htmx/references/patterns.md +113 -0
- package/skills/shared/htmx/references/server-contract.md +91 -0
- package/skills/shared/htmx/scripts/verify.sh +93 -0
- package/skills/shared/huggingface/SKILL.md +191 -0
- package/skills/shared/huggingface/evals/README.md +11 -0
- package/skills/shared/huggingface/evals/cases.yaml +41 -0
- package/skills/shared/huggingface/references/endpoints-and-spaces.md +99 -0
- package/skills/shared/huggingface/references/hub-and-cli.md +85 -0
- package/skills/shared/huggingface/references/inference-providers.md +115 -0
- package/skills/shared/huggingface/scripts/verify.sh +123 -0
- package/skills/shared/idea-refinement/SKILL.md +121 -0
- package/skills/shared/idea-refinement/evals/README.md +3 -0
- package/skills/shared/idea-refinement/evals/cases.yaml +42 -0
- package/skills/shared/implement/SKILL.md +383 -0
- package/skills/shared/implement/evals/README.md +56 -0
- package/skills/shared/implement/evals/cases.yaml +43 -0
- package/skills/shared/implement/references/per-task-review.md +46 -0
- package/skills/shared/implement/scripts/review-package +59 -0
- package/skills/shared/implement/scripts/sdd-workspace +47 -0
- package/skills/shared/implement/scripts/task-brief +77 -0
- package/skills/shared/init/SKILL.md +209 -0
- package/skills/shared/init/evals/README.md +49 -0
- package/skills/shared/init/evals/cases.yaml +74 -0
- package/skills/shared/init/references/accompaniment-and-profile.md +122 -0
- package/skills/shared/init/references/discovery.md +90 -0
- package/skills/shared/init/references/recommend-skills.md +115 -0
- package/skills/shared/init/scripts/verify.sh +118 -0
- package/skills/shared/java/SKILL.md +341 -0
- package/skills/shared/java/evals/README.md +23 -0
- package/skills/shared/java/evals/cases.yaml +43 -0
- package/skills/shared/java/references/builds.md +133 -0
- package/skills/shared/java/references/concurrency.md +108 -0
- package/skills/shared/java/references/streams.md +102 -0
- package/skills/shared/java/scripts/verify.sh +107 -0
- package/skills/shared/knowledge-ops/SKILL.md +122 -0
- package/skills/shared/knowledge-ops/evals/README.md +16 -0
- package/skills/shared/knowledge-ops/evals/cases.yaml +50 -0
- package/skills/shared/knowledge-ops/references/gardening-playbook.md +126 -0
- package/skills/shared/kotlin-android/SKILL.md +245 -0
- package/skills/shared/kotlin-android/evals/README.md +13 -0
- package/skills/shared/kotlin-android/evals/cases.yaml +56 -0
- package/skills/shared/kotlin-android/references/architecture.md +200 -0
- package/skills/shared/kotlin-android/references/gradle-setup.md +125 -0
- package/skills/shared/kotlin-android/scripts/verify.sh +109 -0
- package/skills/shared/laravel/SKILL.md +301 -0
- package/skills/shared/laravel/evals/README.md +10 -0
- package/skills/shared/laravel/evals/cases.yaml +45 -0
- package/skills/shared/laravel/references/eloquent-patterns.md +126 -0
- package/skills/shared/laravel/references/queues-and-scheduling.md +153 -0
- package/skills/shared/laravel/scripts/verify.sh +128 -0
- package/skills/shared/level-design/SKILL.md +143 -0
- package/skills/shared/level-design/evals/README.md +35 -0
- package/skills/shared/level-design/evals/cases.yaml +58 -0
- package/skills/shared/level-design/references/blockout-to-art.md +118 -0
- package/skills/shared/level-design/references/guidance-and-readability.md +152 -0
- package/skills/shared/level-design/references/pacing-and-encounters.md +142 -0
- package/skills/shared/llm-pipeline/SKILL.md +150 -0
- package/skills/shared/llm-pipeline/evals/README.md +3 -0
- package/skills/shared/llm-pipeline/evals/cases.yaml +44 -0
- package/skills/shared/llm-pipeline/references/caching-layers.md +60 -0
- package/skills/shared/llm-pipeline/references/litellm-router.md +101 -0
- package/skills/shared/llm-pipeline/scripts/verify.sh +169 -0
- package/skills/shared/machine-learning/SKILL.md +228 -0
- package/skills/shared/machine-learning/evals/README.md +15 -0
- package/skills/shared/machine-learning/evals/cases.yaml +54 -0
- package/skills/shared/machine-learning/references/gbdt-and-tuning.md +83 -0
- package/skills/shared/machine-learning/references/metrics-and-imbalance.md +82 -0
- package/skills/shared/machine-learning/references/pipelines-and-cv.md +135 -0
- package/skills/shared/modal/SKILL.md +290 -0
- package/skills/shared/modal/evals/README.md +29 -0
- package/skills/shared/modal/evals/cases.yaml +50 -0
- package/skills/shared/modal/references/images-gpu-cookbook.md +160 -0
- package/skills/shared/modal/references/web-and-scaling.md +138 -0
- package/skills/shared/modal/scripts/verify.sh +127 -0
- package/skills/shared/mongodb/SKILL.md +342 -0
- package/skills/shared/mongodb/evals/README.md +29 -0
- package/skills/shared/mongodb/evals/cases.yaml +41 -0
- package/skills/shared/mongodb/references/aggregation.md +115 -0
- package/skills/shared/mongodb/references/data-modeling.md +135 -0
- package/skills/shared/mongodb/references/transactions-and-ops.md +128 -0
- package/skills/shared/mongodb/scripts/verify.sh +151 -0
- package/skills/shared/monitoring/SKILL.md +155 -0
- package/skills/shared/monitoring/evals/README.md +3 -0
- package/skills/shared/monitoring/evals/cases.yaml +47 -0
- package/skills/shared/monitoring/references/burn-rate-and-oncall.md +128 -0
- package/skills/shared/monitoring/references/tool-setup.md +154 -0
- package/skills/shared/monitoring/scripts/verify.sh +145 -0
- package/skills/shared/mysql/SKILL.md +249 -0
- package/skills/shared/mysql/evals/README.md +12 -0
- package/skills/shared/mysql/evals/cases.yaml +49 -0
- package/skills/shared/mysql/references/indexing-and-explain.md +161 -0
- package/skills/shared/mysql/references/mysql-vs-mariadb.md +78 -0
- package/skills/shared/mysql/references/online-ddl-and-migrations.md +120 -0
- package/skills/shared/mysql/references/replication-and-ha.md +115 -0
- package/skills/shared/mysql/scripts/verify.sh +141 -0
- package/skills/shared/neon/SKILL.md +218 -0
- package/skills/shared/neon/evals/README.md +11 -0
- package/skills/shared/neon/evals/cases.yaml +45 -0
- package/skills/shared/neon/references/branching-ci.md +86 -0
- package/skills/shared/neon/scripts/verify.sh +78 -0
- package/skills/shared/nestjs/SKILL.md +217 -0
- package/skills/shared/nestjs/evals/README.md +3 -0
- package/skills/shared/nestjs/evals/cases.yaml +38 -0
- package/skills/shared/nestjs/references/cross-cutting.md +135 -0
- package/skills/shared/nestjs/references/testing-recipes.md +105 -0
- package/skills/shared/nestjs/scripts/verify.sh +98 -0
- package/skills/shared/netlify/SKILL.md +208 -0
- package/skills/shared/netlify/evals/README.md +13 -0
- package/skills/shared/netlify/evals/cases.yaml +43 -0
- package/skills/shared/netlify/references/functions.md +97 -0
- package/skills/shared/netlify/references/netlify-toml.md +115 -0
- package/skills/shared/netlify/scripts/verify.sh +95 -0
- package/skills/shared/nextjs/SKILL.md +400 -0
- package/skills/shared/nextjs/evals/README.md +59 -0
- package/skills/shared/nextjs/evals/cases.yaml +56 -0
- package/skills/shared/nextjs/references/data-and-caching.md +309 -0
- package/skills/shared/nextjs/references/metadata.md +208 -0
- package/skills/shared/nextjs/references/performance.md +325 -0
- package/skills/shared/nextjs/references/react.md +383 -0
- package/skills/shared/nextjs/references/security.md +239 -0
- package/skills/shared/nextjs/references/testing.md +290 -0
- package/skills/shared/nextjs/scripts/verify.sh +141 -0
- package/skills/shared/nlp/SKILL.md +225 -0
- package/skills/shared/nlp/evals/README.md +10 -0
- package/skills/shared/nlp/evals/cases.yaml +45 -0
- package/skills/shared/nlp/references/evaluation.md +107 -0
- package/skills/shared/nlp/references/tokenization.md +95 -0
- package/skills/shared/no-code-app/SKILL.md +145 -0
- package/skills/shared/no-code-app/evals/README.md +3 -0
- package/skills/shared/no-code-app/evals/cases.yaml +43 -0
- package/skills/shared/no-code-app/references/platform-limits.md +100 -0
- package/skills/shared/nodejs/SKILL.md +229 -0
- package/skills/shared/nodejs/evals/README.md +3 -0
- package/skills/shared/nodejs/evals/cases.yaml +39 -0
- package/skills/shared/nodejs/references/express5-migration.md +53 -0
- package/skills/shared/nodejs/references/graceful-shutdown.md +73 -0
- package/skills/shared/nodejs/scripts/verify.sh +122 -0
- package/skills/shared/observability/SKILL.md +235 -0
- package/skills/shared/observability/evals/README.md +3 -0
- package/skills/shared/observability/evals/cases.yaml +51 -0
- package/skills/shared/observability/references/collector-config.md +98 -0
- package/skills/shared/observability/references/instrumentation-recipes.md +115 -0
- package/skills/shared/observability/scripts/verify.sh +156 -0
- package/skills/shared/ollama/SKILL.md +213 -0
- package/skills/shared/ollama/evals/README.md +9 -0
- package/skills/shared/ollama/evals/cases.yaml +43 -0
- package/skills/shared/ollama/references/api.md +148 -0
- package/skills/shared/ollama/references/hardware-sizing.md +87 -0
- package/skills/shared/ollama/scripts/verify.sh +116 -0
- package/skills/shared/open-weights/SKILL.md +239 -0
- package/skills/shared/open-weights/evals/README.md +14 -0
- package/skills/shared/open-weights/evals/cases.yaml +42 -0
- package/skills/shared/open-weights/references/licenses.md +123 -0
- package/skills/shared/open-weights/references/model-families.md +83 -0
- package/skills/shared/open-weights/references/sizing-and-quant.md +89 -0
- package/skills/shared/orient/SKILL.md +92 -0
- package/skills/shared/orient/evals/README.md +18 -0
- package/skills/shared/orient/evals/cases.yaml +67 -0
- package/skills/shared/orient/references/explain-ladder.md +93 -0
- package/skills/shared/orient/references/orientation-contract.md +86 -0
- package/skills/shared/parallel/SKILL.md +168 -0
- package/skills/shared/parallel/evals/README.md +62 -0
- package/skills/shared/parallel/evals/cases.yaml +44 -0
- package/skills/shared/performance/SKILL.md +229 -0
- package/skills/shared/performance/evals/README.md +3 -0
- package/skills/shared/performance/evals/cases.yaml +49 -0
- package/skills/shared/performance/references/profiling-playbook.md +54 -0
- package/skills/shared/performance/scripts/verify.sh +94 -0
- package/skills/shared/phoenix/SKILL.md +169 -0
- package/skills/shared/phoenix/evals/README.md +3 -0
- package/skills/shared/phoenix/evals/cases.yaml +40 -0
- package/skills/shared/phoenix/references/auth-and-scopes.md +82 -0
- package/skills/shared/phoenix/references/ecto-patterns.md +93 -0
- package/skills/shared/phoenix/references/liveview.md +134 -0
- package/skills/shared/phoenix/scripts/verify.sh +73 -0
- package/skills/shared/php/SKILL.md +397 -0
- package/skills/shared/php/evals/README.md +12 -0
- package/skills/shared/php/evals/cases.yaml +45 -0
- package/skills/shared/php/references/tooling.md +170 -0
- package/skills/shared/php/references/type-system.md +220 -0
- package/skills/shared/php/scripts/verify.sh +155 -0
- package/skills/shared/plan/SKILL.md +166 -0
- package/skills/shared/plan/evals/README.md +62 -0
- package/skills/shared/plan/evals/cases.yaml +49 -0
- package/skills/shared/plan/references/plan-template.md +153 -0
- package/skills/shared/planetscale/SKILL.md +198 -0
- package/skills/shared/planetscale/evals/README.md +11 -0
- package/skills/shared/planetscale/evals/cases.yaml +46 -0
- package/skills/shared/planetscale/references/deploy-requests.md +75 -0
- package/skills/shared/planetscale/references/no-foreign-keys.md +88 -0
- package/skills/shared/planetscale/scripts/verify.sh +115 -0
- package/skills/shared/planning-with-files/SKILL.md +278 -0
- package/skills/shared/planning-with-files/examples.md +202 -0
- package/skills/shared/planning-with-files/reference.md +218 -0
- package/skills/shared/planning-with-files/scripts/attest-plan.ps1 +118 -0
- package/skills/shared/planning-with-files/scripts/attest-plan.sh +110 -0
- package/skills/shared/planning-with-files/scripts/check-complete.ps1 +44 -0
- package/skills/shared/planning-with-files/scripts/check-complete.sh +46 -0
- package/skills/shared/planning-with-files/scripts/init-session.ps1 +166 -0
- package/skills/shared/planning-with-files/scripts/init-session.sh +284 -0
- package/skills/shared/planning-with-files/scripts/resolve-plan-dir.ps1 +44 -0
- package/skills/shared/planning-with-files/scripts/resolve-plan-dir.sh +76 -0
- package/skills/shared/planning-with-files/scripts/session-catchup.py +438 -0
- package/skills/shared/planning-with-files/scripts/set-active-plan.ps1 +50 -0
- package/skills/shared/planning-with-files/scripts/set-active-plan.sh +50 -0
- package/skills/shared/planning-with-files/templates/findings.md +95 -0
- package/skills/shared/planning-with-files/templates/progress.md +114 -0
- package/skills/shared/planning-with-files/templates/task_plan.md +132 -0
- package/skills/shared/postgresdb/SKILL.md +354 -0
- package/skills/shared/postgresdb/evals/README.md +55 -0
- package/skills/shared/postgresdb/evals/cases.yaml +57 -0
- package/skills/shared/postgresdb/references/migrations.md +279 -0
- package/skills/shared/postgresdb/references/operations-and-security.md +267 -0
- package/skills/shared/postgresdb/references/query-optimization.md +374 -0
- package/skills/shared/postgresdb/references/schema-and-indexing.md +379 -0
- package/skills/shared/postgresdb/scripts/verify.sh +191 -0
- package/skills/shared/prisma-orm/SKILL.md +313 -0
- package/skills/shared/prisma-orm/evals/README.md +12 -0
- package/skills/shared/prisma-orm/evals/cases.yaml +56 -0
- package/skills/shared/prisma-orm/references/migrations-and-v7-upgrade.md +197 -0
- package/skills/shared/prisma-orm/references/queries-and-performance.md +169 -0
- package/skills/shared/prisma-orm/scripts/verify.sh +137 -0
- package/skills/shared/prompt-engineering/SKILL.md +127 -0
- package/skills/shared/prompt-engineering/evals/README.md +11 -0
- package/skills/shared/prompt-engineering/evals/cases.yaml +46 -0
- package/skills/shared/prompt-engineering/references/eval-templates.md +94 -0
- package/skills/shared/prompt-engineering/references/output-contracts.md +120 -0
- package/skills/shared/prompt-engineering/scripts/verify.sh +84 -0
- package/skills/shared/python/SKILL.md +320 -0
- package/skills/shared/python/evals/README.md +19 -0
- package/skills/shared/python/evals/cases.yaml +46 -0
- package/skills/shared/python/references/async.md +136 -0
- package/skills/shared/python/references/stdlib.md +162 -0
- package/skills/shared/python/references/typing.md +160 -0
- package/skills/shared/python/scripts/verify.sh +125 -0
- package/skills/shared/rag/SKILL.md +209 -0
- package/skills/shared/rag/evals/README.md +13 -0
- package/skills/shared/rag/evals/cases.yaml +45 -0
- package/skills/shared/rag/references/evaluation.md +99 -0
- package/skills/shared/rag/references/pipeline.md +151 -0
- package/skills/shared/rag/scripts/verify.sh +99 -0
- package/skills/shared/rails/SKILL.md +264 -0
- package/skills/shared/rails/evals/README.md +12 -0
- package/skills/shared/rails/evals/cases.yaml +47 -0
- package/skills/shared/rails/references/activerecord.md +148 -0
- package/skills/shared/rails/references/hotwire.md +139 -0
- package/skills/shared/rails/references/testing.md +110 -0
- package/skills/shared/rails/scripts/verify.sh +128 -0
- package/skills/shared/railway/SKILL.md +245 -0
- package/skills/shared/railway/evals/README.md +14 -0
- package/skills/shared/railway/evals/cases.yaml +44 -0
- package/skills/shared/railway/references/cli-cookbook.md +137 -0
- package/skills/shared/railway/references/config-as-code.md +120 -0
- package/skills/shared/railway/scripts/verify.sh +162 -0
- package/skills/shared/react/SKILL.md +182 -0
- package/skills/shared/react/evals/README.md +3 -0
- package/skills/shared/react/evals/cases.yaml +43 -0
- package/skills/shared/react/references/data-and-state.md +152 -0
- package/skills/shared/react/references/performance.md +75 -0
- package/skills/shared/react/references/routing.md +99 -0
- package/skills/shared/react/scripts/verify.sh +123 -0
- package/skills/shared/react-native/SKILL.md +215 -0
- package/skills/shared/react-native/evals/README.md +3 -0
- package/skills/shared/react-native/evals/cases.yaml +42 -0
- package/skills/shared/react-native/references/native-modules.md +123 -0
- package/skills/shared/react-native/references/performance-debugging.md +46 -0
- package/skills/shared/react-native/scripts/verify.sh +120 -0
- package/skills/shared/redis/SKILL.md +298 -0
- package/skills/shared/redis/evals/README.md +10 -0
- package/skills/shared/redis/evals/cases.yaml +43 -0
- package/skills/shared/redis/references/caching.md +116 -0
- package/skills/shared/redis/references/locks-and-rate-limiting.md +140 -0
- package/skills/shared/redis/references/queues.md +102 -0
- package/skills/shared/redis/scripts/verify.sh +164 -0
- package/skills/shared/render/SKILL.md +256 -0
- package/skills/shared/render/evals/README.md +12 -0
- package/skills/shared/render/evals/cases.yaml +45 -0
- package/skills/shared/render/references/blueprint-reference.md +203 -0
- package/skills/shared/render/scripts/verify.sh +167 -0
- package/skills/shared/replicate/SKILL.md +210 -0
- package/skills/shared/replicate/evals/README.md +9 -0
- package/skills/shared/replicate/evals/cases.yaml +45 -0
- package/skills/shared/replicate/references/cog-packaging.md +89 -0
- package/skills/shared/replicate/references/deployments-api.md +87 -0
- package/skills/shared/replicate/references/webhooks-and-async.md +110 -0
- package/skills/shared/replicate/scripts/verify.sh +162 -0
- package/skills/shared/research-ops/SKILL.md +200 -0
- package/skills/shared/research-ops/evals/README.md +13 -0
- package/skills/shared/research-ops/evals/cases.yaml +38 -0
- package/skills/shared/research-ops/references/credibility-rubric.md +78 -0
- package/skills/shared/research-ops/references/memo-template.md +63 -0
- package/skills/shared/research-ops/scripts/verify.sh +181 -0
- package/skills/shared/review/SKILL.md +314 -0
- package/skills/shared/review/evals/README.md +84 -0
- package/skills/shared/review/evals/cases.yaml +55 -0
- package/skills/shared/ruby/SKILL.md +295 -0
- package/skills/shared/ruby/evals/README.md +12 -0
- package/skills/shared/ruby/evals/cases.yaml +41 -0
- package/skills/shared/ruby/references/gems-and-testing.md +208 -0
- package/skills/shared/ruby/references/metaprogramming.md +161 -0
- package/skills/shared/ruby/scripts/verify.sh +83 -0
- package/skills/shared/runpod/SKILL.md +238 -0
- package/skills/shared/runpod/evals/README.md +11 -0
- package/skills/shared/runpod/evals/cases.yaml +47 -0
- package/skills/shared/runpod/references/cost-and-scaling.md +85 -0
- package/skills/shared/runpod/references/serverless-workers.md +101 -0
- package/skills/shared/runpod/scripts/verify.sh +126 -0
- package/skills/shared/rust/SKILL.md +320 -0
- package/skills/shared/rust/evals/README.md +12 -0
- package/skills/shared/rust/evals/cases.yaml +42 -0
- package/skills/shared/rust/references/async-tokio.md +141 -0
- package/skills/shared/rust/references/axum-service.md +132 -0
- package/skills/shared/rust/references/ownership.md +86 -0
- package/skills/shared/rust/references/testing.md +108 -0
- package/skills/shared/rust/scripts/verify.sh +91 -0
- package/skills/shared/scaling/SKILL.md +137 -0
- package/skills/shared/scaling/evals/README.md +3 -0
- package/skills/shared/scaling/evals/cases.yaml +42 -0
- package/skills/shared/scaling/references/load-testing-k6.md +127 -0
- package/skills/shared/scaling/scripts/example.load.js +24 -0
- package/skills/shared/scaling/scripts/verify.sh +70 -0
- package/skills/shared/sdd/SKILL.md +250 -0
- package/skills/shared/sdd/evals/README.md +60 -0
- package/skills/shared/sdd/evals/cases.yaml +90 -0
- package/skills/shared/sdd/references/model-routing.md +194 -0
- package/skills/shared/sdd-init/SKILL.md +189 -0
- package/skills/shared/sdd-init/evals/README.md +3 -0
- package/skills/shared/sdd-init/evals/cases.yaml +43 -0
- package/skills/shared/secure-coding/SKILL.md +336 -0
- package/skills/shared/secure-coding/evals/README.md +68 -0
- package/skills/shared/secure-coding/evals/cases.yaml +55 -0
- package/skills/shared/secure-coding/references/authn-authz.md +249 -0
- package/skills/shared/secure-coding/references/owasp-by-stack.md +574 -0
- package/skills/shared/secure-coding/references/secrets-and-supply-chain.md +205 -0
- package/skills/shared/secure-coding/references/threat-modeling.md +213 -0
- package/skills/shared/secure-coding/scripts/verify.sh +208 -0
- package/skills/shared/security-scan/SKILL.md +219 -0
- package/skills/shared/security-scan/evals/README.md +14 -0
- package/skills/shared/security-scan/evals/cases.yaml +50 -0
- package/skills/shared/security-scan/references/tools.md +97 -0
- package/skills/shared/security-scan/references/triage.md +92 -0
- package/skills/shared/security-scan/scripts/verify.sh +108 -0
- package/skills/shared/ship/SKILL.md +272 -0
- package/skills/shared/ship/evals/README.md +89 -0
- package/skills/shared/ship/evals/cases.yaml +44 -0
- package/skills/shared/shopify/SKILL.md +229 -0
- package/skills/shared/shopify/evals/README.md +14 -0
- package/skills/shared/shopify/evals/cases.yaml +41 -0
- package/skills/shared/shopify/references/apps-graphql.md +103 -0
- package/skills/shared/shopify/references/checkout-extensibility.md +71 -0
- package/skills/shared/shopify/references/liquid-themes.md +89 -0
- package/skills/shared/shopify/scripts/verify.sh +120 -0
- package/skills/shared/simplify-code/SKILL.md +101 -0
- package/skills/shared/simplify-code/evals/README.md +3 -0
- package/skills/shared/simplify-code/evals/cases.yaml +42 -0
- package/skills/shared/skill-scout/SKILL.md +169 -0
- package/skills/shared/skill-scout/evals/README.md +12 -0
- package/skills/shared/skill-scout/evals/cases.yaml +56 -0
- package/skills/shared/skill-scout/references/install-commands.md +76 -0
- package/skills/shared/skill-scout/scripts/verify.sh +154 -0
- package/skills/shared/solid-js/SKILL.md +260 -0
- package/skills/shared/solid-js/evals/README.md +3 -0
- package/skills/shared/solid-js/evals/cases.yaml +38 -0
- package/skills/shared/solid-js/references/reactivity-deep-dive.md +89 -0
- package/skills/shared/solid-js/references/router-and-start.md +93 -0
- package/skills/shared/solid-js/scripts/verify.sh +130 -0
- package/skills/shared/source-grounded-development/SKILL.md +108 -0
- package/skills/shared/source-grounded-development/evals/README.md +3 -0
- package/skills/shared/source-grounded-development/evals/cases.yaml +42 -0
- package/skills/shared/specify/SKILL.md +391 -0
- package/skills/shared/specify/evals/README.md +73 -0
- package/skills/shared/specify/evals/cases.yaml +93 -0
- package/skills/shared/specify/references/eliciting-requirements.md +117 -0
- package/skills/shared/specify/references/spec-template.md +101 -0
- package/skills/shared/speckit-analyze/SKILL.md +35 -0
- package/skills/shared/speckit-assess-decide/SKILL.md +36 -0
- package/skills/shared/speckit-assess-define/SKILL.md +36 -0
- package/skills/shared/speckit-assess-intake/SKILL.md +38 -0
- package/skills/shared/speckit-assess-research/SKILL.md +36 -0
- package/skills/shared/speckit-assess-shape/SKILL.md +36 -0
- package/skills/shared/speckit-bug-assess/SKILL.md +38 -0
- package/skills/shared/speckit-bug-fix/SKILL.md +37 -0
- package/skills/shared/speckit-bug-test/SKILL.md +37 -0
- package/skills/shared/speckit-checklist/SKILL.md +35 -0
- package/skills/shared/speckit-clarify/SKILL.md +32 -0
- package/skills/shared/speckit-constitution/SKILL.md +35 -0
- package/skills/shared/speckit-converge/SKILL.md +36 -0
- package/skills/shared/speckit-implement/SKILL.md +32 -0
- package/skills/shared/speckit-plan/SKILL.md +37 -0
- package/skills/shared/speckit-specify/SKILL.md +36 -0
- package/skills/shared/speckit-tasks/SKILL.md +34 -0
- package/skills/shared/spreadsheet-ops/SKILL.md +180 -0
- package/skills/shared/spreadsheet-ops/evals/README.md +33 -0
- package/skills/shared/spreadsheet-ops/evals/cases.yaml +42 -0
- package/skills/shared/spreadsheet-ops/references/formula-cookbook.md +70 -0
- package/skills/shared/spreadsheet-ops/references/python-excel.md +87 -0
- package/skills/shared/spreadsheet-ops/references/sheets-api-appsscript.md +118 -0
- package/skills/shared/spreadsheet-ops/scripts/verify.sh +152 -0
- package/skills/shared/spring-boot/SKILL.md +350 -0
- package/skills/shared/spring-boot/evals/README.md +11 -0
- package/skills/shared/spring-boot/evals/cases.yaml +49 -0
- package/skills/shared/spring-boot/references/jpa.md +94 -0
- package/skills/shared/spring-boot/references/security.md +92 -0
- package/skills/shared/spring-boot/references/testing.md +95 -0
- package/skills/shared/spring-boot/scripts/verify.sh +115 -0
- package/skills/shared/sql/SKILL.md +286 -0
- package/skills/shared/sql/evals/README.md +9 -0
- package/skills/shared/sql/evals/cases.yaml +49 -0
- package/skills/shared/sql/references/ctes-and-recursion.md +63 -0
- package/skills/shared/sql/references/joins-and-sets.md +71 -0
- package/skills/shared/sql/references/portability.md +38 -0
- package/skills/shared/sql/references/window-functions.md +72 -0
- package/skills/shared/sql/scripts/verify.sh +139 -0
- package/skills/shared/sqlite-turso/SKILL.md +214 -0
- package/skills/shared/sqlite-turso/evals/README.md +24 -0
- package/skills/shared/sqlite-turso/evals/cases.yaml +45 -0
- package/skills/shared/sqlite-turso/references/embedded-replicas.md +96 -0
- package/skills/shared/sqlite-turso/scripts/verify.sh +95 -0
- package/skills/shared/structured-extraction/SKILL.md +230 -0
- package/skills/shared/structured-extraction/evals/README.md +13 -0
- package/skills/shared/structured-extraction/evals/cases.yaml +70 -0
- package/skills/shared/structured-extraction/references/providers.md +152 -0
- package/skills/shared/structured-extraction/scripts/verify.sh +160 -0
- package/skills/shared/suggest/SKILL.md +123 -0
- package/skills/shared/suggest/evals/README.md +17 -0
- package/skills/shared/suggest/evals/cases.yaml +78 -0
- package/skills/shared/supabase/SKILL.md +268 -0
- package/skills/shared/supabase/evals/README.md +12 -0
- package/skills/shared/supabase/evals/cases.yaml +42 -0
- package/skills/shared/supabase/references/auth-ssr.md +173 -0
- package/skills/shared/supabase/references/rls-cookbook.md +122 -0
- package/skills/shared/supabase/scripts/verify.sh +149 -0
- package/skills/shared/svelte/SKILL.md +238 -0
- package/skills/shared/svelte/evals/README.md +3 -0
- package/skills/shared/svelte/evals/cases.yaml +41 -0
- package/skills/shared/svelte/references/runes.md +97 -0
- package/skills/shared/svelte/references/sveltekit-data.md +156 -0
- package/skills/shared/svelte/scripts/verify.sh +128 -0
- package/skills/shared/swift-ios/SKILL.md +224 -0
- package/skills/shared/swift-ios/evals/README.md +3 -0
- package/skills/shared/swift-ios/evals/cases.yaml +46 -0
- package/skills/shared/swift-ios/references/concurrency.md +132 -0
- package/skills/shared/swift-ios/references/testing.md +112 -0
- package/skills/shared/swift-ios/scripts/verify.sh +98 -0
- package/skills/shared/tasks/SKILL.md +265 -0
- package/skills/shared/tasks/evals/README.md +70 -0
- package/skills/shared/tasks/evals/cases.yaml +75 -0
- package/skills/shared/tauri/SKILL.md +219 -0
- package/skills/shared/tauri/evals/README.md +12 -0
- package/skills/shared/tauri/evals/cases.yaml +46 -0
- package/skills/shared/tauri/references/bundling-distribution.md +129 -0
- package/skills/shared/tauri/references/security.md +143 -0
- package/skills/shared/tauri/scripts/verify.sh +178 -0
- package/skills/shared/technical-writing/SKILL.md +230 -0
- package/skills/shared/technical-writing/evals/README.md +12 -0
- package/skills/shared/technical-writing/evals/cases.yaml +53 -0
- package/skills/shared/technical-writing/references/diataxis-modes.md +131 -0
- package/skills/shared/technical-writing/references/vale-starter.md +90 -0
- package/skills/shared/technical-writing/scripts/verify.sh +83 -0
- package/skills/shared/testing-go/SKILL.md +263 -0
- package/skills/shared/testing-go/evals/README.md +3 -0
- package/skills/shared/testing-go/evals/cases.yaml +46 -0
- package/skills/shared/testing-go/references/coverage-and-benchmarks.md +85 -0
- package/skills/shared/testing-go/references/mocks-and-fakes.md +140 -0
- package/skills/shared/testing-go/references/synctest-and-concurrency.md +82 -0
- package/skills/shared/testing-go/scripts/verify.sh +72 -0
- package/skills/shared/testing-py/SKILL.md +197 -0
- package/skills/shared/testing-py/evals/README.md +5 -0
- package/skills/shared/testing-py/evals/cases.yaml +44 -0
- package/skills/shared/testing-py/references/mocking.md +141 -0
- package/skills/shared/testing-py/references/property-testing.md +99 -0
- package/skills/shared/testing-py/scripts/verify.sh +117 -0
- package/skills/shared/testing-web/SKILL.md +244 -0
- package/skills/shared/testing-web/evals/README.md +11 -0
- package/skills/shared/testing-web/evals/cases.yaml +52 -0
- package/skills/shared/testing-web/references/jest-setup.md +88 -0
- package/skills/shared/testing-web/references/recipes.md +116 -0
- package/skills/shared/testing-web/scripts/verify.sh +111 -0
- package/skills/shared/together-fireworks/SKILL.md +176 -0
- package/skills/shared/together-fireworks/evals/README.md +3 -0
- package/skills/shared/together-fireworks/evals/cases.yaml +50 -0
- package/skills/shared/together-fireworks/references/batch-and-tuning.md +59 -0
- package/skills/shared/together-fireworks/references/models-and-pricing.md +79 -0
- package/skills/shared/together-fireworks/scripts/verify.sh +165 -0
- package/skills/shared/training-data/SKILL.md +226 -0
- package/skills/shared/training-data/evals/README.md +13 -0
- package/skills/shared/training-data/evals/cases.yaml +41 -0
- package/skills/shared/training-data/references/formats.md +118 -0
- package/skills/shared/training-data/references/synthesis-dedup-quality.md +134 -0
- package/skills/shared/translation-l10n/SKILL.md +229 -0
- package/skills/shared/translation-l10n/evals/README.md +3 -0
- package/skills/shared/translation-l10n/evals/cases.yaml +39 -0
- package/skills/shared/translation-l10n/references/icu-cookbook.md +82 -0
- package/skills/shared/translation-l10n/references/rtl-and-bidi.md +60 -0
- package/skills/shared/typescript/SKILL.md +225 -0
- package/skills/shared/typescript/evals/README.md +15 -0
- package/skills/shared/typescript/evals/cases.yaml +46 -0
- package/skills/shared/typescript/references/build-and-monorepo.md +141 -0
- package/skills/shared/typescript/references/type-system.md +162 -0
- package/skills/shared/typescript/scripts/verify.sh +52 -0
- package/skills/shared/ui-engineering/SKILL.md +113 -0
- package/skills/shared/ui-engineering/evals/cases.yaml +38 -0
- package/skills/shared/unity/SKILL.md +282 -0
- package/skills/shared/unity/evals/README.md +8 -0
- package/skills/shared/unity/evals/cases.yaml +43 -0
- package/skills/shared/unity/references/build-and-platforms.md +65 -0
- package/skills/shared/unity/references/input-system.md +102 -0
- package/skills/shared/unity/references/lifecycle-deep-dive.md +75 -0
- package/skills/shared/unreal/SKILL.md +270 -0
- package/skills/shared/unreal/evals/README.md +12 -0
- package/skills/shared/unreal/evals/cases.yaml +45 -0
- package/skills/shared/unreal/references/blueprint-cpp-parity.md +109 -0
- package/skills/shared/unreal/references/gameplay-framework.md +95 -0
- package/skills/shared/unreal/references/packaging.md +83 -0
- package/skills/shared/unslop/SKILL.md +143 -0
- package/skills/shared/unslop/evals/README.md +25 -0
- package/skills/shared/unslop/evals/cases.yaml +61 -0
- package/skills/shared/unsloth/SKILL.md +254 -0
- package/skills/shared/unsloth/evals/README.md +10 -0
- package/skills/shared/unsloth/evals/cases.yaml +42 -0
- package/skills/shared/unsloth/references/export.md +75 -0
- package/skills/shared/unsloth/references/grpo.md +91 -0
- package/skills/shared/unsloth/references/masking-and-templates.md +91 -0
- package/skills/shared/variant-explorer/SKILL.md +93 -0
- package/skills/shared/variant-explorer/evals/cases.yaml +38 -0
- package/skills/shared/vector-db/SKILL.md +189 -0
- package/skills/shared/vector-db/evals/README.md +10 -0
- package/skills/shared/vector-db/evals/cases.yaml +45 -0
- package/skills/shared/vector-db/references/engines.md +175 -0
- package/skills/shared/vector-db/references/tuning.md +62 -0
- package/skills/shared/vector-db/scripts/verify.sh +110 -0
- package/skills/shared/vercel/SKILL.md +242 -0
- package/skills/shared/vercel/evals/README.md +23 -0
- package/skills/shared/vercel/evals/cases.yaml +45 -0
- package/skills/shared/vercel/references/cli-cookbook.md +98 -0
- package/skills/shared/vercel/references/vercel-json.md +120 -0
- package/skills/shared/vercel/scripts/verify.sh +168 -0
- package/skills/shared/verify/SKILL.md +230 -0
- package/skills/shared/verify/evals/README.md +78 -0
- package/skills/shared/verify/evals/cases.yaml +104 -0
- package/skills/shared/vllm/SKILL.md +235 -0
- package/skills/shared/vllm/evals/README.md +9 -0
- package/skills/shared/vllm/evals/cases.yaml +47 -0
- package/skills/shared/vllm/references/flags-and-endpoints.md +105 -0
- package/skills/shared/vllm/references/memory-and-throughput.md +78 -0
- package/skills/shared/vue-nuxt/SKILL.md +323 -0
- package/skills/shared/vue-nuxt/evals/README.md +11 -0
- package/skills/shared/vue-nuxt/evals/cases.yaml +49 -0
- package/skills/shared/vue-nuxt/references/data-and-state.md +127 -0
- package/skills/shared/vue-nuxt/references/migration-nuxt4.md +79 -0
- package/skills/shared/vue-nuxt/references/nitro-and-rendering.md +117 -0
- package/skills/shared/vue-nuxt/references/reactivity.md +135 -0
- package/skills/shared/vue-nuxt/scripts/verify.sh +148 -0
- package/skills/shared/webhooks/SKILL.md +229 -0
- package/skills/shared/webhooks/evals/README.md +15 -0
- package/skills/shared/webhooks/evals/cases.yaml +46 -0
- package/skills/shared/webhooks/references/framework-raw-body.md +97 -0
- package/skills/shared/webhooks/references/signature-schemes.md +66 -0
- package/skills/shared/webhooks/scripts/verify.sh +142 -0
- package/skills/shared/wordpress/SKILL.md +224 -0
- package/skills/shared/wordpress/evals/README.md +3 -0
- package/skills/shared/wordpress/evals/cases.yaml +50 -0
- package/skills/shared/wordpress/references/hardening.md +108 -0
- package/skills/shared/wordpress/references/performance.md +80 -0
- package/skills/shared/wordpress/references/woocommerce.md +65 -0
- package/skills/shared/wordpress/scripts/verify.sh +96 -0
- package/skills/shared/worktrees/SKILL.md +204 -0
- package/skills/shared/worktrees/evals/README.md +78 -0
- package/skills/shared/worktrees/evals/cases.yaml +47 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Anti-bot reference
|
|
2
|
+
|
|
3
|
+
Anti-bot handling is mandatory in 2026, not optional — basic Puppeteer worked in 2024, but every major site now ships detection. This covers the *legitimate* techniques: realistic fingerprints and pacing on a scrape you are entitled to run. It does **not** cover defeating a control you were shown — that is the legal line from `legal-compliance.md`, and you do not cross it.
|
|
4
|
+
|
|
5
|
+
## TLS / JA3 fingerprinting with curl_cffi
|
|
6
|
+
|
|
7
|
+
Many blocks key on the TLS/JA3/HTTP2 fingerprint, not the User-Agent. A real Chrome handshake looks different from a Python `requests` handshake regardless of headers, so spoofing the UA alone fails. `curl_cffi` impersonates a real browser's full fingerprint.
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from curl_cffi import requests
|
|
11
|
+
|
|
12
|
+
# impersonate="chrome131" sends Chrome's real TLS/JA3 + HTTP2 fingerprint
|
|
13
|
+
r = requests.get(
|
|
14
|
+
"https://example.com/listings",
|
|
15
|
+
impersonate="chrome131",
|
|
16
|
+
timeout=20,
|
|
17
|
+
)
|
|
18
|
+
r.raise_for_status()
|
|
19
|
+
html = r.text
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Use this the moment a static target returns 403 to `httpx` but 200 in a real browser — that gap is almost always fingerprinting.
|
|
23
|
+
|
|
24
|
+
## Realistic header set
|
|
25
|
+
|
|
26
|
+
Send a full, current browser header set, not a lone User-Agent. A bare `python-requests/2.x` UA is an instant tell.
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
HEADERS = {
|
|
30
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
|
31
|
+
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
32
|
+
"Chrome/131.0.0.0 Safari/537.36",
|
|
33
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
34
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
35
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
36
|
+
"Sec-Fetch-Dest": "document",
|
|
37
|
+
"Sec-Fetch-Mode": "navigate",
|
|
38
|
+
"Sec-Fetch-Site": "none",
|
|
39
|
+
"Upgrade-Insecure-Requests": "1",
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Keep the UA current — a stale Chrome version is its own tell. Refresh it when the major version moves.
|
|
44
|
+
|
|
45
|
+
## Playwright launch config
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from playwright.async_api import async_playwright
|
|
49
|
+
|
|
50
|
+
async def fetch(url: str) -> str:
|
|
51
|
+
async with async_playwright() as p:
|
|
52
|
+
browser = await p.chromium.launch(headless=True)
|
|
53
|
+
ctx = await browser.new_context(
|
|
54
|
+
user_agent=HEADERS["User-Agent"],
|
|
55
|
+
locale="en-US",
|
|
56
|
+
viewport={"width": 1366, "height": 768},
|
|
57
|
+
)
|
|
58
|
+
page = await ctx.new_page()
|
|
59
|
+
await page.goto(url, wait_until="networkidle", timeout=30_000)
|
|
60
|
+
html = await page.content()
|
|
61
|
+
await browser.close()
|
|
62
|
+
return html
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For scale, prefer Crawlee's `AdaptivePlaywrightCrawler` with browserforge fingerprints over hand-rolled stealth — it picks the cheapest mode (HTTP vs browser) per request and ships coherent fingerprints. See `frameworks.md`.
|
|
66
|
+
|
|
67
|
+
## Proxy taxonomy — when each is justified
|
|
68
|
+
|
|
69
|
+
Proxies distribute IP load and resolve geo-gating on a scrape you are entitled to run. They are not for evading a block you were explicitly shown.
|
|
70
|
+
|
|
71
|
+
| Type | Cost | Justified when |
|
|
72
|
+
|------|------|----------------|
|
|
73
|
+
| Datacenter | Lowest | High-volume scrape of a permissive target; easiest to detect/block |
|
|
74
|
+
| Residential | Medium | Geo-gated content; target blocks datacenter ranges but permits the scrape |
|
|
75
|
+
| Mobile | Highest | Mobile-only content or the strictest IP reputation requirements |
|
|
76
|
+
|
|
77
|
+
Rule: reach for a proxy to spread load or reach a geo, never to defeat a hard block. The latter is circumvention.
|
|
78
|
+
|
|
79
|
+
## CAPTCHA — the line you do not cross
|
|
80
|
+
|
|
81
|
+
A CAPTCHA is the site explicitly saying "prove you are human or do not proceed." Routing it to a solver service to keep scraping is circumventing a shown access control — exactly the posture at issue in *Reddit v. Perplexity AI* (2025), and the worst place to be legally.
|
|
82
|
+
|
|
83
|
+
When you hit a CAPTCHA or a hard block: **stop.** Re-run the legal gate. Slow down, narrow the path set, or seek permission/an API. Do not solve it.
|
|
84
|
+
|
|
85
|
+
Sources: brightdata.com "Web Scraping With curl_cffi 2026"; curl-cffi.readthedocs.io; dataresearchtools.com TLS mimicry 2026; crawlee.dev/python docs. All accessed 2026-06-02.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Frameworks reference
|
|
2
|
+
|
|
3
|
+
Copy-paste resilient starters. Match the tool to the site profile from the picker in `../SKILL.md`. Every starter assumes the legal gate already passed.
|
|
4
|
+
|
|
5
|
+
## Crawlee (Python) — resilient recurring crawler
|
|
6
|
+
|
|
7
|
+
Default for recurring jobs that must not break. The `RequestQueue` is disk-persisted, so a crash resumes from where it stopped. Per-host concurrency and pacing are config, not hand-rolled.
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
import asyncio
|
|
11
|
+
from crawlee.crawlers import PlaywrightCrawler, PlaywrightCrawlingContext
|
|
12
|
+
|
|
13
|
+
crawler = PlaywrightCrawler(
|
|
14
|
+
max_requests_per_crawl=10_000,
|
|
15
|
+
max_request_retries=4, # retries use backoff internally
|
|
16
|
+
concurrency_settings={"max_concurrency": 4}, # cap per run; pace per host below
|
|
17
|
+
request_handler_timeout_secs=45,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
@crawler.router.default_handler
|
|
21
|
+
async def handle(ctx: PlaywrightCrawlingContext) -> None:
|
|
22
|
+
title = await ctx.page.text_content('[data-testid="listing-card"] h2')
|
|
23
|
+
if not title:
|
|
24
|
+
raise LookupError(f"required field 'title' missing at {ctx.request.url}") # fail loud
|
|
25
|
+
await ctx.push_data({ # idempotent: keyed on url downstream
|
|
26
|
+
"url": ctx.request.url,
|
|
27
|
+
"title": title.strip(),
|
|
28
|
+
})
|
|
29
|
+
await ctx.enqueue_links(selector='a[href^="/listing/"]') # follow only listing links
|
|
30
|
+
|
|
31
|
+
async def main() -> None:
|
|
32
|
+
# seed from sitemap, not a blind crawl
|
|
33
|
+
await crawler.run(["https://example.com/sitemap.xml"])
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
asyncio.run(main())
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Why Crawlee for new resilient work: it wraps Playwright, rotates proxies, ships browserforge fingerprints, and the queue resumes after a crash — all the resilience patterns from `../SKILL.md` come built in instead of hand-rolled.
|
|
40
|
+
|
|
41
|
+
## Playwright direct — one-off SPA scrape
|
|
42
|
+
|
|
43
|
+
When the job is one-shot and a full crawler is overkill, but the data only exists after JS runs.
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import asyncio, random
|
|
47
|
+
from playwright.async_api import async_playwright
|
|
48
|
+
|
|
49
|
+
async def scrape(urls: list[str]) -> list[dict]:
|
|
50
|
+
out = []
|
|
51
|
+
async with async_playwright() as p:
|
|
52
|
+
browser = await p.chromium.launch(headless=True)
|
|
53
|
+
ctx = await browser.new_context(locale="en-US")
|
|
54
|
+
for url in urls:
|
|
55
|
+
page = await ctx.new_page()
|
|
56
|
+
await page.goto(url, wait_until="networkidle", timeout=30_000)
|
|
57
|
+
title = await page.text_content('[data-testid="listing-card"] h2')
|
|
58
|
+
if not title:
|
|
59
|
+
raise LookupError(f"required field 'title' missing at {url}")
|
|
60
|
+
out.append({"url": url, "title": title.strip()})
|
|
61
|
+
await page.close()
|
|
62
|
+
await asyncio.sleep(random.uniform(1.0, 3.0)) # 1-3s per host, jittered
|
|
63
|
+
await browser.close()
|
|
64
|
+
return out
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Scrapy — pure-Python static, AUTOTHROTTLE
|
|
68
|
+
|
|
69
|
+
Legacy/static targets. AUTOTHROTTLE adapts the delay to the host's response latency instead of a fixed sleep.
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
# settings.py
|
|
73
|
+
ROBOTSTXT_OBEY = True # honor robots.txt, non-negotiable
|
|
74
|
+
AUTOTHROTTLE_ENABLED = True
|
|
75
|
+
AUTOTHROTTLE_START_DELAY = 1.0 # seconds
|
|
76
|
+
AUTOTHROTTLE_MAX_DELAY = 10.0
|
|
77
|
+
AUTOTHROTTLE_TARGET_CONCURRENCY = 2.0 # keep it low, per host
|
|
78
|
+
CONCURRENT_REQUESTS_PER_DOMAIN = 4
|
|
79
|
+
DOWNLOAD_DELAY = 1.0
|
|
80
|
+
RETRY_ENABLED = True
|
|
81
|
+
RETRY_TIMES = 3 # Scrapy backs off between retries
|
|
82
|
+
DEFAULT_REQUEST_HEADERS = {"Accept-Language": "en-US,en;q=0.9"}
|
|
83
|
+
HTTPCACHE_ENABLED = True # conditional-GET style caching on re-crawl
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Pick Scrapy only for an existing Scrapy codebase or pure static targets — its Twisted core lags the asyncio ecosystem, so new resilient work goes to Crawlee.
|
|
87
|
+
|
|
88
|
+
## httpx + selectolax — static, no fingerprint wall
|
|
89
|
+
|
|
90
|
+
Cheapest path when the HTML is server-rendered and the host does not fingerprint.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import time, random, httpx
|
|
94
|
+
from selectolax.parser import HTMLParser
|
|
95
|
+
|
|
96
|
+
def scrape(urls: list[str], headers: dict) -> list[dict]:
|
|
97
|
+
out = []
|
|
98
|
+
with httpx.Client(headers=headers, timeout=20, follow_redirects=True) as c:
|
|
99
|
+
for url in urls:
|
|
100
|
+
r = c.get(url)
|
|
101
|
+
if r.status_code == 429: # honor Retry-After
|
|
102
|
+
time.sleep(int(r.headers.get("Retry-After", "30")))
|
|
103
|
+
r = c.get(url)
|
|
104
|
+
r.raise_for_status()
|
|
105
|
+
tree = HTMLParser(r.text)
|
|
106
|
+
node = tree.css_first('[data-testid="listing-card"] h2')
|
|
107
|
+
if node is None:
|
|
108
|
+
raise LookupError(f"required field 'title' missing at {url}")
|
|
109
|
+
out.append({"url": url, "title": node.text(strip=True)})
|
|
110
|
+
time.sleep(random.uniform(1.0, 3.0)) # 1-3s per host
|
|
111
|
+
return out
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If this starts returning 403 while a browser returns 200, swap `httpx` for `curl_cffi` with `impersonate="chrome131"` (see `anti-bot.md`).
|
|
115
|
+
|
|
116
|
+
Sources: crawlee.dev/python changelog; npmjs.com/package/playwright & pypi.org/project/playwright (1.60.0; 1.59 shipped 2026-04-01); use-apify.com "Crawlee vs Scrapy vs BeautifulSoup 2026". All accessed 2026-06-02.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Legal & compliance reference
|
|
2
|
+
|
|
3
|
+
Depth behind the legal gate in `../SKILL.md`. You are not a lawyer and you never claim to be — you document the basis and flag where a human must sign off.
|
|
4
|
+
|
|
5
|
+
## robots.txt and ai.txt
|
|
6
|
+
|
|
7
|
+
Fetch both before queuing URLs. `robots.txt` states crawler preferences by user-agent and path; `ai.txt` (and the `noai` / `noimageai` signals some sites publish) is the emerging objection channel for AI training use specifically.
|
|
8
|
+
|
|
9
|
+
**Neither is law.** robots.txt is a voluntary convention from 1994 with no statutory force — no jurisdiction makes a `Disallow` binding by itself, and courts treat it as evidence of the parties' expectations, not as the thing you violated. So it is input to your decision, never a hard stop. What *is* binding sits in the sections below: an accepted ToS, data-protection law, and anti-circumvention.
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
import urllib.robotparser, urllib.parse
|
|
13
|
+
|
|
14
|
+
def allowed(url: str, ua: str = "my-crawler") -> bool:
|
|
15
|
+
base = "{0.scheme}://{0.netloc}".format(urllib.parse.urlparse(url))
|
|
16
|
+
rp = urllib.robotparser.RobotFileParser()
|
|
17
|
+
rp.set_url(base + "/robots.txt")
|
|
18
|
+
rp.read() # network call; cache per host
|
|
19
|
+
return rp.can_fetch(ua, url) # False -> do not queue this URL
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Rules:
|
|
23
|
+
|
|
24
|
+
Working defaults — deviate consciously, not by accident:
|
|
25
|
+
|
|
26
|
+
- A `Disallow` for your path is the host's stated preference. Honoring it is the default and costs you little; overriding it is a judgment call you record, not a rule you break. Scraping your own property, a site you have written permission for, or public pages for research and archiving are all ordinary reasons to override.
|
|
27
|
+
- Respect `Crawl-delay` if present — it is the host telling you its tolerance, and the cheapest way to not get banned.
|
|
28
|
+
- An `ai.txt` / `noai` objection means the site objects to AI-training use. Honoring it is the cleanest evidence of good faith and matters most where the use is exactly what was objected to.
|
|
29
|
+
- Whatever you decide, log it with the scrape. "We read robots, disallowed `/search`, proceeded anyway because X" is a defensible record; silence is not.
|
|
30
|
+
|
|
31
|
+
## ToS red flags
|
|
32
|
+
|
|
33
|
+
Read the terms before scraping. The presence of any of these moves you toward **narrow** or **stop**:
|
|
34
|
+
|
|
35
|
+
- An explicit "no automated access / no scraping / no crawling" clause.
|
|
36
|
+
- Acceptance gated by **login** — accepting at sign-in is the contract hook that made *Meta v. Bright Data* a breach-of-contract case rather than a CFAA one.
|
|
37
|
+
- A clause assigning IP/database rights over the listings themselves (common on directories and aggregators).
|
|
38
|
+
- An API offered under separate commercial terms — using it routes you to `../api-connector-builder/SKILL.md` and scraping around it looks like circumvention.
|
|
39
|
+
|
|
40
|
+
## GDPR lawful-basis decision flow
|
|
41
|
+
|
|
42
|
+
Personal data = names, emails, photos, reviews, IP addresses, anything identifying a natural person. If the scrape touches any:
|
|
43
|
+
|
|
44
|
+
1. **New purpose check.** Is your purpose the same as why the data was published? Reusing public personal data for aggregation, resale, or AI training is a *new* purpose and a severe breach risk — fines reach tens of millions of EUR.
|
|
45
|
+
2. **Lawful basis.** Usually **legitimate interest** for public-data scraping — but it requires a balancing test (your interest vs. the person's reasonable expectations). Document it. See `../gdpr-privacy/SKILL.md` for the LIA.
|
|
46
|
+
3. **Minimization.** Collect only the fields the purpose needs. Drop everything else at extraction, not later.
|
|
47
|
+
4. **Special categories.** Health, politics, religion, sexual orientation, biometrics (Art. 9) — filter these out at the source. Do not collect them speculatively.
|
|
48
|
+
5. **Objection signals.** Honor robots.txt / ai.txt objections as evidence of respecting data-subject expectations.
|
|
49
|
+
|
|
50
|
+
## Minimization & retention checklist
|
|
51
|
+
|
|
52
|
+
- [ ] Field list maps 1:1 to the stated purpose — no "just in case" columns.
|
|
53
|
+
- [ ] Special categories filtered at extraction.
|
|
54
|
+
- [ ] Retention period set, with a deletion trigger (not "keep forever").
|
|
55
|
+
- [ ] Source URL + scrape timestamp recorded per record for provenance.
|
|
56
|
+
- [ ] A human owner signed off on the basis if any personal data is involved.
|
|
57
|
+
|
|
58
|
+
## Case summaries (2024-2025)
|
|
59
|
+
|
|
60
|
+
- **hiQ v. LinkedIn** — scraping *public* data is not automatically a CFAA violation. The floor, not a license; everything else (auth, contract, GDPR) still applies.
|
|
61
|
+
- **Meta v. Bright Data (2024)** — the exposure is **breach of contract** when you accepted ToS, typically by logging in. Logged-out public scraping weakens the contract claim. Lesson: stay logged-out, never bypass auth.
|
|
62
|
+
- **Reddit v. Perplexity AI (2025)** — centers on whether **rate limits and anti-bot measures were circumvented**, distinct from the public-vs-private axis. Bypassing a control you were shown (CAPTCHA, hard block, enforced limit) is materially worse than pacing public pages. Lesson: pace, do not circumvent.
|
|
63
|
+
|
|
64
|
+
Sources: groupbwt.com "Web Scraping Legal Issues: 2025 Enterprise Compliance Guide"; sociavault.com court-case roundup; promptcloud.com 2026 compliance guide; medium.com/deep-tech-insights "The €20 Million GDPR Mistake" (2025); zyte.com AI personal-data scraping guidance. All accessed 2026-06-02.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# verify.sh — compliance/resilience linter for the `data-scraper` skill.
|
|
4
|
+
#
|
|
5
|
+
# WHAT IT DOES (read-only; never edits a file)
|
|
6
|
+
# Statically lints a candidate scraper (a file or directory of source) for the
|
|
7
|
+
# four properties the skill insists on before a scrape ships. It greps source
|
|
8
|
+
# for signal patterns — it does not run the scraper or hit any network.
|
|
9
|
+
#
|
|
10
|
+
# Per-file scan of *.py *.js *.ts *.mjs *.cjs (the languages the starters use).
|
|
11
|
+
# A file with no scraping signal at all is skipped, so this never false-fails
|
|
12
|
+
# on an unrelated repo (and an empty/clean target exits 0).
|
|
13
|
+
#
|
|
14
|
+
# Checks (a FAILURE is only ever an unbounded scrape or a circumvention call —
|
|
15
|
+
# those are not judgement calls):
|
|
16
|
+
# 1. Compliance preflight present -> robots.txt / ToS / ai.txt / robotparser
|
|
17
|
+
# / ROBOTSTXT_OBEY reference somewhere in the target. (missing -> warn)
|
|
18
|
+
# 2. Per-host pacing present -> a delay/sleep/throttle/concurrency/
|
|
19
|
+
# rate-limit/Crawl-delay/AUTOTHROTTLE signal. (missing -> FAIL)
|
|
20
|
+
# 3. Retry / backoff present -> backoff/retry/Retry-After/max_retries
|
|
21
|
+
# /exponential signal. (missing -> warn)
|
|
22
|
+
# 4. No circumvention -> a CAPTCHA-solver call (2captcha,
|
|
23
|
+
# twocaptcha, anticaptcha, capsolver, deathbycaptcha, solve_captcha) or an obvious
|
|
24
|
+
# auth-bypass marker. (present -> FAIL)
|
|
25
|
+
#
|
|
26
|
+
# "Scraping signal" = the file imports/uses one of: requests, httpx, curl_cffi,
|
|
27
|
+
# playwright, crawlee, scrapy, beautifulsoup/bs4, selectolax, puppeteer, cheerio.
|
|
28
|
+
#
|
|
29
|
+
# HOW TO RUN (inside YOUR project, not the skills repo)
|
|
30
|
+
# ./verify.sh # scan ./ for scraper source
|
|
31
|
+
# ./verify.sh --path src # scan a subdirectory or a single file
|
|
32
|
+
# ./verify.sh --strict # treat any warning as a failure (exit 1)
|
|
33
|
+
#
|
|
34
|
+
# EXIT CODES
|
|
35
|
+
# 0 clean, or warnings only without --strict (also: nothing to check)
|
|
36
|
+
# 1 an unbounded scrape (no pacing) or a circumvention call, or --strict + warn
|
|
37
|
+
# 2 bad usage
|
|
38
|
+
#
|
|
39
|
+
# Runs on stock macOS bash 3.2 — no mapfile, no associative arrays.
|
|
40
|
+
|
|
41
|
+
set -euo pipefail
|
|
42
|
+
|
|
43
|
+
if [ -t 1 ]; then
|
|
44
|
+
RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m'; NC=$'\033[0m'
|
|
45
|
+
else
|
|
46
|
+
RED=''; GREEN=''; YELLOW=''; NC=''
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
ok_count=0; skip_count=0; warn_count=0; fail_count=0
|
|
50
|
+
ok() { printf '%s[ ok ]%s %s\n' "$GREEN" "$NC" "$*"; ok_count=$((ok_count + 1)); }
|
|
51
|
+
skip() { printf '%s[skip]%s %s\n' "$YELLOW" "$NC" "$*"; skip_count=$((skip_count + 1)); }
|
|
52
|
+
warn() { printf '%s[warn]%s %s\n' "$YELLOW" "$NC" "$*"; warn_count=$((warn_count + 1)); }
|
|
53
|
+
fail() { printf '%s[fail]%s %s\n' "$RED" "$NC" "$*"; fail_count=$((fail_count + 1)); }
|
|
54
|
+
|
|
55
|
+
usage() { sed -n '2,46p' "$0" | sed 's/^# \{0,1\}//'; }
|
|
56
|
+
|
|
57
|
+
SCAN_PATH="."
|
|
58
|
+
STRICT=0
|
|
59
|
+
while [ $# -gt 0 ]; do
|
|
60
|
+
case "$1" in
|
|
61
|
+
--path) SCAN_PATH="${2:?--path needs a value}"; shift 2 ;;
|
|
62
|
+
--strict) STRICT=1; shift ;;
|
|
63
|
+
-h|--help) usage; exit 0 ;;
|
|
64
|
+
*) printf '%sUnknown argument: %s%s\n\n' "$RED" "$1" "$NC"; usage; exit 2 ;;
|
|
65
|
+
esac
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
if [ ! -e "$SCAN_PATH" ]; then
|
|
69
|
+
printf '%sPath not found: %s%s\n' "$RED" "$SCAN_PATH" "$NC"; exit 2
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# --- collect candidate source files -----------------------------------------
|
|
73
|
+
TMPDIR_V="$(mktemp -d 2>/dev/null || printf '/tmp/dscrape-verify.%s' "$$")"
|
|
74
|
+
mkdir -p "$TMPDIR_V" 2>/dev/null || true
|
|
75
|
+
cleanup() { rm -rf "$TMPDIR_V" 2>/dev/null || true; }
|
|
76
|
+
trap cleanup EXIT
|
|
77
|
+
ALL="$TMPDIR_V/all"
|
|
78
|
+
TARGETS="$TMPDIR_V/targets"
|
|
79
|
+
|
|
80
|
+
find "$SCAN_PATH" -type f \
|
|
81
|
+
\( -name '*.py' -o -name '*.js' -o -name '*.ts' -o -name '*.mjs' -o -name '*.cjs' \) \
|
|
82
|
+
2>/dev/null > "$ALL" || true
|
|
83
|
+
|
|
84
|
+
if [ ! -s "$ALL" ]; then
|
|
85
|
+
skip "no source files (*.py *.js *.ts *.mjs *.cjs) under: $SCAN_PATH"
|
|
86
|
+
printf '\nok=%d skip=%d warn=%d fail=%d\n' "$ok_count" "$skip_count" "$warn_count" "$fail_count"
|
|
87
|
+
exit 0
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Keep only files that look like scrapers (import/use an HTTP/scrape library).
|
|
91
|
+
SCRAPE_LIB='requests|httpx|curl_cffi|playwright|crawlee|scrapy|bs4|beautifulsoup|selectolax|puppeteer|cheerio'
|
|
92
|
+
: > "$TARGETS"
|
|
93
|
+
while IFS= read -r f; do
|
|
94
|
+
[ -z "$f" ] && continue
|
|
95
|
+
if grep -iEq "$SCRAPE_LIB" "$f" 2>/dev/null; then
|
|
96
|
+
printf '%s\n' "$f" >> "$TARGETS"
|
|
97
|
+
fi
|
|
98
|
+
done < "$ALL"
|
|
99
|
+
|
|
100
|
+
if [ ! -s "$TARGETS" ]; then
|
|
101
|
+
skip "no scraper source detected (no requests/httpx/playwright/crawlee/scrapy/... usage)"
|
|
102
|
+
printf '\nok=%d skip=%d warn=%d fail=%d\n' "$ok_count" "$skip_count" "$warn_count" "$fail_count"
|
|
103
|
+
exit 0
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
n_targets="$(wc -l < "$TARGETS" | tr -dc '0-9')"
|
|
107
|
+
ok "scraper source detected in $n_targets file(s)"
|
|
108
|
+
|
|
109
|
+
# Helper: does ANY target file match a (case-insensitive) ERE pattern?
|
|
110
|
+
any_match() {
|
|
111
|
+
pattern="$1"
|
|
112
|
+
while IFS= read -r f; do
|
|
113
|
+
[ -z "$f" ] && continue
|
|
114
|
+
if grep -iEq "$pattern" "$f" 2>/dev/null; then return 0; fi
|
|
115
|
+
done < "$TARGETS"
|
|
116
|
+
return 1
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Helper: list target files that match (for FAIL detail).
|
|
120
|
+
list_match() {
|
|
121
|
+
pattern="$1"
|
|
122
|
+
while IFS= read -r f; do
|
|
123
|
+
[ -z "$f" ] && continue
|
|
124
|
+
if grep -iEq "$pattern" "$f" 2>/dev/null; then printf ' %s\n' "$f"; fi
|
|
125
|
+
done < "$TARGETS"
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# --- 1. compliance preflight -------------------------------------------------
|
|
129
|
+
PREFLIGHT='robots\.txt|robotstxt_obey|robotfileparser|robotparser|can_fetch|ai\.txt|terms of service|tos preflight|compliance preflight'
|
|
130
|
+
if any_match "$PREFLIGHT"; then
|
|
131
|
+
ok "compliance preflight present (robots.txt / ToS / robotparser reference)"
|
|
132
|
+
else
|
|
133
|
+
warn "no robots.txt / ToS / compliance preflight found — add the legal gate before requests"
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# --- 2. per-host pacing (the hard one) ---------------------------------------
|
|
137
|
+
PACING='download_delay|crawl[_-]?delay|autothrottle|rate[_-]?limit|ratelimit|max_concurrency|concurrent_requests|max_requests_per|throttle|time\.sleep|asyncio\.sleep|setTimeout|sleep\('
|
|
138
|
+
if any_match "$PACING"; then
|
|
139
|
+
ok "per-host pacing / concurrency cap present (delay / throttle / concurrency)"
|
|
140
|
+
else
|
|
141
|
+
fail "no rate limit, delay, or concurrency cap found — unbounded scrape will get blocked/banned:"
|
|
142
|
+
list_match "$SCRAPE_LIB"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# --- 3. retry / backoff ------------------------------------------------------
|
|
146
|
+
BACKOFF='backoff|retry|retries|retry-after|retry_after|max_request_retries|exponential|tenacity'
|
|
147
|
+
if any_match "$BACKOFF"; then
|
|
148
|
+
ok "retry / backoff present"
|
|
149
|
+
else
|
|
150
|
+
warn "no retry/backoff found — transient errors will drop records; honor 429/Retry-After"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
# --- 4. no circumvention (the other hard one) --------------------------------
|
|
154
|
+
CIRCUMVENT='2captcha|twocaptcha|anti-?captcha|anticaptcha|capsolver|deathbycaptcha|captcha[_-]?solver|solve[_-]?captcha|bypass[_-]?(auth|login|captcha|block)'
|
|
155
|
+
if any_match "$CIRCUMVENT"; then
|
|
156
|
+
fail "circumvention call detected (CAPTCHA solver / auth-or-block bypass) — this is the legal line you do not cross:"
|
|
157
|
+
list_match "$CIRCUMVENT"
|
|
158
|
+
else
|
|
159
|
+
ok "no CAPTCHA-solver / auth-bypass call detected"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
printf '\nok=%d skip=%d warn=%d fail=%d\n' "$ok_count" "$skip_count" "$warn_count" "$fail_count"
|
|
163
|
+
|
|
164
|
+
if [ "$fail_count" -gt 0 ]; then exit 1; fi
|
|
165
|
+
if [ "$STRICT" -eq 1 ] && [ "$warn_count" -gt 0 ]; then exit 1; fi
|
|
166
|
+
exit 0
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: db-migrations
|
|
3
|
+
description: "Use when a schema change must ship without downtime — NOT NULL, rename, type change, or backfilling millions of live rows — for the expand-contract sequence and the lock/batching discipline that keeps each step from freezing prod. NOT lock internals or EXPLAIN (that is `postgresdb`), NOT drizzle-kit mechanics (that is `drizzle-orm`), NOT PITR (that is `backups`)."
|
|
4
|
+
tags: [migrations, zero-downtime, expand-contract, schema, backfill, ddl]
|
|
5
|
+
recommends: [postgresdb, drizzle-orm, backups, sql, planetscale]
|
|
6
|
+
origin: ai-hub
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Database migrations without downtime
|
|
10
|
+
|
|
11
|
+
A production migration is a **sequence**, not a statement. The moment you treat `ALTER TABLE ... NOT NULL`
|
|
12
|
+
as one atomic change, you have already lost: the lock blocks every writer, the deploy that depends on the
|
|
13
|
+
new column races the deploy that still reads the old one, and a rollback means a second outage. Your job
|
|
14
|
+
is to decompose one risky change into a chain of small steps where **every intermediate state is
|
|
15
|
+
independently deployable** — the old app keeps working, the new app keeps working, and you can stop at any
|
|
16
|
+
point without an outage.
|
|
17
|
+
|
|
18
|
+
This skill is engine-neutral. It owns the *choreography* — what order to run things in and how to keep each
|
|
19
|
+
DDL from freezing the table — across Postgres, MySQL, and serverless variants, whatever runner you use
|
|
20
|
+
(Flyway, Alembic, golang-migrate, drizzle-kit, raw SQL).
|
|
21
|
+
|
|
22
|
+
## Route elsewhere
|
|
23
|
+
|
|
24
|
+
- Postgres lock internals, EXPLAIN/ANALYZE, indexing strategy, RLS, PgBouncer → `../postgresdb/SKILL.md`.
|
|
25
|
+
- Writing schema and running drizzle-kit specifically → `../drizzle-orm/SKILL.md`.
|
|
26
|
+
- PlanetScale deploy-request / branch cutover (Vitess online DDL) → `../planetscale/SKILL.md`.
|
|
27
|
+
- Creating/verifying backups, restore drills, PITR → `../backups/SKILL.md` (a migration *requires* a backup; making it lives there).
|
|
28
|
+
- Pure query logic — joins, windows, CTEs → `../sql/SKILL.md` (backfill batching is here; query correctness is there).
|
|
29
|
+
|
|
30
|
+
## Step 1 — Is this change online-safe in one step?
|
|
31
|
+
|
|
32
|
+
Most outages come from running a multi-step change as a single statement. Decide first:
|
|
33
|
+
|
|
34
|
+
| Change | One step? | Why |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| Add nullable column, no volatile default | Yes | Metadata-only on PG 11+/modern MySQL; no rewrite, no long lock. |
|
|
37
|
+
| Add column with a **constant** default | Yes (PG 11+) | Stored as a catalog default, no table rewrite. |
|
|
38
|
+
| Add column with a **volatile/expression** default | No | Rewrites every row under lock → expand-contract. |
|
|
39
|
+
| Add `NOT NULL` to existing/new column | No | Full-table validation scan under lock → add-nullable → backfill → validate. |
|
|
40
|
+
| Rename column / table | No | App reads the old name; needs dual-name window → expand-contract. |
|
|
41
|
+
| Change column type (non-trivial) | No | Rewrites rows, may invalidate the running app → new column + backfill. |
|
|
42
|
+
| Split / merge columns | No | Two-sided data move → expand-contract. |
|
|
43
|
+
| Drop column / table | No | Running app may still reference it → contract only after a cooling period. |
|
|
44
|
+
| Add foreign key | No | `ADD CONSTRAINT` validates all rows under lock → add `NOT VALID` then `VALIDATE`. |
|
|
45
|
+
| Create index | No, but cheap | Plain `CREATE INDEX` locks writes → use `CONCURRENTLY`. |
|
|
46
|
+
|
|
47
|
+
If the row says **No**, you are doing expand-contract. Go to Step 2.
|
|
48
|
+
|
|
49
|
+
## Step 2 — The expand-contract loop
|
|
50
|
+
|
|
51
|
+
Three phases, each tied to a **distinct deploy**. Worked example: rename `users.email` → `users.email_address`.
|
|
52
|
+
|
|
53
|
+
**Expand** — add the new structure, start dual-writing, leave the old one fully working.
|
|
54
|
+
|
|
55
|
+
```sql
|
|
56
|
+
-- migration 1 (deploy A): additive only, old app untouched
|
|
57
|
+
SET lock_timeout = '1s';
|
|
58
|
+
ALTER TABLE users ADD COLUMN email_address text; -- nullable, no default → metadata-only
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
App deploy A: write BOTH columns on every insert/update; keep READING email.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Backfill** — copy historical data in small background batches (Step 4), then verify counts/checksums.
|
|
66
|
+
|
|
67
|
+
**Switch reads** — once backfilled and verified, deploy the app that reads `email_address`.
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
App deploy B: read email_address; still dual-write both. ← cooling period starts here
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Contract** — only after a cooling period (hours to days) where the new app has run clean and you can
|
|
74
|
+
still roll back the app without touching schema, stop writing the old column and drop it.
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
-- migration 2 (deploy C): runs days later, after cooling period
|
|
78
|
+
SET lock_timeout = '1s';
|
|
79
|
+
ALTER TABLE users DROP COLUMN email;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The cooling period is the point. It is what lets you roll back app deploy B to app deploy A with **zero
|
|
83
|
+
schema change** — because the old column still exists and is still being written. Contracting early throws
|
|
84
|
+
that safety away.
|
|
85
|
+
|
|
86
|
+
## Step 3 — The N/N-1 rule
|
|
87
|
+
|
|
88
|
+
At every moment, two app versions can be live: the one running and the one rolling out. **The schema must
|
|
89
|
+
be compatible with both, and each app must tolerate the other's schema.** That is the entire reason
|
|
90
|
+
dual-write exists — it makes the schema a superset that satisfies app N and app N+1 simultaneously.
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
schema: +email_address ......................... -email
|
|
94
|
+
apps: [N reads email] [N+1 reads email_address] [N+2 ignores email]
|
|
95
|
+
^ both alive during rollout ^ ^ safe to drop now ^
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If you ever have a single instant where one deployed app version cannot run against the current schema,
|
|
99
|
+
your migration is not zero-downtime — it is a timed outage.
|
|
100
|
+
|
|
101
|
+
## Step 4 — Make each DDL statement safe
|
|
102
|
+
|
|
103
|
+
**Always set a short `lock_timeout` first.** A DDL waiting on a lock builds a *queue* — every query behind
|
|
104
|
+
it stalls too, and one slow ALTER freezes the whole table. A short timeout makes the migration fail fast so
|
|
105
|
+
traffic keeps flowing; you retry instead of taking the site down.
|
|
106
|
+
|
|
107
|
+
```sql
|
|
108
|
+
-- Bad: unbounded wait; if a lock is held, this queues every reader/writer behind it
|
|
109
|
+
ALTER TABLE orders ADD COLUMN region text;
|
|
110
|
+
|
|
111
|
+
-- Good: fail fast, retry
|
|
112
|
+
SET lock_timeout = '1s';
|
|
113
|
+
ALTER TABLE orders ADD COLUMN region text;
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Create indexes `CONCURRENTLY`, outside a transaction.** Plain `CREATE INDEX` takes a SHARE lock and
|
|
117
|
+
blocks all writes for its whole duration — that is the "our deploy deadlocks when we add an index" symptom.
|
|
118
|
+
`CONCURRENTLY` takes SHARE UPDATE EXCLUSIVE and does not block writes, but **cannot run inside a transaction
|
|
119
|
+
block**. Runners (Flyway, Alembic, Django, Rails) wrap each migration in a transaction by default, so you
|
|
120
|
+
must opt that step out — see `references/tools-and-runners.md`.
|
|
121
|
+
|
|
122
|
+
```sql
|
|
123
|
+
-- Bad: locks out every writer for the full build
|
|
124
|
+
CREATE INDEX idx_orders_region ON orders (region);
|
|
125
|
+
|
|
126
|
+
-- Good: non-blocking; this statement must NOT be inside BEGIN/COMMIT
|
|
127
|
+
CREATE INDEX CONCURRENTLY idx_orders_region ON orders (region);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
> A failed `CONCURRENTLY` build leaves an INVALID index behind. Drop it (`DROP INDEX CONCURRENTLY`) before
|
|
131
|
+
> retrying. For PG-specific lock-level detail, see `../postgresdb/SKILL.md`.
|
|
132
|
+
|
|
133
|
+
**Add NOT NULL in four steps, never in one.** A single `ALTER ... SET NOT NULL` (or `ADD COLUMN ... NOT
|
|
134
|
+
NULL DEFAULT <volatile>`) scans/rewrites the whole table under lock.
|
|
135
|
+
|
|
136
|
+
```sql
|
|
137
|
+
-- Bad: full-table validation/rewrite under an exclusive lock
|
|
138
|
+
ALTER TABLE users ADD COLUMN status text NOT NULL DEFAULT 'active'; -- on a 40M-row table = outage
|
|
139
|
+
|
|
140
|
+
-- Good: add nullable, backfill in batches (Step 5), then add a constraint without a blocking scan
|
|
141
|
+
SET lock_timeout = '1s';
|
|
142
|
+
ALTER TABLE users ADD COLUMN status text; -- 1. nullable
|
|
143
|
+
-- 2. backfill in batches (Step 5), app dual-writes the new column
|
|
144
|
+
ALTER TABLE users ADD CONSTRAINT users_status_nn
|
|
145
|
+
CHECK (status IS NOT NULL) NOT VALID; -- 3. instant, no scan
|
|
146
|
+
ALTER TABLE users VALIDATE CONSTRAINT users_status_nn; -- 4. scans WITHOUT blocking writes
|
|
147
|
+
-- PG 12+: a validated CHECK (col IS NOT NULL) lets SET NOT NULL skip its own scan
|
|
148
|
+
ALTER TABLE users ALTER COLUMN status SET NOT NULL;
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Same `NOT VALID` → `VALIDATE` pattern for adding a foreign key. The full per-change checklists live in
|
|
152
|
+
`references/expand-contract-playbook.md`.
|
|
153
|
+
|
|
154
|
+
## Step 5 — Backfill at scale
|
|
155
|
+
|
|
156
|
+
**Never one giant `UPDATE`.** A single statement over millions of rows holds locks, bloats WAL/undo, and
|
|
157
|
+
pins replicas behind a wall of lag. Loop bounded chunks, commit each, throttle on lag, then verify.
|
|
158
|
+
|
|
159
|
+
```sql
|
|
160
|
+
-- Bad: one statement locks rows, balloons WAL, spikes replica lag for minutes
|
|
161
|
+
UPDATE users SET email_address = email WHERE email_address IS NULL;
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```sql
|
|
165
|
+
-- Good: bounded PK-range batches, committed individually, throttled between batches
|
|
166
|
+
-- pseudo-loop (driven by your runner/script): a few thousand rows per batch
|
|
167
|
+
UPDATE users
|
|
168
|
+
SET email_address = email
|
|
169
|
+
WHERE id BETWEEN :lo AND :hi
|
|
170
|
+
AND email_address IS NULL;
|
|
171
|
+
-- commit; check replica lag; sleep if lag/error-rate is high; advance :lo/:hi; repeat
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Watch replication lag and the app error rate between batches; back off when either climbs. **Verify before
|
|
175
|
+
contracting** — row counts and a checksum of old-vs-new must match. For very large sets, snapshot + CDC
|
|
176
|
+
instead of an online loop. Postgres and MySQL backfill scripts, the lag-throttle, and checksum queries are
|
|
177
|
+
in `references/backfill-and-batching.md`.
|
|
178
|
+
|
|
179
|
+
## Step 6 — Rollback reality
|
|
180
|
+
|
|
181
|
+
**Forward-only is the prevailing 2025-2026 production stance.** Reliable `down()` migrations are rarely
|
|
182
|
+
worth the effort — whether a rollback is even safe depends on the migration type and how much time has
|
|
183
|
+
passed (data has changed under you). Treat applied migrations as immutable and **fix forward**.
|
|
184
|
+
|
|
185
|
+
Your real safety net is not a `down()` script — it is the expand-contract structure itself: because the old
|
|
186
|
+
column/table still exists during the cooling period, "rolling back" is just redeploying the previous app.
|
|
187
|
+
A reversible down-migration is only worth writing when the change is **additive-only and pre-traffic**
|
|
188
|
+
(e.g. a brand-new table no app version reads yet). For anything that touched live data, a down-migration is
|
|
189
|
+
a trap that looks like a seatbelt.
|
|
190
|
+
|
|
191
|
+
## Step 7 — Pick a runner / OSC tool
|
|
192
|
+
|
|
193
|
+
Versioned runners replay ordered scripts; declarative tools diff your target schema. Pick by stack:
|
|
194
|
+
|
|
195
|
+
| Stack / need | Tool (2026) | Note |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| JVM, SQL-first, 50+ DBs | Flyway 12.6.x | Version-based; Redgate dropped the Teams tier in 2025. |
|
|
198
|
+
| Max format flexibility | Liquibase | SQL/XML/YAML/JSON changelogs; most verbose. |
|
|
199
|
+
| Python / SQLAlchemy | Alembic 1.18.x | Requires Python ≥3.10; plugin system since 1.18.0. |
|
|
200
|
+
| Go | golang-migrate | The Go standard. |
|
|
201
|
+
| TypeScript / Drizzle | drizzle-kit | Mechanics in `../drizzle-orm/SKILL.md`; safety sequence here. |
|
|
202
|
+
| Schema-as-code, planned diffs | Atlas | Declarative — you give the target, it plans the diff. |
|
|
203
|
+
| Big MySQL ALTER, native online DDL can't keep it online | gh-ost or pt-osc | See below. |
|
|
204
|
+
|
|
205
|
+
**gh-ost vs pt-osc** for a large MySQL ALTER: **gh-ost** is triggerless — it copies in chunks and replays
|
|
206
|
+
the binlog, throttles on replica lag, and gives easier pause/cutover control; prefer it on a very busy
|
|
207
|
+
master. **pt-osc** is trigger-based — strictly consistent, but the triggers add write overhead and can fail
|
|
208
|
+
to acquire the metadata lock under highly concurrent or long-transaction load. Decision detail and
|
|
209
|
+
per-runner transaction opt-out in `references/tools-and-runners.md`.
|
|
210
|
+
|
|
211
|
+
## Step 8 — Gate migrations in CI
|
|
212
|
+
|
|
213
|
+
Add a static linter for migration SQL **before merge**, so a bare `CREATE INDEX` or a one-shot `NOT NULL`
|
|
214
|
+
never reaches review. **Squawk** is the standard for Postgres migration SQL — it flags adding NOT NULL
|
|
215
|
+
columns, non-concurrent index creation, blocking constraint adds, and column drops.
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
# CI step: fail the PR on dangerous migration DDL
|
|
219
|
+
- name: Lint migrations
|
|
220
|
+
run: npx squawk@latest migrations/*.sql
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Config snippet and rule notes in `references/tools-and-runners.md`. `scripts/verify.sh` in this skill runs
|
|
224
|
+
the same static checks against the example migrations shipped in `references/`.
|
|
225
|
+
|
|
226
|
+
## Anti-patterns
|
|
227
|
+
|
|
228
|
+
| Anti-pattern | Why it hurts | Do instead |
|
|
229
|
+
|---|---|---|
|
|
230
|
+
| `ALTER TABLE ... ADD COLUMN ... NOT NULL DEFAULT <expr>` on a big table | Full-table rewrite under lock = outage | add nullable → backfill → `NOT VALID` → `VALIDATE` (Step 4) |
|
|
231
|
+
| Plain `CREATE INDEX` in prod | SHARE lock blocks all writes for the build → deploy "deadlock" | `CREATE INDEX CONCURRENTLY`, outside a transaction |
|
|
232
|
+
| DDL with no `lock_timeout` | Builds a lock queue; one slow ALTER freezes the table | `SET lock_timeout='1s'` first, fail fast, retry |
|
|
233
|
+
| One giant backfill `UPDATE` | Locks rows, bloats WAL, spikes replica lag | bounded batches, commit each, throttle on lag (Step 5) |
|
|
234
|
+
| Renaming a column the running app still reads | Instant errors for app version N | dual-name window: add new, dual-write, switch reads, then drop |
|
|
235
|
+
| Contracting before the cooling period | Kills your no-schema-change rollback path | wait until the new app has run clean; then drop |
|
|
236
|
+
| Relying on `down()` in prod | Data already changed; rollback is unsafe or wrong | forward-only; expand-contract IS the rollback (Step 6) |
|
|
237
|
+
| Coupling app + schema in one deploy | Breaks N/N-1; an instant where some app can't run | separate deploys; schema is a superset of both (Step 3) |
|