问题描述
启动 CodeIsland 后,菜单栏岛消失,手动重新启动 app 没有任何反馈(无窗口、无报错),直到打开 Activity Monitor 才发现进程状态为 "Not Responding",必须手动 Force Quit 后重新打开才恢复。
macOS 不会自动为无响应的 app 弹出对话框,只会在 Activity Monitor 中静默标记,因此用户完全没有任何可见反馈。
根因分析
主线程上存在多处同步阻塞调用,任何一处卡住都会导致整个 app 无响应:
1. 启动时同步等待 claude --version 子进程(Critical)
位置: ConfigInstaller.swift:810-829 — detectClaudeVersion()
调用链:
AppDelegate.applicationDidFinishLaunching
→ ConfigInstaller.install()
→ installClaudeHooks()
→ compatibleEvents()
→ detectClaudeVersion()
→ Process().waitUntilExit() // 主线程,无超时
如果 Claude CLI 响应慢、卡住、有权限弹窗、或路径异常,整个 app 在启动阶段就会挂起。
2. Terminal 激活时主线程同步等待子进程(Critical)
位置: TerminalActivator.swift:890-913 — runProcess()
从 SwiftUI 按钮回调(NotchPanelView.swift:950)和快捷键处理(AppDelegate.swift:198)直接在主线程调用。activateGhostty() 会连续调用多次 runProcess()(tmux 命令),每次都 waitUntilExit()。
3. 周期性 hook 修复在主线程做文件 I/O(High)
位置: AppDelegate.swift:68-79
hookRecoveryTimer 每 300 秒触发一次 verifyAndRepair()
- 每次其他 app 激活(
NSWorkspace.didActivateApplicationNotification)也会触发
- 同步读写
~/.claude/settings.json、~/.codex/hooks.json 等多个配置文件
- 如果 home 目录在网络磁盘上,阻塞时间可能很长
建议修复方向
- 将
detectClaudeVersion() 移到后台队列,加超时保护(如 5 秒)
- 将
TerminalActivator.runProcess() 调用移到后台队列,主线程只负责 UI 更新回调
- 将
verifyAndRepair() 移到后台队列,并加 debounce 避免频繁触发
- 所有
Process.waitUntilExit() 调用加超时保护
- 考虑增加 main thread watchdog,当主线程阻塞超过阈值时记录日志或提示用户
环境
- macOS Sequoia
- CodeIsland v1.0.23
问题描述
启动 CodeIsland 后,菜单栏岛消失,手动重新启动 app 没有任何反馈(无窗口、无报错),直到打开 Activity Monitor 才发现进程状态为 "Not Responding",必须手动 Force Quit 后重新打开才恢复。
macOS 不会自动为无响应的 app 弹出对话框,只会在 Activity Monitor 中静默标记,因此用户完全没有任何可见反馈。
根因分析
主线程上存在多处同步阻塞调用,任何一处卡住都会导致整个 app 无响应:
1. 启动时同步等待
claude --version子进程(Critical)位置:
ConfigInstaller.swift:810-829—detectClaudeVersion()调用链:
如果 Claude CLI 响应慢、卡住、有权限弹窗、或路径异常,整个 app 在启动阶段就会挂起。
2. Terminal 激活时主线程同步等待子进程(Critical)
位置:
TerminalActivator.swift:890-913—runProcess()从 SwiftUI 按钮回调(
NotchPanelView.swift:950)和快捷键处理(AppDelegate.swift:198)直接在主线程调用。activateGhostty()会连续调用多次runProcess()(tmux 命令),每次都waitUntilExit()。3. 周期性 hook 修复在主线程做文件 I/O(High)
位置:
AppDelegate.swift:68-79hookRecoveryTimer每 300 秒触发一次verifyAndRepair()NSWorkspace.didActivateApplicationNotification)也会触发~/.claude/settings.json、~/.codex/hooks.json等多个配置文件建议修复方向
detectClaudeVersion()移到后台队列,加超时保护(如 5 秒)TerminalActivator.runProcess()调用移到后台队列,主线程只负责 UI 更新回调verifyAndRepair()移到后台队列,并加 debounce 避免频繁触发Process.waitUntilExit()调用加超时保护环境