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
@@ -16,14 +16,18 @@ Jarvis 安全分析套件 —— Workflow(含可复现直扫基线)
16
16
 
17
17
  from dataclasses import asdict
18
18
  from pathlib import Path
19
- from typing import Any, Dict, Iterable, List, Optional, cast
20
-
21
- import typer
22
-
23
- from jarvis.jarvis_sec.checkers import analyze_c_files, analyze_rust_files
19
+ from typing import Any
20
+ from typing import Dict
21
+ from typing import Iterable
22
+ from typing import List
23
+ from typing import Optional
24
+ from typing import cast
25
+
26
+ from jarvis.jarvis_utils.output import PrettyOutput
27
+ from jarvis.jarvis_sec.checkers import analyze_c_files
28
+ from jarvis.jarvis_sec.checkers import analyze_rust_files
24
29
  from jarvis.jarvis_sec.types import Issue
25
30
 
26
-
27
31
  # ---------------------------
28
32
  # 数据结构
29
33
  # ---------------------------
@@ -50,7 +54,57 @@ def _iter_source_files(
50
54
  return
51
55
 
52
56
  exts = set((languages or ["c", "cpp", "h", "hpp", "rs"]))
53
- excludes = set(exclude_dirs or [".git", "build", "out", "target", "dist", "bin", "obj", "third_party", "vendor", "deps", "dependencies", "libs", "libraries", "external", "node_modules", "test", "tests", "__tests__", "spec", "testsuite", "testdata", "benchmark", "benchmarks", "perf", "performance", "bench", "benches", "profiling", "profiler", "example", "examples", "tmp", "temp", "cache", ".cache", "docs", "doc", "documentation", "generated", "gen", "mocks", "fixtures", "samples", "sample", "playground", "sandbox"])
57
+ excludes = set(
58
+ exclude_dirs
59
+ or [
60
+ ".git",
61
+ "build",
62
+ "out",
63
+ "target",
64
+ "dist",
65
+ "bin",
66
+ "obj",
67
+ "third_party",
68
+ "vendor",
69
+ "deps",
70
+ "dependencies",
71
+ "libs",
72
+ "libraries",
73
+ "external",
74
+ "node_modules",
75
+ "test",
76
+ "tests",
77
+ "__tests__",
78
+ "spec",
79
+ "testsuite",
80
+ "testdata",
81
+ "benchmark",
82
+ "benchmarks",
83
+ "perf",
84
+ "performance",
85
+ "bench",
86
+ "benches",
87
+ "profiling",
88
+ "profiler",
89
+ "example",
90
+ "examples",
91
+ "tmp",
92
+ "temp",
93
+ "cache",
94
+ ".cache",
95
+ "docs",
96
+ "doc",
97
+ "documentation",
98
+ "generated",
99
+ "gen",
100
+ "mocks",
101
+ "fixtures",
102
+ "samples",
103
+ "sample",
104
+ "playground",
105
+ "sandbox",
106
+ ]
107
+ )
54
108
 
55
109
  for p in entry.rglob("*"):
56
110
  if not p.is_file():
@@ -69,11 +123,11 @@ def _iter_source_files(
69
123
  yield p.relative_to(entry)
70
124
 
71
125
 
72
-
73
126
  # ---------------------------
74
127
  # 汇总与报告
75
128
  # ---------------------------
76
129
 
130
+
77
131
  def direct_scan(
78
132
  entry_path: str,
79
133
  languages: Optional[List[str]] = None,
@@ -85,9 +139,56 @@ def direct_scan(
85
139
  """
86
140
  base = Path(entry_path).resolve()
87
141
  # 计算实际使用的排除目录列表
88
- default_excludes = [".git", "build", "out", "target", "dist", "bin", "obj", "third_party", "vendor", "deps", "dependencies", "libs", "libraries", "external", "node_modules", "test", "tests", "__tests__", "spec", "testsuite", "testdata", "benchmark", "benchmarks", "perf", "performance", "bench", "benches", "profiling", "profiler", "example", "examples", "tmp", "temp", "cache", ".cache", "docs", "doc", "documentation", "generated", "gen", "mocks", "fixtures", "samples", "sample", "playground", "sandbox"]
142
+ default_excludes = [
143
+ ".git",
144
+ "build",
145
+ "out",
146
+ "target",
147
+ "dist",
148
+ "bin",
149
+ "obj",
150
+ "third_party",
151
+ "vendor",
152
+ "deps",
153
+ "dependencies",
154
+ "libs",
155
+ "libraries",
156
+ "external",
157
+ "node_modules",
158
+ "test",
159
+ "tests",
160
+ "__tests__",
161
+ "spec",
162
+ "testsuite",
163
+ "testdata",
164
+ "benchmark",
165
+ "benchmarks",
166
+ "perf",
167
+ "performance",
168
+ "bench",
169
+ "benches",
170
+ "profiling",
171
+ "profiler",
172
+ "example",
173
+ "examples",
174
+ "tmp",
175
+ "temp",
176
+ "cache",
177
+ ".cache",
178
+ "docs",
179
+ "doc",
180
+ "documentation",
181
+ "generated",
182
+ "gen",
183
+ "mocks",
184
+ "fixtures",
185
+ "samples",
186
+ "sample",
187
+ "playground",
188
+ "sandbox",
189
+ ]
89
190
  actual_excludes = exclude_dirs if exclude_dirs is not None else default_excludes
90
-
191
+
91
192
  # 检查代码库中实际存在的排除目录
92
193
  excludes_set = set(actual_excludes)
93
194
  actual_excluded_dirs = []
@@ -96,14 +197,16 @@ def direct_scan(
96
197
  rel_path = item.relative_to(base)
97
198
  if str(rel_path) not in actual_excluded_dirs:
98
199
  actual_excluded_dirs.append(str(rel_path))
99
-
200
+
100
201
  if actual_excluded_dirs:
101
- typer.secho("[jarvis-sec] 实际排除的目录:", fg=typer.colors.BLUE)
202
+ PrettyOutput.auto_print("[jarvis-sec] 实际排除的目录:")
102
203
  for dir_path in sorted(actual_excluded_dirs):
103
- typer.secho(f" - {dir_path}", fg=typer.colors.BLUE)
204
+ PrettyOutput.auto_print(f" - {dir_path}")
104
205
  else:
105
- typer.secho(f"[jarvis-sec] 未发现需要排除的目录(配置的排除目录: {', '.join(sorted(actual_excludes))})", fg=typer.colors.BLUE)
106
-
206
+ PrettyOutput.auto_print(
207
+ f"[jarvis-sec] 未发现需要排除的目录(配置的排除目录: {', '.join(sorted(actual_excludes))})"
208
+ )
209
+
107
210
  files = list(_iter_source_files(entry_path, languages, exclude_dirs))
108
211
 
109
212
  # 按语言分组
@@ -114,10 +217,11 @@ def direct_scan(
114
217
 
115
218
  # 调用检查器(保持相对路径,基于 base_path 解析)
116
219
  issues_c = analyze_c_files(str(base), [str(p) for p in c_files]) if c_files else []
117
- issues_r = analyze_rust_files(str(base), [str(p) for p in r_files]) if r_files else []
220
+ issues_r = (
221
+ analyze_rust_files(str(base), [str(p) for p in r_files]) if r_files else []
222
+ )
118
223
  issues: List[Issue] = issues_c + issues_r
119
224
 
120
-
121
225
  summary: Dict[str, Any] = {
122
226
  "total": len(issues),
123
227
  "by_language": {"c/cpp": 0, "rust": 0},
@@ -135,7 +239,9 @@ def direct_scan(
135
239
  cat_counts[it.category] = cat_counts.get(it.category, 0) + 1
136
240
  file_score[it.file] = file_score.get(it.file, 0) + 1
137
241
  # Top 风险文件
138
- summary["top_risk_files"] = [f for f, _ in sorted(file_score.items(), key=lambda x: x[1], reverse=True)[:10]]
242
+ summary["top_risk_files"] = [
243
+ f for f, _ in sorted(file_score.items(), key=lambda x: x[1], reverse=True)[:10]
244
+ ]
139
245
 
140
246
  result = {
141
247
  "summary": summary,
@@ -159,7 +265,9 @@ def format_markdown_report(result_json: Dict) -> str:
159
265
  md.append("")
160
266
  md.append("## 统计概览")
161
267
  by_lang = s.get("by_language", {})
162
- md.append(f"- 按语言: c/cpp={by_lang.get('c/cpp', 0)}, rust={by_lang.get('rust', 0)}")
268
+ md.append(
269
+ f"- 按语言: c/cpp={by_lang.get('c/cpp', 0)}, rust={by_lang.get('rust', 0)}"
270
+ )
163
271
  md.append("- 按类别:")
164
272
  for k, v in s.get("by_category", {}).items():
165
273
  md.append(f" - {k}: {v}")
@@ -170,7 +278,9 @@ def format_markdown_report(result_json: Dict) -> str:
170
278
  md.append("")
171
279
  md.append("## 详细问题")
172
280
  for i, it in enumerate(issues, start=1):
173
- md.append(f"### [{i}] {it.get('file')}:{it.get('line')} ({it.get('language')}, {it.get('category')})")
281
+ md.append(
282
+ f"### [{i}] {it.get('file')}:{it.get('line')} ({it.get('language')}, {it.get('category')})"
283
+ )
174
284
  md.append(f"- 模式: {it.get('pattern')}")
175
285
  md.append(f"- 证据: `{it.get('evidence')}`")
176
286
  md.append(f"- 描述: {it.get('description')}")
@@ -205,6 +315,7 @@ def run_with_agent(
205
315
  - enable_verification: 是否启用二次验证(默认 True),关闭后分析Agent确认的问题将直接写入报告
206
316
  """
207
317
  from jarvis.jarvis_sec import run_security_analysis # 延迟导入,避免循环
318
+
208
319
  return run_security_analysis(
209
320
  entry_path,
210
321
  languages=languages,
@@ -223,4 +334,4 @@ __all__ = [
223
334
  "direct_scan",
224
335
  "format_markdown_report",
225
336
  "run_with_agent",
226
- ]
337
+ ]
@@ -1,13 +1,16 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  import os
4
- from typing import Optional, Tuple
4
+ from typing import Optional
5
+ from typing import Tuple
5
6
 
6
7
  import typer
7
8
 
8
9
  from jarvis.jarvis_platform.registry import PlatformRegistry
9
- from jarvis.jarvis_utils.config import get_shell_name, set_config
10
+ from jarvis.jarvis_utils.config import get_shell_name
11
+ from jarvis.jarvis_utils.config import set_config
10
12
  from jarvis.jarvis_utils.input import get_multiline_input
13
+ from jarvis.jarvis_utils.output import PrettyOutput
11
14
  from jarvis.jarvis_utils.utils import init_env
12
15
 
13
16
  app = typer.Typer(
@@ -22,7 +25,7 @@ Example:
22
25
 
23
26
  def execute_command(command: str, should_run: bool) -> None:
24
27
  """Print command without execution"""
25
- print(command)
28
+ PrettyOutput.auto_print(command)
26
29
  if should_run:
27
30
  os.system(command)
28
31
 
@@ -114,7 +117,7 @@ def install_jss_completion(
114
117
  ) -> None:
115
118
  """为指定的shell安装'命令未找到'处理器,实现自然语言命令建议"""
116
119
  if shell not in ("fish", "bash", "zsh"):
117
- print(
120
+ PrettyOutput.auto_print(
118
121
  f"❌ 错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh"
119
122
  )
120
123
  raise typer.Exit(code=1)
@@ -124,7 +127,7 @@ def install_jss_completion(
124
127
  start_marker, end_marker = _get_markers()
125
128
 
126
129
  if not os.path.exists(config_file):
127
- print("ℹ️ 未找到 config.fish 文件,将创建新文件")
130
+ PrettyOutput.auto_print("ℹ️ 未找到 config.fish 文件,将创建新文件")
128
131
  os.makedirs(os.path.dirname(config_file), exist_ok=True)
129
132
  with open(config_file, "w") as f:
130
133
  f.write("")
@@ -133,7 +136,7 @@ def install_jss_completion(
133
136
  content = f.read()
134
137
 
135
138
  if start_marker in content:
136
- print(
139
+ PrettyOutput.auto_print(
137
140
  "✅ JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish"
138
141
  )
139
142
  return
@@ -155,7 +158,7 @@ end
155
158
  {end_marker}
156
159
  """
157
160
  )
158
- print(
161
+ PrettyOutput.auto_print(
159
162
  "✅ JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish"
160
163
  )
161
164
  elif shell == "bash":
@@ -163,7 +166,7 @@ end
163
166
  start_marker, end_marker = _get_bash_markers()
164
167
 
165
168
  if not os.path.exists(config_file):
166
- print("ℹ️ 未找到 ~/.bashrc 文件,将创建新文件")
169
+ PrettyOutput.auto_print("ℹ️ 未找到 ~/.bashrc 文件,将创建新文件")
167
170
  os.makedirs(os.path.dirname(config_file), exist_ok=True)
168
171
  with open(config_file, "w") as f:
169
172
  f.write("")
@@ -172,7 +175,7 @@ end
172
175
  content = f.read()
173
176
 
174
177
  if start_marker in content:
175
- print(
178
+ PrettyOutput.auto_print(
176
179
  "✅ JSS bash completion 已安装,请执行: source ~/.bashrc"
177
180
  )
178
181
  return
@@ -217,7 +220,7 @@ command_not_found_handle() {{
217
220
  {end_marker}
218
221
  """
219
222
  )
220
- print(
223
+ PrettyOutput.auto_print(
221
224
  "✅ JSS bash completion 已安装,请执行: source ~/.bashrc"
222
225
  )
223
226
  elif shell == "zsh":
@@ -225,7 +228,7 @@ command_not_found_handle() {{
225
228
  start_marker, end_marker = _get_zsh_markers()
226
229
 
227
230
  if not os.path.exists(config_file):
228
- print("ℹ️ 未找到 ~/.zshrc 文件,将创建新文件")
231
+ PrettyOutput.auto_print("ℹ️ 未找到 ~/.zshrc 文件,将创建新文件")
229
232
  os.makedirs(os.path.dirname(config_file), exist_ok=True)
230
233
  with open(config_file, "w") as f:
231
234
  f.write("")
@@ -234,7 +237,7 @@ command_not_found_handle() {{
234
237
  content = f.read()
235
238
 
236
239
  if start_marker in content:
237
- print(
240
+ PrettyOutput.auto_print(
238
241
  "✅ JSS zsh completion 已安装,请执行: source ~/.zshrc"
239
242
  )
240
243
  return
@@ -283,9 +286,7 @@ command_not_found_handler() {{
283
286
  {end_marker}
284
287
  """
285
288
  )
286
- print(
287
- "✅ JSS zsh completion 已安装,请执行: source ~/.zshrc"
288
- )
289
+ PrettyOutput.auto_print("✅ JSS zsh completion 已安装,请执行: source ~/.zshrc")
289
290
  return
290
291
 
291
292
 
@@ -295,7 +296,7 @@ def uninstall_jss_completion(
295
296
  ) -> None:
296
297
  """卸载JSS shell'命令未找到'处理器"""
297
298
  if shell not in ("fish", "bash", "zsh"):
298
- print(
299
+ PrettyOutput.auto_print(
299
300
  f"❌ 错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh"
300
301
  )
301
302
  raise typer.Exit(code=1)
@@ -305,18 +306,14 @@ def uninstall_jss_completion(
305
306
  start_marker, end_marker = _get_markers()
306
307
 
307
308
  if not os.path.exists(config_file):
308
- print(
309
- "ℹ️ 未找到 JSS fish completion 配置,无需卸载"
310
- )
309
+ PrettyOutput.auto_print("ℹ️ 未找到 JSS fish completion 配置,无需卸载")
311
310
  return
312
311
 
313
312
  with open(config_file, "r") as f:
314
313
  content = f.read()
315
314
 
316
315
  if start_marker not in content:
317
- print(
318
- "ℹ️ 未找到 JSS fish completion 配置,无需卸载"
319
- )
316
+ PrettyOutput.auto_print("ℹ️ 未找到 JSS fish completion 配置,无需卸载")
320
317
  return
321
318
 
322
319
  new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
@@ -324,7 +321,7 @@ def uninstall_jss_completion(
324
321
  with open(config_file, "w") as f:
325
322
  f.write(new_content)
326
323
 
327
- print(
324
+ PrettyOutput.auto_print(
328
325
  "✅ JSS fish completion 已卸载,请执行: source ~/.config/fish/config.fish"
329
326
  )
330
327
  elif shell == "bash":
@@ -332,18 +329,14 @@ def uninstall_jss_completion(
332
329
  start_marker, end_marker = _get_bash_markers()
333
330
 
334
331
  if not os.path.exists(config_file):
335
- print(
336
- "ℹ️ 未找到 JSS bash completion 配置,无需卸载"
337
- )
332
+ PrettyOutput.auto_print("ℹ️ 未找到 JSS bash completion 配置,无需卸载")
338
333
  return
339
334
 
340
335
  with open(config_file, "r") as f:
341
336
  content = f.read()
342
337
 
343
338
  if start_marker not in content:
344
- print(
345
- "ℹ️ 未找到 JSS bash completion 配置,无需卸载"
346
- )
339
+ PrettyOutput.auto_print("ℹ️ 未找到 JSS bash completion 配置,无需卸载")
347
340
  return
348
341
 
349
342
  new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
@@ -351,7 +344,7 @@ def uninstall_jss_completion(
351
344
  with open(config_file, "w") as f:
352
345
  f.write(new_content)
353
346
 
354
- print(
347
+ PrettyOutput.auto_print(
355
348
  "✅ JSS bash completion 已卸载,请执行: source ~/.bashrc"
356
349
  )
357
350
  elif shell == "zsh":
@@ -359,18 +352,14 @@ def uninstall_jss_completion(
359
352
  start_marker, end_marker = _get_zsh_markers()
360
353
 
361
354
  if not os.path.exists(config_file):
362
- print(
363
- "ℹ️ 未找到 JSS zsh completion 配置,无需卸载"
364
- )
355
+ PrettyOutput.auto_print("ℹ️ 未找到 JSS zsh completion 配置,无需卸载")
365
356
  return
366
357
 
367
358
  with open(config_file, "r") as f:
368
359
  content = f.read()
369
360
 
370
361
  if start_marker not in content:
371
- print(
372
- "ℹ️ 未找到 JSS zsh completion 配置,无需卸载"
373
- )
362
+ PrettyOutput.auto_print("ℹ️ 未找到 JSS zsh completion 配置,无需卸载")
374
363
  return
375
364
 
376
365
  new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
@@ -378,9 +367,7 @@ def uninstall_jss_completion(
378
367
  with open(config_file, "w") as f:
379
368
  f.write(new_content)
380
369
 
381
- print(
382
- "✅ JSS zsh completion 已卸载,请执行: source ~/.zshrc"
383
- )
370
+ PrettyOutput.auto_print("✅ JSS zsh completion 已卸载,请执行: source ~/.zshrc")
384
371
 
385
372
 
386
373
  def process_request(request: str) -> Optional[str]:
@@ -437,7 +424,7 @@ def process_request(request: str) -> Optional[str]:
437
424
  def request_command(
438
425
  request: Optional[str] = typer.Argument(
439
426
  None, help="描述您想要执行的操作(用自然语言描述),如果未提供则从标准输入读取"
440
- )
427
+ ),
441
428
  ):
442
429
  """描述您想要执行的操作(用自然语言描述)"""
443
430
  should_run = False
@@ -459,7 +446,7 @@ def request_command(
459
446
  def cli():
460
447
  """Typer application entry point"""
461
448
  init_env("")
462
- set_config("JARVIS_PRINT_PROMPT", "false")
449
+ set_config("print_prompt", "false")
463
450
  app()
464
451
 
465
452
 
@@ -5,17 +5,23 @@
5
5
  """
6
6
 
7
7
  import builtins
8
- from datetime import datetime, timedelta
9
- from typing import Optional, List
8
+ from datetime import datetime
9
+ from datetime import timedelta
10
+ from pathlib import Path
11
+ from typing import Dict
12
+ from typing import List
13
+ from typing import Optional
14
+ from typing import Set
15
+
10
16
  import typer
17
+ from rich import print as rprint
11
18
  from rich.console import Console
12
19
  from rich.table import Table
13
- from rich import print as rprint
14
- from pathlib import Path
15
20
 
16
- from .stats import StatsManager
17
- from jarvis.jarvis_utils.utils import init_env
18
21
  from jarvis.jarvis_utils.config import get_data_dir
22
+ from jarvis.jarvis_utils.utils import init_env
23
+
24
+ from .stats import StatsManager
19
25
 
20
26
  app = typer.Typer(help="Jarvis 统计模块命令行工具")
21
27
  console = Console()
@@ -117,7 +123,6 @@ def show(
117
123
 
118
124
  stats.show(
119
125
  metric_name=metric,
120
-
121
126
  aggregation=aggregation,
122
127
  tags=tag_dict if tag_dict else None,
123
128
  )
@@ -198,7 +203,7 @@ def list():
198
203
  count = len(records)
199
204
 
200
205
  # 收集所有唯一的标签
201
- all_tags = {}
206
+ all_tags: Dict[str, Set[str]] = {}
202
207
  for record in records:
203
208
  tags = record.get("tags", {})
204
209
  for k, v in tags.items():
@@ -248,16 +253,13 @@ def clean(
248
253
  @app.command()
249
254
  def export(
250
255
  metric: str = typer.Argument(..., help="指标名称"),
251
-
252
-
253
-
254
256
  tags: Optional[List[str]] = typer.Option(
255
257
  None, "--tag", "-t", help="标签过滤,格式: key=value"
256
258
  ),
257
259
  ):
258
260
  """导出统计数据"""
259
- import json
260
261
  import csv
262
+ import json
261
263
  import sys
262
264
 
263
265
  stats = StatsManager(_get_stats_dir())
@@ -4,12 +4,19 @@
4
4
  提供统计数据的增加、查看、分析等功能的主接口
5
5
  """
6
6
 
7
- from datetime import datetime, timedelta
8
- from typing import Dict, List, Optional, Union, Any
7
+ from jarvis.jarvis_utils.output import PrettyOutput
8
+
9
+ from datetime import datetime
10
+ from datetime import timedelta
11
+ from typing import Any
12
+ from typing import Dict
13
+ from typing import List
14
+ from typing import Optional
15
+ from typing import Union
9
16
 
10
17
  from jarvis.jarvis_stats.storage import StatsStorage
11
18
  from jarvis.jarvis_stats.visualizer import StatsVisualizer
12
- from jarvis.jarvis_utils.output import OutputType, PrettyOutput # 保留用于语法高亮
19
+ from jarvis.jarvis_utils.output import OutputType # 保留用于语法高亮
13
20
 
14
21
 
15
22
  class StatsManager:
@@ -191,10 +198,14 @@ class StatsManager:
191
198
  created_at = info.get("created_at")
192
199
  last_updated = info.get("last_updated")
193
200
  start_dt = start_time or (
194
- datetime.fromisoformat(created_at) if created_at else datetime.now()
201
+ datetime.fromisoformat(created_at)
202
+ if created_at
203
+ else datetime.now()
195
204
  )
196
205
  end_dt = end_time or (
197
- datetime.fromisoformat(last_updated) if last_updated else datetime.now()
206
+ datetime.fromisoformat(last_updated)
207
+ if last_updated
208
+ else datetime.now()
198
209
  )
199
210
  except Exception:
200
211
  start_dt = start_time or (datetime.now() - timedelta(days=7))
@@ -270,10 +281,14 @@ class StatsManager:
270
281
  created_at = info.get("created_at")
271
282
  last_updated = info.get("last_updated")
272
283
  start_dt = start_time or (
273
- datetime.fromisoformat(created_at) if created_at else datetime.now()
284
+ datetime.fromisoformat(created_at)
285
+ if created_at
286
+ else datetime.now()
274
287
  )
275
288
  end_dt = end_time or (
276
- datetime.fromisoformat(last_updated) if last_updated else datetime.now()
289
+ datetime.fromisoformat(last_updated)
290
+ if last_updated
291
+ else datetime.now()
277
292
  )
278
293
  except Exception:
279
294
  start_dt = start_time or (datetime.now() - timedelta(days=7))
@@ -422,8 +437,6 @@ class StatsManager:
422
437
  if start_time is None:
423
438
  start_time = end_time - timedelta(days=7)
424
439
 
425
-
426
-
427
440
  # 计算时间范围列标题
428
441
  if start_time is None or end_time is None:
429
442
  period_label = "值"
@@ -446,7 +459,7 @@ class StatsManager:
446
459
  displayed_count = 0
447
460
  for metric in metrics:
448
461
  # 获取该指标的记录(全历史或指定范围)
449
- if 'all_time' in locals() and all_time:
462
+ if "all_time" in locals() and all_time:
450
463
  _start = None
451
464
  _end = None
452
465
  try:
@@ -549,9 +562,7 @@ class StatsManager:
549
562
  )
550
563
 
551
564
  if not aggregated:
552
- print(
553
- f"⚠️ 没有找到指标 '{metric_name}' 的数据"
554
- )
565
+ PrettyOutput.auto_print(f"⚠️ 没有找到指标 '{metric_name}' 的数据")
555
566
  return
556
567
 
557
568
  # 获取指标信息
@@ -588,8 +599,8 @@ class StatsManager:
588
599
  PrettyOutput.print(chart, OutputType.CODE, lang="text") # 保留用于语法高亮
589
600
 
590
601
  # 显示时间范围
591
- from rich.panel import Panel
592
602
  from rich.console import Console
603
+ from rich.panel import Panel
593
604
 
594
605
  console = Console()
595
606
  console.print(
@@ -681,9 +692,7 @@ class StatsManager:
681
692
  )
682
693
 
683
694
  if not aggregated:
684
- print(
685
- f"⚠️ 没有找到指标 '{metric_name}' 的数据"
686
- )
695
+ PrettyOutput.auto_print(f"⚠️ 没有找到指标 '{metric_name}' 的数据")
687
696
  return
688
697
 
689
698
  # 获取指标信息
@@ -693,11 +702,11 @@ class StatsManager:
693
702
  # 显示汇总
694
703
  summary = visualizer.show_summary(aggregated, metric_name, unit, tags)
695
704
  if summary: # 如果返回了内容才打印(兼容性)
696
- print(f"ℹ️ {summary}")
705
+ PrettyOutput.auto_print(f"ℹ️ {summary}")
697
706
 
698
707
  # 显示时间范围
699
- from rich.panel import Panel
700
708
  from rich.console import Console
709
+ from rich.panel import Panel
701
710
 
702
711
  console = Console()
703
712
  console.print(