CodexBar 菜单栏 Widget 不显示在 Widget 图库时怎么排查注册与签名问题
【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBar
在 macOS 上打开 Widget 图库(桌面/通知中心里的 "+" 添加入口)时,如果完全看不到任何 CodexBar 的 Widget 条目,先不要去改 SwiftUI 视图代码。docs/widgets.md 的 Visibility troubleshooting 章节直接给出了结论:Widget 在图库中完全不出现时,问题几乎总是出在注册、签名或系统守护进程缓存上,而不是 SwiftUI 代码。
本文按该文档的六步排查顺序走一遍。适用条件:macOS 14+(WidgetExtension/Info.plist 中LSMinimumSystemVersion为 14.0,WidgetExtension/project.yml 的 deploymentTarget 也是macOS: "14.0"),应用安装在默认路径/Applications/CodexBar.app;如果你的安装位置不同,下文命令里的APP变量需要换成实际路径。
先确认扩展包的预期形态
排查开始前先明确两个事实,后面的检查步骤都依赖它们:
- Widget 扩展是一个真正的 macOS app extension,由 WidgetExtension/CodexBarWidgetExtension.xcodeproj 构建,打包时带有 app-group 权限,并放入主应用的
Contents/PlugIns/目录(docs/packaging.md 的 Bundle contents 一节)。因此它应该位于/Applications/CodexBar.app/Contents/PlugIns/CodexBarWidget.appex。 - Widget 的 bundle ID 区分发布版和调试版:release 为
com.steipete.codexbar.widget,debug 为com.steipete.codexbar.debug.widget。Scripts/package_app.sh 中由WIDGET_BUNDLE_ID="${BUNDLE_ID}.widget"派生,而BUNDLE_ID在 debug 配置下会被改为com.steipete.codexbar.debug。排查时先确认你手上装的是哪一类构建,后续WIDGET_ID要用对应的值。
第一步:确认扩展包存在于 macOS 期望的位置
按 docs/widgets.md 给出的命令检查 appex 目录本身及其内部结构:
APP="/Applications/CodexBar.app" WAPPEX="$APP/Contents/PlugIns/CodexBarWidget.appex" WIDGET_ID="com.steipete.codexbar.widget" # debug builds use com.steipete.codexbar.debug.widget ls -la "$WAPPEX" "$WAPPEX/Contents" "$WAPPEX/Contents/MacOS"判断方式:ls应能列出 appex 目录、其Contents和Contents/MacOS子目录。如果WAPPEX不存在,说明打包/安装环节没有把 Widget 扩展带进应用(docs/packaging.md 明确该 appex 由 WidgetExtension 工程构建后与主应用一起分发),此时应先解决安装完整性问题,而不是继续后面的注册排查。
第二步:检查并修复 PlugInKit 注册(pkd)
Widget 图库的可见性依赖 PlugInKit 对扩展的注册与"选举"(election)。先查看当前注册状态:
pluginkit -m -p com.apple.widgetkit-extension -v | grep -i codexbar || true pluginkit -m -p com.apple.widgetkit-extension -i "$WIDGET_ID" -vv文档对输出的说明:+表示该扩展被选举使用,-表示被忽略。如果条目缺失或处于忽略状态,执行强制添加并重新选举:
pluginkit -a "$WAPPEX" pluginkit -e use -p com.apple.widgetkit-extension -i "$WIDGET_ID"再用下面的命令检查是否存在重复注册(例如旧版本安装残留导致的版本优先级冲突):
pluginkit -m -D -p com.apple.widgetkit-extension -i "$WIDGET_ID" -vv如果出现多个路径,文档给出的处理是删除旧的安装并提升CFBundleVersion。注意这条操作会删除旧的 CodexBar 应用副本,只删除确认是旧版本的安装,不要动当前使用的/Applications/CodexBar.app;CFBundleVersion需要在重新打包时修改(WidgetExtension/project.yml 中该值来自$(CURRENT_PROJECT_VERSION)构建设置)。
第三步:验证代码签名与 Gatekeeper 评估
文档明确指出:Widget 是由系统守护进程加载的,任何签名失败都可能导致 Widget 被隐藏。对主应用、appex 和其中的可执行文件分别做严格校验,并做 Gatekeeper 评估:
codesign --verify --deep --strict --verbose=4 /Applications/CodexBar.app codesign --verify --strict --verbose=4 "$WAPPEX" codesign --verify --strict --verbose=4 "$WAPPEX/Contents/MacOS/CodexBarWidget" spctl --assess --type execute --verbose=4 /Applications/CodexBar.app判断方式:四条命令都应通过校验且不报签名错误。文档没有给出固定的成功输出文本,以命令本身不报错为准。如果某一级签名失败,需要回到打包环节修复签名(见 docs/packaging.md:默认走 ad-hoc 签名;稳定证书打包需要显式设置CODEXBAR_SIGNING=identity并提供APP_IDENTITY,签名与公证由Scripts/sign-and-notarize.sh执行),而不是手动修补 appex。
第四步:重启相关守护进程
文档特别强调:只重启 NotificationCenter 是不够的。下面命令会强制结束pkd(PlugInKit 守护进程)、chronod(时钟守护进程,需要管理员密码)以及 Dock 和 NotificationCenter 进程,系统会自动拉起它们,副作用是桌面 Dock 和通知中心 UI 短暂重建:
killall -9 pkd || true sudo killall -9 chronod || true killall Dock NotificationCenter || true第五步:打开 Widget 图库的同时观察系统日志
在前一个终端窗口保持日志流,然后在另一个窗口/操作里打开 Widget 图库,观察 PlugInKit 与 WidgetKit 相关子系统的输出,定位卡在哪一层:
log stream --style compact --predicate '(process == "pkd" OR process == "chronod" OR subsystem CONTAINS "PlugInKit" OR subsystem CONTAINS "WidgetKit")'文档将这一步作为排查流程的收尾观察手段,用于配合前四步操作定位注册或签名在系统层面的具体拒绝点。
第六步:核对打包一致性
如果前面步骤都"正常"但 Widget 仍不出现,文档列出三项打包层面的硬性要求,任何一项不符都会导致系统不识别该 Widget 扩展:
| 检查项 | 期望值 |
|---|---|
| Widget bundle ID | release 为com.steipete.codexbar.widget,debug 为com.steipete.codexbar.debug.widget |
NSExtensionPointIdentifier | com.apple.widgetkit-extension(见 WidgetExtension/Info.plist) |
| 扩展文件夹名 | CodexBarWidget.appex |
如果这三项与实际不符,说明拿到的应用包不是按 docs/packaging.md 描述的流程正确打包的,需要重新构建并打包。
可选操作:重新播种 LaunchServices。文档标注这一步"rarely helps, but low risk"(很少有效,但风险低),仅作为最后的补充手段:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -seed边界说明:Widget 出现了但一直显示预览数据
"图库中完全没有条目"和"Widget 出现了但数据不对"是两个不同的问题,本文只处理前者。文档单独列出了后者的一个已知原因:应用把快照写到了 fallback 路径,而 Widget 读的是 app-group 容器;此时应验证应用和 Widget 是否解析到同一个 app-group 容器(详见 docs/widgets.md 的 Common post-visibility issue 一节)。
排查按上述顺序执行后,如果 Widget 出现在图库中即代表完成;文档对这一症状的全部归因就是注册、签名、守护进程缓存三类。如果六步走完图库仍然为空,log stream捕获到的 pkd/chronod/WidgetKit 输出是继续定位的依据,文档没有给出进一步的升级路径。
【免费下载链接】CodexBarShow usage stats for OpenAI Codex and Claude Code, without having to login.项目地址: https://gitcode.com/GitHub_Trending/co/CodexBar
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考