gaia-framework 1.57.0 → 1.57.2
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 +1 -1
- package/bin/gaia-framework.js +27 -19
- package/gaia-install.sh +1 -1
- package/package.json +15 -11
- package/.claude/commands/gaia-a11y-testing.md +0 -17
- package/.claude/commands/gaia-action-items.md +0 -23
- package/.claude/commands/gaia-add-feature.md +0 -17
- package/.claude/commands/gaia-add-stories.md +0 -17
- package/.claude/commands/gaia-advanced-elicitation.md +0 -17
- package/.claude/commands/gaia-adversarial.md +0 -15
- package/.claude/commands/gaia-agent-analyst.md +0 -14
- package/.claude/commands/gaia-agent-architect.md +0 -14
- package/.claude/commands/gaia-agent-brainstorming.md +0 -14
- package/.claude/commands/gaia-agent-data-engineer.md +0 -14
- package/.claude/commands/gaia-agent-design-thinking.md +0 -14
- package/.claude/commands/gaia-agent-dev-angular.md +0 -14
- package/.claude/commands/gaia-agent-dev-flutter.md +0 -14
- package/.claude/commands/gaia-agent-dev-go.md +0 -14
- package/.claude/commands/gaia-agent-dev-java.md +0 -14
- package/.claude/commands/gaia-agent-dev-mobile.md +0 -14
- package/.claude/commands/gaia-agent-dev-python.md +0 -14
- package/.claude/commands/gaia-agent-dev-typescript.md +0 -14
- package/.claude/commands/gaia-agent-devops.md +0 -14
- package/.claude/commands/gaia-agent-innovation.md +0 -14
- package/.claude/commands/gaia-agent-performance.md +0 -14
- package/.claude/commands/gaia-agent-pm.md +0 -14
- package/.claude/commands/gaia-agent-presentation.md +0 -14
- package/.claude/commands/gaia-agent-problem-solver.md +0 -14
- package/.claude/commands/gaia-agent-qa.md +0 -14
- package/.claude/commands/gaia-agent-security.md +0 -14
- package/.claude/commands/gaia-agent-sm.md +0 -14
- package/.claude/commands/gaia-agent-storyteller.md +0 -14
- package/.claude/commands/gaia-agent-tech-writer.md +0 -14
- package/.claude/commands/gaia-agent-test-architect.md +0 -14
- package/.claude/commands/gaia-agent-ux-designer.md +0 -14
- package/.claude/commands/gaia-agent-validator.md +0 -14
- package/.claude/commands/gaia-atdd.md +0 -17
- package/.claude/commands/gaia-brainstorm.md +0 -17
- package/.claude/commands/gaia-brainstorming.md +0 -17
- package/.claude/commands/gaia-brownfield.md +0 -17
- package/.claude/commands/gaia-build-configs.md +0 -22
- package/.claude/commands/gaia-change-request.md +0 -11
- package/.claude/commands/gaia-changelog.md +0 -16
- package/.claude/commands/gaia-check-dod.md +0 -17
- package/.claude/commands/gaia-check-review-gate.md +0 -17
- package/.claude/commands/gaia-ci-setup.md +0 -17
- package/.claude/commands/gaia-code-review.md +0 -17
- package/.claude/commands/gaia-correct-course.md +0 -17
- package/.claude/commands/gaia-create-arch.md +0 -17
- package/.claude/commands/gaia-create-epics.md +0 -17
- package/.claude/commands/gaia-create-prd.md +0 -17
- package/.claude/commands/gaia-create-story.md +0 -23
- package/.claude/commands/gaia-create-ux.md +0 -17
- package/.claude/commands/gaia-creative-sprint.md +0 -17
- package/.claude/commands/gaia-deploy-checklist.md +0 -17
- package/.claude/commands/gaia-design-thinking.md +0 -17
- package/.claude/commands/gaia-dev-story.md +0 -23
- package/.claude/commands/gaia-document-project.md +0 -17
- package/.claude/commands/gaia-domain-research.md +0 -17
- package/.claude/commands/gaia-edge-cases.md +0 -15
- package/.claude/commands/gaia-edit-arch.md +0 -17
- package/.claude/commands/gaia-edit-prd.md +0 -17
- package/.claude/commands/gaia-edit-test-plan.md +0 -17
- package/.claude/commands/gaia-editorial-prose.md +0 -15
- package/.claude/commands/gaia-editorial-structure.md +0 -15
- package/.claude/commands/gaia-epic-status.md +0 -17
- package/.claude/commands/gaia-fix-story.md +0 -17
- package/.claude/commands/gaia-help.md +0 -15
- package/.claude/commands/gaia-index-docs.md +0 -15
- package/.claude/commands/gaia-infra-design.md +0 -17
- package/.claude/commands/gaia-innovation.md +0 -17
- package/.claude/commands/gaia-market-research.md +0 -17
- package/.claude/commands/gaia-memory-hygiene.md +0 -17
- package/.claude/commands/gaia-merge-docs.md +0 -16
- package/.claude/commands/gaia-mobile-testing.md +0 -17
- package/.claude/commands/gaia-nfr.md +0 -17
- package/.claude/commands/gaia-party.md +0 -17
- package/.claude/commands/gaia-perf-testing.md +0 -17
- package/.claude/commands/gaia-performance-review.md +0 -17
- package/.claude/commands/gaia-pitch-deck.md +0 -17
- package/.claude/commands/gaia-post-deploy.md +0 -17
- package/.claude/commands/gaia-problem-solving.md +0 -17
- package/.claude/commands/gaia-product-brief.md +0 -17
- package/.claude/commands/gaia-project-context.md +0 -17
- package/.claude/commands/gaia-qa-tests.md +0 -17
- package/.claude/commands/gaia-quick-dev.md +0 -17
- package/.claude/commands/gaia-quick-spec.md +0 -17
- package/.claude/commands/gaia-readiness-check.md +0 -17
- package/.claude/commands/gaia-refresh-ground-truth.md +0 -17
- package/.claude/commands/gaia-release-plan.md +0 -17
- package/.claude/commands/gaia-resume.md +0 -25
- package/.claude/commands/gaia-retro.md +0 -20
- package/.claude/commands/gaia-review-a11y.md +0 -16
- package/.claude/commands/gaia-review-api.md +0 -16
- package/.claude/commands/gaia-review-deps.md +0 -16
- package/.claude/commands/gaia-review-perf.md +0 -16
- package/.claude/commands/gaia-review-security.md +0 -16
- package/.claude/commands/gaia-rollback-plan.md +0 -17
- package/.claude/commands/gaia-run-all-reviews.md +0 -17
- package/.claude/commands/gaia-security-review.md +0 -17
- package/.claude/commands/gaia-shard-doc.md +0 -15
- package/.claude/commands/gaia-slide-deck.md +0 -17
- package/.claude/commands/gaia-sprint-plan.md +0 -17
- package/.claude/commands/gaia-sprint-status.md +0 -17
- package/.claude/commands/gaia-storytelling.md +0 -17
- package/.claude/commands/gaia-summarize.md +0 -16
- package/.claude/commands/gaia-teach-testing.md +0 -17
- package/.claude/commands/gaia-tech-debt-review.md +0 -20
- package/.claude/commands/gaia-tech-research.md +0 -17
- package/.claude/commands/gaia-test-automate.md +0 -17
- package/.claude/commands/gaia-test-design.md +0 -17
- package/.claude/commands/gaia-test-framework.md +0 -17
- package/.claude/commands/gaia-test-review.md +0 -17
- package/.claude/commands/gaia-threat-model.md +0 -17
- package/.claude/commands/gaia-trace.md +0 -17
- package/.claude/commands/gaia-triage-findings.md +0 -20
- package/.claude/commands/gaia-val-validate-plan.md +0 -17
- package/.claude/commands/gaia-val-validate.md +0 -17
- package/.claude/commands/gaia-validate-framework.md +0 -17
- package/.claude/commands/gaia-validate-prd.md +0 -17
- package/.claude/commands/gaia-validate-story.md +0 -22
- package/.claude/commands/gaia.md +0 -32
- package/CLAUDE.md +0 -165
- package/_gaia/_config/agent-manifest.csv +0 -29
- package/_gaia/_config/agents/CUSTOMIZATION-README.md +0 -117
- package/_gaia/_config/files-manifest.csv +0 -30
- package/_gaia/_config/gaia-help.csv +0 -82
- package/_gaia/_config/global.yaml +0 -45
- package/_gaia/_config/lifecycle-sequence.yaml +0 -593
- package/_gaia/_config/manifest.yaml +0 -24
- package/_gaia/_config/skill-manifest.csv +0 -12
- package/_gaia/_config/task-manifest.csv +0 -17
- package/_gaia/_config/workflow-manifest.csv +0 -73
- package/_gaia/_memory/tier2-results/.gitkeep +0 -0
- package/_gaia/_memory/tier2-results/checkpoint-resume-2026-03-24.yaml +0 -6
- package/_gaia/_memory/tier2-results/engine-scenarios-2026-03-22.yaml +0 -14
- package/_gaia/core/.resolved/.gitkeep +0 -0
- package/_gaia/core/agents/orchestrator.md +0 -303
- package/_gaia/core/config.yaml +0 -8
- package/_gaia/core/engine/error-recovery.xml +0 -28
- package/_gaia/core/engine/protocols/discover-inputs.xml +0 -31
- package/_gaia/core/engine/protocols/handoff.xml +0 -21
- package/_gaia/core/engine/protocols/preflight-check.xml +0 -31
- package/_gaia/core/engine/task-runner.xml +0 -63
- package/_gaia/core/engine/workflow.xml +0 -225
- package/_gaia/core/module-help.csv +0 -21
- package/_gaia/core/protocols/agent-specification-protocol.md +0 -103
- package/_gaia/core/protocols/review-gate-check.xml +0 -29
- package/_gaia/core/protocols/sprint-status-write-safety.xml +0 -35
- package/_gaia/core/protocols/status-sync.xml +0 -49
- package/_gaia/core/tasks/editorial-review-prose.xml +0 -42
- package/_gaia/core/tasks/editorial-review-structure.xml +0 -43
- package/_gaia/core/tasks/generate-changelog.xml +0 -35
- package/_gaia/core/tasks/help.md +0 -45
- package/_gaia/core/tasks/index-docs.xml +0 -46
- package/_gaia/core/tasks/merge-docs.xml +0 -34
- package/_gaia/core/tasks/review-accessibility.xml +0 -47
- package/_gaia/core/tasks/review-adversarial.xml +0 -55
- package/_gaia/core/tasks/review-api-design.xml +0 -38
- package/_gaia/core/tasks/review-dependency-audit.xml +0 -38
- package/_gaia/core/tasks/review-edge-case-hunter.xml +0 -52
- package/_gaia/core/tasks/review-performance.xml +0 -49
- package/_gaia/core/tasks/review-security.xml +0 -37
- package/_gaia/core/tasks/shard-doc.xml +0 -49
- package/_gaia/core/tasks/summarize-doc.xml +0 -33
- package/_gaia/core/tasks/validate-framework.xml +0 -66
- package/_gaia/core/workflows/brainstorming/steps/step-01-session-setup.md +0 -7
- package/_gaia/core/workflows/brainstorming/steps/step-02-technique-selection.md +0 -20
- package/_gaia/core/workflows/brainstorming/steps/step-03-technique-execution.md +0 -11
- package/_gaia/core/workflows/brainstorming/steps/step-04-idea-organization.md +0 -14
- package/_gaia/core/workflows/brainstorming/template.md +0 -38
- package/_gaia/core/workflows/brainstorming/workflow.yaml +0 -26
- package/_gaia/core/workflows/party-mode/steps/step-01-agent-loading.md +0 -11
- package/_gaia/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +0 -16
- package/_gaia/core/workflows/party-mode/steps/step-03-graceful-exit.md +0 -10
- package/_gaia/core/workflows/party-mode/workflow.yaml +0 -23
- package/_gaia/creative/.resolved/.gitkeep +0 -0
- package/_gaia/creative/agents/brainstorming-coach.md +0 -93
- package/_gaia/creative/agents/design-thinking-coach.md +0 -91
- package/_gaia/creative/agents/innovation-strategist.md +0 -89
- package/_gaia/creative/agents/presentation-designer.md +0 -99
- package/_gaia/creative/agents/problem-solver.md +0 -90
- package/_gaia/creative/agents/storyteller.md +0 -90
- package/_gaia/creative/config.yaml +0 -8
- package/_gaia/creative/data/design-methods.csv +0 -28
- package/_gaia/creative/data/innovation-frameworks.csv +0 -15
- package/_gaia/creative/data/solving-methods.csv +0 -14
- package/_gaia/creative/data/story-types.csv +0 -12
- package/_gaia/creative/module-help.csv +0 -8
- package/_gaia/creative/teams/creative-squad.yaml +0 -10
- package/_gaia/creative/workflows/creative-sprint/checklist.md +0 -10
- package/_gaia/creative/workflows/creative-sprint/instructions.xml +0 -40
- package/_gaia/creative/workflows/creative-sprint/workflow.yaml +0 -11
- package/_gaia/creative/workflows/design-thinking/checklist.md +0 -25
- package/_gaia/creative/workflows/design-thinking/instructions.xml +0 -38
- package/_gaia/creative/workflows/design-thinking/workflow.yaml +0 -13
- package/_gaia/creative/workflows/innovation-strategy/checklist.md +0 -26
- package/_gaia/creative/workflows/innovation-strategy/instructions.xml +0 -34
- package/_gaia/creative/workflows/innovation-strategy/workflow.yaml +0 -13
- package/_gaia/creative/workflows/pitch-deck/checklist.md +0 -22
- package/_gaia/creative/workflows/pitch-deck/instructions.xml +0 -49
- package/_gaia/creative/workflows/pitch-deck/workflow.yaml +0 -15
- package/_gaia/creative/workflows/problem-solving/checklist.md +0 -26
- package/_gaia/creative/workflows/problem-solving/instructions.xml +0 -39
- package/_gaia/creative/workflows/problem-solving/workflow.yaml +0 -13
- package/_gaia/creative/workflows/slide-deck/checklist.md +0 -21
- package/_gaia/creative/workflows/slide-deck/instructions.xml +0 -39
- package/_gaia/creative/workflows/slide-deck/workflow.yaml +0 -15
- package/_gaia/creative/workflows/storytelling/checklist.md +0 -26
- package/_gaia/creative/workflows/storytelling/instructions.xml +0 -38
- package/_gaia/creative/workflows/storytelling/workflow.yaml +0 -13
- package/_gaia/dev/agents/_base-dev.md +0 -180
- package/_gaia/dev/agents/angular-dev.md +0 -70
- package/_gaia/dev/agents/flutter-dev.md +0 -70
- package/_gaia/dev/agents/go-dev.md +0 -72
- package/_gaia/dev/agents/java-dev.md +0 -70
- package/_gaia/dev/agents/mobile-dev.md +0 -70
- package/_gaia/dev/agents/python-dev.md +0 -70
- package/_gaia/dev/agents/typescript-dev.md +0 -70
- package/_gaia/dev/config.yaml +0 -11
- package/_gaia/dev/knowledge/_index.csv +0 -25
- package/_gaia/dev/knowledge/angular/angular-conventions.md +0 -119
- package/_gaia/dev/knowledge/angular/angular-patterns.md +0 -126
- package/_gaia/dev/knowledge/angular/ngrx-state.md +0 -124
- package/_gaia/dev/knowledge/angular/rxjs-patterns.md +0 -119
- package/_gaia/dev/knowledge/flutter/dart-conventions.md +0 -143
- package/_gaia/dev/knowledge/flutter/platform-channels.md +0 -144
- package/_gaia/dev/knowledge/flutter/state-management.md +0 -144
- package/_gaia/dev/knowledge/flutter/widget-patterns.md +0 -134
- package/_gaia/dev/knowledge/go/gin-fiber-patterns.md +0 -40
- package/_gaia/dev/knowledge/go/go-conventions.md +0 -54
- package/_gaia/dev/knowledge/go/go-stdlib-patterns.md +0 -39
- package/_gaia/dev/knowledge/go/go-testing-patterns.md +0 -39
- package/_gaia/dev/knowledge/java/jpa-patterns.md +0 -136
- package/_gaia/dev/knowledge/java/maven-gradle.md +0 -189
- package/_gaia/dev/knowledge/java/microservices.md +0 -159
- package/_gaia/dev/knowledge/java/spring-boot-patterns.md +0 -160
- package/_gaia/dev/knowledge/mobile/kotlin-patterns.md +0 -193
- package/_gaia/dev/knowledge/mobile/mobile-testing.md +0 -186
- package/_gaia/dev/knowledge/mobile/react-native-patterns.md +0 -162
- package/_gaia/dev/knowledge/mobile/swift-patterns.md +0 -190
- package/_gaia/dev/knowledge/python/data-pipelines.md +0 -169
- package/_gaia/dev/knowledge/python/django-patterns.md +0 -145
- package/_gaia/dev/knowledge/python/fastapi-patterns.md +0 -164
- package/_gaia/dev/knowledge/python/python-conventions.md +0 -170
- package/_gaia/dev/knowledge/typescript/express-patterns.md +0 -188
- package/_gaia/dev/knowledge/typescript/nextjs-patterns.md +0 -166
- package/_gaia/dev/knowledge/typescript/react-patterns.md +0 -176
- package/_gaia/dev/knowledge/typescript/ts-conventions.md +0 -133
- package/_gaia/dev/module-help.csv +0 -10
- package/_gaia/dev/skills/_skill-index.yaml +0 -55
- package/_gaia/dev/skills/api-design.md +0 -229
- package/_gaia/dev/skills/code-review-standards.md +0 -226
- package/_gaia/dev/skills/database-design.md +0 -172
- package/_gaia/dev/skills/docker-workflow.md +0 -222
- package/_gaia/dev/skills/documentation-standards.md +0 -256
- package/_gaia/dev/skills/git-workflow.md +0 -157
- package/_gaia/dev/skills/security-basics.md +0 -230
- package/_gaia/dev/skills/testing-patterns.md +0 -232
- package/_gaia/lifecycle/.resolved/.gitkeep +0 -0
- package/_gaia/lifecycle/agents/analyst.md +0 -104
- package/_gaia/lifecycle/agents/architect.md +0 -109
- package/_gaia/lifecycle/agents/data-engineer.md +0 -99
- package/_gaia/lifecycle/agents/devops.md +0 -110
- package/_gaia/lifecycle/agents/performance.md +0 -92
- package/_gaia/lifecycle/agents/pm.md +0 -112
- package/_gaia/lifecycle/agents/qa.md +0 -89
- package/_gaia/lifecycle/agents/security.md +0 -108
- package/_gaia/lifecycle/agents/sm.md +0 -119
- package/_gaia/lifecycle/agents/tech-writer.md +0 -94
- package/_gaia/lifecycle/agents/ux-designer.md +0 -94
- package/_gaia/lifecycle/agents/validator.md +0 -189
- package/_gaia/lifecycle/config.yaml +0 -14
- package/_gaia/lifecycle/module-help.csv +0 -39
- package/_gaia/lifecycle/skills/ground-truth-management.md +0 -252
- package/_gaia/lifecycle/skills/memory-management.md +0 -322
- package/_gaia/lifecycle/skills/validation-patterns.md +0 -230
- package/_gaia/lifecycle/teams/team-data-intensive.yaml +0 -12
- package/_gaia/lifecycle/teams/team-enterprise.yaml +0 -16
- package/_gaia/lifecycle/teams/team-full.yaml +0 -13
- package/_gaia/lifecycle/teams/team-implementation.yaml +0 -8
- package/_gaia/lifecycle/teams/team-planning.yaml +0 -9
- package/_gaia/lifecycle/teams/team-quick-ship.yaml +0 -6
- package/_gaia/lifecycle/teams/team-security-focused.yaml +0 -13
- package/_gaia/lifecycle/templates/api-documentation-template.md +0 -112
- package/_gaia/lifecycle/templates/architecture-template.md +0 -65
- package/_gaia/lifecycle/templates/brownfield-architecture-template.md +0 -198
- package/_gaia/lifecycle/templates/brownfield-assessment-template.md +0 -78
- package/_gaia/lifecycle/templates/brownfield-onboarding-template.md +0 -160
- package/_gaia/lifecycle/templates/dependency-map-template.md +0 -73
- package/_gaia/lifecycle/templates/deployment-template.md +0 -52
- package/_gaia/lifecycle/templates/epic-status-template.md +0 -64
- package/_gaia/lifecycle/templates/event-catalog-template.md +0 -78
- package/_gaia/lifecycle/templates/nfr-assessment-template.md +0 -96
- package/_gaia/lifecycle/templates/prd-template.md +0 -83
- package/_gaia/lifecycle/templates/product-brief-template.md +0 -48
- package/_gaia/lifecycle/templates/review-template.md +0 -47
- package/_gaia/lifecycle/templates/sprint-plan-template.md +0 -45
- package/_gaia/lifecycle/templates/story-template.md +0 -118
- package/_gaia/lifecycle/templates/tech-debt-dashboard-template.md +0 -71
- package/_gaia/lifecycle/templates/test-plan-template.md +0 -56
- package/_gaia/lifecycle/templates/ux-design-assessment-template.md +0 -122
- package/_gaia/lifecycle/workflows/1-analysis/advanced-elicitation/instructions.xml +0 -44
- package/_gaia/lifecycle/workflows/1-analysis/advanced-elicitation/methods.csv +0 -9
- package/_gaia/lifecycle/workflows/1-analysis/advanced-elicitation/workflow.yaml +0 -33
- package/_gaia/lifecycle/workflows/1-analysis/brainstorm-project/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/1-analysis/brainstorm-project/instructions.xml +0 -39
- package/_gaia/lifecycle/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/checklist.md +0 -27
- package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/instructions.xml +0 -57
- package/_gaia/lifecycle/workflows/1-analysis/create-product-brief/workflow.yaml +0 -38
- package/_gaia/lifecycle/workflows/1-analysis/domain-research/checklist.md +0 -22
- package/_gaia/lifecycle/workflows/1-analysis/domain-research/instructions.xml +0 -34
- package/_gaia/lifecycle/workflows/1-analysis/domain-research/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/1-analysis/market-research/checklist.md +0 -28
- package/_gaia/lifecycle/workflows/1-analysis/market-research/instructions.xml +0 -42
- package/_gaia/lifecycle/workflows/1-analysis/market-research/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/1-analysis/technical-research/checklist.md +0 -22
- package/_gaia/lifecycle/workflows/1-analysis/technical-research/instructions.xml +0 -34
- package/_gaia/lifecycle/workflows/1-analysis/technical-research/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/2-planning/create-prd/checklist.md +0 -36
- package/_gaia/lifecycle/workflows/2-planning/create-prd/instructions.xml +0 -80
- package/_gaia/lifecycle/workflows/2-planning/create-prd/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/checklist.md +0 -26
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/instructions.xml +0 -49
- package/_gaia/lifecycle/workflows/2-planning/create-ux-design/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/2-planning/edit-prd/checklist.md +0 -17
- package/_gaia/lifecycle/workflows/2-planning/edit-prd/instructions.xml +0 -50
- package/_gaia/lifecycle/workflows/2-planning/edit-prd/workflow.yaml +0 -22
- package/_gaia/lifecycle/workflows/2-planning/validate-prd/checklist.md +0 -12
- package/_gaia/lifecycle/workflows/2-planning/validate-prd/instructions.xml +0 -52
- package/_gaia/lifecycle/workflows/2-planning/validate-prd/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/checklist.md +0 -32
- package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/instructions.xml +0 -100
- package/_gaia/lifecycle/workflows/3-solutioning/create-architecture/workflow.yaml +0 -41
- package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/checklist.md +0 -30
- package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/instructions.xml +0 -86
- package/_gaia/lifecycle/workflows/3-solutioning/create-epics-stories/workflow.yaml +0 -34
- package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/instructions.xml +0 -91
- package/_gaia/lifecycle/workflows/3-solutioning/edit-architecture/workflow.yaml +0 -32
- package/_gaia/lifecycle/workflows/3-solutioning/implementation-readiness/checklist.md +0 -66
- package/_gaia/lifecycle/workflows/3-solutioning/implementation-readiness/instructions.xml +0 -160
- package/_gaia/lifecycle/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -48
- package/_gaia/lifecycle/workflows/3-solutioning/infrastructure-design/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/3-solutioning/infrastructure-design/instructions.xml +0 -44
- package/_gaia/lifecycle/workflows/3-solutioning/infrastructure-design/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/instructions.xml +0 -55
- package/_gaia/lifecycle/workflows/3-solutioning/security-threat-model/workflow.yaml +0 -23
- package/_gaia/lifecycle/workflows/4-implementation/action-items/instructions.xml +0 -131
- package/_gaia/lifecycle/workflows/4-implementation/action-items/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/checklist.md +0 -27
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/instructions.xml +0 -100
- package/_gaia/lifecycle/workflows/4-implementation/add-stories/workflow.yaml +0 -35
- package/_gaia/lifecycle/workflows/4-implementation/change-request/checklist.md +0 -25
- package/_gaia/lifecycle/workflows/4-implementation/change-request/instructions.xml +0 -123
- package/_gaia/lifecycle/workflows/4-implementation/change-request/workflow.yaml +0 -38
- package/_gaia/lifecycle/workflows/4-implementation/check-dod/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/check-dod/instructions.xml +0 -54
- package/_gaia/lifecycle/workflows/4-implementation/check-dod/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/check-review-gate/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/check-review-gate/instructions.xml +0 -53
- package/_gaia/lifecycle/workflows/4-implementation/check-review-gate/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/code-review/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/code-review/instructions.xml +0 -50
- package/_gaia/lifecycle/workflows/4-implementation/code-review/workflow.yaml +0 -24
- package/_gaia/lifecycle/workflows/4-implementation/correct-course/checklist.md +0 -21
- package/_gaia/lifecycle/workflows/4-implementation/correct-course/instructions.xml +0 -63
- package/_gaia/lifecycle/workflows/4-implementation/correct-course/workflow.yaml +0 -25
- package/_gaia/lifecycle/workflows/4-implementation/create-story/checklist.md +0 -38
- package/_gaia/lifecycle/workflows/4-implementation/create-story/instructions.xml +0 -194
- package/_gaia/lifecycle/workflows/4-implementation/create-story/workflow.yaml +0 -26
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/checklist.md +0 -26
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/instructions.xml +0 -268
- package/_gaia/lifecycle/workflows/4-implementation/dev-story/workflow.yaml +0 -51
- package/_gaia/lifecycle/workflows/4-implementation/epic-status/checklist.md +0 -25
- package/_gaia/lifecycle/workflows/4-implementation/epic-status/instructions.xml +0 -62
- package/_gaia/lifecycle/workflows/4-implementation/epic-status/workflow.yaml +0 -24
- package/_gaia/lifecycle/workflows/4-implementation/fix-story/checklist.md +0 -12
- package/_gaia/lifecycle/workflows/4-implementation/fix-story/instructions.xml +0 -67
- package/_gaia/lifecycle/workflows/4-implementation/fix-story/workflow.yaml +0 -17
- package/_gaia/lifecycle/workflows/4-implementation/qa-generate-tests/checklist.md +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/qa-generate-tests/instructions.xml +0 -52
- package/_gaia/lifecycle/workflows/4-implementation/qa-generate-tests/workflow.yaml +0 -20
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/checklist.md +0 -15
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/instructions.xml +0 -164
- package/_gaia/lifecycle/workflows/4-implementation/retrospective/workflow.yaml +0 -30
- package/_gaia/lifecycle/workflows/4-implementation/run-all-reviews/checklist.md +0 -14
- package/_gaia/lifecycle/workflows/4-implementation/run-all-reviews/instructions.xml +0 -78
- package/_gaia/lifecycle/workflows/4-implementation/run-all-reviews/workflow.yaml +0 -16
- package/_gaia/lifecycle/workflows/4-implementation/security-review/checklist.md +0 -29
- package/_gaia/lifecycle/workflows/4-implementation/security-review/instructions.xml +0 -80
- package/_gaia/lifecycle/workflows/4-implementation/security-review/workflow.yaml +0 -27
- package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/checklist.md +0 -29
- package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/instructions.xml +0 -140
- package/_gaia/lifecycle/workflows/4-implementation/sprint-planning/workflow.yaml +0 -33
- package/_gaia/lifecycle/workflows/4-implementation/sprint-status/checklist.md +0 -18
- package/_gaia/lifecycle/workflows/4-implementation/sprint-status/instructions.xml +0 -36
- package/_gaia/lifecycle/workflows/4-implementation/sprint-status/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/4-implementation/tech-debt-review/checklist.md +0 -30
- package/_gaia/lifecycle/workflows/4-implementation/tech-debt-review/instructions.xml +0 -147
- package/_gaia/lifecycle/workflows/4-implementation/tech-debt-review/workflow.yaml +0 -24
- package/_gaia/lifecycle/workflows/4-implementation/triage-findings/checklist.md +0 -17
- package/_gaia/lifecycle/workflows/4-implementation/triage-findings/instructions.xml +0 -124
- package/_gaia/lifecycle/workflows/4-implementation/triage-findings/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/checklist.md +0 -48
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/instructions.xml +0 -125
- package/_gaia/lifecycle/workflows/4-implementation/val-refresh-ground-truth/workflow.yaml +0 -31
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/checklist.md +0 -54
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/instructions.xml +0 -147
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/test-structure.sh +0 -116
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-artifact/workflow.yaml +0 -29
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/checklist.md +0 -34
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/instructions.xml +0 -162
- package/_gaia/lifecycle/workflows/4-implementation/val-validate-plan/workflow.yaml +0 -39
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/checklist.md +0 -23
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/instructions.xml +0 -146
- package/_gaia/lifecycle/workflows/4-implementation/validate-story/workflow.yaml +0 -25
- package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/checklist.md +0 -29
- package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/instructions.xml +0 -59
- package/_gaia/lifecycle/workflows/5-deployment/deployment-checklist/workflow.yaml +0 -39
- package/_gaia/lifecycle/workflows/5-deployment/post-deploy-verify/checklist.md +0 -19
- package/_gaia/lifecycle/workflows/5-deployment/post-deploy-verify/instructions.xml +0 -33
- package/_gaia/lifecycle/workflows/5-deployment/post-deploy-verify/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/5-deployment/release-plan/checklist.md +0 -20
- package/_gaia/lifecycle/workflows/5-deployment/release-plan/instructions.xml +0 -33
- package/_gaia/lifecycle/workflows/5-deployment/release-plan/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/5-deployment/rollback-plan/checklist.md +0 -20
- package/_gaia/lifecycle/workflows/5-deployment/rollback-plan/instructions.xml +0 -33
- package/_gaia/lifecycle/workflows/5-deployment/rollback-plan/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/checklist.md +0 -52
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/instructions.xml +0 -122
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/test-step7.sh +0 -149
- package/_gaia/lifecycle/workflows/anytime/brownfield-onboarding/workflow.yaml +0 -33
- package/_gaia/lifecycle/workflows/anytime/document-project/checklist.md +0 -11
- package/_gaia/lifecycle/workflows/anytime/document-project/instructions.xml +0 -26
- package/_gaia/lifecycle/workflows/anytime/document-project/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/generate-project-context/checklist.md +0 -11
- package/_gaia/lifecycle/workflows/anytime/generate-project-context/instructions.xml +0 -22
- package/_gaia/lifecycle/workflows/anytime/generate-project-context/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/memory-hygiene/checklist.md +0 -24
- package/_gaia/lifecycle/workflows/anytime/memory-hygiene/instructions.xml +0 -108
- package/_gaia/lifecycle/workflows/anytime/memory-hygiene/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/anytime/performance-review/checklist.md +0 -25
- package/_gaia/lifecycle/workflows/anytime/performance-review/instructions.xml +0 -62
- package/_gaia/lifecycle/workflows/anytime/performance-review/workflow.yaml +0 -15
- package/_gaia/lifecycle/workflows/cross-phase/add-feature/checklist.md +0 -30
- package/_gaia/lifecycle/workflows/cross-phase/add-feature/instructions.xml +0 -85
- package/_gaia/lifecycle/workflows/cross-phase/add-feature/workflow.yaml +0 -37
- package/_gaia/lifecycle/workflows/quick-flow/quick-dev/checklist.md +0 -11
- package/_gaia/lifecycle/workflows/quick-flow/quick-dev/instructions.xml +0 -26
- package/_gaia/lifecycle/workflows/quick-flow/quick-dev/workflow.yaml +0 -19
- package/_gaia/lifecycle/workflows/quick-flow/quick-spec/checklist.md +0 -13
- package/_gaia/lifecycle/workflows/quick-flow/quick-spec/instructions.xml +0 -27
- package/_gaia/lifecycle/workflows/quick-flow/quick-spec/workflow.yaml +0 -15
- package/_gaia/testing/.resolved/.gitkeep +0 -0
- package/_gaia/testing/agents/test-architect.md +0 -131
- package/_gaia/testing/config.yaml +0 -8
- package/_gaia/testing/knowledge/_index.csv +0 -22
- package/_gaia/testing/knowledge/accessibility/axe-core-patterns.md +0 -177
- package/_gaia/testing/knowledge/accessibility/wcag-checks.md +0 -191
- package/_gaia/testing/knowledge/core/deterministic-testing.md +0 -167
- package/_gaia/testing/knowledge/core/fixture-architecture.md +0 -131
- package/_gaia/testing/knowledge/core/test-isolation.md +0 -142
- package/_gaia/testing/knowledge/core/test-pyramid.md +0 -129
- package/_gaia/testing/knowledge/extended/api-testing-patterns.md +0 -196
- package/_gaia/testing/knowledge/extended/data-factories.md +0 -158
- package/_gaia/testing/knowledge/extended/risk-governance.md +0 -119
- package/_gaia/testing/knowledge/extended/selector-resilience.md +0 -109
- package/_gaia/testing/knowledge/mobile-testing/appium-patterns.md +0 -164
- package/_gaia/testing/knowledge/mobile-testing/react-native-testing.md +0 -193
- package/_gaia/testing/knowledge/mobile-testing/responsive-testing.md +0 -177
- package/_gaia/testing/knowledge/performance/k6-patterns.md +0 -200
- package/_gaia/testing/knowledge/performance/lighthouse-ci.md +0 -158
- package/_gaia/testing/knowledge/specialized/contract-testing.md +0 -173
- package/_gaia/testing/knowledge/specialized/test-healing.md +0 -129
- package/_gaia/testing/knowledge/specialized/visual-testing.md +0 -129
- package/_gaia/testing/knowledge/unit-testing/jest-vitest-patterns.md +0 -193
- package/_gaia/testing/knowledge/unit-testing/junit5-patterns.md +0 -200
- package/_gaia/testing/knowledge/unit-testing/pytest-patterns.md +0 -185
- package/_gaia/testing/module-help.csv +0 -13
- package/_gaia/testing/workflows/accessibility-testing/checklist.md +0 -12
- package/_gaia/testing/workflows/accessibility-testing/instructions.xml +0 -41
- package/_gaia/testing/workflows/accessibility-testing/workflow.yaml +0 -13
- package/_gaia/testing/workflows/atdd/checklist.md +0 -6
- package/_gaia/testing/workflows/atdd/instructions.xml +0 -36
- package/_gaia/testing/workflows/atdd/workflow.yaml +0 -22
- package/_gaia/testing/workflows/ci-setup/checklist.md +0 -9
- package/_gaia/testing/workflows/ci-setup/instructions.xml +0 -43
- package/_gaia/testing/workflows/ci-setup/workflow.yaml +0 -11
- package/_gaia/testing/workflows/edit-test-plan/checklist.md +0 -20
- package/_gaia/testing/workflows/edit-test-plan/instructions.xml +0 -65
- package/_gaia/testing/workflows/edit-test-plan/workflow.yaml +0 -35
- package/_gaia/testing/workflows/mobile-testing/checklist.md +0 -13
- package/_gaia/testing/workflows/mobile-testing/instructions.xml +0 -41
- package/_gaia/testing/workflows/mobile-testing/workflow.yaml +0 -11
- package/_gaia/testing/workflows/nfr-assessment/checklist.md +0 -7
- package/_gaia/testing/workflows/nfr-assessment/instructions.xml +0 -26
- package/_gaia/testing/workflows/nfr-assessment/workflow.yaml +0 -11
- package/_gaia/testing/workflows/performance-testing/checklist.md +0 -11
- package/_gaia/testing/workflows/performance-testing/instructions.xml +0 -41
- package/_gaia/testing/workflows/performance-testing/workflow.yaml +0 -11
- package/_gaia/testing/workflows/teach-me-testing/checklist.md +0 -6
- package/_gaia/testing/workflows/teach-me-testing/instructions.xml +0 -28
- package/_gaia/testing/workflows/teach-me-testing/workflow.yaml +0 -12
- package/_gaia/testing/workflows/test-automation/checklist.md +0 -6
- package/_gaia/testing/workflows/test-automation/instructions.xml +0 -49
- package/_gaia/testing/workflows/test-automation/workflow.yaml +0 -11
- package/_gaia/testing/workflows/test-design/checklist.md +0 -9
- package/_gaia/testing/workflows/test-design/instructions.xml +0 -47
- package/_gaia/testing/workflows/test-design/workflow.yaml +0 -11
- package/_gaia/testing/workflows/test-framework/checklist.md +0 -8
- package/_gaia/testing/workflows/test-framework/instructions.xml +0 -25
- package/_gaia/testing/workflows/test-framework/workflow.yaml +0 -11
- package/_gaia/testing/workflows/test-review/checklist.md +0 -9
- package/_gaia/testing/workflows/test-review/instructions.xml +0 -51
- package/_gaia/testing/workflows/test-review/workflow.yaml +0 -11
- package/_gaia/testing/workflows/traceability/checklist.md +0 -6
- package/_gaia/testing/workflows/traceability/instructions.xml +0 -49
- package/_gaia/testing/workflows/traceability/workflow.yaml +0 -21
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: RxJS Observable Patterns
|
|
3
|
-
stack: angular
|
|
4
|
-
version: "1.0"
|
|
5
|
-
focus: [rxjs]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# RxJS Observable Patterns
|
|
9
|
-
|
|
10
|
-
## Principle
|
|
11
|
-
|
|
12
|
-
Use RxJS observables as the primary mechanism for managing asynchronous data flows. Choose operators deliberately based on the concurrency semantics required (switch, merge, concat, exhaust). Always manage subscription lifecycle to prevent memory leaks.
|
|
13
|
-
|
|
14
|
-
## Rationale
|
|
15
|
-
|
|
16
|
-
RxJS provides a composable, declarative approach to async operations. Choosing the right flattening operator prevents subtle bugs: `switchMap` cancels prior requests (ideal for search), `concatMap` queues them (ideal for ordered writes), `mergeMap` runs concurrently, and `exhaustMap` ignores new emissions while one is active (ideal for form submissions). Proper subscription management is critical because Angular components are created and destroyed frequently.
|
|
17
|
-
|
|
18
|
-
## Pattern Examples
|
|
19
|
-
|
|
20
|
-
### Pattern 1: Type-Ahead Search with switchMap
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
@Component({ /* ... */ })
|
|
24
|
-
export class SearchComponent implements OnInit, OnDestroy {
|
|
25
|
-
searchControl = new FormControl('');
|
|
26
|
-
results$!: Observable<SearchResult[]>;
|
|
27
|
-
private destroy$ = new Subject<void>();
|
|
28
|
-
|
|
29
|
-
constructor(private searchService: SearchService) {}
|
|
30
|
-
|
|
31
|
-
ngOnInit(): void {
|
|
32
|
-
this.results$ = this.searchControl.valueChanges.pipe(
|
|
33
|
-
debounceTime(300),
|
|
34
|
-
distinctUntilChanged(),
|
|
35
|
-
filter((term): term is string => term !== null && term.length >= 2),
|
|
36
|
-
switchMap(term => this.searchService.search(term).pipe(
|
|
37
|
-
catchError(() => of([])) // Recover per-request, not globally
|
|
38
|
-
)),
|
|
39
|
-
takeUntil(this.destroy$)
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
ngOnDestroy(): void {
|
|
44
|
-
this.destroy$.next();
|
|
45
|
-
this.destroy$.complete();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Pattern 2: Combining Multiple Streams
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
export class DashboardComponent implements OnInit {
|
|
54
|
-
vm$!: Observable<DashboardViewModel>;
|
|
55
|
-
|
|
56
|
-
ngOnInit(): void {
|
|
57
|
-
this.vm$ = combineLatest([
|
|
58
|
-
this.store.select(selectUser),
|
|
59
|
-
this.store.select(selectNotifications),
|
|
60
|
-
this.store.select(selectMetrics),
|
|
61
|
-
]).pipe(
|
|
62
|
-
map(([user, notifications, metrics]) => ({
|
|
63
|
-
user,
|
|
64
|
-
notifications,
|
|
65
|
-
metrics,
|
|
66
|
-
hasUnread: notifications.some(n => !n.read),
|
|
67
|
-
}))
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Template: single async pipe, one subscription
|
|
73
|
-
// <ng-container *ngIf="vm$ | async as vm">
|
|
74
|
-
// <app-header [user]="vm.user" [unread]="vm.hasUnread" />
|
|
75
|
-
// <app-metrics [data]="vm.metrics" />
|
|
76
|
-
// </ng-container>
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Pattern 3: Retry with Exponential Backoff
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
export function retryWithBackoff<T>(
|
|
83
|
-
maxRetries = 3,
|
|
84
|
-
delayMs = 1000
|
|
85
|
-
): MonoTypeOperatorFunction<T> {
|
|
86
|
-
return (source: Observable<T>) =>
|
|
87
|
-
source.pipe(
|
|
88
|
-
retry({
|
|
89
|
-
count: maxRetries,
|
|
90
|
-
delay: (error, retryCount) => {
|
|
91
|
-
const backoff = delayMs * Math.pow(2, retryCount - 1);
|
|
92
|
-
console.warn(`Retry #${retryCount} in ${backoff}ms`, error.message);
|
|
93
|
-
return timer(backoff);
|
|
94
|
-
},
|
|
95
|
-
})
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Usage
|
|
100
|
-
this.http.get<Data[]>('/api/data').pipe(
|
|
101
|
-
retryWithBackoff(3, 500),
|
|
102
|
-
catchError(() => of([]))
|
|
103
|
-
);
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Anti-Patterns
|
|
107
|
-
|
|
108
|
-
- **Nested subscriptions**: Never subscribe inside a subscribe callback; use flattening operators (`switchMap`, `mergeMap`, etc.) instead.
|
|
109
|
-
- **Forgetting to unsubscribe**: Every manual `.subscribe()` in a component must be cleaned up via `takeUntil`, `DestroyRef`, or the `async` pipe.
|
|
110
|
-
- **Using `mergeMap` for search**: `mergeMap` does not cancel prior emissions; race conditions will show stale results. Use `switchMap`.
|
|
111
|
-
- **Catching errors at the top level**: Placing `catchError` outside the inner observable kills the outer stream on first error.
|
|
112
|
-
- **Subscribing multiple times to the same HTTP call**: HTTP observables are cold; each subscription triggers a new request. Use `shareReplay(1)` when sharing.
|
|
113
|
-
|
|
114
|
-
## Integration Points
|
|
115
|
-
|
|
116
|
-
- **Angular HttpClient**: Returns cold observables; combine with RxJS operators for caching, retry, and transformation.
|
|
117
|
-
- **NgRx Effects**: Effects are observable streams that listen to actions and dispatch new actions; see `ngrx-state.md`.
|
|
118
|
-
- **Angular Forms**: `valueChanges` and `statusChanges` are observables on reactive form controls.
|
|
119
|
-
- **Component lifecycle**: Tie subscriptions to `OnDestroy` via the `destroy$` pattern or Angular 16+ `DestroyRef`.
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Dart Language Conventions
|
|
3
|
-
stack: flutter
|
|
4
|
-
version: "1.0"
|
|
5
|
-
focus: [dart]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Dart Language Conventions
|
|
9
|
-
|
|
10
|
-
## Principle
|
|
11
|
-
|
|
12
|
-
Follow Effective Dart guidelines: embrace null safety, use strong typing with type inference where clear, prefer immutable data, and use `async`/`await` over raw `Future` chains. Write code that reads like well-structured prose, using Dart's expressive syntax features (cascades, collection literals, extension methods).
|
|
13
|
-
|
|
14
|
-
## Rationale
|
|
15
|
-
|
|
16
|
-
Dart's sound null safety eliminates entire categories of runtime errors at compile time. Type inference reduces verbosity without sacrificing safety. Extension methods add functionality to types without modifying them, keeping code modular. Consistent adherence to Effective Dart conventions ensures that code is idiomatic, readable, and maintainable across teams.
|
|
17
|
-
|
|
18
|
-
## Pattern Examples
|
|
19
|
-
|
|
20
|
-
### Pattern 1: Null Safety and Smart Typing
|
|
21
|
-
|
|
22
|
-
```dart
|
|
23
|
-
// Sound null safety — explicit nullable vs non-nullable
|
|
24
|
-
class UserProfile {
|
|
25
|
-
final String name; // required, never null
|
|
26
|
-
final String? bio; // optional, may be null
|
|
27
|
-
final DateTime createdAt;
|
|
28
|
-
|
|
29
|
-
const UserProfile({
|
|
30
|
-
required this.name,
|
|
31
|
-
this.bio,
|
|
32
|
-
required this.createdAt,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Null-aware operators
|
|
36
|
-
String get displayBio => bio ?? 'No bio provided';
|
|
37
|
-
int? get bioLength => bio?.length; // null if bio is null
|
|
38
|
-
|
|
39
|
-
// Pattern matching with null checks (Dart 3)
|
|
40
|
-
String describe() => switch (bio) {
|
|
41
|
-
final b? when b.length > 100 => '${name} has a detailed bio',
|
|
42
|
-
final b? => '${name}: $b',
|
|
43
|
-
null => '${name} (no bio)',
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Pattern 2: Extension Methods and Typedefs
|
|
49
|
-
|
|
50
|
-
```dart
|
|
51
|
-
// Extension on String for domain-specific logic
|
|
52
|
-
extension StringValidation on String {
|
|
53
|
-
bool get isValidEmail =>
|
|
54
|
-
RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(this);
|
|
55
|
-
|
|
56
|
-
String get capitalized =>
|
|
57
|
-
isEmpty ? this : '${this[0].toUpperCase()}${substring(1)}';
|
|
58
|
-
|
|
59
|
-
String truncate(int maxLength, {String suffix = '...'}) =>
|
|
60
|
-
length <= maxLength ? this : '${substring(0, maxLength)}$suffix';
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Extension on DateTime
|
|
64
|
-
extension DateTimeFormat on DateTime {
|
|
65
|
-
String get iso8601Date => toIso8601String().split('T').first;
|
|
66
|
-
bool get isToday {
|
|
67
|
-
final now = DateTime.now();
|
|
68
|
-
return year == now.year && month == now.month && day == now.day;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Typedef for readability
|
|
73
|
-
typedef JsonMap = Map<String, dynamic>;
|
|
74
|
-
typedef FromJson<T> = T Function(JsonMap json);
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
### Pattern 3: Async/Await Patterns
|
|
78
|
-
|
|
79
|
-
```dart
|
|
80
|
-
// Structured async with error handling
|
|
81
|
-
class ApiClient {
|
|
82
|
-
Future<Result<T>> safeRequest<T>(
|
|
83
|
-
Future<T> Function() request,
|
|
84
|
-
) async {
|
|
85
|
-
try {
|
|
86
|
-
final data = await request();
|
|
87
|
-
return Result.success(data);
|
|
88
|
-
} on SocketException {
|
|
89
|
-
return Result.failure('No internet connection');
|
|
90
|
-
} on TimeoutException {
|
|
91
|
-
return Result.failure('Request timed out');
|
|
92
|
-
} on FormatException catch (e) {
|
|
93
|
-
return Result.failure('Invalid response: ${e.message}');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Result type for explicit error handling
|
|
99
|
-
sealed class Result<T> {
|
|
100
|
-
const Result();
|
|
101
|
-
const factory Result.success(T data) = Success;
|
|
102
|
-
const factory Result.failure(String message) = Failure;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
class Success<T> extends Result<T> {
|
|
106
|
-
final T data;
|
|
107
|
-
const Success(this.data);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
class Failure<T> extends Result<T> {
|
|
111
|
-
final String message;
|
|
112
|
-
const Failure(this.message);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Parallel async operations
|
|
116
|
-
Future<DashboardData> loadDashboard() async {
|
|
117
|
-
final results = await Future.wait([
|
|
118
|
-
fetchUserProfile(),
|
|
119
|
-
fetchNotifications(),
|
|
120
|
-
fetchMetrics(),
|
|
121
|
-
]);
|
|
122
|
-
return DashboardData(
|
|
123
|
-
profile: results[0] as UserProfile,
|
|
124
|
-
notifications: results[1] as List<Notification>,
|
|
125
|
-
metrics: results[2] as Metrics,
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
## Anti-Patterns
|
|
131
|
-
|
|
132
|
-
- **Using `dynamic` to avoid typing**: Defeats null safety and type checking. Use generics or union types instead.
|
|
133
|
-
- **Catching `Exception` generically**: Catch specific exception types for proper error handling.
|
|
134
|
-
- **Mutable data classes**: Prefer `final` fields and `const` constructors for value objects. Use `copyWith` for modifications.
|
|
135
|
-
- **Ignoring linter rules**: Configure `analysis_options.yaml` with recommended rules and fix all warnings.
|
|
136
|
-
- **Nested `.then()` chains**: Use `async`/`await` for readability. Reserve `.then()` only for fire-and-forget scenarios.
|
|
137
|
-
|
|
138
|
-
## Integration Points
|
|
139
|
-
|
|
140
|
-
- **Flutter Widgets**: Dart conventions (const, null safety, sealed classes) directly impact widget code; see `widget-patterns.md`.
|
|
141
|
-
- **State Management**: Sealed classes and pattern matching define state hierarchies; see `state-management.md`.
|
|
142
|
-
- **Platform Channels**: Async/await wraps channel calls; see `platform-channels.md`.
|
|
143
|
-
- **Linting**: Use `flutter_lints` or `very_good_analysis` for enforcement.
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Flutter Platform Channels
|
|
3
|
-
stack: flutter
|
|
4
|
-
version: "1.0"
|
|
5
|
-
focus: [flutter]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Flutter Platform Channels
|
|
9
|
-
|
|
10
|
-
## Principle
|
|
11
|
-
|
|
12
|
-
Use platform channels to bridge Dart and native code (iOS/Android) when Flutter APIs do not cover a native capability. Use `MethodChannel` for request/response calls, `EventChannel` for continuous native-to-Dart streams, and `BasicMessageChannel` for simple bidirectional messaging. Always handle platform exceptions and check platform availability before invoking.
|
|
13
|
-
|
|
14
|
-
## Rationale
|
|
15
|
-
|
|
16
|
-
Flutter provides a rich set of plugins, but some features (biometrics, Bluetooth LE, custom camera pipelines, native SDKs) require direct native integration. Platform channels provide a structured, type-safe mechanism for this communication. Proper error handling and platform detection ensure the app degrades gracefully on unsupported platforms.
|
|
17
|
-
|
|
18
|
-
## Pattern Examples
|
|
19
|
-
|
|
20
|
-
### Pattern 1: MethodChannel for Native Calls
|
|
21
|
-
|
|
22
|
-
```dart
|
|
23
|
-
// Dart side — request/response pattern
|
|
24
|
-
class BatteryService {
|
|
25
|
-
static const _channel = MethodChannel('com.example.app/battery');
|
|
26
|
-
|
|
27
|
-
Future<int> getBatteryLevel() async {
|
|
28
|
-
try {
|
|
29
|
-
final int level = await _channel.invokeMethod('getBatteryLevel');
|
|
30
|
-
return level;
|
|
31
|
-
} on PlatformException catch (e) {
|
|
32
|
-
throw BatteryException('Failed to get battery level: ${e.message}');
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Android (Kotlin)
|
|
38
|
-
class MainActivity : FlutterActivity() {
|
|
39
|
-
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
|
40
|
-
super.configureFlutterEngine(flutterEngine)
|
|
41
|
-
MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
|
|
42
|
-
"com.example.app/battery"
|
|
43
|
-
).setMethodCallHandler { call, result ->
|
|
44
|
-
when (call.method) {
|
|
45
|
-
"getBatteryLevel" -> {
|
|
46
|
-
val level = getBatteryLevel()
|
|
47
|
-
if (level != -1) result.success(level)
|
|
48
|
-
else result.error("UNAVAILABLE", "Battery level unavailable", null)
|
|
49
|
-
}
|
|
50
|
-
else -> result.notImplemented()
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// iOS (Swift)
|
|
57
|
-
@UIApplicationMain
|
|
58
|
-
class AppDelegate: FlutterAppDelegate {
|
|
59
|
-
override func application(
|
|
60
|
-
_ application: UIApplication,
|
|
61
|
-
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
62
|
-
) -> Bool {
|
|
63
|
-
let controller = window?.rootViewController as! FlutterViewController
|
|
64
|
-
let channel = FlutterMethodChannel(
|
|
65
|
-
name: "com.example.app/battery",
|
|
66
|
-
binaryMessenger: controller.binaryMessenger
|
|
67
|
-
)
|
|
68
|
-
channel.setMethodCallHandler { call, result in
|
|
69
|
-
guard call.method == "getBatteryLevel" else {
|
|
70
|
-
result(FlutterMethodNotImplemented)
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
result(UIDevice.current.batteryLevel * 100)
|
|
74
|
-
}
|
|
75
|
-
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Pattern 2: EventChannel for Streaming Data
|
|
81
|
-
|
|
82
|
-
```dart
|
|
83
|
-
// Dart — continuous stream from native
|
|
84
|
-
class AccelerometerService {
|
|
85
|
-
static const _eventChannel = EventChannel('com.example.app/accelerometer');
|
|
86
|
-
|
|
87
|
-
Stream<AccelerometerData> get readings {
|
|
88
|
-
return _eventChannel.receiveBroadcastStream().map((event) {
|
|
89
|
-
final map = Map<String, double>.from(event as Map);
|
|
90
|
-
return AccelerometerData(x: map['x']!, y: map['y']!, z: map['z']!);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Consumed in widget
|
|
96
|
-
StreamBuilder<AccelerometerData>(
|
|
97
|
-
stream: accelerometerService.readings,
|
|
98
|
-
builder: (context, snapshot) {
|
|
99
|
-
if (!snapshot.hasData) return const Text('Waiting...');
|
|
100
|
-
final data = snapshot.data!;
|
|
101
|
-
return Text('X: ${data.x.toStringAsFixed(2)}');
|
|
102
|
-
},
|
|
103
|
-
);
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Pattern 3: Platform Detection
|
|
107
|
-
|
|
108
|
-
```dart
|
|
109
|
-
import 'dart:io' show Platform;
|
|
110
|
-
import 'package:flutter/foundation.dart' show kIsWeb;
|
|
111
|
-
|
|
112
|
-
class PlatformService {
|
|
113
|
-
static bool get isIOS => !kIsWeb && Platform.isIOS;
|
|
114
|
-
static bool get isAndroid => !kIsWeb && Platform.isAndroid;
|
|
115
|
-
static bool get isMobile => isIOS || isAndroid;
|
|
116
|
-
static bool get isDesktop =>
|
|
117
|
-
!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux);
|
|
118
|
-
|
|
119
|
-
static Future<T> platformSpecific<T>({
|
|
120
|
-
required Future<T> Function() ios,
|
|
121
|
-
required Future<T> Function() android,
|
|
122
|
-
Future<T> Function()? fallback,
|
|
123
|
-
}) async {
|
|
124
|
-
if (isIOS) return ios();
|
|
125
|
-
if (isAndroid) return android();
|
|
126
|
-
if (fallback != null) return fallback();
|
|
127
|
-
throw UnsupportedError('Platform not supported');
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Anti-Patterns
|
|
133
|
-
|
|
134
|
-
- **String-typed channel names without constants**: Typos in channel names cause silent failures. Define names as `static const`.
|
|
135
|
-
- **No error handling on native side**: Unhandled native exceptions crash the app. Always wrap in try/catch and use `result.error()`.
|
|
136
|
-
- **Heavy computation on the platform thread**: Blocking the main thread on native side causes UI jank. Use background threads for heavy work.
|
|
137
|
-
- **Ignoring platform availability**: Calling iOS-only APIs on Android throws. Always check the platform first.
|
|
138
|
-
|
|
139
|
-
## Integration Points
|
|
140
|
-
|
|
141
|
-
- **State Management**: Native data streams feed into BLoC/Cubit state; see `state-management.md`.
|
|
142
|
-
- **Widget Layer**: Platform-specific widgets use conditional rendering; see `widget-patterns.md`.
|
|
143
|
-
- **Dart Conventions**: Follow async/await patterns for channel calls; see `dart-conventions.md`.
|
|
144
|
-
- **Testing**: Mock the method channel in tests using `TestDefaultBinaryMessengerBinding`.
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Flutter State Management
|
|
3
|
-
stack: flutter
|
|
4
|
-
version: "1.0"
|
|
5
|
-
focus: [flutter]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Flutter State Management
|
|
9
|
-
|
|
10
|
-
## Principle
|
|
11
|
-
|
|
12
|
-
Choose the state management approach that matches the complexity of the state being managed. Use `setState` for local ephemeral state, `Provider`/`Riverpod` for simple shared state, and BLoC/Cubit for complex business logic with well-defined state transitions. Never mix approaches arbitrarily within the same feature.
|
|
13
|
-
|
|
14
|
-
## Rationale
|
|
15
|
-
|
|
16
|
-
Flutter has no single "right" state management solution. The key is matching the tool to the problem. `setState` is perfect for UI-only state (tab index, animation). Provider offers simple dependency injection and reactive rebuilds. Riverpod improves on Provider with compile-time safety and no `BuildContext` dependency. BLoC enforces a strict event-driven architecture ideal for complex flows with testable state transitions.
|
|
17
|
-
|
|
18
|
-
## Pattern Examples
|
|
19
|
-
|
|
20
|
-
### Pattern 1: BLoC/Cubit Pattern
|
|
21
|
-
|
|
22
|
-
```dart
|
|
23
|
-
// State definition — sealed class for exhaustive matching
|
|
24
|
-
sealed class AuthState {}
|
|
25
|
-
class AuthInitial extends AuthState {}
|
|
26
|
-
class AuthLoading extends AuthState {}
|
|
27
|
-
class AuthAuthenticated extends AuthState {
|
|
28
|
-
final User user;
|
|
29
|
-
AuthAuthenticated(this.user);
|
|
30
|
-
}
|
|
31
|
-
class AuthError extends AuthState {
|
|
32
|
-
final String message;
|
|
33
|
-
AuthError(this.message);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Cubit — simpler than full BLoC when events aren't needed
|
|
37
|
-
class AuthCubit extends Cubit<AuthState> {
|
|
38
|
-
AuthCubit(this._authRepo) : super(AuthInitial());
|
|
39
|
-
final AuthRepository _authRepo;
|
|
40
|
-
|
|
41
|
-
Future<void> signIn(String email, String password) async {
|
|
42
|
-
emit(AuthLoading());
|
|
43
|
-
try {
|
|
44
|
-
final user = await _authRepo.signIn(email, password);
|
|
45
|
-
emit(AuthAuthenticated(user));
|
|
46
|
-
} catch (e) {
|
|
47
|
-
emit(AuthError(e.toString()));
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
Future<void> signOut() async {
|
|
52
|
-
await _authRepo.signOut();
|
|
53
|
-
emit(AuthInitial());
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Widget consumption
|
|
58
|
-
BlocBuilder<AuthCubit, AuthState>(
|
|
59
|
-
builder: (context, state) => switch (state) {
|
|
60
|
-
AuthInitial() => const LoginForm(),
|
|
61
|
-
AuthLoading() => const CircularProgressIndicator(),
|
|
62
|
-
AuthAuthenticated(:final user) => HomeScreen(user: user),
|
|
63
|
-
AuthError(:final message) => ErrorView(message: message),
|
|
64
|
-
},
|
|
65
|
-
);
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Pattern 2: Riverpod with AsyncNotifier
|
|
69
|
-
|
|
70
|
-
```dart
|
|
71
|
-
// Provider definition — no BuildContext needed
|
|
72
|
-
@riverpod
|
|
73
|
-
class TodoList extends _$TodoList {
|
|
74
|
-
@override
|
|
75
|
-
Future<List<Todo>> build() async {
|
|
76
|
-
return ref.read(todoRepositoryProvider).fetchAll();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
Future<void> addTodo(String title) async {
|
|
80
|
-
state = const AsyncLoading();
|
|
81
|
-
state = await AsyncValue.guard(() async {
|
|
82
|
-
await ref.read(todoRepositoryProvider).add(title);
|
|
83
|
-
return ref.read(todoRepositoryProvider).fetchAll();
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Widget consumption
|
|
89
|
-
class TodoScreen extends ConsumerWidget {
|
|
90
|
-
const TodoScreen({super.key});
|
|
91
|
-
|
|
92
|
-
@override
|
|
93
|
-
Widget build(BuildContext context, WidgetRef ref) {
|
|
94
|
-
final todosAsync = ref.watch(todoListProvider);
|
|
95
|
-
return todosAsync.when(
|
|
96
|
-
data: (todos) => TodoListView(todos: todos),
|
|
97
|
-
loading: () => const CircularProgressIndicator(),
|
|
98
|
-
error: (err, stack) => ErrorView(message: err.toString()),
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Pattern 3: Provider for Simple DI
|
|
105
|
-
|
|
106
|
-
```dart
|
|
107
|
-
// Simple shared state with ChangeNotifier
|
|
108
|
-
class CartModel extends ChangeNotifier {
|
|
109
|
-
final List<Product> _items = [];
|
|
110
|
-
List<Product> get items => List.unmodifiable(_items);
|
|
111
|
-
double get total => _items.fold(0, (sum, p) => sum + p.price);
|
|
112
|
-
|
|
113
|
-
void add(Product product) {
|
|
114
|
-
_items.add(product);
|
|
115
|
-
notifyListeners();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
void remove(String productId) {
|
|
119
|
-
_items.removeWhere((p) => p.id == productId);
|
|
120
|
-
notifyListeners();
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Provided at app root
|
|
125
|
-
ChangeNotifierProvider(create: (_) => CartModel(), child: const MyApp());
|
|
126
|
-
|
|
127
|
-
// Consumed
|
|
128
|
-
final cart = context.watch<CartModel>();
|
|
129
|
-
Text('Total: \$${cart.total.toStringAsFixed(2)}');
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Anti-Patterns
|
|
133
|
-
|
|
134
|
-
- **Global state for everything**: Using BLoC for toggle buttons or tab indices. Use `setState` for ephemeral UI state.
|
|
135
|
-
- **Mixing approaches randomly**: Using Provider in one feature, BLoC in another, and Riverpod in a third within the same app.
|
|
136
|
-
- **Fat BLoCs**: Putting UI formatting logic in BLoC. BLoC handles business logic; the widget formats display.
|
|
137
|
-
- **Not sealing state classes**: Using abstract base class without sealed means the compiler cannot check exhaustiveness in switch statements.
|
|
138
|
-
|
|
139
|
-
## Integration Points
|
|
140
|
-
|
|
141
|
-
- **Widgets**: State is consumed in the widget layer via `BlocBuilder`, `Consumer`, or `context.watch`; see `widget-patterns.md`.
|
|
142
|
-
- **Platform Channels**: Async platform calls feed into state management layer; see `platform-channels.md`.
|
|
143
|
-
- **Testing**: Cubits and Notifiers are plain Dart classes, easily testable without Flutter test harness.
|
|
144
|
-
- **Navigation**: State transitions (authenticated/unauthenticated) drive route guards.
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Flutter Widget Patterns
|
|
3
|
-
stack: flutter
|
|
4
|
-
version: "1.0"
|
|
5
|
-
focus: [flutter]
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Flutter Widget Patterns
|
|
9
|
-
|
|
10
|
-
## Principle
|
|
11
|
-
|
|
12
|
-
Build UIs through small, composable widgets. Use `const` constructors wherever possible to enable framework-level render optimization. Understand the widget-element-renderobject tree to make informed decisions about when to split widgets, use keys, and optimize rebuilds.
|
|
13
|
-
|
|
14
|
-
## Rationale
|
|
15
|
-
|
|
16
|
-
Flutter rebuilds widgets frequently. The framework diffs the widget tree and only updates elements whose configuration changed. `const` widgets are canonicalized at compile time, so the framework skips diffing them entirely. Splitting large build methods into smaller widgets gives Flutter finer granularity for selective rebuilds, and `Key` objects ensure correct element reuse when lists reorder.
|
|
17
|
-
|
|
18
|
-
## Pattern Examples
|
|
19
|
-
|
|
20
|
-
### Pattern 1: Const Constructors and Widget Extraction
|
|
21
|
-
|
|
22
|
-
```dart
|
|
23
|
-
// Good: const constructor enables compile-time canonicalization
|
|
24
|
-
class StatusBadge extends StatelessWidget {
|
|
25
|
-
const StatusBadge({super.key, required this.label, required this.color});
|
|
26
|
-
|
|
27
|
-
final String label;
|
|
28
|
-
final Color color;
|
|
29
|
-
|
|
30
|
-
@override
|
|
31
|
-
Widget build(BuildContext context) {
|
|
32
|
-
return Container(
|
|
33
|
-
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
34
|
-
decoration: BoxDecoration(
|
|
35
|
-
color: color.withOpacity(0.15),
|
|
36
|
-
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
|
37
|
-
),
|
|
38
|
-
child: Text(
|
|
39
|
-
label,
|
|
40
|
-
style: TextStyle(color: color, fontWeight: FontWeight.w600),
|
|
41
|
-
),
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Usage with const — Flutter skips rebuild entirely
|
|
47
|
-
const StatusBadge(label: 'Active', color: Colors.green);
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Pattern 2: Keys for List Reordering
|
|
51
|
-
|
|
52
|
-
```dart
|
|
53
|
-
class TodoList extends StatelessWidget {
|
|
54
|
-
const TodoList({super.key, required this.items});
|
|
55
|
-
final List<TodoItem> items;
|
|
56
|
-
|
|
57
|
-
@override
|
|
58
|
-
Widget build(BuildContext context) {
|
|
59
|
-
return ListView.builder(
|
|
60
|
-
itemCount: items.length,
|
|
61
|
-
itemBuilder: (context, index) {
|
|
62
|
-
final item = items[index];
|
|
63
|
-
// ValueKey ensures correct element reuse when items reorder
|
|
64
|
-
return Dismissible(
|
|
65
|
-
key: ValueKey(item.id),
|
|
66
|
-
onDismissed: (_) => context.read<TodoCubit>().remove(item.id),
|
|
67
|
-
child: TodoTile(item: item),
|
|
68
|
-
);
|
|
69
|
-
},
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Pattern 3: Custom Widget with Composition
|
|
76
|
-
|
|
77
|
-
```dart
|
|
78
|
-
class UserCard extends StatelessWidget {
|
|
79
|
-
const UserCard({
|
|
80
|
-
super.key,
|
|
81
|
-
required this.user,
|
|
82
|
-
this.onTap,
|
|
83
|
-
this.trailing,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
final User user;
|
|
87
|
-
final VoidCallback? onTap;
|
|
88
|
-
final Widget? trailing;
|
|
89
|
-
|
|
90
|
-
@override
|
|
91
|
-
Widget build(BuildContext context) {
|
|
92
|
-
final theme = Theme.of(context);
|
|
93
|
-
return Card(
|
|
94
|
-
child: InkWell(
|
|
95
|
-
onTap: onTap,
|
|
96
|
-
borderRadius: BorderRadius.circular(12),
|
|
97
|
-
child: Padding(
|
|
98
|
-
padding: const EdgeInsets.all(16),
|
|
99
|
-
child: Row(
|
|
100
|
-
children: [
|
|
101
|
-
CircleAvatar(backgroundImage: NetworkImage(user.avatarUrl)),
|
|
102
|
-
const SizedBox(width: 12),
|
|
103
|
-
Expanded(
|
|
104
|
-
child: Column(
|
|
105
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
106
|
-
children: [
|
|
107
|
-
Text(user.name, style: theme.textTheme.titleMedium),
|
|
108
|
-
Text(user.email, style: theme.textTheme.bodySmall),
|
|
109
|
-
],
|
|
110
|
-
),
|
|
111
|
-
),
|
|
112
|
-
if (trailing != null) trailing!,
|
|
113
|
-
],
|
|
114
|
-
),
|
|
115
|
-
),
|
|
116
|
-
),
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Anti-Patterns
|
|
123
|
-
|
|
124
|
-
- **Mega build methods**: A single `build()` with 200+ lines. Extract sub-widgets so Flutter can selectively rebuild.
|
|
125
|
-
- **Missing const**: Omitting `const` on constructors and widget instantiations wastes the canonicalization optimization.
|
|
126
|
-
- **Using `GlobalKey` for everything**: `GlobalKey` is expensive; prefer `ValueKey` or `ObjectKey` for list items.
|
|
127
|
-
- **Rebuilding the entire tree on state change**: Not splitting stateful and stateless parts. Place `StatefulWidget` at the narrowest scope possible.
|
|
128
|
-
|
|
129
|
-
## Integration Points
|
|
130
|
-
|
|
131
|
-
- **State Management**: Widgets consume state from BLoC/Cubit/Provider; see `state-management.md`.
|
|
132
|
-
- **Platform Channels**: Custom widgets may wrap platform-specific views; see `platform-channels.md`.
|
|
133
|
-
- **Dart Conventions**: Follow `const` and null-safety patterns from `dart-conventions.md`.
|
|
134
|
-
- **Theme**: Access `Theme.of(context)` for consistent styling; define tokens in `ThemeData`.
|