FaceLink
# FaceLink
[](https://github.com/xuebazhou-blip/FaceLink/actions/workflows/python-ci.yml)
[](https://github.com/xuebazhou-blip/FaceLink/releases)
[](LICENSE)
FaceLink turns a constrained shot description into **editable Blender scene animation**.
It is aimed at previs/white-model work: actors, props and cameras remain ordinary Blender
objects with ordinary keyframes, so artists can drag, retime and override the result.
FaceLink is not a text-to-video generator and does not give an LLM unrestricted Python
execution. The model produces a typed `ShotSpec`; FaceLink validates it, compiles it into a
small whitelist of patch operations, stages a human-readable review in Blender, and changes
the scene only after the artist presses **Apply Staged Patch**.
## Demo
[](docs/assets/facelink-demo.mp4)
This four-second demo is rendered from the included
[editable `.blend` scene](docs/assets/facelink-demo.blend). The movement was applied through
FaceLink's real patch executor and remains 24 ordinary editable keyframe values—not a generated
video baked outside Blender.
## Current MVP
- scans the open Blender scene and gives objects stable FaceLink IDs;
- compiles `move_to`, `turn_to`, `look_at`, `wait` and `play_clip` beats;
- creates/updates editable transforms, keyframes, cameras and tracking constraints;
- plans transforms in world space and converts them for parented Blender objects;
- exposes the workflow through an MCP server for Codex/ChatGPT-compatible MCP clients;
- supports OpenAI API-key planning with Structured Outputs;
- runs a localhost-only authenticated bridge between the MCP process and Blender;
- supports Blender-side stage/review/apply/discard, persistent audit history and safe
rollback to a selected current-session revision.
- persists a bounded, payload-free task lifecycle journal for explicit startup recovery and
never replays interrupted work automatically;
- adds a bounded Blender task/recovery center for connection state, queue progress, queued-job
cancellation, recent outcomes and privacy-safe startup guidance;
- negotiates local bridge protocol 1.12/1.13 explicitly and attaches request/correlation IDs
to jobs and stable errors for cross-layer troubleshooting;
- exposes an authenticated, bounded diagnostic endpoint and a separate privacy-safe local JSON
export without automatic upload;
- rejects internally overlapping transform/action timelines, warns before overwriting
existing keyframes and rejects colliding FaceLink NLA clips;
- previews staged world-space motion paths and predicted camera frustums directly in the
Blender viewport without creating scene datablocks;
- scans explicitly marked navigation meshes and obstacles, plans deterministic multi-segment
locomotion paths, and warns when an actor's swept bounds intersect a marked obstacle;
- fingerprints the complete navigation environment so a newly added obstacle or edited
navigation mesh invalidates an already staged plan;
- inventories armature bone hierarchies and editable Blender Actions, including pose-bone
channels, rest orientations, frame ranges and deterministic content fingerprints;
- suggests review-only bone maps using deterministic name normalization, then measures mapped
hierarchy, local rest axes and scale-normalized bone proportions before execution;
- copies compatible Actions through an open `rename_only` bone-map profile, rewrites editable
FCurve paths, places the result in NLA, and removes created copies during rollback;
- samples reviewed `bake_pose` profiles into ordinary editable target Actions, correcting
different local rest axes and bone scale with explicit root-motion policy and bounded work;
- evaluates existing self-contained source-rig constraints and drivers with
`bake_evaluated_pose`, then bakes the final deform-bone pose into an ordinary editable Action;
- optionally transfers Armature object root motion as a placement-preserving relative delta,
with source-unit or rig-scale-adjusted translation;
- predicts the staged camera frame without creating scene datablocks, measuring target size,
center offset, safe-area fit, clipping and center-point occlusion before the artist applies;
- rejects a staged plan when a referenced transform, parent link, lock or scene timing value
changed after the scene scan.
## Blender 任务与恢复中心(开发分支)
打开 **3D 视图 → 侧边栏 → FaceLink**,点击 **Start Bridge** 后,顶部会显示当前连接、
队列、活动任务和最近结果。展开 **Tasks** 可以取消仍在排队的任务;运行中的任务不会被
异步强杀,只能在安全检查点协作式停止。由于 Blender 场景操作同步占用主线程,长任务
运行时面板按钮可能无法及时响应,运行中取消目前主要由独立 MCP/HTTP 客户端发起。
界面显示 **Local bridge ready** 只表示本机 Blender 桥接已就绪,不表示 AI、Codex 账号
或 API Key 已连接。
如果上一次 Blender 会话异常中断,面板会要求先检查场景、历史并重新扫描。点击
**I Reviewed** 只确认用户看过恢复提示,不会重放、应用、撤销或回滚任何任务。打开其他
`.blend`、未保存文件首次保存或 **Save As** 改变路径时,桥接会停止并要求为当前文件
重新启动,防止继续写入旧工作区日志。
恢复确认以前,Blender UI 会禁用应用暂存、撤销和历史回滚;本机 HTTP 还会拒绝上述
三类以及直接应用,返回 `recovery_review_required` 且不创建任务。扫描和读取等检查
操作仍可使用。
这一切片不包含 Blender 内的 Codex/ChatGPT 订阅登录或 API Key 表单,也不会读取
Codex 的 `auth.json`。完整状态、取消、恢复、文件切换和隐私边界见
[Blender 任务与恢复中心](docs/TASK_CENTER.md)。
## Supported Blender versions
- Primary: Blender **4.5 LTS** (tested with 4.5.12)
- Minimum: Blender **4.2 LTS**
- Best effort: Blender 5.x
The Blender 4.0.2 installation found on the development machine predates the extension
baseline. FaceLink's source can still be loaded there for smoke testing, but 4.0 is not a
declared supported version.
桥接协议、数据结构和升级/降级并不跟产品版本共用一个编号。当前未发布代码的桥接协议
为 1.13,只明确兼容 1.12 和 1.13;详见
[兼容性与迁移政策](docs/COMPATIBILITY.md)。
## Install the alpha release
Download `FaceLink-Setup-0.3.9.exe` from the
[FaceLink 0.3.9 Alpha release](https://github.com/xuebazhou-blip/FaceLink/releases/tag/v0.3.9),
open it, choose **Check setup**, then **Install FaceLink**.
This alpha EXE is not yet code-signed, so Windows SmartScreen may show an unknown-publisher
warning. Verify it against the release `SHA256SUMS.txt` before choosing **More info → Run
anyway**, and only use files downloaded from the official FaceLink release page.

FaceLink does **not** bundle Blender. It detects an existing official Blender 4.2-or-newer
installation, which keeps the release small and lets each artist choose Blender 4.5 LTS or a
newer compatible version. If Blender is missing, install it from the
[official Blender LTS page](https://www.blender.org/download/lts/).
The graphical installer contains the FaceLink host, extension, checksum manifest and safe
PowerShell backend in one small EXE. It verifies the embedded files, detects Python and Blender,
installs both FaceLink components, and safely configures the shared local ChatGPT Desktop/Codex
MCP file. It does not request administrator access or store an API key.
For a manual Windows install, keep the four raw release files together and run:
```powershell
.\install-windows.ps1 `
-WheelPath .\facelink-0.3.9-py3-none-any.whl `
-ExtensionZipPath .\facelink-0.3.9.zip `
-ChecksumsPath .\SHA256SUMS.txt
```
The script verifies the release hashes, finds Python 3.11+ and Blender 4.2+, creates an
isolated FaceLink host, installs the extension and configures the exact `facelink-mcp.exe` path.
Pass `-PlanOnly` to inspect every resolved path without installing anything. Pass
`-BlenderExe C:\path\to\blender.exe` when Blender is portable or not on a conventional path.
Pass `-SkipMcpConfiguration` to leave the local MCP configuration untouched.
For an existing FaceLink extension, update it from Blender Preferences or remove the old
version before running the extension-install step.
After starting FaceLink's bridge in Blender, validate the complete setup:
```powershell
facelink doctor --blender-exe C:\path\to\blender.exe
```
Doctor 不打印 API Key 或 Blender 桥接 Bearer Token;缺少 API Key 只是警告,因为 MCP
客户端可以使用自己的模型。不过 Doctor 面向本机排错,仍可能显示 Blender、MCP 启动器
和发现目录的绝对路径,不应原样公开分享。需要生成支持附件时使用:
```powershell
facelink diagnostics --out facelink-diagnostics.json
```
该命令只在本地原子写出最多 1 MiB 的单个 JSON,默认不覆盖已有文件,也不会自动上传。
它通过严格允许列表排除绝对路径、场景/对象/骨骼/Action 名称、brief/prompt、请求
payload/result、原始异常、Token、API Key 和私钥;只保留版本、能力、计数、状态、稳定
错误码及随机关联编号。分享前仍应人工打开检查。隐私边界见
[威胁模型](docs/THREAT_MODEL.md)。
To install the two components manually, continue below.
In Blender 4.2 or newer, open **Edit → Preferences → Get Extensions → Install from Disk**,
select `facelink-0.3.9.zip`, enable FaceLink, open the **FaceLink** tab in the 3D Viewport
sidebar and press **Start Bridge**.
Install the Python host in an isolated Python 3.11-or-newer environment:
```powershell
py -3.11 -m venv .venv
.\.venv\Scripts\python -m pip install .\facelink-0.3.9-py3-none-any.whl
.\.venv\Scripts\facelink-mcp
```
Use `SHA256SUMS.txt` from the release to verify every downloaded artifact. Continue below for
MCP client configuration and the safe stage/review/apply workflow.
## Install for development
```powershell
git clone https://github.com/xuebazhou-blip/FaceLink.git
cd FaceLink
$env:UV_CACHE_DIR = Join-Path $PWD '.cache\uv'
uv sync --extra dev
uv run pytest
```
For the reproducible multi-version acceptance matrix, including real extension installation:
```powershell
./scripts/run_acceptance.ps1
```
The harness writes JUnit, coverage, per-Blender JSON and command logs below `artifacts/`.
See [docs/TESTING.md](docs/TESTING.md) for the exact gates and known exclusions.
Build the Blender extension:
```powershell
$env:FACELINK_BLENDER_EXE='C:\path\to\Blender\blender.exe' # optional if on PATH
./scripts/build_extension.ps1
```
Then in Blender 4.5: **Edit → Preferences → Get Extensions → Install from Disk**, choose
`dist/facelink-0.3.9.zip`, enable FaceLink, and open the **FaceLink** tab in the 3D Viewport
sidebar. Press **Start Bridge**.
Run the MCP server:
```powershell
uv run facelink-mcp
```
Safely create or update the shared local ChatGPT Desktop/Codex configuration:
```powershell
$projectRoot = (Resolve-Path .).Path
uv run facelink configure-mcp `
--mcp-launcher (Join-Path $projectRoot '.venv\Scripts\facelink-mcp.exe') `
--instance-dir (Join-Path $projectRoot '.facelink\instances')
```
FaceLink backs up an existing `~/.codex/config.toml`, preserves unrelated settings and owns
only its clearly marked block. The resulting OpenAI-compatible configuration is TOML:
```toml
[mcp_servers.facelink]
command = "C:\\path\\to\\FaceLink\\.venv\\Scripts\\facelink-mcp.exe"
enabled = true
[mcp_servers.facelink.env]
FACELINK_INSTANCE_DIR = "C:\\path\\to\\FaceLink\\.facelink\\instances"
```
The ChatGPT desktop app, Codex CLI and Codex IDE extension share this local configuration.
ChatGPT on the web does not read local MCP configuration and would require a separately hosted
plugin. See the [official OpenAI MCP documentation](https://developers.openai.com/codex/mcp/).
The same `FACELINK_INSTANCE_DIR` is set for future Blender processes; restart Blender and the
MCP client after installation.
With an MCP client, the safe default sequence is:
1. `scan_scene`
2. turn the user's natural-language request into a typed shot and call `preview_shot`
3. call `stage_scene_patch`
4. let the user inspect the summary in Blender and press **Apply Staged Patch** or **Discard**
This path uses the model already available in the MCP client; FaceLink itself needs no API
key. `apply_scene_patch` remains available as an explicit power-user bypass.
## BYOK planning
```powershell
$env:OPENAI_API_KEY='your-key'
uv run facelink plan --brief "Cube walks to Marker in 2 seconds, camera follows Cube" `
--snapshot scene.json --out shot.json
```
Or scan the running Blender scene, plan, compile and stage the result in one command:
```powershell
$env:OPENAI_API_KEY='your-key'
uv run facelink workflow `
--brief "Cube walks to Marker in 2 seconds, camera follows Cube"
```
The command does not apply anything. Review and approve the staged result in Blender.
To make an existing Action target a compatible armature whose bone names differ, pass a
reviewed open profile:
```powershell
uv run facelink validate-profile `
--profile profiles/mixamo_to_facelink_compact.json
uv run facelink suggest-profile `
--snapshot scene.json --source-rig source-armature-id `
--target-rig target-armature-id --action "Mixamo Walk" `
--name "Reviewed map" --out suggestion.json
uv run facelink analyze-profile `
--profile profiles/mixamo_to_facelink_compact.json `
--snapshot scene.json --source-rig source-armature-id `
--target-rig target-armature-id --out compatibility.json
uv run facelink plan `
--brief "Apply Mixamo Walk to the target rig for two seconds" `
--snapshot scene.json `
--retarget-profile profiles/mixamo_to_facelink_compact.json `
--out shot.json
```
Suggestions are never applied automatically and always carry `review_required: true`. The
compatibility result is `safe`, `review`, `bake_required` or `incompatible`. The compiler
blocks `rename_only` when hierarchy, rest orientation or proportions require baking. FaceLink
fingerprints both Actions and referenced rigs, so curve or rest-pose edits after scanning fail
before mutation; it also blocks unscaled pose-bone translation channels across differently
sized rigs. Generated Actions and NLA strips remain ordinary editable Blender data. See
[profiles/README.md](profiles/README.md) and
[examples/retargeted_clip_shot.json](examples/retargeted_clip_shot.json).
When analysis says `bake_required` because local rest axes or rig scale differ, change the
reviewed profile to `adapter: "bake_pose"`, set its explicit `source_rig`, and optionally set
`sample_step` (1-16) and `root_motion` (`scale`, `preserve` or `drop`). FaceLink samples the
source Action's native frame range, writes linear location/rotation/scale keys to a normal
target Action, and puts it in the same editable NLA workflow. Object-level Action channels are
omitted unless `object_motion` is explicit; otherwise root motion must be on a mapped root pose
bone. This first adapter requires equivalent
mapped parent hierarchy and unconstrained source/target deform bones. See
[profiles/mixamo_to_facelink_compact_bake.json](profiles/mixamo_to_facelink_compact_bake.json)
and [examples/baked_retargeted_clip_shot.json](examples/baked_retargeted_clip_shot.json).
When the source Action animates controller bones or custom properties and the source deform
bones receive their final motion through constraints/drivers, use
`adapter: "bake_evaluated_pose"`. The reviewed `bone_map` maps source deform bones—not the
controller channels—to target deform bones. Version 1 permits only dependencies on the same
source armature object/data, rejects external helper objects and scene-driven variables, and
still requires equivalent mapped parent hierarchy plus unconstrained/undriven target bones.
It does not discover controllers or convert IK/FK systems automatically. See
[profiles/controller_to_deform_evaluated_bake.json](profiles/controller_to_deform_evaluated_bake.json)
and [examples/evaluated_retargeted_clip_shot.json](examples/evaluated_retargeted_clip_shot.json).
If overall character movement lives on the source Armature object, add
`object_motion: "preserve"` or `"scale"` to either bake adapter. FaceLink uses the source
object's transform relative to its first sampled frame, applies that delta after the target's
current world transform, and writes ordinary object location/rotation/scale FCurves into the
same generated Action. `scale` multiplies delta translation by the mapped-rig median length
ratio; `preserve` keeps source units. Version 1 requires unparented source/target Armatures with
no object constraints or driven target object transforms. See
[profiles/object_motion_bake.json](profiles/object_motion_bake.json) and
[examples/object_motion_clip_shot.json](examples/object_motion_clip_shot.json).
Inspect or roll back FaceLink revisions from the command line:
```powershell
uv run facelink history
uv run facelink rollback --revision rev-0123456789abcdef
```
Revision metadata is stored in the `.blend` file. Executable rollback snapshots intentionally
remain session-only because they contain live Blender datablock references. Rolling back an
older revision also rolls back every newer FaceLink revision to preserve a linear scene state.
An API key is optional when an MCP client performs the language-model planning itself.
ChatGPT subscriptions and OpenAI API billing are separate; a ChatGPT membership is not an
API key. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the trust boundary.
使用 BYOK 规划时,FaceLink 会把用户 brief、序列化 Scene Snapshot 和可选重定向配置发给
所配置的 OpenAI 兼容端点;这些内容可能包含场景、对象、骨骼、Action 名称和变换。
API Key 不会进入 `.blend`、任务日志或安全诊断包,但远端提供商、代理及自定义
`base_url` 的数据政策仍由用户负责审查。MCP 客户端也可能按自身政策把工具输入/输出
发送给其模型提供商。
## Navigation workflow
Select a walkable mesh and use **FaceLink → Navigation → Navmesh**. Select walls, props or
other blocking objects and mark them as **Obstacle**. A `move_to` beat keeps the legacy
straight line by default; set `path_mode` to `navmesh` to route through connected navigation
triangles. The compiler distributes ordinary editable location keyframes by path distance
and forces linear interpolation so curved handles cannot leave the walkable corridor.
Navigation is deliberately explicit. FaceLink does not guess from object names or silently
treat every mesh as an obstacle. Current v0.3.0 planning is projected onto XY and is intended
for single-level previs floors; stacked floors, live moving obstacles and crowd routing are
not yet supported. See [examples/navmesh_walk_shot.json](examples/navmesh_walk_shot.json).
## Camera composition preflight
Camera shots with a target are checked during staging. FaceLink projects the target's
world-space bounds into the predicted camera frame and reports clipping, unsafe margins,
subject size and center offset. A read-only Blender ray cast reports when another object blocks
the target center. `dolly_in` checks both its start and end positions. Thresholds are typed in
`camera.composition`, remain visible in the ShotSpec and can be disabled explicitly. See
[examples/composition_checked_shot.json](examples/composition_checked_shot.json).
This is a deterministic preflight, not an artistic quality score. It does not render, use a
vision model, judge lighting or guarantee that every part of a complex subject is unoccluded.
Version 0.3.3 evaluates perspective cameras without lens shift and reports other projection
types as unsupported instead of returning misleading metrics.
## Repository map
```text
src/facelink/ Core schemas, compiler, bridge client, providers, CLI and MCP server
blender_extension/ Zero-dependency Blender extension and local bridge
schemas/ Portable JSON Schema for integrations
examples/ Example editable shot specifications
tests/ Unit tests and a Blender headless smoke test
scripts/ Build and verification scripts
docs/ Architecture, protocol and development notes
```
## Project status
Version 0.3.9 is a creator-review alpha, not yet a production animation system. It performs
bounded transform-aware pose baking for reviewed mappings and can evaluate existing constraints
and drivers when every dependency stays on the explicit source armature. It can also transfer
unparented, unconstrained Armature-object motion without moving the target's starting placement.
It does not infer controllers, translate IK/FK systems, follow external helper objects, solve
different mapped parent hierarchies, handle parented/constrained object roots, synthesize missing
motion or judge the visual result. Multi-level navigation,
multi-shot sequencing and visual diff overlays remain follow-up work.
The Windows release now has a single-file graphical installer, safe local MCP configuration,
a secret-safe environment doctor and a reproducible real-Blender demo. Before promoting this
alpha more broadly, test installation with non-developer users and complete Linux/macOS
installation coverage.
## License
FaceLink is free software licensed under
[GNU GPL version 3 or any later version](LICENSE). The Blender extension distribution includes
the same license text.
TDQS
Scored across 17 tools
The tools are largely separated by lifecycle stage and resource type, such as validate, preview, stage, apply, and rollback. A couple of pairs, like validate_retarget_profile vs analyze_retarget_profile and apply_staged_patch vs apply_scene_patch, are close enough to require careful reading, but the descriptions do distinguish them.
Most tools follow a clean action_object snake_case pattern like list_, get_, validate_, stage_, apply_, and discard_. facelink_health breaks the pattern as a noun phrase, and rollback_to_revision uses a preposition instead of a direct object, but these are minor deviations.
17 tools is slightly above the typical 3-15 range, but the server covers several distinct workflow areas: instance health, retargeting, shots, staged patches, and revisions. The count is reasonable for the scope, though it could be tightened.
The set covers the core safety-oriented lifecycle: scan, validate, preview, stage, review, apply, and rollback. Obvious minor gaps exist, such as no Blender job submission/cancellation and no explicit apply/save for retarget profiles, but agents can work around them via scene patches and external job submission.