# 🐱 SenSu 万能 Python TUI 项目管理器 — 插件化架构,任何项目都能挂载运行。 [![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE) [![Python](https://img.shields.io/badge/python-3.11%2B-blue)]() --- ## ✨ 特性 - 🎨 **Textual TUI** — 系统监控面板 + 命令补全 + CLI 回退 - 🔌 **插件系统** — 热加载、权限隔离、依赖解析、进程隔离 - 📁 **文件管理器** — 全文件系统浏览、编辑、上传、右键菜单,Windows/Linux/macOS 兼容 - 🗄️ **项目引擎** — 接管任何 Python/命令行项目 (subprocess + 日志 + stdin) - 🔀 **反向代理** — HTTP/WS 代理,本地/局域网/公网端口映射 - 📊 **SQLite 持久化** — 插件状态、权限、审计日志统一存储 - 🌐 **Web 管理面板** — aiohttp MD3 WebUI,日夜主题切换,WebSocket 实时推送 - 🔐 **安全认证** — PBKDF2-SHA256、环境变量密码 - 🐳 **Docker 部署** — Alpine 镜像,systemd 服务文件 - 🧪 **28 个回归测试** — pytest,零失败 - 🛠️ **插件 SDK** — 命令装饰器 + Web 面板 + API + SSE 推送 + 文件选择器 ## 🚀 快速开始 ```bash pip install -r requirements.txt python main.py # TUI 模式 python main.py --headless # 后台模式 (Web 面板 :4200) python -m pytest tests/ -v # 运行测试 ``` ## 🏗️ 架构 ``` main.py → SenSuFramework (15+ 服务) ├── ProjectEngine ← 接管任何项目 (subprocess + 日志) ├── ProxyService ← 反向代理 (HTTP+WS) ├── PyEnvManager ← Python 版本 + venv + git clone ├── PluginWebMixin ← 插件 Web 控制面板 SDK ├── PluginService ← 热加载 + 状态追踪 ├── SenSuDB ← SQLite 5 表 ├── TuiService ← Textual + 系统监控 ├── InternetService ← HTTP :4200 + WS :4240 └── WebPanelManager ← /SenSu 管理面板 (路由 + WS + 文件管理) ``` ## 📁 目录 ``` SenSu/ ├── main.py, service_manager.py ├── sdk/ plugin_command, plugin_status, plugin_error, plugin_web ├── services/ 15+ 核心服务 + web_panel/ (路由 + 工具) ├── bridges/ CoreBridge + PluginBridge ├── plugins/ 插件目录 + example_plugin ├── static/ MD3 CSS + JS + 页面 ├── deploy/ systemd + Dockerfile ├── tests/ 28 个测试 └── docs/ 开发文档 ``` ## 🌐 Web 面板 ``` http://0.0.0.0:4200/SenSu/ ├── /dashboard 仪表盘 (WS 实时推送 CPU/内存/网速双线图) ├── /pages/files 文件管理器 (全系统浏览/编辑/上传/右键菜单) ├── /pages/projects 项目管理 (添加/启动/Git部署) ├── /pages/proxy 反向代理管理 ├── /pages/plugins 插件管理 (启用/停用/重载) ├── /pages/logs 实时日志 (WS 推送/500行上限/批量渲染) ├── /pages/console Web 终端 └── /plugin/{name} 插件控制面板 ``` ## 🔌 插件开发 ```python from sdk.plugin_command_decorator import plugin_command from sdk.plugin_web import PluginWebMixin class Plugin(PluginWebMixin): def __init__(self, plugin_name=None, config=None, bridge=None): PluginWebMixin.__init__(self) self.plugin_name = plugin_name async def initialize(self): self.register_web_page("my_plugin", "My Panel", "

Hello

") @plugin_command(name="hello") async def cmd_hello(self, *args): return "Hello World!" ``` ## 🔧 环境变量 | 变量 | 默认值 | |------|------| | `SENSU_ADMIN_PASSWORD` | `admin123` | | `SENSU_API_PASSWORD` | `api123` | | `SENSU_PANEL_USER` | `admin` | | `SENSU_PANEL_PASS` | `admin` | ## 📄 许可证 Apache License 2.0 · Copyright 2026 AskaEth