Right now cargo run -p we-browser is the only way to launch the browser. There is no .app bundle, no icon, no code-signing, no Launch Services registration, and no way to associate the app with http:///https:// URLs or .html files. Mirror what ~/misc/mct/build.sh does for MCT and produce a real macOS app.
Reference#
Look at ~/misc/mct/build.sh (and ~/misc/mct/.env for the signing identity convention). The full mct script is the working template — adapt it for a Rust/Cargo build.
Scope#
Add a build.sh at the repo root that, in this order:
-
Load
./.env(gitignored) if present, exportingCERT_NAME. If missing, fall through to ad-hoc signing (codesign --sign -) so the script still works for contributors without the Apple Developer cert. -
Compile release binary:
cargo build --release -p we-browser --target aarch64-apple-darwin -
Lay out the bundle at
build/we.app/:we.app/ Contents/ Info.plist PkgInfo # \"APPL????\" MacOS/we # copied from target/aarch64-apple-darwin/release/browser Resources/AppIcon.icns -
Generate the icon in pure Rust. We have
we-imagewith a PNG encoder — write a tinytools/generate_iconbinary (in this repo, not an external swiftc script) that emits a 1024x1024 PNG to a path, then slice and pack it viasips+iconutilexactly as mct does:sips -z 16 16 ... ; sips -z 32 32 ... ; ... iconutil --convert icns ...Cache the
.icnsunderbuild/icon/so we don't regenerate every build.The icon design can be simple — a stylised
wewordmark on a rounded-rect gradient background. Keep it placeholder-quality; the point is to have a real icon slot, not to ship final branding. -
Write the
Info.plist. Browser-specific keys (in addition to the mct boilerplate):CFBundleIdentifier=com.we.browserCFBundleName=weCFBundleDisplayName=weCFBundleShortVersionString= read fromcrates/browser/Cargo.toml[package].versionCFBundleVersion= sameCFBundleExecutable=weCFBundleIconFile=AppIconCFBundlePackageType=APPLLSMinimumSystemVersion=14.0LSApplicationCategoryType=public.app-category.web-browserCFBundleURLTypes— registerhttpandhttpsschemes soopen https://...and OS-wide "set default browser" can targetwe:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key><string>HTTP</string> <key>CFBundleURLSchemes</key><array><string>http</string></array> </dict> <dict> <key>CFBundleURLName</key><string>HTTPS</string> <key>CFBundleURLSchemes</key><array><string>https</string></array> </dict> </array>CFBundleDocumentTypes— register.html,.htm,.xhtmlso double-clicking opens inwe.NSAppTransportSecuritywithNSAllowsArbitraryLoads=truefor now (we need plain HTTP until issue3mm2gmpx46624ships proper TLS).
The browser binary will need a tiny extra: handle the
application:openURL:AppKit callback (or readargvon launch when LaunchServices passes the file). Existing argv handling already covers the file-path case; the URL-scheme case ("Get URL" Apple Event) is a future ticket — register the schemes now so the OS knows the app is willing. -
PkgInfo= literalAPPL????(8 bytes). -
Code-sign:
codesign --force --options runtime --sign \"$CERT_NAME\" build/we.app(Or
--sign -ifCERT_NAMEis empty.)--options runtimeenables the hardened runtime, required for Developer ID notarization. Add an entitlements plisttools/we.entitlementsgrantingcom.apple.security.network.client(otherwise the sandbox blocks outbound sockets). Pass it via--entitlements. -
Install to
/Applications/we.app:pkill -x we 2>/dev/null || true rm -rf /Applications/we.app cp -R build/we.app /Applications/we.app codesign --force --options runtime --sign \"$CERT_NAME\" /Applications/we.app -
Refresh Launch Services so Finder/launchd see the new bundle:
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f /Applications/we.app -
open /Applications/we.appand report success.
.gitignore#
Add build/ and .env to .gitignore so the bundle output and signing identity stay out of git.
Documentation#
- Update
CLAUDE.mdCommands section with a./build.shentry that says "produce signedwe.appand install to/Applications". - Mention the optional
.envwithCERT_NAME=<Developer ID Application: …>and that omitting it falls back to ad-hoc signing.
Acceptance#
./build.shexits 0 with no signing identity present, producing/Applications/we.appthat launches and shows the browser window.- With a
CERT_NAMEset in./.env,codesign --verify --deep --strict /Applications/we.apppasses, andspctl --assess /Applications/we.appsucceeds (or returns the expected "unnotarized" message for a Developer ID build — explicit notarization is out of scope here, separate ticket). mdls /Applications/we.appshows the bundle as a Web Browser category app.- Right-clicking an
.htmlfile in Finder listsweunder "Open With". defaults read /Applications/we.app/Contents/Info.plist CFBundleURLTypeslistshttpandhttps.- The Dock shows the generated app icon on launch.
Out of scope (separate tickets)#
- Apple notarization (
xcrun notarytool). - Universal binary (x86_64 + arm64). For now arm64-only matches the project's stated platform.
- Sparkle/auto-update.
- Handling "Get URL" Apple Events for live URL-scheme dispatch (currently we just declare the schemes so the OS will list
weas an option). - DMG packaging / public release artefact.