thothctl 0.16.2__tar.gz → 0.16.4__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 (505) hide show
  1. {thothctl-0.16.2 → thothctl-0.16.4}/PKG-INFO +1 -1
  2. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/check_project_iac.md +90 -0
  3. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/scan/scan_iac.md +90 -2
  4. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/scan/scan_overview.md +4 -2
  5. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/tasks/create_template.md +4 -4
  6. {thothctl-0.16.2 → thothctl-0.16.4}/docs/index.md +2 -0
  7. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/commands/project/iac.py +89 -3
  8. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/version_tools.py +1 -1
  9. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/ai_agent.py +30 -2
  10. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/analyzers/code_reviewer.py +7 -1
  11. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/analyzers/context_builder.py +77 -27
  12. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/config/ai_settings.py +1 -1
  13. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/providers/ollama_provider.py +63 -4
  14. thothctl-0.16.4/src/thothctl/services/ai_review/strands_agent.py +119 -0
  15. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/utils/prompts.py +31 -10
  16. thothctl-0.16.4/src/thothctl/services/check/org_policy_loader.py +95 -0
  17. thothctl-0.16.4/src/thothctl/services/check/rule_merger.py +182 -0
  18. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scan_service.py +2 -1
  19. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/opa.py +10 -0
  20. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/scanners.py +2 -1
  21. thothctl-0.16.4/src/thothctl/services/scan/scanners/terraform_compliance.py +338 -0
  22. thothctl-0.16.4/src/thothctl/version.py +2 -0
  23. thothctl-0.16.2/src/thothctl/services/scan/scanners/terraform_compliance.py +0 -0
  24. thothctl-0.16.2/src/thothctl/version.py +0 -2
  25. {thothctl-0.16.2 → thothctl-0.16.4}/.devcontainer/Dockerfile +0 -0
  26. {thothctl-0.16.2 → thothctl-0.16.4}/.devcontainer/README.md +0 -0
  27. {thothctl-0.16.2 → thothctl-0.16.4}/.devcontainer/devcontainer.json +0 -0
  28. {thothctl-0.16.2 → thothctl-0.16.4}/.github/workflows/docs.yml +0 -0
  29. {thothctl-0.16.2 → thothctl-0.16.4}/.github/workflows/python-publish.yml +0 -0
  30. {thothctl-0.16.2 → thothctl-0.16.4}/.gitignore +0 -0
  31. {thothctl-0.16.2 → thothctl-0.16.4}/.pre-commit-config.yaml +0 -0
  32. {thothctl-0.16.2 → thothctl-0.16.4}/.readthedocs.yaml +0 -0
  33. {thothctl-0.16.2 → thothctl-0.16.4}/AWS_PRICING_API_FINAL_REPORT.md +0 -0
  34. {thothctl-0.16.2 → thothctl-0.16.4}/AWS_PRICING_API_IMPLEMENTATION_PLAN.md +0 -0
  35. {thothctl-0.16.2 → thothctl-0.16.4}/AWS_PRICING_REFACTOR_REPORT.md +0 -0
  36. {thothctl-0.16.2 → thothctl-0.16.4}/Dockerfile +0 -0
  37. {thothctl-0.16.2 → thothctl-0.16.4}/LICENSE +0 -0
  38. {thothctl-0.16.2 → thothctl-0.16.4}/README.md +0 -0
  39. {thothctl-0.16.2 → thothctl-0.16.4}/TECHNICAL_DEBT_METRICS.md +0 -0
  40. {thothctl-0.16.2 → thothctl-0.16.4}/__init__.py +0 -0
  41. {thothctl-0.16.2 → thothctl-0.16.4}/docs/catalog/catalog-info.yaml +0 -0
  42. {thothctl-0.16.2 → thothctl-0.16.4}/docs/dashboard/README.md +0 -0
  43. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/ai-review/README.md +0 -0
  44. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/ai-review/agent_specifications.md +0 -0
  45. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/ai-review/agentcore.md +0 -0
  46. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/blast-radius.md +0 -0
  47. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/check_environment.md +0 -0
  48. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/check_iac.md +0 -0
  49. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/check_overview.md +0 -0
  50. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/check_space.md +0 -0
  51. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/cost-analysis-quick-reference.md +0 -0
  52. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/cost-analysis.md +0 -0
  53. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/customizing_rules.md +0 -0
  54. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/deps-advanced.md +0 -0
  55. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/deps.md +0 -0
  56. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/drift-detection.md +0 -0
  57. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/check/plan.md +0 -0
  58. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/document/customizing_docs.md +0 -0
  59. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/document/document_iac.md +0 -0
  60. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/document/document_overview.md +0 -0
  61. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/document/iac.md +0 -0
  62. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/document/use_cases.md +0 -0
  63. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/generate/generate_components.md +0 -0
  64. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/generate/generate_stacks.md +0 -0
  65. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/init/init.md +0 -0
  66. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/init/init_space.md +0 -0
  67. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/inventory/CHANGELOG.md +0 -0
  68. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/inventory/frameworks/terraform.md +0 -0
  69. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/inventory/frameworks/terragrunt.md +0 -0
  70. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/inventory/iac.md +0 -0
  71. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/inventory/inventory_iac.md +0 -0
  72. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/inventory/inventory_overview.md +0 -0
  73. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/list/list_overview.md +0 -0
  74. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/list/list_projects.md +0 -0
  75. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/list/list_spaces.md +0 -0
  76. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/mcp/mcp.md +0 -0
  77. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/project/iac.md +0 -0
  78. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/project/project_cleanup.md +0 -0
  79. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/project/project_convert.md +0 -0
  80. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/project/project_overview.md +0 -0
  81. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/project/project_upgrade.md +0 -0
  82. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/project/use_cases.md +0 -0
  83. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/remove/remove_overview.md +0 -0
  84. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/remove/remove_project.md +0 -0
  85. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/remove/remove_space.md +0 -0
  86. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/scan/iac.md +0 -0
  87. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/scan/use_cases.md +0 -0
  88. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/commands/upgrade/upgrade_overview.md +0 -0
  89. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/concepts.md +0 -0
  90. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/cross_platform_support.md +0 -0
  91. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/framework_architecture.md +0 -0
  92. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/infrasctructure_composition.md +0 -0
  93. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/policy_as_code.md +0 -0
  94. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/roadmap_fdi.md +0 -0
  95. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/software_architecture.md +0 -0
  96. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/space_configuration.md +0 -0
  97. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/README.md +0 -0
  98. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/ai_dlc.md +0 -0
  99. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/check_command.md +0 -0
  100. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/devsecops_quickstart.md +0 -0
  101. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/devsecops_sdlc.md +0 -0
  102. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/inventory_command.md +0 -0
  103. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/platform_engineering_templates.md +0 -0
  104. {thothctl-0.16.2 → thothctl-0.16.4}/docs/framework/use_cases/space_management.md +0 -0
  105. {thothctl-0.16.2 → thothctl-0.16.4}/docs/iac_devsecops_use_case.md +0 -0
  106. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/automate_tasks_command.png +0 -0
  107. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/commnad_init.png +0 -0
  108. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/create_component.gif +0 -0
  109. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/create_inventory.gif +0 -0
  110. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/doc_command.png +0 -0
  111. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/document_project_code.gif +0 -0
  112. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/framework/thothforge-framework.svg +0 -0
  113. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/framework/thothfr.png +0 -0
  114. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/iacpeerbot_summary.png +0 -0
  115. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/icon-light.png +0 -0
  116. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/icon.png +0 -0
  117. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/init_project.gif +0 -0
  118. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/inventory_command.png +0 -0
  119. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/notification_img.png +0 -0
  120. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/report_dependencies.png +0 -0
  121. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/report_dependencies_summary.png +0 -0
  122. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/restore_inventory_version.gif +0 -0
  123. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/reuse_project_pattern.gif +0 -0
  124. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/scan_code.gif +0 -0
  125. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/scan_command.png +0 -0
  126. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/sync_wk_command.png +0 -0
  127. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/transform_command.png +0 -0
  128. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/update_inventory_version.gif +0 -0
  129. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/validate_command.png +0 -0
  130. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/validate_environment.gif +0 -0
  131. {thothctl-0.16.2 → thothctl-0.16.4}/docs/img/validate_project.gif +0 -0
  132. {thothctl-0.16.2 → thothctl-0.16.4}/docs/includes/abbreviations.md +0 -0
  133. {thothctl-0.16.2 → thothctl-0.16.4}/docs/installation/linux_installation.md +0 -0
  134. {thothctl-0.16.2 → thothctl-0.16.4}/docs/installation/windows_installation.md +0 -0
  135. {thothctl-0.16.2 → thothctl-0.16.4}/docs/javascripts/tablesort.js +0 -0
  136. {thothctl-0.16.2 → thothctl-0.16.4}/docs/mcp.md +0 -0
  137. {thothctl-0.16.2 → thothctl-0.16.4}/docs/navigation.md +0 -0
  138. {thothctl-0.16.2 → thothctl-0.16.4}/docs/quick_start.md +0 -0
  139. {thothctl-0.16.2 → thothctl-0.16.4}/docs/requirements.txt +0 -0
  140. {thothctl-0.16.2 → thothctl-0.16.4}/docs/stylesheets/extra-enhanced.css +0 -0
  141. {thothctl-0.16.2 → thothctl-0.16.4}/docs/stylesheets/extra.css +0 -0
  142. {thothctl-0.16.2 → thothctl-0.16.4}/docs/telemetry.md +0 -0
  143. {thothctl-0.16.2 → thothctl-0.16.4}/docs/template_engine/cli_commands_audit.md +0 -0
  144. {thothctl-0.16.2 → thothctl-0.16.4}/docs/template_engine/for_developers.md +0 -0
  145. {thothctl-0.16.2 → thothctl-0.16.4}/docs/template_engine/for_platform_engineers.md +0 -0
  146. {thothctl-0.16.2 → thothctl-0.16.4}/docs/template_engine/github_templates.md +0 -0
  147. {thothctl-0.16.2 → thothctl-0.16.4}/docs/template_engine/template_engine.md +0 -0
  148. {thothctl-0.16.2 → thothctl-0.16.4}/docs/troubleshooting/linux_troubleshooting.md +0 -0
  149. {thothctl-0.16.2 → thothctl-0.16.4}/docs/troubleshooting/macos_troubleshooting.md +0 -0
  150. {thothctl-0.16.2 → thothctl-0.16.4}/docs/troubleshooting/troubleshooting.md +0 -0
  151. {thothctl-0.16.2 → thothctl-0.16.4}/docs/troubleshooting/windows_troubleshooting.md +0 -0
  152. {thothctl-0.16.2 → thothctl-0.16.4}/mkdocs.yaml +0 -0
  153. {thothctl-0.16.2 → thothctl-0.16.4}/pyproject.toml +0 -0
  154. {thothctl-0.16.2 → thothctl-0.16.4}/scripts/run_mcp_server.sh +0 -0
  155. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/__init__.py +0 -0
  156. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/application/__init__.py +0 -0
  157. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/autocomplete.py +0 -0
  158. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/cli.py +0 -0
  159. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/__init__.py +0 -0
  160. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/__init__.py +0 -0
  161. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/cli.py +0 -0
  162. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/__init__.py +0 -0
  163. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/analyze.py +0 -0
  164. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/apply_fix.py +0 -0
  165. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/configure.py +0 -0
  166. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/configure_decisions.py +0 -0
  167. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/decide.py +0 -0
  168. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/history.py +0 -0
  169. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/improve.py +0 -0
  170. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/orchestrate.py +0 -0
  171. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/override.py +0 -0
  172. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/report.py +0 -0
  173. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/ai_review/commands/serve.py +0 -0
  174. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/__init__.py +0 -0
  175. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/cli.py +0 -0
  176. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/commands/__init__.py +0 -0
  177. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/commands/environment.py +0 -0
  178. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/commands/iac.py +0 -0
  179. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/commands/project/__init__.py +0 -0
  180. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/check/commands/project.py +0 -0
  181. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/dashboard/__init__.py +0 -0
  182. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/dashboard/cli.py +0 -0
  183. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/dashboard/commands/__init__.py +0 -0
  184. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/dashboard/commands/launch.py +0 -0
  185. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/document/__init__.py +0 -0
  186. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/document/cli.py +0 -0
  187. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/document/commands/__init__.py +0 -0
  188. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/document/commands/iac.py +0 -0
  189. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/generate/__init__.py +0 -0
  190. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/generate/cli.py +0 -0
  191. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/generate/commands/__init__.py +0 -0
  192. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/generate/commands/component.py +0 -0
  193. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/generate/commands/stacks.py +0 -0
  194. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/__init__.py +0 -0
  195. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/cli.py +0 -0
  196. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/commands/__init__.py +0 -0
  197. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/commands/env.py +0 -0
  198. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/commands/project.py +0 -0
  199. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/commands/space.py +0 -0
  200. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/init/commands/template.py +0 -0
  201. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/inventory/__init__.py +0 -0
  202. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/inventory/cli.py +0 -0
  203. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/inventory/commands/__init__.py +0 -0
  204. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/inventory/commands/check.py +0 -0
  205. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/inventory/commands/iac.py +0 -0
  206. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/list/__init__.py +0 -0
  207. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/list/cli.py +0 -0
  208. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/list/commands/__init__.py +0 -0
  209. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/list/commands/projects.py +0 -0
  210. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/list/commands/spaces.py +0 -0
  211. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/__init__.py +0 -0
  212. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/cli.py +0 -0
  213. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/commands/__init__.py +0 -0
  214. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/commands/register.py +0 -0
  215. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/commands/server.py +0 -0
  216. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/commands/status.py +0 -0
  217. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/mcp/commands/stop.py +0 -0
  218. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/__init__.py +0 -0
  219. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/cli.py +0 -0
  220. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/commands/__init__.py +0 -0
  221. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/commands/bootstrap.py +0 -0
  222. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/commands/cleanup.py +0 -0
  223. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/commands/convert.py +0 -0
  224. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/project/commands/upgrade.py +0 -0
  225. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/remove/__init__.py +0 -0
  226. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/remove/cli.py +0 -0
  227. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/remove/project.py +0 -0
  228. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/remove/space.py +0 -0
  229. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/scan/__init__.py +0 -0
  230. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/scan/cli.py +0 -0
  231. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/scan/commands/__init__.py +0 -0
  232. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/scan/commands/iac.py +0 -0
  233. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/space/__init__.py +0 -0
  234. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/space/cli.py +0 -0
  235. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/space/commands/__init__.py +0 -0
  236. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/space/commands/activate.py +0 -0
  237. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/space/commands/update.py +0 -0
  238. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/commands/upgrade/cli.py +0 -0
  239. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/.thothcf.setup.toml +0 -0
  240. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/.thothcf_home.toml +0 -0
  241. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/.thothcf_module.toml +0 -0
  242. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/.thothcf_project.toml +0 -0
  243. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/.thothcf_template_parameters.toml +0 -0
  244. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/__init__.py +0 -0
  245. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/common.py +0 -0
  246. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/common/terragrunt/.thothcf_project.toml +0 -0
  247. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/__init__.py +0 -0
  248. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/constants.py +0 -0
  249. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/default_values.py +0 -0
  250. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/defaults.py +0 -0
  251. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/models.py +0 -0
  252. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/settings.py +0 -0
  253. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/template_config.py +0 -0
  254. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/template_configs.py +0 -0
  255. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/templates.py +0 -0
  256. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/config/validation.py +0 -0
  257. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/__init__.py +0 -0
  258. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/cli_ui.py +0 -0
  259. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/commands.py +0 -0
  260. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/config.py +0 -0
  261. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/__init__.py +0 -0
  262. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/azure_devops/__init__.py +0 -0
  263. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/azure_devops/get_azure_devops.py +0 -0
  264. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/azure_devops/pull_request_comments.py +0 -0
  265. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/github/get_github.py +0 -0
  266. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/github/pull_request_comments.py +0 -0
  267. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/integrate_messages_services/__init__.py +0 -0
  268. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/integrate_messages_services/microsoft_teams.py +0 -0
  269. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/integrate_messages_services/sent_message_teams.py +0 -0
  270. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/pattern_names.py +0 -0
  271. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/pr_comments/__init__.py +0 -0
  272. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/integrations/pr_comments/pr_comment_publisher.py +0 -0
  273. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/logger.py +0 -0
  274. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/core/telemetry.py +0 -0
  275. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/domain/__init__.py +0 -0
  276. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/domain/interfaces/__init__.py +0 -0
  277. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/domain/models/__init__.py +0 -0
  278. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/mcp/README.md +0 -0
  279. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/mcp/__init__.py +0 -0
  280. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/mcp/server.py +0 -0
  281. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/__init__.py +0 -0
  282. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/__init__.py +0 -0
  283. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/agentcore/agentcore.json +0 -0
  284. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/analyzers/__init__.py +0 -0
  285. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/analyzers/report_analyzer.py +0 -0
  286. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/analyzers/risk_assessor.py +0 -0
  287. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/bedrock_agent_api.py +0 -0
  288. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/config/__init__.py +0 -0
  289. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/config/decision_rules.py +0 -0
  290. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/decision_engine.py +0 -0
  291. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/main.py +0 -0
  292. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/memory.py +0 -0
  293. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/orchestrator.py +0 -0
  294. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/pr_decision_publisher.py +0 -0
  295. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/providers/__init__.py +0 -0
  296. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/providers/azure_provider.py +0 -0
  297. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/providers/bedrock_agent_provider.py +0 -0
  298. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/providers/bedrock_provider.py +0 -0
  299. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/providers/openai_provider.py +0 -0
  300. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/safety/__init__.py +0 -0
  301. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/safety/safety_guard.py +0 -0
  302. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/tracing.py +0 -0
  303. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/utils/__init__.py +0 -0
  304. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/utils/cost_tracker.py +0 -0
  305. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/utils/fix_patterns.py +0 -0
  306. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/utils/fix_prompts.py +0 -0
  307. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/ai_review/utils/formatters.py +0 -0
  308. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/__init__.py +0 -0
  309. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/environment/__init__.py +0 -0
  310. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/environment/check_environment.py +0 -0
  311. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/__init__.py +0 -0
  312. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/blast_radius_service.py +0 -0
  313. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/check_origin_version.py +0 -0
  314. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/check_project_structure.py +0 -0
  315. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/__init__.py +0 -0
  316. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/cost_analyzer.py +0 -0
  317. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/models/__init__.py +0 -0
  318. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/models/cloudformation_mapper.py +0 -0
  319. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/models/cost_models.py +0 -0
  320. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/__init__.py +0 -0
  321. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/aws_pricing_client.py +0 -0
  322. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/base_pricing.py +0 -0
  323. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/__init__.py +0 -0
  324. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/apigateway_pricing.py +0 -0
  325. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/bedrock_pricing.py +0 -0
  326. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/cloudwatch_pricing.py +0 -0
  327. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/dynamodb_pricing.py +0 -0
  328. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/ebs_pricing.py +0 -0
  329. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/ec2_pricing.py +0 -0
  330. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/ecs_pricing.py +0 -0
  331. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/eip_pricing.py +0 -0
  332. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/eks_pricing.py +0 -0
  333. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/elb_pricing.py +0 -0
  334. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/free_resources_pricing.py +0 -0
  335. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/kms_pricing.py +0 -0
  336. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/lambda_pricing.py +0 -0
  337. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/msk_pricing.py +0 -0
  338. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/rds_pricing.py +0 -0
  339. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/s3_pricing.py +0 -0
  340. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/secrets_manager_pricing.py +0 -0
  341. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/pricing/providers/vpc_pricing.py +0 -0
  342. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/cost/unified_cost_report.py +0 -0
  343. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/__init__.py +0 -0
  344. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/drift_ai.py +0 -0
  345. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/drift_history.py +0 -0
  346. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/drift_policy.py +0 -0
  347. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/drift_report.py +0 -0
  348. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/drift_service.py +0 -0
  349. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/drift/models.py +0 -0
  350. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/risk_assessment.py +0 -0
  351. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/check/project/validate_project_structure.py +0 -0
  352. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/dashboard/__init__.py +0 -0
  353. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/dashboard/dashboard_service.py +0 -0
  354. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/dashboard/data_loader.py +0 -0
  355. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/__init__.py +0 -0
  356. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/create_documentation.py +0 -0
  357. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/files_content.py +0 -0
  358. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/files_scan.py +0 -0
  359. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/iac_documentation.py +0 -0
  360. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/iac_grunt_graph.py +0 -0
  361. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/document/iac_grunt_info.py +0 -0
  362. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/__init__.py +0 -0
  363. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_stacks/__init__.py +0 -0
  364. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_stacks/config_generator.py +0 -0
  365. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_stacks/remote_config_generation.py +0 -0
  366. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_stacks/stack_service.py +0 -0
  367. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_stacks/templates/terragrunt.hcl.j2 +0 -0
  368. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/__init__.py +0 -0
  369. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/config.yaml +0 -0
  370. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/create_code.py +0 -0
  371. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/create_component.py +0 -0
  372. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/create_component_service.py +0 -0
  373. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/create_stacks.py +0 -0
  374. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/create_template.py +0 -0
  375. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/files_content.py +0 -0
  376. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/github_template_loader.py +0 -0
  377. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/generate/create_template/project_templates.py +0 -0
  378. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/__init__.py +0 -0
  379. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/environment/__init__.py +0 -0
  380. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/environment/install_tools.py +0 -0
  381. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/project/__init__.py +0 -0
  382. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/project/project.py +0 -0
  383. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/space/__init__.py +0 -0
  384. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/space/example_space.toml +0 -0
  385. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/space/local_registry.py +0 -0
  386. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/init/space/space.py +0 -0
  387. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/__init__.py +0 -0
  388. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/changelog_parser.py +0 -0
  389. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/inventory_service.py +0 -0
  390. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/models.py +0 -0
  391. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/module_compatibility_service.py +0 -0
  392. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/report_service.py +0 -0
  393. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/schema_compatibility_service.py +0 -0
  394. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/terragrunt_parser.py +0 -0
  395. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/update_versions.py +0 -0
  396. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/inventory/version_service.py +0 -0
  397. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/mcp/README.md +0 -0
  398. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/mcp/__init__.py +0 -0
  399. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/mcp/amazon_q_server.py +0 -0
  400. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/mcp/example.py +0 -0
  401. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/mcp/service.py +0 -0
  402. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/mcp/simple_http_server.py +0 -0
  403. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/__init__.py +0 -0
  404. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/bootstrap/__init__.py +0 -0
  405. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/bootstrap/bootstrap_service.py +0 -0
  406. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/cleanup/__init__.py +0 -0
  407. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/cleanup/clean_project.py +0 -0
  408. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/cleanup/clean_space.py +0 -0
  409. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/__init__.py +0 -0
  410. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/conversion_service.py +0 -0
  411. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/get_project_data.py +0 -0
  412. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/post_init.py +0 -0
  413. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/project_converter.py +0 -0
  414. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/project_defaults.py +0 -0
  415. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/convert/set_project_parameters.py +0 -0
  416. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/create_terramate/__init__.py +0 -0
  417. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/create_terramate/create_terramate_stacks.py +0 -0
  418. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/create_terramate/detect_changes_stacks.py +0 -0
  419. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/create_terramate/manage_terramate_stacks.py +0 -0
  420. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/upgrade/__init__.py +0 -0
  421. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/project/upgrade/upgrade_service.py +0 -0
  422. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/__init__.py +0 -0
  423. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/compliance_review.py +0 -0
  424. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/import_reports.py +0 -0
  425. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/models.py +0 -0
  426. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/report_parser.py +0 -0
  427. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/sarif_output.py +0 -0
  428. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scan_history.py +0 -0
  429. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/__init__.py +0 -0
  430. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/checkov.py +0 -0
  431. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/kics.py +0 -0
  432. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/scan_reports.py +0 -0
  433. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/tfsec.py +0 -0
  434. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/services/scan/scanners/trivy.py +0 -0
  435. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/templates/reports/inventory_report.html +0 -0
  436. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/templates/reports/inventory_report.js +0 -0
  437. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/templates/unified_report_styles.css +0 -0
  438. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/__init__.py +0 -0
  439. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/banner.py +0 -0
  440. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/__init__.py +0 -0
  441. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/create_compliance_html_reports.py +0 -0
  442. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/create_html_reports.py +0 -0
  443. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/delete_directory.py +0 -0
  444. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/fix_report_styling.py +0 -0
  445. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/render_scan_report.py +0 -0
  446. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/report_html_utils.py +0 -0
  447. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/dashboard.html +0 -0
  448. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/index_report.html +0 -0
  449. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/individual_report.html +0 -0
  450. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/simple_report.html +0 -0
  451. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/unified_report_styles.css +0 -0
  452. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/unified_scan_report.html +0 -0
  453. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/unified_simple_report.html +0 -0
  454. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/common/templates/xunit_report.html +0 -0
  455. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/crypto.py +0 -0
  456. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/manage_backend_resources/__init__.py +0 -0
  457. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/manage_backend_resources/manage_backend_resources.py +0 -0
  458. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/modules_ops/__init__.py +0 -0
  459. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/modules_ops/terraform_module_details.py +0 -0
  460. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/modules_ops/terraform_modules_fetcher.py +0 -0
  461. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/platform_utils.py +0 -0
  462. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/process_hcl/__init__.py +0 -0
  463. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/process_hcl/analyze_terraform_plan.py +0 -0
  464. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/process_hcl/graph_manager.py +0 -0
  465. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/process_hcl/graph_terragrunt_dependencies.py +0 -0
  466. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/process_hcl/process_terraform_file.py +0 -0
  467. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/process_hcl/risk_analyzing_terraform_plan.py +0 -0
  468. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/sync_workspaces/__init__.py +0 -0
  469. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/sync_workspaces/sync_terraform_workspaces.py +0 -0
  470. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/sync_workspaces/sync_terragrunt_workspaces.py +0 -0
  471. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/template_loader.py +0 -0
  472. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/utils/thoth_colors.py +0 -0
  473. {thothctl-0.16.2 → thothctl-0.16.4}/src/thothctl/wellcome_banner.py +0 -0
  474. {thothctl-0.16.2 → thothctl-0.16.4}/tests/conftest.py +0 -0
  475. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_agentcore_entrypoint.py +0 -0
  476. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_aws_pricing_client.py +0 -0
  477. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_azure_devops_pr_comments.py +0 -0
  478. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_bedrock_pricing.py +0 -0
  479. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_cdk_language_selection.py +0 -0
  480. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_context_steering.py +0 -0
  481. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_cost_analyzer.py +0 -0
  482. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_cost_models.py +0 -0
  483. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_cost_pr_comments.py +0 -0
  484. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_dashboard_loading_fix.py +0 -0
  485. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_dashboard_service.py +0 -0
  486. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_drift.py +0 -0
  487. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_drift_detection.py +0 -0
  488. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_ec2_pricing.py +0 -0
  489. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_github_pr_comments.py +0 -0
  490. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_iac_cost_integration.py +0 -0
  491. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_inventory_pr_comments.py +0 -0
  492. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_kics_scanner.py +0 -0
  493. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_mermaid_edge_labels.py +0 -0
  494. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_new_cost_providers.py +0 -0
  495. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_parallel_scan.py +0 -0
  496. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_platform_utils.py +0 -0
  497. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_pr_comment_publisher.py +0 -0
  498. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_provider_source_url_fix.py +0 -0
  499. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_provider_versions.py +0 -0
  500. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_scan_pr_comments.py +0 -0
  501. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_space_command.py +0 -0
  502. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_space_management.py +0 -0
  503. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_template_url_fix.py +0 -0
  504. {thothctl-0.16.2 → thothctl-0.16.4}/tests/test_terragrunt_parser.py +0 -0
  505. {thothctl-0.16.2 → thothctl-0.16.4}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thothctl
3
- Version: 0.16.2
3
+ Version: 0.16.4
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
@@ -17,9 +17,99 @@ Options:
17
17
  Type of IaC check to perform [default: structure]
18
18
  -p, --project-type [stack|module]
19
19
  Project type: stack or module [default: stack]
20
+ --org-policy TEXT Organization policy source (Git URL or local path)
21
+ --enforcement [soft|hard] Enforcement mode: soft (report) or hard (fail pipeline)
20
22
  --help Show this message and exit.
21
23
  ```
22
24
 
25
+ ## Organization Policy Enforcement
26
+
27
+ ThothCTL can enforce organizational standards that projects **cannot override**. This ensures all projects in your organization follow the same structure, naming, and tagging rules — regardless of what individual `.thothcf.toml` files contain.
28
+
29
+ ### How It Works
30
+
31
+ 1. Set `THOTH_ORG_POLICY` to your org policy Git repo (or pass `--org-policy`)
32
+ 2. The repo contains `rules/base.toml` + `rules/<project_type>.toml`
33
+ 3. ThothCTL merges org rules with project rules — **mandatory org rules cannot be weakened**
34
+ 4. Violations are reported with enforcement level (mandatory = fail, recommended = warn)
35
+
36
+ ### Usage
37
+
38
+ ```bash
39
+ # Via env var (CI/CD recommended)
40
+ export THOTH_ORG_POLICY=https://github.com/myorg/org-policies.git
41
+ thothctl check project iac --enforcement hard
42
+
43
+ # Pin to a version
44
+ export THOTH_ORG_POLICY=https://github.com/myorg/org-policies.git@v1.0
45
+ thothctl check project iac --enforcement hard
46
+
47
+ # Via flag
48
+ thothctl check project iac --org-policy /path/to/org-policies --enforcement hard
49
+
50
+ # Local path (development)
51
+ thothctl check project iac --org-policy ../org-iac-policies
52
+ ```
53
+
54
+ ### Enforcement Levels
55
+
56
+ | Level | Behavior | Project Can Override? |
57
+ |-------|----------|---------------------|
58
+ | `mandatory` | Fails pipeline with `--enforcement hard` | ❌ No |
59
+ | `recommended` | Warning only | ⚠️ Can opt-out |
60
+ | `informational` | Report only | ✅ Yes |
61
+
62
+ ### Org Policy Repo Structure
63
+
64
+ ```
65
+ org-policies/
66
+ ├── rules/ # ThothCTL structural rules
67
+ │ ├── base.toml # All project types
68
+ │ ├── terraform-terragrunt.toml
69
+ │ ├── terraform_module.toml
70
+ │ └── cdkv2.toml
71
+ ├── shared/policy/ # OPA/Rego policies (used by scan iac -t opa)
72
+ │ ├── naming.rego
73
+ │ ├── tagging.rego
74
+ │ └── regions.rego
75
+ └── README.md
76
+ ```
77
+
78
+ The same repo serves both:
79
+ - **`thothctl check project iac`** → reads `rules/`
80
+ - **`thothctl scan iac -t opa`** → reads `shared/policy/` (auto-discovered via `THOTH_ORG_POLICY`)
81
+
82
+ ### Example Output
83
+
84
+ ```
85
+ 📜 Loading org policy from: https://github.com/myorg/org-policies.git
86
+
87
+ ❌ Mandatory Violations
88
+ ┌────────────────────────────────────┬─────────────────┬─────────┐
89
+ │ Rule │ Expected │ Found │
90
+ ├────────────────────────────────────┼─────────────────┼─────────┤
91
+ │ project_structure.folders.docs │ docs/ exists │ missing │
92
+ │ project_structure.root_files │ .pre-commit... │ missing │
93
+ └────────────────────────────────────┴─────────────────┴─────────┘
94
+
95
+ ⚠️ Recommendations
96
+ ┌────────────────────────────────────┬─────────────────┬─────────┐
97
+ │ Rule │ Expected │ Found │
98
+ ├────────────────────────────────────┼─────────────────┼─────────┤
99
+ │ project_structure.folders.common │ common/ exists │ missing │
100
+ └────────────────────────────────────┴─────────────────┴─────────┘
101
+ ```
102
+
103
+ ### CI/CD Integration
104
+
105
+ ```yaml
106
+ # GitHub Actions
107
+ - name: Check org compliance
108
+ run: thothctl check project iac --enforcement hard
109
+ env:
110
+ THOTH_ORG_POLICY: https://github.com/myorg/org-policies.git@v1.0
111
+ ```
112
+
23
113
  ## Project Types
24
114
 
25
115
  ### Stack Projects (`-p stack`)
@@ -58,13 +58,101 @@ thothctl scan iac -t kics
58
58
 
59
59
  ### Terraform-compliance
60
60
 
61
- [Terraform-compliance](https://terraform-compliance.com/) is a lightweight, security and compliance focused test framework against Terraform that enables negative testing capability for your infrastructure-as-code.
61
+ [Terraform-compliance](https://terraform-compliance.com/) (v1.15.1) is a lightweight BDD test framework that evaluates `tfplan.json` files against Gherkin `.feature` files. It enables human-readable compliance scenarios like "S3 buckets must have encryption enabled."
62
+
63
+ #### Prerequisites
62
64
 
63
65
  ```bash
64
- # Scan with Terraform-compliance
66
+ pip install terraform-compliance
67
+ ```
68
+
69
+ Requires `tfplan.json` files in your project (generated with `terraform show -json tfplan.binary > tfplan.json`).
70
+
71
+ #### Usage
72
+
73
+ ```bash
74
+ # Local features directory
75
+ thothctl scan iac -t terraform-compliance -o "features_dir=features"
76
+
77
+ # Git repository with subpath (//subpath syntax)
78
+ thothctl scan iac -t terraform-compliance -o "features_dir=https://github.com/myorg/org-policies.git//compliance/features"
79
+
80
+ # Git repository (auto-discovers compliance/features/ or features/)
81
+ thothctl scan iac -t terraform-compliance -o "features_dir=https://github.com/myorg/org-policies.git"
82
+
83
+ # SSH Git URL with subpath
84
+ thothctl scan iac -t terraform-compliance -o "features_dir=git@github.com:myorg/compliance.git//features"
85
+
86
+ # Auto-discover from THOTH_ORG_POLICY (looks in compliance/features/)
87
+ export THOTH_ORG_POLICY=https://github.com/myorg/org-policies.git
65
88
  thothctl scan iac -t terraform-compliance
66
89
  ```
67
90
 
91
+ #### Features Resolution
92
+
93
+ | Priority | Source | Example |
94
+ |----------|--------|---------|
95
+ | 1 | **Git URL with `//subpath`** | `https://github.com/myorg/policies.git//compliance/features` |
96
+ | 2 | **Git URL** (auto-discovers `compliance/features/` or `features/`) | `https://github.com/myorg/policies.git` |
97
+ | 3 | **Relative to project** | `features/` |
98
+ | 4 | **Absolute path** | `/shared/compliance/features` |
99
+ | 5 | **`THOTH_ORG_POLICY` env** → `compliance/features/` | Auto-discovered |
100
+
101
+ #### Writing Feature Files
102
+
103
+ Feature files use Gherkin syntax:
104
+
105
+ ```gherkin
106
+ Feature: Ensure encryption is enabled for all storage resources
107
+
108
+ Scenario: S3 buckets must have encryption
109
+ Given I have aws_s3_bucket defined
110
+ Then it must have server_side_encryption_configuration
111
+
112
+ Scenario: RDS instances must be encrypted
113
+ Given I have aws_db_instance defined
114
+ Then it must have storage_encrypted
115
+ And its value must be true
116
+ ```
117
+
118
+ ```gherkin
119
+ Feature: Ensure all resources have required tags
120
+
121
+ Scenario Outline: Resources must have mandatory tags
122
+ Given I have resource that supports tags defined
123
+ Then it must have tags
124
+ And it must contain <tag>
125
+
126
+ Examples:
127
+ | tag |
128
+ | Environment |
129
+ | Owner |
130
+ | Project |
131
+ ```
132
+
133
+ #### Per-Stack Scanning
134
+
135
+ ThothCTL finds all `tfplan.json` files in your project and runs terraform-compliance against each one individually. Results are aggregated into:
136
+
137
+ - Per-stack HTML reports at `Reports/terraform-compliance/html_reports/`
138
+ - Unified `scan_report.html` alongside other tools
139
+
140
+ #### Organization Policy Integration
141
+
142
+ Store feature files in your org policy repo alongside OPA policies:
143
+
144
+ ```
145
+ org-policies/
146
+ ├── compliance/features/ ← terraform-compliance features
147
+ │ ├── encryption.feature
148
+ │ ├── tagging.feature
149
+ │ └── networking.feature
150
+ ├── shared/policy/ ← OPA/Rego policies
151
+ └── rules/ ← ThothCTL structure rules
152
+ ```
153
+
154
+ Both tools share the same `THOTH_ORG_POLICY` env var.
155
+
68
156
  ### OPA / Conftest
69
157
 
70
158
  [Open Policy Agent (OPA)](https://www.openpolicyagent.org/) is a CNCF-graduated general-purpose policy engine. ThothCTL integrates OPA through two modes:
@@ -79,10 +79,12 @@ ThothCTL automatically tracks scan results in `~/.thothcf/scan_history.db` (SQLi
79
79
  | **Checkov** | Static analysis with built-in rules | `checkov` binary |
80
80
  | **Trivy** | Vulnerability and misconfiguration detection | `trivy` binary |
81
81
  | **KICS** | Static analysis via Docker | Docker |
82
- | **Terraform-compliance** | BDD-style compliance testing | `terraform-compliance` binary |
82
+ | **Terraform-compliance** | BDD-style compliance testing against tfplan.json | `terraform-compliance` (pip) |
83
83
  | **OPA/Conftest** | Custom policy evaluation with Rego | `conftest` and/or `opa` binary |
84
84
 
85
- Each tool has its own strengths. Combine built-in rule scanners (Checkov, Trivy) with custom policy tools (OPA) for comprehensive coverage.
85
+ Each tool has its own strengths. Combine built-in rule scanners (Checkov, Trivy) with custom policy tools (OPA, Terraform-compliance) for comprehensive coverage.
86
+
87
+ **Organization Policy Repo**: Set `THOTH_ORG_POLICY` env var to point all policy tools (OPA, terraform-compliance, project structure rules) to a single centralized governance repository.
86
88
 
87
89
  ## Next Steps
88
90
 
@@ -269,8 +269,8 @@ content = ["main.tf", "variables.tf", "outputs.tf"]
269
269
 
270
270
  ## Related Documentation
271
271
 
272
- - [Template Engine Overview](../../template_engine/template_engine.md)
273
- - [GitHub Templates](../../template_engine/github_templates.md)
274
- - [Project Convert](../commands/project/project_convert.md)
275
- - [Project Upgrade](../commands/project/project_upgrade.md)
272
+ - [Template Engine Overview](../../../template_engine/template_engine.md)
273
+ - [GitHub Templates](../../../template_engine/github_templates.md)
274
+ - [Project Convert](../../commands/project/project_convert.md)
275
+ - [Project Upgrade](../../commands/project/project_upgrade.md)
276
276
  - [Platform Engineering Templates](../platform_engineering_templates.md)
@@ -52,6 +52,8 @@ pip install thothctl
52
52
  | **Security** | [Checkov](https://www.checkov.io/) | Native (pip) |
53
53
  | **Security** | [Trivy](https://trivy.dev/) | CLI binary |
54
54
  | **Security** | [KICS](https://docs.kics.io/) | Docker container |
55
+ | **Compliance** | [Terraform-compliance](https://terraform-compliance.com/) | CLI binary |
56
+ | **Policy** | [OPA/Conftest](https://www.openpolicyagent.org/) | CLI binary |
55
57
  | **Docs** | [Terraform-docs](https://terraform-docs.io/) | CLI binary |
56
58
  | **AI** | [OpenAI](https://platform.openai.com/) | GPT-4 Turbo |
57
59
  | **AI** | [AWS Bedrock](https://aws.amazon.com/bedrock/) | Claude Sonnet (InvokeModel + Agent) |
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import os
2
3
  import click
3
4
  import sys
4
5
  import io
@@ -173,6 +174,8 @@ class CheckProjectIaCCommand(ClickCommand):
173
174
  ctx = click.get_current_context()
174
175
  directory = ctx.obj.get("CODE_DIRECTORY", ".")
175
176
  project_type = kwargs.get('project_type', 'stack')
177
+ org_policy = kwargs.get('org_policy')
178
+ enforcement = kwargs.get('enforcement', 'soft')
176
179
 
177
180
  # Create header with project type
178
181
  header_text = f"🏗️ Infrastructure as Code {'Module' if project_type == 'module' else 'Stack'} Structure Check"
@@ -184,6 +187,9 @@ class CheckProjectIaCCommand(ClickCommand):
184
187
  ))
185
188
 
186
189
  try:
190
+ # Run org policy check if source is provided
191
+ org_violations = self._check_org_policy(directory, project_type, org_policy)
192
+
187
193
  # Capture stdout to format it nicely
188
194
  captured_output = io.StringIO()
189
195
 
@@ -196,13 +202,19 @@ class CheckProjectIaCCommand(ClickCommand):
196
202
  project_type=project_type
197
203
  )
198
204
  except SystemExit as e:
199
- # Handle sys.exit() from validation service
200
205
  result = e.code == 0
201
206
 
202
207
  # Format and display the captured output
203
208
  output = captured_output.getvalue()
204
209
  if output.strip():
205
210
  self._format_validation_output(output)
211
+
212
+ # Display org policy results
213
+ if org_violations is not None:
214
+ self._display_org_violations(org_violations, enforcement)
215
+ mandatory_fails = [v for v in org_violations if v.enforcement == "mandatory"]
216
+ if mandatory_fails and enforcement == "hard":
217
+ result = False
206
218
 
207
219
  # Create summary
208
220
  if result:
@@ -224,8 +236,8 @@ class CheckProjectIaCCommand(ClickCommand):
224
236
  self.console.print()
225
237
  self.console.print(summary_panel)
226
238
 
227
- # Only exit with error code in strict mode
228
- if not result and kwargs.get('mode') == 'strict':
239
+ # Exit with error code if hard enforcement has mandatory violations
240
+ if not result and (kwargs.get('mode') == 'strict' or enforcement == 'hard'):
229
241
  exit(1)
230
242
 
231
243
  except Exception as e:
@@ -233,6 +245,69 @@ class CheckProjectIaCCommand(ClickCommand):
233
245
  self.logger.error(f"Failed to execute IaC project check: {str(e)}")
234
246
  raise
235
247
 
248
+ def _check_org_policy(self, directory: str, project_type: str, org_policy=None):
249
+ """Check project against organizational policy if available."""
250
+ from .....services.check.org_policy_loader import get_org_policy_path, resolve_rules_dir
251
+ from .....services.check.rule_merger import load_org_rules, merge_with_project, evaluate
252
+
253
+ org_path = get_org_policy_path(org_policy)
254
+ if not org_path:
255
+ return None
256
+
257
+ rules_dir = resolve_rules_dir(org_path)
258
+ if not rules_dir:
259
+ logger.info(f"No rules/ directory in org policy at {org_path}")
260
+ return None
261
+
262
+ self.console.print(f"[blue]📜 Loading org policy from: {org_path}[/blue]")
263
+
264
+ # Map CLI project_type to toml filename
265
+ type_map = {"stack": "terraform-terragrunt", "module": "terraform_module"}
266
+ rule_type = type_map.get(project_type, project_type)
267
+
268
+ ruleset = load_org_rules(rules_dir, rule_type)
269
+ project_toml = os.path.join(directory, ".thothcf.toml")
270
+ ruleset = merge_with_project(ruleset, project_toml)
271
+
272
+ return evaluate(ruleset, directory)
273
+
274
+ def _display_org_violations(self, violations, enforcement: str):
275
+ """Display org policy violations in a Rich table."""
276
+ if not violations:
277
+ self.console.print(Panel(
278
+ "✅ [green]Organization policy check passed[/green]",
279
+ title="Org Policy",
280
+ style="green",
281
+ box=box.ROUNDED,
282
+ ))
283
+ return
284
+
285
+ mandatory = [v for v in violations if v.enforcement == "mandatory"]
286
+ recommended = [v for v in violations if v.enforcement == "recommended"]
287
+ info = [v for v in violations if v.enforcement == "informational"]
288
+
289
+ if mandatory:
290
+ table = Table(title="❌ Mandatory Violations", box=box.ROUNDED, header_style="bold red")
291
+ table.add_column("Rule", style="cyan")
292
+ table.add_column("Expected", style="green")
293
+ table.add_column("Found", style="red")
294
+ for v in mandatory:
295
+ table.add_row(v.rule, v.expected, v.found)
296
+ self.console.print(table)
297
+
298
+ if recommended:
299
+ table = Table(title="⚠️ Recommendations", box=box.ROUNDED, header_style="bold yellow")
300
+ table.add_column("Rule", style="cyan")
301
+ table.add_column("Expected", style="green")
302
+ table.add_column("Found", style="yellow")
303
+ for v in recommended:
304
+ table.add_row(v.rule, v.expected, v.found)
305
+ self.console.print(table)
306
+
307
+ if info:
308
+ for v in info:
309
+ self.console.print(f" ℹ️ {v.rule}: {v.expected} (found: {v.found})")
310
+
236
311
  def _validate_project_structure(self, directory: str, mode: str = "soft", check_type: str = "structure", project_type: str = "stack") -> bool:
237
312
  """Validate the IaC project structure
238
313
 
@@ -269,4 +344,15 @@ cli = CheckProjectIaCCommand.as_click_command(
269
344
  type=click.Choice(["stack", "module"], case_sensitive=False),
270
345
  default="stack"
271
346
  ),
347
+ click.option(
348
+ "--org-policy",
349
+ help="Organization policy source (Git URL or local path). Also reads THOTH_ORG_POLICY env var.",
350
+ default=None,
351
+ ),
352
+ click.option(
353
+ "--enforcement",
354
+ help="Enforcement mode: soft (report only) or hard (fail on mandatory violations)",
355
+ type=click.Choice(["soft", "hard"], case_sensitive=False),
356
+ default="soft",
357
+ ),
272
358
  )
@@ -38,7 +38,7 @@ version_tools = """[
38
38
  },
39
39
  {
40
40
  "name": "terraform-compliance",
41
- "version": "1.13.0"
41
+ "version": "1.15.1"
42
42
  },
43
43
  {
44
44
  "name": "terramate",
@@ -18,6 +18,7 @@ from .utils.prompts import (
18
18
  SYSTEM_SECURITY_ANALYST,
19
19
  SYSTEM_CODE_REVIEWER,
20
20
  SYSTEM_FULL_ANALYSIS,
21
+ SYSTEM_COMPACT,
21
22
  )
22
23
  from .utils.fix_prompts import SYSTEM_FIX_GENERATOR
23
24
  from .tracing import span
@@ -85,10 +86,12 @@ class AIReviewAgent:
85
86
  """
86
87
  with span("ai_agent.analyze_directory", {"directory": directory}) as s:
87
88
  logger.info(f"Building rich context for {directory}")
89
+ self._emit_status("📦 Collecting project context (inventory, scan reports, plans)...")
88
90
  ctx = self.context_builder.build_context(directory)
89
91
 
90
92
  basic_risk = None
91
93
  if ctx.scan_results.get("total_findings", 0) > 0:
94
+ self._emit_status(f"⚠️ Found {ctx.scan_results['total_findings']} scan findings, assessing risk...")
92
95
  basic_risk = self.risk_assessor.assess_risk(ctx.scan_results)
93
96
 
94
97
  if not self.cost_tracker.check_budget():
@@ -98,9 +101,28 @@ class AIReviewAgent:
98
101
  return self._basic_analysis(ctx.scan_results, basic_risk)
99
102
  return self._empty_result()
100
103
 
104
+ self._emit_status("🤖 Sending context to LLM for security analysis...")
101
105
  formatted = self.context_builder.format_for_ai(ctx)
102
- fallback = (lambda: self._basic_analysis(ctx.scan_results, basic_risk)) if basic_risk else self._empty_result
103
- result = self._call_ai(SYSTEM_FULL_ANALYSIS, formatted, "analyze_directory", fallback=fallback)
106
+
107
+ # Use compact prompt for local models (Ollama) to fit VRAM constraints
108
+ if self._provider.name == "ollama":
109
+ # Hybrid: scan data for structured findings + LLM for recommendations
110
+ base_result = self._basic_analysis(ctx.scan_results, basic_risk) if basic_risk else self._empty_result()
111
+ try:
112
+ ai_response = self._provider.analyze(SYSTEM_COMPACT, formatted)
113
+ # AI might return JSON or text — either way, use it as recommendations
114
+ if isinstance(ai_response, dict) and ai_response.get("recommendations"):
115
+ base_result["recommendations"] = ai_response["recommendations"]
116
+ base_result["architecture_assessment"] = ai_response.get("architecture_assessment", "")
117
+ elif isinstance(ai_response, dict) and ai_response.get("_raw_text"):
118
+ base_result["recommendations"] = [ai_response["_raw_text"][:2000]]
119
+ except Exception as e:
120
+ logger.debug(f"LLM recommendations failed: {e}")
121
+ result = base_result
122
+ else:
123
+ system_prompt = SYSTEM_FULL_ANALYSIS
124
+ fallback = (lambda: self._basic_analysis(ctx.scan_results, basic_risk)) if basic_risk else self._empty_result
125
+ result = self._call_ai(system_prompt, formatted, "analyze_directory", fallback=fallback)
104
126
 
105
127
  result["_context"] = {
106
128
  "project_type": ctx.project_type,
@@ -265,6 +287,12 @@ class AIReviewAgent:
265
287
  return fallback()
266
288
  return self._empty_result()
267
289
 
290
+ @staticmethod
291
+ def _emit_status(msg: str) -> None:
292
+ """Print a status message visible during the spinner."""
293
+ from rich.console import Console
294
+ Console(stderr=True).print(f"[dim]{msg}[/dim]")
295
+
268
296
  @staticmethod
269
297
  def _empty_result() -> Dict[str, Any]:
270
298
  return {
@@ -6,7 +6,7 @@ from typing import Dict, Any, List
6
6
  logger = logging.getLogger(__name__)
7
7
 
8
8
  # File extensions to analyze
9
- IAC_EXTENSIONS = {".tf", ".hcl", ".tfvars", ".yaml", ".yml", ".json"}
9
+ IAC_EXTENSIONS = {".tf", ".hcl", ".tfvars"}
10
10
 
11
11
 
12
12
  class CodeReviewer:
@@ -24,6 +24,12 @@ class CodeReviewer:
24
24
 
25
25
  for f in dir_path.rglob("*"):
26
26
  if f.suffix in exts and not any(p.startswith(".") for p in f.parts):
27
+ # Skip non-IaC directories
28
+ if any(skip in f.parts for skip in (
29
+ "Reports", ".terraform", "node_modules", ".terragrunt-cache",
30
+ "cdk.out", "__pycache__", ".git", "html_reports", "tfplan",
31
+ )):
32
+ continue
27
33
  try:
28
34
  content = f.read_text(errors="ignore")
29
35
  rel_path = str(f.relative_to(dir_path))
@@ -38,6 +38,7 @@ class ContextBuilder:
38
38
  # Run each collector independently — failures don't block others
39
39
  self._collect_inventory(ctx)
40
40
  self._collect_scan_results(ctx)
41
+ self._collect_plan_files(ctx)
41
42
  self._collect_blast_radius(ctx)
42
43
  self._collect_code(ctx)
43
44
 
@@ -97,12 +98,30 @@ class ContextBuilder:
97
98
  )
98
99
  sections.append("")
99
100
 
100
- # Code section (only key files, truncated)
101
+ # Code section only include files referenced in findings + plan summaries
101
102
  if ctx.code_files:
102
103
  sections.append("## Key IaC Files")
103
- char_budget = 30000
104
+ char_budget = 12000 # ~3K tokens for code context
105
+
106
+ # Prioritize: plans first, then files mentioned in scan findings
107
+ referenced_files = set()
108
+ for tool_data in ctx.scan_results.get("tools", {}).values():
109
+ for f in tool_data.get("findings", []):
110
+ ref = f.get("file", "")
111
+ if ref:
112
+ referenced_files.add(ref)
113
+
114
+ # Sort: plans first, then referenced files, then others
115
+ def priority(item):
116
+ path, _ = item
117
+ if "[PLAN]" in path:
118
+ return 0
119
+ if any(ref in path for ref in referenced_files):
120
+ return 1
121
+ return 2
122
+
104
123
  used = 0
105
- for path, content in sorted(ctx.code_files.items()):
124
+ for path, content in sorted(ctx.code_files.items(), key=priority):
106
125
  header = f"\n--- {path} ---\n"
107
126
  if used + len(header) + len(content) > char_budget:
108
127
  remaining = len(ctx.code_files) - len([s for s in sections if s.startswith("--- ")])
@@ -165,43 +184,74 @@ class ContextBuilder:
165
184
  ctx.errors.append(f"Inventory unavailable: {e}")
166
185
 
167
186
  def _collect_scan_results(self, ctx: IaCContext) -> None:
168
- """Check for existing scan reports or run a quick scan."""
187
+ """Check for existing scan reports at project root."""
169
188
  try:
170
- from ..report_analyzer import ReportAnalyzer
189
+ from .report_analyzer import ReportAnalyzer
171
190
 
172
191
  analyzer = ReportAnalyzer()
173
- reports_dir = Path(ctx.directory) / "Reports"
174
192
 
175
- # First check if reports already exist
176
- if reports_dir.exists():
193
+ # Look for Reports/ at target dir and up to project root
194
+ target = Path(ctx.directory)
195
+ reports_dir = None
196
+ for parent in [target] + list(target.parents):
197
+ candidate = parent / "Reports"
198
+ if candidate.exists():
199
+ reports_dir = candidate
200
+ break
201
+ if (parent / ".thothcf.toml").exists() or (parent / ".git").exists():
202
+ break
203
+
204
+ if reports_dir and reports_dir.exists():
177
205
  ctx.scan_results = analyzer.parse_scan_results(str(reports_dir))
178
206
  if ctx.scan_results.get("total_findings", 0) > 0:
179
207
  logger.info(f"Found existing scan results: {ctx.scan_results['total_findings']} findings")
180
208
  return
181
209
 
182
- # Try running a quick checkov scan
183
- try:
184
- from ...scan.scan_service import ScanService
185
-
186
- scan_svc = ScanService()
187
- tmp_reports = str(Path(ctx.directory) / "Reports")
188
- scan_svc.execute_scans(
189
- directory=ctx.directory,
190
- reports_dir=tmp_reports,
191
- selected_tools=["checkov"],
192
- options={},
193
- html_reports_format="simple",
194
- )
195
- ctx.scan_results = analyzer.parse_scan_results(tmp_reports)
196
- logger.info(f"Quick scan: {ctx.scan_results.get('total_findings', 0)} findings")
197
- except Exception as scan_err:
198
- logger.debug(f"Quick scan failed: {scan_err}")
199
- ctx.errors.append(f"Live scan unavailable: {scan_err}")
210
+ ctx.errors.append("No scan reports found. Run 'thothctl scan iac' first for richer AI analysis.")
200
211
 
201
212
  except Exception as e:
202
213
  logger.debug(f"Scan results collection failed: {e}")
203
214
  ctx.errors.append(f"Scan results unavailable: {e}")
204
215
 
216
+ def _collect_plan_files(self, ctx: IaCContext) -> None:
217
+ """Collect tfplan.json summaries for change analysis."""
218
+ try:
219
+ import json as _json
220
+ target = Path(ctx.directory)
221
+
222
+ # Find tfplan.json in target and project-level stacks/tfplan/
223
+ plan_files = list(target.rglob("tfplan.json"))
224
+ for parent in [target] + list(target.parents):
225
+ if (parent / ".thothcf.toml").exists() or (parent / ".git").exists():
226
+ tfplan_dir = parent / "stacks" / "tfplan"
227
+ if tfplan_dir.exists():
228
+ plan_files.extend(tfplan_dir.rglob("tfplan.json"))
229
+ break
230
+
231
+ for pf in plan_files[:5]:
232
+ try:
233
+ with open(pf) as f:
234
+ plan = _json.load(f)
235
+ changes = plan.get("resource_changes", [])
236
+ creates = sum(1 for c in changes if "create" in c.get("change", {}).get("actions", []))
237
+ updates = sum(1 for c in changes if "update" in c.get("change", {}).get("actions", []))
238
+ deletes = sum(1 for c in changes if "delete" in c.get("change", {}).get("actions", []))
239
+ ctx.code_files[f"[PLAN] {pf.name} ({pf.parent.name})"] = (
240
+ f"# Terraform Plan: {pf.parent.name}\n"
241
+ f"# Creates: {creates}, Updates: {updates}, Deletes: {deletes}\n"
242
+ f"# Total resource changes: {len(changes)}\n"
243
+ + "\n".join(
244
+ f"# {c['type']}.{c['name']} → {c['change']['actions']}"
245
+ for c in changes[:20]
246
+ )
247
+ )
248
+ except Exception:
249
+ pass
250
+ if plan_files:
251
+ logger.info(f"Found {len(plan_files)} tfplan.json files")
252
+ except Exception as e:
253
+ logger.debug(f"Plan file collection failed: {e}")
254
+
205
255
  def _collect_blast_radius(self, ctx: IaCContext) -> None:
206
256
  """Run BlastRadiusService for dependency analysis."""
207
257
  try:
@@ -235,7 +285,7 @@ class ContextBuilder:
235
285
  def _collect_code(self, ctx: IaCContext) -> None:
236
286
  """Collect raw IaC files as supplementary context."""
237
287
  try:
238
- from ..code_reviewer import CodeReviewer
288
+ from .code_reviewer import CodeReviewer
239
289
 
240
290
  reviewer = CodeReviewer()
241
291
  ctx.code_files = reviewer.collect_code_for_review(ctx.directory)
@@ -18,7 +18,7 @@ DEFAULT_CONFIG_FILE = "ai_config.yaml"
18
18
  class ProviderConfig:
19
19
  """Configuration for a single AI provider."""
20
20
  model: str = ""
21
- max_tokens: int = 4000
21
+ max_tokens: int = 8000
22
22
  temperature: float = 0.1
23
23
  api_key: str = ""
24
24
  region: str = "us-east-1"