jarvis-ai-assistant 0.1.130__py3-none-any.whl → 0.1.131__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.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +23 -9
- jarvis/jarvis_agent/builtin_input_handler.py +73 -0
- jarvis/{jarvis_code_agent → jarvis_agent}/file_input_handler.py +1 -1
- jarvis/jarvis_agent/main.py +1 -1
- jarvis/{jarvis_code_agent → jarvis_agent}/patch.py +23 -19
- jarvis/{jarvis_code_agent → jarvis_agent}/shell_input_handler.py +0 -1
- jarvis/jarvis_code_agent/code_agent.py +20 -16
- jarvis/jarvis_codebase/main.py +5 -5
- jarvis/jarvis_dev/main.py +1 -1
- jarvis/jarvis_git_squash/main.py +1 -1
- jarvis/jarvis_lsp/base.py +2 -26
- jarvis/jarvis_lsp/cpp.py +2 -14
- jarvis/jarvis_lsp/go.py +0 -13
- jarvis/jarvis_lsp/python.py +1 -30
- jarvis/jarvis_lsp/registry.py +10 -14
- jarvis/jarvis_lsp/rust.py +0 -12
- jarvis/jarvis_multi_agent/__init__.py +1 -1
- jarvis/jarvis_platform/registry.py +1 -1
- jarvis/jarvis_platform_manager/main.py +3 -3
- jarvis/jarvis_rag/main.py +1 -1
- jarvis/jarvis_tools/ask_codebase.py +40 -20
- jarvis/jarvis_tools/code_review.py +180 -143
- jarvis/jarvis_tools/create_code_agent.py +76 -72
- jarvis/jarvis_tools/create_sub_agent.py +32 -15
- jarvis/jarvis_tools/execute_shell.py +2 -2
- jarvis/jarvis_tools/execute_shell_script.py +1 -1
- jarvis/jarvis_tools/file_operation.py +2 -2
- jarvis/jarvis_tools/git_commiter.py +87 -68
- jarvis/jarvis_tools/lsp_find_definition.py +83 -67
- jarvis/jarvis_tools/lsp_find_references.py +62 -46
- jarvis/jarvis_tools/lsp_get_diagnostics.py +90 -74
- jarvis/jarvis_tools/methodology.py +3 -3
- jarvis/jarvis_tools/read_code.py +1 -1
- jarvis/jarvis_tools/search_web.py +18 -20
- jarvis/jarvis_tools/tool_generator.py +1 -1
- jarvis/jarvis_tools/treesitter_analyzer.py +331 -0
- jarvis/jarvis_treesitter/README.md +104 -0
- jarvis/jarvis_treesitter/__init__.py +20 -0
- jarvis/jarvis_treesitter/database.py +258 -0
- jarvis/jarvis_treesitter/example.py +115 -0
- jarvis/jarvis_treesitter/grammar_builder.py +182 -0
- jarvis/jarvis_treesitter/language.py +117 -0
- jarvis/jarvis_treesitter/symbol.py +31 -0
- jarvis/jarvis_treesitter/tools_usage.md +121 -0
- jarvis/jarvis_utils/git_utils.py +10 -2
- jarvis/jarvis_utils/input.py +3 -1
- jarvis/jarvis_utils/methodology.py +1 -1
- jarvis/jarvis_utils/utils.py +3 -3
- {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/METADATA +2 -4
- jarvis_ai_assistant-0.1.131.dist-info/RECORD +85 -0
- jarvis/jarvis_c2rust/c2rust.yaml +0 -734
- jarvis/jarvis_code_agent/builtin_input_handler.py +0 -43
- jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -87
- jarvis/jarvis_tools/lsp_prepare_rename.py +0 -130
- jarvis_ai_assistant-0.1.130.dist-info/RECORD +0 -79
- {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.130.dist-info → jarvis_ai_assistant-0.1.131.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from typing import Dict, Any
|
|
2
|
+
import os
|
|
2
3
|
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
3
4
|
from jarvis.jarvis_tools.git_commiter import GitCommitTool
|
|
4
5
|
from jarvis.jarvis_tools.code_review import CodeReviewTool, extract_code_report
|
|
@@ -11,63 +12,83 @@ class CreateCodeAgentTool:
|
|
|
11
12
|
name = "create_code_agent"
|
|
12
13
|
description = "技术代码实现和开发过程管理工具"
|
|
13
14
|
parameters = {
|
|
14
|
-
"requirement": "
|
|
15
|
+
"requirement": """代码实现的技术规范,必须包含以下完整信息:
|
|
16
|
+
1. 项目代码目录 - 项目根目录的绝对路径
|
|
17
|
+
2. 项目功能 - 项目的主要功能和目标
|
|
18
|
+
3. 本次要实现的feature - 本次开发要完成的具体功能需求
|
|
19
|
+
4. 涉及的文件 - 需要修改或新增的文件列表
|
|
20
|
+
5. 额外需要注意的信息 - 开发时需要额外注意的信息
|
|
21
|
+
""",
|
|
22
|
+
"root_dir": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "代码库根目录路径(可选)",
|
|
25
|
+
"default": "."
|
|
26
|
+
}
|
|
15
27
|
}
|
|
16
28
|
|
|
17
29
|
|
|
18
30
|
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
19
31
|
try:
|
|
20
32
|
requirement = args.get("requirement", "")
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
"success": False,
|
|
24
|
-
"stderr": "Requirement must be provided",
|
|
25
|
-
"stdout": ""
|
|
26
|
-
}
|
|
33
|
+
root_dir = args.get("root_dir", ".")
|
|
27
34
|
|
|
28
|
-
#
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if not
|
|
35
|
+
# Store current directory
|
|
36
|
+
original_dir = os.getcwd()
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
# Change to root_dir
|
|
40
|
+
os.chdir(root_dir)
|
|
41
|
+
if not requirement:
|
|
35
42
|
return {
|
|
36
43
|
"success": False,
|
|
37
|
-
"stderr": "
|
|
44
|
+
"stderr": "Requirement must be provided",
|
|
38
45
|
"stdout": ""
|
|
39
46
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
47
|
+
|
|
48
|
+
# Step 1: Handle uncommitted changes
|
|
49
|
+
start_commit = None
|
|
50
|
+
if has_uncommitted_changes():
|
|
51
|
+
PrettyOutput.print("发现未提交的更改,正在提交...", OutputType.INFO)
|
|
52
|
+
git_commiter = GitCommitTool()
|
|
53
|
+
result = git_commiter.execute({})
|
|
54
|
+
if not result["success"]:
|
|
55
|
+
return {
|
|
56
|
+
"success": False,
|
|
57
|
+
"stderr": "Failed to commit changes: " + result["stderr"],
|
|
58
|
+
"stdout": ""
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Get current commit hash
|
|
62
|
+
start_commit = get_latest_commit_hash()
|
|
63
|
+
|
|
64
|
+
# Step 2: Development
|
|
65
|
+
PrettyOutput.print("开始开发...", OutputType.INFO)
|
|
66
|
+
agent = CodeAgent()
|
|
67
|
+
agent.run(requirement)
|
|
68
|
+
|
|
69
|
+
# Get new commit hash after development
|
|
70
|
+
end_commit = get_latest_commit_hash()
|
|
71
|
+
|
|
72
|
+
# Step 3: Code Review
|
|
73
|
+
PrettyOutput.print("开始代码审查...", OutputType.INFO)
|
|
74
|
+
reviewer = CodeReviewTool()
|
|
75
|
+
review_result = reviewer.execute({
|
|
76
|
+
"review_type": "range",
|
|
77
|
+
"start_commit": start_commit,
|
|
78
|
+
"end_commit": end_commit,
|
|
79
|
+
"root_dir": root_dir
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
if not review_result["success"]:
|
|
83
|
+
return {
|
|
84
|
+
"success": False,
|
|
85
|
+
"stderr": "Code review failed: " + review_result["stderr"],
|
|
86
|
+
"stdout": ""
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Step 4: Generate Summary
|
|
90
|
+
summary = f"""开发总结:
|
|
91
|
+
|
|
71
92
|
开始提交: {start_commit}
|
|
72
93
|
结束提交: {end_commit}
|
|
73
94
|
|
|
@@ -77,12 +98,15 @@ class CreateCodeAgentTool:
|
|
|
77
98
|
代码审查结果:
|
|
78
99
|
{extract_code_report(review_result["stdout"])}
|
|
79
100
|
"""
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
"success": True,
|
|
104
|
+
"stdout": summary,
|
|
105
|
+
"stderr": ""
|
|
106
|
+
}
|
|
107
|
+
finally:
|
|
108
|
+
# Always restore original directory
|
|
109
|
+
os.chdir(original_dir)
|
|
86
110
|
|
|
87
111
|
except Exception as e:
|
|
88
112
|
return {
|
|
@@ -90,23 +114,3 @@ class CreateCodeAgentTool:
|
|
|
90
114
|
"stderr": f"Development workflow failed: {str(e)}",
|
|
91
115
|
"stdout": ""
|
|
92
116
|
}
|
|
93
|
-
|
|
94
|
-
def main():
|
|
95
|
-
"""CLI entry point"""
|
|
96
|
-
import argparse
|
|
97
|
-
|
|
98
|
-
parser = argparse.ArgumentParser(description='Code development workflow tool')
|
|
99
|
-
parser.add_argument('requirement', help='Development requirement or task description')
|
|
100
|
-
|
|
101
|
-
args = parser.parse_args()
|
|
102
|
-
|
|
103
|
-
tool = CreateCodeAgentTool()
|
|
104
|
-
result = tool.execute({"requirement": args.requirement})
|
|
105
|
-
|
|
106
|
-
if result["success"]:
|
|
107
|
-
PrettyOutput.print(result["stdout"], OutputType.SUCCESS)
|
|
108
|
-
else:
|
|
109
|
-
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
110
|
-
|
|
111
|
-
if __name__ == "__main__":
|
|
112
|
-
main()
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from typing import Dict, Any
|
|
2
|
+
import os
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
from jarvis.jarvis_agent import Agent, origin_agent_system_prompt
|
|
@@ -30,8 +31,13 @@ class SubAgentTool:
|
|
|
30
31
|
"description": "任务的完成目标",
|
|
31
32
|
"default": ""
|
|
32
33
|
},
|
|
34
|
+
"root_dir": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "任务执行的根目录路径(可选)",
|
|
37
|
+
"default": "."
|
|
38
|
+
}
|
|
33
39
|
},
|
|
34
|
-
"required": ["agent_name", "task"
|
|
40
|
+
"required": ["agent_name", "task"]
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
|
|
@@ -42,6 +48,7 @@ class SubAgentTool:
|
|
|
42
48
|
task = args["task"]
|
|
43
49
|
context = args.get("context", "")
|
|
44
50
|
goal = args.get("goal", "")
|
|
51
|
+
root_dir = args.get("root_dir", ".")
|
|
45
52
|
|
|
46
53
|
PrettyOutput.print(f"创建子代理: {agent_name}", OutputType.INFO)
|
|
47
54
|
|
|
@@ -53,22 +60,32 @@ class SubAgentTool:
|
|
|
53
60
|
task_description += f"\n\nCompletion goal:\n{goal}"
|
|
54
61
|
|
|
55
62
|
|
|
56
|
-
#
|
|
57
|
-
|
|
58
|
-
system_prompt=origin_agent_system_prompt,
|
|
59
|
-
name=f"Agent({agent_name})",
|
|
60
|
-
is_sub_agent=True
|
|
61
|
-
)
|
|
63
|
+
# Store current directory
|
|
64
|
+
original_dir = os.getcwd()
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
try:
|
|
67
|
+
# Change to root_dir
|
|
68
|
+
os.chdir(root_dir)
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
# Create sub-agent
|
|
71
|
+
sub_agent = Agent(
|
|
72
|
+
system_prompt=origin_agent_system_prompt,
|
|
73
|
+
name=f"Agent({agent_name})",
|
|
74
|
+
is_sub_agent=True
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Run sub-agent, pass file list
|
|
78
|
+
PrettyOutput.print("子代理开始执行任务...", OutputType.INFO)
|
|
79
|
+
result = sub_agent.run(task_description)
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"success": True,
|
|
83
|
+
"stdout": f"Sub-agent task completed\n\n{result}",
|
|
84
|
+
"stderr": ""
|
|
85
|
+
}
|
|
86
|
+
finally:
|
|
87
|
+
# Always restore original directory
|
|
88
|
+
os.chdir(original_dir)
|
|
72
89
|
|
|
73
90
|
except Exception as e:
|
|
74
91
|
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
@@ -74,11 +74,11 @@ class ShellTool:
|
|
|
74
74
|
tee_command = f"script -q -c '{escaped_command}' {output_file}"
|
|
75
75
|
|
|
76
76
|
# Execute command and capture return code
|
|
77
|
-
|
|
77
|
+
os.system(tee_command)
|
|
78
78
|
|
|
79
79
|
# Read and process output file
|
|
80
80
|
try:
|
|
81
|
-
with open(output_file, 'r', encoding='utf-8', errors='
|
|
81
|
+
with open(output_file, 'r', encoding='utf-8', errors='ignore') as f:
|
|
82
82
|
output = f.read()
|
|
83
83
|
# Remove header and footer added by script command
|
|
84
84
|
if output:
|
|
@@ -33,7 +33,7 @@ class ShellScriptTool:
|
|
|
33
33
|
# Create temporary script file
|
|
34
34
|
script_path = os.path.join(tempfile.gettempdir(), f"jarvis_script_{os.getpid()}.sh")
|
|
35
35
|
try:
|
|
36
|
-
with open(script_path, 'w', encoding='utf-8') as f:
|
|
36
|
+
with open(script_path, 'w', encoding='utf-8', errors="ignore") as f:
|
|
37
37
|
f.write(script_content)
|
|
38
38
|
# Use execute_shell to run the script
|
|
39
39
|
from jarvis.jarvis_tools.execute_shell import ShellTool
|
|
@@ -55,7 +55,7 @@ class FileOperationTool:
|
|
|
55
55
|
"stderr": "File too large (>10MB)"
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
with open(abs_path, 'r', encoding='utf-8') as f:
|
|
58
|
+
with open(abs_path, 'r', encoding='utf-8', errors="ignore") as f:
|
|
59
59
|
lines = f.readlines()
|
|
60
60
|
|
|
61
61
|
|
|
@@ -90,7 +90,7 @@ class FileOperationTool:
|
|
|
90
90
|
elif operation == "write":
|
|
91
91
|
with yaspin(text=f"正在写入文件: {abs_path}...", color="cyan") as spinner:
|
|
92
92
|
os.makedirs(os.path.dirname(os.path.abspath(abs_path)), exist_ok=True)
|
|
93
|
-
with open(abs_path, 'w', encoding='utf-8') as f:
|
|
93
|
+
with open(abs_path, 'w', encoding='utf-8', errors="ignore") as f:
|
|
94
94
|
f.write(content)
|
|
95
95
|
spinner.text = f"文件写入完成: {abs_path}"
|
|
96
96
|
spinner.ok("✅")
|
|
@@ -8,6 +8,7 @@ from yaspin import yaspin
|
|
|
8
8
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
9
9
|
import sys
|
|
10
10
|
import argparse
|
|
11
|
+
import os
|
|
11
12
|
|
|
12
13
|
from jarvis.jarvis_utils.git_utils import find_git_root, has_uncommitted_changes
|
|
13
14
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
@@ -24,6 +25,11 @@ class GitCommitTool:
|
|
|
24
25
|
"type": "string",
|
|
25
26
|
"description": "提交信息的语言",
|
|
26
27
|
"default": "Chinese"
|
|
28
|
+
},
|
|
29
|
+
"root_dir": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Git仓库的根目录路径(可选)",
|
|
32
|
+
"default": "."
|
|
27
33
|
}
|
|
28
34
|
},
|
|
29
35
|
"required": []
|
|
@@ -51,83 +57,95 @@ class GitCommitTool:
|
|
|
51
57
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
52
58
|
"""Execute automatic commit process with support for multi-line messages and special characters"""
|
|
53
59
|
try:
|
|
54
|
-
|
|
55
|
-
if not has_uncommitted_changes():
|
|
56
|
-
PrettyOutput.print("没有未提交的更改", OutputType.SUCCESS)
|
|
57
|
-
return {"success": True, "stdout": "No changes to commit", "stderr": ""}
|
|
60
|
+
root_dir = args.get("root_dir", ".")
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
stderr=subprocess.DEVNULL
|
|
66
|
-
).wait()
|
|
67
|
-
spinner.write("✅ 添加文件到提交")
|
|
68
|
-
|
|
69
|
-
# 获取差异
|
|
70
|
-
spinner.text = "正在获取代码差异..."
|
|
71
|
-
process = subprocess.Popen(
|
|
72
|
-
["git", "diff", "--cached", "--exit-code"],
|
|
73
|
-
stdout=subprocess.PIPE,
|
|
74
|
-
stderr=subprocess.PIPE
|
|
75
|
-
)
|
|
76
|
-
diff = process.communicate()[0].decode()
|
|
77
|
-
spinner.write("✅ 获取差异")
|
|
62
|
+
# Store current directory
|
|
63
|
+
original_dir = os.getcwd()
|
|
64
|
+
|
|
65
|
+
try:
|
|
66
|
+
# Change to root_dir
|
|
67
|
+
os.chdir(root_dir)
|
|
78
68
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# 必需结构
|
|
84
|
-
必须使用以下格式:
|
|
85
|
-
<COMMIT_MESSAGE>
|
|
86
|
-
<类型>(<范围>): <主题>
|
|
87
|
-
使用祈使语气描述变更内容
|
|
88
|
-
</COMMIT_MESSAGE>
|
|
89
|
-
# 格式规则
|
|
90
|
-
1. 类型: fix, feat, docs, style, refactor, test, chore
|
|
91
|
-
2. 范围表示模块 (例如: auth, database)
|
|
92
|
-
3. 主题行 <= 72个字符,不以句号结尾
|
|
93
|
-
4. 正文使用现在时态解释每个变更的内容和原因
|
|
94
|
-
5. 不要遗漏任何变更
|
|
95
|
-
# 分析材料
|
|
96
|
-
{diff}
|
|
97
|
-
'''
|
|
98
|
-
platform = PlatformRegistry().get_codegen_platform()
|
|
99
|
-
commit_message = platform.chat_until_success(prompt)
|
|
100
|
-
commit_message = self._extract_commit_message(commit_message)
|
|
101
|
-
spinner.write("✅ 生成提交消息")
|
|
69
|
+
find_git_root()
|
|
70
|
+
if not has_uncommitted_changes():
|
|
71
|
+
PrettyOutput.print("没有未提交的更改", OutputType.SUCCESS)
|
|
72
|
+
return {"success": True, "stdout": "No changes to commit", "stderr": ""}
|
|
102
73
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
tmp_file.write(commit_message)
|
|
107
|
-
tmp_file.flush()
|
|
108
|
-
spinner.text = "正在执行提交..."
|
|
109
|
-
commit_cmd = ["git", "commit", "-F", tmp_file.name]
|
|
74
|
+
with yaspin(text="正在初始化提交流程...", color="cyan") as spinner:
|
|
75
|
+
# 添加文件
|
|
76
|
+
spinner.text = "正在添加文件到提交..."
|
|
110
77
|
subprocess.Popen(
|
|
111
|
-
|
|
78
|
+
["git", "add", "."],
|
|
112
79
|
stdout=subprocess.DEVNULL,
|
|
113
80
|
stderr=subprocess.DEVNULL
|
|
114
81
|
).wait()
|
|
115
|
-
spinner.write("✅
|
|
82
|
+
spinner.write("✅ 添加文件到提交")
|
|
83
|
+
|
|
84
|
+
# 获取差异
|
|
85
|
+
spinner.text = "正在获取代码差异..."
|
|
86
|
+
process = subprocess.Popen(
|
|
87
|
+
["git", "diff", "--cached", "--exit-code"],
|
|
88
|
+
stdout=subprocess.PIPE,
|
|
89
|
+
stderr=subprocess.PIPE
|
|
90
|
+
)
|
|
91
|
+
diff = process.communicate()[0].decode()
|
|
92
|
+
spinner.write("✅ 获取差异")
|
|
93
|
+
|
|
94
|
+
# 生成提交信息
|
|
95
|
+
spinner.text = "正在生成提交消息..."
|
|
96
|
+
prompt = f'''根据以下规则生成提交信息:
|
|
97
|
+
提交信息应使用{args.get('lang', '中文')}书写
|
|
98
|
+
# 必需结构
|
|
99
|
+
必须使用以下格式:
|
|
100
|
+
<COMMIT_MESSAGE>
|
|
101
|
+
<类型>(<范围>): <主题>
|
|
102
|
+
使用祈使语气描述变更内容
|
|
103
|
+
</COMMIT_MESSAGE>
|
|
104
|
+
# 格式规则
|
|
105
|
+
1. 类型: fix, feat, docs, style, refactor, test, chore
|
|
106
|
+
2. 范围表示模块 (例如: auth, database)
|
|
107
|
+
3. 主题行 <= 72个字符,不以句号结尾
|
|
108
|
+
4. 正文使用现在时态解释每个变更的内容和原因
|
|
109
|
+
5. 不要遗漏任何变更
|
|
110
|
+
# 分析材料
|
|
111
|
+
{diff}
|
|
112
|
+
'''
|
|
113
|
+
platform = PlatformRegistry().get_codegen_platform()
|
|
114
|
+
commit_message = platform.chat_until_success(prompt)
|
|
115
|
+
commit_message = self._extract_commit_message(commit_message)
|
|
116
|
+
spinner.write("✅ 生成提交消息")
|
|
117
|
+
|
|
118
|
+
# 执行提交
|
|
119
|
+
spinner.text = "正在准备提交..."
|
|
120
|
+
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
|
|
121
|
+
tmp_file.write(commit_message)
|
|
122
|
+
tmp_file.flush()
|
|
123
|
+
spinner.text = "正在执行提交..."
|
|
124
|
+
commit_cmd = ["git", "commit", "-F", tmp_file.name]
|
|
125
|
+
subprocess.Popen(
|
|
126
|
+
commit_cmd,
|
|
127
|
+
stdout=subprocess.DEVNULL,
|
|
128
|
+
stderr=subprocess.DEVNULL
|
|
129
|
+
).wait()
|
|
130
|
+
spinner.write("✅ 提交")
|
|
116
131
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
commit_hash = self._get_last_commit_hash()
|
|
133
|
+
spinner.text = "完成提交"
|
|
134
|
+
spinner.ok("✅")
|
|
120
135
|
|
|
121
|
-
|
|
136
|
+
PrettyOutput.print(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
return {
|
|
139
|
+
"success": True,
|
|
140
|
+
"stdout": yaml.safe_dump({
|
|
141
|
+
"commit_hash": commit_hash,
|
|
142
|
+
"commit_message": commit_message
|
|
143
|
+
}),
|
|
144
|
+
"stderr": ""
|
|
145
|
+
}
|
|
146
|
+
finally:
|
|
147
|
+
# Always restore original directory
|
|
148
|
+
os.chdir(original_dir)
|
|
131
149
|
|
|
132
150
|
except Exception as e:
|
|
133
151
|
return {
|
|
@@ -140,9 +158,10 @@ def main():
|
|
|
140
158
|
init_env()
|
|
141
159
|
parser = argparse.ArgumentParser(description='Git commit tool')
|
|
142
160
|
parser.add_argument('--lang', type=str, default='Chinese', help='Language for commit messages')
|
|
161
|
+
parser.add_argument('--root-dir', type=str, default='.', help='Root directory of the Git repository')
|
|
143
162
|
args = parser.parse_args()
|
|
144
163
|
tool = GitCommitTool()
|
|
145
|
-
tool.execute({"lang": args.lang if hasattr(args, 'lang') else 'Chinese'})
|
|
164
|
+
tool.execute({"lang": args.lang if hasattr(args, 'lang') else 'Chinese', "root_dir": args.root_dir})
|
|
146
165
|
|
|
147
166
|
if __name__ == "__main__":
|
|
148
167
|
sys.exit(main())
|