jarvis-ai-assistant 0.1.222__py3-none-any.whl → 0.7.0__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +1143 -245
- jarvis/jarvis_agent/agent_manager.py +97 -0
- jarvis/jarvis_agent/builtin_input_handler.py +12 -10
- jarvis/jarvis_agent/config_editor.py +57 -0
- jarvis/jarvis_agent/edit_file_handler.py +392 -99
- jarvis/jarvis_agent/event_bus.py +48 -0
- jarvis/jarvis_agent/events.py +157 -0
- jarvis/jarvis_agent/file_context_handler.py +79 -0
- jarvis/jarvis_agent/file_methodology_manager.py +117 -0
- jarvis/jarvis_agent/jarvis.py +1117 -147
- jarvis/jarvis_agent/main.py +78 -34
- jarvis/jarvis_agent/memory_manager.py +195 -0
- jarvis/jarvis_agent/methodology_share_manager.py +174 -0
- jarvis/jarvis_agent/prompt_manager.py +82 -0
- jarvis/jarvis_agent/prompts.py +46 -9
- jarvis/jarvis_agent/protocols.py +4 -1
- jarvis/jarvis_agent/rewrite_file_handler.py +141 -0
- jarvis/jarvis_agent/run_loop.py +146 -0
- jarvis/jarvis_agent/session_manager.py +9 -9
- jarvis/jarvis_agent/share_manager.py +228 -0
- jarvis/jarvis_agent/shell_input_handler.py +23 -3
- jarvis/jarvis_agent/stdio_redirect.py +295 -0
- jarvis/jarvis_agent/task_analyzer.py +212 -0
- jarvis/jarvis_agent/task_manager.py +154 -0
- jarvis/jarvis_agent/task_planner.py +496 -0
- jarvis/jarvis_agent/tool_executor.py +8 -4
- jarvis/jarvis_agent/tool_share_manager.py +139 -0
- jarvis/jarvis_agent/user_interaction.py +42 -0
- jarvis/jarvis_agent/utils.py +54 -0
- jarvis/jarvis_agent/web_bridge.py +189 -0
- jarvis/jarvis_agent/web_output_sink.py +53 -0
- jarvis/jarvis_agent/web_server.py +751 -0
- jarvis/jarvis_c2rust/__init__.py +26 -0
- jarvis/jarvis_c2rust/cli.py +613 -0
- jarvis/jarvis_c2rust/collector.py +258 -0
- jarvis/jarvis_c2rust/library_replacer.py +1122 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +1300 -0
- jarvis/jarvis_c2rust/optimizer.py +960 -0
- jarvis/jarvis_c2rust/scanner.py +1681 -0
- jarvis/jarvis_c2rust/transpiler.py +2325 -0
- jarvis/jarvis_code_agent/build_validation_config.py +133 -0
- jarvis/jarvis_code_agent/code_agent.py +1605 -178
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +62 -0
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +74 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +102 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +59 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +125 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +69 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +38 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +38 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +50 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +93 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +129 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +54 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +154 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +43 -0
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +363 -0
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +18 -0
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +132 -0
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +330 -0
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +781 -0
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +185 -0
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +89 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +31 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +231 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +183 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +219 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +209 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +451 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +77 -0
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +48 -0
- jarvis/jarvis_code_agent/lint.py +275 -13
- jarvis/jarvis_code_agent/utils.py +142 -0
- jarvis/jarvis_code_analysis/checklists/loader.py +20 -6
- jarvis/jarvis_code_analysis/code_review.py +583 -548
- jarvis/jarvis_data/config_schema.json +339 -28
- jarvis/jarvis_git_squash/main.py +22 -13
- jarvis/jarvis_git_utils/git_commiter.py +171 -55
- jarvis/jarvis_mcp/sse_mcp_client.py +22 -15
- jarvis/jarvis_mcp/stdio_mcp_client.py +4 -4
- jarvis/jarvis_mcp/streamable_mcp_client.py +36 -16
- jarvis/jarvis_memory_organizer/memory_organizer.py +753 -0
- jarvis/jarvis_methodology/main.py +48 -63
- jarvis/jarvis_multi_agent/__init__.py +302 -43
- jarvis/jarvis_multi_agent/main.py +70 -24
- jarvis/jarvis_platform/ai8.py +40 -23
- jarvis/jarvis_platform/base.py +210 -49
- jarvis/jarvis_platform/human.py +11 -1
- jarvis/jarvis_platform/kimi.py +82 -76
- jarvis/jarvis_platform/openai.py +73 -1
- jarvis/jarvis_platform/registry.py +8 -15
- jarvis/jarvis_platform/tongyi.py +115 -101
- jarvis/jarvis_platform/yuanbao.py +89 -63
- jarvis/jarvis_platform_manager/main.py +194 -132
- jarvis/jarvis_platform_manager/service.py +122 -86
- jarvis/jarvis_rag/cli.py +156 -53
- jarvis/jarvis_rag/embedding_manager.py +155 -12
- jarvis/jarvis_rag/llm_interface.py +10 -13
- jarvis/jarvis_rag/query_rewriter.py +63 -12
- jarvis/jarvis_rag/rag_pipeline.py +222 -40
- jarvis/jarvis_rag/reranker.py +26 -3
- jarvis/jarvis_rag/retriever.py +270 -14
- jarvis/jarvis_sec/__init__.py +3605 -0
- jarvis/jarvis_sec/checkers/__init__.py +32 -0
- jarvis/jarvis_sec/checkers/c_checker.py +2680 -0
- jarvis/jarvis_sec/checkers/rust_checker.py +1108 -0
- jarvis/jarvis_sec/cli.py +116 -0
- jarvis/jarvis_sec/report.py +257 -0
- jarvis/jarvis_sec/status.py +264 -0
- jarvis/jarvis_sec/types.py +20 -0
- jarvis/jarvis_sec/workflow.py +219 -0
- jarvis/jarvis_smart_shell/main.py +405 -137
- jarvis/jarvis_stats/__init__.py +13 -0
- jarvis/jarvis_stats/cli.py +387 -0
- jarvis/jarvis_stats/stats.py +711 -0
- jarvis/jarvis_stats/storage.py +612 -0
- jarvis/jarvis_stats/visualizer.py +282 -0
- jarvis/jarvis_tools/ask_user.py +1 -0
- jarvis/jarvis_tools/base.py +18 -2
- jarvis/jarvis_tools/clear_memory.py +239 -0
- jarvis/jarvis_tools/cli/main.py +220 -144
- jarvis/jarvis_tools/execute_script.py +52 -12
- jarvis/jarvis_tools/file_analyzer.py +17 -12
- jarvis/jarvis_tools/generate_new_tool.py +46 -24
- jarvis/jarvis_tools/read_code.py +277 -18
- jarvis/jarvis_tools/read_symbols.py +141 -0
- jarvis/jarvis_tools/read_webpage.py +86 -13
- jarvis/jarvis_tools/registry.py +294 -90
- jarvis/jarvis_tools/retrieve_memory.py +227 -0
- jarvis/jarvis_tools/save_memory.py +194 -0
- jarvis/jarvis_tools/search_web.py +62 -28
- jarvis/jarvis_tools/sub_agent.py +205 -0
- jarvis/jarvis_tools/sub_code_agent.py +217 -0
- jarvis/jarvis_tools/virtual_tty.py +330 -62
- jarvis/jarvis_utils/builtin_replace_map.py +4 -5
- jarvis/jarvis_utils/clipboard.py +90 -0
- jarvis/jarvis_utils/config.py +607 -50
- jarvis/jarvis_utils/embedding.py +3 -0
- jarvis/jarvis_utils/fzf.py +57 -0
- jarvis/jarvis_utils/git_utils.py +251 -29
- jarvis/jarvis_utils/globals.py +174 -17
- jarvis/jarvis_utils/http.py +58 -79
- jarvis/jarvis_utils/input.py +899 -153
- jarvis/jarvis_utils/methodology.py +210 -83
- jarvis/jarvis_utils/output.py +220 -137
- jarvis/jarvis_utils/utils.py +1906 -135
- jarvis_ai_assistant-0.7.0.dist-info/METADATA +465 -0
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +192 -0
- {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/entry_points.txt +8 -2
- jarvis/jarvis_git_details/main.py +0 -265
- jarvis/jarvis_platform/oyi.py +0 -357
- jarvis/jarvis_tools/edit_file.py +0 -255
- jarvis/jarvis_tools/rewrite_file.py +0 -195
- jarvis_ai_assistant-0.1.222.dist-info/METADATA +0 -767
- jarvis_ai_assistant-0.1.222.dist-info/RECORD +0 -110
- /jarvis/{jarvis_git_details → jarvis_memory_organizer}/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
import argparse
|
|
4
3
|
import os
|
|
5
|
-
import sys
|
|
6
4
|
from typing import Optional, Tuple
|
|
7
5
|
|
|
6
|
+
import typer
|
|
7
|
+
|
|
8
8
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
9
9
|
from jarvis.jarvis_utils.config import get_shell_name, set_config
|
|
10
10
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
11
11
|
from jarvis.jarvis_utils.utils import init_env
|
|
12
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
13
|
+
|
|
14
|
+
app = typer.Typer(
|
|
15
|
+
help="将自然语言要求转换为shell命令",
|
|
16
|
+
epilog="""
|
|
17
|
+
Example:
|
|
18
|
+
jss request "Find all Python files in the current directory"
|
|
19
|
+
jss install
|
|
20
|
+
""",
|
|
21
|
+
)
|
|
12
22
|
|
|
13
23
|
|
|
14
24
|
def execute_command(command: str, should_run: bool) -> None:
|
|
@@ -18,59 +28,121 @@ def execute_command(command: str, should_run: bool) -> None:
|
|
|
18
28
|
os.system(command)
|
|
19
29
|
|
|
20
30
|
|
|
21
|
-
def _check_fish_shell() -> bool:
|
|
22
|
-
"""Check if current shell is fish
|
|
23
|
-
|
|
24
|
-
Returns:
|
|
25
|
-
bool: True if fish shell, False otherwise
|
|
26
|
-
"""
|
|
27
|
-
return get_shell_name() == "fish"
|
|
28
|
-
|
|
29
31
|
def _get_config_file() -> str:
|
|
30
32
|
"""Get fish config file path
|
|
31
|
-
|
|
33
|
+
|
|
32
34
|
Returns:
|
|
33
35
|
str: Path to fish config file
|
|
34
36
|
"""
|
|
35
37
|
return os.path.expanduser("~/.config/fish/config.fish")
|
|
36
38
|
|
|
39
|
+
|
|
37
40
|
def _get_markers() -> Tuple[str, str]:
|
|
38
41
|
"""Get start and end markers for JSS completion
|
|
39
|
-
|
|
42
|
+
|
|
40
43
|
Returns:
|
|
41
44
|
Tuple[str, str]: (start_marker, end_marker)
|
|
42
45
|
"""
|
|
43
46
|
return (
|
|
44
47
|
"# ===== JARVIS JSS FISH COMPLETION START =====",
|
|
45
|
-
"# ===== JARVIS JSS FISH COMPLETION END ====="
|
|
48
|
+
"# ===== JARVIS JSS FISH COMPLETION END =====",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _check_bash_shell() -> bool:
|
|
53
|
+
"""Check if current shell is bash
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
bool: True if bash shell, False otherwise
|
|
57
|
+
"""
|
|
58
|
+
return get_shell_name() == "bash"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _get_bash_config_file() -> str:
|
|
62
|
+
"""Get bash config file path
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
str: Path to bash config file (~/.bashrc)
|
|
66
|
+
"""
|
|
67
|
+
return os.path.expanduser("~/.bashrc")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _get_bash_markers() -> Tuple[str, str]:
|
|
71
|
+
"""Get start and end markers for JSS completion in bash
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
Tuple[str, str]: (start_marker, end_marker)
|
|
75
|
+
"""
|
|
76
|
+
return (
|
|
77
|
+
"# ===== JARVIS JSS BASH COMPLETION START =====",
|
|
78
|
+
"# ===== JARVIS JSS BASH COMPLETION END =====",
|
|
46
79
|
)
|
|
47
80
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
81
|
+
|
|
82
|
+
def _check_zsh_shell() -> bool:
|
|
83
|
+
"""Check if current shell is zsh
|
|
84
|
+
|
|
51
85
|
Returns:
|
|
52
|
-
|
|
86
|
+
bool: True if zsh shell, False otherwise
|
|
53
87
|
"""
|
|
54
|
-
|
|
55
|
-
print("当前不是fish shell,无需安装")
|
|
56
|
-
return 0
|
|
88
|
+
return get_shell_name() == "zsh"
|
|
57
89
|
|
|
58
|
-
config_file = _get_config_file()
|
|
59
|
-
start_marker, end_marker = _get_markers()
|
|
60
90
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
91
|
+
def _get_zsh_config_file() -> str:
|
|
92
|
+
"""Get zsh config file path
|
|
64
93
|
|
|
65
|
-
|
|
66
|
-
|
|
94
|
+
Returns:
|
|
95
|
+
str: Path to zsh config file (~/.zshrc)
|
|
96
|
+
"""
|
|
97
|
+
return os.path.expanduser("~/.zshrc")
|
|
67
98
|
|
|
68
|
-
if start_marker in content:
|
|
69
|
-
print("JSS fish completion已安装,请执行: source ~/.config/fish/config.fish")
|
|
70
|
-
return 0
|
|
71
99
|
|
|
72
|
-
|
|
73
|
-
|
|
100
|
+
def _get_zsh_markers() -> Tuple[str, str]:
|
|
101
|
+
"""Get start and end markers for JSS completion in zsh
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Tuple[str, str]: (start_marker, end_marker)
|
|
105
|
+
"""
|
|
106
|
+
return (
|
|
107
|
+
"# ===== JARVIS JSS ZSH COMPLETION START =====",
|
|
108
|
+
"# ===== JARVIS JSS ZSH COMPLETION END =====",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@app.command("install")
|
|
113
|
+
def install_jss_completion(
|
|
114
|
+
shell: str = typer.Option("fish", help="指定shell类型(支持fish, bash, zsh)"),
|
|
115
|
+
) -> None:
|
|
116
|
+
"""为指定的shell安装'命令未找到'处理器,实现自然语言命令建议"""
|
|
117
|
+
if shell not in ("fish", "bash", "zsh"):
|
|
118
|
+
PrettyOutput.print(
|
|
119
|
+
f"错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh", OutputType.ERROR
|
|
120
|
+
)
|
|
121
|
+
raise typer.Exit(code=1)
|
|
122
|
+
|
|
123
|
+
if shell == "fish":
|
|
124
|
+
config_file = _get_config_file()
|
|
125
|
+
start_marker, end_marker = _get_markers()
|
|
126
|
+
|
|
127
|
+
if not os.path.exists(config_file):
|
|
128
|
+
PrettyOutput.print("未找到 config.fish 文件,将创建新文件", OutputType.INFO)
|
|
129
|
+
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
130
|
+
with open(config_file, "w") as f:
|
|
131
|
+
f.write("")
|
|
132
|
+
|
|
133
|
+
with open(config_file, "r") as f:
|
|
134
|
+
content = f.read()
|
|
135
|
+
|
|
136
|
+
if start_marker in content:
|
|
137
|
+
PrettyOutput.print(
|
|
138
|
+
"JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish",
|
|
139
|
+
OutputType.SUCCESS,
|
|
140
|
+
)
|
|
141
|
+
return
|
|
142
|
+
|
|
143
|
+
with open(config_file, "a") as f:
|
|
144
|
+
f.write(
|
|
145
|
+
f"""
|
|
74
146
|
{start_marker}
|
|
75
147
|
function fish_command_not_found
|
|
76
148
|
if test (string length "$argv") -lt 10
|
|
@@ -83,41 +155,282 @@ function __fish_command_not_found_handler --on-event fish_command_not_found
|
|
|
83
155
|
fish_command_not_found "$argv"
|
|
84
156
|
end
|
|
85
157
|
{end_marker}
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
158
|
+
"""
|
|
159
|
+
)
|
|
160
|
+
PrettyOutput.print(
|
|
161
|
+
"JSS fish completion 已安装,请执行: source ~/.config/fish/config.fish",
|
|
162
|
+
OutputType.SUCCESS,
|
|
163
|
+
)
|
|
164
|
+
elif shell == "bash":
|
|
165
|
+
config_file = _get_bash_config_file()
|
|
166
|
+
start_marker, end_marker = _get_bash_markers()
|
|
167
|
+
|
|
168
|
+
if not os.path.exists(config_file):
|
|
169
|
+
PrettyOutput.print("未找到 ~/.bashrc 文件,将创建新文件", OutputType.INFO)
|
|
170
|
+
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
171
|
+
with open(config_file, "w") as f:
|
|
172
|
+
f.write("")
|
|
173
|
+
|
|
174
|
+
with open(config_file, "r") as f:
|
|
175
|
+
content = f.read()
|
|
176
|
+
|
|
177
|
+
if start_marker in content:
|
|
178
|
+
PrettyOutput.print(
|
|
179
|
+
"JSS bash completion 已安装,请执行: source ~/.bashrc",
|
|
180
|
+
OutputType.SUCCESS,
|
|
181
|
+
)
|
|
182
|
+
return
|
|
183
|
+
else:
|
|
184
|
+
with open(config_file, "a") as f:
|
|
185
|
+
f.write(
|
|
186
|
+
f"""
|
|
187
|
+
{start_marker}
|
|
188
|
+
# Bash 'command not found' handler for JSS
|
|
189
|
+
# 行为:
|
|
190
|
+
# - 生成可编辑的建议命令,用户可直接编辑后回车执行
|
|
191
|
+
# - 非交互模式下仅打印建议
|
|
192
|
+
command_not_found_handle() {{
|
|
193
|
+
local cmd="$1"
|
|
194
|
+
shift || true
|
|
195
|
+
local text="$cmd $*"
|
|
196
|
+
|
|
197
|
+
# 与 fish 行为保持一致:对过短输入不处理
|
|
198
|
+
if [ ${{#text}} -lt 10 ]; then
|
|
199
|
+
return 127
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
local suggestion edited
|
|
203
|
+
suggestion=$(jss request "$text")
|
|
204
|
+
if [ -n "$suggestion" ]; then
|
|
205
|
+
# 交互式:用 readline 预填命令,用户可直接回车执行或编辑
|
|
206
|
+
if [[ $- == *i* ]]; then
|
|
207
|
+
edited="$suggestion"
|
|
208
|
+
# -e 启用 readline;-i 预填默认值;无提示前缀,使体验更接近 fish 的“替换命令行”
|
|
209
|
+
read -e -i "$edited" edited
|
|
210
|
+
if [ -n "$edited" ]; then
|
|
211
|
+
eval "$edited"
|
|
212
|
+
return $?
|
|
213
|
+
fi
|
|
214
|
+
else
|
|
215
|
+
# 非交互:仅打印建议
|
|
216
|
+
printf '%s\n' "$suggestion"
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
return 127
|
|
220
|
+
}}
|
|
221
|
+
{end_marker}
|
|
222
|
+
"""
|
|
223
|
+
)
|
|
224
|
+
PrettyOutput.print(
|
|
225
|
+
"JSS bash completion 已安装,请执行: source ~/.bashrc",
|
|
226
|
+
OutputType.SUCCESS,
|
|
227
|
+
)
|
|
228
|
+
elif shell == "zsh":
|
|
229
|
+
config_file = _get_zsh_config_file()
|
|
230
|
+
start_marker, end_marker = _get_zsh_markers()
|
|
231
|
+
|
|
232
|
+
if not os.path.exists(config_file):
|
|
233
|
+
PrettyOutput.print("未找到 ~/.zshrc 文件,将创建新文件", OutputType.INFO)
|
|
234
|
+
os.makedirs(os.path.dirname(config_file), exist_ok=True)
|
|
235
|
+
with open(config_file, "w") as f:
|
|
236
|
+
f.write("")
|
|
237
|
+
|
|
238
|
+
with open(config_file, "r") as f:
|
|
239
|
+
content = f.read()
|
|
240
|
+
|
|
241
|
+
if start_marker in content:
|
|
242
|
+
PrettyOutput.print(
|
|
243
|
+
"JSS zsh completion 已安装,请执行: source ~/.zshrc", OutputType.SUCCESS
|
|
244
|
+
)
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
with open(config_file, "a") as f:
|
|
248
|
+
f.write(
|
|
249
|
+
f"""
|
|
250
|
+
{start_marker}
|
|
251
|
+
# Zsh 'command not found' handler for JSS
|
|
252
|
+
# 行为:
|
|
253
|
+
# - 生成可编辑的建议命令,用户可直接编辑后回车执行
|
|
254
|
+
# - 非交互模式下仅打印建议
|
|
255
|
+
command_not_found_handler() {{
|
|
256
|
+
local cmd="$1"
|
|
257
|
+
shift || true
|
|
258
|
+
local text="$cmd $*"
|
|
259
|
+
|
|
260
|
+
# 与 fish 行为保持一致:对过短输入不处理
|
|
261
|
+
if [ ${{#text}} -lt 10 ]; then
|
|
262
|
+
return 127
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
local suggestion edited
|
|
266
|
+
suggestion=$(jss request "$text")
|
|
267
|
+
if [ -n "$suggestion" ]; then
|
|
268
|
+
if [[ -o interactive ]]; then
|
|
269
|
+
local editor="${{VISUAL:-${{EDITOR:-vi}}}}"
|
|
270
|
+
local tmpfile edited
|
|
271
|
+
tmpfile="$(mktemp -t jss-edit-XXXXXX)"
|
|
272
|
+
printf '%s\n' "$suggestion" > "$tmpfile"
|
|
273
|
+
"$editor" "$tmpfile"
|
|
274
|
+
edited="$(sed -n '/./{{p;q;}}' "$tmpfile" | tr -d '\r')"
|
|
275
|
+
rm -f "$tmpfile"
|
|
276
|
+
if [ -z "$edited" ]; then
|
|
277
|
+
edited="$suggestion"
|
|
278
|
+
fi
|
|
279
|
+
eval "$edited"
|
|
280
|
+
return $?
|
|
281
|
+
else
|
|
282
|
+
# 非交互:仅打印建议
|
|
283
|
+
print -r -- "$suggestion"
|
|
284
|
+
fi
|
|
285
|
+
fi
|
|
286
|
+
return 127
|
|
287
|
+
}}
|
|
288
|
+
{end_marker}
|
|
289
|
+
"""
|
|
290
|
+
)
|
|
291
|
+
PrettyOutput.print(
|
|
292
|
+
"JSS zsh completion 已安装,请执行: source ~/.zshrc", OutputType.SUCCESS
|
|
293
|
+
)
|
|
294
|
+
return
|
|
113
295
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
296
|
+
with open(config_file, "a") as f:
|
|
297
|
+
f.write(
|
|
298
|
+
f"""
|
|
299
|
+
{start_marker}
|
|
300
|
+
# Bash 'command not found' handler for JSS
|
|
301
|
+
# 行为:
|
|
302
|
+
# - 生成可编辑的建议命令,用户可直接编辑后回车执行
|
|
303
|
+
# - 非交互模式下仅打印建议
|
|
304
|
+
command_not_found_handle() {{
|
|
305
|
+
local cmd="$1"
|
|
306
|
+
shift || true
|
|
307
|
+
local text="$cmd $*"
|
|
308
|
+
|
|
309
|
+
# 与 fish 行为保持一致:对过短输入不处理
|
|
310
|
+
if [ ${{#text}} -lt 10 ]; then
|
|
311
|
+
return 127
|
|
312
|
+
fi
|
|
313
|
+
|
|
314
|
+
local suggestion edited
|
|
315
|
+
suggestion=$(jss request "$text")
|
|
316
|
+
if [ -n "$suggestion" ]; then
|
|
317
|
+
# 交互式:用 readline 预填命令,用户可直接回车执行或编辑
|
|
318
|
+
if [[ $- == *i* ]]; then
|
|
319
|
+
edited="$suggestion"
|
|
320
|
+
# -e 启用 readline;-i 预填默认值;无提示前缀,使体验更接近 fish 的“替换命令行”
|
|
321
|
+
read -e -i "$edited" edited
|
|
322
|
+
if [ -n "$edited" ]; then
|
|
323
|
+
eval "$edited"
|
|
324
|
+
return $?
|
|
325
|
+
fi
|
|
326
|
+
else
|
|
327
|
+
# 非交互:仅打印建议
|
|
328
|
+
printf '%s\n' "$suggestion"
|
|
329
|
+
fi
|
|
330
|
+
fi
|
|
331
|
+
return 127
|
|
332
|
+
}}
|
|
333
|
+
{end_marker}
|
|
334
|
+
"""
|
|
335
|
+
)
|
|
336
|
+
PrettyOutput.print(
|
|
337
|
+
"JSS bash completion 已安装,请执行: source ~/.bashrc", OutputType.SUCCESS
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@app.command("uninstall")
|
|
342
|
+
def uninstall_jss_completion(
|
|
343
|
+
shell: str = typer.Option("fish", help="指定shell类型(支持fish, bash, zsh)"),
|
|
344
|
+
) -> None:
|
|
345
|
+
"""卸载JSS shell'命令未找到'处理器"""
|
|
346
|
+
if shell not in ("fish", "bash", "zsh"):
|
|
347
|
+
PrettyOutput.print(
|
|
348
|
+
f"错误: 不支持的shell类型: {shell}, 仅支持fish, bash, zsh", OutputType.ERROR
|
|
349
|
+
)
|
|
350
|
+
raise typer.Exit(code=1)
|
|
351
|
+
|
|
352
|
+
if shell == "fish":
|
|
353
|
+
config_file = _get_config_file()
|
|
354
|
+
start_marker, end_marker = _get_markers()
|
|
355
|
+
|
|
356
|
+
if not os.path.exists(config_file):
|
|
357
|
+
PrettyOutput.print(
|
|
358
|
+
"未找到 JSS fish completion 配置,无需卸载", OutputType.INFO
|
|
359
|
+
)
|
|
360
|
+
return
|
|
361
|
+
|
|
362
|
+
with open(config_file, "r") as f:
|
|
363
|
+
content = f.read()
|
|
364
|
+
|
|
365
|
+
if start_marker not in content:
|
|
366
|
+
PrettyOutput.print(
|
|
367
|
+
"未找到 JSS fish completion 配置,无需卸载", OutputType.INFO
|
|
368
|
+
)
|
|
369
|
+
return
|
|
370
|
+
|
|
371
|
+
new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
|
|
372
|
+
|
|
373
|
+
with open(config_file, "w") as f:
|
|
374
|
+
f.write(new_content)
|
|
375
|
+
|
|
376
|
+
PrettyOutput.print(
|
|
377
|
+
"JSS fish completion 已卸载,请执行: source ~/.config/fish/config.fish",
|
|
378
|
+
OutputType.SUCCESS,
|
|
379
|
+
)
|
|
380
|
+
elif shell == "bash":
|
|
381
|
+
config_file = _get_bash_config_file()
|
|
382
|
+
start_marker, end_marker = _get_bash_markers()
|
|
383
|
+
|
|
384
|
+
if not os.path.exists(config_file):
|
|
385
|
+
PrettyOutput.print(
|
|
386
|
+
"未找到 JSS bash completion 配置,无需卸载", OutputType.INFO
|
|
387
|
+
)
|
|
388
|
+
return
|
|
389
|
+
|
|
390
|
+
with open(config_file, "r") as f:
|
|
391
|
+
content = f.read()
|
|
392
|
+
|
|
393
|
+
if start_marker not in content:
|
|
394
|
+
PrettyOutput.print(
|
|
395
|
+
"未找到 JSS bash completion 配置,无需卸载", OutputType.INFO
|
|
396
|
+
)
|
|
397
|
+
return
|
|
398
|
+
|
|
399
|
+
new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
|
|
400
|
+
|
|
401
|
+
with open(config_file, "w") as f:
|
|
402
|
+
f.write(new_content)
|
|
403
|
+
|
|
404
|
+
PrettyOutput.print(
|
|
405
|
+
"JSS bash completion 已卸载,请执行: source ~/.bashrc", OutputType.SUCCESS
|
|
406
|
+
)
|
|
407
|
+
elif shell == "zsh":
|
|
408
|
+
config_file = _get_zsh_config_file()
|
|
409
|
+
start_marker, end_marker = _get_zsh_markers()
|
|
410
|
+
|
|
411
|
+
if not os.path.exists(config_file):
|
|
412
|
+
PrettyOutput.print(
|
|
413
|
+
"未找到 JSS zsh completion 配置,无需卸载", OutputType.INFO
|
|
414
|
+
)
|
|
415
|
+
return
|
|
416
|
+
|
|
417
|
+
with open(config_file, "r") as f:
|
|
418
|
+
content = f.read()
|
|
419
|
+
|
|
420
|
+
if start_marker not in content:
|
|
421
|
+
PrettyOutput.print(
|
|
422
|
+
"未找到 JSS zsh completion 配置,无需卸载", OutputType.INFO
|
|
423
|
+
)
|
|
424
|
+
return
|
|
425
|
+
|
|
426
|
+
new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
|
|
427
|
+
|
|
428
|
+
with open(config_file, "w") as f:
|
|
429
|
+
f.write(new_content)
|
|
430
|
+
|
|
431
|
+
PrettyOutput.print(
|
|
432
|
+
"JSS zsh completion 已卸载,请执行: source ~/.zshrc", OutputType.SUCCESS
|
|
433
|
+
)
|
|
121
434
|
|
|
122
435
|
|
|
123
436
|
def process_request(request: str) -> Optional[str]:
|
|
@@ -148,8 +461,8 @@ def process_request(request: str) -> Optional[str]:
|
|
|
148
461
|
4. 多个命令用&&连接
|
|
149
462
|
|
|
150
463
|
# 示例
|
|
151
|
-
输入: "
|
|
152
|
-
输出:
|
|
464
|
+
输入: "显示当前目录内容"
|
|
465
|
+
输出: ls -la
|
|
153
466
|
"""
|
|
154
467
|
model.set_system_prompt(system_message)
|
|
155
468
|
|
|
@@ -169,85 +482,40 @@ def process_request(request: str) -> Optional[str]:
|
|
|
169
482
|
return None
|
|
170
483
|
|
|
171
484
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
set_config("JARVIS_PRINT_PROMPT", "false")
|
|
177
|
-
|
|
178
|
-
parser = argparse.ArgumentParser(
|
|
179
|
-
description="将自然语言要求转换为shell命令",
|
|
180
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
181
|
-
epilog="""
|
|
182
|
-
Example:
|
|
183
|
-
%(prog)s request "Find all Python files in the current directory"
|
|
184
|
-
%(prog)s install
|
|
185
|
-
""",
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
# 创建子命令解析器
|
|
189
|
-
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
190
|
-
|
|
191
|
-
# request子命令
|
|
192
|
-
request_parser = subparsers.add_parser(
|
|
193
|
-
"request", help="描述您想要执行的操作(用自然语言描述)"
|
|
194
|
-
)
|
|
195
|
-
request_parser.add_argument(
|
|
196
|
-
"request",
|
|
197
|
-
nargs="?", # 设置为可选参数
|
|
198
|
-
help="描述您想要执行的操作(用自然语言描述),如果未提供则从标准输入读取",
|
|
199
|
-
)
|
|
200
|
-
|
|
201
|
-
# install子命令
|
|
202
|
-
install_parser = subparsers.add_parser(
|
|
203
|
-
"install", help="安装JSS fish shell命令补全功能"
|
|
204
|
-
)
|
|
205
|
-
install_parser.add_argument(
|
|
206
|
-
"--shell", choices=["fish"], default="fish", help="指定shell类型(仅支持fish)"
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
# 添加uninstall子命令
|
|
210
|
-
uninstall_parser = subparsers.add_parser(
|
|
211
|
-
"uninstall", help="卸载JSS fish shell命令补全功能"
|
|
212
|
-
)
|
|
213
|
-
uninstall_parser.add_argument(
|
|
214
|
-
"--shell", choices=["fish"], default="fish", help="指定shell类型(仅支持fish)"
|
|
485
|
+
@app.command("request")
|
|
486
|
+
def request_command(
|
|
487
|
+
request: Optional[str] = typer.Argument(
|
|
488
|
+
None, help="描述您想要执行的操作(用自然语言描述),如果未提供则从标准输入读取"
|
|
215
489
|
)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
args = parser.parse_args()
|
|
219
|
-
|
|
490
|
+
):
|
|
491
|
+
"""描述您想要执行的操作(用自然语言描述)"""
|
|
220
492
|
should_run = False
|
|
221
|
-
|
|
222
|
-
# 处理install命令
|
|
223
|
-
if args.command == "install":
|
|
224
|
-
if args.shell != "fish":
|
|
225
|
-
print(f"错误: 不支持的shell类型: {args.shell}, 仅支持fish")
|
|
226
|
-
return 1
|
|
227
|
-
return install_jss_completion()
|
|
228
|
-
|
|
229
|
-
# 处理uninstall命令
|
|
230
|
-
if args.command == "uninstall":
|
|
231
|
-
if args.shell != "fish":
|
|
232
|
-
print(f"错误: 不支持的shell类型: {args.shell}, 仅支持fish")
|
|
233
|
-
return 1
|
|
234
|
-
return uninstall_jss_completion()
|
|
235
|
-
|
|
236
|
-
# 处理request命令
|
|
237
|
-
if not args.request:
|
|
493
|
+
if not request:
|
|
238
494
|
# 检查是否在交互式终端中运行
|
|
239
|
-
|
|
495
|
+
request = get_multiline_input(tip="请输入您要执行的功能:")
|
|
240
496
|
should_run = True
|
|
497
|
+
|
|
241
498
|
# 处理请求
|
|
242
|
-
command = process_request(
|
|
499
|
+
command = process_request(request)
|
|
243
500
|
|
|
244
501
|
# 输出结果
|
|
245
502
|
if command:
|
|
246
503
|
execute_command(command, should_run) # 显示并执行命令
|
|
247
|
-
return 0
|
|
248
504
|
else:
|
|
249
|
-
|
|
505
|
+
raise typer.Exit(code=1)
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def cli():
|
|
509
|
+
"""Typer application entry point"""
|
|
510
|
+
init_env("")
|
|
511
|
+
set_config("JARVIS_PRINT_PROMPT", "false")
|
|
512
|
+
app()
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
def main():
|
|
516
|
+
"""Main entry point for the script"""
|
|
517
|
+
cli()
|
|
250
518
|
|
|
251
519
|
|
|
252
520
|
if __name__ == "__main__":
|
|
253
|
-
|
|
521
|
+
main()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Jarvis统计模块
|
|
3
|
+
|
|
4
|
+
提供指标统计、数据持久化、可视化展示等功能
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from jarvis.jarvis_stats.stats import StatsManager
|
|
8
|
+
from jarvis.jarvis_stats.storage import StatsStorage
|
|
9
|
+
from jarvis.jarvis_stats.visualizer import StatsVisualizer
|
|
10
|
+
|
|
11
|
+
__all__ = ["StatsManager", "StatsStorage", "StatsVisualizer"]
|
|
12
|
+
|
|
13
|
+
__version__ = "1.0.0"
|