chore: 整理插件分类 - 删除图像类,移动娱乐类

删除(图像类):
- ai_image.py (AI生图)
- image_generator.py (ComfyUI生图)
- send_image.py (远程发图)

移至插件仓库(娱乐/可选):
- color_picker.py
- bookmark_manager.py
- audio_player.py

保留24个必备生产力插件:
核心: code_editor/git_tools/file_manager/cmd_executor/terminal
工程: auto_engineer/frontend_tester/workflow/sub_agent
搜索: ai_search/tool_search/network_tools
自动化: browser_auto/gui_auto
数据: json_toolkit/regex_tester/markdown_tool/id_generator/snippet_manager
系统: scheduler/task_manager/memory_plugin/operit_bridge/speech_recognition

更新 README.md/plugin_registry.json/plugins_config.py
This commit is contained in:
xiaoli-cli bot committed 2026-06-23 09:25:25 +00:00
1 parent 5ea19b75ae
commit 125e00a485
10 files changed
+194 -2425

No files matched your search

+130 -180
View File
@@ -1,229 +1,179 @@
"""终端模拟器插件测试"""
"""终端模拟器 v2 测试"""
import os
import sys
import time
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from plugins.terminal import Liugin, TerminalSession
from plugins.terminal import Liugin, Terminal
def test_basic_open_close():
"""打开和关闭终端"""
p = Liugin()
r = p.handle("open")
assert "✓" in r
assert "s1" in r or "main" in r
assert "已打开" in r
r = p.handle("list")
assert "终端" in r
assert "main" in r
r = p.handle("close")
assert "✓" in r
assert "已关闭" in r
r = p.handle("list")
assert "暂无" in r
assert "无终端" in r
print("✓ test_basic_open_close")
def test_send_command():
"""发送命令并获取输出"""
def test_type_and_enter():
p = Liugin()
p.handle("open")
r = p.handle("send echo hello_world")
assert "hello_world" in r, f"期望 hello_world,实际: {r}"
r = p.handle("send echo 42")
assert "42" in r
p.handle("close")
print("✓ test_send_command")
def test_cwd():
"""切换目录"""
p = Liugin()
p.handle("open")
r = p.handle("cwd /tmp")
assert "✓" in r
r = p.handle("send pwd")
assert "/tmp" in r
p.handle("close")
print("✓ test_cwd")
def test_env():
"""环境变量"""
p = Liugin()
p.handle("open")
r = p.handle("env MY_TEST_VAR hello123")
assert "✓" in r
r = p.handle("send echo $MY_TEST_VAR")
assert "hello123" in r
p.handle("close")
print("✓ test_env")
def test_multiple_sessions():
"""多会话管理"""
p = Liugin()
p.handle("open bash session1")
p.handle("open bash session2")
r = p.handle("list")
assert "2 个" in r
# 第一个会话是 main
p.handle("send echo AAA") # 当前是 s2,发给 s2
p.handle("switch main")
p.handle("send echo BBB") # 发给 main
r = p.handle("close main")
assert "✓" in r
r = p.handle("list")
assert "1 个" in r
p.handle("close s2")
print("✓ test_multiple_sessions")
def test_keys():
"""特殊按键"""
p = Liugin()
p.handle("open")
r = p.handle("keys")
assert "ctrl+c" in r
# 发送 Ctrl+C(不应该报错)
r = p.handle("keys ctrl+c")
assert "←" in r
p.handle("close")
print("✓ test_keys")
def test_input():
"""纯文本输入"""
p = Liugin()
p.handle("open")
p.handle("send cat << 'EOF'")
p.handle("input line1")
p.handle("input line2")
p.handle("input EOF")
p.handle("close")
print("✓ test_input")
def test_status():
"""状态查询"""
p = Liugin()
p.handle("open")
r = p.handle("status")
assert "终端状态" in r
assert "运行中" in r
p.handle("close")
print("✓ test_status")
def test_read_output():
"""读取输出"""
p = Liugin()
p.handle("open")
p.handle("send echo AAA")
p.handle("send echo BBB")
p.handle("send echo CCC")
p.handle("type echo hello_v2")
p.handle("key enter")
time.sleep(0.5)
r = p.handle("read")
# read 返回最近一次 send_cmd 的结果
assert "CCC" in r, f"read 结果: {r[:100]}"
assert "hello_v2" in r
p.handle("close")
print("✓ test_read_output")
print("✓ test_type_and_enter")
def test_last_n():
p = Liugin()
p.handle("open")
for i in range(10):
p.handle(f"type echo line_{i}")
p.handle("key enter")
time.sleep(0.15)
time.sleep(0.5)
r = p.handle("last 3")
assert "line_9" in r
# last 3 不应该包含 line_0
assert "line_0" not in r
p.handle("close")
print("✓ test_last_n")
def test_read_shortcut():
"""read 5 等同 last 5"""
p = Liugin()
p.handle("open")
p.handle("type echo aaa")
p.handle("key enter")
time.sleep(0.3)
p.handle("type echo bbb")
p.handle("key enter")
time.sleep(0.3)
r = p.handle("read 5")
assert "bbb" in r
p.handle("close")
print("✓ test_read_shortcut")
def test_env_persist():
p = Liugin()
p.handle("open")
p.handle("type export MYVAR=hello")
p.handle("key enter")
time.sleep(0.3)
p.handle("type echo val=$MYVAR")
p.handle("key enter")
time.sleep(0.5)
r = p.handle("read")
assert "val=hello" in r
p.handle("close")
print("✓ test_env_persist")
def test_python_repl():
"""Python REPL 交互"""
p = Liugin()
p.handle("open python3 Python-REPL")
import time; time.sleep(1)
# REPL 用 input 发送(不触发哨兵),用 read 拿输出
p.handle('input print(2 + 3)')
time.sleep(0.8)
r = p.handle('read')
assert "5" in r, f"Python REPL 输出: {r[:200]}"
p.handle("open python3")
time.sleep(1)
p.handle("type print(2+3)")
p.handle("key enter")
time.sleep(0.5)
r = p.handle("read")
assert "5" in r
p.handle("close")
print("✓ test_python_repl")
def test_session_persistence():
"""会话持久性 — 环境变量在命令间保持"""
def test_ctrl_c():
p = Liugin()
p.handle("open")
p.handle("send export FOO=bar123")
r = p.handle("send echo $FOO")
assert "bar123" in r, f"环境变量未保持: {r}"
p.handle("send cd /var")
r = p.handle("send pwd")
assert "/var" in r, f"目录未保持: {r}"
p.handle("type python3 -c 'import time; time.sleep(99)'")
p.handle("key enter")
time.sleep(0.5)
p.handle("key ctrl+c")
time.sleep(0.3)
# 终端应该还活着
r = p.handle("list")
assert "●" in r
p.handle("close")
print("✓ test_session_persistence")
print("✓ test_ctrl_c")
def test_auto_create_session():
"""无会话时自动创建"""
def test_multi_session():
p = Liugin()
# 不 open,直接 send
r = p.handle("send echo auto_created")
assert "auto_created" in r
p.handle("open")
p.handle("open python3")
r = p.handle("list")
assert "main" in r
assert "s2" in r
p.handle("switch main")
p.handle("type echo from_bash")
p.handle("key enter")
time.sleep(0.3)
r = p.handle("read")
assert "from_bash" in r
p.handle("close s2")
p.handle("close main")
print("✓ test_multi_session")
def test_cwd():
p = Liugin()
p.handle("open")
p.handle("type cd /tmp")
p.handle("key enter")
time.sleep(0.3)
p.handle("type pwd")
p.handle("key enter")
time.sleep(0.5)
r = p.handle("read")
assert "/tmp" in r
p.handle("close")
print("✓ test_auto_create_session")
print("✓ test_cwd")
def test_long_output():
"""长输出处理"""
p = Liugin()
p.handle("open")
# 生成长输出
r = p.handle("send seq 1 200")
assert "200" in r or "1" in r
p.handle("type seq 1 100")
p.handle("key enter")
time.sleep(1)
r = p.handle("last 5")
assert "100" in r
p.handle("close")
print("✓ test_long_output")
def test_auto_create():
"""不 open 直接 type,自动创建终端"""
p = Liugin()
p.handle("type echo auto")
p.handle("key enter")
time.sleep(0.5)
r = p.handle("read")
assert "auto" in r
p.handle("close")
print("✓ test_auto_create")
if __name__ == "__main__":
test_basic_open_close()
test_send_command()
test_cwd()
test_env()
test_multiple_sessions()
test_keys()
test_input()
test_status()
test_read_output()
test_type_and_enter()
test_last_n()
test_read_shortcut()
test_env_persist()
test_python_repl()
test_session_persistence()
test_auto_create_session()
test_ctrl_c()
test_multi_session()
test_cwd()
test_long_output()
print("\n🎉 全部 13 个测试通过!")
test_auto_create()
print("\n🎉 全部 11 个测试通过!")