oh-my-customcodex 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +327 -0
- package/dist/cli/index.js +32054 -0
- package/dist/index.js +5469 -0
- package/package.json +89 -0
- package/templates/.claude/agents/arch-documenter.md +38 -0
- package/templates/.claude/agents/arch-speckit-agent.md +66 -0
- package/templates/.claude/agents/be-django-expert.md +47 -0
- package/templates/.claude/agents/be-express-expert.md +31 -0
- package/templates/.claude/agents/be-fastapi-expert.md +45 -0
- package/templates/.claude/agents/be-go-backend-expert.md +45 -0
- package/templates/.claude/agents/be-nestjs-expert.md +29 -0
- package/templates/.claude/agents/be-springboot-expert.md +42 -0
- package/templates/.claude/agents/db-alembic-expert.md +73 -0
- package/templates/.claude/agents/db-postgres-expert.md +38 -0
- package/templates/.claude/agents/db-redis-expert.md +38 -0
- package/templates/.claude/agents/db-supabase-expert.md +37 -0
- package/templates/.claude/agents/de-airflow-expert.md +48 -0
- package/templates/.claude/agents/de-dbt-expert.md +36 -0
- package/templates/.claude/agents/de-kafka-expert.md +83 -0
- package/templates/.claude/agents/de-pipeline-expert.md +34 -0
- package/templates/.claude/agents/de-snowflake-expert.md +38 -0
- package/templates/.claude/agents/de-spark-expert.md +38 -0
- package/templates/.claude/agents/fe-design-expert.md +120 -0
- package/templates/.claude/agents/fe-flutter-agent.md +48 -0
- package/templates/.claude/agents/fe-svelte-agent.md +33 -0
- package/templates/.claude/agents/fe-vercel-agent.md +40 -0
- package/templates/.claude/agents/fe-vuejs-agent.md +34 -0
- package/templates/.claude/agents/infra-aws-expert.md +49 -0
- package/templates/.claude/agents/infra-docker-expert.md +49 -0
- package/templates/.claude/agents/lang-golang-expert.md +46 -0
- package/templates/.claude/agents/lang-java21-expert.md +42 -0
- package/templates/.claude/agents/lang-kotlin-expert.md +45 -0
- package/templates/.claude/agents/lang-python-expert.md +45 -0
- package/templates/.claude/agents/lang-rust-expert.md +45 -0
- package/templates/.claude/agents/lang-typescript-expert.md +45 -0
- package/templates/.claude/agents/mgr-claude-code-bible.md +62 -0
- package/templates/.claude/agents/mgr-creator.md +57 -0
- package/templates/.claude/agents/mgr-gitnerd.md +50 -0
- package/templates/.claude/agents/mgr-sauron.md +163 -0
- package/templates/.claude/agents/mgr-supplier.md +39 -0
- package/templates/.claude/agents/mgr-updater.md +40 -0
- package/templates/.claude/agents/qa-engineer.md +36 -0
- package/templates/.claude/agents/qa-planner.md +78 -0
- package/templates/.claude/agents/qa-writer.md +32 -0
- package/templates/.claude/agents/sec-codeql-expert.md +56 -0
- package/templates/.claude/agents/slack-cli-expert.md +98 -0
- package/templates/.claude/agents/souls/lang-golang-expert.soul.md +21 -0
- package/templates/.claude/agents/sys-memory-keeper.md +123 -0
- package/templates/.claude/agents/sys-naggy.md +76 -0
- package/templates/.claude/agents/tool-bun-expert.md +26 -0
- package/templates/.claude/agents/tool-npm-expert.md +31 -0
- package/templates/.claude/agents/tool-optimizer.md +37 -0
- package/templates/.claude/agents/wiki-curator.md +72 -0
- package/templates/.claude/config/required-plugins.json +30 -0
- package/templates/.claude/contexts/dev.md +20 -0
- package/templates/.claude/contexts/ecomode.md +110 -0
- package/templates/.claude/contexts/index.yaml +41 -0
- package/templates/.claude/contexts/research.md +28 -0
- package/templates/.claude/contexts/review.md +23 -0
- package/templates/.claude/hooks/hooks.json +533 -0
- package/templates/.claude/hooks/scripts/adaptive-harness-scan.sh +45 -0
- package/templates/.claude/hooks/scripts/agent-start-recorder.sh +40 -0
- package/templates/.claude/hooks/scripts/agent-teams-advisor.sh +76 -0
- package/templates/.claude/hooks/scripts/audit-log.sh +64 -0
- package/templates/.claude/hooks/scripts/auto-continue-guard.sh +33 -0
- package/templates/.claude/hooks/scripts/content-hash-validator.sh +75 -0
- package/templates/.claude/hooks/scripts/context-budget-advisor.sh +107 -0
- package/templates/.claude/hooks/scripts/cost-cap-advisor.sh +71 -0
- package/templates/.claude/hooks/scripts/cwd-change-detector.sh +36 -0
- package/templates/.claude/hooks/scripts/eval-core-batch-save.sh +46 -0
- package/templates/.claude/hooks/scripts/feedback-collector.sh +92 -0
- package/templates/.claude/hooks/scripts/file-change-validator.sh +26 -0
- package/templates/.claude/hooks/scripts/git-delegation-guard.sh +57 -0
- package/templates/.claude/hooks/scripts/model-escalation-advisor.sh +106 -0
- package/templates/.claude/hooks/scripts/omcodex-auto-update.sh +4 -0
- package/templates/.claude/hooks/scripts/omcustom-auto-update.sh +177 -0
- package/templates/.claude/hooks/scripts/rtk-intercept.sh +77 -0
- package/templates/.claude/hooks/scripts/rule-deletion-guard.sh +60 -0
- package/templates/.claude/hooks/scripts/schema-validator.sh +106 -0
- package/templates/.claude/hooks/scripts/secret-filter.sh +100 -0
- package/templates/.claude/hooks/scripts/session-autofix-prompt.sh +34 -0
- package/templates/.claude/hooks/scripts/session-autofix.sh +146 -0
- package/templates/.claude/hooks/scripts/session-env-check.sh +254 -0
- package/templates/.claude/hooks/scripts/skill-extractor-analyzer.sh +49 -0
- package/templates/.claude/hooks/scripts/stage-blocker.sh +16 -0
- package/templates/.claude/hooks/scripts/stale-todo-scanner.sh +91 -0
- package/templates/.claude/hooks/scripts/stall-detection-advisor.sh +112 -0
- package/templates/.claude/hooks/scripts/stop-console-audit.sh +46 -0
- package/templates/.claude/hooks/scripts/stuck-detector.sh +199 -0
- package/templates/.claude/hooks/scripts/task-outcome-recorder.sh +119 -0
- package/templates/.claude/hooks/scripts/task-state-precompact.sh +58 -0
- package/templates/.claude/hooks/scripts/user-prompt-preprocessor.sh +32 -0
- package/templates/.claude/hooks/skill-count-reminder.sh +34 -0
- package/templates/.claude/install-hooks.sh +100 -0
- package/templates/.claude/ontology/agents.yaml +546 -0
- package/templates/.claude/ontology/graphs/agent-skill.json +102 -0
- package/templates/.claude/ontology/graphs/full-graph.json +629 -0
- package/templates/.claude/ontology/graphs/routing.json +112 -0
- package/templates/.claude/ontology/graphs/skill-rule.json +78 -0
- package/templates/.claude/ontology/rules.yaml +251 -0
- package/templates/.claude/ontology/schema.yaml +144 -0
- package/templates/.claude/ontology/skills.yaml +575 -0
- package/templates/.claude/rules/MAY-optimization.md +42 -0
- package/templates/.claude/rules/MUST-agent-design.md +340 -0
- package/templates/.claude/rules/MUST-agent-identification.md +77 -0
- package/templates/.claude/rules/MUST-agent-teams.md +293 -0
- package/templates/.claude/rules/MUST-completion-verification.md +112 -0
- package/templates/.claude/rules/MUST-continuous-improvement.md +69 -0
- package/templates/.claude/rules/MUST-enforcement-policy.md +50 -0
- package/templates/.claude/rules/MUST-intent-transparency.md +74 -0
- package/templates/.claude/rules/MUST-language-policy.md +28 -0
- package/templates/.claude/rules/MUST-orchestrator-coordination.md +399 -0
- package/templates/.claude/rules/MUST-parallel-execution.md +184 -0
- package/templates/.claude/rules/MUST-permissions.md +32 -0
- package/templates/.claude/rules/MUST-safety.md +23 -0
- package/templates/.claude/rules/MUST-sync-verification.md +145 -0
- package/templates/.claude/rules/MUST-tool-identification.md +97 -0
- package/templates/.claude/rules/SHOULD-ecomode.md +123 -0
- package/templates/.claude/rules/SHOULD-error-handling.md +33 -0
- package/templates/.claude/rules/SHOULD-hud-statusline.md +51 -0
- package/templates/.claude/rules/SHOULD-interaction.md +77 -0
- package/templates/.claude/rules/SHOULD-memory-integration.md +371 -0
- package/templates/.claude/rules/SHOULD-ontology-rag-routing.md +49 -0
- package/templates/.claude/rules/SHOULD-wiki-sync.md +73 -0
- package/templates/.claude/rules/index.yaml +141 -0
- package/templates/.claude/schemas/tool-inputs.json +62 -0
- package/templates/.claude/skills/action-validator/SKILL.md +89 -0
- package/templates/.claude/skills/adaptive-harness/SKILL.md +335 -0
- package/templates/.claude/skills/adversarial-review/SKILL.md +80 -0
- package/templates/.claude/skills/agora/SKILL.md +194 -0
- package/templates/.claude/skills/airflow-best-practices/SKILL.md +94 -0
- package/templates/.claude/skills/alembic-best-practices/SKILL.md +295 -0
- package/templates/.claude/skills/ambiguity-gate/SKILL.md +94 -0
- package/templates/.claude/skills/analysis/SKILL.md +223 -0
- package/templates/.claude/skills/audit-agents/SKILL.md +118 -0
- package/templates/.claude/skills/aws-best-practices/SKILL.md +281 -0
- package/templates/.claude/skills/claude-code-bible/SKILL.md +93 -0
- package/templates/.claude/skills/claude-code-bible/scripts/fetch-docs.js +244 -0
- package/templates/.claude/skills/claude-native/SKILL.md +215 -0
- package/templates/.claude/skills/codex-exec/SKILL.md +206 -0
- package/templates/.claude/skills/codex-exec/scripts/codex-wrapper.cjs +430 -0
- package/templates/.claude/skills/create-agent/SKILL.md +94 -0
- package/templates/.claude/skills/cve-triage/SKILL.md +91 -0
- package/templates/.claude/skills/dag-orchestration/SKILL.md +201 -0
- package/templates/.claude/skills/dbt-best-practices/SKILL.md +55 -0
- package/templates/.claude/skills/de-lead-routing/SKILL.md +230 -0
- package/templates/.claude/skills/deep-plan/SKILL.md +344 -0
- package/templates/.claude/skills/deep-verify/SKILL.md +111 -0
- package/templates/.claude/skills/dev-lead-routing/SKILL.md +161 -0
- package/templates/.claude/skills/dev-refactor/SKILL.md +234 -0
- package/templates/.claude/skills/dev-review/SKILL.md +172 -0
- package/templates/.claude/skills/django-best-practices/SKILL.md +334 -0
- package/templates/.claude/skills/docker-best-practices/SKILL.md +276 -0
- package/templates/.claude/skills/evaluator-optimizer/SKILL.md +421 -0
- package/templates/.claude/skills/fastapi-best-practices/SKILL.md +271 -0
- package/templates/.claude/skills/fix-refs/SKILL.md +109 -0
- package/templates/.claude/skills/flutter-best-practices/SKILL.md +325 -0
- package/templates/.claude/skills/gemini-exec/SKILL.md +215 -0
- package/templates/.claude/skills/gemini-exec/scripts/gemini-wrapper.cjs +485 -0
- package/templates/.claude/skills/go-backend-best-practices/SKILL.md +135 -0
- package/templates/.claude/skills/go-best-practices/SKILL.md +204 -0
- package/templates/.claude/skills/hada-scout/SKILL.md +92 -0
- package/templates/.claude/skills/harness-eval/SKILL.md +95 -0
- package/templates/.claude/skills/harness-synthesizer/SKILL.md +145 -0
- package/templates/.claude/skills/help/SKILL.md +127 -0
- package/templates/.claude/skills/idea/SKILL.md +88 -0
- package/templates/.claude/skills/impeccable-design/SKILL.md +173 -0
- package/templates/.claude/skills/intent-detection/SKILL.md +293 -0
- package/templates/.claude/skills/intent-detection/patterns/agent-triggers.yaml +438 -0
- package/templates/.claude/skills/java21-best-practices/SKILL.md +190 -0
- package/templates/.claude/skills/jinja2-prompts/SKILL.md +86 -0
- package/templates/.claude/skills/kafka-best-practices/SKILL.md +53 -0
- package/templates/.claude/skills/kotlin-best-practices/SKILL.md +257 -0
- package/templates/.claude/skills/lists/SKILL.md +80 -0
- package/templates/.claude/skills/memory-management/SKILL.md +196 -0
- package/templates/.claude/skills/memory-recall/SKILL.md +172 -0
- package/templates/.claude/skills/memory-save/SKILL.md +128 -0
- package/templates/.claude/skills/model-escalation/SKILL.md +62 -0
- package/templates/.claude/skills/monitoring-setup/SKILL.md +215 -0
- package/templates/.claude/skills/multi-model-verification/SKILL.md +130 -0
- package/templates/.claude/skills/npm-audit/SKILL.md +74 -0
- package/templates/.claude/skills/npm-publish/SKILL.md +65 -0
- package/templates/.claude/skills/npm-version/SKILL.md +104 -0
- package/templates/.claude/skills/omcodex-auto-improve/SKILL.md +136 -0
- package/templates/.claude/skills/omcodex-feedback/SKILL.md +205 -0
- package/templates/.claude/skills/omcodex-improve-report/SKILL.md +65 -0
- package/templates/.claude/skills/omcodex-loop/SKILL.md +45 -0
- package/templates/.claude/skills/omcodex-release-notes/SKILL.md +117 -0
- package/templates/.claude/skills/omcodex-takeover/SKILL.md +115 -0
- package/templates/.claude/skills/omcodex-web/SKILL.md +95 -0
- package/templates/.claude/skills/optimize-analyze/SKILL.md +57 -0
- package/templates/.claude/skills/optimize-bundle/SKILL.md +69 -0
- package/templates/.claude/skills/optimize-report/SKILL.md +76 -0
- package/templates/.claude/skills/peer-messaging/SKILL.md +59 -0
- package/templates/.claude/skills/pipeline/SKILL.md +103 -0
- package/templates/.claude/skills/pipeline-architecture-patterns/SKILL.md +84 -0
- package/templates/.claude/skills/pipeline-guards/SKILL.md +173 -0
- package/templates/.claude/skills/post-release-followup/SKILL.md +134 -0
- package/templates/.claude/skills/postgres-best-practices/SKILL.md +67 -0
- package/templates/.claude/skills/pr-auto-improve/SKILL.md +129 -0
- package/templates/.claude/skills/professor-triage/SKILL.md +321 -0
- package/templates/.claude/skills/python-best-practices/SKILL.md +223 -0
- package/templates/.claude/skills/qa-lead-routing/SKILL.md +104 -0
- package/templates/.claude/skills/react-best-practices/SKILL.md +102 -0
- package/templates/.claude/skills/reasoning-sandwich/SKILL.md +64 -0
- package/templates/.claude/skills/redis-best-practices/SKILL.md +84 -0
- package/templates/.claude/skills/release-plan/SKILL.md +207 -0
- package/templates/.claude/skills/research/SKILL.md +493 -0
- package/templates/.claude/skills/result-aggregation/SKILL.md +165 -0
- package/templates/.claude/skills/rtk-exec/SKILL.md +199 -0
- package/templates/.claude/skills/rtk-exec/scripts/rtk-wrapper.cjs +377 -0
- package/templates/.claude/skills/rust-best-practices/SKILL.md +268 -0
- package/templates/.claude/skills/sauron-watch/SKILL.md +239 -0
- package/templates/.claude/skills/scout/SKILL.md +250 -0
- package/templates/.claude/skills/sdd/SKILL.md +24 -0
- package/templates/.claude/skills/sdd-dev/SKILL.md +257 -0
- package/templates/.claude/skills/sdd-development/SKILL.md +24 -0
- package/templates/.claude/skills/secretary-routing/SKILL.md +132 -0
- package/templates/.claude/skills/skill-extractor/SKILL.md +155 -0
- package/templates/.claude/skills/skills-sh-search/SKILL.md +210 -0
- package/templates/.claude/skills/snowflake-best-practices/SKILL.md +66 -0
- package/templates/.claude/skills/spark-best-practices/SKILL.md +53 -0
- package/templates/.claude/skills/springboot-best-practices/SKILL.md +74 -0
- package/templates/.claude/skills/springboot-best-practices/examples/config-properties-example.java +22 -0
- package/templates/.claude/skills/springboot-best-practices/examples/controller-example.java +28 -0
- package/templates/.claude/skills/springboot-best-practices/examples/controller-test-example.java +33 -0
- package/templates/.claude/skills/springboot-best-practices/examples/entity-example.java +22 -0
- package/templates/.claude/skills/springboot-best-practices/examples/exception-handler-example.java +30 -0
- package/templates/.claude/skills/springboot-best-practices/examples/repository-example.java +17 -0
- package/templates/.claude/skills/springboot-best-practices/examples/repository-test-example.java +23 -0
- package/templates/.claude/skills/springboot-best-practices/examples/security-config-example.java +27 -0
- package/templates/.claude/skills/springboot-best-practices/examples/service-example.java +33 -0
- package/templates/.claude/skills/status/SKILL.md +155 -0
- package/templates/.claude/skills/structured-dev-cycle/SKILL.md +200 -0
- package/templates/.claude/skills/stuck-recovery/SKILL.md +80 -0
- package/templates/.claude/skills/supabase-postgres-best-practices/SKILL.md +100 -0
- package/templates/.claude/skills/systematic-debugging/SKILL.md +288 -0
- package/templates/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +278 -0
- package/templates/.claude/skills/systematic-debugging/condition-based-waiting.md +240 -0
- package/templates/.claude/skills/systematic-debugging/defense-in-depth.md +252 -0
- package/templates/.claude/skills/systematic-debugging/find-polluter.sh +147 -0
- package/templates/.claude/skills/systematic-debugging/root-cause-tracing.md +87 -0
- package/templates/.claude/skills/task-decomposition/SKILL.md +197 -0
- package/templates/.claude/skills/typescript-best-practices/SKILL.md +322 -0
- package/templates/.claude/skills/update-docs/SKILL.md +142 -0
- package/templates/.claude/skills/update-external/SKILL.md +169 -0
- package/templates/.claude/skills/vercel-deploy/SKILL.md +75 -0
- package/templates/.claude/skills/web-design-guidelines/SKILL.md +119 -0
- package/templates/.claude/skills/wiki/SKILL.md +426 -0
- package/templates/.claude/skills/wiki-rag/SKILL.md +154 -0
- package/templates/.claude/skills/worker-reviewer-pipeline/SKILL.md +165 -0
- package/templates/.claude/skills/writing-clearly-and-concisely/SKILL.md +66 -0
- package/templates/.claude/statusline.sh +380 -0
- package/templates/.claude/uninstall-hooks.sh +52 -0
- package/templates/.github/workflows/wiki-sync.yml +132 -0
- package/templates/AGENTS.md.en +255 -0
- package/templates/AGENTS.md.ko +255 -0
- package/templates/CLAUDE.md +263 -0
- package/templates/CLAUDE.md.en +256 -0
- package/templates/CLAUDE.md.ko +256 -0
- package/templates/deprecated-files.json +10 -0
- package/templates/guides/agents-md-quality/README.md +110 -0
- package/templates/guides/airflow/README.md +47 -0
- package/templates/guides/alembic/README.md +438 -0
- package/templates/guides/aws/common-patterns.md +169 -0
- package/templates/guides/aws/index.yaml +26 -0
- package/templates/guides/aws/well-architected.md +143 -0
- package/templates/guides/cc-token-saver/README.md +97 -0
- package/templates/guides/claude-code/01-overview.md +42 -0
- package/templates/guides/claude-code/03-tools.md +107 -0
- package/templates/guides/claude-code/04-agent-skills.md +90 -0
- package/templates/guides/claude-code/05-agent-sdk.md +129 -0
- package/templates/guides/claude-code/06-mcp.md +165 -0
- package/templates/guides/claude-code/07-prompt-engineering.md +100 -0
- package/templates/guides/claude-code/08-testing.md +56 -0
- package/templates/guides/claude-code/09-guardrails.md +78 -0
- package/templates/guides/claude-code/10-monitoring.md +87 -0
- package/templates/guides/claude-code/11-sub-agents.md +159 -0
- package/templates/guides/claude-code/12-workflow-patterns.md +182 -0
- package/templates/guides/claude-code/13-cli-flags.md +151 -0
- package/templates/guides/claude-code/index.yaml +61 -0
- package/templates/guides/dbt/README.md +32 -0
- package/templates/guides/django-best-practices/README.md +476 -0
- package/templates/guides/docker/compose-best-practices.md +284 -0
- package/templates/guides/docker/dockerfile-best-practices.md +262 -0
- package/templates/guides/docker/index.yaml +26 -0
- package/templates/guides/drizzle-orm/README.md +69 -0
- package/templates/guides/elements-of-style/elements-of-style.html +2609 -0
- package/templates/guides/fastapi/best-practices.md +232 -0
- package/templates/guides/fastapi/index.yaml +21 -0
- package/templates/guides/flutter/architecture.md +141 -0
- package/templates/guides/flutter/fundamentals.md +119 -0
- package/templates/guides/flutter/index.yaml +44 -0
- package/templates/guides/flutter/performance.md +119 -0
- package/templates/guides/flutter/security.md +120 -0
- package/templates/guides/flutter/state-management.md +144 -0
- package/templates/guides/flutter/testing.md +155 -0
- package/templates/guides/git-worktree-workflow/README.md +138 -0
- package/templates/guides/go-backend/index.yaml +26 -0
- package/templates/guides/go-backend/project-layout.md +243 -0
- package/templates/guides/go-backend/uber-style.md +212 -0
- package/templates/guides/golang/concurrency.md +282 -0
- package/templates/guides/golang/effective-go.md +309 -0
- package/templates/guides/golang/error-handling.md +250 -0
- package/templates/guides/golang/index.yaml +27 -0
- package/templates/guides/hook-data-flow/README.md +135 -0
- package/templates/guides/iceberg/README.md +49 -0
- package/templates/guides/impeccable-design/color-and-contrast.md +278 -0
- package/templates/guides/impeccable-design/index.yaml +12 -0
- package/templates/guides/impeccable-design/motion-design.md +390 -0
- package/templates/guides/impeccable-design/typography.md +386 -0
- package/templates/guides/impeccable-design/ux-writing.md +400 -0
- package/templates/guides/index.yaml +265 -0
- package/templates/guides/java21/index.yaml +29 -0
- package/templates/guides/java21/java-style-guide.md +248 -0
- package/templates/guides/java21/modern-java21.md +303 -0
- package/templates/guides/kafka/README.md +32 -0
- package/templates/guides/kotlin/coding-conventions.md +247 -0
- package/templates/guides/kotlin/idioms.md +234 -0
- package/templates/guides/kotlin/index.yaml +26 -0
- package/templates/guides/multi-model-routing/README.md +101 -0
- package/templates/guides/multi-provider-exec/README.md +83 -0
- package/templates/guides/postgres/README.md +58 -0
- package/templates/guides/python/index.yaml +26 -0
- package/templates/guides/python/pep8-style-guide.md +202 -0
- package/templates/guides/python/zen-of-python.md +79 -0
- package/templates/guides/redis/README.md +50 -0
- package/templates/guides/rust/error-handling.md +262 -0
- package/templates/guides/rust/index.yaml +26 -0
- package/templates/guides/rust/ownership.md +180 -0
- package/templates/guides/skill-bundle-design/README.md +106 -0
- package/templates/guides/slack-cli/README.md +145 -0
- package/templates/guides/snowflake/README.md +32 -0
- package/templates/guides/spark/README.md +32 -0
- package/templates/guides/springboot/best-practices.md +361 -0
- package/templates/guides/springboot/index.yaml +22 -0
- package/templates/guides/supabase-postgres/README.md +32 -0
- package/templates/guides/supabase-postgres/index.yaml +19 -0
- package/templates/guides/typescript/advanced-types.md +225 -0
- package/templates/guides/typescript/index.yaml +26 -0
- package/templates/guides/typescript/type-system.md +219 -0
- package/templates/guides/web-design/accessibility.md +66 -0
- package/templates/guides/web-design/index.yaml +20 -0
- package/templates/guides/web-design/performance.md +102 -0
- package/templates/guides/web-scraping/README.md +926 -0
- package/templates/guides/web-scraping/index.yaml +19 -0
- package/templates/guides/worktree-lifecycle/README.md +104 -0
- package/templates/index.yaml +18 -0
- package/templates/manifest.json +49 -0
- package/templates/workflows/auto-dev.yaml +46 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# FastAPI Best Practices
|
|
2
|
+
|
|
3
|
+
> Source: https://fastapi.tiangolo.com/ and community patterns
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
Organize by domain, not by file type:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
├── auth/
|
|
12
|
+
│ ├── router.py # API endpoints
|
|
13
|
+
│ ├── schemas.py # Pydantic models
|
|
14
|
+
│ ├── models.py # Database models
|
|
15
|
+
│ ├── service.py # Business logic
|
|
16
|
+
│ ├── dependencies.py # Route validators
|
|
17
|
+
│ └── exceptions.py # Custom exceptions
|
|
18
|
+
├── users/
|
|
19
|
+
│ └── ...
|
|
20
|
+
├── config.py
|
|
21
|
+
└── main.py
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Async Best Practices
|
|
25
|
+
|
|
26
|
+
### I/O-Intensive Tasks
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
# Use async def with await for non-blocking I/O
|
|
30
|
+
async def fetch_user(user_id: int) -> User:
|
|
31
|
+
async with httpx.AsyncClient() as client:
|
|
32
|
+
response = await client.get(f"/api/users/{user_id}")
|
|
33
|
+
return User(**response.json())
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Sync I/O Operations
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
# Use regular def - FastAPI offloads to threadpool
|
|
40
|
+
def read_config() -> dict:
|
|
41
|
+
with open("config.yaml") as f:
|
|
42
|
+
return yaml.safe_load(f)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### CPU-Intensive Tasks
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
# Use separate worker processes
|
|
49
|
+
from celery import Celery
|
|
50
|
+
|
|
51
|
+
celery_app = Celery("tasks", broker="redis://localhost")
|
|
52
|
+
|
|
53
|
+
@celery_app.task
|
|
54
|
+
def process_data(data: dict) -> dict:
|
|
55
|
+
# Heavy computation
|
|
56
|
+
return result
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Never Do This
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
# WRONG: Blocks event loop
|
|
63
|
+
async def bad_example():
|
|
64
|
+
time.sleep(5) # Never use time.sleep in async!
|
|
65
|
+
|
|
66
|
+
# CORRECT: Use asyncio.sleep
|
|
67
|
+
async def good_example():
|
|
68
|
+
await asyncio.sleep(5)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Pydantic Models
|
|
72
|
+
|
|
73
|
+
### Custom Base Model
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pydantic import BaseModel
|
|
77
|
+
from datetime import datetime
|
|
78
|
+
|
|
79
|
+
class AppBaseModel(BaseModel):
|
|
80
|
+
class Config:
|
|
81
|
+
from_attributes = True
|
|
82
|
+
json_encoders = {
|
|
83
|
+
datetime: lambda v: v.isoformat()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
class UserResponse(AppBaseModel):
|
|
87
|
+
id: int
|
|
88
|
+
email: str
|
|
89
|
+
created_at: datetime
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Validation
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from pydantic import BaseModel, EmailStr, Field, validator
|
|
96
|
+
|
|
97
|
+
class UserCreate(BaseModel):
|
|
98
|
+
email: EmailStr
|
|
99
|
+
password: str = Field(..., min_length=8)
|
|
100
|
+
age: int = Field(..., ge=18, le=120)
|
|
101
|
+
|
|
102
|
+
@validator("password")
|
|
103
|
+
def password_strength(cls, v):
|
|
104
|
+
if not any(c.isupper() for c in v):
|
|
105
|
+
raise ValueError("Password must contain uppercase")
|
|
106
|
+
return v
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Dependencies
|
|
110
|
+
|
|
111
|
+
### Authentication
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from fastapi import Depends, HTTPException
|
|
115
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
116
|
+
|
|
117
|
+
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
|
118
|
+
|
|
119
|
+
async def get_current_user(
|
|
120
|
+
token: str = Depends(oauth2_scheme),
|
|
121
|
+
db: AsyncSession = Depends(get_db)
|
|
122
|
+
) -> User:
|
|
123
|
+
user = await verify_token(token, db)
|
|
124
|
+
if not user:
|
|
125
|
+
raise HTTPException(status_code=401)
|
|
126
|
+
return user
|
|
127
|
+
|
|
128
|
+
async def get_active_user(
|
|
129
|
+
user: User = Depends(get_current_user)
|
|
130
|
+
) -> User:
|
|
131
|
+
if not user.is_active:
|
|
132
|
+
raise HTTPException(status_code=403)
|
|
133
|
+
return user
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Database Session
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
|
140
|
+
|
|
141
|
+
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
|
142
|
+
async with async_session() as session:
|
|
143
|
+
try:
|
|
144
|
+
yield session
|
|
145
|
+
await session.commit()
|
|
146
|
+
except Exception:
|
|
147
|
+
await session.rollback()
|
|
148
|
+
raise
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Error Handling
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
# Custom exceptions
|
|
155
|
+
class AuthException(Exception):
|
|
156
|
+
pass
|
|
157
|
+
|
|
158
|
+
class InvalidCredentials(AuthException):
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
# Exception handler
|
|
162
|
+
@app.exception_handler(AuthException)
|
|
163
|
+
async def auth_exception_handler(request, exc):
|
|
164
|
+
return JSONResponse(
|
|
165
|
+
status_code=401,
|
|
166
|
+
content={"detail": str(exc)}
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# In router
|
|
170
|
+
@router.post("/login")
|
|
171
|
+
async def login(credentials: LoginSchema):
|
|
172
|
+
try:
|
|
173
|
+
return await auth_service.login(credentials)
|
|
174
|
+
except InvalidCredentials:
|
|
175
|
+
raise HTTPException(status_code=401, detail="Invalid credentials")
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## API Design
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from fastapi import APIRouter
|
|
182
|
+
|
|
183
|
+
router = APIRouter(
|
|
184
|
+
prefix="/users",
|
|
185
|
+
tags=["users"]
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
@router.get(
|
|
189
|
+
"/{user_id}",
|
|
190
|
+
response_model=UserResponse,
|
|
191
|
+
summary="Get user by ID",
|
|
192
|
+
responses={
|
|
193
|
+
404: {"model": ErrorResponse, "description": "User not found"}
|
|
194
|
+
}
|
|
195
|
+
)
|
|
196
|
+
async def get_user(
|
|
197
|
+
user_id: int,
|
|
198
|
+
db: AsyncSession = Depends(get_db),
|
|
199
|
+
current_user: User = Depends(get_current_user)
|
|
200
|
+
) -> UserResponse:
|
|
201
|
+
"""
|
|
202
|
+
Get a specific user by their ID.
|
|
203
|
+
|
|
204
|
+
- **user_id**: The unique identifier of the user
|
|
205
|
+
"""
|
|
206
|
+
user = await user_service.get(db, user_id)
|
|
207
|
+
if not user:
|
|
208
|
+
raise HTTPException(status_code=404, detail="User not found")
|
|
209
|
+
return user
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Testing
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
import pytest
|
|
216
|
+
from httpx import AsyncClient
|
|
217
|
+
from main import app
|
|
218
|
+
|
|
219
|
+
@pytest.fixture
|
|
220
|
+
async def client():
|
|
221
|
+
async with AsyncClient(app=app, base_url="http://test") as ac:
|
|
222
|
+
yield ac
|
|
223
|
+
|
|
224
|
+
@pytest.mark.asyncio
|
|
225
|
+
async def test_create_user(client: AsyncClient):
|
|
226
|
+
response = await client.post(
|
|
227
|
+
"/users/",
|
|
228
|
+
json={"email": "test@example.com", "password": "Password123"}
|
|
229
|
+
)
|
|
230
|
+
assert response.status_code == 201
|
|
231
|
+
assert response.json()["email"] == "test@example.com"
|
|
232
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# FastAPI Guide
|
|
2
|
+
|
|
3
|
+
metadata:
|
|
4
|
+
name: fastapi
|
|
5
|
+
description: FastAPI framework reference documentation
|
|
6
|
+
|
|
7
|
+
source:
|
|
8
|
+
type: external
|
|
9
|
+
origin: fastapi.tiangolo.com
|
|
10
|
+
urls:
|
|
11
|
+
- https://fastapi.tiangolo.com/
|
|
12
|
+
- https://github.com/zhanymkanov/fastapi-best-practices
|
|
13
|
+
last_fetched: "2026-01-22"
|
|
14
|
+
|
|
15
|
+
documents:
|
|
16
|
+
- name: best-practices
|
|
17
|
+
path: ./best-practices.md
|
|
18
|
+
description: FastAPI best practices and patterns
|
|
19
|
+
|
|
20
|
+
used_by:
|
|
21
|
+
- be-fastapi-expert
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Flutter Architecture
|
|
2
|
+
|
|
3
|
+
> Reference: docs.flutter.dev/app-architecture
|
|
4
|
+
|
|
5
|
+
## Official MVVM Pattern
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
UI Layer
|
|
9
|
+
├─ View (Widget) — display only, no business logic
|
|
10
|
+
└─ ViewModel (ChangeNotifier / Notifier) — state + commands
|
|
11
|
+
|
|
12
|
+
Data Layer
|
|
13
|
+
├─ Repository — single source of truth per domain
|
|
14
|
+
└─ Service — stateless external API wrapper
|
|
15
|
+
|
|
16
|
+
Domain Layer (optional)
|
|
17
|
+
└─ UseCase — cross-repository business logic
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Dependency Rules
|
|
21
|
+
|
|
22
|
+
- View knows only its ViewModel
|
|
23
|
+
- ViewModel knows Repositories (private)
|
|
24
|
+
- Repository knows Services (private)
|
|
25
|
+
- **Direction always inward** — UI depends on data, never reverse
|
|
26
|
+
|
|
27
|
+
### ViewModel with Commands
|
|
28
|
+
|
|
29
|
+
```dart
|
|
30
|
+
class HomeViewModel extends ChangeNotifier {
|
|
31
|
+
HomeViewModel({required BookingRepository bookingRepository})
|
|
32
|
+
: _bookingRepository = bookingRepository {
|
|
33
|
+
load = Command0(_load)..execute();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
final BookingRepository _bookingRepository;
|
|
37
|
+
late final Command0 load;
|
|
38
|
+
|
|
39
|
+
List<BookingSummary> _bookings = [];
|
|
40
|
+
UnmodifiableListView<BookingSummary> get bookings =>
|
|
41
|
+
UnmodifiableListView(_bookings);
|
|
42
|
+
|
|
43
|
+
Future<Result> _load() async {
|
|
44
|
+
final result = await _bookingRepository.getBookingsList();
|
|
45
|
+
if (result case Ok(:final value)) _bookings = value;
|
|
46
|
+
notifyListeners();
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Project Structure
|
|
53
|
+
|
|
54
|
+
### Medium Apps (Official MVVM)
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
lib/
|
|
58
|
+
├── ui/
|
|
59
|
+
│ ├── core/
|
|
60
|
+
│ │ ├── themes/app_theme.dart
|
|
61
|
+
│ │ └── widgets/loading_indicator.dart
|
|
62
|
+
│ └── home/
|
|
63
|
+
│ ├── home_screen.dart
|
|
64
|
+
│ └── home_viewmodel.dart
|
|
65
|
+
├── data/
|
|
66
|
+
│ ├── repositories/booking_repository.dart
|
|
67
|
+
│ └── services/api_service.dart
|
|
68
|
+
└── domain/ (optional)
|
|
69
|
+
└── use_cases/get_bookings_usecase.dart
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Large Apps (Clean Architecture)
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
lib/
|
|
76
|
+
├── core/
|
|
77
|
+
│ ├── error/failures.dart
|
|
78
|
+
│ ├── network/api_client.dart
|
|
79
|
+
│ └── utils/extensions.dart
|
|
80
|
+
└── features/
|
|
81
|
+
└── auth/
|
|
82
|
+
├── data/
|
|
83
|
+
│ ├── datasources/auth_remote_datasource.dart
|
|
84
|
+
│ ├── models/user_model.dart
|
|
85
|
+
│ └── repositories/auth_repository_impl.dart
|
|
86
|
+
├── domain/
|
|
87
|
+
│ ├── entities/user.dart
|
|
88
|
+
│ ├── repositories/auth_repository.dart
|
|
89
|
+
│ └── use_cases/login_usecase.dart
|
|
90
|
+
└── presentation/
|
|
91
|
+
├── bloc/auth_bloc.dart
|
|
92
|
+
├── pages/login_page.dart
|
|
93
|
+
└── widgets/login_form.dart
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Navigation (go_router)
|
|
97
|
+
|
|
98
|
+
```dart
|
|
99
|
+
final router = GoRouter(
|
|
100
|
+
initialLocation: '/',
|
|
101
|
+
routes: [
|
|
102
|
+
GoRoute(
|
|
103
|
+
path: '/',
|
|
104
|
+
builder: (context, state) => const HomeScreen(),
|
|
105
|
+
),
|
|
106
|
+
GoRoute(
|
|
107
|
+
path: '/product/:id',
|
|
108
|
+
builder: (context, state) {
|
|
109
|
+
final id = state.pathParameters['id']!;
|
|
110
|
+
return ProductDetailScreen(id: id);
|
|
111
|
+
},
|
|
112
|
+
),
|
|
113
|
+
ShellRoute(
|
|
114
|
+
builder: (context, state, child) => ScaffoldWithNavBar(child: child),
|
|
115
|
+
routes: [/* nested tab routes */],
|
|
116
|
+
),
|
|
117
|
+
],
|
|
118
|
+
redirect: (context, state) {
|
|
119
|
+
final isLoggedIn = /* check auth */;
|
|
120
|
+
if (!isLoggedIn && state.matchedLocation != '/login') return '/login';
|
|
121
|
+
return null;
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Data Models (freezed)
|
|
127
|
+
|
|
128
|
+
```dart
|
|
129
|
+
@freezed
|
|
130
|
+
class Product with _$Product {
|
|
131
|
+
const factory Product({
|
|
132
|
+
required int id,
|
|
133
|
+
required String name,
|
|
134
|
+
required double price,
|
|
135
|
+
@Default('') String description,
|
|
136
|
+
}) = _Product;
|
|
137
|
+
|
|
138
|
+
factory Product.fromJson(Map<String, dynamic> json) =>
|
|
139
|
+
_$ProductFromJson(json);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Flutter Fundamentals
|
|
2
|
+
|
|
3
|
+
> Reference: Flutter Official Documentation (docs.flutter.dev)
|
|
4
|
+
|
|
5
|
+
## Widget System
|
|
6
|
+
|
|
7
|
+
Flutter's UI is built with a composition of widgets. Everything is a widget — including padding, alignment, and decoration.
|
|
8
|
+
|
|
9
|
+
### Widget Types
|
|
10
|
+
|
|
11
|
+
| Type | Use Case | State |
|
|
12
|
+
|------|----------|-------|
|
|
13
|
+
| `StatelessWidget` | Pure rendering, no mutable state | Immutable |
|
|
14
|
+
| `StatefulWidget` | Local ephemeral state (animations, forms) | Mutable via `State<T>` |
|
|
15
|
+
| `InheritedWidget` | Data propagation down widget tree | Foundation of Provider |
|
|
16
|
+
|
|
17
|
+
### Widget Lifecycle
|
|
18
|
+
|
|
19
|
+
```dart
|
|
20
|
+
// StatefulWidget lifecycle
|
|
21
|
+
class MyWidget extends StatefulWidget {
|
|
22
|
+
@override
|
|
23
|
+
State<MyWidget> createState() => _MyWidgetState();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class _MyWidgetState extends State<MyWidget> {
|
|
27
|
+
@override
|
|
28
|
+
void initState() { super.initState(); /* one-time setup */ }
|
|
29
|
+
|
|
30
|
+
@override
|
|
31
|
+
void didChangeDependencies() { super.didChangeDependencies(); /* InheritedWidget changed */ }
|
|
32
|
+
|
|
33
|
+
@override
|
|
34
|
+
void didUpdateWidget(MyWidget oldWidget) { super.didUpdateWidget(oldWidget); /* parent rebuilt */ }
|
|
35
|
+
|
|
36
|
+
@override
|
|
37
|
+
Widget build(BuildContext context) { return Container(); /* called on every rebuild */ }
|
|
38
|
+
|
|
39
|
+
@override
|
|
40
|
+
void dispose() { /* cleanup controllers, subscriptions */ super.dispose(); }
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Three-Tree Architecture
|
|
45
|
+
|
|
46
|
+
Flutter maintains three parallel trees:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Widget Tree (immutable descriptions)
|
|
50
|
+
↓ createElement()
|
|
51
|
+
Element Tree (persistent, mutable handles)
|
|
52
|
+
↓ createRenderObject()
|
|
53
|
+
RenderObject Tree (layout + paint primitives)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- **Widget**: Lightweight, immutable configuration. Rebuilt frequently.
|
|
57
|
+
- **Element**: Persistent handle that manages widget lifecycle. Enables efficient diffing.
|
|
58
|
+
- **RenderObject**: Expensive layout/paint primitives. Only updated when properties change.
|
|
59
|
+
|
|
60
|
+
### Layout Algorithm
|
|
61
|
+
|
|
62
|
+
**Constraints go down, sizes go up, parent decides position.**
|
|
63
|
+
|
|
64
|
+
```dart
|
|
65
|
+
// Parent passes BoxConstraints to child
|
|
66
|
+
// Child returns its chosen Size within those constraints
|
|
67
|
+
// Parent positions child at an Offset
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Common layout errors:
|
|
71
|
+
- Unbounded height/width in `Column`/`Row` → wrap with `Expanded` or `Flexible`
|
|
72
|
+
- `Viewport was given unbounded height` → provide explicit height or use `SliverList`
|
|
73
|
+
|
|
74
|
+
## BuildContext
|
|
75
|
+
|
|
76
|
+
`BuildContext` is a handle to the widget's location in the Element tree.
|
|
77
|
+
|
|
78
|
+
```dart
|
|
79
|
+
// Access inherited data
|
|
80
|
+
final theme = Theme.of(context);
|
|
81
|
+
final mediaQuery = MediaQuery.of(context);
|
|
82
|
+
|
|
83
|
+
// NEVER store context across async gaps
|
|
84
|
+
// ALWAYS check mounted before using context after await
|
|
85
|
+
if (!mounted) return;
|
|
86
|
+
Navigator.of(context).push(...);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Keys
|
|
90
|
+
|
|
91
|
+
| Key Type | When to Use |
|
|
92
|
+
|----------|-------------|
|
|
93
|
+
| `ValueKey` | Items with unique business identity (user ID, product SKU) |
|
|
94
|
+
| `ObjectKey` | Items without natural key (use the object itself) |
|
|
95
|
+
| `UniqueKey` | Force new Element every build (rare, expensive) |
|
|
96
|
+
| `GlobalKey` | Cross-widget state access (use sparingly — breaks encapsulation) |
|
|
97
|
+
|
|
98
|
+
```dart
|
|
99
|
+
// Reorderable list MUST use keys
|
|
100
|
+
ListView(
|
|
101
|
+
children: items.map((item) => ListTile(
|
|
102
|
+
key: ValueKey(item.id),
|
|
103
|
+
title: Text(item.name),
|
|
104
|
+
)).toList(),
|
|
105
|
+
);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Package Recommendations
|
|
109
|
+
|
|
110
|
+
| Category | Package | Notes |
|
|
111
|
+
|----------|---------|-------|
|
|
112
|
+
| State (default) | `flutter_riverpod` | Compile-time safe, built-in DI |
|
|
113
|
+
| State (enterprise) | `flutter_bloc` | Event-driven, audit trails |
|
|
114
|
+
| Navigation | `go_router` | Official, deep linking, web |
|
|
115
|
+
| Models | `freezed` + `json_serializable` | Immutable, code-gen |
|
|
116
|
+
| HTTP | `dio` | Interceptors, cancellation |
|
|
117
|
+
| Linting | `very_good_analysis` | Community standard rules |
|
|
118
|
+
| Testing | `mocktail` | Null-safe mocking, no codegen |
|
|
119
|
+
| Secure Storage | `flutter_secure_storage` | Keychain/Keystore |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Flutter Guide
|
|
2
|
+
|
|
3
|
+
metadata:
|
|
4
|
+
name: flutter
|
|
5
|
+
description: Flutter cross-platform development reference documentation
|
|
6
|
+
|
|
7
|
+
source:
|
|
8
|
+
type: external
|
|
9
|
+
origin: flutter.dev
|
|
10
|
+
urls:
|
|
11
|
+
- https://docs.flutter.dev/
|
|
12
|
+
- https://docs.flutter.dev/app-architecture
|
|
13
|
+
- https://riverpod.dev/docs/introduction/getting_started
|
|
14
|
+
- https://bloclibrary.dev/
|
|
15
|
+
- https://dart.dev/effective-dart
|
|
16
|
+
last_fetched: "2026-03-11"
|
|
17
|
+
|
|
18
|
+
documents:
|
|
19
|
+
- name: fundamentals
|
|
20
|
+
path: ./fundamentals.md
|
|
21
|
+
description: Flutter widget system, BuildContext, rendering pipeline
|
|
22
|
+
|
|
23
|
+
- name: state-management
|
|
24
|
+
path: ./state-management.md
|
|
25
|
+
description: Riverpod 3.0, BLoC 9.0, Provider patterns and selection guide
|
|
26
|
+
|
|
27
|
+
- name: architecture
|
|
28
|
+
path: ./architecture.md
|
|
29
|
+
description: MVVM structure, project organization, go_router, freezed
|
|
30
|
+
|
|
31
|
+
- name: performance
|
|
32
|
+
path: ./performance.md
|
|
33
|
+
description: DevTools, const optimization, RepaintBoundary, Isolate
|
|
34
|
+
|
|
35
|
+
- name: testing
|
|
36
|
+
path: ./testing.md
|
|
37
|
+
description: Widget tests, golden tests, integration tests, mocking
|
|
38
|
+
|
|
39
|
+
- name: security
|
|
40
|
+
path: ./security.md
|
|
41
|
+
description: OWASP Mobile Top 10, secure storage, certificate pinning, platform security
|
|
42
|
+
|
|
43
|
+
used_by:
|
|
44
|
+
- fe-flutter-agent
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Flutter Performance
|
|
2
|
+
|
|
3
|
+
> Reference: docs.flutter.dev/perf/best-practices
|
|
4
|
+
|
|
5
|
+
## Frame Budget
|
|
6
|
+
|
|
7
|
+
- Target: **<8ms build + <8ms render = 16.67ms** (60fps)
|
|
8
|
+
- Profile with: `flutter run --profile` (not debug mode)
|
|
9
|
+
- Tool: DevTools Performance view → identify jank frames
|
|
10
|
+
|
|
11
|
+
## Build-Time Optimization
|
|
12
|
+
|
|
13
|
+
### const Constructors
|
|
14
|
+
|
|
15
|
+
```dart
|
|
16
|
+
// GOOD — zero rebuild cost
|
|
17
|
+
const Text('Hello');
|
|
18
|
+
const SizedBox(height: 8);
|
|
19
|
+
const Icon(Icons.star);
|
|
20
|
+
|
|
21
|
+
// BAD — new instance every build
|
|
22
|
+
Text('Hello');
|
|
23
|
+
SizedBox(height: 8);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Localize setState
|
|
27
|
+
|
|
28
|
+
```dart
|
|
29
|
+
// BAD — rebuilds entire screen
|
|
30
|
+
class _ScreenState extends State<Screen> {
|
|
31
|
+
int count = 0;
|
|
32
|
+
Widget build(BuildContext context) {
|
|
33
|
+
return Column(children: [
|
|
34
|
+
ExpensiveHeader(), // rebuilt unnecessarily
|
|
35
|
+
Text('$count'),
|
|
36
|
+
ElevatedButton(onPressed: () => setState(() => count++), child: Text('+'))
|
|
37
|
+
]);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// GOOD — only counter rebuilds
|
|
42
|
+
class _ScreenState extends State<Screen> {
|
|
43
|
+
Widget build(BuildContext context) {
|
|
44
|
+
return Column(children: [
|
|
45
|
+
const ExpensiveHeader(), // not rebuilt
|
|
46
|
+
CounterWidget(), // isolated StatefulWidget
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Extract Widgets (not methods)
|
|
53
|
+
|
|
54
|
+
```dart
|
|
55
|
+
// BAD — no Element identity, always rebuilds
|
|
56
|
+
Widget _buildHeader() => Container(...);
|
|
57
|
+
|
|
58
|
+
// GOOD — has Element identity, diffed efficiently
|
|
59
|
+
class HeaderWidget extends StatelessWidget {
|
|
60
|
+
const HeaderWidget({super.key});
|
|
61
|
+
@override
|
|
62
|
+
Widget build(BuildContext context) => Container(...);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Rendering Optimization
|
|
67
|
+
|
|
68
|
+
### RepaintBoundary
|
|
69
|
+
|
|
70
|
+
```dart
|
|
71
|
+
// Wrap frequently repainting subtrees
|
|
72
|
+
RepaintBoundary(
|
|
73
|
+
child: AnimatedWidget(...), // only this subtree repaints
|
|
74
|
+
)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Detect with: DevTools → Rendering → "Highlight repaints"
|
|
78
|
+
|
|
79
|
+
### Avoid Expensive Widgets
|
|
80
|
+
|
|
81
|
+
| Avoid | Use Instead | Reason |
|
|
82
|
+
|-------|-------------|--------|
|
|
83
|
+
| `Opacity` widget | `color.withValues(alpha: 0.5)` | Opacity widget triggers saveLayer |
|
|
84
|
+
| `ClipRRect` in animations | Pre-clip static content | saveLayer per frame |
|
|
85
|
+
| `Container` for sizing | `SizedBox` | Lighter, no decoration |
|
|
86
|
+
|
|
87
|
+
## List Performance
|
|
88
|
+
|
|
89
|
+
```dart
|
|
90
|
+
// GOOD — lazy construction, O(visible) not O(total)
|
|
91
|
+
ListView.builder(
|
|
92
|
+
itemCount: items.length,
|
|
93
|
+
itemExtent: 72.0, // skip intrinsic layout passes
|
|
94
|
+
itemBuilder: (context, index) => ProductTile(items[index]),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// BAD — builds ALL children upfront
|
|
98
|
+
ListView(children: items.map((i) => ProductTile(i)).toList());
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Compute Offloading
|
|
102
|
+
|
|
103
|
+
```dart
|
|
104
|
+
// CPU-intensive work (>16ms) on isolate
|
|
105
|
+
final result = await Isolate.run(() {
|
|
106
|
+
return heavyJsonParsing(rawData);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Web-compatible alternative
|
|
110
|
+
final result = await compute(heavyJsonParsing, rawData);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## DevTools Workflow
|
|
114
|
+
|
|
115
|
+
1. **Inspector** → identify widget causing rebuild
|
|
116
|
+
2. **Performance view** → identify jank frames (>16ms)
|
|
117
|
+
3. **CPU Profiler** → identify expensive Dart methods
|
|
118
|
+
4. **Memory view** → detect object leaks
|
|
119
|
+
5. **Network** → monitor API call timing
|