Metadata-Version: 2.4
Name: ue-prism
Version: 1.1.1
Summary: 面向 Unreal Engine 项目的 MCP 诊断服务器（日志 / 性能 / 引用，结构化只读）
Author: Za0Shu1
License: MIT
Project-URL: Homepage, https://github.com/Za0Shu1/ue-prism
Project-URL: Repository, https://github.com/Za0Shu1/ue-prism
Project-URL: Issues, https://github.com/Za0Shu1/ue-prism/issues
Project-URL: Documentation, https://github.com/Za0Shu1/ue-prism/blob/main/docs/SETUP.md
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp<3,>=2
Requires-Dist: tomli>=1.1.0; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

# ue-prism

> 把 Unreal 项目像棱镜一样分光解析——日志、性能开销、资产引用，交给 AI agent 逐条检验。

**ue-prism** 是一个面向 Unreal Engine 项目的 MCP（Model Context Protocol）诊断服务器：让 AI agent 读取并分析**编辑器/cook/package 日志**（报错归因）、**场景性能与资产开销**（优化建议）、**资产引用链**（迁移决策），所有结果结构化返回、机器可读。

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
![UE](https://img.shields.io/badge/UE-5.0%20%E2%80%93%205.8%2B-blue)
![状态](https://img.shields.io/badge/状态-v1.1-brightgreen)

> 当前进度：**v1.0 已交付**。v0.1 连通链路 → v0.2 cook/package → v0.3 性能静态规则引擎（`get_perf_report` 7 规则、`get_asset_metrics` 度量，5.4/5.8 校准一致）→ **v1.0**：连接发现（零配置 · bridge 自注册 · 全工具 `project=` 选择器 · `list_projects`）、引用链分析（`get_asset_chain` 递归 `uses`/`used_by` 闭包，按类聚合数量/体量）、迁移套件（写操作 `migrate_asset_rename`/`_move`/`_asset`〔A·同工程复制依赖闭包〕，双钥 dry_run + 成功后自动清理 redirector 桩）、发布（GitHub Releases 已就绪 · `release.yml`；PyPI 走 Trusted Publishing 待注册免费账号 · `publish.yml` 由 `PYPI_PUBLISH` 变量开关））、一条命令安装器（`prism setup --client`，幂等/可卸载/`--dry-run`）+ `server.json` 注册清单。UE 5.4.4 真机实证完毕。**v1.1 增量**：bridge 打包成**免编译 UE 插件**（`prism plugin-install --project`，`init_unreal.py` 自启、跨 5.0–5.8、UE 5.3.2/5.4.4 双版本真机实证）、`project=` 选择器优先于默认 pin、工程名按 `.uproject` 主干名取（消除按文件夹命名的歧义）。共 **18 工具、139 测试**（其中 1 项需真机在线桥）。详细需求与验收见 [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)。

## 为什么要做这个

UE 5.8 随引擎发布了实验性官方 MCP 插件（ModelContextProtocol + AllToolsets），但实测与社区反馈暴露了系统性缺陷。ue-prism 的每一条设计都是它的反面：

| 官方插件的问题 | ue-prism 的对策 |
|---|---|
| 失败以 `Ok` 文本返回，agent 无法判别成败 | 统一结构化错误信封，错误绝不伪装成成功 |
| 无就绪握手，早期拿到残缺工具表 | `ping` 握手，先确认编辑器在线 |
| 52+ toolset 数百函数，lazy 发现、schema 巨大 | ≤20 个扁平工具，签名全在文档里 |
| 静默截断（列表限 20 条不提示） | 所有列表携带 `total / truncated / cap` |
| 绑定 5.8 Experimental API，随版本漂移 | 只依赖 `unreal` Python API + 纯标准库传输，5.0–5.8+ 通吃 |

**默认只读。** 写操作（cook、迁移改名/移动）一律 dry-run 预览 + 双钥确认（`dry_run=False` 且 `confirm=True`）才落盘。

## 架构

```
 Claude Code / Cursor / opencode
        │  stdio (MCP)
        ▼
 prism server (Python 3.10+，不碰任何引擎 API)
        │  文件总线：cmd_*.json ⇄ res_*.json
        ▼
 bridge (UE 编辑器内 Python，主线程 tick 轮询)
        │  白名单函数分发
        ▼
 domain/*.py  ── 纯 `unreal` API + 标准库
 （日志分析 / 资产扫描 / 场景清单 / 引用查询）
```

文件总线刻意做得"无聊"：原子 rename、无 socket、无线程，编辑器崩溃不拖累外部进程，任何带 Python 插件的引擎版本都能用。轮询放在**主线程 tick**（UE 5.6+ 禁止在非 game thread 调用 `unreal`）。bridge 顺带限频写一个仅含时间戳的心跳标记，客户端据此对"编辑器已关/主线程停摆"立即快速失败，不再空等 30s 超时；超时崩溃残留的孤儿命令/响应文件会被自动清扫。将来可无痛替换为 socket/HTTP。

## 仓库结构

```text
prism/
├── server.py          # 协议层：MCP 工具（18 个），绝不 import unreal
├── bridge.py          # 传输层：编辑器内白名单分发 + 信封透传 + v1.0 自注册指针
├── registry.py        # v1.0 连接发现：固定目录指针写/读 + 现场心跳新鲜度
├── autostart.py       # v1.0 pip 安装后 UE 侧一行自启（随包发布，无需 sys.path）
├── pluginpack.py      # v1.1 免编译 UE 插件打包：从已装 prism 拷贝引擎侧闭包，组装 UEPrism 插件树
├── bus.py             # 文件总线：原子写 / 心跳标记 / 孤儿清扫
├── envelope.py        # 统一信封与错误码（三层通用，纯标准库）
├── tasks.py           # v0.2 任务登记表：惰性状态推导 / BUSY 互斥
├── uat.py             # v0.2 UAT 定位与提交：引擎路由 / 命令模板 / 跨重启合成
├── attributelog.py    # v0.2 日志→资产归因：指纹分组 / 磁盘解析 / 批量富化
├── rules.py             # v0.3 规则引擎：profile/TOML 阈值 + 7 规则 + 报告聚合
├── logscan.py         # read_editor_log 离线聚合
├── folderscan.py      # scan_folder_assets 离线审计
└── domain/            # 领域层：ping / actors / assets / metrics（含 describe_many、
                       #   referencers_many 批量函数），纯 unreal + 标准库，守 3.7 子集
scripts/               # autostart_bridge.py + verify_connection.py / verify_migration.py + CLI 手测
tests/                 # 123 项无引擎测试（总线/任务/cook/归因/规则引擎/扫描 + 连接发现 / 引用链 / 迁移）
docs/                  # SETUP.md（操作）· REQUIREMENTS.md（契约单一事实源）· DESIGN_v0.2.md
.github/workflows/     # CI：push/PR 跑 pytest（3.10 / 3.12 矩阵）
```

## 工具（18 个：只读诊断/引用链 + 双钥确认的 cook / 迁移 + 规则报告 + 连接发现）

经 bridge（需编辑器在线）：

| 工具 | 说明 |
|---|---|
| `ping` | bridge 心跳、UE 版本、工程路径、已加载地图 |
| `list_level_actors` | 场景清单：类名/标签过滤、transform、组件数 |
| `describe_asset` | 单资产元数据：类、包路径、磁盘大小、脏标记 |
| `get_asset_references` | 双向引用：`uses`(依赖) / `used_by`(被引用)，可递归、限量 |

离线（不依赖编辑器，读磁盘）：

| 工具 | 说明 |
|---|---|
| `read_editor_log` | 日志聚合：Error/Warning 分组、计数、首现时间、样本 |
| `scan_folder_assets` | 目录资产审计：按大小排序、类型汇总、Top 开销元凶 |

外部进程（server 侧调 UAT，编辑器须关闭；首个非只读工具族）：

| 工具 | 说明 |
|---|---|
| `cook_package` | 触发 cook/package；**默认 dry-run，`dry_run=False`+`confirm=True` 双钥才执行**；同工程 BUSY 互斥 |
| `get_cook_status` | 任务状态**读时惰性推导**（done 标记/硬时限/pid/日志收束行），无守护进程 |
| `attribute_cook_errors` | 日志→资产归因：指纹分组 + 磁盘解析；桥在线时 `describe_many`/`referencers_many` 批量富化 |

性能规则（v0.3 · 混合通道：桥在线出全量、离线自动半份并逐条注明 skip）：

| 工具 | 说明 |
|---|---|
| `get_perf_report` | 静态性能健康报告：7 规则（资产大小/纹理尺寸/网格三角+单LOD/光源重复/WP 外部 actor 数/cook 静默丢弃/cook 空煮），top-80 大资产抽样度量 |
| `list_perf_rules` | 当前 profile 生效规则与阈值（可解释性入口；pc/console/mobile 三档 + 工程 prism.toml 覆盖） |
| `get_asset_metrics` | 批量原语度量：纹理 px / 网格 LOD 三角，带 `tried` API 证据链（5.4/5.8 双版本校准） |

连接发现 · 引用链 · 迁移（v1.0 · 去硬编码路径 + 依赖闭包分析 + 写操作）：

| 工具 | 说明 |
|---|---|
| `list_projects` | 零配置枚举已注册工程 + 活跃态（`live`/`heartbeat_age`）；供 agent 先探后用 |
| `get_asset_chain` | 递归依赖闭包（迁移分析）：`uses`=要带走的全部 `/Game` 依赖（带类别/磁盘大小，`by_class` 聚合体量）；`used_by`=谁依赖它；`scope=game` 默认滤引擎噪声 |
| `preview_asset_migration` | 只读迁移预览：源/目标冲突检测 + `used_by` 影响面 → dry-run 计划（目标仅剩改名遗留的 `ObjectRedirector` 桩时不算冲突） |
| `migrate_asset_rename` | 真改名（写 · 双钥）：走 `rename_asset(pkg,pkg)` 自动修引用，成功后默认清一次重定向桩 |
| `migrate_asset_move` | 真移动（写 · 双钥）：移动到目录，可带 new_name 同时改名，默认清桩 |
| `migrate_asset` | 迁移 A·同工程复制（写 · 双钥）：把资产 + 其 `/Game` `uses` 闭包镜像复制到目标目录；默认 dry-run 出复制计划（按类数量/体量/冲突）；原件不动 |

所有桥 / 离线 / cook / 迁移工具接受可选 `project=` 选择器；未配置工程路径时按判定阶梯自动定位（详见 REQUIREMENTS §3.5）。

## 快速开始

> v0.1/v0.2 均已跑通。完整操作（`pip` 安装 / UE 开机自启 / Codex·opencode 配置 / cook 双钥）见 [docs/SETUP.md](docs/SETUP.md)；设计契约见 [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)。下面是最小三步速览（`<REPO>`=仓库绝对路径、`<PROJ>`=UE 工程根，均用正斜杠）。

```bash
# 1. 安装 server
pip install git+https://github.com/Za0Shu1/ue-prism.git   # 现在即可用（GitHub Releases 也已就绪）
# pip install ue-prism   # PyPI：注册免费账号 + 配 Trusted Publishing 后启用（见 docs/SETUP.md §7）

# 2. 编辑器自启（推荐）：在工程 Config/DefaultEngine.ini 注册一次后，重开编辑器即自动起 bridge：
#    [/Script/PythonScriptPlugin.PythonScriptPluginSettings]
#    +StartupScripts="<REPO>/scripts/autostart_bridge.py"
#    手动兜底（Output Log 的 [PY] 控制台）：
import sys; sys.path.insert(0, r"<REPO>")
import prism.bridge; prism.bridge.start(r"<PROJ>/Saved/Prism")

# 3. 在 MCP 客户端注册（一条命令幂等写入、零工程路径；v1.0 bridge 自注册后 server 自动发现）：
prism setup --client codex        # 或 opencode / cursor / claude / claude-code / all；--dry-run 预览、--uninstall 移除
#    等价手写：command: python -m prism.server   （或装包后 ue-prism）
#    多工程时 agent 先 list_projects 探测、或调用时传 project=<工程名>
#    （仍可钉死单工程：加 env PRISM_BUS_DIR=<PROJ>/Saved/Prism  PRISM_PROJECT_DIR=<PROJ>）
```

先问 agent 一句验证连通：*"你现在连上的是哪个 UE 项目？里面加载了哪些地图？"*
接入日志工具后，可试：*"把最近编辑器日志里的 Error/Warning 归类，指出可疑原因。"*
cook 回路（关编辑器、双钥）可试：*"先 dry-run 看看 cook 会跑什么命令"* → *"确认执行"* → *"把这次 cook 的报错归因到资产"*

## 路线图

- **v0.1**（已发布 · v0.1.0）：三层骨架 + 文件总线 + `ping` 端到端连通 + 结构化错误契约 + UE 5.4 实测 + 6 只读工具 + bridge 编辑器开机自启
- **v0.2**（已发布 · v0.2.0，v0.2.1 已清尾）：cook/package 全回路真机实证完毕 —— cook 容错三坑、package 25s/786MB 一次通过、5.8 版式（`PRISM_ENGINE_ROOT`）同工程通过、失败注入还原闭环
- **v0.3**（已发布 · v0.3.0）：性能静态规则引擎（7 规则全来自真机案例；纹理/网格度量 5.4 与 5.8 校准一致；桥离线自动半份报告）
- **v1.0**（已发布 PyPI · 当前 1.0.1；1.0.0 建议 yank）：连接发现（零配置/自注册/`project=` 选择器）+ 引用链分析（`get_asset_chain` 传递闭包）+ 迁移套件（rename/move/copy 写操作，双钥 + redirector 自动清理）；UE 5.4.4 真机实证完毕
- 之后：bridge 打包成正式 UE 插件、socket 传输、Epic 官方 5.8 toolset 可选后端、截图验证工具

## 运行要求

- Unreal Engine 5.0+，启用 Python Editor Scripting（launcher 安装自带）
- 编辑器侧：引擎内嵌 Python 随 UE 版本 3.7→3.11（domain 层守 3.7 语法子集）
- server 侧：Python ≥3.10 + MCP Python SDK（锁 2.x），无引擎依赖

## 本机真机测试（UE 5.4）

- 工程目录：`F:/UE_Projects/TestProject/UE_PRISM_Project`（已在 DefaultEngine.ini 注册 bridge 自启；5.4.4 与 5.8.2 双版本真机验证过）
- 文件总线目录：`<工程>/Saved/Prism`（含 `heartbeat.json` 活性标记与 `tasks/` 任务档案）
- ue-prism 仓库：`F:/VibeCoding/ue-prism`；server 侧解释器：`F:/venv/Scripts/python.exe`

**1) 双击打开工程（EngineAssociation=5.4）**——bridge 已由 StartupScripts 自启，Output Log 出现 `[prism] bridge started` 即在线；`<工程>/Saved/Prism/heartbeat.json` 应每秒级更新。

**2) 另开系统终端，从总线外部验证连通与快速失败：**
```powershell
F:\venv\Scripts\python.exe F:\VibeCoding\ue-prism\scripts\ping_cli.py "F:/UE_Projects/TestProject/UE_PRISM_Project/Saved/Prism"
```
期望：`ok:true`；关编辑器再戳 → 约 1s 内 `BRIDGE_UNREACHABLE`（心跳陈旧），不再空等 30s。

**3) cook 回路（关闭编辑器后；细则见 docs/SETUP.md §4）：**
```powershell
F:\venv\Scripts\python.exe -m prism.server --project-dir F:\UE_Projects\TestProject\UE_PRISM_Project
# 或在 agent 里：cook_package() 干跑 -> cook_package(dry_run=False, confirm=True) -> get_cook_status(task_id)
```

**4) 可选——无头探针（unreal API 名跨版本校核）：**
```powershell
& "E:\UnrealEngine\UE_5.4\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" `
  "F:\UE_Projects\TestProject\UE_PRISM_Project\UE_PRISM_Project.uproject" `
  -run=pythonscript -script="F:\VibeCoding\ue-prism\scripts\probe_unreal.py"
```
## 相关项目

- [chongdashu/unreal-mcp](https://github.com/chongdashu/unreal-mcp)、[IvanMurzak/Unreal-MCP](https://github.com/IvanMurzak/Unreal-MCP) —— 侧重编辑器**操控**；ue-prism 侧重**诊断与分析**
- Epic 官方 `ModelContextProtocol` 插件（UE 5.8）—— 原生但实验性；ue-prism 覆盖 5.0–5.8 行为一致

## 设计文档

需求、契约与决策记录见 [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)；设计草案：[v0.2 cook 全回路](docs/DESIGN_v0.2.md)（已实现并真机实证）· [v0.3 性能静态规则引擎](docs/DESIGN_v0.3.md)（评审中）。

## License

MIT © [Za0Shu1](https://github.com/Za0Shu1)

---

Unreal® 与 Unreal Engine® 为 Epic Games, Inc. 注册商标。本项目与 Epic Games 无关联，亦未获其背书。
