crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

DateCommit messageAuthorFiles+-
2026-06-26 22:08Centralise CloudQuery desired key listsMichael Camilleri3+104-15
2026-06-26 22:01Fold shared clock opens into the Player open burstMichael Camilleri2+18-0
2026-06-26 21:56Ignore stale PlayerRoster share refreshesMichael Camilleri1+14-4
2026-06-26 21:51Quiet unchanged badge refresh diagnosticsMichael Camilleri3+42-25
2026-06-26 21:45Make log line more accurateMichael Camilleri1+1-1
2026-06-26 21:38Coalesce duplicate accountSeen pushesMichael Camilleri1+22-4
2026-06-26 13:26Expand diagnostic logging for summary bannersMichael Camilleri3+108-3
2026-06-26 13:04Rotate one-player collaborator colours within companion setsMichael Camilleri3+58-7
2026-06-26 10:09Heal legacy games that are still erroneously unreadMichael Camilleri3+47-6
2026-06-26 09:55Heal legacy games that are erroneously unreadMichael Camilleri5+111-6
2026-06-26 09:35Fixed app badging on legacy puzzlesMichael Camilleri2+63-10
2026-06-26 08:46Preserve solve-clock time across freshens, completion, and the archiveMichael Camilleri10+110-27
2026-06-26 08:09Add a synced solve-time clockMichael Camilleri13+786-5
2026-06-26 05:45Display an unread dot on completed gamesMichael Camilleri2+18-7
2026-06-26 05:04Mint the notification content key at share timeMichael Camilleri1+9-0
2026-06-26 02:19Harden link creation and decline retries against share racesMichael Camilleri2+39-2
2026-06-26 01:34Trim whitespace around rebus entriesMichael Camilleri2+34-1
2026-06-26 00:51Fix plural errorMichael Camilleri1+2-2
2026-06-26 00:51Bump Crossmate-flavoured XD versionMichael Camilleri1+1-1
2026-06-26 00:39Preserve puzzle titles from external providersMichael Camilleri2+27-2
2026-06-26 00:22Pick collaborator colours that stay distinct when washed outMichael Camilleri4+160-24
2026-06-25 21:37Make the puzzle's share link and direct invites mutually exclusiveMichael Camilleri1+35-4
2026-06-25 21:17Free the seat and notify on invitation declineMichael Camilleri6+219-26
2026-06-25 10:55Build the joined game from the invite to skip the share fetchMichael Camilleri6+135-17
2026-06-25 09:21Stop collaborator push churn from dragging out a share joinMichael Camilleri3+137-26
2026-06-25 03:46Retry transient push-worker sends and wait for connectivityMichael Camilleri1+62-9
2026-06-24 21:33Encrypt the push payload so the push worker can't read itMichael Camilleri15+508-76
2026-06-24 19:31Tweak log line when counting zonesMichael Camilleri1+17-10
2026-06-24 19:13Tear down the archive backup when a finished game is deletedMichael Camilleri3+41-65
2026-06-24 18:47Use a broader diagnostic to identify orphan zonesMichael Camilleri1+38-55
2026-06-24 18:27Stop cursor moves bumping a game's Game List timestampMichael Camilleri2+92-9
2026-06-24 16:59Improve user-facing messagesMichael Camilleri8+81-19
2026-06-24 15:43Seed the share-screen checkmarks before the first frameMichael Camilleri3+30-3
2026-06-24 15:13Show already-invited friends when re-opening the share screenMichael Camilleri3+43-3
2026-06-24 12:23Remove the unused File and View menus on iPadMichael Camilleri1+13-1
2026-06-23 22:17Coalesce session-end pushes into one silent per-game tileMichael Camilleri10+413-20
2026-06-22 21:42Stop the puzzle command menu hanging the menu builderMichael Camilleri1+19-7
2026-06-22 20:07List puzzle shortcuts in the hold-⌘ overlay on iPadMichael Camilleri5+121-19
2026-06-22 19:11Fix hardware-keyboard rebus entry on iPadMichael Camilleri1+12-1
2026-06-22 11:19Notify the room when a player joins a shared gameMichael Camilleri12+211-30
2026-06-22 06:26Preserve clue emphasis as inline .xd markupMichael Camilleri9+405-16
2026-06-22 03:23Use the system keyboard for rebus entryMichael Camilleri2+52-10
2026-06-22 01:08Update CmVersion fieldsMichael Camilleri2+4-2
2026-06-22 01:06Accept slash-separated answers on .xd cluesMichael Camilleri2+92-5
2026-06-22 00:06Support blank squares in puzzlesMichael Camilleri6+201-12
2026-06-21 16:20Separate the random puzzle trigger from its menusMichael Camilleri1+35-19
2026-06-21 15:18Stop a second game invite from revoking the firstMichael Camilleri1+37-14
2026-06-20 22:18Discard a finished game's peer-change ledgerMichael Camilleri3+47-4
2026-06-20 21:56Keep a ledger of peer changesMichael Camilleri9+504-230
2026-06-20 07:22Tweak wording of tips furtherMichael Camilleri1+15-15
2026-06-20 07:09Fix alignment of 'Players' headingMichael Camilleri1+3-4
2026-06-20 05:55Spread collaborator colours evenly across the eligible paletteMichael Camilleri1+30-17
2026-06-20 05:52Recover root Game conflicts while sharingMichael Camilleri1+17-1
2026-06-20 05:16Refit the scoreboard into the Puzzle Header at larger type sizesMichael Camilleri2+67-32
2026-06-20 04:07Tweak wording of nudge tipMichael Camilleri1+1-1
2026-06-20 03:50Use 'puzzle' rather than 'game'Michael Camilleri2+6-6
2026-06-20 03:48Add onboarding tipsMichael Camilleri12+491-13
2026-06-20 01:22Change resume icon in Game ListMichael Camilleri1+1-1
2026-06-20 01:16Fix vertical height of rebus scrim on iPadMichael Camilleri1+8-6
2026-06-20 01:08Hint that the Share Game friend row scrollsMichael Camilleri1+24-0
2026-06-20 00:31Remove the dead .play presence notificationMichael Camilleri5+16-42
2026-06-19 14:04Stop gating push notifications on the stale presence leaseMichael Camilleri6+51-85
2026-06-19 11:26Fix nudge button cooldownMichael Camilleri2+79-60
2026-06-19 09:27Fix nudge button dimming behaviourMichael Camilleri7+88-50
2026-06-19 08:37Use glass effect button for nudgesMichael Camilleri2+116-25
2026-06-19 08:20Replay nicknames after friendship bootstrapMichael Camilleri3+151-1
2026-06-19 07:42Adjust spacing of header scoreboard againMichael Camilleri1+1-1
2026-06-19 07:32Adjust spacing of header scoreboardMichael Camilleri1+4-2
2026-06-19 07:01Add a Simulator demo seedMichael Camilleri2+223-2
2026-06-19 07:01Fold the nudge button into the scoreboard's Players headingMichael Camilleri1+56-51
2026-06-19 06:58Derive collaborator colours per gameMichael Camilleri10+149-80
2026-06-18 22:11Derive in-game collaborator colours from the Friends listMichael Camilleri4+40-18
2026-06-18 15:33Retire the per-peer Moves-snapshot baselineMichael Camilleri5+12-148
2026-06-18 13:22Unify the catch-up banner and away-change highlightsMichael Camilleri12+318-539
2026-06-18 07:45Ignore pairwise friend bootstraps for other playersMichael Camilleri3+26-0
2026-06-18 02:56Render share-link previews for non-square gridsMichael Camilleri10+267-116
2026-06-18 02:31Store public-link ticket state in the Ping payloadMichael Camilleri1+54-40
2026-06-18 02:21Revert use of gradient in stripMichael Camilleri2+1-19
2026-06-18 01:56Derive the Game List strip order from one participant listMichael Camilleri2+28-23
2026-06-18 01:50Add a sheen and separators to the participant stripMichael Camilleri2+32-10
2026-06-18 00:56Increase player limit to threeMichael Camilleri4+184-37
2026-06-17 23:59Ink correct pencil entries on checkMichael Camilleri2+20-7
2026-06-17 23:48Order Game List players by puzzle scoreMichael Camilleri5+101-38
2026-06-17 22:29Adjust spacing of nudge button on the iPadMichael Camilleri1+1-1
2026-06-17 21:44Expose nudges from the scoreboardMichael Camilleri4+154-7
2026-06-17 21:01Add user to player popover in the Game ListMichael Camilleri5+85-18
2026-06-17 20:50Remove nudge icon from menuMichael Camilleri1+1-3
2026-06-17 20:35Replace session-begin pushes with manual nudgesMichael Camilleri19+291-374
2026-06-17 19:15Derive friend avatar colours in consistent mannerMichael Camilleri4+14-7
2026-06-17 06:19Show shared participants on in-progress Game List rowsMichael Camilleri9+426-131
2026-06-17 04:04Support puzzles with number and symbol squaresMichael Camilleri5+268-75
2026-06-17 02:02Retain account-seen pushes brieflyMichael Camilleri1+12-8
2026-06-17 00:59Display diagnostics log in sheet when called in-gameMichael Camilleri1+26-9
2026-06-16 21:14Reposition share link composite imageMichael Camilleri1+56-71
2026-06-16 21:01Composite app icon onto share link preview imageMichael Camilleri1+149-15
2026-06-16 16:09Soften recent-change cell bordersMichael Camilleri2+12-14
2026-06-16 14:49Clarify removed-puzzle announcements on the Game ListMichael Camilleri3+14-4
2026-06-16 14:24Fetch the accepted share zone directlyMichael Camilleri2+95-12
2026-06-16 13:59Show the joining screen from Game List acceptsMichael Camilleri3+54-9
2026-06-16 13:23Explain a share-link join that opens no puzzleMichael Camilleri4+74-6
2026-06-16 11:43Wait on the joining screen until a shared puzzle is readyMichael Camilleri3+71-12
2026-06-16 11:04Fix joining a shared puzzle from a link or inviteMichael Camilleri4+229-28
2026-06-16 08:03Fix support for 3-segment OS numbersMichael Camilleri3+9-6
2026-06-16 08:01Support iOS/iPadOS 17.5Michael Camilleri6+49-12
2026-06-16 03:23Add development notesMichael Camilleri13+1882-1
2026-06-16 02:58Ignore checks when highlighting changes on rejoinMichael Camilleri3+112-18
2026-06-16 02:40Gate push notifications on game participationMichael Camilleri13+639-77
2026-06-15 22:11Purge the local store on an iCloud account switchMichael Camilleri4+86-2
2026-06-15 21:44Refresh the library row when a puzzle upgrade rewrites its gridMichael Camilleri1+21-3
2026-06-15 21:29Rename engagement-related worker filesMichael Camilleri5+24-24
2026-06-15 21:12Group the Views by featureMichael Camilleri37+2956-2866
2026-06-15 20:24Add colour selection to SettingsMichael Camilleri1+52-0
2026-06-15 11:35Recompose notification text to apply a friend's nicknameMichael Camilleri13+303-248
2026-06-15 09:51Preview the grid on internal invitationsMichael Camilleri6+73-4
2026-06-15 09:17Show canonical rebus fills on a solved puzzleMichael Camilleri1+18-2
2026-06-15 07:33Highlight cells a peer changed while awayMichael Camilleri10+382-18
2026-06-15 02:39Stop counting checked peer letters as session-summary fillsMichael Camilleri4+120-28
2026-06-14 23:43Add logging to notification rewritingMichael Camilleri1+40-9
2026-06-14 21:14Update joining message to assure userMichael Camilleri1+24-1
2026-06-14 16:45Show the puzzle while a shared link is being joinedMichael Camilleri15+823-54
2026-06-14 05:12Fix main-actor isolation warnings in Core Data background closuresMichael Camilleri2+7-3
2026-06-14 04:55Correct the foreground flag from the OS state on push wakesMichael Camilleri1+14-0
2026-06-13 23:52Lock orientation on iOSMichael Camilleri2+6-0
2026-06-13 21:25Notify for a game invite once (and not over the Game List)Michael Camilleri2+35-4
2026-06-13 21:07Fix fill letters and Clue Bar colour in Dark ModeMichael Camilleri3+22-8
2026-06-13 20:51Re-enqueue recovered Game/Moves/Player saves after a lost tag raceMichael Camilleri1+25-3
2026-06-13 20:34Re-enqueue versioned Decision saves after a lost tag raceMichael Camilleri1+15-12
2026-06-13 19:55Add logging to Decision applicationMichael Camilleri1+12-0
2026-06-13 13:15Fix nickname Decisions never syncing across a user's devicesMichael Camilleri2+61-4
2026-06-13 06:44Add support for command-line options to screenshot scriptMichael Camilleri1+19-4
2026-06-13 04:54Suggest user set profile name on first launchMichael Camilleri2+50-7
2026-06-13 00:03Gate share links on seat capacity instead of a global switchMichael Camilleri2+41-30
2026-06-12 23:36Name the puzzle in short-link previewsMichael Camilleri4+124-30
2026-06-12 23:17Serve share links through a link-shortening workerMichael Camilleri12+400-101
2026-06-12 14:59Keep unread notifications through presence leasesMichael Camilleri4+28-3
2026-06-12 14:07Truncate identifiers in the diagnostics logMichael Camilleri3+137-1
2026-06-12 13:48Seed the share sheet's invite limit from the shareMichael Camilleri3+47-5
2026-06-12 13:23Settle public-link joins with a consumable seat ticketMichael Camilleri2+127-12
2026-06-12 09:54Limit shared puzzles to one inviteeMichael Camilleri5+165-44
2026-06-12 09:23Add script to generate marketing imageMichael Camilleri5+349-60
2026-06-12 08:04Prevent animated transition when changing nicknamesMichael Camilleri1+1-2
2026-06-12 07:59Use nicknames in announcement bannersMichael Camilleri3+45-1
2026-06-12 07:41Support adding nicknames to friendsMichael Camilleri18+744-18
2026-06-12 03:18Log the worker's publish delivery counts in diagnosticsMichael Camilleri2+44-8
2026-06-12 02:41Reenable sound for session begin notificationsMichael Camilleri1+3-10
2026-06-12 02:38Add per-kind notification preferencesMichael Camilleri7+211-16
2026-06-12 01:46Add store-and-forward window for meaningful eventsMichael Camilleri1+21-4
2026-06-12 01:26Add a Crossmates sheet for viewing and blocking friendsMichael Camilleri5+158-38
2026-06-12 00:44Register engagement room secrets instead of trusting first connectMichael Camilleri5+239-42
2026-06-11 23:44Preserve the failing Core Data store before destructive recoveryMichael Camilleri3+135-7
2026-06-11 23:30Guard push secret generation and document the address capability boundaryMichael Camilleri2+20-5
2026-06-11 23:24Derive the APNs environment from a single build settingMichael Camilleri5+28-7
2026-06-11 22:55Remove bearer token support from Cloudflare WorkerMichael Camilleri2+4-20
2026-06-11 20:44Remove diagnostic logging in Cloudflare WorkerMichael Camilleri1+0-205
2026-06-11 20:27Fix App Attest assertion verification in the push workerMichael Camilleri2+410-53
2026-06-11 07:17Authenticate push worker requests with App AttestMichael Camilleri8+944-43
2026-06-11 05:45Cap the Diagnostics event list at the last 50 entriesMichael Camilleri1+13-2
2026-06-11 05:40Mirror EventLog breadcrumbs into the unified system logMichael Camilleri1+21-0
2026-06-11 05:39Skip session pushes to recipients leased into the gameMichael Camilleri3+93-13
2026-06-11 03:41Add profile name to Settings viewMichael Camilleri1+76-0
2026-06-11 02:52Sync display names as versioned 'name' Decisions in friend zonesMichael Camilleri15+809-252
2026-06-10 23:53Derive a completed game's thumbnail from the completion latchMichael Camilleri3+116-4
2026-06-10 15:12Ignore unchanged self Player echoes and log read-cursor adoptionsMichael Camilleri3+33-6
2026-06-10 13:12Collapse session timers into a per-open-game PuzzleSession controllerMichael Camilleri7+620-265
2026-06-10 08:59Extract account push credentials and the replay cache from AppServicesMichael Camilleri6+440-350
2026-06-10 08:30Extract the invite/ping manager from AppServicesMichael Camilleri6+672-595
2026-06-10 08:11Split AppServices into composed session/engagement/badge servicesMichael Camilleri9+1340-1137
2026-06-10 07:33Scope Moves enqueues to the current author's rowMichael Camilleri2+134-18
2026-06-10 04:07Fix incorrect commentMichael Camilleri1+10-4
2026-06-10 04:05Trace inbound-apply save failures to the diagnostics logMichael Camilleri2+61-32
2026-06-10 03:57Split the badge ledger's seen horizon from its suppression horizonMichael Camilleri3+188-9
2026-06-10 02:58Split the read watermark from the presence leaseMichael Camilleri10+226-84
2026-06-09 19:09Stop draining CKSyncEngine on every live Moves editMichael Camilleri6+70-30
2026-06-09 18:02Remove replay tuning from Settings menuMichael Camilleri2+7-76
2026-06-09 17:56Remove engagement menu optionMichael Camilleri4+5-42
2026-06-09 17:40Grace a lapsed read lease before treating a peer as goneMichael Camilleri7+130-25
2026-06-09 16:11Reconcile badge ledger repeatedlyMichael Camilleri1+8-1
2026-06-09 14:18Stop forcing CloudKit drains on leave-path Player sendsMichael Camilleri5+62-36
2026-06-09 10:38Window session-end pushes on a per-peer notified-through markMichael Camilleri5+119-10
2026-06-09 02:07Persist the diagnostics event log across launchesMichael Camilleri2+97-5
2026-06-09 01:55Fix warning about unused variableMichael Camilleri1+1-1
2026-06-09 01:44Reassert the active read lease after a sibling collapseMichael Camilleri3+53-98
2026-06-09 00:31Recompute the read horizon from sibling leasesMichael Camilleri3+110-45
2026-06-08 23:18Refuse to collapse an active read lease from a sibling horizonMichael Camilleri3+36-11
2026-06-08 22:49Converge the catch-up baseline regardless of cursor recencyMichael Camilleri2+106-11
2026-06-08 15:09Allow the account push secret to be rotatedMichael Camilleri6+313-62
2026-06-08 14:20Preserve unknown provider sessionsMichael Camilleri8+242-54
2026-06-08 13:32Sync the catch-up baseline across devicesMichael Camilleri10+259-73
2026-06-07 22:45Prune stale invite and badge rowsMichael Camilleri2+136-12
2026-06-07 21:42Consume declined invite Pings across devicesMichael Camilleri3+70-24
2026-06-07 10:53Use symbols rather than labels where possibleMichael Camilleri6+41-10
2026-06-07 10:23Tweak announcement wordingMichael Camilleri3+18-8
2026-06-07 09:29Refine NYT random puzzle selectionMichael Camilleri3+56-22
2026-06-07 07:31Bound archive replay retries to cold launchMichael Camilleri3+50-12
2026-06-07 07:06Consume unactionable invite Pings before presentationMichael Camilleri2+111-20
2026-06-07 06:36Tweak announcement formattingMichael Camilleri2+4-4
2026-06-07 06:11Adjust font size in announcement bannersMichael Camilleri1+2-2
2026-06-07 05:53Restyle announcement bannersMichael Camilleri6+70-56
2026-06-07 04:54Add random puzzle button to provider's browse viewMichael Camilleri1+146-1
2026-06-07 00:47Rename field on Archive record typeMichael Camilleri1+2-2
2026-06-06 23:43Archive finished shared games to each player's private zoneMichael Camilleri9+1114-5
2026-06-06 17:27Delete the invite Ping when leaving a shared gameMichael Camilleri2+52-0
2026-06-06 15:44Hoist clue-at-position lookup onto PuzzleMichael Camilleri3+12-18
2026-06-06 15:36Retain diagnostics events by time, not countMichael Camilleri1+30-2
2026-06-06 15:23Move iPadOS's Clue List during replayMichael Camilleri2+38-5
2026-06-06 14:15Add express gameID to Puzzle GridMichael Camilleri1+1-0
2026-06-06 14:10Add logging to app badgingMichael Camilleri2+18-0
2026-06-06 13:57Count pending invites toward the app-icon badgeMichael Camilleri8+151-11
2026-06-06 06:52Shrink the Puzzle Header at large Dynamic TypeMichael Camilleri1+18-1
2026-06-06 05:54Adjust placement of replay controlsMichael Camilleri1+6-2
2026-06-06 04:24Show replay progress in Success PanelMichael Camilleri8+157-35
2026-06-06 03:45Add cache busting value for undo/redoMichael Camilleri1+9-0
2026-06-06 03:37Fix header pinning incorrectlyMichael Camilleri1+1-1
2026-06-06 03:36Remove superfluous copy buttonMichael Camilleri1+0-4
2026-06-06 02:37Bump maximum log entries to 1000Michael Camilleri1+1-1
2026-06-06 02:33Clarify replay playback controlsMichael Camilleri10+383-355
2026-06-06 01:55Support sharing of diagnostics via a text fileMichael Camilleri1+37-1
2026-06-06 01:45Widen scope where push notifications are in Notification CentreMichael Camilleri1+2-2
2026-06-06 00:34Add logging for lease mintingMichael Camilleri1+10-0
2026-06-06 00:04Add logging for foreign Player writesMichael Camilleri1+51-0
2026-06-05 21:47Render the local cursor behind the grid, not in every cellMichael Camilleri2+97-52
2026-06-05 20:50Keep puzzle grid layers aligned on iPadMichael Camilleri1+110-50
2026-06-05 13:39Add logging for badges on launchMichael Camilleri1+65-0
2026-06-05 13:20Adopt a sibling's push secret before minting a competing oneMichael Camilleri1+28-0
2026-06-05 11:18Make account decision payloads durable and adopt on conflictMichael Camilleri1+70-11
2026-06-05 10:31Derive per-game push addresses from one account secretMichael Camilleri7+300-139
2026-06-05 07:36Unify completion detection into one provenance-tagged eventMichael Camilleri3+105-39
2026-06-05 06:05Log remote peer presence transitionsMichael Camilleri1+47-0
2026-06-05 05:20Treat pending private zones as freshen-readyMichael Camilleri5+104-21
2026-06-05 05:19Rename directory to WorkersMichael Camilleri7+3-2
2026-06-05 03:27Update AGENTS.mdMichael Camilleri2+15-11
2026-06-04 23:20Show wrong-fill alert only for local attemptsMichael Camilleri3+45-15
2026-06-04 15:30Refresh the roster on new contributors onlyMichael Camilleri5+164-23
2026-06-04 14:53Apply remote moves as a diff in GameStore.restoreMichael Camilleri1+31-6
2026-06-04 12:37Handle deleting games from the notification ledgeMichael Camilleri4+65-12
2026-06-04 06:33Seed Core Data unread values into the badge ledger for the NSEMichael Camilleri5+79-9
2026-06-04 05:53Propagate seen horizons to sibling devicesMichael Camilleri1+27-5
2026-06-04 05:43Track badge unread state with horizonsMichael Camilleri4+121-52
2026-06-04 05:25Add account-level silent push routingMichael Camilleri8+281-14
2026-06-03 23:04Tweak grace periodsMichael Camilleri1+2-2
2026-06-03 22:51Restore observed cell state when undoing local editsMichael Camilleri4+95-5
2026-06-03 22:49Add logging for cookie errorsMichael Camilleri3+43-5
2026-06-03 06:36Nudge absent devices to upload replay journalsMichael Camilleri6+94-22
2026-06-03 05:09Lengthen the cursor debounce while a live room carries itMichael Camilleri3+75-17
2026-06-03 04:41Add name to creditsMichael Camilleri1+12-0
2026-06-03 02:31Render peer cursor tints behind the grid, not in every cellMichael Camilleri2+141-46
2026-06-02 20:32Collapse the cell-mark triple to a single markCodeMichael Camilleri24+317-256
2026-06-02 19:37Memoise the assembled replay timeline per gameMichael Camilleri4+131-21
2026-06-02 13:56Cache game replays in Core DataMichael Camilleri7+308-30
2026-06-02 13:15Set a maximum width for scoreboard in Success PanelMichael Camilleri1+5-1
2026-06-02 12:43Replay puzzles with a fast-forward controlMichael Camilleri4+212-5
2026-06-02 08:45Add version information to diagnostic logsMichael Camilleri1+11-0
2026-06-02 08:02Summarise a paused session by gesture not touchMichael Camilleri7+390-89
2026-06-02 05:14Extract ensureInBackground for guaranteed flushesMichael Camilleri1+45-67
2026-06-02 05:02Keep a completed puzzle's authorship correctMichael Camilleri5+78-14
2026-06-02 02:20Harden the engagement room and keep idle sockets warmMichael Camilleri2+86-4
2026-06-02 01:54Gate the engagement socket on foregroundMichael Camilleri2+23-0
2026-06-01 22:36Add logging to push notificationsMichael Camilleri7+327-10
2026-06-01 15:37Fix Swift Concurrency warningsMichael Camilleri4+4-5
2026-06-01 15:19Make a completed game terminal and read-onlyMichael Camilleri6+275-7
2026-06-01 15:17Flush buffered cell edits under a background assertionMichael Camilleri2+43-3
2026-06-01 08:06Reduce log noise regarding settled journalsMichael Camilleri1+8-0
2026-06-01 07:59Settle redundant journal uploads instead of retryingMichael Camilleri1+29-3
2026-06-01 07:19Ensure a completed game's replay journal gets uploadedMichael Camilleri4+127-20
2026-06-01 06:29Add logging to replay downloadsMichael Camilleri3+46-4
2026-06-01 05:54Coalesce a bulk gesture into one live updateMichael Camilleri4+194-69
2026-06-01 02:43Renew the read lease only while the app is foregroundedMichael Camilleri2+76-7
2026-06-01 00:48Hold the replay scrubber's height while it loadsMichael Camilleri1+7-4
2026-05-31 23:13Tint the replay playhead with the acting author's colourMichael Camilleri5+64-14
2026-05-31 23:11Retire the live session when a puzzle is completedMichael Camilleri5+29-1
2026-05-31 14:38Add replay support to Success PanelsMichael Camilleri14+707-31
2026-05-31 05:07Carry session-push semantics in an opaque payloadMichael Camilleri10+466-43
2026-05-31 00:02Restore the typing direction when undoing a letterMichael Camilleri7+126-35
2026-05-30 21:40Defer the session-begin push behind a grace windowMichael Camilleri2+61-10
2026-05-30 21:20Build the cross-device replay data layerMichael Camilleri9+459-7
2026-05-30 20:03Gate the peer cursor and engagement teardown on the readAt leaseMichael Camilleri4+256-97
2026-05-30 14:39Stop the engagement backstop from re-leasing readAt in the backgroundMichael Camilleri2+12-2
2026-05-30 12:35Give MovesUpdater's flush context a merge policyMichael Camilleri1+8-0
2026-05-30 12:28Stop dropping move-journal entries on Core Data merge conflictsMichael Camilleri4+18-6
2026-05-30 06:27Follow the cursor on undo and redoMichael Camilleri5+71-27
2026-05-30 04:46Wire up undo/redo controls in the puzzle gridMichael Camilleri3+68-16
2026-05-30 01:57Upload move journal at game completionMichael Camilleri8+554-1
2026-05-29 23:54Fix direct fetches dropping collaboration fieldsMichael Camilleri2+32-8
2026-05-29 22:12Add move journal with undo/redoMichael Camilleri9+877-51
2026-05-29 12:22Group revoked games into their own list sectionMichael Camilleri2+45-2
2026-05-29 12:14Increase spacing in date pickerMichael Camilleri1+1-1
2026-05-29 11:32Tighten debouncing gatingMichael Camilleri1+12-0
2026-05-29 11:04Change label for manual engagementsMichael Camilleri1+1-1
2026-05-29 07:42Add remote-only active-puzzle debounceMichael Camilleri1+35-1
2026-05-29 07:19Coalesce overlapping game-list refreshesMichael Camilleri1+25-0
2026-05-29 07:06Log visible push notificationsMichael Camilleri4+105-0
2026-05-29 06:56Reduce CloudKit polling after fetch fan-out changesMichael Camilleri2+126-57
2026-05-29 06:32Reduce CloudKit fetch fan-out during collaborationMichael Camilleri5+129-161
2026-05-29 04:46Rendezvous live-engagement rooms on the Game recordMichael Camilleri8+271-477
2026-05-29 03:26Harden live-engagement reconnectionMichael Camilleri5+172-23
2026-05-29 02:00Improve success likelihood of session-end pushMichael Camilleri1+47-2
2026-05-29 01:24Address push notifications by capability tokenMichael Camilleri12+429-80
2026-05-28 23:03Navigate to puzzle after creationMichael Camilleri2+6-2
2026-05-28 22:29Load Schrödinger puzzles as rebusesMichael Camilleri2+125-8
2026-05-28 14:00Rearchitect session summary push notificationsMichael Camilleri10+382-349
2026-05-28 05:33Update app badge from Notification Service ExtensionMichael Camilleri11+406-26
2026-05-28 04:27Navigate to game on push notification tapMichael Camilleri4+9-135
2026-05-28 03:06Refresh peer baselines on sibling readAt syncMichael Camilleri3+98-1
2026-05-28 02:44Share session snapshot across an author's devicesMichael Camilleri11+337-98
2026-05-28 01:02Stop tracking local build server configMichael Camilleri2+1-20
2026-05-27 22:52Use session-activity calculations consistentlyMichael Camilleri11+697-713
2026-05-27 06:37Use private struct rather than long tuple for return valueMichael Camilleri2+66-67
2026-05-27 06:27Wake engagement on existing player presence updatesMichael Camilleri5+221-9
2026-05-27 05:29Consume stale .invite Pings before presenting themMichael Camilleri1+58-15
2026-05-27 05:13Suppress play/pause pushes for finished or revoked gamesMichael Camilleri3+77-20
2026-05-27 04:44Stamp completion from observed solved stateMichael Camilleri3+74-11
2026-05-27 03:37Send play/pause notifications more judiciouslyMichael Camilleri2+62-7
2026-05-27 03:12Update .gitignoreMichael Camilleri1+1-1
2026-05-27 02:43Address concurrency false positiveMichael Camilleri1+1-1
2026-05-27 02:41Add push notification loggingMichael Camilleri2+44-14
2026-05-27 01:43Suppress stale peer cursor presenceMichael Camilleri3+52-17
2026-05-27 00:51Drain retired play-event pings and rename play/pause push kindsMichael Camilleri4+81-9
2026-05-27 00:38Move user-facing notifications to APNs via a Cloudflare WorkerMichael Camilleri42+951-833
2026-05-26 21:53Make worker configuration explicitMichael Camilleri2+7-0
2026-05-26 09:31Simplify sync designMichael Camilleri5+47-251
2026-05-25 21:48Tweak colours of announcement iconsMichael Camilleri1+9-6
2026-05-25 17:44Deduplicate ping handling before dispatchMichael Camilleri9+31-318
2026-05-25 17:24Disable polling while engagement is liveMichael Camilleri1+6-2
2026-05-25 17:12Stabilize socket engagementsMichael Camilleri5+83-18
2026-05-25 16:50Ensure protocol in URLs is wssMichael Camilleri2+34-3
2026-05-25 16:39Remove excessive loggingMichael Camilleri1+0-6
2026-05-25 16:21Replace WebRTC engagements with socket roomsMichael Camilleri16+696-1837
2026-05-25 15:00Add lag measuring instrumentationMichael Camilleri1+9-4
2026-05-25 14:38Add further instrumentation to WebRTC bridgeMichael Camilleri1+99-0
2026-05-25 14:27Force engagements to use TURN serverMichael Camilleri1+27-1
2026-05-25 14:07Add additional instrumentation to WebRTC bridgeMichael Camilleri1+35-2
2026-05-25 13:48Keep engagement connections alive briefly after grid exitMichael Camilleri6+73-6
2026-05-25 13:21Update Cloudflare app nameMichael Camilleri1+1-1
2026-05-25 13:00Update .gitignoreMichael Camilleri1+1-0
2026-05-25 12:54Add Cloudflare TURN credentials for engagementsMichael Camilleri9+233-20
2026-05-25 10:57Make engagement channel delivery reliableMichael Camilleri3+18-4
2026-05-25 10:19Use cursor tracks for engagement presenceMichael Camilleri2+127-26
2026-05-25 09:56Fix manual engagement offers targeting selfMichael Camilleri2+34-3
2026-05-25 09:24Defer engagement .live promotion until the channel opensMichael Camilleri2+120-16
2026-05-25 07:43Browse zones and records from Record EditorMichael Camilleri2+201-0
2026-05-25 07:21Handle stuck engagement handshakesMichael Camilleri2+227-10
2026-05-25 07:04Add WebRTC engagement bridge for co-solving engagementsMichael Camilleri24+2882-34
2026-05-24 21:12Wrap puzzle teardown in a Player send burstMichael Camilleri1+9-0
2026-05-24 20:58Avoid peer presence pre-empting selection debounceMichael Camilleri2+35-1
2026-05-24 20:48Gate cursor-track sends on peer presenceMichael Camilleri5+198-6
2026-05-24 09:02Tweak icons used in announcementsMichael Camilleri1+3-3
2026-05-24 05:39Add confirmation dialog when revealingMichael Camilleri1+56-3
2026-05-24 04:15Replace Player coalesce timer with an explicit open burstMichael Camilleri8+105-57
2026-05-24 00:41Select external provider if already enabledMichael Camilleri1+5-0
2026-05-23 22:16Change symbol for info announcementsMichael Camilleri1+1-1
2026-05-23 22:14Tweak time for coalescingMichael Camilleri1+7-4
2026-05-23 21:53Coalesce Player-record sends and log send success correctlyMichael Camilleri6+105-16
2026-05-23 21:06Improve sophistication of try handlingMichael Camilleri9+214-68
2026-05-23 19:16Surface Core Data save failures in the diagnostics logMichael Camilleri6+97-25
2026-05-23 19:14Set up xcode-build-serverMichael Camilleri2+24-0
2026-05-23 18:13Use 'Diagnostics Log' for name of log viewMichael Camilleri3+3-87
2026-05-23 10:10Use correct time when refetching puzzleMichael Camilleri1+10-1
2026-05-23 09:12Increase diagnostic detailMichael Camilleri2+27-9
2026-05-23 08:49Surface NYT upgrade outcome in the diagnostics logMichael Camilleri5+58-24
2026-05-23 08:12Restore retry on failed NYT puzzle upgradesMichael Camilleri3+2-4
2026-05-23 07:10Isolate NotificationState's UserDefaults per testMichael Camilleri5+68-4
2026-05-23 06:57Support refreshing puzzles from external providersMichael Camilleri11+397-3
2026-05-22 21:45Lay out the game list as a card grid on iPadMichael Camilleri1+373-55
2026-05-22 13:09Withdraw a game's notifications when a sibling device opens itMichael Camilleri1+11-2
2026-05-22 08:12Tweak colour of info announcementsMichael Camilleri1+1-1
2026-05-22 06:27Tweak animations to make sending more obviousMichael Camilleri1+85-9
2026-05-22 03:13Preview bundled puzzles in the puzzle pickerMichael Camilleri25+616-136
2026-05-21 23:28Browse bundled puzzles by named bundleMichael Camilleri26+1194-1104
2026-05-21 23:20Delimit Fillmake's XD sections with two blank linesMichael Camilleri1+1-0
2026-05-21 16:44Add icons to announcement bannersMichael Camilleri1+43-17
2026-05-21 15:20Use player colour for info announcementsMichael Camilleri1+4-1
2026-05-21 14:36Drop a pending invite when its game's zone syncs inMichael Camilleri2+42-3
2026-05-21 13:40Accept the CKShare when joining from an invite notificationMichael Camilleri2+62-9
2026-05-21 13:17Show banners when a puzzle's game is revoked or removedMichael Camilleri7+138-7
2026-05-21 07:56Store session notification dedup per keyMichael Camilleri1+56-15
2026-05-21 07:23Thread tint colour consistently to SwiftUI viewsMichael Camilleri3+11-6
2026-05-21 05:24Tweak Clue Bar background colourMichael Camilleri3+8-3
2026-05-21 05:07Move session notification policy into SessionMonitorMichael Camilleri5+184-91
2026-05-21 04:35Use consistent puzzle titleMichael Camilleri2+43-1
2026-05-21 04:35Support mockable sleep function in AnnouncementCenterMichael Camilleri3+50-10
2026-05-21 03:47Improve NYT date navigationMichael Camilleri1+57-1
2026-05-21 03:24Tweak colour tintsMichael Camilleri1+2-3
2026-05-21 03:04Block input on access-revoked puzzles via the announcement bannerMichael Camilleri4+48-35
2026-05-21 02:53Promote correct draft entries when checkingMichael Camilleri2+14-2
2026-05-21 02:51Prevent solved puzzle opens from sending win pingsMichael Camilleri1+33-20
2026-05-21 01:41Move the invite-accept error onto the announcement bannerMichael Camilleri1+26-14
2026-05-21 00:53Add in-puzzle announcement banner for session-end summariesMichael Camilleri10+571-7
2026-05-20 23:29Notify when a collaborator's play session endsMichael Camilleri11+1032-45
2026-05-20 21:21Avoid republishing unchanged roster entriesMichael Camilleri1+5-2
2026-05-20 12:38Remove numbers from all grid cellsMichael Camilleri2+2-43
2026-05-20 10:55Tidy sync engine support codeMichael Camilleri9+1777-1747
2026-05-20 10:21Add directive to use xcodegen to AGENTS.mdMichael Camilleri1+1-0
2026-05-20 09:47Adjust display of text in grid cellsMichael Camilleri2+91-42
2026-05-20 06:06Direct and consume invite pingsMichael Camilleri5+170-12
2026-05-20 05:45Deduplicate cursor track publishingMichael Camilleri3+18-16
2026-05-20 05:38Detach CKSyncEngine send drains from enqueue pathsMichael Camilleri1+20-13
2026-05-20 04:30Change merge policy to avoid loading failure errorsMichael Camilleri1+1-0
2026-05-20 04:25Improve diagnostic informationMichael Camilleri1+43-3
2026-05-20 04:00Use lease-based suppression strategy while a puzzle is openMichael Camilleri6+177-60
2026-05-20 02:09Fetch readAt field in direct sync pathsMichael Camilleri2+9-4
2026-05-20 00:11Replace .opened/.closed lease pings with Player.readAtMichael Camilleri15+594-1000
2026-05-19 22:55Support seenOtherAt cursor on the Player recordMichael Camilleri2+53-0
2026-05-19 18:17Disable Release linker code-folding so crash frames symbolicateMichael Camilleri2+14-5
2026-05-19 18:16Detach CKSyncEngine re-entry out of the onPings delegate callbackMichael Camilleri2+17-5
2026-05-19 11:55Fan out a directed .resign when resigning from the libraryMichael Camilleri3+9-0
2026-05-19 11:37Replace the eternal win ping with directed, self-cleaning pingsMichael Camilleri5+222-102
2026-05-19 10:48Replace the broadcast win ping with directed completion pingsMichael Camilleri7+92-17
2026-05-19 07:02Wait for an invited game to sync before erroringMichael Camilleri3+131-20
2026-05-19 06:44Add revision number and bundle identifier to templateMichael Camilleri1+2-0
2026-05-19 02:43Attempt to constrain height of scoreboardMichael Camilleri1+2-0
2026-05-19 02:23Stick Puzzle Grid scoreboard to bottom of headerMichael Camilleri1+1-1
2026-05-19 02:10Add Cluemake for generated crossword cluesMichael Camilleri4+596-7
2026-05-19 01:38Use invitation animations in short list as wellMichael Camilleri1+17-18
2026-05-19 01:31Title the header scoreboard instead of centring itMichael Camilleri1+11-7
2026-05-19 00:39Clean .puz author strings and label the credits pageMichael Camilleri1+16-1
2026-05-19 00:37Wrap and centre the header scoreboard chipsMichael Camilleri1+86-10
2026-05-18 22:15Add bundle-puzzles.sh to renumber picks into the app bundleMichael Camilleri1+47-0
2026-05-18 22:11Update select_puzzles.sh to copy a ranked puzzle batchMichael Camilleri2+59-13
2026-05-18 20:49Rebuild puzzle generation around Fillmake, Gridmake and PickmakeMichael Camilleri11+2544-737
2026-05-18 20:25Add swipeable title/scoreboard/credits to Puzzle GridMichael Camilleri2+177-2
2026-05-18 10:55Animate the friend's own glyph as invite feedbackMichael Camilleri2+47-12
2026-05-18 04:20Spread the player palette and keep collaborators off similar huesMichael Camilleri1+63-19
2026-05-18 00:16Propagate shared game departure to the user's own devicesMichael Camilleri4+160-7
2026-05-17 23:31Add high-level architecture description to AGENTS.mdMichael Camilleri1+12-0
2026-05-17 23:24Tweak pattern opacityMichael Camilleri1+1-1
2026-05-17 23:03Fix ping bugsMichael Camilleri5+129-23
2026-05-17 22:10Sync the active-puzzle lease across a user's own devicesMichael Camilleri9+412-58
2026-05-17 15:33Hold a just-left puzzle active through a short grace windowMichael Camilleri3+90-10
2026-05-17 13:34Phase cross-reference hatching onto a grid-wide latticeMichael Camilleri2+73-14
2026-05-17 13:15Make friend colours stable across gamesMichael Camilleri9+69-458
2026-05-17 12:53Share the clue cell-walk behind a built-once start indexMichael Camilleri2+74-42
2026-05-17 12:32Mark cross-referenced squares with a passive patternMichael Camilleri3+166-1
2026-05-17 10:52Exclude completed puzzles from the ping fast pathMichael Camilleri1+27-2
2026-05-17 09:51Keep the ping fast-path from matching its own newest recordMichael Camilleri1+38-3
2026-05-17 08:56Fix misleading zone countMichael Camilleri1+8-1
2026-05-17 07:35Reap pending sends that can no longer be builtMichael Camilleri3+135-2
2026-05-17 07:10Trace the ping send path in enqueuePingMichael Camilleri1+29-2
2026-05-17 04:57Reap stale .opened pings from the account zoneMichael Camilleri3+129-1
2026-05-17 03:44Update script to archive into the Xcode libraryMichael Camilleri1+11-2
2026-05-17 03:27Stop awaiting CKSyncEngine from inside delegate callbackMichael Camilleri1+12-3
2026-05-17 00:00Keep the clue list pinned to the current clue across foregroundingMichael Camilleri1+9-0
2026-05-16 23:58Add build scriptMichael Camilleri4+46-21
2026-05-16 21:05Fix test helper for debounce-coalesce testsMichael Camilleri1+14-0
2026-05-16 20:48Improve friend-related features on multiple devicesMichael Camilleri4+333-11
2026-05-16 13:53Preview friend invites in the share sheetMichael Camilleri4+182-22
2026-05-16 08:48Tighten friend invite acceptance and namesMichael Camilleri3+57-12
2026-05-16 07:56Add friend invites for past collaboratorsMichael Camilleri18+1529-30
2026-05-15 21:45Persist the local cursor per gameMichael Camilleri6+294-19
2026-05-15 21:18Keep buffered letters from reverting on remote refreshMichael Camilleri6+301-3
2026-05-15 11:12Represent XD specials with grid symbolsMichael Camilleri22+529-149
2026-05-15 09:12Show seven completed puzzles on launchMichael Camilleri1+55-24
2026-05-15 08:45Use selection fill for remote Cursor TrackMichael Camilleri2+9-77
2026-05-15 07:48Dismiss notifications across user's devicesMichael Camilleri6+233-19
2026-05-15 07:43Gate lastSeenOtherMoveAt advance on puzzle visibilityMichael Camilleri2+72-0
2026-05-15 06:09Dismiss notifications when entering relevant gameMichael Camilleri2+22-0
2026-05-15 05:41Suppress redundant freshens between push signalsMichael Camilleri2+79-3
2026-05-15 02:59Preserve in-flight Game record against clobberingMichael Camilleri6+80-8
2026-05-15 01:58Synchronise on state instead of wall-clock in mutator/clear testsMichael Camilleri3+36-11
2026-05-14 19:22Expand usage of injectable debounce timingMichael Camilleri4+61-35
2026-05-14 19:19Improve notificationsMichael Camilleri3+41-1
2026-05-14 18:36Show updated-game count on the app iconMichael Camilleri4+84-5
2026-05-14 18:16Freshen the puzzle grid as its own sync surfaceMichael Camilleri4+90-39
2026-05-14 16:00Add border to Cursor TrackMichael Camilleri2+69-11
2026-05-14 08:02Persist Cursor Track instead of Cursor ReticleMichael Camilleri9+73-34
2026-05-14 06:39Coalesce Game List freshness checksMichael Camilleri2+78-10
2026-05-14 06:06Freshen the game list as its own sync surfaceMichael Camilleri3+111-10
2026-05-14 05:40Coalesce duplicate remote notification handlersMichael Camilleri1+58-0
2026-05-14 05:35Avoid updated timestamps in Game records being overwritten with earlier timestampsMichael Camilleri2+38-3
2026-05-14 05:24Catch up Game/Moves after background pushesMichael Camilleri2+210-0
2026-05-14 05:05Refresh viewContext after MovesUpdater flushMichael Camilleri1+24-1
2026-05-14 04:41Cut redundant CloudKit workMichael Camilleri5+78-46
2026-05-14 04:07Trace PlayerRoster only after the post-fetch publishMichael Camilleri1+31-15
2026-05-14 03:35Orphan shared zones whose participant binding turns invalidMichael Camilleri1+56-12
2026-05-14 03:21Clear last sync error when its phase succeeds againMichael Camilleri1+7-0
2026-05-14 03:20Drop fetched record snapshots older than local cacheMichael Camilleri2+58-8
2026-05-14 02:28Skip grid refresh when Moves save self-echoesMichael Camilleri2+11-7
2026-05-14 02:00Use live fetches for open synced puzzlesMichael Camilleri3+45-30
2026-05-14 01:21Scope player name publish to open gameMichael Camilleri5+184-29
2026-05-13 23:58Clarify timezone in copied log linesMichael Camilleri1+1-0
2026-05-13 23:24Display log events in-app using local timeMichael Camilleri1+35-20
2026-05-13 23:06Use UTC when loggingMichael Camilleri1+3-1
2026-05-13 22:55Update length of log historyMichael Camilleri2+2-1
2026-05-13 22:47Add upload-only scriptMichael Camilleri2+43-2
2026-05-13 21:49Infer session notifications from Player recordsMichael Camilleri9+322-99
2026-05-12 20:31Skip the cell-cache rewrite when refreshing the current gameMichael Camilleri1+10-3
2026-05-12 20:09Make MovesUpdater debounce timing test-injectableMichael Camilleri2+51-6
2026-05-12 20:08Parallelise refreshLibrary across database scopesMichael Camilleri1+16-12
2026-05-12 19:48Parallelise discoverNewZonesDirect across zones and record typesMichael Camilleri1+62-33
2026-05-12 19:44Parallelise fetchPushPingsDirect across zonesMichael Camilleri1+39-17
2026-05-12 19:42Lower MovesUpdater debounce from 1500ms to 500msMichael Camilleri2+2-2
2026-05-12 19:29Kick sendChanges() on player, game and delete enqueuesMichael Camilleri1+3-0
2026-05-12 19:24Parallelise the silent-push handler and skip wasteful zone discoveryMichael Camilleri1+34-35
2026-05-12 10:16Increase timeout for flakey testMichael Camilleri1+1-1
2026-05-12 10:11Parallelise the library refresh and skip completed gamesMichael Camilleri1+56-27
2026-05-12 09:10Pull updates for known game zones on library refreshMichael Camilleri2+77-0
2026-05-12 08:40Discover unseen game zones without waiting on CKSyncEngineMichael Camilleri4+164-22
2026-05-12 08:07Bump Crossmate-flavoured XD versionMichael Camilleri14+31-14
2026-05-12 08:04Render circled cells in converted puzzlesMichael Camilleri2+40-27
2026-05-12 07:19Surface collaborator pings on background push wakesMichael Camilleri4+167-0
2026-05-11 22:23Tweak Clue Bar layoutMichael Camilleri1+5-4
2026-05-10 18:55Add Crossmate version to puzzle data structuresMichael Camilleri26+187-19
2026-05-10 18:30Update .gitignoreMichael Camilleri1+1-0
2026-05-10 16:42Use publisher as a consistent nameMichael Camilleri14+768-768
2026-05-10 16:18Fix movement when deleting first letter of a wordMichael Camilleri2+85-3
2026-05-10 16:13Fix movement when typing last letter in a directionMichael Camilleri3+109-10
2026-05-10 15:55Adjust touch target for previous/next buttons in Clue BarMichael Camilleri1+5-4
2026-05-10 15:25Improve latency of pingsMichael Camilleri1+1-0
2026-05-10 14:17Clean up completed game ping recordsMichael Camilleri3+93-1
2026-05-10 13:55Tweak layout of Clue List on iOSMichael Camilleri1+25-11
2026-05-10 11:01Move diagnostics menu option into Puzzle MenuMichael Camilleri1+10-15
2026-05-10 10:49Make diagnostics accessible from Puzzle ViewMichael Camilleri1+16-0
2026-05-10 10:23Simplify push notification fallbackMichael Camilleri1+2-8
2026-05-10 06:18Limit push fallback to active gameMichael Camilleri2+139-89
2026-05-10 05:51Include Player records in fallback fetchMichael Camilleri1+6-1
2026-05-09 05:09Disable solved puzzle toolbar actionsMichael Camilleri1+10-2
2026-05-09 03:01Load puzzles before roster refreshMichael Camilleri5+93-50
2026-05-09 02:40Retry pending move flushes until persistedMichael Camilleri3+35-15
2026-05-09 01:28Fix notification replay bugMichael Camilleri3+12-20
2026-05-09 00:19Preserve local Moves record at all timesMichael Camilleri4+166-3
2026-05-08 22:40Fix Success Panel animationMichael Camilleri1+23-9
2026-05-08 22:17Improve Success Panel animationMichael Camilleri1+30-23
2026-05-08 21:14Extend divider into safe area in landscapeMichael Camilleri1+1-0
2026-05-08 15:00Disable author tinting for local gamesMichael Camilleri2+11-12
2026-05-08 14:39Collapse roster list in ScoreboardMichael Camilleri2+8-10
2026-05-08 14:33Make roster always presentMichael Camilleri4+46-28
2026-05-08 13:58Add logging for rostersMichael Camilleri1+18-0
2026-05-08 13:38Add alternative CloudKit path for notified changesMichael Camilleri3+216-44
2026-05-08 13:25Use more targeted CloudKit fetchesMichael Camilleri2+18-11
2026-05-08 13:09Fetch current puzzle zone on pushMichael Camilleri2+45-6
2026-05-08 12:39Create push subscriptions expresslyMichael Camilleri1+52-0
2026-05-08 12:29Add more instrumentation to push notificationsMichael Camilleri1+33-0
2026-05-08 12:12Set APN environment to productionMichael Camilleri1+1-1
2026-05-08 11:37Instrument notification code pathMichael Camilleri2+29-0
2026-05-08 07:54Push Moves immediately after debounced flushMichael Camilleri3+49-12
2026-05-08 03:31Rewrite sync approachMichael Camilleri32+1898-2210
2026-05-07 22:40Stop CKSyncEngine from looping on ZoneNotFoundMichael Camilleri3+260-4
2026-05-07 22:39Add testing instructions to AGENTS.mdMichael Camilleri1+9-0
2026-05-07 21:11Apply private-DB zone deletions on receiving devicesMichael Camilleri3+93-32
2026-05-07 20:31Recover from CloudKit etag drift on Player and Move recordsMichael Camilleri3+49-1
2026-05-07 20:30Add basic AGENTS.md fileMichael Camilleri1+13-0
2026-05-07 10:26Add initial 10 bundled puzzlesMichael Camilleri15+1081-4
2026-05-07 09:49Move debug puzzles to new top-level directoryMichael Camilleri10+85-47
2026-05-07 08:09Support Across Lite puzzle importMichael Camilleri9+569-8
2026-05-07 07:15Add external sources section to SettingsMichael Camilleri1+31-5
2026-05-07 05:36Fetch account e-mail through GraphQL profileMichael Camilleri4+230-23
2026-05-07 04:41Add About screen to SettingsMichael Camilleri5+111-1
2026-05-06 23:21Fix silent record drops in inbound CloudKit syncMichael Camilleri4+172-42
2026-05-06 21:58Replace in-memory engines on reset sync stateMichael Camilleri1+20-2
2026-05-06 19:31Propagate ckShareRecordName to other owner-devicesMichael Camilleri6+302-3
2026-05-06 18:30Fix XD accepted-answer rebus completionMichael Camilleri3+117-8
2026-05-06 17:51Update text in notification messagesMichael Camilleri5+91-4
2026-05-06 17:38Tweak count on in-progress scoreboard on iPadOSMichael Camilleri1+44-6
2026-05-06 17:34Improve final scoreboard display on iPadOSMichael Camilleri1+20-6
2026-05-06 16:52Replace clear menu with entry menuMichael Camilleri1+21-14
2026-05-06 16:22Fix concurrency warning about isolationMichael Camilleri1+6-4
2026-05-06 15:51Support XD clue metadata accepted answersMichael Camilleri7+503-27
2026-05-06 14:03Support additional iPad orientationMichael Camilleri2+2-0
2026-05-06 13:56Change swipe gesture to change cursor axis to tap gestureMichael Camilleri2+11-9
2026-05-06 13:17Add iPad portrait layoutMichael Camilleri2+97-18
2026-05-06 09:17Add external keyboard input handlingMichael Camilleri6+339-2
2026-05-06 04:23Add initial iPad layoutMichael Camilleri6+541-83
2026-05-06 01:20Add keyboard swipe to set entry directionMichael Camilleri2+16-0
2026-05-06 00:07Preserve cell author on same-letter rewrites and reveal-of-correctMichael Camilleri4+172-8
2026-05-05 22:16Expand scope of notifications of collaborator actionsMichael Camilleri9+247-97
2026-05-05 15:19Make GameStore collaborators required at constructionMichael Camilleri10+510-447
2026-05-05 11:43Persist local author identity across launchesMichael Camilleri4+45-15
2026-05-04 00:36Ensure notifications display during backgroundingMichael Camilleri4+59-4
2026-05-04 00:01Prevent author tinting on empty squaresMichael Camilleri1+3-1
2026-05-03 23:54Tweak behaviour regarding shared gamesMichael Camilleri1+16-3
2026-05-03 23:13Support author tinting on shareMichael Camilleri5+55-32
2026-05-03 22:58Update author tints dynamicallyMichael Camilleri3+7-3
2026-05-03 05:31Use a faint background to differentiate authorsMichael Camilleri2+12-12
2026-05-03 04:20Add colours to text in shared gamesMichael Camilleri2+20-3
2026-05-02 16:54Avoid using icons in puzzle view menusMichael Camilleri1+3-9
2026-05-02 16:43Fix warnings about discarded resultsMichael Camilleri1+1-0
2026-05-02 16:42Fix leaving of shared gamesMichael Camilleri1+9-2
2026-05-02 15:28Improve consistency between game list menu and puzzle menuMichael Camilleri3+387-179
2026-05-02 15:06Simplify leave/deletion options for shared gamesMichael Camilleri5+139-24
2026-05-02 11:29Unwind changes to reduce CloudKit callsMichael Camilleri5+88-42
2026-05-02 08:25Remove performance loggingMichael Camilleri10+9-423
2026-05-02 08:13Fix needless game parsing on key strokesMichael Camilleri5+156-28
2026-05-02 08:09Reenable ProMotionMichael Camilleri2+3-0
2026-05-02 04:13Disable ProMotionMichael Camilleri2+0-3
2026-05-02 01:36Allow certain logging to be disabledMichael Camilleri5+109-55
2026-05-02 01:06Support toggling iCloud syncingMichael Camilleri4+78-17
2026-05-02 00:52Increase granularity of loggingMichael Camilleri1+29-1
2026-05-02 00:42Make grid squares equatableMichael Camilleri2+16-7
2026-05-02 00:06Add performance logging to SwiftUI-related functionsMichael Camilleri4+164-1
2026-05-01 23:22Reduce workload during flushesMichael Camilleri3+122-4
2026-05-01 23:14Add more detail to performance loggingMichael Camilleri2+30-4
2026-05-01 23:06Add performance loggingMichael Camilleri10+429-91
2026-05-01 22:48Defer CloudKit move enqueues while typingMichael Camilleri5+140-17
2026-05-01 22:41Reduce puzzle input workMichael Camilleri4+92-9
2026-05-01 17:47Improve responsiveness in puzzle viewMichael Camilleri3+168-106
2026-05-01 16:32Reduce calculations during renderingMichael Camilleri2+45-17
2026-05-01 13:54Improve scoreboard revealMichael Camilleri3+38-15
2026-05-01 13:14Add scoreboard to success panelMichael Camilleri3+187-25
2026-05-01 11:47Recover existing CloudKit zone sharesMichael Camilleri1+95-14
2026-05-01 11:04Use panel rather than sheet on puzzle completionMichael Camilleri2+30-37
2026-05-01 09:20Switch to using canvas for thumbnail previewsMichael Camilleri1+31-65
2026-05-01 08:54Tweak centring of puzzle againMichael Camilleri1+1-0
2026-05-01 07:52Add separation between title and gridMichael Camilleri1+1-1
2026-05-01 07:37Adjust centring approach againMichael Camilleri1+1-1
2026-05-01 07:28Adjust centring approachMichael Camilleri1+34-28
2026-05-01 04:35Centre grid in puzzle viewMichael Camilleri1+119-47
2026-04-30 23:45Support high refresh ratesMichael Camilleri2+3-0
2026-04-30 23:33Detect more forms of cross-referenced cluesMichael Camilleri2+127-11
2026-04-30 22:04Make last update time update liveMichael Camilleri1+37-5
2026-04-30 21:52Change display of cross-referenced cluesMichael Camilleri5+218-73
2026-04-30 21:50Add scripts to translate JSON to XDMichael Camilleri3+128-0
2026-04-30 12:51Change reveal tool to only mark mistakes as correctMichael Camilleri2+41-2
2026-04-30 05:05Tweak threshhold for roomier displayMichael Camilleri1+1-1
2026-04-30 05:00Make game list styling dependent on scene sizeMichael Camilleri1+59-38
2026-04-30 04:36Change date formatting in PuzzleViewMichael Camilleri1+2-2
2026-04-30 04:30Tweak game list stylingMichael Camilleri1+75-14
2026-04-30 04:17Show unread badge for unseen shared puzzle changesMichael Camilleri6+186-4
2026-04-30 03:55Navigate to games from notification tapsMichael Camilleri1+52-0
2026-04-30 03:43Remove remote-alert notification pathMichael Camilleri11+11-404
2026-04-30 02:30Use synced pings for activity notificationsMichael Camilleri3+103-35
2026-04-29 14:30Add app notifications for shared puzzle activityMichael Camilleri15+738-10
2026-04-29 12:50Use grey for thematic colouringMichael Camilleri1+2-2
2026-04-29 10:34Add Crossmake toolMichael Camilleri6+355703-0
2026-04-29 07:32Fix 'ghost' player in rosterMichael Camilleri1+2-1
2026-04-29 04:44Fix name broadcasting in share puzzlesMichael Camilleri6+70-15
2026-04-28 23:34Drop parent references from Move, Snapshot and Player recordsMichael Camilleri3+2-52
2026-04-28 23:24Show peer cursor in shared puzzlesMichael Camilleri15+718-15
2026-04-28 17:37Add more logging for shared gamesMichael Camilleri3+77-14
2026-04-28 09:05Add poll-based synchronisation when inside puzzleMichael Camilleri2+30-0
2026-04-28 05:52Treat italicised clues as related groupMichael Camilleri3+94-6
2026-04-28 05:11Add CloudKit shares to a queue on launchMichael Camilleri3+60-51
2026-04-28 03:46Fix handling of shared games from linksMichael Camilleri3+64-2
2026-04-28 03:44Tweak display of puzzles in GameListViewMichael Camilleri7+88-21
2026-04-28 02:49Fix puzzle timestamp updatingMichael Camilleri3+35-0
2026-04-28 02:35Avoid flash as iCloud link is checkedMichael Camilleri1+1-1
2026-04-28 02:25Use existing link in share sheetMichael Camilleri2+58-2
2026-04-28 02:14Tweak share sheetMichael Camilleri1+3-10
2026-04-28 01:17Replace share sheet with link creation sheetMichael Camilleri9+482-252
2026-04-28 00:11Fix share link creationMichael Camilleri3+111-31
2026-04-27 00:31Revert to previous share sheetMichael Camilleri5+23-157
2026-04-27 00:10Gate share buttonMichael Camilleri5+157-23
2026-04-26 23:47Switch share sheet to ShareLinkMichael Camilleri6+83-110
2026-04-26 12:44Improve display of share sheetMichael Camilleri1+13-3
2026-04-26 11:03Extract CloudService and ImportService from AppServicesMichael Camilleri7+161-119
2026-04-26 10:43Remove unnecessary lockMichael Camilleri6+18-49
2026-04-26 10:25Tighten up testsMichael Camilleri6+76-47
2026-04-26 05:03Add missing tests and fix colour cleanup on game deleteMichael Camilleri8+465-5
2026-04-26 02:29Use shorter identifiersMichael Camilleri4+14-14
2026-04-26 02:23Defer snapshot move pruning until upload succeedsMichael Camilleri6+226-13
2026-04-26 02:09Unify CKContainer instancesMichael Camilleri1+2-3
2026-04-26 01:55Share player names in multiplayerMichael Camilleri12+971-15
2026-04-24 19:12Add CKShare sharing via per-game zones and dual sync enginesMichael Camilleri20+1088-176
2026-04-24 09:08Make iCloud error recording asynchronousMichael Camilleri1+13-4
2026-04-24 08:01Add reset database button to SettingsMichael Camilleri2+19-20
2026-04-24 07:57Fix gaps in synchronisation logicMichael Camilleri2+16-0
2026-04-24 04:06Fix correctness issues in new data flowMichael Camilleri4+43-13
2026-04-24 03:46Improve snapshots creationMichael Camilleri9+224-29
2026-04-23 21:53Ensure that list previews are up to dateMichael Camilleri3+54-1
2026-04-23 21:35Adopt move-log architecture and CKSyncEngineMichael Camilleri21+1135-2444
2026-04-22 09:36Begin process of moving to snapshots and move logMichael Camilleri5+588-0
2026-04-22 09:19Improve throttle avoidanceMichael Camilleri6+222-17
2026-04-22 09:00Avoid data loss caused by pending updatesMichael Camilleri2+210-0
2026-04-21 23:11Support shaded cells in certain crosswordsMichael Camilleri1+64-2
2026-04-21 21:59Change version formatMichael Camilleri2+2-2
2026-04-21 21:48Use clue list to display long cluesMichael Camilleri4+94-1
2026-04-21 20:52Support relative relationships between cluesMichael Camilleri7+364-1
2026-04-21 19:25Provide feedback to user when puzzle is filled inMichael Camilleri2+94-0
2026-04-21 19:07Support direction toggle via the Clue BarMichael Camilleri1+4-0
2026-04-21 19:02Fix auto-advancingMichael Camilleri1+19-7
2026-04-17 20:26Tweak app iconMichael Camilleri2+0-0
2026-04-17 10:04Revert Clue Bar to having a dynamic heightMichael Camilleri1+0-5
2026-04-17 09:42Fix clue slidingMichael Camilleri1+23-23
2026-04-17 09:13Add padding above custom keyboardMichael Camilleri1+1-0
2026-04-17 08:32Add draft toggling to the keyboard overflowMichael Camilleri1+12-1
2026-04-17 08:26Display location in all capsMichael Camilleri1+1-0
2026-04-17 08:21Tweak change name alertMichael Camilleri1+4-0
2026-04-17 06:51Tidy up namingMichael Camilleri1+10-15
2026-04-17 06:32Rename UbiquityMonitor to DriveMonitorMichael Camilleri6+294-294
2026-04-17 05:52Inject sync services via environmentMichael Camilleri5+15-12
2026-04-17 03:24Improve separation of concerns in architectureMichael Camilleri10+265-180
2026-04-14 22:58Ensure Core Data changes are sent to iCloudMichael Camilleri6+221-19
2026-04-14 17:32Sync deletion of gamesMichael Camilleri4+181-24
2026-04-14 17:19Ensure game creation triggers iCloud syncMichael Camilleri2+31-9
2026-04-14 17:04Refactor to use @FetchRequestMichael Camilleri5+86-139
2026-04-14 16:00Support repairing of broken gamesMichael Camilleri1+52-0
2026-04-14 15:20Attempt to address missing entity IDMichael Camilleri1+26-5
2026-04-14 14:38Change gating logic for iCloud fetchesMichael Camilleri1+13-9
2026-04-14 14:03Add telemetry for iCloud debuggingMichael Camilleri1+26-2
2026-04-14 13:36Ensure zone ID is known before pushes and fetchesMichael Camilleri1+31-2
2026-04-14 11:59Remove Crossmate headingMichael Camilleri1+8-3
2026-04-14 10:04Clarify scope of XD file supportMichael Camilleri2+3-0
2026-04-14 09:52Improve support for importing XD puzzlesMichael Camilleri6+118-1
2026-04-14 09:42Improve robustness of puzzle selectionMichael Camilleri6+90-23
2026-04-14 05:06Add player menuMichael Camilleri3+87-4
2026-04-14 00:23Add submit button to calendar pickerMichael Camilleri2+49-4
2026-04-13 23:20Add date field to XD structMichael Camilleri6+34-24
2026-04-13 21:26Change colours used in clue bar and start squaresMichael Camilleri3+35-7
2026-04-13 09:51Add support for external puzzlesMichael Camilleri8+357-45
2026-04-12 23:39Ensure game records are saved before square recordsMichael Camilleri3+103-33
2026-04-12 21:39Expand instrumentation of sync logicMichael Camilleri2+87-6
2026-04-12 19:54Switch to different iCloud containerMichael Camilleri2+3-1
2026-04-12 19:42Add write probe as part of iCloud debugging supportMichael Camilleri1+42-0
2026-04-12 17:29Add even more iCloud debugging supportMichael Camilleri3+56-1
2026-04-12 17:09Add more iCloud debugging supportMichael Camilleri2+28-0
2026-04-12 15:36Add sync monitorMichael Camilleri7+346-15
2026-04-12 11:17Ensure placeholder file is added to iCloud DriveMichael Camilleri1+12-0
2026-04-12 08:13Set initial version to 1.0Michael Camilleri4+46-4
2026-04-12 07:52Add support for additional puzzle sourcesMichael Camilleri17+675-10
2026-04-12 02:09Settings and NYT authenticationMichael Camilleri9+740-0
2026-04-11 10:20Add puzzle catalogMichael Camilleri11+791-80
2026-04-11 10:14Add CloudKit-based sync engineMichael Camilleri23+2011-129
2026-04-09 21:22Add persistenceMichael Camilleri6+298-3
2026-04-09 21:06Add support for specialsMichael Camilleri4+51-16
2026-04-09 20:55Add initial prototypeMichael Camilleri19+2291-0
2026-04-08 22:53Initial commitMichael Camilleri1+10-0