jarvis-ai-assistant 0.1.193__py3-none-any.whl → 0.1.194__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.

Files changed (91) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +34 -41
  3. jarvis/jarvis_agent/builtin_input_handler.py +26 -4
  4. jarvis/jarvis_agent/jarvis.py +38 -22
  5. jarvis/jarvis_agent/main.py +20 -12
  6. jarvis/jarvis_agent/output_handler.py +7 -7
  7. jarvis/jarvis_agent/shell_input_handler.py +14 -11
  8. jarvis/jarvis_code_agent/code_agent.py +91 -85
  9. jarvis/jarvis_code_agent/lint.py +92 -105
  10. jarvis/jarvis_code_analysis/checklists/__init__.py +1 -1
  11. jarvis/jarvis_code_analysis/checklists/c_cpp.py +1 -1
  12. jarvis/jarvis_code_analysis/checklists/csharp.py +1 -1
  13. jarvis/jarvis_code_analysis/checklists/data_format.py +1 -1
  14. jarvis/jarvis_code_analysis/checklists/devops.py +1 -1
  15. jarvis/jarvis_code_analysis/checklists/docs.py +1 -1
  16. jarvis/jarvis_code_analysis/checklists/go.py +1 -1
  17. jarvis/jarvis_code_analysis/checklists/infrastructure.py +1 -1
  18. jarvis/jarvis_code_analysis/checklists/java.py +1 -1
  19. jarvis/jarvis_code_analysis/checklists/javascript.py +1 -1
  20. jarvis/jarvis_code_analysis/checklists/kotlin.py +1 -1
  21. jarvis/jarvis_code_analysis/checklists/loader.py +51 -35
  22. jarvis/jarvis_code_analysis/checklists/php.py +1 -1
  23. jarvis/jarvis_code_analysis/checklists/python.py +1 -1
  24. jarvis/jarvis_code_analysis/checklists/ruby.py +1 -1
  25. jarvis/jarvis_code_analysis/checklists/rust.py +1 -1
  26. jarvis/jarvis_code_analysis/checklists/shell.py +1 -1
  27. jarvis/jarvis_code_analysis/checklists/sql.py +1 -1
  28. jarvis/jarvis_code_analysis/checklists/swift.py +1 -1
  29. jarvis/jarvis_code_analysis/checklists/web.py +1 -1
  30. jarvis/jarvis_code_analysis/code_review.py +293 -192
  31. jarvis/jarvis_dev/main.py +73 -56
  32. jarvis/jarvis_git_details/main.py +29 -33
  33. jarvis/jarvis_git_squash/main.py +13 -11
  34. jarvis/jarvis_git_utils/git_commiter.py +12 -3
  35. jarvis/jarvis_mcp/__init__.py +8 -10
  36. jarvis/jarvis_mcp/sse_mcp_client.py +182 -205
  37. jarvis/jarvis_mcp/stdio_mcp_client.py +93 -120
  38. jarvis/jarvis_mcp/streamable_mcp_client.py +117 -142
  39. jarvis/jarvis_methodology/main.py +75 -41
  40. jarvis/jarvis_multi_agent/__init__.py +24 -16
  41. jarvis/jarvis_multi_agent/main.py +10 -4
  42. jarvis/jarvis_platform/__init__.py +1 -1
  43. jarvis/jarvis_platform/base.py +49 -21
  44. jarvis/jarvis_platform/human.py +5 -3
  45. jarvis/jarvis_platform/kimi.py +96 -72
  46. jarvis/jarvis_platform/openai.py +23 -28
  47. jarvis/jarvis_platform/registry.py +50 -33
  48. jarvis/jarvis_platform/tongyi.py +16 -10
  49. jarvis/jarvis_platform/yuanbao.py +197 -144
  50. jarvis/jarvis_platform_manager/main.py +4 -2
  51. jarvis/jarvis_smart_shell/main.py +35 -29
  52. jarvis/jarvis_tools/ask_user.py +8 -16
  53. jarvis/jarvis_tools/base.py +3 -2
  54. jarvis/jarvis_tools/chdir.py +7 -19
  55. jarvis/jarvis_tools/cli/main.py +14 -10
  56. jarvis/jarvis_tools/code_plan.py +10 -31
  57. jarvis/jarvis_tools/create_code_agent.py +10 -13
  58. jarvis/jarvis_tools/create_sub_agent.py +10 -22
  59. jarvis/jarvis_tools/edit_file.py +98 -76
  60. jarvis/jarvis_tools/execute_script.py +46 -46
  61. jarvis/jarvis_tools/file_analyzer.py +22 -34
  62. jarvis/jarvis_tools/file_operation.py +69 -62
  63. jarvis/jarvis_tools/generate_new_tool.py +0 -2
  64. jarvis/jarvis_tools/methodology.py +19 -23
  65. jarvis/jarvis_tools/read_code.py +35 -35
  66. jarvis/jarvis_tools/read_webpage.py +7 -16
  67. jarvis/jarvis_tools/registry.py +63 -30
  68. jarvis/jarvis_tools/rewrite_file.py +26 -29
  69. jarvis/jarvis_tools/search_web.py +5 -8
  70. jarvis/jarvis_tools/virtual_tty.py +133 -122
  71. jarvis/jarvis_utils/__init__.py +0 -1
  72. jarvis/jarvis_utils/builtin_replace_map.py +9 -9
  73. jarvis/jarvis_utils/config.py +59 -32
  74. jarvis/jarvis_utils/embedding.py +17 -14
  75. jarvis/jarvis_utils/file_processors.py +16 -9
  76. jarvis/jarvis_utils/git_utils.py +140 -99
  77. jarvis/jarvis_utils/globals.py +1 -1
  78. jarvis/jarvis_utils/input.py +84 -52
  79. jarvis/jarvis_utils/methodology.py +28 -21
  80. jarvis/jarvis_utils/output.py +159 -78
  81. jarvis/jarvis_utils/tag.py +2 -1
  82. jarvis/jarvis_utils/utils.py +85 -51
  83. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/METADATA +314 -230
  84. jarvis_ai_assistant-0.1.194.dist-info/RECORD +97 -0
  85. jarvis/jarvis_agent/file_input_handler.py +0 -112
  86. jarvis/jarvis_event/__init__.py +0 -0
  87. jarvis_ai_assistant-0.1.193.dist-info/RECORD +0 -99
  88. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/WHEEL +0 -0
  89. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/entry_points.txt +0 -0
  90. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/licenses/LICENSE +0 -0
  91. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.194.dist-info}/top_level.txt +0 -0
@@ -14,8 +14,7 @@ import re
14
14
  import subprocess
15
15
  from typing import Any, Dict, List, Tuple
16
16
 
17
- from jarvis.jarvis_utils.config import (get_auto_update,
18
- is_confirm_before_apply_patch)
17
+ from jarvis.jarvis_utils.config import get_auto_update, is_confirm_before_apply_patch
19
18
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
20
19
  from jarvis.jarvis_utils.utils import user_confirm
21
20
 
@@ -42,29 +41,47 @@ def find_git_root(start_dir: str = ".") -> str:
42
41
  git_root = os.path.abspath(".")
43
42
  os.chdir(git_root)
44
43
  return git_root
44
+
45
+
45
46
  def has_uncommitted_changes() -> bool:
46
47
  """检查Git仓库中是否有未提交的更改
47
-
48
+
48
49
  返回:
49
50
  bool: 如果有未提交的更改返回True,否则返回False
50
51
  """
51
52
  # 静默添加所有更改
52
- subprocess.run(["git", "add", "."], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
53
+ subprocess.run(
54
+ ["git", "add", "."], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
55
+ )
53
56
 
54
57
  # 检查工作目录更改
55
- working_changes = subprocess.run(["git", "diff", "--exit-code"],
56
- stdout=subprocess.DEVNULL,
57
- stderr=subprocess.DEVNULL).returncode != 0
58
+ working_changes = (
59
+ subprocess.run(
60
+ ["git", "diff", "--exit-code"],
61
+ stdout=subprocess.DEVNULL,
62
+ stderr=subprocess.DEVNULL,
63
+ ).returncode
64
+ != 0
65
+ )
58
66
 
59
67
  # 检查暂存区更改
60
- staged_changes = subprocess.run(["git", "diff", "--cached", "--exit-code"],
61
- stdout=subprocess.DEVNULL,
62
- stderr=subprocess.DEVNULL).returncode != 0
68
+ staged_changes = (
69
+ subprocess.run(
70
+ ["git", "diff", "--cached", "--exit-code"],
71
+ stdout=subprocess.DEVNULL,
72
+ stderr=subprocess.DEVNULL,
73
+ ).returncode
74
+ != 0
75
+ )
63
76
 
64
77
  # 静默重置更改
65
- subprocess.run(["git", "reset"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
78
+ subprocess.run(
79
+ ["git", "reset"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL
80
+ )
66
81
 
67
82
  return working_changes or staged_changes
83
+
84
+
68
85
  def get_commits_between(start_hash: str, end_hash: str) -> List[Tuple[str, str]]:
69
86
  """获取两个提交哈希值之间的提交列表
70
87
 
@@ -78,103 +95,100 @@ def get_commits_between(start_hash: str, end_hash: str) -> List[Tuple[str, str]]
78
95
  try:
79
96
  # 使用git log和pretty格式获取哈希值和信息
80
97
  result = subprocess.run(
81
- ['git', 'log', f'{start_hash}..{end_hash}', '--pretty=format:%H|%s'],
98
+ ["git", "log", f"{start_hash}..{end_hash}", "--pretty=format:%H|%s"],
82
99
  stdout=subprocess.PIPE,
83
100
  stderr=subprocess.PIPE,
84
- text=False # 禁用自动文本解码
101
+ text=False, # 禁用自动文本解码
85
102
  )
86
103
  if result.returncode != 0:
87
- error_msg = result.stderr.decode('utf-8', errors='replace')
104
+ error_msg = result.stderr.decode("utf-8", errors="replace")
88
105
  PrettyOutput.print(f"获取commit历史失败: {error_msg}", OutputType.ERROR)
89
106
  return []
90
107
 
91
- output = result.stdout.decode('utf-8', errors='replace')
108
+ output = result.stdout.decode("utf-8", errors="replace")
92
109
  commits = []
93
110
  for line in output.splitlines():
94
- if '|' in line:
95
- commit_hash, message = line.split('|', 1)
111
+ if "|" in line:
112
+ commit_hash, message = line.split("|", 1)
96
113
  commits.append((commit_hash, message))
97
114
  return commits
98
115
 
99
116
  except Exception as e:
100
117
  PrettyOutput.print(f"获取commit历史异常: {str(e)}", OutputType.ERROR)
101
118
  return []
102
-
119
+
103
120
 
104
121
  # 修改后的获取差异函数
105
122
 
106
123
 
107
124
  def get_diff() -> str:
108
125
  """使用git获取工作区差异,包括修改和新增的文件内容
109
-
126
+
110
127
  返回:
111
128
  str: 差异内容或错误信息
112
129
  """
113
130
  try:
114
131
  # 暂存新增文件
115
- subprocess.run(['git', 'add', '-N', '.'], check=True)
116
-
132
+ subprocess.run(["git", "add", "-N", "."], check=True)
133
+
117
134
  # 获取所有差异(包括新增文件)
118
135
  result = subprocess.run(
119
- ['git', 'diff', 'HEAD'],
120
- capture_output=True,
121
- text=False,
122
- check=True
136
+ ["git", "diff", "HEAD"], capture_output=True, text=False, check=True
123
137
  )
124
-
138
+
125
139
  # 重置暂存区
126
- subprocess.run(['git', 'reset'], check=True)
127
-
140
+ subprocess.run(["git", "reset"], check=True)
141
+
128
142
  try:
129
- return result.stdout.decode('utf-8')
143
+ return result.stdout.decode("utf-8")
130
144
  except UnicodeDecodeError:
131
- return result.stdout.decode('utf-8', errors='replace')
132
-
145
+ return result.stdout.decode("utf-8", errors="replace")
146
+
133
147
  except subprocess.CalledProcessError as e:
134
148
  return f"获取差异失败: {str(e)}"
135
149
  except Exception as e:
136
150
  return f"发生意外错误: {str(e)}"
137
151
 
138
152
 
139
-
140
-
141
-
142
153
  def revert_file(filepath: str) -> None:
143
154
  """增强版git恢复,处理新文件"""
144
155
  import subprocess
156
+
145
157
  try:
146
158
  # 检查文件是否在版本控制中
147
159
  result = subprocess.run(
148
- ['git', 'ls-files', '--error-unmatch', filepath],
160
+ ["git", "ls-files", "--error-unmatch", filepath],
149
161
  stderr=subprocess.PIPE,
150
- text=False # 禁用自动文本解码
162
+ text=False, # 禁用自动文本解码
151
163
  )
152
164
  if result.returncode == 0:
153
- subprocess.run(['git', 'checkout', 'HEAD',
154
- '--', filepath], check=True)
165
+ subprocess.run(["git", "checkout", "HEAD", "--", filepath], check=True)
155
166
  else:
156
167
  if os.path.exists(filepath):
157
168
  os.remove(filepath)
158
- subprocess.run(['git', 'clean', '-f', '--', filepath], check=True)
169
+ subprocess.run(["git", "clean", "-f", "--", filepath], check=True)
159
170
  except subprocess.CalledProcessError as e:
160
- error_msg = e.stderr.decode('utf-8', errors='replace') if e.stderr else str(e)
171
+ error_msg = e.stderr.decode("utf-8", errors="replace") if e.stderr else str(e)
161
172
  PrettyOutput.print(f"恢复文件失败: {error_msg}", OutputType.ERROR)
173
+
174
+
162
175
  # 修改后的恢复函数
163
176
 
164
177
 
165
178
  def revert_change() -> None:
166
179
  """恢复所有未提交的修改到HEAD状态"""
167
180
  import subprocess
181
+
168
182
  try:
169
183
  # 检查是否为空仓库
170
184
  head_check = subprocess.run(
171
- ['git', 'rev-parse', '--verify', 'HEAD'],
185
+ ["git", "rev-parse", "--verify", "HEAD"],
172
186
  stderr=subprocess.PIPE,
173
- stdout=subprocess.PIPE
187
+ stdout=subprocess.PIPE,
174
188
  )
175
189
  if head_check.returncode == 0:
176
- subprocess.run(['git', 'reset', '--hard', 'HEAD'], check=True)
177
- subprocess.run(['git', 'clean', '-fd'], check=True)
190
+ subprocess.run(["git", "reset", "--hard", "HEAD"], check=True)
191
+ subprocess.run(["git", "clean", "-fd"], check=True)
178
192
  except subprocess.CalledProcessError as e:
179
193
  PrettyOutput.print(f"恢复更改失败: {str(e)}", OutputType.ERROR)
180
194
 
@@ -185,30 +199,30 @@ def handle_commit_workflow() -> bool:
185
199
  Returns:
186
200
  bool: 提交是否成功
187
201
  """
188
- if is_confirm_before_apply_patch() and not user_confirm("是否要提交代码?", default=True):
202
+ if is_confirm_before_apply_patch() and not user_confirm(
203
+ "是否要提交代码?", default=True
204
+ ):
189
205
  revert_change()
190
206
  return False
191
-
207
+
192
208
  import subprocess
209
+
193
210
  try:
194
211
  # 获取当前分支的提交总数
195
212
  commit_result = subprocess.run(
196
- ['git', 'rev-list', '--count', 'HEAD'],
197
- capture_output=True,
198
- text=True
213
+ ["git", "rev-list", "--count", "HEAD"], capture_output=True, text=True
199
214
  )
200
215
  if commit_result.returncode != 0:
201
216
  return False
202
-
217
+
203
218
  commit_count = int(commit_result.stdout.strip())
204
-
219
+
205
220
  # 暂存所有修改
206
- subprocess.run(['git', 'add', '.'], check=True)
207
-
221
+ subprocess.run(["git", "add", "."], check=True)
222
+
208
223
  # 提交变更
209
224
  subprocess.run(
210
- ['git', 'commit', '-m', f'CheckPoint #{commit_count + 1}'],
211
- check=True
225
+ ["git", "commit", "-m", f"CheckPoint #{commit_count + 1}"], check=True
212
226
  )
213
227
  return True
214
228
  except subprocess.CalledProcessError as e:
@@ -224,24 +238,30 @@ def get_latest_commit_hash() -> str:
224
238
  try:
225
239
  # 首先检查是否存在HEAD引用
226
240
  head_check = subprocess.run(
227
- ['git', 'rev-parse', '--verify', 'HEAD'],
241
+ ["git", "rev-parse", "--verify", "HEAD"],
228
242
  stdout=subprocess.PIPE,
229
243
  stderr=subprocess.PIPE,
230
- text=False
244
+ text=False,
231
245
  )
232
246
  if head_check.returncode != 0:
233
247
  return "" # 空仓库或无效HEAD
234
248
 
235
249
  # 获取HEAD的完整哈希值
236
250
  result = subprocess.run(
237
- ['git', 'rev-parse', 'HEAD'],
251
+ ["git", "rev-parse", "HEAD"],
238
252
  stdout=subprocess.PIPE,
239
253
  stderr=subprocess.PIPE,
240
- text=False
254
+ text=False,
255
+ )
256
+ return (
257
+ result.stdout.decode("utf-8", errors="replace").strip()
258
+ if result.returncode == 0
259
+ else ""
241
260
  )
242
- return result.stdout.decode('utf-8', errors='replace').strip() if result.returncode == 0 else ""
243
261
  except Exception:
244
262
  return ""
263
+
264
+
245
265
  def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
246
266
  """从Git差异中获取所有更改文件的修改行范围
247
267
 
@@ -274,18 +294,16 @@ def get_modified_line_ranges() -> Dict[str, Tuple[int, int]]:
274
294
  return result
275
295
 
276
296
 
277
-
278
297
  def is_file_in_git_repo(filepath: str) -> bool:
279
298
  """检查文件是否在当前Git仓库中"""
280
299
  import subprocess
300
+
281
301
  try:
282
302
  # 获取Git仓库根目录
283
303
  repo_root = subprocess.run(
284
- ['git', 'rev-parse', '--show-toplevel'],
285
- capture_output=True,
286
- text=True
304
+ ["git", "rev-parse", "--show-toplevel"], capture_output=True, text=True
287
305
  ).stdout.strip()
288
-
306
+
289
307
  # 检查文件路径是否在仓库根目录下
290
308
  return os.path.abspath(filepath).startswith(os.path.abspath(repo_root))
291
309
  except:
@@ -316,25 +334,49 @@ def check_and_update_git_repo(repo_path: str) -> bool:
316
334
  # 获取远程tag更新
317
335
  subprocess.run(["git", "fetch", "--tags"], cwd=git_root, check=True)
318
336
  # 获取最新本地tag
319
- local_tag_result = subprocess.run(["git", "describe", "--tags", "--abbrev=0"],
320
- cwd=git_root, capture_output=True, text=True)
337
+ local_tag_result = subprocess.run(
338
+ ["git", "describe", "--tags", "--abbrev=0"],
339
+ cwd=git_root,
340
+ capture_output=True,
341
+ text=True,
342
+ )
321
343
  # 获取最新远程tag
322
344
  remote_tag_result = subprocess.run(
323
345
  ["git", "ls-remote", "--tags", "--refs", "origin"],
324
- cwd=git_root, capture_output=True, text=True
346
+ cwd=git_root,
347
+ capture_output=True,
348
+ text=True,
325
349
  )
326
350
  if remote_tag_result.returncode == 0:
327
351
  # 提取最新的tag名称
328
352
  tags = [ref.split("/")[-1] for ref in remote_tag_result.stdout.splitlines()]
329
- tags = sorted(tags, key=lambda x: [int(i) if i.isdigit() else i for i in re.split(r'([0-9]+)', x)])
353
+ tags = sorted(
354
+ tags,
355
+ key=lambda x: [
356
+ int(i) if i.isdigit() else i for i in re.split(r"([0-9]+)", x)
357
+ ],
358
+ )
330
359
  remote_tag = tags[-1] if tags else ""
331
360
  remote_tag_result.stdout = remote_tag
332
361
 
333
- if (local_tag_result.returncode == 0 and remote_tag_result.returncode == 0 and
334
- local_tag_result.stdout.strip() != remote_tag_result.stdout.strip()):
335
- PrettyOutput.print(f"检测到新版本tag {remote_tag_result.stdout.strip()},正在更新Jarvis...", OutputType.INFO)
336
- subprocess.run(["git", "checkout", remote_tag_result.stdout.strip()], cwd=git_root, check=True)
337
- PrettyOutput.print(f"Jarvis已更新到tag {remote_tag_result.stdout.strip()}", OutputType.SUCCESS)
362
+ if (
363
+ local_tag_result.returncode == 0
364
+ and remote_tag_result.returncode == 0
365
+ and local_tag_result.stdout.strip() != remote_tag_result.stdout.strip()
366
+ ):
367
+ PrettyOutput.print(
368
+ f"检测到新版本tag {remote_tag_result.stdout.strip()},正在更新Jarvis...",
369
+ OutputType.INFO,
370
+ )
371
+ subprocess.run(
372
+ ["git", "checkout", remote_tag_result.stdout.strip()],
373
+ cwd=git_root,
374
+ check=True,
375
+ )
376
+ PrettyOutput.print(
377
+ f"Jarvis已更新到tag {remote_tag_result.stdout.strip()}",
378
+ OutputType.SUCCESS,
379
+ )
338
380
  return True
339
381
  return False
340
382
  except Exception as e:
@@ -346,30 +388,30 @@ def check_and_update_git_repo(repo_path: str) -> bool:
346
388
 
347
389
  def get_diff_file_list() -> List[str]:
348
390
  """获取HEAD到当前变更的文件列表,包括修改和新增的文件
349
-
391
+
350
392
  返回:
351
393
  List[str]: 修改和新增的文件路径列表
352
394
  """
353
395
  try:
354
396
  # 暂存新增文件
355
- subprocess.run(['git', 'add', '-N', '.'], check=True)
356
-
397
+ subprocess.run(["git", "add", "-N", "."], check=True)
398
+
357
399
  # 获取所有差异文件(包括新增文件)
358
400
  result = subprocess.run(
359
- ['git', 'diff', '--name-only', 'HEAD'],
360
- capture_output=True,
361
- text=True
401
+ ["git", "diff", "--name-only", "HEAD"], capture_output=True, text=True
362
402
  )
363
-
403
+
364
404
  # 重置暂存区
365
- subprocess.run(['git', 'reset'], check=True)
366
-
405
+ subprocess.run(["git", "reset"], check=True)
406
+
367
407
  if result.returncode != 0:
368
- PrettyOutput.print(f"获取差异文件列表失败: {result.stderr}", OutputType.ERROR)
408
+ PrettyOutput.print(
409
+ f"获取差异文件列表失败: {result.stderr}", OutputType.ERROR
410
+ )
369
411
  return []
370
-
412
+
371
413
  return [f for f in result.stdout.splitlines() if f]
372
-
414
+
373
415
  except subprocess.CalledProcessError as e:
374
416
  PrettyOutput.print(f"获取差异文件列表失败: {str(e)}", OutputType.ERROR)
375
417
  return []
@@ -378,10 +420,9 @@ def get_diff_file_list() -> List[str]:
378
420
  return []
379
421
 
380
422
 
381
-
382
423
  def get_recent_commits_with_files() -> List[Dict[str, Any]]:
383
424
  """获取最近5次提交的commit信息和文件清单
384
-
425
+
385
426
  返回:
386
427
  List[Dict[str, Any]]: 包含commit信息和文件清单的字典列表,格式为:
387
428
  [
@@ -399,9 +440,9 @@ def get_recent_commits_with_files() -> List[Dict[str, Any]]:
399
440
  try:
400
441
  # 获取最近5次提交的基本信息
401
442
  result = subprocess.run(
402
- ['git', 'log', '-5', '--pretty=format:%H%n%s%n%an%n%ad'],
443
+ ["git", "log", "-5", "--pretty=format:%H%n%s%n%an%n%ad"],
403
444
  capture_output=True,
404
- text=True
445
+ text=True,
405
446
  )
406
447
  if result.returncode != 0:
407
448
  return []
@@ -413,26 +454,26 @@ def get_recent_commits_with_files() -> List[Dict[str, Any]]:
413
454
  if i + 3 >= len(lines):
414
455
  break
415
456
  commit = {
416
- 'hash': lines[i],
417
- 'message': lines[i+1],
418
- 'author': lines[i+2],
419
- 'date': lines[i+3],
420
- 'files': []
457
+ "hash": lines[i],
458
+ "message": lines[i + 1],
459
+ "author": lines[i + 2],
460
+ "date": lines[i + 3],
461
+ "files": [],
421
462
  }
422
463
  commits.append(commit)
423
464
 
424
465
  # 获取每个提交的文件修改清单
425
466
  for commit in commits:
426
467
  files_result = subprocess.run(
427
- ['git', 'show', '--name-only', '--pretty=format:', commit['hash']],
468
+ ["git", "show", "--name-only", "--pretty=format:", commit["hash"]],
428
469
  capture_output=True,
429
- text=True
470
+ text=True,
430
471
  )
431
472
  if files_result.returncode == 0:
432
473
  files = list(set(filter(None, files_result.stdout.splitlines())))
433
- commit['files'] = files[:20] # 限制最多20个文件
474
+ commit["files"] = files[:20] # 限制最多20个文件
434
475
 
435
476
  return commits
436
477
 
437
478
  except subprocess.CalledProcessError:
438
- return []
479
+ return []
@@ -8,7 +8,7 @@
8
8
  - 环境初始化
9
9
  """
10
10
  import os
11
- from typing import Any, Dict, Set
11
+ from typing import Any, Set
12
12
 
13
13
  import colorama
14
14
  from rich.console import Console