cycode 3.1.1.dev6__tar.gz → 3.2.1.dev1__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.
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/PKG-INFO +2 -1
- cycode-3.2.1.dev1/cycode/__init__.py +1 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/mcp/mcp_command.py +94 -46
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/pyproject.toml +2 -1
- cycode-3.1.1.dev6/cycode/__init__.py +0 -1
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/LICENCE +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/README.md +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/__main__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/app.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/auth/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/auth/auth_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/auth/auth_common.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/auth/auth_manager.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/auth/models.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/configure/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/configure/configure_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/configure/consts.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/configure/messages.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/configure/prompts.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ignore/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ignore/ignore_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/mcp/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/report_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/common.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/aggregation_report.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/code_scanner.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/commit_range_scanner.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/detection_excluder.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/path/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/path/path_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/repository/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/scan_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/scan_parameters.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/scan_result.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/status/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/status/get_cli_status.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/status/models.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/status/status_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/status/version_command.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/cli_types.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/config.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/console.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/consts.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/custom_exceptions.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/handle_errors.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/commit_range_documents.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/file_excluder.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/iac/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/models/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/path_documents.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/repository_documents.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/sca_file_collector.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/walk_ignore.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/zip_documents.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/logger.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/main.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/models.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/console_printer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/json_printer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/printer_base.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/rich_printer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/tables/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/tables/table.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/tables/table_models.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/tables/table_printer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/tables/table_printer_base.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/text_printer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/detection_data.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/detection_ordering/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/rich_helpers.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/user_settings/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/user_settings/base_file_manager.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/user_settings/config_file_manager.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/user_settings/configuration_manager.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/user_settings/credentials_manager.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/user_settings/jwt_creator.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/enum_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/get_api_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/git_proxy.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/ignore_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/jwt_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/path_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/progress_bar.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/scan_batch.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/scan_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/sentry.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/shell_executor.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/string_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/task_timer.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/version_checker.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/utils/yaml_utils.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/config.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/__init__.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/auth_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/client_creator.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/config.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/config_dev.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/cycode_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/cycode_client_base.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/cycode_dev_based_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/cycode_token_based_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/headers.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/logger.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/models.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/report_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/scan_client.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cyclient/scan_config_base.py +0 -0
- {cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/logger.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cycode
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.1.dev1
|
|
4
4
|
Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
|
|
5
5
|
Home-page: https://github.com/cycodehq/cycode-cli
|
|
6
6
|
License: MIT
|
|
@@ -29,6 +29,7 @@ Requires-Dist: gitpython (>=3.1.30,<3.2.0)
|
|
|
29
29
|
Requires-Dist: marshmallow (>=3.15.0,<3.23.0)
|
|
30
30
|
Requires-Dist: mcp (>=1.9.3,<2.0.0) ; python_version >= "3.10"
|
|
31
31
|
Requires-Dist: patch-ng (==1.18.1)
|
|
32
|
+
Requires-Dist: pathvalidate (>=3.3.1,<4.0.0)
|
|
32
33
|
Requires-Dist: pydantic (>=2.11.5,<3.0.0)
|
|
33
34
|
Requires-Dist: pyjwt (>=2.8.0,<3.0)
|
|
34
35
|
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '3.2.1.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -2,13 +2,14 @@ import asyncio
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
|
+
import shutil
|
|
5
6
|
import sys
|
|
6
7
|
import tempfile
|
|
7
8
|
import uuid
|
|
8
|
-
from pathlib import Path
|
|
9
9
|
from typing import Annotated, Any
|
|
10
10
|
|
|
11
11
|
import typer
|
|
12
|
+
from pathvalidate import sanitize_filepath
|
|
12
13
|
from pydantic import Field
|
|
13
14
|
|
|
14
15
|
from cycode.cli.cli_types import McpTransportOption, ScanTypeOption
|
|
@@ -26,7 +27,7 @@ except ImportError:
|
|
|
26
27
|
|
|
27
28
|
_logger = get_logger('Cycode MCP')
|
|
28
29
|
|
|
29
|
-
_DEFAULT_RUN_COMMAND_TIMEOUT =
|
|
30
|
+
_DEFAULT_RUN_COMMAND_TIMEOUT = 10 * 60
|
|
30
31
|
|
|
31
32
|
_FILES_TOOL_FIELD = Field(description='Files to scan, mapping file paths to their content')
|
|
32
33
|
|
|
@@ -91,48 +92,76 @@ async def _run_cycode_command(*args: str, timeout: int = _DEFAULT_RUN_COMMAND_TI
|
|
|
91
92
|
return {'error': f'Failed to run command: {e!s}'}
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
def
|
|
95
|
-
"""
|
|
96
|
-
temp_dir = tempfile.mkdtemp(prefix='cycode_mcp_')
|
|
97
|
-
temp_files = []
|
|
95
|
+
def _sanitize_file_path(file_path: str) -> str:
|
|
96
|
+
"""Sanitize file path to prevent path traversal and other security issues.
|
|
98
97
|
|
|
99
|
-
|
|
98
|
+
Args:
|
|
99
|
+
file_path: The file path to sanitize
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
temp_file_path = os.path.join(temp_dir, safe_filename)
|
|
101
|
+
Returns:
|
|
102
|
+
Sanitized file path safe for use in temporary directory
|
|
104
103
|
|
|
105
|
-
|
|
104
|
+
Raises:
|
|
105
|
+
ValueError: If the path is invalid or potentially dangerous
|
|
106
|
+
"""
|
|
107
|
+
if not file_path or not isinstance(file_path, str):
|
|
108
|
+
raise ValueError('File path must be a non-empty string')
|
|
106
109
|
|
|
107
|
-
|
|
108
|
-
with open(temp_file_path, 'w', encoding='UTF-8') as f:
|
|
109
|
-
f.write(content)
|
|
110
|
+
return sanitize_filepath(file_path, platform='auto', validate_after_sanitize=True)
|
|
110
111
|
|
|
111
|
-
temp_files.append(temp_file_path)
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
class _TempFilesManager:
|
|
114
|
+
"""Context manager for creating and cleaning up temporary files.
|
|
114
115
|
|
|
116
|
+
Creates a temporary directory structure that preserves original file paths
|
|
117
|
+
inside a call_id as a suffix. Automatically cleans up all files and directories
|
|
118
|
+
when exiting the context.
|
|
119
|
+
"""
|
|
115
120
|
|
|
116
|
-
def
|
|
117
|
-
|
|
121
|
+
def __init__(self, files_content: dict[str, str], call_id: str) -> None:
|
|
122
|
+
self.files_content = files_content
|
|
123
|
+
self.call_id = call_id
|
|
124
|
+
self.temp_base_dir = None
|
|
125
|
+
self.temp_files = []
|
|
118
126
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
def __enter__(self) -> list[str]:
|
|
128
|
+
self.temp_base_dir = tempfile.mkdtemp(prefix='cycode_mcp_', suffix=self.call_id)
|
|
129
|
+
_logger.debug('Creating temporary files in directory: %s', self.temp_base_dir)
|
|
130
|
+
|
|
131
|
+
for file_path, content in self.files_content.items():
|
|
132
|
+
try:
|
|
133
|
+
sanitized_path = _sanitize_file_path(file_path)
|
|
134
|
+
temp_file_path = os.path.join(self.temp_base_dir, sanitized_path)
|
|
135
|
+
|
|
136
|
+
# Ensure the normalized path is still within our temp directory
|
|
137
|
+
normalized_temp_path = os.path.normpath(temp_file_path)
|
|
138
|
+
normalized_base_path = os.path.normpath(self.temp_base_dir)
|
|
139
|
+
if not normalized_temp_path.startswith(normalized_base_path + os.sep):
|
|
140
|
+
raise ValueError(f'Path escapes temporary directory: {file_path}')
|
|
141
|
+
|
|
142
|
+
os.makedirs(os.path.dirname(temp_file_path), exist_ok=True)
|
|
143
|
+
|
|
144
|
+
_logger.debug('Creating temp file: %s (from: %s)', temp_file_path, file_path)
|
|
145
|
+
with open(temp_file_path, 'w', encoding='UTF-8') as f:
|
|
146
|
+
f.write(content)
|
|
147
|
+
|
|
148
|
+
self.temp_files.append(temp_file_path)
|
|
149
|
+
except ValueError as e:
|
|
150
|
+
_logger.error('Invalid file path rejected: %s - %s', file_path, str(e))
|
|
151
|
+
continue
|
|
152
|
+
except Exception as e:
|
|
153
|
+
_logger.error('Failed to create temp file for %s: %s', file_path, str(e))
|
|
154
|
+
continue
|
|
155
|
+
|
|
156
|
+
if not self.temp_files:
|
|
157
|
+
raise ValueError('No valid files provided after sanitization')
|
|
158
|
+
|
|
159
|
+
return self.temp_files
|
|
160
|
+
|
|
161
|
+
def __exit__(self, *_) -> None:
|
|
162
|
+
if self.temp_base_dir and os.path.exists(self.temp_base_dir):
|
|
163
|
+
_logger.debug('Removing temp directory recursively: %s', self.temp_base_dir)
|
|
164
|
+
shutil.rmtree(self.temp_base_dir, ignore_errors=True)
|
|
136
165
|
|
|
137
166
|
|
|
138
167
|
async def _run_cycode_scan(scan_type: ScanTypeOption, temp_files: list[str]) -> dict[str, Any]:
|
|
@@ -153,21 +182,36 @@ async def _cycode_scan_tool(scan_type: ScanTypeOption, files: dict[str, str] = _
|
|
|
153
182
|
_logger.error('No files provided for scan')
|
|
154
183
|
return json.dumps({'error': 'No files provided'})
|
|
155
184
|
|
|
156
|
-
temp_files = _create_temp_files(files)
|
|
157
|
-
|
|
158
185
|
try:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
186
|
+
with _TempFilesManager(files, _tool_call_id) as temp_files:
|
|
187
|
+
original_count = len(files)
|
|
188
|
+
processed_count = len(temp_files)
|
|
189
|
+
|
|
190
|
+
if processed_count < original_count:
|
|
191
|
+
_logger.warning(
|
|
192
|
+
'Some files were rejected during sanitization, %s',
|
|
193
|
+
{
|
|
194
|
+
'scan_type': scan_type,
|
|
195
|
+
'original_count': original_count,
|
|
196
|
+
'processed_count': processed_count,
|
|
197
|
+
'call_id': _tool_call_id,
|
|
198
|
+
},
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
_logger.info(
|
|
202
|
+
'Running Cycode scan, %s',
|
|
203
|
+
{'scan_type': scan_type, 'files_count': processed_count, 'call_id': _tool_call_id},
|
|
204
|
+
)
|
|
205
|
+
result = await _run_cycode_scan(scan_type, temp_files)
|
|
206
|
+
|
|
207
|
+
_logger.info('Scan completed, %s', {'scan_type': scan_type, 'call_id': _tool_call_id})
|
|
208
|
+
return json.dumps(result, indent=2)
|
|
209
|
+
except ValueError as e:
|
|
210
|
+
_logger.error('Invalid input files, %s', {'scan_type': scan_type, 'call_id': _tool_call_id, 'error': str(e)})
|
|
211
|
+
return json.dumps({'error': f'Invalid input files: {e!s}'}, indent=2)
|
|
166
212
|
except Exception as e:
|
|
167
213
|
_logger.error('Scan failed, %s', {'scan_type': scan_type, 'call_id': _tool_call_id, 'error': str(e)})
|
|
168
214
|
return json.dumps({'error': f'Scan failed: {e!s}'}, indent=2)
|
|
169
|
-
finally:
|
|
170
|
-
_cleanup_temp_files(temp_files)
|
|
171
215
|
|
|
172
216
|
|
|
173
217
|
async def cycode_secret_scan(files: dict[str, str] = _FILES_TOOL_FIELD) -> str:
|
|
@@ -197,6 +241,10 @@ async def cycode_sca_scan(files: dict[str, str] = _FILES_TOOL_FIELD) -> str:
|
|
|
197
241
|
- verify software supply chain security
|
|
198
242
|
- review package.json, requirements.txt, pom.xml and other dependency files
|
|
199
243
|
|
|
244
|
+
Important:
|
|
245
|
+
You must also include lock files (like package-lock.json, Pipfile.lock, etc.) to get accurate results.
|
|
246
|
+
You must provide manifest and lock files together.
|
|
247
|
+
|
|
200
248
|
Args:
|
|
201
249
|
files: Dictionary mapping file paths to their content
|
|
202
250
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "cycode"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.2.1.dev1" # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
4
4
|
description = "Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning."
|
|
5
5
|
keywords=["secret-scan", "cycode", "devops", "token", "secret", "security", "cycode", "code"]
|
|
6
6
|
authors = ["Cycode <support@cycode.com>"]
|
|
@@ -44,6 +44,7 @@ typer = "^0.15.3"
|
|
|
44
44
|
tenacity = ">=9.0.0,<9.1.0"
|
|
45
45
|
mcp = { version = ">=1.9.3,<2.0.0", markers = "python_version >= '3.10'" }
|
|
46
46
|
pydantic = ">=2.11.5,<3.0.0"
|
|
47
|
+
pathvalidate = ">=3.3.1,<4.0.0"
|
|
47
48
|
|
|
48
49
|
[tool.poetry.group.test.dependencies]
|
|
49
50
|
mock = ">=4.0.3,<4.1.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '3.1.1.dev6' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/ai_remediation/ai_remediation_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/report/sbom/repository_url/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py
RENAMED
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/apps/scan/repository/repository_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/exceptions/handle_ai_remediation_errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/commit_range_documents.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/iac/tf_content_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/base_restore_dependencies.py
RENAMED
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/files_collector/sca/sca_file_collector.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/detection_ordering/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cycode-3.1.1.dev6 → cycode-3.2.1.dev1}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|