cicada-mcp 0.1.5__py3-none-any.whl → 0.2.0__py3-none-any.whl

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 (53) hide show
  1. cicada/ascii_art.py +60 -0
  2. cicada/clean.py +195 -60
  3. cicada/cli.py +757 -0
  4. cicada/colors.py +27 -0
  5. cicada/command_logger.py +14 -16
  6. cicada/dead_code_analyzer.py +12 -19
  7. cicada/extractors/__init__.py +6 -6
  8. cicada/extractors/base.py +3 -3
  9. cicada/extractors/call.py +11 -15
  10. cicada/extractors/dependency.py +39 -51
  11. cicada/extractors/doc.py +8 -9
  12. cicada/extractors/function.py +12 -24
  13. cicada/extractors/module.py +11 -15
  14. cicada/extractors/spec.py +8 -12
  15. cicada/find_dead_code.py +15 -39
  16. cicada/formatter.py +37 -91
  17. cicada/git_helper.py +22 -34
  18. cicada/indexer.py +165 -132
  19. cicada/interactive_setup.py +490 -0
  20. cicada/keybert_extractor.py +286 -0
  21. cicada/keyword_search.py +22 -30
  22. cicada/keyword_test.py +127 -0
  23. cicada/lightweight_keyword_extractor.py +5 -13
  24. cicada/mcp_entry.py +683 -0
  25. cicada/mcp_server.py +110 -232
  26. cicada/parser.py +9 -9
  27. cicada/pr_finder.py +15 -19
  28. cicada/pr_indexer/__init__.py +3 -3
  29. cicada/pr_indexer/cli.py +4 -9
  30. cicada/pr_indexer/github_api_client.py +22 -37
  31. cicada/pr_indexer/indexer.py +17 -29
  32. cicada/pr_indexer/line_mapper.py +8 -12
  33. cicada/pr_indexer/pr_index_builder.py +22 -34
  34. cicada/setup.py +198 -89
  35. cicada/utils/__init__.py +9 -9
  36. cicada/utils/call_site_formatter.py +4 -6
  37. cicada/utils/function_grouper.py +4 -4
  38. cicada/utils/hash_utils.py +12 -15
  39. cicada/utils/index_utils.py +15 -15
  40. cicada/utils/path_utils.py +24 -29
  41. cicada/utils/signature_builder.py +3 -3
  42. cicada/utils/subprocess_runner.py +17 -19
  43. cicada/utils/text_utils.py +1 -2
  44. cicada/version_check.py +2 -5
  45. {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/METADATA +144 -55
  46. cicada_mcp-0.2.0.dist-info/RECORD +53 -0
  47. cicada_mcp-0.2.0.dist-info/entry_points.txt +4 -0
  48. cicada/install.py +0 -741
  49. cicada_mcp-0.1.5.dist-info/RECORD +0 -47
  50. cicada_mcp-0.1.5.dist-info/entry_points.txt +0 -9
  51. {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/WHEEL +0 -0
  52. {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/licenses/LICENSE +0 -0
  53. {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/top_level.txt +0 -0
cicada/git_helper.py CHANGED
@@ -8,12 +8,12 @@ offering comprehensive commit history for files and functions.
8
8
  Author: Cursor(Auto)
9
9
  """
10
10
 
11
- import git
12
11
  import subprocess
13
12
  from datetime import datetime
14
- from typing import List, Dict, Optional
15
13
  from pathlib import Path
16
14
 
15
+ import git
16
+
17
17
 
18
18
  class GitHelper:
19
19
  """Helper class for extracting git commit history"""
@@ -31,7 +31,7 @@ class GitHelper:
31
31
  self.repo = git.Repo(repo_path)
32
32
  self.repo_path = Path(repo_path)
33
33
 
34
- def get_file_history(self, file_path: str, max_commits: int = 10) -> List[Dict]:
34
+ def get_file_history(self, file_path: str, max_commits: int = 10) -> list[dict]:
35
35
  """
36
36
  Get commit history for a specific file
37
37
 
@@ -53,9 +53,7 @@ class GitHelper:
53
53
 
54
54
  try:
55
55
  # Get commits that touched this file
56
- for commit in self.repo.iter_commits(
57
- paths=file_path, max_count=max_commits
58
- ):
56
+ for commit in self.repo.iter_commits(paths=file_path, max_count=max_commits):
59
57
  commits.append(
60
58
  {
61
59
  "sha": commit.hexsha[:8], # Short SHA
@@ -78,7 +76,7 @@ class GitHelper:
78
76
  function_name: str,
79
77
  _line_number: int,
80
78
  max_commits: int = 5,
81
- ) -> List[Dict]:
79
+ ) -> list[dict]:
82
80
  """
83
81
  Get commit history for a specific function using heuristics.
84
82
 
@@ -123,11 +121,11 @@ class GitHelper:
123
121
  def get_function_history_precise(
124
122
  self,
125
123
  file_path: str,
126
- start_line: Optional[int] = None,
127
- end_line: Optional[int] = None,
128
- function_name: Optional[str] = None,
124
+ start_line: int | None = None,
125
+ end_line: int | None = None,
126
+ function_name: str | None = None,
129
127
  max_commits: int = 5,
130
- ) -> List[Dict]:
128
+ ) -> list[dict]:
131
129
  """
132
130
  Get precise commit history for a function using git log -L.
133
131
 
@@ -158,14 +156,13 @@ class GitHelper:
158
156
  - Requires .gitattributes with "*.ex diff=elixir" for function tracking
159
157
  """
160
158
  commits = []
161
- import subprocess
162
159
 
163
160
  # Determine tracking mode
164
161
  use_function_tracking = function_name is not None
165
162
  use_line_tracking = start_line is not None and end_line is not None
166
163
 
167
164
  if not use_function_tracking and not use_line_tracking:
168
- print(f"Error: Must provide either function_name or (start_line, end_line)")
165
+ print("Error: Must provide either function_name or (start_line, end_line)")
169
166
  return []
170
167
 
171
168
  try:
@@ -239,10 +236,10 @@ class GitHelper:
239
236
  def get_function_evolution(
240
237
  self,
241
238
  file_path: str,
242
- start_line: Optional[int] = None,
243
- end_line: Optional[int] = None,
244
- function_name: Optional[str] = None,
245
- ) -> Optional[Dict]:
239
+ start_line: int | None = None,
240
+ end_line: int | None = None,
241
+ function_name: str | None = None,
242
+ ) -> dict | None:
246
243
  """
247
244
  Get evolution metadata for a function (creation, last modification, change count).
248
245
 
@@ -297,9 +294,7 @@ class GitHelper:
297
294
  if days_between > 0:
298
295
  months = days_between / 30.0
299
296
  modification_frequency = (
300
- total_modifications / months
301
- if months > 0
302
- else total_modifications
297
+ total_modifications / months if months > 0 else total_modifications
303
298
  )
304
299
  except Exception:
305
300
  # If date parsing fails, skip frequency calculation
@@ -330,9 +325,7 @@ class GitHelper:
330
325
  print(f"Error getting function evolution for {file_path}: {e}")
331
326
  return None
332
327
 
333
- def get_function_history(
334
- self, file_path: str, start_line: int, end_line: int
335
- ) -> List[Dict]:
328
+ def get_function_history(self, file_path: str, start_line: int, end_line: int) -> list[dict]:
336
329
  """
337
330
  Get line-by-line authorship for a function using git blame.
338
331
 
@@ -357,7 +350,6 @@ class GitHelper:
357
350
  - lines: List of {number, content} for each line
358
351
  """
359
352
  blame_groups = []
360
- import subprocess
361
353
 
362
354
  try:
363
355
  # Use git blame with line range
@@ -401,10 +393,8 @@ class GitHelper:
401
393
  elif line.startswith("author-time "):
402
394
  try:
403
395
  timestamp = int(line[12:])
404
- current_commit["date"] = datetime.fromtimestamp(
405
- timestamp
406
- ).isoformat()
407
- except:
396
+ current_commit["date"] = datetime.fromtimestamp(timestamp).isoformat()
397
+ except (ValueError, OSError):
408
398
  current_commit["date"] = line[12:]
409
399
  # Actual code line (starts with tab)
410
400
  elif line.startswith("\t"):
@@ -469,9 +459,7 @@ class GitHelper:
469
459
 
470
460
  except subprocess.CalledProcessError as e:
471
461
  error_msg = e.stderr if e.stderr else str(e)
472
- print(
473
- f"Warning: git blame failed for {file_path}:{start_line}-{end_line}: {error_msg}"
474
- )
462
+ print(f"Warning: git blame failed for {file_path}:{start_line}-{end_line}: {error_msg}")
475
463
  return []
476
464
  except Exception as e:
477
465
  print(f"Error getting blame for {file_path}: {e}")
@@ -479,7 +467,7 @@ class GitHelper:
479
467
 
480
468
  return blame_groups
481
469
 
482
- def get_recent_commits(self, max_count: int = 20) -> List[Dict]:
470
+ def get_recent_commits(self, max_count: int = 20) -> list[dict]:
483
471
  """
484
472
  Get recent commits in the repository
485
473
 
@@ -512,7 +500,7 @@ class GitHelper:
512
500
 
513
501
  return commits
514
502
 
515
- def get_commit_details(self, commit_sha: str) -> Optional[Dict]:
503
+ def get_commit_details(self, commit_sha: str) -> dict | None:
516
504
  """
517
505
  Get detailed information about a specific commit
518
506
 
@@ -560,7 +548,7 @@ class GitHelper:
560
548
  print(f"Error getting commit {commit_sha}: {e}")
561
549
  return None
562
550
 
563
- def search_commits(self, query: str, max_results: int = 10) -> List[Dict]:
551
+ def search_commits(self, query: str, max_results: int = 10) -> list[dict]:
564
552
  """
565
553
  Search commit messages for a query string
566
554