jarvis-ai-assistant 0.7.0__py3-none-any.whl → 0.7.8__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 +243 -139
- jarvis/jarvis_agent/agent_manager.py +5 -10
- jarvis/jarvis_agent/builtin_input_handler.py +2 -6
- jarvis/jarvis_agent/config_editor.py +2 -7
- jarvis/jarvis_agent/event_bus.py +82 -12
- jarvis/jarvis_agent/file_context_handler.py +265 -15
- jarvis/jarvis_agent/file_methodology_manager.py +3 -4
- jarvis/jarvis_agent/jarvis.py +113 -98
- jarvis/jarvis_agent/language_extractors/__init__.py +57 -0
- jarvis/jarvis_agent/language_extractors/c_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/go_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/java_extractor.py +84 -0
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +79 -0
- jarvis/jarvis_agent/language_extractors/python_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +84 -0
- jarvis/jarvis_agent/language_support_info.py +486 -0
- jarvis/jarvis_agent/main.py +6 -12
- jarvis/jarvis_agent/memory_manager.py +7 -16
- jarvis/jarvis_agent/methodology_share_manager.py +10 -16
- jarvis/jarvis_agent/prompt_manager.py +1 -1
- jarvis/jarvis_agent/prompts.py +193 -171
- jarvis/jarvis_agent/protocols.py +8 -12
- jarvis/jarvis_agent/run_loop.py +77 -14
- jarvis/jarvis_agent/session_manager.py +2 -3
- jarvis/jarvis_agent/share_manager.py +12 -21
- jarvis/jarvis_agent/shell_input_handler.py +1 -2
- jarvis/jarvis_agent/task_analyzer.py +26 -4
- jarvis/jarvis_agent/task_manager.py +11 -27
- jarvis/jarvis_agent/tool_executor.py +2 -3
- jarvis/jarvis_agent/tool_share_manager.py +12 -24
- jarvis/jarvis_agent/web_server.py +55 -20
- jarvis/jarvis_c2rust/__init__.py +5 -5
- jarvis/jarvis_c2rust/cli.py +461 -499
- jarvis/jarvis_c2rust/collector.py +45 -53
- jarvis/jarvis_c2rust/constants.py +26 -0
- jarvis/jarvis_c2rust/library_replacer.py +264 -132
- jarvis/jarvis_c2rust/llm_module_agent.py +162 -190
- jarvis/jarvis_c2rust/loaders.py +207 -0
- jarvis/jarvis_c2rust/models.py +28 -0
- jarvis/jarvis_c2rust/optimizer.py +1592 -395
- jarvis/jarvis_c2rust/transpiler.py +1722 -1064
- jarvis/jarvis_c2rust/utils.py +385 -0
- jarvis/jarvis_code_agent/build_validation_config.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +394 -320
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +4 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +17 -2
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +36 -4
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +12 -1
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +22 -5
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +57 -32
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +62 -6
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +8 -9
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +290 -5
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +21 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +72 -4
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +35 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +212 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +254 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +52 -2
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +73 -1
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +306 -152
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +193 -18
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +18 -8
- jarvis/jarvis_code_agent/lint.py +258 -27
- jarvis/jarvis_code_agent/utils.py +0 -1
- jarvis/jarvis_code_analysis/code_review.py +19 -24
- jarvis/jarvis_data/config_schema.json +53 -26
- jarvis/jarvis_git_squash/main.py +4 -5
- jarvis/jarvis_git_utils/git_commiter.py +44 -49
- jarvis/jarvis_mcp/sse_mcp_client.py +20 -27
- jarvis/jarvis_mcp/stdio_mcp_client.py +11 -12
- jarvis/jarvis_mcp/streamable_mcp_client.py +15 -14
- jarvis/jarvis_memory_organizer/memory_organizer.py +55 -74
- jarvis/jarvis_methodology/main.py +32 -48
- jarvis/jarvis_multi_agent/__init__.py +79 -61
- jarvis/jarvis_multi_agent/main.py +3 -7
- jarvis/jarvis_platform/base.py +469 -199
- jarvis/jarvis_platform/human.py +7 -8
- jarvis/jarvis_platform/kimi.py +30 -36
- jarvis/jarvis_platform/openai.py +65 -27
- jarvis/jarvis_platform/registry.py +26 -10
- jarvis/jarvis_platform/tongyi.py +24 -25
- jarvis/jarvis_platform/yuanbao.py +31 -42
- jarvis/jarvis_platform_manager/main.py +66 -77
- jarvis/jarvis_platform_manager/service.py +8 -13
- jarvis/jarvis_rag/cli.py +49 -51
- jarvis/jarvis_rag/embedding_manager.py +13 -18
- jarvis/jarvis_rag/llm_interface.py +8 -9
- jarvis/jarvis_rag/query_rewriter.py +10 -21
- jarvis/jarvis_rag/rag_pipeline.py +24 -27
- jarvis/jarvis_rag/reranker.py +4 -5
- jarvis/jarvis_rag/retriever.py +28 -30
- jarvis/jarvis_sec/__init__.py +220 -3520
- jarvis/jarvis_sec/agents.py +143 -0
- jarvis/jarvis_sec/analysis.py +276 -0
- jarvis/jarvis_sec/cli.py +29 -6
- jarvis/jarvis_sec/clustering.py +1439 -0
- jarvis/jarvis_sec/file_manager.py +427 -0
- jarvis/jarvis_sec/parsers.py +73 -0
- jarvis/jarvis_sec/prompts.py +268 -0
- jarvis/jarvis_sec/report.py +83 -4
- jarvis/jarvis_sec/review.py +453 -0
- jarvis/jarvis_sec/utils.py +499 -0
- jarvis/jarvis_sec/verification.py +848 -0
- jarvis/jarvis_sec/workflow.py +7 -0
- jarvis/jarvis_smart_shell/main.py +38 -87
- jarvis/jarvis_stats/cli.py +1 -1
- jarvis/jarvis_stats/stats.py +7 -7
- jarvis/jarvis_stats/storage.py +15 -21
- jarvis/jarvis_tools/clear_memory.py +3 -20
- jarvis/jarvis_tools/cli/main.py +20 -23
- jarvis/jarvis_tools/edit_file.py +1066 -0
- jarvis/jarvis_tools/execute_script.py +42 -21
- jarvis/jarvis_tools/file_analyzer.py +6 -9
- jarvis/jarvis_tools/generate_new_tool.py +11 -20
- jarvis/jarvis_tools/lsp_client.py +1552 -0
- jarvis/jarvis_tools/methodology.py +2 -3
- jarvis/jarvis_tools/read_code.py +1525 -87
- jarvis/jarvis_tools/read_symbols.py +2 -3
- jarvis/jarvis_tools/read_webpage.py +7 -10
- jarvis/jarvis_tools/registry.py +370 -181
- jarvis/jarvis_tools/retrieve_memory.py +20 -19
- jarvis/jarvis_tools/rewrite_file.py +105 -0
- jarvis/jarvis_tools/save_memory.py +3 -15
- jarvis/jarvis_tools/search_web.py +3 -7
- jarvis/jarvis_tools/sub_agent.py +17 -6
- jarvis/jarvis_tools/sub_code_agent.py +14 -16
- jarvis/jarvis_tools/virtual_tty.py +54 -32
- jarvis/jarvis_utils/clipboard.py +7 -10
- jarvis/jarvis_utils/config.py +98 -63
- jarvis/jarvis_utils/embedding.py +5 -5
- jarvis/jarvis_utils/fzf.py +8 -8
- jarvis/jarvis_utils/git_utils.py +81 -67
- jarvis/jarvis_utils/input.py +24 -49
- jarvis/jarvis_utils/jsonnet_compat.py +465 -0
- jarvis/jarvis_utils/methodology.py +33 -35
- jarvis/jarvis_utils/utils.py +245 -202
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/METADATA +205 -70
- jarvis_ai_assistant-0.7.8.dist-info/RECORD +218 -0
- jarvis/jarvis_agent/edit_file_handler.py +0 -584
- jarvis/jarvis_agent/rewrite_file_handler.py +0 -141
- jarvis/jarvis_agent/task_planner.py +0 -496
- jarvis/jarvis_platform/ai8.py +0 -332
- jarvis/jarvis_tools/ask_user.py +0 -54
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +0 -192
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.8.dist-info}/top_level.txt +0 -0
jarvis/jarvis_utils/input.py
CHANGED
|
@@ -13,7 +13,6 @@ import sys
|
|
|
13
13
|
import base64
|
|
14
14
|
from typing import Iterable, List, Optional
|
|
15
15
|
import wcwidth
|
|
16
|
-
|
|
17
16
|
from colorama import Fore
|
|
18
17
|
from colorama import Style as ColoramaStyle
|
|
19
18
|
from fuzzywuzzy import process
|
|
@@ -35,11 +34,9 @@ from prompt_toolkit.layout.containers import Window
|
|
|
35
34
|
from prompt_toolkit.layout.controls import FormattedTextControl
|
|
36
35
|
from prompt_toolkit.layout.layout import Layout
|
|
37
36
|
from prompt_toolkit.styles import Style as PromptStyle
|
|
38
|
-
|
|
39
37
|
from jarvis.jarvis_utils.clipboard import copy_to_clipboard
|
|
40
38
|
from jarvis.jarvis_utils.config import get_data_dir, get_replace_map
|
|
41
39
|
from jarvis.jarvis_utils.globals import get_message_history
|
|
42
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
43
40
|
from jarvis.jarvis_utils.tag import ot
|
|
44
41
|
|
|
45
42
|
# Sentinel value to indicate that Ctrl+O was pressed
|
|
@@ -54,9 +51,8 @@ FZF_REQUEST_ALL_SENTINEL_PREFIX = "__FZF_REQUEST_ALL__::"
|
|
|
54
51
|
# Persistent hint marker for multiline input (shown only once across runs)
|
|
55
52
|
_MULTILINE_HINT_MARK_FILE = os.path.join(get_data_dir(), "multiline_enter_hint_shown")
|
|
56
53
|
|
|
57
|
-
|
|
58
54
|
def _display_width(s: str) -> int:
|
|
59
|
-
"""
|
|
55
|
+
"""计算字符串在终端中的可打印宽度(处理宽字符)。"""
|
|
60
56
|
try:
|
|
61
57
|
w = 0
|
|
62
58
|
for ch in s:
|
|
@@ -69,11 +65,10 @@ def _display_width(s: str) -> int:
|
|
|
69
65
|
except Exception:
|
|
70
66
|
return len(s)
|
|
71
67
|
|
|
72
|
-
|
|
73
68
|
def _calc_prompt_rows(prev_text: str) -> int:
|
|
74
69
|
"""
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
估算上一个提示占用了多少终端行数。
|
|
71
|
+
考虑提示前缀和跨终端列的软换行。
|
|
77
72
|
"""
|
|
78
73
|
try:
|
|
79
74
|
cols = os.get_terminal_size().columns
|
|
@@ -102,17 +97,15 @@ def _calc_prompt_rows(prev_text: str) -> int:
|
|
|
102
97
|
total_rows += rows
|
|
103
98
|
return max(1, total_rows)
|
|
104
99
|
|
|
105
|
-
|
|
106
100
|
def _multiline_hint_already_shown() -> bool:
|
|
107
|
-
"""
|
|
101
|
+
"""检查是否已显示过多行输入提示(持久化存储)。"""
|
|
108
102
|
try:
|
|
109
103
|
return os.path.exists(_MULTILINE_HINT_MARK_FILE)
|
|
110
104
|
except Exception:
|
|
111
105
|
return False
|
|
112
106
|
|
|
113
|
-
|
|
114
107
|
def _mark_multiline_hint_shown() -> None:
|
|
115
|
-
"""
|
|
108
|
+
"""持久化存储多行输入提示已显示的状态。"""
|
|
116
109
|
try:
|
|
117
110
|
os.makedirs(os.path.dirname(_MULTILINE_HINT_MARK_FILE), exist_ok=True)
|
|
118
111
|
with open(_MULTILINE_HINT_MARK_FILE, "w", encoding="utf-8") as f:
|
|
@@ -121,7 +114,6 @@ def _mark_multiline_hint_shown() -> None:
|
|
|
121
114
|
# Non-critical persistence failure; ignore to avoid breaking input flow
|
|
122
115
|
pass
|
|
123
116
|
|
|
124
|
-
|
|
125
117
|
def get_single_line_input(tip: str, default: str = "") -> str:
|
|
126
118
|
"""
|
|
127
119
|
获取支持历史记录的单行输入。
|
|
@@ -133,7 +125,6 @@ def get_single_line_input(tip: str, default: str = "") -> str:
|
|
|
133
125
|
prompt = FormattedText([("class:prompt", f"👤 > {tip}")])
|
|
134
126
|
return session.prompt(prompt, default=default, style=style)
|
|
135
127
|
|
|
136
|
-
|
|
137
128
|
def get_choice(tip: str, choices: List[str]) -> str:
|
|
138
129
|
"""
|
|
139
130
|
提供一个可滚动的选择列表供用户选择。
|
|
@@ -229,7 +220,6 @@ def get_choice(tip: str, choices: List[str]) -> str:
|
|
|
229
220
|
except (KeyboardInterrupt, EOFError):
|
|
230
221
|
return ""
|
|
231
222
|
|
|
232
|
-
|
|
233
223
|
class FileCompleter(Completer):
|
|
234
224
|
"""
|
|
235
225
|
带有模糊匹配的文件路径自定义补全器。
|
|
@@ -375,7 +365,6 @@ def _get_current_agent_for_input():
|
|
|
375
365
|
except Exception:
|
|
376
366
|
pass
|
|
377
367
|
return None
|
|
378
|
-
|
|
379
368
|
def _is_non_interactive_for_current_agent() -> bool:
|
|
380
369
|
try:
|
|
381
370
|
from jarvis.jarvis_utils.config import is_non_interactive
|
|
@@ -386,7 +375,6 @@ def _is_non_interactive_for_current_agent() -> bool:
|
|
|
386
375
|
return bool(is_non_interactive())
|
|
387
376
|
except Exception:
|
|
388
377
|
return False
|
|
389
|
-
|
|
390
378
|
def _is_auto_complete_for_current_agent() -> bool:
|
|
391
379
|
try:
|
|
392
380
|
from jarvis.jarvis_utils.config import GLOBAL_CONFIG_DATA
|
|
@@ -402,7 +390,6 @@ def _is_auto_complete_for_current_agent() -> bool:
|
|
|
402
390
|
return bool(GLOBAL_CONFIG_DATA.get("JARVIS_AUTO_COMPLETE", False))
|
|
403
391
|
except Exception:
|
|
404
392
|
return False
|
|
405
|
-
|
|
406
393
|
def user_confirm(tip: str, default: bool = True) -> bool:
|
|
407
394
|
"""提示用户确认是/否问题(按当前Agent优先判断非交互)"""
|
|
408
395
|
try:
|
|
@@ -414,16 +401,15 @@ def user_confirm(tip: str, default: bool = True) -> bool:
|
|
|
414
401
|
except KeyboardInterrupt:
|
|
415
402
|
return False
|
|
416
403
|
|
|
417
|
-
|
|
418
404
|
def _show_history_and_copy():
|
|
419
405
|
"""
|
|
420
|
-
|
|
421
|
-
|
|
406
|
+
显示消息历史记录并处理复制到剪贴板。
|
|
407
|
+
此函数使用标准I/O,可在提示会话之外安全调用。
|
|
422
408
|
"""
|
|
423
409
|
|
|
424
410
|
history = get_message_history()
|
|
425
411
|
if not history:
|
|
426
|
-
|
|
412
|
+
print("ℹ️ 没有可复制的消息")
|
|
427
413
|
return
|
|
428
414
|
|
|
429
415
|
# 为避免 PrettyOutput 在循环中为每行加框,先拼接后统一打印
|
|
@@ -435,8 +421,8 @@ def _show_history_and_copy():
|
|
|
435
421
|
(cleaned_msg[:70] + "...") if len(cleaned_msg) > 70 else cleaned_msg
|
|
436
422
|
)
|
|
437
423
|
lines.append(f" {i + 1}: {display_msg.strip()}")
|
|
438
|
-
|
|
439
|
-
|
|
424
|
+
lines.append("=" * 58 + "\n")
|
|
425
|
+
print("ℹ️ " + "\n".join(lines))
|
|
440
426
|
|
|
441
427
|
while True:
|
|
442
428
|
try:
|
|
@@ -445,11 +431,11 @@ def _show_history_and_copy():
|
|
|
445
431
|
|
|
446
432
|
if not choice_str: # User pressed Enter
|
|
447
433
|
if not history:
|
|
448
|
-
|
|
434
|
+
print("ℹ️ 没有历史记录可供选择。")
|
|
449
435
|
break
|
|
450
436
|
choice = len(history) - 1
|
|
451
437
|
elif choice_str.lower() == "c":
|
|
452
|
-
|
|
438
|
+
print("ℹ️ 已取消")
|
|
453
439
|
break
|
|
454
440
|
else:
|
|
455
441
|
choice = int(choice_str) - 1
|
|
@@ -457,19 +443,16 @@ def _show_history_and_copy():
|
|
|
457
443
|
if 0 <= choice < len(history):
|
|
458
444
|
selected_msg = history[choice]
|
|
459
445
|
copy_to_clipboard(selected_msg)
|
|
460
|
-
|
|
461
|
-
f"已复制消息: {selected_msg[:70]}...", OutputType.SUCCESS
|
|
462
|
-
)
|
|
446
|
+
print(f"✅ 已复制消息: {selected_msg[:70]}...")
|
|
463
447
|
break
|
|
464
448
|
else:
|
|
465
|
-
|
|
449
|
+
print("⚠️ 无效的序号,请重试。")
|
|
466
450
|
except ValueError:
|
|
467
|
-
|
|
451
|
+
print("⚠️ 无效的输入,请输入数字。")
|
|
468
452
|
except (KeyboardInterrupt, EOFError):
|
|
469
|
-
|
|
453
|
+
print("\nℹ️ 操作取消")
|
|
470
454
|
break
|
|
471
455
|
|
|
472
|
-
|
|
473
456
|
def _get_multiline_input_internal(
|
|
474
457
|
tip: str, preset: Optional[str] = None, preset_cursor: Optional[int] = None
|
|
475
458
|
) -> str:
|
|
@@ -489,10 +472,7 @@ def _get_multiline_input_internal(
|
|
|
489
472
|
first_enter_hint_shown = True
|
|
490
473
|
|
|
491
474
|
def _show_notice():
|
|
492
|
-
|
|
493
|
-
"提示:当前支持多行输入。输入完成请使用 Ctrl+J 确认;Enter 仅用于换行。",
|
|
494
|
-
OutputType.INFO,
|
|
495
|
-
)
|
|
475
|
+
print("ℹ️ 提示:当前支持多行输入。输入完成请使用 Ctrl+J 确认;Enter 仅用于换行。")
|
|
496
476
|
try:
|
|
497
477
|
input("按回车继续...")
|
|
498
478
|
except Exception:
|
|
@@ -692,7 +672,6 @@ def _get_multiline_input_internal(
|
|
|
692
672
|
except (KeyboardInterrupt, EOFError):
|
|
693
673
|
return ""
|
|
694
674
|
|
|
695
|
-
|
|
696
675
|
def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
697
676
|
"""
|
|
698
677
|
获取带有增强补全和确认功能的多行输入。
|
|
@@ -771,9 +750,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
771
750
|
import subprocess
|
|
772
751
|
|
|
773
752
|
if shutil.which("fzf") is None:
|
|
774
|
-
|
|
775
|
-
"未检测到 fzf,无法打开文件选择器。", OutputType.WARNING
|
|
776
|
-
)
|
|
753
|
+
print("⚠️ 未检测到 fzf,无法打开文件选择器。")
|
|
777
754
|
else:
|
|
778
755
|
files = []
|
|
779
756
|
try:
|
|
@@ -802,7 +779,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
802
779
|
break
|
|
803
780
|
|
|
804
781
|
if not files:
|
|
805
|
-
|
|
782
|
+
print("ℹ️ 未找到可选择的文件。")
|
|
806
783
|
else:
|
|
807
784
|
try:
|
|
808
785
|
specials = [
|
|
@@ -846,7 +823,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
846
823
|
if sel:
|
|
847
824
|
selected_path = sel
|
|
848
825
|
except Exception as e:
|
|
849
|
-
|
|
826
|
+
print(f"❌ FZF 执行失败: {e}")
|
|
850
827
|
|
|
851
828
|
# Compute new text based on selection (or keep original if none)
|
|
852
829
|
if selected_path:
|
|
@@ -904,9 +881,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
904
881
|
import subprocess
|
|
905
882
|
|
|
906
883
|
if shutil.which("fzf") is None:
|
|
907
|
-
|
|
908
|
-
"未检测到 fzf,无法打开文件选择器。", OutputType.WARNING
|
|
909
|
-
)
|
|
884
|
+
print("⚠️ 未检测到 fzf,无法打开文件选择器。")
|
|
910
885
|
else:
|
|
911
886
|
files = []
|
|
912
887
|
try:
|
|
@@ -927,7 +902,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
927
902
|
files = []
|
|
928
903
|
|
|
929
904
|
if not files:
|
|
930
|
-
|
|
905
|
+
print("ℹ️ 未找到可选择的文件。")
|
|
931
906
|
else:
|
|
932
907
|
try:
|
|
933
908
|
specials = [
|
|
@@ -971,7 +946,7 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
971
946
|
if sel:
|
|
972
947
|
selected_path = sel
|
|
973
948
|
except Exception as e:
|
|
974
|
-
|
|
949
|
+
print(f"❌ FZF 执行失败: {e}")
|
|
975
950
|
|
|
976
951
|
# Compute new text based on selection (or keep original if none)
|
|
977
952
|
if selected_path:
|
|
@@ -1025,5 +1000,5 @@ def get_multiline_input(tip: str, print_on_empty: bool = True) -> str:
|
|
|
1025
1000
|
continue
|
|
1026
1001
|
else:
|
|
1027
1002
|
if not user_input and print_on_empty:
|
|
1028
|
-
|
|
1003
|
+
print("ℹ️ 输入已取消")
|
|
1029
1004
|
return user_input
|