@ketecode/loom 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/README.md +616 -2
- package/agents/accessibility-reviewer/AGENT.md +70 -0
- package/agents/accessibility-reviewer/evals/triggers.json +15 -0
- package/agents/agent-evaluator/AGENT.md +74 -0
- package/agents/agent-evaluator/evals/triggers.json +15 -0
- package/agents/architect/AGENT.md +82 -0
- package/agents/architect/evals/triggers.json +17 -0
- package/agents/billing-reviewer/AGENT.md +68 -0
- package/agents/billing-reviewer/evals/triggers.json +16 -0
- package/agents/code-reviewer/AGENT.md +51 -0
- package/agents/code-reviewer/evals/behavior.json +60 -0
- package/agents/code-reviewer/evals/triggers.json +14 -0
- package/agents/code-simplifier/AGENT.md +74 -0
- package/agents/code-simplifier/evals/triggers.json +15 -0
- package/agents/cpp-build-resolver/AGENT.md +73 -0
- package/agents/cpp-build-resolver/evals/triggers.json +16 -0
- package/agents/cpp-reviewer/AGENT.md +59 -0
- package/agents/cpp-reviewer/evals/triggers.json +16 -0
- package/agents/csharp-build-resolver/AGENT.md +84 -0
- package/agents/csharp-build-resolver/evals/triggers.json +17 -0
- package/agents/csharp-reviewer/AGENT.md +88 -0
- package/agents/csharp-reviewer/evals/triggers.json +17 -0
- package/agents/dart-build-resolver/AGENT.md +80 -0
- package/agents/dart-build-resolver/evals/triggers.json +17 -0
- package/agents/dart-reviewer/AGENT.md +66 -0
- package/agents/dart-reviewer/evals/triggers.json +17 -0
- package/agents/database-reviewer/AGENT.md +72 -0
- package/agents/database-reviewer/evals/triggers.json +16 -0
- package/agents/django-reviewer/AGENT.md +61 -0
- package/agents/django-reviewer/evals/triggers.json +15 -0
- package/agents/doc-updater/AGENT.md +92 -0
- package/agents/doc-updater/evals/triggers.json +14 -0
- package/agents/e2e-runner/AGENT.md +88 -0
- package/agents/e2e-runner/evals/triggers.json +16 -0
- package/agents/fastapi-reviewer/AGENT.md +63 -0
- package/agents/fastapi-reviewer/evals/triggers.json +15 -0
- package/agents/flutter-reviewer/AGENT.md +70 -0
- package/agents/flutter-reviewer/evals/triggers.json +15 -0
- package/agents/fsharp-build-resolver/AGENT.md +81 -0
- package/agents/fsharp-build-resolver/evals/triggers.json +15 -0
- package/agents/fsharp-reviewer/AGENT.md +77 -0
- package/agents/fsharp-reviewer/evals/triggers.json +15 -0
- package/agents/go-build-resolver/AGENT.md +85 -0
- package/agents/go-build-resolver/evals/triggers.json +16 -0
- package/agents/go-reviewer/AGENT.md +66 -0
- package/agents/go-reviewer/evals/triggers.json +16 -0
- package/agents/healthcare-reviewer/AGENT.md +65 -0
- package/agents/healthcare-reviewer/evals/triggers.json +16 -0
- package/agents/i18n-reviewer/AGENT.md +64 -0
- package/agents/i18n-reviewer/evals/triggers.json +16 -0
- package/agents/inbox-triager/AGENT.md +98 -0
- package/agents/inbox-triager/evals/triggers.json +16 -0
- package/agents/infra-reviewer/AGENT.md +93 -0
- package/agents/infra-reviewer/evals/triggers.json +15 -0
- package/agents/java-build-resolver/AGENT.md +82 -0
- package/agents/java-build-resolver/evals/triggers.json +16 -0
- package/agents/java-reviewer/AGENT.md +64 -0
- package/agents/java-reviewer/evals/triggers.json +16 -0
- package/agents/kotlin-build-resolver/AGENT.md +89 -0
- package/agents/kotlin-build-resolver/evals/triggers.json +16 -0
- package/agents/kotlin-reviewer/AGENT.md +75 -0
- package/agents/kotlin-reviewer/evals/triggers.json +16 -0
- package/agents/mle-reviewer/AGENT.md +68 -0
- package/agents/mle-reviewer/evals/triggers.json +16 -0
- package/agents/network-config-reviewer/AGENT.md +68 -0
- package/agents/network-config-reviewer/evals/triggers.json +17 -0
- package/agents/payments-reviewer/AGENT.md +64 -0
- package/agents/payments-reviewer/evals/triggers.json +16 -0
- package/agents/performance-optimizer/AGENT.md +86 -0
- package/agents/performance-optimizer/evals/triggers.json +16 -0
- package/agents/perl-build-resolver/AGENT.md +84 -0
- package/agents/perl-build-resolver/evals/triggers.json +15 -0
- package/agents/perl-reviewer/AGENT.md +77 -0
- package/agents/perl-reviewer/evals/triggers.json +15 -0
- package/agents/php-build-resolver/AGENT.md +88 -0
- package/agents/php-build-resolver/evals/triggers.json +16 -0
- package/agents/php-reviewer/AGENT.md +61 -0
- package/agents/php-reviewer/evals/triggers.json +15 -0
- package/agents/planner/AGENT.md +75 -0
- package/agents/planner/evals/triggers.json +17 -0
- package/agents/pr-test-analyzer/AGENT.md +82 -0
- package/agents/pr-test-analyzer/evals/triggers.json +16 -0
- package/agents/python-build-resolver/AGENT.md +87 -0
- package/agents/python-build-resolver/evals/triggers.json +16 -0
- package/agents/python-reviewer/AGENT.md +63 -0
- package/agents/python-reviewer/evals/triggers.json +15 -0
- package/agents/rag-reviewer/AGENT.md +71 -0
- package/agents/rag-reviewer/evals/triggers.json +16 -0
- package/agents/react-reviewer/AGENT.md +70 -0
- package/agents/react-reviewer/evals/triggers.json +16 -0
- package/agents/refactor-cleaner/AGENT.md +82 -0
- package/agents/refactor-cleaner/evals/triggers.json +16 -0
- package/agents/ruby-build-resolver/AGENT.md +93 -0
- package/agents/ruby-build-resolver/evals/triggers.json +16 -0
- package/agents/ruby-reviewer/AGENT.md +62 -0
- package/agents/ruby-reviewer/evals/triggers.json +16 -0
- package/agents/rust-build-resolver/AGENT.md +98 -0
- package/agents/rust-build-resolver/evals/triggers.json +16 -0
- package/agents/rust-reviewer/AGENT.md +78 -0
- package/agents/rust-reviewer/evals/triggers.json +15 -0
- package/agents/security-reviewer/AGENT.md +84 -0
- package/agents/security-reviewer/evals/triggers.json +16 -0
- package/agents/silent-failure-hunter/AGENT.md +66 -0
- package/agents/silent-failure-hunter/evals/triggers.json +16 -0
- package/agents/solidity-reviewer/AGENT.md +70 -0
- package/agents/solidity-reviewer/evals/triggers.json +16 -0
- package/agents/spec-reviewer/AGENT.md +95 -0
- package/agents/spec-reviewer/evals/behavior.json +57 -0
- package/agents/spec-reviewer/evals/triggers.json +16 -0
- package/agents/swift-build-resolver/AGENT.md +85 -0
- package/agents/swift-build-resolver/evals/triggers.json +15 -0
- package/agents/swift-reviewer/AGENT.md +75 -0
- package/agents/swift-reviewer/evals/triggers.json +15 -0
- package/agents/task-implementer/AGENT.md +89 -0
- package/agents/task-implementer/evals/behavior.json +47 -0
- package/agents/task-implementer/evals/triggers.json +16 -0
- package/agents/typescript-build-resolver/AGENT.md +76 -0
- package/agents/typescript-build-resolver/evals/triggers.json +15 -0
- package/agents/typescript-reviewer/AGENT.md +76 -0
- package/agents/typescript-reviewer/evals/triggers.json +15 -0
- package/agents/vue-reviewer/AGENT.md +75 -0
- package/agents/vue-reviewer/evals/triggers.json +15 -0
- package/bin/kete-loom.js +723 -0
- package/commands/aside.md +19 -0
- package/commands/brainstorm.md +25 -0
- package/commands/build-fix.md +26 -0
- package/commands/campaign.md +19 -0
- package/commands/changelog.md +36 -0
- package/commands/checkpoint.md +26 -0
- package/commands/codemap.md +25 -0
- package/commands/commit.md +26 -0
- package/commands/debug.md +27 -0
- package/commands/deps-audit.md +32 -0
- package/commands/dual-review.md +34 -0
- package/commands/epic-decompose.md +21 -0
- package/commands/explain.md +37 -0
- package/commands/feature-dev.md +23 -0
- package/commands/finish-branch.md +26 -0
- package/commands/fix-bug.md +38 -0
- package/commands/hookify.md +23 -0
- package/commands/i18n-check.md +39 -0
- package/commands/issue-sync.md +22 -0
- package/commands/jira.md +19 -0
- package/commands/learn.md +23 -0
- package/commands/loom.md +21 -0
- package/commands/loop.md +20 -0
- package/commands/model-route.md +27 -0
- package/commands/onboard.md +35 -0
- package/commands/orchestrate.md +21 -0
- package/commands/plan-feature.md +36 -0
- package/commands/postmortem.md +42 -0
- package/commands/pr-describe.md +39 -0
- package/commands/pr.md +22 -0
- package/commands/prd.md +41 -0
- package/commands/production-readiness.md +45 -0
- package/commands/project-init.md +21 -0
- package/commands/refactor-clean.md +24 -0
- package/commands/resume-session.md +22 -0
- package/commands/review.md +35 -0
- package/commands/save-session.md +37 -0
- package/commands/security-scan.md +32 -0
- package/commands/sessions.md +21 -0
- package/commands/skill-create.md +21 -0
- package/commands/tdd.md +36 -0
- package/commands/test-coverage.md +24 -0
- package/commands/threat-model.md +36 -0
- package/commands/update-docs.md +25 -0
- package/commands/usage-report.md +43 -0
- package/commands/verify.md +21 -0
- package/hooks/block-dangerous-commands/HOOK.md +30 -0
- package/hooks/block-dangerous-commands/cases.json +50 -0
- package/hooks/block-dangerous-commands/hook.js +75 -0
- package/hooks/block-foreground-servers/HOOK.md +34 -0
- package/hooks/block-foreground-servers/cases.json +31 -0
- package/hooks/block-foreground-servers/hook.js +41 -0
- package/hooks/block-no-verify/HOOK.md +25 -0
- package/hooks/block-no-verify/cases.json +30 -0
- package/hooks/block-no-verify/hook.js +43 -0
- package/hooks/capture-lessons/HOOK.md +24 -0
- package/hooks/capture-lessons/hook.js +48 -0
- package/hooks/format-on-edit/HOOK.md +24 -0
- package/hooks/format-on-edit/hook.js +89 -0
- package/hooks/guard-secrets/HOOK.md +19 -0
- package/hooks/guard-secrets/cases.json +110 -0
- package/hooks/guard-secrets/hook.js +44 -0
- package/hooks/load-session-context/HOOK.md +20 -0
- package/hooks/load-session-context/hook.js +56 -0
- package/hooks/notify-on-stop/HOOK.md +25 -0
- package/hooks/notify-on-stop/hook.js +27 -0
- package/hooks/protect-files/HOOK.md +24 -0
- package/hooks/protect-files/cases.json +27 -0
- package/hooks/protect-files/hook.js +39 -0
- package/hooks/protect-lint-config/HOOK.md +29 -0
- package/hooks/protect-lint-config/cases.json +18 -0
- package/hooks/protect-lint-config/fixtures/.eslintrc.json +1 -0
- package/hooks/protect-lint-config/fixtures/.golangci.yml +1 -0
- package/hooks/protect-lint-config/fixtures/.prettierrc +1 -0
- package/hooks/protect-lint-config/fixtures/.rubocop.yml +1 -0
- package/hooks/protect-lint-config/fixtures/biome.json +1 -0
- package/hooks/protect-lint-config/fixtures/eslint.config.mjs +1 -0
- package/hooks/protect-lint-config/fixtures/ruff.toml +1 -0
- package/hooks/protect-lint-config/hook.js +25 -0
- package/hooks/read-before-edit/HOOK.md +26 -0
- package/hooks/read-before-edit/cases.json +15 -0
- package/hooks/read-before-edit/hook.js +50 -0
- package/hooks/run.js +148 -0
- package/hooks/verify-before-stop/HOOK.md +32 -0
- package/hooks/verify-before-stop/hook.js +70 -0
- package/mcp/atlassian.json +11 -0
- package/mcp/chrome-devtools.json +18 -0
- package/mcp/clickhouse.json +11 -0
- package/mcp/cloudflare.json +11 -0
- package/mcp/context7.json +11 -0
- package/mcp/exa.json +11 -0
- package/mcp/fetch.json +17 -0
- package/mcp/figma.json +11 -0
- package/mcp/firecrawl.json +11 -0
- package/mcp/git.json +17 -0
- package/mcp/github.json +11 -0
- package/mcp/linear.json +11 -0
- package/mcp/memory.json +18 -0
- package/mcp/notion.json +11 -0
- package/mcp/playwright.json +18 -0
- package/mcp/sentry.json +11 -0
- package/mcp/stripe.json +11 -0
- package/mcp/supabase.json +11 -0
- package/mcp/time.json +17 -0
- package/mcp/vercel.json +11 -0
- package/package.json +61 -4
- package/profiles.json +214 -0
- package/rules/common.md +21 -0
- package/rules/cpp.md +29 -0
- package/rules/csharp.md +25 -0
- package/rules/dart.md +29 -0
- package/rules/fsharp.md +28 -0
- package/rules/git.md +26 -0
- package/rules/go.md +29 -0
- package/rules/java.md +29 -0
- package/rules/kotlin.md +27 -0
- package/rules/perl.md +26 -0
- package/rules/php.md +28 -0
- package/rules/python.md +30 -0
- package/rules/ruby.md +27 -0
- package/rules/rust.md +26 -0
- package/rules/security.md +29 -0
- package/rules/swift.md +28 -0
- package/rules/testing.md +25 -0
- package/rules/typescript.md +29 -0
- package/rules/use-skills.md +23 -0
- package/schemas/skill-frontmatter.schema.json +52 -0
- package/scripts/lib/audit.js +96 -0
- package/scripts/lib/behavior.js +52 -0
- package/scripts/lib/frontmatter.js +65 -0
- package/scripts/lib/hooks-install.js +294 -0
- package/scripts/lib/i18n.js +51 -0
- package/scripts/lib/inventory.js +85 -0
- package/scripts/lib/lint.js +180 -0
- package/scripts/lib/mcp-install.js +288 -0
- package/scripts/lib/profiles.js +128 -0
- package/scripts/lib/render.js +92 -0
- package/scripts/lib/rules-install.js +118 -0
- package/scripts/lib/skills.js +87 -0
- package/scripts/lib/targets.js +123 -0
- package/skills/accounting-api-integration/SKILL.md +81 -0
- package/skills/accounting-api-integration/evals/triggers.json +17 -0
- package/skills/accounting-api-integration/references/quickbooks.md +48 -0
- package/skills/accounting-api-integration/references/xero.md +45 -0
- package/skills/agent-failure-debugging/SKILL.md +92 -0
- package/skills/agent-failure-debugging/evals/triggers.json +16 -0
- package/skills/agent-harness-design/SKILL.md +125 -0
- package/skills/agent-harness-design/evals/triggers.json +21 -0
- package/skills/agent-outbound-messaging/SKILL.md +92 -0
- package/skills/agent-outbound-messaging/evals/triggers.json +16 -0
- package/skills/agent-security/SKILL.md +117 -0
- package/skills/agent-security/evals/triggers.json +16 -0
- package/skills/agent-security/references/host-configs.md +37 -0
- package/skills/ai-media-generation/SKILL.md +89 -0
- package/skills/ai-media-generation/evals/triggers.json +16 -0
- package/skills/ai-media-generation/references/job-pipeline.md +76 -0
- package/skills/angular-patterns/SKILL.md +122 -0
- package/skills/angular-patterns/evals/triggers.json +16 -0
- package/skills/api-client-integration/SKILL.md +86 -0
- package/skills/api-client-integration/evals/triggers.json +16 -0
- package/skills/api-client-integration/references/resilience.md +57 -0
- package/skills/api-design/SKILL.md +96 -0
- package/skills/api-design/evals/triggers.json +18 -0
- package/skills/api-design/references/conventions.md +133 -0
- package/skills/architecture-decision-records/SKILL.md +98 -0
- package/skills/architecture-decision-records/evals/triggers.json +17 -0
- package/skills/article-writing/SKILL.md +108 -0
- package/skills/article-writing/evals/triggers.json +16 -0
- package/skills/aspnet-core-patterns/SKILL.md +149 -0
- package/skills/aspnet-core-patterns/evals/triggers.json +16 -0
- package/skills/auth-patterns/SKILL.md +104 -0
- package/skills/auth-patterns/evals/triggers.json +17 -0
- package/skills/auth-patterns/references/oauth-oidc.md +64 -0
- package/skills/autonomous-loops/SKILL.md +99 -0
- package/skills/autonomous-loops/evals/triggers.json +14 -0
- package/skills/aws-patterns/SKILL.md +91 -0
- package/skills/aws-patterns/evals/triggers.json +16 -0
- package/skills/azure-patterns/SKILL.md +86 -0
- package/skills/azure-patterns/evals/triggers.json +16 -0
- package/skills/benchmark-methodology/SKILL.md +88 -0
- package/skills/benchmark-methodology/evals/triggers.json +16 -0
- package/skills/benchmark-methodology/references/language-harnesses.md +130 -0
- package/skills/bgp-diagnostics/SKILL.md +84 -0
- package/skills/bgp-diagnostics/evals/triggers.json +18 -0
- package/skills/bgp-diagnostics/references/bgp-reference.md +81 -0
- package/skills/bioinformatics-workflows/SKILL.md +108 -0
- package/skills/bioinformatics-workflows/evals/triggers.json +16 -0
- package/skills/bioinformatics-workflows/references/commands.md +71 -0
- package/skills/bioinformatics-workflows/references/formats.md +24 -0
- package/skills/bioinformatics-workflows/references/workflow-managers.md +107 -0
- package/skills/blender-automation/SKILL.md +100 -0
- package/skills/blender-automation/evals/triggers.json +16 -0
- package/skills/blender-automation/references/batch-and-render.md +77 -0
- package/skills/blender-automation/references/bpy-inspection.md +91 -0
- package/skills/blender-automation/references/rig-and-retarget-checks.md +23 -0
- package/skills/brand-strategy/SKILL.md +83 -0
- package/skills/brand-strategy/evals/triggers.json +16 -0
- package/skills/brand-voice/SKILL.md +112 -0
- package/skills/brand-voice/evals/triggers.json +16 -0
- package/skills/browser-qa/SKILL.md +99 -0
- package/skills/browser-qa/evals/triggers.json +16 -0
- package/skills/bun-runtime/SKILL.md +93 -0
- package/skills/bun-runtime/evals/triggers.json +16 -0
- package/skills/change-impact-analysis/SKILL.md +89 -0
- package/skills/change-impact-analysis/evals/triggers.json +16 -0
- package/skills/change-impact-analysis/references/graph-commands.md +28 -0
- package/skills/cisco-ios-config/SKILL.md +101 -0
- package/skills/cisco-ios-config/evals/triggers.json +18 -0
- package/skills/cisco-ios-config/references/verification.md +63 -0
- package/skills/clickhouse-patterns/SKILL.md +101 -0
- package/skills/clickhouse-patterns/evals/triggers.json +18 -0
- package/skills/clickhouse-patterns/references/engines-and-views.md +138 -0
- package/skills/clinical-decision-support/SKILL.md +90 -0
- package/skills/clinical-decision-support/evals/triggers.json +16 -0
- package/skills/clinical-decision-support/references/cds-hooks.md +76 -0
- package/skills/clinical-decision-support/references/regulatory-boundaries.md +37 -0
- package/skills/code-tour/SKILL.md +97 -0
- package/skills/code-tour/evals/triggers.json +14 -0
- package/skills/codebase-onboarding/SKILL.md +112 -0
- package/skills/codebase-onboarding/evals/triggers.json +14 -0
- package/skills/cold-outreach-sequences/SKILL.md +90 -0
- package/skills/cold-outreach-sequences/evals/triggers.json +16 -0
- package/skills/content-repurposing/SKILL.md +82 -0
- package/skills/content-repurposing/evals/triggers.json +16 -0
- package/skills/context-budget/SKILL.md +84 -0
- package/skills/context-budget/evals/triggers.json +14 -0
- package/skills/contract-drafting/SKILL.md +96 -0
- package/skills/contract-drafting/evals/triggers.json +16 -0
- package/skills/contract-drafting/references/term-sheets.md +68 -0
- package/skills/contract-first-development/SKILL.md +86 -0
- package/skills/contract-first-development/evals/triggers.json +16 -0
- package/skills/contract-first-development/references/tooling.md +46 -0
- package/skills/conventional-commits/SKILL.md +144 -0
- package/skills/conventional-commits/evals/triggers.json +16 -0
- package/skills/cpp-patterns/SKILL.md +129 -0
- package/skills/cpp-patterns/evals/triggers.json +16 -0
- package/skills/cpp-patterns/references/cmake-and-tooling.md +88 -0
- package/skills/cpp-patterns/references/undefined-behaviour.md +75 -0
- package/skills/cpp-testing/SKILL.md +131 -0
- package/skills/cpp-testing/evals/triggers.json +16 -0
- package/skills/csharp-patterns/SKILL.md +110 -0
- package/skills/csharp-patterns/evals/triggers.json +17 -0
- package/skills/csharp-patterns/references/analyzers.md +59 -0
- package/skills/csharp-testing/SKILL.md +85 -0
- package/skills/csharp-testing/evals/triggers.json +17 -0
- package/skills/csharp-testing/references/integration-tests.md +77 -0
- package/skills/css-architecture/SKILL.md +143 -0
- package/skills/css-architecture/evals/triggers.json +16 -0
- package/skills/customs-trade-compliance/SKILL.md +95 -0
- package/skills/customs-trade-compliance/evals/triggers.json +16 -0
- package/skills/customs-trade-compliance/references/incoterms-2020.md +42 -0
- package/skills/dart-patterns/SKILL.md +157 -0
- package/skills/dart-patterns/evals/triggers.json +18 -0
- package/skills/dart-testing/SKILL.md +164 -0
- package/skills/dart-testing/evals/triggers.json +18 -0
- package/skills/data-analysis-notebooks/SKILL.md +113 -0
- package/skills/data-analysis-notebooks/evals/triggers.json +16 -0
- package/skills/data-analysis-notebooks/references/dataframe-pitfalls.md +49 -0
- package/skills/data-analysis-notebooks/references/statistics-pitfalls.md +24 -0
- package/skills/data-pipelines/SKILL.md +90 -0
- package/skills/data-pipelines/evals/triggers.json +16 -0
- package/skills/data-pipelines/references/orchestrators.md +64 -0
- package/skills/database-migrations/SKILL.md +102 -0
- package/skills/database-migrations/evals/triggers.json +16 -0
- package/skills/database-migrations/references/recipes.md +98 -0
- package/skills/database-migrations/references/tools.md +21 -0
- package/skills/dbt-patterns/SKILL.md +96 -0
- package/skills/dbt-patterns/evals/triggers.json +16 -0
- package/skills/dbt-patterns/references/yaml-examples.md +114 -0
- package/skills/decision-council/SKILL.md +98 -0
- package/skills/decision-council/evals/triggers.json +16 -0
- package/skills/deep-research/SKILL.md +107 -0
- package/skills/deep-research/evals/triggers.json +14 -0
- package/skills/dependency-audit/SKILL.md +103 -0
- package/skills/dependency-audit/evals/triggers.json +16 -0
- package/skills/dependency-audit/references/tools.md +124 -0
- package/skills/deployment-strategies/SKILL.md +108 -0
- package/skills/deployment-strategies/evals/triggers.json +16 -0
- package/skills/design-brainstorming/SKILL.md +132 -0
- package/skills/design-brainstorming/evals/behavior.json +55 -0
- package/skills/design-brainstorming/evals/triggers.json +16 -0
- package/skills/design-brainstorming/references/visual-mockups.md +34 -0
- package/skills/desktop-app-testing/SKILL.md +104 -0
- package/skills/desktop-app-testing/evals/triggers.json +16 -0
- package/skills/desktop-app-testing/references/drivers.md +81 -0
- package/skills/django-patterns/SKILL.md +123 -0
- package/skills/django-patterns/evals/triggers.json +16 -0
- package/skills/docker-patterns/SKILL.md +132 -0
- package/skills/docker-patterns/evals/triggers.json +16 -0
- package/skills/docker-patterns/references/dockerfiles.md +105 -0
- package/skills/document-processing/SKILL.md +100 -0
- package/skills/document-processing/evals/triggers.json +17 -0
- package/skills/document-processing/references/extraction-and-ocr.md +71 -0
- package/skills/document-processing/references/forms-and-conversion.md +69 -0
- package/skills/document-processing/references/redaction.md +61 -0
- package/skills/e2e-testing-playwright/SKILL.md +94 -0
- package/skills/e2e-testing-playwright/evals/triggers.json +16 -0
- package/skills/e2e-testing-playwright/references/config-and-ci.md +129 -0
- package/skills/ef-core-patterns/SKILL.md +117 -0
- package/skills/ef-core-patterns/evals/triggers.json +16 -0
- package/skills/email-deliverability/SKILL.md +99 -0
- package/skills/email-deliverability/evals/triggers.json +17 -0
- package/skills/email-deliverability/references/dns-records.md +85 -0
- package/skills/energy-procurement/SKILL.md +106 -0
- package/skills/energy-procurement/evals/triggers.json +16 -0
- package/skills/error-handling-patterns/SKILL.md +112 -0
- package/skills/error-handling-patterns/evals/triggers.json +18 -0
- package/skills/error-handling-patterns/references/language-idioms.md +49 -0
- package/skills/estimation-and-scoping/SKILL.md +97 -0
- package/skills/estimation-and-scoping/evals/triggers.json +14 -0
- package/skills/evm-dapp-integration/SKILL.md +73 -0
- package/skills/evm-dapp-integration/evals/triggers.json +16 -0
- package/skills/fastapi-patterns/SKILL.md +127 -0
- package/skills/fastapi-patterns/evals/triggers.json +16 -0
- package/skills/ffmpeg-media-processing/SKILL.md +94 -0
- package/skills/ffmpeg-media-processing/evals/triggers.json +16 -0
- package/skills/ffmpeg-media-processing/references/recipes.md +112 -0
- package/skills/fhir-integration/SKILL.md +81 -0
- package/skills/fhir-integration/evals/triggers.json +16 -0
- package/skills/fhir-integration/references/search-and-bundles.md +73 -0
- package/skills/fhir-integration/references/smart-on-fhir.md +50 -0
- package/skills/finishing-a-branch/SKILL.md +127 -0
- package/skills/finishing-a-branch/evals/behavior.json +49 -0
- package/skills/finishing-a-branch/evals/triggers.json +16 -0
- package/skills/flask-patterns/SKILL.md +132 -0
- package/skills/flask-patterns/evals/triggers.json +16 -0
- package/skills/flutter-patterns/SKILL.md +99 -0
- package/skills/flutter-patterns/evals/triggers.json +16 -0
- package/skills/flutterwave-integration/SKILL.md +75 -0
- package/skills/flutterwave-integration/evals/triggers.json +16 -0
- package/skills/flutterwave-integration/references/api.md +73 -0
- package/skills/flutterwave-integration/references/webhooks.md +49 -0
- package/skills/freight-carrier-management/SKILL.md +107 -0
- package/skills/freight-carrier-management/evals/triggers.json +16 -0
- package/skills/fsharp-patterns/SKILL.md +133 -0
- package/skills/fsharp-patterns/evals/triggers.json +16 -0
- package/skills/fsharp-testing/SKILL.md +136 -0
- package/skills/fsharp-testing/evals/triggers.json +16 -0
- package/skills/gcp-patterns/SKILL.md +86 -0
- package/skills/gcp-patterns/evals/triggers.json +16 -0
- package/skills/git-workflow/SKILL.md +114 -0
- package/skills/git-workflow/evals/triggers.json +16 -0
- package/skills/git-worktrees/SKILL.md +130 -0
- package/skills/git-worktrees/evals/behavior.json +56 -0
- package/skills/git-worktrees/evals/triggers.json +16 -0
- package/skills/github-actions-ci/SKILL.md +117 -0
- package/skills/github-actions-ci/evals/triggers.json +16 -0
- package/skills/github-api-automation/SKILL.md +101 -0
- package/skills/github-api-automation/evals/triggers.json +17 -0
- package/skills/go-patterns/SKILL.md +118 -0
- package/skills/go-patterns/evals/triggers.json +17 -0
- package/skills/go-patterns/references/concurrency.md +162 -0
- package/skills/go-testing/SKILL.md +154 -0
- package/skills/go-testing/evals/triggers.json +17 -0
- package/skills/google-workspace-integration/SKILL.md +65 -0
- package/skills/google-workspace-integration/evals/triggers.json +17 -0
- package/skills/google-workspace-integration/references/api.md +121 -0
- package/skills/harmonyos-arkts/SKILL.md +117 -0
- package/skills/harmonyos-arkts/evals/triggers.json +16 -0
- package/skills/harmonyos-arkts/references/build-errors.md +42 -0
- package/skills/hexagonal-architecture/SKILL.md +89 -0
- package/skills/hexagonal-architecture/evals/triggers.json +17 -0
- package/skills/hipaa-compliance/SKILL.md +91 -0
- package/skills/hipaa-compliance/evals/triggers.json +18 -0
- package/skills/hipaa-compliance/references/safeguards.md +68 -0
- package/skills/hl7v2-integration/SKILL.md +69 -0
- package/skills/hl7v2-integration/evals/triggers.json +16 -0
- package/skills/hl7v2-integration/references/messages-and-ack.md +78 -0
- package/skills/homelab-network-setup/SKILL.md +125 -0
- package/skills/homelab-network-setup/evals/triggers.json +18 -0
- package/skills/homelab-network-setup/references/firewall-and-dns.md +45 -0
- package/skills/homelab-network-setup/references/wireguard.md +72 -0
- package/skills/hubtel-integration/SKILL.md +77 -0
- package/skills/hubtel-integration/evals/triggers.json +16 -0
- package/skills/hubtel-integration/references/api.md +92 -0
- package/skills/i18n-localization/SKILL.md +114 -0
- package/skills/i18n-localization/evals/triggers.json +16 -0
- package/skills/i18n-localization/references/libraries.md +52 -0
- package/skills/implementation-plans/SKILL.md +117 -0
- package/skills/implementation-plans/evals/behavior.json +54 -0
- package/skills/implementation-plans/evals/triggers.json +16 -0
- package/skills/incident-postmortem/SKILL.md +118 -0
- package/skills/incident-postmortem/evals/triggers.json +14 -0
- package/skills/inventory-demand-planning/SKILL.md +89 -0
- package/skills/inventory-demand-planning/evals/triggers.json +16 -0
- package/skills/inventory-demand-planning/references/formulas.md +62 -0
- package/skills/investor-materials/SKILL.md +127 -0
- package/skills/investor-materials/evals/triggers.json +16 -0
- package/skills/investor-materials/references/templates.md +74 -0
- package/skills/invoicing-and-tax/SKILL.md +84 -0
- package/skills/invoicing-and-tax/evals/triggers.json +17 -0
- package/skills/invoicing-and-tax/references/e-invoicing.md +24 -0
- package/skills/invoicing-and-tax/references/invoice-fields.md +38 -0
- package/skills/invoicing-and-tax/references/rounding.md +26 -0
- package/skills/ios-platform-features/SKILL.md +99 -0
- package/skills/ios-platform-features/evals/triggers.json +16 -0
- package/skills/ios-platform-features/references/foundation-models.md +90 -0
- package/skills/java-patterns/SKILL.md +141 -0
- package/skills/java-patterns/evals/triggers.json +17 -0
- package/skills/java-testing/SKILL.md +142 -0
- package/skills/java-testing/evals/triggers.json +16 -0
- package/skills/jetpack-compose-patterns/SKILL.md +88 -0
- package/skills/jetpack-compose-patterns/evals/triggers.json +16 -0
- package/skills/jira-integration/SKILL.md +92 -0
- package/skills/jira-integration/evals/triggers.json +17 -0
- package/skills/jpa-hibernate/SKILL.md +92 -0
- package/skills/jpa-hibernate/evals/triggers.json +18 -0
- package/skills/jpa-hibernate/references/mapping.md +99 -0
- package/skills/jvm-sql-mappers/SKILL.md +98 -0
- package/skills/jvm-sql-mappers/evals/triggers.json +16 -0
- package/skills/jvm-sql-mappers/references/examples.md +129 -0
- package/skills/kotlin-multiplatform/SKILL.md +97 -0
- package/skills/kotlin-multiplatform/evals/triggers.json +16 -0
- package/skills/kotlin-patterns/SKILL.md +128 -0
- package/skills/kotlin-patterns/evals/triggers.json +16 -0
- package/skills/kotlin-testing/SKILL.md +117 -0
- package/skills/kotlin-testing/evals/triggers.json +16 -0
- package/skills/ktor-patterns/SKILL.md +135 -0
- package/skills/ktor-patterns/evals/triggers.json +18 -0
- package/skills/kubernetes-patterns/SKILL.md +106 -0
- package/skills/kubernetes-patterns/evals/triggers.json +16 -0
- package/skills/kubernetes-patterns/references/manifests.md +115 -0
- package/skills/laravel-patterns/SKILL.md +136 -0
- package/skills/laravel-patterns/evals/triggers.json +16 -0
- package/skills/linear-integration/SKILL.md +98 -0
- package/skills/linear-integration/evals/triggers.json +17 -0
- package/skills/literature-review/SKILL.md +109 -0
- package/skills/literature-review/evals/triggers.json +16 -0
- package/skills/literature-review/references/appraisal.md +41 -0
- package/skills/literature-review/references/search-sources.md +39 -0
- package/skills/llm-app-patterns/SKILL.md +97 -0
- package/skills/llm-app-patterns/evals/triggers.json +17 -0
- package/skills/llm-evals/SKILL.md +98 -0
- package/skills/llm-evals/evals/triggers.json +16 -0
- package/skills/llm-evals/references/graders.md +66 -0
- package/skills/logistics-exception-management/SKILL.md +90 -0
- package/skills/logistics-exception-management/evals/triggers.json +16 -0
- package/skills/manim-animations/SKILL.md +106 -0
- package/skills/manim-animations/evals/triggers.json +16 -0
- package/skills/market-research/SKILL.md +117 -0
- package/skills/market-research/evals/triggers.json +16 -0
- package/skills/marketing-campaign/SKILL.md +111 -0
- package/skills/marketing-campaign/evals/triggers.json +16 -0
- package/skills/mcp-server-patterns/SKILL.md +127 -0
- package/skills/mcp-server-patterns/evals/triggers.json +18 -0
- package/skills/mcp-server-patterns/references/protocol-notes.md +68 -0
- package/skills/metrics-dashboards/SKILL.md +113 -0
- package/skills/metrics-dashboards/evals/triggers.json +16 -0
- package/skills/ml-experiment-workflow/SKILL.md +125 -0
- package/skills/ml-experiment-workflow/evals/triggers.json +16 -0
- package/skills/mobile-accessibility/SKILL.md +94 -0
- package/skills/mobile-accessibility/evals/triggers.json +16 -0
- package/skills/mongodb-patterns/SKILL.md +115 -0
- package/skills/mongodb-patterns/evals/triggers.json +18 -0
- package/skills/mongodb-patterns/references/indexes-and-aggregation.md +94 -0
- package/skills/mpesa-daraja-integration/SKILL.md +70 -0
- package/skills/mpesa-daraja-integration/evals/triggers.json +16 -0
- package/skills/mpesa-daraja-integration/references/api.md +103 -0
- package/skills/mpesa-daraja-integration/references/callbacks.md +74 -0
- package/skills/mtn-momo-integration/SKILL.md +66 -0
- package/skills/mtn-momo-integration/evals/triggers.json +16 -0
- package/skills/mtn-momo-integration/references/api.md +153 -0
- package/skills/mtn-momo-integration/references/callbacks.md +92 -0
- package/skills/mtn-momo-integration/references/sandbox-and-go-live.md +51 -0
- package/skills/mtn-momo-integration/scripts/sandbox-setup.js +79 -0
- package/skills/mysql-patterns/SKILL.md +96 -0
- package/skills/mysql-patterns/evals/triggers.json +16 -0
- package/skills/mysql-patterns/references/explain.md +34 -0
- package/skills/mysql-patterns/references/online-ddl.md +41 -0
- package/skills/nestjs-patterns/SKILL.md +114 -0
- package/skills/nestjs-patterns/evals/triggers.json +16 -0
- package/skills/nestjs-patterns/references/testing.md +68 -0
- package/skills/network-automation/SKILL.md +107 -0
- package/skills/network-automation/evals/triggers.json +18 -0
- package/skills/network-automation/references/tool-snippets.md +153 -0
- package/skills/network-design/SKILL.md +98 -0
- package/skills/network-design/evals/triggers.json +16 -0
- package/skills/network-troubleshooting/SKILL.md +152 -0
- package/skills/network-troubleshooting/evals/triggers.json +18 -0
- package/skills/network-troubleshooting/references/commands.md +33 -0
- package/skills/nextjs-patterns/SKILL.md +150 -0
- package/skills/nextjs-patterns/evals/triggers.json +18 -0
- package/skills/nextjs-patterns/references/caching.md +87 -0
- package/skills/node-backend-patterns/SKILL.md +103 -0
- package/skills/node-backend-patterns/evals/triggers.json +16 -0
- package/skills/node-backend-patterns/references/templates.md +122 -0
- package/skills/nuxt-patterns/SKILL.md +103 -0
- package/skills/nuxt-patterns/evals/triggers.json +16 -0
- package/skills/observability/SKILL.md +125 -0
- package/skills/observability/evals/triggers.json +17 -0
- package/skills/observability/references/otel-setup.md +87 -0
- package/skills/observability/references/slo-alerts.md +70 -0
- package/skills/open-source-release/SKILL.md +107 -0
- package/skills/open-source-release/evals/triggers.json +15 -0
- package/skills/open-source-release/references/history-scrub.md +65 -0
- package/skills/parallel-agent-orchestration/SKILL.md +106 -0
- package/skills/parallel-agent-orchestration/evals/triggers.json +14 -0
- package/skills/patent-research/SKILL.md +94 -0
- package/skills/patent-research/evals/triggers.json +16 -0
- package/skills/patent-research/references/databases-and-queries.md +52 -0
- package/skills/paystack-integration/SKILL.md +59 -0
- package/skills/paystack-integration/evals/triggers.json +14 -0
- package/skills/paystack-integration/references/api.md +73 -0
- package/skills/paystack-integration/references/mobile-money.md +50 -0
- package/skills/paystack-integration/references/webhooks.md +80 -0
- package/skills/pci-dss-scope/SKILL.md +103 -0
- package/skills/pci-dss-scope/evals/triggers.json +18 -0
- package/skills/pci-dss-scope/references/saq-and-data.md +36 -0
- package/skills/perl-patterns/SKILL.md +135 -0
- package/skills/perl-patterns/evals/triggers.json +18 -0
- package/skills/perl-testing/SKILL.md +126 -0
- package/skills/perl-testing/evals/triggers.json +17 -0
- package/skills/php-patterns/SKILL.md +116 -0
- package/skills/php-patterns/evals/triggers.json +16 -0
- package/skills/php-testing/SKILL.md +123 -0
- package/skills/php-testing/evals/triggers.json +16 -0
- package/skills/postgres-patterns/SKILL.md +103 -0
- package/skills/postgres-patterns/evals/triggers.json +17 -0
- package/skills/postgres-patterns/references/explain.md +59 -0
- package/skills/postgres-patterns/references/locks.md +53 -0
- package/skills/prd-writing/SKILL.md +124 -0
- package/skills/prd-writing/evals/triggers.json +15 -0
- package/skills/prisma-patterns/SKILL.md +83 -0
- package/skills/prisma-patterns/evals/triggers.json +18 -0
- package/skills/prisma-patterns/references/prisma-8.md +46 -0
- package/skills/prisma-patterns/references/workflow.md +50 -0
- package/skills/privacy-compliance/SKILL.md +121 -0
- package/skills/privacy-compliance/evals/triggers.json +18 -0
- package/skills/privacy-compliance/references/jurisdictions.md +51 -0
- package/skills/production-scheduling/SKILL.md +98 -0
- package/skills/production-scheduling/evals/triggers.json +16 -0
- package/skills/prompt-engineering/SKILL.md +92 -0
- package/skills/prompt-engineering/evals/triggers.json +16 -0
- package/skills/prospect-research/SKILL.md +87 -0
- package/skills/prospect-research/evals/triggers.json +16 -0
- package/skills/python-app-distribution/SKILL.md +107 -0
- package/skills/python-app-distribution/evals/triggers.json +16 -0
- package/skills/python-app-distribution/references/pypi-trusted-publishing.md +55 -0
- package/skills/python-app-distribution/references/windows-macos-signing.md +70 -0
- package/skills/python-patterns/SKILL.md +107 -0
- package/skills/python-patterns/evals/triggers.json +16 -0
- package/skills/python-patterns/references/tooling.md +101 -0
- package/skills/python-testing/SKILL.md +126 -0
- package/skills/python-testing/evals/triggers.json +16 -0
- package/skills/python-testing/references/mocking.md +71 -0
- package/skills/pytorch-patterns/SKILL.md +139 -0
- package/skills/pytorch-patterns/evals/triggers.json +16 -0
- package/skills/pytorch-patterns/references/debugging.md +39 -0
- package/skills/quality-nonconformance/SKILL.md +107 -0
- package/skills/quality-nonconformance/evals/triggers.json +16 -0
- package/skills/quality-nonconformance/references/8d-and-capa.md +46 -0
- package/skills/quarkus-patterns/SKILL.md +93 -0
- package/skills/quarkus-patterns/evals/triggers.json +18 -0
- package/skills/rag-pipeline-patterns/SKILL.md +117 -0
- package/skills/rag-pipeline-patterns/evals/triggers.json +18 -0
- package/skills/rag-pipeline-patterns/references/evaluation.md +37 -0
- package/skills/rag-pipeline-patterns/references/retrieval-recipes.md +78 -0
- package/skills/rails-patterns/SKILL.md +132 -0
- package/skills/rails-patterns/evals/triggers.json +16 -0
- package/skills/react-native-patterns/SKILL.md +101 -0
- package/skills/react-native-patterns/evals/triggers.json +16 -0
- package/skills/react-patterns/SKILL.md +140 -0
- package/skills/react-patterns/evals/triggers.json +18 -0
- package/skills/react-performance/SKILL.md +107 -0
- package/skills/react-performance/evals/triggers.json +18 -0
- package/skills/react-testing/SKILL.md +121 -0
- package/skills/react-testing/evals/triggers.json +18 -0
- package/skills/react-testing/references/msw.md +64 -0
- package/skills/react-testing/references/queries.md +41 -0
- package/skills/react-testing/references/setup.md +74 -0
- package/skills/recommender-systems/SKILL.md +119 -0
- package/skills/recommender-systems/evals/triggers.json +16 -0
- package/skills/recommender-systems/references/evaluation.md +39 -0
- package/skills/redis-patterns/SKILL.md +109 -0
- package/skills/redis-patterns/evals/triggers.json +18 -0
- package/skills/redis-patterns/references/operations.md +61 -0
- package/skills/refactoring-safely/SKILL.md +107 -0
- package/skills/refactoring-safely/evals/behavior.json +57 -0
- package/skills/refactoring-safely/evals/triggers.json +17 -0
- package/skills/release-management/SKILL.md +141 -0
- package/skills/release-management/evals/triggers.json +16 -0
- package/skills/remotion-video/SKILL.md +91 -0
- package/skills/remotion-video/evals/triggers.json +16 -0
- package/skills/remotion-video/references/lambda.md +66 -0
- package/skills/reproducible-dev-environments/SKILL.md +132 -0
- package/skills/reproducible-dev-environments/evals/triggers.json +16 -0
- package/skills/responding-to-code-review/SKILL.md +124 -0
- package/skills/responding-to-code-review/evals/behavior.json +54 -0
- package/skills/responding-to-code-review/evals/triggers.json +16 -0
- package/skills/returns-reverse-logistics/SKILL.md +97 -0
- package/skills/returns-reverse-logistics/evals/triggers.json +16 -0
- package/skills/ruby-patterns/SKILL.md +127 -0
- package/skills/ruby-patterns/evals/triggers.json +18 -0
- package/skills/ruby-testing/SKILL.md +113 -0
- package/skills/ruby-testing/evals/triggers.json +18 -0
- package/skills/runbook-writing/SKILL.md +101 -0
- package/skills/runbook-writing/evals/triggers.json +14 -0
- package/skills/rust-patterns/SKILL.md +118 -0
- package/skills/rust-patterns/evals/triggers.json +16 -0
- package/skills/rust-patterns/references/cargo-and-clippy.md +105 -0
- package/skills/rust-patterns/references/errors-and-traits.md +97 -0
- package/skills/rust-testing/SKILL.md +148 -0
- package/skills/rust-testing/evals/triggers.json +16 -0
- package/skills/rust-testing/references/fakes-proptest-async.md +113 -0
- package/skills/search-first/SKILL.md +73 -0
- package/skills/search-first/evals/triggers.json +14 -0
- package/skills/security-review/SKILL.md +58 -0
- package/skills/security-review/evals/behavior.json +56 -0
- package/skills/security-review/evals/triggers.json +14 -0
- package/skills/security-review/references/checklist.md +54 -0
- package/skills/security-review/scripts/scan-secrets.js +79 -0
- package/skills/seo-audit/SKILL.md +111 -0
- package/skills/seo-audit/evals/triggers.json +16 -0
- package/skills/seo-audit/references/checks.md +65 -0
- package/skills/session-handoff/SKILL.md +101 -0
- package/skills/session-handoff/evals/behavior.json +55 -0
- package/skills/session-handoff/evals/triggers.json +14 -0
- package/skills/skill-authoring/SKILL.md +98 -0
- package/skills/skill-authoring/evals/triggers.json +15 -0
- package/skills/skill-authoring/references/frontmatter.md +40 -0
- package/skills/skill-authoring/references/pressure-testing.md +87 -0
- package/skills/slack-app-integration/SKILL.md +108 -0
- package/skills/slack-app-integration/evals/triggers.json +17 -0
- package/skills/slide-decks/SKILL.md +107 -0
- package/skills/slide-decks/evals/triggers.json +18 -0
- package/skills/slide-decks/references/html-decks.md +86 -0
- package/skills/slide-decks/references/layouts.md +45 -0
- package/skills/slide-decks/references/pptx.md +87 -0
- package/skills/smart-contract-security/SKILL.md +110 -0
- package/skills/smart-contract-security/evals/triggers.json +16 -0
- package/skills/smart-contract-security/references/vulnerability-checklist.md +79 -0
- package/skills/social-media-publishing/SKILL.md +84 -0
- package/skills/social-media-publishing/evals/triggers.json +17 -0
- package/skills/social-media-publishing/references/platform-apis.md +116 -0
- package/skills/solidity-patterns/SKILL.md +95 -0
- package/skills/solidity-patterns/evals/triggers.json +16 -0
- package/skills/spring-boot-patterns/SKILL.md +128 -0
- package/skills/spring-boot-patterns/evals/triggers.json +18 -0
- package/skills/spring-boot-patterns/references/testing.md +72 -0
- package/skills/stripe-integration/SKILL.md +69 -0
- package/skills/stripe-integration/evals/triggers.json +16 -0
- package/skills/stripe-integration/references/api.md +71 -0
- package/skills/stripe-integration/references/billing.md +58 -0
- package/skills/stripe-integration/references/webhooks.md +76 -0
- package/skills/subagent-driven-development/SKILL.md +109 -0
- package/skills/subagent-driven-development/evals/behavior.json +53 -0
- package/skills/subagent-driven-development/evals/triggers.json +15 -0
- package/skills/subagent-driven-development/references/implementer-brief.md +60 -0
- package/skills/subagent-driven-development/references/reviewer-briefs.md +52 -0
- package/skills/subscription-billing-ops/SKILL.md +118 -0
- package/skills/subscription-billing-ops/evals/triggers.json +17 -0
- package/skills/subscription-billing-ops/references/proration.md +47 -0
- package/skills/subscription-billing-ops/references/revenue-metrics.md +38 -0
- package/skills/svelte-patterns/SKILL.md +122 -0
- package/skills/svelte-patterns/evals/triggers.json +16 -0
- package/skills/swift-patterns/SKILL.md +113 -0
- package/skills/swift-patterns/evals/triggers.json +16 -0
- package/skills/swift-patterns/references/concurrency-migration.md +40 -0
- package/skills/swift-testing/SKILL.md +121 -0
- package/skills/swift-testing/evals/triggers.json +16 -0
- package/skills/swift-testing/references/swift-testing-cheatsheet.md +81 -0
- package/skills/swiftui-patterns/SKILL.md +102 -0
- package/skills/swiftui-patterns/evals/triggers.json +16 -0
- package/skills/systematic-debugging/SKILL.md +92 -0
- package/skills/systematic-debugging/evals/behavior.json +59 -0
- package/skills/systematic-debugging/evals/triggers.json +16 -0
- package/skills/systematic-debugging/references/condition-waiting.md +52 -0
- package/skills/systematic-debugging/references/root-cause-tracing.md +49 -0
- package/skills/systematic-debugging/references/test-pollution.md +46 -0
- package/skills/tdd-workflow/SKILL.md +69 -0
- package/skills/tdd-workflow/evals/behavior.json +55 -0
- package/skills/tdd-workflow/evals/triggers.json +15 -0
- package/skills/tdd-workflow/references/testing-anti-patterns.md +87 -0
- package/skills/technical-writing/SKILL.md +95 -0
- package/skills/technical-writing/evals/triggers.json +14 -0
- package/skills/terraform-patterns/SKILL.md +122 -0
- package/skills/terraform-patterns/evals/triggers.json +16 -0
- package/skills/terraform-patterns/references/backends.md +67 -0
- package/skills/test-coverage-improvement/SKILL.md +107 -0
- package/skills/test-coverage-improvement/evals/triggers.json +16 -0
- package/skills/threat-modeling/SKILL.md +113 -0
- package/skills/threat-modeling/evals/triggers.json +16 -0
- package/skills/transactional-email/SKILL.md +68 -0
- package/skills/transactional-email/evals/triggers.json +17 -0
- package/skills/transactional-email/references/providers.md +63 -0
- package/skills/typescript-patterns/SKILL.md +122 -0
- package/skills/typescript-patterns/evals/triggers.json +16 -0
- package/skills/typescript-testing/SKILL.md +101 -0
- package/skills/typescript-testing/evals/triggers.json +16 -0
- package/skills/ui-demo-recording/SKILL.md +93 -0
- package/skills/ui-demo-recording/evals/triggers.json +16 -0
- package/skills/ui-demo-recording/references/cursor-and-captions.md +48 -0
- package/skills/ui-demo-recording/references/playwright-recording.md +63 -0
- package/skills/ui-demo-recording/references/post-processing.md +57 -0
- package/skills/ui-design-polish/SKILL.md +113 -0
- package/skills/ui-design-polish/evals/triggers.json +18 -0
- package/skills/ui-design-polish/references/detail-checklist.md +45 -0
- package/skills/ui-design-polish/references/tokens.md +68 -0
- package/skills/ui-flow-audit/SKILL.md +112 -0
- package/skills/ui-flow-audit/evals/triggers.json +17 -0
- package/skills/ui-motion/SKILL.md +103 -0
- package/skills/ui-motion/evals/triggers.json +18 -0
- package/skills/ui-motion/references/patterns.md +138 -0
- package/skills/ui-motion/references/tokens.md +52 -0
- package/skills/unicode-text-processing/SKILL.md +103 -0
- package/skills/unicode-text-processing/evals/triggers.json +17 -0
- package/skills/unicode-text-processing/references/apis.md +89 -0
- package/skills/unicode-text-processing/references/script-notes.md +50 -0
- package/skills/verification-loop/SKILL.md +70 -0
- package/skills/verification-loop/evals/behavior.json +52 -0
- package/skills/verification-loop/evals/triggers.json +14 -0
- package/skills/verification-loop/scripts/detect-checks.js +102 -0
- package/skills/video-editing/SKILL.md +111 -0
- package/skills/video-editing/evals/triggers.json +16 -0
- package/skills/video-editing/references/edl-and-logging.md +44 -0
- package/skills/video-editing/references/ffmpeg-edit-recipes.md +92 -0
- package/skills/video-editing/references/resolve-scripting.md +53 -0
- package/skills/vite-patterns/SKILL.md +117 -0
- package/skills/vite-patterns/evals/triggers.json +16 -0
- package/skills/vue-patterns/SKILL.md +104 -0
- package/skills/vue-patterns/evals/triggers.json +16 -0
- package/skills/web-accessibility/SKILL.md +119 -0
- package/skills/web-accessibility/evals/triggers.json +16 -0
- package/skills/web-performance/SKILL.md +107 -0
- package/skills/web-performance/evals/triggers.json +16 -0
- package/skills/web-scraping/SKILL.md +80 -0
- package/skills/web-scraping/evals/triggers.json +16 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-patterns
|
|
3
|
+
description: Modern Angular guidance for standalone components, signal state with input(), output(), model(), computed and effect, RxJS subscriptions that cannot leak, OnPush and zoneless change detection, inject()-based dependency injection, typed reactive or signal forms, and TestBed component tests. Use when writing, migrating or debugging an Angular application, such as moving NgModules to standalone, replacing decorators with signals, fixing a view that does not refresh, or stopping a subscription leak.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Targets Angular 17+ and notes where v20, v21 and v22 changed defaults. Needs the Angular CLI (ng) to build and test.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: coding
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/requires: "ng"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Angular patterns
|
|
15
|
+
|
|
16
|
+
Write Angular that uses signals for state, RxJS for streams, and lets change detection do as little as possible. Match the version the project is on; do not introduce APIs it does not have.
|
|
17
|
+
|
|
18
|
+
## 0. Orient first
|
|
19
|
+
|
|
20
|
+
1. Read `package.json` for the `@angular/core` major. Read `angular.json` for the builder and test runner (Vitest, Karma or Jest).
|
|
21
|
+
2. Check `main.ts` / `app.config.ts`: `bootstrapApplication` means standalone; `provideZonelessChangeDetection()` or no `zone.js` in `polyfills` means zoneless.
|
|
22
|
+
3. Know the default shifts:
|
|
23
|
+
- Standalone is the default for components, directives and pipes since v19.
|
|
24
|
+
- New apps are zoneless by default since v21, and new projects use Vitest.
|
|
25
|
+
- From v22, components without a `changeDetection` setting are OnPush; the old default is named `ChangeDetectionStrategy.Eager`.
|
|
26
|
+
4. Run the CLI migrations instead of rewriting by hand when moving a codebase: `ng generate @angular/core:standalone`, `@angular/core:control-flow`, `@angular/core:signal-input-migration`, `@angular/core:inject`. Review their diff.
|
|
27
|
+
|
|
28
|
+
## 1. Components
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
@Component({
|
|
32
|
+
selector: 'app-user-card',
|
|
33
|
+
imports: [DatePipe],
|
|
34
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
35
|
+
template: `
|
|
36
|
+
@if (user(); as u) { <h2>{{ u.name }}</h2> } @else { <p>Loading</p> }
|
|
37
|
+
@for (tag of tags(); track tag.id) { <span>{{ tag.label }}</span> } @empty { <p>No tags</p> }
|
|
38
|
+
`,
|
|
39
|
+
})
|
|
40
|
+
export class UserCard {
|
|
41
|
+
user = input.required<User>();
|
|
42
|
+
tags = input<Tag[]>([]);
|
|
43
|
+
selected = output<string>();
|
|
44
|
+
expanded = model(false);
|
|
45
|
+
initials = computed(() => this.user().name.slice(0, 2).toUpperCase());
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- Use built-in control flow (`@if`, `@for`, `@switch`) over `*ngIf`/`*ngFor` in new code. `@for` requires `track`: use a stable id, `$index` only for static lists.
|
|
50
|
+
- Set `OnPush` explicitly on versions before v22 so behaviour is the same after upgrade.
|
|
51
|
+
- Keep templates free of method calls that compute; use `computed` or a pure pipe.
|
|
52
|
+
- Use `@defer` for heavy below-the-fold components.
|
|
53
|
+
|
|
54
|
+
## 2. Signals
|
|
55
|
+
|
|
56
|
+
- `signal()` for local state, `computed()` for anything derived, `input()`/`model()` for component inputs.
|
|
57
|
+
- Update with `.set()` or `.update(v => ...)`. Never mutate an object inside a signal in place; produce a new object or the change is not seen.
|
|
58
|
+
- `effect()` is for syncing to the outside world (localStorage, logging, a non-Angular widget). Do not use it to copy one signal into another; use `computed`, or `linkedSignal` when the derived value must also be writable.
|
|
59
|
+
- For async data, prefer `resource()` / `httpResource()` (stable in v22; check status on older versions) or `toSignal(observable$)` over manual subscribe-and-set.
|
|
60
|
+
- Bridge with `toSignal` and `toObservable` from `@angular/core/rxjs-interop`. `toSignal` needs an injection context and an `initialValue` unless you handle `undefined`.
|
|
61
|
+
|
|
62
|
+
## 3. RxJS without leaks
|
|
63
|
+
|
|
64
|
+
Every `subscribe()` needs a teardown. In order of preference:
|
|
65
|
+
|
|
66
|
+
1. Do not subscribe: use the `async` pipe or `toSignal`.
|
|
67
|
+
2. `takeUntilDestroyed()` in a constructor or field initialiser, or `takeUntilDestroyed(this.destroyRef)` elsewhere.
|
|
68
|
+
3. Explicit `Subscription` cleaned in `DestroyRef.onDestroy`.
|
|
69
|
+
|
|
70
|
+
Rules:
|
|
71
|
+
|
|
72
|
+
- No nested `subscribe` inside `subscribe`. Use `switchMap` (cancel previous, for search and route params), `concatMap` (keep order, for writes), `exhaustMap` (ignore while busy, for submit buttons) or `mergeMap` (parallel).
|
|
73
|
+
- `HttpClient` calls complete on their own, but long-lived sources (`valueChanges`, router events, `interval`, websockets, store selects) never do.
|
|
74
|
+
- Handle errors with `catchError` inside the inner observable so one failure does not kill the outer stream.
|
|
75
|
+
- Use `shareReplay({ bufferSize: 1, refCount: true })` for shared HTTP results, not bare `shareReplay(1)` on infinite sources.
|
|
76
|
+
|
|
77
|
+
## 4. Change detection
|
|
78
|
+
|
|
79
|
+
- With OnPush or zoneless, a view refreshes when a signal it reads changes, an input reference changes, a template event fires, or the `async` pipe emits. Setting a plain field from a `setTimeout` or a third-party callback does not refresh the view: make that field a signal.
|
|
80
|
+
- Never fix a stale view with `ChangeDetectorRef.detectChanges()` sprinkled in callbacks, or `setTimeout(() => ...)`. Convert the state to a signal.
|
|
81
|
+
- `ExpressionChangedAfterItHasBeenCheckedError` means a value changes during the check; move the write into a `computed`, an event handler, or `afterNextRender`.
|
|
82
|
+
- Run DOM-measuring or browser-only code in `afterNextRender` / `afterEveryRender`, which do not run on the server.
|
|
83
|
+
|
|
84
|
+
## 5. Dependency injection
|
|
85
|
+
|
|
86
|
+
- Use `inject(Service)` in field initialisers; constructor injection is still valid in codebases that use it.
|
|
87
|
+
- `@Injectable({ providedIn: 'root' })` for app-wide singletons. Provide per-feature services in route `providers` or a component's `providers` when each instance needs its own state.
|
|
88
|
+
- Use `InjectionToken<T>` for config values, provided in `app.config.ts`.
|
|
89
|
+
- `inject()` only works in an injection context; outside one, pass an `Injector` and use `runInInjectionContext`.
|
|
90
|
+
- Use functional guards, resolvers and interceptors (`CanActivateFn`, `HttpInterceptorFn` with `provideHttpClient(withInterceptors([...]))`).
|
|
91
|
+
|
|
92
|
+
## 6. Forms
|
|
93
|
+
|
|
94
|
+
- Use typed reactive forms (`FormBuilder.nonNullable.group`, `FormControl<string>`) for new forms on versions before v22. Avoid `UntypedFormGroup` in new code.
|
|
95
|
+
- On v22+, signal forms (`form()` with the `[formField]` directive) are stable; use them for new forms if the codebase has adopted them, and do not mix both styles inside one form.
|
|
96
|
+
- Put validation in validators, not in submit handlers. Show errors from the control's state (`invalid && touched`).
|
|
97
|
+
- Disable the submit button while pending and use `exhaustMap` (or a pending signal) to stop double submits.
|
|
98
|
+
|
|
99
|
+
## 7. Tests
|
|
100
|
+
|
|
101
|
+
1. Run the project's test command (`ng test`, which uses Vitest in new v21+ projects or Karma in older ones). Do not switch runners as a side effect.
|
|
102
|
+
2. Standalone components: `TestBed.configureTestingModule({ imports: [UserCard] })`, then `const fixture = TestBed.createComponent(UserCard)`.
|
|
103
|
+
3. Set signal inputs with `fixture.componentRef.setInput('user', user)`, then `await fixture.whenStable()` (or `fixture.detectChanges()` in zone-based tests).
|
|
104
|
+
4. Use `provideHttpClient()` plus `provideHttpClientTesting()` and `HttpTestingController` to assert requests; call `httpMock.verify()` after each test.
|
|
105
|
+
5. Query by role, text or `data-testid`, and assert what the user sees.
|
|
106
|
+
|
|
107
|
+
## Stop and ask the user
|
|
108
|
+
|
|
109
|
+
- Moving the app from zone.js to zoneless, or from Karma to Vitest.
|
|
110
|
+
- A migration schematic touches more than the files you were asked to change.
|
|
111
|
+
- Upgrading the Angular major is the simplest fix.
|
|
112
|
+
|
|
113
|
+
## Never
|
|
114
|
+
|
|
115
|
+
- Never leave a `subscribe()` on a long-lived observable without teardown.
|
|
116
|
+
- Never mutate inputs or objects held in signals in place.
|
|
117
|
+
- Never call `detectChanges()` or `setTimeout` to paper over a state that is not reactive.
|
|
118
|
+
- Never bypass sanitisation with `bypassSecurityTrustHtml` on user content.
|
|
119
|
+
|
|
120
|
+
## Report back
|
|
121
|
+
|
|
122
|
+
List the files changed, the Angular version assumptions you relied on, the build and test commands you ran with their results, and any migration left for later.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Convert this Angular NgModule feature to standalone components",
|
|
4
|
+
"My Angular component subscribes to valueChanges and never unsubscribes, fix the leak",
|
|
5
|
+
"Replace the @Input decorators in this Angular component with signal inputs",
|
|
6
|
+
"The Angular view doesn't refresh after the websocket callback sets a field, using OnPush",
|
|
7
|
+
"Write a TestBed test for the Angular user card component that sets a signal input"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Fix the TypeScript strict null errors in our Express server",
|
|
11
|
+
"Write a Vue 3 composable that wraps a websocket connection",
|
|
12
|
+
"My Svelte 5 $effect runs in an infinite loop",
|
|
13
|
+
"Set up Playwright end-to-end tests for the checkout flow",
|
|
14
|
+
"Review this Nuxt change for hydration mismatches"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-client-integration
|
|
3
|
+
description: Builds a dependable client or connector for any third-party HTTP API that has no dedicated Kete Loom skill, covering API-key and OAuth 2.0 auth with single-flight token refresh, connect and read timeouts, retries with exponential backoff and jitter limited to idempotent calls or calls carrying an idempotency key, Retry-After and rate-limit headers, cursor, offset and Link-header pagination, HMAC webhook signature checks on the raw body, and recorded-response contract tests, all shaped to the integration patterns the repo already uses. Use when wiring up a new vendor or partner REST API, writing a sync job or connector against an external service, or hardening a flaky integration that times out, hits 429s or double-submits.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Live calls need network access to the vendor; tests use the project's HTTP mocking or record/replay library.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: integrations
|
|
9
|
+
kete-loom/risk: network
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# API client integration
|
|
14
|
+
|
|
15
|
+
Build a client for an external API that fails predictably: bounded time per call, safe retries, honest errors, no secrets in logs, and tests that run without the network.
|
|
16
|
+
|
|
17
|
+
If a provider-specific Kete Loom skill exists (for example `stripe-integration`, `paystack-integration`, `github-api-automation`, `slack-app-integration`, `jira-integration`, `accounting-api-integration`), use it for that provider; this skill is the general method. For deciding error and retry policy in your own code generally, see `error-handling-patterns`.
|
|
18
|
+
|
|
19
|
+
## 0. Read before writing
|
|
20
|
+
|
|
21
|
+
1. **Find the house pattern.** Search the codebase for existing integrations: a shared HTTP client, base class, retry helper, secrets loader, logging redaction, test fixtures or cassettes. Copy its structure, naming, config style and error types. A new integration that looks unlike the others is a defect.
|
|
22
|
+
2. **Read the vendor docs** for: base URLs per environment, auth method and token lifetime, rate limits and their headers, pagination style, which endpoints accept an idempotency key, error format, webhook signing, API versioning header, sandbox availability. Note the doc URL and date in a comment or the integration's README. Never invent an endpoint, header or limit; if the docs don't say, ask the user or treat it as unknown.
|
|
23
|
+
3. **Prefer the official SDK** if it is maintained, typed and already allowed in the project; wrap it the same way. Hand-roll only when there isn't one or it's unsuitable, and say why.
|
|
24
|
+
4. **Stop and ask** before adding a new dependency, before any call that creates, charges, sends or deletes in a live account, and if credentials would need to be stored somewhere new.
|
|
25
|
+
|
|
26
|
+
## 1. Shape of the client
|
|
27
|
+
|
|
28
|
+
- One module per vendor with a small interface the app calls (`getCustomer`, `listInvoices`), hiding transport details. Callers never build URLs.
|
|
29
|
+
- Config from the environment or the secrets manager: base URL, credentials, timeouts. Sandbox and production differ only by config.
|
|
30
|
+
- Map vendor responses to your own types at the boundary; validate the fields you rely on and fail loudly on schema surprises.
|
|
31
|
+
- Typed errors: distinguish auth (401/403), not found, validation (400/422), rate limited (429), retryable server/network (5xx, timeouts, resets) and unknown. Keep the vendor's request ID in the error.
|
|
32
|
+
|
|
33
|
+
## 2. Auth
|
|
34
|
+
|
|
35
|
+
- API keys: send in the header the vendor specifies, not in query strings (they end up in logs); if the vendor only accepts a query parameter, redact URLs before logging them.
|
|
36
|
+
- OAuth 2.0 client credentials or refresh tokens: cache the access token with its expiry, refresh a little before expiry, and make refresh **single-flight** so concurrent requests share one refresh. On a 401, refresh once and retry once; a second 401 is a real auth error.
|
|
37
|
+
- Rotating refresh tokens: persist the new refresh token atomically before using the new access token, or you lock yourself out.
|
|
38
|
+
- Redact `Authorization`, cookies, tokens and secrets from logs, errors and recorded fixtures.
|
|
39
|
+
|
|
40
|
+
## 3. Timeouts, retries, idempotency
|
|
41
|
+
|
|
42
|
+
Details and pseudocode: `references/resilience.md`.
|
|
43
|
+
|
|
44
|
+
- Set a connect timeout and a total/read timeout on every call (no library defaults of "forever").
|
|
45
|
+
- Retry only: network errors, timeouts, 429, 502, 503, 504 (and 500 if the vendor documents it as transient). Never retry 4xx validation or auth errors.
|
|
46
|
+
- Retry a non-idempotent call (`POST` that creates, charges or sends) **only** if it carries an idempotency key the vendor honours, reused unchanged across attempts. Otherwise surface the error and reconcile.
|
|
47
|
+
- Exponential backoff with full jitter, a max attempt count (3 to 5) and an overall deadline. Honour `Retry-After` (seconds or HTTP date) over your own delay.
|
|
48
|
+
- Respect published rate limits proactively with a client-side limiter where the vendor publishes them; read remaining-quota headers if provided.
|
|
49
|
+
- Add a circuit breaker or bulkhead only if the repo already has one or the user asks.
|
|
50
|
+
|
|
51
|
+
## 4. Pagination
|
|
52
|
+
|
|
53
|
+
Use the vendor's style; never assume page numbers. Cursor or `next` token: loop until it's absent. `Link: <...>; rel="next"`: follow the URL as given. Offset/limit: stop on a short page, and be aware rows can shift between pages. Expose an iterator or async generator; cap total pages for safety and log when the cap is hit.
|
|
54
|
+
|
|
55
|
+
## 5. Webhooks from the vendor
|
|
56
|
+
|
|
57
|
+
- Verify the signature on the **raw request body bytes** with the vendor's algorithm (commonly HMAC-SHA256) and a constant-time compare; reject if the header is missing.
|
|
58
|
+
- Check the timestamp tolerance where the vendor signs one (Standard Webhooks uses `webhook-id`, `webhook-timestamp`, `webhook-signature`).
|
|
59
|
+
- Deduplicate by event ID, return 2xx fast, process asynchronously, and handle out-of-order delivery by re-fetching the resource when order matters.
|
|
60
|
+
|
|
61
|
+
## 6. Tests
|
|
62
|
+
|
|
63
|
+
- Unit-test the client against recorded or hand-built responses, with the project's mock or record/replay tool (for example nock, msw, responses, respx, VCR.py, WireMock). Scrub secrets from recordings.
|
|
64
|
+
- Cover: success, each error class, 429 with `Retry-After`, timeout, token expiry then refresh, multi-page listing, empty page, malformed body, bad webhook signature.
|
|
65
|
+
- One opt-in smoke test against the sandbox, skipped unless credentials are present; never against production.
|
|
66
|
+
|
|
67
|
+
## Never
|
|
68
|
+
|
|
69
|
+
- Never log full request or response bodies containing personal data or secrets.
|
|
70
|
+
- Never retry in two layers (SDK and your wrapper) without knowing the combined count.
|
|
71
|
+
- Never swallow an error and return an empty list; that looks like "no data".
|
|
72
|
+
- Never hard-code a production URL or credential.
|
|
73
|
+
|
|
74
|
+
## Report
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
## Integration: <vendor> (<SDK or hand-rolled>)
|
|
78
|
+
Follows house pattern: <module it mirrors>
|
|
79
|
+
Auth: <method>, refresh: <single-flight yes/no>
|
|
80
|
+
Timeouts: connect <s>, total <s> | Retries: <codes>, max <n>, idempotency: <how>
|
|
81
|
+
Rate limits: <documented limit and handling>
|
|
82
|
+
Pagination: <style>
|
|
83
|
+
Webhooks: <verification method, dedupe> | n/a
|
|
84
|
+
Tests: <command> -> <result>; sandbox smoke: <ran/skipped>
|
|
85
|
+
Unknown from docs: <items to confirm with the vendor>
|
|
86
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Write a connector for the Acme Logistics REST API: OAuth client credentials, cursor pagination and rate limits",
|
|
4
|
+
"Our sync job against the vendor's API keeps getting 429s and sometimes creates duplicate records on retry. Make the client robust.",
|
|
5
|
+
"Add a client for the partner's shipment-tracking API that matches how our other integrations in src/integrations are built",
|
|
6
|
+
"The CRM vendor's access token expires mid-sync and several workers all refresh at once. Fix the token handling in our client.",
|
|
7
|
+
"Build a typed wrapper around this third-party weather API with timeouts, retries and recorded tests"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Add Stripe Checkout and the customer portal to our billing page",
|
|
11
|
+
"Design the endpoints and error format for our own public REST API",
|
|
12
|
+
"Set up an OpenAPI spec and mock server so the frontend and backend teams can work in parallel",
|
|
13
|
+
"Write a GitHub App that labels new issues using the REST API",
|
|
14
|
+
"Explain in general when a function should throw versus return an error value"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Resilience details for API clients
|
|
2
|
+
|
|
3
|
+
## Retry decision
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
retryable(response or error, request):
|
|
7
|
+
if error is connect error, DNS failure, connection reset, timeout: transient = true
|
|
8
|
+
elif status in (429, 502, 503, 504): transient = true
|
|
9
|
+
elif status == 500 and vendor documents 500 as transient: transient = true
|
|
10
|
+
else: return false
|
|
11
|
+
if request.method in (GET, HEAD, OPTIONS, PUT, DELETE): return transient
|
|
12
|
+
return transient and request.has_idempotency_key # POST/PATCH only with a key
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`PUT` and `DELETE` are idempotent by HTTP semantics (RFC 9110), but check the vendor actually implements them that way.
|
|
16
|
+
|
|
17
|
+
## Backoff with full jitter
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
delay(attempt) = random(0, min(cap, base * 2^attempt)) # base ~0.5s, cap ~30s
|
|
21
|
+
if Retry-After present:
|
|
22
|
+
delay = seconds value, or (HTTP-date - now) # never shorter than the server asked
|
|
23
|
+
stop when attempt == max_attempts or now + delay > deadline
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Log each retry at debug/info with attempt number, status and vendor request ID; log the final failure once at warn/error.
|
|
27
|
+
|
|
28
|
+
## Idempotency keys
|
|
29
|
+
|
|
30
|
+
- Generate one key per logical operation (UUID v4), store it with the local record (order, payout, message) before the first attempt, and reuse it on every retry and on a later replay.
|
|
31
|
+
- Header name is vendor-specific (`Idempotency-Key` is common; some use a body field or a client reference ID). Check the docs.
|
|
32
|
+
- Note the vendor's key expiry window; replays after it can create duplicates.
|
|
33
|
+
- If the vendor has no idempotency support, don't retry creates; instead look the object up by your own reference before trying again.
|
|
34
|
+
|
|
35
|
+
## Rate limits
|
|
36
|
+
|
|
37
|
+
- Common headers: `Retry-After`; vendor-specific `X-RateLimit-Limit` / `-Remaining` / `-Reset`; the IETF `RateLimit` / `RateLimit-Policy` fields are still a draft, so treat them as vendor-specific too.
|
|
38
|
+
- Use a token bucket sized below the documented limit, shared across workers if the limit is per account (for example in Redis), not per process.
|
|
39
|
+
- Bulk or batch endpoints are often cheaper against the limit than many single calls.
|
|
40
|
+
|
|
41
|
+
## Token refresh, single-flight
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
get_token():
|
|
45
|
+
if cached and cached.expires_at - now > skew (60s): return cached
|
|
46
|
+
if refresh_in_progress: await it; return cached
|
|
47
|
+
start refresh; on success persist (new refresh token first), cache, resolve waiters
|
|
48
|
+
on failure: reject waiters, clear in-progress flag
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
In multi-process deployments, store the token in a shared cache with a lock, or accept one refresh per process if the vendor allows parallel tokens.
|
|
52
|
+
|
|
53
|
+
## Timeouts
|
|
54
|
+
|
|
55
|
+
- Connect timeout small (2 to 5 s); read or total timeout based on the endpoint's documented or observed p99 plus margin.
|
|
56
|
+
- The overall deadline (all retries) must be less than the caller's own timeout, such as an HTTP handler or queue visibility timeout.
|
|
57
|
+
- Streaming or file downloads: use an idle/read timeout rather than a total timeout.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api-design
|
|
3
|
+
description: HTTP API contract design covering resource modelling, REST versus RPC-style endpoints, status codes and RFC 9457 problem details, cursor pagination, filtering, versioning and deprecation headers, Idempotency-Key retries, OpenAPI-first contracts, and when GraphQL is worth it. Use when designing a new HTTP or GraphQL API, adding endpoints to an existing one, reviewing an API contract or OpenAPI file before it ships, or planning a breaking change.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Language and framework neutral; examples are HTTP and OpenAPI YAML.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: coding
|
|
9
|
+
kete-loom/risk: writes-files
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# API design
|
|
14
|
+
|
|
15
|
+
Design the contract first, then the code. A published API is a promise: every field, status code and default you ship is something a client will depend on.
|
|
16
|
+
|
|
17
|
+
## Before you design
|
|
18
|
+
|
|
19
|
+
1. Find what already exists: search the codebase for an OpenAPI/Swagger file, GraphQL schema, route definitions and an existing error format. **Match the house conventions** (casing, error shape, pagination style) even where this skill would choose differently; consistency beats local perfection.
|
|
20
|
+
2. Name the consumers: browser app, mobile app (slow to update, so breaking changes hurt for months), partners, internal services.
|
|
21
|
+
3. **Stop and ask the user** when you don't know: who the clients are, whether the API is public or internal, the auth model, or whether a breaking change is acceptable.
|
|
22
|
+
|
|
23
|
+
## Choose the style
|
|
24
|
+
|
|
25
|
+
| Situation | Choose |
|
|
26
|
+
|---|---|
|
|
27
|
+
| CRUD-ish domain, many clients, caching matters | REST (resources + HTTP methods) |
|
|
28
|
+
| Actions that don't map to a resource (`send`, `recalculate`) | REST with a sub-resource or action resource (`POST /invoices/{id}/send`), not a verb in every path |
|
|
29
|
+
| Internal service-to-service, strict schemas, streaming | gRPC or another RPC framework |
|
|
30
|
+
| Many client shapes over a graph of data, one team owns the schema | GraphQL, if you accept the costs below |
|
|
31
|
+
|
|
32
|
+
GraphQL costs: HTTP caching mostly lost, query cost limits and depth limits needed, N+1 resolvers (needs batching such as DataLoader), errors returned with `200`, and authorization per field. Don't choose it only to avoid writing endpoints.
|
|
33
|
+
|
|
34
|
+
## Resource modelling (REST)
|
|
35
|
+
|
|
36
|
+
1. Nouns, plural, lowercase, hyphenated: `/orders`, `/orders/{orderId}/line-items`. Nest at most one level; beyond that, link by id.
|
|
37
|
+
2. Methods mean what HTTP says: `GET` safe, `PUT` and `DELETE` idempotent, `PATCH` partial update, `POST` create or action.
|
|
38
|
+
3. IDs are opaque strings to clients. Never expose auto-increment IDs on public APIs if enumeration matters.
|
|
39
|
+
4. One casing for JSON fields across the whole API (pick `camelCase` or `snake_case`, match what exists).
|
|
40
|
+
5. Timestamps in RFC 3339 / ISO 8601 UTC (`2026-03-01T12:00:00Z`). Money as integer minor units plus a currency code, or a decimal string; never a float.
|
|
41
|
+
6. Return the created resource and `Location` header on `201`. Return `204` only when there is truly nothing to say.
|
|
42
|
+
7. Design for additive change: clients must ignore unknown fields, and enums must tolerate new values.
|
|
43
|
+
|
|
44
|
+
## Errors
|
|
45
|
+
|
|
46
|
+
- Use the status code that matches the failure (table in `references/conventions.md`). `400` malformed, `401` unauthenticated, `403` not allowed, `404` not found (also for "exists but you can't see it"), `409` conflict, `422` validation, `429` rate limited, `5xx` server fault.
|
|
47
|
+
- Body uses **Problem Details (RFC 9457)** with `Content-Type: application/problem+json`: `type`, `title`, `status`, `detail`, `instance`, plus extension members such as `errors` for field-level validation.
|
|
48
|
+
- Never leak stack traces, SQL or internal hostnames in `detail`.
|
|
49
|
+
- Error `type` URIs and machine-readable codes are part of the contract. Clients branch on them, not on `detail` text.
|
|
50
|
+
|
|
51
|
+
## Pagination, filtering, sorting
|
|
52
|
+
|
|
53
|
+
1. Default to **cursor pagination** for anything that grows: `?limit=50&cursor=<opaque>`, respond with `next_cursor` (null at the end). Offset pagination is fine for small, stable admin lists.
|
|
54
|
+
2. Always enforce a maximum `limit`, and a default when it is absent.
|
|
55
|
+
3. Cursors are opaque (encode the sort key and id); never let clients build them.
|
|
56
|
+
4. Filtering via plain query params (`?status=paid&created_after=...`). Sorting via `?sort=-created_at,id`, always with a unique tiebreaker so pages are stable.
|
|
57
|
+
5. Only add filters someone needs. Each one is an index and a promise.
|
|
58
|
+
|
|
59
|
+
## Idempotency and concurrency
|
|
60
|
+
|
|
61
|
+
- Make retryable `POST`s safe with an `Idempotency-Key` request header: store key + request fingerprint + response for a retention window; replay the stored response on a repeat; return `422` or `409` if the same key arrives with a different body. Required for payments and anything that sends messages or moves money.
|
|
62
|
+
- Prevent lost updates with `ETag` + `If-Match` on `PUT`/`PATCH`; return `412 Precondition Failed` on mismatch.
|
|
63
|
+
- Rate limit with `429` and a `Retry-After` header.
|
|
64
|
+
|
|
65
|
+
## Versioning and deprecation
|
|
66
|
+
|
|
67
|
+
1. Prefer evolving one version additively. A breaking change is: removing or renaming a field, changing a type or meaning, adding a required input, tightening validation, changing a default or status code.
|
|
68
|
+
2. When you must break, pick one scheme and keep it: URL major version (`/v2/...`, simplest for public APIs) or a header/media-type version. Don't mix.
|
|
69
|
+
3. Deprecate before removing: announce, send the `Deprecation` header (RFC 9745) and a `Sunset` header (RFC 8594) with the removal date, and a `Link` with `rel="deprecation"` to the migration guide. Measure usage before switching off.
|
|
70
|
+
4. **Stop and ask** before shipping any breaking change to a public or mobile-facing API.
|
|
71
|
+
|
|
72
|
+
## OpenAPI contract
|
|
73
|
+
|
|
74
|
+
1. Write or update the OpenAPI document (3.1 or later; 3.2 was published in September 2025, so check what your generators and linters support before adopting it) **before** the handler code, and review it as the source of truth.
|
|
75
|
+
2. Every operation has an `operationId`, request/response schemas under `components/schemas`, and documented error responses using a shared problem-details schema.
|
|
76
|
+
3. Lint it (for example Spectral or Redocly CLI, whichever the repo already uses) and validate requests/responses against it in tests where possible.
|
|
77
|
+
4. See `references/conventions.md` for a skeleton.
|
|
78
|
+
|
|
79
|
+
## Never
|
|
80
|
+
|
|
81
|
+
- Verbs in resource paths (`/getUser`), or `200` with `{"error": ...}` on REST endpoints.
|
|
82
|
+
- Unbounded list endpoints.
|
|
83
|
+
- Accepting a price, role or owner id from the client when the server can derive it.
|
|
84
|
+
- Silent breaking changes in a "minor" release.
|
|
85
|
+
|
|
86
|
+
## Report back
|
|
87
|
+
|
|
88
|
+
When you design or review an API, return:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Style: REST | RPC | GraphQL, and why (one line)
|
|
92
|
+
Endpoints: METHOD path → status codes (one line each)
|
|
93
|
+
Contract file: path to OpenAPI/schema written or changed
|
|
94
|
+
Breaking changes: none | list
|
|
95
|
+
Open questions: what the user must decide
|
|
96
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Design the REST endpoints for a bookings service: create, list, cancel, reschedule",
|
|
4
|
+
"What should our error response body look like? Right now every endpoint returns something different",
|
|
5
|
+
"Our /transactions list endpoint times out with big accounts, how should we paginate it?",
|
|
6
|
+
"We need to rename the customer_name field in the public API without breaking the mobile app",
|
|
7
|
+
"Review this openapi.yaml before we publish it to partners",
|
|
8
|
+
"Should we build the partner API in GraphQL or REST?"
|
|
9
|
+
],
|
|
10
|
+
"should_not_trigger": [
|
|
11
|
+
"Integrate Stripe checkout into our Node backend",
|
|
12
|
+
"Restructure the service so the domain logic doesn't import Express or the ORM",
|
|
13
|
+
"Write an ADR recording why we picked gRPC for internal services",
|
|
14
|
+
"Write the SQL migration that adds an index on orders.created_at",
|
|
15
|
+
"Add JWT authentication with refresh tokens to the login endpoint",
|
|
16
|
+
"Break the reporting feature into an ordered implementation plan"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# API conventions reference
|
|
2
|
+
|
|
3
|
+
Read this when choosing a status code, writing an error body, or starting an OpenAPI file.
|
|
4
|
+
|
|
5
|
+
## Status codes
|
|
6
|
+
|
|
7
|
+
| Code | Use for |
|
|
8
|
+
|---|---|
|
|
9
|
+
| 200 OK | Successful read, or update that returns the resource |
|
|
10
|
+
| 201 Created | Resource created; include `Location` and the body |
|
|
11
|
+
| 202 Accepted | Work queued; return a status resource to poll |
|
|
12
|
+
| 204 No Content | Success with no body (for example `DELETE`) |
|
|
13
|
+
| 304 Not Modified | Conditional `GET` with matching `If-None-Match` |
|
|
14
|
+
| 400 Bad Request | Malformed syntax, unparsable JSON, wrong types |
|
|
15
|
+
| 401 Unauthorized | Missing or invalid credentials; send `WWW-Authenticate` |
|
|
16
|
+
| 403 Forbidden | Authenticated but not allowed |
|
|
17
|
+
| 404 Not Found | No such resource, or caller may not know it exists |
|
|
18
|
+
| 405 Method Not Allowed | Method not supported on this path; send `Allow` |
|
|
19
|
+
| 409 Conflict | State conflict (duplicate, wrong state transition) |
|
|
20
|
+
| 412 Precondition Failed | `If-Match` ETag mismatch |
|
|
21
|
+
| 415 Unsupported Media Type | Wrong `Content-Type` |
|
|
22
|
+
| 422 Unprocessable Content | Well-formed but fails validation |
|
|
23
|
+
| 429 Too Many Requests | Rate limited; send `Retry-After` |
|
|
24
|
+
| 500 Internal Server Error | Unexpected server fault |
|
|
25
|
+
| 503 Service Unavailable | Overloaded or down for maintenance; send `Retry-After` |
|
|
26
|
+
|
|
27
|
+
## Problem details (RFC 9457)
|
|
28
|
+
|
|
29
|
+
```http
|
|
30
|
+
HTTP/1.1 422 Unprocessable Content
|
|
31
|
+
Content-Type: application/problem+json
|
|
32
|
+
|
|
33
|
+
{
|
|
34
|
+
"type": "https://api.example.com/problems/validation-error",
|
|
35
|
+
"title": "Request validation failed",
|
|
36
|
+
"status": 422,
|
|
37
|
+
"detail": "2 fields are invalid.",
|
|
38
|
+
"instance": "/orders/req_7f3a",
|
|
39
|
+
"errors": [
|
|
40
|
+
{ "pointer": "#/email", "detail": "must be a valid email address" },
|
|
41
|
+
{ "pointer": "#/quantity", "detail": "must be at least 1" }
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`type` defaults to `about:blank` when no specific type exists. `errors` is an extension member (RFC 9457 shows this shape, with `pointer` as a JSON Pointer into the request body); keep its shape identical everywhere.
|
|
47
|
+
|
|
48
|
+
## Cursor pagination
|
|
49
|
+
|
|
50
|
+
```http
|
|
51
|
+
GET /orders?limit=2&cursor=eyJjIjoiMjAyNi0wMy0wMVQxMjowMDowMFoiLCJpZCI6Im9yZF85In0
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"data": [ { "id": "ord_8" }, { "id": "ord_7" } ],
|
|
57
|
+
"next_cursor": "eyJjIjoiMjAyNi0wMi0yOFQwOTowMDowMFoiLCJpZCI6Im9yZF83In0"
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Server side: decode the cursor to `(created_at, id)` and query `WHERE (created_at, id) < (:c, :id) ORDER BY created_at DESC, id DESC LIMIT :limit + 1`. Fetching one extra row tells you whether `next_cursor` is null. Back it with an index on the sort columns.
|
|
62
|
+
|
|
63
|
+
## Idempotency-Key flow
|
|
64
|
+
|
|
65
|
+
1. Client sends `Idempotency-Key: <uuid>` on `POST`.
|
|
66
|
+
2. Server looks up the key scoped to the caller.
|
|
67
|
+
- Not found: insert a row (key, fingerprint of method+path+body, status `processing`), run the operation, store the response.
|
|
68
|
+
- Found, same fingerprint, finished: return the stored response unchanged.
|
|
69
|
+
- Found, same fingerprint, still processing: return `409`.
|
|
70
|
+
- Found, different fingerprint: return `422`.
|
|
71
|
+
3. Expire keys after a documented window (24 hours is common).
|
|
72
|
+
|
|
73
|
+
The `Idempotency-Key` header is specified in an IETF HTTPAPI working-group Internet-Draft; Stripe and other payment APIs use the same pattern.
|
|
74
|
+
|
|
75
|
+
## Deprecation headers
|
|
76
|
+
|
|
77
|
+
```http
|
|
78
|
+
Deprecation: @1767225599
|
|
79
|
+
Sunset: Thu, 31 Dec 2026 23:59:59 GMT
|
|
80
|
+
Link: <https://api.example.com/docs/migrate-v2>; rel="deprecation"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`Deprecation` (RFC 9745) carries a structured-field date (`@` + Unix seconds). `Sunset` (RFC 8594) carries an HTTP-date.
|
|
84
|
+
|
|
85
|
+
## OpenAPI skeleton
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
openapi: 3.1.0
|
|
89
|
+
info: { title: Orders API, version: 1.0.0 }
|
|
90
|
+
paths:
|
|
91
|
+
/orders:
|
|
92
|
+
get:
|
|
93
|
+
operationId: listOrders
|
|
94
|
+
parameters:
|
|
95
|
+
- { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 50 } }
|
|
96
|
+
- { name: cursor, in: query, schema: { type: string } }
|
|
97
|
+
responses:
|
|
98
|
+
"200":
|
|
99
|
+
description: A page of orders
|
|
100
|
+
content:
|
|
101
|
+
application/json:
|
|
102
|
+
schema: { $ref: "#/components/schemas/OrderPage" }
|
|
103
|
+
default:
|
|
104
|
+
description: Error
|
|
105
|
+
content:
|
|
106
|
+
application/problem+json:
|
|
107
|
+
schema: { $ref: "#/components/schemas/Problem" }
|
|
108
|
+
components:
|
|
109
|
+
schemas:
|
|
110
|
+
Problem:
|
|
111
|
+
type: object
|
|
112
|
+
properties:
|
|
113
|
+
type: { type: string, format: uri-reference }
|
|
114
|
+
title: { type: string }
|
|
115
|
+
status: { type: integer }
|
|
116
|
+
detail: { type: string }
|
|
117
|
+
instance: { type: string, format: uri-reference }
|
|
118
|
+
Order:
|
|
119
|
+
type: object
|
|
120
|
+
required: [id, status, total_minor, currency, created_at]
|
|
121
|
+
properties:
|
|
122
|
+
id: { type: string }
|
|
123
|
+
status: { type: string, enum: [pending, paid, cancelled] }
|
|
124
|
+
total_minor: { type: integer }
|
|
125
|
+
currency: { type: string, minLength: 3, maxLength: 3 }
|
|
126
|
+
created_at: { type: string, format: date-time }
|
|
127
|
+
OrderPage:
|
|
128
|
+
type: object
|
|
129
|
+
required: [data, next_cursor]
|
|
130
|
+
properties:
|
|
131
|
+
data: { type: array, items: { $ref: "#/components/schemas/Order" } }
|
|
132
|
+
next_cursor: { type: [string, "null"] }
|
|
133
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture-decision-records
|
|
3
|
+
description: Writes and maintains Architecture Decision Records (ADRs), deciding whether a choice deserves one, filling a short template (Nygard sections plus options considered) with context, the options weighed, the decision and its consequences, numbering and storing it next to the code, and superseding old records instead of rewriting them. Use when the user wants to record or document a technical decision, start an ADR log in a repo, or update the status of an earlier decision.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Writes Markdown files; git is optional.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: docs
|
|
9
|
+
kete-loom/risk: writes-files
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Architecture decision records
|
|
14
|
+
|
|
15
|
+
An ADR captures one decision, the reason for it, and what it costs, so a future reader can tell whether the reason still holds. It is short, dated and never silently edited.
|
|
16
|
+
|
|
17
|
+
## Does this need an ADR?
|
|
18
|
+
|
|
19
|
+
Write one when the decision is **hard to reverse, affects more than one module or team, or someone will later ask "why did we do it this way?"** Examples: choosing a database, message broker, auth provider, framework, API style, deployment model; adopting or dropping an architectural pattern; a deliberate trade-off against a stated quality (accepting eventual consistency, skipping multi-region).
|
|
20
|
+
|
|
21
|
+
Don't write one for: library patch upgrades, naming, formatting, decisions fully captured by a ticket, or anything trivially reversible. Say so and stop.
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
1. **Find the log.** Search the repo for an existing ADR directory: `docs/adr/`, `doc/adr/` (the adr-tools default), `docs/decisions/`, `doc/architecture/decisions/`, `adr/`, or an `.adr-dir` file (adr-tools stores the chosen directory there). Use it and its template and numbering exactly. If none exists, propose `docs/adr/` and create `0001-record-architecture-decisions.md` first, then the user's ADR.
|
|
26
|
+
2. **Gather the facts.** You need: the problem and forces (constraints, requirements, deadlines), at least two real options (including "do nothing" when plausible), the chosen option, and who decided. **Stop and ask the user** for anything missing. Never invent the reasons, the alternatives considered or the people involved.
|
|
27
|
+
3. **Number and name.** Next free four-digit number, kebab-case title stating the decision: `0007-use-postgres-for-event-store.md`. Numbers are never reused.
|
|
28
|
+
4. **Write it** with the template below. Keep it to one or two screens. Link to longer analysis rather than pasting it.
|
|
29
|
+
5. **Set the status** (see lifecycle). New records start as `Proposed` unless the user says the decision is made.
|
|
30
|
+
6. **Supersede, don't rewrite.** When a decision changes, write a new ADR, set the old one's status to `Superseded by ADR-00NN` and add `Supersedes ADR-00MM` to the new one. Only typo fixes and status lines change in accepted ADRs.
|
|
31
|
+
7. **Index.** If the log has a README or index listing ADRs, add the new line.
|
|
32
|
+
|
|
33
|
+
## Template
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
# ADR-0007: Use Postgres for the event store
|
|
37
|
+
|
|
38
|
+
- Status: Proposed | Accepted | Rejected | Deprecated | Superseded by ADR-00NN
|
|
39
|
+
- Date: 2026-03-01
|
|
40
|
+
- Deciders: names or roles
|
|
41
|
+
- Supersedes: ADR-00MM (if any)
|
|
42
|
+
|
|
43
|
+
## Context
|
|
44
|
+
|
|
45
|
+
What problem forces a decision now. Constraints, requirements, quality
|
|
46
|
+
attributes that matter (cost, latency, team skills, compliance). Facts, not
|
|
47
|
+
the conclusion.
|
|
48
|
+
|
|
49
|
+
## Options considered
|
|
50
|
+
|
|
51
|
+
1. **Postgres with an append-only events table**: pros, cons.
|
|
52
|
+
2. **EventStoreDB**: pros, cons.
|
|
53
|
+
3. **Kafka as the system of record**: pros, cons.
|
|
54
|
+
|
|
55
|
+
## Decision
|
|
56
|
+
|
|
57
|
+
We will use option 1 because <the deciding reasons, tied to the context>.
|
|
58
|
+
|
|
59
|
+
## Consequences
|
|
60
|
+
|
|
61
|
+
- Positive: what gets easier.
|
|
62
|
+
- Negative: what gets harder or what we accept (the trade-off, stated plainly).
|
|
63
|
+
- Follow-ups: work this creates, and the signal that would make us revisit it.
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Status lifecycle
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Proposed ──▶ Accepted ──▶ Deprecated
|
|
70
|
+
│ └──────▶ Superseded by ADR-NNNN
|
|
71
|
+
└──▶ Rejected
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- `Proposed`: under discussion, usually in a pull request.
|
|
75
|
+
- `Accepted`: merged and in force.
|
|
76
|
+
- `Rejected`: kept on purpose, so the option isn't re-litigated without new facts.
|
|
77
|
+
- `Deprecated`: no longer relevant (the system it governed is gone).
|
|
78
|
+
- `Superseded`: replaced by a newer ADR, linked both ways.
|
|
79
|
+
|
|
80
|
+
## Where to store them
|
|
81
|
+
|
|
82
|
+
- In the repo of the code they govern, as Markdown, reviewed in pull requests like code. Cross-cutting decisions go in a shared architecture repo, linked from each affected repo.
|
|
83
|
+
- If the team uses a tool (adr-tools, Log4brains), follow its file layout and commands instead of hand-numbering.
|
|
84
|
+
|
|
85
|
+
## Writing rules
|
|
86
|
+
|
|
87
|
+
- One decision per ADR. If you need "and" in the title, split it.
|
|
88
|
+
- The Consequences section must include at least one negative. A decision with no cost wasn't a decision.
|
|
89
|
+
- Write the context so a new hire understands it without the meeting.
|
|
90
|
+
- Dates are absolute (`2026-03-01`), never "last sprint".
|
|
91
|
+
|
|
92
|
+
## Report back
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
ADR: path/to/NNNN-title.md (status)
|
|
96
|
+
Updated: older ADRs whose status changed, index file
|
|
97
|
+
Missing facts: anything you left as a question for the user
|
|
98
|
+
```
|