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.
Files changed (279) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +567 -222
  3. jarvis/jarvis_agent/agent_manager.py +19 -12
  4. jarvis/jarvis_agent/builtin_input_handler.py +79 -11
  5. jarvis/jarvis_agent/config_editor.py +7 -2
  6. jarvis/jarvis_agent/event_bus.py +24 -13
  7. jarvis/jarvis_agent/events.py +19 -1
  8. jarvis/jarvis_agent/file_context_handler.py +67 -64
  9. jarvis/jarvis_agent/file_methodology_manager.py +38 -24
  10. jarvis/jarvis_agent/jarvis.py +186 -114
  11. jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
  12. jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
  13. jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
  14. jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
  15. jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
  16. jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
  17. jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
  18. jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
  19. jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
  20. jarvis/jarvis_agent/language_support_info.py +250 -219
  21. jarvis/jarvis_agent/main.py +19 -23
  22. jarvis/jarvis_agent/memory_manager.py +9 -6
  23. jarvis/jarvis_agent/methodology_share_manager.py +21 -15
  24. jarvis/jarvis_agent/output_handler.py +4 -2
  25. jarvis/jarvis_agent/prompt_builder.py +7 -6
  26. jarvis/jarvis_agent/prompt_manager.py +113 -8
  27. jarvis/jarvis_agent/prompts.py +317 -85
  28. jarvis/jarvis_agent/protocols.py +5 -2
  29. jarvis/jarvis_agent/run_loop.py +192 -32
  30. jarvis/jarvis_agent/session_manager.py +7 -3
  31. jarvis/jarvis_agent/share_manager.py +23 -13
  32. jarvis/jarvis_agent/shell_input_handler.py +12 -8
  33. jarvis/jarvis_agent/stdio_redirect.py +25 -26
  34. jarvis/jarvis_agent/task_analyzer.py +29 -23
  35. jarvis/jarvis_agent/task_list.py +869 -0
  36. jarvis/jarvis_agent/task_manager.py +26 -23
  37. jarvis/jarvis_agent/tool_executor.py +6 -5
  38. jarvis/jarvis_agent/tool_share_manager.py +24 -14
  39. jarvis/jarvis_agent/user_interaction.py +3 -3
  40. jarvis/jarvis_agent/utils.py +9 -1
  41. jarvis/jarvis_agent/web_bridge.py +37 -17
  42. jarvis/jarvis_agent/web_output_sink.py +5 -2
  43. jarvis/jarvis_agent/web_server.py +165 -36
  44. jarvis/jarvis_c2rust/__init__.py +1 -1
  45. jarvis/jarvis_c2rust/cli.py +260 -141
  46. jarvis/jarvis_c2rust/collector.py +37 -18
  47. jarvis/jarvis_c2rust/constants.py +60 -0
  48. jarvis/jarvis_c2rust/library_replacer.py +242 -1010
  49. jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
  50. jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
  51. jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
  52. jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
  53. jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
  54. jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
  55. jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
  56. jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
  57. jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
  58. jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
  59. jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
  60. jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
  61. jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
  62. jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
  63. jarvis/jarvis_c2rust/loaders.py +28 -10
  64. jarvis/jarvis_c2rust/models.py +5 -2
  65. jarvis/jarvis_c2rust/optimizer.py +192 -1974
  66. jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
  67. jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
  68. jarvis/jarvis_c2rust/optimizer_config.py +49 -0
  69. jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
  70. jarvis/jarvis_c2rust/optimizer_options.py +48 -0
  71. jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
  72. jarvis/jarvis_c2rust/optimizer_report.py +52 -0
  73. jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
  74. jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
  75. jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
  76. jarvis/jarvis_c2rust/scanner.py +229 -166
  77. jarvis/jarvis_c2rust/transpiler.py +531 -2732
  78. jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
  79. jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
  80. jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
  81. jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
  82. jarvis/jarvis_c2rust/transpiler_config.py +178 -0
  83. jarvis/jarvis_c2rust/transpiler_context.py +122 -0
  84. jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
  85. jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
  86. jarvis/jarvis_c2rust/transpiler_git.py +163 -0
  87. jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
  88. jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
  89. jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
  90. jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
  91. jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
  92. jarvis/jarvis_c2rust/utils.py +269 -79
  93. jarvis/jarvis_code_agent/after_change.py +233 -0
  94. jarvis/jarvis_code_agent/build_validation_config.py +37 -30
  95. jarvis/jarvis_code_agent/builtin_rules.py +68 -0
  96. jarvis/jarvis_code_agent/code_agent.py +976 -1517
  97. jarvis/jarvis_code_agent/code_agent_build.py +227 -0
  98. jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
  99. jarvis/jarvis_code_agent/code_agent_git.py +525 -0
  100. jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
  101. jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
  102. jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
  103. jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
  104. jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
  105. jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
  106. jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
  107. jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
  108. jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
  109. jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
  110. jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
  111. jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
  112. jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
  113. jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
  114. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
  115. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
  116. jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
  117. jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
  118. jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
  119. jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
  120. jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
  121. jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
  122. jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
  123. jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
  124. jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
  125. jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
  126. jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
  127. jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
  128. jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
  129. jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
  130. jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
  131. jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
  132. jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
  133. jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
  134. jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
  135. jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
  136. jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
  137. jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
  138. jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
  139. jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
  140. jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
  141. jarvis/jarvis_code_agent/lint.py +223 -524
  142. jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
  143. jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
  144. jarvis/jarvis_code_agent/rules/code_review.md +115 -0
  145. jarvis/jarvis_code_agent/rules/documentation.md +165 -0
  146. jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
  147. jarvis/jarvis_code_agent/rules/performance.md +158 -0
  148. jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
  149. jarvis/jarvis_code_agent/rules/security.md +160 -0
  150. jarvis/jarvis_code_agent/rules/tdd.md +78 -0
  151. jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
  152. jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
  153. jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
  154. jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
  155. jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
  156. jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
  157. jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
  158. jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
  159. jarvis/jarvis_code_agent/utils.py +36 -26
  160. jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
  161. jarvis/jarvis_code_analysis/code_review.py +64 -33
  162. jarvis/jarvis_data/config_schema.json +285 -192
  163. jarvis/jarvis_git_squash/main.py +8 -6
  164. jarvis/jarvis_git_utils/git_commiter.py +53 -76
  165. jarvis/jarvis_mcp/__init__.py +5 -2
  166. jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
  167. jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
  168. jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
  169. jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
  170. jarvis/jarvis_methodology/main.py +48 -39
  171. jarvis/jarvis_multi_agent/__init__.py +56 -23
  172. jarvis/jarvis_multi_agent/main.py +15 -18
  173. jarvis/jarvis_platform/base.py +179 -111
  174. jarvis/jarvis_platform/human.py +27 -16
  175. jarvis/jarvis_platform/kimi.py +52 -45
  176. jarvis/jarvis_platform/openai.py +101 -40
  177. jarvis/jarvis_platform/registry.py +51 -33
  178. jarvis/jarvis_platform/tongyi.py +68 -38
  179. jarvis/jarvis_platform/yuanbao.py +59 -43
  180. jarvis/jarvis_platform_manager/main.py +68 -76
  181. jarvis/jarvis_platform_manager/service.py +24 -14
  182. jarvis/jarvis_rag/README_CONFIG.md +314 -0
  183. jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
  184. jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
  185. jarvis/jarvis_rag/__init__.py +57 -4
  186. jarvis/jarvis_rag/cache.py +3 -1
  187. jarvis/jarvis_rag/cli.py +48 -68
  188. jarvis/jarvis_rag/embedding_interface.py +39 -0
  189. jarvis/jarvis_rag/embedding_manager.py +7 -230
  190. jarvis/jarvis_rag/embeddings/__init__.py +41 -0
  191. jarvis/jarvis_rag/embeddings/base.py +114 -0
  192. jarvis/jarvis_rag/embeddings/cohere.py +66 -0
  193. jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
  194. jarvis/jarvis_rag/embeddings/local.py +260 -0
  195. jarvis/jarvis_rag/embeddings/openai.py +62 -0
  196. jarvis/jarvis_rag/embeddings/registry.py +293 -0
  197. jarvis/jarvis_rag/llm_interface.py +8 -6
  198. jarvis/jarvis_rag/query_rewriter.py +8 -9
  199. jarvis/jarvis_rag/rag_pipeline.py +61 -52
  200. jarvis/jarvis_rag/reranker.py +7 -75
  201. jarvis/jarvis_rag/reranker_interface.py +32 -0
  202. jarvis/jarvis_rag/rerankers/__init__.py +41 -0
  203. jarvis/jarvis_rag/rerankers/base.py +109 -0
  204. jarvis/jarvis_rag/rerankers/cohere.py +67 -0
  205. jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
  206. jarvis/jarvis_rag/rerankers/jina.py +79 -0
  207. jarvis/jarvis_rag/rerankers/local.py +89 -0
  208. jarvis/jarvis_rag/rerankers/registry.py +293 -0
  209. jarvis/jarvis_rag/retriever.py +58 -43
  210. jarvis/jarvis_sec/__init__.py +66 -141
  211. jarvis/jarvis_sec/agents.py +21 -17
  212. jarvis/jarvis_sec/analysis.py +80 -33
  213. jarvis/jarvis_sec/checkers/__init__.py +7 -13
  214. jarvis/jarvis_sec/checkers/c_checker.py +356 -164
  215. jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
  216. jarvis/jarvis_sec/cli.py +43 -21
  217. jarvis/jarvis_sec/clustering.py +430 -272
  218. jarvis/jarvis_sec/file_manager.py +99 -55
  219. jarvis/jarvis_sec/parsers.py +9 -6
  220. jarvis/jarvis_sec/prompts.py +4 -3
  221. jarvis/jarvis_sec/report.py +44 -22
  222. jarvis/jarvis_sec/review.py +180 -107
  223. jarvis/jarvis_sec/status.py +50 -41
  224. jarvis/jarvis_sec/types.py +3 -0
  225. jarvis/jarvis_sec/utils.py +160 -83
  226. jarvis/jarvis_sec/verification.py +411 -181
  227. jarvis/jarvis_sec/workflow.py +132 -21
  228. jarvis/jarvis_smart_shell/main.py +28 -41
  229. jarvis/jarvis_stats/cli.py +14 -12
  230. jarvis/jarvis_stats/stats.py +28 -19
  231. jarvis/jarvis_stats/storage.py +14 -8
  232. jarvis/jarvis_stats/visualizer.py +12 -7
  233. jarvis/jarvis_tools/base.py +5 -2
  234. jarvis/jarvis_tools/clear_memory.py +13 -9
  235. jarvis/jarvis_tools/cli/main.py +23 -18
  236. jarvis/jarvis_tools/edit_file.py +572 -873
  237. jarvis/jarvis_tools/execute_script.py +10 -7
  238. jarvis/jarvis_tools/file_analyzer.py +7 -8
  239. jarvis/jarvis_tools/meta_agent.py +287 -0
  240. jarvis/jarvis_tools/methodology.py +5 -3
  241. jarvis/jarvis_tools/read_code.py +305 -1438
  242. jarvis/jarvis_tools/read_symbols.py +50 -17
  243. jarvis/jarvis_tools/read_webpage.py +19 -18
  244. jarvis/jarvis_tools/registry.py +435 -156
  245. jarvis/jarvis_tools/retrieve_memory.py +16 -11
  246. jarvis/jarvis_tools/save_memory.py +8 -6
  247. jarvis/jarvis_tools/search_web.py +31 -31
  248. jarvis/jarvis_tools/sub_agent.py +32 -28
  249. jarvis/jarvis_tools/sub_code_agent.py +44 -60
  250. jarvis/jarvis_tools/task_list_manager.py +1811 -0
  251. jarvis/jarvis_tools/virtual_tty.py +29 -19
  252. jarvis/jarvis_utils/__init__.py +4 -0
  253. jarvis/jarvis_utils/builtin_replace_map.py +2 -1
  254. jarvis/jarvis_utils/clipboard.py +9 -8
  255. jarvis/jarvis_utils/collections.py +331 -0
  256. jarvis/jarvis_utils/config.py +699 -194
  257. jarvis/jarvis_utils/dialogue_recorder.py +294 -0
  258. jarvis/jarvis_utils/embedding.py +6 -3
  259. jarvis/jarvis_utils/file_processors.py +7 -1
  260. jarvis/jarvis_utils/fzf.py +9 -3
  261. jarvis/jarvis_utils/git_utils.py +71 -42
  262. jarvis/jarvis_utils/globals.py +116 -32
  263. jarvis/jarvis_utils/http.py +6 -2
  264. jarvis/jarvis_utils/input.py +318 -83
  265. jarvis/jarvis_utils/jsonnet_compat.py +119 -104
  266. jarvis/jarvis_utils/methodology.py +37 -28
  267. jarvis/jarvis_utils/output.py +201 -44
  268. jarvis/jarvis_utils/utils.py +986 -628
  269. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
  270. jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
  271. jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
  272. jarvis/jarvis_tools/generate_new_tool.py +0 -205
  273. jarvis/jarvis_tools/lsp_client.py +0 -1552
  274. jarvis/jarvis_tools/rewrite_file.py +0 -105
  275. jarvis_ai_assistant-0.7.8.dist-info/RECORD +0 -218
  276. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
  277. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
  278. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
  279. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
@@ -4,123 +4,146 @@
4
4
  提供语言功能支持情况的收集和展示功能。
5
5
  """
6
6
 
7
- import subprocess
8
- from typing import Dict, Any, List
7
+ from typing import Any
8
+ from typing import Dict
9
+ from typing import List
9
10
 
10
11
 
11
12
  def _collect_language_support_info() -> Dict[str, Dict[str, Any]]:
12
13
  """收集所有语言的功能支持信息"""
13
14
  info: Dict[str, Dict[str, Any]] = {}
14
-
15
+
15
16
  # 确保语言支持模块已加载(触发自动注册)
16
17
  try:
17
- import jarvis.jarvis_code_agent.code_analyzer.language_support # noqa: F401
18
+ pass
18
19
  except Exception:
19
20
  pass
20
-
21
+
21
22
  # 从 code_analyzer 获取语言支持
22
23
  try:
23
- from jarvis.jarvis_code_agent.code_analyzer.language_registry import get_registry
24
+ from jarvis.jarvis_code_agent.code_analyzer.language_registry import (
25
+ get_registry,
26
+ )
27
+
24
28
  registry = get_registry()
25
-
29
+
26
30
  for lang_name in registry.get_supported_languages():
27
31
  lang_support = registry.get_language_support(lang_name)
28
32
  if lang_support:
29
33
  if lang_name not in info:
30
34
  info[lang_name] = {}
31
-
35
+
32
36
  # 检查符号提取支持
33
37
  try:
34
38
  extractor = lang_support.create_symbol_extractor()
35
- info[lang_name]['符号提取'] = extractor is not None
39
+ info[lang_name]["符号提取"] = extractor is not None
36
40
  except Exception:
37
41
  # 如果创建失败,先标记为 False,后续会检查 file_context_handler 中的提取器
38
- info[lang_name]['符号提取'] = False
39
-
42
+ info[lang_name]["符号提取"] = False
43
+
40
44
  # 检查依赖分析支持
41
45
  try:
42
46
  analyzer = lang_support.create_dependency_analyzer()
43
- info[lang_name]['依赖分析'] = analyzer is not None
47
+ info[lang_name]["依赖分析"] = analyzer is not None
44
48
  except Exception:
45
- info[lang_name]['依赖分析'] = False
46
-
47
- # 检查结构化编辑支持(基于符号提取器)
48
- try:
49
- # 结构化编辑需要符号提取器支持
50
- extractor = lang_support.create_symbol_extractor()
51
- info[lang_name]['结构化编辑'] = extractor is not None
52
- except Exception:
53
- info[lang_name]['结构化编辑'] = False
49
+ info[lang_name]["依赖分析"] = False
50
+
54
51
  except Exception:
55
52
  pass
56
-
53
+
57
54
  # 从 file_context_handler 获取上下文提取支持,同时也用于补充符号提取支持
58
55
  try:
59
56
  from jarvis.jarvis_agent.file_context_handler import _LANGUAGE_EXTRACTORS
60
-
57
+
61
58
  # 扩展名到语言名称的映射
62
59
  lang_name_map = {
63
- '.py': 'python', '.pyw': 'python',
64
- '.rs': 'rust',
65
- '.go': 'go',
66
- '.c': 'c', '.h': 'c',
67
- '.cpp': 'cpp', '.cc': 'cpp', '.cxx': 'cpp', '.hpp': 'cpp', '.hxx': 'cpp',
68
- '.js': 'javascript', '.jsx': 'javascript',
69
- '.ts': 'typescript', '.tsx': 'typescript',
70
- '.java': 'java',
60
+ ".py": "python",
61
+ ".pyw": "python",
62
+ ".rs": "rust",
63
+ ".go": "go",
64
+ ".c": "c",
65
+ ".h": "c",
66
+ ".cpp": "cpp",
67
+ ".cc": "cpp",
68
+ ".cxx": "cpp",
69
+ ".hpp": "cpp",
70
+ ".hxx": "cpp",
71
+ ".js": "javascript",
72
+ ".jsx": "javascript",
73
+ ".ts": "typescript",
74
+ ".tsx": "typescript",
75
+ ".java": "java",
71
76
  }
72
-
77
+
73
78
  for ext, factory in _LANGUAGE_EXTRACTORS.items():
74
79
  try:
75
80
  # 尝试创建提取器,只有成功创建才标记为支持
76
81
  extractor = factory()
77
82
  if extractor is not None:
78
- lang_name = lang_name_map.get(ext, ext[1:] if ext.startswith('.') else ext)
79
-
83
+ lang_name = lang_name_map.get(
84
+ ext, ext[1:] if ext.startswith(".") else ext
85
+ )
86
+
80
87
  if lang_name not in info:
81
88
  info[lang_name] = {}
82
-
89
+
83
90
  # 上下文提取支持(只有成功创建才支持)
84
- info[lang_name]['上下文提取'] = True
85
-
91
+ info[lang_name]["上下文提取"] = True
92
+
86
93
  # 如果 code_analyzer 中的符号提取不支持,但 file_context_handler 中能成功创建提取器,也标记为支持
87
- if '符号提取' not in info[lang_name] or not info[lang_name]['符号提取']:
88
- info[lang_name]['符号提取'] = True
94
+ if (
95
+ "符号提取" not in info[lang_name]
96
+ or not info[lang_name]["符号提取"]
97
+ ):
98
+ info[lang_name]["符号提取"] = True
89
99
  except Exception:
90
100
  # 静默失败,不记录错误(避免输出过多调试信息)
91
101
  pass
92
102
  except Exception:
93
103
  pass
94
-
104
+
95
105
  # 检查构建验证支持(自动发现所有构建验证器)
96
106
  try:
97
- from jarvis.jarvis_code_agent.code_analyzer.build_validator import __all__
98
- from jarvis.jarvis_code_agent.code_analyzer.build_validator.base import BuildValidatorBase
99
107
  import jarvis.jarvis_code_agent.code_analyzer.build_validator as build_validator_module
100
-
108
+ from jarvis.jarvis_code_agent.code_analyzer.build_validator import __all__
109
+ from jarvis.jarvis_code_agent.code_analyzer.build_validator.base import (
110
+ BuildValidatorBase,
111
+ )
112
+
101
113
  # 自动发现所有构建验证器类(排除基类和工具类)
102
114
  validator_classes = []
103
- exclude_classes = {'BuildValidatorBase', 'BuildSystemDetector', 'BuildValidator', 'BuildSystem', 'BuildResult'}
104
-
115
+ exclude_classes = {
116
+ "BuildValidatorBase",
117
+ "BuildSystemDetector",
118
+ "BuildValidator",
119
+ "BuildSystem",
120
+ "BuildResult",
121
+ }
122
+
105
123
  for name in __all__:
106
- if name not in exclude_classes and name.endswith('BuildValidator'):
124
+ if name not in exclude_classes and name.endswith("BuildValidator"):
107
125
  try:
108
126
  validator_class = getattr(build_validator_module, name)
109
127
  # 检查是否是 BuildValidatorBase 的子类
110
- if issubclass(validator_class, BuildValidatorBase) and validator_class != BuildValidatorBase:
128
+ if (
129
+ issubclass(validator_class, BuildValidatorBase)
130
+ and validator_class != BuildValidatorBase
131
+ ):
111
132
  validator_classes.append(validator_class)
112
133
  except (AttributeError, TypeError, Exception):
113
134
  continue
114
-
135
+
115
136
  # 为每种语言收集支持的构建系统名称
116
137
  lang_to_build_systems: Dict[str, List[str]] = {}
117
-
138
+
118
139
  for validator_class in validator_classes:
119
140
  try:
120
141
  # 检查类是否有 BUILD_SYSTEM_NAME 和 SUPPORTED_LANGUAGES
121
- build_system_name = getattr(validator_class, 'BUILD_SYSTEM_NAME', '')
122
- supported_languages = getattr(validator_class, 'SUPPORTED_LANGUAGES', [])
123
-
142
+ build_system_name = getattr(validator_class, "BUILD_SYSTEM_NAME", "")
143
+ supported_languages = getattr(
144
+ validator_class, "SUPPORTED_LANGUAGES", []
145
+ )
146
+
124
147
  if build_system_name and supported_languages:
125
148
  for lang in supported_languages:
126
149
  if lang not in lang_to_build_systems:
@@ -129,93 +152,101 @@ def _collect_language_support_info() -> Dict[str, Dict[str, Any]]:
129
152
  lang_to_build_systems[lang].append(build_system_name)
130
153
  except (AttributeError, Exception):
131
154
  continue
132
-
155
+
133
156
  # 将构建系统信息添加到 info 中
134
157
  for lang_name, build_systems in lang_to_build_systems.items():
135
158
  if lang_name not in info:
136
159
  info[lang_name] = {}
137
160
  if build_systems:
138
161
  # 存储构建系统名称列表(用于显示)
139
- info[lang_name]['构建验证'] = ', '.join(sorted(build_systems))
162
+ info[lang_name]["构建验证"] = ", ".join(sorted(build_systems))
140
163
  else:
141
- info[lang_name]['构建验证'] = False
142
-
164
+ info[lang_name]["构建验证"] = False
165
+
143
166
  except (ImportError, Exception):
144
167
  pass
145
-
168
+
146
169
  # 检查静态检查支持(从 lint.py 获取)
147
170
  try:
148
- from jarvis.jarvis_code_agent.lint import LINT_TOOLS
149
-
171
+ from jarvis.jarvis_code_agent.lint import LINT_COMMAND_TEMPLATES_BY_FILE
172
+
150
173
  # 扩展名到语言名称的映射
151
174
  ext_to_lang_for_lint = {
152
- '.py': 'python', '.pyw': 'python', '.pyi': 'python',
153
- '.rs': 'rust',
154
- '.go': 'go',
155
- '.c': 'c', '.h': 'c',
156
- '.cpp': 'cpp', '.cc': 'cpp', '.cxx': 'cpp', '.hpp': 'cpp', '.hxx': 'cpp',
157
- '.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',
158
- '.ts': 'typescript', '.tsx': 'typescript', '.cts': 'typescript', '.mts': 'typescript',
159
- '.java': 'java',
175
+ ".py": "python",
176
+ ".pyw": "python",
177
+ ".pyi": "python",
178
+ ".rs": "rust",
179
+ ".go": "go",
180
+ ".c": "c",
181
+ ".h": "c",
182
+ ".cpp": "cpp",
183
+ ".cc": "cpp",
184
+ ".cxx": "cpp",
185
+ ".hpp": "cpp",
186
+ ".hxx": "cpp",
187
+ ".js": "javascript",
188
+ ".jsx": "javascript",
189
+ ".mjs": "javascript",
190
+ ".cjs": "javascript",
191
+ ".ts": "typescript",
192
+ ".tsx": "typescript",
193
+ ".cts": "typescript",
194
+ ".mts": "typescript",
195
+ ".java": "java",
160
196
  }
161
-
197
+
162
198
  # 检查每种语言是否有对应的 lint 工具
163
199
  for ext, lang_name in ext_to_lang_for_lint.items():
164
200
  if lang_name not in info:
165
201
  info[lang_name] = {}
166
- if ext in LINT_TOOLS and LINT_TOOLS[ext]:
167
- info[lang_name]['静态检查'] = True
202
+ if (
203
+ ext in LINT_COMMAND_TEMPLATES_BY_FILE
204
+ and LINT_COMMAND_TEMPLATES_BY_FILE.get(ext)
205
+ ):
206
+ info[lang_name]["静态检查"] = True
168
207
  except Exception:
169
208
  pass
170
-
171
- # 检查LSP支持(从 lsp_client.py 获取,并验证实际可用性)
172
- from jarvis.jarvis_tools.lsp_client import LSP_SERVERS
173
-
174
- # LSP服务器配置中的语言名称到标准语言名称的映射
175
- lsp_lang_map = {
176
- 'python': 'python',
177
- 'typescript': 'typescript',
178
- 'javascript': 'javascript',
179
- 'c': 'c',
180
- 'cpp': 'cpp',
181
- 'rust': 'rust',
182
- 'go': 'go',
183
- 'java': 'java',
184
- }
185
-
186
- # 检查每种语言是否有对应的 LSP 服务器配置,并验证实际可用性
187
- for lsp_lang, lang_name in lsp_lang_map.items():
188
- if lang_name not in info:
189
- info[lang_name] = {}
190
-
191
- if lsp_lang in LSP_SERVERS:
192
- config = LSP_SERVERS[lsp_lang]
193
- # 检查服务器是否实际可用
194
- is_available = _check_lsp_server_available(config)
195
- info[lang_name]['LSP支持'] = is_available
196
-
209
+
197
210
  # 确保所有已知语言都在 info 中(即使某些功能不支持)
198
211
  # 这样表格会显示所有语言,即使某些功能不支持
199
- known_languages = ['python', 'c', 'cpp', 'rust', 'go', 'javascript', 'typescript', 'java']
212
+ known_languages = [
213
+ "python",
214
+ "c",
215
+ "cpp",
216
+ "rust",
217
+ "go",
218
+ "javascript",
219
+ "typescript",
220
+ "java",
221
+ ]
200
222
  for lang_name in known_languages:
201
223
  if lang_name not in info:
202
224
  info[lang_name] = {}
203
225
  # 确保所有功能字段都存在
204
- for feature in ['符号提取', '依赖分析', '上下文提取', '构建验证', '静态检查', 'LSP支持', '结构化编辑']:
226
+ for feature in [
227
+ "符号提取",
228
+ "依赖分析",
229
+ "上下文提取",
230
+ "构建验证",
231
+ "静态检查",
232
+ ]:
205
233
  if feature not in info[lang_name]:
206
234
  # 对于上下文提取,检查是否有对应的提取器
207
- if feature == '上下文提取':
235
+ if feature == "上下文提取":
208
236
  try:
209
- from jarvis.jarvis_agent.file_context_handler import _LANGUAGE_EXTRACTORS
237
+ from jarvis.jarvis_agent.file_context_handler import (
238
+ _LANGUAGE_EXTRACTORS,
239
+ )
240
+
210
241
  ext_map = {
211
- 'python': ['.py', '.pyw'],
212
- 'rust': ['.rs'],
213
- 'go': ['.go'],
214
- 'c': ['.c', '.h'],
215
- 'cpp': ['.cpp', '.cc', '.cxx', '.hpp', '.hxx'],
216
- 'javascript': ['.js', '.jsx'],
217
- 'typescript': ['.ts', '.tsx'],
218
- 'java': ['.java'],
242
+ "python": [".py", ".pyw"],
243
+ "rust": [".rs"],
244
+ "go": [".go"],
245
+ "c": [".c", ".h"],
246
+ "cpp": [".cpp", ".cc", ".cxx", ".hpp", ".hxx"],
247
+ "javascript": [".js", ".jsx"],
248
+ "typescript": [".ts", ".tsx"],
249
+ "java": [".java"],
219
250
  }
220
251
  exts = ext_map.get(lang_name, [])
221
252
  # 尝试创建提取器,只有成功创建才认为支持(需要 tree-sitter 已安装)
@@ -233,20 +264,26 @@ def _collect_language_support_info() -> Dict[str, Dict[str, Any]]:
233
264
  info[lang_name][feature] = has_extractor
234
265
  except Exception:
235
266
  info[lang_name][feature] = False
236
- elif feature == '符号提取':
267
+ elif feature == "符号提取":
237
268
  # 如果之前没有设置或为 False,再次检查 file_context_handler 中的提取器
238
269
  # 只有能成功创建提取器才标记为支持(需要 tree-sitter 已安装)
239
- if '符号提取' not in info[lang_name] or not info[lang_name]['符号提取']:
270
+ if (
271
+ "符号提取" not in info[lang_name]
272
+ or not info[lang_name]["符号提取"]
273
+ ):
240
274
  try:
241
- from jarvis.jarvis_agent.file_context_handler import _LANGUAGE_EXTRACTORS
275
+ from jarvis.jarvis_agent.file_context_handler import (
276
+ _LANGUAGE_EXTRACTORS,
277
+ )
278
+
242
279
  ext_map = {
243
- 'python': ['.py', '.pyw'],
244
- 'rust': ['.rs'],
245
- 'go': ['.go'],
246
- 'c': ['.c', '.h'],
247
- 'cpp': ['.cpp', '.cc', '.cxx', '.hpp', '.hxx'],
248
- 'javascript': ['.js', '.jsx'],
249
- 'typescript': ['.ts', '.tsx'],
280
+ "python": [".py", ".pyw"],
281
+ "rust": [".rs"],
282
+ "go": [".go"],
283
+ "c": [".c", ".h"],
284
+ "cpp": [".cpp", ".cc", ".cxx", ".hpp", ".hxx"],
285
+ "javascript": [".js", ".jsx"],
286
+ "typescript": [".ts", ".tsx"],
250
287
  }
251
288
  exts = ext_map.get(lang_name, [])
252
289
  # 尝试创建提取器,只有成功创建才认为支持
@@ -264,41 +301,56 @@ def _collect_language_support_info() -> Dict[str, Dict[str, Any]]:
264
301
  info[lang_name][feature] = has_extractor
265
302
  except Exception:
266
303
  info[lang_name][feature] = False
267
- elif feature == '构建验证':
304
+ elif feature == "构建验证":
268
305
  # 默认 False,已在上面检查过(可能是字符串或False)
269
306
  if feature not in info[lang_name]:
270
307
  info[lang_name][feature] = False
271
- elif feature == '静态检查':
272
- # 默认 False,已在上面检查过
273
- info[lang_name][feature] = info[lang_name].get(feature, False)
274
- elif feature == 'LSP支持':
308
+ elif feature == "静态检查":
275
309
  # 默认 False,已在上面检查过
276
310
  info[lang_name][feature] = info[lang_name].get(feature, False)
277
311
  else:
278
312
  info[lang_name][feature] = False
279
-
313
+
280
314
  # 确保所有已知语言都在 info 中(即使某些功能不支持)
281
315
  # 这样表格会显示所有语言,即使某些功能不支持
282
- known_languages = ['python', 'c', 'cpp', 'rust', 'go', 'javascript', 'typescript', 'java']
316
+ known_languages = [
317
+ "python",
318
+ "c",
319
+ "cpp",
320
+ "rust",
321
+ "go",
322
+ "javascript",
323
+ "typescript",
324
+ "java",
325
+ ]
283
326
  for lang_name in known_languages:
284
327
  if lang_name not in info:
285
328
  info[lang_name] = {}
286
329
  # 确保所有功能字段都存在
287
- for feature in ['符号提取', '依赖分析', '上下文提取', '构建验证', '静态检查', 'LSP支持', '结构化编辑']:
330
+ for feature in [
331
+ "符号提取",
332
+ "依赖分析",
333
+ "上下文提取",
334
+ "构建验证",
335
+ "静态检查",
336
+ ]:
288
337
  if feature not in info[lang_name]:
289
338
  # 对于上下文提取,检查是否有对应的提取器
290
- if feature == '上下文提取':
339
+ if feature == "上下文提取":
291
340
  try:
292
- from jarvis.jarvis_agent.file_context_handler import _LANGUAGE_EXTRACTORS
341
+ from jarvis.jarvis_agent.file_context_handler import (
342
+ _LANGUAGE_EXTRACTORS,
343
+ )
344
+
293
345
  ext_map = {
294
- 'python': ['.py', '.pyw'],
295
- 'rust': ['.rs'],
296
- 'go': ['.go'],
297
- 'c': ['.c', '.h'],
298
- 'cpp': ['.cpp', '.cc', '.cxx', '.hpp', '.hxx'],
299
- 'javascript': ['.js', '.jsx'],
300
- 'typescript': ['.ts', '.tsx'],
301
- 'java': ['.java'],
346
+ "python": [".py", ".pyw"],
347
+ "rust": [".rs"],
348
+ "go": [".go"],
349
+ "c": [".c", ".h"],
350
+ "cpp": [".cpp", ".cc", ".cxx", ".hpp", ".hxx"],
351
+ "javascript": [".js", ".jsx"],
352
+ "typescript": [".ts", ".tsx"],
353
+ "java": [".java"],
302
354
  }
303
355
  exts = ext_map.get(lang_name, [])
304
356
  # 尝试创建提取器,只有成功创建才认为支持(需要 tree-sitter 已安装)
@@ -316,20 +368,26 @@ def _collect_language_support_info() -> Dict[str, Dict[str, Any]]:
316
368
  info[lang_name][feature] = has_extractor
317
369
  except Exception:
318
370
  info[lang_name][feature] = False
319
- elif feature == '符号提取':
371
+ elif feature == "符号提取":
320
372
  # 如果之前没有设置或为 False,再次检查 file_context_handler 中的提取器
321
373
  # 只有能成功创建提取器才标记为支持(需要 tree-sitter 已安装)
322
- if '符号提取' not in info[lang_name] or not info[lang_name]['符号提取']:
374
+ if (
375
+ "符号提取" not in info[lang_name]
376
+ or not info[lang_name]["符号提取"]
377
+ ):
323
378
  try:
324
- from jarvis.jarvis_agent.file_context_handler import _LANGUAGE_EXTRACTORS
379
+ from jarvis.jarvis_agent.file_context_handler import (
380
+ _LANGUAGE_EXTRACTORS,
381
+ )
382
+
325
383
  ext_map = {
326
- 'python': ['.py', '.pyw'],
327
- 'rust': ['.rs'],
328
- 'go': ['.go'],
329
- 'c': ['.c', '.h'],
330
- 'cpp': ['.cpp', '.cc', '.cxx', '.hpp', '.hxx'],
331
- 'javascript': ['.js', '.jsx'],
332
- 'typescript': ['.ts', '.tsx'],
384
+ "python": [".py", ".pyw"],
385
+ "rust": [".rs"],
386
+ "go": [".go"],
387
+ "c": [".c", ".h"],
388
+ "cpp": [".cpp", ".cc", ".cxx", ".hpp", ".hxx"],
389
+ "javascript": [".js", ".jsx"],
390
+ "typescript": [".ts", ".tsx"],
333
391
  }
334
392
  exts = ext_map.get(lang_name, [])
335
393
  # 尝试创建提取器,只有成功创建才认为支持
@@ -347,102 +405,76 @@ def _collect_language_support_info() -> Dict[str, Dict[str, Any]]:
347
405
  info[lang_name][feature] = has_extractor
348
406
  except Exception:
349
407
  info[lang_name][feature] = False
350
- elif feature == '构建验证':
408
+ elif feature == "构建验证":
351
409
  # 默认 False,已在上面检查过(可能是字符串或False)
352
410
  if feature not in info[lang_name]:
353
411
  info[lang_name][feature] = False
354
- elif feature == '静态检查':
355
- # 默认 False,已在上面检查过
356
- info[lang_name][feature] = info[lang_name].get(feature, False)
357
- elif feature == 'LSP支持':
412
+ elif feature == "静态检查":
358
413
  # 默认 False,已在上面检查过
359
414
  info[lang_name][feature] = info[lang_name].get(feature, False)
360
415
  else:
361
416
  info[lang_name][feature] = False
362
-
363
- return info
364
417
 
365
-
366
- def _check_lsp_server_available(config) -> bool:
367
- """检查LSP服务器是否实际可用。
368
-
369
- Args:
370
- config: LSPServerConfig 配置对象
371
-
372
- Returns:
373
- bool: 如果服务器可用返回True,否则返回False
374
- """
375
- # 使用检测命令或主命令来验证
376
- check_cmd = config.check_command or config.command
377
-
378
- try:
379
- # 尝试运行检测命令
380
- subprocess.run(
381
- check_cmd,
382
- capture_output=True,
383
- text=True,
384
- timeout=5,
385
- check=False
386
- )
387
-
388
- # 只要命令能执行(不是FileNotFoundError),就认为可用
389
- # 某些LSP服务器即使返回非零退出码也可能可用
390
- return True
391
-
392
- except FileNotFoundError:
393
- return False
394
- except subprocess.TimeoutExpired:
395
- return False
396
- except Exception:
397
- return False
418
+ return info
398
419
 
399
420
 
400
421
  def print_language_support_table() -> None:
401
422
  """打印语言功能支持表格"""
423
+ from rich.align import Align
402
424
  from rich.console import Console
403
425
  from rich.table import Table
404
- from rich.align import Align
405
-
426
+
406
427
  info = _collect_language_support_info()
407
-
428
+
408
429
  if not info:
409
430
  return
410
-
431
+
411
432
  # 定义功能列表
412
- features = ['符号提取', '依赖分析', '上下文提取', '构建验证', '静态检查', 'LSP支持', '结构化编辑']
413
-
433
+ features = [
434
+ "符号提取",
435
+ "依赖分析",
436
+ "上下文提取",
437
+ "构建验证",
438
+ "静态检查",
439
+ ]
440
+
414
441
  # 定义语言显示名称映射
415
442
  lang_display_names = {
416
- 'python': 'Python',
417
- 'rust': 'Rust',
418
- 'go': 'Go',
419
- 'c': 'C',
420
- 'cpp': 'C++',
421
- 'javascript': 'JavaScript',
422
- 'typescript': 'TypeScript',
423
- 'java': 'Java',
443
+ "python": "Python",
444
+ "rust": "Rust",
445
+ "go": "Go",
446
+ "c": "C",
447
+ "cpp": "C++",
448
+ "javascript": "JavaScript",
449
+ "typescript": "TypeScript",
450
+ "java": "Java",
424
451
  }
425
-
452
+
426
453
  # 获取所有语言(按固定顺序,优先显示 C, C++, Rust, Go)
427
- priority_languages = ['c', 'cpp', 'rust', 'go']
428
- other_languages = ['python', 'javascript', 'typescript', 'java']
429
- all_languages = priority_languages + [lang for lang in other_languages if lang not in priority_languages]
454
+ priority_languages = ["c", "cpp", "rust", "go"]
455
+ other_languages = ["python", "javascript", "typescript", "java"]
456
+ all_languages = priority_languages + [
457
+ lang for lang in other_languages if lang not in priority_languages
458
+ ]
430
459
  # 显示所有已知语言,即使某些功能不支持(只要在 info 中有记录)
431
460
  languages = [lang for lang in all_languages if lang in info]
432
-
461
+
433
462
  # 如果没有任何语言,尝试显示 info 中的所有语言
434
463
  if not languages:
435
464
  languages = list(info.keys())
436
465
  # 按优先级排序
437
- languages = sorted(languages, key=lambda x: (
438
- 0 if x in priority_languages else 1,
439
- priority_languages.index(x) if x in priority_languages else 999,
440
- x
441
- ))
442
-
466
+ languages = sorted(
467
+ languages,
468
+ key=lambda x: (
469
+ 0 if x in priority_languages else 1,
470
+ priority_languages.index(x) if x in priority_languages else 999,
471
+ x,
472
+ ),
473
+ )
474
+
443
475
  if not languages:
444
476
  return
445
-
477
+
446
478
  # 创建表格
447
479
  table = Table(
448
480
  title="[bold cyan]编程语言功能支持情况[/bold cyan]",
@@ -453,14 +485,14 @@ def print_language_support_table() -> None:
453
485
  show_lines=False,
454
486
  padding=(0, 1),
455
487
  )
456
-
488
+
457
489
  # 添加语言列(第一列)
458
490
  table.add_column("语言", style="cyan", no_wrap=True, justify="left")
459
-
491
+
460
492
  # 添加功能列
461
493
  for feature in features:
462
494
  table.add_column(feature, justify="center", style="green", no_wrap=True)
463
-
495
+
464
496
  # 添加语言行
465
497
  for lang in languages:
466
498
  display_name = lang_display_names.get(lang, lang.capitalize())
@@ -469,18 +501,17 @@ def print_language_support_table() -> None:
469
501
  supported = info.get(lang, {}).get(feature, False)
470
502
  if supported:
471
503
  # 如果是构建验证,显示构建系统名称
472
- if feature == '构建验证' and isinstance(supported, str):
504
+ if feature == "构建验证" and isinstance(supported, str):
473
505
  row.append(f"[bold green]{supported}[/bold green]")
474
506
  else:
475
507
  row.append("[bold green]✓[/bold green]")
476
508
  else:
477
509
  row.append("[bold red]✗[/bold red]")
478
510
  table.add_row(*row)
479
-
511
+
480
512
  console = Console()
481
513
  console.print()
482
514
  # 居中显示表格
483
515
  aligned_table = Align.center(table)
484
516
  console.print(aligned_table)
485
517
  console.print()
486
-