claude-autopm 2.8.2 → 2.8.4
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/README.md +399 -637
- package/install/install.js +15 -5
- package/package.json +2 -1
- package/packages/plugin-ai/LICENSE +21 -0
- package/packages/plugin-ai/README.md +316 -0
- package/packages/plugin-ai/agents/anthropic-claude-expert.md +579 -0
- package/packages/plugin-ai/agents/azure-openai-expert.md +1411 -0
- package/packages/plugin-ai/agents/gemini-api-expert.md +880 -0
- package/packages/plugin-ai/agents/google-a2a-expert.md +1445 -0
- package/packages/plugin-ai/agents/huggingface-expert.md +2131 -0
- package/packages/plugin-ai/agents/langchain-expert.md +1427 -0
- package/packages/plugin-ai/agents/langgraph-workflow-expert.md +520 -0
- package/packages/plugin-ai/agents/openai-python-expert.md +1087 -0
- package/packages/plugin-ai/commands/a2a-setup.md +886 -0
- package/packages/plugin-ai/commands/ai-model-deployment.md +481 -0
- package/packages/plugin-ai/commands/anthropic-optimize.md +793 -0
- package/packages/plugin-ai/commands/huggingface-deploy.md +789 -0
- package/packages/plugin-ai/commands/langchain-optimize.md +807 -0
- package/packages/plugin-ai/commands/llm-optimize.md +348 -0
- package/packages/plugin-ai/commands/openai-optimize.md +863 -0
- package/packages/plugin-ai/commands/rag-optimize.md +841 -0
- package/packages/plugin-ai/commands/rag-setup-scaffold.md +382 -0
- package/packages/plugin-ai/package.json +66 -0
- package/packages/plugin-ai/plugin.json +519 -0
- package/packages/plugin-ai/rules/ai-model-standards.md +449 -0
- package/packages/plugin-ai/rules/prompt-engineering-standards.md +509 -0
- package/packages/plugin-ai/scripts/examples/huggingface-inference-example.py +145 -0
- package/packages/plugin-ai/scripts/examples/langchain-rag-example.py +366 -0
- package/packages/plugin-ai/scripts/examples/mlflow-tracking-example.py +224 -0
- package/packages/plugin-ai/scripts/examples/openai-chat-example.py +425 -0
- package/packages/plugin-cloud/README.md +268 -0
- package/packages/plugin-cloud/agents/README.md +55 -0
- package/packages/plugin-cloud/agents/aws-cloud-architect.md +521 -0
- package/packages/plugin-cloud/agents/azure-cloud-architect.md +436 -0
- package/packages/plugin-cloud/agents/gcp-cloud-architect.md +385 -0
- package/packages/plugin-cloud/agents/gcp-cloud-functions-engineer.md +306 -0
- package/packages/plugin-cloud/agents/gemini-api-expert.md +880 -0
- package/packages/plugin-cloud/agents/kubernetes-orchestrator.md +566 -0
- package/packages/plugin-cloud/agents/openai-python-expert.md +1087 -0
- package/packages/plugin-cloud/agents/terraform-infrastructure-expert.md +454 -0
- package/packages/plugin-cloud/commands/cloud-cost-optimize.md +243 -0
- package/packages/plugin-cloud/commands/cloud-validate.md +196 -0
- package/packages/plugin-cloud/commands/infra-deploy.md +38 -0
- package/packages/plugin-cloud/commands/k8s-deploy.md +37 -0
- package/packages/plugin-cloud/commands/ssh-security.md +65 -0
- package/packages/plugin-cloud/commands/traefik-setup.md +65 -0
- package/packages/plugin-cloud/hooks/pre-cloud-deploy.js +456 -0
- package/packages/plugin-cloud/package.json +64 -0
- package/packages/plugin-cloud/plugin.json +338 -0
- package/packages/plugin-cloud/rules/cloud-security-compliance.md +313 -0
- package/packages/plugin-cloud/rules/infrastructure-pipeline.md +128 -0
- package/packages/plugin-cloud/scripts/examples/aws-validate.sh +30 -0
- package/packages/plugin-cloud/scripts/examples/azure-setup.sh +33 -0
- package/packages/plugin-cloud/scripts/examples/gcp-setup.sh +39 -0
- package/packages/plugin-cloud/scripts/examples/k8s-validate.sh +40 -0
- package/packages/plugin-cloud/scripts/examples/terraform-init.sh +26 -0
- package/packages/plugin-core/README.md +274 -0
- package/packages/plugin-core/agents/core/agent-manager.md +296 -0
- package/packages/plugin-core/agents/core/code-analyzer.md +131 -0
- package/packages/plugin-core/agents/core/file-analyzer.md +162 -0
- package/packages/plugin-core/agents/core/test-runner.md +200 -0
- package/packages/plugin-core/commands/code-rabbit.md +128 -0
- package/packages/plugin-core/commands/prompt.md +9 -0
- package/packages/plugin-core/commands/re-init.md +9 -0
- package/packages/plugin-core/hooks/context7-reminder.md +29 -0
- package/packages/plugin-core/hooks/enforce-agents.js +125 -0
- package/packages/plugin-core/hooks/enforce-agents.sh +35 -0
- package/packages/plugin-core/hooks/pre-agent-context7.js +224 -0
- package/packages/plugin-core/hooks/pre-command-context7.js +229 -0
- package/packages/plugin-core/hooks/strict-enforce-agents.sh +39 -0
- package/packages/plugin-core/hooks/test-hook.sh +21 -0
- package/packages/plugin-core/hooks/unified-context7-enforcement.sh +38 -0
- package/packages/plugin-core/package.json +45 -0
- package/packages/plugin-core/plugin.json +387 -0
- package/packages/plugin-core/rules/agent-coordination.md +549 -0
- package/packages/plugin-core/rules/agent-mandatory.md +170 -0
- package/packages/plugin-core/rules/ai-integration-patterns.md +219 -0
- package/packages/plugin-core/rules/command-pipelines.md +208 -0
- package/packages/plugin-core/rules/context-optimization.md +176 -0
- package/packages/plugin-core/rules/context7-enforcement.md +327 -0
- package/packages/plugin-core/rules/datetime.md +122 -0
- package/packages/plugin-core/rules/definition-of-done.md +272 -0
- package/packages/plugin-core/rules/development-environments.md +19 -0
- package/packages/plugin-core/rules/development-workflow.md +198 -0
- package/packages/plugin-core/rules/framework-path-rules.md +180 -0
- package/packages/plugin-core/rules/frontmatter-operations.md +64 -0
- package/packages/plugin-core/rules/git-strategy.md +237 -0
- package/packages/plugin-core/rules/golden-rules.md +181 -0
- package/packages/plugin-core/rules/naming-conventions.md +111 -0
- package/packages/plugin-core/rules/no-pr-workflow.md +183 -0
- package/packages/plugin-core/rules/performance-guidelines.md +403 -0
- package/packages/plugin-core/rules/pipeline-mandatory.md +109 -0
- package/packages/plugin-core/rules/security-checklist.md +318 -0
- package/packages/plugin-core/rules/standard-patterns.md +197 -0
- package/packages/plugin-core/rules/strip-frontmatter.md +85 -0
- package/packages/plugin-core/rules/tdd.enforcement.md +103 -0
- package/packages/plugin-core/rules/use-ast-grep.md +113 -0
- package/packages/plugin-core/scripts/lib/datetime-utils.sh +254 -0
- package/packages/plugin-core/scripts/lib/frontmatter-utils.sh +294 -0
- package/packages/plugin-core/scripts/lib/github-utils.sh +221 -0
- package/packages/plugin-core/scripts/lib/logging-utils.sh +199 -0
- package/packages/plugin-core/scripts/lib/validation-utils.sh +339 -0
- package/packages/plugin-core/scripts/mcp/add.sh +7 -0
- package/packages/plugin-core/scripts/mcp/disable.sh +12 -0
- package/packages/plugin-core/scripts/mcp/enable.sh +12 -0
- package/packages/plugin-core/scripts/mcp/list.sh +7 -0
- package/packages/plugin-core/scripts/mcp/sync.sh +8 -0
- package/packages/plugin-data/README.md +315 -0
- package/packages/plugin-data/agents/airflow-orchestration-expert.md +158 -0
- package/packages/plugin-data/agents/kedro-pipeline-expert.md +304 -0
- package/packages/plugin-data/agents/langgraph-workflow-expert.md +530 -0
- package/packages/plugin-data/commands/airflow-dag-scaffold.md +413 -0
- package/packages/plugin-data/commands/kafka-pipeline-scaffold.md +503 -0
- package/packages/plugin-data/package.json +66 -0
- package/packages/plugin-data/plugin.json +294 -0
- package/packages/plugin-data/rules/data-quality-standards.md +373 -0
- package/packages/plugin-data/rules/etl-pipeline-standards.md +255 -0
- package/packages/plugin-data/scripts/examples/airflow-dag-example.py +245 -0
- package/packages/plugin-data/scripts/examples/dbt-transform-example.sql +238 -0
- package/packages/plugin-data/scripts/examples/kafka-streaming-example.py +257 -0
- package/packages/plugin-data/scripts/examples/pandas-etl-example.py +332 -0
- package/packages/plugin-databases/README.md +330 -0
- package/packages/plugin-databases/agents/README.md +50 -0
- package/packages/plugin-databases/agents/bigquery-expert.md +401 -0
- package/packages/plugin-databases/agents/cosmosdb-expert.md +375 -0
- package/packages/plugin-databases/agents/mongodb-expert.md +407 -0
- package/packages/plugin-databases/agents/postgresql-expert.md +329 -0
- package/packages/plugin-databases/agents/redis-expert.md +74 -0
- package/packages/plugin-databases/commands/db-optimize.md +612 -0
- package/packages/plugin-databases/package.json +60 -0
- package/packages/plugin-databases/plugin.json +237 -0
- package/packages/plugin-databases/rules/database-management-strategy.md +146 -0
- package/packages/plugin-databases/rules/database-pipeline.md +316 -0
- package/packages/plugin-databases/scripts/examples/bigquery-cost-analyze.sh +160 -0
- package/packages/plugin-databases/scripts/examples/cosmosdb-ru-optimize.sh +163 -0
- package/packages/plugin-databases/scripts/examples/mongodb-shard-check.sh +120 -0
- package/packages/plugin-databases/scripts/examples/postgres-index-analyze.sh +95 -0
- package/packages/plugin-databases/scripts/examples/redis-cache-stats.sh +121 -0
- package/packages/plugin-devops/README.md +367 -0
- package/packages/plugin-devops/agents/README.md +52 -0
- package/packages/plugin-devops/agents/azure-devops-specialist.md +308 -0
- package/packages/plugin-devops/agents/docker-containerization-expert.md +298 -0
- package/packages/plugin-devops/agents/github-operations-specialist.md +335 -0
- package/packages/plugin-devops/agents/mcp-context-manager.md +319 -0
- package/packages/plugin-devops/agents/observability-engineer.md +574 -0
- package/packages/plugin-devops/agents/ssh-operations-expert.md +1093 -0
- package/packages/plugin-devops/agents/traefik-proxy-expert.md +444 -0
- package/packages/plugin-devops/commands/ci-pipeline-create.md +581 -0
- package/packages/plugin-devops/commands/docker-optimize.md +493 -0
- package/packages/plugin-devops/commands/workflow-create.md +42 -0
- package/packages/plugin-devops/hooks/pre-docker-build.js +472 -0
- package/packages/plugin-devops/package.json +61 -0
- package/packages/plugin-devops/plugin.json +302 -0
- package/packages/plugin-devops/rules/ci-cd-kubernetes-strategy.md +25 -0
- package/packages/plugin-devops/rules/devops-troubleshooting-playbook.md +450 -0
- package/packages/plugin-devops/rules/docker-first-development.md +404 -0
- package/packages/plugin-devops/rules/github-operations.md +92 -0
- package/packages/plugin-devops/scripts/examples/docker-build-multistage.sh +43 -0
- package/packages/plugin-devops/scripts/examples/docker-compose-validate.sh +74 -0
- package/packages/plugin-devops/scripts/examples/github-workflow-validate.sh +48 -0
- package/packages/plugin-devops/scripts/examples/prometheus-health-check.sh +58 -0
- package/packages/plugin-devops/scripts/examples/ssh-key-setup.sh +74 -0
- package/packages/plugin-frameworks/README.md +309 -0
- package/packages/plugin-frameworks/agents/README.md +64 -0
- package/packages/plugin-frameworks/agents/e2e-test-engineer.md +579 -0
- package/packages/plugin-frameworks/agents/nats-messaging-expert.md +254 -0
- package/packages/plugin-frameworks/agents/react-frontend-engineer.md +393 -0
- package/packages/plugin-frameworks/agents/react-ui-expert.md +226 -0
- package/packages/plugin-frameworks/agents/tailwindcss-expert.md +1021 -0
- package/packages/plugin-frameworks/agents/ux-design-expert.md +244 -0
- package/packages/plugin-frameworks/commands/app-scaffold.md +50 -0
- package/packages/plugin-frameworks/commands/nextjs-optimize.md +692 -0
- package/packages/plugin-frameworks/commands/react-optimize.md +583 -0
- package/packages/plugin-frameworks/commands/tailwind-system.md +64 -0
- package/packages/plugin-frameworks/package.json +59 -0
- package/packages/plugin-frameworks/plugin.json +224 -0
- package/packages/plugin-frameworks/rules/performance-guidelines.md +403 -0
- package/packages/plugin-frameworks/rules/ui-development-standards.md +281 -0
- package/packages/plugin-frameworks/rules/ui-framework-rules.md +151 -0
- package/packages/plugin-frameworks/scripts/examples/react-component-perf.sh +34 -0
- package/packages/plugin-frameworks/scripts/examples/tailwind-optimize.sh +44 -0
- package/packages/plugin-frameworks/scripts/examples/vue-composition-check.sh +41 -0
- package/packages/plugin-languages/README.md +333 -0
- package/packages/plugin-languages/agents/README.md +50 -0
- package/packages/plugin-languages/agents/bash-scripting-expert.md +541 -0
- package/packages/plugin-languages/agents/javascript-frontend-engineer.md +197 -0
- package/packages/plugin-languages/agents/nodejs-backend-engineer.md +226 -0
- package/packages/plugin-languages/agents/python-backend-engineer.md +214 -0
- package/packages/plugin-languages/agents/python-backend-expert.md +289 -0
- package/packages/plugin-languages/commands/javascript-optimize.md +636 -0
- package/packages/plugin-languages/commands/nodejs-api-scaffold.md +341 -0
- package/packages/plugin-languages/commands/nodejs-optimize.md +689 -0
- package/packages/plugin-languages/commands/python-api-scaffold.md +261 -0
- package/packages/plugin-languages/commands/python-optimize.md +593 -0
- package/packages/plugin-languages/package.json +65 -0
- package/packages/plugin-languages/plugin.json +265 -0
- package/packages/plugin-languages/rules/code-quality-standards.md +496 -0
- package/packages/plugin-languages/rules/testing-standards.md +768 -0
- package/packages/plugin-languages/scripts/examples/bash-production-script.sh +520 -0
- package/packages/plugin-languages/scripts/examples/javascript-es6-patterns.js +291 -0
- package/packages/plugin-languages/scripts/examples/nodejs-async-iteration.js +360 -0
- package/packages/plugin-languages/scripts/examples/python-async-patterns.py +289 -0
- package/packages/plugin-languages/scripts/examples/typescript-patterns.ts +432 -0
- package/packages/plugin-ml/README.md +430 -0
- package/packages/plugin-ml/agents/automl-expert.md +326 -0
- package/packages/plugin-ml/agents/computer-vision-expert.md +550 -0
- package/packages/plugin-ml/agents/gradient-boosting-expert.md +455 -0
- package/packages/plugin-ml/agents/neural-network-architect.md +1228 -0
- package/packages/plugin-ml/agents/nlp-transformer-expert.md +584 -0
- package/packages/plugin-ml/agents/pytorch-expert.md +412 -0
- package/packages/plugin-ml/agents/reinforcement-learning-expert.md +2088 -0
- package/packages/plugin-ml/agents/scikit-learn-expert.md +228 -0
- package/packages/plugin-ml/agents/tensorflow-keras-expert.md +509 -0
- package/packages/plugin-ml/agents/time-series-expert.md +303 -0
- package/packages/plugin-ml/commands/ml-automl.md +572 -0
- package/packages/plugin-ml/commands/ml-train-optimize.md +657 -0
- package/packages/plugin-ml/package.json +52 -0
- package/packages/plugin-ml/plugin.json +338 -0
- package/packages/plugin-pm/README.md +368 -0
- package/packages/plugin-pm/claudeautopm-plugin-pm-2.0.0.tgz +0 -0
- package/packages/plugin-pm/commands/azure/COMMANDS.md +107 -0
- package/packages/plugin-pm/commands/azure/COMMAND_MAPPING.md +252 -0
- package/packages/plugin-pm/commands/azure/INTEGRATION_FIX.md +103 -0
- package/packages/plugin-pm/commands/azure/README.md +246 -0
- package/packages/plugin-pm/commands/azure/active-work.md +198 -0
- package/packages/plugin-pm/commands/azure/aliases.md +143 -0
- package/packages/plugin-pm/commands/azure/blocked-items.md +287 -0
- package/packages/plugin-pm/commands/azure/clean.md +93 -0
- package/packages/plugin-pm/commands/azure/docs-query.md +48 -0
- package/packages/plugin-pm/commands/azure/feature-decompose.md +380 -0
- package/packages/plugin-pm/commands/azure/feature-list.md +61 -0
- package/packages/plugin-pm/commands/azure/feature-new.md +115 -0
- package/packages/plugin-pm/commands/azure/feature-show.md +205 -0
- package/packages/plugin-pm/commands/azure/feature-start.md +130 -0
- package/packages/plugin-pm/commands/azure/fix-integration-example.md +93 -0
- package/packages/plugin-pm/commands/azure/help.md +150 -0
- package/packages/plugin-pm/commands/azure/import-us.md +269 -0
- package/packages/plugin-pm/commands/azure/init.md +211 -0
- package/packages/plugin-pm/commands/azure/next-task.md +262 -0
- package/packages/plugin-pm/commands/azure/search.md +160 -0
- package/packages/plugin-pm/commands/azure/sprint-status.md +235 -0
- package/packages/plugin-pm/commands/azure/standup.md +260 -0
- package/packages/plugin-pm/commands/azure/sync-all.md +99 -0
- package/packages/plugin-pm/commands/azure/task-analyze.md +186 -0
- package/packages/plugin-pm/commands/azure/task-close.md +329 -0
- package/packages/plugin-pm/commands/azure/task-edit.md +145 -0
- package/packages/plugin-pm/commands/azure/task-list.md +263 -0
- package/packages/plugin-pm/commands/azure/task-new.md +84 -0
- package/packages/plugin-pm/commands/azure/task-reopen.md +79 -0
- package/packages/plugin-pm/commands/azure/task-show.md +126 -0
- package/packages/plugin-pm/commands/azure/task-start.md +301 -0
- package/packages/plugin-pm/commands/azure/task-status.md +65 -0
- package/packages/plugin-pm/commands/azure/task-sync.md +67 -0
- package/packages/plugin-pm/commands/azure/us-edit.md +164 -0
- package/packages/plugin-pm/commands/azure/us-list.md +202 -0
- package/packages/plugin-pm/commands/azure/us-new.md +265 -0
- package/packages/plugin-pm/commands/azure/us-parse.md +253 -0
- package/packages/plugin-pm/commands/azure/us-show.md +188 -0
- package/packages/plugin-pm/commands/azure/us-status.md +320 -0
- package/packages/plugin-pm/commands/azure/validate.md +86 -0
- package/packages/plugin-pm/commands/azure/work-item-sync.md +47 -0
- package/packages/plugin-pm/commands/blocked.md +28 -0
- package/packages/plugin-pm/commands/clean.md +119 -0
- package/packages/plugin-pm/commands/context-create.md +136 -0
- package/packages/plugin-pm/commands/context-prime.md +170 -0
- package/packages/plugin-pm/commands/context-update.md +292 -0
- package/packages/plugin-pm/commands/context.md +28 -0
- package/packages/plugin-pm/commands/epic-close.md +86 -0
- package/packages/plugin-pm/commands/epic-decompose.md +370 -0
- package/packages/plugin-pm/commands/epic-edit.md +83 -0
- package/packages/plugin-pm/commands/epic-list.md +30 -0
- package/packages/plugin-pm/commands/epic-merge.md +222 -0
- package/packages/plugin-pm/commands/epic-oneshot.md +119 -0
- package/packages/plugin-pm/commands/epic-refresh.md +119 -0
- package/packages/plugin-pm/commands/epic-show.md +28 -0
- package/packages/plugin-pm/commands/epic-split.md +120 -0
- package/packages/plugin-pm/commands/epic-start.md +195 -0
- package/packages/plugin-pm/commands/epic-status.md +28 -0
- package/packages/plugin-pm/commands/epic-sync-modular.md +338 -0
- package/packages/plugin-pm/commands/epic-sync-original.md +473 -0
- package/packages/plugin-pm/commands/epic-sync.md +486 -0
- package/packages/plugin-pm/commands/github/workflow-create.md +42 -0
- package/packages/plugin-pm/commands/help.md +28 -0
- package/packages/plugin-pm/commands/import.md +115 -0
- package/packages/plugin-pm/commands/in-progress.md +28 -0
- package/packages/plugin-pm/commands/init.md +28 -0
- package/packages/plugin-pm/commands/issue-analyze.md +202 -0
- package/packages/plugin-pm/commands/issue-close.md +119 -0
- package/packages/plugin-pm/commands/issue-edit.md +93 -0
- package/packages/plugin-pm/commands/issue-reopen.md +87 -0
- package/packages/plugin-pm/commands/issue-show.md +41 -0
- package/packages/plugin-pm/commands/issue-start.md +234 -0
- package/packages/plugin-pm/commands/issue-status.md +95 -0
- package/packages/plugin-pm/commands/issue-sync.md +411 -0
- package/packages/plugin-pm/commands/next.md +28 -0
- package/packages/plugin-pm/commands/prd-edit.md +82 -0
- package/packages/plugin-pm/commands/prd-list.md +28 -0
- package/packages/plugin-pm/commands/prd-new.md +55 -0
- package/packages/plugin-pm/commands/prd-parse.md +42 -0
- package/packages/plugin-pm/commands/prd-status.md +28 -0
- package/packages/plugin-pm/commands/search.md +28 -0
- package/packages/plugin-pm/commands/standup.md +28 -0
- package/packages/plugin-pm/commands/status.md +28 -0
- package/packages/plugin-pm/commands/sync.md +99 -0
- package/packages/plugin-pm/commands/test-reference-update.md +151 -0
- package/packages/plugin-pm/commands/validate.md +28 -0
- package/packages/plugin-pm/commands/what-next.md +28 -0
- package/packages/plugin-pm/package.json +57 -0
- package/packages/plugin-pm/plugin.json +503 -0
- package/packages/plugin-pm/scripts/pm/analytics.js +425 -0
- package/packages/plugin-pm/scripts/pm/blocked.js +164 -0
- package/packages/plugin-pm/scripts/pm/blocked.sh +78 -0
- package/packages/plugin-pm/scripts/pm/clean.js +464 -0
- package/packages/plugin-pm/scripts/pm/context-create.js +216 -0
- package/packages/plugin-pm/scripts/pm/context-prime.js +335 -0
- package/packages/plugin-pm/scripts/pm/context-update.js +344 -0
- package/packages/plugin-pm/scripts/pm/context.js +338 -0
- package/packages/plugin-pm/scripts/pm/epic-close.js +347 -0
- package/packages/plugin-pm/scripts/pm/epic-edit.js +382 -0
- package/packages/plugin-pm/scripts/pm/epic-list.js +273 -0
- package/packages/plugin-pm/scripts/pm/epic-list.sh +109 -0
- package/packages/plugin-pm/scripts/pm/epic-show.js +291 -0
- package/packages/plugin-pm/scripts/pm/epic-show.sh +105 -0
- package/packages/plugin-pm/scripts/pm/epic-split.js +522 -0
- package/packages/plugin-pm/scripts/pm/epic-start/epic-start.js +183 -0
- package/packages/plugin-pm/scripts/pm/epic-start/epic-start.sh +94 -0
- package/packages/plugin-pm/scripts/pm/epic-status.js +291 -0
- package/packages/plugin-pm/scripts/pm/epic-status.sh +104 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/README.md +208 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/create-epic-issue.sh +77 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/create-task-issues.sh +86 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/update-epic-file.sh +79 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/update-references.sh +89 -0
- package/packages/plugin-pm/scripts/pm/epic-sync.sh +137 -0
- package/packages/plugin-pm/scripts/pm/help.js +92 -0
- package/packages/plugin-pm/scripts/pm/help.sh +90 -0
- package/packages/plugin-pm/scripts/pm/in-progress.js +178 -0
- package/packages/plugin-pm/scripts/pm/in-progress.sh +93 -0
- package/packages/plugin-pm/scripts/pm/init.js +321 -0
- package/packages/plugin-pm/scripts/pm/init.sh +178 -0
- package/packages/plugin-pm/scripts/pm/issue-close.js +232 -0
- package/packages/plugin-pm/scripts/pm/issue-edit.js +310 -0
- package/packages/plugin-pm/scripts/pm/issue-show.js +272 -0
- package/packages/plugin-pm/scripts/pm/issue-start.js +181 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/format-comment.sh +468 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/gather-updates.sh +460 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/post-comment.sh +330 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/preflight-validation.sh +348 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/update-frontmatter.sh +387 -0
- package/packages/plugin-pm/scripts/pm/lib/README.md +85 -0
- package/packages/plugin-pm/scripts/pm/lib/epic-discovery.js +119 -0
- package/packages/plugin-pm/scripts/pm/lib/logger.js +78 -0
- package/packages/plugin-pm/scripts/pm/next.js +189 -0
- package/packages/plugin-pm/scripts/pm/next.sh +72 -0
- package/packages/plugin-pm/scripts/pm/optimize.js +407 -0
- package/packages/plugin-pm/scripts/pm/pr-create.js +337 -0
- package/packages/plugin-pm/scripts/pm/pr-list.js +257 -0
- package/packages/plugin-pm/scripts/pm/prd-list.js +242 -0
- package/packages/plugin-pm/scripts/pm/prd-list.sh +103 -0
- package/packages/plugin-pm/scripts/pm/prd-new.js +684 -0
- package/packages/plugin-pm/scripts/pm/prd-parse.js +547 -0
- package/packages/plugin-pm/scripts/pm/prd-status.js +152 -0
- package/packages/plugin-pm/scripts/pm/prd-status.sh +63 -0
- package/packages/plugin-pm/scripts/pm/release.js +460 -0
- package/packages/plugin-pm/scripts/pm/search.js +192 -0
- package/packages/plugin-pm/scripts/pm/search.sh +89 -0
- package/packages/plugin-pm/scripts/pm/standup.js +362 -0
- package/packages/plugin-pm/scripts/pm/standup.sh +95 -0
- package/packages/plugin-pm/scripts/pm/status.js +148 -0
- package/packages/plugin-pm/scripts/pm/status.sh +59 -0
- package/packages/plugin-pm/scripts/pm/sync-batch.js +337 -0
- package/packages/plugin-pm/scripts/pm/sync.js +343 -0
- package/packages/plugin-pm/scripts/pm/template-list.js +141 -0
- package/packages/plugin-pm/scripts/pm/template-new.js +366 -0
- package/packages/plugin-pm/scripts/pm/validate.js +274 -0
- package/packages/plugin-pm/scripts/pm/validate.sh +106 -0
- package/packages/plugin-pm/scripts/pm/what-next.js +660 -0
- package/packages/plugin-testing/README.md +401 -0
- package/packages/plugin-testing/agents/frontend-testing-engineer.md +768 -0
- package/packages/plugin-testing/commands/jest-optimize.md +800 -0
- package/packages/plugin-testing/commands/playwright-optimize.md +887 -0
- package/packages/plugin-testing/commands/test-coverage.md +512 -0
- package/packages/plugin-testing/commands/test-performance.md +1041 -0
- package/packages/plugin-testing/commands/test-setup.md +414 -0
- package/packages/plugin-testing/package.json +40 -0
- package/packages/plugin-testing/plugin.json +197 -0
- package/packages/plugin-testing/rules/test-coverage-requirements.md +581 -0
- package/packages/plugin-testing/rules/testing-standards.md +529 -0
- package/packages/plugin-testing/scripts/examples/react-testing-example.test.jsx +460 -0
- package/packages/plugin-testing/scripts/examples/vitest-config-example.js +352 -0
- package/packages/plugin-testing/scripts/examples/vue-testing-example.test.js +586 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Python Async Patterns - Context7 Best Practices
|
|
4
|
+
|
|
5
|
+
Demonstrates modern Python async patterns from Context7 documentation:
|
|
6
|
+
- AsyncIterator type hints
|
|
7
|
+
- ParamSpec for type-safe decorators
|
|
8
|
+
- TypeIs for type narrowing
|
|
9
|
+
- TYPE_CHECKING for conditional imports
|
|
10
|
+
|
|
11
|
+
Source: /python/cpython (19,631 snippets, trust 8.9)
|
|
12
|
+
Source: /websites/fastapi_tiangolo (28,852 snippets, trust 9.0)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import asyncio
|
|
16
|
+
from typing import (
|
|
17
|
+
AsyncIterator,
|
|
18
|
+
Callable,
|
|
19
|
+
ParamSpec,
|
|
20
|
+
TypeVar,
|
|
21
|
+
TypeIs,
|
|
22
|
+
TYPE_CHECKING,
|
|
23
|
+
)
|
|
24
|
+
from collections.abc import Sequence
|
|
25
|
+
|
|
26
|
+
# Conditional imports for type checking only (Context7 pattern)
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from pydantic import BaseModel # Only imported during type checking
|
|
29
|
+
|
|
30
|
+
# Type variables for generic functions
|
|
31
|
+
P = ParamSpec('P')
|
|
32
|
+
R = TypeVar('R')
|
|
33
|
+
T = TypeVar('T')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Context7 Pattern 1: AsyncIterator for async generators
|
|
37
|
+
async def infinite_stream(start: int) -> AsyncIterator[int]:
|
|
38
|
+
"""
|
|
39
|
+
Generate infinite stream of integers.
|
|
40
|
+
|
|
41
|
+
Context7 Best Practice: Use AsyncIterator type hint for async generators
|
|
42
|
+
Source: /python/cpython
|
|
43
|
+
"""
|
|
44
|
+
current = start
|
|
45
|
+
while True:
|
|
46
|
+
yield current
|
|
47
|
+
current = await increment(current)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def increment(value: int) -> int:
|
|
51
|
+
"""Async increment operation."""
|
|
52
|
+
await asyncio.sleep(0.01) # Simulate async work
|
|
53
|
+
return value + 1
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def take(n: int, ait: AsyncIterator[T]) -> list[T]:
|
|
57
|
+
"""
|
|
58
|
+
Take n items from async iterator.
|
|
59
|
+
|
|
60
|
+
Context7 Pattern: Generic async iterator consumer
|
|
61
|
+
"""
|
|
62
|
+
items = []
|
|
63
|
+
async for item in ait:
|
|
64
|
+
items.append(item)
|
|
65
|
+
if len(items) >= n:
|
|
66
|
+
break
|
|
67
|
+
return items
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Context7 Pattern 2: ParamSpec for type-safe decorators
|
|
71
|
+
def with_retry(
|
|
72
|
+
max_attempts: int = 3,
|
|
73
|
+
delay: float = 1.0
|
|
74
|
+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
75
|
+
"""
|
|
76
|
+
Decorator with retry logic - type-safe using ParamSpec.
|
|
77
|
+
|
|
78
|
+
Context7 Best Practice: Use ParamSpec for decorators that preserve signatures
|
|
79
|
+
Source: /python/cpython
|
|
80
|
+
"""
|
|
81
|
+
def decorator(func: Callable[P, R]) -> Callable[P, R]:
|
|
82
|
+
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
83
|
+
last_exception = None
|
|
84
|
+
for attempt in range(max_attempts):
|
|
85
|
+
try:
|
|
86
|
+
if asyncio.iscoroutinefunction(func):
|
|
87
|
+
return await func(*args, **kwargs)
|
|
88
|
+
return func(*args, **kwargs)
|
|
89
|
+
except Exception as e:
|
|
90
|
+
last_exception = e
|
|
91
|
+
if attempt < max_attempts - 1:
|
|
92
|
+
await asyncio.sleep(delay * (attempt + 1))
|
|
93
|
+
|
|
94
|
+
raise last_exception
|
|
95
|
+
|
|
96
|
+
return wrapper # type: ignore[return-value]
|
|
97
|
+
|
|
98
|
+
return decorator
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# Context7 Pattern 3: TypeIs for type narrowing
|
|
102
|
+
def is_str_list(val: list[object]) -> TypeIs[list[str]]:
|
|
103
|
+
"""
|
|
104
|
+
Type guard using TypeIs.
|
|
105
|
+
|
|
106
|
+
Context7 Best Practice: Use TypeIs for type narrowing in conditionals
|
|
107
|
+
Source: /python/cpython
|
|
108
|
+
"""
|
|
109
|
+
return all(isinstance(x, str) for x in val)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def process_strings(items: list[object]) -> list[str]:
|
|
113
|
+
"""
|
|
114
|
+
Process list of items, ensuring they are strings.
|
|
115
|
+
|
|
116
|
+
Context7 Pattern: Type narrowing with TypeIs
|
|
117
|
+
"""
|
|
118
|
+
if is_str_list(items):
|
|
119
|
+
# Type checker knows items is list[str] here
|
|
120
|
+
return [s.upper() for s in items]
|
|
121
|
+
|
|
122
|
+
raise TypeError("All items must be strings")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# FastAPI Async Patterns (Context7 verified)
|
|
126
|
+
class DataProcessor:
|
|
127
|
+
"""
|
|
128
|
+
Demonstrates FastAPI async patterns.
|
|
129
|
+
|
|
130
|
+
Context7 Source: /websites/fastapi_tiangolo
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
@with_retry(max_attempts=3, delay=0.5)
|
|
134
|
+
async def fetch_data(self, url: str) -> dict:
|
|
135
|
+
"""
|
|
136
|
+
Fetch data with retry logic.
|
|
137
|
+
|
|
138
|
+
Context7 Pattern: Async methods with decorators
|
|
139
|
+
"""
|
|
140
|
+
# Simulate API call
|
|
141
|
+
await asyncio.sleep(0.1)
|
|
142
|
+
return {"url": url, "data": "sample"}
|
|
143
|
+
|
|
144
|
+
async def process_batch(
|
|
145
|
+
self,
|
|
146
|
+
items: Sequence[str]
|
|
147
|
+
) -> AsyncIterator[dict]:
|
|
148
|
+
"""
|
|
149
|
+
Process items in batch, yielding results.
|
|
150
|
+
|
|
151
|
+
Context7 Pattern: AsyncIterator for streaming results
|
|
152
|
+
"""
|
|
153
|
+
for item in items:
|
|
154
|
+
result = await self.fetch_data(item)
|
|
155
|
+
await asyncio.sleep(0.05)
|
|
156
|
+
yield result
|
|
157
|
+
|
|
158
|
+
async def aggregate_results(
|
|
159
|
+
self,
|
|
160
|
+
items: Sequence[str]
|
|
161
|
+
) -> list[dict]:
|
|
162
|
+
"""
|
|
163
|
+
Aggregate all results from async iterator.
|
|
164
|
+
|
|
165
|
+
Context7 Pattern: Consuming async iterators
|
|
166
|
+
"""
|
|
167
|
+
results = []
|
|
168
|
+
async for result in self.process_batch(items):
|
|
169
|
+
results.append(result)
|
|
170
|
+
return results
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# Example usage with type safety
|
|
174
|
+
async def main() -> None:
|
|
175
|
+
"""Demonstrate all Context7 patterns."""
|
|
176
|
+
|
|
177
|
+
# Pattern 1: AsyncIterator
|
|
178
|
+
print("Pattern 1: AsyncIterator")
|
|
179
|
+
stream = infinite_stream(1)
|
|
180
|
+
first_five = await take(5, stream)
|
|
181
|
+
print(f"First 5 from stream: {first_five}")
|
|
182
|
+
|
|
183
|
+
# Pattern 2: ParamSpec decorator
|
|
184
|
+
print("\nPattern 2: ParamSpec Decorator")
|
|
185
|
+
processor = DataProcessor()
|
|
186
|
+
result = await processor.fetch_data("https://api.example.com/data")
|
|
187
|
+
print(f"Fetched: {result}")
|
|
188
|
+
|
|
189
|
+
# Pattern 3: TypeIs type narrowing
|
|
190
|
+
print("\nPattern 3: TypeIs Type Narrowing")
|
|
191
|
+
mixed_list: list[object] = ["hello", "world"]
|
|
192
|
+
try:
|
|
193
|
+
processed = process_strings(mixed_list)
|
|
194
|
+
print(f"Processed strings: {processed}")
|
|
195
|
+
except TypeError as e:
|
|
196
|
+
print(f"Type error: {e}")
|
|
197
|
+
|
|
198
|
+
# FastAPI async patterns
|
|
199
|
+
print("\nFastAPI Async Patterns")
|
|
200
|
+
items = ["item1", "item2", "item3"]
|
|
201
|
+
|
|
202
|
+
# Streaming results
|
|
203
|
+
print("Streaming results:")
|
|
204
|
+
async for result in processor.process_batch(items):
|
|
205
|
+
print(f" Processed: {result}")
|
|
206
|
+
|
|
207
|
+
# Aggregated results
|
|
208
|
+
all_results = await processor.aggregate_results(items)
|
|
209
|
+
print(f"All results: {len(all_results)} items")
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
if __name__ == "__main__":
|
|
213
|
+
# Run async main
|
|
214
|
+
asyncio.run(main())
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
# Additional Context7 Best Practices
|
|
218
|
+
|
|
219
|
+
# 1. Type hints for all functions (MANDATORY)
|
|
220
|
+
def typed_function(param: str, count: int = 1) -> list[str]:
|
|
221
|
+
"""All functions must have type hints."""
|
|
222
|
+
return [param] * count
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# 2. Use modern type syntax (list[T] not List[T])
|
|
226
|
+
def modern_types(items: list[str], mapping: dict[str, int]) -> set[str]:
|
|
227
|
+
"""Use built-in generics (Python 3.9+)."""
|
|
228
|
+
return set(items)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# 3. Async context managers for resource cleanup
|
|
232
|
+
class AsyncResource:
|
|
233
|
+
"""Context7 Pattern: Async context manager."""
|
|
234
|
+
|
|
235
|
+
async def __aenter__(self) -> 'AsyncResource':
|
|
236
|
+
"""Acquire resource."""
|
|
237
|
+
await asyncio.sleep(0.01)
|
|
238
|
+
return self
|
|
239
|
+
|
|
240
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
241
|
+
"""Release resource."""
|
|
242
|
+
await asyncio.sleep(0.01)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
async def use_resource() -> None:
|
|
246
|
+
"""Demonstrate async context manager."""
|
|
247
|
+
async with AsyncResource() as resource:
|
|
248
|
+
print("Using resource")
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
# 4. Dataclasses for structured data
|
|
252
|
+
from dataclasses import dataclass
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@dataclass
|
|
256
|
+
class User:
|
|
257
|
+
"""Context7 Pattern: Dataclasses for data models."""
|
|
258
|
+
id: int
|
|
259
|
+
email: str
|
|
260
|
+
username: str
|
|
261
|
+
active: bool = True
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# 5. Pydantic for validation (when FastAPI is used)
|
|
265
|
+
# This would normally import from pydantic, but we use TYPE_CHECKING
|
|
266
|
+
if TYPE_CHECKING:
|
|
267
|
+
class UserCreate(BaseModel):
|
|
268
|
+
"""User creation schema with validation."""
|
|
269
|
+
email: str # Would use EmailStr from pydantic
|
|
270
|
+
username: str
|
|
271
|
+
password: str # Would use SecretStr from pydantic
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
print("""
|
|
275
|
+
Context7 Verified Best Practices Applied:
|
|
276
|
+
==========================================
|
|
277
|
+
1. ✅ AsyncIterator type hints for async generators
|
|
278
|
+
2. ✅ ParamSpec for type-safe decorators
|
|
279
|
+
3. ✅ TypeIs for type narrowing
|
|
280
|
+
4. ✅ TYPE_CHECKING for conditional imports
|
|
281
|
+
5. ✅ Modern type syntax (list[T] not List[T])
|
|
282
|
+
6. ✅ Async context managers
|
|
283
|
+
7. ✅ Dataclasses for data models
|
|
284
|
+
8. ✅ Comprehensive type hints
|
|
285
|
+
|
|
286
|
+
Sources:
|
|
287
|
+
- /python/cpython (19,631 snippets, trust 8.9)
|
|
288
|
+
- /websites/fastapi_tiangolo (28,852 snippets, trust 9.0)
|
|
289
|
+
""")
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* TypeScript Patterns - Context7 Best Practices
|
|
4
|
+
*
|
|
5
|
+
* Demonstrates modern TypeScript patterns for Node.js backend:
|
|
6
|
+
* - Type-safe API client with generics
|
|
7
|
+
* - Discriminated unions for type safety
|
|
8
|
+
* - Utility types for transformation
|
|
9
|
+
* - Decorators for cross-cutting concerns
|
|
10
|
+
* - Async patterns with proper typing
|
|
11
|
+
*
|
|
12
|
+
* Combines patterns from:
|
|
13
|
+
* - /nodejs/node (Node.js async patterns)
|
|
14
|
+
* - /airbnb/javascript (ES6 best practices)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Type-safe API Response with Generics
|
|
18
|
+
interface ApiResponse<T> {
|
|
19
|
+
status: number;
|
|
20
|
+
data: T;
|
|
21
|
+
error?: string;
|
|
22
|
+
timestamp: Date;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Discriminated Unions for Type Safety
|
|
26
|
+
type Result<T, E = Error> =
|
|
27
|
+
| { success: true; value: T }
|
|
28
|
+
| { success: false; error: E };
|
|
29
|
+
|
|
30
|
+
// Utility Type Examples
|
|
31
|
+
type User = {
|
|
32
|
+
id: number;
|
|
33
|
+
email: string;
|
|
34
|
+
username: string;
|
|
35
|
+
password: string;
|
|
36
|
+
createdAt: Date;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// ✅ CORRECT: Use Omit to exclude password from public user
|
|
40
|
+
type PublicUser = Omit<User, 'password'>;
|
|
41
|
+
|
|
42
|
+
// ✅ CORRECT: Use Pick to select specific fields
|
|
43
|
+
type UserCredentials = Pick<User, 'email' | 'password'>;
|
|
44
|
+
|
|
45
|
+
// ✅ CORRECT: Use Partial for update operations
|
|
46
|
+
type UserUpdate = Partial<Omit<User, 'id' | 'createdAt'>>;
|
|
47
|
+
|
|
48
|
+
// ✅ CORRECT: Use Required to enforce all fields
|
|
49
|
+
type CompleteUser = Required<User>;
|
|
50
|
+
|
|
51
|
+
// Type-Safe API Client
|
|
52
|
+
class ApiClient {
|
|
53
|
+
constructor(
|
|
54
|
+
private baseURL: string,
|
|
55
|
+
private timeout: number = 5000
|
|
56
|
+
) {}
|
|
57
|
+
|
|
58
|
+
// Generic method with proper typing
|
|
59
|
+
async get<T>(endpoint: string): Promise<Result<T, string>> {
|
|
60
|
+
try {
|
|
61
|
+
// Simulate API call with AbortSignal (Node.js pattern)
|
|
62
|
+
const controller = new AbortController();
|
|
63
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
// In real implementation, use fetch with signal
|
|
67
|
+
await this.delay(100);
|
|
68
|
+
clearTimeout(timeoutId);
|
|
69
|
+
|
|
70
|
+
const data = { example: 'data' } as unknown as T;
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
success: true,
|
|
74
|
+
value: data,
|
|
75
|
+
};
|
|
76
|
+
} catch (error) {
|
|
77
|
+
clearTimeout(timeoutId);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return {
|
|
82
|
+
success: false,
|
|
83
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async post<T, D>(
|
|
89
|
+
endpoint: string,
|
|
90
|
+
data: D
|
|
91
|
+
): Promise<Result<T, string>> {
|
|
92
|
+
try {
|
|
93
|
+
await this.delay(100);
|
|
94
|
+
const result = data as unknown as T;
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
value: result,
|
|
99
|
+
};
|
|
100
|
+
} catch (error) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private delay(ms: number): Promise<void> {
|
|
109
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Type-Safe Repository Pattern
|
|
114
|
+
interface Repository<T> {
|
|
115
|
+
findById(id: number): Promise<T | null>;
|
|
116
|
+
findAll(): Promise<T[]>;
|
|
117
|
+
create(data: Omit<T, 'id'>): Promise<T>;
|
|
118
|
+
update(id: number, data: Partial<T>): Promise<T>;
|
|
119
|
+
delete(id: number): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class UserRepository implements Repository<User> {
|
|
123
|
+
private users: Map<number, User> = new Map();
|
|
124
|
+
private nextId = 1;
|
|
125
|
+
|
|
126
|
+
async findById(id: number): Promise<User | null> {
|
|
127
|
+
return this.users.get(id) ?? null;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async findAll(): Promise<User[]> {
|
|
131
|
+
return Array.from(this.users.values());
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async create(data: Omit<User, 'id'>): Promise<User> {
|
|
135
|
+
const user: User = {
|
|
136
|
+
id: this.nextId++,
|
|
137
|
+
...data,
|
|
138
|
+
};
|
|
139
|
+
this.users.set(user.id, user);
|
|
140
|
+
return user;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async update(id: number, data: Partial<User>): Promise<User> {
|
|
144
|
+
const existing = this.users.get(id);
|
|
145
|
+
if (!existing) {
|
|
146
|
+
throw new Error(`User ${id} not found`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const updated = { ...existing, ...data };
|
|
150
|
+
this.users.set(id, updated);
|
|
151
|
+
return updated;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async delete(id: number): Promise<void> {
|
|
155
|
+
this.users.delete(id);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Service Layer with Type Safety
|
|
160
|
+
class UserService {
|
|
161
|
+
constructor(
|
|
162
|
+
private repository: UserRepository,
|
|
163
|
+
private apiClient: ApiClient
|
|
164
|
+
) {}
|
|
165
|
+
|
|
166
|
+
async createUser(
|
|
167
|
+
credentials: UserCredentials
|
|
168
|
+
): Promise<Result<PublicUser, string>> {
|
|
169
|
+
try {
|
|
170
|
+
// Validate email format
|
|
171
|
+
if (!this.isValidEmail(credentials.email)) {
|
|
172
|
+
return {
|
|
173
|
+
success: false,
|
|
174
|
+
error: 'Invalid email format',
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Hash password (simplified)
|
|
179
|
+
const hashedPassword = await this.hashPassword(credentials.password);
|
|
180
|
+
|
|
181
|
+
// Create user
|
|
182
|
+
const user = await this.repository.create({
|
|
183
|
+
...credentials,
|
|
184
|
+
password: hashedPassword,
|
|
185
|
+
username: credentials.email.split('@')[0],
|
|
186
|
+
createdAt: new Date(),
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Return public user (without password)
|
|
190
|
+
const publicUser = this.toPublicUser(user);
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
success: true,
|
|
194
|
+
value: publicUser,
|
|
195
|
+
};
|
|
196
|
+
} catch (error) {
|
|
197
|
+
return {
|
|
198
|
+
success: false,
|
|
199
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async getUser(id: number): Promise<Result<PublicUser, string>> {
|
|
205
|
+
const user = await this.repository.findById(id);
|
|
206
|
+
|
|
207
|
+
if (!user) {
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
error: `User ${id} not found`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
success: true,
|
|
216
|
+
value: this.toPublicUser(user),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async updateUser(
|
|
221
|
+
id: number,
|
|
222
|
+
update: UserUpdate
|
|
223
|
+
): Promise<Result<PublicUser, string>> {
|
|
224
|
+
try {
|
|
225
|
+
const updated = await this.repository.update(id, update);
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
success: true,
|
|
229
|
+
value: this.toPublicUser(updated),
|
|
230
|
+
};
|
|
231
|
+
} catch (error) {
|
|
232
|
+
return {
|
|
233
|
+
success: false,
|
|
234
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Type guard
|
|
240
|
+
private isValidEmail(email: string): boolean {
|
|
241
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
242
|
+
return emailRegex.test(email);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
private async hashPassword(password: string): Promise<string> {
|
|
246
|
+
// Simplified hashing
|
|
247
|
+
return `hashed_${password}`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Type transformation helper
|
|
251
|
+
private toPublicUser(user: User): PublicUser {
|
|
252
|
+
// ✅ CORRECT: Use destructuring with rest to omit password
|
|
253
|
+
const { password, ...publicUser } = user;
|
|
254
|
+
return publicUser;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Async Iterator with TypeScript (Node.js pattern)
|
|
259
|
+
class AsyncDataProcessor<T> {
|
|
260
|
+
constructor(private items: T[]) {}
|
|
261
|
+
|
|
262
|
+
// ✅ CORRECT: Properly typed async generator
|
|
263
|
+
async *process(): AsyncIterableIterator<T> {
|
|
264
|
+
for (const item of this.items) {
|
|
265
|
+
// Simulate async processing
|
|
266
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
267
|
+
yield item;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async collect(): Promise<T[]> {
|
|
272
|
+
const results: T[] = [];
|
|
273
|
+
|
|
274
|
+
// ✅ CORRECT: for await...of with proper typing
|
|
275
|
+
for await (const item of this.process()) {
|
|
276
|
+
results.push(item);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return results;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Type-Safe Event Emitter
|
|
284
|
+
type EventMap = {
|
|
285
|
+
userCreated: (user: PublicUser) => void;
|
|
286
|
+
userUpdated: (id: number, updates: UserUpdate) => void;
|
|
287
|
+
userDeleted: (id: number) => void;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
class TypedEventEmitter {
|
|
291
|
+
private handlers: Map<keyof EventMap, Set<Function>> = new Map();
|
|
292
|
+
|
|
293
|
+
on<K extends keyof EventMap>(event: K, handler: EventMap[K]): void {
|
|
294
|
+
if (!this.handlers.has(event)) {
|
|
295
|
+
this.handlers.set(event, new Set());
|
|
296
|
+
}
|
|
297
|
+
this.handlers.get(event)!.add(handler);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
emit<K extends keyof EventMap>(
|
|
301
|
+
event: K,
|
|
302
|
+
...args: Parameters<EventMap[K]>
|
|
303
|
+
): void {
|
|
304
|
+
const handlers = this.handlers.get(event);
|
|
305
|
+
if (handlers) {
|
|
306
|
+
handlers.forEach((handler) => handler(...args));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
off<K extends keyof EventMap>(event: K, handler: EventMap[K]): void {
|
|
311
|
+
const handlers = this.handlers.get(event);
|
|
312
|
+
if (handlers) {
|
|
313
|
+
handlers.delete(handler);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Demo Application
|
|
319
|
+
async function main() {
|
|
320
|
+
console.log('TypeScript Patterns - Context7 Best Practices');
|
|
321
|
+
console.log('='.repeat(60));
|
|
322
|
+
|
|
323
|
+
// Initialize services
|
|
324
|
+
const repository = new UserRepository();
|
|
325
|
+
const apiClient = new ApiClient('https://api.example.com');
|
|
326
|
+
const userService = new UserService(repository, apiClient);
|
|
327
|
+
const eventEmitter = new TypedEventEmitter();
|
|
328
|
+
|
|
329
|
+
// Setup event handlers
|
|
330
|
+
eventEmitter.on('userCreated', (user) => {
|
|
331
|
+
console.log(`\n[Event] User created: ${user.username} (${user.email})`);
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
eventEmitter.on('userUpdated', (id, updates) => {
|
|
335
|
+
console.log(`\n[Event] User ${id} updated:`, updates);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// Pattern 1: Creating User with Type Safety
|
|
339
|
+
console.log('\nPattern 1: Create User with Type Safety');
|
|
340
|
+
const createResult = await userService.createUser({
|
|
341
|
+
email: 'alice@example.com',
|
|
342
|
+
password: 'securepass123',
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
if (createResult.success) {
|
|
346
|
+
console.log('Created user:', createResult.value);
|
|
347
|
+
eventEmitter.emit('userCreated', createResult.value);
|
|
348
|
+
} else {
|
|
349
|
+
console.error('Failed to create user:', createResult.error);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Pattern 2: Type-Safe Updates with Partial
|
|
353
|
+
console.log('\nPattern 2: Type-Safe Updates');
|
|
354
|
+
if (createResult.success) {
|
|
355
|
+
const updateResult = await userService.updateUser(createResult.value.id, {
|
|
356
|
+
username: 'alice_smith',
|
|
357
|
+
email: 'alice.smith@example.com',
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
if (updateResult.success) {
|
|
361
|
+
console.log('Updated user:', updateResult.value);
|
|
362
|
+
eventEmitter.emit('userUpdated', updateResult.value.id, {
|
|
363
|
+
username: 'alice_smith',
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Pattern 3: Async Iterator with TypeScript
|
|
369
|
+
console.log('\nPattern 3: Async Iterator Processing');
|
|
370
|
+
const processor = new AsyncDataProcessor([1, 2, 3, 4, 5]);
|
|
371
|
+
|
|
372
|
+
console.log('Processing items...');
|
|
373
|
+
for await (const item of processor.process()) {
|
|
374
|
+
console.log(` Processed: ${item}`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Pattern 4: Generic API Client
|
|
378
|
+
console.log('\nPattern 4: Generic API Client');
|
|
379
|
+
type TodoItem = { id: number; title: string; completed: boolean };
|
|
380
|
+
|
|
381
|
+
const todoResult = await apiClient.get<TodoItem[]>('/todos');
|
|
382
|
+
|
|
383
|
+
if (todoResult.success) {
|
|
384
|
+
console.log('Fetched todos:', todoResult.value);
|
|
385
|
+
} else {
|
|
386
|
+
console.error('Failed to fetch todos:', todoResult.error);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Pattern 5: Result Type Pattern
|
|
390
|
+
console.log('\nPattern 5: Result Type Pattern');
|
|
391
|
+
const users = await repository.findAll();
|
|
392
|
+
console.log(`Total users in repository: ${users.length}`);
|
|
393
|
+
|
|
394
|
+
users.forEach((user) => {
|
|
395
|
+
const publicUser: PublicUser = {
|
|
396
|
+
id: user.id,
|
|
397
|
+
email: user.email,
|
|
398
|
+
username: user.username,
|
|
399
|
+
createdAt: user.createdAt,
|
|
400
|
+
};
|
|
401
|
+
console.log(` - ${publicUser.username} (${publicUser.email})`);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
console.log(`
|
|
405
|
+
Context7 Verified TypeScript Patterns:
|
|
406
|
+
======================================
|
|
407
|
+
1. ✅ Generic types for reusable components
|
|
408
|
+
2. ✅ Discriminated unions for type-safe error handling
|
|
409
|
+
3. ✅ Utility types (Omit, Pick, Partial, Required)
|
|
410
|
+
4. ✅ Type guards and type narrowing
|
|
411
|
+
5. ✅ Async iterators with proper typing
|
|
412
|
+
6. ✅ Type-safe event emitters
|
|
413
|
+
7. ✅ Repository pattern with generics
|
|
414
|
+
8. ✅ Service layer with error handling
|
|
415
|
+
9. ✅ Result type pattern for operations
|
|
416
|
+
10. ✅ Proper async/await typing
|
|
417
|
+
|
|
418
|
+
Sources:
|
|
419
|
+
- /nodejs/node (async patterns with typing)
|
|
420
|
+
- /airbnb/javascript (ES6 patterns with TypeScript)
|
|
421
|
+
|
|
422
|
+
Type Safety Benefits:
|
|
423
|
+
- Compile-time error detection
|
|
424
|
+
- IDE autocomplete and IntelliSense
|
|
425
|
+
- Refactoring confidence
|
|
426
|
+
- Self-documenting code
|
|
427
|
+
- Reduced runtime errors
|
|
428
|
+
`);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Run the demo
|
|
432
|
+
main().catch(console.error);
|