chore: import upstream snapshot with attribution
This commit is contained in:
+107
@@ -0,0 +1,107 @@
|
||||
---
|
||||
summary: "WidgetKit snapshot pipeline + visibility troubleshooting for CodexBar widgets."
|
||||
read_when:
|
||||
- Modifying WidgetKit extension behavior or snapshot format
|
||||
- Debugging widget update timing
|
||||
- Widget gallery shows no CodexBar widgets
|
||||
---
|
||||
|
||||
# Widgets
|
||||
|
||||
## Snapshot pipeline
|
||||
- `WidgetSnapshotStore` writes compact JSON snapshots to the app-group container.
|
||||
- Widgets read the snapshot and render usage/credits/history states.
|
||||
- The app writes snapshots after the main refresh pipeline and token-usage refreshes; narrow single-provider refresh paths may wait for the next snapshot write.
|
||||
- Claude local cost/token history remains eligible for widget snapshots when its account does not expose numeric
|
||||
session or weekly quota data.
|
||||
- If no snapshot is available, widgets fall back to preview/empty data.
|
||||
|
||||
## Extension
|
||||
- `Sources/CodexBarWidget` contains timeline + views.
|
||||
- `WidgetExtension/CodexBarWidgetExtension.xcodeproj` builds those sources as the packaged macOS WidgetKit app extension.
|
||||
- Keep data shape in sync with `WidgetSnapshot` in the main app.
|
||||
|
||||
## Widget types
|
||||
- **CodexBar Switcher** (`CodexBarSwitcherWidget`): static provider switcher widget, small/medium/large.
|
||||
- **CodexBar Usage** (`CodexBarUsageWidget`): configurable provider usage widget, small/medium/large.
|
||||
- **CodexBar History** (`CodexBarHistoryWidget`): configurable usage-history chart, medium/large.
|
||||
- **CodexBar Metric** (`CodexBarCompactWidget`): compact credits/today-cost/30-day-cost widget, small only.
|
||||
- **CodexBar Burn Down** (`CodexBarBurnDownWidget`): configurable session or weekly burn-down chart, medium only.
|
||||
- **CodexBar Burn Down (Combined)** (`CodexBarCombinedBurnDownWidget`): session and weekly burn-down charts, medium only.
|
||||
|
||||
## Provider picker support
|
||||
The configurable provider widgets currently expose:
|
||||
Codex, Claude, Cursor, Gemini, Alibaba, Antigravity, z.ai, Copilot, MiniMax, Kilo, OpenCode, and OpenCode Go.
|
||||
|
||||
Providers without a `ProviderChoice` case can still be present in the app snapshot, but they are not selectable from the widget configuration UI yet.
|
||||
|
||||
Burn-down widgets currently support Codex and Claude. Their dedicated configuration intents keep existing Usage and History widget configurations unchanged.
|
||||
|
||||
## Visibility troubleshooting (macOS 14+)
|
||||
When widgets do not appear in the gallery at all, the issue is almost always
|
||||
registration, signing, or daemon caching (not SwiftUI code).
|
||||
|
||||
### 1) Verify the extension bundle exists where macOS expects it
|
||||
```
|
||||
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"
|
||||
```
|
||||
|
||||
### 2) PlugInKit registration (pkd)
|
||||
```
|
||||
pluginkit -m -p com.apple.widgetkit-extension -v | grep -i codexbar || true
|
||||
pluginkit -m -p com.apple.widgetkit-extension -i "$WIDGET_ID" -vv
|
||||
```
|
||||
Notes:
|
||||
- `+` = elected to use, `-` = ignored (PlugInKit elections).
|
||||
- If missing or ignored, force-add and re-elect:
|
||||
```
|
||||
pluginkit -a "$WAPPEX"
|
||||
pluginkit -e use -p com.apple.widgetkit-extension -i "$WIDGET_ID"
|
||||
```
|
||||
- Check for duplicates (old installs or version precedence):
|
||||
```
|
||||
pluginkit -m -D -p com.apple.widgetkit-extension -i "$WIDGET_ID" -vv
|
||||
```
|
||||
If multiple paths appear, delete older installs and bump `CFBundleVersion`.
|
||||
|
||||
### 3) Code signing + Gatekeeper assessment
|
||||
Widgets are loaded by system daemons. Any signing failure can hide the widget.
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
### 4) Restart the right daemons (NotificationCenter alone is not enough)
|
||||
```
|
||||
killall -9 pkd || true
|
||||
sudo killall -9 chronod || true
|
||||
killall Dock NotificationCenter || true
|
||||
```
|
||||
|
||||
### 5) Watch logs while opening the widget gallery
|
||||
```
|
||||
log stream --style compact --predicate '(process == "pkd" OR process == "chronod" OR subsystem CONTAINS "PlugInKit" OR subsystem CONTAINS "WidgetKit")'
|
||||
```
|
||||
|
||||
### 6) Packaging sanity checks
|
||||
- Widget bundle id should be `com.steipete.codexbar.widget` for release and `com.steipete.codexbar.debug.widget` for debug.
|
||||
- `NSExtensionPointIdentifier` must be `com.apple.widgetkit-extension`.
|
||||
- Bundle folder name should match: `CodexBarWidget.appex`.
|
||||
|
||||
Optional: re-seed LaunchServices (rarely helps, but low risk):
|
||||
```
|
||||
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -seed
|
||||
```
|
||||
|
||||
## Common post-visibility issue: stale data
|
||||
If the widget appears but always shows preview data:
|
||||
- App writes snapshot to fallback path while widget reads app-group container.
|
||||
- Validate that both app and widget resolve the same app-group container.
|
||||
|
||||
See also: `docs/ui.md`, `docs/packaging.md`.
|
||||
Reference in New Issue
Block a user