feat(macos): add beta distribution lane - #150
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (11)
📜 Recent review details🧰 Additional context used🧬 Code graph analysis (3)macos/ClawDnDApp/Sources/ClawDnDApp/Views/WebView.swift (1)
macos/ClawDnDApp/Sources/ClawDnDApp/Services/RepositoryLocator.swift (1)
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift (1)
🪛 Ruff (0.15.14)viewer/server.py[warning] 2869-2870: (PERF203) 🪛 SwiftLint (0.63.2)macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift[Warning] 5-5: Classes should have an explicit deinit method (required_deinit) 🔇 Additional comments (15)
📝 WalkthroughWalkthroughAdds Sparkle-based update support and UpdaterService, bundles OpenWorlds UI into the macOS app and injects CLAWDND_OPENWORLDS_DIR/CLAWDND_BETA_CHANNEL_DIR into child processes, expands the native bridge with updater/window commands and UI controls, and adds packaging, signing, tests, and docs. ChangesSparkle Updates and Native Bridge Expansion
Sequence DiagramsequenceDiagram
participant UI as RootView
participant Updater as UpdaterService
participant Sparkle as SPUStandardUpdaterController
UI->>Updater: request checkForUpdates()
Updater->>Updater: validate config, set lastCheckRequestedAt
Updater->>Sparkle: checkForUpdates(nil)
Sparkle-->>Updater: callbacks update lastError/status
Updater-->>UI: return statusPayload
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/OPENWORLDS_NATIVE_APP_ROADMAP.md`:
- Around line 72-75: The docs currently reference a hardcoded beta channel
volume path which limits portability; update the markdown around the listed app
bundle and update feed to note this is the maintainer's local setup and add
guidance on how contributors can override it (e.g., set an environment variable
like BETA_OUTPUT_DIR, pass a script parameter, or change a config file) and
include a short example note line such as "(Local setup: maintainers use their
own volume path; contributors can modify the script or set BETA_OUTPUT_DIR)" so
others know how to configure their own beta channel.
- Around line 131-133: Add payload/response schema docs for the new bridge
request types: document `updaterStatus` (no request payload, returns status
object with fields like canCheck, isChecking, updateAvailable, etc.),
`checkForUpdates` (no payload, triggers update check and returns updated
status), and `windowCommand` (request payload `{ command: "close" | "minimize" |
"zoom" }`, no return payload). Insert this short schema block after the listed
items and before `openFallbackDashboard` so the README clearly shows expected
request/response shapes for `updaterStatus`, `checkForUpdates`, and
`windowCommand`.
In `@macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift`:
- Around line 12-18: The current checks in UpdaterService.swift only test for
presence of keys via Bundle.main.object(forInfoDictionaryKey: "SUFeedURL") and
"SUPublicEDKey" but allow empty strings; update these checks to cast to String,
trim whitespace (use .trimmingCharacters(in: .whitespacesAndNewlines)) and
verify .isEmpty == false before initializing updaterController; if either
SUFeedURL or SUPublicEDKey is missing or empty set updaterController = nil and
set lastError to a clear message (e.g., "Sparkle feed URL is missing or
empty..." / "Sparkle public key is missing or empty...") to match existing
behavior.
In `@script/package_macos_beta.sh`:
- Line 306: The artifact stem currently hardcodes "beta.1" in the variable
artifact_stem; make the pre-release suffix configurable by adding a PRERELEASE
parameter/flag (or environment variable) and using it when constructing
artifact_stem (e.g., read PRERELEASE with a default of "beta.1" and set
artifact_stem to "${APP_NAME}-${version}-${PRERELEASE}"); update any help/usage
text to document the new --prerelease/PRERELEASE option and validate/normalize
the value (non-empty) before building.
In `@viewer/openworlds/screen-settings.jsx`:
- Around line 307-311: The "Check for Updates" button can be clicked when the
native bridge isn't available; update the enablement logic so the button is
disabled unless the bridge exists. In the BrassButton instance that uses
onClick={() => nativeAction("checkForUpdates")} and disabled={!bridgeReady ||
!updater.canCheckForUpdates}, add a hasBridge() guard (or wrap the onClick to
early-return if !hasBridge()) so the button's disabled state includes
!hasBridge(), ensuring nativeAction("checkForUpdates") is never invoked when the
bridge is absent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: a2584c9c-52fb-43b0-b7fe-5f2e6dd1a1bb
📒 Files selected for processing (14)
docs/OPENWORLDS_NATIVE_APP_ROADMAP.mdmacos/ClawDnDApp/Package.resolvedmacos/ClawDnDApp/Package.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/App/ClawDnDApp.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swiftmacos/ClawDnDApp/SparklePublicKey.txtscript/package_macos_beta.shviewer/openworlds/chrome.jsxviewer/openworlds/screen-settings.jsxviewer/openworlds/styles.cssviewer/server.pyviewer/tests/test_openworlds_static.py
📜 Review details
🧰 Additional context used
🧬 Code graph analysis (2)
viewer/openworlds/screen-settings.jsx (1)
viewer/openworlds/screen-character.jsx (1)
StatLine(445-457)
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift (1)
viewer/openworlds/native-bridge.js (1)
request(9-14)
🪛 LanguageTool
docs/OPENWORLDS_NATIVE_APP_ROADMAP.md
[uncategorized] ~83-~83: The operating system from Apple is written “macOS”.
Context: ... The repo stores only the public key in macos/ClawDnDApp/SparklePublicKey.txt. Impl...
(MAC_OS)
🪛 Shellcheck (0.11.0)
script/package_macos_beta.sh
[info] 221-221: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
[info] 222-222: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
[info] 223-223: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
[info] 224-224: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
[info] 225-225: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
[info] 226-226: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
[info] 227-227: Expressions don't expand in single quotes, use double quotes for that.
(SC2016)
🪛 SwiftLint (0.63.2)
macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift
[Warning] 5-5: Classes should have an explicit deinit method
(required_deinit)
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift
[Warning] 415-415: Classes should have an explicit deinit method
(required_deinit)
🔇 Additional comments (20)
docs/OPENWORLDS_NATIVE_APP_ROADMAP.md (2)
63-67: LGTM!
96-98: LGTM!macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift (1)
13-13: LGTM!Also applies to: 26-27, 79-80, 158-167, 178-179, 339-354
viewer/server.py (1)
52-53: LGTM!Also applies to: 65-73, 2799-2810
viewer/tests/test_openworlds_static.py (1)
28-32: LGTM!Also applies to: 49-53, 92-103
viewer/openworlds/chrome.jsx (1)
369-412: LGTM!viewer/openworlds/screen-settings.jsx (1)
224-224: LGTM!Also applies to: 289-306, 312-318
viewer/openworlds/styles.css (1)
200-220: LGTM!script/package_macos_beta.sh (7)
1-73: LGTM!
75-114: LGTM!
116-164: LGTM!
166-180: LGTM!
182-234: LGTM!Note: Shellcheck SC2016 warnings on lines 221-227 are false positives—the single-quoted backticks are intentional markdown formatting in the output, not shell variable expansion.
236-293: LGTM!
294-357: LGTM!macos/ClawDnDApp/Package.swift (1)
13-22: LGTM!macos/ClawDnDApp/Package.resolved (1)
1-14: LGTM!macos/ClawDnDApp/SparklePublicKey.txt (1)
1-1: LGTM!macos/ClawDnDApp/Sources/ClawDnDApp/App/ClawDnDApp.swift (1)
10-10: LGTM!Also applies to: 17-17, 24-24
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift (1)
8-8: LGTM!Also applies to: 57-61, 180-186, 269-270, 276-294, 407-421
|
Beta handoff update after Sparkle crash validation:
Focused validation already run from bash -n script/build_and_run.sh script/package_macos_beta.sh
python3 -m py_compile viewer/server.py
python3 -m unittest viewer.tests.test_openworlds_static -q
swift build --package-path macos/ClawDnDApp
./script/package_macos_beta.sh --version 0.3.0 --build 2026052601 --channel local-beta
codesign --verify --deep --strict /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app
plutil -lint /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app/Contents/Info.plist
hdiutil verify /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD-0.3.0-beta.1.dmg
python3 scripts/license_check.py
git diff --checkKnown remaining before taking out of draft: manual visual smoke in the actual app window, CodeRabbit reviewDecision refresh on the latest head, and notarization follow-up tracked separately in #151. @coderabbitai review |
|
✅ Actions performedReview triggered.
|
|
Additional runtime fix pushed in Root cause:
Fix:
Validation after rebuild/regeneration: swift build --package-path macos/ClawDnDApp
python3 -m unittest viewer.tests.test_openworlds_static -q
./script/package_macos_beta.sh --version 0.3.0 --build 2026052601 --channel local-beta
codesign --verify --deep --strict /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app
plutil -lint /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app/Contents/Info.plist
hdiutil verify /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD-0.3.0-beta.1.dmg
python3 scripts/license_check.py
git diff --checkRuntime smoke:
Remaining manual checks are now limited to traffic-light behavior, drag strip behavior, and the Settings/Sparkle panel interaction. @coderabbitai review |
🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
# Get the diff for the new commit
git show 58d1f3151f138af97ba311d7e9c6b50e0eb2217d --stat
echo "---DIFF---"
git show 58d1f3151f138af97ba311d7e9c6b50e0eb2217dLength of output: 12755
🔴
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift (1)
32-48: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueMinor inconsistency:
publicKeyConfigureddoesn't trim whitespace.Line 41 checks
(info["SUPublicEDKey"] as? String)?.isEmpty == falsewithout trimming, whileinit()trims whitespace before validating. A key containing only whitespace would showpublicKeyConfigured: truein the payload despite failing initialization.Not a runtime bug (controller would be nil, status would be "unavailable"), but the payload could be misleading during debugging.
Proposed fix for consistency
- "publicKeyConfigured": (info["SUPublicEDKey"] as? String)?.isEmpty == false, + "publicKeyConfigured": ((info["SUPublicEDKey"] as? String)? + .trimmingCharacters(in: .whitespacesAndNewlines))?.isEmpty == false,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift` around lines 32 - 48, In statusPayload, publicKeyConfigured currently checks (info["SUPublicEDKey"] as? String)?.isEmpty == false which doesn't trim whitespace; change it to mirror the init() validation by trimming the SUPublicEDKey string (e.g., calling .trimmingCharacters(in: .whitespacesAndNewlines)) and then testing isEmpty == false so keys of only whitespace report false; update the publicKeyConfigured expression in the statusPayload computed property accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift`:
- Around line 32-48: In statusPayload, publicKeyConfigured currently checks
(info["SUPublicEDKey"] as? String)?.isEmpty == false which doesn't trim
whitespace; change it to mirror the init() validation by trimming the
SUPublicEDKey string (e.g., calling .trimmingCharacters(in:
.whitespacesAndNewlines)) and then testing isEmpty == false so keys of only
whitespace report false; update the publicKeyConfigured expression in the
statusPayload computed property accordingly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 84a7b037-25af-45cc-85cd-fa2089aaa0b2
📒 Files selected for processing (9)
docs/OPENWORLDS_APP_SURFACE_MAP.mddocs/OPENWORLDS_NATIVE_APP_ROADMAP.mdmacos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/Services/RepositoryLocator.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swiftmacos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swiftscript/build_and_run.shscript/package_macos_beta.shviewer/openworlds/screen-settings.jsx
📜 Review details
🧰 Additional context used
🧬 Code graph analysis (3)
script/build_and_run.sh (1)
script/package_macos_beta.sh (1)
copy_sparkle_framework(345-345)
macos/ClawDnDApp/Sources/ClawDnDApp/Services/RepositoryLocator.swift (2)
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift (1)
defaultRepoPath(11-11)macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift (1)
providerStatuses(52-54)
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift (2)
macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift (1)
providerStatuses(52-54)macos/ClawDnDApp/Sources/ClawDnDApp/Services/CampaignStore.swift (1)
reload(11-32)
🪛 LanguageTool
docs/OPENWORLDS_NATIVE_APP_ROADMAP.md
[style] ~154-~154: Consider using the typographical ellipsis character here instead.
Context: ...erStatus", "payload": {} } ``` Returns `{ "updater": { "version": "0.3.0", "build": "2026052601", "feedURL": "...", "channel": "local-beta", "canCheckFor...
(ELLIPSIS)
[style] ~168-~168: Consider using the typographical ellipsis character here instead.
Context: ..., or zoom; the native reply includes { "command": "...", "performed": true }`. Native replies...
(ELLIPSIS)
🔍 Remote MCP
The DeepWiki tool is unavailable for this private repository. However, based on the comprehensive context provided in your PR summary, I can identify the key factual information already gathered that's relevant for review:
Summary of Additional Relevant Context Found
Sparkle Framework Integration
The PR integrates Sparkle 2.9.2 pinned in both Package.resolved and Package.swift. The implementation requires:
SUFeedURLandSUPublicEDKeyconfigured inInfo.plist(UpdaterService validates these at initialization)- The public key stored in
macos/ClawDnDApp/SparklePublicKey.txt - Framework bundled at
Contents/Frameworks/Sparkle.frameworkwith proper runtime search path (@executable_path/../Frameworks) set viainstall_name_tool
OpenWorlds Asset Bundling & Environment Variable
- Bundled assets are placed at
ClawDnD.app/Contents/Resources/openworlds - Launched via
CLAWDND_OPENWORLDS_DIRenvironment variable (injected byAppProcessService) - Detection validates presence of
openworlds/index.htmlin Bundle.main - Python viewer (
viewer/server.py) resolves assets dynamically based onCLAWDND_OPENWORLDS_DIR, defaulting toviewer/openworldsif unset
State Authority Boundaries
Per the PR objectives:
- App controls: Swift shell updates, bundled OpenWorlds UI assets
- Repo/state-backed: Python viewer, engine, state directories, play-state, QA state, campaign truth
- No change in scope: Browser actions and game-state writes remain in existing lanes (not moved to app)
Native Bridge Extension
New request types added via RootView:
updaterStatus→ returnsUpdaterService.statusPayloadcheckForUpdates→ triggersUpdaterService.checkForUpdates()windowCommand→ validates command (close/minimize/zoom), locates active window, executes operation
Repository Detection Enhancement
RepositoryLocator.supportsOpenWorldsViewer(_:) now validates repo capability by checking viewer/server.py for OpenWorlds marker strings before allowing asset bundling.
Validation Artifacts
The packaging script (script/package_macos_beta.sh) produces:
- Signed
.app,.zip,.dmgoutputs appcast.xml(generated via Sparkle'sgenerate_appcastwith Ed25519 private key)RELEASE_NOTES.md,CHECKSUMS.txt, validation report- All outputs staged to
/Volumes/LEXAR/Codex/clawdnd-beta-channel
🔇 Additional comments (34)
docs/OPENWORLDS_APP_SURFACE_MAP.md (1)
1-74: LGTM!docs/OPENWORLDS_NATIVE_APP_ROADMAP.md (2)
71-75: LGTM!Also applies to: 85-92
148-169: LGTM!macos/ClawDnDApp/Sources/ClawDnDApp/Services/UpdaterService.swift (2)
12-22: LGTM!
51-62: LGTM!macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift (6)
57-61: LGTM!Also applies to: 78-82, 94-96
185-194: LGTM!Also applies to: 200-212
214-234: LGTM!Also applies to: 236-249, 251-283
285-303: LGTM!
332-344: LGTM!Also applies to: 346-369
442-456: LGTM!viewer/openworlds/screen-settings.jsx (1)
228-228: LGTM!Also applies to: 308-314
macos/ClawDnDApp/Sources/ClawDnDApp/Services/AppProcessService.swift (6)
13-13: LGTM!Also applies to: 26-26
65-69: LGTM!
84-85: LGTM!
130-134: LGTM!
168-169: LGTM!Also applies to: 176-176, 188-188
349-364: LGTM!macos/ClawDnDApp/Sources/ClawDnDApp/Services/RepositoryLocator.swift (5)
4-14: LGTM!
16-23: LGTM!
25-39: LGTM!
41-86: LGTM!
95-102: LGTM!script/build_and_run.sh (5)
16-17: LGTM!Also applies to: 35-35
38-40: LGTM!
75-84: LGTM!
86-90: LGTM!
92-96: LGTM!script/package_macos_beta.sh (6)
14-14: LGTM!Also applies to: 21-21
25-42: LGTM!
91-97: LGTM!
252-252: LGTM!Also applies to: 271-275
290-295: LGTM!
328-328: LGTM!Also applies to: 346-346
|
Current-head cleanup pushed in Addressed the follow-up review items:
Focused validation after the cleanup: swift build --package-path macos/ClawDnDApp
python3 -m unittest viewer.tests.test_openworlds_static -q
python3 -m py_compile viewer/server.py
bash -n script/build_and_run.sh script/package_macos_beta.sh
./script/package_macos_beta.sh --version 0.3.0 --build 2026052601 --channel local-beta
codesign --verify --deep --strict /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app
plutil -lint /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app/Contents/Info.plist
hdiutil verify /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD-0.3.0-beta.1.dmg
python3 scripts/license_check.py
git diff --checkInstalled-app smoke after regenerating the beta artifact:
@coderabbitai review |
🧩 Analysis chain🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
git show 3bc24b346d6a697d4e6c70e3681628d0c2553a12 --stat
echo "---DIFF---"
git show 3bc24b346d6a697d4e6c70e3681628d0c2553a12Length of output: 639 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
# Check current branch and latest commits
git log --oneline -10
echo "---"
# Look at the key files changed in the cleanup
cat macos/ClawDnDApp/Sources/ClawDnDApp/Services/RepositoryLocator.swift
echo "---ROOTVIEW---"
grep -n "resolveAndPersistRepoPath\|resolvedRepoPath\|requireRepoPath" macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swiftLength of output: 5700 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
# Read the resolvedRepoPath / resolveAndPersistRepoPath helpers in full
awk '/private func requireRepoPath/,/^ private func [a-z]/' \
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift | head -60Length of output: 346 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
# Get lines from requireRepoPath onwards to end of file
grep -n "private func requireRepoPath\|private func resolveAndPersistRepoPath\|private func resolvedRepoPath" \
macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swift
echo "---TAIL---"
# Show the last 60 lines where these helpers likely live
tail -80 macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swiftLength of output: 3271 🏁 Script executed: #!/usr/bin/env bash
set -euo pipefail
# Extract from line 346 onwards, about 40 lines
sed -n '346,390p' macos/ClawDnDApp/Sources/ClawDnDApp/Views/RootView.swiftLength of output: 1722
One minor observation (not a blocker): Triggering review on the current head. ✅ Actions performedReview triggered.
|
|
Update on commit Fixed the Sparkle local-beta blocker found during packaged-app smoke. Sparkle 2 rejects raw Also fixed the packaged-app blank-window regression by keeping the titled window style bit while hiding native title/buttons; this preserves WKWebView rendering while leaving OpenWorlds as the visible app chrome. Focused validation from
Manual packaged-app smoke:
Current GitHub status note: CodeRabbit is green/approved on the latest head. GitHub Actions are failing before repo code runs: Ubuntu CI cannot download |
|
Adversarial follow-up pushed in What changed after the last approved head:
Validation from bash -n script/package_macos_beta.sh script/build_and_run.sh
python3 -m unittest viewer.tests.test_openworlds_static -q
python3 -m py_compile viewer/server.py
swift build --package-path macos/ClawDnDApp
python3 scripts/license_check.py
git diff --check
./script/package_macos_beta.sh --version 0.3.0 --build 2026052601 --channel local-beta
codesign --verify --deep --strict /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app
plutil -lint /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD.app/Contents/Info.plist
hdiutil verify /Volumes/LEXAR/Codex/clawdnd-beta-channel/ClawDnD-0.3.0-beta.1.dmgResults: 19 viewer tests passing, Swift build passing, license check passing, code signing verify passing, Info.plist lint passing, DMG verification passing. Negative path checks also reject slash-bearing versions and escaped beta output roots before packaging. Known external gate: GitHub Actions are still failing before repo code runs because checkout/action downloads are returning GitHub 403/codeload/account errors. I am leaving the branch unsquashed for auditability; it can be rebased or squashed later once the external CI/merge gate is healthy. |
|
macOS Sparkle beta-distribution lane — deferred (see #134) and hard-conflicted by the ClawDnD→WorldOS rename. Closing the stale PR; re-port fresh when the beta lane is prioritized. |
Summary
Adds the local beta distribution lane for the OpenWorlds-first ClawDnD macOS app.
UpdaterServiceplus OpenWorlds bridge requests forupdaterStatus,checkForUpdates, andwindowCommand.viewer/openworlds/intoClawDnD.app/Contents/Resources/openworldsand launches the repo-backed Python viewer withCLAWDND_OPENWORLDS_DIRpointing at bundled UI assets.file://, so Sparkle can check local beta updates safely.script/package_macos_beta.shto build, sign, zip, DMG, appcast, checksums, release notes, and validation output under/Volumes/LEXAR/Codex/clawdnd-beta-channel.State Authority
This keeps the app in the supervisor/read-surface lane:
.appcan update the Swift shell and bundled OpenWorlds UI assets.Local Beta Output
Generated locally by:
Expected local channel:
Runtime Sparkle feed in the packaged app:
The packaged app stores the local channel path in
Info.plist; the Swift supervisor passesCLAWDND_BETA_CHANNEL_DIRto the viewer, and the viewer rewrites appcast URLs to the live loopback port.Adversarial Review Fixes
After CodeRabbit approval, four read-only adversarial slice agents reviewed the PR. Verified findings fixed in commit
3b85fca:feedAvailable, only overriding Sparkle to loopback whenlocalBetaChannelPathexists, and failing closed before invoking Sparkle.BETA_OUTPUT_DIRor slash-bearing release tokens. Fixed by canonicalizingOUTPUT_ROOT, validating version/build/channel/prerelease tokens, and asserting generated artifacts stay under the resolved channel root.Hostheader. Fixed by deriving appcast artifact URLs from the bound loopback server port and adding a spoofed-Host regression test.windowCommandcould target the wrong macOS window if another window was key. Fixed by passing the sourceWKWebViewwindow through the native bridge and applying close/minimize/zoom only to that window.BETA_OUTPUT_DIR; updated docs/help to state the Lexar-backed local beta constraint.Review clearances included: no private Sparkle key committed, Sparkle framework/resources are bundled, appcast targets ZIP not DMG, notarization is correctly deferred to #151, and state authority remains outside the app bundle.
Validation
Ran from
/Volumes/LEXAR/repos/ClawDnD-macos-beta-distribution:Focused negative checks:
Results:
codesign --verify --deep --strict: passing.spctl: rejected asUnnotarized Developer ID, expected because notarization is tracked separately in [macos][release] Add notarized public-beta distribution lane #151.Current External Gate
GitHub Actions are failing before repo code runs because GitHub checkout/action download is returning external auth/codeload errors (
403,Your account is suspended, and setup-uv codeload download failures). Local focused validation is clean; these CI failures should be retried after the GitHub account/action-fetch issue clears.Follow-Up
mainis moving.Refs #134
Refs #136
Refs #151
Summary by CodeRabbit
New Features
Documentation