cmux-debugging

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

cmux 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
  • reload.sh
    writes the current path to
    /tmp/cmux-last-debug-log-path
  • reload.sh
    writes the selected dev CLI path to
    /tmp/cmux-last-cli-path
  • reload.sh
    updates
    /tmp/cmux-cli
    and
    $HOME/.local/bin/cmux-dev
    to that CLI
  • Implementation:
    Packages/CMUXDebugLog/Sources/CMUXDebugLog/DebugEventLog.swift
  • App shim:
    Sources/App/DebugLogging.swift
  • Free function
    cmuxDebugLog("message")
    logs with timestamp and appends to file in real time from cmux code
  • The package implementation and app shim are
    #if DEBUG
    ; all call sites must be wrapped in
    #if DEBUG
    /
    #endif
  • 500-entry ring buffer;
    CMUXDebugLog.DebugEventLog.shared.dump()
    writes full buffer to file
  • Key events logged in
    AppDelegate.swift
    (monitor, performKeyEquivalent)
  • Mouse/UI events logged inline in views (ContentView, BrowserPanelView, etc.)
  • Focus events:
    focus.panel
    ,
    focus.bonsplit
    ,
    focus.firstResponder
    ,
    focus.moveFocus
  • Bonsplit events:
    tab.select
    ,
    tab.close
    ,
    tab.dragStart
    ,
    tab.drop
    ,
    pane.focus
    ,
    pane.drop
    ,
    divider.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
  • reload.sh
    会将选中的开发CLI路径写入
    /tmp/cmux-last-cli-path
  • reload.sh
    会将
    /tmp/cmux-cli
    $HOME/.local/bin/cmux-dev
    更新为该CLI路径
  • 实现代码:
    Packages/CMUXDebugLog/Sources/CMUXDebugLog/DebugEventLog.swift
  • 应用适配层:
    Sources/App/DebugLogging.swift
  • 全局函数
    cmuxDebugLog("message")
    会带时间戳记录日志,并实时追加到cmux代码对应的文件中
  • 包实现和应用适配层均包含
    #if DEBUG
    条件编译;所有调用点必须包裹在
    #if DEBUG
    /
    #endif
  • 采用500条记录的环形缓冲区;
    CMUXDebugLog.DebugEventLog.shared.dump()
    会将完整缓冲区内容写入文件
  • 按键事件在
    AppDelegate.swift
    中记录(monitor、performKeyEquivalent方法)
  • 鼠标/UI事件在视图内联记录(ContentView、BrowserPanelView等)
  • 焦点事件:
    focus.panel
    focus.bonsplit
    focus.firstResponder
    focus.moveFocus
  • Bonsplit事件:
    tab.select
    tab.close
    tab.dragStart
    tab.drop
    pane.focus
    pane.drop
    divider.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
    NSWindowController
    subclass with a
    shared
    singleton, add it to the "Debug Windows" menu in
    Sources/cmuxApp.swift
    , and add a SwiftUI view with
    @AppStorage
    bindings for live changes.
  • When the user says "debug menu" or "debug window", they mean this menu, not
    defaults write
    .
仅在DEBUG构建版本中,macOS菜单栏会显示Debug菜单,用于视觉迭代调试。
  • Debug > Debug Windows包含用于调整布局、颜色和行为的面板,菜单项按字母排序,无分隔线。
  • 如需添加调试开关或视觉选项:创建
    NSWindowController
    子类并实现
    shared
    单例,在
    Sources/cmuxApp.swift
    中将其添加到“Debug Windows”菜单,然后添加带有
    @AppStorage
    绑定的SwiftUI视图以支持实时修改。
  • 当用户提及“调试菜单”或“调试窗口”时,指的是该菜单,而非
    defaults write
    命令。

Runtime pitfalls

运行时陷阱

  • Custom UTTypes for drag-and-drop must be declared in
    Resources/Info.plist
    under
    UTExportedTypeDeclarations
    .
  • Do not add an app-level display link or manual
    ghostty_surface_draw
    loop; rely on Ghostty wakeups/renderer to avoid typing lag.
  • WindowTerminalHostView.hitTest()
    is typing-latency-sensitive. All divider/sidebar/drag routing is gated to pointer events only. Do not add work outside the
    isPointerEvent
    guard.
  • TabItemView
    uses
    Equatable
    conformance plus
    .equatable()
    to skip body re-evaluation during typing. Do not add environment/store/binding reads without updating equality and the call site.
  • TerminalSurface.forceRefresh()
    is called on every keystroke. Do not add allocations, file I/O, or formatting there.
  • SurfaceSearchOverlay
    must be mounted from
    GhosttySurfaceScrollView
    in
    Sources/GhosttyTerminalView.swift
    , not from SwiftUI panel containers.
  • List subtrees with
    LazyVStack
    ,
    LazyHStack
    ,
    List
    , or
    ForEach
    must pass immutable row snapshots plus closures below the boundary. Do not pass observable stores into row views.
  • Functions called from SwiftUI
    body
    must not mutate state or schedule store writes.
  • 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_surface_draw
    循环;依赖Ghostty的唤醒/渲染机制以避免输入延迟。
  • WindowTerminalHostView.hitTest()
    属于输入延迟敏感路径,所有分栏/侧边栏/拖放路由仅针对指针事件处理,请勿在
    isPointerEvent
    guard之外添加额外操作。
  • TabItemView
    使用
    Equatable
    协议一致性加
    .equatable()
    来避免输入期间的body重评估。若要添加环境/存储/绑定读取,必须更新相等性逻辑和调用点。
  • TerminalSurface.forceRefresh()
    会在每次按键时调用,请勿在此处添加内存分配、文件I/O或格式化操作。
  • SurfaceSearchOverlay
    必须从
    GhosttySurfaceScrollView
    (位于
    Sources/GhosttyTerminalView.swift
    )挂载,而非SwiftUI面板容器。
  • 使用
    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