Android 1.9.0 — 2026-07-20 (versionCode 12)
- Features
- web: add analytics with GDPR consent chain (74b6017)
- add real homepage waitlist with email capture (8ba7541)
- add page-level SEO metadata to marketing pages (e036cdd)
- analytics: add signup-source attribution and one activation event (cce07bc)
- mobile: show over-plan-cap freeze on projects (068ccb5)
- i18n: add switch.* keys for /switch/[tool] page (24dd265)
- web: rewrite hero headline to offline/encrypted framing (f41c3b4)
- web: fill download hero with real app screenshot (248dc35)
- web: add download-page + landing-desktop i18n keys across 5 locales (a71b419)
- api: route web checkout/portal/subscription through BillingProvider (d113aa3)
- db: rename Stripe billing columns to provider-agnostic + add billing_provider (68bb5d8)
- web: add /download page with OS-aware installer picker (79fac52)
- implement Google Play Billing, Tauri public releases, and Web Sync conflict resolution (7e63fce)
- ui: dismissable toast messages (web + mobile) (e447a89)
- ui: dismissable toasts — always-visible ✕ (web + mobile) + swipe-to-dismiss (mobile) (5b34ae4)
- mobile: wire sync-recovery panel into settings (7be00d7)
- i18n: add a11y.dismiss_toast label across locales (a110808)
- ui: add shared sync-recovery composite (aa3c5ae)
- mobile: keep the view toggle mounted while project detail loads (4d1ca56)
- mobile: debounce focus loading and skeleton the stats list (f04deff)
- mobile: gate filter edit at the route so create mode stays unaffected (afb431b)
- mobile: gate project edit on a layout-mirroring skeleton (e4daab0)
- mobile: skeleton the members list and drop the unused loading string (c62873f)
- mobile: replace list spinners with skeletons on sync-conflicts and blocked-users (5d2b71e)
- mobile: mirror notification-prefs layout with form skeletons (29a6eec)
- mobile: show task-detail skeleton instead of spinner while loading (219bcdc)
- ui: add FormFieldSkeleton and FormGroupSkeleton primitives (c60a6d7)
- mobile: fill haptic coverage gaps via central facade (8cfab42)
- mobile: central haptics vocabulary + Sound & Haptics setting (3e3fdf8)
- mobile: illustrate + rewire empty states + migrate filter-results empty to shared primitive (6e88d88)
- ui: add empty-state illustration kit (6 spot illustrations) (e7c4829)
- ui: add illustration palette hook (e56a4b7)
- ui: add illustration prop to EmptyState primitive (ec78688)
- shared: add jittered exponential backoff primitive (3dc6550)
- mobile: show parent title on Today subtask rows (4c1a268)
- ui: allow a parent-only task breadcrumb (a836920)
- mobile: open-in-calendar row on task detail (475305f)
- web: show calendar link on task details (62f26e6)
- api: capture calendar htmlLink and expose it per task (fe3a525)
- db: add html_link column to calendar_event_links (7684062)
- mcp: OAuth hardening (MCP-1 consent disclosure, MCP-2 reachability+scope backstop) (0a15dfe)
- mcp-shared: export reachable map + McpGrantScope alias (dcddb27)
- mcp-shared: add canonical MCP reachability/scope map (1127b2f)
- mcp-shared: add satisfiesScope rank check (264646c)
- web: settings billing section + prod price-id boot gate (e2669b4)
- habits: amber skipped-day color + glyph on habit calendar (c45ab2d)
- web: task-row dependency indicators (Blocked by / Blocking) (ca17921)
- triage: visible focused-row action bar on web (9ab4ceb)
- mobile: triage move-to-project chip + picker + cascade (6096c2b)
- shared: end-of-scope key + subtree walk for triage move (fbf2dfa)
- web: triage move-to-project action (816bdf8)
- db: project projection on triage deck query (3505912)
- shared: triage project-suggestion selector (400a465)
- i18n: triage move-to-project keys (7452550)
- web: flag not-in-app users on admin entitlement grant (c27b7d0)
- web: rename sidebar project-tree header to Your projects (6d7bea1)
- api: resolve admin entitlement lookup via Clerk, provision on grant (2497007)
- web: redesign 404 not-found page — Off the route (4a3ef73)
- mobile: refetch badge on tasks.badgeCount sync-bus (55e56ee)
- api: admin entitlement grant/strip mechanism (0d49067)
- mobile: open Today from Home widget tap (962c0aa)
- web: admin entitlements grant/strip page (141599f)
- api: admin entitlements REST router (grant/revoke/lookup/list) (9c4e09b)
- add manual entitlement source to wire union + settings label (9acf019)
- mobile: open fullscreen focus route from the inline timer (e783fb1)
- i18n: add focus.open_fullscreen_a11y across locales (cd0a449)
- ui: add expand affordance to active focus timer (f137400)
- mobile: present focus route as fullScreenModal (834f48a)
- db: store-demo seed scenario for App Store screenshots (4778643)
- web: minimal support page for ASC Support URL (04f7069)
- web: populate review-and-reflect marketing story (bdd213f)
- web: merge humanized filter chips + edit-in-modal (4884c9d)
- web: humanize filter chips and edit filters in a modal (516b29a)
- mobile: browse quick actions 3x2 grid (f4f8f6c)
- humanize filter queries into clause chips (d6a3a08)
- mobile: add the productivity stats screen (2ea7fb8)
- i18n: add stats screen keys, drop the legacy streak string (73ea871)
- mobile: show filter clause chips instead of the raw query (8307cbb)
- ui: share the velocity-bar builder between web and mobile (68c08ad)
- ui: add an InsightCards composite (7661acd)
- ui: add StatTiles and PriorityDistribution composites (c58b635)
- mobile: register stats.getProductivity in the REST registry (e73ace9)
- mobile: row-parity Create project CTA in Browse search (668206e)
- mobile: resolve and render filter summary chips (6597d11)
- mobile: add the filter summary chip primitive (067ba2e)
- mobile: row-parity Create project CTA in Browse search (cecc6cb)
- shared: humanize a VisualFilter into clause descriptors (993e468)
- web: drop the never-lose-a-thought story (6b7a66f)
- mobile comment mentions (pill render + autocomplete) (a3a6939)
- mobile: thread projectId into the comment composer's mention picker (0a4c486)
- ui: three-row mention autocomplete above the mobile composer (51d3bfb)
- merge comment edit and delete (ca9231e)
- comment edit and delete on web and mobile (1c9b5eb)
- db: throw on unknown column in drizzle writes (91e66ec)
- db: add work-together-showcase seed scenario (cbe3809)
- ui: add web/desktop Tooltip primitive (0b401bb)
- web: describe the sync-status indicator with a tooltip (4e3ff9d)
- ui: show tooltip labels on the web markdown toolbar (7a60fe1)
- ui: add tooltip and shortcut props to IconButton (9f8d2be)
- ui: add web Tooltip primitive (50e700d)
- web: redesign due-time picker as hour·minute columns (e182e24)
- web: label attach/detach + inline create in task-detail sidebar (60b76c3)
- i18n: deadline picker + relative keys across 5 locales (0c8f758)
- shared: time-aware deadline display + parseNaturalDateParts (959763e)
- web: reminders in compose modal (8f4800b)
- web: compose modal parity — time, recurrence, duration, labels, month grid (4552417)
- web: float idle task-detail focus menu in a popover (a95488c)
- mobile: add-task repeat menu parity with task-details (f530910)
- mobile: reuse shared recurrence builder in add-task repeat chip (bec781f)
- web: timezone region-city cascade picker in settings (e98d413)
- web: replace native timezone select with region-city cascade (d07a6a4)
- mobile: thread ai-fill phase from hook into the row (24077c4)
- mobile: render ai-fill row across 4 phases with pulse + a11y (6c11774)
- mobile: add ai-fill row phase→descriptor map (7249837)
- mobile: add useSparklePulse reanimated loading pulse hook (e9f1010)
- mobile: surface ai-fill phase (loading/success/error) from hook (b20f88b)
- shared: add AI-fill loader i18n keys across locales (1e2d27c)
- shared: add picker.time.* i18n keys across all locales (bcc5345)
- attachments: mobile task + comment attachment UI (e9dad7a)
- attachments: promote view/format helpers to shared, add comment slots (cd5ff47)
- web: task-detail attachments UI with offline-queued uploads (36e0505)
- shared: offline upload-queue orchestrator for attachments (45c9af3)
- db: local-only attachment_uploads upload queue table (2496a1b)
- api: presigned GET URL for viewing attachments (cbb8d70)
- api: mint presigned PUT URL for attachment uploads (80353ae)
- shared: attachment MIME rendering classifier (c65d7d1)
- mobile: task-detail duration edit (377dd98)
- mobile: add-task duration chip (7924764)
- mobile: duration picker sheet and preset chip (65d6dc9)
- shared: i18n keys for duration picker (035a0c3)
- shared: duration wins over start+due window in event derivation (788edde)
- shared: duration presets and parse/format helpers (314e23d)
- i18n: merge hardcoded-string sweep into dev (bc367e7)
- i18n: catch ternary literals, localize leaks (78b65c5)
- i18n: route shared UI copy through labels bags (13f327c)
- web: translate hardcoded UI strings via next-intl (23830c5)
- mobile: route hardcoded UI copy through i18n (b06557e)
- i18n: add 9 sweep keys for JSX-expression blind spots (199791a)
- i18n: add sweep catalog keys + fix two i18n:scan gaps (024b0b2)
- ui: show selected state on bold label color chips (9b16486)
- mobile: merge task-detail remote calendar selector into dev (37359e4)
- mobile: calendar routing selector on task detail (ebc6806)
- db: expose target_calendar_id on task-by-id queries (249c54e)
- web,mobile: surface calendar reconnect prompt for dead credentials (8de7582)
- api: detect dead calendar credentials and surface reauth state (5d74a50)
- mobile: add per-day "+ Add" button to Upcoming week days (70d1d84)
- db: add reauth state columns to calendar_connections (653cc79)
- Fixes
- db: add missing ledger probe for 0068 waitlist_signups (d5a96b4)
- api: close three plan-cap holes (a5b8fc6)
- web: honor Priority support, unify support email (252c7d7)
- web: honor Priority support, unify support email (af8d2dc)
- db: register analytics_events as server-only for the upload guard (5128c48)
- i18n: lowercase brand name to "etappi" in running copy (8967b63)
- web: swap fake testimonial for builder note (b4e903d)
- api: merge wave1 sync-seam replay authz mirror into dev (d01fdac)
- api: reconcile wave1 sync-seam onto dev (7ea4506)
- db: entitlement seed source 'stripe'->'web' + doc-comment sync (d5c2fe7)
- shared: surrogate-safe inbound calendar text clamp (R14) (2f86689)
- api: clamp inbound calendar title/description (R14) (944fb3c)
- mobile: null-coalesce purchaseToken for verifyAndroidPurchase (add6d82)
- reminders: correct relative reminder sign so recompute fires before due (981992a)
- harden sync authz, billing, and supply chain (90fff5d)
- ui: item owns toast auto-dismiss so expiry animates out (1cdff12)
- mobile: drop duplicate Plan-with-AI CTA from projects empty state (fe69fac)
- sync-recovery: localize drop reasons in the recovery readout (08c614e)
- ui: address toast-dismiss review — timer leak, fling direction, dead export (d207906)
- mobile: guard focus screens' debounce window against wrong-state flash on REST reads (5641873)
- mobile: silence toast haptics; centralize completion buzz (c01a9e6)
- mobile: tighten members.tsx hook grouping to stay under the 150 LOC cap (a5a8039)
- mobile: make Sentry crash-free rate measurable (504a95f)
- ui: treat empty breadcrumb halves as absent (1d50906)
- i18n: de-anglicize and correct Ukrainian locale strings (30e7892)
- api: stop VAPID keys from gating Expo push (e7bda80)
- ui: render markdown paragraphs in foreground (cca939f)
- calendar: owner-scope task link + https-only htmlLink (b6c92ec)
- realtime: constrain resolveUserIds scope to canonical RealtimeScope schema (9e59300)
- api: close entitlement reconciliation gaps (6717885)
- web: restore include-archived toggle on /search (e8485d1)
- shared: fold -/_ separators in log redaction key match (88124cc)
- db: backdate habits seed createdAt to first log day (22eaf83)
- focus: normalize legacy tz + surface stats fetch errors (8c4d29a)
- shared: pluralize focus.running_a11y across locales (5216b67)
- ui: pass useAnimatedStyle deps array on web (43f9923)
- db: store plan_grace_started_at as timestamptz (d9a97ed)
- billing: consume resolved access on the client, harden grace UI (7b2bcff)
- api: close the Stripe webhook idempotency crash window (3091a95)
- api: surface resolved plan authority on users.me (6125cf6)
- mobile: fire draft reminders after sheet closes (4d2abed)
- mobile: label sync-conflict toast with the task title, not "tasks" (1c61131)
- ui: rotate focus chevron on expand, match app icon (f6b9605)
- db: backdate store-demo habits so streaks read 5 (83e9458)
- db: author owner users row in stats-showcase seed (9449343)
- ui: centre Tooltip anchor on cross axis (09d74b9)
- i18n: fold suffix plurals into ICU plural messages (f9c5418)
- i18n: fold suffix plurals into ICU plural messages (79666b7)
- mobile: drop the duplicate colour dot from the filter header (16fc472)
- ui: make the shared stats composites survive a phone-width column (3eea6b2)
- format sheet dismiss label at call site (bf09452)
- stats: compare the REST error against null, not undefined (c180041)
- ui: let stats charts declare what is behind them (57e80e3)
- mobile: mirror evaluator project matching in summary chips (88f39c8)
- mobile: land ICU plurals and the Hermes Intl.Locale polyfill (e983d00)
- mobile: polyfill Intl.Locale so ICU plurals resolve on Hermes (fabd9c8)
- mobile: make summary chip testID a prop and pin chip colour map (7c0f251)
- i18n: use genitive plural for uk assignee count fallback (b73ca57)
- shared: lex all-numeric UUIDs as idents, not numbers (adc5f51)
- i18n: render ICU plurals on mobile via i18next-icu (1cad66d)
- mobile: free up viewport for Browse search results (b9e3fc3)
- mobile: let Browse search match the Inbox project (cdaeea9)
- mobile: route plan-gated filter save to the paywall (9326b88)
- mobile: lift the label creator above the keyboard (3703fc8)
- mobile: reveal the comment composer when the keyboard opens (67d3f2f)
- mobile: drop the bogus keyboard offset on task detail (28ecd7b)
- ui: float the mobile mention panel above the composer (a8b8afa)
- ui: bound the iOS mention pill and pin the row typeface (d125faa)
- mobile: resolve comment author names instead of labelling every comment "You" (09899f0)
- sync comment threads to all project members, not just author (d6f23b6)
- web: count completed tasks while collapsed (65a6190)
- mobile: reserve FAB height in scroll insets (fe8b505)
- ui: use tooltip as the native icon-button accessibilityLabel fallback (c072c11)
- ui: harden tooltip dismiss + close review gaps (cb76b23)
- mobile: unnest label hue chip Pressable (097420f)
- i18n: plural-correct deadline relative labels (a627eb5)
- shared: compare deadline by calendar day in triage + filter (327c305)
- web: guard compose reminders vs orphan+race (19e7052)
- i18n: de-calque uk 'included' phrasing (f1aafa3)
- i18n: correct uk Russianisms and normalize loans (8af3e12)
- i18n: de-russify and normalize uk locale strings (e25a0cb)
- i18n: de-loan uk account + shortcuts terms (0341b41)
- i18n: harmonize uk focus vocabulary (f378e16)
- i18n: reframe uk deps strings to blocking (f5fcf4b)
- mobile: lazy-import expo-document-picker (ec20d2b)
- i18n: polish pl/de/fr landing calques (offline-first, calm) (ba86381)
- i18n: polish Ukrainian lexical calques in landing copy (2b8a422)
- mobile: merge ai-fill empty-state feedback and persistent hide (4815059)
- mobile: ai-fill empty-state feedback and persistent hide (65678eb)
- i18n: remove English calques and reconcile drifted strings in uk/pl/de/fr (2b8efd5)
- ui: let Popover trigger own the open/close toggle (744ddc5)
- mobile: resolve ai-fill zero-chip dead-end (60a33e0)
- ui: decouple offline banner visual from screen-reader debounce (6cef6e3)
- mobile: optimistic reminder preset selection (81618f7)
- ui: portal Popover to escape stacking traps (2af6b81)
- harden task attachments (5ce3370)
- attachments: close replay cross-tenant read + XSS (16f8533)
- mobile: wire compose duration + picker layout (ee62eee)
- i18n: align en duration.remove with locales (3f118e8)
- shared: cap task duration at 24h across boundaries (4013729)
- mobile: pixel maxHeight for label picker list (7ef7f86)
- mobile: keep picker search above keyboard (f73ae01)
- mobile: derive inbox id synchronously (d30e87f)
- mobile: theme-accent done days + hug Edit header capsule (73ef020)
- ui: enlarge task checkbox touch targets to 44/48dp (4025dc7)
- Other
- shared: drop orphaned settings.subscription.source.stripe i18n label (a8886bd)
- api,shared,mobile,web: entitlement source 'stripe'->'web' (provider-neutral wire enum) (770e844)
- mobile: debounce loading gates on the six remaining raw-isLoading screens (f9e57a1)
- mobile: use nativeSafeRole for task-detail loading role (82ebd7a)
- mobile: route haptic call sites through central facade (2e4086d)
- mobile: jitter realtime reconnect backoff (06ccb17)
- db: split store-demo.rows into domain siblings under 150-LOC cap (5ef612d)
- mobile: drop dead accent/wide/TileDef after grid split (87439f7)
- ui: extract a generic BarChart from the focus stats chart (d5e6149)
- mobile: extract root stack screens to a sibling module (bc5d2a2)
- relocate mention logic to shared, pill render to ui (ea86dd9)
- db: normalize prettier + split work-together seed under LOC cap (2f35f93)
- mobile: extract applySuggestionsToEmpty from ai-fill hook (e080b41)
iOS 1.17.0 — 2026-07-20 (build 64)
- Features
- web: add analytics with GDPR consent chain (74b6017)
- add real homepage waitlist with email capture (8ba7541)
- add page-level SEO metadata to marketing pages (e036cdd)
- analytics: add signup-source attribution and one activation event (cce07bc)
- mobile: show over-plan-cap freeze on projects (068ccb5)
- i18n: add switch.* keys for /switch/[tool] page (24dd265)
- web: rewrite hero headline to offline/encrypted framing (f41c3b4)
- web: fill download hero with real app screenshot (248dc35)
- web: add download-page + landing-desktop i18n keys across 5 locales (a71b419)
- api: route web checkout/portal/subscription through BillingProvider (d113aa3)
- db: rename Stripe billing columns to provider-agnostic + add billing_provider (68bb5d8)
- web: add /download page with OS-aware installer picker (79fac52)
- implement Google Play Billing, Tauri public releases, and Web Sync conflict resolution (7e63fce)
- ui: dismissable toast messages (web + mobile) (e447a89)
- ui: dismissable toasts — always-visible ✕ (web + mobile) + swipe-to-dismiss (mobile) (5b34ae4)
- mobile: wire sync-recovery panel into settings (7be00d7)
- i18n: add a11y.dismiss_toast label across locales (a110808)
- ui: add shared sync-recovery composite (aa3c5ae)
- mobile: keep the view toggle mounted while project detail loads (4d1ca56)
- mobile: debounce focus loading and skeleton the stats list (f04deff)
- mobile: gate filter edit at the route so create mode stays unaffected (afb431b)
- mobile: gate project edit on a layout-mirroring skeleton (e4daab0)
- mobile: skeleton the members list and drop the unused loading string (c62873f)
- mobile: replace list spinners with skeletons on sync-conflicts and blocked-users (5d2b71e)
- mobile: mirror notification-prefs layout with form skeletons (29a6eec)
- mobile: show task-detail skeleton instead of spinner while loading (219bcdc)
- ui: add FormFieldSkeleton and FormGroupSkeleton primitives (c60a6d7)
- mobile: fill haptic coverage gaps via central facade (8cfab42)
- mobile: central haptics vocabulary + Sound & Haptics setting (3e3fdf8)
- mobile: illustrate + rewire empty states + migrate filter-results empty to shared primitive (6e88d88)
- ui: add empty-state illustration kit (6 spot illustrations) (e7c4829)
- ui: add illustration palette hook (e56a4b7)
- ui: add illustration prop to EmptyState primitive (ec78688)
- shared: add jittered exponential backoff primitive (3dc6550)
- mobile: show parent title on Today subtask rows (4c1a268)
- ui: allow a parent-only task breadcrumb (a836920)
- mobile: open-in-calendar row on task detail (475305f)
- web: show calendar link on task details (62f26e6)
- api: capture calendar htmlLink and expose it per task (fe3a525)
- db: add html_link column to calendar_event_links (7684062)
- mcp: OAuth hardening (MCP-1 consent disclosure, MCP-2 reachability+scope backstop) (0a15dfe)
- mcp-shared: export reachable map + McpGrantScope alias (dcddb27)
- mcp-shared: add canonical MCP reachability/scope map (1127b2f)
- mcp-shared: add satisfiesScope rank check (264646c)
- web: settings billing section + prod price-id boot gate (e2669b4)
- habits: amber skipped-day color + glyph on habit calendar (c45ab2d)
- web: task-row dependency indicators (Blocked by / Blocking) (ca17921)
- triage: visible focused-row action bar on web (9ab4ceb)
- mobile: triage move-to-project chip + picker + cascade (6096c2b)
- shared: end-of-scope key + subtree walk for triage move (fbf2dfa)
- web: triage move-to-project action (816bdf8)
- db: project projection on triage deck query (3505912)
- shared: triage project-suggestion selector (400a465)
- i18n: triage move-to-project keys (7452550)
- web: flag not-in-app users on admin entitlement grant (c27b7d0)
- web: rename sidebar project-tree header to Your projects (6d7bea1)
- api: resolve admin entitlement lookup via Clerk, provision on grant (2497007)
- web: redesign 404 not-found page — Off the route (4a3ef73)
- mobile: refetch badge on tasks.badgeCount sync-bus (55e56ee)
- api: admin entitlement grant/strip mechanism (0d49067)
- mobile: open Today from Home widget tap (962c0aa)
- web: admin entitlements grant/strip page (141599f)
- api: admin entitlements REST router (grant/revoke/lookup/list) (9c4e09b)
- add manual entitlement source to wire union + settings label (9acf019)
- Fixes
- db: add missing ledger probe for 0068 waitlist_signups (d5a96b4)
- api: close three plan-cap holes (a5b8fc6)
- web: honor Priority support, unify support email (252c7d7)
- web: honor Priority support, unify support email (af8d2dc)
- db: register analytics_events as server-only for the upload guard (5128c48)
- i18n: lowercase brand name to "etappi" in running copy (8967b63)
- web: swap fake testimonial for builder note (b4e903d)
- api: merge wave1 sync-seam replay authz mirror into dev (d01fdac)
- api: reconcile wave1 sync-seam onto dev (7ea4506)
- db: entitlement seed source 'stripe'->'web' + doc-comment sync (d5c2fe7)
- shared: surrogate-safe inbound calendar text clamp (R14) (2f86689)
- api: clamp inbound calendar title/description (R14) (944fb3c)
- mobile: null-coalesce purchaseToken for verifyAndroidPurchase (add6d82)
- reminders: correct relative reminder sign so recompute fires before due (981992a)
- harden sync authz, billing, and supply chain (90fff5d)
- ui: item owns toast auto-dismiss so expiry animates out (1cdff12)
- mobile: drop duplicate Plan-with-AI CTA from projects empty state (fe69fac)
- sync-recovery: localize drop reasons in the recovery readout (08c614e)
- ui: address toast-dismiss review — timer leak, fling direction, dead export (d207906)
- mobile: guard focus screens' debounce window against wrong-state flash on REST reads (5641873)
- mobile: silence toast haptics; centralize completion buzz (c01a9e6)
- mobile: tighten members.tsx hook grouping to stay under the 150 LOC cap (a5a8039)
- mobile: make Sentry crash-free rate measurable (504a95f)
- ui: treat empty breadcrumb halves as absent (1d50906)
- i18n: de-anglicize and correct Ukrainian locale strings (30e7892)
- api: stop VAPID keys from gating Expo push (e7bda80)
- ui: render markdown paragraphs in foreground (cca939f)
- calendar: owner-scope task link + https-only htmlLink (b6c92ec)
- realtime: constrain resolveUserIds scope to canonical RealtimeScope schema (9e59300)
- api: close entitlement reconciliation gaps (6717885)
- web: restore include-archived toggle on /search (e8485d1)
- shared: fold -/_ separators in log redaction key match (88124cc)
- db: backdate habits seed createdAt to first log day (22eaf83)
- focus: normalize legacy tz + surface stats fetch errors (8c4d29a)
- shared: pluralize focus.running_a11y across locales (5216b67)
- ui: pass useAnimatedStyle deps array on web (43f9923)
- db: store plan_grace_started_at as timestamptz (d9a97ed)
- billing: consume resolved access on the client, harden grace UI (7b2bcff)
- api: close the Stripe webhook idempotency crash window (3091a95)
- api: surface resolved plan authority on users.me (6125cf6)
- Other
- shared: drop orphaned settings.subscription.source.stripe i18n label (a8886bd)
- api,shared,mobile,web: entitlement source 'stripe'->'web' (provider-neutral wire enum) (770e844)
- mobile: debounce loading gates on the six remaining raw-isLoading screens (f9e57a1)
- mobile: use nativeSafeRole for task-detail loading role (82ebd7a)
- mobile: route haptic call sites through central facade (2e4086d)
- mobile: jitter realtime reconnect backoff (06ccb17)
iOS 1.16.0 — 2026-07-12 (build 63)
- Features
- mobile: open fullscreen focus route from the inline timer (e783fb1)
- i18n: add focus.open_fullscreen_a11y across locales (cd0a449)
- ui: add expand affordance to active focus timer (f137400)
- mobile: present focus route as fullScreenModal (834f48a)
- db: store-demo seed scenario for App Store screenshots (4778643)
- web: minimal support page for ASC Support URL (04f7069)
- web: populate review-and-reflect marketing story (bdd213f)
- web: merge humanized filter chips + edit-in-modal (4884c9d)
- web: humanize filter chips and edit filters in a modal (516b29a)
- mobile: browse quick actions 3x2 grid (f4f8f6c)
- humanize filter queries into clause chips (d6a3a08)
- mobile: add the productivity stats screen (2ea7fb8)
- i18n: add stats screen keys, drop the legacy streak string (73ea871)
- mobile: show filter clause chips instead of the raw query (8307cbb)
- ui: share the velocity-bar builder between web and mobile (68c08ad)
- ui: add an InsightCards composite (7661acd)
- ui: add StatTiles and PriorityDistribution composites (c58b635)
- mobile: register stats.getProductivity in the REST registry (e73ace9)
- mobile: row-parity Create project CTA in Browse search (668206e)
- mobile: resolve and render filter summary chips (6597d11)
- mobile: add the filter summary chip primitive (067ba2e)
- mobile: row-parity Create project CTA in Browse search (cecc6cb)
- shared: humanize a VisualFilter into clause descriptors (993e468)
- web: drop the never-lose-a-thought story (6b7a66f)
- mobile comment mentions (pill render + autocomplete) (a3a6939)
- mobile: thread projectId into the comment composer's mention picker (0a4c486)
- ui: three-row mention autocomplete above the mobile composer (51d3bfb)
- merge comment edit and delete (ca9231e)
- comment edit and delete on web and mobile (1c9b5eb)
- db: throw on unknown column in drizzle writes (91e66ec)
- db: add work-together-showcase seed scenario (cbe3809)
- ui: add web/desktop Tooltip primitive (0b401bb)
- web: describe the sync-status indicator with a tooltip (4e3ff9d)
- ui: show tooltip labels on the web markdown toolbar (7a60fe1)
- ui: add tooltip and shortcut props to IconButton (9f8d2be)
- ui: add web Tooltip primitive (50e700d)
- web: redesign due-time picker as hour·minute columns (e182e24)
- web: label attach/detach + inline create in task-detail sidebar (60b76c3)
- i18n: deadline picker + relative keys across 5 locales (0c8f758)
- shared: time-aware deadline display + parseNaturalDateParts (959763e)
- web: reminders in compose modal (8f4800b)
- web: compose modal parity — time, recurrence, duration, labels, month grid (4552417)
- web: float idle task-detail focus menu in a popover (a95488c)
- mobile: add-task repeat menu parity with task-details (f530910)
- mobile: reuse shared recurrence builder in add-task repeat chip (bec781f)
- web: timezone region-city cascade picker in settings (e98d413)
- web: replace native timezone select with region-city cascade (d07a6a4)
- mobile: thread ai-fill phase from hook into the row (24077c4)
- mobile: render ai-fill row across 4 phases with pulse + a11y (6c11774)
- mobile: add ai-fill row phase→descriptor map (7249837)
- mobile: add useSparklePulse reanimated loading pulse hook (e9f1010)
- mobile: surface ai-fill phase (loading/success/error) from hook (b20f88b)
- shared: add AI-fill loader i18n keys across locales (1e2d27c)
- shared: add picker.time.* i18n keys across all locales (bcc5345)
- Fixes
- mobile: fire draft reminders after sheet closes (4d2abed)
- mobile: label sync-conflict toast with the task title, not "tasks" (1c61131)
- ui: rotate focus chevron on expand, match app icon (f6b9605)
- db: backdate store-demo habits so streaks read 5 (83e9458)
- db: author owner users row in stats-showcase seed (9449343)
- ui: centre Tooltip anchor on cross axis (09d74b9)
- i18n: fold suffix plurals into ICU plural messages (f9c5418)
- i18n: fold suffix plurals into ICU plural messages (79666b7)
- mobile: drop the duplicate colour dot from the filter header (16fc472)
- ui: make the shared stats composites survive a phone-width column (3eea6b2)
- format sheet dismiss label at call site (bf09452)
- stats: compare the REST error against null, not undefined (c180041)
- ui: let stats charts declare what is behind them (57e80e3)
- mobile: mirror evaluator project matching in summary chips (88f39c8)
- mobile: land ICU plurals and the Hermes Intl.Locale polyfill (e983d00)
- mobile: polyfill Intl.Locale so ICU plurals resolve on Hermes (fabd9c8)
- mobile: make summary chip testID a prop and pin chip colour map (7c0f251)
- i18n: use genitive plural for uk assignee count fallback (b73ca57)
- shared: lex all-numeric UUIDs as idents, not numbers (adc5f51)
- i18n: render ICU plurals on mobile via i18next-icu (1cad66d)
- mobile: free up viewport for Browse search results (b9e3fc3)
- mobile: let Browse search match the Inbox project (cdaeea9)
- mobile: route plan-gated filter save to the paywall (9326b88)
- mobile: lift the label creator above the keyboard (3703fc8)
- mobile: reveal the comment composer when the keyboard opens (67d3f2f)
- mobile: drop the bogus keyboard offset on task detail (28ecd7b)
- ui: float the mobile mention panel above the composer (a8b8afa)
- ui: bound the iOS mention pill and pin the row typeface (d125faa)
- mobile: resolve comment author names instead of labelling every comment "You" (09899f0)
- sync comment threads to all project members, not just author (d6f23b6)
- web: count completed tasks while collapsed (65a6190)
- mobile: reserve FAB height in scroll insets (fe8b505)
- ui: use tooltip as the native icon-button accessibilityLabel fallback (c072c11)
- ui: harden tooltip dismiss + close review gaps (cb76b23)
- mobile: unnest label hue chip Pressable (097420f)
- i18n: plural-correct deadline relative labels (a627eb5)
- shared: compare deadline by calendar day in triage + filter (327c305)
- web: guard compose reminders vs orphan+race (19e7052)
- i18n: de-calque uk 'included' phrasing (f1aafa3)
- i18n: correct uk Russianisms and normalize loans (8af3e12)
- i18n: de-russify and normalize uk locale strings (e25a0cb)
- i18n: de-loan uk account + shortcuts terms (0341b41)
- i18n: harmonize uk focus vocabulary (f378e16)
- i18n: reframe uk deps strings to blocking (f5fcf4b)
- mobile: lazy-import expo-document-picker (ec20d2b)
- i18n: polish pl/de/fr landing calques (offline-first, calm) (ba86381)
- i18n: polish Ukrainian lexical calques in landing copy (2b8a422)
- mobile: merge ai-fill empty-state feedback and persistent hide (4815059)
- mobile: ai-fill empty-state feedback and persistent hide (65678eb)
- i18n: remove English calques and reconcile drifted strings in uk/pl/de/fr (2b8efd5)
- ui: let Popover trigger own the open/close toggle (744ddc5)
- mobile: resolve ai-fill zero-chip dead-end (60a33e0)
- Other
- db: split store-demo.rows into domain siblings under 150-LOC cap (5ef612d)
- mobile: drop dead accent/wide/TileDef after grid split (87439f7)
- ui: extract a generic BarChart from the focus stats chart (d5e6149)
- mobile: extract root stack screens to a sibling module (bc5d2a2)
- relocate mention logic to shared, pill render to ui (ea86dd9)
- db: normalize prettier + split work-together seed under LOC cap (2f35f93)
- mobile: extract applySuggestionsToEmpty from ai-fill hook (e080b41)
iOS 1.15.0 — 2026-07-05 (build 62)
- Features
- attachments: mobile task + comment attachment UI (e9dad7a)
- attachments: promote view/format helpers to shared, add comment slots (cd5ff47)
- web: task-detail attachments UI with offline-queued uploads (36e0505)
- shared: offline upload-queue orchestrator for attachments (45c9af3)
- db: local-only attachment_uploads upload queue table (2496a1b)
- api: presigned GET URL for viewing attachments (cbb8d70)
- api: mint presigned PUT URL for attachment uploads (80353ae)
- shared: attachment MIME rendering classifier (c65d7d1)
- mobile: task-detail duration edit (377dd98)
- mobile: add-task duration chip (7924764)
- mobile: duration picker sheet and preset chip (65d6dc9)
- shared: i18n keys for duration picker (035a0c3)
- shared: duration wins over start+due window in event derivation (788edde)
- shared: duration presets and parse/format helpers (314e23d)
- i18n: merge hardcoded-string sweep into dev (bc367e7)
- i18n: catch ternary literals, localize leaks (78b65c5)
- i18n: route shared UI copy through labels bags (13f327c)
- web: translate hardcoded UI strings via next-intl (23830c5)
- mobile: route hardcoded UI copy through i18n (b06557e)
- i18n: add 9 sweep keys for JSX-expression blind spots (199791a)
- i18n: add sweep catalog keys + fix two i18n:scan gaps (024b0b2)
- ui: show selected state on bold label color chips (9b16486)
- mobile: merge task-detail remote calendar selector into dev (37359e4)
- mobile: calendar routing selector on task detail (ebc6806)
- db: expose target_calendar_id on task-by-id queries (249c54e)
- web,mobile: surface calendar reconnect prompt for dead credentials (8de7582)
- api: detect dead calendar credentials and surface reauth state (5d74a50)
- mobile: add per-day "+ Add" button to Upcoming week days (70d1d84)
- db: add reauth state columns to calendar_connections (653cc79)
- Fixes
- ui: decouple offline banner visual from screen-reader debounce (6cef6e3)
- mobile: optimistic reminder preset selection (81618f7)
- ui: portal Popover to escape stacking traps (2af6b81)
- harden task attachments (5ce3370)
- attachments: close replay cross-tenant read + XSS (16f8533)
- mobile: wire compose duration + picker layout (ee62eee)
- i18n: align en duration.remove with locales (3f118e8)
- shared: cap task duration at 24h across boundaries (4013729)
- mobile: pixel maxHeight for label picker list (7ef7f86)
- mobile: keep picker search above keyboard (f73ae01)
- mobile: derive inbox id synchronously (d30e87f)
- mobile: theme-accent done days + hug Edit header capsule (73ef020)
- ui: enlarge task checkbox touch targets to 44/48dp (4025dc7)
- deploy: gate Vercel deploys behind schema migrations (fe374a1)
Android 1.8.0 — 2026-07-01 (versionCode 11)
- Features
- project-picker search — filtered-tree picker with gated search (mobile + web) (bdba1f8)
- web: project-picker search — gated FilterInput + filtered-tree highlight (e6a172f)
- mobile: project-picker search — gated FilterInput + filtered-tree highlight (8a8bd7a)
- i18n: project-picker search strings (5 locales) (d0cc679)
- shared: filtered-tree project-picker search core (1f5fd57)
- mobile: merge locale-aware due-time preset labels into dev (fbe06f8)
- mobile: derive due-time preset labels from locale hour-cycle (d562635)
- mobile: de-emphasize "fill empty with AI" row in compose (17e4c80)
- web: merge notifications settings restyle to match Preferences (9e97aaf)
- web: restyle notifications settings to match preferences (ddd6b0e)
- web: redesign settings preferences as compact auto-saving cards (15f5dad)
- web: redesign settings modal (Direction C — unified & airy) (cc3741b)
- db: add capture-showcase seed scenario (b71aff3)
- web: give settings profile pane a manage-account action row (d797ec5)
- web: always show Today section in Upcoming list (7b29d6a)
- web: rebalance task modal type scale to 18/14/12 (2b54d26)
- web: drag-to-reschedule tasks in the Upcoming list view (455ac2d)
- mobile: board, project, decompose create local-first (edb9a93)
- mobile: compose writes task local-first (b4bd1f4)
- shared: createTask binds description + appends position (46272ef)
- web: day-grouped collapsible Upcoming list view (4a197f9)
- web: drop Day view from Upcoming page (f53b8c3)
- web: disable Team sidebar link with Coming soon badge (2eb3b82)
- web: show web + mobile together in stories (paired device frames) (085f721)
- web: hero subheadline slogan — Organize your everyday (a7ee44d)
- web: add stories portal i18n copy (en + de/fr/pl/uk) (43d9b32)
- Fixes
- deploy: gate Vercel deploys behind schema migrations (fe374a1)
- mobile: lengthen offline-banner debounce to 8s (70c2438)
- mobile: legible add-task empty chips (fd943ac)
- shared: preserve UTF-16 length when folding emoji in picker filter (fe2f695)
- ui: theme OfflineIndicator banner via Typography (1330e03)
- mobile: close add-task modal before reminder write (c28f50a)
- ui: white quick-add chip text, drop seconds (371f843)
- web: merge offline indicator in-column banner into dev (5595767)
- web: show offline indicator as in-column banner, sr-only when online (077bb2c)
- web: color due/deadline labels via inline style not className (8cd5009)
- shared: keep brand pun 'etappi' literal across locales (5c7bebf)
- shared: scope top-level append to parent_id IS NULL (6806a87)
- shared: createTask append ignores null-default slot (c977520)
- web: soften plan-your-week shot-2 alt to fit web+mobile (c0dbf84)
- web: habit recurrence label + segmented control (ac4d892)
- Other
- web: locale-aware custom tile month + memoize due-tiles (d7b2fae)
- shared: promote day-presets math from mobile to @etappi/shared (432a7ba)
- move pointerEvents prop to style.pointerEvents (3f1a1ef)
iOS 1.14.0 — 2026-06-30 (build 61)
- Features
- project-picker search — filtered-tree picker with gated search (mobile + web) (bdba1f8)
- web: project-picker search — gated FilterInput + filtered-tree highlight (e6a172f)
- mobile: project-picker search — gated FilterInput + filtered-tree highlight (8a8bd7a)
- i18n: project-picker search strings (5 locales) (d0cc679)
- shared: filtered-tree project-picker search core (1f5fd57)
- mobile: merge locale-aware due-time preset labels into dev (fbe06f8)
- mobile: derive due-time preset labels from locale hour-cycle (d562635)
- mobile: de-emphasize "fill empty with AI" row in compose (17e4c80)
- web: merge notifications settings restyle to match Preferences (9e97aaf)
- web: restyle notifications settings to match preferences (ddd6b0e)
- web: redesign settings preferences as compact auto-saving cards (15f5dad)
- web: redesign settings modal (Direction C — unified & airy) (cc3741b)
- db: add capture-showcase seed scenario (b71aff3)
- web: give settings profile pane a manage-account action row (d797ec5)
- web: always show Today section in Upcoming list (7b29d6a)
- web: rebalance task modal type scale to 18/14/12 (2b54d26)
- web: drag-to-reschedule tasks in the Upcoming list view (455ac2d)
- mobile: board, project, decompose create local-first (edb9a93)
- mobile: compose writes task local-first (b4bd1f4)
- shared: createTask binds description + appends position (46272ef)
- web: day-grouped collapsible Upcoming list view (4a197f9)
- web: drop Day view from Upcoming page (f53b8c3)
- web: disable Team sidebar link with Coming soon badge (2eb3b82)
- web: show web + mobile together in stories (paired device frames) (085f721)
- web: hero subheadline slogan — Organize your everyday (a7ee44d)
- web: add stories portal i18n copy (en + de/fr/pl/uk) (43d9b32)
- mobile,web: calendar picker + day-planner time-blocks (ada8d7c)
- api: multi-calendar routing, time-blocks, per-calendar color (d428f39)
- mobile: create labels from the add-task picker sheet (052951d)
- ui: add avoidKeyboard prop to BottomSheetShell (811802f)
- db: add tasks.targetCalendarId + deriveEventTime (bbe53ac)
- Fixes
- mobile: lengthen offline-banner debounce to 8s (70c2438)
- mobile: legible add-task empty chips (fd943ac)
- shared: preserve UTF-16 length when folding emoji in picker filter (fe2f695)
- ui: theme OfflineIndicator banner via Typography (1330e03)
- mobile: close add-task modal before reminder write (c28f50a)
- ui: white quick-add chip text, drop seconds (371f843)
- web: merge offline indicator in-column banner into dev (5595767)
- web: show offline indicator as in-column banner, sr-only when online (077bb2c)
- web: color due/deadline labels via inline style not className (8cd5009)
- shared: keep brand pun 'etappi' literal across locales (5c7bebf)
- shared: scope top-level append to parent_id IS NULL (6806a87)
- shared: createTask append ignores null-default slot (c977520)
- web: soften plan-your-week shot-2 alt to fit web+mobile (c0dbf84)
- web: habit recurrence label + segmented control (ac4d892)
- mobile: gate offline banner on real reachability, not sync status (0b7e8a8)
- mobile: reserve top-bar height before Today loading skeleton (0bbc027)
- calendar: preserve start fields in deriveEventTime, 15m no-duration fallback (e28a39b)
- mobile: guard label create against double-submit (968c547)
- Other
- web: locale-aware custom tile month + memoize due-tiles (d7b2fae)
- shared: promote day-presets math from mobile to @etappi/shared (432a7ba)
- move pointerEvents prop to style.pointerEvents (3f1a1ef)
- mobile: extract insertLocalLabel helper (e8e9a05)
iOS 1.14.0 — 2026-06-30 (build 61)
- Features
- project-picker search — filtered-tree picker with gated search (mobile + web) (bdba1f8)
- web: project-picker search — gated FilterInput + filtered-tree highlight (e6a172f)
- mobile: project-picker search — gated FilterInput + filtered-tree highlight (8a8bd7a)
- i18n: project-picker search strings (5 locales) (d0cc679)
- shared: filtered-tree project-picker search core (1f5fd57)
- mobile: merge locale-aware due-time preset labels into dev (fbe06f8)
- mobile: derive due-time preset labels from locale hour-cycle (d562635)
- mobile: de-emphasize "fill empty with AI" row in compose (17e4c80)
- web: merge notifications settings restyle to match Preferences (9e97aaf)
- web: restyle notifications settings to match preferences (ddd6b0e)
- web: redesign settings preferences as compact auto-saving cards (15f5dad)
- web: redesign settings modal (Direction C — unified & airy) (cc3741b)
- db: add capture-showcase seed scenario (b71aff3)
- web: give settings profile pane a manage-account action row (d797ec5)
- web: always show Today section in Upcoming list (7b29d6a)
- web: rebalance task modal type scale to 18/14/12 (2b54d26)
- web: drag-to-reschedule tasks in the Upcoming list view (455ac2d)
- mobile: board, project, decompose create local-first (edb9a93)
- mobile: compose writes task local-first (b4bd1f4)
- shared: createTask binds description + appends position (46272ef)
- web: day-grouped collapsible Upcoming list view (4a197f9)
- web: drop Day view from Upcoming page (f53b8c3)
- web: disable Team sidebar link with Coming soon badge (2eb3b82)
- web: show web + mobile together in stories (paired device frames) (085f721)
- web: hero subheadline slogan — Organize your everyday (a7ee44d)
- web: add stories portal i18n copy (en + de/fr/pl/uk) (43d9b32)
- mobile,web: calendar picker + day-planner time-blocks (ada8d7c)
- api: multi-calendar routing, time-blocks, per-calendar color (d428f39)
- mobile: create labels from the add-task picker sheet (052951d)
- ui: add avoidKeyboard prop to BottomSheetShell (811802f)
- db: add tasks.targetCalendarId + deriveEventTime (bbe53ac)
- Fixes
- mobile: lengthen offline-banner debounce to 8s (70c2438)
- mobile: legible add-task empty chips (fd943ac)
- shared: preserve UTF-16 length when folding emoji in picker filter (fe2f695)
- ui: theme OfflineIndicator banner via Typography (1330e03)
- mobile: close add-task modal before reminder write (c28f50a)
- ui: white quick-add chip text, drop seconds (371f843)
- web: merge offline indicator in-column banner into dev (5595767)
- web: show offline indicator as in-column banner, sr-only when online (077bb2c)
- web: color due/deadline labels via inline style not className (8cd5009)
- shared: keep brand pun 'etappi' literal across locales (5c7bebf)
- shared: scope top-level append to parent_id IS NULL (6806a87)
- shared: createTask append ignores null-default slot (c977520)
- web: soften plan-your-week shot-2 alt to fit web+mobile (c0dbf84)
- web: habit recurrence label + segmented control (ac4d892)
- mobile: gate offline banner on real reachability, not sync status (0b7e8a8)
- mobile: reserve top-bar height before Today loading skeleton (0bbc027)
- calendar: preserve start fields in deriveEventTime, 15m no-duration fallback (e28a39b)
- mobile: guard label create against double-submit (968c547)
- Other
- web: locale-aware custom tile month + memoize due-tiles (d7b2fae)
- shared: promote day-presets math from mobile to @etappi/shared (432a7ba)
- move pointerEvents prop to style.pointerEvents (3f1a1ef)
- mobile: extract insertLocalLabel helper (e8e9a05)
iOS 1.13.0 — 2026-06-26 (build 60)
- Features
- mobile: hide sync cloud icon in prod builds (d74da95)
- mobile: remove "Back online" badge (4bee91f)
- mobile: hide habit checklist on past calendar days (7665f57)
- mobile: auto-hide offline banner + add "Back online" badge (d546d65)
- pending email invitations with signup reconciliation (68db802)
- Fixes
- ui: anchor create-project modal above keyboard (e4ba793)
- mobile: stop sync icon flap on 60s JWT recycle (9dde474)
- mobile: keep add-task keyboard up on sync (5a374e1)
Android 1.7.0 — 2026-06-26 (versionCode 10)
- Features
- mobile,web: calendar picker + day-planner time-blocks (ada8d7c)
- api: multi-calendar routing, time-blocks, per-calendar color (d428f39)
- db: add tasks.targetCalendarId + deriveEventTime (bbe53ac)
- Fixes
- mobile: gate offline banner on real reachability, not sync status (0b7e8a8)
- mobile: reserve top-bar height before Today loading skeleton (0bbc027)
- calendar: preserve start fields in deriveEventTime, 15m no-duration fallback (e28a39b)
Android 1.6.0 — 2026-06-26 (versionCode 9)
- Features
- mobile: create labels from the add-task picker sheet (052951d)
- ui: add avoidKeyboard prop to BottomSheetShell (811802f)
- mobile: hide sync cloud icon in prod builds (d74da95)
- mobile: remove "Back online" badge (4bee91f)
- mobile: hide habit checklist on past calendar days (7665f57)
- mobile: auto-hide offline banner + add "Back online" badge (d546d65)
- pending email invitations with signup reconciliation (68db802)
- mobile: compass action bar for triage swipe discoverability (4042726)
- triage: hide add-task FAB on triage screen, lift action bar off bottom edge (efef75e)
- triage: celebratory check-circle icon on empty state (82deef7)
- triage: orchestrate progress + peek deck + hint + action bar in deck view (6cc0726)
- triage: tappable action bar wired to card flingTo (today hero / tinted / ghost) (bdeb560)
- triage: progress bar (segmented/continuous) + slim swipe-or-tap hint (ff6c171)
- triage: stacked-card deck with two dimmed peek cards (62523dd)
- triage: overdue-days chip + flingTo handle + drag-badge overlay on card (50d8540)
- triage: live colored drag badge driven by gesture progress (0279c48)
- triage: tap-parity flingTo + drag-progress derived value + reduced-motion gating (b4ee3ea)
- triage: classifyDue overdue helper + unit tests (9b7f50c)
- triage: i18n keys for deck redesign (progress + actions), drop deck.counter, reword hint (55065f7)
- web region & week-start formatting parity (0b06d78)
- thread user week start through date UI and filter (3e50e3a)
- mobile: localize date/time renders via format locale (914aaf4)
- mobile: read region prefs from synced users row (f11a76e)
- mobile: unify search filter creation on the visual builder (b528ca0)
- mobile: add Language & Region screen (4f1d740)
- shared: add locale/week-start formatting core (P2) (81c0dd3)
- mobile: merge rich-label + active-value search filter picker (521a31e)
- mobile: rich labels + active-value selection for search filter picker (0d92720)
- add synced region + weekStartsOn user prefs (schema + REST) (e4cc7f8)
- mobile: show priority meaning in picker (b072a40)
- mobile: localize project action + color sheet labels (a3c3c87)
- ui: merge adaptive reminder custom button + hide dead presets (b2a9a4d)
- ui: adaptive reminder custom-date button + hide dead presets (a217670)
- ui: add avoidKeyboard + dismissOnScrimPress to SheetScaffold (930b547)
- ui: square bottom-sheet top corners (8ba4ab4)
- mobile: redesign project & task action sheets (Direction C) (dbd970f)
- ui: rounded sheet scaffold + action-sheet primitives (67d701b)
- mobile: add Members to project header menu (c8699c6)
- mobile: add confirm-password field to sign-up (48adddd)
- mobile: drive cross-screen onboarding tour navigation (84d49f2)
- prioritize: localize inbox prioritize label set (4083e48)
- mobile: redesign task overflow sheet into grouped icon cards (214a4ff)
- mobile: Save/Cancel editing mode for task title & description (a60b719)
- web: hierarchical project+section picker on compose modal (7364f08)
- shared: add project-picker expand/collapse/section a11y strings (cd5f43d)
- mobile: wire section selection through add-task + compose (c327c23)
- mobile: wire task-detail project picker to sections + sub-projects (055dc7a)
- mobile: hierarchical project-picker sheet with expandable rows + sections (d7d2951)
- mobile: project-picker tree + expand-state hook with tests (b7434d2)
- db: add allSectionsQuery for hierarchical project picker (b4da95f)
- mobile: live deterministic NLP on the compose sheet (718b5bd)
- mobile: attach sign-up errors to offending field (eb4a99c)
- mobile: inline conflict resolution with value diff (e32fc70)
- mobile: mirror optional serverValues in conflict entry schema (8c4d8d6)
- sync: carry server field values in stale-write skipped[] for conflict diff (7244ee2)
- mobile: promote task labels to their own LABELS section (a7ce9e8)
- mobile: hide past reminders in task detail (a10b18d)
- ui: sectioned Repeat sheet with interval and end-date (b856628)
- ui: add Stepper primitive (native + web) (7c8efd7)
- ui: add recurrence state model, build, parse, preview (363a3b8)
- tasks: WHEN tiles tap-to-clear + calendar icon, block past due-times today (754401d)
- calendar: surface add-another-calendar providers when connected (59ab560)
- tasks: make Set-time chip discoverable on task detail (eea0f8b)
- calendar: surface Google OAuth error on mobile connect failure (13695ae)
- i18n: translate habits.reminders.* into uk/pl/de/fr (6c91671)
- mobile: schedule habit reminders as local notifications (90c34a2)
- mobile: reminder time pill on habit edit screen (31b673c)
- i18n: add habits.reminders.* source keys (e137ba3)
- habits: persist + sync per-item & habit-level reminder times (9cb4c67)
- Fixes
- mobile: guard label create against double-submit (968c547)
- ui: anchor create-project modal above keyboard (e4ba793)
- mobile: stop sync icon flap on 60s JWT recycle (9dde474)
- mobile: keep add-task keyboard up on sync (5a374e1)
- triage: use @etappi/ui Pressable in action button (a11y lint rule) (4d3cc38)
- mobile: honor region locale in date pickers (ef933c6)
- mobile: reuse canonical picker chrome for search filter values (6f315d0)
- mobile: fill iOS 26 header capsule (32→36pt) (f7ed3ab)
- ui: announce sheet header titles as accessibility headings (a822283)
- mobile: center icon glyph in iOS 26 header glass capsule (11cd632)
- mobile: mark sheet picker titles as a11y headers (554f750)
- mobile: color inbox prioritize sparkle icon (cd9447b)
- mobile: size iOS 26 header glass capsules (739c4fe)
- ui: pair native fontWeight with font family (24f6579)
- on-primary text on primary-filled surfaces (ed4b2fe)
- mobile: show member name in confirm alerts (e2e1a22)
- mobile: use on-primary ink for invite role chips and button (488de77)
- ui: keep secondary Button readable on press (5a18feb)
- mobile: theme calendar paywall title color (9cb8216)
- mobile: notify subscribers when welcome completes locally (da10cdb)
- mobile: tour spotlight measures + FAB tappable (820f5ce)
- prioritize: empty state + AI request timeouts (cc0aa22)
- mobile: hide inbox AI prioritize on empty inbox (742cad0)
- onboarding: reset process-local onboarding state on sign-out (3f05435)
- onboarding: activate mobile tour for fresh users + wire missing targets (584e045)
- mobile: commit task description on navigate-away too (5ac5bd2)
- mobile: commit task description on keyboard dismiss (73e497c)
- shared: accept geofence columns in task sync schema (540a07b)
- shared: anchor date-only due to local midnight for stable iso (7c9f7bd)
- mobile: add gap below auth subtitle before form (e75dfc3)
- mobile: location picker keyboard, search visibility, current-location default (0386c23)
- mobile: theme conflict primary-button text via on-primary token (0c3a033)
- mobile: block sign-up OTP advance on failed create (7422adf)
- web: localize hardcoded UI strings via next-intl (a0af987)
- mobile: gate PowerSync connection on AppState lifecycle (431ab9d)
- api: health probe false-negative on local db (ea401e6)
- mobile: pin auth-surface text to fixed ink in dark mode (0887cb3)
- mobile: bound realtime reconnect loop to stop native-memory leak (0509ee5)
- mobile: hide AI fill card until task name typed (7405a1b)
- mobile: preserve custom date & time reminders in compose sheet (a78a0b6)
- mobile: anchor compose sheet above keyboard (812a262)
- ui: omit until clause in recurrence preview when no date set (fced775)
- reminders: kill the reminder double-create at every layer (f1de5c3)
- mobile: guard persistent reminder creates against fast double-tap (1562de8)
- mobile: dedupe reminder presets on fast double-tap (1b068b6)
- reminders: dedupe draft preset reminders on fast double-tap (396dfa1)
- tasks: seed time picker at the earliest allowed time on both platforms (cce2753)
- i18n: use single-brace count/remaining placeholders across locales (b747cdc)
- projects: keyboard-avoid board view so add-column input stays visible (496b727)
- mobile: add sso-callback route to stop Android +not-found flash (545470c)
- habits: address reminder scheduler review findings (fb17f33)
- calendar: unstick mobile Google OAuth connect flow (57f1f6d)
- mobile: repair Google SSO redirect and gate splash reveal (cfbc787)
- Other
- mobile: extract insertLocalLabel helper (e8e9a05)
- web: drop Business plan, align pricing CTAs (5b19390)
- remove unused types + dead invite prop (b6232de)
- mobile: notification priority picker onto bottom sheet (cfed822)
- mobile: route group-by pickers onto canonical sheet chrome (b5928ab)
- mobile: native back + text edit headers (a3f863d)
- mobile: migrate project header actions to action sheet (a80a9e6)
- mobile: migrate board column actions to action sheet (e9181c4)
- mobile: migrate add-column dialog to bottom sheet (f5bbde2)
- mobile: migrate save-as-template dialog to bottom sheet (8a2a7b7)
- mobile: migrate task overflow menu to shared sheet (922412c)
- mobile: migrate inbox group-by picker to bottom sheet (ccc926e)
- mobile: migrate search filter-value picker to bottom sheet (833f2b6)
- mobile: dedupe iOS 26 version check (adb1d3e)
- mobile: migrate 3 complex batch-4 sheets onto SheetScaffold (091def4)
- mobile: migrate 6 batch-3 sheets onto SheetScaffold (debd647)
- mobile: migrate 6 moderate sheets onto shared SheetScaffold (30f451b)
- mobile: migrate 6 simple sheets onto shared SheetScaffold (04b237a)
- ui: collapse bottom-sheet shells onto SheetScaffold (f98f422)
- mobile: scroll task detail body under sticky header (38fcbe2)
- ui: move family task-list-row chevron to trailing edge (de3ac25)
iOS 1.13.0 — 2026-06-26 (build 60)
- Features
- mobile: hide sync cloud icon in prod builds (d74da95)
- mobile: remove "Back online" badge (4bee91f)
- mobile: hide habit checklist on past calendar days (7665f57)
- mobile: auto-hide offline banner + add "Back online" badge (d546d65)
- pending email invitations with signup reconciliation (68db802)
- Fixes
- ui: anchor create-project modal above keyboard (e4ba793)
- mobile: stop sync icon flap on 60s JWT recycle (9dde474)
- mobile: keep add-task keyboard up on sync (5a374e1)
iOS 1.12.0 — 2026-06-25 (build 59)
- Features
- mobile: compass action bar for triage swipe discoverability (4042726)
- triage: hide add-task FAB on triage screen, lift action bar off bottom edge (efef75e)
- triage: celebratory check-circle icon on empty state (82deef7)
- triage: orchestrate progress + peek deck + hint + action bar in deck view (6cc0726)
- triage: tappable action bar wired to card flingTo (today hero / tinted / ghost) (bdeb560)
- triage: progress bar (segmented/continuous) + slim swipe-or-tap hint (ff6c171)
- triage: stacked-card deck with two dimmed peek cards (62523dd)
- triage: overdue-days chip + flingTo handle + drag-badge overlay on card (50d8540)
- triage: live colored drag badge driven by gesture progress (0279c48)
- triage: tap-parity flingTo + drag-progress derived value + reduced-motion gating (b4ee3ea)
- triage: classifyDue overdue helper + unit tests (9b7f50c)
- triage: i18n keys for deck redesign (progress + actions), drop deck.counter, reword hint (55065f7)
- web region & week-start formatting parity (0b06d78)
- thread user week start through date UI and filter (3e50e3a)
- mobile: localize date/time renders via format locale (914aaf4)
- mobile: read region prefs from synced users row (f11a76e)
- mobile: unify search filter creation on the visual builder (b528ca0)
- mobile: add Language & Region screen (4f1d740)
- shared: add locale/week-start formatting core (P2) (81c0dd3)
- mobile: merge rich-label + active-value search filter picker (521a31e)
- mobile: rich labels + active-value selection for search filter picker (0d92720)
- add synced region + weekStartsOn user prefs (schema + REST) (e4cc7f8)
- mobile: show priority meaning in picker (b072a40)
- mobile: localize project action + color sheet labels (a3c3c87)
- ui: merge adaptive reminder custom button + hide dead presets (b2a9a4d)
- ui: adaptive reminder custom-date button + hide dead presets (a217670)
- ui: add avoidKeyboard + dismissOnScrimPress to SheetScaffold (930b547)
- ui: square bottom-sheet top corners (8ba4ab4)
- mobile: redesign project & task action sheets (Direction C) (dbd970f)
- ui: rounded sheet scaffold + action-sheet primitives (67d701b)
- mobile: add Members to project header menu (c8699c6)
- mobile: add confirm-password field to sign-up (48adddd)
- mobile: drive cross-screen onboarding tour navigation (84d49f2)
- prioritize: localize inbox prioritize label set (4083e48)
- mobile: redesign task overflow sheet into grouped icon cards (214a4ff)
- mobile: Save/Cancel editing mode for task title & description (a60b719)
- web: hierarchical project+section picker on compose modal (7364f08)
- shared: add project-picker expand/collapse/section a11y strings (cd5f43d)
- mobile: wire section selection through add-task + compose (c327c23)
- mobile: wire task-detail project picker to sections + sub-projects (055dc7a)
- mobile: hierarchical project-picker sheet with expandable rows + sections (d7d2951)
- mobile: project-picker tree + expand-state hook with tests (b7434d2)
- db: add allSectionsQuery for hierarchical project picker (b4da95f)
- mobile: live deterministic NLP on the compose sheet (718b5bd)
- mobile: attach sign-up errors to offending field (eb4a99c)
- mobile: inline conflict resolution with value diff (e32fc70)
- mobile: mirror optional serverValues in conflict entry schema (8c4d8d6)
- sync: carry server field values in stale-write skipped[] for conflict diff (7244ee2)
- Fixes
- triage: use @etappi/ui Pressable in action button (a11y lint rule) (4d3cc38)
- mobile: honor region locale in date pickers (ef933c6)
- mobile: reuse canonical picker chrome for search filter values (6f315d0)
- mobile: fill iOS 26 header capsule (32→36pt) (f7ed3ab)
- ui: announce sheet header titles as accessibility headings (a822283)
- mobile: center icon glyph in iOS 26 header glass capsule (11cd632)
- mobile: mark sheet picker titles as a11y headers (554f750)
- mobile: color inbox prioritize sparkle icon (cd9447b)
- mobile: size iOS 26 header glass capsules (739c4fe)
- ui: pair native fontWeight with font family (24f6579)
- on-primary text on primary-filled surfaces (ed4b2fe)
- mobile: show member name in confirm alerts (e2e1a22)
- mobile: use on-primary ink for invite role chips and button (488de77)
- ui: keep secondary Button readable on press (5a18feb)
- mobile: theme calendar paywall title color (9cb8216)
- mobile: notify subscribers when welcome completes locally (da10cdb)
- mobile: tour spotlight measures + FAB tappable (820f5ce)
- prioritize: empty state + AI request timeouts (cc0aa22)
- mobile: hide inbox AI prioritize on empty inbox (742cad0)
- onboarding: reset process-local onboarding state on sign-out (3f05435)
- onboarding: activate mobile tour for fresh users + wire missing targets (584e045)
- mobile: commit task description on navigate-away too (5ac5bd2)
- mobile: commit task description on keyboard dismiss (73e497c)
- shared: accept geofence columns in task sync schema (540a07b)
- shared: anchor date-only due to local midnight for stable iso (7c9f7bd)
- mobile: add gap below auth subtitle before form (e75dfc3)
- mobile: location picker keyboard, search visibility, current-location default (0386c23)
- mobile: theme conflict primary-button text via on-primary token (0c3a033)
- mobile: block sign-up OTP advance on failed create (7422adf)
- web: localize hardcoded UI strings via next-intl (a0af987)
- mobile: gate PowerSync connection on AppState lifecycle (431ab9d)
- api: health probe false-negative on local db (ea401e6)
- mobile: pin auth-surface text to fixed ink in dark mode (0887cb3)
- mobile: bound realtime reconnect loop to stop native-memory leak (0509ee5)
- mobile: hide AI fill card until task name typed (7405a1b)
- mobile: preserve custom date & time reminders in compose sheet (a78a0b6)
- mobile: anchor compose sheet above keyboard (812a262)
- Other
- remove unused types + dead invite prop (b6232de)
- mobile: notification priority picker onto bottom sheet (cfed822)
- mobile: route group-by pickers onto canonical sheet chrome (b5928ab)
- mobile: native back + text edit headers (a3f863d)
- mobile: migrate project header actions to action sheet (a80a9e6)
- mobile: migrate board column actions to action sheet (e9181c4)
- mobile: migrate add-column dialog to bottom sheet (f5bbde2)
- mobile: migrate save-as-template dialog to bottom sheet (8a2a7b7)
- mobile: migrate task overflow menu to shared sheet (922412c)
- mobile: migrate inbox group-by picker to bottom sheet (ccc926e)
- mobile: migrate search filter-value picker to bottom sheet (833f2b6)
- mobile: dedupe iOS 26 version check (adb1d3e)
- mobile: migrate 3 complex batch-4 sheets onto SheetScaffold (091def4)
- mobile: migrate 6 batch-3 sheets onto SheetScaffold (debd647)
- mobile: migrate 6 moderate sheets onto shared SheetScaffold (30f451b)
- mobile: migrate 6 simple sheets onto shared SheetScaffold (04b237a)
- ui: collapse bottom-sheet shells onto SheetScaffold (f98f422)
iOS 1.11.0 — 2026-06-21 (build 58)
- Features
- mobile: promote task labels to their own LABELS section (a7ce9e8)
- mobile: hide past reminders in task detail (a10b18d)
- ui: sectioned Repeat sheet with interval and end-date (b856628)
- ui: add Stepper primitive (native + web) (7c8efd7)
- ui: add recurrence state model, build, parse, preview (363a3b8)
- tasks: WHEN tiles tap-to-clear + calendar icon, block past due-times today (754401d)
- calendar: surface add-another-calendar providers when connected (59ab560)
- tasks: make Set-time chip discoverable on task detail (eea0f8b)
- calendar: surface Google OAuth error on mobile connect failure (13695ae)
- i18n: translate habits.reminders.* into uk/pl/de/fr (6c91671)
- mobile: schedule habit reminders as local notifications (90c34a2)
- mobile: reminder time pill on habit edit screen (31b673c)
- i18n: add habits.reminders.* source keys (e137ba3)
- habits: persist + sync per-item & habit-level reminder times (9cb4c67)
- Fixes
- ui: omit until clause in recurrence preview when no date set (fced775)
- reminders: kill the reminder double-create at every layer (f1de5c3)
- mobile: guard persistent reminder creates against fast double-tap (1562de8)
- mobile: dedupe reminder presets on fast double-tap (1b068b6)
- reminders: dedupe draft preset reminders on fast double-tap (396dfa1)
- tasks: seed time picker at the earliest allowed time on both platforms (cce2753)
- i18n: use single-brace count/remaining placeholders across locales (b747cdc)
- projects: keyboard-avoid board view so add-column input stays visible (496b727)
- mobile: add sso-callback route to stop Android +not-found flash (545470c)
- habits: address reminder scheduler review findings (fb17f33)
- calendar: unstick mobile Google OAuth connect flow (57f1f6d)
- Other
- mobile: scroll task detail body under sticky header (38fcbe2)
- ui: move family task-list-row chevron to trailing edge (de3ac25)
iOS 1.10.2 — 2026-06-20 (build 57)
- Fixes
- mobile: repair Google SSO redirect and gate splash reveal (cfbc787)
iOS 1.10.2 — 2026-06-20 (build 57)
- Fixes
- mobile: repair Google SSO redirect and gate splash reveal (cfbc787)
iOS 1.10.1 — 2026-06-19 (build 56)
No user-visible changes since previous release.
Android 1.5.0 — 2026-06-19 (versionCode 8)
- Features
- calendar: multi-calendar support with one default push target (bd69e45)
- mobile: resume abandoned email-code sign-up verification (043ce7b)
iOS 1.10.0 — 2026-06-19 (build 55)
- Features
- calendar: multi-calendar support with one default push target (bd69e45)
- mobile: resume abandoned email-code sign-up verification (043ce7b)
Android 1.4.0 — 2026-06-19 (versionCode 7)
- Features
- mobile: checkmark + split-tap habit rows (b4d698a)
- mobile: habit calendar history + habit_logs PATCH sync (61c8bfe)
- mobile: replace habit heatmap with a month-calendar history (07c311f)
- api: add PATCH /api/sync/habit_logs for in-place habit-log edits (a93d338)
- i18n: add settings hub group + sub-screen header keys (e9e457a)
- mobile: rewrite settings hub as grouped nav-row list (869ca3a)
- mobile: add routed settings sub-screens hosting existing sections (bcf6d32)
- i18n: route hardcoded mobile + web strings through i18n (0910bfd)
- ui: surface habits on Today + Browse (mobile) and a Routines sidebar group (web) (bbafeff)
- checkbox completion dwell — hold just-completed rows checked before they leave (f9f3412)
- i18n: translate habits empty-state + Routines keys for de/fr/pl/uk (fe373b0)
- mobile: promote Browse Habits tile to a full-width hero (c05bdec)
- mobile: persistent 3-state habits section on Today (ce0d943)
- i18n: add habits-today empty-card + routines keys (en source) (2c83d77)
- mobile: dwell just-completed Today rows in place before re-bucketing to Done (643f113)
- ui: lighten prominent primary glyphs via contrast-aware --color-on-primary-vivid (e9c2e8e)
- mobile: wire completion dwell into vanishing lists (inbox, next actions, projects, search) (1365b46)
- mobile: present compose as centered modal dialog (ae06105)
- mobile: offline-durable reminders + wire reminders into compose (4814935)
- mobile: add completion-dwell hook for checked task rows (7809e4c)
- mobile: remove swipe-to-change-tabs gesture and edge gutters (4da73a6)
- mobile: merge task-detail offline-safe local-first writes (858fdc0)
- mobile: make task-detail edits local-first (offline-safe) (055d321)
- mobile: fire task-created toast after compose create (cb158b2)
- BETA_FREE_PROAI giveaway floor (all users → Pro+AI, reversible) (60d9b66)
- ui: unify Add section/sub-project trigger to body 16px semibold (fdb6e7d)
- mobile: merge collapsible Quick Actions header on Browse (c4383c3)
- collapsible Quick Actions header on mobile Browse (ff3804d)
- mobile: merge auth redesign — floating-card UI + brand-orange CTA (248f96d)
- mobile: restyle welcome screen to match auth redesign (77c051e)
- mobile: rebuild auth screens on floating-card design (636f9ce)
- mobile: add shared auth UI components (3226e93)
- i18n: add auth.or_continue_with social divider key (2a0192f)
- ui: add Button.loading prop with spinner state (90e2c1b)
- task-created 'Open' toast on mobile add-task + web compose/quick-add (92180d2)
- mobile: show 'Task created · Open' toast after add-task save (2dc1c9f)
- shared/i18n: add toast.task_created + toast.open keys (82708c0)
- web,mobile: guard PowerSync-path create/edit handlers against double-submit (a23a9e9)
- web,mobile: guard useRestMutation against double-submit (395060c)
- shared: add useSubmitGuard re-entrancy guard hook (5495d33)
- api: merge plan-gate 6 — dev/setPlan all paid tiers + entitlements.tier CHECK (30450e0)
- api: widen dev/setPlan to all paid tiers + lock entitlements.tier (e4b6200)
- mobile/paywall: redesign paywall screen (Direction C, tap-to-buy) (1f4bd34)
- i18n: translate paywall redesign keys to de/fr/pl/uk (f562545)
- mobile/paywall: compose new sub-components in screen shell (6ec3cbf)
- mobile/paywall: inline restored panel + reload via reloadTick (b45e3c3)
- web: gate activity log behind paid plan (ada49af)
- mobile/paywall: redesign plan cards (split row, featured outline, MOST POPULAR badge) (65b23bd)
- shared: add planHasActivityLog plan-tier helper (562428f)
- mobile/paywall: add PaywallError + PaywallRestored panels (68ce006)
- mobile/paywall: add PaywallUnavailable component (71b1f8f)
- mobile/paywall: add PaywallFeaturesList component (2d6a284)
- mobile/paywall: add PaywallHero component (7ce0a70)
- i18n: add paywall redesign keys (en) (37e1613)
- shared: add planIsPaid helper; use in web focus stats gate (7906b7f)
- mobile: always play full splash reveal animation (64f62b9)
- mobile: splash squares reveal animation (ff36b5b)
- mobile: promote Plan with AI to solid full-width tile + brand fresh-user sparkle (bc4058d)
- Fixes
- mobile: sync i18n bootstrap before splash (8bd5ca3)
- mobile: eliminate cold-start white flash before splash animation (af461ba)
- habits: local-first create + edit so the detail screen shows saved changes (2d98a22)
- mobile: label reminder chip "1 reminder" + bell, not ambiguous "1 set" (d07c9a5)
- mobile: drop blank habit checklist rows before save (627b723)
- mobile: centralize Hermes-safe id generation behind injectable newId (fca7fb5)
- mobile: mint habit-log id via expo-crypto, not uuid (Hermes crash) (b30abaf)
- mobile: make habit-log toggle local-first (2148821)
- today: always render the habits section regardless of task count (e49a33b)
- mobile: repair compose sheet create + layout (159e58c)
- dwell: resolve completion snapshot race-free via prev-render window (5964f8b)
- mobile: silence no-spacer-view on browse filter boundary gap (14303bd)
- mobile: add gap between browse filter and project list (34a195e)
- mobile: center project-row rail in leading inset (197fdcb)
- api: merge comment-push amplification throttle (faaa3b3)
- api: throttle comment-push fan-out to close sync-limiter amplification (554d886)
- mobile: floor compose sheet footer at safe-area bottom inset (5f32099)
- mobile: unfragment dashed scheduling-chip outline (22e7f0b)
- mobile: use paddingTop for inbox top inset (2c0741f)
- mobile: inbox subtask indent + collapse (491a064)
- mobile: bound project header title so long names ellipsize (cd263b2)
- mobile: merge widget extension version fix (ITMS-90473) (1373386)
- mobile: track widget extension version from ios.version (e3b392b)
- mobile: keep tab FAB mounted on blur, clear on unmount (e82eb0f)
- mobile: render neutral bg while biometric pref loads (6382646)
- mobile: tint board column with surface token instead of background (07f1baa)
- mobile: match Browse FAB plus glyph size to other tabs (214e88b)
- ui: raise quick-add bar contrast, add bottom inset (740d2ec)
- mobile: wire auth text to fixed inks + brand-orange CTA (28a65e5)
- one-Inbox-per-user dedupe + slow-query proxy data-loss fix (5245f9e)
- api: stop slow-query proxy from breaking db.delete().where() (923faaf)
- db: guarantee one Inbox per user (dedupe migration + unique index + adopt-existing) (77cfdbf)
- mobile: theme add-task modal card (a1b8b58)
- mobile: focus compose title after sheet enter (4cf3fe5)
- shared: normalize labelIds to string[] at schema boundary (eecf005)
- api: hand off OAuth-start auth via single-use nonce, keep JWT out of URLs (2819021)
- repair failing local CI gates (0a19da1)
- mobile: fire task-created toast on insert, not after reminder write (c21e8c3)
- mobile/paywall: use useGuardedRouter for the close handler (18a7ad2)
- mobile/biometric: correct off-by-one in PIN attempts-before-lockout counter (a07d096)
- mobile/paywall: set transparent header at root, override headerLeft in screen (2f88cac)
- mobile/paywall: add transparent header with X close button (f63998d)
- mobile: restyle compose footer Cancel/Create as full-width buttons (f811e49)
- mobile/paywall: register paywall as modal at root stack (1deab3a)
- mobile/paywall: hide redundant modal header above hero (7c071b5)
- mobile: merge fab follow-ups — tourTarget thread + config owner guard (7d177e1)
- mobile: thread FAB tourTarget, guard config owner (957c7fc)
- mobile: hoist tab FAB out of animated scenes (49d8d1b)
- web: fit inbox placeholder to column width (b08a75b)
- mobile: soften Plan with AI tile fill to 90% primary (9ffa951)
- mobile: slow add-task modal slide-up to 500ms (06907ce)
- mobile: slow tab-switch animation to 300ms (ca3695b)
- keyboard avoidance broken on Android edge-to-edge (d79fa39)
- mobile: keep splash up until ClerkLoaded to avoid +not-found flash (114e468)
- ui: avoid keyboard overlap in create-project modal (097958c)
- Other
- mobile: use SectionLabel for task-dependencies heading (78d16b6)
- mobile: extract CalendarMonthShell from CalendarMonth (0f22b47)
- mobile: drop section wrappers superseded by settings hub (050e565)
- mobile: restyle settings-row with leading icon + rounded section card (8a92f05)
- mobile: fixed splash hold, drop sync-gated readiness (3a49cb8)
- mobile: centralize pre-auth color palette (f1d6348)
- web,mobile: keep submit-guarded files under the 150 LOC cap (611d0b6)
iOS 1.9.0 — 2026-06-19 (build 54)
- Features
- mobile: checkmark + split-tap habit rows (b4d698a)
- Fixes
- mobile: sync i18n bootstrap before splash (8bd5ca3)
iOS 1.8.0 — 2026-06-19 (build 53)
- Features
- mobile: habit calendar history + habit_logs PATCH sync (61c8bfe)
- mobile: replace habit heatmap with a month-calendar history (07c311f)
- api: add PATCH /api/sync/habit_logs for in-place habit-log edits (a93d338)
- i18n: add settings hub group + sub-screen header keys (e9e457a)
- mobile: rewrite settings hub as grouped nav-row list (869ca3a)
- mobile: add routed settings sub-screens hosting existing sections (bcf6d32)
- i18n: route hardcoded mobile + web strings through i18n (0910bfd)
- ui: surface habits on Today + Browse (mobile) and a Routines sidebar group (web) (bbafeff)
- checkbox completion dwell — hold just-completed rows checked before they leave (f9f3412)
- i18n: translate habits empty-state + Routines keys for de/fr/pl/uk (fe373b0)
- mobile: promote Browse Habits tile to a full-width hero (c05bdec)
- mobile: persistent 3-state habits section on Today (ce0d943)
- i18n: add habits-today empty-card + routines keys (en source) (2c83d77)
- mobile: dwell just-completed Today rows in place before re-bucketing to Done (643f113)
- ui: lighten prominent primary glyphs via contrast-aware --color-on-primary-vivid (e9c2e8e)
- mobile: wire completion dwell into vanishing lists (inbox, next actions, projects, search) (1365b46)
- mobile: present compose as centered modal dialog (ae06105)
- mobile: offline-durable reminders + wire reminders into compose (4814935)
- mobile: add completion-dwell hook for checked task rows (7809e4c)
- mobile: remove swipe-to-change-tabs gesture and edge gutters (4da73a6)
- mobile: merge task-detail offline-safe local-first writes (858fdc0)
- mobile: make task-detail edits local-first (offline-safe) (055d321)
- Fixes
- mobile: eliminate cold-start white flash before splash animation (af461ba)
- habits: local-first create + edit so the detail screen shows saved changes (2d98a22)
- mobile: label reminder chip "1 reminder" + bell, not ambiguous "1 set" (d07c9a5)
- mobile: drop blank habit checklist rows before save (627b723)
- mobile: centralize Hermes-safe id generation behind injectable newId (fca7fb5)
- mobile: mint habit-log id via expo-crypto, not uuid (Hermes crash) (b30abaf)
- mobile: make habit-log toggle local-first (2148821)
- today: always render the habits section regardless of task count (e49a33b)
- mobile: repair compose sheet create + layout (159e58c)
- dwell: resolve completion snapshot race-free via prev-render window (5964f8b)
- mobile: silence no-spacer-view on browse filter boundary gap (14303bd)
- mobile: add gap between browse filter and project list (34a195e)
- mobile: center project-row rail in leading inset (197fdcb)
- api: merge comment-push amplification throttle (faaa3b3)
- api: throttle comment-push fan-out to close sync-limiter amplification (554d886)
- mobile: floor compose sheet footer at safe-area bottom inset (5f32099)
- mobile: unfragment dashed scheduling-chip outline (22e7f0b)
- Other
- mobile: use SectionLabel for task-dependencies heading (78d16b6)
- mobile: extract CalendarMonthShell from CalendarMonth (0f22b47)
- mobile: drop section wrappers superseded by settings hub (050e565)
- mobile: restyle settings-row with leading icon + rounded section card (8a92f05)
iOS 1.7.0 — 2026-06-17 (build 52)
- Features
- mobile: remove swipe-to-change-tabs gesture and edge gutters (4da73a6)
- mobile: merge task-detail offline-safe local-first writes (858fdc0)
- mobile: make task-detail edits local-first (offline-safe) (055d321)
- Fixes
- api: merge comment-push amplification throttle (faaa3b3)
- api: throttle comment-push fan-out to close sync-limiter amplification (554d886)
- mobile: floor compose sheet footer at safe-area bottom inset (5f32099)
- mobile: unfragment dashed scheduling-chip outline (22e7f0b)
iOS 1.6.1 — 2026-06-16 (build 51)
- Features
- mobile: fire task-created toast after compose create (cb158b2)
- BETA_FREE_PROAI giveaway floor (all users → Pro+AI, reversible) (60d9b66)
- Fixes
- mobile: use paddingTop for inbox top inset (2c0741f)
- mobile: inbox subtask indent + collapse (491a064)
- mobile: bound project header title so long names ellipsize (cd263b2)
- mobile: merge widget extension version fix (ITMS-90473) (1373386)
- mobile: track widget extension version from ios.version (e3b392b)
- mobile: keep tab FAB mounted on blur, clear on unmount (e82eb0f)
- mobile: render neutral bg while biometric pref loads (6382646)
- Other
- mobile: fixed splash hold, drop sync-gated readiness (3a49cb8)
iOS 1.3.0 — 2026-06-15 (build 44)
- Features
- ui: unify Add section/sub-project trigger to body 16px semibold (fdb6e7d)
- mobile: merge collapsible Quick Actions header on Browse (c4383c3)
- collapsible Quick Actions header on mobile Browse (ff3804d)
- mobile: merge auth redesign — floating-card UI + brand-orange CTA (248f96d)
- mobile: restyle welcome screen to match auth redesign (77c051e)
- mobile: rebuild auth screens on floating-card design (636f9ce)
- mobile: add shared auth UI components (3226e93)
- i18n: add auth.or_continue_with social divider key (2a0192f)
- ui: add Button.loading prop with spinner state (90e2c1b)
- task-created 'Open' toast on mobile add-task + web compose/quick-add (92180d2)
- mobile: show 'Task created · Open' toast after add-task save (2dc1c9f)
- shared/i18n: add toast.task_created + toast.open keys (82708c0)
- web,mobile: guard PowerSync-path create/edit handlers against double-submit (a23a9e9)
- web,mobile: guard useRestMutation against double-submit (395060c)
- shared: add useSubmitGuard re-entrancy guard hook (5495d33)
- api: merge plan-gate 6 — dev/setPlan all paid tiers + entitlements.tier CHECK (30450e0)
- api: widen dev/setPlan to all paid tiers + lock entitlements.tier (e4b6200)
- mobile/paywall: redesign paywall screen (Direction C, tap-to-buy) (1f4bd34)
- i18n: translate paywall redesign keys to de/fr/pl/uk (f562545)
- mobile/paywall: compose new sub-components in screen shell (6ec3cbf)
- mobile/paywall: inline restored panel + reload via reloadTick (b45e3c3)
- web: gate activity log behind paid plan (ada49af)
- mobile/paywall: redesign plan cards (split row, featured outline, MOST POPULAR badge) (65b23bd)
- shared: add planHasActivityLog plan-tier helper (562428f)
- mobile/paywall: add PaywallError + PaywallRestored panels (68ce006)
- mobile/paywall: add PaywallUnavailable component (71b1f8f)
- mobile/paywall: add PaywallFeaturesList component (2d6a284)
- mobile/paywall: add PaywallHero component (7ce0a70)
- i18n: add paywall redesign keys (en) (37e1613)
- shared: add planIsPaid helper; use in web focus stats gate (7906b7f)
- mobile: always play full splash reveal animation (64f62b9)
- mobile: splash squares reveal animation (ff36b5b)
- mobile: promote Plan with AI to solid full-width tile + brand fresh-user sparkle (bc4058d)
- mobile: drop ContextFAB from project detail screen (5a1c1f5)
- i18n: add task.add_a11y, task.add_to_project_a11y, filters.new_a11y (20fa59d)
- mobile: context-aware FAB on project, board, filter, habits, next-actions, triage (1e89f29)
- mobile: wire ContextFAB on 4 tab screens, seed compose context (c1d64fb)
- mobile: add ContextFAB chrome primitive + tests (5cf5ac5)
- mobile: board column footer redesign (1d1a52d)
- mobile: add SheetHandle component and handle_a11y i18n key (43afa1c)
- mobile: hoist title input and manual keyboard tracking in compose sheet (b418784)
- i18n,docs: visual filter builder strings + docs/features/filters.md (a007570)
- mobile: wire filter editor nav + drop inline creator (6ba4cf4)
- mobile: visual filter create/edit screens with live preview (4790884)
- mobile: visual filter builder primitives (rows + sheets) (fba3477)
- shared: visual filter model + DSL serializer + legacy parser (1e4668d)
- mobile: name the blocking task when tapping a blocked checkbox (a1e628e)
- Fixes
- mobile: tint board column with surface token instead of background (07f1baa)
- mobile: match Browse FAB plus glyph size to other tabs (214e88b)
- ui: raise quick-add bar contrast, add bottom inset (740d2ec)
- mobile: wire auth text to fixed inks + brand-orange CTA (28a65e5)
- one-Inbox-per-user dedupe + slow-query proxy data-loss fix (5245f9e)
- api: stop slow-query proxy from breaking db.delete().where() (923faaf)
- db: guarantee one Inbox per user (dedupe migration + unique index + adopt-existing) (77cfdbf)
- mobile: theme add-task modal card (a1b8b58)
- mobile: focus compose title after sheet enter (4cf3fe5)
- shared: normalize labelIds to string[] at schema boundary (eecf005)
- api: hand off OAuth-start auth via single-use nonce, keep JWT out of URLs (2819021)
- repair failing local CI gates (0a19da1)
- mobile: fire task-created toast on insert, not after reminder write (c21e8c3)
- mobile/paywall: use useGuardedRouter for the close handler (18a7ad2)
- mobile/biometric: correct off-by-one in PIN attempts-before-lockout counter (a07d096)
- mobile/paywall: set transparent header at root, override headerLeft in screen (2f88cac)
- mobile/paywall: add transparent header with X close button (f63998d)
- mobile: restyle compose footer Cancel/Create as full-width buttons (f811e49)
- mobile/paywall: register paywall as modal at root stack (1deab3a)
- mobile/paywall: hide redundant modal header above hero (7c071b5)
- mobile: merge fab follow-ups — tourTarget thread + config owner guard (7d177e1)
- mobile: thread FAB tourTarget, guard config owner (957c7fc)
- mobile: hoist tab FAB out of animated scenes (49d8d1b)
- web: fit inbox placeholder to column width (b08a75b)
- mobile: soften Plan with AI tile fill to 90% primary (9ffa951)
- mobile: slow add-task modal slide-up to 500ms (06907ce)
- mobile: slow tab-switch animation to 300ms (ca3695b)
- keyboard avoidance broken on Android edge-to-edge (d79fa39)
- mobile: keep splash up until ClerkLoaded to avoid +not-found flash (114e468)
- ui: avoid keyboard overlap in create-project modal (097958c)
- ui: size native Skeleton fill correctly (c436b97)
- ui: size Skeleton fill correctly + restore pulse (9706403)
- mobile: wire compose Create button to tasks.create (3d429be)
- mobile: always-mount compose sheet to kill open flash (511b0bb)
- mobile: snap compose scrim instead of fading on open (2d4ec49)
- mobile: snap compose scrim opacity to kill open flash (f14cb4e)
- mobile: slide compose sheet in and cover keyboard gap (b55c771)
- mobile: edit button on run screen main branch + lint escape for legacy header (4e9546a)
- mobile: show blocked-by chip on project task rows (625c000)
- mobile: AI plan sheet keyboard avoidance + 60s timeout + header ellipsis (7183a92)
- Other
- mobile: centralize pre-auth color palette (f1d6348)
- web,mobile: keep submit-guarded files under the 150 LOC cap (611d0b6)
- mobile: collapse compose sheet to detailed-only (c882974)
iOS 1.2.0 — 2026-06-15 (build 43)
- Features
- task-created 'Open' toast on mobile add-task + web compose/quick-add (92180d2)
- mobile: show 'Task created · Open' toast after add-task save (2dc1c9f)
- shared/i18n: add toast.task_created + toast.open keys (82708c0)
- web,mobile: guard PowerSync-path create/edit handlers against double-submit (a23a9e9)
- web,mobile: guard useRestMutation against double-submit (395060c)
- shared: add useSubmitGuard re-entrancy guard hook (5495d33)
- api: merge plan-gate 6 — dev/setPlan all paid tiers + entitlements.tier CHECK (30450e0)
- api: widen dev/setPlan to all paid tiers + lock entitlements.tier (e4b6200)
- mobile/paywall: redesign paywall screen (Direction C, tap-to-buy) (1f4bd34)
- i18n: translate paywall redesign keys to de/fr/pl/uk (f562545)
- mobile/paywall: compose new sub-components in screen shell (6ec3cbf)
- mobile/paywall: inline restored panel + reload via reloadTick (b45e3c3)
- web: gate activity log behind paid plan (ada49af)
- mobile/paywall: redesign plan cards (split row, featured outline, MOST POPULAR badge) (65b23bd)
- shared: add planHasActivityLog plan-tier helper (562428f)
- mobile/paywall: add PaywallError + PaywallRestored panels (68ce006)
- mobile/paywall: add PaywallUnavailable component (71b1f8f)
- mobile/paywall: add PaywallFeaturesList component (2d6a284)
- mobile/paywall: add PaywallHero component (7ce0a70)
- i18n: add paywall redesign keys (en) (37e1613)
- shared: add planIsPaid helper; use in web focus stats gate (7906b7f)
- mobile: always play full splash reveal animation (64f62b9)
- mobile: splash squares reveal animation (ff36b5b)
- mobile: promote Plan with AI to solid full-width tile + brand fresh-user sparkle (bc4058d)
- mobile: drop ContextFAB from project detail screen (5a1c1f5)
- i18n: add task.add_a11y, task.add_to_project_a11y, filters.new_a11y (20fa59d)
- mobile: context-aware FAB on project, board, filter, habits, next-actions, triage (1e89f29)
- mobile: wire ContextFAB on 4 tab screens, seed compose context (c1d64fb)
- mobile: add ContextFAB chrome primitive + tests (5cf5ac5)
- mobile: board column footer redesign (1d1a52d)
- mobile: add SheetHandle component and handle_a11y i18n key (43afa1c)
- mobile: hoist title input and manual keyboard tracking in compose sheet (b418784)
- i18n,docs: visual filter builder strings + docs/features/filters.md (a007570)
- mobile: wire filter editor nav + drop inline creator (6ba4cf4)
- mobile: visual filter create/edit screens with live preview (4790884)
- mobile: visual filter builder primitives (rows + sheets) (fba3477)
- shared: visual filter model + DSL serializer + legacy parser (1e4668d)
- mobile: name the blocking task when tapping a blocked checkbox (a1e628e)
- Fixes
- mobile: fire task-created toast on insert, not after reminder write (c21e8c3)
- mobile/paywall: use useGuardedRouter for the close handler (18a7ad2)
- mobile/biometric: correct off-by-one in PIN attempts-before-lockout counter (a07d096)
- mobile/paywall: set transparent header at root, override headerLeft in screen (2f88cac)
- mobile/paywall: add transparent header with X close button (f63998d)
- mobile: restyle compose footer Cancel/Create as full-width buttons (f811e49)
- mobile/paywall: register paywall as modal at root stack (1deab3a)
- mobile/paywall: hide redundant modal header above hero (7c071b5)
- mobile: merge fab follow-ups — tourTarget thread + config owner guard (7d177e1)
- mobile: thread FAB tourTarget, guard config owner (957c7fc)
- mobile: hoist tab FAB out of animated scenes (49d8d1b)
- web: fit inbox placeholder to column width (b08a75b)
- mobile: soften Plan with AI tile fill to 90% primary (9ffa951)
- mobile: slow add-task modal slide-up to 500ms (06907ce)
- mobile: slow tab-switch animation to 300ms (ca3695b)
- keyboard avoidance broken on Android edge-to-edge (d79fa39)
- mobile: keep splash up until ClerkLoaded to avoid +not-found flash (114e468)
- ui: avoid keyboard overlap in create-project modal (097958c)
- ui: size native Skeleton fill correctly (c436b97)
- ui: size Skeleton fill correctly + restore pulse (9706403)
- mobile: wire compose Create button to tasks.create (3d429be)
- mobile: always-mount compose sheet to kill open flash (511b0bb)
- mobile: snap compose scrim instead of fading on open (2d4ec49)
- mobile: snap compose scrim opacity to kill open flash (f14cb4e)
- mobile: slide compose sheet in and cover keyboard gap (b55c771)
- mobile: edit button on run screen main branch + lint escape for legacy header (4e9546a)
- mobile: show blocked-by chip on project task rows (625c000)
- mobile: AI plan sheet keyboard avoidance + 60s timeout + header ellipsis (7183a92)
- Other
- web,mobile: keep submit-guarded files under the 150 LOC cap (611d0b6)
- mobile: collapse compose sheet to detailed-only (c882974)
Android 1.2.0 — 2026-06-13 (versionCode 5)
- Features
- mobile: drop ContextFAB from project detail screen (5a1c1f5)
- i18n: add task.add_a11y, task.add_to_project_a11y, filters.new_a11y (20fa59d)
- mobile: context-aware FAB on project, board, filter, habits, next-actions, triage (1e89f29)
- mobile: wire ContextFAB on 4 tab screens, seed compose context (c1d64fb)
- mobile: add ContextFAB chrome primitive + tests (5cf5ac5)
- mobile: board column footer redesign (1d1a52d)
- mobile: add SheetHandle component and handle_a11y i18n key (43afa1c)
- mobile: hoist title input and manual keyboard tracking in compose sheet (b418784)
- i18n,docs: visual filter builder strings + docs/features/filters.md (a007570)
- mobile: wire filter editor nav + drop inline creator (6ba4cf4)
- mobile: visual filter create/edit screens with live preview (4790884)
- mobile: visual filter builder primitives (rows + sheets) (fba3477)
- shared: visual filter model + DSL serializer + legacy parser (1e4668d)
- mobile: name the blocking task when tapping a blocked checkbox (a1e628e)
- Fixes
- ui: size native Skeleton fill correctly (c436b97)
- ui: size Skeleton fill correctly + restore pulse (9706403)
- mobile: wire compose Create button to tasks.create (3d429be)
- mobile: always-mount compose sheet to kill open flash (511b0bb)
- mobile: snap compose scrim instead of fading on open (2d4ec49)
- mobile: snap compose scrim opacity to kill open flash (f14cb4e)
- mobile: slide compose sheet in and cover keyboard gap (b55c771)
- mobile: edit button on run screen main branch + lint escape for legacy header (4e9546a)
- mobile: show blocked-by chip on project task rows (625c000)
- mobile: AI plan sheet keyboard avoidance + 60s timeout + header ellipsis (7183a92)
- Other
- mobile: collapse compose sheet to detailed-only (c882974)
iOS 1.2.0 — 2026-06-13 (build 42)
- Features
- mobile: drop ContextFAB from project detail screen (5a1c1f5)
- i18n: add task.add_a11y, task.add_to_project_a11y, filters.new_a11y (20fa59d)
- mobile: context-aware FAB on project, board, filter, habits, next-actions, triage (1e89f29)
- mobile: wire ContextFAB on 4 tab screens, seed compose context (c1d64fb)
- mobile: add ContextFAB chrome primitive + tests (5cf5ac5)
- mobile: board column footer redesign (1d1a52d)
- mobile: add SheetHandle component and handle_a11y i18n key (43afa1c)
- mobile: hoist title input and manual keyboard tracking in compose sheet (b418784)
- i18n,docs: visual filter builder strings + docs/features/filters.md (a007570)
- mobile: wire filter editor nav + drop inline creator (6ba4cf4)
- mobile: visual filter create/edit screens with live preview (4790884)
- mobile: visual filter builder primitives (rows + sheets) (fba3477)
- shared: visual filter model + DSL serializer + legacy parser (1e4668d)
- mobile: name the blocking task when tapping a blocked checkbox (a1e628e)
- Fixes
- ui: size native Skeleton fill correctly (c436b97)
- ui: size Skeleton fill correctly + restore pulse (9706403)
- mobile: wire compose Create button to tasks.create (3d429be)
- mobile: always-mount compose sheet to kill open flash (511b0bb)
- mobile: snap compose scrim instead of fading on open (2d4ec49)
- mobile: snap compose scrim opacity to kill open flash (f14cb4e)
- mobile: slide compose sheet in and cover keyboard gap (b55c771)
- mobile: edit button on run screen main branch + lint escape for legacy header (4e9546a)
- mobile: show blocked-by chip on project task rows (625c000)
- mobile: AI plan sheet keyboard avoidance + 60s timeout + header ellipsis (7183a92)
- Other
- mobile: collapse compose sheet to detailed-only (c882974)
Android 1.1.0 — 2026-06-12 (versionCode 4)
No user-visible changes since previous release. versionCode bump only — first end-to-end run of scripts/android-release.sh. Finalize step bug (wrong-platform write) caused a reverted commit; see release-versioning design doc followup.
iOS 1.1.0 — 2026-06-11 (build 41)
Seeded — pre-mechanism release history not backfilled.
Android 1.1.0 — 2026-06-11 (versionCode 3)
Seeded — pre-mechanism release history not backfilled.