cfsa-antigravity 1.0.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/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bullmq
|
|
3
|
+
description: Redis-based job queue with BullMQ. Use when building background job processing, task scheduling, rate-limited workflows, or distributed job pipelines with Node.js. Triggers on BullMQ, Queue, Worker, job queue, background jobs, delayed jobs, repeatable jobs, Bull Board.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# BullMQ
|
|
8
|
+
|
|
9
|
+
BullMQ is a Redis-based queue for Node.js. It provides reliable job processing with retries, delays, priorities, rate limiting, repeatable jobs, parent-child flows, and sandboxed processors. It is the successor to Bull and the standard choice for production job queues in the Node.js ecosystem.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add bullmq
|
|
15
|
+
# Redis is required — BullMQ connects to Redis, not an embedded store
|
|
16
|
+
pnpm add ioredis # peer dependency
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Core Architecture
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Producer (Queue) ──enqueue──> Redis <──dequeue── Consumer (Worker)
|
|
23
|
+
│
|
|
24
|
+
QueueEvents (listener)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Three primary classes:
|
|
28
|
+
- **Queue**: Enqueues jobs (producer side)
|
|
29
|
+
- **Worker**: Processes jobs (consumer side)
|
|
30
|
+
- **QueueEvents**: Listens to lifecycle events (monitoring side)
|
|
31
|
+
|
|
32
|
+
## Connection Configuration
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { Queue, Worker } from 'bullmq';
|
|
36
|
+
import IORedis from 'ioredis';
|
|
37
|
+
|
|
38
|
+
// Shared connection — reuse across Queue, Worker, QueueEvents
|
|
39
|
+
const connection = new IORedis({
|
|
40
|
+
host: process.env.REDIS_HOST ?? '127.0.0.1',
|
|
41
|
+
port: Number(process.env.REDIS_PORT ?? 6379),
|
|
42
|
+
password: process.env.REDIS_PASSWORD,
|
|
43
|
+
maxRetriesPerRequest: null, // Required for BullMQ workers
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const queue = new Queue('email', { connection });
|
|
47
|
+
const worker = new Worker('email', processEmail, { connection });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Anti-pattern**: Never set `maxRetriesPerRequest` to a number on worker connections. BullMQ uses blocking Redis commands (`BRPOPLPUSH`) that must not be retried automatically.
|
|
51
|
+
|
|
52
|
+
## Queue — Producing Jobs
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { Queue } from 'bullmq';
|
|
56
|
+
|
|
57
|
+
const emailQueue = new Queue('email', { connection });
|
|
58
|
+
|
|
59
|
+
// Basic job
|
|
60
|
+
await emailQueue.add('welcome', { userId: 'u_123', template: 'welcome' });
|
|
61
|
+
|
|
62
|
+
// Job with options
|
|
63
|
+
await emailQueue.add('invoice', { orderId: 'ord_456' }, {
|
|
64
|
+
delay: 5000, // Wait 5s before processing
|
|
65
|
+
attempts: 3, // Retry up to 3 times on failure
|
|
66
|
+
backoff: {
|
|
67
|
+
type: 'exponential', // 'fixed' | 'exponential'
|
|
68
|
+
delay: 1000, // Base delay in ms
|
|
69
|
+
},
|
|
70
|
+
priority: 1, // Lower number = higher priority (default: 0)
|
|
71
|
+
removeOnComplete: { count: 1000 }, // Keep last 1000 completed
|
|
72
|
+
removeOnFail: { age: 7 * 24 * 3600 }, // Keep failures for 7 days
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Bulk Add
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
await emailQueue.addBulk([
|
|
80
|
+
{ name: 'welcome', data: { userId: 'u_1' } },
|
|
81
|
+
{ name: 'welcome', data: { userId: 'u_2' } },
|
|
82
|
+
{ name: 'welcome', data: { userId: 'u_3' } },
|
|
83
|
+
]);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Repeatable Jobs (Cron / Interval)
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// Cron-based
|
|
90
|
+
await emailQueue.add('daily-digest', {}, {
|
|
91
|
+
repeat: { pattern: '0 9 * * *' }, // Every day at 09:00 UTC
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Interval-based
|
|
95
|
+
await emailQueue.add('health-check', {}, {
|
|
96
|
+
repeat: { every: 30_000 }, // Every 30 seconds
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Remove a repeatable job
|
|
100
|
+
const repeatableJobs = await emailQueue.getRepeatableJobs();
|
|
101
|
+
await emailQueue.removeRepeatableByKey(repeatableJobs[0].key);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Worker — Processing Jobs
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { Worker, Job } from 'bullmq';
|
|
108
|
+
|
|
109
|
+
const worker = new Worker('email', async (job: Job) => {
|
|
110
|
+
// job.name — the job name ('welcome', 'invoice')
|
|
111
|
+
// job.data — the payload
|
|
112
|
+
// job.id — unique job ID
|
|
113
|
+
// job.attemptsMade — current attempt number
|
|
114
|
+
|
|
115
|
+
await sendEmail(job.data.userId, job.data.template);
|
|
116
|
+
|
|
117
|
+
// Return value is stored as job result
|
|
118
|
+
return { sent: true, timestamp: Date.now() };
|
|
119
|
+
}, {
|
|
120
|
+
connection,
|
|
121
|
+
concurrency: 5, // Process up to 5 jobs in parallel
|
|
122
|
+
limiter: {
|
|
123
|
+
max: 100, // Max 100 jobs
|
|
124
|
+
duration: 60_000, // Per 60 seconds (rate limiting)
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Named Processors
|
|
130
|
+
|
|
131
|
+
Handle different job types in one worker:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
const worker = new Worker('notifications', async (job: Job) => {
|
|
135
|
+
switch (job.name) {
|
|
136
|
+
case 'email':
|
|
137
|
+
return await handleEmail(job.data);
|
|
138
|
+
case 'sms':
|
|
139
|
+
return await handleSms(job.data);
|
|
140
|
+
case 'push':
|
|
141
|
+
return await handlePush(job.data);
|
|
142
|
+
default:
|
|
143
|
+
throw new Error(`Unknown job type: ${job.name}`);
|
|
144
|
+
}
|
|
145
|
+
}, { connection });
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Progress Reporting
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const worker = new Worker('video-encode', async (job: Job) => {
|
|
152
|
+
for (let i = 0; i < 100; i++) {
|
|
153
|
+
await encodeChunk(i);
|
|
154
|
+
await job.updateProgress(i + 1);
|
|
155
|
+
}
|
|
156
|
+
return { encoded: true };
|
|
157
|
+
}, { connection });
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Sandboxed Processors
|
|
161
|
+
|
|
162
|
+
Run processor in a separate child process to isolate crashes:
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { Worker } from 'bullmq';
|
|
166
|
+
import path from 'node:path';
|
|
167
|
+
|
|
168
|
+
const worker = new Worker(
|
|
169
|
+
'heavy-compute',
|
|
170
|
+
path.join(__dirname, 'processors/heavy-compute.js'),
|
|
171
|
+
{ connection, useWorkerThreads: true } // Worker threads instead of child process
|
|
172
|
+
);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// processors/heavy-compute.js
|
|
177
|
+
import { SandboxedJob } from 'bullmq';
|
|
178
|
+
|
|
179
|
+
export default async function (job: SandboxedJob) {
|
|
180
|
+
// Runs in isolation — a crash here does not kill the main process
|
|
181
|
+
return await computeResult(job.data);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Flow Producer — Parent-Child Job Graphs
|
|
186
|
+
|
|
187
|
+
Create dependency trees where children must complete before the parent processes:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { FlowProducer } from 'bullmq';
|
|
191
|
+
|
|
192
|
+
const flow = new FlowProducer({ connection });
|
|
193
|
+
|
|
194
|
+
await flow.add({
|
|
195
|
+
name: 'generate-report',
|
|
196
|
+
queueName: 'reports',
|
|
197
|
+
data: { reportId: 'r_1' },
|
|
198
|
+
children: [
|
|
199
|
+
{
|
|
200
|
+
name: 'fetch-sales',
|
|
201
|
+
queueName: 'data-fetch',
|
|
202
|
+
data: { source: 'sales' },
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'fetch-inventory',
|
|
206
|
+
queueName: 'data-fetch',
|
|
207
|
+
data: { source: 'inventory' },
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
});
|
|
211
|
+
// Parent job waits until both children complete, then processes with their results
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Access child results from parent:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const worker = new Worker('reports', async (job: Job) => {
|
|
218
|
+
const childValues = await job.getChildrenValues();
|
|
219
|
+
// childValues is Record<string, ReturnType> keyed by `queueName:jobId`
|
|
220
|
+
return buildReport(childValues);
|
|
221
|
+
}, { connection });
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## QueueEvents — Lifecycle Monitoring
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { QueueEvents } from 'bullmq';
|
|
228
|
+
|
|
229
|
+
const events = new QueueEvents('email', { connection });
|
|
230
|
+
|
|
231
|
+
events.on('completed', ({ jobId, returnvalue }) => {
|
|
232
|
+
console.log(`Job ${jobId} completed with`, returnvalue);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
events.on('failed', ({ jobId, failedReason }) => {
|
|
236
|
+
console.error(`Job ${jobId} failed:`, failedReason);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
events.on('progress', ({ jobId, data: progress }) => {
|
|
240
|
+
console.log(`Job ${jobId} progress:`, progress);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
events.on('stalled', ({ jobId }) => {
|
|
244
|
+
console.warn(`Job ${jobId} stalled — worker may have crashed`);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
events.on('delayed', ({ jobId, delay }) => {
|
|
248
|
+
console.log(`Job ${jobId} delayed by ${delay}ms`);
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Stalled Jobs
|
|
253
|
+
|
|
254
|
+
A job is stalled when the worker processing it stops sending heartbeats (crash, memory pressure, blocked event loop). BullMQ automatically moves stalled jobs back to the waiting state.
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const worker = new Worker('critical', processor, {
|
|
258
|
+
connection,
|
|
259
|
+
stalledInterval: 30_000, // Check for stalled jobs every 30s (default)
|
|
260
|
+
maxStalledCount: 1, // Mark as failed after 1 stall (default: 1)
|
|
261
|
+
lockDuration: 30_000, // How long a job lock lasts before considered stalled
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Anti-pattern**: Setting `lockDuration` too low for long-running jobs. If your job takes 5 minutes, set `lockDuration` to at least 600_000 (10 minutes) to avoid false stalls.
|
|
266
|
+
|
|
267
|
+
## Dashboard — Bull Board
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
pnpm add @bull-board/api @bull-board/express
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { createBullBoard } from '@bull-board/api';
|
|
275
|
+
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
|
|
276
|
+
import { ExpressAdapter } from '@bull-board/express';
|
|
277
|
+
import express from 'express';
|
|
278
|
+
|
|
279
|
+
const serverAdapter = new ExpressAdapter();
|
|
280
|
+
serverAdapter.setBasePath('/admin/queues');
|
|
281
|
+
|
|
282
|
+
createBullBoard({
|
|
283
|
+
queues: [
|
|
284
|
+
new BullMQAdapter(emailQueue),
|
|
285
|
+
new BullMQAdapter(videoQueue),
|
|
286
|
+
],
|
|
287
|
+
serverAdapter,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const app = express();
|
|
291
|
+
app.use('/admin/queues', serverAdapter.getRouter());
|
|
292
|
+
app.listen(3000);
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Testing
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import { Queue, Worker, Job } from 'bullmq';
|
|
299
|
+
import { describe, it, expect, afterAll } from 'vitest';
|
|
300
|
+
|
|
301
|
+
describe('email queue', () => {
|
|
302
|
+
const connection = { host: '127.0.0.1', port: 6379 };
|
|
303
|
+
const queue = new Queue('test-email', { connection });
|
|
304
|
+
|
|
305
|
+
afterAll(async () => {
|
|
306
|
+
await queue.obliterate({ force: true }); // Clean up test queue
|
|
307
|
+
await queue.close();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('processes welcome email', async () => {
|
|
311
|
+
const result = await new Promise<string>(async (resolve) => {
|
|
312
|
+
const worker = new Worker('test-email', async (job: Job) => {
|
|
313
|
+
return `sent-to-${job.data.userId}`;
|
|
314
|
+
}, { connection });
|
|
315
|
+
|
|
316
|
+
worker.on('completed', async (job: Job) => {
|
|
317
|
+
resolve(await job.returnvalue);
|
|
318
|
+
await worker.close();
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
await queue.add('welcome', { userId: 'u_test' });
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
expect(result).toBe('sent-to-u_test');
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Testing anti-pattern**: Do not mock BullMQ internals. Use a real Redis instance (Docker or CI service) for integration tests. Mock only external services your processor calls.
|
|
330
|
+
|
|
331
|
+
## Graceful Shutdown
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { Worker, Queue } from 'bullmq';
|
|
335
|
+
|
|
336
|
+
const workers: Worker[] = [];
|
|
337
|
+
|
|
338
|
+
function createWorker(name: string, processor: (job: Job) => Promise<unknown>) {
|
|
339
|
+
const worker = new Worker(name, processor, { connection });
|
|
340
|
+
workers.push(worker);
|
|
341
|
+
return worker;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
async function shutdown() {
|
|
345
|
+
console.log('Shutting down gracefully...');
|
|
346
|
+
|
|
347
|
+
// Close workers first — finishes current jobs, stops taking new ones
|
|
348
|
+
await Promise.all(workers.map((w) => w.close()));
|
|
349
|
+
|
|
350
|
+
// Then close queues
|
|
351
|
+
await emailQueue.close();
|
|
352
|
+
|
|
353
|
+
// Finally close Redis connection
|
|
354
|
+
await connection.quit();
|
|
355
|
+
|
|
356
|
+
process.exit(0);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
process.on('SIGTERM', shutdown);
|
|
360
|
+
process.on('SIGINT', shutdown);
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Anti-Patterns
|
|
364
|
+
|
|
365
|
+
| Anti-Pattern | Why It Fails | Correct Approach |
|
|
366
|
+
|-------------|-------------|-----------------|
|
|
367
|
+
| Storing large payloads in job data | Redis memory pressure, slow serialization | Store data externally, pass IDs in job data |
|
|
368
|
+
| Not setting `removeOnComplete` | Redis fills up with completed job records | Use `{ count: 1000 }` or `{ age: 86400 }` |
|
|
369
|
+
| Using `maxRetriesPerRequest` on worker connections | BullMQ blocking commands fail | Set `maxRetriesPerRequest: null` |
|
|
370
|
+
| Processing side effects without idempotency | Retries cause duplicate actions | Design processors to be idempotent |
|
|
371
|
+
| Not closing workers on shutdown | Jobs get stalled, then retried | Call `worker.close()` on SIGTERM/SIGINT |
|
|
372
|
+
| Short `lockDuration` with long jobs | Jobs falsely stall mid-processing | Set `lockDuration` > max expected job duration |
|
|
373
|
+
|
|
374
|
+
## Decision Guide
|
|
375
|
+
|
|
376
|
+
| Need | BullMQ Feature |
|
|
377
|
+
|------|---------------|
|
|
378
|
+
| Retry failed jobs | `attempts` + `backoff` options |
|
|
379
|
+
| Schedule future work | `delay` option |
|
|
380
|
+
| Recurring tasks | `repeat` with cron pattern or interval |
|
|
381
|
+
| Rate limit processing | `limiter` on Worker |
|
|
382
|
+
| Job dependencies | FlowProducer parent-child trees |
|
|
383
|
+
| Crash isolation | Sandboxed processors |
|
|
384
|
+
| Monitor job status | QueueEvents or Bull Board dashboard |
|
|
385
|
+
| Priority processing | `priority` option (lower = higher priority) |
|