groundwork-method 0.0.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +823 -0
- package/LICENSE +21 -0
- package/README.md +44 -29
- package/bin/groundwork.js +1723 -0
- package/dist/src/generators/add-capability/generator.d.ts +8 -0
- package/dist/src/generators/add-capability/generator.js +60 -0
- package/dist/src/generators/add-capability/generator.js.map +1 -0
- package/dist/src/generators/cli-app/generator.d.ts +9 -0
- package/dist/src/generators/cli-app/generator.js +140 -0
- package/dist/src/generators/cli-app/generator.js.map +1 -0
- package/dist/src/generators/docs-site/generator.d.ts +5 -0
- package/dist/src/generators/docs-site/generator.js +441 -0
- package/dist/src/generators/docs-site/generator.js.map +1 -0
- package/dist/src/generators/electron-app/generator.d.ts +6 -0
- package/dist/src/generators/electron-app/generator.js +261 -0
- package/dist/src/generators/electron-app/generator.js.map +1 -0
- package/dist/src/generators/flutter-app/generator.d.ts +6 -0
- package/dist/src/generators/flutter-app/generator.js +314 -0
- package/dist/src/generators/flutter-app/generator.js.map +1 -0
- package/dist/src/generators/go-microservice/generator.d.ts +8 -0
- package/dist/src/generators/go-microservice/generator.js +232 -0
- package/dist/src/generators/go-microservice/generator.js.map +1 -0
- package/dist/src/generators/nextjs-app/generator.d.ts +8 -0
- package/dist/src/generators/nextjs-app/generator.js +294 -0
- package/dist/src/generators/nextjs-app/generator.js.map +1 -0
- package/dist/src/generators/python-microservice/generator.d.ts +13 -0
- package/dist/src/generators/python-microservice/generator.js +265 -0
- package/dist/src/generators/python-microservice/generator.js.map +1 -0
- package/dist/src/generators/shared/brand-tokens.d.ts +89 -0
- package/dist/src/generators/shared/brand-tokens.js +308 -0
- package/dist/src/generators/shared/brand-tokens.js.map +1 -0
- package/dist/src/generators/shared/capabilities.d.ts +101 -0
- package/dist/src/generators/shared/capabilities.js +279 -0
- package/dist/src/generators/shared/capabilities.js.map +1 -0
- package/dist/src/generators/shared/provenance.d.ts +2 -0
- package/dist/src/generators/shared/provenance.js +85 -0
- package/dist/src/generators/shared/provenance.js.map +1 -0
- package/dist/src/generators/shared/scaffold-helpers.d.ts +72 -0
- package/dist/src/generators/shared/scaffold-helpers.js +309 -0
- package/dist/src/generators/shared/scaffold-helpers.js.map +1 -0
- package/dist/src/generators/system-test-runner/generator.d.ts +23 -0
- package/dist/src/generators/system-test-runner/generator.js +173 -0
- package/dist/src/generators/system-test-runner/generator.js.map +1 -0
- package/dist/src/generators/workspace-dev-cli/generator.d.ts +7 -0
- package/dist/src/generators/workspace-dev-cli/generator.js +138 -0
- package/dist/src/generators/workspace-dev-cli/generator.js.map +1 -0
- package/generators.json +57 -0
- package/lib/repo-map/grammars/tree-sitter-c.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-cpp.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-csharp.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-dart.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-go.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-java.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-javascript.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-kotlin.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-lua.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-php.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-python.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-ruby.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-rust.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-scala.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-swift.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-tsx.wasm +0 -0
- package/lib/repo-map/grammars/tree-sitter-typescript.wasm +0 -0
- package/lib/repo-map/index.js +386 -0
- package/lib/repo-map/languages.js +514 -0
- package/lib/repo-map/pagerank.js +59 -0
- package/migrations/README.md +60 -0
- package/migrations/_template/cli-migration.js +27 -0
- package/migrations/gw-bet-prose-redesign.js +105 -0
- package/migrations/gw-drop-test-manifest.js +37 -0
- package/migrations/gw-register-serena-mcp.js +42 -0
- package/migrations/gw-relocate-hidden-skills.js +40 -0
- package/migrations/gw-seed-config-toml.js +24 -0
- package/migrations/index.json +40 -0
- package/package.json +70 -6
- package/src/AGENTS.md +36 -0
- package/src/config/config.toml +30 -0
- package/src/config/groundwork-state.json +5 -0
- package/src/docs/llms.txt +72 -0
- package/src/docs/principles/ai-native/agent-native-systems.md +90 -0
- package/src/docs/principles/ai-native/agentic-systems.md +78 -0
- package/src/docs/principles/ai-native/ai-engineering.md +100 -0
- package/src/docs/principles/ai-native/ai-native-product.md +76 -0
- package/src/docs/principles/delivery/cost-engineering.md +89 -0
- package/src/docs/principles/delivery/day-2-operational-baseline.md +57 -0
- package/src/docs/principles/delivery/devex.md +88 -0
- package/src/docs/principles/delivery/platform.md +101 -0
- package/src/docs/principles/delivery/progressive-delivery.md +92 -0
- package/src/docs/principles/design/ai-native-design.md +73 -0
- package/src/docs/principles/design/design-foundations.md +80 -0
- package/src/docs/principles/design/design-systems-and-tokens.md +72 -0
- package/src/docs/principles/design/interaction-and-motion.md +69 -0
- package/src/docs/principles/design/layout-and-space.md +72 -0
- package/src/docs/principles/design/usability-and-ux.md +79 -0
- package/src/docs/principles/design/visual-design.md +84 -0
- package/src/docs/principles/foundations/code-craft.md +86 -0
- package/src/docs/principles/foundations/continuous-discovery.md +75 -0
- package/src/docs/principles/foundations/documentation.md +102 -0
- package/src/docs/principles/foundations/prioritization-and-appetite.md +78 -0
- package/src/docs/principles/foundations/product-engineering.md +90 -0
- package/src/docs/principles/foundations/product-risks.md +89 -0
- package/src/docs/principles/foundations/requirements-and-specs.md +80 -0
- package/src/docs/principles/foundations/success-metrics.md +66 -0
- package/src/docs/principles/foundations/testing.md +108 -0
- package/src/docs/principles/index.md +24 -0
- package/src/docs/principles/quality/accessibility.md +88 -0
- package/src/docs/principles/quality/observability.md +84 -0
- package/src/docs/principles/quality/performance.md +84 -0
- package/src/docs/principles/quality/privacy.md +92 -0
- package/src/docs/principles/quality/reliability.md +89 -0
- package/src/docs/principles/quality/security.md +78 -0
- package/src/docs/principles/stack/postgres.md +100 -0
- package/src/docs/principles/system-design/api-design.md +86 -0
- package/src/docs/principles/system-design/architecture-decisions.md +81 -0
- package/src/docs/principles/system-design/code-structure.md +104 -0
- package/src/docs/principles/system-design/data-engineering.md +87 -0
- package/src/docs/principles/system-design/durable-execution.md +89 -0
- package/src/docs/principles/system-design/evolutionary-architecture.md +81 -0
- package/src/docs/principles/system-design/identity-and-access.md +76 -0
- package/src/docs/principles/system-design/integration-patterns.md +84 -0
- package/src/docs/principles/system-design/real-time.md +83 -0
- package/src/docs/principles/system-design/surface-architecture.md +74 -0
- package/src/docs/ways-of-working/documentation.md +69 -0
- package/src/docs/ways-of-working/how-we-work.md +76 -0
- package/src/docs/ways-of-working/units-of-work.md +40 -0
- package/src/engineer-skills/groundwork-electron-engineer/SKILL.md +123 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/documentation.md +126 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/performance-and-reliability.md +80 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/process-model.md +94 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/security.md +107 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +129 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/theming-and-tokens.md +74 -0
- package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +22 -0
- package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +114 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/accessibility.md +92 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/architecture.md +189 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/data-and-contracts.md +136 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/documentation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/navigation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/performance-and-reliability.md +100 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/platform-channels.md +93 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/releases-and-distribution.md +84 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/security.md +96 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/state-management.md +166 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +160 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/theming-and-design-tokens.md +109 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/widgets-and-composition.md +123 -0
- package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +24 -0
- package/src/engineer-skills/groundwork-go-engineer/SKILL.md +174 -0
- package/src/engineer-skills/groundwork-go-engineer/references/api-design.md +82 -0
- package/src/engineer-skills/groundwork-go-engineer/references/architecture.md +42 -0
- package/src/engineer-skills/groundwork-go-engineer/references/capability-ports.md +50 -0
- package/src/engineer-skills/groundwork-go-engineer/references/code-craft-security.md +34 -0
- package/src/engineer-skills/groundwork-go-engineer/references/concurrency.md +108 -0
- package/src/engineer-skills/groundwork-go-engineer/references/documentation.md +130 -0
- package/src/engineer-skills/groundwork-go-engineer/references/go-services.md +77 -0
- package/src/engineer-skills/groundwork-go-engineer/references/http-handlers.md +172 -0
- package/src/engineer-skills/groundwork-go-engineer/references/implementation-patterns.md +156 -0
- package/src/engineer-skills/groundwork-go-engineer/references/integration-realtime-data.md +57 -0
- package/src/engineer-skills/groundwork-go-engineer/references/observability.md +49 -0
- package/src/engineer-skills/groundwork-go-engineer/references/postgres.md +41 -0
- package/src/engineer-skills/groundwork-go-engineer/references/reliability-performance.md +105 -0
- package/src/engineer-skills/groundwork-go-engineer/references/testing.md +201 -0
- package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +20 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +112 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/accessibility.md +111 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/architecture.md +323 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/data-fetching.md +458 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/documentation.md +324 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/error-boundaries.md +383 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/mutations-and-forms.md +396 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/observability.md +48 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/performance-and-deployment.md +947 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/routing-and-navigation.md +405 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/security.md +131 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/server-components.md +394 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/tailwind-and-styling.md +134 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +491 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/type-system.md +368 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +230 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +16 -0
- package/src/engineer-skills/groundwork-python-engineer/SKILL.md +199 -0
- package/src/engineer-skills/groundwork-python-engineer/references/api-standards.md +88 -0
- package/src/engineer-skills/groundwork-python-engineer/references/architecture.md +57 -0
- package/src/engineer-skills/groundwork-python-engineer/references/async-patterns.md +103 -0
- package/src/engineer-skills/groundwork-python-engineer/references/capability-ports.md +44 -0
- package/src/engineer-skills/groundwork-python-engineer/references/database.md +88 -0
- package/src/engineer-skills/groundwork-python-engineer/references/documentation-mcp.md +167 -0
- package/src/engineer-skills/groundwork-python-engineer/references/implementation-patterns.md +166 -0
- package/src/engineer-skills/groundwork-python-engineer/references/ml-pipelines.md +119 -0
- package/src/engineer-skills/groundwork-python-engineer/references/ml-systems-ai-engineering.md +74 -0
- package/src/engineer-skills/groundwork-python-engineer/references/observability.md +57 -0
- package/src/engineer-skills/groundwork-python-engineer/references/resilience.md +126 -0
- package/src/engineer-skills/groundwork-python-engineer/references/security.md +148 -0
- package/src/engineer-skills/groundwork-python-engineer/references/testing.md +216 -0
- package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +20 -0
- package/src/generators/add-capability/generator.ts +70 -0
- package/src/generators/add-capability/schema.json +30 -0
- package/src/generators/capabilities/llm/capability.json +28 -0
- package/src/generators/capabilities/llm/providers/anthropic/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/anthropic/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/anthropic/stacks/python/src/__packageName__/adapters/llm.py.template +61 -0
- package/src/generators/capabilities/llm/providers/local/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/local/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/local/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/localai/footprint.json +29 -0
- package/src/generators/capabilities/llm/providers/localai/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/localai/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/none/footprint.json +9 -0
- package/src/generators/capabilities/llm/providers/none/stacks/go/internal/llm/llm.go.template +35 -0
- package/src/generators/capabilities/llm/providers/none/stacks/python/src/__packageName__/adapters/llm.py.template +25 -0
- package/src/generators/capabilities/llm/providers/ollama/footprint.json +20 -0
- package/src/generators/capabilities/llm/providers/ollama/stacks/go/internal/llm/llm.go.template +102 -0
- package/src/generators/capabilities/llm/providers/ollama/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
- package/src/generators/capabilities/llm/providers/openai/footprint.json +13 -0
- package/src/generators/capabilities/llm/providers/openai/stacks/go/internal/llm/llm.go.template +98 -0
- package/src/generators/capabilities/llm/providers/openai/stacks/python/src/__packageName__/adapters/llm.py.template +60 -0
- package/src/generators/capabilities/llm/stacks/go/internal/core/service/llm.go.template +12 -0
- package/src/generators/capabilities/llm/stacks/go/internal/llm/llm_test.go.template +33 -0
- package/src/generators/capabilities/llm/stacks/python/src/__packageName__/core/llm.py.template +15 -0
- package/src/generators/capabilities/llm/stacks/python/tests/contracts/test_llm.py.template +37 -0
- package/src/generators/cli-app/files/README.md.template +76 -0
- package/src/generators/cli-app/files/build.mjs.template +15 -0
- package/src/generators/cli-app/files/package.json.template +21 -0
- package/src/generators/cli-app/files/src/cli.ts.template +67 -0
- package/src/generators/cli-app/files/src/commands/hello.ts.template +17 -0
- package/src/generators/cli-app/files/src/commands/status.ts.template +23 -0
- package/src/generators/cli-app/files/src/core/client.test.ts.template +80 -0
- package/src/generators/cli-app/files/src/core/client.ts.template +64 -0
- package/src/generators/cli-app/files/src/registry.test.ts.template +35 -0
- package/src/generators/cli-app/files/src/registry.ts.template +31 -0
- package/src/generators/cli-app/files/tsconfig.json.template +16 -0
- package/src/generators/cli-app/files/tsconfig.test.json.template +11 -0
- package/src/generators/cli-app/generator.ts +138 -0
- package/src/generators/cli-app/schema.json +24 -0
- package/src/generators/docs-site/files/.gitignore.ejs +40 -0
- package/src/generators/docs-site/files/app/docs/__slug__/page.tsx +101 -0
- package/src/generators/docs-site/files/app/docs/layout.tsx +14 -0
- package/src/generators/docs-site/files/app/docs.css +43 -0
- package/src/generators/docs-site/files/app/layout.tsx +24 -0
- package/src/generators/docs-site/files/app/page.tsx +135 -0
- package/src/generators/docs-site/files/app/source.ts +8 -0
- package/src/generators/docs-site/files/components/mermaid.tsx +67 -0
- package/src/generators/docs-site/files/next.config.mjs +10 -0
- package/src/generators/docs-site/files/package.json +32 -0
- package/src/generators/docs-site/files/pnpm-workspace.yaml +7 -0
- package/src/generators/docs-site/files/postcss.config.mjs +6 -0
- package/src/generators/docs-site/files/source.config.ts +77 -0
- package/src/generators/docs-site/files/tailwind.config.js +10 -0
- package/src/generators/docs-site/files/tsconfig.json +27 -0
- package/src/generators/docs-site/generator.ts +476 -0
- package/src/generators/docs-site/schema.json +17 -0
- package/src/generators/electron-app/docs/principles/stack/electron/index.md +49 -0
- package/src/generators/electron-app/docs/principles/stack/electron/ipc-contracts.md +71 -0
- package/src/generators/electron-app/docs/principles/stack/electron/packaging-and-updates.md +59 -0
- package/src/generators/electron-app/docs/principles/stack/electron/process-model.md +53 -0
- package/src/generators/electron-app/docs/principles/stack/electron/security.md +70 -0
- package/src/generators/electron-app/docs/principles/stack/typescript/frontend.md +65 -0
- package/src/generators/electron-app/files/.gitignore.template +20 -0
- package/src/generators/electron-app/files/README.md.template +125 -0
- package/src/generators/electron-app/files/electron.vite.config.ts +31 -0
- package/src/generators/electron-app/files/eslint.config.mjs +92 -0
- package/src/generators/electron-app/files/forge.config.ts.template +44 -0
- package/src/generators/electron-app/files/package.json.template +54 -0
- package/src/generators/electron-app/files/playwright.config.ts +18 -0
- package/src/generators/electron-app/files/project.json.template +65 -0
- package/src/generators/electron-app/files/src/main/core-client.test.ts +81 -0
- package/src/generators/electron-app/files/src/main/core-client.ts +55 -0
- package/src/generators/electron-app/files/src/main/index.ts +157 -0
- package/src/generators/electron-app/files/src/main/ipc.ts +52 -0
- package/src/generators/electron-app/files/src/main/policy.test.ts +71 -0
- package/src/generators/electron-app/files/src/main/policy.ts +73 -0
- package/src/generators/electron-app/files/src/preload/index.ts +23 -0
- package/src/generators/electron-app/files/src/renderer/index.html.template +20 -0
- package/src/generators/electron-app/files/src/renderer/src/App.test.tsx +61 -0
- package/src/generators/electron-app/files/src/renderer/src/App.tsx.template +43 -0
- package/src/generators/electron-app/files/src/renderer/src/assets/main.css +40 -0
- package/src/generators/electron-app/files/src/renderer/src/env.d.ts +14 -0
- package/src/generators/electron-app/files/src/renderer/src/main.tsx +25 -0
- package/src/generators/electron-app/files/src/shared/ipc.ts +54 -0
- package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +133 -0
- package/src/generators/electron-app/files/tool/electron_exec.sh.template +83 -0
- package/src/generators/electron-app/files/tsconfig.json +7 -0
- package/src/generators/electron-app/files/tsconfig.node.json +27 -0
- package/src/generators/electron-app/files/tsconfig.web.json +22 -0
- package/src/generators/electron-app/files/vitest.config.ts +32 -0
- package/src/generators/electron-app/files/vitest.setup.ts +1 -0
- package/src/generators/electron-app/generator.ts +288 -0
- package/src/generators/electron-app/schema.json +23 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/architecture.md +78 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/index.md +38 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/platform-channels.md +51 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/releases-and-distribution.md +59 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/state-management.md +85 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +86 -0
- package/src/generators/flutter-app/docs/principles/stack/flutter/widgets-and-composition.md +69 -0
- package/src/generators/flutter-app/files/.gitignore.template +30 -0
- package/src/generators/flutter-app/files/README.md.template +100 -0
- package/src/generators/flutter-app/files/analysis_options.yaml.template +18 -0
- package/src/generators/flutter-app/files/integration_test/app_test.dart.template +64 -0
- package/src/generators/flutter-app/files/lib/app.dart.template +24 -0
- package/src/generators/flutter-app/files/lib/config/app_config.dart +15 -0
- package/src/generators/flutter-app/files/lib/data/repositories/status_repository.dart +36 -0
- package/src/generators/flutter-app/files/lib/data/services/api_client.dart +71 -0
- package/src/generators/flutter-app/files/lib/domain/models/health_status.dart +23 -0
- package/src/generators/flutter-app/files/lib/main.dart +11 -0
- package/src/generators/flutter-app/files/lib/router.dart +23 -0
- package/src/generators/flutter-app/files/lib/ui/core/theme/app_theme.dart +110 -0
- package/src/generators/flutter-app/files/lib/ui/home/home_view.dart +89 -0
- package/src/generators/flutter-app/files/lib/ui/home/home_view_model.dart.template +38 -0
- package/src/generators/flutter-app/files/project.json.template +51 -0
- package/src/generators/flutter-app/files/pubspec.yaml.template +47 -0
- package/src/generators/flutter-app/files/test/api_client_test.dart.template +63 -0
- package/src/generators/flutter-app/files/test/fakes/fake_status_repository.dart.template +19 -0
- package/src/generators/flutter-app/files/test/home_view_test.dart.template +58 -0
- package/src/generators/flutter-app/files/tool/flutter_exec.sh.template +60 -0
- package/src/generators/flutter-app/generator.ts +362 -0
- package/src/generators/flutter-app/schema.json +23 -0
- package/src/generators/go-microservice/docs/principles/stack/go/concurrency.md +123 -0
- package/src/generators/go-microservice/docs/principles/stack/go/index.md +70 -0
- package/src/generators/go-microservice/docs/principles/stack/go/testing.md +168 -0
- package/src/generators/go-microservice/files/.air.toml.template +38 -0
- package/src/generators/go-microservice/files/.env.template +4 -0
- package/src/generators/go-microservice/files/.golangci.yml.template +82 -0
- package/src/generators/go-microservice/files/Dockerfile.dev.template +12 -0
- package/src/generators/go-microservice/files/asyncapi-pubsub.yaml.template +33 -0
- package/src/generators/go-microservice/files/asyncapi-ws.yaml.template +34 -0
- package/src/generators/go-microservice/files/cmd/api/main.go.template +149 -0
- package/src/generators/go-microservice/files/cmd/api/main_test.go.template +99 -0
- package/src/generators/go-microservice/files/cmd/worker/cleanup/main.go.template +39 -0
- package/src/generators/go-microservice/files/db/schema.sql.template +24 -0
- package/src/generators/go-microservice/files/go.mod.template +39 -0
- package/src/generators/go-microservice/files/internal/config/config.go.template +52 -0
- package/src/generators/go-microservice/files/internal/config/otel.go.template +93 -0
- package/src/generators/go-microservice/files/internal/core/domain/errors.go.template +16 -0
- package/src/generators/go-microservice/files/internal/core/domain/model.go.template +28 -0
- package/src/generators/go-microservice/files/internal/core/domain/user.go.template +13 -0
- package/src/generators/go-microservice/files/internal/core/pagination.go.template +16 -0
- package/src/generators/go-microservice/files/internal/core/service/app_service.go.template +79 -0
- package/src/generators/go-microservice/files/internal/core/service/event_hub.go.template +9 -0
- package/src/generators/go-microservice/files/internal/core/service/message_queue.go.template +10 -0
- package/src/generators/go-microservice/files/internal/core/service/outbox_repository.go.template +31 -0
- package/src/generators/go-microservice/files/internal/core/service/repository.go.template +23 -0
- package/src/generators/go-microservice/files/internal/core/service/user_repository.go.template +15 -0
- package/src/generators/go-microservice/files/internal/core/service/user_service.go.template +43 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/app_handler.go.template +108 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/auth_middleware_test.go.template +52 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook.go.template +202 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook_test.go.template +82 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/health_handler.go.template +80 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware.go.template +87 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware_test.go.template +76 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/repository.go.template +37 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_auth.go.template +40 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_loadshed.go.template +38 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_logging.go.template +40 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_ratelimit.go.template +48 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_test.go.template +81 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/router.go.template +105 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/types.go.template +70 -0
- package/src/generators/go-microservice/files/internal/entrypoints/api/websocket_handler.go.template +39 -0
- package/src/generators/go-microservice/files/internal/httpclient/http_client.go.template +87 -0
- package/src/generators/go-microservice/files/internal/kafka/kafka.go.template +34 -0
- package/src/generators/go-microservice/files/internal/postgres/postgres.go.template +195 -0
- package/src/generators/go-microservice/files/internal/postgres/postgres_test.go.template +156 -0
- package/src/generators/go-microservice/files/internal/postgres/user_repository.go.template +56 -0
- package/src/generators/go-microservice/files/internal/pubsub/gcp_pubsub.go.template +35 -0
- package/src/generators/go-microservice/files/internal/websocket/client.go.template +151 -0
- package/src/generators/go-microservice/files/internal/websocket/hub.go.template +261 -0
- package/src/generators/go-microservice/files/scripts/apply-schema.sh.template +21 -0
- package/src/generators/go-microservice/files/tools/tools.go.template +10 -0
- package/src/generators/go-microservice/generator.ts +240 -0
- package/src/generators/go-microservice/schema.json +63 -0
- package/src/generators/nextjs-app/docs/principles/stack/typescript/frontend.md +65 -0
- package/src/generators/nextjs-app/files/.dockerignore.template +7 -0
- package/src/generators/nextjs-app/files/.env.example.template +24 -0
- package/src/generators/nextjs-app/files/.gitignore.template +5 -0
- package/src/generators/nextjs-app/files/Dockerfile +53 -0
- package/src/generators/nextjs-app/files/app/(auth)/sign-in/__sign-in__/page.tsx.template +9 -0
- package/src/generators/nextjs-app/files/app/(auth)/sign-up/__sign-up__/page.tsx.template +9 -0
- package/src/generators/nextjs-app/files/app/api/config/route.ts.template +39 -0
- package/src/generators/nextjs-app/files/app/api/healthz/route.test.ts +15 -0
- package/src/generators/nextjs-app/files/app/api/healthz/route.ts +5 -0
- package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.test.ts.template +55 -0
- package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.ts.template +126 -0
- package/src/generators/nextjs-app/files/app/error.tsx +39 -0
- package/src/generators/nextjs-app/files/app/global-error.tsx +68 -0
- package/src/generators/nextjs-app/files/app/globals.css +105 -0
- package/src/generators/nextjs-app/files/app/layout.tsx +59 -0
- package/src/generators/nextjs-app/files/app/loading.tsx +13 -0
- package/src/generators/nextjs-app/files/app/not-found.tsx +30 -0
- package/src/generators/nextjs-app/files/app/page.tsx +20 -0
- package/src/generators/nextjs-app/files/components/providers/default.tsx +19 -0
- package/src/generators/nextjs-app/files/components/providers/production.tsx +32 -0
- package/src/generators/nextjs-app/files/components/providers/telemetry.tsx +76 -0
- package/src/generators/nextjs-app/files/components/render-smoke.test.tsx +29 -0
- package/src/generators/nextjs-app/files/components/theme-provider.tsx +11 -0
- package/src/generators/nextjs-app/files/components.json +21 -0
- package/src/generators/nextjs-app/files/eslint.config.mjs +120 -0
- package/src/generators/nextjs-app/files/hooks/use-toast.ts +7 -0
- package/src/generators/nextjs-app/files/instrumentation.ts +90 -0
- package/src/generators/nextjs-app/files/lib/api/fetcher.ts.template +130 -0
- package/src/generators/nextjs-app/files/lib/config.ts +21 -0
- package/src/generators/nextjs-app/files/lib/logger.ts +29 -0
- package/src/generators/nextjs-app/files/lib/schemas/index.ts +19 -0
- package/src/generators/nextjs-app/files/lib/utils.ts +6 -0
- package/src/generators/nextjs-app/files/next.config.mjs +9 -0
- package/src/generators/nextjs-app/files/package.json +70 -0
- package/src/generators/nextjs-app/files/postcss.config.mjs +8 -0
- package/src/generators/nextjs-app/files/proxy.test.ts.template +30 -0
- package/src/generators/nextjs-app/files/proxy.ts +31 -0
- package/src/generators/nextjs-app/files/public/.gitkeep +1 -0
- package/src/generators/nextjs-app/files/tsconfig.json +42 -0
- package/src/generators/nextjs-app/files/vitest.config.mts +15 -0
- package/src/generators/nextjs-app/files/vitest.setup.ts +7 -0
- package/src/generators/nextjs-app/generator.ts +307 -0
- package/src/generators/nextjs-app/schema.json +44 -0
- package/src/generators/python-microservice/docs/principles/stack/python/async.md +168 -0
- package/src/generators/python-microservice/docs/principles/stack/python/documentation.md +240 -0
- package/src/generators/python-microservice/docs/principles/stack/python/mcp.md +147 -0
- package/src/generators/python-microservice/docs/principles/stack/python/resilience.md +193 -0
- package/src/generators/python-microservice/docs/principles/stack/python/testing.md +322 -0
- package/src/generators/python-microservice/files/.env.example.template +30 -0
- package/src/generators/python-microservice/files/Dockerfile.template +36 -0
- package/src/generators/python-microservice/files/db/schema.sql.template +19 -0
- package/src/generators/python-microservice/files/pyproject.toml.template +76 -0
- package/src/generators/python-microservice/files/scripts/apply-schema.sh.template +25 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/comfyui.py.template +87 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/config.py.template +48 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/database.py.template +21 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/message_queue.py.template +29 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/repository.py.template +130 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/telemetry.py.template +68 -0
- package/src/generators/python-microservice/files/src/__packageName__/adapters/websocket_hub.py.template +36 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/domain/entities.py.template +22 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/domain/exceptions.py.template +43 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/ports.py.template +42 -0
- package/src/generators/python-microservice/files/src/__packageName__/core/service/example_service.py.template +68 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/dependencies.py.template +50 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/middleware.py.template +131 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/router.py.template +37 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/websocket_handler.py.template +20 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/cleanup.py.template +35 -0
- package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/worker.py.template +28 -0
- package/src/generators/python-microservice/files/src/__packageName__/main.py.template +108 -0
- package/src/generators/python-microservice/files/tests/test_main.py.template +74 -0
- package/src/generators/python-microservice/files/tests/test_middleware.py.template +109 -0
- package/src/generators/python-microservice/files/tests/test_worker.py.template +16 -0
- package/src/generators/python-microservice/generator.ts +286 -0
- package/src/generators/python-microservice/schema.json +86 -0
- package/src/generators/shared/brand-tokens.ts +301 -0
- package/src/generators/shared/capabilities.ts +349 -0
- package/src/generators/shared/provenance.ts +61 -0
- package/src/generators/shared/scaffold-helpers.ts +309 -0
- package/src/generators/system-test-runner/NATIVE-CHECK-CONTRACT.md +20 -0
- package/src/generators/system-test-runner/files/tests/bets/.gitkeep +0 -0
- package/src/generators/system-test-runner/files/tests/bets/_archive/.gitkeep +0 -0
- package/src/generators/system-test-runner/files/tests/conftest.py.template +503 -0
- package/src/generators/system-test-runner/files/tests/pyproject.toml.template +20 -0
- package/src/generators/system-test-runner/files/tests/system/pages/__init__.py.template +9 -0
- package/src/generators/system-test-runner/files/tests/system/pages/base_page.py.template +36 -0
- package/src/generators/system-test-runner/files/tests/system/test_a11y_smoke.py.template +132 -0
- package/src/generators/system-test-runner/files/tests/system/test_contract_conformance.py.template +140 -0
- package/src/generators/system-test-runner/files/tests/system/test_layout_geometry.py.template +109 -0
- package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +257 -0
- package/src/generators/system-test-runner/files/tests/system/test_system.py.template +158 -0
- package/src/generators/system-test-runner/files/tests/system/test_token_conformance.py.template +206 -0
- package/src/generators/system-test-runner/files/tests/system/test_visual_regression.py.template +104 -0
- package/src/generators/system-test-runner/generator.ts +196 -0
- package/src/generators/system-test-runner/schema.json +24 -0
- package/src/generators/workspace-dev-cli/cli-src/build.mjs +42 -0
- package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +2168 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/bet.ts +442 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/completion.ts +87 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/doctor.ts +139 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/lifecycle.ts +548 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/quality.ts +127 -0
- package/src/generators/workspace-dev-cli/cli-src/src/commands/surface.ts +214 -0
- package/src/generators/workspace-dev-cli/cli-src/src/index.ts +127 -0
- package/src/generators/workspace-dev-cli/cli-src/src/registry.ts +194 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/color.ts +130 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/render.ts +158 -0
- package/src/generators/workspace-dev-cli/cli-src/src/theme/tokens.ts +122 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/context.ts +43 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/extensions.ts +99 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/paths.ts +46 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/proc.ts +106 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/prompt.ts +108 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/runners.ts +70 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/services.ts +221 -0
- package/src/generators/workspace-dev-cli/cli-src/src/util/version.ts +21 -0
- package/src/generators/workspace-dev-cli/cli-src/tsconfig.json +16 -0
- package/src/generators/workspace-dev-cli/files/.agents/skills/workspace-cli/SKILL.md.template +74 -0
- package/src/generators/workspace-dev-cli/files/dev.template +16 -0
- package/src/generators/workspace-dev-cli/files/docker-compose.yml.template +20 -0
- package/src/generators/workspace-dev-cli/files/scripts/cli/templates/milestone-test.pytmpl.template +46 -0
- package/src/generators/workspace-dev-cli/files/scripts/cli/templates/slice-test.pytmpl.template +38 -0
- package/src/generators/workspace-dev-cli/generator.ts +136 -0
- package/src/generators/workspace-dev-cli/schema.json +22 -0
- package/src/hidden-skills/code-intelligence.md +135 -0
- package/src/hidden-skills/groundwork-architect/SKILL.md +114 -0
- package/src/hidden-skills/groundwork-architect/references/agentic-systems.md +44 -0
- package/src/hidden-skills/groundwork-architect/references/ai-native-architecture.md +37 -0
- package/src/hidden-skills/groundwork-architect/references/api-and-contracts.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/core-and-boundaries.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/data-architecture.md +33 -0
- package/src/hidden-skills/groundwork-architect/references/decision-records.md +34 -0
- package/src/hidden-skills/groundwork-architect/references/durable-execution.md +45 -0
- package/src/hidden-skills/groundwork-architect/references/evolutionary-architecture.md +37 -0
- package/src/hidden-skills/groundwork-architect/references/identity-and-access.md +41 -0
- package/src/hidden-skills/groundwork-architect/references/integration-patterns.md +39 -0
- package/src/hidden-skills/groundwork-architect/references/observability.md +36 -0
- package/src/hidden-skills/groundwork-architect/references/performance-and-scale.md +41 -0
- package/src/hidden-skills/groundwork-architect/references/platform-and-delivery.md +47 -0
- package/src/hidden-skills/groundwork-architect/references/realtime-and-async.md +28 -0
- package/src/hidden-skills/groundwork-architect/references/reliability.md +31 -0
- package/src/hidden-skills/groundwork-architect/references/security-and-trust.md +47 -0
- package/src/hidden-skills/groundwork-architect/references/surface-architecture.md +40 -0
- package/src/hidden-skills/groundwork-architect/sync-anchor.md +34 -0
- package/src/hidden-skills/groundwork-architecture/architecture-template.md +50 -0
- package/src/hidden-skills/groundwork-architecture/instructions.md +139 -0
- package/src/hidden-skills/groundwork-architecture/phases/01-context-ingestion.md +18 -0
- package/src/hidden-skills/groundwork-architecture/phases/02-technical-constraints.md +27 -0
- package/src/hidden-skills/groundwork-architecture/phases/03-service-design.md +19 -0
- package/src/hidden-skills/groundwork-architecture/phases/04-data-flow-communication.md +23 -0
- package/src/hidden-skills/groundwork-architecture/phases/05-component-boundaries-contracts.md +17 -0
- package/src/hidden-skills/groundwork-architecture/phases/06-draft-review-present.md +38 -0
- package/src/hidden-skills/groundwork-architecture/phases/07-commit.md +33 -0
- package/src/hidden-skills/groundwork-architecture/templates/architecture-cache.md +43 -0
- package/src/hidden-skills/groundwork-architecture-extract/instructions.md +163 -0
- package/src/hidden-skills/groundwork-architecture-extract/templates/architecture-extract-cache.md +21 -0
- package/src/hidden-skills/groundwork-bet/briefs/acceptance-auditor.md +68 -0
- package/src/hidden-skills/groundwork-bet/briefs/blind-reviewer.md +56 -0
- package/src/hidden-skills/groundwork-bet/briefs/coverage-auditor.md +95 -0
- package/src/hidden-skills/groundwork-bet/briefs/edge-case-tracer.md +64 -0
- package/src/hidden-skills/groundwork-bet/briefs/experience-auditor.md +83 -0
- package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +257 -0
- package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
- package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +115 -0
- package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +38 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/meta.json +4 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +31 -0
- package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +31 -0
- package/src/hidden-skills/groundwork-bet/templates/pitch.md +45 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/01-ui-design.md +51 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/02-data-flows.md +36 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +90 -0
- package/src/hidden-skills/groundwork-bet/templates/technical-design/04-data-design.md +29 -0
- package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +200 -0
- package/src/hidden-skills/groundwork-bet/workflows/02-design.md +178 -0
- package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +242 -0
- package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +226 -0
- package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +210 -0
- package/src/hidden-skills/groundwork-design-system/instructions.md +125 -0
- package/src/hidden-skills/groundwork-design-system/templates/brand-tokens.md +182 -0
- package/src/hidden-skills/groundwork-design-system/templates/design-system-cache.md +64 -0
- package/src/hidden-skills/groundwork-design-system/tracks/_foundation.md +136 -0
- package/src/hidden-skills/groundwork-design-system/tracks/agentic-protocol.md +269 -0
- package/src/hidden-skills/groundwork-design-system/tracks/cli.md +355 -0
- package/src/hidden-skills/groundwork-design-system/tracks/graphical-ui.md +330 -0
- package/src/hidden-skills/groundwork-design-system-extract/instructions.md +124 -0
- package/src/hidden-skills/groundwork-design-system-extract/templates/design-system-extract-cache.md +19 -0
- package/src/hidden-skills/groundwork-designer/SKILL.md +108 -0
- package/src/hidden-skills/groundwork-designer/references/accessibility.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/ai-native-design.md +37 -0
- package/src/hidden-skills/groundwork-designer/references/design-review.md +29 -0
- package/src/hidden-skills/groundwork-designer/references/design-systems-and-tokens.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/interaction-and-motion.md +37 -0
- package/src/hidden-skills/groundwork-designer/references/layout-and-space.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/usability-and-ux.md +33 -0
- package/src/hidden-skills/groundwork-designer/references/visual-craft.md +49 -0
- package/src/hidden-skills/groundwork-designer/sync-anchor.md +20 -0
- package/src/hidden-skills/groundwork-doc-sync/instructions.md +100 -0
- package/src/hidden-skills/groundwork-elicit/instructions.md +66 -0
- package/src/hidden-skills/groundwork-elicit/methods.md +65 -0
- package/src/hidden-skills/groundwork-infra-adopt/instructions.md +168 -0
- package/src/hidden-skills/groundwork-infra-adopt/templates/infra-adopt-cache.md +21 -0
- package/src/hidden-skills/groundwork-mvp/instructions.md +223 -0
- package/src/hidden-skills/groundwork-mvp/templates/mvp-cache.md +9 -0
- package/src/hidden-skills/groundwork-patch/instructions.md +40 -0
- package/src/hidden-skills/groundwork-persona/instructions.md +65 -0
- package/src/hidden-skills/groundwork-product/SKILL.md +102 -0
- package/src/hidden-skills/groundwork-product/references/ai-native-product.md +45 -0
- package/src/hidden-skills/groundwork-product/references/discovery-and-opportunity.md +38 -0
- package/src/hidden-skills/groundwork-product/references/product-risks.md +52 -0
- package/src/hidden-skills/groundwork-product/references/requirements-and-specs.md +39 -0
- package/src/hidden-skills/groundwork-product/references/scope-and-sequencing.md +35 -0
- package/src/hidden-skills/groundwork-product/references/shaping-and-appetite.md +48 -0
- package/src/hidden-skills/groundwork-product/references/success-metrics-and-signals.md +37 -0
- package/src/hidden-skills/groundwork-product/sync-anchor.md +19 -0
- package/src/hidden-skills/groundwork-product-brief/instructions.md +231 -0
- package/src/hidden-skills/groundwork-product-brief-extract/instructions.md +139 -0
- package/src/hidden-skills/groundwork-product-brief-extract/templates/product-brief-extract-cache.md +17 -0
- package/src/hidden-skills/groundwork-review/checklists/architecture.md +93 -0
- package/src/hidden-skills/groundwork-review/checklists/bet-pitch.md +94 -0
- package/src/hidden-skills/groundwork-review/checklists/decomposition.md +135 -0
- package/src/hidden-skills/groundwork-review/checklists/design-system.md +85 -0
- package/src/hidden-skills/groundwork-review/checklists/domain-entity.md +66 -0
- package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +47 -0
- package/src/hidden-skills/groundwork-review/checklists/infrastructure.md +68 -0
- package/src/hidden-skills/groundwork-review/checklists/maturity.md +71 -0
- package/src/hidden-skills/groundwork-review/checklists/product-brief.md +69 -0
- package/src/hidden-skills/groundwork-review/checklists/technical-design.md +112 -0
- package/src/hidden-skills/groundwork-review/instructions.md +181 -0
- package/src/hidden-skills/groundwork-scaffold/instructions.md +254 -0
- package/src/hidden-skills/groundwork-scaffold/phases/01-ingestion-service-mapping.md +87 -0
- package/src/hidden-skills/groundwork-scaffold/phases/02-scaffolding-execution.md +15 -0
- package/src/hidden-skills/groundwork-scaffold/phases/03-service-documentation-api-stubs.md +100 -0
- package/src/hidden-skills/groundwork-scaffold/phases/04-infrastructure-verification.md +17 -0
- package/src/hidden-skills/groundwork-scaffold/phases/05-draft-review.md +19 -0
- package/src/hidden-skills/groundwork-scaffold/phases/06-commit.md +19 -0
- package/src/hidden-skills/groundwork-scaffold/templates/scaffold-cache.md +23 -0
- package/src/hidden-skills/groundwork-scan/instructions.md +164 -0
- package/src/hidden-skills/groundwork-scan/references/digest-schema.md +66 -0
- package/src/hidden-skills/groundwork-scan/references/exclusions.md +44 -0
- package/src/hidden-skills/groundwork-scan/templates/architecture-findings.md +42 -0
- package/src/hidden-skills/groundwork-scan/templates/design-findings.md +23 -0
- package/src/hidden-skills/groundwork-scan/templates/overview.md +26 -0
- package/src/hidden-skills/groundwork-scan/templates/product-findings.md +23 -0
- package/src/hidden-skills/groundwork-scan/templates/scan-state.json +19 -0
- package/src/hidden-skills/groundwork-stack-forge/instructions.md +150 -0
- package/src/hidden-skills/groundwork-stack-forge/references/authoring-engineer-skills.md +107 -0
- package/src/hidden-skills/groundwork-surface-activation/instructions.md +138 -0
- package/src/hidden-skills/groundwork-update/briefs/reconcile-worker.md +196 -0
- package/src/hidden-skills/groundwork-update/instructions.md +200 -0
- package/src/hidden-skills/groundwork-writer/SKILL.md +278 -0
- package/src/hidden-skills/maturity-model.md +125 -0
- package/src/hidden-skills/operating-contract.md +400 -0
- package/src/hidden-skills/repo-map-schema.md +90 -0
- package/src/hidden-skills/templates/adr.md +57 -0
- package/src/hidden-skills/templates/capability-ports.md +71 -0
- package/src/hidden-skills/templates/discovery-notes.md +33 -0
- package/src/hidden-skills/templates/domain-entity.md +80 -0
- package/src/hidden-skills/templates/gap-ledger.md +21 -0
- package/src/hidden-skills/templates/handoff.md +37 -0
- package/src/hidden-skills/templates/maturity.md +39 -0
- package/src/hidden-skills/templates/surfaces.md +207 -0
- package/src/skills/groundwork-check/SKILL.md +56 -0
- package/src/skills/groundwork-check/instructions.md +70 -0
- package/src/skills/groundwork-orchestrator/SKILL.md +176 -0
- package/src/skills/groundwork-orchestrator/workflow-index.md +50 -0
|
@@ -0,0 +1,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
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Electron Desktop Shell
|
|
3
|
+
description: Process model, IPC contracts, security defaults, and packaging for Electron desktop applications.
|
|
4
|
+
status: active
|
|
5
|
+
last_reviewed: 2026-06-12
|
|
6
|
+
---
|
|
7
|
+
# Electron Desktop Shell
|
|
8
|
+
|
|
9
|
+
## TL;DR
|
|
10
|
+
|
|
11
|
+
Electron is GroundWork's standard desktop surface. This set owns what the desktop shell adds over a web app: the process model, the IPC seam, the security posture, and packaging/updates. Everything the renderer shares with a web frontend — component idiom, styling, accessibility, design-system discipline — is owned by [TypeScript Frontend](../typescript/frontend.md) and is not restated here.
|
|
12
|
+
|
|
13
|
+
## Why Electron
|
|
14
|
+
|
|
15
|
+
[Surface Stack Selection](../../surface-stack-selection.md) picks Electron on the agent-closable-loop axis: Electron renders on bundled Chromium, so Playwright's `_electron` driver launches the real packaged app, drives its windows as ordinary `Page`s, and evaluates code in the main process — one deterministic engine on every OS, headless under Xvfb in CI. No other desktop option closes generate → boot → test → observe without a human in the loop. The renderer reusing the web stack and brand-token projection wholesale is the second axis win. Tauri is the recorded alternative when binary size and RAM dominate — its per-OS system webviews and WebDriver-only testing surrender the loop, so it is never the default.
|
|
16
|
+
|
|
17
|
+
That `_electron` smoke (`tests/smoke/app.spec.ts`) is the Electron side of the **native UI check contract** (`src/generators/system-test-runner/NATIVE-CHECK-CONTRACT.md`): the `system-test-runner` drives it as the surface's visual gate, so it carries the contract's dimensions on the real binary — it renders without a blank or crash frame, drives the **named async state** (a deterministically unreachable core renders its designed state, not a crash), and confirms the **design-system tokens landed** (the brand custom properties resolve and the heading paints the projected primary token, not an unstyled default). Navigation / no-dead-ends is exempt while the app is single-screen; a bet that adds screens drives between them and back here. Keep it thin — the milestone's front-door bet-progress proof is what drives the real pipeline end to end.
|
|
18
|
+
|
|
19
|
+
## What this set owns
|
|
20
|
+
|
|
21
|
+
| File | Owns |
|
|
22
|
+
|---|---|
|
|
23
|
+
| [Process Model](process-model.md) | Main/renderer/utility split, `utilityProcess`, the enforced folder boundary |
|
|
24
|
+
| [IPC Contracts](ipc-contracts.md) | The typed bridge, validation at the process seam, renderer data fetching over IPC |
|
|
25
|
+
| [Security](security.md) | The hardened defaults, fuses, navigation and permission policy |
|
|
26
|
+
| [Packaging & Updates](packaging-and-updates.md) | Forge, electron-vite, auto-update routes, code signing |
|
|
27
|
+
|
|
28
|
+
The split follows the capability-core model: the renderer is a thin surface adapter, and the desktop shell's job is to host it safely. Where the shell adds something to the renderer's world, the addition lives here and the rest defers:
|
|
29
|
+
|
|
30
|
+
- **Tailwind v4** loads as a Vite plugin (`@tailwindcss/vite`) in the **renderer section** of `electron.vite.config.ts` — no `tailwind.config.js`; brand tokens live as CSS custom properties via `@theme`. Composition rules: [TypeScript Frontend](../typescript/frontend.md).
|
|
31
|
+
- **Theme sync** is `nativeTheme` in main, broadcast over IPC, mapped to an attribute on `<html>`. What the theme contains: [TypeScript Frontend](../typescript/frontend.md).
|
|
32
|
+
- Everything else about components, styling, and accessibility: [TypeScript Frontend](../typescript/frontend.md), unmodified.
|
|
33
|
+
|
|
34
|
+
## Currency is a security obligation
|
|
35
|
+
|
|
36
|
+
Electron 42 is current (released 2026-05-05, Chromium M148, Node 24). A new major ships every 8 weeks, and only the latest **three** majors receive security patches — Chromium CVEs land in your app on that clock whether you upgrade or not. An app more than three majors behind is out of security support, so the upgrade cadence is scheduled work, not deferred maintenance. Pin the version, take every major within its support window, and treat a skipped window as a security finding.
|
|
37
|
+
|
|
38
|
+
## Survey basis
|
|
39
|
+
|
|
40
|
+
Authored from the Electron ecosystem survey dated **2026-06-12**. Load-bearing sources:
|
|
41
|
+
|
|
42
|
+
- [Electron security checklist](https://www.electronjs.org/docs/latest/tutorial/security) and [process model](https://www.electronjs.org/docs/latest/tutorial/process-model) — the official baseline.
|
|
43
|
+
- [IPC tutorial](https://www.electronjs.org/docs/latest/tutorial/ipc) and [`utilityProcess` API](https://www.electronjs.org/docs/latest/api/utility-process).
|
|
44
|
+
- [endoflife.date/electron](https://endoflife.date/electron) and [Electron timelines](https://www.electronjs.org/docs/latest/tutorial/electron-timelines) — version and support windows.
|
|
45
|
+
- [VS Code sandbox migration](https://code.visualstudio.com/blogs/2022/11/28/vscode-sandbox) and [Slack: The App Sandbox](https://slack.engineering/the-app-sandbox/) — the reference process architectures.
|
|
46
|
+
- [Trail of Bits, CVE-2025-55305](https://blog.trailofbits.com/2025/09/03/subverting-code-integrity-checks-to-locally-backdoor-signal-1password-slack-and-more/) — why fuses are now expected.
|
|
47
|
+
- [Why Electron Forge](https://www.electronforge.io/core-concepts/why-electron-forge), [electron-vite](https://electron-vite.org/guide/) (v5, alex8088), [Updating Applications](https://www.electronjs.org/docs/latest/tutorial/updates), [update.electronjs.org](https://github.com/electron/update.electronjs.org).
|
|
48
|
+
- [Playwright Electron class](https://playwright.dev/docs/architecture/api/class-electron) — the loop driver.
|
|
49
|
+
- [Azure Artifact Signing](https://azure.microsoft.com/en-us/products/artifact-signing) — Windows signing (renamed from Trusted Signing, GA Jan 2026).
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: IPC Contracts
|
|
3
|
+
description: The typed bridge, invoke/handle, runtime validation at the process seam, and IPC-aware data fetching in the renderer.
|
|
4
|
+
status: active
|
|
5
|
+
last_reviewed: 2026-06-12
|
|
6
|
+
---
|
|
7
|
+
# IPC Contracts
|
|
8
|
+
|
|
9
|
+
## TL;DR
|
|
10
|
+
|
|
11
|
+
The main↔renderer seam is a contract boundary and gets the same discipline the capability core enforces at its contracts: a narrow, purpose-named bridge; `invoke`/`handle` for two-way calls; one shared TypeScript contract type both sides consume; runtime validation in main because renderer input is untrusted. `ipcRenderer` is never exposed and `sendSync` is forbidden.
|
|
12
|
+
|
|
13
|
+
## Why this matters
|
|
14
|
+
|
|
15
|
+
IPC is where the privileged process meets the sandboxed one. A wide or untyped bridge re-creates the Node-enabled renderer one channel at a time, and an unvalidated handler lets a compromised renderer drive privileged code with arbitrary payloads. Treating the seam as a typed, validated contract keeps the sandbox meaningful — and gives the agent a single place to read what the shell can do.
|
|
16
|
+
|
|
17
|
+
## Our principles
|
|
18
|
+
|
|
19
|
+
### 1. The bridge is narrow and purpose-named
|
|
20
|
+
|
|
21
|
+
Preload exposes a small API object via `contextBridge.exposeInMainWorld()` whose methods name capabilities, not transport:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// src/preload/index.ts
|
|
25
|
+
contextBridge.exposeInMainWorld('api', {
|
|
26
|
+
openProject: (path: string) => ipcRenderer.invoke('project:open', path),
|
|
27
|
+
onThemeChanged: (cb: (theme: Theme) => void) => {
|
|
28
|
+
ipcRenderer.on('theme:changed', (_e, theme) => cb(theme));
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`ipcRenderer` itself — or any whole Electron module — is never put on `window`; the official docs forbid it for security reasons, because a raw `ipcRenderer` lets injected code call every channel the app has.
|
|
34
|
+
|
|
35
|
+
### 2. `invoke`/`handle` for two-way, `send`/`on` for one-way
|
|
36
|
+
|
|
37
|
+
`ipcRenderer.invoke` / `ipcMain.handle` is the request/response pattern — promise-based, with errors propagating to the caller. `send`/`on` carries one-way pushes from main (theme changes, update events, file-watcher notifications). `sendSync` is forbidden: it blocks the renderer's event loop for the round trip.
|
|
38
|
+
|
|
39
|
+
### 3. One shared contract type, consumed by both sides
|
|
40
|
+
|
|
41
|
+
A channel-name → request/response signature map lives in `src/shared/` and types a thin wrapper on each side, so a channel rename or payload change is a compile error in both processes:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
// src/shared/ipc.ts
|
|
45
|
+
export type IpcContract = {
|
|
46
|
+
'project:open': { args: [path: string]; result: ProjectSummary };
|
|
47
|
+
'settings:get': { args: []; result: Settings };
|
|
48
|
+
};
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This is the hand-rolled convergent pattern. **electron-trpc** (tRPC over IPC, Zod inputs, subscriptions) is the documented variant for apps that want a full RPC layer — but it sits in a maintenance lull (last release 2024-12-07; tRPC v11 support lives in forks) and adds per-call overhead on hot paths, so it is a recorded choice, not the default.
|
|
52
|
+
|
|
53
|
+
### 4. Main validates everything it receives
|
|
54
|
+
|
|
55
|
+
Main treats renderer input as untrusted, the same way an API treats the public internet. Two checks in every non-trivial `ipcMain.handle`:
|
|
56
|
+
|
|
57
|
+
- **Payload validation** with zod for anything beyond a trivial getter — the TypeScript types vanish at runtime, and a compromised renderer is not bound by them.
|
|
58
|
+
- **Sender validation** via `event.senderFrame` (security checklist item 17) — verify the call comes from your app's frame, not an iframe or a navigated-away window.
|
|
59
|
+
|
|
60
|
+
### 5. Renderer data fetching is TanStack Query over the bridge
|
|
61
|
+
|
|
62
|
+
The renderer's data source is IPC, not HTTP, and TanStack Query is the convergent IPC-aware pattern: `queryFn`s call the typed bridge (`window.api.foo()`), and main-process push events arrive through a bridge subscription that invalidates queries. Caching, retry, and invalidation work exactly as in an HTTP app. This is the desktop shell's one deviation from the web stack's SWR pick in [TypeScript Frontend](../typescript/frontend.md) — the one-cache-one-mental-model rule there still holds: TanStack Query is the renderer's only query library. Theme is the canonical push example: `nativeTheme` in main, broadcast over `send`, mapped to an attribute on `<html>`; everything about what the theme contains defers to [TypeScript Frontend](../typescript/frontend.md).
|
|
63
|
+
|
|
64
|
+
## Anti-patterns we reject
|
|
65
|
+
|
|
66
|
+
- **Exposing `ipcRenderer` or Electron modules on `window`.** The bridge exists to be narrow; this makes it infinitely wide.
|
|
67
|
+
- **`sendSync`.** It blocks the renderer event loop. There is always an async shape.
|
|
68
|
+
- **String-typed ad-hoc channels.** A channel with no entry in the shared contract is an untyped seam that drifts silently.
|
|
69
|
+
- **Trusting renderer payloads or senders in main.** Compile-time types are not runtime guarantees.
|
|
70
|
+
- **The `remote` module.** Removed from core; any dependency resurrecting it is a finding.
|
|
71
|
+
- **Raw `useEffect` IPC fetching in React.** Same rule as the web stack: data goes through the cache layer, not effect spaghetti.
|