TiXL Debug Protocol 实现指南:让外部 Agent 通过 TCP 驱动实时图形编辑器 TiXL Debug Protocol 实现指南让外部 Agent 通过 TCP 驱动实时图形编辑器【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3TiXLt3是开源实时动态图形创作软件本文围绕其内置的Debug Protocol本地调试桥展开它通过 JSON-lines over TCP 的方式让外部客户端Claude 等 LLM Agent、shell 脚本、.NET 测试运行器对运行中的编辑器拥有完整的读、写与控制访问——包括命令派发、图状态查询、日志尾读、截图、热重载与视觉回归测试。读完本文你将掌握该协议的启动方式、全部 RPC 方法的参数语义、求值模型陷阱、分阶段实施路线以及如何用它在不触碰 UI 的前提下驱动 TiXL 完成改码→重载→派发→检视状态→截图的自动化闭环。该协议以 tixl-debug-protocol-plan.md 为实施蓝图服务端实现在 DebugServer.cs配套的 Agent 中性参考手册见 DEBUG_PROTOCOL.md类型化 .NET 客户端位于 Tests/TiXL.DebugClient/DebugProtocolClient.cs。背景协议要替代的痛点协议的设计源于 2026-09-01 一次真实的外场验证Field validation经历当时为验证一个资源泄漏修复SceneSetup.Dispose存在反转的守卫条件Agent 不得不通过合成鼠标输入和屏幕截图来驱动编辑器。这次经历暴露了三类根本性问题直接塑造了协议的设计决策像素猜测在手势歧义前失效。一次瞄准空白画布的双击被解释成离开合成静默导航到了 Projects 中心。虽然最终靠截图 diff 恢复了现场但每一次误操作都要付出完整的观察-决策-行动往返代价。协议中的dispatch直接消灭了这一整类问题。合成输入会抢占用户的鼠标键盘。会话被迫夺走用户正在并行工作的焦点且一旦用户重新接管机器驱动即告失败。因此免焦点运行focus-free被确立为显式设计决策而非锦上添花。泄漏本身因为无人测量而未被察觉。有问题的Dispose静默上线事后验证不得不从进程外部读取 Windows GPU 性能计数器。而在协议中加入一条廉价的内存指标读取就能把这一类 bug 变成一行断言——这正是 Phase 2 中getMetrics的由来。当天真正需要的操作清单是启动、打开工程、添加两个算子、连接它们、反复点击一个触发参数、截图、尾读日志、读取 GPU 内存。Phase 1–3 完整覆盖了这些需求。总体设计一条主线与三块基石协议的总体目标写在其标题行给外部客户端对 TiXL 实时状态的读与控制访问——命令、图状态、日志、ImGui 状态、截图——通过一个简单的本地协议完成并把热重载纳入闭环。测试只是该协议的一个客户端不反过来塑造协议形态。三条贯穿始终的设计主线单线程执行模型。所有请求的解析、执行与响应序列化都发生在主线程帧循环中的唯一一个点输入之后、绘制之前见 T3Ui.Update.cs 中DebugServer.ProcessMainThreadQueue()的调用位置socket 线程只负责读行并入队模型状态永不加锁。信封携带状态快照。每个响应都免费附带frame、playbackFrame、structureVersion客户端永远知道自己观察到的是哪个状态。错误即数据。失败不丢连接而是返回{ok:false,error:{code:...,detail:...}}。Phase 0 — 审计动手前盘点可变路径Phase 0 不写代码约半天只做三件事枚举全部UserAction与Command逐一判断能否仅由纯数据id、值构造还是捕获了活对象引用找出绕过命令路径的直接模型编辑UI 代码直改模型——先不修只列出因为它们是状态查询返回了命令日志无法解释的数据的位置盘点现有标识体系算子、符号、实例如何寻址协议需要为客户端可引用的每个实体提供稳定的 string/GUID 寻址。输出物是一份短文档即 tixl-debug-protocol-audit.md记录可寻址实体、可序列化命令、已知绕过点。该阶段的关键决策socket 线程只入队原始行、主线程泵解析/执行/响应信封携带 ImGui 帧号 播放帧号 全局SymbolUi.GlobalVersionCounter变更直接派发命令而非 UserAction已在审计文档中定稿并在后续实现中逐条落地。Phase 1 — 传输层与骨架1–2 天Phase 1 是有意做得无聊的一层核心约束如下传输TCP 监听127.0.0.1端口可配置由--debug-server port命令行开关启用JSON-lines一行一请求、一行一响应每条请求携带客户端自选的id。线程socket 线程只解析并入队所有请求执行发生在帧循环中的唯一点——输入之后、绘制之前见 T3Ui.Update.cs响应也在此写回模型状态全程无锁。信封格式{id:a1,method:ping} {id:a1,ok:true,result:{version:1,frame:8842,structureVersion:89}}计划文档中的示例信封只带frame与structureVersion实际实现DebugServer.cs 的StampEnvelope额外增加了playbackFrame使客户端能同时跟踪 UI 帧与播放帧两个时间轴。本阶段方法ping、shutdown、getVersion。验收标准echo {id:1,method:ping} | nc localhost 9042在应用满帧率运行时即时返回。该阶段在 2026-09-02 已实现并通过实机验证Phase 1 ✅shutdown走EditorUi.Instance.ExitApplication()Application.Exit()只会触发退出对话框服务在 Program.cs 中解析--debug-server port参数并调用DebugServer.Start(port)启动。Phase 2 — 读表面2–4 天按最高价值优先排序Phase 2 提供七个只读方法getLogTail {sinceSeq?, minLevel?}— 从内存环形缓冲取日志记录JSON 记录、带递增序列号。实现在 DebugLogBuffer.cs容量 4096 的环形缓冲ProcessEntry可从任意线程写入主线程读取CollectEntries支持sinceSeq负数返回最新 N 条、minLeveldebug/info/warning/error、maxCount返回latestSeq与oldestAvailableSeq便于增量拉取。它与dispatch组合能消灭大多数盲猜。getGraphState {compositionId?, includeDefaults?}— 算子ops、连接、选中项与参数值。实现中按symbol.Children枚举每个 child 输出childId、symbolId、symbolName可选name自定义名、isBypassed、isDisabled、画布坐标posX/posY以及各输入项的id/name/isDefault/value默认值输入在includeDefaults为 false 时跳过连接则以sourceParentOrChildId/sourceSlotId/targetParentOrChildId/targetSlotId四元组输出。getStructureVersion— 廉价轮询原语自上次查看以来是否发生变化。实现返回EditorSymbolPackage.SymbolStructureVersionCounter。getContext— 活动合成、当前时间、播放状态、选中算子。实现还额外返回输出窗口的 pinning 状态outputView是否 pin、展示的是哪个 child、求值起点是否不同——这正对应 DEBUG_PROTOCOL.md 中从用户正在看的东西开始的引导。screenshot {path}— 将 PNG 写入磁盘并返回路径。实现通过OutputWindow.GetCurrentTexture()取当前输出纹理按扩展名选择 JPG/PNG经ScreenshotWriter.StartSavingToFile异步保存在回读完成时稍后帧的主线程回调中响应若队列忙碌返回SCREENSHOT_BUSY。getUiState {panel?}— ImGui 绘制前状态窗口/面板树、具名控件的 widget 矩形、焦点、悬停。计划明确要求从最小做起按需增长因为这是唯一能回答为什么控件不在图状态所说的位置的表面。该阶段按子集范围被跳过见下文实施状态。getMetrics— 帧时间、进程的 GPU 专用/共享内存、若干 ResourceManager 计数活缓冲、SRV、纹理。实现中 GPU 内存通过Adapter3.QueryVideoMemoryInfoSharpDX DXGI读取进程本地显存段的CurrentUsageMb与budgetMb——这正是泄漏检测指标另有fps、gcTotalMemoryMb与renderStatsRenderStatsCollector.ResultsForLastFrame。它让资源泄漏回归变成可断言的重载 N 次后内存增量 ≈ 0——2026-09 的SceneSetup.Dispose泄漏若在会被它精确捕获。验收标准应用打开工程时脚本无需触碰 UI 即可转储图状态、截图、尾读日志。Phase 3 — 控制表面2–3 天Phase 3 将协议从观察推进到控制提供七个方法dispatch {action, args}— 用数据构造并派发 UserAction/Command基于 Phase 0 的清单响应含commandId与结果structureVersion。未知/不可序列化动作返回干净的错误并指明缺什么——这成为命令覆盖率的活待办清单。undo/redo— 经由现有队列执行。setTime {seconds}/setPlayback {playing}— 注入的时钟控制。实现支持timeInBars或timeInSecs两种取值以及speed或playing两种播放设置并回传当前值。pumpFrames {count}— 推进 N 帧后响应是动作→让它渲染→再看的原语。实现中用_pendingPumps列表在每次ProcessMainThreadQueue即每帧递减计数归零即响应天然与帧循环对齐。openProject {name}/openComposition {symbolId}— 会话引导。每个脚本化场景都从这里开始否则 hub 只能靠点击到达。实现走OpenedProject.TryCreate/TryCreateWithExplicitHome打开工程寻找可见的图窗口并TrySetToProject默认pinOutput: true把根实例 pin 到主输出窗口。语义保证被派发的命令与其它一切在同一帧循环点应用响应在应用之后发出因此dispatch→getGraphState永远是 read-your-writes。验收标准仅凭 shell 脚本即可创建算子、连接、改参数、截图、撤销——应用全程不被手触碰。已实现扩展Phase 3 的完整形态Phase 3 验收于 2026-09-02 通过后又补充了一批方法使脚本建图真正闭环全部实现在 DebugServer.csnewProject {name}— 完整调用ProjectSetup.TryCreateProject脚手架 编译返回displayName形如name (namespace)与homeSymbolId。注意项目模板并非空工程首次创建时有 14 个 child / 5 条连接的基线该模板内容后来通过协议被删空现为 0 child加载极快。addOp {symbolName|symbolId, posX, posY}— 跨包按名查找重名返回AMBIGUOUS错误并列出候选返回新 child 的childId。未传坐标时不再堆叠到原点而是自动排到图中最低算子下方的新行左对齐、200px 间距见FindFreeRow。connect— 输出/输入槽按 guid、名称或第一个匹配解析内置两道护栏TYPE_MISMATCH类型不匹配的连接会崩溃求值直接拒绝与CYCLE经Structure.CheckForCycle防环。deleteOp、pin {childId}把某个 child pin 到输出窗口恢复被addOp抢走的输出视图、undo/redo。计划之外的实用方法setBypass {childId, bypassed}需算子可旁路IsBypassable、resetView复位输出相机配合截图断言、setAgentState {state, note}busy/ready/驱动应用栏 IO 指示灯Agent 工作时品红、报告ready时变绿任何后续请求自动翻回 busy防止过期的 ready 残留。验收由 Scripts/protocol-acceptance.py首次运行时在pixtur._agentTests下创建游乐场工程端到端跑通构建 CubeMesh→DrawMesh、pin、截图、经setInput改色Vector4 以{X:..,Y:..,Z:..,W:..}传输、校验图像变化、undo 回基线、断言日志干净。同时 Scripts/run-visual-tests.py 已能全自动驱动 98 个视觉参考测试约 13 秒 启动时间含#hashId/IgnoredTestIds往返。Phase 4 — 日志关联1 天Phase 4 的目标是因果追溯每个协议派发的命令获得commandId一个volatile环境量持有当前正在应用的命令日志写入器为每条记录盖章{commandId?, structureVersion, frame}getLogTail增加{commandId}过滤显示这条命令同步引发的一切可选把commandId作为originCommand传入应用期间派生的异步工作——按需延迟实现。计划特意强调不发明步骤编号——关联使用应用自身的因果链。该阶段被刻意推迟见实施状态。Phase 5 — 客户端工具1 天一个让协议可从 bash 直接使用的小 CLI也因此可供 Agent 在会话中使用tixlctl dispatch AddOp {symbol:Blur,composition:...} tixlctl graph --depth 1 tixlctl logs --since-last --min-level warn tixlctl shot /tmp/after.png tixlctl pump 3设计极薄解析参数 → 发送一行 → 打印响应。后续可选包装为 MCP server但 CLI 本身已足以改变开发会话。该阶段同样被推迟且已明确Tests/TiXL.DebugClient类型化客户端库是其未来核心。Phase 6 — 热重载进入闭环reload {project}方法或文件监视触发调用现有热重载路径响应成功/编译错误 耗时。响应中的编译错误文本最重要——它闭环了编辑 →tixlctl reload→ 读错误或继续状态查询。实现已验证reload同步调用EditableSymbolProject.TryRecompile(updatePackage: true)已放宽为 internal成功返回durationSeconds_agentTests约 1 秒编译错误原样回传于COMPILE_FAILED的 detail 中实测损坏源码 → 精确的 MSBuildCS1031错误含文件与行号修复后 → ok未知工程 →NOT_FOUND并提示内置包需重启。注意两点重编译会阻塞帧循环客户端需用宽松的超时只有可编辑用户工程支持重载Lib/examples 的变更仍需重启编辑器——这正是算子开发先在_agentTests迭代的原因。openProject接受工程短名显示名为name (namespace)。验收标准完整闭环——编辑代码、重载、派发、检视状态、截图——无需重启应用每次迭代数秒内完成。Phase 7 — 把测试变成协议的一个客户端Phase 7 只有在实际使用 Phases 1–6 之后才开始并由真实用法塑形cue 文件只是一份录制/撰写的协议调用清单附带预期日志预算、状态谓词、可选图像基线运行器是独立客户端以--debug-server启动 Tixl、播放脚本、检查预期、写报告——应用内不掺任何测试专属代码录制器是唯一值得加入应用侧的例外把实时命令流序列化为可重放脚本让一次手动复现会话变成回归测试断言优先用状态 日志仅当状态转储无法表达预期时才用视觉基线首个 cue 文件已按 2026-09 泄漏会话定好范围打开_Tests派发AddOp LoadGltfSceneAddOp DrawScene 连接泵帧快照getMetrics触发TriggerUpdate参数 ×10每次之间泵帧然后断言输出非黑、日志尾无 Skipping draw call 警告、GPU 内存增量 ≈ 0。一个小脚本同时覆盖文件加载、材质创建、场景派发、重载时释放以及 metrics/log/screenshot 表面——它应当成为协议的 hello-world 回归测试。CI自托管 GPU runner只是运行器在失败时非零退出的配置任务。已提前落地的测试基建Phase 7 于 2026-09-02 提前到达Python 探针脚本被正式的 .NET 测试基建取代。Tests/TiXL.DebugClient类型化协议客户端线格式集中管理Tests/Editor.IntegrationTestsxUnit。测试夹具 EditorFixture.cs 的行为通过环境变量TIXL_DEBUG_PORT默认 9042尝试附加到已在运行的编辑器失败则自行以--debug-server {port} --window 1280x720 --no-splash启动TiXL.exe可用TIXL_EXE指定路径并等待端口测试串行执行DisableTestParallelization共享一个编辑器实例与一条协议连接打开_agentTests游乐场后先resetView再统计基线规避输出相机跨会话持久导致截图全空的陷阱关闭时若是自己启动的进程则shutdown并等待退出。覆盖的 11 项事实包括协议基础、Phase 3 验收往返、重载路径以及视觉参考套件标记为[Trait(Category,VisualSuite)]。快速运行dotnet test Tests/Editor.IntegrationTests --filter Category!VisualSuite约 7 秒 启动全量含视觉套件约 30 秒 启动。该成果顺带削减了 Plan_AutomaticTests.md 中推迟的 xUnit 工作——其 Phases 1–2纯模型测试现在可以直接并入 Tests/ 目录。设计决策先行定死协议在设计上先行锁定了六条决策全部可在实现中逐一验证仅 localhost 显式开关。v1 无鉴权--debug-server开关本身就是鉴权。服务端绑定IPAddress.LoopbackDebugServer.cs。免焦点构造。任何方法都不得要求窗口处于前台、聚焦甚至可见绝不使用合成 OS 输入。用户可以在客户端驱动 Tixl 的同时继续使用其他应用。协议自第一条消息起版本化getVersion返回protocolVersion与editorVersion允许 CLI 与应用各自漂移。错误即数据{ok:false,error:{code:UNKNOWN_ACTION,detail:...}}永不丢连接。实现中的错误码包括PARSE_ERROR、MISSING_METHOD、UNKNOWN_METHOD、MISSING_PARAM、INVALID_PARAM、NOT_FOUND、NO_COMPOSITION、NO_OUTPUT、TYPE_MISMATCH、CYCLE、AMBIGUOUS、CREATE_FAILED、OPEN_FAILED、COMPILE_FAILED、SCREENSHOT_FAILED、SCREENSHOT_BUSY、INTERNAL_ERROR等。读写全部在主线程帧循环的唯一点。简单性优先于延迟人/Agent 的时间尺度完全容忍一帧的响应时间。应用内无测试概念。步骤、稳定等待、基线、cue 全是客户端约定无需触碰 Tixl 即可迭代。风险与缓解计划明确列出三项风险及其缓解命令序列化缺口Phase 0 的绕过清单是真正的进度风险——协议的价值上限等于可经它触达的变更比例。缓解UNKNOWN_ACTION错误路径让缺口可见、可排优先级而不是阻塞。大型工程的图状态转储体积。缓解从第一天起就用depth/compositionId作用域控制。ImGui 状态提取是最具探索性的部分。缓解getUiState保持最小化、需求驱动而非尝试完整镜像。实际使用速查求值模型与陷阱DEBUG_PROTOCOL.md 沉淀了实机使用中踩过的坑是任何协议客户端开发者的必读。核心一条编辑器是拉取式求值——算子只有被某物每帧显示才会求值setInput不会运行图。由此衍生出八条操作准则用 select 触发求值。构建或修改图后select关心的算子UI 预览会每帧拉取它此后getOutput/screenshot才反映当前值。每次变更后泵帧。setInput/select/openProject后先pumpFrames10–25 帧再读回。触发输入需要边沿。bool 触发参数在跨帧的 false→true 跃变时触发设 false、泵帧、设 true、泵帧对已为 true 的输入设 true 无效。自动保存地雷。setInput会标记工程已修改并触发编辑器自动保存。实验务必在_agentTests工程空、加载快、位于仓库外的用户工程目录、可编辑故支持reload热重载中进行绝不要在Lib、playground或真实用户工程里做。输出相机跨会话持久——截图全空时先resetView复位原点。不要堆叠算子。addOp不带坐标会自动排新行用getGraphState返回的posX/posY沿行布局且跨探针运行不要复用固定坐标上一轮的算子还在图上。addOp可能抢走输出视图。新增的不可渲染算子获得焦点后screenshot会报NO_OUTPUTpin一个可渲染算子如 draw 算子恢复输出窗口。不要手改已加载文件。编辑器处于运行状态时手改.t3/.t3ui/算子.csproj保存时会被重写先关闭或重启编辑器。线格式与寻址要点Vector2/3/4以{X:..,Y:..}Newtonsoft 默认Listint以{Values:[...]}包装见 SymbolPackage.TypeRegistration.csopenProject接受短名前缀算子按getGraphState返回的childIdGUID寻址符号名在跨包重名时优先用 id。代码变更后的编辑器重启流程发送shutdownfire-and-forgetDebug 构建立即退出teardown 约 2–10 秒轮询进程列表→dotnet build受影响工程 → 用启动参数重新拉起并等待端口。若在shutdown后立刻重建Lib注意编辑器退出时可能重写算子.cs文件使它们比旧 DLL 更新导致 MSBuild 跳过编译——先touch被编辑的文件并确认 DLL 确实变了。实施状态总览截至 2026-09-02Phase 0 ✅审计完成见 tixl-debug-protocol-audit.md。Phase 1 ✅实机验证传输层 ping/getVersion/shutdown。Phase 2 ✅实机验证除需开工程的 happy-pathgetLogTail/getGraphState/getContext/getStructureVersion/getMetrics/screenshotgetUiState按子集范围跳过。Phase 3 ✅核心端到端验证openProject/select/setInput/getOutput/pumpFrames/setTime/setPlayback及后续补充的newProject/addOp/connect/deleteOp/pin/undo/redo/setBypass/resetView/setAgentState。Phase 6 ✅已验证reload。Phase 7 提前完成核心部分Tests/TiXL.DebugClientTests/Editor.IntegrationTests视觉参考套件全自动运行。有意推迟Phase 4 日志关联、Phase 5tixlctlCLIDebugClient 库是其未来核心、CI 接线需 GPU runner、getUiState。按照计划编排2026-09-02Phase 0/1/2不含getUiState/3/5/6 的收窄子集是 Plan_ProceduralGeometry.md Phase 1 的前置条件——几何工作的验证闭环正是该协议的回报所在这也解释了为什么协议以验证闭环而非自动化测试为第一优先。【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考