mirror of
https://gitcode.com/JianFeeeee/TrulyMEM-TrueHumanMEM.git
synced 2026-09-21 17:38:18 +00:00
多用户系统 + Admin 角色权限 + Web/TUI 同步 + 构建集成
本轮实现功能: 1. 多用户隔离:每个用户独立 config.json + graph.db 2. TUI 登录页 + 旧版自动迁移(core/migrate.py) 3. Admin/User 角色体系(core/embedded_db.py) 4. Web 后台管理 API(userinfo + admin CRUD) 5. Web 设置页用户管理区(仅 admin 可见) 6. TUI 侧栏配置区权限同步(非 admin 隐藏 Web 服务设置) 7. Web 服务打包为独立二进制(trulymem-web) 8. 双入口 PyInstaller 构建脚本(TUI + Web) 9. 活动记录器(core/activity_recorder.py) 10. 静态页面模板(登录/设置/首次引导)
This commit is contained in:
@ -12,7 +12,9 @@ APPDIR="$PROJECT_ROOT/TrulyMEM.AppDir"
|
||||
rm -rf "$APPDIR"
|
||||
mkdir -p "$APPDIR/usr/bin"
|
||||
mkdir -p "$APPDIR/usr/share/trulymem"
|
||||
echo "===== Step 1: Build binary with PyInstaller ====="
|
||||
mkdir -p "$APPDIR/usr/share/trulymem-web"
|
||||
|
||||
echo "===== Step 1: Build binaries with PyInstaller ====="
|
||||
VENV_DIR="$PROJECT_ROOT/.venv_appimage"
|
||||
rm -rf "$VENV_DIR"
|
||||
python3 -m venv "$VENV_DIR"
|
||||
@ -21,16 +23,33 @@ pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
rm -rf "$PROJECT_ROOT/build/pyinstaller_build" "$PROJECT_ROOT/dist"
|
||||
echo "Running PyInstaller..."
|
||||
|
||||
CORE_HIDDEN=(
|
||||
--hidden-import core
|
||||
--hidden-import core.embedded_db
|
||||
--hidden-import core.graph_client
|
||||
--hidden-import core.tool_executor
|
||||
--hidden-import core.tool_limiter
|
||||
--hidden-import core.tools
|
||||
--hidden-import core.tools.memory_tools
|
||||
--hidden-import core.prompts
|
||||
--hidden-import core.prompts.prompt_manager
|
||||
--hidden-import core.server
|
||||
--hidden-import core.client
|
||||
--hidden-import core.migrate
|
||||
--hidden-import core.activity_recorder
|
||||
)
|
||||
|
||||
echo "Running PyInstaller for TUI..."
|
||||
pyinstaller trulymem_entry.py \
|
||||
--clean \
|
||||
--onefile \
|
||||
--console \
|
||||
--name TrulyMEM \
|
||||
--clean --onefile --console --name TrulyMEM \
|
||||
--distpath "$PROJECT_ROOT/dist" \
|
||||
--workpath "$PROJECT_ROOT/build/pyinstaller_build" \
|
||||
--workpath "$PROJECT_ROOT/build/pyinstaller_build/tui" \
|
||||
--add-data "ui/styles:ui/styles" \
|
||||
--add-data "core/prompts/templates:core/prompts/templates" \
|
||||
--add-data "static:static" \
|
||||
--add-data "templates:templates" \
|
||||
--add-data "web_api.py:." \
|
||||
--hidden-import textual \
|
||||
--hidden-import textual.app \
|
||||
--hidden-import textual.widgets \
|
||||
@ -39,17 +58,10 @@ pyinstaller trulymem_entry.py \
|
||||
--hidden-import openai._client \
|
||||
--hidden-import neo4j \
|
||||
--hidden-import sqlite3 \
|
||||
--hidden-import core \
|
||||
--hidden-import core.embedded_db \
|
||||
--hidden-import core.graph_client \
|
||||
--hidden-import core.tool_executor \
|
||||
--hidden-import core.tool_limiter \
|
||||
--hidden-import core.tools \
|
||||
--hidden-import core.tools.memory_tools \
|
||||
--hidden-import core.prompts \
|
||||
--hidden-import core.prompts.prompt_manager \
|
||||
"${CORE_HIDDEN[@]}" \
|
||||
--hidden-import ui \
|
||||
--hidden-import ui.app \
|
||||
--hidden-import ui.login_screen \
|
||||
--hidden-import ui.models \
|
||||
--hidden-import ui.models.message \
|
||||
--hidden-import ui.models.config \
|
||||
@ -59,10 +71,28 @@ pyinstaller trulymem_entry.py \
|
||||
--hidden-import ui.services \
|
||||
--hidden-import ui.services.config_manager \
|
||||
--hidden-import ui.services.config_service \
|
||||
--hidden-import web_api \
|
||||
--hidden-import flask \
|
||||
--hidden-import flask_cors \
|
||||
--collect-all textual \
|
||||
--noconfirm
|
||||
|
||||
echo "Running PyInstaller for Web..."
|
||||
pyinstaller web_api.py \
|
||||
--clean --onefile --console --name trulymem-web \
|
||||
--distpath "$PROJECT_ROOT/dist" \
|
||||
--workpath "$PROJECT_ROOT/build/pyinstaller_build/web" \
|
||||
--add-data "templates:templates" \
|
||||
--add-data "static:static" \
|
||||
--hidden-import flask \
|
||||
--hidden-import flask_cors \
|
||||
"${CORE_HIDDEN[@]}" \
|
||||
--noconfirm
|
||||
|
||||
cp "$PROJECT_ROOT/dist/TrulyMEM" "$APPDIR/usr/bin/"
|
||||
cp "$PROJECT_ROOT/dist/trulymem-web" "$APPDIR/usr/bin/"
|
||||
cp "$PROJECT_ROOT/trulymem_entry.py" "$APPDIR/usr/share/trulymem/"
|
||||
|
||||
echo "===== Step 2: Create AppImage structure ====="
|
||||
cat > "$APPDIR/AppRun" << 'EOF'
|
||||
#!/bin/bash
|
||||
@ -73,6 +103,7 @@ export PATH="$APPDIR/usr/bin:$PATH"
|
||||
exec "$APPDIR/usr/bin/TrulyMEM" "$@"
|
||||
EOF
|
||||
chmod +x "$APPDIR/AppRun"
|
||||
|
||||
cat > "$APPDIR/trulymem.desktop" << 'EOF'
|
||||
[Desktop Entry]
|
||||
Name=TrulyMEM
|
||||
@ -83,7 +114,8 @@ Terminal=true
|
||||
Type=Application
|
||||
Categories=Utility;X-AI;
|
||||
EOF
|
||||
# Copy icon file (try multiple possible locations)
|
||||
|
||||
# Copy icon
|
||||
if [ -f "$PROJECT_ROOT/pic/TrulyMEM.png" ]; then
|
||||
cp "$PROJECT_ROOT/pic/TrulyMEM.png" "$APPDIR/trulymem.png"
|
||||
elif [ -f "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_256x256.png" ]; then
|
||||
@ -91,13 +123,12 @@ elif [ -f "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_256x256.png" ]; then
|
||||
elif [ -f "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_128x128.png" ]; then
|
||||
cp "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_128x128.png" "$APPDIR/trulymem.png"
|
||||
else
|
||||
echo "Warning: No icon file found, creating placeholder"
|
||||
# Create a simple placeholder icon
|
||||
convert -size 256x256 xc:blue "$APPDIR/trulymem.png" 2>/dev/null || \
|
||||
echo "Note: Install ImageMagick to generate placeholder icon"
|
||||
echo "Warning: No icon file found"
|
||||
fi
|
||||
|
||||
APPIMAGE="$PROJECT_ROOT/TrulyMEM.AppImage"
|
||||
rm -f "$APPIMAGE"
|
||||
|
||||
echo "===== Step 3: Package as AppImage ====="
|
||||
cd /tmp
|
||||
if ! command -v appimagetool &> /dev/null; then
|
||||
@ -108,30 +139,23 @@ if ! command -v appimagetool &> /dev/null; then
|
||||
fi
|
||||
cd "$PROJECT_ROOT"
|
||||
if [ -x /tmp/appimagetool ]; then
|
||||
/tmp/appimagetool "$APPDIR" "$APPIMAGE" || {
|
||||
echo "appimagetool failed, keeping AppDir for manual packaging"
|
||||
}
|
||||
/tmp/appimagetool "$APPDIR" "$APPIMAGE" || echo "appimagetool failed, keeping AppDir"
|
||||
elif command -v appimagetool &> /dev/null; then
|
||||
appimagetool "$APPDIR" "$APPIMAGE"
|
||||
else
|
||||
echo "Warning: appimagetool not available"
|
||||
echo "AppDir created at: $APPDIR"
|
||||
echo "You can manually run: appimagetool $APPDIR $APPIMAGE"
|
||||
echo "Warning: appimagetool not available, AppDir at: $APPDIR"
|
||||
fi
|
||||
|
||||
echo "===== Build Complete ====="
|
||||
[ -f "$APPIMAGE" ] && echo "AppImage: $APPIMAGE" && ls -la "$APPIMAGE"
|
||||
[ -d "$APPDIR" ] && echo "AppDir: $APPDIR (can be packaged manually with appimagetool)"
|
||||
echo "===== Cleaning up build artifacts ====="
|
||||
[ -d "$APPDIR" ] && echo "AppDir: $APPDIR"
|
||||
|
||||
echo "===== Cleanup ====="
|
||||
deactivate
|
||||
rm -rf "$VENV_DIR"
|
||||
rm -rf "$PROJECT_ROOT/build/pyinstaller_build"
|
||||
rm -rf "$PROJECT_ROOT/build/pyinstaller_build"
|
||||
rm -f /tmp/appimagetool
|
||||
# Only remove AppDir if AppImage was successfully created
|
||||
if [ -f "$APPIMAGE" ]; then
|
||||
echo "Removing AppDir since AppImage was created successfully"
|
||||
rm -rf "$APPDIR"
|
||||
else
|
||||
echo "Keeping AppDir for manual packaging"
|
||||
fi
|
||||
echo "Done!"
|
||||
echo "Done!"
|
||||
|
||||
Reference in New Issue
Block a user