jarvis-ai-assistant 0.7.8__py3-none-any.whl → 1.0.2__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +567 -222
- jarvis/jarvis_agent/agent_manager.py +19 -12
- jarvis/jarvis_agent/builtin_input_handler.py +79 -11
- jarvis/jarvis_agent/config_editor.py +7 -2
- jarvis/jarvis_agent/event_bus.py +24 -13
- jarvis/jarvis_agent/events.py +19 -1
- jarvis/jarvis_agent/file_context_handler.py +67 -64
- jarvis/jarvis_agent/file_methodology_manager.py +38 -24
- jarvis/jarvis_agent/jarvis.py +186 -114
- jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
- jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
- jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
- jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
- jarvis/jarvis_agent/language_support_info.py +250 -219
- jarvis/jarvis_agent/main.py +19 -23
- jarvis/jarvis_agent/memory_manager.py +9 -6
- jarvis/jarvis_agent/methodology_share_manager.py +21 -15
- jarvis/jarvis_agent/output_handler.py +4 -2
- jarvis/jarvis_agent/prompt_builder.py +7 -6
- jarvis/jarvis_agent/prompt_manager.py +113 -8
- jarvis/jarvis_agent/prompts.py +317 -85
- jarvis/jarvis_agent/protocols.py +5 -2
- jarvis/jarvis_agent/run_loop.py +192 -32
- jarvis/jarvis_agent/session_manager.py +7 -3
- jarvis/jarvis_agent/share_manager.py +23 -13
- jarvis/jarvis_agent/shell_input_handler.py +12 -8
- jarvis/jarvis_agent/stdio_redirect.py +25 -26
- jarvis/jarvis_agent/task_analyzer.py +29 -23
- jarvis/jarvis_agent/task_list.py +869 -0
- jarvis/jarvis_agent/task_manager.py +26 -23
- jarvis/jarvis_agent/tool_executor.py +6 -5
- jarvis/jarvis_agent/tool_share_manager.py +24 -14
- jarvis/jarvis_agent/user_interaction.py +3 -3
- jarvis/jarvis_agent/utils.py +9 -1
- jarvis/jarvis_agent/web_bridge.py +37 -17
- jarvis/jarvis_agent/web_output_sink.py +5 -2
- jarvis/jarvis_agent/web_server.py +165 -36
- jarvis/jarvis_c2rust/__init__.py +1 -1
- jarvis/jarvis_c2rust/cli.py +260 -141
- jarvis/jarvis_c2rust/collector.py +37 -18
- jarvis/jarvis_c2rust/constants.py +60 -0
- jarvis/jarvis_c2rust/library_replacer.py +242 -1010
- jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
- jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
- jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
- jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
- jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
- jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
- jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
- jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
- jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
- jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
- jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
- jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
- jarvis/jarvis_c2rust/loaders.py +28 -10
- jarvis/jarvis_c2rust/models.py +5 -2
- jarvis/jarvis_c2rust/optimizer.py +192 -1974
- jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
- jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
- jarvis/jarvis_c2rust/optimizer_config.py +49 -0
- jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
- jarvis/jarvis_c2rust/optimizer_options.py +48 -0
- jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
- jarvis/jarvis_c2rust/optimizer_report.py +52 -0
- jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
- jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
- jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
- jarvis/jarvis_c2rust/scanner.py +229 -166
- jarvis/jarvis_c2rust/transpiler.py +531 -2732
- jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
- jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
- jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
- jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
- jarvis/jarvis_c2rust/transpiler_config.py +178 -0
- jarvis/jarvis_c2rust/transpiler_context.py +122 -0
- jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
- jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
- jarvis/jarvis_c2rust/transpiler_git.py +163 -0
- jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
- jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
- jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
- jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
- jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
- jarvis/jarvis_c2rust/utils.py +269 -79
- jarvis/jarvis_code_agent/after_change.py +233 -0
- jarvis/jarvis_code_agent/build_validation_config.py +37 -30
- jarvis/jarvis_code_agent/builtin_rules.py +68 -0
- jarvis/jarvis_code_agent/code_agent.py +976 -1517
- jarvis/jarvis_code_agent/code_agent_build.py +227 -0
- jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
- jarvis/jarvis_code_agent/code_agent_git.py +525 -0
- jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
- jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
- jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
- jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
- jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
- jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
- jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
- jarvis/jarvis_code_agent/lint.py +223 -524
- jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
- jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
- jarvis/jarvis_code_agent/rules/code_review.md +115 -0
- jarvis/jarvis_code_agent/rules/documentation.md +165 -0
- jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
- jarvis/jarvis_code_agent/rules/performance.md +158 -0
- jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
- jarvis/jarvis_code_agent/rules/security.md +160 -0
- jarvis/jarvis_code_agent/rules/tdd.md +78 -0
- jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
- jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
- jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
- jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
- jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
- jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
- jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
- jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
- jarvis/jarvis_code_agent/utils.py +36 -26
- jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
- jarvis/jarvis_code_analysis/code_review.py +64 -33
- jarvis/jarvis_data/config_schema.json +285 -192
- jarvis/jarvis_git_squash/main.py +8 -6
- jarvis/jarvis_git_utils/git_commiter.py +53 -76
- jarvis/jarvis_mcp/__init__.py +5 -2
- jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
- jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
- jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
- jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
- jarvis/jarvis_methodology/main.py +48 -39
- jarvis/jarvis_multi_agent/__init__.py +56 -23
- jarvis/jarvis_multi_agent/main.py +15 -18
- jarvis/jarvis_platform/base.py +179 -111
- jarvis/jarvis_platform/human.py +27 -16
- jarvis/jarvis_platform/kimi.py +52 -45
- jarvis/jarvis_platform/openai.py +101 -40
- jarvis/jarvis_platform/registry.py +51 -33
- jarvis/jarvis_platform/tongyi.py +68 -38
- jarvis/jarvis_platform/yuanbao.py +59 -43
- jarvis/jarvis_platform_manager/main.py +68 -76
- jarvis/jarvis_platform_manager/service.py +24 -14
- jarvis/jarvis_rag/README_CONFIG.md +314 -0
- jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
- jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
- jarvis/jarvis_rag/__init__.py +57 -4
- jarvis/jarvis_rag/cache.py +3 -1
- jarvis/jarvis_rag/cli.py +48 -68
- jarvis/jarvis_rag/embedding_interface.py +39 -0
- jarvis/jarvis_rag/embedding_manager.py +7 -230
- jarvis/jarvis_rag/embeddings/__init__.py +41 -0
- jarvis/jarvis_rag/embeddings/base.py +114 -0
- jarvis/jarvis_rag/embeddings/cohere.py +66 -0
- jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
- jarvis/jarvis_rag/embeddings/local.py +260 -0
- jarvis/jarvis_rag/embeddings/openai.py +62 -0
- jarvis/jarvis_rag/embeddings/registry.py +293 -0
- jarvis/jarvis_rag/llm_interface.py +8 -6
- jarvis/jarvis_rag/query_rewriter.py +8 -9
- jarvis/jarvis_rag/rag_pipeline.py +61 -52
- jarvis/jarvis_rag/reranker.py +7 -75
- jarvis/jarvis_rag/reranker_interface.py +32 -0
- jarvis/jarvis_rag/rerankers/__init__.py +41 -0
- jarvis/jarvis_rag/rerankers/base.py +109 -0
- jarvis/jarvis_rag/rerankers/cohere.py +67 -0
- jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
- jarvis/jarvis_rag/rerankers/jina.py +79 -0
- jarvis/jarvis_rag/rerankers/local.py +89 -0
- jarvis/jarvis_rag/rerankers/registry.py +293 -0
- jarvis/jarvis_rag/retriever.py +58 -43
- jarvis/jarvis_sec/__init__.py +66 -141
- jarvis/jarvis_sec/agents.py +21 -17
- jarvis/jarvis_sec/analysis.py +80 -33
- jarvis/jarvis_sec/checkers/__init__.py +7 -13
- jarvis/jarvis_sec/checkers/c_checker.py +356 -164
- jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
- jarvis/jarvis_sec/cli.py +43 -21
- jarvis/jarvis_sec/clustering.py +430 -272
- jarvis/jarvis_sec/file_manager.py +99 -55
- jarvis/jarvis_sec/parsers.py +9 -6
- jarvis/jarvis_sec/prompts.py +4 -3
- jarvis/jarvis_sec/report.py +44 -22
- jarvis/jarvis_sec/review.py +180 -107
- jarvis/jarvis_sec/status.py +50 -41
- jarvis/jarvis_sec/types.py +3 -0
- jarvis/jarvis_sec/utils.py +160 -83
- jarvis/jarvis_sec/verification.py +411 -181
- jarvis/jarvis_sec/workflow.py +132 -21
- jarvis/jarvis_smart_shell/main.py +28 -41
- jarvis/jarvis_stats/cli.py +14 -12
- jarvis/jarvis_stats/stats.py +28 -19
- jarvis/jarvis_stats/storage.py +14 -8
- jarvis/jarvis_stats/visualizer.py +12 -7
- jarvis/jarvis_tools/base.py +5 -2
- jarvis/jarvis_tools/clear_memory.py +13 -9
- jarvis/jarvis_tools/cli/main.py +23 -18
- jarvis/jarvis_tools/edit_file.py +572 -873
- jarvis/jarvis_tools/execute_script.py +10 -7
- jarvis/jarvis_tools/file_analyzer.py +7 -8
- jarvis/jarvis_tools/meta_agent.py +287 -0
- jarvis/jarvis_tools/methodology.py +5 -3
- jarvis/jarvis_tools/read_code.py +305 -1438
- jarvis/jarvis_tools/read_symbols.py +50 -17
- jarvis/jarvis_tools/read_webpage.py +19 -18
- jarvis/jarvis_tools/registry.py +435 -156
- jarvis/jarvis_tools/retrieve_memory.py +16 -11
- jarvis/jarvis_tools/save_memory.py +8 -6
- jarvis/jarvis_tools/search_web.py +31 -31
- jarvis/jarvis_tools/sub_agent.py +32 -28
- jarvis/jarvis_tools/sub_code_agent.py +44 -60
- jarvis/jarvis_tools/task_list_manager.py +1811 -0
- jarvis/jarvis_tools/virtual_tty.py +29 -19
- jarvis/jarvis_utils/__init__.py +4 -0
- jarvis/jarvis_utils/builtin_replace_map.py +2 -1
- jarvis/jarvis_utils/clipboard.py +9 -8
- jarvis/jarvis_utils/collections.py +331 -0
- jarvis/jarvis_utils/config.py +699 -194
- jarvis/jarvis_utils/dialogue_recorder.py +294 -0
- jarvis/jarvis_utils/embedding.py +6 -3
- jarvis/jarvis_utils/file_processors.py +7 -1
- jarvis/jarvis_utils/fzf.py +9 -3
- jarvis/jarvis_utils/git_utils.py +71 -42
- jarvis/jarvis_utils/globals.py +116 -32
- jarvis/jarvis_utils/http.py +6 -2
- jarvis/jarvis_utils/input.py +318 -83
- jarvis/jarvis_utils/jsonnet_compat.py +119 -104
- jarvis/jarvis_utils/methodology.py +37 -28
- jarvis/jarvis_utils/output.py +201 -44
- jarvis/jarvis_utils/utils.py +986 -628
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
- jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
- jarvis/jarvis_tools/generate_new_tool.py +0 -205
- jarvis/jarvis_tools/lsp_client.py +0 -1552
- jarvis/jarvis_tools/rewrite_file.py +0 -105
- jarvis_ai_assistant-0.7.8.dist-info/RECORD +0 -218
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -5,21 +5,26 @@
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import subprocess
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import Any
|
|
9
|
+
from typing import Dict
|
|
10
|
+
from typing import List
|
|
11
|
+
from typing import Optional
|
|
9
12
|
|
|
10
13
|
from jarvis.jarvis_utils.git_utils import get_recent_commits_with_files
|
|
11
14
|
from jarvis.jarvis_utils.utils import get_loc_stats
|
|
12
15
|
|
|
13
16
|
|
|
14
|
-
def get_git_tracked_files_info(
|
|
17
|
+
def get_git_tracked_files_info(
|
|
18
|
+
project_root: str, max_files: int = 100
|
|
19
|
+
) -> Optional[str]:
|
|
15
20
|
"""获取git托管的文件列表或目录结构
|
|
16
|
-
|
|
21
|
+
|
|
17
22
|
如果文件数量超过max_files,则返回目录结构(不含文件)
|
|
18
|
-
|
|
23
|
+
|
|
19
24
|
参数:
|
|
20
25
|
project_root: 项目根目录
|
|
21
26
|
max_files: 文件数量阈值,超过此值则返回目录结构
|
|
22
|
-
|
|
27
|
+
|
|
23
28
|
返回:
|
|
24
29
|
str: 文件列表或目录结构的字符串表示,失败时返回None
|
|
25
30
|
"""
|
|
@@ -34,16 +39,18 @@ def get_git_tracked_files_info(project_root: str, max_files: int = 100) -> Optio
|
|
|
34
39
|
check=True,
|
|
35
40
|
cwd=project_root,
|
|
36
41
|
)
|
|
37
|
-
|
|
42
|
+
|
|
38
43
|
if result.returncode != 0 or not result.stdout.strip():
|
|
39
44
|
return None
|
|
40
|
-
|
|
41
|
-
files = [
|
|
45
|
+
|
|
46
|
+
files = [
|
|
47
|
+
line.strip() for line in result.stdout.strip().splitlines() if line.strip()
|
|
48
|
+
]
|
|
42
49
|
file_count = len(files)
|
|
43
|
-
|
|
50
|
+
|
|
44
51
|
if file_count == 0:
|
|
45
52
|
return None
|
|
46
|
-
|
|
53
|
+
|
|
47
54
|
# 如果文件数量超过阈值,返回目录结构
|
|
48
55
|
if file_count > max_files:
|
|
49
56
|
# 提取所有目录路径
|
|
@@ -55,9 +62,9 @@ def get_git_tracked_files_info(project_root: str, max_files: int = 100) -> Optio
|
|
|
55
62
|
dir_path = "/".join(parts[:i])
|
|
56
63
|
if dir_path:
|
|
57
64
|
dirs.add(dir_path)
|
|
58
|
-
|
|
65
|
+
|
|
59
66
|
# 构建树形目录结构
|
|
60
|
-
dir_tree = {}
|
|
67
|
+
dir_tree: Dict[str, Any] = {}
|
|
61
68
|
for dir_path in sorted(dirs):
|
|
62
69
|
parts = dir_path.split("/")
|
|
63
70
|
current = dir_tree
|
|
@@ -65,8 +72,10 @@ def get_git_tracked_files_info(project_root: str, max_files: int = 100) -> Optio
|
|
|
65
72
|
if part not in current:
|
|
66
73
|
current[part] = {}
|
|
67
74
|
current = current[part]
|
|
68
|
-
|
|
69
|
-
def format_tree(
|
|
75
|
+
|
|
76
|
+
def format_tree(
|
|
77
|
+
tree: dict, prefix: str = "", is_last: bool = True
|
|
78
|
+
) -> List[str]:
|
|
70
79
|
"""格式化目录树"""
|
|
71
80
|
lines = []
|
|
72
81
|
items = sorted(tree.items())
|
|
@@ -74,19 +83,21 @@ def get_git_tracked_files_info(project_root: str, max_files: int = 100) -> Optio
|
|
|
74
83
|
is_last_item = i == len(items) - 1
|
|
75
84
|
connector = "└── " if is_last_item else "├── "
|
|
76
85
|
lines.append(f"{prefix}{connector}{name}/")
|
|
77
|
-
|
|
86
|
+
|
|
78
87
|
extension = " " if is_last_item else "│ "
|
|
79
88
|
if subtree:
|
|
80
|
-
lines.extend(
|
|
89
|
+
lines.extend(
|
|
90
|
+
format_tree(subtree, prefix + extension, is_last_item)
|
|
91
|
+
)
|
|
81
92
|
return lines
|
|
82
|
-
|
|
93
|
+
|
|
83
94
|
tree_lines = format_tree(dir_tree)
|
|
84
95
|
return f"Git托管目录结构(共{file_count}个文件):\n" + "\n".join(tree_lines)
|
|
85
96
|
else:
|
|
86
97
|
# 文件数量不多,直接返回文件列表
|
|
87
98
|
files_str = "\n".join(f" - {file}" for file in sorted(files))
|
|
88
99
|
return f"Git托管文件列表(共{file_count}个文件):\n{files_str}"
|
|
89
|
-
|
|
100
|
+
|
|
90
101
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
91
102
|
return None
|
|
92
103
|
except Exception:
|
|
@@ -96,15 +107,15 @@ def get_git_tracked_files_info(project_root: str, max_files: int = 100) -> Optio
|
|
|
96
107
|
|
|
97
108
|
def get_project_overview(project_root: str) -> str:
|
|
98
109
|
"""获取项目概况信息
|
|
99
|
-
|
|
110
|
+
|
|
100
111
|
参数:
|
|
101
112
|
project_root: 项目根目录
|
|
102
|
-
|
|
113
|
+
|
|
103
114
|
返回:
|
|
104
115
|
项目概况字符串
|
|
105
116
|
"""
|
|
106
117
|
project_info = []
|
|
107
|
-
|
|
118
|
+
|
|
108
119
|
# 获取代码统计
|
|
109
120
|
try:
|
|
110
121
|
loc_stats = get_loc_stats()
|
|
@@ -112,7 +123,7 @@ def get_project_overview(project_root: str) -> str:
|
|
|
112
123
|
project_info.append(f"代码统计:\n{loc_stats}")
|
|
113
124
|
except Exception:
|
|
114
125
|
pass
|
|
115
|
-
|
|
126
|
+
|
|
116
127
|
# 获取Git托管的文件信息
|
|
117
128
|
try:
|
|
118
129
|
git_files_info = get_git_tracked_files_info(project_root)
|
|
@@ -120,13 +131,13 @@ def get_project_overview(project_root: str) -> str:
|
|
|
120
131
|
project_info.append(git_files_info)
|
|
121
132
|
except Exception:
|
|
122
133
|
pass
|
|
123
|
-
|
|
134
|
+
|
|
124
135
|
# 获取最近提交信息
|
|
125
136
|
try:
|
|
126
137
|
commits_info = get_recent_commits_with_files()
|
|
127
138
|
if commits_info:
|
|
128
139
|
commits_str = "\n".join(
|
|
129
|
-
f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n"
|
|
140
|
+
f"提交 {i + 1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n"
|
|
130
141
|
+ "\n".join(f" - {file}" for file in commit["files"][:5])
|
|
131
142
|
+ ("\n ..." if len(commit["files"]) > 5 else "")
|
|
132
143
|
for i, commit in enumerate(commits_info[:5])
|
|
@@ -134,8 +145,7 @@ def get_project_overview(project_root: str) -> str:
|
|
|
134
145
|
project_info.append(f"最近提交:\n{commits_str}")
|
|
135
146
|
except Exception:
|
|
136
147
|
pass
|
|
137
|
-
|
|
148
|
+
|
|
138
149
|
if project_info:
|
|
139
150
|
return "项目概况:\n" + "\n\n".join(project_info)
|
|
140
151
|
return ""
|
|
141
|
-
|
|
@@ -2,29 +2,29 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Utility module for loading language-specific code review checklists.
|
|
4
4
|
"""
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
from typing import Dict
|
|
7
|
+
from typing import Optional
|
|
6
8
|
|
|
7
9
|
# Import checklist modules
|
|
8
|
-
from jarvis.jarvis_code_analysis.checklists import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
web,
|
|
27
|
-
)
|
|
10
|
+
from jarvis.jarvis_code_analysis.checklists import c_cpp
|
|
11
|
+
from jarvis.jarvis_code_analysis.checklists import csharp
|
|
12
|
+
from jarvis.jarvis_code_analysis.checklists import data_format
|
|
13
|
+
from jarvis.jarvis_code_analysis.checklists import devops
|
|
14
|
+
from jarvis.jarvis_code_analysis.checklists import docs
|
|
15
|
+
from jarvis.jarvis_code_analysis.checklists import go
|
|
16
|
+
from jarvis.jarvis_code_analysis.checklists import infrastructure
|
|
17
|
+
from jarvis.jarvis_code_analysis.checklists import java
|
|
18
|
+
from jarvis.jarvis_code_analysis.checklists import javascript
|
|
19
|
+
from jarvis.jarvis_code_analysis.checklists import kotlin
|
|
20
|
+
from jarvis.jarvis_code_analysis.checklists import php
|
|
21
|
+
from jarvis.jarvis_code_analysis.checklists import python
|
|
22
|
+
from jarvis.jarvis_code_analysis.checklists import ruby
|
|
23
|
+
from jarvis.jarvis_code_analysis.checklists import rust
|
|
24
|
+
from jarvis.jarvis_code_analysis.checklists import shell
|
|
25
|
+
from jarvis.jarvis_code_analysis.checklists import sql
|
|
26
|
+
from jarvis.jarvis_code_analysis.checklists import swift
|
|
27
|
+
from jarvis.jarvis_code_analysis.checklists import web
|
|
28
28
|
|
|
29
29
|
# Map of language identifiers to their checklist content
|
|
30
30
|
CHECKLIST_MAP = {
|
|
@@ -3,18 +3,22 @@ import os
|
|
|
3
3
|
import re
|
|
4
4
|
import subprocess
|
|
5
5
|
import tempfile
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing import Dict
|
|
8
|
+
from typing import List
|
|
9
|
+
from typing import Optional
|
|
7
10
|
|
|
8
11
|
import typer
|
|
9
12
|
|
|
10
13
|
from jarvis.jarvis_agent import Agent
|
|
11
14
|
from jarvis.jarvis_code_analysis.checklists.loader import get_language_checklist
|
|
12
|
-
|
|
13
15
|
from jarvis.jarvis_tools.read_code import ReadCodeTool
|
|
14
|
-
|
|
15
|
-
from jarvis.jarvis_utils.output import
|
|
16
|
-
from jarvis.jarvis_utils.tag import ct
|
|
17
|
-
from jarvis.jarvis_utils.
|
|
16
|
+
from jarvis.jarvis_utils.output import OutputType # 保留用于语法高亮
|
|
17
|
+
from jarvis.jarvis_utils.output import PrettyOutput
|
|
18
|
+
from jarvis.jarvis_utils.tag import ct
|
|
19
|
+
from jarvis.jarvis_utils.tag import ot
|
|
20
|
+
from jarvis.jarvis_utils.utils import init_env
|
|
21
|
+
from jarvis.jarvis_utils.utils import is_context_overflow
|
|
18
22
|
|
|
19
23
|
app = typer.Typer(help="自动代码审查工具")
|
|
20
24
|
|
|
@@ -282,9 +286,13 @@ def execute_code_review(
|
|
|
282
286
|
# Extract changed files using git command
|
|
283
287
|
files_cmd = f"git show --name-only --pretty=format: {commit_sha}"
|
|
284
288
|
try:
|
|
285
|
-
files_output = subprocess.check_output(
|
|
289
|
+
files_output = subprocess.check_output(
|
|
290
|
+
files_cmd, shell=True, text=True
|
|
291
|
+
)
|
|
286
292
|
# Filter out empty lines without using grep
|
|
287
|
-
file_paths = [
|
|
293
|
+
file_paths = [
|
|
294
|
+
f.strip() for f in files_output.split("\n") if f.strip()
|
|
295
|
+
]
|
|
288
296
|
except subprocess.CalledProcessError:
|
|
289
297
|
# Fallback to regex extraction if git command fails
|
|
290
298
|
file_pattern = r"diff --git a/.*?\s+b/(.*?)(\n|$)"
|
|
@@ -320,8 +328,12 @@ def execute_code_review(
|
|
|
320
328
|
# Extract changed files using git command
|
|
321
329
|
files_cmd = f"git diff --name-only {start_commit}..{end_commit}"
|
|
322
330
|
try:
|
|
323
|
-
files_output = subprocess.check_output(
|
|
324
|
-
|
|
331
|
+
files_output = subprocess.check_output(
|
|
332
|
+
files_cmd, shell=True, text=True
|
|
333
|
+
)
|
|
334
|
+
file_paths = [
|
|
335
|
+
f.strip() for f in files_output.split("\n") if f.strip()
|
|
336
|
+
]
|
|
325
337
|
except subprocess.CalledProcessError:
|
|
326
338
|
# Fallback to regex extraction if git command fails
|
|
327
339
|
file_pattern = r"diff --git a/.*?\s+b/(.*?)(\n|$)"
|
|
@@ -337,7 +349,9 @@ def execute_code_review(
|
|
|
337
349
|
}
|
|
338
350
|
file_path = args["file_path"].strip()
|
|
339
351
|
file_paths = [file_path]
|
|
340
|
-
diff_output = ReadCodeTool().execute({"files": [{"path": file_path}]})[
|
|
352
|
+
diff_output = ReadCodeTool().execute({"files": [{"path": file_path}]})[
|
|
353
|
+
"stdout"
|
|
354
|
+
]
|
|
341
355
|
|
|
342
356
|
else: # current changes
|
|
343
357
|
diff_cmd = "git diff HEAD | cat -"
|
|
@@ -360,8 +374,12 @@ def execute_code_review(
|
|
|
360
374
|
# Extract changed files using git command
|
|
361
375
|
files_cmd = "git diff --name-only HEAD"
|
|
362
376
|
try:
|
|
363
|
-
files_output = subprocess.check_output(
|
|
364
|
-
|
|
377
|
+
files_output = subprocess.check_output(
|
|
378
|
+
files_cmd, shell=True, text=True
|
|
379
|
+
)
|
|
380
|
+
file_paths = [
|
|
381
|
+
f.strip() for f in files_output.split("\n") if f.strip()
|
|
382
|
+
]
|
|
365
383
|
except subprocess.CalledProcessError:
|
|
366
384
|
# Fallback to regex extraction if git command fails
|
|
367
385
|
file_pattern = r"diff --git a/.*?\s+b/(.*?)(\n|$)"
|
|
@@ -408,7 +426,9 @@ def execute_code_review(
|
|
|
408
426
|
# Combine review info with diff output
|
|
409
427
|
diff_output = review_info + diff_output
|
|
410
428
|
|
|
411
|
-
PrettyOutput.print(
|
|
429
|
+
PrettyOutput.print(
|
|
430
|
+
diff_output, OutputType.CODE, lang="diff"
|
|
431
|
+
) # 保留语法高亮
|
|
412
432
|
|
|
413
433
|
system_prompt = """<code_review_guide>
|
|
414
434
|
<role>
|
|
@@ -542,7 +562,6 @@ def execute_code_review(
|
|
|
542
562
|
# Get model_group from args (thinking mode removed)
|
|
543
563
|
model_group = args.get("model_group")
|
|
544
564
|
|
|
545
|
-
|
|
546
565
|
agent = Agent(
|
|
547
566
|
system_prompt=system_prompt,
|
|
548
567
|
name="Code Review Agent",
|
|
@@ -621,7 +640,9 @@ def execute_code_review(
|
|
|
621
640
|
max_diff_size = 100 * 1024 * 1024 # Limit to 100MB
|
|
622
641
|
|
|
623
642
|
if len(diff_output) > max_diff_size:
|
|
624
|
-
|
|
643
|
+
PrettyOutput.auto_print(
|
|
644
|
+
f"⚠️ 代码差异内容总大小超过限制 ({len(diff_output)} > {max_diff_size} 字节),将截断内容"
|
|
645
|
+
)
|
|
625
646
|
diff_output = (
|
|
626
647
|
diff_output[:max_diff_size]
|
|
627
648
|
+ "\n\n[diff content truncated due to size limitations...]"
|
|
@@ -633,12 +654,14 @@ def execute_code_review(
|
|
|
633
654
|
代码信息:
|
|
634
655
|
- 审查类型: {review_type}
|
|
635
656
|
- 变更文件列表: {len(file_paths)} 个文件
|
|
636
|
-
- 检测到的编程语言: {
|
|
657
|
+
- 检测到的编程语言: {", ".join(detected_languages) if detected_languages else "未检测到特定语言"}
|
|
637
658
|
|
|
638
659
|
请根据SCRIPPPS框架和语言特定的审查清单进行分析,提供详细的代码审查报告。"""
|
|
639
660
|
|
|
640
661
|
# Write the full diff output to a temporary file for uploading
|
|
641
|
-
with tempfile.NamedTemporaryFile(
|
|
662
|
+
with tempfile.NamedTemporaryFile(
|
|
663
|
+
mode="w", suffix=".diff", delete=False
|
|
664
|
+
) as temp_file:
|
|
642
665
|
temp_file_path = temp_file.name
|
|
643
666
|
temp_file.write(diff_output)
|
|
644
667
|
temp_file.flush()
|
|
@@ -679,7 +702,7 @@ def execute_code_review(
|
|
|
679
702
|
我已上传了一个包含代码差异的文件。该文件包含:
|
|
680
703
|
- 审查类型: {review_type}
|
|
681
704
|
- 变更文件数量: {len(file_paths)} 个文件
|
|
682
|
-
- 检测到的编程语言: {
|
|
705
|
+
- 检测到的编程语言: {", ".join(detected_languages) if detected_languages else "未检测到特定语言"}
|
|
683
706
|
|
|
684
707
|
请基于上传的代码差异文件进行全面审查,并生成详细的代码审查报告。"""
|
|
685
708
|
)
|
|
@@ -699,7 +722,7 @@ def execute_code_review(
|
|
|
699
722
|
try:
|
|
700
723
|
os.unlink(temp_file_path)
|
|
701
724
|
except Exception:
|
|
702
|
-
|
|
725
|
+
PrettyOutput.auto_print(f"⚠️ 临时文件 {temp_file_path} 未能删除")
|
|
703
726
|
|
|
704
727
|
return {"success": True, "stdout": result, "stderr": ""}
|
|
705
728
|
finally:
|
|
@@ -728,7 +751,9 @@ def review_commit(
|
|
|
728
751
|
model_group: Optional[str] = typer.Option(
|
|
729
752
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
|
730
753
|
),
|
|
731
|
-
auto_complete: bool = typer.Option(
|
|
754
|
+
auto_complete: bool = typer.Option(
|
|
755
|
+
False, "--auto-complete/--no-auto-complete", help="是否自动完成"
|
|
756
|
+
),
|
|
732
757
|
):
|
|
733
758
|
"""审查指定的提交"""
|
|
734
759
|
tool_args = {
|
|
@@ -740,11 +765,11 @@ def review_commit(
|
|
|
740
765
|
}
|
|
741
766
|
result = execute_code_review(tool_args)
|
|
742
767
|
if result["success"]:
|
|
743
|
-
|
|
768
|
+
PrettyOutput.auto_print("✅ 自动代码审查结果:")
|
|
744
769
|
report = extract_code_report(result["stdout"])
|
|
745
770
|
PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown") # 保留语法高亮
|
|
746
771
|
else:
|
|
747
|
-
|
|
772
|
+
PrettyOutput.auto_print(f"⚠️ {result['stderr']}")
|
|
748
773
|
|
|
749
774
|
|
|
750
775
|
@app.command("current")
|
|
@@ -753,7 +778,9 @@ def review_current(
|
|
|
753
778
|
model_group: Optional[str] = typer.Option(
|
|
754
779
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
|
755
780
|
),
|
|
756
|
-
auto_complete: bool = typer.Option(
|
|
781
|
+
auto_complete: bool = typer.Option(
|
|
782
|
+
False, "--auto-complete/--no-auto-complete", help="是否自动完成"
|
|
783
|
+
),
|
|
757
784
|
):
|
|
758
785
|
"""审查当前的变更"""
|
|
759
786
|
tool_args = {
|
|
@@ -764,11 +791,11 @@ def review_current(
|
|
|
764
791
|
}
|
|
765
792
|
result = execute_code_review(tool_args)
|
|
766
793
|
if result["success"]:
|
|
767
|
-
|
|
794
|
+
PrettyOutput.auto_print("✅ 自动代码审查结果:")
|
|
768
795
|
report = extract_code_report(result["stdout"])
|
|
769
796
|
PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown") # 保留语法高亮
|
|
770
797
|
else:
|
|
771
|
-
|
|
798
|
+
PrettyOutput.auto_print(f"⚠️ {result['stderr']}")
|
|
772
799
|
|
|
773
800
|
|
|
774
801
|
@app.command("range")
|
|
@@ -779,7 +806,9 @@ def review_range(
|
|
|
779
806
|
model_group: Optional[str] = typer.Option(
|
|
780
807
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
|
781
808
|
),
|
|
782
|
-
auto_complete: bool = typer.Option(
|
|
809
|
+
auto_complete: bool = typer.Option(
|
|
810
|
+
False, "--auto-complete/--no-auto-complete", help="是否自动完成"
|
|
811
|
+
),
|
|
783
812
|
):
|
|
784
813
|
"""审查提交范围"""
|
|
785
814
|
tool_args = {
|
|
@@ -792,11 +821,11 @@ def review_range(
|
|
|
792
821
|
}
|
|
793
822
|
result = execute_code_review(tool_args)
|
|
794
823
|
if result["success"]:
|
|
795
|
-
|
|
824
|
+
PrettyOutput.auto_print("✅ 自动代码审查结果:")
|
|
796
825
|
report = extract_code_report(result["stdout"])
|
|
797
826
|
PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown") # 保留语法高亮
|
|
798
827
|
else:
|
|
799
|
-
|
|
828
|
+
PrettyOutput.auto_print(f"⚠️ {result['stderr']}")
|
|
800
829
|
|
|
801
830
|
|
|
802
831
|
@app.command("file")
|
|
@@ -806,7 +835,9 @@ def review_file(
|
|
|
806
835
|
model_group: Optional[str] = typer.Option(
|
|
807
836
|
None, "-g", "--llm-group", help="使用的模型组,覆盖配置文件中的设置"
|
|
808
837
|
),
|
|
809
|
-
auto_complete: bool = typer.Option(
|
|
838
|
+
auto_complete: bool = typer.Option(
|
|
839
|
+
False, "--auto-complete/--no-auto-complete", help="是否自动完成"
|
|
840
|
+
),
|
|
810
841
|
):
|
|
811
842
|
"""审查指定的文件"""
|
|
812
843
|
tool_args = {
|
|
@@ -818,11 +849,11 @@ def review_file(
|
|
|
818
849
|
}
|
|
819
850
|
result = execute_code_review(tool_args)
|
|
820
851
|
if result["success"]:
|
|
821
|
-
|
|
852
|
+
PrettyOutput.auto_print("✅ 自动代码审查结果:")
|
|
822
853
|
report = extract_code_report(result["stdout"])
|
|
823
854
|
PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown") # 保留语法高亮
|
|
824
855
|
else:
|
|
825
|
-
|
|
856
|
+
PrettyOutput.auto_print(f"⚠️ {result['stderr']}")
|
|
826
857
|
|
|
827
858
|
|
|
828
859
|
def cli():
|
|
@@ -837,4 +868,4 @@ def main():
|
|
|
837
868
|
|
|
838
869
|
|
|
839
870
|
if __name__ == "__main__":
|
|
840
|
-
main()
|
|
871
|
+
main()
|