thothctl 0.18.4__tar.gz → 0.18.6__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 (503) hide show
  1. {thothctl-0.18.4 → thothctl-0.18.6}/PKG-INFO +1 -1
  2. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/ai-review/README.md +65 -0
  3. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/inventory/inventory_iac.md +27 -37
  4. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/analyze.py +3 -1
  5. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/orchestrate.py +10 -0
  6. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/dashboard/dashboard_service.py +18 -29
  7. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/dashboard/data_loader.py +66 -8
  8. thothctl-0.18.6/src/thothctl/utils/common/templates/dashboard.html +254 -0
  9. thothctl-0.18.6/src/thothctl/version.py +2 -0
  10. thothctl-0.18.4/src/thothctl/utils/common/templates/dashboard.html +0 -633
  11. thothctl-0.18.4/src/thothctl/version.py +0 -2
  12. {thothctl-0.18.4 → thothctl-0.18.6}/.devcontainer/Dockerfile +0 -0
  13. {thothctl-0.18.4 → thothctl-0.18.6}/.devcontainer/README.md +0 -0
  14. {thothctl-0.18.4 → thothctl-0.18.6}/.devcontainer/devcontainer.json +0 -0
  15. {thothctl-0.18.4 → thothctl-0.18.6}/.github/workflows/docs.yml +0 -0
  16. {thothctl-0.18.4 → thothctl-0.18.6}/.github/workflows/python-publish.yml +0 -0
  17. {thothctl-0.18.4 → thothctl-0.18.6}/.gitignore +0 -0
  18. {thothctl-0.18.4 → thothctl-0.18.6}/.pre-commit-config.yaml +0 -0
  19. {thothctl-0.18.4 → thothctl-0.18.6}/.readthedocs.yaml +0 -0
  20. {thothctl-0.18.4 → thothctl-0.18.6}/Dockerfile +0 -0
  21. {thothctl-0.18.4 → thothctl-0.18.6}/LICENSE +0 -0
  22. {thothctl-0.18.4 → thothctl-0.18.6}/README.md +0 -0
  23. {thothctl-0.18.4 → thothctl-0.18.6}/__init__.py +0 -0
  24. {thothctl-0.18.4 → thothctl-0.18.6}/docs/catalog/catalog-info.yaml +0 -0
  25. {thothctl-0.18.4 → thothctl-0.18.6}/docs/dashboard/README.md +0 -0
  26. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/ai-review/agent_specifications.md +0 -0
  27. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/ai-review/agentcore.md +0 -0
  28. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/blast-radius.md +0 -0
  29. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/check_environment.md +0 -0
  30. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/check_iac.md +0 -0
  31. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/check_overview.md +0 -0
  32. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/check_project_iac.md +0 -0
  33. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/check_space.md +0 -0
  34. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/cost-analysis-quick-reference.md +0 -0
  35. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/cost-analysis.md +0 -0
  36. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/customizing_rules.md +0 -0
  37. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/deps-advanced.md +0 -0
  38. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/deps.md +0 -0
  39. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/drift-detection.md +0 -0
  40. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/check/plan.md +0 -0
  41. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/document/customizing_docs.md +0 -0
  42. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/document/document_iac.md +0 -0
  43. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/document/document_overview.md +0 -0
  44. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/document/iac.md +0 -0
  45. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/document/use_cases.md +0 -0
  46. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/generate/generate_components.md +0 -0
  47. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/generate/generate_stacks.md +0 -0
  48. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/init/init.md +0 -0
  49. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/init/init_space.md +0 -0
  50. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/inventory/CHANGELOG.md +0 -0
  51. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/inventory/frameworks/terraform.md +0 -0
  52. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/inventory/frameworks/terragrunt.md +0 -0
  53. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/inventory/iac.md +0 -0
  54. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/inventory/inventory_overview.md +0 -0
  55. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/list/list_overview.md +0 -0
  56. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/list/list_projects.md +0 -0
  57. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/list/list_spaces.md +0 -0
  58. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/mcp/mcp.md +0 -0
  59. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/project/iac.md +0 -0
  60. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/project/project_cleanup.md +0 -0
  61. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/project/project_convert.md +0 -0
  62. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/project/project_overview.md +0 -0
  63. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/project/project_upgrade.md +0 -0
  64. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/project/use_cases.md +0 -0
  65. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/remove/remove_overview.md +0 -0
  66. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/remove/remove_project.md +0 -0
  67. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/remove/remove_space.md +0 -0
  68. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/scan/iac.md +0 -0
  69. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/scan/scan_iac.md +0 -0
  70. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/scan/scan_overview.md +0 -0
  71. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/scan/use_cases.md +0 -0
  72. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/commands/upgrade/upgrade_overview.md +0 -0
  73. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/concepts.md +0 -0
  74. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/cross_platform_support.md +0 -0
  75. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/framework_architecture.md +0 -0
  76. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/infrasctructure_composition.md +0 -0
  77. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/policy_as_code.md +0 -0
  78. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/roadmap_fdi.md +0 -0
  79. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/software_architecture.md +0 -0
  80. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/space_configuration.md +0 -0
  81. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/README.md +0 -0
  82. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/ai_dlc.md +0 -0
  83. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/check_command.md +0 -0
  84. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/devsecops_quickstart.md +0 -0
  85. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/devsecops_sdlc.md +0 -0
  86. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/inventory_command.md +0 -0
  87. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/platform_engineering_templates.md +0 -0
  88. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/space_management.md +0 -0
  89. {thothctl-0.18.4 → thothctl-0.18.6}/docs/framework/use_cases/tasks/create_template.md +0 -0
  90. {thothctl-0.18.4 → thothctl-0.18.6}/docs/iac_devsecops_use_case.md +0 -0
  91. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/automate_tasks_command.png +0 -0
  92. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/commnad_init.png +0 -0
  93. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/create_component.gif +0 -0
  94. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/create_inventory.gif +0 -0
  95. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/doc_command.png +0 -0
  96. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/document_project_code.gif +0 -0
  97. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/framework/thothforge-framework.svg +0 -0
  98. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/framework/thothfr.png +0 -0
  99. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/iacpeerbot_summary.png +0 -0
  100. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/icon-light.png +0 -0
  101. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/icon.png +0 -0
  102. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/init_project.gif +0 -0
  103. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/inventory_command.png +0 -0
  104. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/notification_img.png +0 -0
  105. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/report_dependencies.png +0 -0
  106. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/report_dependencies_summary.png +0 -0
  107. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/restore_inventory_version.gif +0 -0
  108. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/reuse_project_pattern.gif +0 -0
  109. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/scan_code.gif +0 -0
  110. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/scan_command.png +0 -0
  111. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/stable/scan_report_example.png +0 -0
  112. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/sync_wk_command.png +0 -0
  113. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/transform_command.png +0 -0
  114. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/update_inventory_version.gif +0 -0
  115. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/validate_command.png +0 -0
  116. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/validate_environment.gif +0 -0
  117. {thothctl-0.18.4 → thothctl-0.18.6}/docs/img/validate_project.gif +0 -0
  118. {thothctl-0.18.4 → thothctl-0.18.6}/docs/includes/abbreviations.md +0 -0
  119. {thothctl-0.18.4 → thothctl-0.18.6}/docs/index.md +0 -0
  120. {thothctl-0.18.4 → thothctl-0.18.6}/docs/installation/linux_installation.md +0 -0
  121. {thothctl-0.18.4 → thothctl-0.18.6}/docs/installation/windows_installation.md +0 -0
  122. {thothctl-0.18.4 → thothctl-0.18.6}/docs/javascripts/tablesort.js +0 -0
  123. {thothctl-0.18.4 → thothctl-0.18.6}/docs/mcp.md +0 -0
  124. {thothctl-0.18.4 → thothctl-0.18.6}/docs/navigation.md +0 -0
  125. {thothctl-0.18.4 → thothctl-0.18.6}/docs/quick_start.md +0 -0
  126. {thothctl-0.18.4 → thothctl-0.18.6}/docs/requirements.txt +0 -0
  127. {thothctl-0.18.4 → thothctl-0.18.6}/docs/stylesheets/extra-enhanced.css +0 -0
  128. {thothctl-0.18.4 → thothctl-0.18.6}/docs/stylesheets/extra.css +0 -0
  129. {thothctl-0.18.4 → thothctl-0.18.6}/docs/telemetry.md +0 -0
  130. {thothctl-0.18.4 → thothctl-0.18.6}/docs/template_engine/cli_commands_audit.md +0 -0
  131. {thothctl-0.18.4 → thothctl-0.18.6}/docs/template_engine/for_developers.md +0 -0
  132. {thothctl-0.18.4 → thothctl-0.18.6}/docs/template_engine/for_platform_engineers.md +0 -0
  133. {thothctl-0.18.4 → thothctl-0.18.6}/docs/template_engine/github_templates.md +0 -0
  134. {thothctl-0.18.4 → thothctl-0.18.6}/docs/template_engine/template_engine.md +0 -0
  135. {thothctl-0.18.4 → thothctl-0.18.6}/docs/troubleshooting/linux_troubleshooting.md +0 -0
  136. {thothctl-0.18.4 → thothctl-0.18.6}/docs/troubleshooting/macos_troubleshooting.md +0 -0
  137. {thothctl-0.18.4 → thothctl-0.18.6}/docs/troubleshooting/troubleshooting.md +0 -0
  138. {thothctl-0.18.4 → thothctl-0.18.6}/docs/troubleshooting/windows_troubleshooting.md +0 -0
  139. {thothctl-0.18.4 → thothctl-0.18.6}/mkdocs.yaml +0 -0
  140. {thothctl-0.18.4 → thothctl-0.18.6}/pyproject.toml +0 -0
  141. {thothctl-0.18.4 → thothctl-0.18.6}/scripts/run_mcp_server.sh +0 -0
  142. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/__init__.py +0 -0
  143. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/application/__init__.py +0 -0
  144. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/autocomplete.py +0 -0
  145. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/cli.py +0 -0
  146. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/__init__.py +0 -0
  147. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/__init__.py +0 -0
  148. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/cli.py +0 -0
  149. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/__init__.py +0 -0
  150. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/apply_fix.py +0 -0
  151. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/configure.py +0 -0
  152. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/configure_decisions.py +0 -0
  153. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/decide.py +0 -0
  154. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/history.py +0 -0
  155. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/improve.py +0 -0
  156. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/override.py +0 -0
  157. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/report.py +0 -0
  158. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/ai_review/commands/serve.py +0 -0
  159. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/__init__.py +0 -0
  160. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/cli.py +0 -0
  161. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/commands/__init__.py +0 -0
  162. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/commands/environment.py +0 -0
  163. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/commands/iac.py +0 -0
  164. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/commands/project/__init__.py +0 -0
  165. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/commands/project/iac.py +0 -0
  166. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/check/commands/project.py +0 -0
  167. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/dashboard/__init__.py +0 -0
  168. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/dashboard/cli.py +0 -0
  169. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/dashboard/commands/__init__.py +0 -0
  170. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/dashboard/commands/launch.py +0 -0
  171. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/document/__init__.py +0 -0
  172. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/document/cli.py +0 -0
  173. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/document/commands/__init__.py +0 -0
  174. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/document/commands/iac.py +0 -0
  175. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/generate/__init__.py +0 -0
  176. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/generate/cli.py +0 -0
  177. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/generate/commands/__init__.py +0 -0
  178. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/generate/commands/component.py +0 -0
  179. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/generate/commands/stacks.py +0 -0
  180. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/__init__.py +0 -0
  181. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/cli.py +0 -0
  182. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/commands/__init__.py +0 -0
  183. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/commands/env.py +0 -0
  184. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/commands/project.py +0 -0
  185. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/commands/space.py +0 -0
  186. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/init/commands/template.py +0 -0
  187. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/inventory/__init__.py +0 -0
  188. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/inventory/cli.py +0 -0
  189. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/inventory/commands/__init__.py +0 -0
  190. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/inventory/commands/check.py +0 -0
  191. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/inventory/commands/iac.py +0 -0
  192. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/list/__init__.py +0 -0
  193. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/list/cli.py +0 -0
  194. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/list/commands/__init__.py +0 -0
  195. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/list/commands/projects.py +0 -0
  196. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/list/commands/spaces.py +0 -0
  197. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/__init__.py +0 -0
  198. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/cli.py +0 -0
  199. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/commands/__init__.py +0 -0
  200. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/commands/register.py +0 -0
  201. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/commands/server.py +0 -0
  202. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/commands/status.py +0 -0
  203. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/mcp/commands/stop.py +0 -0
  204. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/__init__.py +0 -0
  205. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/cli.py +0 -0
  206. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/commands/__init__.py +0 -0
  207. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/commands/bootstrap.py +0 -0
  208. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/commands/cleanup.py +0 -0
  209. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/commands/convert.py +0 -0
  210. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/project/commands/upgrade.py +0 -0
  211. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/remove/__init__.py +0 -0
  212. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/remove/cli.py +0 -0
  213. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/remove/project.py +0 -0
  214. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/remove/space.py +0 -0
  215. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/scan/__init__.py +0 -0
  216. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/scan/cli.py +0 -0
  217. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/scan/commands/__init__.py +0 -0
  218. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/scan/commands/iac.py +0 -0
  219. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/space/__init__.py +0 -0
  220. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/space/cli.py +0 -0
  221. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/space/commands/__init__.py +0 -0
  222. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/space/commands/activate.py +0 -0
  223. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/space/commands/show.py +0 -0
  224. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/space/commands/update.py +0 -0
  225. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/commands/upgrade/cli.py +0 -0
  226. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/.thothcf.setup.toml +0 -0
  227. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/.thothcf_home.toml +0 -0
  228. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/.thothcf_module.toml +0 -0
  229. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/.thothcf_project.toml +0 -0
  230. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/.thothcf_template_parameters.toml +0 -0
  231. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/__init__.py +0 -0
  232. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/common.py +0 -0
  233. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/common/terragrunt/.thothcf_project.toml +0 -0
  234. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/__init__.py +0 -0
  235. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/constants.py +0 -0
  236. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/default_values.py +0 -0
  237. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/defaults.py +0 -0
  238. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/models.py +0 -0
  239. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/settings.py +0 -0
  240. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/template_config.py +0 -0
  241. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/template_configs.py +0 -0
  242. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/templates.py +0 -0
  243. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/config/validation.py +0 -0
  244. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/__init__.py +0 -0
  245. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/cli_ui.py +0 -0
  246. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/commands.py +0 -0
  247. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/config.py +0 -0
  248. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/__init__.py +0 -0
  249. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/azure_devops/__init__.py +0 -0
  250. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/azure_devops/get_azure_devops.py +0 -0
  251. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/azure_devops/pull_request_comments.py +0 -0
  252. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/github/get_github.py +0 -0
  253. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/github/pull_request_comments.py +0 -0
  254. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/integrate_messages_services/__init__.py +0 -0
  255. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/integrate_messages_services/microsoft_teams.py +0 -0
  256. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/integrate_messages_services/sent_message_teams.py +0 -0
  257. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/pattern_names.py +0 -0
  258. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/pr_comments/__init__.py +0 -0
  259. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/integrations/pr_comments/pr_comment_publisher.py +0 -0
  260. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/logger.py +0 -0
  261. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/telemetry.py +0 -0
  262. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/core/version_tools.py +0 -0
  263. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/domain/__init__.py +0 -0
  264. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/domain/interfaces/__init__.py +0 -0
  265. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/domain/models/__init__.py +0 -0
  266. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/mcp/README.md +0 -0
  267. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/mcp/__init__.py +0 -0
  268. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/mcp/server.py +0 -0
  269. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/__init__.py +0 -0
  270. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/__init__.py +0 -0
  271. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/agentcore/agentcore.json +0 -0
  272. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/ai_agent.py +0 -0
  273. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/analyzers/__init__.py +0 -0
  274. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/analyzers/code_reviewer.py +0 -0
  275. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/analyzers/context_builder.py +0 -0
  276. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/analyzers/report_analyzer.py +0 -0
  277. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/analyzers/risk_assessor.py +0 -0
  278. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/bedrock_agent_api.py +0 -0
  279. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/config/__init__.py +0 -0
  280. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/config/ai_settings.py +0 -0
  281. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/config/decision_rules.py +0 -0
  282. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/decision_engine.py +0 -0
  283. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/main.py +0 -0
  284. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/memory.py +0 -0
  285. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/orchestrator.py +0 -0
  286. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/pr_decision_publisher.py +0 -0
  287. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/providers/__init__.py +0 -0
  288. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/providers/azure_provider.py +0 -0
  289. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/providers/bedrock_agent_provider.py +0 -0
  290. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/providers/bedrock_provider.py +0 -0
  291. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/providers/ollama_provider.py +0 -0
  292. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/providers/openai_provider.py +0 -0
  293. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/safety/__init__.py +0 -0
  294. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/safety/safety_guard.py +0 -0
  295. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/strands_agent.py +0 -0
  296. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/tracing.py +0 -0
  297. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/utils/__init__.py +0 -0
  298. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/utils/cost_tracker.py +0 -0
  299. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/utils/fix_patterns.py +0 -0
  300. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/utils/fix_prompts.py +0 -0
  301. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/utils/formatters.py +0 -0
  302. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/ai_review/utils/prompts.py +0 -0
  303. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/__init__.py +0 -0
  304. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/environment/__init__.py +0 -0
  305. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/environment/check_environment.py +0 -0
  306. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/org_policy_loader.py +0 -0
  307. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/__init__.py +0 -0
  308. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/blast_radius_service.py +0 -0
  309. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/check_origin_version.py +0 -0
  310. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/check_project_structure.py +0 -0
  311. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/__init__.py +0 -0
  312. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/cost_analyzer.py +0 -0
  313. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/models/__init__.py +0 -0
  314. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/models/cloudformation_mapper.py +0 -0
  315. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/models/cost_models.py +0 -0
  316. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/__init__.py +0 -0
  317. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/aws_pricing_client.py +0 -0
  318. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/base_pricing.py +0 -0
  319. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/__init__.py +0 -0
  320. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/apigateway_pricing.py +0 -0
  321. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/bedrock_pricing.py +0 -0
  322. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/cloudwatch_pricing.py +0 -0
  323. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/dynamodb_pricing.py +0 -0
  324. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/ebs_pricing.py +0 -0
  325. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/ec2_pricing.py +0 -0
  326. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/ecs_pricing.py +0 -0
  327. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/eip_pricing.py +0 -0
  328. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/eks_pricing.py +0 -0
  329. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/elb_pricing.py +0 -0
  330. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/free_resources_pricing.py +0 -0
  331. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/kms_pricing.py +0 -0
  332. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/lambda_pricing.py +0 -0
  333. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/msk_pricing.py +0 -0
  334. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/rds_pricing.py +0 -0
  335. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/s3_pricing.py +0 -0
  336. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/secrets_manager_pricing.py +0 -0
  337. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/pricing/providers/vpc_pricing.py +0 -0
  338. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/cost/unified_cost_report.py +0 -0
  339. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/__init__.py +0 -0
  340. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/drift_ai.py +0 -0
  341. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/drift_history.py +0 -0
  342. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/drift_policy.py +0 -0
  343. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/drift_report.py +0 -0
  344. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/drift_service.py +0 -0
  345. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/drift/models.py +0 -0
  346. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/risk_assessment.py +0 -0
  347. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/project/validate_project_structure.py +0 -0
  348. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/rule_merger.py +0 -0
  349. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/check/stack_optimizer/__init__.py +0 -0
  350. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/dashboard/__init__.py +0 -0
  351. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/__init__.py +0 -0
  352. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/create_documentation.py +0 -0
  353. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/files_content.py +0 -0
  354. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/files_scan.py +0 -0
  355. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/iac_documentation.py +0 -0
  356. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/iac_grunt_graph.py +0 -0
  357. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/document/iac_grunt_info.py +0 -0
  358. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/__init__.py +0 -0
  359. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_stacks/__init__.py +0 -0
  360. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_stacks/config_generator.py +0 -0
  361. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_stacks/remote_config_generation.py +0 -0
  362. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_stacks/stack_service.py +0 -0
  363. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_stacks/templates/terragrunt.hcl.j2 +0 -0
  364. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/__init__.py +0 -0
  365. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/config.yaml +0 -0
  366. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/create_code.py +0 -0
  367. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/create_component.py +0 -0
  368. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/create_component_service.py +0 -0
  369. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/create_stacks.py +0 -0
  370. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/create_template.py +0 -0
  371. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/files_content.py +0 -0
  372. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/github_template_loader.py +0 -0
  373. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/generate/create_template/project_templates.py +0 -0
  374. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/__init__.py +0 -0
  375. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/environment/__init__.py +0 -0
  376. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/environment/install_tools.py +0 -0
  377. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/project/__init__.py +0 -0
  378. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/project/project.py +0 -0
  379. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/space/__init__.py +0 -0
  380. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/space/example_space.toml +0 -0
  381. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/space/local_registry.py +0 -0
  382. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/init/space/space.py +0 -0
  383. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/__init__.py +0 -0
  384. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/changelog_parser.py +0 -0
  385. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/inventory_service.py +0 -0
  386. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/models.py +0 -0
  387. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/module_compatibility_service.py +0 -0
  388. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/report_service.py +0 -0
  389. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/schema_compatibility_service.py +0 -0
  390. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/terragrunt_parser.py +0 -0
  391. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/update_versions.py +0 -0
  392. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/inventory/version_service.py +0 -0
  393. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/mcp/README.md +0 -0
  394. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/mcp/__init__.py +0 -0
  395. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/mcp/simple_http_server.py +0 -0
  396. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/mcp/stdio_server.py +0 -0
  397. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/__init__.py +0 -0
  398. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/bootstrap/__init__.py +0 -0
  399. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/bootstrap/bootstrap_service.py +0 -0
  400. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/cleanup/__init__.py +0 -0
  401. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/cleanup/clean_project.py +0 -0
  402. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/cleanup/clean_space.py +0 -0
  403. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/__init__.py +0 -0
  404. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/conversion_service.py +0 -0
  405. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/get_project_data.py +0 -0
  406. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/post_init.py +0 -0
  407. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/project_converter.py +0 -0
  408. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/project_defaults.py +0 -0
  409. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/convert/set_project_parameters.py +0 -0
  410. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/create_terramate/__init__.py +0 -0
  411. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/create_terramate/create_terramate_stacks.py +0 -0
  412. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/create_terramate/detect_changes_stacks.py +0 -0
  413. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/create_terramate/manage_terramate_stacks.py +0 -0
  414. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/upgrade/__init__.py +0 -0
  415. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/project/upgrade/upgrade_service.py +0 -0
  416. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/__init__.py +0 -0
  417. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/compliance_review.py +0 -0
  418. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/import_reports.py +0 -0
  419. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/models.py +0 -0
  420. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/report_parser.py +0 -0
  421. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/sarif_output.py +0 -0
  422. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scan_history.py +0 -0
  423. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scan_service.py +0 -0
  424. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/__init__.py +0 -0
  425. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/checkov.py +0 -0
  426. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/kics.py +0 -0
  427. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/opa.py +0 -0
  428. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/scan_reports.py +0 -0
  429. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/scanners.py +0 -0
  430. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/terraform_compliance.py +0 -0
  431. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/tfsec.py +0 -0
  432. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/services/scan/scanners/trivy.py +0 -0
  433. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/templates/reports/inventory_report.html +0 -0
  434. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/templates/reports/inventory_report.js +0 -0
  435. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/templates/unified_report_styles.css +0 -0
  436. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/__init__.py +0 -0
  437. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/banner.py +0 -0
  438. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/__init__.py +0 -0
  439. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/create_compliance_html_reports.py +0 -0
  440. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/create_html_reports.py +0 -0
  441. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/delete_directory.py +0 -0
  442. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/fix_report_styling.py +0 -0
  443. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/render_scan_report.py +0 -0
  444. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/report_html_utils.py +0 -0
  445. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/index_report.html +0 -0
  446. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/individual_report.html +0 -0
  447. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/simple_report.html +0 -0
  448. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/unified_report_styles.css +0 -0
  449. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/unified_scan_report.html +0 -0
  450. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/unified_simple_report.html +0 -0
  451. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/common/templates/xunit_report.html +0 -0
  452. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/crypto.py +0 -0
  453. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/manage_backend_resources/__init__.py +0 -0
  454. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/manage_backend_resources/manage_backend_resources.py +0 -0
  455. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/modules_ops/__init__.py +0 -0
  456. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/modules_ops/terraform_module_details.py +0 -0
  457. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/modules_ops/terraform_modules_fetcher.py +0 -0
  458. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/platform_utils.py +0 -0
  459. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/process_hcl/__init__.py +0 -0
  460. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/process_hcl/analyze_terraform_plan.py +0 -0
  461. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/process_hcl/graph_manager.py +0 -0
  462. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/process_hcl/graph_terragrunt_dependencies.py +0 -0
  463. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/process_hcl/process_terraform_file.py +0 -0
  464. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/process_hcl/risk_analyzing_terraform_plan.py +0 -0
  465. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/sync_workspaces/__init__.py +0 -0
  466. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/sync_workspaces/sync_terraform_workspaces.py +0 -0
  467. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/sync_workspaces/sync_terragrunt_workspaces.py +0 -0
  468. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/template_loader.py +0 -0
  469. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/utils/thoth_colors.py +0 -0
  470. {thothctl-0.18.4 → thothctl-0.18.6}/src/thothctl/wellcome_banner.py +0 -0
  471. {thothctl-0.18.4 → thothctl-0.18.6}/tests/conftest.py +0 -0
  472. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_agentcore_entrypoint.py +0 -0
  473. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_aws_pricing_client.py +0 -0
  474. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_azure_devops_pr_comments.py +0 -0
  475. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_bedrock_pricing.py +0 -0
  476. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_cdk_language_selection.py +0 -0
  477. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_context_steering.py +0 -0
  478. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_cost_analyzer.py +0 -0
  479. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_cost_models.py +0 -0
  480. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_cost_pr_comments.py +0 -0
  481. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_dashboard_loading_fix.py +0 -0
  482. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_dashboard_service.py +0 -0
  483. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_drift.py +0 -0
  484. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_drift_detection.py +0 -0
  485. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_ec2_pricing.py +0 -0
  486. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_github_pr_comments.py +0 -0
  487. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_iac_cost_integration.py +0 -0
  488. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_inventory_pr_comments.py +0 -0
  489. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_kics_scanner.py +0 -0
  490. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_mermaid_edge_labels.py +0 -0
  491. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_new_cost_providers.py +0 -0
  492. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_parallel_scan.py +0 -0
  493. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_platform_utils.py +0 -0
  494. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_pr_comment_publisher.py +0 -0
  495. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_provider_source_url_fix.py +0 -0
  496. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_provider_versions.py +0 -0
  497. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_scan_pr_comments.py +0 -0
  498. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_space_command.py +0 -0
  499. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_space_management.py +0 -0
  500. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_stack_optimizer.py +0 -0
  501. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_template_url_fix.py +0 -0
  502. {thothctl-0.18.4 → thothctl-0.18.6}/tests/test_terragrunt_parser.py +0 -0
  503. {thothctl-0.18.4 → thothctl-0.18.6}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thothctl
3
- Version: 0.18.4
3
+ Version: 0.18.6
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
@@ -541,6 +541,71 @@ The `improve` command includes 13 built-in fix patterns that work without AI:
541
541
  | `CKV_AWS_116` | Add Lambda dead letter config |
542
542
  | `CKV_AWS_272` | Enable Lambda code signing |
543
543
 
544
+ ## Token Usage & Cost Tracking
545
+
546
+ Every AI interaction reports token consumption (input/output) and estimated cost in the command output:
547
+
548
+ ```
549
+ 💰 Today's AI cost: $0.0234 (3 requests, ↑12,450 in / ↓3,210 out tokens)
550
+ ```
551
+
552
+ ### Per-Command Output
553
+
554
+ | Command | Token Info Shown |
555
+ |---------|-----------------|
556
+ | `analyze` | Daily totals: cost, requests, input/output tokens |
557
+ | `orchestrate` | Per-run: cost, input/output tokens, model used |
558
+ | `report` | Full breakdown by period, provider, and model |
559
+
560
+ ### Cost Report
561
+
562
+ ```bash
563
+ # Daily summary
564
+ thothctl ai-review report --period daily
565
+
566
+ # Monthly breakdown
567
+ thothctl ai-review report --period monthly
568
+
569
+ # Export to JSON
570
+ thothctl ai-review report --period monthly --export costs.json
571
+ ```
572
+
573
+ Output:
574
+ ```
575
+ ┌────────────────────┬──────────────┐
576
+ │ Metric │ Value │
577
+ ├────────────────────┼──────────────┤
578
+ │ Total Cost │ $0.1240 │
579
+ │ Total Requests │ 12 │
580
+ │ Input Tokens │ 45,200 │
581
+ │ Output Tokens │ 8,340 │
582
+ └────────────────────┴──────────────┘
583
+ ```
584
+
585
+ ### Budget Controls
586
+
587
+ ```bash
588
+ # Set daily and monthly limits
589
+ thothctl ai-review configure --daily-limit 50 --monthly-budget 200
590
+ ```
591
+
592
+ | Control | Default | Description |
593
+ |---------|---------|-------------|
594
+ | Daily limit | $100 | Max spend per day |
595
+ | Monthly budget | $200 | Max spend per month |
596
+ | Auto fallback | true | Falls back to pattern-based fixes when budget exceeded |
597
+
598
+ Cost logs are stored at `.thothctl/ai_costs/<date>.jsonl` (one JSON record per API call).
599
+
600
+ ### Supported Pricing
601
+
602
+ | Provider | Tracked | Notes |
603
+ |----------|---------|-------|
604
+ | OpenAI | ✅ | GPT-3.5, GPT-4, GPT-4 Turbo |
605
+ | Bedrock | ✅ | Claude 3 Sonnet, Haiku |
606
+ | Azure OpenAI | ✅ | Same as OpenAI pricing |
607
+ | Ollama | ✅ (zero cost) | Local models — no API charges |
608
+
544
609
  ## MCP Integration
545
610
 
546
611
  The AI review is exposed as an MCP tool (`thothctl_ai_review`) for AI assistant interoperability:
@@ -6,10 +6,9 @@ The `thothctl inventory iac` command creates, updates, and manages an inventory
6
6
 
7
7
  ## Recent Improvements ✨
8
8
 
9
- - **🎯 Unified Version Checking**: Single `--check-versions` flag handles both module and provider version checking
9
+ - **🎯 Independent Version Checking**: Separate flags for module versions (`-cv`) and provider versions (`-cpv`) — check what you need
10
10
  - **🎨 Modern HTML Reports**: Professional styling with Inter font, gradients, and responsive design
11
11
  - **📊 Enhanced Provider Analysis**: Comprehensive provider version tracking with status indicators
12
- - **🚀 Intelligent Automation**: Automatic provider checking when version checking is enabled
13
12
  - **📱 Responsive Design**: Reports work perfectly on desktop, tablet, and mobile devices
14
13
 
15
14
  ## Command Options
@@ -20,33 +19,21 @@ Usage: thothctl inventory iac [OPTIONS]
20
19
  Create a inventory about IaC modules composition for terraform/tofu/terragrunt projects
21
20
 
22
21
  Options:
23
- -pj, --project-name TEXT Specify a custom project name for the
24
- inventory report
25
- --provider-tool [tofu|terraform]
26
- Tool to use for checking providers (default:
27
- tofu)
28
- --check-providers Check and report provider information for
29
- each stack (automatically enabled with
30
- --check-versions)
31
- --complete Include .terraform and .terragrunt-cache
32
- folders in analysis (complete analysis)
33
- -ft, --framework-type [auto|terraform|terragrunt|terraform-terragrunt]
34
- Framework type to analyze (auto for
35
- automatic detection)
22
+ -cv, --check-versions Check latest versions for modules
23
+ -cpv, --check-provider-versions Check latest versions for providers
24
+ --check-providers Check and report provider information for each stack
25
+ -ft, --framework-type [auto|terraform|terragrunt|terraform-terragrunt|module|cdkv2]
26
+ Framework type to analyze (auto for automatic detection)
36
27
  -r, --report-type [html|json|cyclonedx|all]
37
- Type of report to generate (cyclonedx
38
- generates OWASP CycloneDX SBOM format)
28
+ Type of report to generate
39
29
  -iact, --inventory-action [create|update|restore]
40
30
  Action for inventory tasks
41
- -auto, --auto-approve Use with --update_dependencies option for
42
- auto approve updating dependencies.
43
- -updep, --update-dependencies-path
44
- Pass the inventory json file path for
45
- updating dependencies.
46
- -cv, --check-versions Check latest versions for modules and
47
- providers (includes provider version
48
- checking)
49
31
  -iph, --inventory-path PATH Path for saving inventory reports
32
+ -pj, --project-name TEXT Custom project name for the report
33
+ --provider-tool [tofu|terraform]
34
+ Tool to use for checking providers (default: tofu)
35
+ --complete Include .terraform and .terragrunt-cache in analysis
36
+ -auto, --auto-approve Auto approve updating dependencies
50
37
  --post-to-pr Post inventory summary as a PR comment
51
38
  (Azure DevOps or GitHub)
52
39
  --vcs-provider [auto|azure_repos|github]
@@ -67,18 +54,21 @@ thothctl inventory iac
67
54
 
68
55
  This creates an inventory of all IaC components in the current directory and generates a **modern HTML report** in the default location (`./Reports/Inventory`).
69
56
 
70
- ### Create an Inventory with Version Checking (Recommended) 🚀
57
+ ### Create an Inventory with Version Checking
71
58
 
72
59
  ```bash
73
- thothctl inventory iac --check-versions
74
- ```
60
+ # Check module versions only
61
+ thothctl inventory iac -cv
75
62
 
76
- This creates a comprehensive inventory that:
77
- - Checks latest versions for all modules
78
- - ✅ Automatically enables provider checking
79
- - Analyzes provider versions against registries
80
- - Shows "Latest Version" and "Status" columns
81
- - ✅ Generates modern, professional HTML reports
63
+ # Check provider versions only
64
+ thothctl inventory iac -cpv
65
+
66
+ # Check both module and provider versions
67
+ thothctl inventory iac -cv -cpv
68
+
69
+ # Provider info without version lookup
70
+ thothctl inventory iac --check-providers
71
+ ```
82
72
 
83
73
  ### Generate Different Report Types
84
74
 
@@ -100,7 +90,7 @@ thothctl inventory iac --report-type all
100
90
 
101
91
  ```bash
102
92
  thothctl inventory iac \
103
- --check-versions \
93
+ -cv -cpv \
104
94
  --inventory-path ./docs/infrastructure \
105
95
  --project-name "Production Infrastructure"
106
96
  ```
@@ -129,10 +119,10 @@ ThothCTL now supports generating **CycloneDX Software Bill of Materials (SBOM)**
129
119
  ### Example:
130
120
  ```bash
131
121
  # Generate CycloneDX SBOM for security audit
132
- thothctl inventory iac --check-versions --report-type cyclonedx
122
+ thothctl inventory iac -cv -cpv --report-type cyclonedx
133
123
 
134
124
  # Complete analysis with all formats including SBOM
135
- thothctl inventory iac --check-versions --report-type all
125
+ thothctl inventory iac -cv -cpv --report-type all
136
126
  ```
137
127
 
138
128
  The CycloneDX report includes:
@@ -61,7 +61,9 @@ class AnalyzeCommand(ClickCommand):
61
61
  if cost_report["total_cost"] > 0:
62
62
  self.ui.print_info(
63
63
  f"💰 Today's AI cost: ${cost_report['total_cost']:.4f} "
64
- f"({cost_report['total_requests']} requests)"
64
+ f"({cost_report['total_requests']} requests, "
65
+ f"↑{cost_report['total_input_tokens']:,} in / "
66
+ f"↓{cost_report['total_output_tokens']:,} out tokens)"
65
67
  )
66
68
 
67
69
  except ImportError as e:
@@ -91,6 +91,16 @@ class OrchestrateCommand(ClickCommand):
91
91
  json.dump(data, f, indent=2, default=str)
92
92
  self.ui.print_success(f"Full results saved to {output}")
93
93
 
94
+ # Show token usage
95
+ if hasattr(result, 'cost') and result.cost:
96
+ cost = result.cost
97
+ self.ui.print_info(
98
+ f"💰 Usage: ${cost.get('total_cost', 0):.4f} | "
99
+ f"↑{cost.get('input_tokens', 0):,} in / "
100
+ f"↓{cost.get('output_tokens', 0):,} out tokens | "
101
+ f"Model: {cost.get('model', 'unknown')}"
102
+ )
103
+
94
104
  def _display_security(self, data):
95
105
  summary = data.get("summary", {})
96
106
  table = Table(title="🔒 Security Agent")
@@ -27,35 +27,6 @@ class DashboardService:
27
27
  def _setup_routes(self):
28
28
  """Setup FastAPI routes for the dashboard."""
29
29
 
30
- @self.app.get("/minimal", response_class=HTMLResponse)
31
- async def minimal_test():
32
- """Minimal test page to isolate JavaScript issues."""
33
- return '''<!DOCTYPE html>
34
- <html>
35
- <head><title>Test</title></head>
36
- <body>
37
- <h1>Minimal Test Page</h1>
38
- <div id="test">Loading...</div>
39
- <script>
40
- console.log('Script started');
41
- document.addEventListener('DOMContentLoaded', function() {
42
- console.log('DOM loaded');
43
- document.getElementById('test').innerHTML = 'JavaScript Working!';
44
- });
45
- console.log('Script ended');
46
- </script>
47
- </body>
48
- </html>'''
49
-
50
- @self.app.get("/debug", response_class=HTMLResponse)
51
- async def debug_page():
52
- """Debug test page."""
53
- try:
54
- with open('/home/labvel/projects/tools/ThothForge/thothctl/debug_dashboard.html') as f:
55
- return f.read()
56
- except FileNotFoundError:
57
- return "<html><body><h1>Debug file not found</h1></body></html>"
58
-
59
30
  @self.app.get("/", response_class=HTMLResponse)
60
31
  async def dashboard():
61
32
  """Main dashboard page."""
@@ -123,6 +94,24 @@ class DashboardService:
123
94
  except Exception as e:
124
95
  logger.error(f"Refresh API error: {e}")
125
96
  raise HTTPException(status_code=500, detail=str(e))
97
+
98
+ @self.app.get("/api/drift")
99
+ async def api_drift():
100
+ """API endpoint for drift detection data."""
101
+ try:
102
+ return self.data_loader.get_drift_data()
103
+ except Exception as e:
104
+ logger.error(f"Drift API error: {e}")
105
+ raise HTTPException(status_code=500, detail=str(e))
106
+
107
+ @self.app.get("/api/ai-usage")
108
+ async def api_ai_usage():
109
+ """API endpoint for AI token/cost usage."""
110
+ try:
111
+ return self.data_loader.get_ai_usage()
112
+ except Exception as e:
113
+ logger.error(f"AI usage API error: {e}")
114
+ raise HTTPException(status_code=500, detail=str(e))
126
115
 
127
116
  def _get_dashboard_template(self) -> str:
128
117
  """Get the dashboard HTML template."""
@@ -164,21 +164,79 @@ class DashboardDataLoader:
164
164
  return {
165
165
  "message": "No risk analysis available.",
166
166
  "action": "Run project check to generate blast radius analysis",
167
- "command": "thothctl check project --blast-radius"
167
+ "command": "thothctl check iac -type blast-radius --recursive"
168
168
  }
169
169
 
170
170
  except json.JSONDecodeError:
171
+ return {"error": "Invalid blast radius file format", "action": "Regenerate", "command": "thothctl check iac -type blast-radius --recursive"}
172
+ except Exception as e:
173
+ return {"error": f"Error loading risk data: {str(e)}"}
174
+
175
+ def get_drift_data(self) -> Dict[str, Any]:
176
+ """Load from existing drift detection reports."""
177
+ cache_key = "drift"
178
+ if self._is_cache_valid(cache_key):
179
+ return self.cache[cache_key]["data"]
180
+
181
+ try:
182
+ drift_files = list(self.reports_dir.glob("**/drift_*.json"))
183
+ if drift_files:
184
+ latest_file = max(drift_files, key=lambda f: f.stat().st_mtime)
185
+ with open(latest_file, "r", encoding="utf-8") as f:
186
+ data = json.load(f)
187
+ self._cache_data(cache_key, data)
188
+ return data
189
+
171
190
  return {
172
- "error": "Invalid blast radius file format",
173
- "action": "Regenerate blast radius analysis",
174
- "command": "thothctl check project --blast-radius"
191
+ "message": "No drift data available.",
192
+ "action": "Run drift detection",
193
+ "command": "thothctl check iac -type drift --recursive"
175
194
  }
176
195
  except Exception as e:
177
- return {
178
- "error": f"Error loading risk data: {str(e)}",
179
- "action": "Check file permissions and try again",
180
- "command": "ls -la Reports/"
196
+ return {"error": f"Error loading drift data: {str(e)}"}
197
+
198
+ def get_ai_usage(self) -> Dict[str, Any]:
199
+ """Load AI usage/cost data from cost logs."""
200
+ cache_key = "ai_usage"
201
+ if self._is_cache_valid(cache_key):
202
+ return self.cache[cache_key]["data"]
203
+
204
+ try:
205
+ from datetime import date as date_mod
206
+ cost_dir = Path(".thothctl/ai_costs")
207
+ if not cost_dir.exists():
208
+ return {
209
+ "message": "No AI usage data.",
210
+ "action": "Run AI review to generate usage logs",
211
+ "command": "thothctl ai-review analyze -d ."
212
+ }
213
+
214
+ records = []
215
+ month_prefix = date_mod.today().strftime("%Y-%m")
216
+ for log_file in sorted(cost_dir.glob(f"{month_prefix}*.jsonl")):
217
+ with open(log_file) as f:
218
+ for line in f:
219
+ if line.strip():
220
+ records.append(json.loads(line.strip()))
221
+
222
+ if not records:
223
+ return {"message": "No AI usage this month.", "records": []}
224
+
225
+ total_cost = sum(r.get("cost", 0) for r in records)
226
+ total_input = sum(r.get("input_tokens", 0) for r in records)
227
+ total_output = sum(r.get("output_tokens", 0) for r in records)
228
+
229
+ data = {
230
+ "total_cost": total_cost,
231
+ "total_requests": len(records),
232
+ "total_input_tokens": total_input,
233
+ "total_output_tokens": total_output,
234
+ "records": records[-20:], # Last 20 records
181
235
  }
236
+ self._cache_data(cache_key, data)
237
+ return data
238
+ except Exception as e:
239
+ return {"error": f"Error loading AI usage: {str(e)}"}
182
240
 
183
241
  def _is_cache_valid(self, key: str) -> bool:
184
242
  """Check if cached data is still valid."""
@@ -0,0 +1,254 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ThothCTL Dashboard</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8
+ <style>
9
+ :root {
10
+ --primary: #007bff; --secondary: #6c757d; --success: #28a745;
11
+ --warning: #ffc107; --danger: #dc3545; --info: #17a2b8;
12
+ --bg: #f8f9fa; --dark: #343a40; --radius: 8px;
13
+ --shadow: 0 2px 8px rgba(0,0,0,0.08);
14
+ }
15
+ * { margin:0; padding:0; box-sizing:border-box; }
16
+ body {
17
+ font-family: 'Inter', system-ui, sans-serif;
18
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
19
+ min-height: 100vh; padding: 20px; color: var(--dark);
20
+ }
21
+ body.dark-mode { background: #1a1a2e; }
22
+ body.dark-mode .container { background: #16213e; color: #e0e0e0; }
23
+ body.dark-mode .nav-header { background: linear-gradient(135deg, #0f3460, #1a1a2e); }
24
+ body.dark-mode .card { background: #1a1a2e; border-color: #2a2a4e; }
25
+ body.dark-mode .data-table th { background: #0f3460; }
26
+ body.dark-mode .data-table td { border-color: #2a2a4e; }
27
+
28
+ .container { max-width:1400px; margin:0 auto; background:#fff; border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden; }
29
+ .nav-header { background:linear-gradient(135deg, var(--primary), #0056b3); color:#fff; padding:20px 30px; position:sticky; top:0; z-index:100; }
30
+ .nav-title { font-size:1.6rem; font-weight:700; }
31
+ .nav-subtitle { font-size:0.85rem; opacity:0.85; margin:4px 0 12px; }
32
+ .nav-menu { display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
33
+ .nav-link { color:rgba(255,255,255,0.85); text-decoration:none; padding:6px 14px; border-radius:20px; font-size:0.8rem; font-weight:500; cursor:pointer; transition:all .2s; }
34
+ .nav-link:hover, .nav-link.active { background:rgba(255,255,255,0.2); color:#fff; }
35
+ .nav-actions { margin-left:auto; display:flex; gap:8px; }
36
+ .btn { padding:6px 12px; border:none; border-radius:16px; cursor:pointer; font-size:0.75rem; font-weight:500; transition:all .2s; }
37
+ .btn-refresh { background:var(--success); color:#fff; }
38
+ .btn-export { background:rgba(255,255,255,0.2); color:#fff; }
39
+ .btn:hover { transform:translateY(-1px); opacity:0.9; }
40
+
41
+ .content-section { padding:24px 30px; display:none; }
42
+ .content-section.active { display:block; }
43
+ .section-title { font-size:1.3rem; font-weight:600; color:var(--primary); margin-bottom:16px; }
44
+
45
+ .summary-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(180px,1fr)); gap:16px; margin-bottom:24px; }
46
+ .card { background:#fff; padding:20px; border-radius:var(--radius); text-align:center; box-shadow:var(--shadow); border-left:4px solid var(--primary); cursor:pointer; transition:all .2s; }
47
+ .card:hover { transform:translateY(-2px); box-shadow:0 4px 16px rgba(0,0,0,0.12); }
48
+ .card-number { font-size:2rem; font-weight:700; color:var(--primary); }
49
+ .card-label { font-size:0.75rem; color:var(--secondary); text-transform:uppercase; letter-spacing:0.5px; margin-top:4px; }
50
+
51
+ .data-table { width:100%; border-collapse:collapse; margin:16px 0; font-size:0.85rem; }
52
+ .data-table th { background:linear-gradient(135deg, var(--primary), #0056b3); color:#fff; padding:10px 12px; text-align:left; font-weight:600; }
53
+ .data-table td { padding:10px 12px; border-bottom:1px solid #e9ecef; }
54
+ .data-table tr:hover { background:#f8f9fa; }
55
+
56
+ .badge { display:inline-block; padding:2px 8px; border-radius:10px; font-size:0.7rem; font-weight:600; }
57
+ .badge-success { background:#d4edda; color:#155724; }
58
+ .badge-warning { background:#fff3cd; color:#856404; }
59
+ .badge-danger { background:#f8d7da; color:#721c24; }
60
+ .badge-info { background:#d1ecf1; color:#0c5460; }
61
+
62
+ .message { padding:20px; text-align:center; color:var(--secondary); }
63
+ .message code { background:#e9ecef; padding:2px 6px; border-radius:4px; font-size:0.8rem; }
64
+ .error { background:#f8d7da; color:#721c24; padding:12px; border-radius:var(--radius); border-left:4px solid var(--danger); }
65
+
66
+ @media (max-width:768px) { body { padding:8px; } .content-section { padding:16px; } .nav-menu { gap:4px; } }
67
+ @media print { .nav-header { position:static; } .nav-actions { display:none; } body { background:#fff; padding:0; } }
68
+ </style>
69
+ </head>
70
+ <body>
71
+ <div class="container">
72
+ <div class="nav-header">
73
+ <div class="nav-title">🚀 ThothCTL Dashboard</div>
74
+ <div class="nav-subtitle">Infrastructure Lifecycle Console</div>
75
+ <nav class="nav-menu">
76
+ <a class="nav-link active" data-section="overview">📊 Overview</a>
77
+ <a class="nav-link" data-section="inventory">📦 Inventory</a>
78
+ <a class="nav-link" data-section="security">🔒 Scan</a>
79
+ <a class="nav-link" data-section="costs">💰 Costs</a>
80
+ <a class="nav-link" data-section="risks">💥 Blast Radius</a>
81
+ <a class="nav-link" data-section="drift">🔍 Drift</a>
82
+ <a class="nav-link" data-section="ai">🤖 AI Usage</a>
83
+ <div class="nav-actions">
84
+ <button class="btn btn-refresh" onclick="refreshAll()">🔄 Refresh</button>
85
+ <button class="btn btn-export" onclick="window.print()">📄 Export</button>
86
+ <button class="btn btn-export" onclick="toggleDark()">🌙</button>
87
+ </div>
88
+ </nav>
89
+ </div>
90
+
91
+ <section id="overview" class="content-section active"><h2 class="section-title">📊 Overview</h2><div id="overview-content"><div class="message">Loading...</div></div></section>
92
+ <section id="inventory" class="content-section"><h2 class="section-title">📦 Infrastructure Inventory</h2><div id="inventory-content"><div class="message">Loading...</div></div></section>
93
+ <section id="security" class="content-section"><h2 class="section-title">🔒 Security Scan Results</h2><div id="security-content"><div class="message">Loading...</div></div></section>
94
+ <section id="costs" class="content-section"><h2 class="section-title">💰 Cost Analysis</h2><div id="costs-content"><div class="message">Loading...</div></div></section>
95
+ <section id="risks" class="content-section"><h2 class="section-title">💥 Blast Radius</h2><div id="risks-content"><div class="message">Loading...</div></div></section>
96
+ <section id="drift" class="content-section"><h2 class="section-title">🔍 Drift Detection</h2><div id="drift-content"><div class="message">Loading...</div></div></section>
97
+ <section id="ai" class="content-section"><h2 class="section-title">🤖 AI Token Usage</h2><div id="ai-content"><div class="message">Loading...</div></div></section>
98
+ </div>
99
+
100
+ <script>
101
+ const D = {};
102
+
103
+ document.addEventListener('DOMContentLoaded', () => {
104
+ if (localStorage.getItem('darkMode')==='true') { document.body.classList.add('dark-mode'); }
105
+ document.querySelectorAll('.nav-link[data-section]').forEach(link => {
106
+ link.addEventListener('click', () => {
107
+ document.querySelectorAll('.nav-link').forEach(l=>l.classList.remove('active'));
108
+ document.querySelectorAll('.content-section').forEach(s=>s.classList.remove('active'));
109
+ link.classList.add('active');
110
+ document.getElementById(link.dataset.section).classList.add('active');
111
+ });
112
+ });
113
+ loadAll();
114
+ });
115
+
116
+ function toggleDark() {
117
+ document.body.classList.toggle('dark-mode');
118
+ localStorage.setItem('darkMode', document.body.classList.contains('dark-mode'));
119
+ }
120
+
121
+ async function refreshAll() { await fetch('/api/refresh'); loadAll(); }
122
+
123
+ async function loadAll() {
124
+ const endpoints = {inventory:'/api/inventory', security:'/api/scan-results', costs:'/api/cost-analysis', risks:'/api/blast-radius', drift:'/api/drift', ai:'/api/ai-usage'};
125
+ const results = await Promise.allSettled(Object.entries(endpoints).map(async ([k,url]) => {
126
+ const r = await fetch(url); D[k] = await r.json(); return k;
127
+ }));
128
+ renderOverview(); renderInventory(); renderSecurity(); renderCosts(); renderRisks(); renderDrift(); renderAI();
129
+ }
130
+
131
+ function msg(text, cmd) { return `<div class="message">${text}${cmd ? '<br><code>'+cmd+'</code>' : ''}</div>`; }
132
+ function err(data) { return data && (data.error || data.message); }
133
+
134
+ function renderOverview() {
135
+ const inv = D.inventory||{}, sec = D.security||{}, cost = D.costs||{}, risk = D.risks||{}, drift = D.drift||{}, ai = D.ai||{};
136
+ const comps = Array.isArray(inv.components) ? inv.components.length : (inv.stacks ? inv.stacks.length : 0);
137
+ const issues = sec.summary ? sec.summary.total_issues : 0;
138
+ const monthly = typeof cost.total_monthly_cost === 'number' ? cost.total_monthly_cost.toFixed(2) : '—';
139
+ const riskLvl = risk.risk_level || risk.overall_risk || '—';
140
+ const drifted = drift.total_drifted || (drift.results ? drift.results.reduce((a,r)=>a+(r.drifted_resources||[]).length,0) : 0);
141
+ const aiCost = typeof ai.total_cost === 'number' ? '$'+ai.total_cost.toFixed(4) : '—';
142
+ document.getElementById('overview-content').innerHTML = `
143
+ <div class="summary-grid">
144
+ <div class="card" onclick="nav('inventory')"><div class="card-number">${comps}</div><div class="card-label">Components</div></div>
145
+ <div class="card" onclick="nav('security')" style="border-color:var(--danger)"><div class="card-number" style="color:var(--danger)">${issues}</div><div class="card-label">Security Issues</div></div>
146
+ <div class="card" onclick="nav('costs')" style="border-color:var(--warning)"><div class="card-number" style="color:var(--warning)">$${monthly}</div><div class="card-label">Monthly Cost</div></div>
147
+ <div class="card" onclick="nav('risks')" style="border-color:var(--info)"><div class="card-number" style="color:var(--info)">${riskLvl}</div><div class="card-label">Risk Level</div></div>
148
+ <div class="card" onclick="nav('drift')" style="border-color:#9c27b0"><div class="card-number" style="color:#9c27b0">${drifted}</div><div class="card-label">Drifted Resources</div></div>
149
+ <div class="card" onclick="nav('ai')" style="border-color:#00bcd4"><div class="card-number" style="color:#00bcd4">${aiCost}</div><div class="card-label">AI Cost (Month)</div></div>
150
+ </div>`;
151
+ }
152
+
153
+ function nav(section) { document.querySelector(`[data-section="${section}"]`).click(); }
154
+
155
+ function renderInventory() {
156
+ const d = D.inventory;
157
+ if (!d || err(d)) { document.getElementById('inventory-content').innerHTML = msg(d?.error||d?.message||'No data', d?.command); return; }
158
+ const stacks = d.stacks || d.components || [];
159
+ if (!stacks.length) { document.getElementById('inventory-content').innerHTML = msg('No components found'); return; }
160
+ let html = `<div class="summary-grid"><div class="card"><div class="card-number">${stacks.length}</div><div class="card-label">Stacks</div></div></div>`;
161
+ html += '<table class="data-table"><thead><tr><th>Stack</th><th>Modules</th><th>Providers</th></tr></thead><tbody>';
162
+ stacks.forEach(s => {
163
+ const name = s.stack || s.name || 'unknown';
164
+ const mods = s.modules ? s.modules.length : (s.components ? s.components.length : 0);
165
+ const provs = s.providers ? s.providers.length : 0;
166
+ html += `<tr><td><strong>${name}</strong></td><td>${mods}</td><td>${provs}</td></tr>`;
167
+ });
168
+ html += '</tbody></table>';
169
+ document.getElementById('inventory-content').innerHTML = html;
170
+ }
171
+
172
+ function renderSecurity() {
173
+ const d = D.security;
174
+ if (!d || err(d)) { document.getElementById('security-content').innerHTML = msg(d?.error||d?.message||'No data', d?.command); return; }
175
+ const issues = d.summary ? d.summary.total_issues : 0;
176
+ const reports = d.reports || [];
177
+ let html = `<div class="summary-grid"><div class="card" style="border-color:var(--danger)"><div class="card-number" style="color:var(--danger)">${issues}</div><div class="card-label">Total Issues</div></div><div class="card"><div class="card-number">${reports.length}</div><div class="card-label">Reports</div></div></div>`;
178
+ if (reports.length) {
179
+ html += '<table class="data-table"><thead><tr><th>Report</th><th>Type</th><th>Date</th><th>Size</th></tr></thead><tbody>';
180
+ reports.slice(0,20).forEach(r => {
181
+ html += `<tr><td>${r.file}</td><td><span class="badge badge-info">${r.type||'—'}</span></td><td>${r.timestamp ? new Date(r.timestamp).toLocaleDateString() : '—'}</td><td>${r.size ? (r.size/1024).toFixed(1)+'KB' : '—'}</td></tr>`;
182
+ });
183
+ html += '</tbody></table>';
184
+ }
185
+ document.getElementById('security-content').innerHTML = html;
186
+ }
187
+
188
+ function renderCosts() {
189
+ const d = D.costs;
190
+ if (!d || err(d)) { document.getElementById('costs-content').innerHTML = msg(d?.error||d?.message||'No data', d?.command); return; }
191
+ const monthly = d.total_monthly_cost||0, annual = d.total_annual_cost||0;
192
+ let html = `<div class="summary-grid"><div class="card" style="border-color:var(--warning)"><div class="card-number" style="color:var(--warning)">$${monthly.toFixed(2)}</div><div class="card-label">Monthly</div></div><div class="card" style="border-color:var(--danger)"><div class="card-number" style="color:var(--danger)">$${annual.toFixed(2)}</div><div class="card-label">Annual</div></div></div>`;
193
+ if (d.cost_breakdown_by_service) {
194
+ html += '<table class="data-table"><thead><tr><th>Service</th><th>Monthly Cost</th></tr></thead><tbody>';
195
+ Object.entries(d.cost_breakdown_by_service).sort((a,b)=>b[1]-a[1]).forEach(([svc,cost]) => {
196
+ html += `<tr><td>${svc}</td><td>$${cost.toFixed(2)}</td></tr>`;
197
+ });
198
+ html += '</tbody></table>';
199
+ }
200
+ if (d.recommendations && d.recommendations.length) {
201
+ html += '<h3 style="margin:16px 0 8px">💡 Recommendations</h3><ul style="padding-left:20px">';
202
+ d.recommendations.forEach(r => html += `<li style="margin:4px 0">${r}</li>`);
203
+ html += '</ul>';
204
+ }
205
+ document.getElementById('costs-content').innerHTML = html;
206
+ }
207
+
208
+ function renderRisks() {
209
+ const d = D.risks;
210
+ if (!d || err(d)) { document.getElementById('risks-content').innerHTML = msg(d?.error||d?.message||'No data', d?.command); return; }
211
+ const riskColor = {'LOW':'var(--success)','MEDIUM':'var(--warning)','HIGH':'var(--danger)','CRITICAL':'var(--danger)'}[d.risk_level?.toUpperCase()]||'var(--info)';
212
+ let html = `<div class="summary-grid"><div class="card" style="border-color:${riskColor}"><div class="card-number" style="color:${riskColor}">${d.risk_level||'—'}</div><div class="card-label">Risk Level</div></div><div class="card"><div class="card-number">${d.change_type||'—'}</div><div class="card-label">Change Type</div></div><div class="card"><div class="card-number">${d.affected_components||d.total_components||0}</div><div class="card-label">Affected</div></div></div>`;
213
+ if (d.recommendations && d.recommendations.length) {
214
+ html += '<h3 style="margin:16px 0 8px">📋 Recommendations</h3><ul style="padding-left:20px">';
215
+ d.recommendations.forEach(r => html += `<li style="margin:4px 0">${r}</li>`);
216
+ html += '</ul>';
217
+ }
218
+ document.getElementById('risks-content').innerHTML = html;
219
+ }
220
+
221
+ function renderDrift() {
222
+ const d = D.drift;
223
+ if (!d || err(d)) { document.getElementById('drift-content').innerHTML = msg(d?.error||d?.message||'No data', d?.command); return; }
224
+ const results = d.results || [];
225
+ const totalDrifted = results.reduce((a,r)=>a+(r.drifted_resources||[]).length, 0);
226
+ const coverage = d.iac_coverage_percentage != null ? d.iac_coverage_percentage.toFixed(1)+'%' : '—';
227
+ let html = `<div class="summary-grid"><div class="card" style="border-color:#9c27b0"><div class="card-number" style="color:#9c27b0">${totalDrifted}</div><div class="card-label">Drifted Resources</div></div><div class="card"><div class="card-number">${coverage}</div><div class="card-label">IaC Coverage</div></div><div class="card"><div class="card-number">${results.length}</div><div class="card-label">Stacks Checked</div></div></div>`;
228
+ if (totalDrifted > 0) {
229
+ html += '<table class="data-table"><thead><tr><th>Resource</th><th>Type</th><th>Drift Type</th><th>Severity</th></tr></thead><tbody>';
230
+ results.forEach(r => (r.drifted_resources||[]).forEach(res => {
231
+ const sevClass = {'critical':'badge-danger','high':'badge-danger','medium':'badge-warning','low':'badge-info'}[res.severity]||'badge-info';
232
+ html += `<tr><td>${res.address||'—'}</td><td>${res.resource_type||'—'}</td><td>${res.drift_type||'—'}</td><td><span class="badge ${sevClass}">${res.severity||'—'}</span></td></tr>`;
233
+ }));
234
+ html += '</tbody></table>';
235
+ }
236
+ document.getElementById('drift-content').innerHTML = html;
237
+ }
238
+
239
+ function renderAI() {
240
+ const d = D.ai;
241
+ if (!d || err(d)) { document.getElementById('ai-content').innerHTML = msg(d?.error||d?.message||'No data', d?.command); return; }
242
+ let html = `<div class="summary-grid"><div class="card" style="border-color:#00bcd4"><div class="card-number" style="color:#00bcd4">$${(d.total_cost||0).toFixed(4)}</div><div class="card-label">Total Cost</div></div><div class="card"><div class="card-number">${d.total_requests||0}</div><div class="card-label">Requests</div></div><div class="card"><div class="card-number">${(d.total_input_tokens||0).toLocaleString()}</div><div class="card-label">Input Tokens</div></div><div class="card"><div class="card-number">${(d.total_output_tokens||0).toLocaleString()}</div><div class="card-label">Output Tokens</div></div></div>`;
243
+ if (d.records && d.records.length) {
244
+ html += '<table class="data-table"><thead><tr><th>Time</th><th>Provider</th><th>Model</th><th>In</th><th>Out</th><th>Cost</th></tr></thead><tbody>';
245
+ d.records.slice().reverse().forEach(r => {
246
+ html += `<tr><td>${r.timestamp ? new Date(r.timestamp).toLocaleString() : '—'}</td><td>${r.provider||'—'}</td><td>${r.model||'—'}</td><td>${(r.input_tokens||0).toLocaleString()}</td><td>${(r.output_tokens||0).toLocaleString()}</td><td>$${(r.cost||0).toFixed(4)}</td></tr>`;
247
+ });
248
+ html += '</tbody></table>';
249
+ }
250
+ document.getElementById('ai-content').innerHTML = html;
251
+ }
252
+ </script>
253
+ </body>
254
+ </html>
@@ -0,0 +1,2 @@
1
+ """Version module."""
2
+ __version__ = "0.18.6"