cycode 3.19.1__tar.gz → 3.19.2.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.
Files changed (217) hide show
  1. {cycode-3.19.1 → cycode-3.19.2.dev1}/PKG-INFO +1 -1
  2. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/__init__.py +1 -1
  3. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/claude_code.py +3 -9
  4. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/copilot.py +116 -48
  5. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/scan_command.py +1 -9
  6. {cycode-3.19.1 → cycode-3.19.2.dev1}/pyproject.toml +1 -1
  7. {cycode-3.19.1 → cycode-3.19.2.dev1}/LICENCE +0 -0
  8. {cycode-3.19.1 → cycode-3.19.2.dev1}/README.md +0 -0
  9. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/__main__.py +0 -0
  10. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/__init__.py +0 -0
  11. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/app.py +0 -0
  12. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/__init__.py +0 -0
  13. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/activation_manager.py +0 -0
  14. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/__init__.py +0 -0
  15. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/command_utils.py +0 -0
  16. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/consts.py +0 -0
  17. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/hooks_manager.py +0 -0
  18. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/__init__.py +0 -0
  19. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/_plugin_utils.py +0 -0
  20. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/base.py +0 -0
  21. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/codex.py +0 -0
  22. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/ides/cursor.py +0 -0
  23. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/install_command.py +0 -0
  24. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/__init__.py +0 -0
  25. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/consts.py +0 -0
  26. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/handlers.py +0 -0
  27. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/payload.py +0 -0
  28. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/policy.py +0 -0
  29. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/types.py +0 -0
  30. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/scan/utils.py +0 -0
  31. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/session_start_command.py +0 -0
  32. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/status_command.py +0 -0
  33. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_guardrails/uninstall_command.py +0 -0
  34. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
  35. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
  36. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
  37. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
  38. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/api/__init__.py +0 -0
  39. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/api/api_command.py +0 -0
  40. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/api/openapi_spec.py +0 -0
  41. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/auth/__init__.py +0 -0
  42. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/auth/auth_command.py +0 -0
  43. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/auth/auth_common.py +0 -0
  44. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/auth/auth_manager.py +0 -0
  45. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/auth/models.py +0 -0
  46. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/configure/__init__.py +0 -0
  47. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/configure/configure_command.py +0 -0
  48. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/configure/consts.py +0 -0
  49. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/configure/messages.py +0 -0
  50. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/configure/prompts.py +0 -0
  51. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ignore/__init__.py +0 -0
  52. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/ignore/ignore_command.py +0 -0
  53. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/mcp/__init__.py +0 -0
  54. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/mcp/mcp_command.py +0 -0
  55. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/__init__.py +0 -0
  56. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/report_command.py +0 -0
  57. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/__init__.py +0 -0
  58. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/common.py +0 -0
  59. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
  60. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
  61. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
  62. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
  63. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
  64. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
  65. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report_import/__init__.py +0 -0
  66. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report_import/report_import_command.py +0 -0
  67. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report_import/sbom/__init__.py +0 -0
  68. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/report_import/sbom/sbom_command.py +0 -0
  69. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/sca_options.py +0 -0
  70. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/__init__.py +0 -0
  71. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/aggregation_report.py +0 -0
  72. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/code_scanner.py +0 -0
  73. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
  74. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
  75. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/commit_range_scanner.py +0 -0
  76. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/detection_excluder.py +0 -0
  77. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/path/__init__.py +0 -0
  78. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/path/path_command.py +0 -0
  79. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
  80. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +0 -0
  81. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/pre_push/__init__.py +0 -0
  82. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/pre_push/pre_push_command.py +0 -0
  83. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
  84. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
  85. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/remote_url_resolver.py +0 -0
  86. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/repository/__init__.py +0 -0
  87. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/repository/repository_command.py +0 -0
  88. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
  89. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
  90. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
  91. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/scan_command.py +0 -0
  92. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/scan_parameters.py +0 -0
  93. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/scan/scan_result.py +0 -0
  94. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/status/__init__.py +0 -0
  95. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/status/get_cli_status.py +0 -0
  96. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/status/models.py +0 -0
  97. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/status/status_command.py +0 -0
  98. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/apps/status/version_command.py +0 -0
  99. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/cli_types.py +0 -0
  100. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/config.py +0 -0
  101. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/console.py +0 -0
  102. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/consts.py +0 -0
  103. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/__init__.py +0 -0
  104. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/custom_exceptions.py +0 -0
  105. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
  106. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
  107. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/handle_errors.py +0 -0
  108. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
  109. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
  110. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/__init__.py +0 -0
  111. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/commit_range_documents.py +0 -0
  112. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/documents_walk_ignore.py +0 -0
  113. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/file_excluder.py +0 -0
  114. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/iac/__init__.py +0 -0
  115. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
  116. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/models/__init__.py +0 -0
  117. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
  118. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/path_documents.py +0 -0
  119. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/repository_documents.py +0 -0
  120. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/__init__.py +0 -0
  121. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
  122. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
  123. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
  124. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
  125. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
  126. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
  127. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
  128. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/npm/restore_bun_dependencies.py +0 -0
  129. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/npm/restore_deno_dependencies.py +0 -0
  130. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
  131. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/npm/restore_pnpm_dependencies.py +0 -0
  132. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/npm/restore_yarn_dependencies.py +0 -0
  133. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
  134. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
  135. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/php/__init__.py +0 -0
  136. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/php/restore_composer_dependencies.py +0 -0
  137. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/python/__init__.py +0 -0
  138. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/python/restore_pip_dependencies.py +0 -0
  139. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/python/restore_pipenv_dependencies.py +0 -0
  140. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/python/restore_poetry_dependencies.py +0 -0
  141. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/python/restore_uv_dependencies.py +0 -0
  142. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
  143. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
  144. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
  145. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
  146. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/sca/sca_file_collector.py +0 -0
  147. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/walk_ignore.py +0 -0
  148. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/files_collector/zip_documents.py +0 -0
  149. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/logger.py +0 -0
  150. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/main.py +0 -0
  151. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/models.py +0 -0
  152. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/__init__.py +0 -0
  153. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/console_printer.py +0 -0
  154. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/json_printer.py +0 -0
  155. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/printer_base.py +0 -0
  156. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/rich_printer.py +0 -0
  157. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/tables/__init__.py +0 -0
  158. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
  159. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/tables/table.py +0 -0
  160. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/tables/table_models.py +0 -0
  161. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/tables/table_printer.py +0 -0
  162. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/tables/table_printer_base.py +0 -0
  163. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/text_printer.py +0 -0
  164. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/__init__.py +0 -0
  165. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
  166. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/detection_data.py +0 -0
  167. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/detection_ordering/__init__.py +0 -0
  168. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
  169. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
  170. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/printers/utils/rich_helpers.py +0 -0
  171. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/user_settings/__init__.py +0 -0
  172. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/user_settings/base_file_manager.py +0 -0
  173. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/user_settings/config_file_manager.py +0 -0
  174. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/user_settings/configuration_manager.py +0 -0
  175. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/user_settings/credentials_manager.py +0 -0
  176. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/user_settings/jwt_creator.py +0 -0
  177. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/__init__.py +0 -0
  178. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/binary_utils.py +0 -0
  179. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/enum_utils.py +0 -0
  180. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/get_api_client.py +0 -0
  181. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/git_proxy.py +0 -0
  182. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/host_info.py +0 -0
  183. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/ignore_utils.py +0 -0
  184. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/jwt_utils.py +0 -0
  185. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/path_utils.py +0 -0
  186. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/progress_bar.py +0 -0
  187. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/scan_batch.py +0 -0
  188. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/scan_utils.py +0 -0
  189. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/shell_executor.py +0 -0
  190. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/string_utils.py +0 -0
  191. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/task_timer.py +0 -0
  192. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/url_utils.py +0 -0
  193. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/version_checker.py +0 -0
  194. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cli/utils/yaml_utils.py +0 -0
  195. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/config.py +0 -0
  196. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/__init__.py +0 -0
  197. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/ai_security_manager_client.py +0 -0
  198. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/ai_security_manager_service_config.py +0 -0
  199. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/auth_client.py +0 -0
  200. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/base_token_auth_client.py +0 -0
  201. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/cli_activation_client.py +0 -0
  202. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/client_creator.py +0 -0
  203. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/config.py +0 -0
  204. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/config_dev.py +0 -0
  205. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/cycode_client.py +0 -0
  206. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/cycode_client_base.py +0 -0
  207. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/cycode_dev_based_client.py +0 -0
  208. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/cycode_oidc_based_client.py +0 -0
  209. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/cycode_token_based_client.py +0 -0
  210. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/headers.py +0 -0
  211. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/import_sbom_client.py +0 -0
  212. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/logger.py +0 -0
  213. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/models.py +0 -0
  214. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/report_client.py +0 -0
  215. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/scan_client.py +0 -0
  216. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/cyclient/scan_config_base.py +0 -0
  217. {cycode-3.19.1 → cycode-3.19.2.dev1}/cycode/logger.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycode
3
- Version: 3.19.1
3
+ Version: 3.19.2.dev1
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
@@ -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.19.1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
8
+ __version__ = '3.19.2.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
@@ -282,15 +282,9 @@ class ClaudeCode(IDE):
282
282
  }
283
283
 
284
284
  def matches_payload(self, raw_payload: dict) -> bool:
285
- # transcript_path is a documented Claude Code common field, present on every
286
- # hook event. VS Code Copilot emits near-identical payloads (same event names,
287
- # snake_case fields) Copilot additionally carries a top-level
288
- # timestamp, which Claude Code never sends.
289
- return (
290
- raw_payload.get('hook_event_name', '') in _CLAUDE_CODE_EVENT_NAMES
291
- and 'transcript_path' in raw_payload
292
- and 'timestamp' not in raw_payload
293
- )
285
+ # transcript_path is a documented Claude Code field, present on every hook event.
286
+ # Positive test by design: an absence check breaks silently when a vendor adds a field.
287
+ return raw_payload.get('hook_event_name', '') in _CLAUDE_CODE_EVENT_NAMES and 'transcript_path' in raw_payload
294
288
 
295
289
  def is_synthetic_prompt(self, raw_payload: dict) -> bool:
296
290
  if raw_payload.get('hook_event_name') != 'UserPromptSubmit':
@@ -1,17 +1,24 @@
1
- """GitHub Copilot (VS Code extension) integration for AI guardrails.
1
+ """GitHub Copilot integration for AI guardrails.
2
2
 
3
3
  Hooks are installed in Copilot's native format to ``~/.copilot/hooks/cycode.json``
4
- (user scope) or ``<repo>/.github/hooks/cycode.json`` (repo scope). Both locations
5
- are also read by Copilot CLI and the Copilot cloud coding agent, but only the
6
- VS Code payload dialect is parsed here CLI payloads (camelCase, no event name)
7
- are rejected by ``matches_payload`` and fall through to the allow-and-skip path.
8
-
9
- VS Code sends Claude-style payloads (``hook_event_name``, ``tool_name``,
10
- ``tool_input``), told apart by the one field Claude Code never sends: a top-level
11
- ISO ``timestamp``. VS Code also sends a ``transcript_path`` of its own once a
12
- workspace has chat history, so that field cannot discriminate. Copilot hooks have no
13
- matchers, so ``preToolUse`` fires for every tool; tools we don't scan pass
14
- through as raw event names, which match no handler and allow immediately.
4
+ (user scope) or ``<repo>/.github/hooks/cycode.json`` (repo scope). One file, but
5
+ two runtimes are known to execute it: VS Code's own chat runtime, and the Copilot
6
+ agent runtime (Copilot CLI, and VS Code agent sessions). The repo-scope location
7
+ is also read by the Copilot cloud coding agent, whose dialect is untested here.
8
+
9
+ Both deliver Claude-style payloads (``hook_event_name``, ``tool_name``,
10
+ ``tool_input``) when the event keys are registered in PascalCase; the agent runtime
11
+ answers camelCase keys with its own dialect (``sessionId``, no event name) instead.
12
+ Copilot payloads are told apart from Claude Code's by the one field Claude Code
13
+ never sends, a top-level ``timestamp``; ``transcript_path`` cannot discriminate,
14
+ since VS Code sends one of its own whenever a folder is open.
15
+
16
+ The tool vocabulary still differs by runtime — VS Code reads files with
17
+ ``read_file``/``filePath`` and names MCP tools ``mcp_<server>_<tool>``, the agent
18
+ runtime uses ``Read``/``path`` and ``<server>-<tool>`` — so both are accepted.
19
+ Copilot hooks have no matchers, so ``PreToolUse`` fires for every tool; tools we
20
+ don't scan pass through as raw event names, which match no handler and allow
21
+ immediately.
15
22
  """
16
23
 
17
24
  import json
@@ -37,20 +44,36 @@ from cycode.logger import get_logger
37
44
 
38
45
  logger = get_logger('AI Guardrails Copilot')
39
46
 
40
- # Payload dialect (VS Code sends Claude-style PascalCase event names).
47
+ # Payload dialect (Claude-style PascalCase event names).
41
48
  _COPILOT_SCAN_EVENT_NAMES = frozenset({'UserPromptSubmit', 'PreToolUse'})
42
- _READ_FILE_TOOL = 'read_file'
43
- # VS Code names MCP tools `mcp_<server>_<tool>` (single underscores).
49
+
50
+ # Two tool vocabularies reach us through one hooks file: VS Code's own runtime
51
+ # names file reads `read_file` with a `filePath` argument, while the Copilot agent
52
+ # runtime (Copilot CLI, and VS Code agent sessions) names them `Read` with `path`.
53
+ # The names are disjoint, so both are accepted rather than switched between.
54
+ _READ_FILE_TOOLS = frozenset({'read_file', 'Read'})
55
+ _READ_PATH_KEYS = ('path', 'filePath')
56
+
57
+ # VS Code names MCP tools `mcp_<server>_<tool>` (single underscores); the agent
58
+ # runtime uses `<server>-<tool>` with no prefix (its SDK documents that wire form),
59
+ # leaving a hyphen as the only marker of an MCP call there. Every built-in agent
60
+ # tool observed is lower snake_case (`view`, `glob`, `str_replace`, `ask_user`) or
61
+ # PascalCase (`Read`), so this holds for them — but SDK- or custom-agent-registered
62
+ # tools may be named freely. A hyphenated custom tool would be scanned as an MCP
63
+ # call with no resolvable server: an extra scan, never a missed one, which is the
64
+ # safe direction to err for a guardrail.
44
65
  _MCP_TOOL_PREFIX = 'mcp_'
66
+ _MCP_AGENT_SEPARATOR = '-'
45
67
 
46
- # Hooks-file dialect (Copilot-native camelCase event names).
47
- _HOOK_EVENTS = ['userPromptSubmitted', 'preToolUse']
68
+ # Hooks-file event keys. Their case selects the agent runtime's payload dialect.
69
+ _HOOK_EVENTS = ['UserPromptSubmit', 'PreToolUse']
48
70
 
49
71
  _COPILOT_HOME_ENV_VAR = 'COPILOT_HOME'
50
72
  _HOOKS_FILE_NAME = 'cycode.json'
51
73
  _REPO_HOOKS_SUBDIR = Path('.github') / 'hooks'
52
74
  _HOOK_TIMEOUT_SEC = 20
53
75
  _MCP_CONFIG_FILENAME = 'mcp.json'
76
+ _AGENT_MCP_CONFIG_FILENAME = 'mcp-config.json'
54
77
 
55
78
  # Plugin sources. CLI installs register in ~/.copilot/config.json and auto-surface
56
79
  # in VS Code; VS Code UI installs register in ~/.vscode/agent-plugins/installed.json;
@@ -68,13 +91,9 @@ _PLUGIN_MANIFEST_LOCATIONS = (
68
91
  Path('.claude-plugin') / 'plugin.json',
69
92
  )
70
93
 
71
- # --event is ignored by the VS Code payload parsing (the payload self-describes)
72
- # but Copilot CLI payloads carry no event name at all — baking the flag in now
73
- # means CLI support won't require customers to re-install hooks. Values use the
74
- # payload-dialect spelling so a future CLI path can inject them straight into
75
- # hook_event_name and reuse the existing parsing.
76
- _SCAN_PROMPT_COMMAND = f'{CYCODE_SCAN_PROMPT_COMMAND} --ide copilot --event UserPromptSubmit'
77
- _SCAN_TOOL_COMMAND = f'{CYCODE_SCAN_PROMPT_COMMAND} --ide copilot --event PreToolUse'
94
+ # One command for both events: every runtime self-describes via hook_event_name once
95
+ # the events are registered in PascalCase, so --event is no longer passed.
96
+ _SCAN_COMMAND = f'{CYCODE_SCAN_PROMPT_COMMAND} --ide copilot'
78
97
  _SESSION_START_COMMAND = f'{CYCODE_SESSION_START_COMMAND} --ide copilot'
79
98
 
80
99
 
@@ -253,7 +272,11 @@ def _collect_installed_plugins() -> dict:
253
272
 
254
273
 
255
274
  def _known_mcp_server_names() -> list[str]:
256
- """Config-declared MCP server names: user-level ``mcp.json`` + plugin configs.
275
+ """Config-declared MCP server names, across both runtimes' config files.
276
+
277
+ VS Code declares them in its user-level ``mcp.json`` under ``servers``; the
278
+ agent runtime uses ``~/.copilot/mcp-config.json`` under ``mcpServers``. Both are
279
+ read because one hooks file serves both, and plugin configs contribute to either.
257
280
 
258
281
  Best-effort inventory: servers contributed by extensions, ``chat.mcp.discovery``
259
282
  imports, dev containers, or non-default profiles are not discoverable from disk.
@@ -261,6 +284,12 @@ def _known_mcp_server_names() -> list[str]:
261
284
  config = _load_vscode_mcp_config()
262
285
  servers = (config or {}).get('servers')
263
286
  names = list(servers.keys()) if isinstance(servers, dict) else []
287
+
288
+ agent_config = _load_jsonc(_copilot_home() / _AGENT_MCP_CONFIG_FILENAME) or {}
289
+ agent_servers = agent_config.get('mcpServers')
290
+ if isinstance(agent_servers, dict):
291
+ names.extend(agent_servers.keys())
292
+
264
293
  for plugin in _collect_installed_plugins().values():
265
294
  names.extend(plugin.get('mcp_server_names') or [])
266
295
  return names
@@ -279,22 +308,57 @@ def _server_name_variants(server_name: str) -> set[str]:
279
308
  return {v for v in (server_name, underscored, collapsed) if v}
280
309
 
281
310
 
282
- def split_mcp_tool_name(tool_name: str, server_names: Iterable[str]) -> tuple[Optional[str], Optional[str]]:
283
- """Split ``mcp_<server>_<tool>`` into ``(server, tool)``.
311
+ def _read_file_path(tool_name: str, tool_input: object) -> Optional[str]:
312
+ """Path of a file-read tool call, or None when this isn't one.
313
+
314
+ The agent runtime reuses its read tool for directory listings, with a payload
315
+ identical to a file read, so the path has to be stat-ed to tell them apart —
316
+ VS Code has no such ambiguity (`read_file` vs `list_dir`). A path that isn't an
317
+ existing file (a directory, or already deleted) has nothing to scan.
318
+ """
319
+ if tool_name not in _READ_FILE_TOOLS or not isinstance(tool_input, dict):
320
+ return None
321
+
322
+ raw_path = next((tool_input[key] for key in _READ_PATH_KEYS if tool_input.get(key)), None)
323
+ if not isinstance(raw_path, str):
324
+ return None
325
+
326
+ try:
327
+ if not Path(raw_path).is_file():
328
+ return None
329
+ except OSError as e:
330
+ logger.debug('Failed to stat read path, %s', {'path': raw_path}, exc_info=e)
331
+ return None
332
+ return raw_path
333
+
284
334
 
285
- The ``<server>`` part is VS Code's sanitized (and possibly truncated) form of
286
- the server's SELF-REPORTED handshake name, not the config key so matching
287
- against known config names (and their normalized variants) is best-effort.
288
- When nothing matches, return the unsplit remainder as the tool rather than
289
- fabricating a server from a guessed split.
335
+ def is_mcp_tool_name(tool_name: str) -> bool:
336
+ """Whether a tool name is an MCP call in either runtime's naming scheme."""
337
+ return tool_name.startswith(_MCP_TOOL_PREFIX) or _MCP_AGENT_SEPARATOR in tool_name
338
+
339
+
340
+ def split_mcp_tool_name(tool_name: str, server_names: Iterable[str]) -> tuple[Optional[str], Optional[str]]:
341
+ """Split an MCP tool name into ``(server, tool)``.
342
+
343
+ Handles both naming schemes: VS Code's ``mcp_<server>_<tool>`` and the agent
344
+ runtime's prefix-less ``<server>-<tool>``. In the VS Code form the ``<server>``
345
+ part is a sanitized (and possibly truncated) form of the server's SELF-REPORTED
346
+ handshake name rather than the config key, so matching against known config
347
+ names (and their normalized variants) is best-effort. Server names may
348
+ themselves contain the separator, hence the longest-match. When nothing
349
+ matches, return the unsplit remainder as the tool rather than fabricating a
350
+ server from a guessed split.
290
351
  """
291
- rest = tool_name[len(_MCP_TOOL_PREFIX) :]
352
+ if tool_name.startswith(_MCP_TOOL_PREFIX):
353
+ rest, separator = tool_name[len(_MCP_TOOL_PREFIX) :], '_'
354
+ else:
355
+ rest, separator = tool_name, _MCP_AGENT_SEPARATOR
292
356
 
293
357
  best_server = None
294
358
  best_variant_len = -1
295
359
  for server in server_names:
296
360
  for variant in _server_name_variants(server):
297
- if (rest == variant or rest.startswith(f'{variant}_')) and len(variant) > best_variant_len:
361
+ if (rest == variant or rest.startswith(f'{variant}{separator}')) and len(variant) > best_variant_len:
298
362
  best_server = server
299
363
  best_variant_len = len(variant)
300
364
  if best_server is not None:
@@ -318,13 +382,17 @@ class Copilot(IDE):
318
382
  def render_hooks_config(self, async_mode: bool = False) -> dict:
319
383
  def entry(command: str) -> dict:
320
384
  if async_mode:
321
- # Copilot has no async hook flag; background via shell on unix. The
322
- # explicit <&0 keeps the payload flowing: a bare `cmd &` gets its stdin
323
- # reattached to /dev/null by the shell (job control is off in hooks).
324
- # Windows PowerShell has no trailing-& operator, so it stays sync.
385
+ # Copilot has no async hook flag; background via shell on unix. Both
386
+ # redirects are load-bearing. `<&0` keeps the payload flowing: a bare
387
+ # `cmd &` gets its stdin reattached to /dev/null by the shell (job
388
+ # control is off in hooks), so the scan reads nothing and allows. The
389
+ # stdout redirect is what actually makes it async: the backgrounded
390
+ # child inherits the hook's stdout and the runner waits on that pipe
391
+ # for EOF, so without it the scan blocks the response it was meant to
392
+ # run behind. Windows PowerShell has no trailing-&, so it stays sync.
325
393
  return {
326
394
  'type': 'command',
327
- 'bash': f'{command} <&0 &',
395
+ 'bash': f'{command} <&0 >/dev/null 2>&1 &',
328
396
  'powershell': command,
329
397
  'timeoutSec': _HOOK_TIMEOUT_SEC,
330
398
  }
@@ -334,9 +402,9 @@ class Copilot(IDE):
334
402
  return {
335
403
  'version': 1,
336
404
  'hooks': {
337
- 'sessionStart': [{'type': 'command', 'command': _SESSION_START_COMMAND}],
338
- 'userPromptSubmitted': [entry(_SCAN_PROMPT_COMMAND)],
339
- 'preToolUse': [entry(_SCAN_TOOL_COMMAND)],
405
+ 'SessionStart': [{'type': 'command', 'command': _SESSION_START_COMMAND}],
406
+ 'UserPromptSubmit': [entry(_SCAN_COMMAND)],
407
+ 'PreToolUse': [entry(_SCAN_COMMAND)],
340
408
  },
341
409
  }
342
410
 
@@ -350,21 +418,21 @@ class Copilot(IDE):
350
418
  tool_name = raw_payload.get('tool_name', '')
351
419
  tool_input = raw_payload.get('tool_input')
352
420
 
421
+ read_path = _read_file_path(tool_name, tool_input)
422
+
353
423
  if hook_event_name == 'UserPromptSubmit':
354
424
  canonical_event: Union[AiHookEventType, str] = AiHookEventType.PROMPT
355
- elif hook_event_name == 'PreToolUse' and tool_name == _READ_FILE_TOOL:
425
+ elif hook_event_name == 'PreToolUse' and read_path is not None:
356
426
  canonical_event = AiHookEventType.FILE_READ
357
- elif hook_event_name == 'PreToolUse' and tool_name.startswith(_MCP_TOOL_PREFIX):
427
+ elif hook_event_name == 'PreToolUse' and is_mcp_tool_name(tool_name):
358
428
  canonical_event = AiHookEventType.MCP_EXECUTION
359
429
  else:
360
- # No matchers in Copilot hooks: preToolUse fires for every tool. Pass
430
+ # No matchers in Copilot hooks: PreToolUse fires for every tool. Pass
361
431
  # the raw tool name through — it matches no handler, so scan_command
362
432
  # answers with a neutral allow before any policy/network work.
363
433
  canonical_event = tool_name or hook_event_name
364
434
 
365
- file_path = None
366
- if canonical_event == AiHookEventType.FILE_READ and isinstance(tool_input, dict):
367
- file_path = tool_input.get('filePath')
435
+ file_path = read_path if canonical_event == AiHookEventType.FILE_READ else None
368
436
 
369
437
  mcp_server_name = None
370
438
  mcp_tool_name = None
@@ -83,14 +83,6 @@ def scan_command(
83
83
  hidden=True,
84
84
  ),
85
85
  ] = DEFAULT_IDE_NAME,
86
- event: Annotated[
87
- Optional[str],
88
- typer.Option(
89
- '--event',
90
- help='Hook event that triggered the scan, for IDEs whose payloads omit it (e.g. Copilot CLI).',
91
- hidden=True,
92
- ),
93
- ] = None,
94
86
  ) -> None:
95
87
  """Scan content from AI IDE hooks for secrets.
96
88
 
@@ -132,7 +124,7 @@ def scan_command(
132
124
  event_name = unified_payload.event_name
133
125
  logger.debug(
134
126
  'Processing AI guardrails hook',
135
- extra={'event_name': event_name, 'ide': ide_integration.name, 'cli_event_hint': event},
127
+ extra={'event_name': event_name, 'ide': ide_integration.name},
136
128
  )
137
129
 
138
130
  # Resolved before any policy/client work: Copilot hooks have no matchers, so
@@ -21,7 +21,7 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3.14",
22
22
  ]
23
23
  dynamic = ["dependencies"]
24
- version = "3.19.1"
24
+ version = "3.19.2.dev1"
25
25
 
26
26
  [project.scripts]
27
27
  cycode = "cycode.cli.app:app"
File without changes
File without changes
File without changes
File without changes