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.
- cicada/ascii_art.py +60 -0
- cicada/clean.py +195 -60
- cicada/cli.py +757 -0
- cicada/colors.py +27 -0
- cicada/command_logger.py +14 -16
- cicada/dead_code_analyzer.py +12 -19
- cicada/extractors/__init__.py +6 -6
- cicada/extractors/base.py +3 -3
- cicada/extractors/call.py +11 -15
- cicada/extractors/dependency.py +39 -51
- cicada/extractors/doc.py +8 -9
- cicada/extractors/function.py +12 -24
- cicada/extractors/module.py +11 -15
- cicada/extractors/spec.py +8 -12
- cicada/find_dead_code.py +15 -39
- cicada/formatter.py +37 -91
- cicada/git_helper.py +22 -34
- cicada/indexer.py +165 -132
- cicada/interactive_setup.py +490 -0
- cicada/keybert_extractor.py +286 -0
- cicada/keyword_search.py +22 -30
- cicada/keyword_test.py +127 -0
- cicada/lightweight_keyword_extractor.py +5 -13
- cicada/mcp_entry.py +683 -0
- cicada/mcp_server.py +110 -232
- cicada/parser.py +9 -9
- cicada/pr_finder.py +15 -19
- cicada/pr_indexer/__init__.py +3 -3
- cicada/pr_indexer/cli.py +4 -9
- cicada/pr_indexer/github_api_client.py +22 -37
- cicada/pr_indexer/indexer.py +17 -29
- cicada/pr_indexer/line_mapper.py +8 -12
- cicada/pr_indexer/pr_index_builder.py +22 -34
- cicada/setup.py +198 -89
- cicada/utils/__init__.py +9 -9
- cicada/utils/call_site_formatter.py +4 -6
- cicada/utils/function_grouper.py +4 -4
- cicada/utils/hash_utils.py +12 -15
- cicada/utils/index_utils.py +15 -15
- cicada/utils/path_utils.py +24 -29
- cicada/utils/signature_builder.py +3 -3
- cicada/utils/subprocess_runner.py +17 -19
- cicada/utils/text_utils.py +1 -2
- cicada/version_check.py +2 -5
- {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/METADATA +144 -55
- cicada_mcp-0.2.0.dist-info/RECORD +53 -0
- cicada_mcp-0.2.0.dist-info/entry_points.txt +4 -0
- cicada/install.py +0 -741
- cicada_mcp-0.1.5.dist-info/RECORD +0 -47
- cicada_mcp-0.1.5.dist-info/entry_points.txt +0 -9
- {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/WHEEL +0 -0
- {cicada_mcp-0.1.5.dist-info → cicada_mcp-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {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) ->
|
|
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
|
-
) ->
|
|
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:
|
|
127
|
-
end_line:
|
|
128
|
-
function_name:
|
|
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
|
-
) ->
|
|
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(
|
|
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:
|
|
243
|
-
end_line:
|
|
244
|
-
function_name:
|
|
245
|
-
) ->
|
|
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
|
-
|
|
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) ->
|
|
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) ->
|
|
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) ->
|
|
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
|
|