cmux-debugging
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesecmux Debugging
cmux 调试
Debug event log
调试事件日志
When adding debug event instrumentation, put events (keys, mouse, focus, splits, tabs) in the unified DEBUG build log. This is not a blanket requirement to add logs to every new code path. Most temporary probes should be added only during the dogfood debug loop and removed before merge.
bash
tail -f "$(cat /tmp/cmux-last-debug-log-path 2>/dev/null || echo /tmp/cmux-debug.log)"- Untagged Debug app:
/tmp/cmux-debug.log - Tagged Debug app ():
./scripts/reload.sh --tag <tag>/tmp/cmux-debug-<tag>.log - writes the current path to
reload.sh/tmp/cmux-last-debug-log-path - writes the selected dev CLI path to
reload.sh/tmp/cmux-last-cli-path - updates
reload.shand/tmp/cmux-clito that CLI$HOME/.local/bin/cmux-dev - Implementation:
Packages/CMUXDebugLog/Sources/CMUXDebugLog/DebugEventLog.swift - App shim:
Sources/App/DebugLogging.swift - Free function logs with timestamp and appends to file in real time from cmux code
cmuxDebugLog("message") - The package implementation and app shim are ; all call sites must be wrapped in
#if DEBUG/#if DEBUG#endif - 500-entry ring buffer; writes full buffer to file
CMUXDebugLog.DebugEventLog.shared.dump() - Key events logged in (monitor, performKeyEquivalent)
AppDelegate.swift - Mouse/UI events logged inline in views (ContentView, BrowserPanelView, etc.)
- Focus events: ,
focus.panel,focus.bonsplit,focus.firstResponderfocus.moveFocus - Bonsplit events: ,
tab.select,tab.close,tab.dragStart,tab.drop,pane.focus,pane.dropdivider.dragStart
添加调试事件埋点时,请将事件(按键、鼠标、焦点、分屏、标签页)记录到统一的DEBUG构建日志中。这并不要求为所有新代码路径添加日志,大多数临时探针仅需在内部测试调试周期中添加,并在合并代码前移除。
bash
tail -f "$(cat /tmp/cmux-last-debug-log-path 2>/dev/null || echo /tmp/cmux-debug.log)"- 未标记的Debug应用:
/tmp/cmux-debug.log - 带标记的Debug应用():
./scripts/reload.sh --tag <tag>/tmp/cmux-debug-<tag>.log - 会将当前路径写入
reload.sh/tmp/cmux-last-debug-log-path - 会将选中的开发CLI路径写入
reload.sh/tmp/cmux-last-cli-path - 会将
reload.sh和/tmp/cmux-cli更新为该CLI路径$HOME/.local/bin/cmux-dev - 实现代码:
Packages/CMUXDebugLog/Sources/CMUXDebugLog/DebugEventLog.swift - 应用适配层:
Sources/App/DebugLogging.swift - 全局函数会带时间戳记录日志,并实时追加到cmux代码对应的文件中
cmuxDebugLog("message") - 包实现和应用适配层均包含条件编译;所有调用点必须包裹在
#if DEBUG/#if DEBUG中#endif - 采用500条记录的环形缓冲区;会将完整缓冲区内容写入文件
CMUXDebugLog.DebugEventLog.shared.dump() - 按键事件在中记录(monitor、performKeyEquivalent方法)
AppDelegate.swift - 鼠标/UI事件在视图内联记录(ContentView、BrowserPanelView等)
- 焦点事件:、
focus.panel、focus.bonsplit、focus.firstResponderfocus.moveFocus - Bonsplit事件:、
tab.select、tab.close、tab.dragStart、tab.drop、pane.focus、pane.dropdivider.dragStart
Debug menu
调试菜单
The app has a Debug menu in the macOS menu bar only in DEBUG builds. Use it for visual iteration.
- Debug > Debug Windows contains panels for tuning layout, colors, and behavior. Entries are alphabetical with no dividers.
- To add a debug toggle or visual option: create an subclass with a
NSWindowControllersingleton, add it to the "Debug Windows" menu inshared, and add a SwiftUI view withSources/cmuxApp.swiftbindings for live changes.@AppStorage - When the user says "debug menu" or "debug window", they mean this menu, not .
defaults write
仅在DEBUG构建版本中,macOS菜单栏会显示Debug菜单,用于视觉迭代调试。
- Debug > Debug Windows包含用于调整布局、颜色和行为的面板,菜单项按字母排序,无分隔线。
- 如需添加调试开关或视觉选项:创建子类并实现
NSWindowController单例,在shared中将其添加到“Debug Windows”菜单,然后添加带有Sources/cmuxApp.swift绑定的SwiftUI视图以支持实时修改。@AppStorage - 当用户提及“调试菜单”或“调试窗口”时,指的是该菜单,而非命令。
defaults write
Runtime pitfalls
运行时陷阱
- Custom UTTypes for drag-and-drop must be declared in under
Resources/Info.plist.UTExportedTypeDeclarations - Do not add an app-level display link or manual loop; rely on Ghostty wakeups/renderer to avoid typing lag.
ghostty_surface_draw - is typing-latency-sensitive. All divider/sidebar/drag routing is gated to pointer events only. Do not add work outside the
WindowTerminalHostView.hitTest()guard.isPointerEvent - uses
TabItemViewconformance plusEquatableto skip body re-evaluation during typing. Do not add environment/store/binding reads without updating equality and the call site..equatable() - is called on every keystroke. Do not add allocations, file I/O, or formatting there.
TerminalSurface.forceRefresh() - must be mounted from
SurfaceSearchOverlayinGhosttySurfaceScrollView, not from SwiftUI panel containers.Sources/GhosttyTerminalView.swift - List subtrees with ,
LazyVStack,LazyHStack, orListmust pass immutable row snapshots plus closures below the boundary. Do not pass observable stores into row views.ForEach - Functions called from SwiftUI must not mutate state or schedule store writes.
body - Foundation, SwiftUI, AttributeGraph, and WebKit semantics can change between macOS major versions. Test on the reporter's macOS before declaring a user repro disproven.
- 用于拖放的自定义UTTypes必须在的
Resources/Info.plist下声明。UTExportedTypeDeclarations - 请勿添加应用级别的显示链接或手动循环;依赖Ghostty的唤醒/渲染机制以避免输入延迟。
ghostty_surface_draw - 属于输入延迟敏感路径,所有分栏/侧边栏/拖放路由仅针对指针事件处理,请勿在
WindowTerminalHostView.hitTest()guard之外添加额外操作。isPointerEvent - 使用
TabItemView协议一致性加Equatable来避免输入期间的body重评估。若要添加环境/存储/绑定读取,必须更新相等性逻辑和调用点。.equatable() - 会在每次按键时调用,请勿在此处添加内存分配、文件I/O或格式化操作。
TerminalSurface.forceRefresh() - 必须从
SurfaceSearchOverlay(位于GhosttySurfaceScrollView)挂载,而非SwiftUI面板容器。Sources/GhosttyTerminalView.swift - 使用、
LazyVStack、LazyHStack或List的列表子树,必须在边界下方传递不可变行快照和闭包,请勿将可观察存储传递到行视图中。ForEach - SwiftUI 中调用的函数不得修改状态或调度存储写入操作。
body - Foundation、SwiftUI、AttributeGraph和WebKit的语义在macOS主版本之间可能会变化,在判定用户反馈的问题无法复现前,请先在反馈者使用的macOS版本上测试。
Detailed references
详细参考
- Read references/debug-event-log.md when adding or interpreting debug log probes.
- Read references/runtime-pitfalls.md before touching terminal rendering, hit testing, tab rows, list virtualization, search overlay layering, or OS-version-sensitive code.
- 添加或解读调试日志探针时,请阅读references/debug-event-log.md。
- 在处理终端渲染、点击测试、标签行、列表虚拟化、搜索覆盖层分层或操作系统版本敏感代码前,请阅读references/runtime-pitfalls.md。