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.
Files changed (629) hide show
  1. package/CHANGELOG.md +781 -0
  2. package/LICENSE +21 -0
  3. package/README.md +44 -29
  4. package/bin/groundwork.js +1654 -0
  5. package/dist/src/generators/add-capability/generator.d.ts +8 -0
  6. package/dist/src/generators/add-capability/generator.js +60 -0
  7. package/dist/src/generators/add-capability/generator.js.map +1 -0
  8. package/dist/src/generators/cli-app/generator.d.ts +9 -0
  9. package/dist/src/generators/cli-app/generator.js +140 -0
  10. package/dist/src/generators/cli-app/generator.js.map +1 -0
  11. package/dist/src/generators/docs-site/generator.d.ts +5 -0
  12. package/dist/src/generators/docs-site/generator.js +441 -0
  13. package/dist/src/generators/docs-site/generator.js.map +1 -0
  14. package/dist/src/generators/electron-app/generator.d.ts +6 -0
  15. package/dist/src/generators/electron-app/generator.js +261 -0
  16. package/dist/src/generators/electron-app/generator.js.map +1 -0
  17. package/dist/src/generators/flutter-app/generator.d.ts +6 -0
  18. package/dist/src/generators/flutter-app/generator.js +314 -0
  19. package/dist/src/generators/flutter-app/generator.js.map +1 -0
  20. package/dist/src/generators/go-microservice/generator.d.ts +8 -0
  21. package/dist/src/generators/go-microservice/generator.js +232 -0
  22. package/dist/src/generators/go-microservice/generator.js.map +1 -0
  23. package/dist/src/generators/nextjs-app/generator.d.ts +8 -0
  24. package/dist/src/generators/nextjs-app/generator.js +294 -0
  25. package/dist/src/generators/nextjs-app/generator.js.map +1 -0
  26. package/dist/src/generators/python-microservice/generator.d.ts +13 -0
  27. package/dist/src/generators/python-microservice/generator.js +265 -0
  28. package/dist/src/generators/python-microservice/generator.js.map +1 -0
  29. package/dist/src/generators/shared/brand-tokens.d.ts +89 -0
  30. package/dist/src/generators/shared/brand-tokens.js +308 -0
  31. package/dist/src/generators/shared/brand-tokens.js.map +1 -0
  32. package/dist/src/generators/shared/capabilities.d.ts +101 -0
  33. package/dist/src/generators/shared/capabilities.js +279 -0
  34. package/dist/src/generators/shared/capabilities.js.map +1 -0
  35. package/dist/src/generators/shared/provenance.d.ts +2 -0
  36. package/dist/src/generators/shared/provenance.js +85 -0
  37. package/dist/src/generators/shared/provenance.js.map +1 -0
  38. package/dist/src/generators/shared/scaffold-helpers.d.ts +72 -0
  39. package/dist/src/generators/shared/scaffold-helpers.js +309 -0
  40. package/dist/src/generators/shared/scaffold-helpers.js.map +1 -0
  41. package/dist/src/generators/system-test-runner/generator.d.ts +23 -0
  42. package/dist/src/generators/system-test-runner/generator.js +125 -0
  43. package/dist/src/generators/system-test-runner/generator.js.map +1 -0
  44. package/dist/src/generators/workspace-dev-cli/generator.d.ts +7 -0
  45. package/dist/src/generators/workspace-dev-cli/generator.js +138 -0
  46. package/dist/src/generators/workspace-dev-cli/generator.js.map +1 -0
  47. package/generators.json +57 -0
  48. package/lib/repo-map/grammars/tree-sitter-c.wasm +0 -0
  49. package/lib/repo-map/grammars/tree-sitter-cpp.wasm +0 -0
  50. package/lib/repo-map/grammars/tree-sitter-csharp.wasm +0 -0
  51. package/lib/repo-map/grammars/tree-sitter-dart.wasm +0 -0
  52. package/lib/repo-map/grammars/tree-sitter-go.wasm +0 -0
  53. package/lib/repo-map/grammars/tree-sitter-java.wasm +0 -0
  54. package/lib/repo-map/grammars/tree-sitter-javascript.wasm +0 -0
  55. package/lib/repo-map/grammars/tree-sitter-kotlin.wasm +0 -0
  56. package/lib/repo-map/grammars/tree-sitter-lua.wasm +0 -0
  57. package/lib/repo-map/grammars/tree-sitter-php.wasm +0 -0
  58. package/lib/repo-map/grammars/tree-sitter-python.wasm +0 -0
  59. package/lib/repo-map/grammars/tree-sitter-ruby.wasm +0 -0
  60. package/lib/repo-map/grammars/tree-sitter-rust.wasm +0 -0
  61. package/lib/repo-map/grammars/tree-sitter-scala.wasm +0 -0
  62. package/lib/repo-map/grammars/tree-sitter-swift.wasm +0 -0
  63. package/lib/repo-map/grammars/tree-sitter-tsx.wasm +0 -0
  64. package/lib/repo-map/grammars/tree-sitter-typescript.wasm +0 -0
  65. package/lib/repo-map/index.js +386 -0
  66. package/lib/repo-map/languages.js +514 -0
  67. package/lib/repo-map/pagerank.js +59 -0
  68. package/migrations/README.md +60 -0
  69. package/migrations/_template/cli-migration.js +27 -0
  70. package/migrations/gw-bet-prose-redesign.js +105 -0
  71. package/migrations/gw-drop-test-manifest.js +37 -0
  72. package/migrations/gw-register-serena-mcp.js +42 -0
  73. package/migrations/gw-relocate-hidden-skills.js +40 -0
  74. package/migrations/gw-seed-config-toml.js +24 -0
  75. package/migrations/index.json +40 -0
  76. package/package.json +70 -6
  77. package/src/AGENTS.md +36 -0
  78. package/src/config/config.toml +30 -0
  79. package/src/config/groundwork-state.json +5 -0
  80. package/src/docs/llms.txt +72 -0
  81. package/src/docs/principles/ai-native/agent-native-systems.md +90 -0
  82. package/src/docs/principles/ai-native/agentic-systems.md +78 -0
  83. package/src/docs/principles/ai-native/ai-engineering.md +100 -0
  84. package/src/docs/principles/ai-native/ai-native-product.md +76 -0
  85. package/src/docs/principles/delivery/cost-engineering.md +89 -0
  86. package/src/docs/principles/delivery/day-2-operational-baseline.md +57 -0
  87. package/src/docs/principles/delivery/devex.md +88 -0
  88. package/src/docs/principles/delivery/platform.md +101 -0
  89. package/src/docs/principles/delivery/progressive-delivery.md +92 -0
  90. package/src/docs/principles/design/ai-native-design.md +73 -0
  91. package/src/docs/principles/design/design-foundations.md +80 -0
  92. package/src/docs/principles/design/design-systems-and-tokens.md +72 -0
  93. package/src/docs/principles/design/interaction-and-motion.md +69 -0
  94. package/src/docs/principles/design/layout-and-space.md +72 -0
  95. package/src/docs/principles/design/usability-and-ux.md +68 -0
  96. package/src/docs/principles/design/visual-design.md +84 -0
  97. package/src/docs/principles/foundations/code-craft.md +86 -0
  98. package/src/docs/principles/foundations/continuous-discovery.md +75 -0
  99. package/src/docs/principles/foundations/documentation.md +102 -0
  100. package/src/docs/principles/foundations/prioritization-and-appetite.md +78 -0
  101. package/src/docs/principles/foundations/product-engineering.md +90 -0
  102. package/src/docs/principles/foundations/product-risks.md +89 -0
  103. package/src/docs/principles/foundations/requirements-and-specs.md +80 -0
  104. package/src/docs/principles/foundations/success-metrics.md +66 -0
  105. package/src/docs/principles/foundations/testing.md +82 -0
  106. package/src/docs/principles/index.md +23 -0
  107. package/src/docs/principles/quality/accessibility.md +88 -0
  108. package/src/docs/principles/quality/observability.md +84 -0
  109. package/src/docs/principles/quality/performance.md +84 -0
  110. package/src/docs/principles/quality/privacy.md +92 -0
  111. package/src/docs/principles/quality/reliability.md +89 -0
  112. package/src/docs/principles/quality/security.md +78 -0
  113. package/src/docs/principles/stack/postgres.md +100 -0
  114. package/src/docs/principles/system-design/api-design.md +86 -0
  115. package/src/docs/principles/system-design/architecture-decisions.md +81 -0
  116. package/src/docs/principles/system-design/code-structure.md +104 -0
  117. package/src/docs/principles/system-design/data-engineering.md +87 -0
  118. package/src/docs/principles/system-design/durable-execution.md +89 -0
  119. package/src/docs/principles/system-design/evolutionary-architecture.md +81 -0
  120. package/src/docs/principles/system-design/identity-and-access.md +76 -0
  121. package/src/docs/principles/system-design/integration-patterns.md +84 -0
  122. package/src/docs/principles/system-design/real-time.md +83 -0
  123. package/src/docs/principles/system-design/surface-architecture.md +74 -0
  124. package/src/docs/ways-of-working/documentation.md +69 -0
  125. package/src/docs/ways-of-working/how-we-work.md +76 -0
  126. package/src/docs/ways-of-working/units-of-work.md +40 -0
  127. package/src/engineer-skills/groundwork-electron-engineer/SKILL.md +118 -0
  128. package/src/engineer-skills/groundwork-electron-engineer/references/ipc-contracts.md +138 -0
  129. package/src/engineer-skills/groundwork-electron-engineer/references/packaging-and-updates.md +82 -0
  130. package/src/engineer-skills/groundwork-electron-engineer/references/process-model.md +94 -0
  131. package/src/engineer-skills/groundwork-electron-engineer/references/security.md +107 -0
  132. package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +107 -0
  133. package/src/engineer-skills/groundwork-electron-engineer/references/theming-and-tokens.md +74 -0
  134. package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +14 -0
  135. package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +108 -0
  136. package/src/engineer-skills/groundwork-flutter-engineer/references/accessibility.md +92 -0
  137. package/src/engineer-skills/groundwork-flutter-engineer/references/architecture.md +189 -0
  138. package/src/engineer-skills/groundwork-flutter-engineer/references/data-and-contracts.md +136 -0
  139. package/src/engineer-skills/groundwork-flutter-engineer/references/navigation.md +122 -0
  140. package/src/engineer-skills/groundwork-flutter-engineer/references/platform-channels.md +93 -0
  141. package/src/engineer-skills/groundwork-flutter-engineer/references/releases-and-distribution.md +84 -0
  142. package/src/engineer-skills/groundwork-flutter-engineer/references/state-management.md +166 -0
  143. package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +135 -0
  144. package/src/engineer-skills/groundwork-flutter-engineer/references/theming-and-design-tokens.md +109 -0
  145. package/src/engineer-skills/groundwork-flutter-engineer/references/widgets-and-composition.md +123 -0
  146. package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +15 -0
  147. package/src/engineer-skills/groundwork-go-engineer/SKILL.md +171 -0
  148. package/src/engineer-skills/groundwork-go-engineer/references/api-design.md +82 -0
  149. package/src/engineer-skills/groundwork-go-engineer/references/architecture.md +42 -0
  150. package/src/engineer-skills/groundwork-go-engineer/references/capability-ports.md +50 -0
  151. package/src/engineer-skills/groundwork-go-engineer/references/code-craft-security.md +34 -0
  152. package/src/engineer-skills/groundwork-go-engineer/references/concurrency.md +108 -0
  153. package/src/engineer-skills/groundwork-go-engineer/references/go-services.md +77 -0
  154. package/src/engineer-skills/groundwork-go-engineer/references/http-handlers.md +172 -0
  155. package/src/engineer-skills/groundwork-go-engineer/references/implementation-patterns.md +156 -0
  156. package/src/engineer-skills/groundwork-go-engineer/references/integration-realtime-data.md +57 -0
  157. package/src/engineer-skills/groundwork-go-engineer/references/observability.md +49 -0
  158. package/src/engineer-skills/groundwork-go-engineer/references/postgres.md +41 -0
  159. package/src/engineer-skills/groundwork-go-engineer/references/reliability-performance.md +105 -0
  160. package/src/engineer-skills/groundwork-go-engineer/references/testing.md +139 -0
  161. package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +11 -0
  162. package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +107 -0
  163. package/src/engineer-skills/groundwork-nextjs-engineer/references/architecture.md +323 -0
  164. package/src/engineer-skills/groundwork-nextjs-engineer/references/data-fetching.md +458 -0
  165. package/src/engineer-skills/groundwork-nextjs-engineer/references/documentation.md +324 -0
  166. package/src/engineer-skills/groundwork-nextjs-engineer/references/error-boundaries.md +383 -0
  167. package/src/engineer-skills/groundwork-nextjs-engineer/references/mutations-and-forms.md +396 -0
  168. package/src/engineer-skills/groundwork-nextjs-engineer/references/performance-and-deployment.md +947 -0
  169. package/src/engineer-skills/groundwork-nextjs-engineer/references/routing-and-navigation.md +405 -0
  170. package/src/engineer-skills/groundwork-nextjs-engineer/references/server-components.md +394 -0
  171. package/src/engineer-skills/groundwork-nextjs-engineer/references/tailwind-and-styling.md +134 -0
  172. package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +433 -0
  173. package/src/engineer-skills/groundwork-nextjs-engineer/references/type-system.md +368 -0
  174. package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +278 -0
  175. package/src/engineer-skills/groundwork-nextjs-engineer/references/visual-language.md +69 -0
  176. package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +9 -0
  177. package/src/engineer-skills/groundwork-python-engineer/SKILL.md +196 -0
  178. package/src/engineer-skills/groundwork-python-engineer/references/api-standards.md +88 -0
  179. package/src/engineer-skills/groundwork-python-engineer/references/architecture.md +57 -0
  180. package/src/engineer-skills/groundwork-python-engineer/references/async-patterns.md +103 -0
  181. package/src/engineer-skills/groundwork-python-engineer/references/capability-ports.md +44 -0
  182. package/src/engineer-skills/groundwork-python-engineer/references/database.md +88 -0
  183. package/src/engineer-skills/groundwork-python-engineer/references/documentation-mcp.md +167 -0
  184. package/src/engineer-skills/groundwork-python-engineer/references/implementation-patterns.md +166 -0
  185. package/src/engineer-skills/groundwork-python-engineer/references/ml-pipelines.md +119 -0
  186. package/src/engineer-skills/groundwork-python-engineer/references/ml-systems-ai-engineering.md +74 -0
  187. package/src/engineer-skills/groundwork-python-engineer/references/observability.md +57 -0
  188. package/src/engineer-skills/groundwork-python-engineer/references/resilience.md +126 -0
  189. package/src/engineer-skills/groundwork-python-engineer/references/testing.md +177 -0
  190. package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +13 -0
  191. package/src/generators/add-capability/generator.ts +70 -0
  192. package/src/generators/add-capability/schema.json +30 -0
  193. package/src/generators/capabilities/llm/capability.json +28 -0
  194. package/src/generators/capabilities/llm/providers/anthropic/footprint.json +13 -0
  195. package/src/generators/capabilities/llm/providers/anthropic/stacks/go/internal/llm/llm.go.template +102 -0
  196. package/src/generators/capabilities/llm/providers/anthropic/stacks/python/src/__packageName__/adapters/llm.py.template +61 -0
  197. package/src/generators/capabilities/llm/providers/local/footprint.json +13 -0
  198. package/src/generators/capabilities/llm/providers/local/stacks/go/internal/llm/llm.go.template +102 -0
  199. package/src/generators/capabilities/llm/providers/local/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  200. package/src/generators/capabilities/llm/providers/localai/footprint.json +29 -0
  201. package/src/generators/capabilities/llm/providers/localai/stacks/go/internal/llm/llm.go.template +102 -0
  202. package/src/generators/capabilities/llm/providers/localai/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  203. package/src/generators/capabilities/llm/providers/none/footprint.json +9 -0
  204. package/src/generators/capabilities/llm/providers/none/stacks/go/internal/llm/llm.go.template +35 -0
  205. package/src/generators/capabilities/llm/providers/none/stacks/python/src/__packageName__/adapters/llm.py.template +25 -0
  206. package/src/generators/capabilities/llm/providers/ollama/footprint.json +20 -0
  207. package/src/generators/capabilities/llm/providers/ollama/stacks/go/internal/llm/llm.go.template +102 -0
  208. package/src/generators/capabilities/llm/providers/ollama/stacks/python/src/__packageName__/adapters/llm.py.template +53 -0
  209. package/src/generators/capabilities/llm/providers/openai/footprint.json +13 -0
  210. package/src/generators/capabilities/llm/providers/openai/stacks/go/internal/llm/llm.go.template +98 -0
  211. package/src/generators/capabilities/llm/providers/openai/stacks/python/src/__packageName__/adapters/llm.py.template +60 -0
  212. package/src/generators/capabilities/llm/stacks/go/internal/core/service/llm.go.template +12 -0
  213. package/src/generators/capabilities/llm/stacks/go/internal/llm/llm_test.go.template +33 -0
  214. package/src/generators/capabilities/llm/stacks/python/src/__packageName__/core/llm.py.template +15 -0
  215. package/src/generators/capabilities/llm/stacks/python/tests/contracts/test_llm.py.template +37 -0
  216. package/src/generators/cli-app/files/README.md.template +76 -0
  217. package/src/generators/cli-app/files/build.mjs.template +15 -0
  218. package/src/generators/cli-app/files/package.json.template +21 -0
  219. package/src/generators/cli-app/files/src/cli.ts.template +67 -0
  220. package/src/generators/cli-app/files/src/commands/hello.ts.template +17 -0
  221. package/src/generators/cli-app/files/src/commands/status.ts.template +23 -0
  222. package/src/generators/cli-app/files/src/core/client.test.ts.template +80 -0
  223. package/src/generators/cli-app/files/src/core/client.ts.template +64 -0
  224. package/src/generators/cli-app/files/src/registry.test.ts.template +35 -0
  225. package/src/generators/cli-app/files/src/registry.ts.template +31 -0
  226. package/src/generators/cli-app/files/tsconfig.json.template +16 -0
  227. package/src/generators/cli-app/files/tsconfig.test.json.template +11 -0
  228. package/src/generators/cli-app/generator.ts +138 -0
  229. package/src/generators/cli-app/schema.json +24 -0
  230. package/src/generators/docs-site/files/.gitignore.ejs +40 -0
  231. package/src/generators/docs-site/files/app/docs/__slug__/page.tsx +101 -0
  232. package/src/generators/docs-site/files/app/docs/layout.tsx +14 -0
  233. package/src/generators/docs-site/files/app/docs.css +43 -0
  234. package/src/generators/docs-site/files/app/layout.tsx +24 -0
  235. package/src/generators/docs-site/files/app/page.tsx +135 -0
  236. package/src/generators/docs-site/files/app/source.ts +8 -0
  237. package/src/generators/docs-site/files/components/mermaid.tsx +67 -0
  238. package/src/generators/docs-site/files/next.config.mjs +10 -0
  239. package/src/generators/docs-site/files/package.json +32 -0
  240. package/src/generators/docs-site/files/pnpm-workspace.yaml +7 -0
  241. package/src/generators/docs-site/files/postcss.config.mjs +6 -0
  242. package/src/generators/docs-site/files/source.config.ts +77 -0
  243. package/src/generators/docs-site/files/tailwind.config.js +10 -0
  244. package/src/generators/docs-site/files/tsconfig.json +27 -0
  245. package/src/generators/docs-site/generator.ts +476 -0
  246. package/src/generators/docs-site/schema.json +17 -0
  247. package/src/generators/electron-app/docs/principles/stack/electron/index.md +47 -0
  248. package/src/generators/electron-app/docs/principles/stack/electron/ipc-contracts.md +71 -0
  249. package/src/generators/electron-app/docs/principles/stack/electron/packaging-and-updates.md +59 -0
  250. package/src/generators/electron-app/docs/principles/stack/electron/process-model.md +53 -0
  251. package/src/generators/electron-app/docs/principles/stack/electron/security.md +70 -0
  252. package/src/generators/electron-app/docs/principles/stack/typescript/frontend.md +65 -0
  253. package/src/generators/electron-app/files/.gitignore.template +20 -0
  254. package/src/generators/electron-app/files/README.md.template +125 -0
  255. package/src/generators/electron-app/files/electron.vite.config.ts +31 -0
  256. package/src/generators/electron-app/files/eslint.config.mjs +92 -0
  257. package/src/generators/electron-app/files/forge.config.ts.template +44 -0
  258. package/src/generators/electron-app/files/package.json.template +54 -0
  259. package/src/generators/electron-app/files/playwright.config.ts +18 -0
  260. package/src/generators/electron-app/files/project.json.template +65 -0
  261. package/src/generators/electron-app/files/src/main/core-client.test.ts +81 -0
  262. package/src/generators/electron-app/files/src/main/core-client.ts +55 -0
  263. package/src/generators/electron-app/files/src/main/index.ts +157 -0
  264. package/src/generators/electron-app/files/src/main/ipc.ts +52 -0
  265. package/src/generators/electron-app/files/src/main/policy.test.ts +71 -0
  266. package/src/generators/electron-app/files/src/main/policy.ts +73 -0
  267. package/src/generators/electron-app/files/src/preload/index.ts +23 -0
  268. package/src/generators/electron-app/files/src/renderer/index.html.template +20 -0
  269. package/src/generators/electron-app/files/src/renderer/src/App.test.tsx +61 -0
  270. package/src/generators/electron-app/files/src/renderer/src/App.tsx.template +43 -0
  271. package/src/generators/electron-app/files/src/renderer/src/assets/main.css +40 -0
  272. package/src/generators/electron-app/files/src/renderer/src/env.d.ts +14 -0
  273. package/src/generators/electron-app/files/src/renderer/src/main.tsx +25 -0
  274. package/src/generators/electron-app/files/src/shared/ipc.ts +54 -0
  275. package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +68 -0
  276. package/src/generators/electron-app/files/tool/electron_exec.sh.template +83 -0
  277. package/src/generators/electron-app/files/tsconfig.json +7 -0
  278. package/src/generators/electron-app/files/tsconfig.node.json +27 -0
  279. package/src/generators/electron-app/files/tsconfig.web.json +22 -0
  280. package/src/generators/electron-app/files/vitest.config.ts +32 -0
  281. package/src/generators/electron-app/files/vitest.setup.ts +1 -0
  282. package/src/generators/electron-app/generator.ts +288 -0
  283. package/src/generators/electron-app/schema.json +23 -0
  284. package/src/generators/flutter-app/docs/principles/stack/flutter/architecture.md +78 -0
  285. package/src/generators/flutter-app/docs/principles/stack/flutter/index.md +38 -0
  286. package/src/generators/flutter-app/docs/principles/stack/flutter/platform-channels.md +51 -0
  287. package/src/generators/flutter-app/docs/principles/stack/flutter/releases-and-distribution.md +59 -0
  288. package/src/generators/flutter-app/docs/principles/stack/flutter/state-management.md +85 -0
  289. package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +74 -0
  290. package/src/generators/flutter-app/docs/principles/stack/flutter/widgets-and-composition.md +69 -0
  291. package/src/generators/flutter-app/files/.gitignore.template +30 -0
  292. package/src/generators/flutter-app/files/README.md.template +100 -0
  293. package/src/generators/flutter-app/files/analysis_options.yaml.template +18 -0
  294. package/src/generators/flutter-app/files/integration_test/app_test.dart.template +30 -0
  295. package/src/generators/flutter-app/files/lib/app.dart.template +24 -0
  296. package/src/generators/flutter-app/files/lib/config/app_config.dart +15 -0
  297. package/src/generators/flutter-app/files/lib/data/repositories/status_repository.dart +36 -0
  298. package/src/generators/flutter-app/files/lib/data/services/api_client.dart +71 -0
  299. package/src/generators/flutter-app/files/lib/domain/models/health_status.dart +23 -0
  300. package/src/generators/flutter-app/files/lib/main.dart +11 -0
  301. package/src/generators/flutter-app/files/lib/router.dart +23 -0
  302. package/src/generators/flutter-app/files/lib/ui/core/theme/app_theme.dart +110 -0
  303. package/src/generators/flutter-app/files/lib/ui/home/home_view.dart +89 -0
  304. package/src/generators/flutter-app/files/lib/ui/home/home_view_model.dart.template +38 -0
  305. package/src/generators/flutter-app/files/project.json.template +51 -0
  306. package/src/generators/flutter-app/files/pubspec.yaml.template +47 -0
  307. package/src/generators/flutter-app/files/test/api_client_test.dart.template +63 -0
  308. package/src/generators/flutter-app/files/test/fakes/fake_status_repository.dart.template +19 -0
  309. package/src/generators/flutter-app/files/test/home_view_test.dart.template +58 -0
  310. package/src/generators/flutter-app/files/tool/flutter_exec.sh.template +60 -0
  311. package/src/generators/flutter-app/generator.ts +362 -0
  312. package/src/generators/flutter-app/schema.json +23 -0
  313. package/src/generators/go-microservice/docs/principles/stack/go/concurrency.md +123 -0
  314. package/src/generators/go-microservice/docs/principles/stack/go/index.md +70 -0
  315. package/src/generators/go-microservice/docs/principles/stack/go/testing.md +152 -0
  316. package/src/generators/go-microservice/files/.air.toml.template +38 -0
  317. package/src/generators/go-microservice/files/.env.template +4 -0
  318. package/src/generators/go-microservice/files/.golangci.yml.template +82 -0
  319. package/src/generators/go-microservice/files/Dockerfile.dev.template +12 -0
  320. package/src/generators/go-microservice/files/asyncapi-pubsub.yaml.template +33 -0
  321. package/src/generators/go-microservice/files/asyncapi-ws.yaml.template +34 -0
  322. package/src/generators/go-microservice/files/cmd/api/main.go.template +149 -0
  323. package/src/generators/go-microservice/files/cmd/api/main_test.go.template +99 -0
  324. package/src/generators/go-microservice/files/cmd/worker/cleanup/main.go.template +39 -0
  325. package/src/generators/go-microservice/files/db/schema.sql.template +24 -0
  326. package/src/generators/go-microservice/files/go.mod.template +39 -0
  327. package/src/generators/go-microservice/files/internal/config/config.go.template +52 -0
  328. package/src/generators/go-microservice/files/internal/config/otel.go.template +93 -0
  329. package/src/generators/go-microservice/files/internal/core/domain/errors.go.template +16 -0
  330. package/src/generators/go-microservice/files/internal/core/domain/model.go.template +28 -0
  331. package/src/generators/go-microservice/files/internal/core/domain/user.go.template +13 -0
  332. package/src/generators/go-microservice/files/internal/core/pagination.go.template +16 -0
  333. package/src/generators/go-microservice/files/internal/core/service/app_service.go.template +79 -0
  334. package/src/generators/go-microservice/files/internal/core/service/event_hub.go.template +9 -0
  335. package/src/generators/go-microservice/files/internal/core/service/message_queue.go.template +10 -0
  336. package/src/generators/go-microservice/files/internal/core/service/outbox_repository.go.template +31 -0
  337. package/src/generators/go-microservice/files/internal/core/service/repository.go.template +23 -0
  338. package/src/generators/go-microservice/files/internal/core/service/user_repository.go.template +15 -0
  339. package/src/generators/go-microservice/files/internal/core/service/user_service.go.template +43 -0
  340. package/src/generators/go-microservice/files/internal/entrypoints/api/app_handler.go.template +108 -0
  341. package/src/generators/go-microservice/files/internal/entrypoints/api/auth_middleware_test.go.template +52 -0
  342. package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook.go.template +202 -0
  343. package/src/generators/go-microservice/files/internal/entrypoints/api/clerk_webhook_test.go.template +82 -0
  344. package/src/generators/go-microservice/files/internal/entrypoints/api/health_handler.go.template +80 -0
  345. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware.go.template +87 -0
  346. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/middleware_test.go.template +76 -0
  347. package/src/generators/go-microservice/files/internal/entrypoints/api/idempotency/repository.go.template +37 -0
  348. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_auth.go.template +40 -0
  349. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_loadshed.go.template +38 -0
  350. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_logging.go.template +40 -0
  351. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_ratelimit.go.template +48 -0
  352. package/src/generators/go-microservice/files/internal/entrypoints/api/middleware_test.go.template +81 -0
  353. package/src/generators/go-microservice/files/internal/entrypoints/api/router.go.template +105 -0
  354. package/src/generators/go-microservice/files/internal/entrypoints/api/types.go.template +70 -0
  355. package/src/generators/go-microservice/files/internal/entrypoints/api/websocket_handler.go.template +39 -0
  356. package/src/generators/go-microservice/files/internal/httpclient/http_client.go.template +87 -0
  357. package/src/generators/go-microservice/files/internal/kafka/kafka.go.template +34 -0
  358. package/src/generators/go-microservice/files/internal/postgres/postgres.go.template +195 -0
  359. package/src/generators/go-microservice/files/internal/postgres/postgres_test.go.template +156 -0
  360. package/src/generators/go-microservice/files/internal/postgres/user_repository.go.template +56 -0
  361. package/src/generators/go-microservice/files/internal/pubsub/gcp_pubsub.go.template +35 -0
  362. package/src/generators/go-microservice/files/internal/websocket/client.go.template +151 -0
  363. package/src/generators/go-microservice/files/internal/websocket/hub.go.template +261 -0
  364. package/src/generators/go-microservice/files/scripts/apply-schema.sh.template +21 -0
  365. package/src/generators/go-microservice/files/tools/tools.go.template +10 -0
  366. package/src/generators/go-microservice/generator.ts +240 -0
  367. package/src/generators/go-microservice/schema.json +63 -0
  368. package/src/generators/nextjs-app/docs/principles/stack/typescript/frontend.md +65 -0
  369. package/src/generators/nextjs-app/files/.dockerignore.template +7 -0
  370. package/src/generators/nextjs-app/files/.env.example.template +24 -0
  371. package/src/generators/nextjs-app/files/.gitignore.template +5 -0
  372. package/src/generators/nextjs-app/files/Dockerfile +53 -0
  373. package/src/generators/nextjs-app/files/app/(auth)/sign-in/__sign-in__/page.tsx.template +9 -0
  374. package/src/generators/nextjs-app/files/app/(auth)/sign-up/__sign-up__/page.tsx.template +9 -0
  375. package/src/generators/nextjs-app/files/app/api/config/route.ts.template +39 -0
  376. package/src/generators/nextjs-app/files/app/api/healthz/route.test.ts +15 -0
  377. package/src/generators/nextjs-app/files/app/api/healthz/route.ts +5 -0
  378. package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.test.ts.template +55 -0
  379. package/src/generators/nextjs-app/files/app/api/proxy/__path__/route.ts.template +126 -0
  380. package/src/generators/nextjs-app/files/app/error.tsx +39 -0
  381. package/src/generators/nextjs-app/files/app/global-error.tsx +68 -0
  382. package/src/generators/nextjs-app/files/app/globals.css +105 -0
  383. package/src/generators/nextjs-app/files/app/layout.tsx +59 -0
  384. package/src/generators/nextjs-app/files/app/loading.tsx +13 -0
  385. package/src/generators/nextjs-app/files/app/not-found.tsx +30 -0
  386. package/src/generators/nextjs-app/files/app/page.tsx +20 -0
  387. package/src/generators/nextjs-app/files/components/providers/default.tsx +19 -0
  388. package/src/generators/nextjs-app/files/components/providers/production.tsx +32 -0
  389. package/src/generators/nextjs-app/files/components/providers/telemetry.tsx +76 -0
  390. package/src/generators/nextjs-app/files/components/render-smoke.test.tsx +29 -0
  391. package/src/generators/nextjs-app/files/components/theme-provider.tsx +11 -0
  392. package/src/generators/nextjs-app/files/components.json +21 -0
  393. package/src/generators/nextjs-app/files/eslint.config.mjs +120 -0
  394. package/src/generators/nextjs-app/files/hooks/use-toast.ts +7 -0
  395. package/src/generators/nextjs-app/files/instrumentation.ts +90 -0
  396. package/src/generators/nextjs-app/files/lib/api/fetcher.ts.template +130 -0
  397. package/src/generators/nextjs-app/files/lib/config.ts +21 -0
  398. package/src/generators/nextjs-app/files/lib/logger.ts +29 -0
  399. package/src/generators/nextjs-app/files/lib/schemas/index.ts +19 -0
  400. package/src/generators/nextjs-app/files/lib/utils.ts +6 -0
  401. package/src/generators/nextjs-app/files/next.config.mjs +9 -0
  402. package/src/generators/nextjs-app/files/package.json +70 -0
  403. package/src/generators/nextjs-app/files/postcss.config.mjs +8 -0
  404. package/src/generators/nextjs-app/files/proxy.test.ts.template +30 -0
  405. package/src/generators/nextjs-app/files/proxy.ts +31 -0
  406. package/src/generators/nextjs-app/files/public/.gitkeep +1 -0
  407. package/src/generators/nextjs-app/files/tsconfig.json +42 -0
  408. package/src/generators/nextjs-app/files/vitest.config.mts +15 -0
  409. package/src/generators/nextjs-app/files/vitest.setup.ts +7 -0
  410. package/src/generators/nextjs-app/generator.ts +307 -0
  411. package/src/generators/nextjs-app/schema.json +44 -0
  412. package/src/generators/python-microservice/docs/principles/stack/python/async.md +168 -0
  413. package/src/generators/python-microservice/docs/principles/stack/python/documentation.md +240 -0
  414. package/src/generators/python-microservice/docs/principles/stack/python/mcp.md +147 -0
  415. package/src/generators/python-microservice/docs/principles/stack/python/resilience.md +193 -0
  416. package/src/generators/python-microservice/docs/principles/stack/python/testing.md +281 -0
  417. package/src/generators/python-microservice/files/.env.example.template +30 -0
  418. package/src/generators/python-microservice/files/Dockerfile.template +36 -0
  419. package/src/generators/python-microservice/files/db/schema.sql.template +19 -0
  420. package/src/generators/python-microservice/files/pyproject.toml.template +76 -0
  421. package/src/generators/python-microservice/files/scripts/apply-schema.sh.template +25 -0
  422. package/src/generators/python-microservice/files/src/__packageName__/adapters/comfyui.py.template +87 -0
  423. package/src/generators/python-microservice/files/src/__packageName__/adapters/config.py.template +48 -0
  424. package/src/generators/python-microservice/files/src/__packageName__/adapters/database.py.template +21 -0
  425. package/src/generators/python-microservice/files/src/__packageName__/adapters/message_queue.py.template +29 -0
  426. package/src/generators/python-microservice/files/src/__packageName__/adapters/repository.py.template +130 -0
  427. package/src/generators/python-microservice/files/src/__packageName__/adapters/telemetry.py.template +68 -0
  428. package/src/generators/python-microservice/files/src/__packageName__/adapters/websocket_hub.py.template +36 -0
  429. package/src/generators/python-microservice/files/src/__packageName__/core/domain/entities.py.template +22 -0
  430. package/src/generators/python-microservice/files/src/__packageName__/core/domain/exceptions.py.template +43 -0
  431. package/src/generators/python-microservice/files/src/__packageName__/core/ports.py.template +42 -0
  432. package/src/generators/python-microservice/files/src/__packageName__/core/service/example_service.py.template +68 -0
  433. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/dependencies.py.template +50 -0
  434. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/middleware.py.template +131 -0
  435. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/router.py.template +37 -0
  436. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/api/websocket_handler.py.template +20 -0
  437. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/cleanup.py.template +35 -0
  438. package/src/generators/python-microservice/files/src/__packageName__/entrypoints/worker/worker.py.template +28 -0
  439. package/src/generators/python-microservice/files/src/__packageName__/main.py.template +108 -0
  440. package/src/generators/python-microservice/files/tests/test_main.py.template +74 -0
  441. package/src/generators/python-microservice/files/tests/test_middleware.py.template +109 -0
  442. package/src/generators/python-microservice/files/tests/test_worker.py.template +16 -0
  443. package/src/generators/python-microservice/generator.ts +286 -0
  444. package/src/generators/python-microservice/schema.json +86 -0
  445. package/src/generators/shared/brand-tokens.ts +301 -0
  446. package/src/generators/shared/capabilities.ts +349 -0
  447. package/src/generators/shared/provenance.ts +61 -0
  448. package/src/generators/shared/scaffold-helpers.ts +309 -0
  449. package/src/generators/system-test-runner/files/tests/bets/.gitkeep +0 -0
  450. package/src/generators/system-test-runner/files/tests/bets/_archive/.gitkeep +0 -0
  451. package/src/generators/system-test-runner/files/tests/conftest.py.template +503 -0
  452. package/src/generators/system-test-runner/files/tests/pyproject.toml.template +20 -0
  453. package/src/generators/system-test-runner/files/tests/system/pages/__init__.py.template +9 -0
  454. package/src/generators/system-test-runner/files/tests/system/pages/base_page.py.template +36 -0
  455. package/src/generators/system-test-runner/files/tests/system/test_a11y_smoke.py.template +132 -0
  456. package/src/generators/system-test-runner/files/tests/system/test_contract_conformance.py.template +140 -0
  457. package/src/generators/system-test-runner/files/tests/system/test_layout_geometry.py.template +109 -0
  458. package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +227 -0
  459. package/src/generators/system-test-runner/files/tests/system/test_system.py.template +158 -0
  460. package/src/generators/system-test-runner/files/tests/system/test_token_conformance.py.template +206 -0
  461. package/src/generators/system-test-runner/files/tests/system/test_visual_regression.py.template +104 -0
  462. package/src/generators/system-test-runner/generator.ts +142 -0
  463. package/src/generators/system-test-runner/schema.json +24 -0
  464. package/src/generators/workspace-dev-cli/cli-src/build.mjs +42 -0
  465. package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +2168 -0
  466. package/src/generators/workspace-dev-cli/cli-src/src/commands/bet.ts +442 -0
  467. package/src/generators/workspace-dev-cli/cli-src/src/commands/completion.ts +87 -0
  468. package/src/generators/workspace-dev-cli/cli-src/src/commands/doctor.ts +139 -0
  469. package/src/generators/workspace-dev-cli/cli-src/src/commands/lifecycle.ts +548 -0
  470. package/src/generators/workspace-dev-cli/cli-src/src/commands/quality.ts +127 -0
  471. package/src/generators/workspace-dev-cli/cli-src/src/commands/surface.ts +214 -0
  472. package/src/generators/workspace-dev-cli/cli-src/src/index.ts +127 -0
  473. package/src/generators/workspace-dev-cli/cli-src/src/registry.ts +194 -0
  474. package/src/generators/workspace-dev-cli/cli-src/src/theme/color.ts +130 -0
  475. package/src/generators/workspace-dev-cli/cli-src/src/theme/render.ts +158 -0
  476. package/src/generators/workspace-dev-cli/cli-src/src/theme/tokens.ts +122 -0
  477. package/src/generators/workspace-dev-cli/cli-src/src/util/context.ts +43 -0
  478. package/src/generators/workspace-dev-cli/cli-src/src/util/extensions.ts +99 -0
  479. package/src/generators/workspace-dev-cli/cli-src/src/util/paths.ts +46 -0
  480. package/src/generators/workspace-dev-cli/cli-src/src/util/proc.ts +106 -0
  481. package/src/generators/workspace-dev-cli/cli-src/src/util/prompt.ts +108 -0
  482. package/src/generators/workspace-dev-cli/cli-src/src/util/runners.ts +70 -0
  483. package/src/generators/workspace-dev-cli/cli-src/src/util/services.ts +221 -0
  484. package/src/generators/workspace-dev-cli/cli-src/src/util/version.ts +21 -0
  485. package/src/generators/workspace-dev-cli/cli-src/tsconfig.json +16 -0
  486. package/src/generators/workspace-dev-cli/files/.agents/skills/workspace-cli/SKILL.md.template +74 -0
  487. package/src/generators/workspace-dev-cli/files/dev.template +16 -0
  488. package/src/generators/workspace-dev-cli/files/docker-compose.yml.template +20 -0
  489. package/src/generators/workspace-dev-cli/files/scripts/cli/templates/milestone-test.pytmpl.template +46 -0
  490. package/src/generators/workspace-dev-cli/files/scripts/cli/templates/slice-test.pytmpl.template +38 -0
  491. package/src/generators/workspace-dev-cli/generator.ts +136 -0
  492. package/src/generators/workspace-dev-cli/schema.json +22 -0
  493. package/src/hidden-skills/code-intelligence.md +129 -0
  494. package/src/hidden-skills/groundwork-architect/SKILL.md +114 -0
  495. package/src/hidden-skills/groundwork-architect/references/agentic-systems.md +44 -0
  496. package/src/hidden-skills/groundwork-architect/references/ai-native-architecture.md +37 -0
  497. package/src/hidden-skills/groundwork-architect/references/api-and-contracts.md +45 -0
  498. package/src/hidden-skills/groundwork-architect/references/core-and-boundaries.md +45 -0
  499. package/src/hidden-skills/groundwork-architect/references/data-architecture.md +33 -0
  500. package/src/hidden-skills/groundwork-architect/references/decision-records.md +34 -0
  501. package/src/hidden-skills/groundwork-architect/references/durable-execution.md +45 -0
  502. package/src/hidden-skills/groundwork-architect/references/evolutionary-architecture.md +37 -0
  503. package/src/hidden-skills/groundwork-architect/references/identity-and-access.md +41 -0
  504. package/src/hidden-skills/groundwork-architect/references/integration-patterns.md +39 -0
  505. package/src/hidden-skills/groundwork-architect/references/observability.md +36 -0
  506. package/src/hidden-skills/groundwork-architect/references/performance-and-scale.md +41 -0
  507. package/src/hidden-skills/groundwork-architect/references/platform-and-delivery.md +47 -0
  508. package/src/hidden-skills/groundwork-architect/references/realtime-and-async.md +28 -0
  509. package/src/hidden-skills/groundwork-architect/references/reliability.md +31 -0
  510. package/src/hidden-skills/groundwork-architect/references/security-and-trust.md +47 -0
  511. package/src/hidden-skills/groundwork-architect/references/surface-architecture.md +40 -0
  512. package/src/hidden-skills/groundwork-architect/sync-anchor.md +34 -0
  513. package/src/hidden-skills/groundwork-architecture/architecture-template.md +50 -0
  514. package/src/hidden-skills/groundwork-architecture/instructions.md +139 -0
  515. package/src/hidden-skills/groundwork-architecture/phases/01-context-ingestion.md +18 -0
  516. package/src/hidden-skills/groundwork-architecture/phases/02-technical-constraints.md +27 -0
  517. package/src/hidden-skills/groundwork-architecture/phases/03-service-design.md +19 -0
  518. package/src/hidden-skills/groundwork-architecture/phases/04-data-flow-communication.md +23 -0
  519. package/src/hidden-skills/groundwork-architecture/phases/05-component-boundaries-contracts.md +17 -0
  520. package/src/hidden-skills/groundwork-architecture/phases/06-draft-review-present.md +38 -0
  521. package/src/hidden-skills/groundwork-architecture/phases/07-commit.md +33 -0
  522. package/src/hidden-skills/groundwork-architecture/templates/architecture-cache.md +43 -0
  523. package/src/hidden-skills/groundwork-architecture-extract/instructions.md +163 -0
  524. package/src/hidden-skills/groundwork-architecture-extract/templates/architecture-extract-cache.md +21 -0
  525. package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +191 -0
  526. package/src/hidden-skills/groundwork-bet/instructions.md +88 -0
  527. package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +126 -0
  528. package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +38 -0
  529. package/src/hidden-skills/groundwork-bet/templates/decomposition/meta.json +4 -0
  530. package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +35 -0
  531. package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +35 -0
  532. package/src/hidden-skills/groundwork-bet/templates/pitch.md +45 -0
  533. package/src/hidden-skills/groundwork-bet/templates/technical-design/01-ui-design.md +51 -0
  534. package/src/hidden-skills/groundwork-bet/templates/technical-design/02-data-flows.md +36 -0
  535. package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +90 -0
  536. package/src/hidden-skills/groundwork-bet/templates/technical-design/04-data-design.md +29 -0
  537. package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +198 -0
  538. package/src/hidden-skills/groundwork-bet/workflows/02-design.md +168 -0
  539. package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +246 -0
  540. package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +193 -0
  541. package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +199 -0
  542. package/src/hidden-skills/groundwork-design-system/instructions.md +125 -0
  543. package/src/hidden-skills/groundwork-design-system/templates/brand-tokens.md +182 -0
  544. package/src/hidden-skills/groundwork-design-system/templates/design-system-cache.md +64 -0
  545. package/src/hidden-skills/groundwork-design-system/tracks/_foundation.md +136 -0
  546. package/src/hidden-skills/groundwork-design-system/tracks/agentic-protocol.md +269 -0
  547. package/src/hidden-skills/groundwork-design-system/tracks/cli.md +355 -0
  548. package/src/hidden-skills/groundwork-design-system/tracks/graphical-ui.md +330 -0
  549. package/src/hidden-skills/groundwork-design-system-extract/instructions.md +124 -0
  550. package/src/hidden-skills/groundwork-design-system-extract/templates/design-system-extract-cache.md +19 -0
  551. package/src/hidden-skills/groundwork-designer/SKILL.md +108 -0
  552. package/src/hidden-skills/groundwork-designer/references/accessibility.md +33 -0
  553. package/src/hidden-skills/groundwork-designer/references/ai-native-design.md +37 -0
  554. package/src/hidden-skills/groundwork-designer/references/design-review.md +29 -0
  555. package/src/hidden-skills/groundwork-designer/references/design-systems-and-tokens.md +33 -0
  556. package/src/hidden-skills/groundwork-designer/references/interaction-and-motion.md +37 -0
  557. package/src/hidden-skills/groundwork-designer/references/layout-and-space.md +33 -0
  558. package/src/hidden-skills/groundwork-designer/references/usability-and-ux.md +33 -0
  559. package/src/hidden-skills/groundwork-designer/references/visual-craft.md +49 -0
  560. package/src/hidden-skills/groundwork-designer/sync-anchor.md +20 -0
  561. package/src/hidden-skills/groundwork-doc-sync/instructions.md +100 -0
  562. package/src/hidden-skills/groundwork-elicit/instructions.md +66 -0
  563. package/src/hidden-skills/groundwork-elicit/methods.md +65 -0
  564. package/src/hidden-skills/groundwork-infra-adopt/instructions.md +168 -0
  565. package/src/hidden-skills/groundwork-infra-adopt/templates/infra-adopt-cache.md +21 -0
  566. package/src/hidden-skills/groundwork-mvp/instructions.md +223 -0
  567. package/src/hidden-skills/groundwork-mvp/templates/mvp-cache.md +9 -0
  568. package/src/hidden-skills/groundwork-patch/instructions.md +40 -0
  569. package/src/hidden-skills/groundwork-persona/instructions.md +54 -0
  570. package/src/hidden-skills/groundwork-product/SKILL.md +102 -0
  571. package/src/hidden-skills/groundwork-product/references/ai-native-product.md +45 -0
  572. package/src/hidden-skills/groundwork-product/references/discovery-and-opportunity.md +38 -0
  573. package/src/hidden-skills/groundwork-product/references/product-risks.md +52 -0
  574. package/src/hidden-skills/groundwork-product/references/requirements-and-specs.md +39 -0
  575. package/src/hidden-skills/groundwork-product/references/scope-and-sequencing.md +35 -0
  576. package/src/hidden-skills/groundwork-product/references/shaping-and-appetite.md +48 -0
  577. package/src/hidden-skills/groundwork-product/references/success-metrics-and-signals.md +37 -0
  578. package/src/hidden-skills/groundwork-product/sync-anchor.md +19 -0
  579. package/src/hidden-skills/groundwork-product-brief/instructions.md +231 -0
  580. package/src/hidden-skills/groundwork-product-brief-extract/instructions.md +139 -0
  581. package/src/hidden-skills/groundwork-product-brief-extract/templates/product-brief-extract-cache.md +17 -0
  582. package/src/hidden-skills/groundwork-review/checklists/architecture.md +93 -0
  583. package/src/hidden-skills/groundwork-review/checklists/bet-pitch.md +94 -0
  584. package/src/hidden-skills/groundwork-review/checklists/decomposition.md +135 -0
  585. package/src/hidden-skills/groundwork-review/checklists/design-system.md +85 -0
  586. package/src/hidden-skills/groundwork-review/checklists/domain-entity.md +66 -0
  587. package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +46 -0
  588. package/src/hidden-skills/groundwork-review/checklists/infrastructure.md +68 -0
  589. package/src/hidden-skills/groundwork-review/checklists/maturity.md +71 -0
  590. package/src/hidden-skills/groundwork-review/checklists/product-brief.md +69 -0
  591. package/src/hidden-skills/groundwork-review/checklists/technical-design.md +112 -0
  592. package/src/hidden-skills/groundwork-review/instructions.md +181 -0
  593. package/src/hidden-skills/groundwork-scaffold/instructions.md +254 -0
  594. package/src/hidden-skills/groundwork-scaffold/phases/01-ingestion-service-mapping.md +87 -0
  595. package/src/hidden-skills/groundwork-scaffold/phases/02-scaffolding-execution.md +15 -0
  596. package/src/hidden-skills/groundwork-scaffold/phases/03-service-documentation-api-stubs.md +100 -0
  597. package/src/hidden-skills/groundwork-scaffold/phases/04-infrastructure-verification.md +17 -0
  598. package/src/hidden-skills/groundwork-scaffold/phases/05-draft-review.md +19 -0
  599. package/src/hidden-skills/groundwork-scaffold/phases/06-commit.md +19 -0
  600. package/src/hidden-skills/groundwork-scaffold/templates/scaffold-cache.md +23 -0
  601. package/src/hidden-skills/groundwork-scan/instructions.md +164 -0
  602. package/src/hidden-skills/groundwork-scan/references/digest-schema.md +66 -0
  603. package/src/hidden-skills/groundwork-scan/references/exclusions.md +44 -0
  604. package/src/hidden-skills/groundwork-scan/templates/architecture-findings.md +42 -0
  605. package/src/hidden-skills/groundwork-scan/templates/design-findings.md +23 -0
  606. package/src/hidden-skills/groundwork-scan/templates/overview.md +26 -0
  607. package/src/hidden-skills/groundwork-scan/templates/product-findings.md +23 -0
  608. package/src/hidden-skills/groundwork-scan/templates/scan-state.json +19 -0
  609. package/src/hidden-skills/groundwork-stack-forge/instructions.md +150 -0
  610. package/src/hidden-skills/groundwork-stack-forge/references/authoring-engineer-skills.md +107 -0
  611. package/src/hidden-skills/groundwork-surface-activation/instructions.md +138 -0
  612. package/src/hidden-skills/groundwork-update/briefs/reconcile-worker.md +196 -0
  613. package/src/hidden-skills/groundwork-update/instructions.md +200 -0
  614. package/src/hidden-skills/groundwork-writer/SKILL.md +278 -0
  615. package/src/hidden-skills/maturity-model.md +125 -0
  616. package/src/hidden-skills/operating-contract.md +400 -0
  617. package/src/hidden-skills/repo-map-schema.md +90 -0
  618. package/src/hidden-skills/templates/adr.md +57 -0
  619. package/src/hidden-skills/templates/capability-ports.md +71 -0
  620. package/src/hidden-skills/templates/discovery-notes.md +33 -0
  621. package/src/hidden-skills/templates/domain-entity.md +80 -0
  622. package/src/hidden-skills/templates/gap-ledger.md +21 -0
  623. package/src/hidden-skills/templates/handoff.md +37 -0
  624. package/src/hidden-skills/templates/maturity.md +39 -0
  625. package/src/hidden-skills/templates/surfaces.md +207 -0
  626. package/src/skills/groundwork-check/SKILL.md +56 -0
  627. package/src/skills/groundwork-check/instructions.md +70 -0
  628. package/src/skills/groundwork-orchestrator/SKILL.md +176 -0
  629. package/src/skills/groundwork-orchestrator/workflow-index.md +50 -0
@@ -0,0 +1,281 @@
1
+ ---
2
+ title: Testing
3
+ description: Honeycomb testing for Python microservices — service-perimeter tests as the default, unit tests reserved for complex isolated logic.
4
+ status: active
5
+ last_reviewed: 2026-05-26
6
+ ---
7
+
8
+ # Testing
9
+
10
+ ## TL;DR
11
+
12
+ We test from the perimeter of the service inward. A request goes in through the HTTP entrypoint, traverses real service and provider logic, and comes back out — with real infrastructure running in containers. Unit tests are reserved for logic so complex it earns isolation. Most tests never see a mock.
13
+
14
+ ---
15
+
16
+ ## The Model: Why Honeycomb, Not Pyramid
17
+
18
+ The classical test pyramid (many unit tests → some integration tests → few E2E tests) made sense when running a database in a test was expensive and slow. That constraint no longer exists. Testcontainers spins up a real Postgres or Pub/Sub emulator in seconds, and the confidence it provides is categorically different from any mock.
19
+
20
+ The failure mode of a mock-heavy suite is insidious: tests pass while production breaks. Mocked adapters drift from real behaviour. SQL queries are never exercised. Serialisation boundaries are never crossed. The suite is green and the system is broken.
21
+
22
+ The **honeycomb model** inverts the priority:
23
+
24
+ - **Service tests are the default.** The bulk of test coverage comes from tests that exercise the full vertical slice — HTTP in, real infrastructure out.
25
+ - **Unit tests are reserved.** Complex isolated algorithms, domain computations, and pure validation logic earn a unit test. Everything else does not.
26
+ - **System tests are minimal.** A bootstrap test verifies the DI container wires correctly. A small number of golden-path tests exercise the service end-to-end against a live stack.
27
+
28
+ This gives us a suite where a passing run is a meaningful signal. The bugs we care about — boundary mismatches, SQL correctness, serialisation errors, provider contract violations — are caught before they reach production.
29
+
30
+ ---
31
+
32
+ ## The Three Tiers
33
+
34
+ ### Tier 1 — Service Tests (the default)
35
+
36
+ A service test drives the FastAPI app through its HTTP interface using `httpx.AsyncClient` with `ASGITransport`. Infrastructure dependencies (Pub/Sub, storage, databases) run in containers. Provider dependencies that cannot be containerised are replaced at the FastAPI dependency boundary using `dependency_overrides` — not mocked in the interior of the code.
37
+
38
+ This is the tier where most new tests belong. If you are testing a use case, an endpoint, a pipeline step, or a provider interaction with infrastructure — write a service test.
39
+
40
+ **Structure:**
41
+
42
+ ```
43
+ tests/
44
+ integration/
45
+ entrypoints/ # HTTP-level service tests
46
+ providers/ # Provider tests against real containers or live APIs
47
+ ```
48
+
49
+ **Fixture setup — app + async client:**
50
+
51
+ ```python
52
+ # tests/integration/conftest.py
53
+ import pytest
54
+ import httpx
55
+ from app.main import create_app
56
+
57
+ @pytest.fixture(scope="session")
58
+ def app():
59
+ return create_app()
60
+
61
+ @pytest.fixture
62
+ async def client(app):
63
+ async with httpx.AsyncClient(
64
+ transport=httpx.ASGITransport(app=app),
65
+ base_url="http://test",
66
+ ) as c:
67
+ yield c
68
+ ```
69
+
70
+ **Fixture setup — containerised infrastructure:**
71
+
72
+ ```python
73
+ # tests/integration/conftest.py (continued)
74
+ import pytest
75
+ from testcontainers.postgres import PostgresContainer
76
+ from testcontainers.google import PubSubContainer
77
+
78
+ @pytest.fixture(scope="session")
79
+ def postgres():
80
+ with PostgresContainer("postgres:16-alpine") as container:
81
+ yield container
82
+
83
+ @pytest.fixture(scope="session")
84
+ def pubsub():
85
+ with PubSubContainer() as container:
86
+ yield container
87
+ ```
88
+
89
+ Scope containers at `session` when startup cost is high. Reset state between tests using transactions or truncation, not by restarting the container.
90
+
91
+ **Replacing non-containerisable providers:**
92
+
93
+ When a provider calls a live third-party API, replace it at the FastAPI boundary — not by patching the internals:
94
+
95
+ ```python
96
+ # tests/integration/entrypoints/test_transcribe_api.py
97
+ import pytest
98
+ from unittest.mock import AsyncMock
99
+ from app.entrypoints.api.dependencies import get_transcriber
100
+ from app.core.domain.models import Transcript
101
+
102
+ @pytest.fixture
103
+ def fake_transcriber():
104
+ port = AsyncMock()
105
+ port.transcribe.return_value = Transcript(...)
106
+ return port
107
+
108
+ async def test_transcribe_returns_structured_result(client, app, fake_transcriber):
109
+ app.dependency_overrides[get_transcriber] = lambda: fake_transcriber
110
+
111
+ response = await client.post("/transcribe", json={"audio_url": "gs://bucket/file.mp3"})
112
+
113
+ assert response.status_code == 200
114
+ assert response.json()["segments"][0]["confidence"] >= 0.0
115
+ ```
116
+
117
+ The key distinction: we are replacing the provider at the dependency injection boundary. The route handler, service, and validation logic all run for real. Only the external API call is substituted.
118
+
119
+ **Live provider tests** (requiring real API keys) live in `tests/integration/providers/` and are marked `@pytest.mark.live` so they can be excluded from normal runs with pytest's `-m` flag:
120
+
121
+ ```python
122
+ @pytest.mark.live
123
+ async def test_assemblyai_transcribes_real_audio(transcriber, audio_fixture):
124
+ result = await transcriber.transcribe(audio_fixture)
125
+ assert len(result.segments) > 0
126
+ assert result.metadata.duration > 0
127
+ ```
128
+
129
+ Run with: `uv run pytest tests/integration -m live`
130
+
131
+ ---
132
+
133
+ ### Tier 2 — Unit Tests (reserved)
134
+
135
+ A unit test is appropriate when the logic is genuinely complex, has many branches, operates on pure data, and would be painful to exercise through the full HTTP stack. Domain model invariants, audio codec transformations, confidence score calculations, and parsing algorithms are good candidates.
136
+
137
+ The test for "does this service method call the adapter and return the result" is not a unit test. That behaviour is validated by a service test.
138
+
139
+ **What earns a unit test:**
140
+
141
+ - Domain models: immutability, field validation, business rules
142
+ - Complex transformations: audio resampling, segment merging, transcript normalisation
143
+ - Pure algorithms: confidence thresholding, speaker attribution logic, chunking strategies
144
+ - Edge cases too costly to set up through a real HTTP path
145
+
146
+ **What does not earn a unit test:**
147
+
148
+ - Service methods that orchestrate calls between an adapter and a domain object
149
+ - Endpoint handlers that validate input and delegate
150
+ - Providers that translate SDK responses into domain types
151
+
152
+ **Pattern — domain model:**
153
+
154
+ ```python
155
+ # tests/unit/core/domain/test_transcript.py
156
+ class TestTranscriptSegment:
157
+ def test_rejects_confidence_above_one(self):
158
+ with pytest.raises(ValidationError):
159
+ TranscriptSegment(text="hello", confidence=1.5, start=0.0, end=1.0)
160
+
161
+ def test_is_immutable(self):
162
+ segment = TranscriptSegment(text="hello", confidence=0.9, start=0.0, end=1.0)
163
+ with pytest.raises(ValidationError):
164
+ segment.text = "goodbye"
165
+ ```
166
+
167
+ **Pattern — complex algorithm:**
168
+
169
+ ```python
170
+ # tests/unit/providers/test_audio_codec.py
171
+ class TestResample:
172
+ def test_output_matches_target_sample_rate(self, codec, wav_16khz):
173
+ result = codec.resample(wav_16khz, target_hz=8000)
174
+ assert result.sample_rate == 8000
175
+
176
+ def test_duration_is_preserved_within_tolerance(self, codec, wav_16khz):
177
+ result = codec.resample(wav_16khz, target_hz=8000)
178
+ assert abs(result.duration - wav_16khz.duration) < 0.01
179
+ ```
180
+
181
+ ---
182
+
183
+ ### Tier 3 — System Tests (minimal)
184
+
185
+ System tests answer one question: does the fully-wired application start and serve requests correctly? There are two of them.
186
+
187
+ **Bootstrap test** — verifies the DI container initialises without error. Catches missing environment variables, wiring mistakes, and import-time failures before they hit production:
188
+
189
+ ```python
190
+ # tests/system/test_bootstrap.py
191
+ def test_application_starts_without_error():
192
+ app = create_app()
193
+ assert app is not None
194
+ ```
195
+
196
+ **Golden path test** — one end-to-end test per critical user journey, run against the full live stack in CI. Not a substitute for service tests; a smoke check that the seams hold.
197
+
198
+ ---
199
+
200
+ ## Async Configuration
201
+
202
+ All test functions are async by default. `asyncio_mode = "auto"` in `pyproject.toml` means no decorator is needed:
203
+
204
+ ```toml
205
+ [tool.pytest.ini_options]
206
+ asyncio_mode = "auto"
207
+ ```
208
+
209
+ Write async tests as plain `async def` functions:
210
+
211
+ ```python
212
+ async def test_streaming_session_emits_events(client):
213
+ response = await client.post("/streaming/start", json={"meeting_id": "m-1"})
214
+ assert response.status_code == 200
215
+ ```
216
+
217
+ Do not use `@pytest.mark.asyncio` — it is redundant under auto mode and adds noise.
218
+
219
+ ---
220
+
221
+ ## Test Isolation
222
+
223
+ **Container-backed tests** should not share state. Use one of:
224
+
225
+ - **Transaction rollback** — wrap each test in a transaction and roll back on teardown. Zero teardown cost, guaranteed clean state.
226
+ - **Truncation fixture** — truncate relevant tables in a `function`-scoped fixture. Slower but simpler when transactions interfere with the code under test.
227
+
228
+ Never rely on test ordering to manage state. A test that requires a previous test to have run is a broken test.
229
+
230
+ **`dependency_overrides` cleanup** — always reset overrides after a test to prevent state leaking between tests:
231
+
232
+ ```python
233
+ @pytest.fixture(autouse=True)
234
+ def reset_dependency_overrides(app):
235
+ yield
236
+ app.dependency_overrides.clear()
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Naming
242
+
243
+ Every test name describes observable behaviour, not implementation:
244
+
245
+ ```python
246
+ # Good
247
+ async def test_transcribe_returns_422_when_audio_url_is_missing(client): ...
248
+ async def test_streaming_session_assigns_unique_id_per_meeting(client): ...
249
+
250
+ # Bad
251
+ async def test_transcribe_success(client): ...
252
+ async def test_streaming(client): ...
253
+ ```
254
+
255
+ A failing test name should give an on-call engineer enough information to form a hypothesis without opening the test file.
256
+
257
+ ---
258
+
259
+ ## Running Tests
260
+
261
+ ```bash
262
+ uv run pytest tests/unit # Unit tests — no infrastructure required
263
+ uv run pytest tests/integration -m "not live" # Service tests — requires Docker; skips live APIs
264
+ uv run pytest tests/integration -m live # Live API provider tests — requires real keys
265
+ uv run pytest tests/system # Bootstrap + golden path
266
+ uv run pytest # Everything
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Anti-Patterns
272
+
273
+ **Mocking the interior of a service.** Replacing an adapter with `MagicMock` inside a service test asserts nothing about real behaviour. If you are mocking something that could run in a container, use a container.
274
+
275
+ **Testing that delegation happens.** `assert transcriber.transcribe.called_once_with(segment)` is an assertion about the implementation, not the behaviour. Test what comes back out of the system, not which internal methods were invoked.
276
+
277
+ **Fixture factories that mirror the domain.** A fixture that constructs a complex domain object with many defaults trains engineers to not think about what data matters for the test. Construct only what the test needs; leave everything else visible.
278
+
279
+ **`scope="session"` on mutable state.** Session-scoped fixtures that hold mutable objects leak state between tests. Containers are safe at session scope. Application state is not.
280
+
281
+ **Skipping the async client.** `TestClient` is a synchronous wrapper that hides async behaviour. Use `httpx.AsyncClient` with `ASGITransport` for all entrypoint tests so the lifespan and async middleware execute correctly.
@@ -0,0 +1,30 @@
1
+ # Environment Configuration
2
+ # Copy this file to .env and fill in the values.
3
+
4
+ # HTTP server port for this service.
5
+ SERVER_PORT=<%= assignedPort %>
6
+ <% if (postgres) { %>
7
+ # Postgres connection (composed into the async DSN by the service config).
8
+ DB_HOST=localhost
9
+ DB_PORT=5432
10
+ DB_USER=postgres
11
+ DB_PASSWORD=postgres
12
+ DB_NAME=<%= fileName %>
13
+ <% } %>
14
+ <% if (messaging === 'redis' || websockets) { %>
15
+ # Redis (message bus and/or WebSocket backplane).
16
+ REDIS_URL=redis://localhost:6379
17
+ <% } %>
18
+ <% if (messaging === 'kafka') { %>
19
+ # Kafka broker list (comma-separated host:port).
20
+ KAFKA_BROKERS=localhost:9092
21
+ <% } %>
22
+ <% if (messaging === 'gcp-pubsub') { %>
23
+ # GCP Pub/Sub project id (use any value when running against the emulator).
24
+ PUBSUB_PROJECT_ID=local-project
25
+ <% } %>
26
+ # OpenTelemetry OTLP gRPC endpoint for trace export. Docker compose injects the
27
+ # in-cluster Jaeger address; this default covers native (`./dev start`) runs.
28
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
29
+ <%# LLM env vars are written by the llm capability footprint (plan WS-F) so they
30
+ match the chosen provider's defaults — see the "# llm capability" block. %>
@@ -0,0 +1,36 @@
1
+ FROM python:3.12-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # Install system dependencies (e.g. for psycopg2, if needed)
6
+ RUN apt-get update && apt-get install -y --no-install-recommends \
7
+ build-essential \
8
+ libpq-dev \
9
+ && rm -rf /var/lib/apt/lists/*
10
+
11
+ # Install uv for fast dependency resolution
12
+ RUN pip install uv
13
+
14
+ COPY pyproject.toml .
15
+ # Compile locked requirements for layer caching, then install
16
+ RUN uv pip compile pyproject.toml -o requirements.txt \
17
+ && uv pip install --system -r requirements.txt
18
+
19
+ COPY src/ ./src/
20
+ # src-layout: the importable package is src/<%= packageName %>, so the source root
21
+ # (not the app root) is what goes on the import path.
22
+ ENV PYTHONPATH=/app/src
23
+ <% if (postgres) { %>
24
+ # Declarative schema (db/schema.sql) + apply-schema.sh, applied by `./dev migrate`.
25
+ COPY db/ ./db/
26
+ COPY scripts/ ./scripts/
27
+ <% } %>
28
+
29
+ <% if (runpod) { %>
30
+ # Runpod serverless entrypoint
31
+ CMD ["python", "-m", "<%= packageName %>.entrypoints.worker.worker"]
32
+ <% } else { %>
33
+ # FastAPI entrypoint
34
+ EXPOSE <%= assignedPort %>
35
+ CMD ["uvicorn", "<%= packageName %>.main:app", "--host", "0.0.0.0", "--port", "<%= assignedPort %>"]
36
+ <% } %>
@@ -0,0 +1,19 @@
1
+ -- Declarative Schema definition
2
+ -- Use a diffing engine (e.g. pg-schema-diff or atlas) to apply this to the database.
3
+
4
+ CREATE TABLE examples (
5
+ id VARCHAR(36) PRIMARY KEY,
6
+ name VARCHAR(255) NOT NULL,
7
+ description TEXT
8
+ );
9
+
10
+ CREATE TABLE idempotency_keys (
11
+ key VARCHAR(255) PRIMARY KEY,
12
+ user_id VARCHAR(255) NOT NULL,
13
+ status VARCHAR(50) NOT NULL,
14
+ response_code INT,
15
+ response_body TEXT,
16
+ response_headers TEXT,
17
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
18
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
19
+ );
@@ -0,0 +1,76 @@
1
+ [project]
2
+ name = "<%= name %>"
3
+ version = "0.1.0"
4
+ description = "A GroundWork python microservice"
5
+ requires-python = ">=3.12"
6
+ dependencies = [
7
+ "pydantic>=2.0.0",
8
+ "pydantic-settings>=2.0.0",
9
+ "tenacity>=8.0.0",
10
+ "circuitbreaker>=2.0.0",
11
+ "httpx>=0.27.0",
12
+ "opentelemetry-api",
13
+ "opentelemetry-sdk",
14
+ "opentelemetry-instrumentation-fastapi",
15
+ "opentelemetry-exporter-otlp-proto-grpc",
16
+ "python-json-logger>=2.0.0",
17
+ "fastapi>=0.110.0",
18
+ "uvicorn[standard]>=0.29.0",
19
+ <% if (postgres) { %>
20
+ "sqlalchemy>=2.0.0",
21
+ "asyncpg>=0.29.0",
22
+ "alembic>=1.13.0",
23
+ # SQLAlchemy's async engine requires greenlet at runtime; it is not always
24
+ # pulled in transitively (notably on newer Python), so pin it explicitly —
25
+ # without it every async DB call raises "the greenlet library is required".
26
+ "greenlet>=3.0.0",
27
+ <% } %>
28
+ <% if (messaging === 'redis' || websockets) { %>
29
+ "redis>=5.0.0",
30
+ <% } %>
31
+ <% if (runpod) { %>
32
+ "runpod>=1.5.0",
33
+ <% } %>
34
+ ]<%# The LLM provider dependency (anthropic/openai/none) is injected by the llm
35
+ capability footprint, plan WS-F — not declared inline. %>
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "pytest>=8.0.0",
40
+ "pytest-asyncio>=0.23.0",
41
+ "testcontainers[postgres,redis]>=3.7.1",
42
+ "httpx>=0.27.0",
43
+ "import-linter>=2.0",
44
+ "ruff>=0.6.0",
45
+ "black>=24.0.0"
46
+ ]
47
+
48
+ [build-system]
49
+ requires = ["hatchling"]
50
+ build-backend = "hatchling.build"
51
+
52
+ [tool.hatch.build.targets.wheel]
53
+ packages = ["src/<%= packageName %>"]
54
+
55
+ [tool.pytest.ini_options]
56
+ asyncio_mode = "auto"
57
+ testpaths = ["tests"]
58
+
59
+ # import-linter enforces the inward dependency rule structurally: the core
60
+ # (domain + service ports) must never import an adapter, an entrypoint, or a
61
+ # web/db framework. Run `lint-imports` to check it (CI + pre-commit).
62
+ [tool.importlinter]
63
+ root_package = "<%= packageName %>"
64
+
65
+ [[tool.importlinter.contracts]]
66
+ name = "core depends on nothing outward"
67
+ type = "forbidden"
68
+ source_modules = [
69
+ "<%= packageName %>.core",
70
+ ]
71
+ forbidden_modules = [
72
+ "<%= packageName %>.adapters",
73
+ "<%= packageName %>.entrypoints",
74
+ "fastapi",
75
+ "sqlalchemy",
76
+ ]
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # Loads environment variables if .env exists
5
+ if [ -f .env ]; then
6
+ export $(cat .env | xargs)
7
+ fi
8
+
9
+ # Ensure database URL is available
10
+ DB_URL=${DATABASE_URL:-"postgres://postgres:postgres@localhost:5432/<%= name %>?sslmode=disable"}
11
+
12
+ echo "Applying declarative schema to database..."
13
+
14
+ # Uses Stripe's pg-schema-diff to declaratively migrate the database to match
15
+ # db/schema.sql. This is a Python service (no go.mod), so the tool is pinned with
16
+ # an explicit @version — `go run <pkg>@<ver>` runs module-independently, whereas a
17
+ # bare `go run <pkg>` would require a surrounding go.mod. Version matches the Go
18
+ # scaffold's pinned pg-schema-diff for parity. Requires the Go toolchain on PATH
19
+ # (./dev doctor checks for it when a Python service is present).
20
+ go run github.com/stripe/pg-schema-diff/cmd/pg-schema-diff@v1.0.5 apply \
21
+ --from-dsn "$DB_URL" \
22
+ --to-dir ./db \
23
+ --skip-confirm-prompt
24
+
25
+ echo "Schema applied successfully!"
@@ -0,0 +1,87 @@
1
+ import httpx
2
+ import websockets
3
+ import json
4
+ import logging
5
+ from typing import Dict, Any, Optional
6
+ from circuitbreaker import circuit
7
+ from <%= packageName %>.adapters.config import settings
8
+ from <%= packageName %>.core.domain.exceptions import TransientInferenceError, PermanentInferenceError, CircuitBreakerOpenError
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ def comfyui_fallback(e):
13
+ logger.error(f"ComfyUI circuit breaker tripped! {e}")
14
+ raise CircuitBreakerOpenError("ComfyUI server is currently unavailable.")
15
+
16
+ class ComfyUIClient:
17
+ """
18
+ Adapter to interact with a remote ComfyUI instance over REST and WebSockets.
19
+ """
20
+ def __init__(self):
21
+ self.http_client = httpx.AsyncClient(base_url=settings.comfyui_base_url, timeout=60.0)
22
+ # ComfyUI websocket uses ws:// instead of http://
23
+ self.ws_url = settings.comfyui_base_url.replace("http://", "ws://").replace("https://", "wss://") + "/ws"
24
+ self.client_id = "media-service-client-1"
25
+
26
+ @circuit(failure_threshold=3, recovery_timeout=60, fallback_function=comfyui_fallback, expected_exception=TransientInferenceError)
27
+ async def queue_prompt(self, workflow_json: Dict[str, Any]) -> str:
28
+ """
29
+ Submits a workflow to ComfyUI for execution and returns the Prompt ID.
30
+ """
31
+ payload = {
32
+ "prompt": workflow_json,
33
+ "client_id": self.client_id
34
+ }
35
+
36
+ try:
37
+ response = await self.http_client.post("/prompt", json=payload)
38
+
39
+ if response.status_code >= 500:
40
+ raise TransientInferenceError(f"ComfyUI internal server error: {response.text}")
41
+ elif response.status_code >= 400:
42
+ raise PermanentInferenceError(f"Invalid workflow request: {response.text}")
43
+
44
+ data = response.json()
45
+ prompt_id = data.get("prompt_id")
46
+ if not prompt_id:
47
+ raise PermanentInferenceError("ComfyUI response missing prompt_id")
48
+
49
+ return prompt_id
50
+
51
+ except httpx.RequestError as e:
52
+ raise TransientInferenceError(f"Network error connecting to ComfyUI: {e}")
53
+
54
+ async def poll_execution_progress(self, prompt_id: str) -> None:
55
+ """
56
+ Connects via WebSocket to listen for progress updates for a specific prompt_id.
57
+ In a real application, you would yield progress events or store them in Redis.
58
+ """
59
+ try:
60
+ url = f"{self.ws_url}?clientId={self.client_id}"
61
+ async with websockets.connect(url) as ws:
62
+ while True:
63
+ msg = await ws.recv()
64
+ if isinstance(msg, str):
65
+ data = json.loads(msg)
66
+ if data['type'] == 'executing':
67
+ node = data['data'].get('node')
68
+ if node is None and data['data'].get('prompt_id') == prompt_id:
69
+ # Execution is finished
70
+ break
71
+ elif data['type'] == 'progress':
72
+ # Log or publish progress
73
+ pass
74
+ except websockets.exceptions.WebSocketException as e:
75
+ raise TransientInferenceError(f"WebSocket disconnected from ComfyUI: {e}")
76
+
77
+ async def get_history(self, prompt_id: str) -> Dict[str, Any]:
78
+ """Fetches the generated artifacts/outputs from ComfyUI history."""
79
+ try:
80
+ response = await self.http_client.get(f"/history/{prompt_id}")
81
+ if response.status_code == 200:
82
+ history = response.json()
83
+ return history.get(prompt_id, {})
84
+ else:
85
+ raise TransientInferenceError("Failed to fetch history")
86
+ except httpx.RequestError as e:
87
+ raise TransientInferenceError(f"Network error fetching history: {e}")
@@ -0,0 +1,48 @@
1
+ from pydantic_settings import BaseSettings, SettingsConfigDict
2
+ from typing import Optional
3
+
4
+ class Settings(BaseSettings):
5
+ model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8', extra='ignore')
6
+
7
+ server_port: int = <%= assignedPort %>
8
+
9
+ # OTLP gRPC endpoint for trace export. Compose injects
10
+ # OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4317 for docker; this default
11
+ # covers native (`./dev start`) runs. BaseSettings maps the env var
12
+ # case-insensitively onto this field.
13
+ otel_exporter_otlp_endpoint: str = "http://localhost:4317"
14
+ <% if (postgres) { %>
15
+ db_host: str = "localhost"
16
+ db_port: int = 5432
17
+ db_user: str = "postgres"
18
+ db_password: str = "postgres"
19
+ db_name: str = "<%= fileName %>"
20
+
21
+ @property
22
+ def database_url(self) -> Optional[str]:
23
+ return f"postgresql+asyncpg://{self.db_user}:{self.db_password}@{self.db_host}:{self.db_port}/{self.db_name}"
24
+ <% } else { %>
25
+ @property
26
+ def database_url(self) -> Optional[str]:
27
+ return None
28
+ <% } %>
29
+
30
+ <% if (messaging === 'redis' || websockets) { %>
31
+ redis_url: str = "redis://localhost:6379"
32
+ <% } %>
33
+
34
+ <% if (messaging === 'kafka') { %>
35
+ kafka_brokers: str = "localhost:9092"
36
+ <% } %>
37
+
38
+ <% if (messaging === 'gcp-pubsub') { %>
39
+ pubsub_project_id: str = "local-project"
40
+ <% } %>
41
+
42
+ <% if (llm) { %>
43
+ llm_api_key: Optional[str] = None
44
+ llm_base_url: Optional[str] = None
45
+ llm_model: str = "<% if (llmProvider === 'anthropic') { %>claude-sonnet-4-6<% } else if (llmProvider === 'local') { %>llama3.1<% } else if (llmProvider === 'none') { %><% } else { %>gpt-4o<% } %>"
46
+ <% } %>
47
+
48
+ settings = Settings()
@@ -0,0 +1,21 @@
1
+ from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
2
+ from sqlalchemy.orm import declarative_base
3
+ from <%= packageName %>.adapters.config import settings
4
+ import asyncio
5
+
6
+ Base = declarative_base()
7
+
8
+ engine = create_async_engine(
9
+ settings.database_url,
10
+ echo=False,
11
+ future=True,
12
+ pool_pre_ping=True
13
+ )
14
+
15
+ async_session_maker = async_sessionmaker(
16
+ engine, expire_on_commit=False
17
+ )
18
+
19
+ async def get_db_session():
20
+ async with async_session_maker() as session:
21
+ yield session
@@ -0,0 +1,29 @@
1
+ import json
2
+ <% if (messaging === 'redis') { %>
3
+ import redis.asyncio as redis
4
+ from <%= packageName %>.adapters.config import settings
5
+
6
+ class RedisMessageQueue:
7
+ def __init__(self):
8
+ self.redis = redis.from_url(settings.redis_url)
9
+
10
+ async def publish(self, topic: str, payload: dict) -> None:
11
+ await self.redis.publish(topic, json.dumps(payload))
12
+
13
+ async def close(self):
14
+ await self.redis.close()
15
+ <% } %>
16
+
17
+ <% if (messaging === 'kafka') { %>
18
+ # Kafka implementation would go here using aiokafka
19
+ class KafkaMessageQueue:
20
+ async def publish(self, topic: str, payload: dict) -> None:
21
+ pass
22
+ <% } %>
23
+
24
+ <% if (messaging === 'gcp-pubsub') { %>
25
+ # GCP PubSub implementation would go here using google-cloud-pubsub
26
+ class GCPMessageQueue:
27
+ async def publish(self, topic: str, payload: dict) -> None:
28
+ pass
29
+ <% } %>