cycode 3.26.0__tar.gz → 3.26.1.dev2__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 (230) hide show
  1. {cycode-3.26.0 → cycode-3.26.1.dev2}/PKG-INFO +2 -2
  2. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/__init__.py +1 -1
  3. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/base.py +10 -0
  4. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/claude_code.py +8 -3
  5. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/codex.py +1 -1
  6. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/copilot.py +2 -1
  7. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/cursor.py +5 -2
  8. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/handlers.py +62 -10
  9. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/utils.py +35 -17
  10. {cycode-3.26.0 → cycode-3.26.1.dev2}/pyproject.toml +2 -2
  11. {cycode-3.26.0 → cycode-3.26.1.dev2}/LICENCE +0 -0
  12. {cycode-3.26.0 → cycode-3.26.1.dev2}/README.md +0 -0
  13. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/__main__.py +0 -0
  14. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/__init__.py +0 -0
  15. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/app.py +0 -0
  16. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/__init__.py +0 -0
  17. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/activation_manager.py +0 -0
  18. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/__init__.py +0 -0
  19. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/command_utils.py +0 -0
  20. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/consts.py +0 -0
  21. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/hooks_manager.py +0 -0
  22. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/__init__.py +0 -0
  23. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/_plugin_utils.py +0 -0
  24. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/ides/_skill_utils.py +0 -0
  25. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/install_command.py +0 -0
  26. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/__init__.py +0 -0
  27. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/consts.py +0 -0
  28. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/detach.py +0 -0
  29. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/guardrail_config.py +0 -0
  30. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/mcp_server_status.py +0 -0
  31. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/payload.py +0 -0
  32. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/policy.py +0 -0
  33. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/scan_command.py +0 -0
  34. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/scan/types.py +0 -0
  35. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/session_start_command.py +0 -0
  36. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/status_command.py +0 -0
  37. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_guardrails/uninstall_command.py +0 -0
  38. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
  39. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
  40. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
  41. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
  42. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/api/__init__.py +0 -0
  43. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/api/api_command.py +0 -0
  44. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/api/openapi_spec.py +0 -0
  45. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/auth/__init__.py +0 -0
  46. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/auth/auth_command.py +0 -0
  47. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/auth/auth_common.py +0 -0
  48. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/auth/auth_manager.py +0 -0
  49. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/auth/models.py +0 -0
  50. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/configure/__init__.py +0 -0
  51. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/configure/configure_command.py +0 -0
  52. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/configure/consts.py +0 -0
  53. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/configure/messages.py +0 -0
  54. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/configure/prompts.py +0 -0
  55. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ignore/__init__.py +0 -0
  56. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/ignore/ignore_command.py +0 -0
  57. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/mcp/__init__.py +0 -0
  58. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/mcp/mcp_command.py +0 -0
  59. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/__init__.py +0 -0
  60. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/report_command.py +0 -0
  61. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/__init__.py +0 -0
  62. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/common.py +0 -0
  63. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
  64. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
  65. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
  66. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
  67. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
  68. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
  69. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report_import/__init__.py +0 -0
  70. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report_import/report_import_command.py +0 -0
  71. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report_import/sbom/__init__.py +0 -0
  72. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/report_import/sbom/sbom_command.py +0 -0
  73. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/sca_options.py +0 -0
  74. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/__init__.py +0 -0
  75. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/aggregation_report.py +0 -0
  76. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/code_scanner.py +0 -0
  77. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
  78. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
  79. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/commit_range_scanner.py +0 -0
  80. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/detection_excluder.py +0 -0
  81. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/path/__init__.py +0 -0
  82. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/path/path_command.py +0 -0
  83. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
  84. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -0
  85. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/pre_push/__init__.py +0 -0
  86. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/pre_push/pre_push_command.py +0 -0
  87. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
  88. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
  89. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
  90. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/repository/__init__.py +0 -0
  91. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
  92. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
  93. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
  94. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
  95. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/scan_command.py +0 -0
  96. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/scan_parameters.py +0 -0
  97. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/scan/scan_result.py +0 -0
  98. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/status/__init__.py +0 -0
  99. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/status/get_cli_status.py +0 -0
  100. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/status/models.py +0 -0
  101. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/status/status_command.py +0 -0
  102. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/apps/status/version_command.py +0 -0
  103. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/cli_types.py +0 -0
  104. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/config.py +0 -0
  105. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/console.py +0 -0
  106. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/consts.py +0 -0
  107. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/__init__.py +0 -0
  108. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/custom_exceptions.py +0 -0
  109. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
  110. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
  111. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/handle_errors.py +0 -0
  112. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
  113. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
  114. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/__init__.py +0 -0
  115. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/commit_range_documents.py +0 -0
  116. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/documents_walk_ignore.py +0 -0
  117. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/file_excluder.py +0 -0
  118. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/iac/__init__.py +0 -0
  119. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
  120. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/models/__init__.py +0 -0
  121. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
  122. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/path_documents.py +0 -0
  123. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/repository_documents.py +0 -0
  124. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/__init__.py +0 -0
  125. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
  126. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
  127. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
  128. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
  129. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
  130. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
  131. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
  132. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/restore_bun_dependencies.py +0 -0
  133. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/restore_deno_dependencies.py +0 -0
  134. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
  135. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/restore_pnpm_dependencies.py +0 -0
  136. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/restore_yarn_dependencies.py +0 -0
  137. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/workspace/__init__.py +0 -0
  138. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/workspace/coverage.py +0 -0
  139. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/workspace/files.py +0 -0
  140. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/workspace/globs.py +0 -0
  141. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/workspace/names.py +0 -0
  142. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/npm/workspace/resolvers.py +0 -0
  143. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
  144. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
  145. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/php/__init__.py +0 -0
  146. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/php/restore_composer_dependencies.py +0 -0
  147. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/python/__init__.py +0 -0
  148. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/python/restore_pip_dependencies.py +0 -0
  149. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/python/restore_pipenv_dependencies.py +0 -0
  150. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/python/restore_poetry_dependencies.py +0 -0
  151. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/python/restore_uv_dependencies.py +0 -0
  152. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
  153. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
  154. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
  155. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
  156. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/sca/sca_file_collector.py +0 -0
  157. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/walk_ignore.py +0 -0
  158. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/files_collector/zip_documents.py +0 -0
  159. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/logger.py +0 -0
  160. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/main.py +0 -0
  161. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/models.py +0 -0
  162. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/__init__.py +0 -0
  163. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/console_printer.py +0 -0
  164. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/json_printer.py +0 -0
  165. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/printer_base.py +0 -0
  166. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/rich_printer.py +0 -0
  167. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/tables/__init__.py +0 -0
  168. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
  169. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/tables/table.py +0 -0
  170. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/tables/table_models.py +0 -0
  171. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/tables/table_printer.py +0 -0
  172. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/tables/table_printer_base.py +0 -0
  173. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/text_printer.py +0 -0
  174. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/__init__.py +0 -0
  175. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
  176. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/detection_data.py +0 -0
  177. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/detection_ordering/__init__.py +0 -0
  178. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
  179. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
  180. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/rich_helpers.py +0 -0
  181. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/sca_ossf.py +0 -0
  182. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/printers/utils/sca_policy_details.py +0 -0
  183. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/user_settings/__init__.py +0 -0
  184. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/user_settings/base_file_manager.py +0 -0
  185. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/user_settings/config_file_manager.py +0 -0
  186. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/user_settings/configuration_manager.py +0 -0
  187. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/user_settings/credentials_manager.py +0 -0
  188. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/user_settings/jwt_creator.py +0 -0
  189. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/__init__.py +0 -0
  190. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/binary_utils.py +0 -0
  191. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/enum_utils.py +0 -0
  192. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/get_api_client.py +0 -0
  193. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/git_proxy.py +0 -0
  194. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/host_info.py +0 -0
  195. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/ignore_utils.py +0 -0
  196. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/jwt_utils.py +0 -0
  197. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/path_utils.py +0 -0
  198. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/progress_bar.py +0 -0
  199. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/scan_batch.py +0 -0
  200. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/scan_utils.py +0 -0
  201. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/shell_executor.py +0 -0
  202. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/string_utils.py +0 -0
  203. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/task_timer.py +0 -0
  204. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/trust_store.py +0 -0
  205. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/url_utils.py +0 -0
  206. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/version_checker.py +0 -0
  207. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cli/utils/yaml_utils.py +0 -0
  208. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/config.py +0 -0
  209. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/__init__.py +0 -0
  210. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/ai_security_manager_client.py +0 -0
  211. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/ai_security_manager_service_config.py +0 -0
  212. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/auth_client.py +0 -0
  213. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/base_token_auth_client.py +0 -0
  214. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/cli_activation_client.py +0 -0
  215. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/client_creator.py +0 -0
  216. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/config.py +0 -0
  217. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/config_dev.py +0 -0
  218. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/cycode_client.py +0 -0
  219. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/cycode_client_base.py +0 -0
  220. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/cycode_dev_based_client.py +0 -0
  221. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/cycode_oidc_based_client.py +0 -0
  222. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/cycode_token_based_client.py +0 -0
  223. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/headers.py +0 -0
  224. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/import_sbom_client.py +0 -0
  225. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/logger.py +0 -0
  226. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/models.py +0 -0
  227. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/report_client.py +0 -0
  228. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/scan_client.py +0 -0
  229. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/cyclient/scan_config_base.py +0 -0
  230. {cycode-3.26.0 → cycode-3.26.1.dev2}/cycode/logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.26.0
3
+ Version: 3.26.1.dev2
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
@@ -25,7 +25,7 @@ Requires-Dist: click (>=8.1.0,<8.2.0)
25
25
  Requires-Dist: colorama (>=0.4.3,<0.5.0)
26
26
  Requires-Dist: gitpython (>=3.1.62,<3.2.0)
27
27
  Requires-Dist: marshmallow (>=4.1.2,<5.0.0)
28
- Requires-Dist: mcp (>=1.28.1,<2.0.0)
28
+ Requires-Dist: mcp (>=1.30.0,<2.0.0)
29
29
  Requires-Dist: patch-ng (==1.19.1)
30
30
  Requires-Dist: pathvalidate (>=3.3.1,<4.0.0)
31
31
  Requires-Dist: pydantic (>=2.11.5,<3.0.0)
@@ -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.26.0' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
8
+ __version__ = '3.26.1.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -47,6 +47,16 @@ class HookDecision:
47
47
  user_message: str | None = None
48
48
  agent_message: str | None = None
49
49
 
50
+ @property
51
+ def model_message(self) -> str:
52
+ """What a tool deny tells the model: the findings the user sees, then the agent's instructions."""
53
+ return '\n'.join(message for message in (self.user_message, self.agent_message) if message)
54
+
55
+ @property
56
+ def permission_reason(self) -> str:
57
+ """A PreToolUse permissionDecisionReason: a deny reason goes to the model, an ask reason to the user."""
58
+ return self.model_message if self.action == DecisionAction.DENY else self.user_message or ''
59
+
50
60
  @classmethod
51
61
  def allow(cls, event_type: AiHookEventType) -> 'HookDecision':
52
62
  return cls(action=DecisionAction.ALLOW, event_type=event_type)
@@ -397,8 +397,13 @@ class ClaudeCode(IDE):
397
397
  if decision.event_type == AiHookEventType.PROMPT:
398
398
  if decision.action == DecisionAction.ALLOW:
399
399
  return {}
400
- # Both DENY and (unexpected) ASK on prompts collapse to a block.
401
- return {'decision': 'block', 'reason': decision.user_message or ''}
400
+ # Both DENY and (unexpected) ASK on prompts collapse to a block. Claude Code echoes the blocked
401
+ # prompt (secret included) under the reason unless suppressed; the reason already locates the finding.
402
+ return {
403
+ 'decision': 'block',
404
+ 'reason': decision.user_message or '',
405
+ 'hookSpecificOutput': {'hookEventName': 'UserPromptSubmit', 'suppressOriginalPrompt': True},
406
+ }
402
407
 
403
408
  # FILE_READ / MCP_EXECUTION → hookSpecificOutput shape.
404
409
  if decision.action == DecisionAction.ALLOW:
@@ -412,7 +417,7 @@ class ClaudeCode(IDE):
412
417
  'hookSpecificOutput': {
413
418
  'hookEventName': 'PreToolUse',
414
419
  'permissionDecision': decision.action.value, # 'deny' or 'ask'
415
- 'permissionDecisionReason': decision.user_message or '',
420
+ 'permissionDecisionReason': decision.permission_reason,
416
421
  }
417
422
  }
418
423
 
@@ -319,7 +319,7 @@ class Codex(IDE):
319
319
  'hookSpecificOutput': {
320
320
  'hookEventName': 'PreToolUse',
321
321
  'permissionDecision': decision.action.value, # 'deny' or 'ask'
322
- 'permissionDecisionReason': decision.user_message or '',
322
+ 'permissionDecisionReason': decision.permission_reason,
323
323
  }
324
324
  }
325
325
 
@@ -474,7 +474,8 @@ class Copilot(IDE):
474
474
  'hookSpecificOutput': {
475
475
  'hookEventName': 'PreToolUse',
476
476
  'permissionDecision': decision.action.value, # 'deny' or 'ask'
477
- 'permissionDecisionReason': decision.user_message or '',
477
+ # Copilot VS Code shows a deny reason to the user rather than the model, which is harmless
478
+ 'permissionDecisionReason': decision.permission_reason,
478
479
  }
479
480
  }
480
481
 
@@ -149,10 +149,13 @@ class Cursor(IDE):
149
149
  # FILE_READ / MCP_EXECUTION → permission shape
150
150
  if decision.action == DecisionAction.ALLOW:
151
151
  return {'permission': 'allow'}
152
+ # beforeReadFile has no agent_message; its deny user_message is what reaches the model
153
+ file_read_deny = decision.event_type == AiHookEventType.FILE_READ and decision.action == DecisionAction.DENY
152
154
  return {
153
155
  'permission': decision.action.value, # 'deny' or 'ask'
154
- 'user_message': decision.user_message or '',
155
- 'agent_message': decision.agent_message or '',
156
+ 'user_message': decision.model_message if file_read_deny else decision.user_message or '',
157
+ # The agent does not see user_message, and needs the findings (their sha) to act on its instructions
158
+ 'agent_message': decision.model_message,
156
159
  }
157
160
 
158
161
  def build_session_payload(self, raw_payload: dict) -> AIHookPayload:
@@ -10,9 +10,11 @@ touching any handler in this module.
10
10
 
11
11
  import json
12
12
  import os
13
+ import sys
13
14
  import threading
14
15
  from collections.abc import Callable
15
16
  from dataclasses import dataclass
17
+ from gettext import ngettext
16
18
  from typing import TYPE_CHECKING, Any, NamedTuple
17
19
 
18
20
  import typer
@@ -46,12 +48,53 @@ logger = get_logger('AI Guardrails')
46
48
  HandlerFn = Callable[[typer.Context, AIHookPayload, dict], HookDecision]
47
49
 
48
50
 
51
+ def _ignore_commands(shas: tuple[str, ...]) -> list[str]:
52
+ """Ready-to-run ignore commands, one per finding, in the order the findings are listed.
53
+
54
+ Names the binary running this hook, which may not be on PATH (e.g. MDM installs). Repo scope: it lands in
55
+ the cwd's .cycode/config.yaml, which matches where the hook reads it as long as the agent runs it.
56
+ """
57
+ executable = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
58
+ if ' ' in executable:
59
+ executable = f'"{executable}"'
60
+ return [f'`{executable} ignore --by-sha {sha}`' for sha in shas]
61
+
62
+
63
+ def _with_ignore_commands(shas: tuple[str, ...], one: str, many: str) -> str:
64
+ """`one` formatted with the single command, or `many` followed by the commands as a list; '' without shas."""
65
+ commands = _ignore_commands(shas)
66
+ if len(commands) == 1:
67
+ return one.format(command=commands[0])
68
+ if commands:
69
+ return many + ''.join(f'\n {command}' for command in commands)
70
+ return ''
71
+
72
+
73
+ def _false_positive_user_hint(shas: tuple[str, ...]) -> str:
74
+ # The agent never saw the blocked prompt, so the command has to be complete for the developer to pass on
75
+ return _with_ignore_commands(
76
+ shas,
77
+ one='Not a real secret? Ask your code agent to run {command}, then resend.',
78
+ many='Not real secrets? Ask your code agent to run the command for each one, then resend:',
79
+ )
80
+
81
+
82
+ def _false_positive_agent_hint(shas: tuple[str, ...]) -> str:
83
+ # Ignoring is the developer's call; the agent may run it for them, but only once they confirm
84
+ return 'Tell the user what was blocked.' + _with_ignore_commands(
85
+ shas,
86
+ one=' Only if the user confirms it is a false positive, run {command} and retry.',
87
+ many=' Only for a finding the user confirms is a false positive, run its command and retry:',
88
+ )
89
+
90
+
49
91
  class ScanOutcome(NamedTuple):
50
92
  """What one guardrail scan came back with; the verdict is the server's, which applied the tenant's floors."""
51
93
 
52
94
  violation_summary: str | None = None
53
95
  scan_id: str | None = None
54
96
  verdict: GuardrailsMode | None = None
97
+ shas: tuple[str, ...] = ()
55
98
 
56
99
 
57
100
  NO_SCAN = ScanOutcome()
@@ -96,7 +139,10 @@ def handle_before_submit_prompt(ctx: typer.Context, payload: AIHookPayload, poli
96
139
  block_reason = SECRETS_BLOCK_REASON_BY_EVENT_TYPE[AiHookEventType.PROMPT]
97
140
  if scan_outcome.verdict == GuardrailsMode.BLOCK:
98
141
  outcome = AIHookOutcome.BLOCKED
99
- user_message = f'Remove secrets before sending. {scan_outcome.violation_summary}'
142
+ secrets = ngettext('secret', 'secrets', len(scan_outcome.shas))
143
+ user_message = f'{scan_outcome.violation_summary}\nRemove the {secrets} and resend.'
144
+ if scan_outcome.shas:
145
+ user_message += f'\n{_false_positive_user_hint(scan_outcome.shas)}'
100
146
  return HookDecision.deny(AiHookEventType.PROMPT, user_message)
101
147
  outcome = AIHookOutcome.WARNED
102
148
  return HookDecision.allow(AiHookEventType.PROMPT)
@@ -164,14 +210,15 @@ def handle_before_read_file(ctx: typer.Context, payload: AIHookPayload, policy:
164
210
  block_reason = SECRETS_BLOCK_REASON_BY_EVENT_TYPE[AiHookEventType.FILE_READ]
165
211
  if scan_outcome.verdict == GuardrailsMode.BLOCK:
166
212
  outcome = AIHookOutcome.BLOCKED
167
- user_message = f'Cycode blocked reading {file_path}. {scan_outcome.violation_summary}'
213
+ user_message = (
214
+ f'Cycode blocked reading {file_path} because it contains a secret.\n'
215
+ f'{scan_outcome.violation_summary}'
216
+ )
168
217
  return HookDecision.deny(
169
- AiHookEventType.FILE_READ,
170
- user_message,
171
- 'Secrets detected; do not send this file to the model.',
218
+ AiHookEventType.FILE_READ, user_message, _false_positive_agent_hint(scan_outcome.shas)
172
219
  )
173
220
  outcome = AIHookOutcome.WARNED
174
- user_message = f'Cycode detected secrets in {file_path}. {scan_outcome.violation_summary}'
221
+ user_message = f'Cycode detected secrets in {file_path}.\n{scan_outcome.violation_summary}'
175
222
  return HookDecision.ask(
176
223
  AiHookEventType.FILE_READ,
177
224
  user_message,
@@ -282,7 +329,7 @@ def _handle_arg_scan(
282
329
  return HookDecision.deny(
283
330
  feature.event_type,
284
331
  feature.deny_message(scan_outcome.violation_summary),
285
- feature.deny_agent_message,
332
+ f'{feature.deny_agent_message} {_false_positive_agent_hint(scan_outcome.shas)}',
286
333
  )
287
334
  outcome = AIHookOutcome.WARNED
288
335
  return HookDecision.ask(
@@ -360,9 +407,11 @@ def handle_before_mcp_execution(ctx: typer.Context, payload: AIHookPayload, poli
360
407
  policy,
361
408
  _ArgScanFeature(
362
409
  event_type=AiHookEventType.MCP_EXECUTION,
363
- deny_message=lambda v: f'Cycode blocked MCP tool call "{tool}". {v}',
410
+ deny_message=lambda v: (
411
+ f'Cycode blocked MCP tool call "{tool}" because its arguments contain a secret.\n{v}'
412
+ ),
364
413
  deny_agent_message='Do not pass secrets to tools. Use secret references (name/id) instead.',
365
- ask_message=lambda v: f'Allow MCP tool call "{tool}"? {v}',
414
+ ask_message=lambda v: f'Allow MCP tool call "{tool}"?\n{v}',
366
415
  ask_agent_message='Possible secrets detected in tool arguments; proceed with caution.',
367
416
  scan_enabled=get_policy_value(policy, 'mcp', 'scan_args', default=True),
368
417
  ),
@@ -478,11 +527,14 @@ def _perform_scan(
478
527
  if not local_scan_result:
479
528
  return NO_SCAN
480
529
 
481
- violation_summary = build_violation_summary([local_scan_result]) if local_scan_result.issue_detected else None
530
+ violation_summary, shas = (
531
+ build_violation_summary([local_scan_result]) if local_scan_result.issue_detected else (None, ())
532
+ )
482
533
  return ScanOutcome(
483
534
  violation_summary=violation_summary,
484
535
  scan_id=local_scan_result.scan_id,
485
536
  verdict=_parse_verdict(local_scan_result.verdict),
537
+ shas=shas,
486
538
  )
487
539
 
488
540
 
@@ -8,14 +8,17 @@ import json
8
8
  import os
9
9
  import sys
10
10
  from collections import defaultdict
11
+ from gettext import ngettext
11
12
  from pathlib import Path
12
13
  from typing import TYPE_CHECKING
13
14
 
14
15
  from cycode.cli.apps.ai_guardrails.scan.policy import get_policy_value
15
16
  from cycode.cli.cli_types import SeverityOption
17
+ from cycode.cli.utils.string_utils import obfuscate_text
16
18
 
17
19
  if TYPE_CHECKING:
18
20
  from cycode.cli.models import LocalScanResult
21
+ from cycode.cyclient.models import Detection
19
22
 
20
23
  # Keeps the hook message readable when a single file trips dozens of detections
21
24
  MAX_VIOLATION_DETAIL_LINES = 5
@@ -98,35 +101,50 @@ def output_json(obj: dict) -> None:
98
101
  print(json.dumps(obj), end='') # noqa: T201
99
102
 
100
103
 
101
- def _build_detection_lines(
104
+ def _describe_detection(detection: 'Detection', content: str) -> str:
105
+ details = detection.detection_details
106
+ description = detection.type or detection.message
107
+
108
+ line = details.get('line')
109
+ if isinstance(line, int) and line >= 0:
110
+ description += f' (line {line + 1})' # the scanner reports 0-based lines
111
+
112
+ start, length = details.get('start_position'), details.get('length')
113
+ if isinstance(start, int) and isinstance(length, int) and start >= 0 and length > 0:
114
+ value = content[start : start + length]
115
+ if value:
116
+ description += f': {obfuscate_text(value)}'
117
+
118
+ return description
119
+
120
+
121
+ def build_violation_summary(
102
122
  local_scan_results: list['LocalScanResult'], max_lines: int = MAX_VIOLATION_DETAIL_LINES
103
- ) -> str:
104
- """One line per distinct finding: what it is, and the value hash identifying it.
123
+ ) -> tuple[str, tuple[str, ...]]:
124
+ """One line per distinct finding (what it is, where, the masked value), and the value hashes to ignore them by.
105
125
 
106
- The value hash is safe to display; the value itself is not. Detections excluded by an existing
126
+ The masked value and hash are safe to display; the value itself is not. Detections excluded by an existing
107
127
  ignore rule are already gone from `document_detections`, so only what actually blocked is listed.
108
128
  """
109
- type_by_sha = {}
129
+ # Keyed by value hash so a repeated value is listed once; detections without one key by their description
130
+ finding_by_key = {}
110
131
  for local_scan_result in local_scan_results:
111
132
  for document_detections in local_scan_result.document_detections:
112
133
  for detection in document_detections.detections:
134
+ description = _describe_detection(detection, document_detections.document.content)
113
135
  sha = detection.detection_details.get('sha512')
114
- if sha and sha not in type_by_sha:
115
- type_by_sha[sha] = detection.type or detection.message
116
-
117
- if not type_by_sha:
118
- return ''
136
+ finding_by_key.setdefault(sha or description, (sha, description))
119
137
 
120
- lines = [f' - {detection_type}: {sha}' for sha, detection_type in list(type_by_sha.items())[:max_lines]]
121
- remaining = len(type_by_sha) - len(lines)
138
+ listed = list(finding_by_key.values())[:max_lines]
139
+ lines = [_build_severity_line(local_scan_results)] + [f' - {description}' for _, description in listed]
140
+ remaining = len(finding_by_key) - len(listed)
122
141
  if remaining:
123
142
  lines.append(f' - ...and {remaining} more')
124
143
 
125
- return '\n' + '\n'.join(lines)
144
+ return '\n'.join(lines), tuple(sha for sha, _ in listed if sha)
126
145
 
127
146
 
128
- def build_violation_summary(local_scan_results: list['LocalScanResult']) -> str:
129
- """Build violation summary string with severity breakdown and emojis."""
147
+ def _build_severity_line(local_scan_results: list['LocalScanResult']) -> str:
130
148
  detections_count = 0
131
149
  severity_counts = defaultdict(int)
132
150
 
@@ -143,5 +161,5 @@ def build_violation_summary(local_scan_results: list['LocalScanResult']) -> str:
143
161
  count = severity_counts[severity]
144
162
  severity_parts.append(f'{emoji} {severity.upper()} - {count}')
145
163
 
146
- summary = f'Cycode found {detections_count} violations: {" | ".join(severity_parts)}'
147
- return summary + _build_detection_lines(local_scan_results)
164
+ violations = ngettext('violation', 'violations', detections_count)
165
+ return f'Cycode found {detections_count} {violations}: {" | ".join(severity_parts)}'
@@ -20,7 +20,7 @@ classifiers = [
20
20
  "Programming Language :: Python :: 3.14",
21
21
  ]
22
22
  dynamic = ["dependencies"]
23
- version = "3.26.0"
23
+ version = "3.26.1.dev2"
24
24
 
25
25
  [project.scripts]
26
26
  cycode = "cycode.cli.app:app"
@@ -46,7 +46,7 @@ rich = ">=15.0.0,<16.0.0"
46
46
  patch-ng = "1.19.1"
47
47
  typer = "^0.15.3"
48
48
  tenacity = ">=9.1.2,<9.2.0"
49
- mcp = ">=1.28.1,<2.0.0"
49
+ mcp = ">=1.30.0,<2.0.0"
50
50
  truststore = ">=0.10.4,<0.11.0"
51
51
  pywin32 = { version = ">=312,<313", markers = "sys_platform == 'win32'" }
52
52
  pydantic = ">=2.11.5,<3.0.0"
File without changes
File without changes
File without changes
File without changes