groundwork-method 0.0.1 → 0.11.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/CHANGELOG.md +823 -0
- package/LICENSE +21 -0
- package/README.md +44 -29
- package/bin/groundwork.js +1723 -0
- package/dist/src/generators/add-capability/generator.d.ts +8 -0
- package/dist/src/generators/add-capability/generator.js +60 -0
- package/dist/src/generators/add-capability/generator.js.map +1 -0
- package/dist/src/generators/cli-app/generator.d.ts +9 -0
- package/dist/src/generators/cli-app/generator.js +140 -0
- package/dist/src/generators/cli-app/generator.js.map +1 -0
- package/dist/src/generators/docs-site/generator.d.ts +5 -0
- package/dist/src/generators/docs-site/generator.js +441 -0
- package/dist/src/generators/docs-site/generator.js.map +1 -0
- package/dist/src/generators/electron-app/generator.d.ts +6 -0
- package/dist/src/generators/electron-app/generator.js +261 -0
- package/dist/src/generators/electron-app/generator.js.map +1 -0
- package/dist/src/generators/flutter-app/generator.d.ts +6 -0
- package/dist/src/generators/flutter-app/generator.js +314 -0
- package/dist/src/generators/flutter-app/generator.js.map +1 -0
- package/dist/src/generators/go-microservice/generator.d.ts +8 -0
- package/dist/src/generators/go-microservice/generator.js +232 -0
- package/dist/src/generators/go-microservice/generator.js.map +1 -0
- package/dist/src/generators/nextjs-app/generator.d.ts +8 -0
- package/dist/src/generators/nextjs-app/generator.js +294 -0
- package/dist/src/generators/nextjs-app/generator.js.map +1 -0
- package/dist/src/generators/python-microservice/generator.d.ts +13 -0
- package/dist/src/generators/python-microservice/generator.js +265 -0
- package/dist/src/generators/python-microservice/generator.js.map +1 -0
- package/dist/src/generators/shared/brand-tokens.d.ts +89 -0
- package/dist/src/generators/shared/brand-tokens.js +308 -0
- package/dist/src/generators/shared/brand-tokens.js.map +1 -0
- package/dist/src/generators/shared/capabilities.d.ts +101 -0
- package/dist/src/generators/shared/capabilities.js +279 -0
- package/dist/src/generators/shared/capabilities.js.map +1 -0
- package/dist/src/generators/shared/provenance.d.ts +2 -0
- package/dist/src/generators/shared/provenance.js +85 -0
- package/dist/src/generators/shared/provenance.js.map +1 -0
- package/dist/src/generators/shared/scaffold-helpers.d.ts +72 -0
- package/dist/src/generators/shared/scaffold-helpers.js +309 -0
- package/dist/src/generators/shared/scaffold-helpers.js.map +1 -0
- package/dist/src/generators/system-test-runner/generator.d.ts +23 -0
- package/dist/src/generators/system-test-runner/generator.js +173 -0
- package/dist/src/generators/system-test-runner/generator.js.map +1 -0
- package/dist/src/generators/workspace-dev-cli/generator.d.ts +7 -0
- package/dist/src/generators/workspace-dev-cli/generator.js +138 -0
- package/dist/src/generators/workspace-dev-cli/generator.js.map +1 -0
- package/generators.json +57 -0
- package/lib/repo-map/grammars/tree-sitter-c.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-cpp.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-csharp.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-dart.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-go.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-java.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-javascript.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-kotlin.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-lua.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-php.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-python.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-ruby.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-rust.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-scala.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-swift.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-tsx.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-typescript.wasm +0 -0
- package/lib/repo-map/index.js +386 -0
- package/lib/repo-map/languages.js +514 -0
- package/lib/repo-map/pagerank.js +59 -0
- package/migrations/README.md +60 -0
- package/migrations/_template/cli-migration.js +27 -0
- package/migrations/gw-bet-prose-redesign.js +105 -0
- package/migrations/gw-drop-test-manifest.js +37 -0
- package/migrations/gw-register-serena-mcp.js +42 -0
- package/migrations/gw-relocate-hidden-skills.js +40 -0
- package/migrations/gw-seed-config-toml.js +24 -0
- package/migrations/index.json +40 -0
- package/package.json +70 -6
- package/src/AGENTS.md +36 -0
- package/src/config/config.toml +30 -0
- package/src/config/groundwork-state.json +5 -0
- package/src/docs/llms.txt +72 -0
- package/src/docs/principles/ai-native/agent-native-systems.md +90 -0
- package/src/docs/principles/ai-native/agentic-systems.md +78 -0
- package/src/docs/principles/ai-native/ai-engineering.md +100 -0
- package/src/docs/principles/ai-native/ai-native-product.md +76 -0
- package/src/docs/principles/delivery/cost-engineering.md +89 -0
- package/src/docs/principles/delivery/day-2-operational-baseline.md +57 -0
- package/src/docs/principles/delivery/devex.md +88 -0
- package/src/docs/principles/delivery/platform.md +101 -0
- package/src/docs/principles/delivery/progressive-delivery.md +92 -0
- package/src/docs/principles/design/ai-native-design.md +73 -0
- package/src/docs/principles/design/design-foundations.md +80 -0
- package/src/docs/principles/design/design-systems-and-tokens.md +72 -0
- package/src/docs/principles/design/interaction-and-motion.md +69 -0
- package/src/docs/principles/design/layout-and-space.md +72 -0
- package/src/docs/principles/design/usability-and-ux.md +79 -0
- package/src/docs/principles/design/visual-design.md +84 -0
- package/src/docs/principles/foundations/code-craft.md +86 -0
- package/src/docs/principles/foundations/continuous-discovery.md +75 -0
- package/src/docs/principles/foundations/documentation.md +102 -0
- package/src/docs/principles/foundations/prioritization-and-appetite.md +78 -0
- package/src/docs/principles/foundations/product-engineering.md +90 -0
- package/src/docs/principles/foundations/product-risks.md +89 -0
- package/src/docs/principles/foundations/requirements-and-specs.md +80 -0
- package/src/docs/principles/foundations/success-metrics.md +66 -0
- package/src/docs/principles/foundations/testing.md +108 -0
- package/src/docs/principles/index.md +24 -0
- package/src/docs/principles/quality/accessibility.md +88 -0
- package/src/docs/principles/quality/observability.md +84 -0
- package/src/docs/principles/quality/performance.md +84 -0
- package/src/docs/principles/quality/privacy.md +92 -0
- package/src/docs/principles/quality/reliability.md +89 -0
- package/src/docs/principles/quality/security.md +78 -0
- package/src/docs/principles/stack/postgres.md +100 -0
- package/src/docs/principles/system-design/api-design.md +86 -0
- package/src/docs/principles/system-design/architecture-decisions.md +81 -0
- package/src/docs/principles/system-design/code-structure.md +104 -0
- package/src/docs/principles/system-design/data-engineering.md +87 -0
- package/src/docs/principles/system-design/durable-execution.md +89 -0
- package/src/docs/principles/system-design/evolutionary-architecture.md +81 -0
- package/src/docs/principles/system-design/identity-and-access.md +76 -0
- package/src/docs/principles/system-design/integration-patterns.md +84 -0
- package/src/docs/principles/system-design/real-time.md +83 -0
- package/src/docs/principles/system-design/surface-architecture.md +74 -0
- package/src/docs/ways-of-working/documentation.md +69 -0
- package/src/docs/ways-of-working/how-we-work.md +76 -0
- package/src/docs/ways-of-working/units-of-work.md +40 -0
- package/src/engineer-skills/groundwork-electron-engineer/SKILL.md +123 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/documentation.md +126 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/performance-and-reliability.md +80 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/process-model.md +94 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/security.md +107 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +129 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/theming-and-tokens.md +74 -0
- package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +22 -0
- package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +114 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/accessibility.md +92 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/architecture.md +189 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/data-and-contracts.md +136 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/documentation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/navigation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/performance-and-reliability.md +100 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/platform-channels.md +93 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/releases-and-distribution.md +84 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/security.md +96 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/state-management.md +166 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +160 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/theming-and-design-tokens.md +109 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/widgets-and-composition.md +123 -0
- package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +24 -0
- package/src/engineer-skills/groundwork-go-engineer/SKILL.md +174 -0
- package/src/engineer-skills/groundwork-go-engineer/references/api-design.md +82 -0
- package/src/engineer-skills/groundwork-go-engineer/references/architecture.md +42 -0
- package/src/engineer-skills/groundwork-go-engineer/references/capability-ports.md +50 -0
- package/src/engineer-skills/groundwork-go-engineer/references/code-craft-security.md +34 -0
- package/src/engineer-skills/groundwork-go-engineer/references/concurrency.md +108 -0
- package/src/engineer-skills/groundwork-go-engineer/references/documentation.md +130 -0
- package/src/engineer-skills/groundwork-go-engineer/references/go-services.md +77 -0
- package/src/engineer-skills/groundwork-go-engineer/references/http-handlers.md +172 -0
- package/src/engineer-skills/groundwork-go-engineer/references/implementation-patterns.md +156 -0
- package/src/engineer-skills/groundwork-go-engineer/references/integration-realtime-data.md +57 -0
- package/src/engineer-skills/groundwork-go-engineer/references/observability.md +49 -0
- package/src/engineer-skills/groundwork-go-engineer/references/postgres.md +41 -0
- package/src/engineer-skills/groundwork-go-engineer/references/reliability-performance.md +105 -0
- package/src/engineer-skills/groundwork-go-engineer/references/testing.md +201 -0
- package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +20 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +112 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/accessibility.md +111 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/architecture.md +323 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/data-fetching.md +458 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/documentation.md +324 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/error-boundaries.md +383 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/mutations-and-forms.md +396 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/observability.md +48 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/performance-and-deployment.md +947 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/routing-and-navigation.md +405 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/security.md +131 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/server-components.md +394 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/tailwind-and-styling.md +134 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +491 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/type-system.md +368 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +230 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +16 -0
- package/src/engineer-skills/groundwork-python-engineer/SKILL.md +199 -0
- package/src/engineer-skills/groundwork-python-engineer/references/api-standards.md +88 -0
- package/src/engineer-skills/groundwork-python-engineer/references/architecture.md +57 -0
- package/src/engineer-skills/groundwork-python-engineer/references/async-patterns.md +103 -0
- package/src/engineer-skills/groundwork-python-engineer/references/capability-ports.md +44 -0
- package/src/engineer-skills/groundwork-python-engineer/references/database.md +88 -0
- package/src/engineer-skills/groundwork-python-engineer/references/documentation-mcp.md +167 -0
- package/src/engineer-skills/groundwork-python-engineer/references/implementation-patterns.md +166 -0
- package/src/engineer-skills/groundwork-python-engineer/references/ml-pipelines.md +119 -0
- package/src/engineer-skills/groundwork-python-engineer/references/ml-systems-ai-engineering.md +74 -0
- package/src/engineer-skills/groundwork-python-engineer/references/observability.md +57 -0
- package/src/engineer-skills/groundwork-python-engineer/references/resilience.md +126 -0
- package/src/engineer-skills/groundwork-python-engineer/references/security.md +148 -0
- package/src/engineer-skills/groundwork-python-engineer/references/testing.md +216 -0
- package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +20 -0
- package/src/generators/add-capability/generator.ts +70 -0
- package/src/generators/add-capability/schema.json +30 -0
- package/src/generators/capabilities/llm/capability.json +28 -0
- package/src/generators/capabilities/llm/providers/anthropic/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/anthropic/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/anthropic/stacks/python/src/__packageName__/adapters/llm.py.template +61 -0
- package/src/generators/capabilities/llm/providers/local/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/local/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/local/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/localai/footprint.json +29 -0
- package/src/generators/capabilities/llm/providers/localai/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/localai/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/none/footprint.json +9 -0
- package/src/generators/capabilities/llm/providers/none/stacks/go/internal/llm/llm.go.template +35 -0
- package/src/generators/capabilities/llm/providers/none/stacks/python/src/__packageName__/adapters/llm.py.template +25 -0
- package/src/generators/capabilities/llm/providers/ollama/footprint.json +20 -0
- package/src/generators/capabilities/llm/providers/ollama/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/ollama/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/openai/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/openai/stacks/go/internal/llm/llm.go.template +98 -0
- package/src/generators/capabilities/llm/providers/openai/stacks/python/src/__packageName__/adapters/llm.py.template +60 -0
- package/src/generators/capabilities/llm/stacks/go/internal/core/service/llm.go.template +12 -0
- package/src/generators/capabilities/llm/stacks/go/internal/llm/llm_test.go.template +33 -0
- package/src/generators/capabilities/llm/stacks/python/src/__packageName__/core/llm.py.template +15 -0
- package/src/generators/capabilities/llm/stacks/python/tests/contracts/test_llm.py.template +37 -0
- package/src/generators/cli-app/files/README.md.template +76 -0
- package/src/generators/cli-app/files/build.mjs.template +15 -0
- package/src/generators/cli-app/files/package.json.template +21 -0
- package/src/generators/cli-app/files/src/cli.ts.template +67 -0
- package/src/generators/cli-app/files/src/commands/hello.ts.template +17 -0
- package/src/generators/cli-app/files/src/commands/status.ts.template +23 -0
- package/src/generators/cli-app/files/src/core/client.test.ts.template +80 -0
- package/src/generators/cli-app/files/src/core/client.ts.template +64 -0
- package/src/generators/cli-app/files/src/registry.test.ts.template +35 -0
- package/src/generators/cli-app/files/src/registry.ts.template +31 -0
- package/src/generators/cli-app/files/tsconfig.json.template +16 -0
- package/src/generators/cli-app/files/tsconfig.test.json.template +11 -0
- package/src/generators/cli-app/generator.ts +138 -0
- package/src/generators/cli-app/schema.json +24 -0
- package/src/generators/docs-site/files/.gitignore.ejs +40 -0
- package/src/generators/docs-site/files/app/docs/__slug__/page.tsx +101 -0
- package/src/generators/docs-site/files/app/docs/layout.tsx +14 -0
- package/src/generators/docs-site/files/app/docs.css +43 -0
- package/src/generators/docs-site/files/app/layout.tsx +24 -0
- package/src/generators/docs-site/files/app/page.tsx +135 -0
- package/src/generators/docs-site/files/app/source.ts +8 -0
- package/src/generators/docs-site/files/components/mermaid.tsx +67 -0
- package/src/generators/docs-site/files/next.config.mjs +10 -0
- package/src/generators/docs-site/files/package.json +32 -0
- package/src/generators/docs-site/files/pnpm-workspace.yaml +7 -0
- package/src/generators/docs-site/files/postcss.config.mjs +6 -0
- package/src/generators/docs-site/files/source.config.ts +77 -0
- package/src/generators/docs-site/files/tailwind.config.js +10 -0
- package/src/generators/docs-site/files/tsconfig.json +27 -0
- package/src/generators/docs-site/generator.ts +476 -0
- package/src/generators/docs-site/schema.json +17 -0
- package/src/generators/electron-app/docs/principles/stack/electron/index.md +49 -0
- package/src/generators/electron-app/docs/principles/stack/electron/ipc-contracts.md +71 -0
- package/src/generators/electron-app/docs/principles/stack/electron/packaging-and-updates.md +59 -0
- package/src/generators/electron-app/docs/principles/stack/electron/process-model.md +53 -0
- package/src/generators/electron-app/docs/principles/stack/electron/security.md +70 -0
- package/src/generators/electron-app/docs/principles/stack/typescript/frontend.md +65 -0
- package/src/generators/electron-app/files/.gitignore.template +20 -0
- package/src/generators/electron-app/files/README.md.template +125 -0
- package/src/generators/electron-app/files/electron.vite.config.ts +31 -0
- package/src/generators/electron-app/files/eslint.config.mjs +92 -0
- package/src/generators/electron-app/files/forge.config.ts.template +44 -0
- package/src/generators/electron-app/files/package.json.template +54 -0
- package/src/generators/electron-app/files/playwright.config.ts +18 -0
- package/src/generators/electron-app/files/project.json.template +65 -0
- package/src/generators/electron-app/files/src/main/core-client.test.ts +81 -0
- package/src/generators/electron-app/files/src/main/core-client.ts +55 -0
- package/src/generators/electron-app/files/src/main/index.ts +157 -0
- package/src/generators/electron-app/files/src/main/ipc.ts +52 -0
- package/src/generators/electron-app/files/src/main/policy.test.ts +71 -0
- package/src/generators/electron-app/files/src/main/policy.ts +73 -0
- package/src/generators/electron-app/files/src/preload/index.ts +23 -0
- package/src/generators/electron-app/files/src/renderer/index.html.template +20 -0
- package/src/generators/electron-app/files/src/renderer/src/App.test.tsx +61 -0
- package/src/generators/electron-app/files/src/renderer/src/App.tsx.template +43 -0
- package/src/generators/electron-app/files/src/renderer/src/assets/main.css +40 -0
- package/src/generators/electron-app/files/src/renderer/src/env.d.ts +14 -0
- package/src/generators/electron-app/files/src/renderer/src/main.tsx +25 -0
- package/src/generators/electron-app/files/src/shared/ipc.ts +54 -0
- package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +133 -0
- package/src/generators/electron-app/files/tool/electron_exec.sh.template +83 -0
- package/src/generators/electron-app/files/tsconfig.json +7 -0
- package/src/generators/electron-app/files/tsconfig.node.json +27 -0
- package/src/generators/electron-app/files/tsconfig.web.json +22 -0
- package/src/generators/electron-app/files/vitest.config.ts +32 -0
- package/src/generators/electron-app/files/vitest.setup.ts +1 -0
- package/src/generators/electron-app/generator.ts +288 -0
- package/src/generators/electron-app/schema.json +23 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/architecture.md +78 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/index.md +38 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/platform-channels.md +51 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/releases-and-distribution.md +59 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/state-management.md +85 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +86 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/widgets-and-composition.md +69 -0
- package/src/generators/flutter-app/files/.gitignore.template +30 -0
- package/src/generators/flutter-app/files/README.md.template +100 -0
- package/src/generators/flutter-app/files/analysis_options.yaml.template +18 -0
- package/src/generators/flutter-app/files/integration_test/app_test.dart.template +64 -0
- package/src/generators/flutter-app/files/lib/app.dart.template +24 -0
- package/src/generators/flutter-app/files/lib/config/app_config.dart +15 -0
- package/src/generators/flutter-app/files/lib/data/repositories/status_repository.dart +36 -0
- package/src/generators/flutter-app/files/lib/data/services/api_client.dart +71 -0
- package/src/generators/flutter-app/files/lib/domain/models/health_status.dart +23 -0
- package/src/generators/flutter-app/files/lib/main.dart +11 -0
- package/src/generators/flutter-app/files/lib/router.dart +23 -0
- package/src/generators/flutter-app/files/lib/ui/core/theme/app_theme.dart +110 -0
- package/src/generators/flutter-app/files/lib/ui/home/home_view.dart +89 -0
- package/src/generators/flutter-app/files/lib/ui/home/home_view_model.dart.template +38 -0
- package/src/generators/flutter-app/files/project.json.template +51 -0
- package/src/generators/flutter-app/files/pubspec.yaml.template +47 -0
- package/src/generators/flutter-app/files/test/api_client_test.dart.template +63 -0
- package/src/generators/flutter-app/files/test/fakes/fake_status_repository.dart.template +19 -0
- package/src/generators/flutter-app/files/test/home_view_test.dart.template +58 -0
- package/src/generators/flutter-app/files/tool/flutter_exec.sh.template +60 -0
- package/src/generators/flutter-app/generator.ts +362 -0
- package/src/generators/flutter-app/schema.json +23 -0
- package/src/generators/go-microservice/docs/principles/stack/go/concurrency.md +123 -0
- package/src/generators/go-microservice/docs/principles/stack/go/index.md +70 -0
- package/src/generators/go-microservice/docs/principles/stack/go/testing.md +168 -0
- package/src/generators/go-microservice/files/.air.toml.template +38 -0
- package/src/generators/go-microservice/files/.env.template +4 -0
- package/src/generators/go-microservice/files/.golangci.yml.template +82 -0
- package/src/generators/go-microservice/files/Dockerfile.dev.template +12 -0
- package/src/generators/go-microservice/files/asyncapi-pubsub.yaml.template +33 -0
- package/src/generators/go-microservice/files/asyncapi-ws.yaml.template +34 -0
- package/src/generators/go-microservice/files/cmd/api/main.go.template +149 -0
- package/src/generators/go-microservice/files/cmd/api/main_test.go.template +99 -0
- package/src/generators/go-microservice/files/cmd/worker/cleanup/main.go.template +39 -0
- package/src/generators/go-microservice/files/db/schema.sql.template +24 -0
- package/src/generators/go-microservice/files/go.mod.template +39 -0
- package/src/generators/go-microservice/files/internal/config/config.go.template +52 -0
- package/src/generators/go-microservice/files/internal/config/otel.go.template +93 -0
- package/src/generators/go-microservice/files/internal/core/domain/errors.go.template +16 -0
- package/src/generators/go-microservice/files/internal/core/domain/model.go.template +28 -0
- package/src/generators/go-microservice/files/internal/core/domain/user.go.template +13 -0
- package/src/generators/go-microservice/files/internal/core/pagination.go.template +16 -0
- package/src/generators/go-microservice/files/internal/core/service/app_service.go.template +79 -0
- package/src/generators/go-microservice/files/internal/core/service/event_hub.go.template +9 -0
- package/src/generators/go-microservice/files/internal/core/service/message_queue.go.template +10 -0
- package/src/generators/go-microservice/files/internal/core/service/outbox_repository.go.template +31 -0
- package/src/generators/go-microservice/files/internal/core/service/repository.go.template +23 -0
- package/src/generators/go-microservice/files/internal/core/service/user_repository.go.template +15 -0
- package/src/generators/go-microservice/files/internal/core/service/user_service.go.template +43 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/app_handler.go.template +108 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/auth_middleware_test.go.template +52 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook.go.template +202 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook_test.go.template +82 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/health_handler.go.template +80 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware.go.template +87 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware_test.go.template +76 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/repository.go.template +37 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_auth.go.template +40 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_loadshed.go.template +38 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_logging.go.template +40 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_ratelimit.go.template +48 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_test.go.template +81 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/router.go.template +105 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/types.go.template +70 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/websocket_handler.go.template +39 -0
- package/src/generators/go-microservice/files/internal/httpclient/http_client.go.template +87 -0
- package/src/generators/go-microservice/files/internal/kafka/kafka.go.template +34 -0
- package/src/generators/go-microservice/files/internal/postgres/postgres.go.template +195 -0
- package/src/generators/go-microservice/files/internal/postgres/postgres_test.go.template +156 -0
- package/src/generators/go-microservice/files/internal/postgres/user_repository.go.template +56 -0
- package/src/generators/go-microservice/files/internal/pubsub/gcp_pubsub.go.template +35 -0
- package/src/generators/go-microservice/files/internal/websocket/client.go.template +151 -0
- package/src/generators/go-microservice/files/internal/websocket/hub.go.template +261 -0
- package/src/generators/go-microservice/files/scripts/apply-schema.sh.template +21 -0
- package/src/generators/go-microservice/files/tools/tools.go.template +10 -0
- package/src/generators/go-microservice/generator.ts +240 -0
- package/src/generators/go-microservice/schema.json +63 -0
- package/src/generators/nextjs-app/docs/principles/stack/typescript/frontend.md +65 -0
- package/src/generators/nextjs-app/files/.dockerignore.template +7 -0
- package/src/generators/nextjs-app/files/.env.example.template +24 -0
- package/src/generators/nextjs-app/files/.gitignore.template +5 -0
- package/src/generators/nextjs-app/files/Dockerfile +53 -0
- package/src/generators/nextjs-app/files/app/(auth)/sign-in/__sign-in__/page.tsx.template +9 -0
- package/src/generators/nextjs-app/files/app/(auth)/sign-up/__sign-up__/page.tsx.template +9 -0
- package/src/generators/nextjs-app/files/app/api/config/route.ts.template +39 -0
- package/src/generators/nextjs-app/files/app/api/healthz/route.test.ts +15 -0
- package/src/generators/nextjs-app/files/app/api/healthz/route.ts +5 -0
- package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.test.ts.template +55 -0
- package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.ts.template +126 -0
- package/src/generators/nextjs-app/files/app/error.tsx +39 -0
- package/src/generators/nextjs-app/files/app/global-error.tsx +68 -0
- package/src/generators/nextjs-app/files/app/globals.css +105 -0
- package/src/generators/nextjs-app/files/app/layout.tsx +59 -0
- package/src/generators/nextjs-app/files/app/loading.tsx +13 -0
- package/src/generators/nextjs-app/files/app/not-found.tsx +30 -0
- package/src/generators/nextjs-app/files/app/page.tsx +20 -0
- package/src/generators/nextjs-app/files/components/providers/default.tsx +19 -0
- package/src/generators/nextjs-app/files/components/providers/production.tsx +32 -0
- package/src/generators/nextjs-app/files/components/providers/telemetry.tsx +76 -0
- package/src/generators/nextjs-app/files/components/render-smoke.test.tsx +29 -0
- package/src/generators/nextjs-app/files/components/theme-provider.tsx +11 -0
- package/src/generators/nextjs-app/files/components.json +21 -0
- package/src/generators/nextjs-app/files/eslint.config.mjs +120 -0
- package/src/generators/nextjs-app/files/hooks/use-toast.ts +7 -0
- package/src/generators/nextjs-app/files/instrumentation.ts +90 -0
- package/src/generators/nextjs-app/files/lib/api/fetcher.ts.template +130 -0
- package/src/generators/nextjs-app/files/lib/config.ts +21 -0
- package/src/generators/nextjs-app/files/lib/logger.ts +29 -0
- package/src/generators/nextjs-app/files/lib/schemas/index.ts +19 -0
- package/src/generators/nextjs-app/files/lib/utils.ts +6 -0
- package/src/generators/nextjs-app/files/next.config.mjs +9 -0
- package/src/generators/nextjs-app/files/package.json +70 -0
- package/src/generators/nextjs-app/files/postcss.config.mjs +8 -0
- package/src/generators/nextjs-app/files/proxy.test.ts.template +30 -0
- package/src/generators/nextjs-app/files/proxy.ts +31 -0
- package/src/generators/nextjs-app/files/public/.gitkeep +1 -0
- package/src/generators/nextjs-app/files/tsconfig.json +42 -0
- package/src/generators/nextjs-app/files/vitest.config.mts +15 -0
- package/src/generators/nextjs-app/files/vitest.setup.ts +7 -0
- package/src/generators/nextjs-app/generator.ts +307 -0
- package/src/generators/nextjs-app/schema.json +44 -0
- package/src/generators/python-microservice/docs/principles/stack/python/async.md +168 -0
- package/src/generators/python-microservice/docs/principles/stack/python/documentation.md +240 -0
- package/src/generators/python-microservice/docs/principles/stack/python/mcp.md +147 -0
- package/src/generators/python-microservice/docs/principles/stack/python/resilience.md +193 -0
- package/src/generators/python-microservice/docs/principles/stack/python/testing.md +322 -0
- package/src/generators/python-microservice/files/.env.example.template +30 -0
- package/src/generators/python-microservice/files/Dockerfile.template +36 -0
- package/src/generators/python-microservice/files/db/schema.sql.template +19 -0
- package/src/generators/python-microservice/files/pyproject.toml.template +76 -0
- package/src/generators/python-microservice/files/scripts/apply-schema.sh.template +25 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/comfyui.py.template +87 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/config.py.template +48 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/database.py.template +21 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/message_queue.py.template +29 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/repository.py.template +130 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/telemetry.py.template +68 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/websocket_hub.py.template +36 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/domain/entities.py.template +22 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/domain/exceptions.py.template +43 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/ports.py.template +42 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/service/example_service.py.template +68 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/dependencies.py.template +50 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/middleware.py.template +131 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/router.py.template +37 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/websocket_handler.py.template +20 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/cleanup.py.template +35 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/worker.py.template +28 -0
- package/src/generators/python-microservice/files/src/__packageName__/main.py.template +108 -0
- package/src/generators/python-microservice/files/tests/test_main.py.template +74 -0
- package/src/generators/python-microservice/files/tests/test_middleware.py.template +109 -0
- package/src/generators/python-microservice/files/tests/test_worker.py.template +16 -0
- package/src/generators/python-microservice/generator.ts +286 -0
- package/src/generators/python-microservice/schema.json +86 -0
- package/src/generators/shared/brand-tokens.ts +301 -0
- package/src/generators/shared/capabilities.ts +349 -0
- package/src/generators/shared/provenance.ts +61 -0
- package/src/generators/shared/scaffold-helpers.ts +309 -0
- package/src/generators/system-test-runner/NATIVE-CHECK-CONTRACT.md +20 -0
- package/src/generators/system-test-runner/files/tests/bets/.gitkeep +0 -0
- package/src/generators/system-test-runner/files/tests/bets/_archive/.gitkeep +0 -0
- package/src/generators/system-test-runner/files/tests/conftest.py.template +503 -0
- package/src/generators/system-test-runner/files/tests/pyproject.toml.template +20 -0
- package/src/generators/system-test-runner/files/tests/system/pages/__init__.py.template +9 -0
- package/src/generators/system-test-runner/files/tests/system/pages/base_page.py.template +36 -0
- package/src/generators/system-test-runner/files/tests/system/test_a11y_smoke.py.template +132 -0
- package/src/generators/system-test-runner/files/tests/system/test_contract_conformance.py.template +140 -0
- package/src/generators/system-test-runner/files/tests/system/test_layout_geometry.py.template +109 -0
- package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +257 -0
- package/src/generators/system-test-runner/files/tests/system/test_system.py.template +158 -0
- package/src/generators/system-test-runner/files/tests/system/test_token_conformance.py.template +206 -0
- package/src/generators/system-test-runner/files/tests/system/test_visual_regression.py.template +104 -0
- package/src/generators/system-test-runner/generator.ts +196 -0
- package/src/generators/system-test-runner/schema.json +24 -0
- package/src/generators/workspace-dev-cli/cli-src/build.mjs +42 -0
- package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +2168 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/bet.ts +442 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/completion.ts +87 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/doctor.ts +139 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/lifecycle.ts +548 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/quality.ts +127 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/surface.ts +214 -0
- package/src/generators/workspace-dev-cli/cli-src/src/index.ts +127 -0
- package/src/generators/workspace-dev-cli/cli-src/src/registry.ts +194 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/color.ts +130 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/render.ts +158 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/tokens.ts +122 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/context.ts +43 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/extensions.ts +99 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/paths.ts +46 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/proc.ts +106 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/prompt.ts +108 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/runners.ts +70 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/services.ts +221 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/version.ts +21 -0
- package/src/generators/workspace-dev-cli/cli-src/tsconfig.json +16 -0
- package/src/generators/workspace-dev-cli/files/.agents/skills/workspace-cli/SKILL.md.template +74 -0
- package/src/generators/workspace-dev-cli/files/dev.template +16 -0
- package/src/generators/workspace-dev-cli/files/docker-compose.yml.template +20 -0
- package/src/generators/workspace-dev-cli/files/scripts/cli/templates/milestone-test.pytmpl.template +46 -0
- package/src/generators/workspace-dev-cli/files/scripts/cli/templates/slice-test.pytmpl.template +38 -0
- package/src/generators/workspace-dev-cli/generator.ts +136 -0
- package/src/generators/workspace-dev-cli/schema.json +22 -0
- package/src/hidden-skills/code-intelligence.md +135 -0
- package/src/hidden-skills/groundwork-architect/SKILL.md +114 -0
- package/src/hidden-skills/groundwork-architect/references/agentic-systems.md +44 -0
- package/src/hidden-skills/groundwork-architect/references/ai-native-architecture.md +37 -0
- package/src/hidden-skills/groundwork-architect/references/api-and-contracts.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/core-and-boundaries.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/data-architecture.md +33 -0
- package/src/hidden-skills/groundwork-architect/references/decision-records.md +34 -0
- package/src/hidden-skills/groundwork-architect/references/durable-execution.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/evolutionary-architecture.md +37 -0
- package/src/hidden-skills/groundwork-architect/references/identity-and-access.md +41 -0
- package/src/hidden-skills/groundwork-architect/references/integration-patterns.md +39 -0
- package/src/hidden-skills/groundwork-architect/references/observability.md +36 -0
- package/src/hidden-skills/groundwork-architect/references/performance-and-scale.md +41 -0
- package/src/hidden-skills/groundwork-architect/references/platform-and-delivery.md +47 -0
- package/src/hidden-skills/groundwork-architect/references/realtime-and-async.md +28 -0
- package/src/hidden-skills/groundwork-architect/references/reliability.md +31 -0
- package/src/hidden-skills/groundwork-architect/references/security-and-trust.md +47 -0
- package/src/hidden-skills/groundwork-architect/references/surface-architecture.md +40 -0
- package/src/hidden-skills/groundwork-architect/sync-anchor.md +34 -0
- package/src/hidden-skills/groundwork-architecture/architecture-template.md +50 -0
- package/src/hidden-skills/groundwork-architecture/instructions.md +139 -0
- package/src/hidden-skills/groundwork-architecture/phases/01-context-ingestion.md +18 -0
- package/src/hidden-skills/groundwork-architecture/phases/02-technical-constraints.md +27 -0
- package/src/hidden-skills/groundwork-architecture/phases/03-service-design.md +19 -0
- package/src/hidden-skills/groundwork-architecture/phases/04-data-flow-communication.md +23 -0
- package/src/hidden-skills/groundwork-architecture/phases/05-component-boundaries-contracts.md +17 -0
- package/src/hidden-skills/groundwork-architecture/phases/06-draft-review-present.md +38 -0
- package/src/hidden-skills/groundwork-architecture/phases/07-commit.md +33 -0
- package/src/hidden-skills/groundwork-architecture/templates/architecture-cache.md +43 -0
- package/src/hidden-skills/groundwork-architecture-extract/instructions.md +163 -0
- package/src/hidden-skills/groundwork-architecture-extract/templates/architecture-extract-cache.md +21 -0
- package/src/hidden-skills/groundwork-bet/briefs/acceptance-auditor.md +68 -0
- package/src/hidden-skills/groundwork-bet/briefs/blind-reviewer.md +56 -0
- package/src/hidden-skills/groundwork-bet/briefs/coverage-auditor.md +95 -0
- package/src/hidden-skills/groundwork-bet/briefs/edge-case-tracer.md +64 -0
- package/src/hidden-skills/groundwork-bet/briefs/experience-auditor.md +83 -0
- package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +257 -0
- package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
- package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +115 -0
- package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +38 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/meta.json +4 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +31 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +31 -0
- package/src/hidden-skills/groundwork-bet/templates/pitch.md +45 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/01-ui-design.md +51 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/02-data-flows.md +36 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +90 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/04-data-design.md +29 -0
- package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +200 -0
- package/src/hidden-skills/groundwork-bet/workflows/02-design.md +178 -0
- package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +242 -0
- package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +226 -0
- package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +210 -0
- package/src/hidden-skills/groundwork-design-system/instructions.md +125 -0
- package/src/hidden-skills/groundwork-design-system/templates/brand-tokens.md +182 -0
- package/src/hidden-skills/groundwork-design-system/templates/design-system-cache.md +64 -0
- package/src/hidden-skills/groundwork-design-system/tracks/_foundation.md +136 -0
- package/src/hidden-skills/groundwork-design-system/tracks/agentic-protocol.md +269 -0
- package/src/hidden-skills/groundwork-design-system/tracks/cli.md +355 -0
- package/src/hidden-skills/groundwork-design-system/tracks/graphical-ui.md +330 -0
- package/src/hidden-skills/groundwork-design-system-extract/instructions.md +124 -0
- package/src/hidden-skills/groundwork-design-system-extract/templates/design-system-extract-cache.md +19 -0
- package/src/hidden-skills/groundwork-designer/SKILL.md +108 -0
- package/src/hidden-skills/groundwork-designer/references/accessibility.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/ai-native-design.md +37 -0
- package/src/hidden-skills/groundwork-designer/references/design-review.md +29 -0
- package/src/hidden-skills/groundwork-designer/references/design-systems-and-tokens.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/interaction-and-motion.md +37 -0
- package/src/hidden-skills/groundwork-designer/references/layout-and-space.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/usability-and-ux.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/visual-craft.md +49 -0
- package/src/hidden-skills/groundwork-designer/sync-anchor.md +20 -0
- package/src/hidden-skills/groundwork-doc-sync/instructions.md +100 -0
- package/src/hidden-skills/groundwork-elicit/instructions.md +66 -0
- package/src/hidden-skills/groundwork-elicit/methods.md +65 -0
- package/src/hidden-skills/groundwork-infra-adopt/instructions.md +168 -0
- package/src/hidden-skills/groundwork-infra-adopt/templates/infra-adopt-cache.md +21 -0
- package/src/hidden-skills/groundwork-mvp/instructions.md +223 -0
- package/src/hidden-skills/groundwork-mvp/templates/mvp-cache.md +9 -0
- package/src/hidden-skills/groundwork-patch/instructions.md +40 -0
- package/src/hidden-skills/groundwork-persona/instructions.md +65 -0
- package/src/hidden-skills/groundwork-product/SKILL.md +102 -0
- package/src/hidden-skills/groundwork-product/references/ai-native-product.md +45 -0
- package/src/hidden-skills/groundwork-product/references/discovery-and-opportunity.md +38 -0
- package/src/hidden-skills/groundwork-product/references/product-risks.md +52 -0
- package/src/hidden-skills/groundwork-product/references/requirements-and-specs.md +39 -0
- package/src/hidden-skills/groundwork-product/references/scope-and-sequencing.md +35 -0
- package/src/hidden-skills/groundwork-product/references/shaping-and-appetite.md +48 -0
- package/src/hidden-skills/groundwork-product/references/success-metrics-and-signals.md +37 -0
- package/src/hidden-skills/groundwork-product/sync-anchor.md +19 -0
- package/src/hidden-skills/groundwork-product-brief/instructions.md +231 -0
- package/src/hidden-skills/groundwork-product-brief-extract/instructions.md +139 -0
- package/src/hidden-skills/groundwork-product-brief-extract/templates/product-brief-extract-cache.md +17 -0
- package/src/hidden-skills/groundwork-review/checklists/architecture.md +93 -0
- package/src/hidden-skills/groundwork-review/checklists/bet-pitch.md +94 -0
- package/src/hidden-skills/groundwork-review/checklists/decomposition.md +135 -0
- package/src/hidden-skills/groundwork-review/checklists/design-system.md +85 -0
- package/src/hidden-skills/groundwork-review/checklists/domain-entity.md +66 -0
- package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +47 -0
- package/src/hidden-skills/groundwork-review/checklists/infrastructure.md +68 -0
- package/src/hidden-skills/groundwork-review/checklists/maturity.md +71 -0
- package/src/hidden-skills/groundwork-review/checklists/product-brief.md +69 -0
- package/src/hidden-skills/groundwork-review/checklists/technical-design.md +112 -0
- package/src/hidden-skills/groundwork-review/instructions.md +181 -0
- package/src/hidden-skills/groundwork-scaffold/instructions.md +254 -0
- package/src/hidden-skills/groundwork-scaffold/phases/01-ingestion-service-mapping.md +87 -0
- package/src/hidden-skills/groundwork-scaffold/phases/02-scaffolding-execution.md +15 -0
- package/src/hidden-skills/groundwork-scaffold/phases/03-service-documentation-api-stubs.md +100 -0
- package/src/hidden-skills/groundwork-scaffold/phases/04-infrastructure-verification.md +17 -0
- package/src/hidden-skills/groundwork-scaffold/phases/05-draft-review.md +19 -0
- package/src/hidden-skills/groundwork-scaffold/phases/06-commit.md +19 -0
- package/src/hidden-skills/groundwork-scaffold/templates/scaffold-cache.md +23 -0
- package/src/hidden-skills/groundwork-scan/instructions.md +164 -0
- package/src/hidden-skills/groundwork-scan/references/digest-schema.md +66 -0
- package/src/hidden-skills/groundwork-scan/references/exclusions.md +44 -0
- package/src/hidden-skills/groundwork-scan/templates/architecture-findings.md +42 -0
- package/src/hidden-skills/groundwork-scan/templates/design-findings.md +23 -0
- package/src/hidden-skills/groundwork-scan/templates/overview.md +26 -0
- package/src/hidden-skills/groundwork-scan/templates/product-findings.md +23 -0
- package/src/hidden-skills/groundwork-scan/templates/scan-state.json +19 -0
- package/src/hidden-skills/groundwork-stack-forge/instructions.md +150 -0
- package/src/hidden-skills/groundwork-stack-forge/references/authoring-engineer-skills.md +107 -0
- package/src/hidden-skills/groundwork-surface-activation/instructions.md +138 -0
- package/src/hidden-skills/groundwork-update/briefs/reconcile-worker.md +196 -0
- package/src/hidden-skills/groundwork-update/instructions.md +200 -0
- package/src/hidden-skills/groundwork-writer/SKILL.md +278 -0
- package/src/hidden-skills/maturity-model.md +125 -0
- package/src/hidden-skills/operating-contract.md +400 -0
- package/src/hidden-skills/repo-map-schema.md +90 -0
- package/src/hidden-skills/templates/adr.md +57 -0
- package/src/hidden-skills/templates/capability-ports.md +71 -0
- package/src/hidden-skills/templates/discovery-notes.md +33 -0
- package/src/hidden-skills/templates/domain-entity.md +80 -0
- package/src/hidden-skills/templates/gap-ledger.md +21 -0
- package/src/hidden-skills/templates/handoff.md +37 -0
- package/src/hidden-skills/templates/maturity.md +39 -0
- package/src/hidden-skills/templates/surfaces.md +207 -0
- package/src/skills/groundwork-check/SKILL.md +56 -0
- package/src/skills/groundwork-check/instructions.md +70 -0
- package/src/skills/groundwork-orchestrator/SKILL.md +176 -0
- package/src/skills/groundwork-orchestrator/workflow-index.md +50 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: groundwork-flutter-engineer
|
|
3
|
+
description: >
|
|
4
|
+
Implement, review, and refactor Flutter mobile applications using the
|
|
5
|
+
official two-layer MVVM architecture, Riverpod state management, go_router
|
|
6
|
+
navigation, token-projected theming, widget and integration testing, Pigeon
|
|
7
|
+
platform channels, and store release engineering. Use for work touching
|
|
8
|
+
views, view models, repositories, services, providers, routing, theming,
|
|
9
|
+
widget tests, integration tests, native interop, or mobile release
|
|
10
|
+
pipelines. Make sure to use this skill whenever a user is working in a
|
|
11
|
+
Flutter or Dart codebase, building mobile UI features, fixing mobile bugs,
|
|
12
|
+
or reviewing Flutter code.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Flutter Engineer
|
|
16
|
+
|
|
17
|
+
Mobile execution engineer for Flutter applications. This skill guides implementation within the official Flutter architecture — MVVM features over a repository data layer, a compile-safe Riverpod provider graph, token-projected theming, and a test pyramid whose expensive tiers stay thin because the surface proves wiring, not business logic.
|
|
18
|
+
|
|
19
|
+
## Operating Contract
|
|
20
|
+
|
|
21
|
+
1. Locate the architectural layer before editing. Views, view models, repositories, services, and domain models each have distinct responsibilities; a change that blurs them is wrong even when it works.
|
|
22
|
+
2. The capability core owns business logic. The surface is wired to it through a typed client in the data layer — never re-implement a rule the core's contract already proves.
|
|
23
|
+
3. Route durable mobile policy to the canonical docs (`docs/principles/stack/flutter/`) instead of duplicating it in code comments or this skill.
|
|
24
|
+
4. Verify lints, widget tests, theme consumption, and accessibility semantics before declaring work complete.
|
|
25
|
+
|
|
26
|
+
## Code intelligence (repo map + Serena)
|
|
27
|
+
|
|
28
|
+
GroundWork gives you a deterministic **repo map** (`npx groundwork-method repo-map` — tree-sitter import edges + PageRank centrality, cached to `.groundwork/cache/repo-map.json`) and the **Serena** MCP server (LSP-backed symbol navigation and editing), registered at init. Orient before reading widely: refresh the map, read its `centrality` ranking to find the hubs, then use Serena to navigate them (`get_symbols_overview` / `find_symbol` / `find_referencing_symbols`) and make reference-aware edits (`replace_symbol_body` / `rename`). Full workflow and the graceful-degradation contract live in `.groundwork/skills/code-intelligence.md`; fall back to ordinary reads and edits when they are unavailable.
|
|
29
|
+
|
|
30
|
+
## Core Pillars
|
|
31
|
+
|
|
32
|
+
1. **MVVM Over Two Layers** — Every feature is one View (widgets only) paired with one ViewModel (state + commands). Repositories are the data layer's source of truth; services wrap external interfaces. A Domain layer is added only when it earns its place. This is the official Flutter architecture, adopted wholesale — code written against it is code every Flutter engineer recognises.
|
|
33
|
+
|
|
34
|
+
2. **The Provider Graph Is the App** — Riverpod 3.x providers carry shared state and double as dependency injection. Construction order, disposal, and test substitution fall out of the graph. There is no service locator, no `provider`-package DI, and no GetX — ever.
|
|
35
|
+
|
|
36
|
+
3. **Theming Is a Projection** — `ThemeData` is built from a palette module generated from the design system's brand tokens. Widgets consume `Theme.of(context)` and theme extensions; a `Color(0xFF...)` literal in a widget file is a review finding.
|
|
37
|
+
|
|
38
|
+
4. **Tests Prove Wiring, Not Rules** — Widget tests are the bulk of coverage; `integration_test` happy paths run on a headless Android emulator; Patrol enters only at the Flutter/OS boundary. Business rules are proven once at the core's contract — surface tests never re-prove them.
|
|
39
|
+
|
|
40
|
+
5. **Native Is a Disciplined Hatch** — Dropping to Swift/Kotlin is a capability decision made through Pigeon's typed boundary, wrapped as a data-layer service. Never a performance reflex, never a raw `MethodChannel` for a real API surface.
|
|
41
|
+
|
|
42
|
+
## How to Use This Skill
|
|
43
|
+
|
|
44
|
+
**Orient first.** On any non-trivial task, refresh the repo map (`npx groundwork-method repo-map`), read its `centrality` ranking to find the hubs, and navigate them with Serena before reading widely (see Code intelligence above) — this is the first step, not optional; fall back to ordinary reads only when those tools are unavailable. Then match the user's task to the smallest relevant reference set. Most tasks touch one or two references.
|
|
45
|
+
|
|
46
|
+
| Topic | Reference | Load When |
|
|
47
|
+
|-------|-----------|-----------|
|
|
48
|
+
| Architecture & Layers | `references/architecture.md` | Placing new code, understanding the MVVM/repository split, file organization, the core-access seam. |
|
|
49
|
+
| State Management | `references/state-management.md` | Providers, Notifiers, Mutations, ephemeral vs app state, provider testing seams. |
|
|
50
|
+
| Widgets & Composition | `references/widgets-and-composition.md` | Building or refactoring widgets, const discipline, build purity, keys, extraction. |
|
|
51
|
+
| Theming & Design Tokens | `references/theming-and-design-tokens.md` | Theme consumption, the generated palette, ThemeExtensions, dark mode, typography. |
|
|
52
|
+
| Navigation | `references/navigation.md` | go_router routes, shell routes, redirects, typed routes, deep links. |
|
|
53
|
+
| Data & Contracts | `references/data-and-contracts.md` | Repositories, services, the dio contract client, error mapping, contract-client tooling. |
|
|
54
|
+
| Testing | `references/testing.md` | Unit/widget/integration taxonomy, fakes, emulator CI, Patrol, goldens, test commands. |
|
|
55
|
+
| Platform Channels | `references/platform-channels.md` | Pigeon APIs, native modules, when to drop to Swift/Kotlin, SwiftPM wiring. |
|
|
56
|
+
| Releases & Distribution | `references/releases-and-distribution.md` | Signing, CI/CD pipelines, versioning, forced upgrade, Shorebird code push. |
|
|
57
|
+
| Accessibility | `references/accessibility.md` | Semantics, tap targets, dynamic type, contrast, a11y-driven testing. |
|
|
58
|
+
| Security | `references/security.md` | Secure storage vs SharedPreferences, no secrets in the bundle, cert pinning, deep-link/intent validation, biometrics. |
|
|
59
|
+
| Performance & Reliability | `references/performance-and-reliability.md` | Frame budget, rebuild discipline, list/image memory, isolates, retry/offline, graceful degradation. |
|
|
60
|
+
| Observability | `references/observability.md` | Crash/error reporting, structured breadcrumbs, client performance traces, PII discipline. |
|
|
61
|
+
| Documentation | `references/documentation.md` | Dartdoc on public API, naming-as-documentation, structure-as-documentation, why-comments. |
|
|
62
|
+
|
|
63
|
+
## Task Routing
|
|
64
|
+
|
|
65
|
+
- **New feature/screen** → Load `references/architecture.md`. One View + one ViewModel under `ui/<feature>/`; repository access only through the view model.
|
|
66
|
+
- **State or data-flow work** → Load `references/state-management.md`. Verify what is app state (provider) vs ephemeral (`setState`).
|
|
67
|
+
- **UI/visual work** → Load `references/widgets-and-composition.md` and `references/theming-and-design-tokens.md`. Check the generated palette before adding any colour.
|
|
68
|
+
- **API/contract work** → Load `references/data-and-contracts.md`. The client is the seam; repositories translate payloads to domain models.
|
|
69
|
+
- **Routing/deep-link work** → Load `references/navigation.md`. Check the existing route table conventions first.
|
|
70
|
+
- **Test work** → Load `references/testing.md`. Pick the cheapest tier that can carry the assertion.
|
|
71
|
+
- **Native capability work** → Load `references/platform-channels.md`. Check pub.dev for a maintained plugin before writing native code.
|
|
72
|
+
- **Release/store work** → Load `references/releases-and-distribution.md`. Signing material never enters the repo.
|
|
73
|
+
- **Security / secure-storage work** → Load `references/security.md`. The client is hostile territory; secrets and trust live server-side.
|
|
74
|
+
- **Performance or offline/resilience work** → Load `references/performance-and-reliability.md`. SLOs and load shedding live in the core, not the client.
|
|
75
|
+
|
|
76
|
+
## Safety Gates
|
|
77
|
+
|
|
78
|
+
- Do not put business logic in widgets or `build` methods — it belongs in the view model, or more likely in the capability core.
|
|
79
|
+
- Do not introduce hardcoded colours, text styles, radii, or spacing. The theme module is generated from brand tokens.
|
|
80
|
+
- Do not add state-management or DI packages (`provider`, `get_it`, GetX, Bloc) without a recorded decision; Riverpod is the standing default.
|
|
81
|
+
- Do not re-implement a rule the core's contract proves, and do not hand-map a large promoted contract — generated clients exist for that.
|
|
82
|
+
- Do not build on experimental Riverpod APIs (offline persistence) in load-bearing paths.
|
|
83
|
+
- Run `flutter analyze` and `flutter test` where the SDK is available; report the tier as skipped (never silently green) where it is not.
|
|
84
|
+
|
|
85
|
+
## Hallucination Controls
|
|
86
|
+
|
|
87
|
+
Before presenting Flutter guidance as factual:
|
|
88
|
+
|
|
89
|
+
- Check `pubspec.yaml` for actual package versions and available dependencies.
|
|
90
|
+
- Check the existing `ui/`, `data/`, and `domain/` directories for naming conventions and patterns before proposing new ones.
|
|
91
|
+
- Check the generated theme module for colour and shape values before recommending visual changes.
|
|
92
|
+
- Check the route table in the router module before inventing paths or navigation flows.
|
|
93
|
+
- Label any recommendation based on general Flutter knowledge (rather than project-specific patterns) as an inference.
|
|
94
|
+
|
|
95
|
+
## Output Expectations
|
|
96
|
+
|
|
97
|
+
- Feature changes name the layer each file belongs to and why.
|
|
98
|
+
- UI changes reference the theme roles or extensions used, or justify an explicit deviation.
|
|
99
|
+
- New features include accessibility considerations (semantic labels, tap targets, dynamic type behaviour).
|
|
100
|
+
- Verification steps include the specific Nx targets or `flutter` commands to run, with the skipped-with-reason caveat when the SDK is absent.
|
|
101
|
+
- Recommendations distinguish project conventions from general Flutter practice.
|
|
102
|
+
|
|
103
|
+
## Antipatterns
|
|
104
|
+
|
|
105
|
+
Reject these patterns:
|
|
106
|
+
|
|
107
|
+
- **Logic in build methods** — Domain branching inside widgets instead of the view model. Build renders state.
|
|
108
|
+
- **setState as architecture** — App state held in `StatefulWidget`s and threaded through constructors. Ephemeral state only.
|
|
109
|
+
- **Hardcoded visual values** — Hex colours, raw `TextStyle`s, magic paddings that fork the design system silently.
|
|
110
|
+
- **Hand-written clients for large promoted contracts** — The contract is promoted precisely so clients can be generated from it.
|
|
111
|
+
- **Re-proving core logic on the surface** — Surface tests assert wiring and rendering; the contract suite already proved the rules.
|
|
112
|
+
- **Fat integration suites** — Emulator minutes are the most expensive test currency; widget tests carry the bulk.
|
|
113
|
+
- **Raw MethodChannels for real APIs** — Stringly-typed, runtime-failing. Pigeon exists.
|
|
114
|
+
- **Preemptive Domain layers** — Pass-through use-case classes add indirection and remove nothing.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Accessibility
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [The Baseline](#the-baseline)
|
|
5
|
+
- [Semantics](#semantics)
|
|
6
|
+
- [Tap Targets](#tap-targets)
|
|
7
|
+
- [Dynamic Type](#dynamic-type)
|
|
8
|
+
- [Contrast](#contrast)
|
|
9
|
+
- [Accessibility as the Test Seam](#accessibility-as-the-test-seam)
|
|
10
|
+
- [Review Checklist](#review-checklist)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The Baseline
|
|
15
|
+
|
|
16
|
+
Accessibility is a merge gate, not a backlog item. The baseline for every feature: semantic labels on interactive widgets, 48dp tap targets, WCAG AA contrast (inherited from the token palette), and layouts that survive large text scales. An accessibility failure blocks the slice the way a failing test does.
|
|
17
|
+
|
|
18
|
+
## Semantics
|
|
19
|
+
|
|
20
|
+
Every interactive widget exposes a meaningful semantic label — through the widget's built-in semantics (`Text`, `Tooltip`, button labels) or an explicit `Semantics` wrapper when the visual content alone is ambiguous:
|
|
21
|
+
|
|
22
|
+
```dart
|
|
23
|
+
// Icon-only button: the tooltip doubles as the semantic label.
|
|
24
|
+
IconButton(
|
|
25
|
+
icon: const Icon(Icons.refresh),
|
|
26
|
+
tooltip: 'Refresh gateway status',
|
|
27
|
+
onPressed: onRefresh,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// Composite tile whose meaning isn't the sum of its texts:
|
|
31
|
+
Semantics(
|
|
32
|
+
label: 'Order ${order.id}, ${order.statusLabel}',
|
|
33
|
+
button: true,
|
|
34
|
+
child: OrderTile(order: order),
|
|
35
|
+
)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Guidelines:
|
|
39
|
+
|
|
40
|
+
- Labels describe **meaning, not appearance** ("Refresh gateway status", not "circular arrow icon").
|
|
41
|
+
- Don't over-wrap: redundant `Semantics` around already-labelled widgets produces double announcements. Use `MergeSemantics` to combine fragments that should read as one.
|
|
42
|
+
- Purely decorative visuals get `ExcludeSemantics`.
|
|
43
|
+
- Dynamic state (loading, error) is announced — render it as text or update the label, don't communicate it by colour alone.
|
|
44
|
+
|
|
45
|
+
## Tap Targets
|
|
46
|
+
|
|
47
|
+
Interactive targets meet the **48dp minimum** in both dimensions. Material widgets enforce this by default (`materialTapTargetSize`); the rule bites with custom `GestureDetector`/`InkWell` wrappers around small visuals:
|
|
48
|
+
|
|
49
|
+
```dart
|
|
50
|
+
// Small visual, full-size target:
|
|
51
|
+
InkWell(
|
|
52
|
+
onTap: onTap,
|
|
53
|
+
child: const SizedBox(
|
|
54
|
+
width: 48,
|
|
55
|
+
height: 48,
|
|
56
|
+
child: Center(child: Icon(Icons.close, size: 20)),
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Dynamic Type
|
|
62
|
+
|
|
63
|
+
Layouts must not break at large text scales. Practical rules:
|
|
64
|
+
|
|
65
|
+
- Never set fixed heights on text-bearing containers; let text size drive layout.
|
|
66
|
+
- Test at scale: pump widget tests with `MediaQuery(textScaler: TextScaler.linear(2.0))` for layout-sensitive components, and exercise device large-text settings during manual passes.
|
|
67
|
+
- Truncation (`overflow: TextOverflow.ellipsis`) is for genuinely unbounded user content, not a fix for layouts that can't absorb scale.
|
|
68
|
+
|
|
69
|
+
## Contrast
|
|
70
|
+
|
|
71
|
+
Contrast meets WCAG AA **via the token palette** — it is enforced at the design-system layer and inherited here. The implementation duty: consume theme roles (see `references/theming-and-design-tokens.md`) so the audited pairs stay paired. Hand-mixed colours (opacity hacks, lightened variants) silently break audited contrast and are review findings on two counts.
|
|
72
|
+
|
|
73
|
+
## Accessibility as the Test Seam
|
|
74
|
+
|
|
75
|
+
Flutter's semantics tree is also the widget-test seam: tests find by `find.bySemanticsLabel` and visible text, so **inaccessible UI is untestable UI**. This makes the baseline self-enforcing — a widget you cannot address semantically in a test is a widget a screen reader cannot address either. When a test reaches for `find.byType` or a key because nothing semantic exists, treat it as the accessibility defect it is and label the widget.
|
|
76
|
+
|
|
77
|
+
```dart
|
|
78
|
+
testWidgets('refresh is reachable by semantics', (tester) async {
|
|
79
|
+
await tester.pumpWidget(harness());
|
|
80
|
+
expect(find.bySemanticsLabel('Refresh gateway status'), findsOneWidget);
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Review Checklist
|
|
85
|
+
|
|
86
|
+
- [ ] Every interactive widget has a meaningful semantic label.
|
|
87
|
+
- [ ] Icon-only buttons carry `tooltip` or `Semantics`.
|
|
88
|
+
- [ ] Custom gesture surfaces meet 48dp.
|
|
89
|
+
- [ ] No state communicated by colour alone.
|
|
90
|
+
- [ ] Layout verified (or tested) at 2.0 text scale.
|
|
91
|
+
- [ ] All colours via theme roles — no hand-mixed variants.
|
|
92
|
+
- [ ] Widget tests find by semantics, not widget types.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [The Layer Model](#the-layer-model)
|
|
5
|
+
- [File Organization](#file-organization)
|
|
6
|
+
- [Views and ViewModels](#views-and-viewmodels)
|
|
7
|
+
- [Repositories and Services](#repositories-and-services)
|
|
8
|
+
- [The Core-Access Seam](#the-core-access-seam)
|
|
9
|
+
- [Domain Models and Immutability](#domain-models-and-immutability)
|
|
10
|
+
- [When a Domain Layer Is Earned](#when-a-domain-layer-is-earned)
|
|
11
|
+
- [Placement Checklist](#placement-checklist)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## The Layer Model
|
|
16
|
+
|
|
17
|
+
This codebase follows the official Flutter architecture: a **UI layer** of MVVM features over a **data layer** of repositories and services. A Domain layer of use-cases exists only where it has earned its place. Dependency direction is strict and single-direction:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
View → ViewModel → Repository (abstract) → Service (ApiClient, platform APIs)
|
|
21
|
+
↓
|
|
22
|
+
domain models
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- A View never imports a repository, a service, or `dio`.
|
|
26
|
+
- A ViewModel never imports widgets or `BuildContext`.
|
|
27
|
+
- A repository never imports another repository — cross-repository orchestration belongs in a view model (or an earned use-case).
|
|
28
|
+
- Services are stateless and never aware of repositories.
|
|
29
|
+
|
|
30
|
+
The app is a **surface adapter** over the workspace's capability core. Business rules live behind the promoted contracts and are proven there; if you find yourself implementing a pricing rule, a permission check, or validation semantics in Dart, stop — that logic belongs in the core, and the surface renders its results.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## File Organization
|
|
35
|
+
|
|
36
|
+
`ui/` is feature-first; `data/` and `domain/` are type-first:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
lib/
|
|
40
|
+
├── main.dart # ProviderScope root — nothing else
|
|
41
|
+
├── app.dart # MaterialApp.router + theme wiring
|
|
42
|
+
├── router.dart # the go_router route table
|
|
43
|
+
├── config/app_config.dart # --dart-define configuration
|
|
44
|
+
├── ui/
|
|
45
|
+
│ ├── core/theme/ # generated palette + theme builder
|
|
46
|
+
│ └── <feature>/
|
|
47
|
+
│ ├── <feature>_view.dart
|
|
48
|
+
│ └── <feature>_view_model.dart
|
|
49
|
+
├── data/
|
|
50
|
+
│ ├── repositories/ # <entity>_repository.dart: abstract + impl
|
|
51
|
+
│ └── services/ # api_client.dart, platform service wrappers
|
|
52
|
+
└── domain/
|
|
53
|
+
└── models/ # immutable models
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Naming is the official convention and is load-bearing — predictable names are how the next agent finds the right file on the first try: `HomeView`/`HomeViewModel`, `UserRepository`/`RemoteUserRepository`, `AuthService`. Do not invent variants (`HomeScreen`, `HomeController`, `UserStore`).
|
|
57
|
+
|
|
58
|
+
For large apps, split features into local packages with Dart pub workspaces (`resolution: workspace`); Melos 7.x (configured under the `melos:` key in the root pubspec) handles scripts and versioning. Layer-first roots (`/screens`, `/widgets`, `/models`) are legacy — do not recreate them.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Views and ViewModels
|
|
63
|
+
|
|
64
|
+
Every feature is exactly one View paired with exactly one ViewModel.
|
|
65
|
+
|
|
66
|
+
**The View** is widgets only — layout, animation, conditional rendering, simple navigation calls. It watches its view model provider and dispatches commands:
|
|
67
|
+
|
|
68
|
+
```dart
|
|
69
|
+
class ProfileView extends ConsumerWidget {
|
|
70
|
+
const ProfileView({super.key});
|
|
71
|
+
|
|
72
|
+
@override
|
|
73
|
+
Widget build(BuildContext context, WidgetRef ref) {
|
|
74
|
+
final state = ref.watch(profileViewModelProvider);
|
|
75
|
+
return state.when(
|
|
76
|
+
loading: () => const CircularProgressIndicator(),
|
|
77
|
+
error: (e, _) => ErrorPanel(error: e),
|
|
78
|
+
data: (profile) => ProfileBody(
|
|
79
|
+
profile: profile,
|
|
80
|
+
onRename: (name) =>
|
|
81
|
+
ref.read(profileViewModelProvider.notifier).rename(name),
|
|
82
|
+
),
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**The ViewModel** is an `AsyncNotifier` (or `Notifier` for synchronous state) exposing an immutable state object and methods as commands:
|
|
89
|
+
|
|
90
|
+
```dart
|
|
91
|
+
class ProfileViewModel extends AsyncNotifier<ProfileState> {
|
|
92
|
+
@override
|
|
93
|
+
Future<ProfileState> build() async {
|
|
94
|
+
final user = await ref.watch(userRepositoryProvider).current();
|
|
95
|
+
return ProfileState(user: user);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Future<void> rename(String name) async {
|
|
99
|
+
state = const AsyncLoading();
|
|
100
|
+
state = await AsyncValue.guard(() async {
|
|
101
|
+
final user = await ref.read(userRepositoryProvider).rename(name);
|
|
102
|
+
return ProfileState(user: user);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Red flags: a `build` method with an `if` on a domain rule; a view model importing `material.dart`; a widget calling a repository.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Repositories and Services
|
|
113
|
+
|
|
114
|
+
**Repositories** are the source of truth. They own caching, retry, polling, and translating contract payloads into domain models. Always an abstract class plus an implementation, exposed as a provider:
|
|
115
|
+
|
|
116
|
+
```dart
|
|
117
|
+
abstract class OrderRepository {
|
|
118
|
+
Future<List<Order>> recent();
|
|
119
|
+
Stream<Order> watch(String id);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
class RemoteOrderRepository implements OrderRepository {
|
|
123
|
+
RemoteOrderRepository(this._client);
|
|
124
|
+
final ApiClient _client;
|
|
125
|
+
// translate contract DTOs → domain models here, nowhere else
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
final orderRepositoryProvider = Provider<OrderRepository>(
|
|
129
|
+
(ref) => RemoteOrderRepository(ref.watch(apiClientProvider)),
|
|
130
|
+
);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The abstract class is the test seam: an in-memory `FakeOrderRepository` serves unit and widget tests without a mocking framework.
|
|
134
|
+
|
|
135
|
+
**Services** are stateless wrappers over external interfaces — the contract client, platform APIs (via Pigeon), local storage — exposing `Future`/`Stream`. They hold no app state and know nothing about repositories or features.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## The Core-Access Seam
|
|
140
|
+
|
|
141
|
+
The typed contract client lives in `data/services/` and is consumed only by repositories:
|
|
142
|
+
|
|
143
|
+
- The client is **thin and hand-rolled while the contract surface is small**: one method per promoted-contract operation, typed models in `domain/models/`. (This is the recorded tooling stance; see `references/data-and-contracts.md`.)
|
|
144
|
+
- When the promoted `openapi.yaml` grows past a handful of operations, switch to generated clients (`openapi_generator` dart-dio) — the repositories keep their shape, so nothing above the data layer changes.
|
|
145
|
+
- **Nothing above the data layer knows the transport.** A view model cannot tell whether the core is REST or gRPC, hosted or embedded. If a view model is constructing URLs or reading `DioException`s, the seam has leaked.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Domain Models and Immutability
|
|
150
|
+
|
|
151
|
+
Domain models are immutable. Plain `const` classes suffice while models are trivial; introduce **freezed** when models carry real shape — unions, `copyWith`, exhaustive matching, JSON round-trips — because at that point its codegen earns the build_runner step:
|
|
152
|
+
|
|
153
|
+
```dart
|
|
154
|
+
@freezed
|
|
155
|
+
sealed class Order with _$Order {
|
|
156
|
+
const factory Order.draft({required String id}) = DraftOrder;
|
|
157
|
+
const factory Order.placed({required String id, required DateTime at}) = PlacedOrder;
|
|
158
|
+
factory Order.fromJson(Map<String, dynamic> json) => _$OrderFromJson(json);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Never add a mutable field to a domain model to "simplify" an update path — that is the unidirectional flow breaking.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## When a Domain Layer Is Earned
|
|
167
|
+
|
|
168
|
+
Add a use-case class only when at least one of these is true:
|
|
169
|
+
|
|
170
|
+
1. Logic **merges multiple repositories** (and would otherwise live awkwardly in one view model).
|
|
171
|
+
2. The logic is **genuinely complex** and burying it in a view model harms testability.
|
|
172
|
+
3. The logic is **reused across view models**.
|
|
173
|
+
|
|
174
|
+
A use-case that forwards a single repository call is indirection tax — delete it. Default is two layers.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Placement Checklist
|
|
179
|
+
|
|
180
|
+
Before creating a file, answer:
|
|
181
|
+
|
|
182
|
+
| The code... | It goes in |
|
|
183
|
+
|---|---|
|
|
184
|
+
| renders widgets | `ui/<feature>/<feature>_view.dart` |
|
|
185
|
+
| holds feature state / handles user events | `ui/<feature>/<feature>_view_model.dart` |
|
|
186
|
+
| decides which data is the truth (cache, retry, merge) | `data/repositories/` |
|
|
187
|
+
| talks to the network, OS, or storage | `data/services/` |
|
|
188
|
+
| is a value the app passes around | `domain/models/` |
|
|
189
|
+
| is a business rule | the capability core, not this app |
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Data and Contracts
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [The Seam](#the-seam)
|
|
5
|
+
- [The Thin Client (Current Stance)](#the-thin-client-current-stance)
|
|
6
|
+
- [When to Switch to Generated Clients](#when-to-switch-to-generated-clients)
|
|
7
|
+
- [Repositories: Translation and Truth](#repositories-translation-and-truth)
|
|
8
|
+
- [Error Mapping](#error-mapping)
|
|
9
|
+
- [Configuration](#configuration)
|
|
10
|
+
- [dio Conventions](#dio-conventions)
|
|
11
|
+
- [Anti-patterns](#anti-patterns)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## The Seam
|
|
16
|
+
|
|
17
|
+
The app reaches the capability core through exactly one seam:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
ViewModel → Repository (abstract) → ApiClient (data/services/) → gateway
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Nothing above the data layer knows the transport. A view model cannot tell whether the core is hosted or embedded, REST or gRPC. If transport details (URLs, status codes, `DioException`) appear above `data/`, the seam has leaked — fix the leak before the feature.
|
|
24
|
+
|
|
25
|
+
## The Thin Client (Current Stance)
|
|
26
|
+
|
|
27
|
+
The recorded contract-tooling stance (O8, settled 2026-06-12): while the promoted contract surface is small, the client is **hand-rolled and thin** — one method per contract operation, typed models in `domain/models/`, no codegen dependency:
|
|
28
|
+
|
|
29
|
+
```dart
|
|
30
|
+
class ApiClient {
|
|
31
|
+
ApiClient(this._dio);
|
|
32
|
+
final Dio _dio;
|
|
33
|
+
|
|
34
|
+
Future<Order> order(String id) async {
|
|
35
|
+
final res = await _dio.get<Map<String, dynamic>>('/api/v1/orders/$id');
|
|
36
|
+
return Order.fromJson(res.data ?? const {});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
Future<Order> placeOrder(PlaceOrderRequest req) async {
|
|
40
|
+
final res = await _dio.post<Map<String, dynamic>>(
|
|
41
|
+
'/api/v1/orders',
|
|
42
|
+
data: req.toJson(),
|
|
43
|
+
);
|
|
44
|
+
return Order.fromJson(res.data ?? const {});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Discipline that keeps "thin" honest:
|
|
50
|
+
|
|
51
|
+
- Every method maps 1:1 to a promoted-contract operation — the method set is the contract's operation list, nothing speculative.
|
|
52
|
+
- Request/response models live in `domain/models/` with explicit `fromJson`/`toJson` that match the contract schema field-for-field.
|
|
53
|
+
- When the contract changes, the client changes in the same slice — the promoted `openapi.yaml` is the source of truth, and drift between it and this client is a defect.
|
|
54
|
+
|
|
55
|
+
## When to Switch to Generated Clients
|
|
56
|
+
|
|
57
|
+
The thin client is the lightest path **while the surface is small**. Once the promoted `openapi.yaml` grows past a handful of operations (or starts carrying complex schemas you are hand-mapping), switch to generation: `openapi_generator`'s **dart-dio** output via build_runner, consuming the promoted spec directly.
|
|
58
|
+
|
|
59
|
+
The migration is contained by construction: repositories keep consuming a client; only the client's implementation becomes generated. Nothing above the data layer changes. Hand-mapping a large promoted contract is the defect the principles warn about — the contract is promoted precisely so clients can be generated from it.
|
|
60
|
+
|
|
61
|
+
## Repositories: Translation and Truth
|
|
62
|
+
|
|
63
|
+
Repositories own the boundary between contract types and domain models:
|
|
64
|
+
|
|
65
|
+
```dart
|
|
66
|
+
class RemoteOrderRepository implements OrderRepository {
|
|
67
|
+
RemoteOrderRepository(this._client);
|
|
68
|
+
final ApiClient _client;
|
|
69
|
+
|
|
70
|
+
List<Order>? _cache;
|
|
71
|
+
|
|
72
|
+
@override
|
|
73
|
+
Future<List<Order>> recent({bool refresh = false}) async {
|
|
74
|
+
if (!refresh && _cache != null) return _cache!;
|
|
75
|
+
_cache = await _client.recentOrders();
|
|
76
|
+
return _cache!;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- Caching, retry policy, polling, and merge logic live here — not in view models, not in the client.
|
|
82
|
+
- Contract DTO → domain model translation happens here and nowhere else.
|
|
83
|
+
- Repositories are many-to-many with view models and never aware of each other.
|
|
84
|
+
|
|
85
|
+
## Error Mapping
|
|
86
|
+
|
|
87
|
+
The data layer converts transport failures into domain-meaningful states; `DioException` never crosses upward:
|
|
88
|
+
|
|
89
|
+
```dart
|
|
90
|
+
@override
|
|
91
|
+
Future<HealthStatus> status() async {
|
|
92
|
+
try {
|
|
93
|
+
return await _client.health();
|
|
94
|
+
} on DioException catch (e) {
|
|
95
|
+
if (e.type == DioExceptionType.connectionTimeout ||
|
|
96
|
+
e.type == DioExceptionType.connectionError) {
|
|
97
|
+
return const HealthStatus.unreachable();
|
|
98
|
+
}
|
|
99
|
+
rethrow; // programming errors still surface loudly
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Rules of thumb:
|
|
105
|
+
|
|
106
|
+
- **Expected failures** (offline, gateway down, 404 on an optional resource) become domain states the UI renders.
|
|
107
|
+
- **Contract violations** (schema mismatch, unexpected 500s) surface as errors — they indicate a defect, and the view renders the error state.
|
|
108
|
+
- Business rules about failures (retry budgets, "is this recoverable") still do not belong in views.
|
|
109
|
+
|
|
110
|
+
## Configuration
|
|
111
|
+
|
|
112
|
+
The gateway URL arrives at build time via `--dart-define`:
|
|
113
|
+
|
|
114
|
+
```dart
|
|
115
|
+
static const String apiBaseUrl = String.fromEnvironment(
|
|
116
|
+
'API_BASE_URL',
|
|
117
|
+
defaultValue: 'http://localhost:4000',
|
|
118
|
+
);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
- Android emulator → host: `http://10.0.2.2:4000`. iOS simulator → `http://localhost:4000`.
|
|
122
|
+
- No `.env` files baked into the binary; no secrets in `--dart-define` either — a mobile binary is fully inspectable, so anything secret stays server-side.
|
|
123
|
+
|
|
124
|
+
## dio Conventions
|
|
125
|
+
|
|
126
|
+
- One `Dio` instance, configured in the client provider: `baseUrl`, timeouts, `Accept: application/json`.
|
|
127
|
+
- Cross-cutting concerns (auth header injection, logging, retry) are **interceptors** on that instance — not per-call options scattered through methods.
|
|
128
|
+
- dio throws on non-2xx by default; keep that behaviour and map in repositories rather than checking status codes inline.
|
|
129
|
+
|
|
130
|
+
## Anti-patterns
|
|
131
|
+
|
|
132
|
+
- **Transport above the data layer** — a view model importing `dio` or parsing status codes.
|
|
133
|
+
- **Hand-mapping a grown contract** — switch to dart-dio generation; the seam is built for it.
|
|
134
|
+
- **Speculative client methods** — operations the promoted contract does not define.
|
|
135
|
+
- **Business rules in the surface** — validation semantics, pricing, permissions re-implemented in Dart. The core proves them; the surface renders results.
|
|
136
|
+
- **Repositories calling repositories** — orchestration belongs in a view model or an earned use-case.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Hierarchy](#hierarchy)
|
|
5
|
+
- [Dartdoc on Public API](#dartdoc-on-public-api)
|
|
6
|
+
- [Names Are the Documentation](#names-are-the-documentation)
|
|
7
|
+
- [Structure as Documentation](#structure-as-documentation)
|
|
8
|
+
- [Inline Comments](#inline-comments)
|
|
9
|
+
- [A Comment Is Often a Smell](#a-comment-is-often-a-smell)
|
|
10
|
+
- [In-Code Markers](#in-code-markers)
|
|
11
|
+
- [What NOT to Document](#what-not-to-document)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
Dart ships its documentation discipline in the toolchain: `dart doc` renders `///` comments to API pages, the formatter normalises them, and the `public_member_api_docs` lint flags missing ones on a public surface. The language — sound null safety, immutable widgets, `const` — is built so that well-shaped code carries most of its own meaning. Lean on that before reaching for prose.
|
|
16
|
+
|
|
17
|
+
## Hierarchy
|
|
18
|
+
|
|
19
|
+
Structure documents more reliably than comments. A comment is a promise no analyzer checks; when the widget tree changes, the comment silently lies. Documentation priority — the foundations principle (`docs/principles/foundations/documentation.md`) written the Flutter way:
|
|
20
|
+
|
|
21
|
+
1. **Types and null safety** — the analyzer rejects incorrect types and unhandled nulls. Zero drift risk.
|
|
22
|
+
2. **Naming** — the official View/ViewModel/Repository conventions, which are load-bearing (`references/architecture.md`). Rename before you comment.
|
|
23
|
+
3. **`const` and immutability** — an immutable model and a `const` constructor declare intent the analyzer enforces (`references/widgets-and-composition.md`).
|
|
24
|
+
4. **Test names** — a widget test named for its behaviour is executable documentation verified by CI.
|
|
25
|
+
5. **Dartdoc `///` on public API** — rendered by `dart doc`; written only when types cannot carry the contract.
|
|
26
|
+
6. **Inline "why" comments** — last resort for a genuinely non-obvious decision.
|
|
27
|
+
|
|
28
|
+
Levels 1–4 are verified by tooling. Levels 5–6 are human promises that drift. Minimise them.
|
|
29
|
+
|
|
30
|
+
## Dartdoc on Public API
|
|
31
|
+
|
|
32
|
+
A dartdoc comment uses `///`, leads with a one-sentence summary, and references other API in square brackets so `dart doc` links them:
|
|
33
|
+
|
|
34
|
+
```dart
|
|
35
|
+
/// Holds stock for an [order] until the reservation TTL expires.
|
|
36
|
+
///
|
|
37
|
+
/// Throws [OutOfStockException] when the requested quantity is unavailable.
|
|
38
|
+
Future<Reservation> reserve(Order order, int quantity);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Document the **public** surface — the exported API a consumer in another library calls. A private widget (`_Header`) is read with the build method that uses it; a doc comment there usually restates the code below.
|
|
42
|
+
|
|
43
|
+
State what the signature cannot: the exceptions a caller must catch, the lifecycle of a returned `Stream`, the units of a parameter. Do not narrate the type.
|
|
44
|
+
|
|
45
|
+
```dart
|
|
46
|
+
// BAD — restates the signature
|
|
47
|
+
/// Returns the user with the given id.
|
|
48
|
+
Future<User> getUser(String id);
|
|
49
|
+
|
|
50
|
+
// GOOD — skip it; the name + types already say this
|
|
51
|
+
Future<User> getUser(String id);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Names Are the Documentation
|
|
55
|
+
|
|
56
|
+
The cheapest documentation is the official name. The architecture conventions are not style preferences — `ProfileView`/`ProfileViewModel`, `OrderRepository`/`RemoteOrderRepository`, `AuthService` are how the next agent finds the right file on the first try (`references/architecture.md`). A `HomeController` or `UserStore` documents nothing because it matches no convention.
|
|
57
|
+
|
|
58
|
+
A small, single-purpose widget names its job in its class declaration:
|
|
59
|
+
|
|
60
|
+
```dart
|
|
61
|
+
// The name is the contract; no comment adds anything.
|
|
62
|
+
class OrderStatusBadge extends StatelessWidget {
|
|
63
|
+
const OrderStatusBadge({super.key, required this.status});
|
|
64
|
+
final OrderStatus status;
|
|
65
|
+
// ...
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Structure as Documentation
|
|
70
|
+
|
|
71
|
+
A composed widget tree documents itself when it is built from small, named, `const` pieces. A `build` method that reads as a list of well-named child widgets needs no comment to explain its layout — the composition *is* the explanation (`references/widgets-and-composition.md`).
|
|
72
|
+
|
|
73
|
+
This is why `Widget _buildHeader()` helpers are a documentation failure as much as a performance one: a method named `_buildHeader` hides a subtree behind a verb, where an extracted `_Header` widget names the thing. Extract the widget; the name replaces the comment.
|
|
74
|
+
|
|
75
|
+
Immutability documents the data flow. A `freezed` sealed union spells out every state a value can hold, exhaustively matched at the call site — prose listing "the order can be draft, placed, or cancelled" is the type, written worse (`references/architecture.md`).
|
|
76
|
+
|
|
77
|
+
## Inline Comments
|
|
78
|
+
|
|
79
|
+
Inline comments explain **why**, never **what**. The widget already says what it renders; the comment captures the reason the next reader cannot recover from the tree.
|
|
80
|
+
|
|
81
|
+
```dart
|
|
82
|
+
// LayoutBuilder, not MediaQuery: this card also renders inside a side
|
|
83
|
+
// pane and a test harness, where screen size is the wrong signal.
|
|
84
|
+
return LayoutBuilder(builder: (context, constraints) { /* ... */ });
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
A comment narrating the obvious is noise — the reader can see the `Column`.
|
|
88
|
+
|
|
89
|
+
```dart
|
|
90
|
+
// BAD — narrates the tree
|
|
91
|
+
// a column with a title and a body
|
|
92
|
+
return Column(children: [Title(), Body()]);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## A Comment Is Often a Smell
|
|
96
|
+
|
|
97
|
+
When you reach for a comment to explain *what* a block does, the widget is asking to be refactored. The comment is debt; the fix is in the code:
|
|
98
|
+
|
|
99
|
+
- A comment heading a chunk of a long `build` → extract a named widget.
|
|
100
|
+
- A comment explaining a magic number → move it to the theme/density system as a named token (`references/theming-and-design-tokens.md`).
|
|
101
|
+
- A comment decoding a boolean argument → name the parameter or introduce an enum.
|
|
102
|
+
- A comment explaining why a field is mutable → it should be immutable; the comment is covering a broken data flow.
|
|
103
|
+
|
|
104
|
+
Delete the comment and fix the structure. The refactor cannot drift; the comment can.
|
|
105
|
+
|
|
106
|
+
## In-Code Markers
|
|
107
|
+
|
|
108
|
+
```dart
|
|
109
|
+
// TODO(bob): paginate once the repository exposes a cursor. Issue #231.
|
|
110
|
+
// FIXME(carol): rebuild storm when the parent re-themes. Issue #245.
|
|
111
|
+
// HACK(dave): clamp negative durations from the platform clock until SDK fix.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Always include `(username)` and an issue reference. A marker without one will never be resolved.
|
|
115
|
+
|
|
116
|
+
## What NOT to Document
|
|
117
|
+
|
|
118
|
+
- Self-evident widgets where the class name and props tell the whole story.
|
|
119
|
+
- Private widgets (`_Header`) read in context with their parent's build method.
|
|
120
|
+
- `@override Widget build(...)` — never document an override the framework defines.
|
|
121
|
+
- Provider declarations whose name states what they expose (`orderRepositoryProvider`).
|
|
122
|
+
- Generated code (`*.g.dart`, `*.freezed.dart`) — never hand-edit comments into it.
|