cycode 3.24.3.dev1__tar.gz → 3.24.3.dev3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/PKG-INFO +38 -7
  2. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/README.md +37 -6
  3. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/__init__.py +1 -1
  4. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/__init__.py +2 -1
  5. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/commit_range_scanner.py +70 -48
  6. cycode-3.24.3.dev3/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +100 -0
  7. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/scan_result.py +2 -2
  8. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/consts.py +20 -0
  9. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/custom_exceptions.py +19 -0
  10. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/handle_scan_errors.py +10 -0
  11. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/commit_range_documents.py +87 -13
  12. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/sca_file_collector.py +11 -4
  13. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/path_utils.py +26 -9
  14. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/pyproject.toml +1 -1
  15. cycode-3.24.3.dev1/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -18
  16. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/LICENCE +0 -0
  17. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/__main__.py +0 -0
  18. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/__init__.py +0 -0
  19. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/app.py +0 -0
  20. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/__init__.py +0 -0
  21. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/activation_manager.py +0 -0
  22. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/__init__.py +0 -0
  23. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/command_utils.py +0 -0
  24. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/consts.py +0 -0
  25. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/hooks_manager.py +0 -0
  26. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/__init__.py +0 -0
  27. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/_plugin_utils.py +0 -0
  28. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/_skill_utils.py +0 -0
  29. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/base.py +0 -0
  30. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/claude_code.py +0 -0
  31. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/codex.py +0 -0
  32. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/copilot.py +0 -0
  33. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/ides/cursor.py +0 -0
  34. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/install_command.py +0 -0
  35. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/__init__.py +0 -0
  36. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/consts.py +0 -0
  37. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/detach.py +0 -0
  38. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/guardrail_config.py +0 -0
  39. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/handlers.py +0 -0
  40. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/payload.py +0 -0
  41. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/policy.py +0 -0
  42. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/scan_command.py +0 -0
  43. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/types.py +0 -0
  44. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/scan/utils.py +0 -0
  45. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/session_start_command.py +0 -0
  46. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/status_command.py +0 -0
  47. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_guardrails/uninstall_command.py +0 -0
  48. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
  49. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
  50. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
  51. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
  52. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/api/__init__.py +0 -0
  53. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/api/api_command.py +0 -0
  54. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/api/openapi_spec.py +0 -0
  55. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/auth/__init__.py +0 -0
  56. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/auth/auth_command.py +0 -0
  57. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/auth/auth_common.py +0 -0
  58. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/auth/auth_manager.py +0 -0
  59. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/auth/models.py +0 -0
  60. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/configure/__init__.py +0 -0
  61. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/configure/configure_command.py +0 -0
  62. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/configure/consts.py +0 -0
  63. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/configure/messages.py +0 -0
  64. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/configure/prompts.py +0 -0
  65. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ignore/__init__.py +0 -0
  66. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/ignore/ignore_command.py +0 -0
  67. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/mcp/__init__.py +0 -0
  68. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/mcp/mcp_command.py +0 -0
  69. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/__init__.py +0 -0
  70. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/report_command.py +0 -0
  71. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/__init__.py +0 -0
  72. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/common.py +0 -0
  73. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
  74. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
  75. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
  76. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
  77. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
  78. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
  79. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report_import/__init__.py +0 -0
  80. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report_import/report_import_command.py +0 -0
  81. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report_import/sbom/__init__.py +0 -0
  82. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/report_import/sbom/sbom_command.py +0 -0
  83. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/sca_options.py +0 -0
  84. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/aggregation_report.py +0 -0
  85. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/code_scanner.py +0 -0
  86. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
  87. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
  88. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/detection_excluder.py +0 -0
  89. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/path/__init__.py +0 -0
  90. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/path/path_command.py +0 -0
  91. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
  92. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/pre_push/__init__.py +0 -0
  93. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/pre_push/pre_push_command.py +0 -0
  94. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
  95. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
  96. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
  97. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/repository/__init__.py +0 -0
  98. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
  99. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
  100. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
  101. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
  102. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/scan_command.py +0 -0
  103. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/scan/scan_parameters.py +0 -0
  104. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/status/__init__.py +0 -0
  105. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/status/get_cli_status.py +0 -0
  106. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/status/models.py +0 -0
  107. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/status/status_command.py +0 -0
  108. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/apps/status/version_command.py +0 -0
  109. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/cli_types.py +0 -0
  110. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/config.py +0 -0
  111. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/console.py +0 -0
  112. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/__init__.py +0 -0
  113. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
  114. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
  115. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/handle_errors.py +0 -0
  116. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
  117. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/__init__.py +0 -0
  118. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/documents_walk_ignore.py +0 -0
  119. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/file_excluder.py +0 -0
  120. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/iac/__init__.py +0 -0
  121. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
  122. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/models/__init__.py +0 -0
  123. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
  124. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/path_documents.py +0 -0
  125. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/repository_documents.py +0 -0
  126. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/__init__.py +0 -0
  127. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
  128. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
  129. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
  130. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
  131. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
  132. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
  133. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
  134. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/npm/restore_bun_dependencies.py +0 -0
  135. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/npm/restore_deno_dependencies.py +0 -0
  136. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
  137. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/npm/restore_pnpm_dependencies.py +0 -0
  138. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/npm/restore_yarn_dependencies.py +0 -0
  139. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
  140. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
  141. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/php/__init__.py +0 -0
  142. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/php/restore_composer_dependencies.py +0 -0
  143. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/python/__init__.py +0 -0
  144. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/python/restore_pip_dependencies.py +0 -0
  145. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/python/restore_pipenv_dependencies.py +0 -0
  146. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/python/restore_poetry_dependencies.py +0 -0
  147. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/python/restore_uv_dependencies.py +0 -0
  148. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
  149. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
  150. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
  151. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
  152. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/walk_ignore.py +0 -0
  153. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/files_collector/zip_documents.py +0 -0
  154. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/logger.py +0 -0
  155. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/main.py +0 -0
  156. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/models.py +0 -0
  157. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/__init__.py +0 -0
  158. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/console_printer.py +0 -0
  159. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/json_printer.py +0 -0
  160. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/printer_base.py +0 -0
  161. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/rich_printer.py +0 -0
  162. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/tables/__init__.py +0 -0
  163. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
  164. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/tables/table.py +0 -0
  165. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/tables/table_models.py +0 -0
  166. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/tables/table_printer.py +0 -0
  167. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/tables/table_printer_base.py +0 -0
  168. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/text_printer.py +0 -0
  169. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/__init__.py +0 -0
  170. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
  171. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/detection_data.py +0 -0
  172. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/detection_ordering/__init__.py +0 -0
  173. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
  174. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
  175. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/rich_helpers.py +0 -0
  176. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/sca_ossf.py +0 -0
  177. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/printers/utils/sca_policy_details.py +0 -0
  178. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/user_settings/__init__.py +0 -0
  179. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/user_settings/base_file_manager.py +0 -0
  180. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/user_settings/config_file_manager.py +0 -0
  181. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/user_settings/configuration_manager.py +0 -0
  182. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/user_settings/credentials_manager.py +0 -0
  183. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/user_settings/jwt_creator.py +0 -0
  184. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/__init__.py +0 -0
  185. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/binary_utils.py +0 -0
  186. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/enum_utils.py +0 -0
  187. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/get_api_client.py +0 -0
  188. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/git_proxy.py +0 -0
  189. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/host_info.py +0 -0
  190. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/ignore_utils.py +0 -0
  191. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/jwt_utils.py +0 -0
  192. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/progress_bar.py +0 -0
  193. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/scan_batch.py +0 -0
  194. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/scan_utils.py +0 -0
  195. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/shell_executor.py +0 -0
  196. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/string_utils.py +0 -0
  197. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/task_timer.py +0 -0
  198. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/trust_store.py +0 -0
  199. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/url_utils.py +0 -0
  200. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/version_checker.py +0 -0
  201. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cli/utils/yaml_utils.py +0 -0
  202. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/config.py +0 -0
  203. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/__init__.py +0 -0
  204. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/ai_security_manager_client.py +0 -0
  205. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/ai_security_manager_service_config.py +0 -0
  206. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/auth_client.py +0 -0
  207. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/base_token_auth_client.py +0 -0
  208. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/cli_activation_client.py +0 -0
  209. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/client_creator.py +0 -0
  210. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/config.py +0 -0
  211. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/config_dev.py +0 -0
  212. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/cycode_client.py +0 -0
  213. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/cycode_client_base.py +0 -0
  214. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/cycode_dev_based_client.py +0 -0
  215. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/cycode_oidc_based_client.py +0 -0
  216. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/cycode_token_based_client.py +0 -0
  217. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/headers.py +0 -0
  218. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/import_sbom_client.py +0 -0
  219. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/logger.py +0 -0
  220. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/models.py +0 -0
  221. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/report_client.py +0 -0
  222. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/scan_client.py +0 -0
  223. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/cyclient/scan_config_base.py +0 -0
  224. {cycode-3.24.3.dev1 → cycode-3.24.3.dev3}/cycode/logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.24.3.dev1
3
+ Version: 3.24.3.dev3
4
4
  Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
5
5
  License-Expression: MIT
6
6
  License-File: LICENCE
@@ -94,6 +94,7 @@ This guide walks you through both installation and usage.
94
94
  4. [Commit History Scan](#commit-history-scan)
95
95
  1. [Commit Range Option (Diff Scanning)](#commit-range-option-diff-scanning)
96
96
  5. [Pre-Commit Scan](#pre-commit-scan)
97
+ 1. [Local Diff Scanning (IDE Integrations)](#local-diff-scanning-ide-integrations)
97
98
  6. [Pre-Push Scan](#pre-push-scan)
98
99
  2. [Scan Results](#scan-results)
99
100
  1. [Show/Hide Secrets](#showhide-secrets)
@@ -844,12 +845,12 @@ The Cycode CLI application offers several types of scans so that you can choose
844
845
  | `--maven-settings-file` | For Maven only, allows using a custom [settings.xml](https://maven.apache.org/settings.html) file when scanning for dependencies |
845
846
  | `--help` | Show options for given command. |
846
847
 
847
- | Command | Description |
848
- |----------------------------------------|-----------------------------------------------------------------------|
849
- | [commit-history](#commit-history-scan) | Scan commit history or perform diff scanning between specific commits |
850
- | [path](#path-scan) | Scan the files in the path supplied in the command |
851
- | [pre-commit](#pre-commit-scan) | Use this command to scan the content that was not committed yet |
852
- | [repository](#repository-scan) | Scan git repository including its history |
848
+ | Command | Description |
849
+ |-----------------------------------------|----------------------------------------------------------------------------------------------------|
850
+ | [commit-history](#commit-history-scan) | Scan commit history or perform diff scanning between specific commits |
851
+ | [path](#path-scan) | Scan the files in the path supplied in the command |
852
+ | [pre-commit](#pre-commit-scan) | Scan content that was not committed yet; also supports local diff scanning via flags (IDE-friendly) |
853
+ | [repository](#repository-scan) | Scan git repository including its history |
853
854
 
854
855
  ### Options
855
856
 
@@ -1131,6 +1132,36 @@ After installing the pre-commit hook, you may occasionally wish to skip scanning
1131
1132
  SKIP=cycode git commit -m <your commit message>`
1132
1133
  ```
1133
1134
 
1135
+ The following options are available for use with this command:
1136
+
1137
+ | Option | Description |
1138
+ |-----------------------|---------------------------------------------------------------------------------------------------------------------|
1139
+ | `-b, --base-ref TEXT` | Git ref (commit, branch, or tag) to diff against; defaults to `HEAD`, matching the pre-commit hook behavior |
1140
+ | `--include-unstaged` | Also scan unstaged changes to tracked files, not just what is staged; off by default |
1141
+ | `--path PATH` | Optional path(s) to scope the diff scan to; repeatable; defaults to the entire working directory |
1142
+
1143
+ #### Local Diff Scanning (IDE Integrations)
1144
+
1145
+ `--base-ref` and `--include-unstaged` turn `pre-commit` into a general-purpose **local diff scan**: comparing any commit (default `HEAD`) against your current working directory — including edits that aren't staged yet. This is intended for IDE plugins and other tools that need continuous, real-time feedback as you work, rather than the git hook flow. Combined with `--include-unstaged`, `--path` lets an IDE scope the scan to just the file currently open in the editor.
1146
+
1147
+ > [!NOTE]
1148
+ > Local diff scanning (via these flags) is not available for IaC scans.
1149
+
1150
+ **Scan everything currently changed (staged + unstaged) against the last commit:**
1151
+ ```bash
1152
+ cycode scan pre-commit --include-unstaged
1153
+ ```
1154
+
1155
+ **Scan changes against a specific commit or branch:**
1156
+ ```bash
1157
+ cycode scan pre-commit --include-unstaged --base-ref main
1158
+ ```
1159
+
1160
+ **Scan only a specific file (e.g., the file currently open in your IDE):**
1161
+ ```bash
1162
+ cycode scan pre-commit --include-unstaged --path src/app.py
1163
+ ```
1164
+
1134
1165
  ### Pre-Push Scan
1135
1166
 
1136
1167
  A pre-push scan automatically identifies any issues before you push changes to the remote repository. This hook runs on the client side and scans only the commits that are about to be pushed, making it efficient for catching issues before they reach the remote repository.
@@ -48,6 +48,7 @@ This guide walks you through both installation and usage.
48
48
  4. [Commit History Scan](#commit-history-scan)
49
49
  1. [Commit Range Option (Diff Scanning)](#commit-range-option-diff-scanning)
50
50
  5. [Pre-Commit Scan](#pre-commit-scan)
51
+ 1. [Local Diff Scanning (IDE Integrations)](#local-diff-scanning-ide-integrations)
51
52
  6. [Pre-Push Scan](#pre-push-scan)
52
53
  2. [Scan Results](#scan-results)
53
54
  1. [Show/Hide Secrets](#showhide-secrets)
@@ -798,12 +799,12 @@ The Cycode CLI application offers several types of scans so that you can choose
798
799
  | `--maven-settings-file` | For Maven only, allows using a custom [settings.xml](https://maven.apache.org/settings.html) file when scanning for dependencies |
799
800
  | `--help` | Show options for given command. |
800
801
 
801
- | Command | Description |
802
- |----------------------------------------|-----------------------------------------------------------------------|
803
- | [commit-history](#commit-history-scan) | Scan commit history or perform diff scanning between specific commits |
804
- | [path](#path-scan) | Scan the files in the path supplied in the command |
805
- | [pre-commit](#pre-commit-scan) | Use this command to scan the content that was not committed yet |
806
- | [repository](#repository-scan) | Scan git repository including its history |
802
+ | Command | Description |
803
+ |-----------------------------------------|----------------------------------------------------------------------------------------------------|
804
+ | [commit-history](#commit-history-scan) | Scan commit history or perform diff scanning between specific commits |
805
+ | [path](#path-scan) | Scan the files in the path supplied in the command |
806
+ | [pre-commit](#pre-commit-scan) | Scan content that was not committed yet; also supports local diff scanning via flags (IDE-friendly) |
807
+ | [repository](#repository-scan) | Scan git repository including its history |
807
808
 
808
809
  ### Options
809
810
 
@@ -1085,6 +1086,36 @@ After installing the pre-commit hook, you may occasionally wish to skip scanning
1085
1086
  SKIP=cycode git commit -m <your commit message>`
1086
1087
  ```
1087
1088
 
1089
+ The following options are available for use with this command:
1090
+
1091
+ | Option | Description |
1092
+ |-----------------------|---------------------------------------------------------------------------------------------------------------------|
1093
+ | `-b, --base-ref TEXT` | Git ref (commit, branch, or tag) to diff against; defaults to `HEAD`, matching the pre-commit hook behavior |
1094
+ | `--include-unstaged` | Also scan unstaged changes to tracked files, not just what is staged; off by default |
1095
+ | `--path PATH` | Optional path(s) to scope the diff scan to; repeatable; defaults to the entire working directory |
1096
+
1097
+ #### Local Diff Scanning (IDE Integrations)
1098
+
1099
+ `--base-ref` and `--include-unstaged` turn `pre-commit` into a general-purpose **local diff scan**: comparing any commit (default `HEAD`) against your current working directory — including edits that aren't staged yet. This is intended for IDE plugins and other tools that need continuous, real-time feedback as you work, rather than the git hook flow. Combined with `--include-unstaged`, `--path` lets an IDE scope the scan to just the file currently open in the editor.
1100
+
1101
+ > [!NOTE]
1102
+ > Local diff scanning (via these flags) is not available for IaC scans.
1103
+
1104
+ **Scan everything currently changed (staged + unstaged) against the last commit:**
1105
+ ```bash
1106
+ cycode scan pre-commit --include-unstaged
1107
+ ```
1108
+
1109
+ **Scan changes against a specific commit or branch:**
1110
+ ```bash
1111
+ cycode scan pre-commit --include-unstaged --base-ref main
1112
+ ```
1113
+
1114
+ **Scan only a specific file (e.g., the file currently open in your IDE):**
1115
+ ```bash
1116
+ cycode scan pre-commit --include-unstaged --path src/app.py
1117
+ ```
1118
+
1088
1119
  ### Pre-Push Scan
1089
1120
 
1090
1121
  A pre-push scan automatically identifies any issues before you push changes to the remote repository. This hook runs on the client side and scans only the commits that are about to be pushed, making it efficient for catching issues before they reach the remote repository.
@@ -5,4 +5,4 @@ import time as _time
5
5
  # end-to-end scan duration from the moment the user actually triggered it.
6
6
  _BOOT_WALL: float = _time.time()
7
7
 
8
- __version__ = '3.24.3.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
8
+ __version__ = '3.24.3.dev3' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -28,7 +28,8 @@ app.command(name='commit-history', short_help='Scan commit history or perform di
28
28
  )
29
29
  app.command(
30
30
  name='pre-commit',
31
- short_help='Use this command in pre-commit hook to scan any content that was not committed yet.',
31
+ short_help='Use this command in pre-commit hook to scan any content that was not committed yet. '
32
+ 'Also supports IDE-style local diff scanning via --base-ref/--include-unstaged/--path.',
32
33
  rich_help_panel=_AUTOMATION_COMMANDS_RICH_HELP_PANEL,
33
34
  )(pre_commit_command)
34
35
  app.command(
@@ -24,10 +24,7 @@ from cycode.cli.exceptions.handle_scan_errors import handle_scan_exception
24
24
  from cycode.cli.files_collector.commit_range_documents import (
25
25
  collect_commit_range_diff_documents,
26
26
  get_commit_range_modified_documents,
27
- get_diff_file_content,
28
- get_diff_file_path,
29
27
  get_pre_commit_modified_documents,
30
- get_staged_diff_index,
31
28
  parse_commit_range,
32
29
  )
33
30
  from cycode.cli.files_collector.documents_walk_ignore import filter_documents_with_cycodeignore
@@ -35,12 +32,10 @@ from cycode.cli.files_collector.file_excluder import excluder
35
32
  from cycode.cli.files_collector.models.in_memory_zip import InMemoryZip
36
33
  from cycode.cli.files_collector.sca.sca_file_collector import (
37
34
  perform_sca_pre_commit_range_scan_actions,
38
- perform_sca_pre_hook_range_scan_actions,
35
+ perform_sca_pre_commit_scan_actions,
39
36
  )
40
37
  from cycode.cli.files_collector.zip_documents import zip_documents
41
38
  from cycode.cli.models import Document
42
- from cycode.cli.utils.git_proxy import git_proxy
43
- from cycode.cli.utils.path_utils import get_path_by_os
44
39
  from cycode.cli.utils.progress_bar import ScanProgressBarSection
45
40
  from cycode.cli.utils.scan_utils import (
46
41
  generate_unique_scan_id,
@@ -329,84 +324,103 @@ def scan_commit_range(ctx: typer.Context, repo_path: str, commit_range: str, **k
329
324
  _SCAN_TYPE_TO_COMMIT_RANGE_HANDLER[scan_type](ctx, repo_path, commit_range, **kwargs)
330
325
 
331
326
 
332
- def _scan_sca_pre_commit(ctx: typer.Context, repo_path: str) -> None:
333
- scan_parameters = get_scan_parameters(ctx)
327
+ def _scan_sca_pre_commit(
328
+ ctx: typer.Context,
329
+ repo_path: str,
330
+ base_ref: str = consts.GIT_HEAD_COMMIT_REV,
331
+ include_unstaged: bool = False,
332
+ paths: Optional[list[str]] = None,
333
+ ) -> None:
334
+ scan_parameters = get_scan_parameters(ctx, (repo_path,))
334
335
 
335
- git_head_documents, pre_committed_documents, _ = get_pre_commit_modified_documents(
336
+ from_ref_documents, working_copy_documents, _diff_documents = get_pre_commit_modified_documents(
336
337
  progress_bar=ctx.obj['progress_bar'],
337
338
  progress_bar_section=ScanProgressBarSection.PREPARE_LOCAL_FILES,
338
339
  repo_path=repo_path,
340
+ base_ref=base_ref,
341
+ include_unstaged=include_unstaged,
342
+ paths=paths,
339
343
  )
340
344
 
341
- git_head_documents = excluder.exclude_irrelevant_documents_to_scan(consts.SCA_SCAN_TYPE, git_head_documents)
342
- pre_committed_documents = excluder.exclude_irrelevant_documents_to_scan(
343
- consts.SCA_SCAN_TYPE, pre_committed_documents
344
- )
345
+ from_ref_documents = excluder.exclude_irrelevant_documents_to_scan(consts.SCA_SCAN_TYPE, from_ref_documents)
346
+ working_copy_documents = excluder.exclude_irrelevant_documents_to_scan(consts.SCA_SCAN_TYPE, working_copy_documents)
345
347
 
346
348
  is_cycodeignore_allowed = is_cycodeignore_allowed_by_scan_config(ctx)
347
- git_head_documents = filter_documents_with_cycodeignore(git_head_documents, repo_path, is_cycodeignore_allowed)
348
- pre_committed_documents = filter_documents_with_cycodeignore(
349
- pre_committed_documents, repo_path, is_cycodeignore_allowed
349
+ from_ref_documents = filter_documents_with_cycodeignore(from_ref_documents, repo_path, is_cycodeignore_allowed)
350
+ working_copy_documents = filter_documents_with_cycodeignore(
351
+ working_copy_documents, repo_path, is_cycodeignore_allowed
350
352
  )
351
353
 
352
- perform_sca_pre_hook_range_scan_actions(repo_path, git_head_documents, pre_committed_documents)
354
+ perform_sca_pre_commit_scan_actions(repo_path, from_ref_documents, base_ref, working_copy_documents)
353
355
 
354
356
  _scan_commit_range_documents(
355
357
  ctx,
356
- git_head_documents,
357
- pre_committed_documents,
358
+ from_ref_documents,
359
+ working_copy_documents,
358
360
  scan_parameters,
359
361
  configuration_manager.get_sca_pre_commit_timeout_in_seconds(),
360
362
  )
361
363
 
362
364
 
363
- def _scan_secret_pre_commit(ctx: typer.Context, repo_path: str) -> None:
364
- progress_bar = ctx.obj['progress_bar']
365
- repo = git_proxy.get_repo(repo_path)
366
- _, diff_index = get_staged_diff_index(repo)
367
-
368
- progress_bar.set_section_length(ScanProgressBarSection.PREPARE_LOCAL_FILES, len(diff_index))
369
-
370
- documents_to_scan = []
371
- for diff in diff_index:
372
- progress_bar.update(ScanProgressBarSection.PREPARE_LOCAL_FILES)
373
- documents_to_scan.append(
374
- Document(
375
- get_path_by_os(get_diff_file_path(diff, repo=repo)),
376
- get_diff_file_content(diff),
377
- is_git_diff_format=True,
378
- )
379
- )
365
+ def _scan_secret_pre_commit(
366
+ ctx: typer.Context,
367
+ repo_path: str,
368
+ base_ref: str = consts.GIT_HEAD_COMMIT_REV,
369
+ include_unstaged: bool = False,
370
+ paths: Optional[list[str]] = None,
371
+ ) -> None:
372
+ # collect_file_contents=False: the secret scan only ever uses diff_documents below, so skip
373
+ # building from_ref_documents/working_copy_documents (a disk read per changed file it would
374
+ # otherwise discard immediately).
375
+ _from_ref_documents, _working_copy_documents, diff_documents = get_pre_commit_modified_documents(
376
+ progress_bar=ctx.obj['progress_bar'],
377
+ progress_bar_section=ScanProgressBarSection.PREPARE_LOCAL_FILES,
378
+ repo_path=repo_path,
379
+ base_ref=base_ref,
380
+ include_unstaged=include_unstaged,
381
+ paths=paths,
382
+ collect_file_contents=False,
383
+ )
380
384
 
381
- documents_to_scan = excluder.exclude_irrelevant_documents_to_scan(consts.SECRET_SCAN_TYPE, documents_to_scan)
385
+ diff_documents = excluder.exclude_irrelevant_documents_to_scan(consts.SECRET_SCAN_TYPE, diff_documents)
382
386
 
383
387
  is_cycodeignore_allowed = is_cycodeignore_allowed_by_scan_config(ctx)
384
- documents_to_scan = filter_documents_with_cycodeignore(documents_to_scan, repo_path, is_cycodeignore_allowed)
388
+ diff_documents = filter_documents_with_cycodeignore(diff_documents, repo_path, is_cycodeignore_allowed)
385
389
 
386
- scan_documents(ctx, documents_to_scan, get_scan_parameters(ctx), is_git_diff=True)
390
+ scan_documents(ctx, diff_documents, get_scan_parameters(ctx, (repo_path,)), is_git_diff=True)
387
391
 
388
392
 
389
- def _scan_sast_pre_commit(ctx: typer.Context, repo_path: str, **_) -> None:
393
+ def _scan_sast_pre_commit(
394
+ ctx: typer.Context,
395
+ repo_path: str,
396
+ base_ref: str = consts.GIT_HEAD_COMMIT_REV,
397
+ include_unstaged: bool = False,
398
+ paths: Optional[list[str]] = None,
399
+ **_,
400
+ ) -> None:
390
401
  scan_parameters = get_scan_parameters(ctx, (repo_path,))
391
402
 
392
- _, pre_committed_documents, diff_documents = get_pre_commit_modified_documents(
403
+ _from_ref_documents, working_copy_documents, diff_documents = get_pre_commit_modified_documents(
393
404
  progress_bar=ctx.obj['progress_bar'],
394
405
  progress_bar_section=ScanProgressBarSection.PREPARE_LOCAL_FILES,
395
406
  repo_path=repo_path,
407
+ base_ref=base_ref,
408
+ include_unstaged=include_unstaged,
409
+ paths=paths,
396
410
  )
397
411
 
398
- pre_committed_documents = excluder.exclude_irrelevant_documents_to_scan(
399
- consts.SAST_SCAN_TYPE, pre_committed_documents
412
+ working_copy_documents = excluder.exclude_irrelevant_documents_to_scan(
413
+ consts.SAST_SCAN_TYPE, working_copy_documents
400
414
  )
401
415
  diff_documents = excluder.exclude_irrelevant_documents_to_scan(consts.SAST_SCAN_TYPE, diff_documents)
402
416
 
403
417
  is_cycodeignore_allowed = is_cycodeignore_allowed_by_scan_config(ctx)
404
- pre_committed_documents = filter_documents_with_cycodeignore(
405
- pre_committed_documents, repo_path, is_cycodeignore_allowed
418
+ working_copy_documents = filter_documents_with_cycodeignore(
419
+ working_copy_documents, repo_path, is_cycodeignore_allowed
406
420
  )
407
421
  diff_documents = filter_documents_with_cycodeignore(diff_documents, repo_path, is_cycodeignore_allowed)
408
422
 
409
- _scan_commit_range_documents(ctx, pre_committed_documents, diff_documents, scan_parameters=scan_parameters)
423
+ _scan_commit_range_documents(ctx, working_copy_documents, diff_documents, scan_parameters=scan_parameters)
410
424
 
411
425
 
412
426
  _SCAN_TYPE_TO_PRE_COMMIT_HANDLER = {
@@ -416,10 +430,18 @@ _SCAN_TYPE_TO_PRE_COMMIT_HANDLER = {
416
430
  }
417
431
 
418
432
 
419
- def scan_pre_commit(ctx: typer.Context, repo_path: str) -> None:
433
+ def scan_pre_commit(
434
+ ctx: typer.Context,
435
+ repo_path: str,
436
+ base_ref: str = consts.GIT_HEAD_COMMIT_REV,
437
+ include_unstaged: bool = False,
438
+ paths: Optional[list[str]] = None,
439
+ ) -> None:
420
440
  scan_type = ctx.obj['scan_type']
421
441
  if scan_type not in _SCAN_TYPE_TO_PRE_COMMIT_HANDLER:
422
442
  raise click.ClickException(f'Pre-commit scanning for {scan_type.upper()} is not supported')
423
443
 
424
- _SCAN_TYPE_TO_PRE_COMMIT_HANDLER[scan_type](ctx, repo_path)
444
+ _SCAN_TYPE_TO_PRE_COMMIT_HANDLER[scan_type](
445
+ ctx, repo_path, base_ref=base_ref, include_unstaged=include_unstaged, paths=paths
446
+ )
425
447
  logger.debug('Pre-commit scan completed successfully')
@@ -0,0 +1,100 @@
1
+ import os
2
+ from pathlib import Path
3
+ from typing import Annotated, Optional
4
+
5
+ import typer
6
+
7
+ from cycode.cli import consts
8
+ from cycode.cli.apps.scan.commit_range_scanner import scan_pre_commit
9
+ from cycode.cli.exceptions.custom_exceptions import ScanPathOutsideRepositoryError, UnresolvedGitRefError
10
+ from cycode.cli.exceptions.handle_scan_errors import handle_scan_exception
11
+ from cycode.cli.logger import logger
12
+ from cycode.cli.utils.git_proxy import git_proxy
13
+
14
+
15
+ def _resolve_repo_root(cwd: str) -> str:
16
+ """Resolve the repository root from `cwd`, which may be any subdirectory of the repo.
17
+
18
+ `git_proxy.get_repo()` requires an exact match (the root or a `.git` dir) unless told to
19
+ search parent directories, so without this, running the command from anywhere but the repo
20
+ root raises a misleading "not a git repository" error. The git pre-commit hook framework
21
+ always invokes from the repo root, so this is a no-op there; it matters for IDE-style
22
+ invocations (--include-unstaged etc.), which may run from any subdirectory.
23
+ """
24
+ repo = git_proxy.get_repo(cwd, search_parent_directories=True)
25
+ return repo.working_tree_dir or cwd
26
+
27
+
28
+ def _validate_base_ref(repo_path: str, base_ref: str) -> None:
29
+ """Raise a clear, user-facing error for an unresolvable `--base-ref`.
30
+
31
+ A repository with no commits at all is a valid state (the diff falls back to comparing
32
+ against the empty tree), so validation is skipped in that case.
33
+ """
34
+ repo = git_proxy.get_repo(repo_path)
35
+
36
+ try:
37
+ repo.rev_parse(consts.GIT_HEAD_COMMIT_REV)
38
+ except Exception as e:
39
+ logger.debug('Repository has no commits yet; skipping --base-ref validation', exc_info=e)
40
+ return
41
+
42
+ try:
43
+ repo.commit(base_ref)
44
+ except Exception as e:
45
+ raise UnresolvedGitRefError(base_ref) from e
46
+
47
+
48
+ def pre_commit_command(
49
+ ctx: typer.Context,
50
+ _: Annotated[Optional[list[str]], typer.Argument(help='Ignored arguments', hidden=True)] = None,
51
+ base_ref: Annotated[
52
+ str,
53
+ typer.Option(
54
+ '--base-ref',
55
+ '-b',
56
+ help='Git ref (commit, branch, or tag) to diff against. Defaults to HEAD, matching the '
57
+ 'pre-commit hook behavior. Combine with --include-unstaged for IDE-style local diff scanning.',
58
+ ),
59
+ ] = consts.GIT_HEAD_COMMIT_REV,
60
+ include_unstaged: Annotated[
61
+ bool,
62
+ typer.Option(
63
+ '--include-unstaged',
64
+ help='Also scan unstaged changes to tracked files, not just what is staged. '
65
+ 'Off by default, so the pre-commit hook flow is unaffected.',
66
+ ),
67
+ ] = False,
68
+ paths: Annotated[
69
+ Optional[list[Path]],
70
+ typer.Option(
71
+ '--path',
72
+ help='Optional paths to scope the diff scan to (e.g. the file currently open in an IDE). '
73
+ 'Defaults to the entire working directory. Repeatable.',
74
+ show_default=False,
75
+ resolve_path=True,
76
+ ),
77
+ ] = None,
78
+ ) -> None:
79
+ try:
80
+ repo_path = _resolve_repo_root(os.getcwd())
81
+ _validate_base_ref(repo_path, base_ref)
82
+ str_paths = [str(path) for path in paths] if paths else None
83
+ # realpath both sides: repo_path (from GitPython) and str_path (from Click's
84
+ # resolve_path=True) can disagree on 8.3 short-name vs long-name form on Windows,
85
+ # which would otherwise make an in-repo path look like it's outside the repo.
86
+ repo_path_real = os.path.realpath(repo_path)
87
+ for str_path in str_paths or []:
88
+ if os.path.commonpath([repo_path_real, os.path.realpath(str_path)]) != repo_path_real:
89
+ raise ScanPathOutsideRepositoryError(str_path, repo_path)
90
+ except Exception as e:
91
+ handle_scan_exception(ctx, e)
92
+ return
93
+
94
+ progress_bar = ctx.obj['progress_bar']
95
+ progress_bar.start()
96
+
97
+ try:
98
+ scan_pre_commit(ctx, repo_path, base_ref=base_ref, include_unstaged=include_unstaged, paths=str_paths)
99
+ except Exception as e:
100
+ handle_scan_exception(ctx, e)
@@ -7,7 +7,7 @@ from cycode.cli import consts
7
7
  from cycode.cli.apps.scan.aggregation_report import try_get_aggregation_report_url_if_needed
8
8
  from cycode.cli.apps.scan.detection_excluder import exclude_irrelevant_document_detections
9
9
  from cycode.cli.models import Document, DocumentDetections, LocalScanResult
10
- from cycode.cli.utils.path_utils import concat_unique_id, get_path_by_os, normalize_file_path
10
+ from cycode.cli.utils.path_utils import concat_unique_id, normalize_file_path
11
11
  from cycode.cyclient.models import (
12
12
  Detection,
13
13
  DetectionSchema,
@@ -49,7 +49,7 @@ def _get_document_detections(
49
49
 
50
50
  document_detections = []
51
51
  for detections_per_file in scan_result.detections_per_file:
52
- file_name = get_path_by_os(detections_per_file.file_name)
52
+ file_name = detections_per_file.file_name
53
53
  commit_id = detections_per_file.commit_id
54
54
 
55
55
  logger.debug(
@@ -1,7 +1,27 @@
1
+ import sys
2
+ from enum import Enum
3
+
1
4
  PROGRAM_NAME = 'cycode'
2
5
  APP_NAME = 'CycodeCLI'
3
6
  CLI_CONTEXT_SETTINGS = {'terminal_width': 10**9, 'max_content_width': 10**9, 'help_option_names': ['-h', '--help']}
4
7
 
8
+
9
+ class OperatingSystem(str, Enum):
10
+ WINDOWS = 'windows'
11
+ MACOS = 'macos'
12
+ LINUX = 'linux'
13
+
14
+
15
+ def _detect_operating_system() -> OperatingSystem:
16
+ if sys.platform == 'win32':
17
+ return OperatingSystem.WINDOWS
18
+ if sys.platform == 'darwin':
19
+ return OperatingSystem.MACOS
20
+ return OperatingSystem.LINUX
21
+
22
+
23
+ OPERATING_SYSTEM = _detect_operating_system()
24
+
5
25
  PRE_COMMIT_COMMAND_SCAN_TYPE = 'pre-commit'
6
26
  PRE_COMMIT_COMMAND_SCAN_TYPE_OLD = 'pre_commit'
7
27
  PRE_RECEIVE_COMMAND_SCAN_TYPE = 'pre-receive'
@@ -103,6 +103,25 @@ class TfplanKeyError(CycodeError):
103
103
  return f'Error occurred while parsing terraform plan file. Path: {self.file_path}'
104
104
 
105
105
 
106
+ class ScanPathOutsideRepositoryError(CycodeError):
107
+ def __init__(self, path: str, repo_path: str) -> None:
108
+ self.path = path
109
+ self.repo_path = repo_path
110
+ super().__init__()
111
+
112
+ def __str__(self) -> str:
113
+ return f'The path {self.path!r} is outside the repository {self.repo_path!r}'
114
+
115
+
116
+ class UnresolvedGitRefError(CycodeError):
117
+ def __init__(self, ref: str) -> None:
118
+ self.ref = ref
119
+ super().__init__()
120
+
121
+ def __str__(self) -> str:
122
+ return f'Could not resolve git ref: {self.ref!r}'
123
+
124
+
106
125
  _SSL_ERROR_CA_BUNDLE_HINT = (
107
126
  'set the REQUESTS_CA_BUNDLE (or CURL_CA_BUNDLE) environment variable to the path of a valid .pem or similar'
108
127
  )
@@ -60,6 +60,16 @@ def handle_scan_exception(ctx: typer.Context, err: Exception, *, return_exceptio
60
60
  message='The path you supplied does not correlate to a Git repository. '
61
61
  'If you still wish to scan this path, use: `cycode scan path <path>`',
62
62
  ),
63
+ custom_exceptions.ScanPathOutsideRepositoryError: CliError(
64
+ soft_fail=False,
65
+ code='invalid_scan_path_error',
66
+ message=f'\n{err!s}\n--path must point to a location inside the scanned repository',
67
+ ),
68
+ custom_exceptions.UnresolvedGitRefError: CliError(
69
+ soft_fail=False,
70
+ code='invalid_git_ref_error',
71
+ message=f'\n{err!s}\nPass a commit, branch, or tag that exists in this repository',
72
+ ),
63
73
  }
64
74
 
65
75
  return handle_errors(ctx, err, errors, return_exception=return_exception)