Max/create first iteration 3oo - #6
Closed
maxonary wants to merge 16 commits into
Closed
Conversation
- Import .p12 cert into temp keychain, sign with "Developer ID Application" - Submit zip to Apple notary service via app-specific password - Staple ticket onto .app, re-zip so the ticket travels in the asset - Release notes drop the xattr workaround — double-click just works now Requires repo secrets BUILD_CERTIFICATE_BASE64, P12_PASSWORD, KEYCHAIN_PASSWORD, APPLE_ID_EMAIL, APPLE_ID_PASSWORD, APPLE_TEAM_ID, plus repo var DEVELOPMENT_TEAM_ID. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Developer ID + notarization setup needs more cert-export debugging that's not worth blocking a working release on. Reverts the workflow to the v0.1.0 state (ad-hoc sign, ditto zip, gh release). Recipients clear Gatekeeper once with xattr -dr; subsequent launches are normal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Re-enables Developer ID signing, notarization, and stapling. Adds an explicit validation gate right after cert import: if the uploaded .p12 doesn't contain a "Developer ID Application" identity, the build stops in ~20s with a single clear error instead of a 90-line archive failure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- notarytool submit --wait exits 0 even when status is Invalid; now parse the JSON, check status == Accepted, and dump notarytool log so we see Apple's actual rejection reason. - Remove the post-rename re-sign step: renaming the .app wrapper does not invalidate the seal, and re-signing the outer bundle can desync nested code seals (likely cause of the Invalid status). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apple rejected v0.2.1 because xcodebuild left two nested binaries without a Developer ID signature + secure timestamp: Sparkle's deeply-nested Updater.app and the mediaremote-adapter test client (copied in as a plain resource). Add a step that signs every nested bundle/dylib inside-out, plus loose Mach-O files in Resources, then re-seals the outer app while preserving its resolved entitlements so network.client survives. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.2.2 still failed: Sparkle.framework/Versions/B/Autoupdate is a bare-named executable my extension-based find missed. Replace the pattern matching with two comprehensive passes — every Mach-O file (detected via `file`), then every bundle wrapper — both deepest-path first. Catches all of Sparkle's nested helpers regardless of naming. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Circle badge 36->26pt, initial 18->13pt - Center the badge + text block horizontally; VStack text centered - Tap anywhere on the incoming view to dismiss it immediately (clears lastIncoming + closes the notch) instead of waiting 6s Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Clearer about what the ping means. Updated in all three places the phrase appears: notch view, macOS notification title, ntfy Title header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Matches the wave metaphor and the hand.wave.fill icon. Updated in the notch view, macOS notification title, and ntfy Title header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ryption The hardcoded 12-char nudgeNonce was in the public repo, so it wasn't really a secret — anyone reading the source could ping the team. This swaps it for a team password the user types on first launch, stored in Keychain. - New NudgeTeamSecret: HKDF-SHA256 derives two values from one password (12-hex topic nonce via info="nudge-topic-id-v1", 32-byte AES key via info="nudge-encryption-key-v1"). Fixed app-level salt = domain separator, not per-user (everyone must derive the same values). - NudgeTransport: sender name is AES-GCM sealed (.combined, base64) on send, opened on receive. Failed decrypts silently drop. Title header is now generic "Nudge" — never leaks the sender in plaintext. - New NudgePasswordPickerView (6-char min, show/hide toggle, Keychain note). - OnboardingView gains a .password step; flips firstLaunch only after both identity and password are set. App resumes onboarding at whichever step is missing. - Transport gates on CombineLatest(identity, hasPassword) — won't start until both present. - Settings: nonce display replaced with team-password status row + "Change password…" sheet (hosts the picker). - Menubar: drops nonce display, shows identity + password status. Migration: existing v0.2.6 installs have an identity but no password. On first v0.3.0 launch they'll be sent through the password step. Existing v0.2.x topics are no longer reachable — that's the breaking change the security upgrade requires. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renders the 👋 emoji onto a warm sunset rounded-square at all 7 distinct macOS app-icon pixel sizes (16, 32, 64, 128, 256, 512, 1024). Generator lives at scripts/generate-app-icon.swift — re-run any time to tweak the emoji, gradient, or sizing. Drops the old notch-stage-icon2 PNGs (10 unused files). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- NudgeStats: per-week sent/received counts persisted in UserDefaults,
plus a peer-leaderboard table populated from data piggybacked on
incoming pings. Bucketed by ISO year-week ("2026-W20").
- Wire format extended from raw sender string to encrypted JSON
{v:1, sender, weekSends}. Subscribe decoder tries JSON first,
falls back to plain-string for v0.3.0-v0.3.2 pings.
- Menu bar: switches to label-based MenuBarExtra so the wave icon
can carry your weekly send count next to it (hidden when 0).
- Settings: new "This week (YYYY-Www)" section with leaderboard +
per-peer sent/received breakdowns.
Sends report a count that already includes the current ping (increment
happens before the broadcast), and the peer-leaderboard is monotonic
to ignore stale messages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the hardcoded [Max, Leon, David] array. Anyone can install the
app, type their own name, and join — discovery is automatic via "hello"
broadcasts on a shared encrypted team topic.
Wire / topic changes:
- One shared topic per team: nudge-team-<HKDF(password)> instead of
per-user topics. Recipient name moves into the encrypted payload.
- v2 payload: {v, type, sender, to?, weekSends}. type ∈ {ping, hello}.
Receivers ignore pings addressed to someone else.
- Transport sends a hello on startReceiving and every ~30min via a
heartbeat task. Also re-sends hello on network-becomes-satisfied.
UX changes:
- NudgeIdentityPickerView: TextField with 1–32 char, no-colon validation.
- NudgeRoster: new @mainactor observable storing name -> last-seen,
persisted to UserDefaults. Cleared when team password changes.
- NudgeNotchView: ping buttons read roster.others(excluding: me).
Empty state: "Waiting for teammates…".
- NudgeStats: leaderboard iterates roster.everyone(including: me)
instead of the hardcoded array. Sent/received breakdowns now read
directly from the stored counts keys.
- Settings: name TextField + Save. New "Known teammates" section with
relative last-seen. Password change clears the roster + forces the
transport to resubscribe on the new topic.
Breaking change: v0.4.0 ↔ v0.3.x are on different topics (different
shape). Everyone on the team has to upgrade together. The previous
team-password upgrade dance applies.
Privacy note: all team messages share one topic — every team member
receives every team member's pings (still encrypted with the team key).
Outsiders see ciphertext.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops ~100 files worth of Boring Notch infrastructure we don't use anymore — music, calendar, battery, HUD, shelf, webcam, drag, XPC, SkyLight overlay, Sparkle UI helpers, etc. Live source set goes from ~130 .swift files to ~32. What got deleted: - managers/ — Music, Calendar, Webcam, BatteryActivity, Brightness, Volume, Image services - MediaControllers/ — AppleMusic, Spotify, NowPlaying, YouTubeMusic - components/ — Music, Calendar, Webcam, Shelf, Tabs, Tips, Live activities, plus orphan single-file views (LottieView, AnimatedFace, EmptyState, ProgressIndicator, TestView, WhatsNewView, BottomRoundedRectangle, HoverButton) - components/Notch/ — BoringExtrasMenu, BoringHeader, NotchHomeView, and the unused BoringNotchWindow.swift (replaced by the slim BoringNotchSkyLightWindow which is now a plain NSPanel — drops the SkyLightWindow SPM dep in the next pass) - components/Onboarding/ — MusicControllerSelectionView, PermissionsRequestView, SparkleView, WelcomeView - components/Settings/ — EditPanelView, ListItemPopover, MusicSlotConfigurationView, SoftwareUpdater - observers/ — DragDetector, FullscreenMediaDetection, MediaKeyInterceptor - XPCHelperClient/, Providers/, menu/ - helpers/ — AppIcons, AppleScriptHelper, ApplicationRelauncher, AudioPlayer, Clipboard+Content, MediaChecker, AssociatedObject - models/ — BatteryStatusViewModel, CalendarModel, EventModel, MusicControlButton, PlaybackState, SharingStateManager - extensions/ — ActionBar, Button+Bouncing, Color+AccentColor, DataTypes+Extensions, KeyboardShortcutsHelper, MouseTracker, NSImage+Extensions, NSItemProvider+LoadHelpers, NSMenu+AssociatedObject, URL+SecurityScoped - animations/HelloAnimation.swift, boring.m4a (welcome sound) What got slimmed (kept but shrunk): - BoringViewModel — dropped webcam/drop-target/fullscreen-detector/ isCameraExpanded/isHoveringCalendar/isBatteryPopoverActive/etc. - BoringViewCoordinator — dropped sneakPeek, expandingView, toggleSneakPeek, toggleExpandingView, helloAnimationRunning, hudReplacement wiring, accessibilityObserver, alwaysShowTabs, openLastTabByDefault, musicLiveActivityEnabled, currentView, legacy screen-name migration - Constants — dropped all music/calendar/battery/HUD/shelf/download/ media-controller Defaults keys. Kept just the keys live Nudge code paths actually read. - enums/generic — dropped SettingsEnum, DownloadIndicator/IconStyle, MirrorShapeEnum, SliderColorEnum, NotchViews, ContentType. - AppDelegate — dropped statusItem, whatsNewWindow, timer, togglePopover, showMenu, quitAction, isScreenLocked, enableSkyLightOnAllWindows, disableSkyLightOnAllWindows. - Shortcuts/ShortcutConstants — dropped 5 unused shortcuts, kept only toggleNotchOpen. - entitlements — pared to app-sandbox + network.client. Dropped camera, calendars, files, network.server, apple-events, temporary-exception entries. What's still on the next pass (Tier 3): - SPM dependencies: Sparkle, Lottie, LaunchAtLogin, MacroVisionKit, SkyLightWindow, AsyncXPCConnection, SwiftUIIntrospect, Pow, swift-collections (none of these are imported by remaining code). - BoringNotchXPCHelper target + mediaremote-adapter resources. - updater/ directory. Build behavior: pbxproj line count dropped from ~1551 to ~1171. The existing release workflow's "sign every nested binary" pass should still notarize cleanly — fewer nested things to sign now. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… (Tier 3) Final pass of the upstream cleanup. With Tier 1+2 having stripped all the .swift files that imported these, they were pure bloat. SPM dependencies removed from the project (none imported by any remaining code): - Sparkle, Lottie (lottie-spm), LaunchAtLogin-Modern, MacroVisionKit, SkyLightWindow, AsyncXPCConnection, SwiftUIIntrospect, Pow, swift-collections (Collections) Kept (still imported): Defaults, KeyboardShortcuts. Targets / embedded resources removed: - The whole BoringNotchXPCHelper.xpc target (PBXNativeTarget, XCConfigurationList, both build configs, the synchronized root group, the ContainerItemProxy + TargetDependency that linked it, the Embed XPC Services build phase entry, and the XPCHelperClient group). The directory on disk is gone too. - The mediaremote-adapter framework + mediaremote-adapter.pl + MediaRemoteAdapterTestClient (Frameworks + Embed Frameworks + the PBXGroup + the file refs). Directory on disk gone. - The Sparkle appcast template at updater/. - TODO_V2_CLEANUP.md (its work is done). pbxproj numbers: 1171 -> 866 lines (-26%). plutil -lint passes. Workflow knock-on: the release workflow's "Sign every nested binary inside-out" pass becomes mostly a no-op now — Sparkle's nested helper binaries and the test client are no longer embedded, so there's nothing for xcodebuild to miss. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.