feat(desktop): bundle WidgetKit appex into the Tauri app, Rust snapshot writer, retire Swift menu bar (desktop stack 4/5) - #5299
Conversation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configurationConfiguration used: Repository: lidge-jun/opencodex/.coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
리뷰 · 우선순위 66 / 80이 PR은 데스크톱 스택 4/5입니다. 기준 브랜치는 하는 일을 쉽게 말하면 세 덩어리입니다. 첫째, Rust가 프록시 상태를 읽어 라인 - 메인테이너의 판단이 필요한 지점
너의 추천 방향은 맞습니다. 다만 지금은 머지하지 마세요. ① README i18n 동기화로 test 실패를 고치고, ② 이 댓글은 grok-bot이 작성했습니다 |
…fest Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Addressed in c44c370:
Not changed, with reasoning:
|
⏳ DRAFT
What to do
Review readiness checklist
0/4 boxes ticked. This pull request was already a draft. Its draft status will be preserved after every issue above is resolved. |
추가 리뷰 · 우선순위 48 / 80이전 리뷰(95f6829) 이후 커밋 라인 - 메인테이너의 판단이 필요한 지점 워크플로·릴리스 표면을 보고 너의 추천 코드 쪽 급한 구멍(README 패리티, 모델 id 인코딩)은 막혔으니 머지 차단 우선순위는 내려갑니다. 그래도 지금은 머지하지 마세요. ① 메인테이너가 워크플로 diff를 보고 스폰서하고, ② #5287이 먼저 들어간 뒤에만 이 PR을 올리고, ③ draft 체크리스트는 로컬/CI 확인 후 작성자가 채우게 하세요. 위젯 갱신 지연·App Group·빌드 훅은 5/5 리뷰에서 한 번에 재확인하면 됩니다. 이 댓글은 grok-bot이 작성했습니다 |
|
Confirming the open items now that 5/5 exists (#5309):
No code change on this PR from this review. |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c44c37047e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| bun run prepare-sidecar | ||
| bun run prepare-widget | ||
| bunx tauri build |
There was a problem hiding this comment.
Enter the desktop package before running its scripts
In the documented scenario immediately after cd opencodex, Bun resolves these commands against the root package.json, which defines neither script; checking this exact path makes bun run prepare-sidecar exit with Script not found. Both scripts and the Tauri configuration reside under desktop/, so the documented source build always stops before compilation; add cd desktop or root-level delegating scripts.
AGENTS.md reference: docs-site/AGENTS.md:L7-L10
Useful? React with 👍 / 👎.
| cd opencodex | ||
| bun run build:macos | ||
| bun run prepare-sidecar | ||
| bun run prepare-widget |
There was a problem hiding this comment.
Disable universal output for the CLT-only build
Even after running this from desktop/, the guide says the Xcode Command Line Tools are sufficient, but prepare-widget defaults UNIVERSAL=1 and therefore builds both architectures; the same page correctly notes below that this requires full Xcode. A user with only the stated prerequisites therefore hits a linker/toolchain failure, so the local command should pass UNIVERSAL=0 or the prerequisites should require full Xcode.
AGENTS.md reference: docs-site/AGENTS.md:L7-L10
Useful? React with 👍 / 👎.
| .unwrap_or_else(|_| json!({ "settings": {} })); | ||
| let today = proxy.usage_today().await.ok(); | ||
| let quota_value = proxy.quotas().await.ok(); | ||
| let timeline_value = proxy.timeline(&timeline_query(&settings)).await.ok(); |
There was a problem hiding this comment.
Honor showChart before fetching a timeline
When companion settings contain showChart: false, this unconditional request still fetches the timeline and make_snapshot serializes it, so the widget continues displaying a chart and performs the expensive usage-log aggregation the user disabled. The replaced Swift coordinator guarded this request with snapshot.settings.showChart; apply the same condition here and leave chart unset when the option is false.
Useful? React with 👍 / 👎.
| today: today_snapshot, | ||
| quotas: quotas(quotas_value), | ||
| chart, | ||
| last_updated: timeline_value.map(|_| now_seconds()), |
There was a problem hiding this comment.
Fall back to the usage refresh time
If /api/usage/timeline fails while /api/usage?range=today succeeds, the snapshot contains fresh metrics but lastUpdated is null, causing every widget size to report “Not updated.” The previous Swift snapshot used timelineUpdated ?? usageUpdated; record the refresh time when either timeline or today's usage succeeds rather than tying freshness solely to the optional chart request.
Useful? React with 👍 / 👎.
|
Superseded by #5318, merged to #5196 landed first as The consolidation applies the tree difference of the stack tip against the point the chain branched from. One file genuinely conflicted and both intents were kept. Everything from the standalone binary through the signed packaging is on Closing as superseded rather than stale. |
Desktop stack 4/5 — stacked on #5287 (base:
devin/1789890042-gui-desktop-shell). Series: #5256 → #5260 → #5287 → this → packaging/updater (5/5).Summary
The Tauri shell now owns the whole macOS companion: it writes the WidgetKit snapshot and bundles the native
OpenCodexWidget.appex, so the standalone Swift menu bar app is retired. WidgetKit itself stays Swift (it must be a native extension).desktop/src-tauri/src/widget.rs(macOS only; no-op elsewhere). MirrorsWidgetSnapshotschema v1 byte-for-byte (camelCase,state/stateTitle/detail,today,quotas,chart{start,bucketSeconds,style,series≤6},lastUpdated,generatedAt); state mapping followsProxySnapshot(running/unreachable/unauthorized/degradedwith the same titles/details).menuTitlereusestray::render_title, so the widget shows exactly what the tray shows. Written to~/Library/Containers/com.opencodex.desktop.widget/Data/Library/Application Support/OpenCodex/snapshot.jsonvia.tmp→chmod 0600→rename, skipped when unchanged modulogeneratedAt; first write at tray install, then every 5th 60 s tray tick. The widget's own.after(5 min)timeline policy picks it up — noWidgetCenterreload needed. NewProxyClient::{startup_health, usage_today, timeline}.desktop/scripts/build-widget.shbuilds the Swift product (universallipoby default), stagesdesktop/src-tauri/widget/OpenCodexWidget.appex(gitignored) withWidget-Info.plist, syncsCFBundleShortVersionString/CFBundleVersionfromtauri.conf.json, and ad-hoc signs withWidget.entitlements(MACOS_SIGN_IDENTITYbranch kept for 5/5).tauri.conf.jsonmaps it viabundle.macOS.files → PlugIns/OpenCodexWidget.appex. Widget bundle id →com.opencodex.desktop.widget(plist +WidgetSnapshotStoredefault).MenuBarApp,MenuBarUI,MenuBarUITests,UIProbe,IconProbe,app/Info.plist,scripts/build-macos-app.sh,scripts/package-macos-release.sh,tests/gui/macos-build-script.test.ts(+ layout entries). Package renamedOpenCodexWidget;MenuBarCore+MenuBarCoreTestskept as the widget's model/formatting layer (trimming is a follow-up). CImacos-app→widget(core tests + appex build +codesign -dv).release.yml:package-macos/attach-macosremoved;attach-standalonekeeps attaching thestandalone-*assets. Release gap: between this PR and 5/5 no macOS companion asset is produced; the Tauri DMG/MSI/AppImage/deb land in 5/5.timeline_querypercent-encodes model ids;readme/i18n-manifest.jsonresynced (review follow-up, c44c370).ocx traydeprecated, not removed — CLI summary/details note that the desktop app supplies the tray on all three OSes; PS1 tray keeps working for installs without the app. Skill surface regenerated.AGENTS.md,structure/overview.md,structure/desktop-shell.md(widget snapshot section),desktop/README.md, macOS guide (5 locales), CLI lifecycle reference (8 locales), READMEs.Verification
cargo fmt --check,cargo clippy --all-targets -- -D warnings,cargo test(10 passed; snapshot serialization vs Swift field names, 4 error-state mappings, write-if-changed ignoringgeneratedAt, series truncation).bash desktop/scripts/build-widget.shon macOS →codesign -dvOK (identifiercom.opencodex.desktop.widget),lipo -archs→x86_64 arm64, plist version2.61.0.swift run --package-path app MenuBarCoreTests(118 passed).bun run typecheck,bun run structure:check,bun run skill:surface:check,git diff --check.bun test tests/ci-workflowsrelease/ci-gate/skill files (162 + 5 + 16 passed), test-layout + tooling (23 passed).lint,lint:i18n; docs-site build (481 pages).tauri buildwith the appex embedded and a widget-gallery screenshot — that is the packaging pass in 5/5; I'll attach it there.Checklist
Link to Devin session: https://app.devin.ai/sessions/f2dce68b7ca349e3ba39dab55bc12300
Open in Devin Desktop: https://app.devin.ai/desktop/session/f2dce68b7ca349e3ba39dab55bc12300?variant=devin
Requested by: @lidge-jun
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
All CI tests are green on my local testing.
I pushed my PR to the latest dev commit.
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.