jarvis-ai-assistant 0.2.1__py3-none-any.whl → 0.2.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.
Files changed (30) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/jarvis.py +61 -59
  3. jarvis/jarvis_agent/main.py +42 -40
  4. jarvis/jarvis_code_agent/code_agent.py +35 -31
  5. jarvis/jarvis_code_analysis/code_review.py +73 -39
  6. jarvis/jarvis_git_squash/main.py +16 -12
  7. jarvis/jarvis_git_utils/git_commiter.py +25 -20
  8. jarvis/jarvis_methodology/main.py +34 -49
  9. jarvis/jarvis_multi_agent/main.py +28 -23
  10. jarvis/jarvis_platform/ai8.py +31 -22
  11. jarvis/jarvis_platform/kimi.py +31 -61
  12. jarvis/jarvis_platform/tongyi.py +62 -76
  13. jarvis/jarvis_platform/yuanbao.py +44 -50
  14. jarvis/jarvis_platform_manager/main.py +55 -90
  15. jarvis/jarvis_smart_shell/main.py +58 -87
  16. jarvis/jarvis_tools/cli/main.py +120 -153
  17. jarvis/jarvis_tools/registry.py +1 -7
  18. jarvis/jarvis_tools/search_web.py +12 -10
  19. jarvis/jarvis_utils/http.py +58 -79
  20. jarvis/jarvis_utils/output.py +1 -1
  21. jarvis_ai_assistant-0.2.2.dist-info/METADATA +228 -0
  22. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.2.dist-info}/RECORD +26 -29
  23. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.2.dist-info}/entry_points.txt +0 -2
  24. jarvis/jarvis_git_details/__init__.py +0 -0
  25. jarvis/jarvis_git_details/main.py +0 -265
  26. jarvis/jarvis_platform/oyi.py +0 -357
  27. jarvis_ai_assistant-0.2.1.dist-info/METADATA +0 -845
  28. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.2.dist-info}/WHEEL +0 -0
  29. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.2.dist-info}/licenses/LICENSE +0 -0
  30. {jarvis_ai_assistant-0.2.1.dist-info → jarvis_ai_assistant-0.2.2.dist-info}/top_level.txt +0 -0
jarvis/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.2.1"
4
+ __version__ = "0.2.2"
@@ -1,5 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
3
2
  import os
4
3
  import shutil
5
4
  import subprocess
@@ -7,6 +6,7 @@ import sys
7
6
  from pathlib import Path
8
7
  from typing import Dict, Optional
9
8
 
9
+ import typer
10
10
  import yaml # type: ignore
11
11
  from prompt_toolkit import prompt # type: ignore
12
12
 
@@ -24,6 +24,8 @@ from jarvis.jarvis_tools.registry import ToolRegistry
24
24
  from jarvis.jarvis_utils.config import get_data_dir
25
25
  from jarvis.jarvis_utils.utils import init_env
26
26
 
27
+ app = typer.Typer(help="Jarvis AI assistant")
28
+
27
29
 
28
30
  def _load_tasks() -> Dict[str, str]:
29
31
  """Load tasks from .jarvis files in user home and current directory."""
@@ -109,48 +111,14 @@ def _select_task(tasks: Dict[str, str]) -> str:
109
111
  PrettyOutput.print(f"选择任务失败: {str(val_err)}", OutputType.ERROR)
110
112
 
111
113
 
112
- def _parse_args() -> argparse.Namespace:
113
- """Parse command line arguments."""
114
- parser = argparse.ArgumentParser(description="Jarvis AI assistant")
115
- parser.add_argument(
116
- "--llm_type",
117
- type=str,
118
- default="normal",
119
- choices=["normal", "thinking"],
120
- help="LLM type to use",
121
- )
122
- parser.add_argument(
123
- "-t",
124
- "--task",
125
- type=str,
126
- help="Directly input task content from command line",
127
- )
128
- parser.add_argument(
129
- "--model_group",
130
- type=str,
131
- help="Model group to use, overriding config",
132
- )
133
- parser.add_argument("-f", "--config", type=str, help="Path to custom config file")
134
- parser.add_argument(
135
- "--restore-session",
136
- action="store_true",
137
- help="Restore session from .jarvis/saved_session.json",
138
- default=False,
139
- )
140
- parser.add_argument(
141
- "-e", "--edit", action="store_true", help="Edit the configuration file"
142
- )
143
- return parser.parse_args()
144
-
145
-
146
- def _handle_edit_mode(args: argparse.Namespace) -> None:
114
+ def _handle_edit_mode(edit: bool, config_file: Optional[str]) -> None:
147
115
  """If edit flag is set, open config file in editor and exit."""
148
- if not args.edit:
116
+ if not edit:
149
117
  return
150
118
 
151
119
  config_file_path = (
152
- Path(args.config)
153
- if args.config
120
+ Path(config_file)
121
+ if config_file
154
122
  else Path(os.path.expanduser("~/.jarvis/config.yaml"))
155
123
  )
156
124
  editors = ["nvim", "vim", "vi"]
@@ -159,30 +127,32 @@ def _handle_edit_mode(args: argparse.Namespace) -> None:
159
127
  if editor:
160
128
  try:
161
129
  subprocess.run([editor, str(config_file_path)], check=True)
162
- sys.exit(0)
130
+ raise typer.Exit(code=0)
163
131
  except (subprocess.CalledProcessError, FileNotFoundError) as e:
164
132
  PrettyOutput.print(f"Failed to open editor: {e}", OutputType.ERROR)
165
- sys.exit(1)
133
+ raise typer.Exit(code=1)
166
134
  else:
167
135
  PrettyOutput.print(
168
136
  "No suitable editor found (nvim, vim, vi).", OutputType.ERROR
169
137
  )
170
- sys.exit(1)
138
+ raise typer.Exit(code=1)
171
139
 
172
140
 
173
- def _initialize_agent(args: argparse.Namespace) -> Agent:
141
+ def _initialize_agent(
142
+ llm_type: str, model_group: Optional[str], restore_session: bool
143
+ ) -> Agent:
174
144
  """Initialize the agent and restore session if requested."""
175
145
  agent = Agent(
176
146
  system_prompt=origin_agent_system_prompt,
177
- llm_type=args.llm_type,
178
- model_group=args.model_group,
147
+ llm_type=llm_type,
148
+ model_group=model_group,
179
149
  input_handler=[shell_input_handler, builtin_input_handler],
180
150
  output_handler=[ToolRegistry()], # type: ignore
181
151
  need_summary=False,
182
152
  )
183
153
 
184
154
  # 尝试恢复会话
185
- if args.restore_session:
155
+ if restore_session:
186
156
  if agent.restore_session():
187
157
  PrettyOutput.print("会话已成功恢复。", OutputType.SUCCESS)
188
158
  else:
@@ -195,36 +165,68 @@ def _get_and_run_task(agent: Agent, task_content: Optional[str] = None) -> None:
195
165
  # 优先处理命令行直接传入的任务
196
166
  if task_content:
197
167
  agent.run(task_content)
198
- sys.exit(0)
168
+ raise typer.Exit(code=0)
199
169
 
200
170
  if agent.first:
201
171
  tasks = _load_tasks()
202
172
  if tasks and (selected_task := _select_task(tasks)):
203
173
  PrettyOutput.print(f"开始执行任务: \n{selected_task}", OutputType.INFO)
204
174
  agent.run(selected_task)
205
- sys.exit(0)
175
+ raise typer.Exit(code=0)
206
176
 
207
177
  user_input = get_multiline_input("请输入你的任务(输入空行退出):")
208
178
  if user_input:
209
179
  agent.run(user_input)
210
- sys.exit(0)
180
+ raise typer.Exit(code=0)
211
181
 
212
182
 
213
- def main() -> None:
214
- """Main function for Jarvis AI assistant."""
215
- args = _parse_args()
216
- _handle_edit_mode(args)
183
+ @app.callback(invoke_without_command=True)
184
+ def run_cli(
185
+ ctx: typer.Context,
186
+ llm_type: str = typer.Option(
187
+ "normal",
188
+ "--llm_type",
189
+ help="LLM type to use, choices are 'normal' and 'thinking'",
190
+ ),
191
+ task: Optional[str] = typer.Option(
192
+ None, "-t", "--task", help="Directly input task content from command line"
193
+ ),
194
+ model_group: Optional[str] = typer.Option(
195
+ None, "--model_group", help="Model group to use, overriding config"
196
+ ),
197
+ config_file: Optional[str] = typer.Option(
198
+ None, "-f", "--config", help="Path to custom config file"
199
+ ),
200
+ restore_session: bool = typer.Option(
201
+ False,
202
+ "--restore-session",
203
+ help="Restore session from .jarvis/saved_session.json",
204
+ ),
205
+ edit: bool = typer.Option(
206
+ False, "-e", "--edit", help="Edit the configuration file"
207
+ ),
208
+ ) -> None:
209
+ """Jarvis AI assistant command-line interface."""
210
+ if ctx.invoked_subcommand is not None:
211
+ return
212
+
213
+ _handle_edit_mode(edit, config_file)
217
214
 
218
- init_env(
219
- "欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
220
- )
215
+ init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=config_file)
221
216
 
222
217
  try:
223
- agent = _initialize_agent(args)
224
- _get_and_run_task(agent, args.task)
218
+ agent = _initialize_agent(llm_type, model_group, restore_session)
219
+ _get_and_run_task(agent, task)
220
+ except typer.Exit:
221
+ raise
225
222
  except Exception as err: # pylint: disable=broad-except
226
223
  PrettyOutput.print(f"初始化错误: {str(err)}", OutputType.ERROR)
227
- sys.exit(1)
224
+ raise typer.Exit(code=1)
225
+
226
+
227
+ def main() -> None:
228
+ """Application entry point."""
229
+ app()
228
230
 
229
231
 
230
232
  if __name__ == "__main__":
@@ -1,7 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
3
2
  import os
3
+ from typing import Optional
4
4
 
5
+ import typer
5
6
  import yaml
6
7
 
7
8
  from jarvis.jarvis_agent import Agent
@@ -9,6 +10,8 @@ from jarvis.jarvis_utils.input import get_multiline_input
9
10
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
10
11
  from jarvis.jarvis_utils.utils import init_env
11
12
 
13
+ app = typer.Typer(help="Jarvis AI assistant")
14
+
12
15
 
13
16
  def load_config(config_path: str) -> dict:
14
17
  """从YAML文件加载配置
@@ -34,59 +37,53 @@ def load_config(config_path: str) -> dict:
34
37
  return {}
35
38
 
36
39
 
37
- def main():
38
- """Main entry point for Jarvis agent"""
39
- # Set up argument parser
40
- parser = argparse.ArgumentParser(description="Jarvis AI assistant")
41
- parser.add_argument(
42
- "-f", "--config", type=str, required=False, help="Path to agent config file"
43
- )
44
- parser.add_argument(
45
- "-c", "--agent_definition", type=str, help="Path to agent definition file"
46
- )
47
- parser.add_argument("-t", "--task", type=str, help="Initial task to execute")
48
- parser.add_argument(
40
+ @app.command()
41
+ def cli(
42
+ config_file: Optional[str] = typer.Option(
43
+ None, "-f", "--config", help="Path to agent config file"
44
+ ),
45
+ agent_definition: Optional[str] = typer.Option(
46
+ None, "-c", "--agent_definition", help="Path to agent definition file"
47
+ ),
48
+ task: Optional[str] = typer.Option(
49
+ None, "-t", "--task", help="Initial task to execute"
50
+ ),
51
+ llm_type: str = typer.Option(
52
+ "normal",
49
53
  "--llm_type",
50
- type=str,
51
- default="normal",
52
- choices=["normal", "thinking"],
53
54
  help="LLM type to use, overriding config",
54
- )
55
- parser.add_argument(
56
- "--model_group",
57
- type=str,
58
- help="Model group to use, overriding config",
59
- )
60
- args = parser.parse_args()
61
-
55
+ ),
56
+ model_group: Optional[str] = typer.Option(
57
+ None, "--model_group", help="Model group to use, overriding config"
58
+ ),
59
+ ):
60
+ """Main entry point for Jarvis agent"""
62
61
  # Initialize environment
63
- init_env(
64
- "欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
65
- )
62
+ init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=config_file)
66
63
 
67
64
  # Load configuration
68
- config = load_config(args.agent_definition) if args.agent_definition else {}
65
+ config = load_config(agent_definition) if agent_definition else {}
69
66
 
70
67
  # Override config with command-line arguments if provided
71
- if args.llm_type:
72
- config["llm_type"] = args.llm_type
73
- if args.model_group:
74
- config["model_group"] = args.model_group
68
+ if llm_type:
69
+ config["llm_type"] = llm_type
70
+ if model_group:
71
+ config["model_group"] = model_group
75
72
 
76
73
  # Create and run agent
77
74
  try:
78
75
  agent = Agent(**config)
79
76
 
80
77
  # Run agent with initial task if specified
81
- if args.task:
82
- PrettyOutput.print(f"执行初始任务: {args.task}", OutputType.INFO)
83
- agent.run(args.task)
84
- return 0
78
+ if task:
79
+ PrettyOutput.print(f"执行初始任务: {task}", OutputType.INFO)
80
+ agent.run(task)
81
+ raise typer.Exit(code=0)
85
82
 
86
83
  try:
87
84
  user_input = get_multiline_input("请输入你的任务(输入空行退出):")
88
85
  if not user_input:
89
- return 0
86
+ raise typer.Exit(code=0)
90
87
  agent.set_addon_prompt(
91
88
  "如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行"
92
89
  )
@@ -94,12 +91,17 @@ def main():
94
91
  except Exception as e:
95
92
  PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
96
93
 
94
+ except typer.Exit:
95
+ raise
97
96
  except Exception as e:
98
97
  PrettyOutput.print(f"初始化错误: {str(e)}", OutputType.ERROR)
99
- return 1
98
+ raise typer.Exit(code=1)
99
+
100
100
 
101
- return 0
101
+ def main() -> None:
102
+ """Application entry point."""
103
+ app()
102
104
 
103
105
 
104
106
  if __name__ == "__main__":
105
- exit(main())
107
+ main()
@@ -4,12 +4,13 @@
4
4
  该模块提供CodeAgent类,用于处理代码修改任务。
5
5
  """
6
6
 
7
- import argparse
8
7
  import os
9
8
  import subprocess
10
9
  import sys
11
10
  from typing import List, Optional, Tuple
12
11
 
12
+ import typer
13
+
13
14
  from jarvis.jarvis_agent import Agent
14
15
  from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
15
16
  from jarvis.jarvis_agent.edit_file_handler import EditFileHandler
@@ -37,6 +38,8 @@ from jarvis.jarvis_utils.input import get_multiline_input, user_confirm
37
38
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
38
39
  from jarvis.jarvis_utils.utils import get_loc_stats, init_env
39
40
 
41
+ app = typer.Typer(help="Jarvis Code Agent")
42
+
40
43
 
41
44
  class CodeAgent:
42
45
  """Jarvis系统的代码修改代理。
@@ -401,33 +404,27 @@ class CodeAgent:
401
404
  agent.session.prompt += final_ret
402
405
 
403
406
 
404
- def main() -> None:
405
- """Jarvis主入口点。"""
406
- init_env("欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!")
407
-
408
- parser = argparse.ArgumentParser(description="Jarvis Code Agent")
409
- parser.add_argument(
407
+ @app.command()
408
+ def cli(
409
+ llm_type: str = typer.Option(
410
+ "normal",
410
411
  "--llm_type",
411
- type=str,
412
- default="normal",
413
- choices=["normal", "thinking"],
414
- help="LLM type to use",
415
- )
416
- parser.add_argument(
417
- "--model_group",
418
- type=str,
419
- help="Model group to use, overriding config",
420
- )
421
- parser.add_argument(
422
- "-r", "--requirement", type=str, help="Requirement to process", default=None
423
- )
424
- parser.add_argument(
412
+ help="LLM type to use, choices are 'normal' and 'thinking'",
413
+ ),
414
+ model_group: Optional[str] = typer.Option(
415
+ None, "--model_group", help="Model group to use, overriding config"
416
+ ),
417
+ requirement: Optional[str] = typer.Option(
418
+ None, "-r", "--requirement", help="Requirement to process"
419
+ ),
420
+ restore_session: bool = typer.Option(
421
+ False,
425
422
  "--restore-session",
426
- action="store_true",
427
423
  help="Restore session from .jarvis/saved_session.json",
428
- default=False,
429
- )
430
- args = parser.parse_args()
424
+ ),
425
+ ) -> None:
426
+ """Jarvis主入口点。"""
427
+ init_env("欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!")
431
428
 
432
429
  curr_dir = os.getcwd()
433
430
  git_dir = find_git_root_and_cd(curr_dir)
@@ -435,13 +432,13 @@ def main() -> None:
435
432
 
436
433
  try:
437
434
  agent = CodeAgent(
438
- llm_type=args.llm_type,
439
- model_group=args.model_group,
435
+ llm_type=llm_type,
436
+ model_group=model_group,
440
437
  need_summary=False,
441
438
  )
442
439
 
443
440
  # 尝试恢复会话
444
- if args.restore_session:
441
+ if restore_session:
445
442
  if agent.agent.restore_session():
446
443
  PrettyOutput.print(
447
444
  "已从 .jarvis/saved_session.json 恢复会话。", OutputType.SUCCESS
@@ -451,19 +448,26 @@ def main() -> None:
451
448
  "无法从 .jarvis/saved_session.json 恢复会话。", OutputType.WARNING
452
449
  )
453
450
 
454
- if args.requirement:
455
- agent.run(args.requirement)
451
+ if requirement:
452
+ agent.run(requirement)
456
453
  else:
457
454
  while True:
458
455
  user_input = get_multiline_input("请输入你的需求(输入空行退出):")
459
456
  if not user_input:
460
- return
457
+ raise typer.Exit(code=0)
461
458
  agent.run(user_input)
462
459
 
460
+ except typer.Exit:
461
+ raise
463
462
  except RuntimeError as e:
464
463
  PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
465
464
  sys.exit(1)
466
465
 
467
466
 
467
+ def main() -> None:
468
+ """Application entry point."""
469
+ app()
470
+
471
+
468
472
  if __name__ == "__main__":
469
473
  main()
@@ -3,8 +3,11 @@ import os
3
3
  import re
4
4
  import subprocess
5
5
  import tempfile
6
+ import sys
6
7
  from typing import Any, Dict, List, Optional
7
8
 
9
+ import typer
10
+
8
11
  from jarvis.jarvis_agent import Agent
9
12
  from jarvis.jarvis_code_analysis.checklists.loader import get_language_checklist
10
13
  from jarvis.jarvis_platform.registry import PlatformRegistry
@@ -14,6 +17,8 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
14
17
  from jarvis.jarvis_utils.tag import ct, ot
15
18
  from jarvis.jarvis_utils.utils import init_env, is_context_overflow
16
19
 
20
+ app = typer.Typer(help="Autonomous code review tool")
21
+
17
22
 
18
23
  class CodeReviewTool:
19
24
  name = "code_review"
@@ -762,60 +767,89 @@ def extract_code_report(result: str) -> str:
762
767
  return result
763
768
 
764
769
 
765
- def main():
766
- """CLI entry point"""
767
- import argparse
768
-
769
- init_env("欢迎使用 Jarvis-CodeReview,您的代码审查助手已准备就绪!")
770
-
771
- parser = argparse.ArgumentParser(description="Autonomous code review tool")
772
- subparsers = parser.add_subparsers(dest="type")
773
-
774
- # Commit subcommand
775
- commit_parser = subparsers.add_parser("commit", help="Review specific commit")
776
- commit_parser.add_argument("commit", help="Commit SHA to review")
770
+ @app.command("commit")
771
+ def review_commit(
772
+ commit: str = typer.Argument(..., help="Commit SHA to review"),
773
+ root_dir: str = typer.Option(".", "--root-dir", help="Root directory of the codebase"),
774
+ ):
775
+ """Review specific commit"""
776
+ tool = CodeReviewTool()
777
+ tool_args = {"review_type": "commit", "commit_sha": commit, "root_dir": root_dir}
778
+ result = tool.execute(tool_args)
779
+ if result["success"]:
780
+ PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
781
+ report = extract_code_report(result["stdout"])
782
+ PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown")
783
+ else:
784
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
777
785
 
778
- # Current subcommand
779
- subparsers.add_parser("current", help="Review current changes")
780
786
 
781
- # Range subcommand
782
- range_parser = subparsers.add_parser("range", help="Review commit range")
783
- range_parser.add_argument("start_commit", help="Start commit SHA")
784
- range_parser.add_argument("end_commit", help="End commit SHA")
787
+ @app.command("current")
788
+ def review_current(
789
+ root_dir: str = typer.Option(".", "--root-dir", help="Root directory of the codebase"),
790
+ ):
791
+ """Review current changes"""
792
+ tool = CodeReviewTool()
793
+ tool_args = {"review_type": "current", "root_dir": root_dir}
794
+ result = tool.execute(tool_args)
795
+ if result["success"]:
796
+ PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
797
+ report = extract_code_report(result["stdout"])
798
+ PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown")
799
+ else:
800
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
785
801
 
786
- # File subcommand
787
- file_parser = subparsers.add_parser("file", help="Review specific file")
788
- file_parser.add_argument("file", help="File path to review")
789
802
 
790
- # Common arguments
791
- parser.add_argument(
792
- "--root-dir", type=str, help="Root directory of the codebase", default="."
793
- )
803
+ @app.command("range")
804
+ def review_range(
805
+ start_commit: str = typer.Argument(..., help="Start commit SHA"),
806
+ end_commit: str = typer.Argument(..., help="End commit SHA"),
807
+ root_dir: str = typer.Option(".", "--root-dir", help="Root directory of the codebase"),
808
+ ):
809
+ """Review commit range"""
810
+ tool = CodeReviewTool()
811
+ tool_args = {
812
+ "review_type": "range",
813
+ "start_commit": start_commit,
814
+ "end_commit": end_commit,
815
+ "root_dir": root_dir,
816
+ }
817
+ result = tool.execute(tool_args)
818
+ if result["success"]:
819
+ PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
820
+ report = extract_code_report(result["stdout"])
821
+ PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown")
822
+ else:
823
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
794
824
 
795
- # Set default subcommand to 'current'
796
- parser.set_defaults(type="current")
797
- args = parser.parse_args()
798
825
 
826
+ @app.command("file")
827
+ def review_file(
828
+ file: str = typer.Argument(..., help="File path to review"),
829
+ root_dir: str = typer.Option(".", "--root-dir", help="Root directory of the codebase"),
830
+ ):
831
+ """Review specific file"""
799
832
  tool = CodeReviewTool()
800
- tool_args = {"review_type": args.type, "root_dir": args.root_dir}
801
- if args.type == "commit":
802
- tool_args["commit_sha"] = args.commit
803
- elif args.type == "range":
804
- tool_args["start_commit"] = args.start_commit
805
- tool_args["end_commit"] = args.end_commit
806
- elif args.type == "file":
807
- tool_args["file_path"] = args.file
808
-
833
+ tool_args = {"review_type": "file", "file_path": file, "root_dir": root_dir}
809
834
  result = tool.execute(tool_args)
810
-
811
835
  if result["success"]:
812
836
  PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
813
837
  report = extract_code_report(result["stdout"])
814
838
  PrettyOutput.print(report, OutputType.SUCCESS, lang="markdown")
815
-
816
839
  else:
817
840
  PrettyOutput.print(result["stderr"], OutputType.WARNING)
818
841
 
819
842
 
843
+ def cli():
844
+ """Typer application entry point"""
845
+ init_env("欢迎使用 Jarvis-CodeReview,您的代码审查助手已准备就绪!")
846
+ app()
847
+
848
+
849
+ def main():
850
+ """Main entry point for the script"""
851
+ cli()
852
+
853
+
820
854
  if __name__ == "__main__":
821
855
  main()
@@ -1,14 +1,16 @@
1
1
  # -*- coding: utf-8 -*-
2
- import argparse
3
2
  import subprocess
4
- import sys
5
3
  from typing import Dict
6
4
 
5
+ import typer
6
+
7
7
  from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
8
8
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
9
  from jarvis.jarvis_utils.utils import init_env
10
10
  from jarvis.jarvis_utils.input import user_confirm
11
11
 
12
+ app = typer.Typer(help="Git squash tool")
13
+
12
14
 
13
15
  class GitSquashTool:
14
16
  name = "git_squash_agent"
@@ -49,18 +51,20 @@ class GitSquashTool:
49
51
  PrettyOutput.print(f"压缩提交失败: {str(e)}", OutputType.WARNING)
50
52
 
51
53
 
52
- def main():
54
+ @app.command()
55
+ def cli(
56
+ commit_hash: str = typer.Argument(..., help="Base commit hash to squash from"),
57
+ lang: str = typer.Option("Chinese", "--lang", help="Language for commit messages"),
58
+ ):
53
59
  init_env("欢迎使用 Jarvis-GitSquash,您的Git压缩助手已准备就绪!")
54
- parser = argparse.ArgumentParser(description="Git squash tool")
55
- parser.add_argument("commit_hash", type=str, help="Base commit hash to squash from")
56
- parser.add_argument(
57
- "--lang", type=str, default="Chinese", help="Language for commit messages"
58
- )
59
- args = parser.parse_args()
60
-
61
60
  tool = GitSquashTool()
62
- tool.execute({"commit_hash": args.commit_hash, "lang": args.lang})
61
+ tool.execute({"commit_hash": commit_hash, "lang": lang})
62
+
63
+
64
+ def main():
65
+ """Application entry point"""
66
+ app()
63
67
 
64
68
 
65
69
  if __name__ == "__main__":
66
- sys.exit(main())
70
+ main()