thothctl 0.25.7__tar.gz → 0.26.0__tar.gz

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 (572) hide show
  1. {thothctl-0.25.7 → thothctl-0.26.0}/PKG-INFO +2 -2
  2. thothctl-0.26.0/docs/framework/specs/phase1.9_composition_generation.md +302 -0
  3. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/generate/commands/iac.py +12 -0
  4. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/providers/bedrock_provider.py +10 -1
  5. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/rules_compiler.py +26 -24
  6. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/code_generator.py +11 -1
  7. thothctl-0.26.0/src/thothctl/services/generate/intent/composition_models.py +182 -0
  8. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/context_builder.py +99 -17
  9. thothctl-0.26.0/src/thothctl/services/generate/intent/intent_decomposer.py +365 -0
  10. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/intent_service.py +156 -0
  11. thothctl-0.26.0/src/thothctl/services/generate/intent/project_assembler.py +396 -0
  12. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/version.py +1 -1
  13. {thothctl-0.25.7 → thothctl-0.26.0}/.devcontainer/Dockerfile +0 -0
  14. {thothctl-0.25.7 → thothctl-0.26.0}/.devcontainer/README.md +0 -0
  15. {thothctl-0.25.7 → thothctl-0.26.0}/.devcontainer/devcontainer.json +0 -0
  16. {thothctl-0.25.7 → thothctl-0.26.0}/.github/workflows/docs.yml +0 -0
  17. {thothctl-0.25.7 → thothctl-0.26.0}/.github/workflows/python-publish.yml +0 -0
  18. {thothctl-0.25.7 → thothctl-0.26.0}/.github/workflows/release.yml +0 -0
  19. {thothctl-0.25.7 → thothctl-0.26.0}/.gitignore +0 -0
  20. {thothctl-0.25.7 → thothctl-0.26.0}/.pre-commit-config.yaml +0 -0
  21. {thothctl-0.25.7 → thothctl-0.26.0}/.pydocstyle +0 -0
  22. {thothctl-0.25.7 → thothctl-0.26.0}/.readthedocs.yaml +0 -0
  23. {thothctl-0.25.7 → thothctl-0.26.0}/Dockerfile +0 -0
  24. {thothctl-0.25.7 → thothctl-0.26.0}/LICENSE +0 -0
  25. {thothctl-0.25.7 → thothctl-0.26.0}/README.md +0 -0
  26. {thothctl-0.25.7 → thothctl-0.26.0}/__init__.py +0 -0
  27. {thothctl-0.25.7 → thothctl-0.26.0}/docs/catalog/catalog-info.yaml +0 -0
  28. {thothctl-0.25.7 → thothctl-0.26.0}/docs/dashboard/README.md +0 -0
  29. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/ai-review/README.md +0 -0
  30. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/ai-review/agent_specifications.md +0 -0
  31. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/ai-review/agentcore.md +0 -0
  32. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/blast-radius.md +0 -0
  33. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/check_environment.md +0 -0
  34. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/check_iac.md +0 -0
  35. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/check_overview.md +0 -0
  36. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/check_project_iac.md +0 -0
  37. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/check_space.md +0 -0
  38. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/cost-analysis-quick-reference.md +0 -0
  39. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/cost-analysis.md +0 -0
  40. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/customizing_rules.md +0 -0
  41. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/deps-advanced.md +0 -0
  42. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/deps.md +0 -0
  43. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/drift-detection.md +0 -0
  44. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/check/plan.md +0 -0
  45. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/dashboard/dashboard_overview.md +0 -0
  46. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/customizing_docs.md +0 -0
  47. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/document_iac.md +0 -0
  48. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/document_overview.md +0 -0
  49. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/iac.md +0 -0
  50. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/mermaid_examples.md +0 -0
  51. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/mermaid_quickref.md +0 -0
  52. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/document/use_cases.md +0 -0
  53. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/generate/generate_components.md +0 -0
  54. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/generate/generate_iac.md +0 -0
  55. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/generate/generate_stacks.md +0 -0
  56. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/init/init.md +0 -0
  57. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/init/init_space.md +0 -0
  58. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/inventory/CHANGELOG.md +0 -0
  59. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/inventory/frameworks/terraform.md +0 -0
  60. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/inventory/frameworks/terragrunt.md +0 -0
  61. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/inventory/iac.md +0 -0
  62. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/inventory/inventory_iac.md +0 -0
  63. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/inventory/inventory_overview.md +0 -0
  64. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/list/list_overview.md +0 -0
  65. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/list/list_projects.md +0 -0
  66. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/list/list_spaces.md +0 -0
  67. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/mcp/mcp.md +0 -0
  68. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/project/iac.md +0 -0
  69. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/project/project_cleanup.md +0 -0
  70. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/project/project_convert.md +0 -0
  71. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/project/project_overview.md +0 -0
  72. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/project/project_upgrade.md +0 -0
  73. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/project/use_cases.md +0 -0
  74. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/remove/remove_overview.md +0 -0
  75. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/remove/remove_project.md +0 -0
  76. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/remove/remove_space.md +0 -0
  77. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/scan/iac.md +0 -0
  78. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/scan/scan_iac.md +0 -0
  79. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/scan/scan_overview.md +0 -0
  80. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/scan/use_cases.md +0 -0
  81. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/space/space_overview.md +0 -0
  82. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/upgrade/upgrade_overview.md +0 -0
  83. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/workflow/workflow_devsecops.md +0 -0
  84. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/commands/workflow/workflow_overview.md +0 -0
  85. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/concepts.md +0 -0
  86. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/cross_platform_support.md +0 -0
  87. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/framework_architecture.md +0 -0
  88. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/infrastructure_composition.md +0 -0
  89. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/policy_as_code.md +0 -0
  90. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/roadmap_fdi.md +0 -0
  91. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/software_architecture.md +0 -0
  92. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/space_configuration.md +0 -0
  93. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/specs/phase1_intent_to_iac.md +0 -0
  94. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/README.md +0 -0
  95. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/ai_dlc.md +0 -0
  96. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/check_command.md +0 -0
  97. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/devsecops_quickstart.md +0 -0
  98. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/devsecops_sdlc.md +0 -0
  99. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/inventory_command.md +0 -0
  100. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/platform_engineering_templates.md +0 -0
  101. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/space_management.md +0 -0
  102. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/tasks/create_template.md +0 -0
  103. {thothctl-0.25.7 → thothctl-0.26.0}/docs/framework/use_cases/tasks/workflow_implementation_plan.md +0 -0
  104. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/commnad_init.png +0 -0
  105. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/framework/thothforge-framework.svg +0 -0
  106. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/framework/thothfr.png +0 -0
  107. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/icon-light.png +0 -0
  108. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/icon.png +0 -0
  109. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/init_project.gif +0 -0
  110. {thothctl-0.25.7 → thothctl-0.26.0}/docs/img/stable/scan_report_example.png +0 -0
  111. {thothctl-0.25.7 → thothctl-0.26.0}/docs/includes/abbreviations.md +0 -0
  112. {thothctl-0.25.7 → thothctl-0.26.0}/docs/index.md +0 -0
  113. {thothctl-0.25.7 → thothctl-0.26.0}/docs/installation/devcontainer_setup.md +0 -0
  114. {thothctl-0.25.7 → thothctl-0.26.0}/docs/installation/linux_installation.md +0 -0
  115. {thothctl-0.25.7 → thothctl-0.26.0}/docs/installation/windows_installation.md +0 -0
  116. {thothctl-0.25.7 → thothctl-0.26.0}/docs/javascripts/tablesort.js +0 -0
  117. {thothctl-0.25.7 → thothctl-0.26.0}/docs/mcp.md +0 -0
  118. {thothctl-0.25.7 → thothctl-0.26.0}/docs/navigation.md +0 -0
  119. {thothctl-0.25.7 → thothctl-0.26.0}/docs/quick_start.md +0 -0
  120. {thothctl-0.25.7 → thothctl-0.26.0}/docs/requirements.txt +0 -0
  121. {thothctl-0.25.7 → thothctl-0.26.0}/docs/stylesheets/extra-enhanced.css +0 -0
  122. {thothctl-0.25.7 → thothctl-0.26.0}/docs/stylesheets/extra.css +0 -0
  123. {thothctl-0.25.7 → thothctl-0.26.0}/docs/telemetry.md +0 -0
  124. {thothctl-0.25.7 → thothctl-0.26.0}/docs/template_engine/cli_commands_audit.md +0 -0
  125. {thothctl-0.25.7 → thothctl-0.26.0}/docs/template_engine/for_developers.md +0 -0
  126. {thothctl-0.25.7 → thothctl-0.26.0}/docs/template_engine/for_platform_engineers.md +0 -0
  127. {thothctl-0.25.7 → thothctl-0.26.0}/docs/template_engine/github_templates.md +0 -0
  128. {thothctl-0.25.7 → thothctl-0.26.0}/docs/template_engine/template_engine.md +0 -0
  129. {thothctl-0.25.7 → thothctl-0.26.0}/docs/toolkit_overview.md +0 -0
  130. {thothctl-0.25.7 → thothctl-0.26.0}/docs/troubleshooting/linux_troubleshooting.md +0 -0
  131. {thothctl-0.25.7 → thothctl-0.26.0}/docs/troubleshooting/macos_troubleshooting.md +0 -0
  132. {thothctl-0.25.7 → thothctl-0.26.0}/docs/troubleshooting/troubleshooting.md +0 -0
  133. {thothctl-0.25.7 → thothctl-0.26.0}/docs/troubleshooting/windows_troubleshooting.md +0 -0
  134. {thothctl-0.25.7 → thothctl-0.26.0}/mkdocs.yaml +0 -0
  135. {thothctl-0.25.7 → thothctl-0.26.0}/pyproject.toml +0 -0
  136. {thothctl-0.25.7 → thothctl-0.26.0}/scripts/check_output_consistency.py +0 -0
  137. {thothctl-0.25.7 → thothctl-0.26.0}/scripts/run_mcp_server.sh +0 -0
  138. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/__init__.py +0 -0
  139. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/application/__init__.py +0 -0
  140. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/autocomplete.py +0 -0
  141. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/cli.py +0 -0
  142. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/__init__.py +0 -0
  143. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/__init__.py +0 -0
  144. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/cli.py +0 -0
  145. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/__init__.py +0 -0
  146. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/analyze.py +0 -0
  147. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/apply_fix.py +0 -0
  148. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/configure.py +0 -0
  149. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/configure_decisions.py +0 -0
  150. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/decide.py +0 -0
  151. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/history.py +0 -0
  152. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/improve.py +0 -0
  153. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/orchestrate.py +0 -0
  154. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/override.py +0 -0
  155. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/report.py +0 -0
  156. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/ai_review/commands/serve.py +0 -0
  157. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/__init__.py +0 -0
  158. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/cli.py +0 -0
  159. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/__init__.py +0 -0
  160. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/config.py +0 -0
  161. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/environment.py +0 -0
  162. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/iac.py +0 -0
  163. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/project/__init__.py +0 -0
  164. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/project/iac.py +0 -0
  165. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/project.py +0 -0
  166. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/check/commands/space.py +0 -0
  167. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/dashboard/__init__.py +0 -0
  168. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/dashboard/cli.py +0 -0
  169. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/dashboard/commands/__init__.py +0 -0
  170. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/dashboard/commands/launch.py +0 -0
  171. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/document/__init__.py +0 -0
  172. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/document/cli.py +0 -0
  173. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/document/commands/__init__.py +0 -0
  174. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/document/commands/iac.py +0 -0
  175. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/generate/__init__.py +0 -0
  176. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/generate/cli.py +0 -0
  177. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/generate/commands/__init__.py +0 -0
  178. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/generate/commands/component.py +0 -0
  179. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/generate/commands/stacks.py +0 -0
  180. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/__init__.py +0 -0
  181. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/cli.py +0 -0
  182. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/commands/__init__.py +0 -0
  183. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/commands/env.py +0 -0
  184. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/commands/project.py +0 -0
  185. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/commands/space.py +0 -0
  186. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/init/commands/template.py +0 -0
  187. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/inventory/__init__.py +0 -0
  188. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/inventory/cli.py +0 -0
  189. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/inventory/commands/__init__.py +0 -0
  190. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/inventory/commands/check.py +0 -0
  191. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/inventory/commands/iac.py +0 -0
  192. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/list/__init__.py +0 -0
  193. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/list/cli.py +0 -0
  194. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/list/commands/__init__.py +0 -0
  195. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/list/commands/projects.py +0 -0
  196. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/list/commands/spaces.py +0 -0
  197. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/list/commands/templates.py +0 -0
  198. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/__init__.py +0 -0
  199. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/cli.py +0 -0
  200. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/commands/__init__.py +0 -0
  201. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/commands/register.py +0 -0
  202. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/commands/server.py +0 -0
  203. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/commands/status.py +0 -0
  204. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/mcp/commands/stop.py +0 -0
  205. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/__init__.py +0 -0
  206. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/cli.py +0 -0
  207. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/commands/__init__.py +0 -0
  208. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/commands/bootstrap.py +0 -0
  209. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/commands/cleanup.py +0 -0
  210. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/commands/convert.py +0 -0
  211. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/project/commands/upgrade.py +0 -0
  212. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/quickstart/__init__.py +0 -0
  213. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/quickstart/cli.py +0 -0
  214. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/remove/__init__.py +0 -0
  215. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/remove/cli.py +0 -0
  216. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/remove/project.py +0 -0
  217. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/remove/space.py +0 -0
  218. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/scan/__init__.py +0 -0
  219. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/scan/cli.py +0 -0
  220. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/scan/commands/__init__.py +0 -0
  221. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/scan/commands/iac.py +0 -0
  222. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/__init__.py +0 -0
  223. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/cli.py +0 -0
  224. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/__init__.py +0 -0
  225. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/activate.py +0 -0
  226. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/deactivate.py +0 -0
  227. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/export_space.py +0 -0
  228. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/import_space.py +0 -0
  229. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/show.py +0 -0
  230. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/space/commands/update.py +0 -0
  231. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/upgrade/cli.py +0 -0
  232. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/workflow/__init__.py +0 -0
  233. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/workflow/cli.py +0 -0
  234. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/workflow/commands/__init__.py +0 -0
  235. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/workflow/commands/devsecops.py +0 -0
  236. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/commands/workflow/commands/run.py +0 -0
  237. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/.thothcf.setup.toml +0 -0
  238. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/.thothcf_home.toml +0 -0
  239. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/.thothcf_module.toml +0 -0
  240. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/.thothcf_project.toml +0 -0
  241. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/.thothcf_template_parameters.toml +0 -0
  242. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/__init__.py +0 -0
  243. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/common.py +0 -0
  244. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/common/terragrunt/.thothcf_project.toml +0 -0
  245. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/__init__.py +0 -0
  246. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/constants.py +0 -0
  247. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/default_values.py +0 -0
  248. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/defaults.py +0 -0
  249. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/models.py +0 -0
  250. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/settings.py +0 -0
  251. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/template_config.py +0 -0
  252. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/template_configs.py +0 -0
  253. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/templates.py +0 -0
  254. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/config/validation.py +0 -0
  255. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/__init__.py +0 -0
  256. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/cli_ui.py +0 -0
  257. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/commands.py +0 -0
  258. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/config.py +0 -0
  259. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/__init__.py +0 -0
  260. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/azure_devops/__init__.py +0 -0
  261. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/azure_devops/get_azure_devops.py +0 -0
  262. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/azure_devops/pull_request_comments.py +0 -0
  263. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/github/get_github.py +0 -0
  264. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/github/pull_request_comments.py +0 -0
  265. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/integrate_messages_services/__init__.py +0 -0
  266. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/integrate_messages_services/microsoft_teams.py +0 -0
  267. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/integrate_messages_services/sent_message_teams.py +0 -0
  268. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/pattern_names.py +0 -0
  269. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/pr_comments/__init__.py +0 -0
  270. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/integrations/pr_comments/pr_comment_publisher.py +0 -0
  271. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/logger.py +0 -0
  272. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/telemetry.py +0 -0
  273. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/core/version_tools.py +0 -0
  274. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/domain/__init__.py +0 -0
  275. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/domain/interfaces/__init__.py +0 -0
  276. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/domain/models/__init__.py +0 -0
  277. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/mcp/README.md +0 -0
  278. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/mcp/__init__.py +0 -0
  279. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/mcp/server.py +0 -0
  280. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/__init__.py +0 -0
  281. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/__init__.py +0 -0
  282. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/agentcore/agentcore.json +0 -0
  283. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/ai_agent.py +0 -0
  284. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/analyzers/__init__.py +0 -0
  285. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/analyzers/code_reviewer.py +0 -0
  286. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/analyzers/context_builder.py +0 -0
  287. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/analyzers/report_analyzer.py +0 -0
  288. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/analyzers/risk_assessor.py +0 -0
  289. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/bedrock_agent_api.py +0 -0
  290. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/config/__init__.py +0 -0
  291. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/config/ai_settings.py +0 -0
  292. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/config/decision_rules.py +0 -0
  293. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/decision_engine.py +0 -0
  294. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/main.py +0 -0
  295. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/memory.py +0 -0
  296. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/orchestrator.py +0 -0
  297. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/pr_decision_publisher.py +0 -0
  298. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/providers/__init__.py +0 -0
  299. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/providers/azure_provider.py +0 -0
  300. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/providers/bedrock_agent_provider.py +0 -0
  301. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/providers/ollama_provider.py +0 -0
  302. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/providers/openai_provider.py +0 -0
  303. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/safety/__init__.py +0 -0
  304. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/safety/safety_guard.py +0 -0
  305. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/strands_agent.py +0 -0
  306. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/tracing.py +0 -0
  307. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/utils/__init__.py +0 -0
  308. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/utils/cost_tracker.py +0 -0
  309. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/utils/fix_patterns.py +0 -0
  310. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/utils/fix_prompts.py +0 -0
  311. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/utils/formatters.py +0 -0
  312. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/ai_review/utils/prompts.py +0 -0
  313. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/__init__.py +0 -0
  314. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/environment/__init__.py +0 -0
  315. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/environment/check_environment.py +0 -0
  316. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/org_policy_loader.py +0 -0
  317. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/__init__.py +0 -0
  318. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/blast_radius_service.py +0 -0
  319. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cfn_blast_radius_service.py +0 -0
  320. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/check_origin_version.py +0 -0
  321. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/check_project_structure.py +0 -0
  322. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/__init__.py +0 -0
  323. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/cost_analyzer.py +0 -0
  324. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/models/__init__.py +0 -0
  325. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/models/cloudformation_mapper.py +0 -0
  326. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/models/cost_models.py +0 -0
  327. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/__init__.py +0 -0
  328. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/aws_pricing_client.py +0 -0
  329. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/base_pricing.py +0 -0
  330. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/__init__.py +0 -0
  331. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/apigateway_pricing.py +0 -0
  332. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/bedrock_pricing.py +0 -0
  333. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/cloudwatch_pricing.py +0 -0
  334. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/dynamodb_pricing.py +0 -0
  335. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/ebs_pricing.py +0 -0
  336. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/ec2_pricing.py +0 -0
  337. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/ecs_pricing.py +0 -0
  338. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/eip_pricing.py +0 -0
  339. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/eks_pricing.py +0 -0
  340. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/elb_pricing.py +0 -0
  341. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/free_resources_pricing.py +0 -0
  342. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/kms_pricing.py +0 -0
  343. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/lambda_pricing.py +0 -0
  344. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/msk_pricing.py +0 -0
  345. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/rds_pricing.py +0 -0
  346. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/s3_pricing.py +0 -0
  347. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/secrets_manager_pricing.py +0 -0
  348. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/pricing/providers/vpc_pricing.py +0 -0
  349. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/cost/unified_cost_report.py +0 -0
  350. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/__init__.py +0 -0
  351. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/cfn_drift_service.py +0 -0
  352. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/drift_ai.py +0 -0
  353. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/drift_history.py +0 -0
  354. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/drift_policy.py +0 -0
  355. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/drift_report.py +0 -0
  356. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/drift_service.py +0 -0
  357. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/drift/models.py +0 -0
  358. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/risk_assessment.py +0 -0
  359. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/project/validate_project_structure.py +0 -0
  360. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/rule_merger.py +0 -0
  361. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/check/stack_optimizer/__init__.py +0 -0
  362. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/dashboard/__init__.py +0 -0
  363. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/dashboard/dashboard_service.py +0 -0
  364. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/dashboard/data_loader.py +0 -0
  365. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/__init__.py +0 -0
  366. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/architecture_renderer.py +0 -0
  367. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/create_documentation.py +0 -0
  368. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/files_content.py +0 -0
  369. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/files_scan.py +0 -0
  370. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/iac_documentation.py +0 -0
  371. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/iac_grunt_graph.py +0 -0
  372. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/iac_grunt_info.py +0 -0
  373. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/document/topology_generator.py +0 -0
  374. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/__init__.py +0 -0
  375. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_stacks/__init__.py +0 -0
  376. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_stacks/config_generator.py +0 -0
  377. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_stacks/remote_config_generation.py +0 -0
  378. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_stacks/stack_service.py +0 -0
  379. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_stacks/templates/terragrunt.hcl.j2 +0 -0
  380. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_stacks/terragrunt.hcl +0 -0
  381. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/__init__.py +0 -0
  382. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/config.yaml +0 -0
  383. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/create_code.py +0 -0
  384. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/create_component.py +0 -0
  385. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/create_component_service.py +0 -0
  386. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/create_stacks.py +0 -0
  387. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/create_template.py +0 -0
  388. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/files_content.py +0 -0
  389. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/github_template_loader.py +0 -0
  390. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/create_template/project_templates.py +0 -0
  391. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/__init__.py +0 -0
  392. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/models.py +0 -0
  393. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/prompts.py +0 -0
  394. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/generate/intent/validator.py +0 -0
  395. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/__init__.py +0 -0
  396. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/environment/__init__.py +0 -0
  397. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/environment/install_tools.py +0 -0
  398. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/environment/prerequisite_checker.py +0 -0
  399. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/environment/tool_packs.py +0 -0
  400. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/project/__init__.py +0 -0
  401. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/project/project.py +0 -0
  402. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/space/__init__.py +0 -0
  403. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/space/example_space.toml +0 -0
  404. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/space/export_import.py +0 -0
  405. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/space/inheritance.py +0 -0
  406. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/space/space.py +0 -0
  407. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/init/space/terraform_module_cache.py +0 -0
  408. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/__init__.py +0 -0
  409. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/cdk_parsers.py +0 -0
  410. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/cdk_sbom_service.py +0 -0
  411. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/changelog_parser.py +0 -0
  412. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/inventory_service.py +0 -0
  413. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/models.py +0 -0
  414. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/module_compatibility_service.py +0 -0
  415. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/report_service.py +0 -0
  416. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/schema_compatibility_service.py +0 -0
  417. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/terragrunt_parser.py +0 -0
  418. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/update_versions.py +0 -0
  419. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/inventory/version_service.py +0 -0
  420. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/mcp/README.md +0 -0
  421. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/mcp/__init__.py +0 -0
  422. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/mcp/simple_http_server.py +0 -0
  423. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/mcp/stdio_server.py +0 -0
  424. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/__init__.py +0 -0
  425. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/bootstrap/__init__.py +0 -0
  426. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/bootstrap/bootstrap_service.py +0 -0
  427. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/cleanup/__init__.py +0 -0
  428. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/cleanup/clean_project.py +0 -0
  429. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/cleanup/clean_space.py +0 -0
  430. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/__init__.py +0 -0
  431. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/conversion_service.py +0 -0
  432. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/get_project_data.py +0 -0
  433. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/post_init.py +0 -0
  434. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/project_converter.py +0 -0
  435. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/project_defaults.py +0 -0
  436. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/convert/set_project_parameters.py +0 -0
  437. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/create_terramate/__init__.py +0 -0
  438. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/create_terramate/create_terramate_stacks.py +0 -0
  439. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/create_terramate/detect_changes_stacks.py +0 -0
  440. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/create_terramate/manage_terramate_stacks.py +0 -0
  441. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/upgrade/__init__.py +0 -0
  442. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/project/upgrade/upgrade_service.py +0 -0
  443. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/__init__.py +0 -0
  444. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/compliance_review.py +0 -0
  445. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/import_reports.py +0 -0
  446. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/models.py +0 -0
  447. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/report_parser.py +0 -0
  448. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/sarif_output.py +0 -0
  449. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scan_history.py +0 -0
  450. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scan_service.py +0 -0
  451. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/__init__.py +0 -0
  452. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/checkov.py +0 -0
  453. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/kics.py +0 -0
  454. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/opa.py +0 -0
  455. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/scan_reports.py +0 -0
  456. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/scanners.py +0 -0
  457. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/terraform_compliance.py +0 -0
  458. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/tfsec.py +0 -0
  459. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/scan/scanners/trivy.py +0 -0
  460. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/__init__.py +0 -0
  461. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/custom_workflow_engine.py +0 -0
  462. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/models.py +0 -0
  463. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/__init__.py +0 -0
  464. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/base.py +0 -0
  465. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/build.py +0 -0
  466. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/deploy.py +0 -0
  467. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/develop.py +0 -0
  468. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/monitor.py +0 -0
  469. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/plan.py +0 -0
  470. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/secure.py +0 -0
  471. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/phases/test.py +0 -0
  472. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/services/workflow/workflow_service.py +0 -0
  473. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/templates/ai_reports/pr_comment.md +0 -0
  474. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/templates/reports/inventory_report.html +0 -0
  475. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/templates/reports/inventory_report.js +0 -0
  476. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/templates/unified_report_styles.css +0 -0
  477. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/__init__.py +0 -0
  478. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/banner.py +0 -0
  479. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/__init__.py +0 -0
  480. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/create_compliance_html_reports.py +0 -0
  481. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/create_html_reports.py +0 -0
  482. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/delete_directory.py +0 -0
  483. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/fix_report_styling.py +0 -0
  484. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/render_scan_report.py +0 -0
  485. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/report_html_utils.py +0 -0
  486. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/dashboard.html +0 -0
  487. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/index_report.html +0 -0
  488. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/individual_report.html +0 -0
  489. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/simple_report.html +0 -0
  490. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/unified_report_styles.css +0 -0
  491. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/unified_scan_report.html +0 -0
  492. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/unified_simple_report.html +0 -0
  493. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/common/templates/xunit_report.html +0 -0
  494. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/crypto.py +0 -0
  495. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/git_changes.py +0 -0
  496. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/manage_backend_resources/__init__.py +0 -0
  497. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/manage_backend_resources/manage_backend_resources.py +0 -0
  498. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/modules_ops/__init__.py +0 -0
  499. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/modules_ops/terraform_module_details.py +0 -0
  500. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/modules_ops/terraform_modules_fetcher.py +0 -0
  501. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/platform_utils.py +0 -0
  502. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/process_hcl/__init__.py +0 -0
  503. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/process_hcl/analyze_terraform_plan.py +0 -0
  504. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/process_hcl/graph_manager.py +0 -0
  505. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/process_hcl/graph_terragrunt_dependencies.py +0 -0
  506. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/process_hcl/process_terraform_file.py +0 -0
  507. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/process_hcl/risk_analyzing_terraform_plan.py +0 -0
  508. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/sync_workspaces/__init__.py +0 -0
  509. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/sync_workspaces/sync_terraform_workspaces.py +0 -0
  510. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/sync_workspaces/sync_terragrunt_workspaces.py +0 -0
  511. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/template_loader.py +0 -0
  512. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/utils/thoth_colors.py +0 -0
  513. {thothctl-0.25.7 → thothctl-0.26.0}/src/thothctl/wellcome_banner.py +0 -0
  514. {thothctl-0.25.7 → thothctl-0.26.0}/tests/conftest.py +0 -0
  515. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_agentcore_entrypoint.py +0 -0
  516. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_apply_fix.py +0 -0
  517. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_decision_engine.py +0 -0
  518. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_fix_patterns.py +0 -0
  519. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_memory.py +0 -0
  520. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_orchestrator.py +0 -0
  521. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_pr_decision.py +0 -0
  522. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ai_safety_guard.py +0 -0
  523. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_aws_pricing_client.py +0 -0
  524. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_azure_devops_pr_comments.py +0 -0
  525. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_bedrock_pricing.py +0 -0
  526. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cdk_inventory.py +0 -0
  527. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cdk_language_selection.py +0 -0
  528. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cfn_blast_radius.py +0 -0
  529. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cfn_drift_detection.py +0 -0
  530. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_context_steering.py +0 -0
  531. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cost_analyzer.py +0 -0
  532. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cost_models.py +0 -0
  533. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cost_policy_enforcement.py +0 -0
  534. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_cost_pr_comments.py +0 -0
  535. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_dashboard_loading_fix.py +0 -0
  536. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_dashboard_service.py +0 -0
  537. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_drift.py +0 -0
  538. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_drift_detection.py +0 -0
  539. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_ec2_pricing.py +0 -0
  540. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_generate_iac_codegen.py +0 -0
  541. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_generate_iac_context.py +0 -0
  542. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_generate_iac_prompts.py +0 -0
  543. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_generate_iac_service.py +0 -0
  544. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_generate_iac_validator.py +0 -0
  545. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_github_pr_comments.py +0 -0
  546. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_iac_cost_integration.py +0 -0
  547. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_init_ai_tools.py +0 -0
  548. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_init_template_params.py +0 -0
  549. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_intent_quick_wins.py +0 -0
  550. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_intent_rules_integration.py +0 -0
  551. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_inventory_pr_comments.py +0 -0
  552. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_kics_scanner.py +0 -0
  553. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_mermaid_edge_labels.py +0 -0
  554. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_new_cost_providers.py +0 -0
  555. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_opa_data_files.py +0 -0
  556. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_parallel_scan.py +0 -0
  557. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_platform_utils.py +0 -0
  558. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_pr_comment_publisher.py +0 -0
  559. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_provider_source_url_fix.py +0 -0
  560. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_provider_versions.py +0 -0
  561. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_rules_compiler.py +0 -0
  562. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_scan_cfn_support.py +0 -0
  563. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_scan_command.py +0 -0
  564. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_scan_pr_comments.py +0 -0
  565. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_space_command.py +0 -0
  566. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_space_management.py +0 -0
  567. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_stack_optimizer.py +0 -0
  568. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_template_url_fix.py +0 -0
  569. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_terragrunt_parser.py +0 -0
  570. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_topology_generator.py +0 -0
  571. {thothctl-0.25.7 → thothctl-0.26.0}/tests/test_workflow_integration.py +0 -0
  572. {thothctl-0.25.7 → thothctl-0.26.0}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: thothctl
3
- Version: 0.25.7
3
+ Version: 0.26.0
4
4
  Summary: A CLI for Developer Control Plane. Accelerate your cloud IaC deployments.
5
5
  Project-URL: SourceCode, https://github.com/thothforge/thothctl
6
6
  Project-URL: HomePage, https://github.com/thothforge/thothctl
@@ -0,0 +1,302 @@
1
+ # Phase 1.9: Composition-Aware Intent-to-IaC Generation — Spec
2
+
3
+ > **Version**: 1.0 | **Target**: v0.26.0 | **Effort**: ~8 days
4
+ > **Author**: ThothForge | **Status**: Ready for implementation
5
+ > **Depends on**: Phase 1 (Intent-to-IaC) ✅, Phase 2.4 (Rules integration) ✅
6
+
7
+ ## Overview
8
+
9
+ Extend `thothctl generate iac` to produce **full multi-stack projects** following the ThothForge scaffold composition rules — not just single flat modules. The AI decomposes a high-level intent into multiple stacks organized by layers, wires dependencies between them, and produces a complete project ready for `terragrunt run-all plan`.
10
+
11
+ ## Design Principles
12
+
13
+ 1. **Scaffold-driven** — output structure comes from `.thothcf_project.toml`, not AI invention
14
+ 2. **Layer-aware** — foundation → platform → application → observability (ordered dependencies)
15
+ 3. **Org policy compliant** — naming, tagging, security rules enforced at generation time
16
+ 4. **Incremental** — can generate into an existing project (adds stacks, doesn't overwrite)
17
+ 5. **Framework-agnostic** — supports terraform-terragrunt, terraform, cdkv2, cloudformation
18
+
19
+ ## Architecture
20
+
21
+ ```
22
+ User Intent (complex, multi-service)
23
+ ↓
24
+ ┌──────────────────────────────────────────────────────────────────┐
25
+ │ 1. Intent Decomposer │
26
+ │ - Breaks intent into discrete infrastructure components │
27
+ │ - Assigns each component to a layer (foundation/platform/app) │
28
+ │ - Identifies dependencies between components │
29
+ │ Output: CompositionPlan (list of stacks + dependency graph) │
30
+ └──────────────┬───────────────────────────────────────────────────┘
31
+ ↓
32
+ ┌──────────────────────────────────────────────────────────────────┐
33
+ │ 2. Stack Generator (per stack) │
34
+ │ - Uses existing CodeGenerator for each stack's code │
35
+ │ - Adds terragrunt.hcl with includes + dependencies │
36
+ │ - Places in correct path: stacks/<layer>/<domain>/<service>/ │
37
+ │ Output: List[GeneratedFile] per stack │
38
+ └──────────────┬───────────────────────────────────────────────────┘
39
+ ↓
40
+ ┌──────────────────────────────────────────────────────────────────┐
41
+ │ 3. Project Assembler │
42
+ │ - Creates root.hcl + common/ if needed │
43
+ │ - Merges all stack files into project structure │
44
+ │ - Runs validation on the full project │
45
+ │ Output: Complete project directory │
46
+ └──────────────────────────────────────────────────────────────────┘
47
+ ```
48
+
49
+ ## Layer Model
50
+
51
+ | Layer | Purpose | Examples | Dependencies |
52
+ |-------|---------|----------|--------------|
53
+ | `foundation` | Core networking & security | VPC, subnets, NAT, KMS keys, IAM baselines | None (root layer) |
54
+ | `platform` | Shared services | ECS/EKS cluster, RDS, ElastiCache, S3 buckets | → foundation |
55
+ | `application` | Workload-specific | Lambda functions, API Gateway, DynamoDB tables | → platform |
56
+ | `observability` | Monitoring & alerting | CloudWatch dashboards, alarms, log groups | → platform |
57
+
58
+ ## CLI Interface
59
+
60
+ ```bash
61
+ # Full project generation (new project)
62
+ thothctl generate iac \
63
+ -i "Microservices platform: VPC with 3 AZs, ECS Fargate cluster, RDS PostgreSQL, S3 data lake, API Gateway" \
64
+ --project-type terraform-terragrunt \
65
+ --composition full \
66
+ -o ./my-platform \
67
+ --apply
68
+
69
+ # Add stacks to existing project (incremental)
70
+ thothctl generate iac \
71
+ -i "Add Redis cache for session management" \
72
+ --project-type terraform-terragrunt \
73
+ --composition incremental \
74
+ --apply
75
+
76
+ # Single stack (current behavior, default)
77
+ thothctl generate iac \
78
+ -i "S3 bucket with encryption" \
79
+ --apply
80
+ ```
81
+
82
+ ## CompositionPlan Model
83
+
84
+ ```python
85
+ @dataclass
86
+ class StackPlan:
87
+ """A single stack to generate."""
88
+ name: str # e.g., "vpc"
89
+ layer: str # foundation | platform | application | observability
90
+ domain: str # e.g., "networking", "data", "compute"
91
+ intent: str # Specific intent for this stack
92
+ depends_on: List[str] # Stack names this depends on
93
+ module_source: Optional[str] # Official module if applicable
94
+
95
+ @dataclass
96
+ class CompositionPlan:
97
+ """Full project composition plan."""
98
+ stacks: List[StackPlan]
99
+ project_type: str
100
+ needs_root_config: bool # True if root.hcl doesn't exist
101
+ needs_common: bool # True if common/ doesn't exist
102
+ ```
103
+
104
+ ## Intent Decomposition Prompt
105
+
106
+ The AI receives the high-level intent + layer model and returns a structured decomposition:
107
+
108
+ ```
109
+ SYSTEM: You are an infrastructure architect. Decompose the user's intent into
110
+ discrete infrastructure stacks following the layer model:
111
+ - foundation: networking, security baselines, encryption keys
112
+ - platform: shared compute, databases, storage
113
+ - application: workload-specific resources
114
+ - observability: monitoring, alerting
115
+
116
+ Return JSON:
117
+ {
118
+ "stacks": [
119
+ {
120
+ "name": "vpc",
121
+ "layer": "foundation",
122
+ "domain": "networking",
123
+ "intent": "VPC with 3 private subnets, 3 public subnets, NAT gateway per AZ",
124
+ "depends_on": [],
125
+ "module_source": "terraform-aws-modules/vpc/aws"
126
+ },
127
+ ...
128
+ ]
129
+ }
130
+ ```
131
+
132
+ ## Terragrunt.hcl Generation
133
+
134
+ For each stack, generate the orchestration file:
135
+
136
+ ```hcl
137
+ # Auto-generated by ThothCTL — stacks/platform/data/s3/terragrunt.hcl
138
+ include "root" {
139
+ path = find_in_parent_folders("root.hcl")
140
+ }
141
+
142
+ dependency "vpc" {
143
+ config_path = "../../../foundation/networking/vpc"
144
+
145
+ mock_outputs = {
146
+ vpc_id = "vpc-mock-12345"
147
+ subnet_ids = ["subnet-mock-1", "subnet-mock-2"]
148
+ }
149
+
150
+ mock_outputs_merge_strategy_with_state = "shallow"
151
+ }
152
+
153
+ inputs = {
154
+ vpc_id = dependency.vpc.outputs.vpc_id
155
+ subnet_ids = dependency.vpc.outputs.subnet_ids
156
+ }
157
+ ```
158
+
159
+ ## Root Config Generation (if needed)
160
+
161
+ ```hcl
162
+ # root.hcl — Generated by ThothCTL
163
+ locals {
164
+ # Environment from directory structure or tfvars
165
+ environment = get_env("TF_VAR_environment", "dev")
166
+ project = "my-platform"
167
+ region = "us-east-1"
168
+ }
169
+
170
+ remote_state {
171
+ backend = "s3"
172
+ generate = {
173
+ path = "backend.tf"
174
+ if_exists = "overwrite_terragrunt"
175
+ }
176
+ config = {
177
+ bucket = "${local.project}-terraform-state"
178
+ key = "${path_relative_to_include()}/terraform.tfstate"
179
+ region = local.region
180
+ encrypt = true
181
+ dynamodb_table = "${local.project}-state-lock"
182
+ }
183
+ }
184
+
185
+ generate "provider" {
186
+ path = "provider.tf"
187
+ if_exists = "overwrite_terragrunt"
188
+ contents = <<EOF
189
+ provider "aws" {
190
+ region = "${local.region}"
191
+
192
+ default_tags {
193
+ tags = {
194
+ Project = "${local.project}"
195
+ Environment = "${local.environment}"
196
+ ManagedBy = "terragrunt"
197
+ }
198
+ }
199
+ }
200
+ EOF
201
+ }
202
+ ```
203
+
204
+ ## Implementation Tasks
205
+
206
+ | # | Task | Effort | Dependencies |
207
+ |---|------|--------|-------------|
208
+ | 1.9.1 | Add `--composition` flag to CLI (full/incremental/single) | 1d | — |
209
+ | 1.9.2 | Create `IntentDecomposer` class (AI call to break intent into stacks) | 2d | — |
210
+ | 1.9.3 | Create `CompositionPlan` + `StackPlan` models | 0.5d | — |
211
+ | 1.9.4 | Create `ProjectAssembler` (root.hcl, common/, merge stacks) | 1.5d | 1.9.3 |
212
+ | 1.9.5 | Generate `terragrunt.hcl` per stack (Jinja2 template + dependency wiring) | 1d | 1.9.4 |
213
+ | 1.9.6 | Loop: generate code per stack using existing `CodeGenerator` | 1d | 1.9.2, 1.9.5 |
214
+ | 1.9.7 | Validate full project (terraform validate per stack + org rules) | 0.5d | 1.9.6 |
215
+ | 1.9.8 | Write tests + docs | 0.5d | 1.9.7 |
216
+
217
+ ## Example Output
218
+
219
+ ```bash
220
+ $ thothctl generate iac \
221
+ -i "Fintech platform: VPC, ECS cluster, PostgreSQL RDS, S3 data lake" \
222
+ --project-type terraform-terragrunt \
223
+ --composition full \
224
+ -o ./fintech-infra \
225
+ --apply
226
+
227
+ 🎯 Intent: Fintech platform: VPC, ECS cluster, PostgreSQL RDS, S3 data lake
228
+ 🤖 Provider: bedrock (model: us.anthropic.claude-sonnet-4-6)
229
+ 📐 Composition: full project (terraform-terragrunt)
230
+
231
+ 🧩 Decomposed into 4 stacks:
232
+ foundation/networking/vpc — VPC with 3 AZs, NAT, flow logs
233
+ platform/compute/ecs — ECS Fargate cluster (depends: vpc)
234
+ platform/data/rds — PostgreSQL RDS Multi-AZ (depends: vpc)
235
+ platform/data/s3 — S3 data lake with KMS (depends: vpc)
236
+
237
+ 📁 Generating project structure...
238
+ ✅ root.hcl
239
+ ✅ common/common.hcl
240
+ ✅ stacks/foundation/networking/vpc/ (4 files)
241
+ ✅ stacks/platform/compute/ecs/ (4 files)
242
+ ✅ stacks/platform/data/rds/ (4 files)
243
+ ✅ stacks/platform/data/s3/ (4 files)
244
+
245
+ 🔒 Validating (Checkov + org rules)...
246
+ ✅ All stacks pass validation
247
+
248
+ ✨ Project generated: ./fintech-infra (18 files, 4 stacks)
249
+ Next: cd fintech-infra && terragrunt run-all plan
250
+ ```
251
+
252
+ ## CDK Composition (cdkv2 project type)
253
+
254
+ For CDK projects, the composition generates the app entry point + stack classes:
255
+
256
+ ```
257
+ my-cdk-app/
258
+ ├── bin/app.ts ← CDK app entry (instantiates all stacks)
259
+ ├── lib/
260
+ │ ├── stacks/
261
+ │ │ ├── foundation/
262
+ │ │ │ └── networking-stack.ts
263
+ │ │ ├── platform/
264
+ │ │ │ ├── compute-stack.ts
265
+ │ │ │ └── data-stack.ts
266
+ │ │ └── application/
267
+ │ │ └── api-stack.ts
268
+ │ └── constructs/ ← Shared L2/L3 constructs
269
+ ├── cdk.json
270
+ ├── package.json
271
+ └── tsconfig.json
272
+ ```
273
+
274
+ ## CloudFormation Composition
275
+
276
+ For CloudFormation, generates nested stacks with cross-stack references:
277
+
278
+ ```
279
+ my-cfn-project/
280
+ ├── templates/
281
+ │ ├── foundation/
282
+ │ │ └── networking.yaml ← Exports VpcId, SubnetIds
283
+ │ ├── platform/
284
+ │ │ ├── compute.yaml ← Imports !ImportValue VpcId
285
+ │ │ └── data.yaml
286
+ │ └── application/
287
+ │ └── api.yaml
288
+ ├── parameters/
289
+ │ ├── dev.json
290
+ │ └── prd.json
291
+ └── deploy.sh ← Ordered deployment script
292
+ ```
293
+
294
+ ## Success Criteria
295
+
296
+ - [ ] `--composition full` generates complete project with root config + multiple stacks
297
+ - [ ] Stacks placed in correct layer paths
298
+ - [ ] Dependencies wired correctly (terragrunt.hcl has dependency blocks)
299
+ - [ ] Org rules enforced across all generated stacks
300
+ - [ ] Works for terraform-terragrunt, cdkv2, cloudformation
301
+ - [ ] Incremental mode adds stacks without overwriting existing
302
+ - [ ] `terragrunt run-all plan` succeeds on generated project (no syntax errors)
@@ -36,6 +36,7 @@ class GenerateIaCCommand(ClickCommand):
36
36
  max_iterations: int = 3,
37
37
  skip_validation: bool = False,
38
38
  include_diagram: bool = True,
39
+ composition: str = "single",
39
40
  **kwargs,
40
41
  ) -> None:
41
42
  """Execute IaC generation from intent."""
@@ -120,6 +121,7 @@ class GenerateIaCCommand(ClickCommand):
120
121
  max_iterations=max_iterations,
121
122
  skip_validation=skip_validation,
122
123
  include_diagram=include_diagram,
124
+ composition=composition,
123
125
  )
124
126
 
125
127
  # Display results
@@ -287,4 +289,14 @@ cli = GenerateIaCCommand.as_click_command(
287
289
  default=True,
288
290
  help="Generate architecture diagram alongside code",
289
291
  ),
292
+ click.option(
293
+ "--composition",
294
+ type=click.Choice(["single", "full", "incremental"], case_sensitive=False),
295
+ default="single",
296
+ help=(
297
+ "Composition mode: 'single' generates one stack (default), "
298
+ "'full' generates a complete project with root config, "
299
+ "'incremental' adds stacks to an existing project"
300
+ ),
301
+ ),
290
302
  )
@@ -25,8 +25,17 @@ class BedrockProvider:
25
25
  if self._client is None:
26
26
  try:
27
27
  import boto3
28
+ from botocore.config import Config
28
29
 
29
- self._client = boto3.client("bedrock-runtime", region_name=self.region)
30
+ # IaC generation responses can be large; increase read timeout
31
+ config = Config(
32
+ read_timeout=300,
33
+ connect_timeout=10,
34
+ retries={"max_attempts": 2},
35
+ )
36
+ self._client = boto3.client(
37
+ "bedrock-runtime", region_name=self.region, config=config
38
+ )
30
39
  except ImportError:
31
40
  raise ImportError(
32
41
  "boto3 package required. Install with: pip install boto3"
@@ -131,15 +131,20 @@ class RulesCompiler:
131
131
 
132
132
  deny_or_warn = "deny" if severity == "error" else "warn"
133
133
 
134
+ type_filter = ""
135
+ if resource_types:
136
+ types_list = ", ".join(f'"{t}"' for t in resource_types)
137
+ type_filter = (
138
+ f"\n allowed_types := [{types_list}]"
139
+ f"\n resource_type == allowed_types[_]"
140
+ )
141
+
134
142
  rego_rule = textwrap.dedent(
135
143
  f"""\
136
144
  # Rule: {name}
137
- {deny_or_warn}[msg] {{
138
- resource_block := input.resource[_]
139
- resource_types := object.keys(resource_block)
140
- resource_type := resource_types[_]
141
- {"type_check := " + repr(resource_types) + chr(10) + " resource_type == type_check[_]" if resource_types else ""}
142
- instances := resource_block[resource_type]
145
+ {deny_or_warn} contains msg if {{
146
+ resource_type := object.keys(input.resource)[_]{type_filter}
147
+ instances := input.resource[resource_type]
143
148
  instance_name := object.keys(instances)[_]
144
149
  not regex.match(`{pattern}`, instance_name)
145
150
  msg := sprintf("{name}: resource '%s.%s' does not match naming pattern '{pattern}'", [resource_type, instance_name])
@@ -194,12 +199,11 @@ class RulesCompiler:
194
199
  rego_rule = textwrap.dedent(
195
200
  f"""\
196
201
  # Rule: {name}
197
- {deny_or_warn}[msg] {{
198
- resource_block := input.resource[_]
199
- resource_type := object.keys(resource_block)[_]
200
- {type_filter_line} instances := resource_block[resource_type]
202
+ {deny_or_warn} contains msg if {{
203
+ resource_type := object.keys(input.resource)[_]
204
+ {type_filter_line} instances := input.resource[resource_type]
201
205
  instance_name := object.keys(instances)[_]
202
- instance := instances[instance_name]
206
+ instance := instances[instance_name][_]
203
207
  required_tags := [{tags_str}]
204
208
  required_tag := required_tags[_]
205
209
  not instance.tags[required_tag]
@@ -248,12 +252,11 @@ class RulesCompiler:
248
252
  rego_rule = textwrap.dedent(
249
253
  f"""\
250
254
  # Rule: {rule_id} — banned pattern: {pattern}
251
- {deny_or_warn}[msg] {{
252
- resource_block := input.resource[_]
253
- resource_type := object.keys(resource_block)[_]
254
- instances := resource_block[resource_type]
255
+ {deny_or_warn} contains msg if {{
256
+ resource_type := object.keys(input.resource)[_]
257
+ instances := input.resource[resource_type]
255
258
  instance_name := object.keys(instances)[_]
256
- instance := instances[instance_name]
259
+ instance := instances[instance_name][_]
257
260
  walk(instance, [path, value])
258
261
  key_str := concat(".", path)
259
262
  val_str := sprintf("%v", [value])
@@ -306,14 +309,13 @@ class RulesCompiler:
306
309
  rego_rule = textwrap.dedent(
307
310
  f"""\
308
311
  # Rule: {name} — require multi-AZ for databases
309
- {deny_or_warn}[msg] {{
310
- resource_block := input.resource[_]
311
- resource_type := object.keys(resource_block)[_]
312
+ {deny_or_warn} contains msg if {{
312
313
  db_types := [{types_str}]
313
- resource_type == db_types[_]
314
- instances := resource_block[resource_type]
314
+ resource_type := db_types[_]
315
+ input.resource[resource_type]
316
+ instances := input.resource[resource_type]
315
317
  instance_name := object.keys(instances)[_]
316
- instance := instances[instance_name]
318
+ instance := instances[instance_name][_]
317
319
  not instance.multi_az == true
318
320
  msg := sprintf("{name}: resource '%s.%s' should have multi_az = true", [resource_type, instance_name])
319
321
  }}
@@ -328,7 +330,7 @@ class RulesCompiler:
328
330
  rego_rule = textwrap.dedent(
329
331
  f"""\
330
332
  # Rule: {name} — require module: {mod}
331
- {deny_or_warn}[msg] {{
333
+ {deny_or_warn} contains msg if {{
332
334
  modules := object.get(input, "module", [])
333
335
  module_sources := [src |
334
336
  mod_block := modules[_]
@@ -348,7 +350,7 @@ class RulesCompiler:
348
350
  rego_rule = textwrap.dedent(
349
351
  f"""\
350
352
  # Rule: {name} — max {max_resources} resources per file
351
- {deny_or_warn}[msg] {{
353
+ {deny_or_warn} contains msg if {{
352
354
  resources := input.resource
353
355
  count(resources) > {max_resources}
354
356
  msg := sprintf("{name}: file has %d resources (max {max_resources})", [count(resources)])
@@ -58,6 +58,8 @@ class CodeGenerator:
58
58
  config = settings.get_provider_config(provider_name)
59
59
  if model:
60
60
  config.model = model
61
+ # IaC generation needs higher token limit than review (full modules)
62
+ config.max_tokens = max(config.max_tokens, 16000)
61
63
  self._provider = cls(config)
62
64
  logger.info(
63
65
  f"AI provider initialized: {provider_name} (model: {config.model})"
@@ -91,7 +93,15 @@ class CodeGenerator:
91
93
 
92
94
  try:
93
95
  raw_result = self._provider.analyze(system_prompt, intent)
94
- return self._parse_response(raw_result)
96
+ output = self._parse_response(raw_result)
97
+
98
+ # Retry once if parsing failed (model sometimes returns malformed JSON)
99
+ if not output.files and output.raw_response:
100
+ logger.warning("First attempt returned no files — retrying generation")
101
+ raw_result = self._provider.analyze(system_prompt, intent)
102
+ output = self._parse_response(raw_result)
103
+
104
+ return output
95
105
  except Exception as e:
96
106
  logger.error(f"AI generation failed: {e}")
97
107
  return GenerationOutput(
@@ -0,0 +1,182 @@
1
+ """Composition models for multi-stack Intent-to-IaC decomposition.
2
+
3
+ Defines the data structures used to represent a decomposed infrastructure
4
+ intent as a collection of ordered stacks organized by architectural layers.
5
+ """
6
+
7
+ from collections import deque
8
+ from dataclasses import dataclass, field
9
+ from typing import Dict, List, Optional
10
+
11
+
12
+ # Canonical layer ordering (lower index = deployed first)
13
+ LAYER_ORDER: Dict[str, int] = {
14
+ "foundation": 0,
15
+ "platform": 1,
16
+ "application": 2,
17
+ "observability": 3,
18
+ }
19
+
20
+
21
+ @dataclass
22
+ class StackPlan:
23
+ """A single infrastructure stack within a composition plan.
24
+
25
+ Represents one logical unit of IaC (e.g., VPC, EKS cluster, RDS)
26
+ that maps to a directory of Terraform/Terragrunt files.
27
+ """
28
+
29
+ name: str # e.g., 'vpc'
30
+ layer: str # foundation | platform | application | observability
31
+ domain: str # e.g., 'networking', 'data', 'compute'
32
+ intent: str # Specific intent for this stack
33
+ depends_on: List[str] = field(default_factory=list) # Stack names
34
+ module_source: Optional[str] = None # Official module if applicable
35
+
36
+ @property
37
+ def path(self) -> str:
38
+ """Return the relative directory path for this stack."""
39
+ return f"stacks/{self.layer}/{self.domain}/{self.name}"
40
+
41
+ def __repr__(self) -> str:
42
+ """Return a concise string representation."""
43
+ deps = ", ".join(self.depends_on) if self.depends_on else "none"
44
+ return (
45
+ f"StackPlan(name={self.name!r}, layer={self.layer!r}, "
46
+ f"domain={self.domain!r}, depends_on=[{deps}])"
47
+ )
48
+
49
+
50
+ @dataclass
51
+ class CompositionPlan:
52
+ """A full decomposition of an intent into ordered stacks.
53
+
54
+ Contains all stacks needed to fulfil the user's infrastructure intent,
55
+ organized by layer with dependency information for correct ordering.
56
+ """
57
+
58
+ stacks: List[StackPlan] = field(default_factory=list)
59
+ project_type: str = "terraform"
60
+ needs_root_config: bool = True
61
+ needs_common: bool = True
62
+
63
+ @property
64
+ def stack_count(self) -> int:
65
+ """Return the total number of stacks in the plan."""
66
+ return len(self.stacks)
67
+
68
+ def get_stacks_by_layer(self, layer: str) -> List[StackPlan]:
69
+ """Return all stacks belonging to the specified layer.
70
+
71
+ Args:
72
+ layer: One of foundation, platform, application, observability.
73
+
74
+ Returns:
75
+ List of StackPlan objects in the given layer.
76
+ """
77
+ return [s for s in self.stacks if s.layer == layer]
78
+
79
+ def topological_order(self) -> List[StackPlan]:
80
+ """Return stacks in dependency-resolved order (Kahn's algorithm).
81
+
82
+ Stacks with no dependencies come first (foundation layer),
83
+ followed by stacks whose dependencies have already been resolved.
84
+ Ties within the same depth are broken by layer order, then name.
85
+
86
+ Returns:
87
+ List of StackPlan in topological (deployment) order.
88
+
89
+ Raises:
90
+ ValueError: If a circular dependency is detected.
91
+ """
92
+ if not self.stacks:
93
+ return []
94
+
95
+ # Build adjacency and in-degree maps by stack name
96
+ name_to_stack: Dict[str, StackPlan] = {s.name: s for s in self.stacks}
97
+ in_degree: Dict[str, int] = {s.name: 0 for s in self.stacks}
98
+ dependents: Dict[str, List[str]] = {s.name: [] for s in self.stacks}
99
+
100
+ for stack in self.stacks:
101
+ for dep in stack.depends_on:
102
+ if dep in name_to_stack:
103
+ in_degree[stack.name] += 1
104
+ dependents[dep].append(stack.name)
105
+
106
+ # Initialize queue with zero in-degree nodes
107
+ queue: deque = deque(
108
+ sorted(
109
+ [name for name, deg in in_degree.items() if deg == 0],
110
+ key=lambda n: (
111
+ LAYER_ORDER.get(name_to_stack[n].layer, 99),
112
+ n,
113
+ ),
114
+ )
115
+ )
116
+
117
+ result: List[StackPlan] = []
118
+ while queue:
119
+ current = queue.popleft()
120
+ result.append(name_to_stack[current])
121
+
122
+ # Collect and sort newly available nodes for determinism
123
+ newly_available: List[str] = []
124
+ for dependent in dependents[current]:
125
+ in_degree[dependent] -= 1
126
+ if in_degree[dependent] == 0:
127
+ newly_available.append(dependent)
128
+
129
+ # Sort by layer order then name for stable output
130
+ newly_available.sort(
131
+ key=lambda n: (
132
+ LAYER_ORDER.get(name_to_stack[n].layer, 99),
133
+ n,
134
+ )
135
+ )
136
+ queue.extend(newly_available)
137
+
138
+ if len(result) != len(self.stacks):
139
+ resolved = {s.name for s in result}
140
+ unresolved = [s.name for s in self.stacks if s.name not in resolved]
141
+ raise ValueError(f"Circular dependency detected among stacks: {unresolved}")
142
+
143
+ return result
144
+
145
+ def validate(self) -> List[str]:
146
+ """Validate the composition plan for common issues.
147
+
148
+ Returns:
149
+ List of warning/error messages (empty if valid).
150
+ """
151
+ issues: List[str] = []
152
+ valid_layers = set(LAYER_ORDER.keys())
153
+ known_names = {s.name for s in self.stacks}
154
+
155
+ for stack in self.stacks:
156
+ if stack.layer not in valid_layers:
157
+ issues.append(
158
+ f"Stack '{stack.name}' has invalid layer "
159
+ f"'{stack.layer}'. Must be one of: "
160
+ f"{', '.join(valid_layers)}"
161
+ )
162
+
163
+ for dep in stack.depends_on:
164
+ if dep not in known_names:
165
+ issues.append(
166
+ f"Stack '{stack.name}' depends on unknown stack '{dep}'"
167
+ )
168
+
169
+ # Check layer ordering consistency
170
+ for dep in stack.depends_on:
171
+ if dep in known_names:
172
+ dep_stack = next(s for s in self.stacks if s.name == dep)
173
+ dep_order = LAYER_ORDER.get(dep_stack.layer, 99)
174
+ self_order = LAYER_ORDER.get(stack.layer, 99)
175
+ if dep_order > self_order:
176
+ issues.append(
177
+ f"Stack '{stack.name}' ({stack.layer}) "
178
+ f"depends on '{dep}' ({dep_stack.layer}) "
179
+ f"which is in a higher layer"
180
+ )
181
+
182
+ return issues