jarvis-ai-assistant 0.7.16__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.16.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.16.dist-info/RECORD +0 -218
  276. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
  277. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
  278. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
  279. {jarvis_ai_assistant-0.7.16.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
@@ -3,8 +3,12 @@
3
3
  管理所有语言支持的注册和发现机制。
4
4
  """
5
5
 
6
+ from jarvis.jarvis_utils.output import PrettyOutput
7
+
6
8
  import os
7
- from typing import Dict, Optional, Set
9
+ from typing import Dict
10
+ from typing import Optional
11
+ from typing import Set
8
12
 
9
13
  from .base_language import BaseLanguageSupport
10
14
  from .dependency_analyzer import DependencyAnalyzer
@@ -13,7 +17,7 @@ from .symbol_extractor import SymbolExtractor
13
17
 
14
18
  class LanguageRegistry:
15
19
  """语言支持注册表。
16
-
20
+
17
21
  负责管理所有已注册的语言支持,提供语言检测和工厂方法。
18
22
  """
19
23
 
@@ -23,25 +27,27 @@ class LanguageRegistry:
23
27
 
24
28
  def register(self, language_support: BaseLanguageSupport) -> None:
25
29
  """注册一个语言支持。
26
-
30
+
27
31
  Args:
28
32
  language_support: 语言支持实例
29
33
  """
30
34
  lang_name = language_support.language_name
31
35
  self._languages[lang_name] = language_support
32
-
36
+
33
37
  # 注册文件扩展名映射
34
38
  for ext in language_support.file_extensions:
35
39
  # 如果扩展名已存在,记录警告但不覆盖(保留第一个注册的)
36
40
  if ext in self._extension_map and self._extension_map[ext] != lang_name:
37
- print(f"Warning: Extension {ext} already registered for "
38
- f"{self._extension_map[ext]}, ignoring registration for {lang_name}")
41
+ PrettyOutput.auto_print(
42
+ f"Warning: Extension {ext} already registered for "
43
+ f"{self._extension_map[ext]}, ignoring registration for {lang_name}"
44
+ )
39
45
  else:
40
46
  self._extension_map[ext] = lang_name
41
47
 
42
48
  def unregister(self, language_name: str) -> None:
43
49
  """取消注册一个语言支持。
44
-
50
+
45
51
  Args:
46
52
  language_name: 语言名称
47
53
  """
@@ -49,7 +55,8 @@ class LanguageRegistry:
49
55
  self._languages.pop(language_name)
50
56
  # 移除扩展名映射
51
57
  extensions_to_remove = [
52
- ext for ext, lang in self._extension_map.items()
58
+ ext
59
+ for ext, lang in self._extension_map.items()
53
60
  if lang == language_name
54
61
  ]
55
62
  for ext in extensions_to_remove:
@@ -57,10 +64,10 @@ class LanguageRegistry:
57
64
 
58
65
  def detect_language(self, file_path: str) -> Optional[str]:
59
66
  """根据文件路径检测编程语言。
60
-
67
+
61
68
  Args:
62
69
  file_path: 文件路径
63
-
70
+
64
71
  Returns:
65
72
  语言名称,如果无法检测则返回None
66
73
  """
@@ -69,10 +76,10 @@ class LanguageRegistry:
69
76
 
70
77
  def get_language_support(self, language_name: str) -> Optional[BaseLanguageSupport]:
71
78
  """获取指定语言的支持实例。
72
-
79
+
73
80
  Args:
74
81
  language_name: 语言名称
75
-
82
+
76
83
  Returns:
77
84
  语言支持实例,如果未注册则返回None
78
85
  """
@@ -80,10 +87,10 @@ class LanguageRegistry:
80
87
 
81
88
  def get_symbol_extractor(self, language_name: str) -> Optional[SymbolExtractor]:
82
89
  """获取指定语言的符号提取器。
83
-
90
+
84
91
  Args:
85
92
  language_name: 语言名称
86
-
93
+
87
94
  Returns:
88
95
  SymbolExtractor实例,如果不支持则返回None
89
96
  """
@@ -92,12 +99,14 @@ class LanguageRegistry:
92
99
  return lang_support.create_symbol_extractor()
93
100
  return None
94
101
 
95
- def get_dependency_analyzer(self, language_name: str) -> Optional[DependencyAnalyzer]:
102
+ def get_dependency_analyzer(
103
+ self, language_name: str
104
+ ) -> Optional[DependencyAnalyzer]:
96
105
  """获取指定语言的依赖分析器。
97
-
106
+
98
107
  Args:
99
108
  language_name: 语言名称
100
-
109
+
101
110
  Returns:
102
111
  DependencyAnalyzer实例,如果不支持则返回None
103
112
  """
@@ -108,7 +117,7 @@ class LanguageRegistry:
108
117
 
109
118
  def get_supported_languages(self) -> Set[str]:
110
119
  """获取所有已注册的语言名称集合。
111
-
120
+
112
121
  Returns:
113
122
  语言名称集合
114
123
  """
@@ -116,10 +125,10 @@ class LanguageRegistry:
116
125
 
117
126
  def is_supported(self, file_path: str) -> bool:
118
127
  """检查文件是否被支持。
119
-
128
+
120
129
  Args:
121
130
  file_path: 文件路径
122
-
131
+
123
132
  Returns:
124
133
  如果文件被支持返回True,否则返回False
125
134
  """
@@ -132,7 +141,7 @@ _registry = LanguageRegistry()
132
141
 
133
142
  def get_registry() -> LanguageRegistry:
134
143
  """获取全局语言注册表实例。
135
-
144
+
136
145
  Returns:
137
146
  全局LanguageRegistry实例
138
147
  """
@@ -141,7 +150,7 @@ def get_registry() -> LanguageRegistry:
141
150
 
142
151
  def register_language(language_support: BaseLanguageSupport) -> None:
143
152
  """注册一个语言支持(便捷函数)。
144
-
153
+
145
154
  Args:
146
155
  language_support: 语言支持实例
147
156
  """
@@ -150,10 +159,10 @@ def register_language(language_support: BaseLanguageSupport) -> None:
150
159
 
151
160
  def detect_language(file_path: str) -> Optional[str]:
152
161
  """检测文件的语言(便捷函数)。
153
-
162
+
154
163
  Args:
155
164
  file_path: 文件路径
156
-
165
+
157
166
  Returns:
158
167
  语言名称,如果无法检测则返回None
159
168
  """
@@ -162,10 +171,10 @@ def detect_language(file_path: str) -> Optional[str]:
162
171
 
163
172
  def get_symbol_extractor(language: str) -> Optional[SymbolExtractor]:
164
173
  """获取指定语言的符号提取器(便捷函数)。
165
-
174
+
166
175
  Args:
167
176
  language: 语言名称
168
-
177
+
169
178
  Returns:
170
179
  SymbolExtractor实例,如果不支持则返回None
171
180
  """
@@ -174,12 +183,11 @@ def get_symbol_extractor(language: str) -> Optional[SymbolExtractor]:
174
183
 
175
184
  def get_dependency_analyzer(language: str) -> Optional[DependencyAnalyzer]:
176
185
  """获取指定语言的依赖分析器(便捷函数)。
177
-
186
+
178
187
  Args:
179
188
  language: 语言名称
180
-
189
+
181
190
  Returns:
182
191
  DependencyAnalyzer实例,如果不支持则返回None
183
192
  """
184
193
  return _registry.get_dependency_analyzer(language)
185
-
@@ -3,15 +3,15 @@
3
3
  提供语言检测和工厂函数,使用语言注册表管理所有语言支持。
4
4
  """
5
5
 
6
+ from jarvis.jarvis_utils.output import PrettyOutput
7
+
6
8
  from typing import Optional
7
9
 
8
10
  from .dependency_analyzer import DependencyAnalyzer
9
- from .language_registry import (
10
- detect_language as _detect_language,
11
- get_dependency_analyzer as _get_dependency_analyzer,
12
- get_symbol_extractor as _get_symbol_extractor,
13
- register_language,
14
- )
11
+ from .language_registry import detect_language as _detect_language
12
+ from .language_registry import get_dependency_analyzer as _get_dependency_analyzer
13
+ from .language_registry import get_symbol_extractor as _get_symbol_extractor
14
+ from .language_registry import register_language
15
15
  from .symbol_extractor import SymbolExtractor
16
16
 
17
17
  # 自动注册所有语言支持
@@ -20,13 +20,15 @@ from .symbol_extractor import SymbolExtractor
20
20
  # Python语言支持(必需,因为它是核心语言)
21
21
  try:
22
22
  from .languages import PythonLanguageSupport
23
+
23
24
  register_language(PythonLanguageSupport())
24
25
  except ImportError as e:
25
- print(f"Warning: Failed to import PythonLanguageSupport: {e}")
26
+ PrettyOutput.auto_print(f"⚠️ Warning: Failed to import PythonLanguageSupport: {e}")
26
27
 
27
28
  # Rust语言支持(可选,需要tree-sitter)
28
29
  try:
29
30
  from .languages import RustLanguageSupport
31
+
30
32
  register_language(RustLanguageSupport())
31
33
  except (ImportError, RuntimeError):
32
34
  pass # 静默失败,tree-sitter可能不可用
@@ -34,6 +36,7 @@ except (ImportError, RuntimeError):
34
36
  # Go语言支持(可选,需要tree-sitter)
35
37
  try:
36
38
  from .languages import GoLanguageSupport
39
+
37
40
  register_language(GoLanguageSupport())
38
41
  except (ImportError, RuntimeError):
39
42
  pass # 静默失败,tree-sitter可能不可用
@@ -41,6 +44,7 @@ except (ImportError, RuntimeError):
41
44
  # C语言支持(可选,需要tree-sitter)
42
45
  try:
43
46
  from .languages import CLanguageSupport
47
+
44
48
  register_language(CLanguageSupport())
45
49
  except (ImportError, RuntimeError):
46
50
  pass # 静默失败,tree-sitter可能不可用
@@ -48,6 +52,7 @@ except (ImportError, RuntimeError):
48
52
  # C++语言支持(可选,需要tree-sitter)
49
53
  try:
50
54
  from .languages import CppLanguageSupport
55
+
51
56
  register_language(CppLanguageSupport())
52
57
  except (ImportError, RuntimeError):
53
58
  pass # 静默失败,tree-sitter可能不可用
@@ -55,6 +60,7 @@ except (ImportError, RuntimeError):
55
60
  # JavaScript语言支持(可选,需要tree-sitter)
56
61
  try:
57
62
  from .languages import JavaScriptLanguageSupport
63
+
58
64
  register_language(JavaScriptLanguageSupport())
59
65
  except (ImportError, RuntimeError):
60
66
  pass # 静默失败,tree-sitter可能不可用
@@ -62,6 +68,7 @@ except (ImportError, RuntimeError):
62
68
  # TypeScript语言支持(可选,需要tree-sitter)
63
69
  try:
64
70
  from .languages import TypeScriptLanguageSupport
71
+
65
72
  register_language(TypeScriptLanguageSupport())
66
73
  except (ImportError, RuntimeError):
67
74
  pass # 静默失败,tree-sitter可能不可用
@@ -69,6 +76,7 @@ except (ImportError, RuntimeError):
69
76
  # Java语言支持(可选,需要tree-sitter)
70
77
  try:
71
78
  from .languages import JavaLanguageSupport
79
+
72
80
  register_language(JavaLanguageSupport())
73
81
  except (ImportError, RuntimeError):
74
82
  pass # 静默失败,tree-sitter可能不可用
@@ -76,10 +84,10 @@ except (ImportError, RuntimeError):
76
84
 
77
85
  def detect_language(file_path: str) -> Optional[str]:
78
86
  """检测文件的编程语言。
79
-
87
+
80
88
  Args:
81
89
  file_path: 文件路径
82
-
90
+
83
91
  Returns:
84
92
  语言名称,如果无法检测则返回None
85
93
  """
@@ -88,10 +96,10 @@ def detect_language(file_path: str) -> Optional[str]:
88
96
 
89
97
  def get_symbol_extractor(language: str) -> Optional[SymbolExtractor]:
90
98
  """获取指定语言的符号提取器。
91
-
99
+
92
100
  Args:
93
101
  language: 语言名称
94
-
102
+
95
103
  Returns:
96
104
  SymbolExtractor实例,如果不支持则返回None
97
105
  """
@@ -100,10 +108,10 @@ def get_symbol_extractor(language: str) -> Optional[SymbolExtractor]:
100
108
 
101
109
  def get_dependency_analyzer(language: str) -> Optional[DependencyAnalyzer]:
102
110
  """获取指定语言的依赖分析器。
103
-
111
+
104
112
  Args:
105
113
  language: 语言名称
106
-
114
+
107
115
  Returns:
108
116
  DependencyAnalyzer实例,如果不支持则返回None
109
117
  """
@@ -8,42 +8,48 @@
8
8
 
9
9
  from .python_language import PythonLanguageSupport
10
10
 
11
- __all__ = ['PythonLanguageSupport']
11
+ __all__ = ["PythonLanguageSupport"]
12
12
 
13
13
  # 尝试导入tree-sitter相关的语言支持
14
14
  try:
15
15
  from .rust_language import RustLanguageSupport # noqa: F401
16
- __all__.append('RustLanguageSupport')
16
+
17
+ __all__.append("RustLanguageSupport")
17
18
  except (ImportError, RuntimeError):
18
19
  pass
19
20
 
20
21
  try:
21
22
  from .go_language import GoLanguageSupport # noqa: F401
22
- __all__.append('GoLanguageSupport')
23
+
24
+ __all__.append("GoLanguageSupport")
23
25
  except (ImportError, RuntimeError):
24
26
  pass
25
27
 
26
28
  try:
27
- from .c_cpp_language import CLanguageSupport, CppLanguageSupport # noqa: F401
28
- __all__.extend(['CLanguageSupport', 'CppLanguageSupport'])
29
+ from .c_cpp_language import CLanguageSupport # noqa: F401
30
+ from .c_cpp_language import CppLanguageSupport # noqa: F401
31
+
32
+ __all__.extend(["CLanguageSupport", "CppLanguageSupport"])
29
33
  except (ImportError, RuntimeError):
30
34
  pass
31
35
 
32
36
  try:
33
37
  from .javascript_language import JavaScriptLanguageSupport # noqa: F401
34
- __all__.append('JavaScriptLanguageSupport')
38
+
39
+ __all__.append("JavaScriptLanguageSupport")
35
40
  except (ImportError, RuntimeError):
36
41
  pass
37
42
 
38
43
  try:
39
44
  from .typescript_language import TypeScriptLanguageSupport # noqa: F401
40
- __all__.append('TypeScriptLanguageSupport')
45
+
46
+ __all__.append("TypeScriptLanguageSupport")
41
47
  except (ImportError, RuntimeError):
42
48
  pass
43
49
 
44
50
  try:
45
51
  from .java_language import JavaLanguageSupport # noqa: F401
46
- __all__.append('JavaLanguageSupport')
52
+
53
+ __all__.append("JavaLanguageSupport")
47
54
  except (ImportError, RuntimeError):
48
55
  pass
49
-
@@ -2,17 +2,23 @@
2
2
 
3
3
  import os
4
4
  import re
5
- from typing import List, Optional, Set
5
+ from typing import List
6
+ from typing import Optional
7
+ from typing import Set
8
+ from typing import cast
6
9
 
7
- from tree_sitter import Language, Node
10
+ from tree_sitter import Language
11
+ from tree_sitter import Node
8
12
 
9
13
  from ..base_language import BaseLanguageSupport
10
- from ..dependency_analyzer import Dependency, DependencyAnalyzer, DependencyGraph
14
+ from ..dependency_analyzer import Dependency
15
+ from ..dependency_analyzer import DependencyAnalyzer
16
+ from ..dependency_analyzer import DependencyGraph
11
17
  from ..file_ignore import filter_walk_dirs
12
- from ..symbol_extractor import Symbol, SymbolExtractor
18
+ from ..symbol_extractor import Symbol
19
+ from ..symbol_extractor import SymbolExtractor
13
20
  from ..tree_sitter_extractor import TreeSitterExtractor
14
21
 
15
-
16
22
  # --- C/C++ Symbol Query ---
17
23
 
18
24
  # C语言查询(不包含class_specifier,因为C不支持class)
@@ -69,19 +75,24 @@ CPP_SYMBOL_QUERY = """
69
75
 
70
76
  try:
71
77
  import tree_sitter_c
72
- C_LANGUAGE: Optional[Language] = tree_sitter_c.language()
78
+
79
+ C_LANGUAGE: Optional[Language] = cast(Optional[Language], tree_sitter_c.language())
73
80
  except (ImportError, Exception):
74
81
  C_LANGUAGE = None
75
82
 
76
83
  try:
77
84
  import tree_sitter_cpp
78
- CPP_LANGUAGE: Optional[Language] = tree_sitter_cpp.language()
85
+
86
+ CPP_LANGUAGE: Optional[Language] = cast(
87
+ Optional[Language], tree_sitter_cpp.language()
88
+ )
79
89
  except (ImportError, Exception):
80
90
  CPP_LANGUAGE = None
81
91
 
82
92
 
83
93
  # --- C/C++ Symbol Extractors ---
84
94
 
95
+
85
96
  class CSymbolExtractor(TreeSitterExtractor):
86
97
  """Extracts symbols from C code using tree-sitter."""
87
98
 
@@ -90,7 +101,9 @@ class CSymbolExtractor(TreeSitterExtractor):
90
101
  raise RuntimeError("C tree-sitter grammar not available.")
91
102
  super().__init__(C_LANGUAGE, C_SYMBOL_QUERY)
92
103
 
93
- def _create_symbol_from_capture(self, node: Node, name: str, file_path: str) -> Optional[Symbol]:
104
+ def _create_symbol_from_capture(
105
+ self, node: Node, name: str, file_path: str
106
+ ) -> Optional[Symbol]:
94
107
  kind_map = {
95
108
  "function.name": "function",
96
109
  "struct.name": "struct",
@@ -103,8 +116,11 @@ class CSymbolExtractor(TreeSitterExtractor):
103
116
  if not symbol_kind:
104
117
  return None
105
118
 
119
+ if node.text is None:
120
+ return None
121
+
106
122
  return Symbol(
107
- name=node.text.decode('utf8'),
123
+ name=node.text.decode("utf8"),
108
124
  kind=symbol_kind,
109
125
  file_path=file_path,
110
126
  line_start=node.start_point[0] + 1,
@@ -120,7 +136,9 @@ class CppSymbolExtractor(TreeSitterExtractor):
120
136
  raise RuntimeError("C++ tree-sitter grammar not available.")
121
137
  super().__init__(CPP_LANGUAGE, CPP_SYMBOL_QUERY)
122
138
 
123
- def _create_symbol_from_capture(self, node: Node, name: str, file_path: str) -> Optional[Symbol]:
139
+ def _create_symbol_from_capture(
140
+ self, node: Node, name: str, file_path: str
141
+ ) -> Optional[Symbol]:
124
142
  kind_map = {
125
143
  "function.name": "function",
126
144
  "struct.name": "struct",
@@ -138,19 +156,23 @@ class CppSymbolExtractor(TreeSitterExtractor):
138
156
 
139
157
  # For anonymous namespaces, use a generated name
140
158
  if name == "namespace.name":
141
- symbol_name = node.text.decode('utf8') if node.text else "<anonymous_namespace>"
159
+ symbol_name = (
160
+ node.text.decode("utf8") if node.text else "<anonymous_namespace>"
161
+ )
142
162
  elif name == "template":
143
163
  # For template declarations, extract the template name or use a generic name
144
164
  # Try to find the function/class name after template
145
- template_text = node.text.decode('utf8').strip()
165
+ if node.text is None:
166
+ return None
167
+ template_text = node.text.decode("utf8").strip()
146
168
  # Extract template parameters and the following declaration
147
169
  # This is a simplified extraction - in practice, you might want more sophisticated parsing
148
- if 'template' in template_text:
170
+ if "template" in template_text:
149
171
  # Try to extract the name after template<...>
150
- parts = template_text.split('>', 1)
172
+ parts = template_text.split(">", 1)
151
173
  if len(parts) > 1:
152
174
  # Look for function/class name in the second part
153
- match = re.search(r'\b(function|class|struct)\s+(\w+)', parts[1])
175
+ match = re.search(r"\b(function|class|struct)\s+(\w+)", parts[1])
154
176
  if match:
155
177
  symbol_name = f"template_{match.group(2)}"
156
178
  else:
@@ -160,8 +182,10 @@ class CppSymbolExtractor(TreeSitterExtractor):
160
182
  else:
161
183
  symbol_name = "template"
162
184
  else:
163
- symbol_name = node.text.decode('utf8')
164
-
185
+ if node.text is None:
186
+ return None
187
+ symbol_name = node.text.decode("utf8")
188
+
165
189
  if not symbol_name:
166
190
  return None
167
191
 
@@ -176,76 +200,83 @@ class CppSymbolExtractor(TreeSitterExtractor):
176
200
 
177
201
  # --- C/C++ Dependency Analyzers ---
178
202
 
203
+
179
204
  class CDependencyAnalyzer(DependencyAnalyzer):
180
205
  """Analyzes C include dependencies."""
181
206
 
182
207
  def analyze_imports(self, file_path: str, content: str) -> List[Dependency]:
183
208
  """Analyzes C #include statements."""
184
209
  dependencies: List[Dependency] = []
185
-
210
+
186
211
  # Match #include directives
187
212
  # Format: #include <header.h> or #include "header.h"
188
213
  include_pattern = re.compile(r'#include\s+[<"]([^>"]+)[>"]')
189
-
190
- for line_num, line in enumerate(content.split('\n'), start=1):
214
+
215
+ for line_num, line in enumerate(content.split("\n"), start=1):
191
216
  match = include_pattern.search(line)
192
217
  if match:
193
218
  header = match.group(1)
194
- dependencies.append(Dependency(
195
- from_module=header,
196
- imported_symbol=None,
197
- file_path=file_path,
198
- line=line_num,
199
- ))
200
-
219
+ dependencies.append(
220
+ Dependency(
221
+ from_module=header,
222
+ imported_symbol=None,
223
+ file_path=file_path,
224
+ line=line_num,
225
+ )
226
+ )
227
+
201
228
  return dependencies
202
229
 
203
230
  def build_dependency_graph(self, project_root: str) -> DependencyGraph:
204
231
  """Builds a dependency graph for a C project."""
205
232
  graph = DependencyGraph()
206
- extensions = {'.c', '.h'}
207
-
233
+ extensions = {".c", ".h"}
234
+
208
235
  for root, dirs, files in os.walk(project_root):
209
236
  dirs[:] = filter_walk_dirs(dirs)
210
-
237
+
211
238
  for file in files:
212
239
  if not any(file.endswith(ext) for ext in extensions):
213
240
  continue
214
-
241
+
215
242
  file_path = os.path.join(root, file)
216
243
  try:
217
- with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
244
+ with open(file_path, "r", encoding="utf-8", errors="replace") as f:
218
245
  content = f.read()
219
-
246
+
220
247
  dependencies = self.analyze_imports(file_path, content)
221
248
  for dep in dependencies:
222
- dep_path = self._resolve_header_path(project_root, dep.from_module, file_path)
249
+ dep_path = self._resolve_header_path(
250
+ project_root, dep.from_module, file_path
251
+ )
223
252
  if dep_path and dep_path != file_path:
224
253
  graph.add_dependency(file_path, dep_path)
225
254
  except Exception:
226
255
  continue
227
-
256
+
228
257
  return graph
229
258
 
230
- def _resolve_header_path(self, project_root: str, header_name: str, from_file: str) -> Optional[str]:
259
+ def _resolve_header_path(
260
+ self, project_root: str, header_name: str, from_file: str
261
+ ) -> Optional[str]:
231
262
  """Resolve a header name to a file path."""
232
263
  # Try relative to current file
233
264
  base_dir = os.path.dirname(from_file)
234
265
  relative_path = os.path.join(base_dir, header_name)
235
266
  if os.path.exists(relative_path):
236
267
  return relative_path
237
-
268
+
238
269
  # Try in project root
239
270
  for root, dirs, files in os.walk(project_root):
240
271
  dirs[:] = filter_walk_dirs(dirs)
241
272
  if header_name in files:
242
273
  return os.path.join(root, header_name)
243
-
274
+
244
275
  return None
245
276
 
246
277
  def _is_source_file(self, file_path: str) -> bool:
247
278
  """Check if a file is a C source file."""
248
- return file_path.endswith(('.c', '.h'))
279
+ return file_path.endswith((".c", ".h"))
249
280
 
250
281
 
251
282
  class CppDependencyAnalyzer(CDependencyAnalyzer):
@@ -253,7 +284,7 @@ class CppDependencyAnalyzer(CDependencyAnalyzer):
253
284
 
254
285
  def _is_source_file(self, file_path: str) -> bool:
255
286
  """Check if a file is a C++ source file."""
256
- return file_path.endswith(('.cpp', '.hpp', '.cc', '.cxx', '.hxx', '.h'))
287
+ return file_path.endswith((".cpp", ".hpp", ".cc", ".cxx", ".hxx", ".h"))
257
288
 
258
289
 
259
290
  class CLanguageSupport(BaseLanguageSupport):
@@ -261,11 +292,11 @@ class CLanguageSupport(BaseLanguageSupport):
261
292
 
262
293
  @property
263
294
  def language_name(self) -> str:
264
- return 'c'
295
+ return "c"
265
296
 
266
297
  @property
267
298
  def file_extensions(self) -> Set[str]:
268
- return {'.c', '.h'}
299
+ return {".c", ".h"}
269
300
 
270
301
  def create_symbol_extractor(self) -> Optional[SymbolExtractor]:
271
302
  try:
@@ -282,11 +313,11 @@ class CppLanguageSupport(BaseLanguageSupport):
282
313
 
283
314
  @property
284
315
  def language_name(self) -> str:
285
- return 'cpp'
316
+ return "cpp"
286
317
 
287
318
  @property
288
319
  def file_extensions(self) -> Set[str]:
289
- return {'.cpp', '.hpp', '.cc', '.cxx', '.hxx'}
320
+ return {".cpp", ".hpp", ".cc", ".cxx", ".hxx"}
290
321
 
291
322
  def create_symbol_extractor(self) -> Optional[SymbolExtractor]:
292
323
  try:
@@ -296,4 +327,3 @@ class CppLanguageSupport(BaseLanguageSupport):
296
327
 
297
328
  def create_dependency_analyzer(self) -> Optional[DependencyAnalyzer]:
298
329
  return CppDependencyAnalyzer()
299
-