SKILL.md
只读
名称
cmux-debugging
描述
针对 cmux 的调试日志、Debug 菜单、运行时踩坑指南、输入延迟敏感路径、SwiftUI 列表快照边界、macOS 系统版本复现及本地视觉迭代。适用于添加调试探针、排查 UI 与运行时问题、修改终端渲染、标签页/侧边栏列表视图、拖拽 UTType 自定义类型或使用 Debug 菜单等场景。
cmux 调试指南
调试事件日志(Debug event log)
在统一的 DEBUG 构建日志中添加调试事件埋点(按键、鼠标、焦点、分屏、标签页等)。并不需要给每个新代码路径都打日志,大部分埋点只是为了狗粮测试(dogfooding)阶段调试,合并前要记得清理掉。
tail -f "$(cat /tmp/cmux-last-debug-log-path 2>/dev/null || echo /tmp/cmux-debug.log)"
- 未指定标签的 Debug 版应用日志输出至
/tmp/cmux-debug.log;带标签的(./scripts/reload.sh --tag <tag>)输出至/tmp/cmux-debug-<tag>.log。 reload.sh会将当前日志路径写入/tmp/cmux-last-debug-log-path,选中的开发版 CLI 路径写入/tmp/cmux-last-cli-path,并把/tmp/cmux-cli和$HOME/.local/bin/cmux-dev指向该 CLI。- 具体实现:
Packages/macOS/CMUXDebugLog/Sources/CMUXDebugLog/DebugEventLog.swift。App 层垫片:Sources/App/DebugLogging.swift。两者均被#if DEBUG包裹,因此所有调用处都必须用#if DEBUG/#endif条件编译。 cmuxDebugLog("message")会带上时间戳实时追加内容。底层维护了一个容量为 500 条的环形缓冲区(ring buffer);调用CMUXDebugLog.DebugEventLog.shared.dump()可将完整的缓冲区内容 dump 到文件。- 按键事件在
AppDelegate.swift(monitor、performKeyEquivalent)中记录;鼠标和 UI 事件则内联在视图中记录(如ContentView、BrowserPanelView)。 - 固定的事件前缀:
focus.panel,focus.bonsplit,focus.firstResponder,focus.moveFocus,tab.select,tab.close,tab.dragStart,tab.drop,pane.focus,pane.drop,divider.dragStart。
Debug 菜单
DEBUG 构建版本会在 macOS 顶部菜单栏显示一个 Debug 菜单。当用户提到“debug menu”或“debug window”时,指的是这个菜单,而不是 defaults write 命令。
Debug > Debug Windows 包含用于调节布局、颜色和行为的面板,按字母顺序排列且没有分隔线。如果要新增面板:创建一个带有 shared 单例的 NSWindowController 子类,在 Sources/cmuxApp.swift 的“Debug Windows”菜单中注册它,并为其配备使用 @AppStorage 绑定(以支持实时修改)的 SwiftUI 视图。
运行时踩坑指南
- 自定义拖拽 UTType 必须声明在
Resources/Info.plist的UTExportedTypeDeclarations下。 - 切勿添加应用级别的 display link 或手动运行
ghostty_surface_draw循环;请依赖 Ghostty 原生的唤醒与渲染机制,以防引起输入延迟。 Sources/TerminalWindowPortal.swift中的WindowTerminalHostView.hitTest()在每次事件(包括键盘输入)发生时都会触发。切勿在isPointerEvent卫语句(guard)之外添加任何繁重逻辑。Sources/ContentView.swift中的TabItemView采用了Equatable结合.equatable()的方式,以便在打字时跳过 body 的重新求值。在未同步更新==并在调用处保留.equatable()的情况下,不要新增任何环境(environment)、store 或 binding 读取。Sources/GhosttyTerminalView.swift中的TerminalSurface.forceRefresh()每次按键都会执行。严禁在其中进行内存分配、文件 I/O 或字符串格式化操作。SurfaceSearchOverlay必须挂载到Sources/GhosttyTerminalView.swift中的GhosttySurfaceScrollView上,而不是挂载到 SwiftUI 面板容器上。- 处于
LazyVStack/LazyHStack/List/ForEach边界下方的视图只会接收不可变快照与闭包,绝不能直接接收可观察的 store(observable store)。 - 在 SwiftUI
body中调用的函数严禁修改状态(state)或计划写入 store(schedule store writes)。 - Foundation、SwiftUI、AttributeGraph 和 WebKit 的行为实现在 macOS 大版本升级间可能有所变化。在断定用户反馈的问题“无法复现”之前,请务必在反馈者所使用的 macOS 系统版本上进行测试。
详细参考文档
- references/debug-event-log.md:何时添加探针以及如何命名探针。
- references/runtime-pitfalls.md:在修改终端渲染、碰撞检测(hit testing)、标签页行、列表虚拟化、搜索遮罩层级或系统版本敏感代码之前,请先阅读此文档。






