groundwork-method 0.0.1 → 0.10.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 +781 -0
- package/LICENSE +21 -0
- package/README.md +44 -29
- package/bin/groundwork.js +1654 -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 +125 -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 +68 -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 +82 -0
- package/src/docs/principles/index.md +23 -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 +118 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -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 +107 -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 +14 -0
- package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +108 -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/navigation.md +122 -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/state-management.md +166 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +135 -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 +15 -0
- package/src/engineer-skills/groundwork-go-engineer/SKILL.md +171 -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/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 +139 -0
- package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +11 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +107 -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/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/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 +433 -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 +278 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +9 -0
- package/src/engineer-skills/groundwork-python-engineer/SKILL.md +196 -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/testing.md +177 -0
- package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +13 -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 +47 -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 +68 -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 +74 -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 +30 -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 +152 -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 +281 -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/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 +227 -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 +142 -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 +129 -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/slice-worker.md +191 -0
- package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
- package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +126 -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 +35 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +35 -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 +198 -0
- package/src/hidden-skills/groundwork-bet/workflows/02-design.md +168 -0
- package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +246 -0
- package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +193 -0
- package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +199 -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 +54 -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 +46 -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,324 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Philosophy: Structure Over Comments](#philosophy-structure-over-comments)
|
|
5
|
+
- [Types and Zod as Documentation](#types-and-zod-as-documentation)
|
|
6
|
+
- [What to Document](#what-to-document)
|
|
7
|
+
- [What NOT to Document](#what-not-to-document)
|
|
8
|
+
- [Component Documentation](#component-documentation)
|
|
9
|
+
- [Server and Client Boundary Notes](#server-and-client-boundary-notes)
|
|
10
|
+
- [Hook Documentation](#hook-documentation)
|
|
11
|
+
- [Inline Comments](#inline-comments)
|
|
12
|
+
- [In-Code Markers](#in-code-markers)
|
|
13
|
+
- [Service README Template](#service-readme-template)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Philosophy: Structure Over Comments
|
|
18
|
+
|
|
19
|
+
Comments are promises that no compiler can verify. When code changes, TypeScript catches type errors and Vitest catches behavioral regressions — but stale TSDoc comments silently mislead. In a codebase where AI agents drive significant code velocity, comment drift is not hypothetical; it is the default outcome.
|
|
20
|
+
|
|
21
|
+
**The hierarchy for TypeScript/React documentation:**
|
|
22
|
+
1. **TypeScript types and interfaces** — the compiler rejects incorrect types (zero drift risk)
|
|
23
|
+
2. **Zod `.describe()`** — part of the code; flows into validation errors and runtime behavior
|
|
24
|
+
3. **Naming** — descriptive component/function/variable names (refactor > comment)
|
|
25
|
+
4. **Test names** — executable documentation verified by CI
|
|
26
|
+
5. **TSDoc on complex public APIs** — only when types genuinely cannot convey the intent
|
|
27
|
+
6. **Inline "why" comments** — last resort for genuinely non-obvious decisions
|
|
28
|
+
|
|
29
|
+
Everything at levels 1-4 is verified by tooling. Levels 5-6 are human promises with drift risk. Minimize them ruthlessly.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Types and Zod as Documentation
|
|
34
|
+
|
|
35
|
+
In the Next.js application codebase, **TypeScript types and Zod schemas are the primary documentation layer.** They are the single source of truth for data structures — verified by the compiler and used by the runtime.
|
|
36
|
+
|
|
37
|
+
### TypeScript Interfaces as Documentation
|
|
38
|
+
|
|
39
|
+
Well-typed interfaces make most prop/parameter documentation redundant:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
// The interface IS the documentation — no TSDoc needed
|
|
43
|
+
interface MeetingCardProps {
|
|
44
|
+
meeting: Meeting;
|
|
45
|
+
onSelect?: (meetingId: string) => void;
|
|
46
|
+
variant?: "standard" | "elevated" | "inset";
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The types `Meeting`, `string`, and the union type `"standard" | "elevated" | "inset"` communicate everything a consumer needs to know. Adding comments like `/** The meeting to display */` is noise.
|
|
51
|
+
|
|
52
|
+
### Zod `.describe()` as Documentation
|
|
53
|
+
|
|
54
|
+
Zod `.describe()` is structural documentation that flows into validation errors and can be extracted by tooling. It cannot drift because it IS the code:
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
export const meetingSchema = z.object({
|
|
58
|
+
id: z.string().uuid(),
|
|
59
|
+
title: z.string().min(1).max(200).describe("Human-readable meeting title"),
|
|
60
|
+
status: z.enum(["draft", "scheduled", "active", "completed"]),
|
|
61
|
+
scheduledAt: z.string().datetime().nullable(),
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Rule:** Use `.describe()` only when the field name and type constraints don't tell the full story. `id: z.string().uuid()` is already self-documenting — `.describe("Meeting ID")` is pure noise.
|
|
66
|
+
|
|
67
|
+
### When Types Are Enough
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
// NO TSDoc needed — the types tell the complete story
|
|
71
|
+
function getMeeting(id: string): Promise<Meeting | null>
|
|
72
|
+
function deleteMeeting(id: string): Promise<void>
|
|
73
|
+
function listMeetings(filter?: MeetingFilter): Promise<Meeting[]>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## What to Document
|
|
79
|
+
|
|
80
|
+
| What | How | Why |
|
|
81
|
+
|------|-----|-----|
|
|
82
|
+
| **Complex exported function** | TSDoc only if the signature doesn't convey the contract | Edge cases, error conditions, non-obvious behavior |
|
|
83
|
+
| **Non-obvious props** | Comment on the interface property (not the component) | When the name + type isn't sufficient |
|
|
84
|
+
| **Hook caching/revalidation** | TSDoc on the hook | Cannot be inferred from the return type |
|
|
85
|
+
| **`"use client"` rationale** | Brief comment above the directive when it's non-obvious | Explains the architectural boundary decision |
|
|
86
|
+
| **Side effects** | Note in TSDoc if invisible in the signature | Mutations, cache invalidation, analytics |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## What NOT to Document
|
|
91
|
+
|
|
92
|
+
**Self-documenting components:**
|
|
93
|
+
```tsx
|
|
94
|
+
// BAD — the name + props type says everything
|
|
95
|
+
/** MeetingCard displays a card for a meeting */
|
|
96
|
+
export function MeetingCard({ meeting }: MeetingCardProps) {
|
|
97
|
+
|
|
98
|
+
// GOOD — skip it; the name IS the documentation
|
|
99
|
+
export function MeetingCard({ meeting }: MeetingCardProps) {
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Obvious props:**
|
|
103
|
+
```tsx
|
|
104
|
+
// BAD — noise
|
|
105
|
+
interface DialogProps {
|
|
106
|
+
/** Whether the dialog is open */
|
|
107
|
+
open: boolean;
|
|
108
|
+
/** Called when the dialog open state changes */
|
|
109
|
+
onOpenChange: (open: boolean) => void;
|
|
110
|
+
/** The dialog title */
|
|
111
|
+
title: string;
|
|
112
|
+
/** The dialog content */
|
|
113
|
+
children: React.ReactNode;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// GOOD — the names + types are the documentation
|
|
117
|
+
interface DialogProps {
|
|
118
|
+
open: boolean;
|
|
119
|
+
onOpenChange: (open: boolean) => void;
|
|
120
|
+
title: string;
|
|
121
|
+
children: React.ReactNode;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Comment only non-obvious props:**
|
|
126
|
+
```tsx
|
|
127
|
+
interface MeetingCardProps {
|
|
128
|
+
meeting: Meeting;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Memoize with `useCallback` to prevent re-renders
|
|
132
|
+
* inside virtualized lists.
|
|
133
|
+
*/
|
|
134
|
+
onSelect?: (meetingId: string) => void;
|
|
135
|
+
|
|
136
|
+
variant?: "standard" | "elevated" | "inset";
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Here, `onSelect` has a non-obvious performance implication. The other props need no comments.
|
|
141
|
+
|
|
142
|
+
**Thin page components:**
|
|
143
|
+
```tsx
|
|
144
|
+
// SKIP — the delegation IS the documentation
|
|
145
|
+
export default async function MeetingsPage() {
|
|
146
|
+
const meetings = await listMeetings();
|
|
147
|
+
return <MeetingList meetings={meetings} />;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**shadcn/ui primitives** — generated code, never add comments.
|
|
152
|
+
|
|
153
|
+
**Zod fields where the name + constraints are clear:**
|
|
154
|
+
```tsx
|
|
155
|
+
// BAD — .describe() adds nothing
|
|
156
|
+
status: z.enum(["draft", "scheduled", "active", "completed"]).describe("Meeting status")
|
|
157
|
+
|
|
158
|
+
// GOOD — skip .describe() when it would just restate the field name
|
|
159
|
+
status: z.enum(["draft", "scheduled", "active", "completed"])
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Tailwind utility classes** — the class names are the documentation.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Component Documentation
|
|
167
|
+
|
|
168
|
+
TSDoc on components is justified **only** when the component has non-obvious behavior that types cannot convey:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
/**
|
|
172
|
+
* Inline meeting editor with optimistic updates.
|
|
173
|
+
*
|
|
174
|
+
* Submits via Server Action and optimistically updates the SWR cache.
|
|
175
|
+
* Rolls back automatically on server error.
|
|
176
|
+
*/
|
|
177
|
+
"use client";
|
|
178
|
+
|
|
179
|
+
export function MeetingEditor({ meeting }: MeetingEditorProps) {
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The optimistic update + rollback behavior is invisible in the props — it justifies documentation. A simple `MeetingCard` that just renders data does not.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Server and Client Boundary Notes
|
|
187
|
+
|
|
188
|
+
The default is React Server Component — no documentation needed. Document the boundary **only** when using `"use client"` and the rationale is non-obvious:
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
/**
|
|
192
|
+
* Client Component: requires useState for search input tracking
|
|
193
|
+
* and useTransition for non-blocking updates.
|
|
194
|
+
*/
|
|
195
|
+
"use client";
|
|
196
|
+
|
|
197
|
+
export function MeetingSearch({ initialResults }: MeetingSearchProps) {
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Skip** when `"use client"` is obviously needed (event handlers, form state):
|
|
201
|
+
```tsx
|
|
202
|
+
// No boundary comment needed — "use client" is obviously required
|
|
203
|
+
// for onClick handlers and useState
|
|
204
|
+
"use client";
|
|
205
|
+
|
|
206
|
+
export function MeetingForm({ onSubmit }: MeetingFormProps) {
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Hook Documentation
|
|
212
|
+
|
|
213
|
+
Custom hooks are the one area where TSDoc is frequently justified — the caching and revalidation behavior cannot be inferred from the return type:
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
/**
|
|
217
|
+
* Fetches a meeting by ID with SWR caching.
|
|
218
|
+
* Revalidates on focus and reconnect.
|
|
219
|
+
* Seed with SWRConfig fallback to avoid loading flash.
|
|
220
|
+
*/
|
|
221
|
+
export function useMeeting(meetingId: string) {
|
|
222
|
+
return useSWR<Meeting>(`/api/meetings/${meetingId}`, fetcher);
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Skip** for trivial hooks:
|
|
227
|
+
```tsx
|
|
228
|
+
// No TSDoc needed — the name + signature are clear
|
|
229
|
+
export function useTheme() {
|
|
230
|
+
return useContext(ThemeContext);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Inline Comments
|
|
237
|
+
|
|
238
|
+
Inline comments within components or functions explain **why**, never **what**:
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
export function MeetingList({ meetings }: MeetingListProps) {
|
|
242
|
+
// Sort descending — server returns chronological, dashboard needs reverse.
|
|
243
|
+
const sorted = useMemo(
|
|
244
|
+
() => [...meetings].sort((a, b) =>
|
|
245
|
+
new Date(b.scheduledAt).getTime() - new Date(a.scheduledAt).getTime()
|
|
246
|
+
),
|
|
247
|
+
[meetings]
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
// Fragment avoids extra div that breaks parent CSS grid layout.
|
|
252
|
+
<>
|
|
253
|
+
{sorted.map((meeting) => (
|
|
254
|
+
<MeetingCard key={meeting.id} meeting={meeting} />
|
|
255
|
+
))}
|
|
256
|
+
</>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## In-Code Markers
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
// TODO(bob): Add virtual scrolling for lists > 100 items. Issue #234.
|
|
267
|
+
|
|
268
|
+
// FIXME(carol): Race between optimistic update and SWR revalidation
|
|
269
|
+
// causes flicker. Needs mutate() with rollback.
|
|
270
|
+
|
|
271
|
+
// HACK(dave): Workaround for Next.js 16 searchParams Suspense
|
|
272
|
+
// requirement. Remove when framework provides a built-in solution.
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Always include `(username)` and issue reference.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Service README Template
|
|
280
|
+
|
|
281
|
+
The app lives inside the workspace monorepo, so its README is a lean orientation page — purpose, how to run it, configuration — not a standalone open-source front door. No clone instructions, badges, or license stanza.
|
|
282
|
+
|
|
283
|
+
```markdown
|
|
284
|
+
# [App Name]
|
|
285
|
+
|
|
286
|
+
One-sentence description of what this frontend does.
|
|
287
|
+
|
|
288
|
+
## Architecture
|
|
289
|
+
|
|
290
|
+
\```
|
|
291
|
+
Pages (app/)
|
|
292
|
+
└── Features (components/<domain>/)
|
|
293
|
+
└── UI Primitives (components/ui/)
|
|
294
|
+
└── Hooks (hooks/)
|
|
295
|
+
└── API Client (lib/api.ts)
|
|
296
|
+
└── Schemas (lib/schemas/)
|
|
297
|
+
\```
|
|
298
|
+
|
|
299
|
+
## Quick Start
|
|
300
|
+
|
|
301
|
+
\```bash
|
|
302
|
+
cp .env.example .env.local
|
|
303
|
+
./dev start
|
|
304
|
+
\```
|
|
305
|
+
|
|
306
|
+
App: `http://localhost:3000`
|
|
307
|
+
|
|
308
|
+
## Configuration
|
|
309
|
+
|
|
310
|
+
| Variable | Default | Description |
|
|
311
|
+
|----------|---------|-------------|
|
|
312
|
+
| `NEXT_PUBLIC_API_URL` | `http://localhost:8080` | Backend API |
|
|
313
|
+
| `NEXT_PUBLIC_APP_ENV` | `development` | Environment |
|
|
314
|
+
|
|
315
|
+
## Testing
|
|
316
|
+
|
|
317
|
+
\```bash
|
|
318
|
+
./dev test
|
|
319
|
+
\```
|
|
320
|
+
|
|
321
|
+
## Further Reading
|
|
322
|
+
|
|
323
|
+
Durable architecture and policy live in `docs/` — this README covers only how to run the app.
|
|
324
|
+
```
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# Error Boundaries
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [Error Hierarchy](#error-hierarchy)
|
|
5
|
+
- [error.tsx](#errortsx)
|
|
6
|
+
- [global-error.tsx](#global-errortsx)
|
|
7
|
+
- [not-found.tsx](#not-foundtsx)
|
|
8
|
+
- [Auth Errors](#auth-errors)
|
|
9
|
+
- [Navigation API Gotcha](#navigation-api-gotcha)
|
|
10
|
+
- [Redirects](#redirects)
|
|
11
|
+
- [Hydration Errors](#hydration-errors)
|
|
12
|
+
- [Post-Response Work with after()](#post-response-work-with-after)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Error Hierarchy
|
|
17
|
+
|
|
18
|
+
Errors bubble up from the component that throws to the nearest error boundary. Place `error.tsx` at different levels to control the granularity of error recovery.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
app/
|
|
22
|
+
├── error.tsx # Catches errors from all children
|
|
23
|
+
├── global-error.tsx # Catches errors in root layout
|
|
24
|
+
├── meetings/
|
|
25
|
+
│ ├── error.tsx # Catches errors in /meetings/*
|
|
26
|
+
│ └── [id]/
|
|
27
|
+
│ ├── error.tsx # Catches errors in /meetings/[id]
|
|
28
|
+
│ └── page.tsx
|
|
29
|
+
└── layout.tsx # Errors here go to global-error.tsx
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
An `error.tsx` boundary does **not** catch errors thrown in the `layout.tsx` of the same segment — those bubble up to the parent segment's error boundary or `global-error.tsx`.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## error.tsx
|
|
37
|
+
|
|
38
|
+
Catches runtime errors in a route segment and its children. Provides a `reset` function to retry rendering.
|
|
39
|
+
|
|
40
|
+
`error.tsx` **must** be a Client Component.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
// app/meetings/error.tsx
|
|
44
|
+
'use client';
|
|
45
|
+
|
|
46
|
+
export default function MeetingsError({
|
|
47
|
+
error,
|
|
48
|
+
reset,
|
|
49
|
+
}: {
|
|
50
|
+
error: Error & { digest?: string };
|
|
51
|
+
reset: () => void;
|
|
52
|
+
}) {
|
|
53
|
+
return (
|
|
54
|
+
<div className="surface-glass p-6 text-center" role="alert">
|
|
55
|
+
<h2 className="text-destructive">Something went wrong</h2>
|
|
56
|
+
<p className="text-muted-foreground mt-2">
|
|
57
|
+
Failed to load meetings. This has been logged.
|
|
58
|
+
</p>
|
|
59
|
+
<button
|
|
60
|
+
onClick={reset}
|
|
61
|
+
className="mt-4 px-4 py-2 bg-primary rounded"
|
|
62
|
+
>
|
|
63
|
+
Try again
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Important
|
|
71
|
+
|
|
72
|
+
- The `digest` property is a hash of the error that was thrown on the server. Use it for log correlation — never display it to users.
|
|
73
|
+
- Sensitive error details (stack traces, internal messages) are stripped before reaching the client. Only generic messages should be shown to users.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## global-error.tsx
|
|
78
|
+
|
|
79
|
+
Catches errors thrown in the **root layout**. Because the root layout is replaced entirely when this renders, `global-error.tsx` must include its own `<html>` and `<body>` tags.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
// app/global-error.tsx
|
|
83
|
+
'use client';
|
|
84
|
+
|
|
85
|
+
export default function GlobalError({
|
|
86
|
+
error,
|
|
87
|
+
reset,
|
|
88
|
+
}: {
|
|
89
|
+
error: Error & { digest?: string };
|
|
90
|
+
reset: () => void;
|
|
91
|
+
}) {
|
|
92
|
+
return (
|
|
93
|
+
<html>
|
|
94
|
+
<body>
|
|
95
|
+
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
96
|
+
<h2>Something went wrong</h2>
|
|
97
|
+
<p>An unexpected error occurred. Please try refreshing the page.</p>
|
|
98
|
+
<button onClick={reset}>Try again</button>
|
|
99
|
+
</div>
|
|
100
|
+
</body>
|
|
101
|
+
</html>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Note: `global-error.tsx` cannot use the app's CSS imports or layout — it replaces the entire document. Keep it self-contained with inline styles.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## not-found.tsx
|
|
111
|
+
|
|
112
|
+
Custom 404 UI for a route segment. Place at any level to customise the 404 experience for that section of the app.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
// app/meetings/not-found.tsx
|
|
116
|
+
import Link from 'next/link';
|
|
117
|
+
|
|
118
|
+
export default function MeetingNotFound() {
|
|
119
|
+
return (
|
|
120
|
+
<div className="surface-glass p-8 text-center">
|
|
121
|
+
<h2 className="text-xl font-semibold">Meeting not found</h2>
|
|
122
|
+
<p className="text-muted-foreground mt-2">
|
|
123
|
+
This meeting may have been deleted or the link is incorrect.
|
|
124
|
+
</p>
|
|
125
|
+
<Link href="/meetings" className="mt-4 text-primary inline-block">
|
|
126
|
+
Back to meetings
|
|
127
|
+
</Link>
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Triggering Not Found
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { notFound } from 'next/navigation';
|
|
137
|
+
|
|
138
|
+
export default async function MeetingPage({ params }: Props) {
|
|
139
|
+
const { id } = await params;
|
|
140
|
+
const meeting = await getMeeting(id);
|
|
141
|
+
|
|
142
|
+
if (!meeting) {
|
|
143
|
+
notFound(); // Renders closest not-found.tsx
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return <MeetingDetail meeting={meeting} />;
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Auth Errors
|
|
153
|
+
|
|
154
|
+
Trigger specific auth-related error pages:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import { forbidden, unauthorized } from 'next/navigation';
|
|
158
|
+
|
|
159
|
+
export default async function AdminPage() {
|
|
160
|
+
const session = await getSession();
|
|
161
|
+
|
|
162
|
+
if (!session) {
|
|
163
|
+
unauthorized(); // Renders unauthorized.tsx (401)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!session.hasAdminAccess) {
|
|
167
|
+
forbidden(); // Renders forbidden.tsx (403)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return <AdminDashboard />;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Create corresponding error pages:
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
// app/forbidden.tsx
|
|
178
|
+
export default function Forbidden() {
|
|
179
|
+
return (
|
|
180
|
+
<div className="surface-glass p-8 text-center">
|
|
181
|
+
<h2>Access Denied</h2>
|
|
182
|
+
<p className="text-muted-foreground">
|
|
183
|
+
You don't have permission to view this resource.
|
|
184
|
+
</p>
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// app/unauthorized.tsx
|
|
190
|
+
export default function Unauthorized() {
|
|
191
|
+
return (
|
|
192
|
+
<div className="surface-glass p-8 text-center">
|
|
193
|
+
<h2>Sign In Required</h2>
|
|
194
|
+
<p className="text-muted-foreground">
|
|
195
|
+
Please sign in to access this page.
|
|
196
|
+
</p>
|
|
197
|
+
</div>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Navigation API Gotcha
|
|
205
|
+
|
|
206
|
+
`redirect()`, `notFound()`, `forbidden()`, and `unauthorized()` work by throwing special internal errors. If you wrap them in a try-catch, the catch block intercepts the navigation error and the navigation silently fails.
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
// ❌ Bad — try-catch catches the navigation "error"
|
|
210
|
+
'use server';
|
|
211
|
+
|
|
212
|
+
async function createMeeting(formData: FormData) {
|
|
213
|
+
try {
|
|
214
|
+
const meeting = await db.meeting.create({ ... });
|
|
215
|
+
redirect(`/meetings/${meeting.id}`); // This throws!
|
|
216
|
+
} catch (error) {
|
|
217
|
+
// redirect() throw is caught here — navigation fails silently!
|
|
218
|
+
return { error: 'Failed to create meeting' };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Fix 1: Call Navigation Outside try-catch
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
// ✅ Good — navigation API outside the try-catch
|
|
227
|
+
async function createMeeting(formData: FormData) {
|
|
228
|
+
let meeting;
|
|
229
|
+
try {
|
|
230
|
+
meeting = await db.meeting.create({ ... });
|
|
231
|
+
} catch (error) {
|
|
232
|
+
return { error: 'Failed to create meeting' };
|
|
233
|
+
}
|
|
234
|
+
redirect(`/meetings/${meeting.id}`); // Outside try-catch
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Fix 2: Re-throw with unstable_rethrow
|
|
239
|
+
|
|
240
|
+
When the navigation must be inside the try-catch:
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import { unstable_rethrow } from 'next/navigation';
|
|
244
|
+
|
|
245
|
+
async function createMeeting(formData: FormData) {
|
|
246
|
+
try {
|
|
247
|
+
const meeting = await db.meeting.create({ ... });
|
|
248
|
+
redirect(`/meetings/${meeting.id}`);
|
|
249
|
+
} catch (error) {
|
|
250
|
+
unstable_rethrow(error); // Re-throws Next.js internal errors
|
|
251
|
+
return { error: 'Failed to create meeting' };
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Affected Functions
|
|
257
|
+
|
|
258
|
+
All of these throw internal errors — never wrap them in try-catch without `unstable_rethrow`:
|
|
259
|
+
- `redirect()` — 307 temporary redirect
|
|
260
|
+
- `permanentRedirect()` — 308 permanent redirect
|
|
261
|
+
- `notFound()` — 404
|
|
262
|
+
- `forbidden()` — 403
|
|
263
|
+
- `unauthorized()` — 401
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Redirects
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
import { redirect, permanentRedirect } from 'next/navigation';
|
|
271
|
+
|
|
272
|
+
// 307 Temporary — use for most cases (auth redirects, feature gates)
|
|
273
|
+
redirect('/new-path');
|
|
274
|
+
|
|
275
|
+
// 308 Permanent — use for URL migrations (browsers cache this)
|
|
276
|
+
permanentRedirect('/new-url');
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Use `redirect()` for dynamic routing decisions (auth, feature flags). Use `permanentRedirect()` only when the old URL is permanently retired and should be cached by browsers and search engines.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Hydration Errors
|
|
284
|
+
|
|
285
|
+
Hydration errors occur when the server-rendered HTML doesn't match the client-rendered HTML. React detects the mismatch and throws an error.
|
|
286
|
+
|
|
287
|
+
### Error Signs
|
|
288
|
+
|
|
289
|
+
- "Hydration failed because the initial UI does not match"
|
|
290
|
+
- "Text content does not match server-rendered HTML"
|
|
291
|
+
|
|
292
|
+
### Common Causes and Fixes
|
|
293
|
+
|
|
294
|
+
#### Browser APIs
|
|
295
|
+
|
|
296
|
+
```tsx
|
|
297
|
+
// ❌ Bad — window doesn't exist on server
|
|
298
|
+
<div>{window.innerWidth}</div>
|
|
299
|
+
|
|
300
|
+
// ✅ Good — render on client only after mount
|
|
301
|
+
'use client';
|
|
302
|
+
import { useState, useEffect } from 'react';
|
|
303
|
+
|
|
304
|
+
export function WindowWidth() {
|
|
305
|
+
const [width, setWidth] = useState<number>();
|
|
306
|
+
useEffect(() => setWidth(window.innerWidth), []);
|
|
307
|
+
return <div>{width ?? 'Loading…'}</div>;
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
#### Date/Time Rendering
|
|
312
|
+
|
|
313
|
+
Server and client may be in different timezones:
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
// ❌ Bad — different timezone on server vs client
|
|
317
|
+
<span>{new Date().toLocaleString()}</span>
|
|
318
|
+
|
|
319
|
+
// ✅ Good — render on client only
|
|
320
|
+
'use client';
|
|
321
|
+
const [time, setTime] = useState<string>();
|
|
322
|
+
useEffect(() => setTime(new Date().toLocaleString()), []);
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Random Values and IDs
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
// ❌ Bad — Math.random differs between server and client
|
|
329
|
+
<div id={Math.random().toString()}>
|
|
330
|
+
|
|
331
|
+
// ✅ Good — useId generates stable IDs across server/client
|
|
332
|
+
import { useId } from 'react';
|
|
333
|
+
|
|
334
|
+
function Input() {
|
|
335
|
+
const id = useId();
|
|
336
|
+
return <input id={id} />;
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### Invalid HTML Nesting
|
|
341
|
+
|
|
342
|
+
```tsx
|
|
343
|
+
// ❌ Bad — <div> inside <p> is invalid HTML
|
|
344
|
+
<p><div>Content</div></p>
|
|
345
|
+
|
|
346
|
+
// ❌ Bad — <p> inside <p> is invalid HTML
|
|
347
|
+
<p><p>Nested</p></p>
|
|
348
|
+
|
|
349
|
+
// ✅ Good — valid nesting
|
|
350
|
+
<div><p>Content</p></div>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Debugging Hydration Errors
|
|
354
|
+
|
|
355
|
+
In development, click the hydration error overlay to see a diff of server vs client HTML. This pinpoints the exact element that mismatched.
|
|
356
|
+
|
|
357
|
+
#### Third-Party Scripts
|
|
358
|
+
|
|
359
|
+
Browser extensions and third-party scripts can inject DOM elements that don't exist in the server-rendered HTML, causing hydration mismatches. If you see hydration errors that disappear in Incognito Mode, a browser extension is the likely cause. Use `next/script` with `strategy="afterInteractive"` instead of raw `<script>` tags to avoid this.
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Post-Response Work with after()
|
|
364
|
+
|
|
365
|
+
`after()` runs code after the response finishes streaming. Use it for logging, analytics, or cleanup that shouldn't delay the response.
|
|
366
|
+
|
|
367
|
+
```tsx
|
|
368
|
+
import { after } from 'next/server';
|
|
369
|
+
|
|
370
|
+
export async function POST(request: Request) {
|
|
371
|
+
const data = await processRequest(request);
|
|
372
|
+
|
|
373
|
+
after(async () => {
|
|
374
|
+
// This runs after the response is sent
|
|
375
|
+
await logAnalytics(data);
|
|
376
|
+
await sendNotification(data);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
return Response.json({ success: true });
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
`after()` does not block the response. The client receives the response immediately while the deferred work runs in the background.
|