agileflow 4.0.0-alpha.2 → 4.0.0-alpha.21
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/CHANGELOG.md +51 -0
- package/content/plugins/accessibility/plugin.yaml +14 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/SKILL.md +392 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/references/aria-patterns.md +528 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/references/testing-checklist.md +457 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/references/wcag-guide.md +683 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/audit-page.md +310 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/implement-accessible-component.md +479 -0
- package/content/plugins/ads/agents/ads-audit-budget.md +185 -0
- package/content/plugins/ads/agents/ads-audit-compliance.md +171 -0
- package/content/plugins/ads/agents/ads-audit-creative.md +168 -0
- package/content/plugins/ads/agents/ads-audit-google.md +227 -0
- package/content/plugins/ads/agents/ads-audit-meta.md +184 -0
- package/content/plugins/ads/agents/ads-audit-tracking.md +205 -0
- package/content/plugins/ads/agents/ads-consensus.md +410 -0
- package/content/plugins/ads/agents/ads-generate.md +152 -0
- package/content/plugins/ads/agents/ads-performance-tracker.md +212 -0
- package/content/plugins/ads/plugin.yaml +23 -4
- package/content/plugins/ads/skills/agileflow-ads/SKILL.md +218 -0
- package/content/plugins/ads/skills/agileflow-ads/references/ad-copy-formula-guide.md +131 -0
- package/content/plugins/ads/skills/agileflow-ads/references/audience-targeting-guide.md +137 -0
- package/content/plugins/ads/skills/agileflow-ads/references/bid-strategy-guide.md +115 -0
- package/content/plugins/ads/skills/agileflow-ads/references/platform-benchmarks.md +100 -0
- package/content/plugins/ads/skills/agileflow-ads/workflows/audit.md +118 -0
- package/content/plugins/ads/skills/agileflow-ads/workflows/generate.md +84 -0
- package/content/plugins/audit/agents/a11y-analyzer-aria.md +173 -0
- package/content/plugins/audit/agents/a11y-analyzer-forms.md +173 -0
- package/content/plugins/audit/agents/a11y-analyzer-keyboard.md +183 -0
- package/content/plugins/audit/agents/a11y-analyzer-semantic.md +169 -0
- package/content/plugins/audit/agents/a11y-analyzer-visual.md +172 -0
- package/content/plugins/audit/agents/a11y-consensus.md +249 -0
- package/content/plugins/audit/agents/accessibility.md +558 -0
- package/content/plugins/audit/agents/api-quality-analyzer-conventions.md +156 -0
- package/content/plugins/audit/agents/api-quality-analyzer-docs.md +184 -0
- package/content/plugins/audit/agents/api-quality-analyzer-errors.md +191 -0
- package/content/plugins/audit/agents/api-quality-analyzer-pagination.md +179 -0
- package/content/plugins/audit/agents/api-quality-analyzer-versioning.md +150 -0
- package/content/plugins/audit/agents/api-quality-consensus.md +217 -0
- package/content/plugins/audit/agents/api-validator.md +191 -0
- package/content/plugins/audit/agents/arch-analyzer-circular.md +156 -0
- package/content/plugins/audit/agents/arch-analyzer-complexity.md +193 -0
- package/content/plugins/audit/agents/arch-analyzer-coupling.md +152 -0
- package/content/plugins/audit/agents/arch-analyzer-layering.md +160 -0
- package/content/plugins/audit/agents/arch-analyzer-patterns.md +210 -0
- package/content/plugins/audit/agents/arch-consensus.md +228 -0
- package/content/plugins/audit/agents/browser-qa.md +342 -0
- package/content/plugins/audit/agents/code-reviewer.md +298 -0
- package/content/plugins/audit/agents/completeness-analyzer-api.md +199 -0
- package/content/plugins/audit/agents/completeness-analyzer-conditional.md +211 -0
- package/content/plugins/audit/agents/completeness-analyzer-handlers.md +166 -0
- package/content/plugins/audit/agents/completeness-analyzer-imports.md +165 -0
- package/content/plugins/audit/agents/completeness-analyzer-routes.md +190 -0
- package/content/plugins/audit/agents/completeness-analyzer-state.md +196 -0
- package/content/plugins/audit/agents/completeness-analyzer-stubs.md +206 -0
- package/content/plugins/audit/agents/completeness-consensus.md +295 -0
- package/content/plugins/audit/agents/error-analyzer.md +213 -0
- package/content/plugins/audit/agents/flow-analyzer-authorization.md +182 -0
- package/content/plugins/audit/agents/flow-analyzer-discovery.md +174 -0
- package/content/plugins/audit/agents/flow-analyzer-errors.md +186 -0
- package/content/plugins/audit/agents/flow-analyzer-feedback.md +185 -0
- package/content/plugins/audit/agents/flow-analyzer-navigation.md +177 -0
- package/content/plugins/audit/agents/flow-analyzer-persistence.md +193 -0
- package/content/plugins/audit/agents/flow-analyzer-wiring.md +169 -0
- package/content/plugins/audit/agents/flow-consensus.md +237 -0
- package/content/plugins/audit/agents/legal-analyzer-a11y.md +114 -0
- package/content/plugins/audit/agents/legal-analyzer-ai.md +121 -0
- package/content/plugins/audit/agents/legal-analyzer-consumer.md +114 -0
- package/content/plugins/audit/agents/legal-analyzer-content.md +117 -0
- package/content/plugins/audit/agents/legal-analyzer-international.md +119 -0
- package/content/plugins/audit/agents/legal-analyzer-licensing.md +119 -0
- package/content/plugins/audit/agents/legal-analyzer-privacy.md +112 -0
- package/content/plugins/audit/agents/legal-analyzer-security.md +116 -0
- package/content/plugins/audit/agents/legal-analyzer-terms.md +115 -0
- package/content/plugins/audit/agents/legal-consensus.md +250 -0
- package/content/plugins/audit/agents/logic-analyzer-edge.md +179 -0
- package/content/plugins/audit/agents/logic-analyzer-flow.md +264 -0
- package/content/plugins/audit/agents/logic-analyzer-invariant.md +215 -0
- package/content/plugins/audit/agents/logic-analyzer-race.md +280 -0
- package/content/plugins/audit/agents/logic-analyzer-type.md +227 -0
- package/content/plugins/audit/agents/logic-consensus.md +259 -0
- package/content/plugins/audit/agents/perf-analyzer-assets.md +182 -0
- package/content/plugins/audit/agents/perf-analyzer-bundle.md +173 -0
- package/content/plugins/audit/agents/perf-analyzer-caching.md +170 -0
- package/content/plugins/audit/agents/perf-analyzer-compute.md +173 -0
- package/content/plugins/audit/agents/perf-analyzer-memory.md +193 -0
- package/content/plugins/audit/agents/perf-analyzer-network.md +165 -0
- package/content/plugins/audit/agents/perf-analyzer-queries.md +162 -0
- package/content/plugins/audit/agents/perf-analyzer-rendering.md +168 -0
- package/content/plugins/audit/agents/perf-consensus.md +287 -0
- package/content/plugins/audit/agents/qa.md +820 -0
- package/content/plugins/audit/agents/quality-analyzer-comments.md +159 -0
- package/content/plugins/audit/agents/quality-analyzer-duplication.md +184 -0
- package/content/plugins/audit/agents/quality-analyzer-naming.md +160 -0
- package/content/plugins/audit/agents/quality-consensus.md +241 -0
- package/content/plugins/audit/agents/schema-validator.md +473 -0
- package/content/plugins/audit/agents/security-analyzer-api.md +210 -0
- package/content/plugins/audit/agents/security-analyzer-auth.md +169 -0
- package/content/plugins/audit/agents/security-analyzer-authz.md +180 -0
- package/content/plugins/audit/agents/security-analyzer-deps.md +153 -0
- package/content/plugins/audit/agents/security-analyzer-infra.md +184 -0
- package/content/plugins/audit/agents/security-analyzer-injection.md +155 -0
- package/content/plugins/audit/agents/security-analyzer-input.md +201 -0
- package/content/plugins/audit/agents/security-analyzer-secrets.md +183 -0
- package/content/plugins/audit/agents/security-consensus.md +283 -0
- package/content/plugins/audit/agents/test-analyzer-assertions.md +188 -0
- package/content/plugins/audit/agents/test-analyzer-coverage.md +189 -0
- package/content/plugins/audit/agents/test-analyzer-fragility.md +193 -0
- package/content/plugins/audit/agents/test-analyzer-integration.md +161 -0
- package/content/plugins/audit/agents/test-analyzer-maintenance.md +180 -0
- package/content/plugins/audit/agents/test-analyzer-mocking.md +188 -0
- package/content/plugins/audit/agents/test-analyzer-patterns.md +196 -0
- package/content/plugins/audit/agents/test-analyzer-structure.md +184 -0
- package/content/plugins/audit/agents/test-consensus.md +301 -0
- package/content/plugins/audit/agents/testing.md +561 -0
- package/content/plugins/audit/agents/ui-validator.md +344 -0
- package/content/plugins/audit/plugin.yaml +186 -5
- package/content/plugins/audit/skills/agileflow-audit/SKILL.md +113 -0
- package/content/plugins/audit/skills/agileflow-audit/references/audit-depth-guide.md +151 -0
- package/content/plugins/audit/skills/agileflow-audit/references/dependency-risk-guide.md +139 -0
- package/content/plugins/audit/skills/agileflow-audit/references/owasp-top10.md +120 -0
- package/content/plugins/audit/skills/agileflow-audit/references/performance-budget-guide.md +143 -0
- package/content/plugins/audit/skills/agileflow-audit/references/wcag-criteria.md +117 -0
- package/content/plugins/audit/skills/agileflow-audit/workflows/run-audit.md +52 -0
- package/content/plugins/audit/skills/agileflow-audit/workflows/tdd.md +66 -0
- package/content/plugins/core/agents/adr-writer.md +521 -0
- package/content/plugins/core/agents/epic-planner.md +520 -0
- package/content/plugins/core/agents/mentor.md +709 -0
- package/content/plugins/core/agents/orchestrator.md +776 -0
- package/content/plugins/core/agents/team-coordinator.md +334 -0
- package/content/plugins/core/agents/team-lead.md +181 -0
- package/content/plugins/core/agents/workspace-orchestrator.md +146 -0
- package/content/plugins/core/hooks/context-loader.js +31 -4
- package/content/plugins/core/hooks/damage-control-bash.js +10 -2
- package/content/plugins/core/hooks/damage-control-edit.js +4 -1
- package/content/plugins/core/hooks/damage-control-patterns.yaml +1 -1
- package/content/plugins/core/hooks/damage-control-write.js +4 -1
- package/content/plugins/core/hooks/{pre-compact-state.js → post-compact-state.js} +25 -8
- package/content/plugins/core/hooks/preferences-injector.js +352 -0
- package/content/plugins/core/plugin.yaml +24 -28
- package/content/plugins/core/skills/agileflow-adr/SKILL.md +34 -8
- package/content/plugins/core/skills/agileflow-adr/references/madr-format-guide.md +86 -0
- package/content/plugins/core/skills/agileflow-adr/workflows/write-adr.md +57 -0
- package/content/plugins/core/skills/agileflow-babysit-mentor/SKILL.md +94 -27
- package/content/plugins/core/skills/agileflow-babysit-mentor/references/mentor-decision-guide.md +81 -0
- package/content/plugins/core/skills/agileflow-babysit-mentor/workflows/mentor-session.md +79 -0
- package/content/plugins/core/skills/agileflow-epic-planner/SKILL.md +37 -7
- package/content/plugins/core/skills/agileflow-epic-planner/references/epic-sizing-guide.md +81 -0
- package/content/plugins/core/skills/agileflow-epic-planner/workflows/plan-epic.md +55 -0
- package/content/plugins/core/skills/agileflow-status-updater/SKILL.md +36 -20
- package/content/plugins/core/skills/agileflow-status-updater/references/status-transitions.md +89 -0
- package/content/plugins/core/skills/agileflow-status-updater/workflows/update-status.md +56 -0
- package/content/plugins/core/skills/agileflow-story-writer/SKILL.md +39 -114
- package/content/plugins/core/skills/agileflow-story-writer/references/estimation-reference.md +36 -0
- package/content/plugins/core/skills/agileflow-story-writer/references/story-template.md +92 -0
- package/content/plugins/core/skills/agileflow-story-writer/workflows/write-story.md +138 -0
- package/content/plugins/council/agents/council-advocate.md +223 -0
- package/content/plugins/council/agents/council-analyst.md +278 -0
- package/content/plugins/council/agents/council-compounder.md +204 -0
- package/content/plugins/council/agents/council-contrarian.md +217 -0
- package/content/plugins/council/agents/council-moonshot.md +217 -0
- package/content/plugins/council/agents/council-optimist.md +185 -0
- package/content/plugins/council/agents/council-revenue.md +200 -0
- package/content/plugins/council/agents/council-technical.md +218 -0
- package/content/plugins/council/agents/multi-expert.md +334 -0
- package/content/plugins/council/plugin.yaml +23 -4
- package/content/plugins/council/skills/agileflow-council/SKILL.md +102 -0
- package/content/plugins/council/skills/agileflow-council/references/decision-log-template.md +109 -0
- package/content/plugins/council/skills/agileflow-council/references/perspective-guide.md +104 -0
- package/content/plugins/council/skills/agileflow-council/references/when-to-convene-guide.md +112 -0
- package/content/plugins/council/skills/agileflow-council/workflows/convene.md +73 -0
- package/content/plugins/council/skills/agileflow-council/workflows/multi-expert.md +75 -0
- package/content/plugins/database/plugin.yaml +14 -0
- package/content/plugins/database/skills/agileflow-database/SKILL.md +284 -0
- package/content/plugins/database/skills/agileflow-database/references/indexing-guide.md +313 -0
- package/content/plugins/database/skills/agileflow-database/references/migration-guide.md +328 -0
- package/content/plugins/database/skills/agileflow-database/references/schema-design-guide.md +467 -0
- package/content/plugins/database/skills/agileflow-database/workflows/design-schema.md +213 -0
- package/content/plugins/database/skills/agileflow-database/workflows/optimize-query.md +253 -0
- package/content/plugins/debugging/plugin.yaml +14 -0
- package/content/plugins/debugging/skills/agileflow-debug/SKILL.md +236 -0
- package/content/plugins/debugging/skills/agileflow-debug/references/common-patterns.md +350 -0
- package/content/plugins/debugging/skills/agileflow-debug/references/debugging-strategies.md +328 -0
- package/content/plugins/debugging/skills/agileflow-debug/workflows/debug-issue.md +187 -0
- package/content/plugins/debugging/skills/agileflow-debug/workflows/reproduce-bug.md +194 -0
- package/content/plugins/delivery/agents/ci.md +547 -0
- package/content/plugins/delivery/agents/devops.md +789 -0
- package/content/plugins/delivery/plugin.yaml +19 -0
- package/content/plugins/delivery/skills/agileflow-delivery/SKILL.md +111 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/changelog-format-guide.md +133 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/ci-pipeline-guide.md +158 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/pr-checklist-guide.md +133 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/release-checklist.md +142 -0
- package/content/plugins/delivery/skills/agileflow-delivery/workflows/changelog.md +72 -0
- package/content/plugins/delivery/skills/agileflow-delivery/workflows/deploy.md +74 -0
- package/content/plugins/delivery/skills/agileflow-delivery/workflows/pr.md +75 -0
- package/content/plugins/docs/agents/documentation.md +544 -0
- package/content/plugins/docs/agents/readme-updater.md +640 -0
- package/content/plugins/docs/plugin.yaml +19 -0
- package/content/plugins/docs/skills/agileflow-docs/SKILL.md +106 -0
- package/content/plugins/docs/skills/agileflow-docs/references/api-doc-template.md +167 -0
- package/content/plugins/docs/skills/agileflow-docs/references/doc-types-guide.md +141 -0
- package/content/plugins/docs/skills/agileflow-docs/references/readme-template.md +156 -0
- package/content/plugins/docs/skills/agileflow-docs/workflows/readme-sync.md +57 -0
- package/content/plugins/docs/skills/agileflow-docs/workflows/sync.md +64 -0
- package/content/plugins/engineering/agents/api.md +718 -0
- package/content/plugins/engineering/agents/codebase-query.md +285 -0
- package/content/plugins/engineering/agents/compliance.md +559 -0
- package/content/plugins/engineering/agents/database.md +644 -0
- package/content/plugins/engineering/agents/integrations.md +644 -0
- package/content/plugins/engineering/agents/mobile.md +552 -0
- package/content/plugins/engineering/agents/monitoring.md +585 -0
- package/content/plugins/engineering/agents/performance.md +529 -0
- package/content/plugins/engineering/agents/refactor.md +592 -0
- package/content/plugins/engineering/agents/security.md +524 -0
- package/content/plugins/engineering/agents/ui.md +1336 -0
- package/content/plugins/engineering/plugin.yaml +37 -0
- package/content/plugins/engineering/skills/agileflow-engineering/SKILL.md +127 -0
- package/content/plugins/engineering/skills/agileflow-engineering/references/code-review-guide.md +126 -0
- package/content/plugins/engineering/skills/agileflow-engineering/references/domain-routing-guide.md +89 -0
- package/content/plugins/engineering/skills/agileflow-engineering/references/refactoring-guide.md +136 -0
- package/content/plugins/engineering/skills/agileflow-engineering/workflows/diagnose.md +63 -0
- package/content/plugins/engineering/skills/agileflow-engineering/workflows/impact.md +60 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-features.md +179 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-growth.md +169 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-integration.md +181 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-market.md +150 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-ux.md +180 -0
- package/content/plugins/ideation/agents/brainstorm-consensus.md +245 -0
- package/content/plugins/ideation/agents/design.md +568 -0
- package/content/plugins/ideation/agents/product.md +582 -0
- package/content/plugins/ideation/plugin.yaml +31 -0
- package/content/plugins/ideation/skills/agileflow-ideation/SKILL.md +109 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/brainstorm-techniques.md +138 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/competitive-analysis-template.md +148 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/feature-prioritization-guide.md +147 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/user-story-patterns.md +152 -0
- package/content/plugins/ideation/skills/agileflow-ideation/workflows/features.md +65 -0
- package/content/plugins/ideation/skills/agileflow-ideation/workflows/ideate.md +54 -0
- package/content/plugins/migration/agents/datamigration.md +757 -0
- package/content/plugins/migration/plugin.yaml +17 -0
- package/content/plugins/migration/skills/agileflow-migration/SKILL.md +106 -0
- package/content/plugins/migration/skills/agileflow-migration/references/data-validation-checklist.md +154 -0
- package/content/plugins/migration/skills/agileflow-migration/references/migration-patterns.md +209 -0
- package/content/plugins/migration/skills/agileflow-migration/references/rollback-playbook.md +171 -0
- package/content/plugins/migration/skills/agileflow-migration/references/version-compatibility-matrix.md +155 -0
- package/content/plugins/migration/skills/agileflow-migration/workflows/plan.md +73 -0
- package/content/plugins/migration/skills/agileflow-migration/workflows/validate.md +71 -0
- package/content/plugins/performance/plugin.yaml +14 -0
- package/content/plugins/performance/skills/agileflow-performance/SKILL.md +224 -0
- package/content/plugins/performance/skills/agileflow-performance/references/optimization-patterns.md +554 -0
- package/content/plugins/performance/skills/agileflow-performance/references/profiling-guide.md +383 -0
- package/content/plugins/performance/skills/agileflow-performance/references/web-vitals-guide.md +360 -0
- package/content/plugins/performance/skills/agileflow-performance/workflows/improve-web-vitals.md +344 -0
- package/content/plugins/performance/skills/agileflow-performance/workflows/profile-and-fix.md +254 -0
- package/content/plugins/planning/agents/analytics.md +670 -0
- package/content/plugins/planning/agents/rlm-subcore.md +215 -0
- package/content/plugins/planning/plugin.yaml +19 -0
- package/content/plugins/planning/skills/agileflow-planning/SKILL.md +111 -0
- package/content/plugins/planning/skills/agileflow-planning/references/estimation-guide.md +114 -0
- package/content/plugins/planning/skills/agileflow-planning/references/rpi-workflow.md +119 -0
- package/content/plugins/planning/skills/agileflow-planning/references/sprint-planning-guide.md +145 -0
- package/content/plugins/planning/skills/agileflow-planning/workflows/impact.md +63 -0
- package/content/plugins/planning/skills/agileflow-planning/workflows/rpi.md +104 -0
- package/content/plugins/psychology/plugin.yaml +14 -0
- package/content/plugins/psychology/skills/agileflow-retention/SKILL.md +252 -0
- package/content/plugins/psychology/skills/agileflow-retention/references/competitor-analysis.md +240 -0
- package/content/plugins/psychology/skills/agileflow-retention/references/psychology-models.md +349 -0
- package/content/plugins/psychology/skills/agileflow-retention/references/retention-patterns.md +279 -0
- package/content/plugins/psychology/skills/agileflow-retention/workflows/design-retention-feature.md +287 -0
- package/content/plugins/psychology/skills/agileflow-retention/workflows/retention-audit.md +259 -0
- package/content/plugins/refactoring/plugin.yaml +14 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/SKILL.md +235 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/references/refactoring-patterns.md +405 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/references/safety-checks.md +177 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/workflows/extract-module.md +226 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/workflows/safe-refactor.md +169 -0
- package/content/plugins/research/agents/research.md +503 -0
- package/content/plugins/research/plugin.yaml +17 -0
- package/content/plugins/research/skills/agileflow-research/SKILL.md +110 -0
- package/content/plugins/research/skills/agileflow-research/references/knowledge-decay-guide.md +121 -0
- package/content/plugins/research/skills/agileflow-research/references/research-prompt-guide.md +141 -0
- package/content/plugins/research/skills/agileflow-research/references/synthesis-template.md +154 -0
- package/content/plugins/research/skills/agileflow-research/workflows/analyze.md +60 -0
- package/content/plugins/research/skills/agileflow-research/workflows/ask.md +64 -0
- package/content/plugins/research/skills/agileflow-research/workflows/import.md +66 -0
- package/content/plugins/research/skills/agileflow-research/workflows/synthesize.md +66 -0
- package/content/plugins/reviews/plugin.yaml +14 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/SKILL.md +241 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/review-checklist.md +200 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/security-patterns.md +328 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/review-pr.md +153 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/security-review.md +177 -0
- package/content/plugins/seo/agents/seo-analyzer-content.md +169 -0
- package/content/plugins/seo/agents/seo-analyzer-images.md +198 -0
- package/content/plugins/seo/agents/seo-analyzer-performance.md +217 -0
- package/content/plugins/seo/agents/seo-analyzer-schema.md +184 -0
- package/content/plugins/seo/agents/seo-analyzer-sitemap.md +177 -0
- package/content/plugins/seo/agents/seo-analyzer-technical.md +151 -0
- package/content/plugins/seo/agents/seo-consensus.md +304 -0
- package/content/plugins/seo/plugin.yaml +19 -4
- package/content/plugins/seo/skills/agileflow-seo/SKILL.md +188 -0
- package/content/plugins/seo/skills/agileflow-seo/references/cwv-thresholds.md +110 -0
- package/content/plugins/seo/skills/agileflow-seo/references/eeat-framework.md +144 -0
- package/content/plugins/seo/skills/agileflow-seo/references/keyword-research-guide.md +125 -0
- package/content/plugins/seo/skills/agileflow-seo/references/schema-types.md +139 -0
- package/content/plugins/seo/skills/agileflow-seo/references/technical-seo-checklist.md +139 -0
- package/content/plugins/seo/skills/agileflow-seo/workflows/audit.md +98 -0
- package/content/plugins/seo/skills/agileflow-seo/workflows/page.md +118 -0
- package/content/plugins/testing/plugin.yaml +16 -0
- package/content/plugins/testing/skills/agileflow-test-writer/SKILL.md +260 -0
- package/content/plugins/testing/skills/agileflow-test-writer/references/coverage-targets.md +239 -0
- package/content/plugins/testing/skills/agileflow-test-writer/references/test-patterns.md +420 -0
- package/content/plugins/testing/skills/agileflow-test-writer/workflows/add-coverage.md +154 -0
- package/content/plugins/testing/skills/agileflow-test-writer/workflows/write-tests-from-ac.md +225 -0
- package/package.json +2 -2
- package/src/cli/commands/doctor.js +818 -30
- package/src/cli/commands/hook.js +17 -14
- package/src/cli/commands/launch.js +1454 -0
- package/src/cli/commands/learn.js +149 -0
- package/src/cli/commands/plugins.js +113 -0
- package/src/cli/commands/setup.js +455 -110
- package/src/cli/commands/skills.js +324 -0
- package/src/cli/commands/status.js +8 -10
- package/src/cli/commands/update.js +76 -15
- package/src/cli/index.js +90 -26
- package/src/cli/wizard/babysit-mode-picker.js +192 -0
- package/src/cli/wizard/behaviors-picker.js +208 -54
- package/src/cli/wizard/ide-picker.js +40 -28
- package/src/cli/wizard/install-scope-picker.js +57 -0
- package/src/cli/wizard/launch-alias-picker.js +50 -0
- package/src/cli/wizard/launch-cli-picker.js +129 -0
- package/src/cli/wizard/launch-tmux-picker.js +133 -0
- package/src/cli/wizard/learnings-picker.js +40 -0
- package/src/cli/wizard/plugin-picker.js +47 -16
- package/src/lib/brand.js +116 -0
- package/src/lib/errors.js +120 -0
- package/src/lib/path-check.js +39 -0
- package/src/runtime/config/defaults.js +22 -17
- package/src/runtime/config/loader.js +77 -8
- package/src/runtime/config/schema.json +43 -16
- package/src/runtime/config/writer.js +3 -1
- package/src/runtime/ide/babysit-skill.js +202 -0
- package/src/runtime/ide/capabilities.js +84 -29
- package/src/runtime/ide/claude-code-content.js +177 -0
- package/src/runtime/ide/claude-code-settings.js +67 -29
- package/src/runtime/ide/claude-code-skills.js +47 -32
- package/src/runtime/ide/codex-config.js +295 -0
- package/src/runtime/installer/install.js +252 -24
- package/src/runtime/launch/alias-installer.js +191 -0
- package/src/runtime/launch/cli-resume.js +244 -0
- package/src/runtime/launch/closed-windows.js +338 -0
- package/src/runtime/launch/defaults.js +66 -0
- package/src/runtime/launch/detect-clis.js +69 -0
- package/src/runtime/launch/doctor.js +464 -0
- package/src/runtime/launch/exec-wrapper.js +114 -0
- package/src/runtime/launch/parallel-session.js +247 -0
- package/src/runtime/launch/prefs.js +211 -0
- package/src/runtime/launch/project-prefs.js +234 -0
- package/src/runtime/launch/resolve-cli.js +56 -0
- package/src/runtime/launch/restore.js +152 -0
- package/src/runtime/launch/schema.json +75 -0
- package/src/runtime/launch/session-lifecycle.js +313 -0
- package/src/runtime/launch/session-registry.js +401 -0
- package/src/runtime/launch/spawn.js +103 -0
- package/src/runtime/launch/tabs.js +350 -0
- package/src/runtime/launch/tmux.js +764 -0
- package/src/runtime/launch/worktree.js +260 -0
- package/src/runtime/plugins/registry.js +16 -11
- package/src/runtime/plugins/validator.js +57 -43
- package/src/runtime/skills/learnings.js +308 -0
- package/content/plugins/core/hooks/babysit-mentor-injector.js +0 -55
- package/src/cli/wizard/personalization.js +0 -64
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# Test Patterns Reference
|
|
2
|
+
|
|
3
|
+
**Load this when:** choosing test structure for a specific layer, deciding on mocking strategies, picking framework-specific patterns, or structuring a new test file from scratch.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Test layer patterns
|
|
8
|
+
|
|
9
|
+
### Unit tests
|
|
10
|
+
|
|
11
|
+
Unit tests verify a single function, class, or module in complete isolation. All dependencies are replaced with fakes, mocks, or stubs.
|
|
12
|
+
|
|
13
|
+
**When to write unit tests:**
|
|
14
|
+
|
|
15
|
+
- Pure functions with deterministic input/output
|
|
16
|
+
- Business logic / domain rules
|
|
17
|
+
- Utility functions
|
|
18
|
+
- State machines and reducers
|
|
19
|
+
- Data transformation / mapping functions
|
|
20
|
+
|
|
21
|
+
**Unit test structure (Vitest / Jest):**
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
25
|
+
import { PricingEngine } from "./pricing-engine";
|
|
26
|
+
|
|
27
|
+
describe("PricingEngine", () => {
|
|
28
|
+
let engine;
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
engine = new PricingEngine({ taxRate: 0.1 });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("calculateTotal", () => {
|
|
35
|
+
it("applies tax to the base price", () => {
|
|
36
|
+
const result = engine.calculateTotal({ basePrice: 100 });
|
|
37
|
+
expect(result.total).toBe(110);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("applies a percentage discount before tax", () => {
|
|
41
|
+
const result = engine.calculateTotal({ basePrice: 100, discountPct: 20 });
|
|
42
|
+
expect(result.total).toBe(88); // (100 * 0.8) * 1.1
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("throws when basePrice is negative", () => {
|
|
46
|
+
expect(() => engine.calculateTotal({ basePrice: -1 })).toThrow(
|
|
47
|
+
"basePrice must be non-negative",
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("returns zero tax when basePrice is zero", () => {
|
|
52
|
+
const result = engine.calculateTotal({ basePrice: 0 });
|
|
53
|
+
expect(result.tax).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Unit test structure (pytest):**
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
import pytest
|
|
63
|
+
from pricing_engine import PricingEngine
|
|
64
|
+
|
|
65
|
+
@pytest.fixture
|
|
66
|
+
def engine():
|
|
67
|
+
return PricingEngine(tax_rate=0.1)
|
|
68
|
+
|
|
69
|
+
class TestCalculateTotal:
|
|
70
|
+
def test_applies_tax_to_base_price(self, engine):
|
|
71
|
+
result = engine.calculate_total(base_price=100)
|
|
72
|
+
assert result.total == pytest.approx(110.0)
|
|
73
|
+
|
|
74
|
+
def test_applies_discount_before_tax(self, engine):
|
|
75
|
+
result = engine.calculate_total(base_price=100, discount_pct=20)
|
|
76
|
+
assert result.total == pytest.approx(88.0)
|
|
77
|
+
|
|
78
|
+
def test_raises_on_negative_price(self, engine):
|
|
79
|
+
with pytest.raises(ValueError, match="non-negative"):
|
|
80
|
+
engine.calculate_total(base_price=-1)
|
|
81
|
+
|
|
82
|
+
@pytest.mark.parametrize("base_price", [0, 0.01, 1, 999999])
|
|
83
|
+
def test_does_not_raise_on_valid_prices(self, engine, base_price):
|
|
84
|
+
engine.calculate_total(base_price=base_price) # should not raise
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Unit test structure (Go):**
|
|
88
|
+
|
|
89
|
+
```go
|
|
90
|
+
func TestCalculateTotal(t *testing.T) {
|
|
91
|
+
engine := NewPricingEngine(0.1)
|
|
92
|
+
|
|
93
|
+
tests := []struct {
|
|
94
|
+
name string
|
|
95
|
+
basePrice float64
|
|
96
|
+
discount float64
|
|
97
|
+
want float64
|
|
98
|
+
wantErr bool
|
|
99
|
+
}{
|
|
100
|
+
{"applies tax to base price", 100, 0, 110.0, false},
|
|
101
|
+
{"applies discount before tax", 100, 20, 88.0, false},
|
|
102
|
+
{"rejects negative price", -1, 0, 0, true},
|
|
103
|
+
{"handles zero price", 0, 0, 0.0, false},
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
for _, tt := range tests {
|
|
107
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
108
|
+
got, err := engine.CalculateTotal(tt.basePrice, tt.discount)
|
|
109
|
+
if (err != nil) != tt.wantErr {
|
|
110
|
+
t.Fatalf("wantErr=%v, got err=%v", tt.wantErr, err)
|
|
111
|
+
}
|
|
112
|
+
if got != tt.want {
|
|
113
|
+
t.Errorf("got %v, want %v", got, tt.want)
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### Integration tests
|
|
123
|
+
|
|
124
|
+
Integration tests verify that two or more real components work together correctly. Use a real database (test instance or in-memory), real module dependencies, but no external network calls.
|
|
125
|
+
|
|
126
|
+
**When to write integration tests:**
|
|
127
|
+
|
|
128
|
+
- Repository / data access layer (real DB queries)
|
|
129
|
+
- Service + repository wired together
|
|
130
|
+
- API route + business logic
|
|
131
|
+
- Module A calling Module B with real data
|
|
132
|
+
|
|
133
|
+
**Integration test structure (Vitest + real SQLite):**
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach } from "vitest";
|
|
137
|
+
import { UserRepository } from "./user-repository";
|
|
138
|
+
import { createTestDatabase, seedUsers, clearUsers } from "../test-helpers/db";
|
|
139
|
+
|
|
140
|
+
describe("UserRepository", () => {
|
|
141
|
+
let db;
|
|
142
|
+
let repo;
|
|
143
|
+
|
|
144
|
+
beforeAll(async () => {
|
|
145
|
+
db = await createTestDatabase(); // in-memory SQLite
|
|
146
|
+
repo = new UserRepository(db);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
afterAll(() => db.close());
|
|
150
|
+
beforeEach(() => clearUsers(db));
|
|
151
|
+
|
|
152
|
+
it("creates a user and retrieves it by id", async () => {
|
|
153
|
+
const created = await repo.create({
|
|
154
|
+
email: "alice@example.com",
|
|
155
|
+
name: "Alice",
|
|
156
|
+
});
|
|
157
|
+
const found = await repo.findById(created.id);
|
|
158
|
+
expect(found.email).toBe("alice@example.com");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("returns null when user does not exist", async () => {
|
|
162
|
+
const found = await repo.findById("non-existent-id");
|
|
163
|
+
expect(found).toBeNull();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("lists all users ordered by created_at desc", async () => {
|
|
167
|
+
await seedUsers(db, [
|
|
168
|
+
{ email: "a@example.com" },
|
|
169
|
+
{ email: "b@example.com" },
|
|
170
|
+
]);
|
|
171
|
+
const users = await repo.findAll();
|
|
172
|
+
expect(users).toHaveLength(2);
|
|
173
|
+
expect(users[0].created_at >= users[1].created_at).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Integration test structure (pytest + SQLAlchemy):**
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
import pytest
|
|
182
|
+
from sqlalchemy import create_engine
|
|
183
|
+
from sqlalchemy.orm import sessionmaker
|
|
184
|
+
from models import Base, User
|
|
185
|
+
from repositories import UserRepository
|
|
186
|
+
|
|
187
|
+
@pytest.fixture(scope="function")
|
|
188
|
+
def db_session():
|
|
189
|
+
engine = create_engine("sqlite:///:memory:")
|
|
190
|
+
Base.metadata.create_all(engine)
|
|
191
|
+
Session = sessionmaker(bind=engine)
|
|
192
|
+
session = Session()
|
|
193
|
+
yield session
|
|
194
|
+
session.close()
|
|
195
|
+
Base.metadata.drop_all(engine)
|
|
196
|
+
|
|
197
|
+
@pytest.fixture
|
|
198
|
+
def user_repo(db_session):
|
|
199
|
+
return UserRepository(db_session)
|
|
200
|
+
|
|
201
|
+
def test_create_and_retrieve_user(user_repo):
|
|
202
|
+
created = user_repo.create(email="alice@example.com", name="Alice")
|
|
203
|
+
found = user_repo.find_by_id(created.id)
|
|
204
|
+
assert found.email == "alice@example.com"
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### API / HTTP integration tests
|
|
210
|
+
|
|
211
|
+
Test HTTP endpoints with a real application instance (no real external dependencies).
|
|
212
|
+
|
|
213
|
+
**Express + Supertest (Jest/Vitest):**
|
|
214
|
+
|
|
215
|
+
```js
|
|
216
|
+
import request from "supertest";
|
|
217
|
+
import { app } from "../app";
|
|
218
|
+
import { createTestDatabase } from "../test-helpers/db";
|
|
219
|
+
|
|
220
|
+
describe("POST /api/users", () => {
|
|
221
|
+
it("creates a user and returns 201", async () => {
|
|
222
|
+
const res = await request(app)
|
|
223
|
+
.post("/api/users")
|
|
224
|
+
.send({ email: "new@example.com", name: "New User" });
|
|
225
|
+
|
|
226
|
+
expect(res.status).toBe(201);
|
|
227
|
+
expect(res.body.id).toBeDefined();
|
|
228
|
+
expect(res.body.email).toBe("new@example.com");
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("returns 400 when email is missing", async () => {
|
|
232
|
+
const res = await request(app)
|
|
233
|
+
.post("/api/users")
|
|
234
|
+
.send({ name: "No Email" });
|
|
235
|
+
|
|
236
|
+
expect(res.status).toBe(400);
|
|
237
|
+
expect(res.body.errors).toContain("email is required");
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it("returns 409 when email already exists", async () => {
|
|
241
|
+
await request(app)
|
|
242
|
+
.post("/api/users")
|
|
243
|
+
.send({ email: "dup@example.com", name: "A" });
|
|
244
|
+
const res = await request(app)
|
|
245
|
+
.post("/api/users")
|
|
246
|
+
.send({ email: "dup@example.com", name: "B" });
|
|
247
|
+
expect(res.status).toBe(409);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Mocking patterns
|
|
255
|
+
|
|
256
|
+
### Mock at the boundary — not inside the unit
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
Your module → [MOCK HERE] → External dependency (DB, HTTP, FS, Time)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Do NOT mock:
|
|
263
|
+
|
|
264
|
+
- The module under test
|
|
265
|
+
- Helper utilities that are pure functions
|
|
266
|
+
- The production database schema (use test DB instead)
|
|
267
|
+
|
|
268
|
+
### Vitest / Jest mock patterns
|
|
269
|
+
|
|
270
|
+
**Mock a module import:**
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
vi.mock("./email-service", () => ({
|
|
274
|
+
sendEmail: vi.fn().mockResolvedValue({ messageId: "msg-123" }),
|
|
275
|
+
}));
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Mock with implementation factory:**
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
const mockSend = vi.fn();
|
|
282
|
+
vi.mock("./email-service", () => ({ sendEmail: mockSend }));
|
|
283
|
+
|
|
284
|
+
it("sends a welcome email on registration", async () => {
|
|
285
|
+
mockSend.mockResolvedValueOnce({ messageId: "abc" });
|
|
286
|
+
await registerUser({ email: "x@example.com" });
|
|
287
|
+
expect(mockSend).toHaveBeenCalledWith({
|
|
288
|
+
to: "x@example.com",
|
|
289
|
+
template: "welcome",
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Spy on real module (partial mock):**
|
|
295
|
+
|
|
296
|
+
```js
|
|
297
|
+
import * as emailService from "./email-service";
|
|
298
|
+
const spy = vi
|
|
299
|
+
.spyOn(emailService, "sendEmail")
|
|
300
|
+
.mockResolvedValue({ messageId: "spy-id" });
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Mock Date.now for time-sensitive tests:**
|
|
304
|
+
|
|
305
|
+
```js
|
|
306
|
+
vi.setSystemTime(new Date("2025-01-01T00:00:00Z"));
|
|
307
|
+
// ... test ...
|
|
308
|
+
vi.useRealTimers();
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### pytest mock patterns
|
|
312
|
+
|
|
313
|
+
```python
|
|
314
|
+
from unittest.mock import patch, MagicMock
|
|
315
|
+
|
|
316
|
+
def test_sends_welcome_email(mocker):
|
|
317
|
+
mock_send = mocker.patch('services.email_service.send_email')
|
|
318
|
+
mock_send.return_value = {'message_id': 'abc'}
|
|
319
|
+
|
|
320
|
+
register_user(email='x@example.com')
|
|
321
|
+
|
|
322
|
+
mock_send.assert_called_once_with(
|
|
323
|
+
to='x@example.com',
|
|
324
|
+
template='welcome'
|
|
325
|
+
)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Fake in-memory implementations
|
|
329
|
+
|
|
330
|
+
Prefer fakes over mocks for stable interfaces:
|
|
331
|
+
|
|
332
|
+
```js
|
|
333
|
+
// Fake in-memory user repository (stable interface, no brittle call assertions)
|
|
334
|
+
class InMemoryUserRepository {
|
|
335
|
+
constructor() {
|
|
336
|
+
this.users = new Map();
|
|
337
|
+
}
|
|
338
|
+
async findById(id) {
|
|
339
|
+
return this.users.get(id) ?? null;
|
|
340
|
+
}
|
|
341
|
+
async create(data) {
|
|
342
|
+
const user = { id: crypto.randomUUID(), ...data };
|
|
343
|
+
this.users.set(user.id, user);
|
|
344
|
+
return user;
|
|
345
|
+
}
|
|
346
|
+
async delete(id) {
|
|
347
|
+
this.users.delete(id);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Async test patterns
|
|
355
|
+
|
|
356
|
+
**Always await async operations — never fire-and-forget in tests:**
|
|
357
|
+
|
|
358
|
+
```js
|
|
359
|
+
// Bad — test may pass before rejection
|
|
360
|
+
it("resolves correctly", () => {
|
|
361
|
+
fetchUser(1).then((u) => expect(u.id).toBe(1));
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
// Good
|
|
365
|
+
it("resolves correctly", async () => {
|
|
366
|
+
const user = await fetchUser(1);
|
|
367
|
+
expect(user.id).toBe(1);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// Good — testing rejection
|
|
371
|
+
it("rejects when user not found", async () => {
|
|
372
|
+
await expect(fetchUser(999)).rejects.toThrow("User not found");
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## Test data patterns
|
|
379
|
+
|
|
380
|
+
### Factory functions (preferred over hard-coded objects)
|
|
381
|
+
|
|
382
|
+
```js
|
|
383
|
+
function createUser(overrides = {}) {
|
|
384
|
+
return {
|
|
385
|
+
id: "user-1",
|
|
386
|
+
email: "test@example.com",
|
|
387
|
+
name: "Test User",
|
|
388
|
+
role: "member",
|
|
389
|
+
createdAt: new Date("2025-01-01"),
|
|
390
|
+
...overrides,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Usage — only specify what matters for the test
|
|
395
|
+
const admin = createUser({ role: "admin" });
|
|
396
|
+
const unverified = createUser({ emailVerified: false });
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Fixtures vs factories
|
|
400
|
+
|
|
401
|
+
| Pattern | When to use |
|
|
402
|
+
| -------------------- | ------------------------------------------------------------ |
|
|
403
|
+
| **Factory function** | Test data that varies per test; prefer this by default |
|
|
404
|
+
| **Fixture file** | Large, complex, stable data (e.g., a full JSON API response) |
|
|
405
|
+
| **Seeding helper** | Integration tests that need data in a real DB |
|
|
406
|
+
| **Inline object** | Simple tests with one or two fields — factory is overkill |
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Common anti-patterns to avoid
|
|
411
|
+
|
|
412
|
+
| Anti-pattern | Problem | Fix |
|
|
413
|
+
| ---------------------------------------------------------- | ----------------------------------------------- | ----------------------------------------------------------- |
|
|
414
|
+
| `expect(result).toBeTruthy()` | Passes on `1`, `"false"`, `{}` — proves nothing | Use `toBe(true)`, `toEqual(expected)`, or specific matchers |
|
|
415
|
+
| `expect(mockFn).toHaveBeenCalled()` without argument check | Doesn't verify correct arguments were passed | Use `toHaveBeenCalledWith(...)` |
|
|
416
|
+
| Tests that depend on execution order | Brittle — fails when test runner parallelises | Use `beforeEach` to reset state; never share mutable state |
|
|
417
|
+
| `setTimeout(fn, 100)` in tests | Flaky — timing-dependent | Use `vi.useFakeTimers()` / `jest.useFakeTimers()` |
|
|
418
|
+
| Asserting on full response body | Brittle to schema changes | Assert on specific fields that matter for the test |
|
|
419
|
+
| Empty `catch` blocks | Hides failures | Always `throw` or `fail()` in error branches |
|
|
420
|
+
| Test file with 0 `expect` calls | Doesn't assert anything | Vitest/Jest won't catch this — audit tests manually |
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Workflow: Add Coverage to Existing Code
|
|
2
|
+
|
|
3
|
+
**Triggers:** "increase test coverage", "add tests to this file", "this module has no tests", user mentions low coverage percentages
|
|
4
|
+
|
|
5
|
+
**Goal:** Analyse an existing file or module, identify the highest-value untested paths, and add tests that meaningfully improve confidence — not just line counts.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Inputs needed
|
|
10
|
+
|
|
11
|
+
| Input | Required | How to get it |
|
|
12
|
+
| ---------------------------------- | -------- | --------------------------------------------------------------- |
|
|
13
|
+
| Target file or module | Yes | User specifies; or ask |
|
|
14
|
+
| Current coverage report | No | Run `npm test -- --coverage` or `pytest --cov` and paste output |
|
|
15
|
+
| Test framework | Yes | Detect from config |
|
|
16
|
+
| Existing test file for this module | No | Search for `*.test.*` or `*_test.*` adjacent to the file |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
### Step 1: Read the target file
|
|
23
|
+
|
|
24
|
+
Read the source file completely. Build a mental model of:
|
|
25
|
+
|
|
26
|
+
- Every exported function / class / method
|
|
27
|
+
- Every branch (if/else, switch, ternary, nullish coalescing)
|
|
28
|
+
- Every error path (throw, reject, catch, return null/undefined)
|
|
29
|
+
- Every async operation
|
|
30
|
+
|
|
31
|
+
### Step 2: Find (or analyse) what's already tested
|
|
32
|
+
|
|
33
|
+
If an existing test file exists, read it. Map each test to the branches it covers. Identify the gaps.
|
|
34
|
+
|
|
35
|
+
If no test file exists, every branch is untested.
|
|
36
|
+
|
|
37
|
+
If a coverage report is available, read it to find:
|
|
38
|
+
|
|
39
|
+
- Uncovered lines (marked with `|` in text reports)
|
|
40
|
+
- Uncovered branches (marked with `U` in branch summary)
|
|
41
|
+
|
|
42
|
+
### Step 3: Rank uncovered paths by value
|
|
43
|
+
|
|
44
|
+
Not all untested code is equally worth testing. Rank by:
|
|
45
|
+
|
|
46
|
+
| Priority | What to test | Rationale |
|
|
47
|
+
| -------- | -------------------------------------------------------------- | --------------------------------- |
|
|
48
|
+
| P0 | Error paths that could cause data loss or security holes | Silent failure is dangerous |
|
|
49
|
+
| P0 | All branches in auth / permission checks | Wrong result = security breach |
|
|
50
|
+
| P1 | Branches in core business logic (pricing, routing, validation) | Bugs here cost real money |
|
|
51
|
+
| P1 | Edge cases on public API inputs | API contracts matter |
|
|
52
|
+
| P2 | Happy paths not yet covered | Baseline confidence |
|
|
53
|
+
| P3 | Simple getters / trivial branches | Low ROI; skip if time-constrained |
|
|
54
|
+
|
|
55
|
+
Present the prioritised list to the user if it's long (10+ items).
|
|
56
|
+
|
|
57
|
+
### Step 4: Choose the right test layer
|
|
58
|
+
|
|
59
|
+
For each gap:
|
|
60
|
+
|
|
61
|
+
- If the gap is in a pure function → unit test
|
|
62
|
+
- If the gap is in a database query / ORM call → integration test (with test DB)
|
|
63
|
+
- If the gap is in an HTTP handler → integration test (with supertest / httptest)
|
|
64
|
+
- If the gap is in a UI component → unit test with a render utility (React Testing Library, Vue Test Utils)
|
|
65
|
+
|
|
66
|
+
### Step 5: Write the tests
|
|
67
|
+
|
|
68
|
+
For each P0 and P1 gap:
|
|
69
|
+
|
|
70
|
+
1. Check if a factory or fixture exists for the required test data
|
|
71
|
+
2. Write the test in the existing test file (or create one next to the source file)
|
|
72
|
+
3. Follow the Arrange → Act → Assert pattern
|
|
73
|
+
4. Use specific assertions — not `toBeTruthy`
|
|
74
|
+
|
|
75
|
+
### Step 6: Estimate coverage improvement
|
|
76
|
+
|
|
77
|
+
After writing tests, estimate:
|
|
78
|
+
|
|
79
|
+
- Which lines / branches are now covered
|
|
80
|
+
- Expected new coverage % (rough estimate)
|
|
81
|
+
- What is still uncovered and why (e.g. infrastructure code, trivial getters excluded intentionally)
|
|
82
|
+
|
|
83
|
+
### Step 7: Present the result
|
|
84
|
+
|
|
85
|
+
```xml
|
|
86
|
+
<invoke name="AskUserQuestion">
|
|
87
|
+
<parameter name="questions">[{
|
|
88
|
+
"question": "Coverage analysis complete for {filename}. Found {N} uncovered paths. Added {M} tests targeting the {K} highest-value gaps.",
|
|
89
|
+
"header": "Next step",
|
|
90
|
+
"multiSelect": false,
|
|
91
|
+
"options": [
|
|
92
|
+
{"label": "Write the updated test file now (Recommended)", "description": "I'll update {test-file-path} with the {M} new tests"},
|
|
93
|
+
{"label": "Also cover the remaining {R} lower-priority paths", "description": "Full coverage pass — will add {R} more tests for trivial branches and getters"},
|
|
94
|
+
{"label": "Review the test plan first", "description": "I'll show you each test I'm planning before writing anything"},
|
|
95
|
+
{"label": "Run coverage to confirm the improvement", "description": "I'll write the file then run the test suite to show the before/after coverage delta"}
|
|
96
|
+
]
|
|
97
|
+
}]</parameter>
|
|
98
|
+
</invoke>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Coverage gap analysis template
|
|
104
|
+
|
|
105
|
+
When presenting gaps to the user, use this format:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Coverage gaps in src/services/user-service.ts
|
|
109
|
+
──────────────────────────────────────────────
|
|
110
|
+
Estimated current: ~45% branch coverage
|
|
111
|
+
|
|
112
|
+
P0 gaps (write these first):
|
|
113
|
+
✗ Line 34-38: deleteUser() — no test for the DB error path (throws CascadeError)
|
|
114
|
+
✗ Line 67: checkPermission() — only 'admin' role tested; 'viewer' and 'editor' untested
|
|
115
|
+
|
|
116
|
+
P1 gaps:
|
|
117
|
+
✗ Line 102: updateEmail() — happy path exists but no test for duplicate email (409 case)
|
|
118
|
+
✗ Line 118-125: sendVerificationEmail() — called but never asserted on
|
|
119
|
+
|
|
120
|
+
P2 gaps:
|
|
121
|
+
✗ Line 77: getUser() — null return when user not found has no test
|
|
122
|
+
✗ Line 89: listUsers() — empty result set not tested
|
|
123
|
+
|
|
124
|
+
Skip (low ROI):
|
|
125
|
+
✗ Line 12: constructor — getter only, no logic
|
|
126
|
+
✗ Line 200-202: formatName() — trivial string concat
|
|
127
|
+
|
|
128
|
+
Estimated coverage after writing P0 + P1: ~78% branch coverage
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Iterative coverage improvement (brownfield strategy)
|
|
134
|
+
|
|
135
|
+
For large legacy files with very low coverage, don't try to cover everything at once. Use the ratchet approach:
|
|
136
|
+
|
|
137
|
+
1. **Today:** Write tests for all P0 and P1 gaps in the files you're currently touching
|
|
138
|
+
2. **Add a coverage gate:** Set the CI threshold to current coverage − 0% (no regression allowed)
|
|
139
|
+
3. **Each PR:** Add tests for new code + one cleanup pass on P1 gaps in touched files
|
|
140
|
+
4. **Never go backwards:** If coverage drops, it fails CI
|
|
141
|
+
|
|
142
|
+
This turns coverage improvement into an automatic side effect of regular development.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## When coverage is the wrong goal
|
|
147
|
+
|
|
148
|
+
Flag to the user when you detect:
|
|
149
|
+
|
|
150
|
+
- Tests that only check `expect(result).toBeDefined()` — this is coverage inflation, not real testing
|
|
151
|
+
- Tests that call the function but assert nothing useful
|
|
152
|
+
- 100% coverage on a file that has no assertions (this is possible!)
|
|
153
|
+
|
|
154
|
+
In these cases, improving assertion quality matters more than adding new tests.
|