From d0cd19cc623de529cd61d19e88fc9fe311b3558e Mon Sep 17 00:00:00 2001 From: Ilan Lidovski Date: Wed, 11 Feb 2026 20:46:44 +0200 Subject: [PATCH 1/2] CM-59486-fix-hook-auth-error-message --- cycode/cli/apps/ai_guardrails/scan/scan_command.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cycode/cli/apps/ai_guardrails/scan/scan_command.py b/cycode/cli/apps/ai_guardrails/scan/scan_command.py index fe1c74a3..add2bb83 100644 --- a/cycode/cli/apps/ai_guardrails/scan/scan_command.py +++ b/cycode/cli/apps/ai_guardrails/scan/scan_command.py @@ -34,17 +34,17 @@ def _get_auth_error_message(error: Exception) -> str: """Get user-friendly message for authentication errors.""" if isinstance(error, click.ClickException): # Missing credentials - return f'{error.message} Please run `cycode configure` to set up your credentials.' + return f'{error.message} Please run `cycode auth` to set up your credentials.' if isinstance(error, HttpUnauthorizedError): # Invalid/expired credentials return ( 'Unable to authenticate to Cycode. Your credentials are invalid or have expired. ' - 'Please run `cycode configure` to update your credentials.' + 'Please run `cycode auth` to update your credentials.' ) # Fallback - return 'Authentication failed. Please run `cycode configure` to set up your credentials.' + return 'Authentication failed. Please run `cycode auth` to set up your credentials.' def _initialize_clients(ctx: typer.Context) -> None: From 3e9773c2dcee6a2e24a61a8b2fe2bafd6fb83311 Mon Sep 17 00:00:00 2001 From: Ilan Lidovski Date: Wed, 18 Feb 2026 16:18:32 +0200 Subject: [PATCH 2/2] CM-59792-read-file-hook-save-file-path --- cycode/cli/apps/ai_guardrails/scan/handlers.py | 1 + cycode/cyclient/ai_security_manager_client.py | 2 ++ tests/cli/commands/ai_guardrails/scan/test_handlers.py | 3 +++ 3 files changed, 6 insertions(+) diff --git a/cycode/cli/apps/ai_guardrails/scan/handlers.py b/cycode/cli/apps/ai_guardrails/scan/handlers.py index 32be1241..2a762a8d 100644 --- a/cycode/cli/apps/ai_guardrails/scan/handlers.py +++ b/cycode/cli/apps/ai_guardrails/scan/handlers.py @@ -170,6 +170,7 @@ def handle_before_read_file(ctx: typer.Context, payload: AIHookPayload, policy: scan_id=scan_id, block_reason=block_reason, error_message=error_message, + file_path=payload.file_path, ) diff --git a/cycode/cyclient/ai_security_manager_client.py b/cycode/cyclient/ai_security_manager_client.py index 1090ad8d..35c1d8c9 100644 --- a/cycode/cyclient/ai_security_manager_client.py +++ b/cycode/cyclient/ai_security_manager_client.py @@ -62,6 +62,7 @@ def create_event( scan_id: Optional[str] = None, block_reason: Optional['BlockReason'] = None, error_message: Optional[str] = None, + file_path: Optional[str] = None, ) -> None: """Create an AI hook event from hook payload.""" conversation_id = payload.conversation_id @@ -79,6 +80,7 @@ def create_event( 'mcp_server_name': payload.mcp_server_name, 'mcp_tool_name': payload.mcp_tool_name, 'error_message': error_message, + 'file_path': file_path, } try: diff --git a/tests/cli/commands/ai_guardrails/scan/test_handlers.py b/tests/cli/commands/ai_guardrails/scan/test_handlers.py index 634469b7..1adfe25b 100644 --- a/tests/cli/commands/ai_guardrails/scan/test_handlers.py +++ b/tests/cli/commands/ai_guardrails/scan/test_handlers.py @@ -194,6 +194,7 @@ def test_handle_before_read_file_sensitive_path( call_args = mock_ctx.obj['ai_security_client'].create_event.call_args assert call_args.args[2] == AIHookOutcome.BLOCKED assert call_args.kwargs['block_reason'] == BlockReason.SENSITIVE_PATH + assert call_args.kwargs['file_path'] == '/path/to/.env' @patch('cycode.cli.apps.ai_guardrails.scan.handlers.is_denied_path') @@ -215,6 +216,7 @@ def test_handle_before_read_file_no_secrets( assert result == {'permission': 'allow'} call_args = mock_ctx.obj['ai_security_client'].create_event.call_args assert call_args.args[2] == AIHookOutcome.ALLOWED + assert call_args.kwargs['file_path'] == '/path/to/file.txt' @patch('cycode.cli.apps.ai_guardrails.scan.handlers.is_denied_path') @@ -238,6 +240,7 @@ def test_handle_before_read_file_with_secrets( call_args = mock_ctx.obj['ai_security_client'].create_event.call_args assert call_args.args[2] == AIHookOutcome.BLOCKED assert call_args.kwargs['block_reason'] == BlockReason.SECRETS_IN_FILE + assert call_args.kwargs['file_path'] == '/path/to/file.txt' @patch('cycode.cli.apps.ai_guardrails.scan.handlers.is_denied_path')