What we shipped on 2026-08-10
Shipped 52 items (34 code, 8 infra, 2 docs, 7 design, 1 release).
Code
fix(infra+marketing): retire app.offkeep.com, wire staging.offkeep.com, restore rn-motion-ui stylesRemove offkeep-app Pages projects/domains/CNAMEs (app.offkeep.com +
feat(marketing): bring offkeep-marketing into the monorepo as apps/marketingPulls the standalone marketing site (Next.js 16 static export, Tailwind v4)
chore(google-auth): wire Google OAuth config plumbing (client IDs via tfvar + GH vars)wrangler.jsonc(.tftpl): GOOGLE CLIENT ID (var, non-secret) + GOOGLE REDIRECT URI per env
chore(staging): move API domain to staging.api.offkeep.comenvironments.tf + wrangler.jsonc(.tftpl): staging api hostname/route/BACKEND URL
fix(backend): register CheckoutSession durable object binding + migrationHosted checkout (/payments/checkout/hosted) 500s in every environment with
chore(backend): drop AIRWALLEX_LINKED_PAYMENT_ACCOUNT_ID var placeholder (moving to secret)The empty var blocks wrangler secret put (binding name already in use).
fix(desktop): generate-desktop-icons works with ImageMagick 6 (convert) and skips iconutil off-macOSResolve IMAGEMAGICK BIN once: prefer 'magick' (IM7, brew/choco), fall back to
feat(alerts): Telegram error channel — health-check + 5xx alerts via dedicated botservices/telegram.ts: sendTelegramAlert (Bot API sendMessage, no-op when
fix(desktop): restore apps/app/assets/logo.svg (deleted in app-new->app restructure, still required by generate-desktop-icons)
chore(infra): Pages custom-domain CNAMEs + Turso provisioning scriptdns.tf: add CNAME app.<env .offkeep.com - <project .pages.dev (Cloudflare
feat(storage): move invoice PDFs off Cloudflare R2 onto MEGA S4Backend: invoice PDF cache now uses S3-compatible object storage via
feat: add tiktok sans font to app
refactor(ui): extract DateInput helpers, PlanChangeConfirmStep, and error titlesExtract 7 pure date-math helpers from DateInput.tsx into
chore: remove dead exports, unused function bodies, and stale referencesApply fallow fix (auto-remove unused export keywords) and
fix(backend): break circular dependency between payments.ts and subscriptions.tsExtract onPaymentSucceeded into a new shared module
chore: delete 5 unused source filesapps/app: mobile-paywall.tsx (dead component, no consumers)
chore: collapse multiline type alias
refactor(ui): replace custom components with rn-motion-ui equivalentsDelete 15 dead components (0 consumers) that duplicate rn-motion-ui:
test(e2e): add Archive, Mirror, and Time Machine sync Maestro flowsThree new Maestro flows exercising each sync mode end-to-end:
test(e2e): update selectors for per-file HoldContextMenu testIDsThe gallery tile menu now uses per-file testIDs ("gallery-tile-menu-<id ")
fix(e2e): update register subflow for keyboard-aware authThe auth modal now applies keyboard-height paddingBottom (see ef42f86),
fix(app): use controlled HoldContextMenu with per-file testIDsSwitch HoldContextMenu from uncontrolled (hold gesture triggers menu)
fix(app): keep auth submit button above keyboard on AndroidFullSheet renders inside a React Native Modal whose detached window is
fix(backend): order FK-aware deletions in sync file lifecycleTwo FK-constraint fixes and several improvements:
fix(backend): prevent audit flush failures from cascading to 500sWrap bumpCounterAndMaybeFlush in a try/catch — the flush counter is a
feat(backend): add file_deleted kind to sync events enumThe reconcile path in folders.ts emits file deleted events; the upload
fix: constrain offkeep logo sizing with overflow-hidden and h-full w-fullReplace fixed width/height attributes on offkeep-logo.svg img tags
feat(site): merge VS3 marketing + console on vs3.offkeep.comapps/landing: the VS3 marketing page (previously deployed ad-hoc as
fix(ui): validate exports map in pre-commit hook, fix 4-segment component path detectioncheck-exports.mjs: deriveExportKey now handles 4-segment component paths
chore: add changeset for drag collision algorithms and SortableList Reanimated
feat(ui): migrate SortableList animations to Reanimated workletsReplace React Native Animated (JS-thread) with react-native-reanimated shared
feat(ui): add drag axis constraint, bounds clamping, Draggable.Handle, and skipRectMeasuredragAxis prop ('x' / 'y' / 'both') constrains pointer movement to a single axis,
feat(ui): add rect collision algorithms to drag hit testingAdds rect-vs-rect collision strategies (intersect / contain / center) as an
fix: sortable list stories
Infra
fix(ci): expose marketing_pages_project + api_url as config job outputsThe config job writes these to GITHUB OUTPUT but never declared them in its
fix(ci): migrate to rn-motion-ui 5.2.0 API, restore green typecheck/fallow/i18nOtpInput: adopt 5.2.0 API (numberOfDigits/onTextChange/onFilled/secureTextEntry)
chore(backend): drop AIRWALLEX_LINKED_PAYMENT_ACCOUNT_ID from terraform templateKeep wrangler.jsonc and its tftpl generator in sync: the placeholder var is
fix(ci): install ImageMagick on desktop runners (generate-desktop-icons needs magick)
chore(ci): commit generated wrangler.jsonc so GitHub Actions deploys workThe deploy workflow checks out the repo fresh and runs wrangler with no
chore: gitignore terraform plan artifacts
chore(staging): drop dead BulkGate bindings, fix terraform outputs, S4 audit storage, BACKEND_URL varRemove BULKGATE APPLICATION ID/TOKEN: SMS already goes through Pingram
chore: add Fallow code-intelligence, replace knip in CI, clean up unused depsAdd .fallowrc.json with 4 entry patterns, 4 dynamic-load patterns,
Docs
docs(app): add apps/app/.env.example (Google client IDs, API URL, Airwallex env)README referenced the file but it never existed (template leftover); document
chore: auto-sync README
Design
style: import node:process in generate-desktop-icons
style: drop non-null assertion in telegram test
style: satisfy biome (simplified logic, one-liner, no as-casts in telegram tests)
style: biome format
style: suppress underline on chrome, button, and nav linksAdd no-underline to link-styled buttons (Button, GlossyButton), the
style: remove redundant hover:underline and text color from inline linksWith the global a rule now providing underline and --link color,
style: add global link token and default underline ruleIntroduce --link CSS variable (blue-600 light / blue-400 dark) and a
Release
rn-motion-ui@5.2.0b56144c: Draggable: collision algorithms, axis constraint, drag bounds, and handle sub-component
← All shipped days