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,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "<%= fileName %>",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start",
|
|
9
|
+
"lint": "next lint",
|
|
10
|
+
"postinstall": "fumadocs-mdx"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"fumadocs-core": "14.7.7",
|
|
14
|
+
"fumadocs-mdx": "11.10.1",
|
|
15
|
+
"fumadocs-ui": "14.7.7",
|
|
16
|
+
"lucide-react": "^0.460.0",
|
|
17
|
+
"mermaid": "^11.4.0",
|
|
18
|
+
"next": "15.1.8",
|
|
19
|
+
"react": "19.0.0",
|
|
20
|
+
"react-dom": "19.0.0",
|
|
21
|
+
"zod": "^3.23.8"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "22.9.1",
|
|
25
|
+
"@types/react": "^19.0.0",
|
|
26
|
+
"@types/react-dom": "^19.0.0",
|
|
27
|
+
"autoprefixer": "^10.4.20",
|
|
28
|
+
"postcss": "^8.4.49",
|
|
29
|
+
"tailwindcss": "^3.4.15",
|
|
30
|
+
"typescript": "5.6.3"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# pnpm 10+ gates dependency build scripts by default and exits non-zero
|
|
2
|
+
# (ERR_PNPM_IGNORED_BUILDS) when it skips them — which also makes `pnpm dev` and
|
|
3
|
+
# `pnpm build` fail their pre-run dependency check. The skipped scripts here are
|
|
4
|
+
# first-party Next.js build deps (esbuild, sharp) whose native binaries this app
|
|
5
|
+
# legitimately wants, so allow dependency builds to run — the same behaviour npm
|
|
6
|
+
# and yarn give by default. (These settings moved out of .npmrc in pnpm 10.)
|
|
7
|
+
dangerouslyAllowAllBuilds: true
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { defineDocs, defineConfig, frontmatterSchema } from 'fumadocs-mdx/config';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// GroundWork docs carry `title` + `description` frontmatter (required by the
|
|
5
|
+
// groundwork-writer skill); the site renders them as the page heading and subtitle.
|
|
6
|
+
// `title` is relaxed to optional only as a fallback: when a doc omits it, the schema
|
|
7
|
+
// derives the title from the document's first `# H1`, so the site still serves any
|
|
8
|
+
// doc (bets, hand-written pages) with a real title in the sidebar and on the page.
|
|
9
|
+
//
|
|
10
|
+
// Note: the schema function runs before remark, so we read the raw `source`. The
|
|
11
|
+
// first `# ` line is the title; a `#` inside an opening code fence is not a case
|
|
12
|
+
// GroundWork docs hit.
|
|
13
|
+
export const { docs, meta } = defineDocs({
|
|
14
|
+
// Direct compile-time access to the pristine root docs directory.
|
|
15
|
+
dir: '../../docs',
|
|
16
|
+
docs: {
|
|
17
|
+
schema: (ctx) =>
|
|
18
|
+
frontmatterSchema
|
|
19
|
+
.extend({ title: z.string().optional() })
|
|
20
|
+
.transform(
|
|
21
|
+
(data): { title: string; description?: string; icon?: string; full?: boolean } => {
|
|
22
|
+
const fm = data as {
|
|
23
|
+
title?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
icon?: string;
|
|
26
|
+
full?: boolean;
|
|
27
|
+
};
|
|
28
|
+
const match = ctx.source.match(/^\s{0,3}#\s+(.+?)\s*#*\s*$/m);
|
|
29
|
+
return {
|
|
30
|
+
title: fm.title ?? (match ? match[1].trim() : 'Untitled'),
|
|
31
|
+
description: fm.description,
|
|
32
|
+
icon: fm.icon,
|
|
33
|
+
full: fm.full,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Render fenced ```mermaid blocks CLIENT-SIDE, with zero build-time dependency on a
|
|
41
|
+
// headless browser. A small remark transform rewrites each `code` node with lang `mermaid`
|
|
42
|
+
// into a `<Mermaid chart="…" />` MDX element (resolved from the components map in the docs
|
|
43
|
+
// page); the `Mermaid` client component renders it in the browser. We deliberately avoid
|
|
44
|
+
// `rehype-mermaid` — it transitively imports `mermaid-isomorphic` → `playwright`, so merely
|
|
45
|
+
// importing it makes `next build`/codegen require Playwright even when no diagram renders at
|
|
46
|
+
// build. The content stays plain Markdown: GitHub renders the same fenced block natively,
|
|
47
|
+
// agents cold-read it, and this site renders it client-side — one source, three readers, no
|
|
48
|
+
// MDX components in the content itself.
|
|
49
|
+
function remarkMermaid() {
|
|
50
|
+
return (tree: { children?: unknown[] }) => {
|
|
51
|
+
const walk = (node: { children?: unknown[] }) => {
|
|
52
|
+
if (!node || !Array.isArray(node.children)) return;
|
|
53
|
+
node.children = node.children.map((child) => {
|
|
54
|
+
const c = child as { type?: string; lang?: string; value?: string };
|
|
55
|
+
if (c.type === 'code' && c.lang === 'mermaid') {
|
|
56
|
+
return {
|
|
57
|
+
type: 'mdxJsxFlowElement',
|
|
58
|
+
name: 'Mermaid',
|
|
59
|
+
attributes: [
|
|
60
|
+
{ type: 'mdxJsxAttribute', name: 'chart', value: c.value ?? '' },
|
|
61
|
+
],
|
|
62
|
+
children: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return child;
|
|
66
|
+
});
|
|
67
|
+
for (const child of node.children) walk(child as { children?: unknown[] });
|
|
68
|
+
};
|
|
69
|
+
walk(tree);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default defineConfig({
|
|
74
|
+
mdxOptions: {
|
|
75
|
+
remarkPlugins: (v) => [remarkMermaid, ...v],
|
|
76
|
+
},
|
|
77
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [
|
|
17
|
+
{
|
|
18
|
+
"name": "next"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
26
|
+
"exclude": ["node_modules"]
|
|
27
|
+
}
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatFiles,
|
|
3
|
+
generateFiles,
|
|
4
|
+
Tree,
|
|
5
|
+
names,
|
|
6
|
+
} from '@nx/devkit';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { recordGeneratorProvenance } from '../shared/provenance';
|
|
9
|
+
import { registerRunner, readProjectPrefix } from '../shared/scaffold-helpers';
|
|
10
|
+
import {
|
|
11
|
+
BRAND_TOKENS_PATH,
|
|
12
|
+
ResolvedVisual,
|
|
13
|
+
resolveVisual,
|
|
14
|
+
validColor,
|
|
15
|
+
} from '../shared/brand-tokens';
|
|
16
|
+
|
|
17
|
+
export interface DocsSiteGeneratorSchema {
|
|
18
|
+
name: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** "magpie-app" → "Magpie App". Used to title the docs nav from the workspace prefix. */
|
|
22
|
+
function toTitle(s: string): string {
|
|
23
|
+
return s
|
|
24
|
+
.replace(/[-_]+/g, ' ')
|
|
25
|
+
.replace(/\b\w/g, (c) => c.toUpperCase())
|
|
26
|
+
.trim();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Brand projection onto Fumadocs (F1, F2)
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
//
|
|
33
|
+
// The scaffold runs Fumadocs UI v14 with Tailwind v3 (`createPreset()` +
|
|
34
|
+
// `fumadocs-ui/style.css`). v14 themes through `--fd-*` CSS variables whose
|
|
35
|
+
// values are HSL CHANNEL TRIPLETS in whitespace form (e.g.
|
|
36
|
+
// `--fd-background: 0 0% 100%`) — Fumadocs consumes them internally as
|
|
37
|
+
// `hsl(var(--fd-...))`. So the projection must convert the brand palette
|
|
38
|
+
// (OKLCH or #rrggbb) to an `H S% L%` triplet, not emit a full colour function.
|
|
39
|
+
|
|
40
|
+
/** Parse `#rgb`/`#rgba`/`#rrggbb`/`#rrggbbaa` into 0–255 RGB (alpha dropped —
|
|
41
|
+
* Fumadocs theme channels are opaque). Returns null on anything else. */
|
|
42
|
+
function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
|
|
43
|
+
let h = hex.trim().replace(/^#/, '');
|
|
44
|
+
if (h.length === 3 || h.length === 4) {
|
|
45
|
+
h = h.split('').slice(0, 3).map((c) => c + c).join('');
|
|
46
|
+
} else if (h.length === 8) {
|
|
47
|
+
h = h.slice(0, 6);
|
|
48
|
+
} else if (h.length !== 6) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const n = parseInt(h, 16);
|
|
52
|
+
if (!Number.isFinite(n)) return null;
|
|
53
|
+
return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** OKLCH string → 0–255 sRGB. Implements the OKLab→linear-sRGB→sRGB pipeline
|
|
57
|
+
* (Björn Ottosson's reference matrices). Handles `oklch(L C H)` with L as a
|
|
58
|
+
* fraction or percentage; alpha is ignored. Returns null if it cannot parse. */
|
|
59
|
+
function oklchToRgb(value: string): { r: number; g: number; b: number } | null {
|
|
60
|
+
const m = value
|
|
61
|
+
.trim()
|
|
62
|
+
.match(/^oklch\(\s*([\d.]+%?)\s+([\d.]+)\s+([\d.]+)(?:deg)?(?:\s*\/\s*[\d.]+%?)?\s*\)$/i);
|
|
63
|
+
if (!m) return null;
|
|
64
|
+
let L = m[1].endsWith('%') ? parseFloat(m[1]) / 100 : parseFloat(m[1]);
|
|
65
|
+
const C = parseFloat(m[2]);
|
|
66
|
+
const Hdeg = parseFloat(m[3]);
|
|
67
|
+
if (![L, C, Hdeg].every(Number.isFinite)) return null;
|
|
68
|
+
const h = (Hdeg * Math.PI) / 180;
|
|
69
|
+
const a = C * Math.cos(h);
|
|
70
|
+
const bb = C * Math.sin(h);
|
|
71
|
+
|
|
72
|
+
// OKLab → LMS (cube of the l'/m'/s' terms)
|
|
73
|
+
const l_ = L + 0.3963377774 * a + 0.2158037573 * bb;
|
|
74
|
+
const m_ = L - 0.1055613458 * a - 0.0638541728 * bb;
|
|
75
|
+
const s_ = L - 0.0894841775 * a - 1.291485548 * bb;
|
|
76
|
+
const l = l_ ** 3;
|
|
77
|
+
const mm = m_ ** 3;
|
|
78
|
+
const s = s_ ** 3;
|
|
79
|
+
|
|
80
|
+
// LMS → linear sRGB
|
|
81
|
+
let lr = +4.0767416621 * l - 3.3077115913 * mm + 0.2309699292 * s;
|
|
82
|
+
let lg = -1.2684380046 * l + 2.6097574011 * mm - 0.3413193965 * s;
|
|
83
|
+
let lb = -0.0041960863 * l - 0.7034186147 * mm + 1.707614701 * s;
|
|
84
|
+
|
|
85
|
+
const toSrgb = (c: number) => {
|
|
86
|
+
const x = Math.min(Math.max(c, 0), 1);
|
|
87
|
+
return x <= 0.0031308 ? 12.92 * x : 1.055 * x ** (1 / 2.4) - 0.055;
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
r: Math.round(toSrgb(lr) * 255),
|
|
91
|
+
g: Math.round(toSrgb(lg) * 255),
|
|
92
|
+
b: Math.round(toSrgb(lb) * 255),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Any validated brand colour (hex or OKLCH) → an `H S% L%` channel triplet
|
|
97
|
+
* for a Fumadocs `--fd-*` variable. Returns null when conversion is not
|
|
98
|
+
* possible, so the caller keeps the stock Fumadocs default for that slot. */
|
|
99
|
+
function colorToHslChannels(value: string | null): string | null {
|
|
100
|
+
if (!value) return null;
|
|
101
|
+
const rgb = value.startsWith('#') ? hexToRgb(value) : oklchToRgb(value);
|
|
102
|
+
if (!rgb) return null;
|
|
103
|
+
const r = rgb.r / 255;
|
|
104
|
+
const g = rgb.g / 255;
|
|
105
|
+
const b = rgb.b / 255;
|
|
106
|
+
const max = Math.max(r, g, b);
|
|
107
|
+
const min = Math.min(r, g, b);
|
|
108
|
+
const lum = (max + min) / 2;
|
|
109
|
+
let hue = 0;
|
|
110
|
+
let sat = 0;
|
|
111
|
+
if (max !== min) {
|
|
112
|
+
const d = max - min;
|
|
113
|
+
sat = lum > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
114
|
+
switch (max) {
|
|
115
|
+
case r:
|
|
116
|
+
hue = (g - b) / d + (g < b ? 6 : 0);
|
|
117
|
+
break;
|
|
118
|
+
case g:
|
|
119
|
+
hue = (b - r) / d + 2;
|
|
120
|
+
break;
|
|
121
|
+
default:
|
|
122
|
+
hue = (r - g) / d + 4;
|
|
123
|
+
}
|
|
124
|
+
hue /= 6;
|
|
125
|
+
}
|
|
126
|
+
const H = Math.round(hue * 360);
|
|
127
|
+
const S = Math.round(sat * 100);
|
|
128
|
+
const Lp = Math.round(lum * 100);
|
|
129
|
+
return `${H} ${S}% ${Lp}%`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Resolve a palette role's light/dark to HSL channel triplets. */
|
|
133
|
+
function paletteChannels(
|
|
134
|
+
v: ResolvedVisual,
|
|
135
|
+
role: string,
|
|
136
|
+
): { light: string | null; dark: string | null } {
|
|
137
|
+
// resolveVisual maps palette roles onto shadcn slots; read them back so the
|
|
138
|
+
// docs theme tracks the same projection the app uses (one brand, one palette).
|
|
139
|
+
const SLOT: Record<string, string> = {
|
|
140
|
+
surface: 'background',
|
|
141
|
+
surfaceAlt: 'secondary',
|
|
142
|
+
textBody: 'foreground',
|
|
143
|
+
primary: 'primary',
|
|
144
|
+
border: 'border',
|
|
145
|
+
};
|
|
146
|
+
const slot = SLOT[role];
|
|
147
|
+
const ld = slot ? v.shadcn[slot] : undefined;
|
|
148
|
+
return {
|
|
149
|
+
light: colorToHslChannels(ld?.light ?? null),
|
|
150
|
+
dark: colorToHslChannels(ld?.dark ?? null),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface DocsBrandInputs {
|
|
155
|
+
v: ResolvedVisual;
|
|
156
|
+
displayFamily: string | null;
|
|
157
|
+
bodyFamily: string | null;
|
|
158
|
+
wordmark: string | null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Read the brand identity bits the docs site wires beyond the palette: the
|
|
162
|
+
* display/body font families (Google-font names) and the wordmark glyph. */
|
|
163
|
+
function readDocsBrandInputs(tree: Tree, v: ResolvedVisual): DocsBrandInputs {
|
|
164
|
+
let displayFamily: string | null = null;
|
|
165
|
+
let bodyFamily: string | null = null;
|
|
166
|
+
let wordmark: string | null = null;
|
|
167
|
+
if (tree.exists(BRAND_TOKENS_PATH)) {
|
|
168
|
+
try {
|
|
169
|
+
const raw = JSON.parse(tree.read(BRAND_TOKENS_PATH, 'utf-8') || '{}');
|
|
170
|
+
const fam = (x: unknown): string | null =>
|
|
171
|
+
typeof x === 'string' && /^[\w][\w .'-]{0,48}$/.test(x.trim()) ? x.trim() : null;
|
|
172
|
+
displayFamily = fam(raw?.visual?.typography?.display?.family);
|
|
173
|
+
bodyFamily = fam(raw?.visual?.typography?.body?.family);
|
|
174
|
+
const wm = raw?.identity?.wordmark;
|
|
175
|
+
wordmark = typeof wm === 'string' && wm.trim() && wm.trim().length <= 4 ? wm.trim() : null;
|
|
176
|
+
} catch {
|
|
177
|
+
/* fall back to nulls — stock appearance */
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return { v, displayFamily, bodyFamily, wordmark };
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Render app/brand.css for the docs site: map the resolved brand palette onto
|
|
184
|
+
* Fumadocs v14 `--fd-*` theme variables (HSL channel triplets). Only slots the
|
|
185
|
+
* palette actually drives are overridden; every other Fumadocs default is left
|
|
186
|
+
* untouched. The reading measure + h1–h4 scale (F2) ship separately in the
|
|
187
|
+
* static app/docs.css so they apply even when a slot keeps its Fumadocs default. */
|
|
188
|
+
function renderDocsBrandCss(inp: DocsBrandInputs): string {
|
|
189
|
+
const { v } = inp;
|
|
190
|
+
const out: string[] = [];
|
|
191
|
+
out.push('/* GENERATED by the GroundWork docs-site generator from');
|
|
192
|
+
out.push(' * .groundwork/config/brand-tokens.json — do not hand-edit this file.');
|
|
193
|
+
out.push(' * Re-run the design system to evolve the brand, then regenerate.');
|
|
194
|
+
out.push(' * Maps the brand palette onto Fumadocs v14 --fd-* theme variables');
|
|
195
|
+
out.push(' * (HSL channel triplets). The reading measure + scale live in docs.css.');
|
|
196
|
+
out.push(` * Projection source: ${v.source}. */`);
|
|
197
|
+
out.push('');
|
|
198
|
+
|
|
199
|
+
const surface = paletteChannels(v, 'surface');
|
|
200
|
+
const surfaceAlt = paletteChannels(v, 'surfaceAlt');
|
|
201
|
+
const text = paletteChannels(v, 'textBody');
|
|
202
|
+
const primary = paletteChannels(v, 'primary');
|
|
203
|
+
const border = paletteChannels(v, 'border');
|
|
204
|
+
|
|
205
|
+
// Which --fd-* slot each palette role drives. Foregrounds-on-colour
|
|
206
|
+
// (primary-foreground) keep the Fumadocs default for contrast safety.
|
|
207
|
+
const lightMap: [string, string | null][] = [
|
|
208
|
+
['--fd-background', surface.light],
|
|
209
|
+
['--fd-card', surface.light],
|
|
210
|
+
['--fd-popover', surface.light],
|
|
211
|
+
['--fd-secondary', surfaceAlt.light],
|
|
212
|
+
['--fd-muted', surfaceAlt.light],
|
|
213
|
+
['--fd-accent', surfaceAlt.light],
|
|
214
|
+
['--fd-foreground', text.light],
|
|
215
|
+
['--fd-card-foreground', text.light],
|
|
216
|
+
['--fd-popover-foreground', text.light],
|
|
217
|
+
['--fd-secondary-foreground', text.light],
|
|
218
|
+
['--fd-accent-foreground', text.light],
|
|
219
|
+
['--fd-primary', primary.light],
|
|
220
|
+
['--fd-ring', primary.light],
|
|
221
|
+
['--fd-border', border.light],
|
|
222
|
+
];
|
|
223
|
+
const darkMap: [string, string | null][] = [
|
|
224
|
+
['--fd-background', surface.dark],
|
|
225
|
+
['--fd-card', surface.dark],
|
|
226
|
+
['--fd-popover', surface.dark],
|
|
227
|
+
['--fd-secondary', surfaceAlt.dark],
|
|
228
|
+
['--fd-muted', surfaceAlt.dark],
|
|
229
|
+
['--fd-accent', surfaceAlt.dark],
|
|
230
|
+
['--fd-foreground', text.dark],
|
|
231
|
+
['--fd-card-foreground', text.dark],
|
|
232
|
+
['--fd-popover-foreground', text.dark],
|
|
233
|
+
['--fd-secondary-foreground', text.dark],
|
|
234
|
+
['--fd-accent-foreground', text.dark],
|
|
235
|
+
['--fd-primary', primary.dark],
|
|
236
|
+
['--fd-ring', primary.dark],
|
|
237
|
+
['--fd-border', border.dark],
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
const block = (selector: string, entries: [string, string | null][]) => {
|
|
241
|
+
const present = entries.filter(([, val]) => val);
|
|
242
|
+
if (present.length === 0) return;
|
|
243
|
+
out.push(`${selector} {`);
|
|
244
|
+
for (const [name, val] of present) out.push(` ${name}: ${val};`);
|
|
245
|
+
out.push('}');
|
|
246
|
+
out.push('');
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
block(':root', lightMap);
|
|
250
|
+
block('.dark', darkMap);
|
|
251
|
+
|
|
252
|
+
return out.join('\n');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export default async function (tree: Tree, options: DocsSiteGeneratorSchema) {
|
|
256
|
+
const serviceNames = names(options.name);
|
|
257
|
+
const projectRoot = `services/${serviceNames.fileName}`;
|
|
258
|
+
|
|
259
|
+
// The docs site is a NATIVE RUNNER, not a docker-compose service. It compiles
|
|
260
|
+
// the repo-root docs/ tree at build time (source.config.ts reads ../../docs),
|
|
261
|
+
// which only resolves when Next runs from the service directory — that path is
|
|
262
|
+
// outside any per-service Docker build context, so a containerized build can
|
|
263
|
+
// never see the docs. Running it natively (`pnpm dev`) also gives live reload
|
|
264
|
+
// as the delivery loop writes docs. Fixed local port; never joins compose.
|
|
265
|
+
const assignedPort = 4000;
|
|
266
|
+
|
|
267
|
+
const prefix = readProjectPrefix(tree);
|
|
268
|
+
const navTitle = prefix && prefix !== 'workspace' ? `${toTitle(prefix)} Docs` : 'Documentation';
|
|
269
|
+
const projectName = prefix && prefix !== 'workspace' ? toTitle(prefix) : 'Project';
|
|
270
|
+
|
|
271
|
+
// Resolve the brand projection once. `source` distinguishes a real brand
|
|
272
|
+
// (visual-block / identity-only) from the unbranded fallback (default): when
|
|
273
|
+
// there is no brand-tokens.json the docs site keeps the stock Fumadocs
|
|
274
|
+
// appearance — no brand.css is emitted and layout.tsx imports nothing extra.
|
|
275
|
+
const visual = resolveVisual(tree);
|
|
276
|
+
const brand = readDocsBrandInputs(tree, visual);
|
|
277
|
+
const branded = visual.source !== 'default';
|
|
278
|
+
|
|
279
|
+
// The brand body font, when the design system named a Google font family —
|
|
280
|
+
// it sets the whole site's type. Falls back to Inter (the stock default) when
|
|
281
|
+
// absent. (A distinct display/heading font can be wired later from the same
|
|
282
|
+
// tokens; body family is the highest-leverage single choice.)
|
|
283
|
+
const bodyFont = brand.bodyFamily ?? null;
|
|
284
|
+
|
|
285
|
+
const templateOptions = {
|
|
286
|
+
...options,
|
|
287
|
+
...serviceNames,
|
|
288
|
+
assignedPort,
|
|
289
|
+
navTitle,
|
|
290
|
+
projectName,
|
|
291
|
+
branded,
|
|
292
|
+
bodyFont,
|
|
293
|
+
wordmark: brand.wordmark ?? '',
|
|
294
|
+
tagline: `Reference documentation for ${projectName}.`,
|
|
295
|
+
tmpl: '', // required by generateFiles
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
generateFiles(
|
|
299
|
+
tree,
|
|
300
|
+
path.join(__dirname, '..', '..', '..', '..', 'src', 'generators', 'docs-site', 'files'),
|
|
301
|
+
projectRoot,
|
|
302
|
+
templateOptions
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// Nx's generateFiles treats __var__ as template substitution.
|
|
306
|
+
// Rename the dynamic catch-all route directory to Next's [[...slug]].
|
|
307
|
+
const oldDir = `${projectRoot}/app/docs/__slug__`;
|
|
308
|
+
const newDir = `${projectRoot}/app/docs/[[...slug]]`;
|
|
309
|
+
for (const child of tree.children(oldDir)) {
|
|
310
|
+
const content = tree.read(`${oldDir}/${child}`);
|
|
311
|
+
if (content) {
|
|
312
|
+
tree.write(`${newDir}/${child}`, content);
|
|
313
|
+
tree.delete(`${oldDir}/${child}`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Brand the docs site (WS-F). Project the brand palette onto Fumadocs --fd-*
|
|
318
|
+
// theme variables (app/brand.css); the reading measure + h1–h4 scale ship in
|
|
319
|
+
// the static app/docs.css. app/layout.tsx imports both. Unbranded projects
|
|
320
|
+
// (no brand-tokens.json) skip this entirely and keep today's stock Fumadocs
|
|
321
|
+
// appearance — brand.css is not written and docs.css is dropped.
|
|
322
|
+
if (branded) {
|
|
323
|
+
tree.write(`${projectRoot}/app/brand.css`, renderDocsBrandCss(brand));
|
|
324
|
+
} else {
|
|
325
|
+
// Unbranded fallback: no brand.css, and the typography sheet is dropped so
|
|
326
|
+
// the emitted tree is the stock Fumadocs starter (layout.tsx imports neither).
|
|
327
|
+
tree.delete(`${projectRoot}/app/docs.css`);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Seed the sidebar ordering as declarative Fumadocs meta.json (WS-G / E1).
|
|
331
|
+
// This lands in the project's content tree (Tier-2 content seeded into docs/),
|
|
332
|
+
// ordering the canonical doc set and collapsing the large principles tree so
|
|
333
|
+
// it no longer dominates the rail. Retires the betsFirst() JS hack. Only seed
|
|
334
|
+
// it once — never clobber a meta.json the project has since hand-tuned.
|
|
335
|
+
seedDocsMeta(tree);
|
|
336
|
+
|
|
337
|
+
// Register with `./dev` as a native runner so start/stop/status/logs manage it
|
|
338
|
+
// like any other surface (electron/flutter/cli do the same). Not autostarted —
|
|
339
|
+
// a docs site is a developer affordance, not part of the boot topology; it is
|
|
340
|
+
// launched on demand (`pnpm dev` in the service dir, or via the runner).
|
|
341
|
+
registerRunner(tree, {
|
|
342
|
+
name: serviceNames.fileName,
|
|
343
|
+
kind: 'surface',
|
|
344
|
+
cmd: 'pnpm dev',
|
|
345
|
+
cwd: projectRoot,
|
|
346
|
+
env: { PORT: String(assignedPort) },
|
|
347
|
+
autostart: false,
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
await formatFiles(tree);
|
|
351
|
+
|
|
352
|
+
recordGeneratorProvenance(tree, 'docs-site', options as unknown as Record<string, unknown>);
|
|
353
|
+
|
|
354
|
+
return () => {
|
|
355
|
+
const { execSync } = require('child_process');
|
|
356
|
+
const fs = require('fs');
|
|
357
|
+
try {
|
|
358
|
+
execSync('pnpm install', { cwd: projectRoot, stdio: 'inherit' });
|
|
359
|
+
} catch (e) {
|
|
360
|
+
// pnpm 10+ exits non-zero on ERR_PNPM_IGNORED_BUILDS — the build scripts of
|
|
361
|
+
// gated dependencies (esbuild/sharp) are skipped by default — even when the
|
|
362
|
+
// install itself succeeded. Treat a populated node_modules as success (pnpm
|
|
363
|
+
// already printed its own approve-builds notice); only warn if deps are
|
|
364
|
+
// genuinely missing, so we never report a false failure over a good install.
|
|
365
|
+
if (!fs.existsSync(path.join(projectRoot, 'node_modules'))) {
|
|
366
|
+
console.warn(`Failed to run pnpm install in ${projectRoot}. Run it manually.`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** The canonical top-level doc order for the sidebar (E1). The rail reads as a
|
|
373
|
+
* product-learning journey: the brief (what the system is) → the design system
|
|
374
|
+
* (how it looks and behaves) → the nested architecture section (how it is
|
|
375
|
+
* built) → ways of working → getting started (how to run it) → bets (delivery
|
|
376
|
+
* work). `...` keeps any doc/folder not named here in its natural position
|
|
377
|
+
* after the named set, and `principles` is pushed last and collapsed so its
|
|
378
|
+
* large tree never dominates the rail. Lands at docs/meta.json — Fumadocs
|
|
379
|
+
* sidebar config, ignored by GitHub and agents, so the docs/ tree stays
|
|
380
|
+
* effectively content-pristine. */
|
|
381
|
+
function seedDocsMeta(tree: Tree): void {
|
|
382
|
+
const metaPath = 'docs/meta.json';
|
|
383
|
+
if (tree.exists(metaPath)) return; // never clobber a project-tuned ordering
|
|
384
|
+
// Fumadocs reads `pages` as the sidebar order. Explicit names come first in
|
|
385
|
+
// the listed order; `...` expands to every remaining page/folder not named;
|
|
386
|
+
// `principles` is named LAST (after `...`) so the large principles tree sinks
|
|
387
|
+
// to the bottom of the rail instead of leading it. `architecture` and
|
|
388
|
+
// `getting-started` are folders here — their own meta.json (below) orders
|
|
389
|
+
// their children.
|
|
390
|
+
const meta = {
|
|
391
|
+
pages: [
|
|
392
|
+
'product-brief',
|
|
393
|
+
'design-system',
|
|
394
|
+
'architecture',
|
|
395
|
+
'ways-of-working',
|
|
396
|
+
'getting-started',
|
|
397
|
+
'bets',
|
|
398
|
+
'...',
|
|
399
|
+
'principles',
|
|
400
|
+
],
|
|
401
|
+
};
|
|
402
|
+
tree.write(metaPath, JSON.stringify(meta, null, 2) + '\n');
|
|
403
|
+
|
|
404
|
+
// Order the nested architecture section: the overview (index, was the flat
|
|
405
|
+
// architecture.md) first, then infrastructure → domain → services → api →
|
|
406
|
+
// decisions, with `...` catching anything else. Seeded only when the folder
|
|
407
|
+
// exists and lacks its own meta — never write a meta.json into an empty folder
|
|
408
|
+
// (Fumadocs renders a content-less folder as a broken nav node and the build
|
|
409
|
+
// trips over it), and never clobber a project's own grouping. The architecture
|
|
410
|
+
// skill seeds this when it first creates the folder, so a fresh scaffold gets
|
|
411
|
+
// the order; this backfills it on regeneration over an older project.
|
|
412
|
+
const architectureMeta = 'docs/architecture/meta.json';
|
|
413
|
+
if (tree.exists('docs/architecture') && !tree.exists(architectureMeta)) {
|
|
414
|
+
tree.write(
|
|
415
|
+
architectureMeta,
|
|
416
|
+
JSON.stringify(
|
|
417
|
+
{
|
|
418
|
+
pages: [
|
|
419
|
+
'index',
|
|
420
|
+
'infrastructure',
|
|
421
|
+
'domain',
|
|
422
|
+
'services',
|
|
423
|
+
'api',
|
|
424
|
+
'decisions',
|
|
425
|
+
'...',
|
|
426
|
+
],
|
|
427
|
+
},
|
|
428
|
+
null,
|
|
429
|
+
2,
|
|
430
|
+
) + '\n',
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Order the getting-started on-ramp: the overview (index) first, then the
|
|
435
|
+
// setup walkthrough and the ./dev command reference. Same folder-must-exist
|
|
436
|
+
// guard as architecture above.
|
|
437
|
+
const gettingStartedMeta = 'docs/getting-started/meta.json';
|
|
438
|
+
if (tree.exists('docs/getting-started') && !tree.exists(gettingStartedMeta)) {
|
|
439
|
+
tree.write(
|
|
440
|
+
gettingStartedMeta,
|
|
441
|
+
JSON.stringify(
|
|
442
|
+
{ pages: ['index', 'setup', 'dev-cli-reference', '...'] },
|
|
443
|
+
null,
|
|
444
|
+
2,
|
|
445
|
+
) + '\n',
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Order the principles subtree last + collapsed via its own meta.json. Seeded
|
|
450
|
+
// only if absent so a project's own grouping is preserved.
|
|
451
|
+
const principlesMeta = 'docs/principles/meta.json';
|
|
452
|
+
if (!tree.exists(principlesMeta) && tree.exists('docs/principles')) {
|
|
453
|
+
tree.write(
|
|
454
|
+
principlesMeta,
|
|
455
|
+
JSON.stringify({ defaultOpen: false, pages: ['...'] }, null, 2) + '\n',
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Within the Bets section, sink the `_archive` folder (delivered bets) to the
|
|
460
|
+
// bottom of the rail so active, in-flight bets read first. `...` expands to
|
|
461
|
+
// every active bet (sorted), then `_archive` is named LAST. The archive folder
|
|
462
|
+
// itself is COLLAPSED via its own docs/bets/_archive/meta.json (defaultOpen:
|
|
463
|
+
// false), written by the dev CLI's `archive` command at delivery time — not
|
|
464
|
+
// here. (Fumadocs has no leading-underscore hide convention, so `_archive`
|
|
465
|
+
// stays visible-but-closed, which is the desired collapse.) The scaffold seeds
|
|
466
|
+
// no docs/bets/ (bets are authored during the lifecycle), so this is normally a
|
|
467
|
+
// no-op at scaffold time; guarded by tree.exists so it only lands when the bets
|
|
468
|
+
// tree is present, and never clobbers a project-tuned ordering.
|
|
469
|
+
const betsMeta = 'docs/bets/meta.json';
|
|
470
|
+
if (!tree.exists(betsMeta) && tree.exists('docs/bets')) {
|
|
471
|
+
tree.write(
|
|
472
|
+
betsMeta,
|
|
473
|
+
JSON.stringify({ pages: ['...', '_archive'] }, null, 2) + '\n',
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"id": "DocsSiteGenerator",
|
|
4
|
+
"title": "Docs Site Generator",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The name of the service (e.g. docs)",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "argv",
|
|
12
|
+
"index": 0
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"required": ["name"]
|
|
17
|
+
}
|