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