thothctl 0.18.7__tar.gz → 0.18.9__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.
- {thothctl-0.18.7 → thothctl-0.18.9}/PKG-INFO +1 -1
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/scan/commands/iac.py +81 -11
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/dashboard/dashboard_service.py +43 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/dashboard/data_loader.py +182 -8
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/dashboard.html +215 -8
- thothctl-0.18.9/src/thothctl/version.py +2 -0
- thothctl-0.18.7/src/thothctl/version.py +0 -2
- {thothctl-0.18.7 → thothctl-0.18.9}/.devcontainer/Dockerfile +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.devcontainer/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.devcontainer/devcontainer.json +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.github/workflows/docs.yml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.github/workflows/python-publish.yml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.gitignore +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.pre-commit-config.yaml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/.readthedocs.yaml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/Dockerfile +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/LICENSE +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/catalog/catalog-info.yaml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/dashboard/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/ai-review/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/ai-review/agent_specifications.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/ai-review/agentcore.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/blast-radius.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/check_environment.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/check_iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/check_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/check_project_iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/check_space.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/cost-analysis-quick-reference.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/cost-analysis.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/customizing_rules.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/deps-advanced.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/deps.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/drift-detection.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/check/plan.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/document/customizing_docs.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/document/document_iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/document/document_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/document/iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/document/use_cases.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/generate/generate_components.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/generate/generate_stacks.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/init/init.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/init/init_space.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/inventory/CHANGELOG.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/inventory/frameworks/terraform.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/inventory/frameworks/terragrunt.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/inventory/iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/inventory/inventory_iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/inventory/inventory_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/list/list_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/list/list_projects.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/list/list_spaces.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/mcp/mcp.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/project/iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/project/project_cleanup.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/project/project_convert.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/project/project_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/project/project_upgrade.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/project/use_cases.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/remove/remove_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/remove/remove_project.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/remove/remove_space.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/scan/iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/scan/scan_iac.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/scan/scan_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/scan/use_cases.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/commands/upgrade/upgrade_overview.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/concepts.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/cross_platform_support.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/framework_architecture.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/infrasctructure_composition.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/policy_as_code.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/roadmap_fdi.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/software_architecture.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/space_configuration.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/ai_dlc.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/check_command.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/devsecops_quickstart.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/devsecops_sdlc.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/inventory_command.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/platform_engineering_templates.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/space_management.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/framework/use_cases/tasks/create_template.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/iac_devsecops_use_case.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/automate_tasks_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/commnad_init.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/create_component.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/create_inventory.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/doc_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/document_project_code.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/framework/thothforge-framework.svg +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/framework/thothfr.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/iacpeerbot_summary.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/icon-light.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/icon.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/init_project.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/inventory_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/notification_img.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/report_dependencies.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/report_dependencies_summary.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/restore_inventory_version.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/reuse_project_pattern.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/scan_code.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/scan_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/stable/scan_report_example.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/sync_wk_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/transform_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/update_inventory_version.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/validate_command.png +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/validate_environment.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/img/validate_project.gif +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/includes/abbreviations.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/index.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/installation/devcontainer_setup.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/installation/linux_installation.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/installation/windows_installation.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/javascripts/tablesort.js +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/mcp.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/navigation.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/quick_start.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/requirements.txt +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/stylesheets/extra-enhanced.css +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/stylesheets/extra.css +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/telemetry.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/template_engine/cli_commands_audit.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/template_engine/for_developers.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/template_engine/for_platform_engineers.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/template_engine/github_templates.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/template_engine/template_engine.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/troubleshooting/linux_troubleshooting.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/troubleshooting/macos_troubleshooting.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/troubleshooting/troubleshooting.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/docs/troubleshooting/windows_troubleshooting.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/mkdocs.yaml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/pyproject.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/scripts/run_mcp_server.sh +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/application/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/autocomplete.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/analyze.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/apply_fix.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/configure.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/configure_decisions.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/decide.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/history.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/improve.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/orchestrate.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/override.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/report.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/ai_review/commands/serve.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/commands/environment.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/commands/iac.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/commands/project/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/commands/project/iac.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/check/commands/project.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/dashboard/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/dashboard/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/dashboard/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/dashboard/commands/launch.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/document/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/document/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/document/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/document/commands/iac.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/generate/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/generate/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/generate/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/generate/commands/component.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/generate/commands/stacks.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/commands/env.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/commands/project.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/commands/space.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/init/commands/template.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/inventory/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/inventory/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/inventory/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/inventory/commands/check.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/inventory/commands/iac.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/list/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/list/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/list/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/list/commands/projects.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/list/commands/spaces.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/commands/register.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/commands/server.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/commands/status.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/mcp/commands/stop.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/commands/bootstrap.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/commands/cleanup.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/commands/convert.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/project/commands/upgrade.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/remove/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/remove/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/remove/project.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/remove/space.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/scan/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/scan/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/scan/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/space/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/space/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/space/commands/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/space/commands/activate.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/space/commands/show.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/space/commands/update.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/commands/upgrade/cli.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/.thothcf.setup.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/.thothcf_home.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/.thothcf_module.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/.thothcf_project.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/.thothcf_template_parameters.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/common.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/common/terragrunt/.thothcf_project.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/constants.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/default_values.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/defaults.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/models.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/settings.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/template_config.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/template_configs.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/templates.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/config/validation.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/cli_ui.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/commands.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/config.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/azure_devops/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/azure_devops/get_azure_devops.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/azure_devops/pull_request_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/github/get_github.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/github/pull_request_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/integrate_messages_services/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/integrate_messages_services/microsoft_teams.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/integrate_messages_services/sent_message_teams.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/pattern_names.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/pr_comments/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/integrations/pr_comments/pr_comment_publisher.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/logger.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/telemetry.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/core/version_tools.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/domain/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/domain/interfaces/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/domain/models/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/mcp/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/mcp/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/mcp/server.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/agentcore/agentcore.json +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/ai_agent.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/analyzers/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/analyzers/code_reviewer.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/analyzers/context_builder.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/analyzers/report_analyzer.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/analyzers/risk_assessor.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/bedrock_agent_api.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/config/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/config/ai_settings.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/config/decision_rules.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/decision_engine.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/main.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/memory.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/orchestrator.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/pr_decision_publisher.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/providers/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/providers/azure_provider.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/providers/bedrock_agent_provider.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/providers/bedrock_provider.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/providers/ollama_provider.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/providers/openai_provider.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/safety/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/safety/safety_guard.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/strands_agent.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/tracing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/utils/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/utils/cost_tracker.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/utils/fix_patterns.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/utils/fix_prompts.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/utils/formatters.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/ai_review/utils/prompts.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/environment/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/environment/check_environment.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/org_policy_loader.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/blast_radius_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/check_origin_version.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/check_project_structure.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/cost_analyzer.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/models/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/models/cloudformation_mapper.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/models/cost_models.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/aws_pricing_client.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/base_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/apigateway_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/bedrock_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/cloudwatch_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/dynamodb_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/ebs_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/ec2_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/ecs_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/eip_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/eks_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/elb_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/free_resources_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/kms_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/lambda_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/msk_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/rds_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/s3_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/secrets_manager_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/pricing/providers/vpc_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/cost/unified_cost_report.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/drift_ai.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/drift_history.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/drift_policy.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/drift_report.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/drift_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/drift/models.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/risk_assessment.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/project/validate_project_structure.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/rule_merger.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/check/stack_optimizer/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/dashboard/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/create_documentation.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/files_content.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/files_scan.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/iac_documentation.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/iac_grunt_graph.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/document/iac_grunt_info.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_stacks/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_stacks/config_generator.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_stacks/remote_config_generation.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_stacks/stack_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_stacks/templates/terragrunt.hcl.j2 +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/config.yaml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/create_code.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/create_component.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/create_component_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/create_stacks.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/create_template.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/files_content.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/github_template_loader.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/generate/create_template/project_templates.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/environment/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/environment/install_tools.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/project/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/project/project.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/space/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/space/example_space.toml +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/space/local_registry.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/init/space/space.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/changelog_parser.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/inventory_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/models.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/module_compatibility_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/report_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/schema_compatibility_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/terragrunt_parser.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/update_versions.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/inventory/version_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/mcp/README.md +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/mcp/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/mcp/simple_http_server.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/mcp/stdio_server.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/bootstrap/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/bootstrap/bootstrap_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/cleanup/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/cleanup/clean_project.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/cleanup/clean_space.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/conversion_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/get_project_data.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/post_init.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/project_converter.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/project_defaults.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/convert/set_project_parameters.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/create_terramate/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/create_terramate/create_terramate_stacks.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/create_terramate/detect_changes_stacks.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/create_terramate/manage_terramate_stacks.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/upgrade/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/project/upgrade/upgrade_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/compliance_review.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/import_reports.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/models.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/report_parser.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/sarif_output.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scan_history.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scan_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/checkov.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/kics.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/opa.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/scan_reports.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/scanners.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/terraform_compliance.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/tfsec.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/services/scan/scanners/trivy.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/templates/reports/inventory_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/templates/reports/inventory_report.js +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/templates/unified_report_styles.css +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/banner.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/create_compliance_html_reports.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/create_html_reports.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/delete_directory.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/fix_report_styling.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/render_scan_report.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/report_html_utils.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/index_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/individual_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/simple_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/unified_report_styles.css +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/unified_scan_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/unified_simple_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/common/templates/xunit_report.html +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/crypto.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/manage_backend_resources/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/manage_backend_resources/manage_backend_resources.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/modules_ops/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/modules_ops/terraform_module_details.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/modules_ops/terraform_modules_fetcher.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/platform_utils.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/process_hcl/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/process_hcl/analyze_terraform_plan.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/process_hcl/graph_manager.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/process_hcl/graph_terragrunt_dependencies.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/process_hcl/process_terraform_file.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/process_hcl/risk_analyzing_terraform_plan.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/sync_workspaces/__init__.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/sync_workspaces/sync_terraform_workspaces.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/sync_workspaces/sync_terragrunt_workspaces.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/template_loader.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/utils/thoth_colors.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/src/thothctl/wellcome_banner.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/conftest.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_agentcore_entrypoint.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_aws_pricing_client.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_azure_devops_pr_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_bedrock_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_cdk_language_selection.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_context_steering.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_cost_analyzer.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_cost_models.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_cost_pr_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_dashboard_loading_fix.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_dashboard_service.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_drift.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_drift_detection.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_ec2_pricing.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_github_pr_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_iac_cost_integration.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_inventory_pr_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_kics_scanner.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_mermaid_edge_labels.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_new_cost_providers.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_parallel_scan.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_platform_utils.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_pr_comment_publisher.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_provider_source_url_fix.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_provider_versions.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_scan_pr_comments.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_space_command.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_space_management.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_stack_optimizer.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_template_url_fix.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tests/test_terragrunt_parser.py +0 -0
- {thothctl-0.18.7 → thothctl-0.18.9}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thothctl
|
|
3
|
-
Version: 0.18.
|
|
3
|
+
Version: 0.18.9
|
|
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
|
|
@@ -67,13 +67,13 @@ class RestoredIaCScanCommand(ClickCommand):
|
|
|
67
67
|
|
|
68
68
|
# Create a panel with scan information
|
|
69
69
|
scan_info = Panel(
|
|
70
|
-
f"[bold]Starting security scan
|
|
70
|
+
f"[bold]Starting security scan[/bold]\n\n"
|
|
71
71
|
f"Directory: [cyan]{code_directory}[/cyan]\n"
|
|
72
72
|
f"Project: [magenta]{project_name}[/magenta]\n"
|
|
73
73
|
f"Tools: [yellow]{', '.join(tools)}[/yellow]\n"
|
|
74
74
|
f"Reports directory: [green]{reports_dir}[/green]\n"
|
|
75
|
-
f"
|
|
76
|
-
title="[bold blue]ThothCTL
|
|
75
|
+
f"Enforcement: [{'red' if self._enforcement == 'hard' else 'green'}]{self._enforcement}[/{'red' if self._enforcement == 'hard' else 'green'}]",
|
|
76
|
+
title="[bold blue]ThothCTL Security Scan[/bold blue]",
|
|
77
77
|
border_style="blue"
|
|
78
78
|
)
|
|
79
79
|
self.console.print(scan_info)
|
|
@@ -171,12 +171,12 @@ class RestoredIaCScanCommand(ClickCommand):
|
|
|
171
171
|
|
|
172
172
|
# Create completion panel
|
|
173
173
|
completion_panel = Panel(
|
|
174
|
-
f"[bold green]
|
|
174
|
+
f"[bold green]Security scan completed![/bold green]\n\n"
|
|
175
175
|
f"⏱️ Scan time: [cyan]{scan_time:.2f} seconds[/cyan]\n"
|
|
176
176
|
f"📊 Reports directory: [blue]{reports_dir}[/blue]\n"
|
|
177
177
|
f"🎨 HTML reports: [blue]Generated with unified styling[/blue]\n"
|
|
178
178
|
f"🔍 Tools used: [yellow]{len(tools)}[/yellow]",
|
|
179
|
-
title="[bold green]
|
|
179
|
+
title="[bold green]Scan Complete[/bold green]",
|
|
180
180
|
border_style="green"
|
|
181
181
|
)
|
|
182
182
|
self.console.print(completion_panel)
|
|
@@ -184,20 +184,90 @@ class RestoredIaCScanCommand(ClickCommand):
|
|
|
184
184
|
# Exit with code 1 if hard enforcement failed
|
|
185
185
|
if has_violations:
|
|
186
186
|
ctx = click.get_current_context()
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
# Collect violation details per tool
|
|
188
|
+
violation_lines = []
|
|
189
|
+
all_findings = []
|
|
190
|
+
for tool_name, tool_result in results.items():
|
|
191
|
+
if tool_name == "summary" or not isinstance(tool_result, dict):
|
|
192
|
+
continue
|
|
193
|
+
rd = tool_result.get("report_data", {})
|
|
194
|
+
failed = rd.get("failed_count", 0)
|
|
195
|
+
errors = rd.get("error_count", 0)
|
|
196
|
+
if failed + errors > 0:
|
|
197
|
+
violation_lines.append(
|
|
198
|
+
f" • [yellow]{tool_name}[/yellow]: {failed} violation{'s' if failed != 1 else ''}, {errors} error{'s' if errors != 1 else ''}"
|
|
199
|
+
)
|
|
200
|
+
# Collect findings for the table (only HIGH/deny-level)
|
|
201
|
+
for f in tool_result.get("findings", []):
|
|
202
|
+
sev = f.get("severity", "HIGH").upper()
|
|
203
|
+
if sev in ("HIGH", "CRITICAL"):
|
|
204
|
+
all_findings.append({**f, "tool": tool_name})
|
|
205
|
+
|
|
206
|
+
# Build non-compliance table
|
|
207
|
+
findings_table = Table(
|
|
208
|
+
title="Non-Compliance Findings",
|
|
209
|
+
box=rich.box.SIMPLE_HEAVY,
|
|
210
|
+
header_style="bold red",
|
|
211
|
+
title_style="bold red",
|
|
212
|
+
show_lines=False,
|
|
213
|
+
expand=True,
|
|
214
|
+
)
|
|
215
|
+
findings_table.add_column("Tool", style="yellow", max_width=12)
|
|
216
|
+
findings_table.add_column("Severity", justify="center", max_width=10)
|
|
217
|
+
findings_table.add_column("Policy Violation", style="white", ratio=3)
|
|
218
|
+
findings_table.add_column("File", style="dim", ratio=2, overflow="ellipsis")
|
|
219
|
+
|
|
220
|
+
# Show up to 15 findings
|
|
221
|
+
display_findings = all_findings[:15]
|
|
222
|
+
for f in display_findings:
|
|
223
|
+
sev = f.get("severity", "HIGH").upper()
|
|
224
|
+
sev_style = "bold red" if sev == "CRITICAL" else "red"
|
|
225
|
+
file_ref = f.get("file", "")
|
|
226
|
+
if file_ref and len(file_ref) > 60:
|
|
227
|
+
file_ref = "..." + file_ref[-57:]
|
|
228
|
+
line = f.get("line", 0)
|
|
229
|
+
file_display = f"{file_ref}:{line}" if line else file_ref
|
|
230
|
+
|
|
231
|
+
findings_table.add_row(
|
|
232
|
+
f.get("tool", ""),
|
|
233
|
+
f"[{sev_style}]{sev}[/{sev_style}]",
|
|
234
|
+
f.get("title", ""),
|
|
235
|
+
file_display,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
remaining = len(all_findings) - len(display_findings)
|
|
239
|
+
if remaining > 0:
|
|
240
|
+
findings_table.add_row(
|
|
241
|
+
"", "", f"[dim]... and {remaining} more[/dim]", ""
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
self.console.print()
|
|
245
|
+
self.console.print(findings_table)
|
|
246
|
+
|
|
247
|
+
violations_detail = "\n".join(violation_lines)
|
|
248
|
+
enforcement_panel = Panel(
|
|
249
|
+
f"[bold red]Security policy violations detected[/bold red]\n\n"
|
|
250
|
+
f"{violations_detail}\n\n"
|
|
251
|
+
f"[dim]Mode:[/dim] [bold]--enforcement hard[/bold] — pipeline will exit with code 1\n"
|
|
252
|
+
f"[dim]Fix:[/dim] Resolve the violations above, or use [bold]--enforcement soft[/bold] to report without blocking.\n"
|
|
253
|
+
f"[dim]Reports:[/dim] See [blue]{reports_dir}[/blue] for details.",
|
|
254
|
+
title="[bold red]⛔ Enforcement Failed[/bold red]",
|
|
255
|
+
border_style="red"
|
|
189
256
|
)
|
|
257
|
+
self.console.print(enforcement_panel)
|
|
190
258
|
ctx.exit(1)
|
|
191
259
|
|
|
192
260
|
except Exception as e:
|
|
193
261
|
error_panel = Panel(
|
|
194
|
-
f"[bold red]
|
|
195
|
-
f"
|
|
196
|
-
|
|
262
|
+
f"[bold red]Security scan could not complete[/bold red]\n\n"
|
|
263
|
+
f"[red]{str(e)}[/red]\n\n"
|
|
264
|
+
f"[dim]This is an execution error, not a policy violation.\n"
|
|
265
|
+
f"Check that the required tools are installed and the target directory is valid.[/dim]",
|
|
266
|
+
title="[bold red]❌ Scan Error[/bold red]",
|
|
197
267
|
border_style="red"
|
|
198
268
|
)
|
|
199
269
|
self.console.print(error_panel)
|
|
200
|
-
self.logger.error(f"
|
|
270
|
+
self.logger.error(f"Scan execution failed: {e}")
|
|
201
271
|
raise
|
|
202
272
|
|
|
203
273
|
def _parse_options(self, options_str: str) -> dict:
|
|
@@ -59,6 +59,49 @@ class DashboardService:
|
|
|
59
59
|
except Exception as e:
|
|
60
60
|
logger.error(f"Scan results API error: {e}")
|
|
61
61
|
raise HTTPException(status_code=500, detail=str(e))
|
|
62
|
+
|
|
63
|
+
@self.app.get("/api/findings")
|
|
64
|
+
async def api_findings(
|
|
65
|
+
tool: str = None,
|
|
66
|
+
severity: str = None,
|
|
67
|
+
search: str = None,
|
|
68
|
+
limit: int = 100,
|
|
69
|
+
offset: int = 0,
|
|
70
|
+
):
|
|
71
|
+
"""API endpoint for individual findings with filtering."""
|
|
72
|
+
try:
|
|
73
|
+
result = self.data_loader.get_findings(
|
|
74
|
+
tool=tool, severity=severity, search=search,
|
|
75
|
+
limit=limit, offset=offset,
|
|
76
|
+
)
|
|
77
|
+
return result
|
|
78
|
+
except Exception as e:
|
|
79
|
+
logger.error(f"Findings API error: {e}")
|
|
80
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
81
|
+
|
|
82
|
+
@self.app.get("/api/reports/{report_path:path}")
|
|
83
|
+
async def api_serve_report(report_path: str):
|
|
84
|
+
"""Serve individual HTML report files for iframe viewing."""
|
|
85
|
+
from fastapi.responses import FileResponse
|
|
86
|
+
import os
|
|
87
|
+
|
|
88
|
+
# Resolve path safely within the project directory
|
|
89
|
+
full_path = Path(os.getcwd()) / report_path
|
|
90
|
+
# Security: ensure the resolved path is within the project
|
|
91
|
+
try:
|
|
92
|
+
full_path = full_path.resolve()
|
|
93
|
+
cwd = Path(os.getcwd()).resolve()
|
|
94
|
+
if not str(full_path).startswith(str(cwd)):
|
|
95
|
+
raise HTTPException(status_code=403, detail="Access denied")
|
|
96
|
+
except Exception:
|
|
97
|
+
raise HTTPException(status_code=403, detail="Invalid path")
|
|
98
|
+
|
|
99
|
+
if not full_path.exists() or not full_path.is_file():
|
|
100
|
+
raise HTTPException(status_code=404, detail="Report not found")
|
|
101
|
+
if full_path.suffix not in (".html", ".json", ".xml", ".sarif"):
|
|
102
|
+
raise HTTPException(status_code=403, detail="File type not allowed")
|
|
103
|
+
|
|
104
|
+
return FileResponse(str(full_path), media_type="text/html" if full_path.suffix == ".html" else "application/json")
|
|
62
105
|
|
|
63
106
|
@self.app.get("/api/cost-analysis")
|
|
64
107
|
async def api_cost_analysis():
|
|
@@ -62,19 +62,31 @@ class DashboardDataLoader:
|
|
|
62
62
|
return self.cache[cache_key]["data"]
|
|
63
63
|
|
|
64
64
|
try:
|
|
65
|
-
results = {"reports": [], "summary": {"total_issues": 0}}
|
|
65
|
+
results = {"reports": [], "summary": {"total_issues": 0}, "tools": []}
|
|
66
66
|
|
|
67
67
|
html_reports = list(self.reports_dir.rglob("*.html"))
|
|
68
68
|
xml_reports = list(self.reports_dir.rglob("*.xml"))
|
|
69
69
|
|
|
70
|
+
# Track which tools have reports
|
|
71
|
+
tools_found = set()
|
|
72
|
+
|
|
70
73
|
for html_file in html_reports:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
rel_path = str(html_file.relative_to(self.base_dir))
|
|
75
|
+
# Determine tool from path
|
|
76
|
+
tool = "other"
|
|
77
|
+
for t in ("checkov", "trivy", "kics", "opa", "terraform-compliance"):
|
|
78
|
+
if t in rel_path:
|
|
79
|
+
tool = t
|
|
80
|
+
tools_found.add(t)
|
|
81
|
+
break
|
|
82
|
+
|
|
83
|
+
results["reports"].append({
|
|
84
|
+
"file": rel_path,
|
|
85
|
+
"type": "html",
|
|
86
|
+
"tool": tool,
|
|
87
|
+
"timestamp": datetime.fromtimestamp(html_file.stat().st_mtime).isoformat(),
|
|
88
|
+
"size": html_file.stat().st_size
|
|
89
|
+
})
|
|
78
90
|
|
|
79
91
|
for xml_file in xml_reports:
|
|
80
92
|
try:
|
|
@@ -86,6 +98,8 @@ class DashboardDataLoader:
|
|
|
86
98
|
except:
|
|
87
99
|
pass
|
|
88
100
|
|
|
101
|
+
results["tools"] = sorted(tools_found)
|
|
102
|
+
|
|
89
103
|
if not results["reports"]:
|
|
90
104
|
return {
|
|
91
105
|
"error": "No scan results found",
|
|
@@ -102,6 +116,166 @@ class DashboardDataLoader:
|
|
|
102
116
|
"action": "Check file permissions and try again",
|
|
103
117
|
"command": "ls -la Reports/"
|
|
104
118
|
}
|
|
119
|
+
|
|
120
|
+
def get_findings(self, tool: str = None, severity: str = None, search: str = None, limit: int = 100, offset: int = 0) -> Dict[str, Any]:
|
|
121
|
+
"""Load individual findings from JSON reports with filtering."""
|
|
122
|
+
cache_key = "findings_all"
|
|
123
|
+
if not self._is_cache_valid(cache_key):
|
|
124
|
+
all_findings = []
|
|
125
|
+
|
|
126
|
+
# Parse Checkov JSON reports
|
|
127
|
+
checkov_dir = self.reports_dir / "checkov" / "security-scan"
|
|
128
|
+
if checkov_dir.exists():
|
|
129
|
+
for json_file in checkov_dir.rglob("results_json.json"):
|
|
130
|
+
try:
|
|
131
|
+
with open(json_file, "r") as f:
|
|
132
|
+
data = json.load(f)
|
|
133
|
+
results = data.get("results", {})
|
|
134
|
+
# Handle both formats
|
|
135
|
+
failed_checks = results.get("failed_checks", [])
|
|
136
|
+
if not failed_checks:
|
|
137
|
+
for check_type_data in results.values():
|
|
138
|
+
if isinstance(check_type_data, dict):
|
|
139
|
+
failed_checks.extend(check_type_data.get("failed_checks", []))
|
|
140
|
+
for check in failed_checks:
|
|
141
|
+
all_findings.append({
|
|
142
|
+
"tool": "checkov",
|
|
143
|
+
"id": check.get("check_id", ""),
|
|
144
|
+
"severity": check.get("severity", "MEDIUM") or "MEDIUM",
|
|
145
|
+
"title": check.get("check_result", {}).get("name", check.get("name", "")),
|
|
146
|
+
"name": check.get("name", ""),
|
|
147
|
+
"file": check.get("file_path", ""),
|
|
148
|
+
"line": check.get("file_line_range", [0, 0])[0],
|
|
149
|
+
"resource": check.get("resource", ""),
|
|
150
|
+
"guideline": check.get("guideline", ""),
|
|
151
|
+
})
|
|
152
|
+
except (json.JSONDecodeError, KeyError):
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
# Parse OPA/Conftest JSON reports
|
|
156
|
+
opa_report = self.reports_dir / "opa" / "conftest_results.json"
|
|
157
|
+
if opa_report.exists():
|
|
158
|
+
try:
|
|
159
|
+
with open(opa_report, "r") as f:
|
|
160
|
+
data = json.load(f)
|
|
161
|
+
if isinstance(data, list):
|
|
162
|
+
for result in data:
|
|
163
|
+
filename = result.get("filename", "")
|
|
164
|
+
for failure in result.get("failures", []):
|
|
165
|
+
all_findings.append({
|
|
166
|
+
"tool": "opa",
|
|
167
|
+
"id": "OPA",
|
|
168
|
+
"severity": "HIGH",
|
|
169
|
+
"title": failure.get("msg", ""),
|
|
170
|
+
"name": failure.get("msg", ""),
|
|
171
|
+
"file": filename,
|
|
172
|
+
"line": 0,
|
|
173
|
+
"resource": "",
|
|
174
|
+
"guideline": "",
|
|
175
|
+
})
|
|
176
|
+
for warning in result.get("warnings", []):
|
|
177
|
+
all_findings.append({
|
|
178
|
+
"tool": "opa",
|
|
179
|
+
"id": "OPA",
|
|
180
|
+
"severity": "MEDIUM",
|
|
181
|
+
"title": warning.get("msg", ""),
|
|
182
|
+
"name": warning.get("msg", ""),
|
|
183
|
+
"file": filename,
|
|
184
|
+
"line": 0,
|
|
185
|
+
"resource": "",
|
|
186
|
+
"guideline": "",
|
|
187
|
+
})
|
|
188
|
+
except (json.JSONDecodeError, KeyError):
|
|
189
|
+
pass
|
|
190
|
+
|
|
191
|
+
# Parse Trivy JSON reports
|
|
192
|
+
trivy_dir = self.reports_dir / "trivy"
|
|
193
|
+
if trivy_dir.exists():
|
|
194
|
+
for json_file in trivy_dir.rglob("results.json"):
|
|
195
|
+
try:
|
|
196
|
+
with open(json_file, "r") as f:
|
|
197
|
+
data = json.load(f)
|
|
198
|
+
for result in data.get("Results", []):
|
|
199
|
+
for misconf in result.get("Misconfigurations", []):
|
|
200
|
+
all_findings.append({
|
|
201
|
+
"tool": "trivy",
|
|
202
|
+
"id": misconf.get("ID", ""),
|
|
203
|
+
"severity": misconf.get("Severity", "MEDIUM"),
|
|
204
|
+
"title": misconf.get("Title", ""),
|
|
205
|
+
"name": misconf.get("Message", misconf.get("Title", "")),
|
|
206
|
+
"file": result.get("Target", ""),
|
|
207
|
+
"line": 0,
|
|
208
|
+
"resource": misconf.get("CauseMetadata", {}).get("Resource", ""),
|
|
209
|
+
"guideline": misconf.get("PrimaryURL", ""),
|
|
210
|
+
})
|
|
211
|
+
except (json.JSONDecodeError, KeyError):
|
|
212
|
+
continue
|
|
213
|
+
|
|
214
|
+
# Parse KICS JSON reports
|
|
215
|
+
kics_report = self.reports_dir / "kics-results.json"
|
|
216
|
+
if kics_report.exists():
|
|
217
|
+
try:
|
|
218
|
+
with open(kics_report, "r") as f:
|
|
219
|
+
data = json.load(f)
|
|
220
|
+
for query in data.get("queries", []):
|
|
221
|
+
sev = (query.get("severity") or "MEDIUM").upper()
|
|
222
|
+
for file_entry in query.get("files", []):
|
|
223
|
+
all_findings.append({
|
|
224
|
+
"tool": "kics",
|
|
225
|
+
"id": query.get("query_id", "")[:12],
|
|
226
|
+
"severity": sev,
|
|
227
|
+
"title": query.get("query_name", ""),
|
|
228
|
+
"name": query.get("query_name", ""),
|
|
229
|
+
"file": file_entry.get("file_name", ""),
|
|
230
|
+
"line": file_entry.get("line", 0),
|
|
231
|
+
"resource": file_entry.get("resource_type", ""),
|
|
232
|
+
"guideline": query.get("query_url", ""),
|
|
233
|
+
})
|
|
234
|
+
except (json.JSONDecodeError, KeyError):
|
|
235
|
+
pass
|
|
236
|
+
|
|
237
|
+
self._cache_data(cache_key, all_findings)
|
|
238
|
+
else:
|
|
239
|
+
all_findings = self.cache[cache_key]["data"]
|
|
240
|
+
|
|
241
|
+
# Apply filters
|
|
242
|
+
filtered = all_findings
|
|
243
|
+
if tool:
|
|
244
|
+
filtered = [f for f in filtered if f["tool"] == tool]
|
|
245
|
+
if severity:
|
|
246
|
+
filtered = [f for f in filtered if f["severity"].upper() == severity.upper()]
|
|
247
|
+
if search:
|
|
248
|
+
search_lower = search.lower()
|
|
249
|
+
filtered = [f for f in filtered if (
|
|
250
|
+
search_lower in f.get("title", "").lower() or
|
|
251
|
+
search_lower in f.get("file", "").lower() or
|
|
252
|
+
search_lower in f.get("resource", "").lower() or
|
|
253
|
+
search_lower in f.get("id", "").lower()
|
|
254
|
+
)]
|
|
255
|
+
|
|
256
|
+
# Severity counts for the filtered set
|
|
257
|
+
sev_counts = {}
|
|
258
|
+
for f in filtered:
|
|
259
|
+
s = f.get("severity", "UNKNOWN").upper()
|
|
260
|
+
sev_counts[s] = sev_counts.get(s, 0) + 1
|
|
261
|
+
|
|
262
|
+
# Tool counts
|
|
263
|
+
tool_counts = {}
|
|
264
|
+
for f in filtered:
|
|
265
|
+
t = f.get("tool", "unknown")
|
|
266
|
+
tool_counts[t] = tool_counts.get(t, 0) + 1
|
|
267
|
+
|
|
268
|
+
total = len(filtered)
|
|
269
|
+
page = filtered[offset:offset + limit]
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
"findings": page,
|
|
273
|
+
"total": total,
|
|
274
|
+
"offset": offset,
|
|
275
|
+
"limit": limit,
|
|
276
|
+
"severity_counts": sev_counts,
|
|
277
|
+
"tool_counts": tool_counts,
|
|
278
|
+
}
|
|
105
279
|
|
|
106
280
|
def get_cost_analysis(self) -> Dict[str, Any]:
|
|
107
281
|
"""Load from terraform plan files or cost analysis cache."""
|