jarvis-ai-assistant 0.1.193__py3-none-any.whl → 0.1.195__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 (92) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +45 -41
  3. jarvis/jarvis_agent/builtin_input_handler.py +26 -4
  4. jarvis/jarvis_agent/jarvis.py +30 -19
  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 +81 -79
  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 +31 -29
  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 +292 -190
  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 +15 -5
  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 +71 -39
  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 +44 -18
  44. jarvis/jarvis_platform/human.py +15 -3
  45. jarvis/jarvis_platform/kimi.py +117 -81
  46. jarvis/jarvis_platform/openai.py +23 -28
  47. jarvis/jarvis_platform/registry.py +43 -29
  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 -30
  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 +6 -11
  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 +60 -37
  74. jarvis/jarvis_utils/embedding.py +24 -19
  75. jarvis/jarvis_utils/file_processors.py +16 -9
  76. jarvis/jarvis_utils/git_utils.py +157 -107
  77. jarvis/jarvis_utils/globals.py +1 -1
  78. jarvis/jarvis_utils/input.py +85 -52
  79. jarvis/jarvis_utils/jarvis_history.py +43 -0
  80. jarvis/jarvis_utils/methodology.py +31 -24
  81. jarvis/jarvis_utils/output.py +164 -80
  82. jarvis/jarvis_utils/tag.py +2 -1
  83. jarvis/jarvis_utils/utils.py +84 -52
  84. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/METADATA +362 -230
  85. jarvis_ai_assistant-0.1.195.dist-info/RECORD +98 -0
  86. jarvis/jarvis_agent/file_input_handler.py +0 -112
  87. jarvis/jarvis_event/__init__.py +0 -0
  88. jarvis_ai_assistant-0.1.193.dist-info/RECORD +0 -99
  89. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/WHEEL +0 -0
  90. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/entry_points.txt +0 -0
  91. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/licenses/LICENSE +0 -0
  92. {jarvis_ai_assistant-0.1.193.dist-info → jarvis_ai_assistant-0.1.195.dist-info}/top_level.txt +0 -0
@@ -12,10 +12,8 @@ from typing import List, Optional, Tuple
12
12
 
13
13
  from yaspin import yaspin # type: ignore
14
14
 
15
- from jarvis import __version__
16
15
  from jarvis.jarvis_agent import Agent
17
16
  from jarvis.jarvis_agent.builtin_input_handler import builtin_input_handler
18
- from jarvis.jarvis_agent.file_input_handler import file_input_handler
19
17
  from jarvis.jarvis_agent.shell_input_handler import shell_input_handler
20
18
  # 忽略yaspin的类型检查
21
19
  from jarvis.jarvis_code_agent.lint import get_lint_tools
@@ -25,7 +23,8 @@ from jarvis.jarvis_tools.registry import ToolRegistry
25
23
  from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
26
24
  from jarvis.jarvis_utils.git_utils import (find_git_root, get_commits_between,
27
25
  get_diff, get_diff_file_list,
28
- get_latest_commit_hash, get_recent_commits_with_files,
26
+ get_latest_commit_hash,
27
+ get_recent_commits_with_files,
29
28
  handle_commit_workflow,
30
29
  has_uncommitted_changes)
31
30
  from jarvis.jarvis_utils.input import get_multiline_input
@@ -39,21 +38,26 @@ class CodeAgent:
39
38
  负责处理代码分析、修改和git操作。
40
39
  """
41
40
 
42
- def __init__(self, platform: Optional[str] = None,
43
- model: Optional[str] = None,
44
- need_summary: bool = True):
41
+ def __init__(
42
+ self,
43
+ platform: Optional[str] = None,
44
+ model: Optional[str] = None,
45
+ need_summary: bool = True,
46
+ ):
45
47
  self.root_dir = os.getcwd()
46
48
  tool_registry = ToolRegistry() # type: ignore
47
- tool_registry.use_tools([
48
- "execute_script",
49
- "search_web",
50
- "ask_user",
51
- "read_code",
52
- "methodology",
53
- "chdir",
54
- "edit_file",
55
- "rewrite_file"
56
- ])
49
+ tool_registry.use_tools(
50
+ [
51
+ "execute_script",
52
+ "search_web",
53
+ "ask_user",
54
+ "read_code",
55
+ "methodology",
56
+ "chdir",
57
+ "edit_file",
58
+ "rewrite_file",
59
+ ]
60
+ )
57
61
  code_system_prompt = """
58
62
  <code_engineer_guide>
59
63
  ## 角色定位
@@ -96,9 +100,11 @@ class CodeAgent:
96
100
  </code_engineer_guide>
97
101
  """
98
102
  # 处理platform参数
99
- platform_instance = (PlatformRegistry().create_platform(platform) # type: ignore
103
+ platform_instance = (
104
+ PlatformRegistry().create_platform(platform) # type: ignore
100
105
  if platform
101
- else PlatformRegistry().get_normal_platform()) # type: ignore
106
+ else PlatformRegistry().get_normal_platform()
107
+ ) # type: ignore
102
108
  if model:
103
109
  platform_instance.set_model_name(model) # type: ignore
104
110
 
@@ -108,26 +114,12 @@ class CodeAgent:
108
114
  auto_complete=False,
109
115
  output_handler=[tool_registry],
110
116
  platform=platform_instance,
111
- input_handler=[
112
- shell_input_handler,
113
- builtin_input_handler
114
- ],
115
- need_summary=need_summary
117
+ input_handler=[shell_input_handler, builtin_input_handler],
118
+ need_summary=need_summary,
116
119
  )
117
120
 
118
121
  self.agent.set_after_tool_call_cb(self.after_tool_call_cb)
119
122
 
120
- def get_root_dir(self) -> str:
121
- """获取项目根目录
122
-
123
- 返回:
124
- str: 项目根目录路径
125
- """
126
- return self.root_dir
127
-
128
-
129
-
130
-
131
123
  def _init_env(self) -> None:
132
124
  """初始化环境,包括:
133
125
  1. 查找git根目录
@@ -153,33 +145,33 @@ class CodeAgent:
153
145
  PrettyOutput.print("检测到未提交的修改,是否要提交?", OutputType.WARNING)
154
146
  if user_confirm("是否要提交?", True):
155
147
  import subprocess
148
+
156
149
  try:
157
150
  # 获取当前分支的提交总数
158
- commit_count = subprocess.run(
159
- ['git', 'rev-list', '--count', 'HEAD'],
151
+ commit_result = subprocess.run(
152
+ ["git", "rev-list", "--count", "HEAD"],
160
153
  capture_output=True,
161
- text=True
154
+ text=True,
155
+ check=True,
162
156
  )
163
- if commit_count.returncode != 0:
157
+ if commit_result.returncode != 0:
164
158
  return
165
-
166
- commit_count = int(commit_count.stdout.strip())
167
-
159
+
160
+ commit_count = int(commit_result.stdout.strip())
161
+
168
162
  # 暂存所有修改
169
- subprocess.run(['git', 'add', '.'], check=True)
170
-
163
+ subprocess.run(["git", "add", "."], check=True)
164
+
171
165
  # 提交变更
172
166
  subprocess.run(
173
- ['git', 'commit', '-m', f'CheckPoint #{commit_count + 1}'],
174
- check=True
167
+ ["git", "commit", "-m", f"CheckPoint #{commit_count + 1}"],
168
+ check=True,
175
169
  )
176
170
  except subprocess.CalledProcessError as e:
177
171
  PrettyOutput.print(f"提交失败: {str(e)}", OutputType.ERROR)
178
172
 
179
173
  def _show_commit_history(
180
- self,
181
- start_commit: Optional[str],
182
- end_commit: Optional[str]
174
+ self, start_commit: Optional[str], end_commit: Optional[str]
183
175
  ) -> List[Tuple[str, str]]:
184
176
  """显示两个提交之间的提交历史
185
177
 
@@ -196,20 +188,14 @@ class CodeAgent:
196
188
  commits = []
197
189
 
198
190
  if commits:
199
- commit_messages = (
200
- "检测到以下提交记录:\n" +
201
- "\n".join(
202
- f"- {commit_hash[:7]}: {message}"
203
- for commit_hash, message in commits
204
- )
191
+ commit_messages = "检测到以下提交记录:\n" + "\n".join(
192
+ f"- {commit_hash[:7]}: {message}" for commit_hash, message in commits
205
193
  )
206
194
  PrettyOutput.print(commit_messages, OutputType.INFO)
207
195
  return commits
208
196
 
209
197
  def _handle_commit_confirmation(
210
- self,
211
- commits: List[Tuple[str, str]],
212
- start_commit: Optional[str]
198
+ self, commits: List[Tuple[str, str]], start_commit: Optional[str]
213
199
  ) -> None:
214
200
  """处理提交确认和可能的重置"""
215
201
  if commits and user_confirm("是否接受以上提交记录?", True):
@@ -217,7 +203,7 @@ class CodeAgent:
217
203
  ["git", "reset", "--mixed", str(start_commit)],
218
204
  stdout=subprocess.DEVNULL,
219
205
  stderr=subprocess.DEVNULL,
220
- check=True
206
+ check=True,
221
207
  )
222
208
  git_commiter = GitCommitTool()
223
209
  git_commiter.execute({})
@@ -241,15 +227,15 @@ class CodeAgent:
241
227
  # 获取项目统计信息并附加到用户输入
242
228
  loc_stats = get_loc_stats()
243
229
  commits_info = get_recent_commits_with_files()
244
-
230
+
245
231
  project_info = []
246
232
  if loc_stats:
247
233
  project_info.append(f"代码统计:\n{loc_stats}")
248
234
  if commits_info:
249
235
  commits_str = "\n".join(
250
- f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n" +
251
- "\n".join(f" - {file}" for file in commit['files'][:5]) +
252
- ("\n ..." if len(commit['files']) > 5 else "")
236
+ f"提交 {i+1}: {commit['hash'][:7]} - {commit['message']} ({len(commit['files'])}个文件)\n"
237
+ + "\n".join(f" - {file}" for file in commit["files"][:5])
238
+ + ("\n ..." if len(commit["files"]) > 5 else "")
253
239
  for i, commit in enumerate(commits_info)
254
240
  )
255
241
  project_info.append(f"最近提交:\n{commits_str}")
@@ -264,7 +250,14 @@ class CodeAgent:
264
250
  """
265
251
 
266
252
  if project_info:
267
- enhanced_input = f"项目概况:\n" + "\n\n".join(project_info) + "\n\n" + first_tip + "\n\n任务描述:\n" + user_input
253
+ enhanced_input = (
254
+ f"项目概况:\n"
255
+ + "\n\n".join(project_info)
256
+ + "\n\n"
257
+ + first_tip
258
+ + "\n\n任务描述:\n"
259
+ + user_input
260
+ )
268
261
  else:
269
262
  enhanced_input = first_tip + "\n\n任务描述:\n" + user_input
270
263
 
@@ -282,7 +275,7 @@ class CodeAgent:
282
275
 
283
276
  except RuntimeError as e:
284
277
  return f"Error during execution: {str(e)}"
285
-
278
+
286
279
  def after_tool_call_cb(self, agent: Agent) -> None:
287
280
  """工具调用后回调函数。"""
288
281
  final_ret = ""
@@ -290,6 +283,7 @@ class CodeAgent:
290
283
  if diff:
291
284
  start_hash = get_latest_commit_hash()
292
285
  PrettyOutput.print(diff, OutputType.CODE, lang="diff")
286
+ modified_files = get_diff_file_list()
293
287
  commited = handle_commit_workflow()
294
288
  if commited:
295
289
  # 获取提交信息
@@ -298,16 +292,21 @@ class CodeAgent:
298
292
 
299
293
  # 添加提交信息到final_ret
300
294
  if commits:
301
- final_ret += f"\n\n代码已修改完成\n补丁内容:\n```diff\n{diff}\n```\n"
302
- modified_files = get_diff_file_list()
295
+ final_ret += (
296
+ f"\n\n代码已修改完成\n补丁内容:\n```diff\n{diff}\n```\n"
297
+ )
303
298
  # 修改后的提示逻辑
304
299
  lint_tools_info = "\n".join(
305
300
  f" - {file}: 使用 {'、'.join(get_lint_tools(file))}"
306
- for file in modified_files
301
+ for file in modified_files
307
302
  if get_lint_tools(file)
308
303
  )
309
304
  file_list = "\n".join(f" - {file}" for file in modified_files)
310
- tool_info = f"建议使用以下lint工具进行检查:\n{lint_tools_info}" if lint_tools_info else ""
305
+ tool_info = (
306
+ f"建议使用以下lint工具进行检查:\n{lint_tools_info}"
307
+ if lint_tools_info
308
+ else ""
309
+ )
311
310
  if lint_tools_info:
312
311
  addon_prompt = f"""
313
312
  请对以下修改的文件进行静态扫描:
@@ -328,7 +327,9 @@ class CodeAgent:
328
327
  agent.prompt += final_ret
329
328
  return
330
329
  PrettyOutput.print(final_ret, OutputType.USER, lang="markdown")
331
- if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
330
+ if not is_confirm_before_apply_patch() or user_confirm(
331
+ "是否使用此回复?", default=True
332
+ ):
332
333
  agent.prompt += final_ret
333
334
  return
334
335
  agent.prompt += final_ret
@@ -342,13 +343,16 @@ def main() -> None:
342
343
  """Jarvis主入口点。"""
343
344
  init_env("欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!")
344
345
 
345
- parser = argparse.ArgumentParser(description='Jarvis Code Agent')
346
- parser.add_argument('-p', '--platform', type=str,
347
- help='Target platform name', default=None)
348
- parser.add_argument('-m', '--model', type=str,
349
- help='Model name to use', default=None)
350
- parser.add_argument('-r', '--requirement', type=str,
351
- help='Requirement to process', default=None)
346
+ parser = argparse.ArgumentParser(description="Jarvis Code Agent")
347
+ parser.add_argument(
348
+ "-p", "--platform", type=str, help="Target platform name", default=None
349
+ )
350
+ parser.add_argument(
351
+ "-m", "--model", type=str, help="Model name to use", default=None
352
+ )
353
+ parser.add_argument(
354
+ "-r", "--requirement", type=str, help="Requirement to process", default=None
355
+ )
352
356
  args = parser.parse_args()
353
357
 
354
358
  curr_dir = os.getcwd()
@@ -362,9 +366,7 @@ def main() -> None:
362
366
  user_input = get_multiline_input("请输入你的需求(输入空行退出):")
363
367
  if not user_input:
364
368
  sys.exit(0)
365
- agent = CodeAgent(platform=args.platform,
366
- model=args.model,
367
- need_summary=False)
369
+ agent = CodeAgent(platform=args.platform, model=args.model, need_summary=False)
368
370
  agent.run(user_input)
369
371
 
370
372
  except RuntimeError as e:
@@ -15,144 +15,131 @@ from jarvis.jarvis_utils.config import get_data_dir
15
15
  # 默认的lint工具配置
16
16
  LINT_TOOLS = {
17
17
  # C/C++
18
- '.c': ['cppcheck', 'clang-tidy'],
19
- '.cpp': ['cppcheck', 'clang-tidy'],
20
- '.cc': ['cppcheck', 'clang-tidy'],
21
- '.cxx': ['cppcheck', 'clang-tidy'],
22
- '.h': ['cppcheck', 'clang-tidy'],
23
- '.hpp': ['cppcheck', 'clang-tidy'],
24
- '.hxx': ['cppcheck', 'clang-tidy'],
25
- '.inl': ['cppcheck', 'clang-tidy'],
26
- '.ipp': ['cppcheck', 'clang-tidy'],
27
-
18
+ ".c": ["clang-tidy"],
19
+ ".cpp": ["clang-tidy"],
20
+ ".cc": ["clang-tidy"],
21
+ ".cxx": ["clang-tidy"],
22
+ ".h": ["clang-tidy"],
23
+ ".hpp": ["clang-tidy"],
24
+ ".hxx": ["clang-tidy"],
25
+ ".inl": ["clang-tidy"],
26
+ ".ipp": ["clang-tidy"],
28
27
  # Go
29
- '.go': ['golint', 'go vet'],
30
-
28
+ ".go": ["go vet"],
31
29
  # Python
32
- '.py': ['black', 'pylint', 'mypy', 'isort'],
33
- '.pyw': ['black', 'pylint', 'mypy', 'isort'],
34
- '.pyi': ['black', 'pylint', 'mypy', 'isort'],
35
- '.pyx': ['black', 'pylint', 'mypy', 'isort'],
36
- '.pxd': ['black', 'pylint', 'mypy', 'isort'],
37
-
30
+ ".py": ["black", "pylint", "mypy", "isort"],
31
+ ".pyw": ["black", "pylint", "mypy", "isort"],
32
+ ".pyi": ["black", "pylint", "mypy", "isort"],
33
+ ".pyx": ["black", "pylint", "mypy", "isort"],
34
+ ".pxd": ["black", "pylint", "mypy", "isort"],
38
35
  # Rust
39
- '.rs': ['cargo clippy', 'rustfmt'],
40
- '.rlib': ['cargo clippy', 'rustfmt'],
41
-
36
+ ".rs": ["cargo clippy", "rustfmt"],
37
+ ".rlib": ["cargo clippy", "rustfmt"],
42
38
  # Java
43
- '.java': ['checkstyle', 'pmd'],
44
- '.class': ['checkstyle', 'pmd'],
45
- '.jar': ['checkstyle', 'pmd'],
46
-
39
+ ".java": ["pmd"],
40
+ ".class": ["pmd"],
41
+ ".jar": ["pmd"],
47
42
  # JavaScript/TypeScript
48
- '.js': ['eslint'],
49
- '.mjs': ['eslint'],
50
- '.cjs': ['eslint'],
51
- '.jsx': ['eslint'],
52
- '.ts': ['eslint', 'tsc'],
53
- '.tsx': ['eslint', 'tsc'],
54
- '.cts': ['eslint', 'tsc'],
55
- '.mts': ['eslint', 'tsc'],
56
-
43
+ ".js": ["eslint"],
44
+ ".mjs": ["eslint"],
45
+ ".cjs": ["eslint"],
46
+ ".jsx": ["eslint"],
47
+ ".ts": ["eslint", "tsc"],
48
+ ".tsx": ["eslint", "tsc"],
49
+ ".cts": ["eslint", "tsc"],
50
+ ".mts": ["eslint", "tsc"],
57
51
  # PHP
58
- '.php': ['phpcs', 'phpstan'],
59
- '.phtml': ['phpcs', 'phpstan'],
60
- '.php5': ['phpcs', 'phpstan'],
61
- '.php7': ['phpcs', 'phpstan'],
62
- '.phps': ['phpcs', 'phpstan'],
63
-
52
+ ".php": ["phpstan"],
53
+ ".phtml": ["phpstan"],
54
+ ".php5": ["phpstan"],
55
+ ".php7": ["phpstan"],
56
+ ".phps": ["phpstan"],
64
57
  # Ruby
65
- '.rb': ['rubocop'],
66
- '.rake': ['rubocop'],
67
- '.gemspec': ['rubocop'],
68
-
58
+ ".rb": ["rubocop"],
59
+ ".rake": ["rubocop"],
60
+ ".gemspec": ["rubocop"],
69
61
  # Swift
70
- '.swift': ['swiftlint'],
71
-
62
+ ".swift": ["swiftlint"],
72
63
  # Kotlin
73
- '.kt': ['ktlint'],
74
- '.kts': ['ktlint'],
75
-
64
+ ".kt": ["ktlint"],
65
+ ".kts": ["ktlint"],
76
66
  # C#
77
- '.cs': ['dotnet-format', 'roslynator'],
78
- '.csx': ['dotnet-format', 'roslynator'],
79
-
67
+ ".cs": ["roslynator"],
68
+ ".csx": ["roslynator"],
80
69
  # SQL
81
- '.sql': ['sqlfluff'],
82
-
70
+ ".sql": ["sqlfluff"],
83
71
  # Shell/Bash
84
- '.sh': ['shellcheck'],
85
- '.bash': ['shellcheck'],
86
-
72
+ ".sh": ["shellcheck"],
73
+ ".bash": ["shellcheck"],
87
74
  # HTML/CSS
88
- '.html': ['htmlhint'],
89
- '.htm': ['htmlhint'],
90
- '.xhtml': ['htmlhint'],
91
- '.css': ['stylelint'],
92
- '.scss': ['stylelint'],
93
- '.sass': ['stylelint'],
94
- '.less': ['stylelint'],
95
-
75
+ ".html": ["htmlhint"],
76
+ ".htm": ["htmlhint"],
77
+ ".xhtml": ["htmlhint"],
78
+ ".css": ["stylelint"],
79
+ ".scss": ["stylelint"],
80
+ ".sass": ["stylelint"],
81
+ ".less": ["stylelint"],
96
82
  # XML/JSON/YAML
97
- '.xml': ['xmllint'],
98
- '.xsd': ['xmllint'],
99
- '.dtd': ['xmllint'],
100
- '.tld': ['xmllint'],
101
- '.jsp': ['xmllint'],
102
- '.jspx': ['xmllint'],
103
- '.tag': ['xmllint'],
104
- '.tagx': ['xmllint'],
105
- '.json': ['jsonlint'],
106
- '.jsonl': ['jsonlint'],
107
- '.json5': ['jsonlint'],
108
- '.yaml': ['yamllint'],
109
- '.yml': ['yamllint'],
110
-
83
+ ".xml": ["xmllint"],
84
+ ".xsd": ["xmllint"],
85
+ ".dtd": ["xmllint"],
86
+ ".tld": ["xmllint"],
87
+ ".jsp": ["xmllint"],
88
+ ".jspx": ["xmllint"],
89
+ ".tag": ["xmllint"],
90
+ ".tagx": ["xmllint"],
91
+ ".json": ["jsonlint"],
92
+ ".jsonl": ["jsonlint"],
93
+ ".json5": ["jsonlint"],
94
+ ".yaml": ["yamllint"],
95
+ ".yml": ["yamllint"],
111
96
  # Markdown/Documentation
112
- '.md': ['markdownlint'],
113
- '.markdown': ['markdownlint'],
114
- '.rst': ['rstcheck'],
115
- '.adoc': ['asciidoctor-lint'],
116
-
97
+ ".md": ["markdownlint"],
98
+ ".markdown": ["markdownlint"],
99
+ ".rst": ["rstcheck"],
100
+ ".adoc": ["asciidoctor-lint"],
117
101
  # Docker/Terraform/Makefile等无后缀文件
118
- 'makefile': ['checkmake'],
119
- 'dockerfile': ['hadolint'],
120
- 'docker-compose.yml': ['hadolint'],
121
- 'docker-compose.yaml': ['hadolint'],
122
- 'jenkinsfile': ['jenkinsfile-linter'],
123
- 'build': ['buildifier'],
124
- 'workspace': ['buildifier'],
125
- '.bashrc': ['shellcheck'],
126
- '.bash_profile': ['shellcheck'],
127
- '.zshrc': ['shellcheck'],
128
- '.gitignore': ['git-lint'],
129
- '.editorconfig': ['editorconfig-checker'],
130
- '.eslintrc': ['eslint'],
131
- '.prettierrc': ['prettier'],
132
- 'cmakelists.txt': ['cmake-format'],
133
- '.cmake': ['cmake-format'],
102
+ "makefile": ["checkmake"],
103
+ "dockerfile": ["hadolint"],
104
+ "docker-compose.yml": ["hadolint"],
105
+ "docker-compose.yaml": ["hadolint"],
106
+ "jenkinsfile": ["jenkinsfile-linter"],
107
+ "build": ["buildifier"],
108
+ "workspace": ["buildifier"],
109
+ ".bashrc": ["shellcheck"],
110
+ ".bash_profile": ["shellcheck"],
111
+ ".zshrc": ["shellcheck"],
112
+ ".gitignore": ["git-lint"],
113
+ ".editorconfig": ["editorconfig-checker"],
114
+ ".eslintrc": ["eslint"],
115
+ ".prettierrc": ["prettier"],
116
+ "cmakelists.txt": ["cmake-format"],
117
+ ".cmake": ["cmake-format"],
134
118
  }
135
119
 
120
+
136
121
  def load_lint_tools_config() -> Dict[str, List[str]]:
137
122
  """从yaml文件加载lint工具配置"""
138
- config_path = os.path.join(get_data_dir(), 'lint_tools.yaml')
123
+ config_path = os.path.join(get_data_dir(), "lint_tools.yaml")
139
124
  if not os.path.exists(config_path):
140
125
  return {}
141
-
142
- with open(config_path, 'r') as f:
126
+
127
+ with open(config_path, "r") as f:
143
128
  config = yaml.safe_load(f) or {}
144
129
  return {k.lower(): v for k, v in config.items()} # 确保key是小写
145
130
 
131
+
146
132
  # 合并默认配置和yaml配置
147
133
  LINT_TOOLS.update(load_lint_tools_config())
148
134
 
135
+
149
136
  def get_lint_tools(filename: str) -> List[str]:
150
137
  """
151
138
  根据文件扩展名或文件名获取对应的lint工具列表
152
-
139
+
153
140
  Args:
154
141
  file_extension_or_name: 文件扩展名(如'.py')或文件名(如'Makefile')
155
-
142
+
156
143
  Returns:
157
144
  对应的lint工具列表,如果找不到则返回空列表
158
145
  """
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """
3
3
  Language-specific checklists for code review.
4
- """
4
+ """
@@ -48,4 +48,4 @@ CHECKLIST = """
48
48
  ### 编译器警告
49
49
  - [ ] 是否有未解决的编译器警告
50
50
  - [ ] 是否启用了合适的警告级别
51
- """
51
+ """
@@ -73,4 +73,4 @@ CHECKLIST = """
73
73
  - [ ] 公共 API 是否有文档说明
74
74
  - [ ] 复杂逻辑是否有注释
75
75
  - [ ] 注释是否与代码保持同步
76
- """
76
+ """
@@ -80,4 +80,4 @@ CHECKLIST = """
80
80
  - [ ] 是否避免了过度暴露内部数据结构
81
81
  - [ ] 序列化/反序列化是否安全
82
82
  - [ ] 是否避免了使用有风险的格式特性
83
- """
83
+ """
@@ -105,4 +105,4 @@ CHECKLIST = """
105
105
  - [ ] 是否有版本控制和变更历史
106
106
  - [ ] 是否有明确的故障排除指南
107
107
  - [ ] 依赖关系是否明确记录
108
- """
108
+ """
@@ -85,4 +85,4 @@ CHECKLIST = """
85
85
  - [ ] 自动化构建和部署是否配置正确
86
86
  - [ ] 是否有预览环境测试文档更改
87
87
  - [ ] 是否集成了持续集成/持续部署流程
88
- """
88
+ """
@@ -50,4 +50,4 @@ CHECKLIST = """
50
50
  ### 文档
51
51
  - [ ] 导出的函数/类型是否有文档注释
52
52
  - [ ] 复杂逻辑是否有注释说明
53
- """
53
+ """
@@ -96,4 +96,4 @@ CHECKLIST = """
96
96
  - [ ] 是否优化了资源成本
97
97
  - [ ] 是否考虑了服务限制和配额
98
98
  - [ ] 是否正确配置了自动扩展
99
- """
99
+ """
@@ -64,4 +64,4 @@ CHECKLIST = """
64
64
  - [ ] 公共 API 是否有 JavaDoc 注释
65
65
  - [ ] 复杂逻辑是否有注释说明
66
66
  - [ ] 注释是否准确且最新
67
- """
67
+ """
@@ -71,4 +71,4 @@ CHECKLIST = """
71
71
  - [ ] 复杂逻辑是否抽象成可测试的函数
72
72
  - [ ] 是否遵循 DRY 原则
73
73
  - [ ] 状态管理是否合理
74
- """
74
+ """
@@ -105,4 +105,4 @@ CHECKLIST = """
105
105
  - [ ] API 参数和返回值是否有文档说明
106
106
  - [ ] 是否包含了示例代码或用例
107
107
  - [ ] 是否维护了 CHANGELOG 记录
108
- """
108
+ """