@ketecode/loom 0.0.0-stage → 0.1.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 +516 -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/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/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/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/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 +683 -0
- package/commands/aside.md +19 -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/deps-audit.md +32 -0
- package/commands/epic-decompose.md +21 -0
- package/commands/explain.md +37 -0
- package/commands/feature-dev.md +22 -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/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/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-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/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/protect-files/HOOK.md +24 -0
- package/hooks/protect-files/cases.json +27 -0
- package/hooks/protect-files/hook.js +39 -0
- package/hooks/run.js +132 -0
- package/mcp/atlassian.json +11 -0
- package/mcp/chrome-devtools.json +18 -0
- package/mcp/cloudflare.json +11 -0
- package/mcp/context7.json +11 -0
- package/mcp/fetch.json +17 -0
- package/mcp/figma.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/package.json +59 -4
- package/profiles.json +165 -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/schemas/skill-frontmatter.schema.json +52 -0
- package/scripts/lib/audit.js +96 -0
- package/scripts/lib/frontmatter.js +65 -0
- package/scripts/lib/hooks-install.js +292 -0
- package/scripts/lib/i18n.js +51 -0
- package/scripts/lib/inventory.js +85 -0
- package/scripts/lib/lint.js +158 -0
- package/scripts/lib/mcp-install.js +284 -0
- package/scripts/lib/profiles.js +128 -0
- package/scripts/lib/render.js +86 -0
- package/scripts/lib/rules-install.js +118 -0
- package/scripts/lib/skills.js +86 -0
- package/scripts/lib/targets.js +113 -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-harness-design/SKILL.md +125 -0
- package/skills/agent-harness-design/evals/triggers.json +21 -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-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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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-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/parallel-agent-orchestration/SKILL.md +106 -0
- package/skills/parallel-agent-orchestration/evals/triggers.json +14 -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/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/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/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/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/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/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/triggers.json +14 -0
- package/skills/skill-authoring/SKILL.md +87 -0
- package/skills/skill-authoring/evals/triggers.json +14 -0
- package/skills/skill-authoring/references/frontmatter.md +40 -0
- package/skills/slack-app-integration/SKILL.md +108 -0
- package/skills/slack-app-integration/evals/triggers.json +17 -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/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/tdd-workflow/SKILL.md +67 -0
- package/skills/tdd-workflow/evals/triggers.json +14 -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/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/verification-loop/SKILL.md +70 -0
- package/skills/verification-loop/evals/triggers.json +14 -0
- package/skills/verification-loop/scripts/detect-checks.js +102 -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,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: threat-modeling
|
|
3
|
+
description: STRIDE threat modelling for a planned feature or an existing system, done before or alongside the code. Maps the data flow, trust boundaries and assets, enumerates spoofing, tampering, repudiation, information disclosure, denial of service and elevation of privilege threats per element, and ends with a ranked list of mitigations the team can turn into tickets. Use when designing a feature that touches auth, money, personal data, uploads, webhooks or third-party integrations, when someone asks what could go wrong or how this could be attacked, or before a security sign-off on an architecture.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Reads design docs and code only; no tools required.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: security
|
|
9
|
+
kete-loom/risk: read-only
|
|
10
|
+
kete-loom/owner: "Kete-org"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Threat modelling (STRIDE)
|
|
14
|
+
|
|
15
|
+
Answer four questions for one feature or system: what are we building, what can go wrong, what are we doing about it, and did we do a good enough job. Keep it lightweight: one sitting, one document, a ranked list at the end. This skill designs defences; it does not review a diff line by line (use the security-review skill or the security-reviewer agent for that).
|
|
16
|
+
|
|
17
|
+
## 1. Set the scope
|
|
18
|
+
|
|
19
|
+
1. Name the one feature, service or flow being modelled. If the request is "the whole platform", **stop and ask** which flow matters most and model that first.
|
|
20
|
+
2. Collect what exists: design doc, ticket, API spec, architecture diagram, or the code if it is already built (search for route definitions, queue consumers, webhook handlers, cron jobs, outbound HTTP clients).
|
|
21
|
+
3. Note the assumptions you are making (hosting, who the users are, which parts are out of scope). List them in the output; a wrong assumption is the most common reason a model misses the real threat.
|
|
22
|
+
|
|
23
|
+
## 2. Draw the data flow
|
|
24
|
+
|
|
25
|
+
Write a text data-flow diagram. Use five element types:
|
|
26
|
+
|
|
27
|
+
| Element | Example |
|
|
28
|
+
|---|---|
|
|
29
|
+
| External entity | browser user, admin, partner API, payment provider |
|
|
30
|
+
| Process | API server, worker, Lambda, LLM agent with tools |
|
|
31
|
+
| Data store | Postgres, S3 bucket, Redis, log pipeline |
|
|
32
|
+
| Data flow | HTTPS request, queue message, webhook, file upload |
|
|
33
|
+
| Trust boundary | internet to edge, app to database, tenant A to tenant B, your code to a third party |
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
[User browser] --HTTPS (session cookie)--> (API) --SQL--> [(orders DB)]
|
|
37
|
+
======= boundary: internet | VPC =======
|
|
38
|
+
(API) --HTTPS (secret key)--> [Payment provider] --webhook (signed)--> (API)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Mark every place data crosses a trust boundary. Threats cluster there.
|
|
42
|
+
|
|
43
|
+
## 3. List the assets
|
|
44
|
+
|
|
45
|
+
What would hurt if stolen, changed or made unavailable: credentials and tokens, personal data, payment state, money movement, admin capability, availability of a critical path, audit logs, model prompts and tool permissions. Rate each **high, medium or low** by impact.
|
|
46
|
+
|
|
47
|
+
## 4. Walk STRIDE per element
|
|
48
|
+
|
|
49
|
+
For each element and each boundary-crossing flow, ask the questions that apply:
|
|
50
|
+
|
|
51
|
+
| Threat | Property broken | Applies to | Ask |
|
|
52
|
+
|---|---|---|---|
|
|
53
|
+
| **S**poofing | Authentication | entities, processes | Can someone pretend to be this user, service or webhook sender? |
|
|
54
|
+
| **T**ampering | Integrity | flows, stores, processes | Can input, a message, a file or a stored row be changed in transit or at rest? Can the client set a price, role or owner ID? |
|
|
55
|
+
| **R**epudiation | Non-repudiation | entities, processes | Could a user deny an action and we can't prove otherwise? Are security events logged with who, what, when? |
|
|
56
|
+
| **I**nformation disclosure | Confidentiality | flows, stores, processes | Can data leak via responses, errors, logs, URLs, caches, backups, other tenants, or an LLM's output? |
|
|
57
|
+
| **D**enial of service | Availability | flows, stores, processes | Can one caller exhaust CPU, memory, connections, queue depth, paid API quota or disk? Is there a rate limit and size limit? |
|
|
58
|
+
| **E**levation of privilege | Authorization | processes | Can a normal user reach admin actions, another tenant's data (IDOR), or code execution via injection or deserialisation? |
|
|
59
|
+
|
|
60
|
+
Rules while walking:
|
|
61
|
+
|
|
62
|
+
- Write each threat as **actor + action + asset + consequence**: "An unauthenticated caller replays a captured webhook to mark an unpaid order as paid."
|
|
63
|
+
- Only list threats that are plausible for this design. Skip a STRIDE letter for an element when it genuinely does not apply; don't pad.
|
|
64
|
+
- Check what already mitigates it (framework CSRF protection, signed webhooks, row-level security). Record it; a threat with a working control is still worth listing at low priority.
|
|
65
|
+
|
|
66
|
+
## 5. Rate and decide
|
|
67
|
+
|
|
68
|
+
Rate each threat with a simple likelihood x impact (each high, medium or low). Do not invent precise scores. Then pick one response:
|
|
69
|
+
|
|
70
|
+
- **Mitigate**: add a control (name the concrete one: "verify HMAC on raw body", "scope query by tenant_id", "argon2id hashing").
|
|
71
|
+
- **Eliminate**: remove the feature or data (don't store card numbers; don't log tokens).
|
|
72
|
+
- **Transfer**: move it to a provider built for it (hosted payment page, managed identity provider).
|
|
73
|
+
- **Accept**: only the user or owner can accept a risk. **Stop and ask** before marking anything high as accepted.
|
|
74
|
+
|
|
75
|
+
## 6. Check your work
|
|
76
|
+
|
|
77
|
+
- Every trust boundary has at least one threat considered.
|
|
78
|
+
- Every high asset has at least one threat and one control.
|
|
79
|
+
- Every mitigation is specific enough to become a ticket and to test.
|
|
80
|
+
- Re-read the assumptions: if one is false, which threats change?
|
|
81
|
+
|
|
82
|
+
## Never
|
|
83
|
+
|
|
84
|
+
- Never produce a generic OWASP list unrelated to the diagram.
|
|
85
|
+
- Never claim the system is secure; say what was modelled and what was not.
|
|
86
|
+
- Never mark a high risk as accepted on the user's behalf.
|
|
87
|
+
- Never include real secrets, hostnames or customer data from the codebase in the document.
|
|
88
|
+
|
|
89
|
+
## Output format
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
# Threat model: <feature>
|
|
93
|
+
Scope: <what is in and out> Date: <date>
|
|
94
|
+
Assumptions: <bulleted>
|
|
95
|
+
|
|
96
|
+
## Data flow
|
|
97
|
+
<text diagram with trust boundaries marked>
|
|
98
|
+
|
|
99
|
+
## Assets
|
|
100
|
+
| Asset | Impact |
|
|
101
|
+
|
|
102
|
+
## Threats
|
|
103
|
+
| ID | STRIDE | Element / flow | Threat (actor, action, asset, consequence) | Existing control | L | I | Response |
|
|
104
|
+
|
|
105
|
+
## Prioritised mitigations
|
|
106
|
+
1. [high] T3, T7: <concrete control> (owner: ?, test: <how to prove it works>)
|
|
107
|
+
2. ...
|
|
108
|
+
|
|
109
|
+
## Open questions
|
|
110
|
+
<things only the team can answer>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Order the mitigations by risk (high likelihood and high impact first), and group threats fixed by one control into a single line.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Threat model the new document upload and sharing feature before we build it",
|
|
4
|
+
"Do a STRIDE analysis of our payment webhook architecture",
|
|
5
|
+
"What could an attacker do to this design? Here's the data flow for our multi-tenant reporting service",
|
|
6
|
+
"We're adding an LLM agent with tool access to our support portal, map the trust boundaries and threats",
|
|
7
|
+
"Before security sign-off, list the assets, threats and mitigations for the mobile login flow and rank them"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Scan the code in this pull request for XSS and injection flaws",
|
|
11
|
+
"Check whether any of our npm packages have known CVEs",
|
|
12
|
+
"Implement role-based access control on the admin routes",
|
|
13
|
+
"Write an architecture decision record for moving from REST to gRPC",
|
|
14
|
+
"Break this feature into implementation tasks and a delivery plan"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript-patterns
|
|
3
|
+
description: Idiomatic TypeScript and modern JavaScript for Node.js and the browser, covering strict tsconfig settings, discriminated unions and narrowing, restrained generics, typed error handling, async/await pitfalls, ESM versus CommonJS packaging, project layout and ESLint/Prettier setup. Use when writing or restructuring TS/JS code, designing types for a module, setting up tsconfig or package.json "type"/"exports", or choosing lint and format tooling.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Needs Node.js 18+ and the project's package manager (npm, pnpm, yarn or bun).
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: coding
|
|
9
|
+
kete-loom/risk: writes-files
|
|
10
|
+
kete-loom/requires: "node"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# TypeScript patterns
|
|
15
|
+
|
|
16
|
+
Write TypeScript that the compiler can actually check. Every rule here exists to keep the types honest about what happens at runtime.
|
|
17
|
+
|
|
18
|
+
## 0. Read the project first
|
|
19
|
+
|
|
20
|
+
1. Read `package.json` (`type`, `exports`, `engines`, scripts), every `tsconfig*.json`, and the lint/format config (`eslint.config.*`, `.eslintrc*`, `.prettierrc*`, `biome.json`).
|
|
21
|
+
2. Note the lockfile (`package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lock*`) and use only that package manager.
|
|
22
|
+
3. Follow the existing style, folder layout and module system. Do not convert a codebase between ESM and CJS, or between tools, unless the user asked.
|
|
23
|
+
4. Find the type-check command (often `tsc --noEmit` or a `typecheck` script) and run it before and after your change.
|
|
24
|
+
|
|
25
|
+
## 1. tsconfig baseline
|
|
26
|
+
|
|
27
|
+
For new projects, or when the user asks to tighten settings, start from:
|
|
28
|
+
|
|
29
|
+
```jsonc
|
|
30
|
+
{
|
|
31
|
+
"compilerOptions": {
|
|
32
|
+
"strict": true,
|
|
33
|
+
"noUncheckedIndexedAccess": true,
|
|
34
|
+
"noImplicitOverride": true,
|
|
35
|
+
"noFallthroughCasesInSwitch": true,
|
|
36
|
+
"exactOptionalPropertyTypes": true, // optional; stricter about `undefined`
|
|
37
|
+
"verbatimModuleSyntax": true,
|
|
38
|
+
"isolatedModules": true,
|
|
39
|
+
"skipLibCheck": true,
|
|
40
|
+
"target": "ES2022",
|
|
41
|
+
"module": "NodeNext", // Node apps and libraries
|
|
42
|
+
"moduleResolution": "NodeNext"
|
|
43
|
+
// bundled browser apps: "module": "ESNext", "moduleResolution": "Bundler"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- Turning on `strict` in an existing codebase can produce hundreds of errors. **Stop and ask** before enabling it repo-wide; offer to enable it per package or fix errors in batches.
|
|
49
|
+
- `verbatimModuleSyntax` suits ESM packages (`"type": "module"`) and bundled apps. In files that compile to CommonJS it rejects `import`/`export` syntax (you would need `import x = require()`), so leave it off for CJS packages.
|
|
50
|
+
- Never weaken a compiler option to make an error go away.
|
|
51
|
+
|
|
52
|
+
## 2. Type design
|
|
53
|
+
|
|
54
|
+
- Model states as **discriminated unions**, not bags of optional fields:
|
|
55
|
+
`type Result = { ok: true; value: User } | { ok: false; error: string }`.
|
|
56
|
+
- Narrow with `typeof`, `instanceof`, `in`, a discriminant check, or a type predicate (`(x): x is Foo`). End exhaustive `switch` statements with `default: return assertNever(x)`, where `function assertNever(x: never): never { throw new Error("Unexpected: " + String(x)) }`, so a new variant fails to compile.
|
|
57
|
+
- Prefer `unknown` over `any` for values you have not checked. Parse untrusted input (HTTP bodies, `JSON.parse`, env vars, files) at the boundary with a schema library the project already uses (zod, valibot, io-ts) or a hand-written guard.
|
|
58
|
+
- Use `as const` and `satisfies` to keep literal types while checking shape: `const routes = {...} satisfies Record<string, Route>`.
|
|
59
|
+
- Use `readonly` arrays and properties for data you do not mutate.
|
|
60
|
+
- Generics: add a type parameter only when it links two or more positions (input to output). If a parameter appears once, replace it with its constraint. Avoid conditional and mapped types in application code unless they remove real duplication.
|
|
61
|
+
- Prefer `type` aliases for unions and `interface` for object shapes that are extended; follow the project if it already chose.
|
|
62
|
+
- Avoid `enum`; use a union of string literals or an `as const` object. Avoid `namespace` in new code.
|
|
63
|
+
|
|
64
|
+
## 3. Things never to do
|
|
65
|
+
|
|
66
|
+
- `any`, `as any`, `@ts-ignore`, or `!` non-null assertions to silence an error. If a cast is truly needed, use `@ts-expect-error` with a reason, or a checked guard.
|
|
67
|
+
- Double casts (`x as unknown as T`) outside tests.
|
|
68
|
+
- `Function`, `Object` or `{}` as types.
|
|
69
|
+
- Default exports in a codebase that uses named exports (or the reverse).
|
|
70
|
+
|
|
71
|
+
## 4. Errors
|
|
72
|
+
|
|
73
|
+
1. Throw `Error` subclasses, never strings or plain objects. Set `name` and pass `{ cause }` when wrapping: `throw new ConfigError("bad port", { cause: err })`.
|
|
74
|
+
2. In `catch (err)`, `err` is `unknown`. Narrow before reading properties: `if (err instanceof HttpError) ...`.
|
|
75
|
+
3. Catch only where you can handle, add context, or translate the error. Do not catch and log and continue unless losing the operation is acceptable.
|
|
76
|
+
4. For expected failures (validation, not-found), returning a result union is often clearer than throwing. Pick one style per module.
|
|
77
|
+
|
|
78
|
+
## 5. Async/await pitfalls
|
|
79
|
+
|
|
80
|
+
| Pitfall | Fix |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Floating promise: `save(x);` with no `await` | `await` it, return it, or mark intentional fire-and-forget with `void save(x).catch(log)` |
|
|
83
|
+
| `arr.forEach(async x => ...)` does not wait | `for (const x of arr) await f(x)` (serial) or `await Promise.all(arr.map(f))` (parallel) |
|
|
84
|
+
| Async callback passed where a sync one is expected (event handlers, `Array.filter`) | Wrap and handle the promise explicitly |
|
|
85
|
+
| Sequential awaits on independent work | `await Promise.all([...])`; use `Promise.allSettled` when one failure must not cancel the rest |
|
|
86
|
+
| Unbounded `Promise.all` over thousands of items | Batch, or use a concurrency limiter the project already has |
|
|
87
|
+
| `return promise` inside `try` without `await` | `return await promise` so the `catch`/`finally` applies |
|
|
88
|
+
| Shared mutable state across awaits (check-then-act) | Re-read after the await, or serialise with a lock/queue |
|
|
89
|
+
| No timeout on network calls | `fetch(url, { signal: AbortSignal.timeout(5000) })` |
|
|
90
|
+
|
|
91
|
+
Turn on `@typescript-eslint/no-floating-promises` and `@typescript-eslint/no-misused-promises` (they need type-aware linting) to catch the first three.
|
|
92
|
+
|
|
93
|
+
## 6. ESM versus CommonJS
|
|
94
|
+
|
|
95
|
+
- `"type": "module"` in `package.json` makes `.js` files ESM; otherwise they are CJS. `.mjs`/`.mts` are always ESM, `.cjs`/`.cts` always CJS.
|
|
96
|
+
- With `module: NodeNext`, relative imports in ESM need the runtime extension: `import { x } from "./util.js"` even though the source is `util.ts`.
|
|
97
|
+
- ESM has no `require`, `__dirname` or `__filename`. Use `import.meta.url` with `fileURLToPath`, or `import.meta.dirname` / `import.meta.filename` (Node 20.11+).
|
|
98
|
+
- Libraries: declare entry points with `exports` (with a `types` condition first in each block). Shipping both ESM and CJS needs a build tool such as tsup; verify with `npx @arethetypeswrong/cli --pack .` before publishing.
|
|
99
|
+
- With `verbatimModuleSyntax`, write `import type { Foo }` for type-only imports.
|
|
100
|
+
- **Stop and ask** before changing `type`, `exports` or `main` on a published package: it is a breaking change for consumers.
|
|
101
|
+
|
|
102
|
+
## 7. Project layout
|
|
103
|
+
|
|
104
|
+
- Source in `src/`, build output in `dist/` (git-ignored), tests next to code (`foo.test.ts`) or in `test/`, following the project.
|
|
105
|
+
- Monorepos: use the package manager's workspaces (`pnpm-workspace.yaml`, `workspaces` in `package.json`) and TypeScript project references (`composite`, `references`) when packages build separately.
|
|
106
|
+
- Keep side effects out of module top level; export functions and wire them in an entry file.
|
|
107
|
+
- Read config from `process.env` once, validate it, and export a typed object.
|
|
108
|
+
|
|
109
|
+
## 8. Lint and format
|
|
110
|
+
|
|
111
|
+
- ESLint 9+ uses flat config (`eslint.config.js`/`.mjs`). Use `typescript-eslint` with `recommendedTypeChecked` (or `strictTypeChecked`) and `parserOptions.projectService: true`.
|
|
112
|
+
- Let Prettier (or Biome, if the project uses it) own formatting; disable stylistic lint rules that conflict (`eslint-config-prettier`).
|
|
113
|
+
- Do not add a new linter, formatter or major dependency without asking.
|
|
114
|
+
|
|
115
|
+
## 9. Finish
|
|
116
|
+
|
|
117
|
+
1. Run, in this order, whatever the project defines: format check, lint, type-check, tests.
|
|
118
|
+
2. Fix what you introduced. Report pre-existing failures instead of fixing them silently.
|
|
119
|
+
|
|
120
|
+
## Report back
|
|
121
|
+
|
|
122
|
+
End with: files changed, the commands you ran with pass/fail, any `any`/casts you could not remove and why, and anything that needs the user's decision (strictness, module system, new dependency).
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Set up a strict tsconfig for a new Node 20 library that ships ESM",
|
|
4
|
+
"How should I type this API response so the success and error cases can't get mixed up?",
|
|
5
|
+
"Our package mixes require and import and half the files are .mjs, what's the right way to structure ESM vs CommonJS here?",
|
|
6
|
+
"Refactor this user service to stop using any and use proper unions and narrowing",
|
|
7
|
+
"Configure ESLint flat config with typescript-eslint and Prettier for our monorepo"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Write Vitest tests for the date formatting helpers and mock the clock",
|
|
11
|
+
"Review my TypeScript pull request for unhandled promises before I merge",
|
|
12
|
+
"tsc fails with TS2307 Cannot find module '@app/config', make the build pass",
|
|
13
|
+
"Add a useMemo to stop this React component re-rendering on every keystroke",
|
|
14
|
+
"Write idiomatic Python dataclasses for the order model"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typescript-testing
|
|
3
|
+
description: Vitest and Jest test suites for TypeScript and JavaScript projects, picking whichever runner the repo already uses, with module mocks, spies, fake timers, async assertions, fixtures, coverage thresholds and a procedure for diagnosing flaky tests. Use when writing or fixing unit and integration tests in a TS/JS codebase, mocking an import or the clock, raising coverage, or chasing a test that passes locally and fails in CI.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. Needs Node.js 18+ and the project's package manager and test runner.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.0"
|
|
8
|
+
kete-loom/category: testing
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/requires: "node"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# TypeScript testing
|
|
15
|
+
|
|
16
|
+
Tests that run fast, fail for one reason, and give the same answer every time. Use the runner the project already has.
|
|
17
|
+
|
|
18
|
+
## 0. Detect the setup
|
|
19
|
+
|
|
20
|
+
1. Check `package.json` (`devDependencies`, `scripts.test`) and config files: `vitest.config.*` or a `test` block in `vite.config.*` means Vitest; `jest.config.*` or a `jest` key means Jest. `node:test` imports mean the built-in Node runner: keep using it (`node --test`, `mock` from `node:test`) and apply the rules below, not the Vitest/Jest APIs.
|
|
21
|
+
2. If none exists, **stop and ask** which to add. Suggest Vitest for Vite or ESM-first projects, and Jest only if the team already knows it.
|
|
22
|
+
3. Note the environment (`node`, `jsdom`, `happy-dom`), setup files, path aliases and whether globals (`describe`, `it`) are enabled or imported.
|
|
23
|
+
4. Run the suite once. If it already fails, report which tests fail before changing anything.
|
|
24
|
+
5. Run a single file while working: `npx vitest run path/to/file.test.ts` or `npx jest path/to/file.test.ts`. Filter by name with `-t "name"`.
|
|
25
|
+
|
|
26
|
+
## 1. Write the test
|
|
27
|
+
|
|
28
|
+
- One behaviour per test; name it after that behaviour (`"rejects an expired token"`).
|
|
29
|
+
- Arrange, act, assert. Test through the public API of the module, not private helpers.
|
|
30
|
+
- Use the narrowest matcher that says what you mean: `toEqual` for structure, `toStrictEqual` when `undefined` properties matter, `toBe` for identity and primitives, `toThrow(ErrorClass)` for errors.
|
|
31
|
+
- Build test data with small factory functions (`makeUser({ role: "admin" })`) rather than large shared fixtures that every test mutates.
|
|
32
|
+
- Keep fixtures in files next to tests (`__fixtures__/`) for large payloads; load them, do not inline 200 lines.
|
|
33
|
+
|
|
34
|
+
## 2. Async code
|
|
35
|
+
|
|
36
|
+
- Always `await` (or `return`) the promise under test. A missing `await` lets the test pass before the assertion runs.
|
|
37
|
+
- Rejections: `await expect(fn()).rejects.toThrow(NotFoundError)`. Never wrap in `try/catch` without `expect.assertions(n)`.
|
|
38
|
+
- Resolutions: `await expect(fn()).resolves.toEqual(value)`.
|
|
39
|
+
- Do not use real `setTimeout` sleeps to wait for work; await the operation, or use fake timers.
|
|
40
|
+
|
|
41
|
+
## 3. Mocks and spies
|
|
42
|
+
|
|
43
|
+
Mock only boundaries: network, clock, randomness, filesystem, third-party SDKs. Never mock the unit under test.
|
|
44
|
+
|
|
45
|
+
| Need | Vitest | Jest |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| Mock a module | `vi.mock("./db", () => ({ query: vi.fn() }))` | `jest.mock("./db", () => ({ query: jest.fn() }))` |
|
|
48
|
+
| Keep the rest of the real module | `vi.mock(import("./db"), async (orig) => ({ ...(await orig()), query: vi.fn() }))` | `jest.mock("./db", () => ({ ...jest.requireActual("./db"), query: jest.fn() }))` |
|
|
49
|
+
| Variable used inside a mock factory | `const m = vi.hoisted(() => vi.fn())` | name it with a `mock` prefix |
|
|
50
|
+
| Spy on a method | `vi.spyOn(obj, "method")` | `jest.spyOn(obj, "method")` |
|
|
51
|
+
| Typed mock | `vi.mocked(fn)` | `jest.mocked(fn)` |
|
|
52
|
+
| Reset between tests | `vi.restoreAllMocks()` in `afterEach`, or `restoreMocks: true` in config | `restoreMocks: true` in config |
|
|
53
|
+
|
|
54
|
+
- `vi.mock` and `jest.mock` are hoisted above imports, so a factory cannot reference normal top-level variables.
|
|
55
|
+
- Jest with native ESM cannot use `jest.mock` on ESM imports; use `jest.unstable_mockModule` followed by a dynamic `await import()`, or run Jest through a CJS transform.
|
|
56
|
+
- For HTTP, prefer intercepting at the network layer (`msw`, `nock`, or `undici` `MockAgent`) over mocking `fetch` by hand, if the project already has one of them.
|
|
57
|
+
- Assert on what matters (`toHaveBeenCalledWith(expected)`), not on call counts that are an implementation detail.
|
|
58
|
+
|
|
59
|
+
## 4. Timers and dates
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
beforeEach(() => { vi.useFakeTimers(); vi.setSystemTime(new Date("2025-01-01T00:00:00Z")); });
|
|
63
|
+
afterEach(() => { vi.useRealTimers(); });
|
|
64
|
+
|
|
65
|
+
it("retries after 1s", async () => {
|
|
66
|
+
const p = withRetry(task);
|
|
67
|
+
await vi.advanceTimersByTimeAsync(1000); // async variant flushes promises between timers
|
|
68
|
+
await expect(p).resolves.toBe("ok");
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Jest equivalents: `jest.useFakeTimers()`, `jest.setSystemTime()`, `jest.advanceTimersByTimeAsync()`. Always restore real timers in `afterEach`.
|
|
73
|
+
|
|
74
|
+
## 5. Coverage
|
|
75
|
+
|
|
76
|
+
- Vitest: `npx vitest run --coverage` (needs `@vitest/coverage-v8` or `@vitest/coverage-istanbul`). Jest: `npx jest --coverage`.
|
|
77
|
+
- Set thresholds in config (`test.coverage.thresholds` in Vitest, `coverageThreshold` in Jest) only if the team wants them enforced.
|
|
78
|
+
- Read the uncovered-lines report and test the **branches** that matter (error paths, boundaries). Do not write tests that only execute lines without asserting.
|
|
79
|
+
|
|
80
|
+
## 6. Flaky tests
|
|
81
|
+
|
|
82
|
+
Follow this order and stop when you find the cause:
|
|
83
|
+
|
|
84
|
+
1. Reproduce: run the single test many times (a shell loop or the runner's repeat option) and the whole file in random order (Vitest `--sequence.shuffle`, Jest `--randomize`).
|
|
85
|
+
2. Run it alone and with the full suite. Passing alone but failing together means **shared state**: module-level variables, unrestored mocks, leftover DB rows, `process.env` changes. Reset in `beforeEach`/`afterEach`.
|
|
86
|
+
3. Look for real time (`Date.now()`, `new Date()`), real timers, randomness, or locale/timezone (`TZ=UTC` in the test script).
|
|
87
|
+
4. Look for missing `await`, unawaited promises in setup, or assertions on work still in progress.
|
|
88
|
+
5. Look for real network, ports already in use, or order-dependent file writes. Use temp dirs (`fs.mkdtemp`) and port `0`.
|
|
89
|
+
6. CI-only failures: compare Node version, CPU count (worker pools), and environment variables.
|
|
90
|
+
|
|
91
|
+
Never fix flakiness by adding retries, longer timeouts or `.skip` without telling the user; those hide the bug.
|
|
92
|
+
|
|
93
|
+
## Rules
|
|
94
|
+
|
|
95
|
+
- Never delete, skip or loosen an existing assertion to get green. If a test is wrong, explain why and ask first.
|
|
96
|
+
- No real network calls, no real time, no dependence on test order.
|
|
97
|
+
- Do not add a new test runner or mocking library without asking.
|
|
98
|
+
|
|
99
|
+
## Report back
|
|
100
|
+
|
|
101
|
+
End with: tests added or changed (file and name), the command you ran, pass/fail counts, coverage change if measured, and for a flaky test the root cause you found.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Write Vitest unit tests for the invoice calculator in src/billing",
|
|
4
|
+
"How do I mock the ./db module in Jest but keep the rest of its real exports?",
|
|
5
|
+
"This retry test uses setTimeout and takes 30 seconds, use fake timers instead",
|
|
6
|
+
"Our auth.test.ts passes locally but fails randomly in CI, find out why",
|
|
7
|
+
"Get coverage on the payments package above 80% with jest --coverage"
|
|
8
|
+
],
|
|
9
|
+
"should_not_trigger": [
|
|
10
|
+
"Set up a strict tsconfig and decide between ESM and CommonJS for the new package",
|
|
11
|
+
"Write Playwright end-to-end tests for the signup flow in the browser",
|
|
12
|
+
"Review this TypeScript diff for type holes and async races",
|
|
13
|
+
"npm run build fails with ERR_REQUIRE_ESM after upgrading a dependency, fix it",
|
|
14
|
+
"Write pytest fixtures for the Django order views"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verification-loop
|
|
3
|
+
description: Pre-merge verification that detects the project's build, lint, type-check and test commands, runs them in order, fixes what it safely can and reports a pass/fail verdict. Use when the user asks to verify, check or validate changes before committing, opening a pull request, merging or shipping.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Any Agent Skills host. The detection script needs Node 18+; without Node, detect commands by reading project files manually.
|
|
6
|
+
metadata:
|
|
7
|
+
kete-loom/version: "0.1.1"
|
|
8
|
+
kete-loom/category: testing
|
|
9
|
+
kete-loom/risk: runs-commands
|
|
10
|
+
kete-loom/requires: "git, node"
|
|
11
|
+
kete-loom/owner: "Kete-org"
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Verification loop
|
|
15
|
+
|
|
16
|
+
Prove the change works before anyone else has to. Run every check the project defines, in a fixed order, and give a clear verdict.
|
|
17
|
+
|
|
18
|
+
## 1. Scope the change
|
|
19
|
+
|
|
20
|
+
Run `git status` and `git diff --stat` against the base branch (usually `main`). Note which files and packages changed. In a monorepo, verify the changed packages plus anything that depends on them.
|
|
21
|
+
|
|
22
|
+
## 2. Detect the checks
|
|
23
|
+
|
|
24
|
+
Run the helper from this skill's folder:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
node scripts/detect-checks.js [project-dir]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
It prints a JSON list of the build, lint, type-check, format-check and test commands it finds (npm/pnpm/yarn/bun scripts, Python, Go, Rust, Java, .NET, Makefile). Also read `AGENTS.md`, the README and the CI workflow files: if CI runs a command the script missed, add it. CI is the source of truth.
|
|
31
|
+
|
|
32
|
+
If nothing is detected, ask the user how they verify changes. Don't invent commands.
|
|
33
|
+
|
|
34
|
+
## 3. Run in this order
|
|
35
|
+
|
|
36
|
+
1. **Install / build**: does it compile?
|
|
37
|
+
2. **Format check**: check mode only (`--check`), never a reformat of the whole repo.
|
|
38
|
+
3. **Lint**
|
|
39
|
+
4. **Type-check**
|
|
40
|
+
5. **Tests**: unit, then integration. Skip end-to-end suites that need external services unless the user asks.
|
|
41
|
+
|
|
42
|
+
Run each command exactly as the project defines it. Capture the exit code and the first relevant error lines.
|
|
43
|
+
|
|
44
|
+
## 4. Fix, then re-run
|
|
45
|
+
|
|
46
|
+
For each failure:
|
|
47
|
+
|
|
48
|
+
- **Caused by this change**: fix it, then re-run that check and everything after it.
|
|
49
|
+
- **Pre-existing** (also fails on the base branch): don't fix it unasked. Report it as pre-existing. Confirm with `git stash` or by checking the base branch only if it's cheap and safe.
|
|
50
|
+
- **Flaky** (passes on retry with no change): report it as flaky, with the test name.
|
|
51
|
+
|
|
52
|
+
Never make a check pass by disabling a rule, adding `skip`/`ignore`, loosening types to `any`, or deleting tests. If that seems like the only path, stop and ask.
|
|
53
|
+
|
|
54
|
+
Stop after three fix rounds on the same check and report.
|
|
55
|
+
|
|
56
|
+
## 5. Final review of the diff
|
|
57
|
+
|
|
58
|
+
Re-read the full diff once. Look for: debug prints, commented-out code, secrets or tokens, TODOs you introduced, unrelated changes, and missing tests for new behaviour.
|
|
59
|
+
|
|
60
|
+
## 6. Verdict
|
|
61
|
+
|
|
62
|
+
Report a table, then one line:
|
|
63
|
+
|
|
64
|
+
| Check | Command | Result |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Build | `npm run build` | ✅ pass |
|
|
67
|
+
| Lint | `npm run lint` | ✅ pass (2 warnings) |
|
|
68
|
+
| Tests | `npm test` | ❌ 1 failing (pre-existing: `auth.spec.ts`) |
|
|
69
|
+
|
|
70
|
+
**Verdict:** READY, READY WITH NOTES, or NOT READY, followed by what must happen before merge.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"should_trigger": [
|
|
3
|
+
"Run all the checks on my branch before I open a pull request",
|
|
4
|
+
"Is this ready to merge? Make sure lint, types and tests all pass",
|
|
5
|
+
"Verify my changes compile and the test suite is green before I push",
|
|
6
|
+
"Do a final pre-ship check of the repo"
|
|
7
|
+
],
|
|
8
|
+
"should_not_trigger": [
|
|
9
|
+
"Add a discount-code field to the checkout service, test first please",
|
|
10
|
+
"Set up GitHub Actions CI for this new repository",
|
|
11
|
+
"Why does this single unit test fail intermittently on Windows?",
|
|
12
|
+
"Write release notes for version 2.3"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Detects a project's verification commands and prints them as JSON.
|
|
5
|
+
// Usage: node detect-checks.js [project-dir]
|
|
6
|
+
// Read-only: it never runs the commands it finds.
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const root = path.resolve(process.argv[2] || '.');
|
|
12
|
+
const has = (f) => fs.existsSync(path.join(root, f));
|
|
13
|
+
const read = (f) => {
|
|
14
|
+
try {
|
|
15
|
+
return fs.readFileSync(path.join(root, f), 'utf8');
|
|
16
|
+
} catch {
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const checks = [];
|
|
21
|
+
const add = (kind, command, source) => {
|
|
22
|
+
if (!checks.some((c) => c.command === command)) checks.push({ kind, command, source });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// JavaScript / TypeScript
|
|
26
|
+
if (has('package.json')) {
|
|
27
|
+
let pkg = {};
|
|
28
|
+
try {
|
|
29
|
+
pkg = JSON.parse(read('package.json'));
|
|
30
|
+
} catch {}
|
|
31
|
+
const pm = has('pnpm-lock.yaml') ? 'pnpm' : has('yarn.lock') ? 'yarn' : has('bun.lockb') || has('bun.lock') ? 'bun' : 'npm';
|
|
32
|
+
// bun needs `run`: `bun test` / `bun build` are its own runner and bundler, not the scripts.
|
|
33
|
+
const run = (s) => (pm === 'npm' || pm === 'bun' ? `${pm} run ${s}` : `${pm} ${s}`);
|
|
34
|
+
const scripts = pkg.scripts || {};
|
|
35
|
+
const map = [
|
|
36
|
+
['build', /^build$/],
|
|
37
|
+
['format', /^(format:check|fmt:check|prettier:check|check:format)$/],
|
|
38
|
+
['lint', /^(lint|eslint|biome)$/],
|
|
39
|
+
['typecheck', /^(typecheck|type-check|tsc|check:types|types)$/],
|
|
40
|
+
['test', /^(test|test:unit|vitest|jest)$/],
|
|
41
|
+
['test-integration', /^test:(integration|int)$/],
|
|
42
|
+
];
|
|
43
|
+
for (const [kind, re] of map) for (const s of Object.keys(scripts)) if (re.test(s)) add(kind, s === 'test' && pm === 'npm' ? 'npm test' : run(s), 'package.json');
|
|
44
|
+
if (!Object.keys(scripts).some((s) => /type/.test(s)) && has('tsconfig.json')) add('typecheck', `${pm === 'npm' ? 'npx' : pm + ' exec'} tsc --noEmit`, 'tsconfig.json');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Python
|
|
48
|
+
if (has('pyproject.toml') || has('setup.cfg') || has('requirements.txt')) {
|
|
49
|
+
const py = read('pyproject.toml') + read('setup.cfg');
|
|
50
|
+
const runner = has('uv.lock') ? 'uv run ' : has('poetry.lock') ? 'poetry run ' : '';
|
|
51
|
+
if (/\[tool\.ruff/.test(py) || has('ruff.toml')) {
|
|
52
|
+
add('format', `${runner}ruff format --check .`, 'ruff');
|
|
53
|
+
add('lint', `${runner}ruff check .`, 'ruff');
|
|
54
|
+
} else if (/flake8/.test(py) || has('.flake8')) add('lint', `${runner}flake8`, 'flake8');
|
|
55
|
+
if (/\[tool\.black/.test(py)) add('format', `${runner}black --check .`, 'black');
|
|
56
|
+
if (/\[tool\.mypy/.test(py) || has('mypy.ini')) add('typecheck', `${runner}mypy .`, 'mypy');
|
|
57
|
+
if (/\[tool\.pyright/.test(py) || has('pyrightconfig.json')) add('typecheck', `${runner}pyright`, 'pyright');
|
|
58
|
+
if (/pytest/.test(py) || has('pytest.ini') || has('tests') || has('conftest.py')) add('test', `${runner}pytest`, 'pytest');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Go
|
|
62
|
+
if (has('go.mod')) {
|
|
63
|
+
add('build', 'go build ./...', 'go.mod');
|
|
64
|
+
add('lint', 'go vet ./...', 'go.mod');
|
|
65
|
+
if (has('.golangci.yml') || has('.golangci.yaml')) add('lint', 'golangci-lint run', '.golangci.yml');
|
|
66
|
+
add('test', 'go test ./...', 'go.mod');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Rust
|
|
70
|
+
if (has('Cargo.toml')) {
|
|
71
|
+
add('format', 'cargo fmt --check', 'Cargo.toml');
|
|
72
|
+
add('lint', 'cargo clippy --all-targets -- -D warnings', 'Cargo.toml');
|
|
73
|
+
add('test', 'cargo test', 'Cargo.toml');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// JVM
|
|
77
|
+
if (has('gradlew')) {
|
|
78
|
+
add('build', './gradlew build -x test', 'gradlew');
|
|
79
|
+
add('test', './gradlew test', 'gradlew');
|
|
80
|
+
} else if (has('pom.xml')) {
|
|
81
|
+
add('build', 'mvn -q -DskipTests package', 'pom.xml');
|
|
82
|
+
add('test', 'mvn -q test', 'pom.xml');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// .NET
|
|
86
|
+
if (fs.readdirSync(root).some((f) => /\.(sln|csproj|fsproj)$/.test(f))) {
|
|
87
|
+
add('build', 'dotnet build', '.NET');
|
|
88
|
+
add('test', 'dotnet test', '.NET');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Makefile targets
|
|
92
|
+
const make = read('Makefile');
|
|
93
|
+
for (const [kind, target] of [['build', 'build'], ['lint', 'lint'], ['typecheck', 'typecheck'], ['test', 'test']]) {
|
|
94
|
+
if (new RegExp(`^${target}:`, 'm').test(make)) add(kind, `make ${target}`, 'Makefile');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const order = ['build', 'format', 'lint', 'typecheck', 'test', 'test-integration'];
|
|
98
|
+
checks.sort((a, b) => order.indexOf(a.kind) - order.indexOf(b.kind));
|
|
99
|
+
|
|
100
|
+
const ci = has('.github/workflows') ? fs.readdirSync(path.join(root, '.github/workflows')).map((f) => `.github/workflows/${f}`) : [];
|
|
101
|
+
console.log(JSON.stringify({ root, checks, ciFilesToReview: ci }, null, 2));
|
|
102
|
+
if (!checks.length) process.exitCode = 3;
|