@@ -111,21 +111,18 @@ def test_invalid_json_stdin_skips_session_init(
111111
112112
113113@patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_claude_config' )
114- @patch ('cycode.cli.apps.ai_guardrails.session_start_command._extract_from_claude_transcript' )
115114@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
116115@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
117116def test_claude_code_creates_conversation (
118117 mock_get_auth : MagicMock ,
119118 mock_get_client : MagicMock ,
120- mock_transcript : MagicMock ,
121119 mock_load_config : MagicMock ,
122120 mock_ctx : MagicMock ,
123121) -> None :
124122 """Claude Code payload should create conversation with session_id, model, email."""
125123 mock_get_auth .return_value = MagicMock ()
126124 mock_ai_client = MagicMock ()
127125 mock_get_client .return_value = mock_ai_client
128- mock_transcript .return_value = ('1.0.0' , 'claude-sonnet' , None )
129126 mock_load_config .return_value = {'oauthAccount' : {'emailAddress' : 'user@example.com' }}
130127
131128 payload = {'session_id' : 'session-123' , 'model' : 'claude-opus' , 'transcript_path' : '/tmp/t.jsonl' }
@@ -172,13 +169,11 @@ def test_cursor_creates_conversation(
172169
173170
174171@patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_claude_config' )
175- @patch ('cycode.cli.apps.ai_guardrails.session_start_command._extract_from_claude_transcript' )
176172@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
177173@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
178174def test_conversation_creation_failure_non_blocking (
179175 mock_get_auth : MagicMock ,
180176 mock_get_client : MagicMock ,
181- mock_transcript : MagicMock ,
182177 mock_load_config : MagicMock ,
183178 mock_ctx : MagicMock ,
184179) -> None :
@@ -187,7 +182,6 @@ def test_conversation_creation_failure_non_blocking(
187182 mock_ai_client = MagicMock ()
188183 mock_ai_client .create_conversation .side_effect = RuntimeError ('API down' )
189184 mock_get_client .return_value = mock_ai_client
190- mock_transcript .return_value = (None , None , None )
191185 mock_load_config .return_value = None
192186
193187 payload = {'session_id' : 'session-123' }
@@ -202,21 +196,18 @@ def test_conversation_creation_failure_non_blocking(
202196
203197
204198@patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_claude_config' )
205- @patch ('cycode.cli.apps.ai_guardrails.session_start_command._extract_from_claude_transcript' )
206199@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
207200@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
208201def test_claude_code_reports_mcp_servers (
209202 mock_get_auth : MagicMock ,
210203 mock_get_client : MagicMock ,
211- mock_transcript : MagicMock ,
212204 mock_load_config : MagicMock ,
213205 mock_ctx : MagicMock ,
214206) -> None :
215207 """Claude Code should report MCP servers from ~/.claude.json."""
216208 mock_get_auth .return_value = MagicMock ()
217209 mock_ai_client = MagicMock ()
218210 mock_get_client .return_value = mock_ai_client
219- mock_transcript .return_value = (None , None , None )
220211 mcp_servers = {
221212 'gitlab' : {'command' : 'npx' , 'args' : ['-y' , '@modelcontextprotocol/server-gitlab' ]},
222213 'filesystem' : {'command' : 'npx' , 'args' : ['-y' , '@modelcontextprotocol/server-filesystem' ]},
@@ -232,21 +223,18 @@ def test_claude_code_reports_mcp_servers(
232223
233224
234225@patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_claude_config' )
235- @patch ('cycode.cli.apps.ai_guardrails.session_start_command._extract_from_claude_transcript' )
236226@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
237227@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
238228def test_claude_code_no_mcp_servers_skips_report (
239229 mock_get_auth : MagicMock ,
240230 mock_get_client : MagicMock ,
241- mock_transcript : MagicMock ,
242231 mock_load_config : MagicMock ,
243232 mock_ctx : MagicMock ,
244233) -> None :
245234 """When no mcpServers in config, report_data_flow should not be called."""
246235 mock_get_auth .return_value = MagicMock ()
247236 mock_ai_client = MagicMock ()
248237 mock_get_client .return_value = mock_ai_client
249- mock_transcript .return_value = (None , None , None )
250238 mock_load_config .return_value = {'oauthAccount' : {'emailAddress' : 'u@e.com' }}
251239
252240 payload = {'session_id' : 'session-123' }
@@ -257,17 +245,44 @@ def test_claude_code_no_mcp_servers_skips_report(
257245 mock_ai_client .report_data_flow .assert_not_called ()
258246
259247
248+ @patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_cursor_config' )
260249@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
261250@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
262- def test_cursor_does_not_report_mcp_servers (
251+ def test_cursor_reports_mcp_servers (
263252 mock_get_auth : MagicMock ,
264253 mock_get_client : MagicMock ,
254+ mock_load_cursor : MagicMock ,
265255 mock_ctx : MagicMock ,
266256) -> None :
267- """Cursor should not report MCP servers."""
257+ """Cursor should report MCP servers from ~/.cursor/mcp.json ."""
268258 mock_get_auth .return_value = MagicMock ()
269259 mock_ai_client = MagicMock ()
270260 mock_get_client .return_value = mock_ai_client
261+ mcp_servers = {'github' : {'command' : 'npx' , 'args' : ['-y' , '@modelcontextprotocol/server-github' ]}}
262+ mock_load_cursor .return_value = {'mcpServers' : mcp_servers }
263+
264+ payload = {'conversation_id' : 'conv-456' , 'model' : 'gpt-4' }
265+
266+ with patch ('sys.stdin' , new = StringIO (json .dumps (payload ))):
267+ session_start_command (mock_ctx , ide = 'cursor' )
268+
269+ mock_ai_client .report_data_flow .assert_called_once_with (mcp_servers )
270+
271+
272+ @patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_cursor_config' )
273+ @patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
274+ @patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
275+ def test_cursor_no_mcp_servers_skips_report (
276+ mock_get_auth : MagicMock ,
277+ mock_get_client : MagicMock ,
278+ mock_load_cursor : MagicMock ,
279+ mock_ctx : MagicMock ,
280+ ) -> None :
281+ """Cursor with no MCP config file should skip report_data_flow."""
282+ mock_get_auth .return_value = MagicMock ()
283+ mock_ai_client = MagicMock ()
284+ mock_get_client .return_value = mock_ai_client
285+ mock_load_cursor .return_value = None
271286
272287 payload = {'conversation_id' : 'conv-456' , 'model' : 'gpt-4' }
273288
@@ -278,13 +293,11 @@ def test_cursor_does_not_report_mcp_servers(
278293
279294
280295@patch ('cycode.cli.apps.ai_guardrails.session_start_command.load_claude_config' )
281- @patch ('cycode.cli.apps.ai_guardrails.session_start_command._extract_from_claude_transcript' )
282296@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_ai_security_manager_client' )
283297@patch ('cycode.cli.apps.ai_guardrails.session_start_command.get_authorization_info' )
284298def test_mcp_report_failure_non_blocking (
285299 mock_get_auth : MagicMock ,
286300 mock_get_client : MagicMock ,
287- mock_transcript : MagicMock ,
288301 mock_load_config : MagicMock ,
289302 mock_ctx : MagicMock ,
290303) -> None :
@@ -293,7 +306,6 @@ def test_mcp_report_failure_non_blocking(
293306 mock_ai_client = MagicMock ()
294307 mock_ai_client .report_data_flow .side_effect = RuntimeError ('API down' )
295308 mock_get_client .return_value = mock_ai_client
296- mock_transcript .return_value = (None , None , None )
297309 mock_load_config .return_value = {
298310 'mcpServers' : {'gitlab' : {'command' : 'npx' }},
299311 }
0 commit comments