FlarePurge
日本語

更新履歴

FlarePurge にこれまで追加されてきた内容を、バージョンごとにまとめています。アプリごとにリリースサイクルが異なるため、プラットフォームを選んで履歴をご覧ください。

更新履歴は全プラットフォーム共通で、英語のみで提供しています(翻訳はしていません)。

macOS & iOS 1.7.3

最新

hardening after specialist review

A robustness pass following a specialist board review (security, correctness, performance, accessibility). The focus is operational security, bulk-purge reliability and favorites sync; the only directly visible changes are accessibility improvements.

Security

  • Remote certificate-pinning kill switch operationalized: at launch the app reads flarepurge.com/status.json (over unpinned TLS) and can disable pinning remotely if Cloudflare rotates to a CA outside the 3 pinned SPKIs — this prevents every installed copy from being bricked until an App Store update ships. Fail-safe: pinning defaults ON. New SPKI drift check in CI.
  • CWE-532: server error messages are no longer written to logs at .public privacy. Only a PII-free diagnostic code (serverError(status:cfCode:)) is logged at .public; the full detail is .private.

Reliability / correctness

  • Cancellable bulk purge: honors cooperative cancellation (stops scheduling new zones, lets in-flight purges finish) and prepare() can no longer swap the queue mid-run (removes a latent out-of-range crash).
  • No lost favorites writes: the local read-modify-write is serialized under a lock so two concurrent changes can't clobber each other.
  • Complete iCloud favorites sync: fetchFavoriteZoneIDs now follows the CloudKit query cursor — previously only the first page was fetched, so with many favorites some never synced.
  • Multi-line paste in selective purge: pasting N URLs/hosts creates N separate entries (previously one malformed entry with embedded newlines that the API rejected).
  • URLSession leak in onboarding token validation fixed (the session is invalidated after validating).

Performance

  • The iPhone zone list uses LazyVStack — initial layout cost stays flat as the number of zones/accounts grows (Mac/iPad already used a native List).

Accessibility

  • VoiceOver announcements when a purge completes (single and bulk) — previously only visual + haptic feedback.
  • Reduce Motion is honored on the main list animations.
  • 44 pt touch targets on the favorite toggle and the token show/hide button.
  • Continued the Dynamic Type sweep to AX5 + WCAG AA contrast.

Localization

  • Localized UI strings that remained hard-coded in English (About screen, token wizard fields, section headers, context menu).

Tests

  • New pinning verdict test (match / mismatch / disabled / unknown host) that now fails if the SPKI comparison is inverted — previously untestable without a live handshake.
  • Tests that the error diagnostic code never leaks server-supplied text (CWE-532).

Version

  • MARKETING_VERSION: 1.7.21.7.3
  • CURRENT_PROJECT_VERSION: 1112

macOS & iOS 1.7.2

parity with FlarePurge Windows 1.0.1

Cross-platform parity polish with the Windows app: the UI now indicates when the last reload happened and distinguishes optimistic painting from cache versus fresh data. The silent refresh error policy is aligned with Windows so that an expired token is always made visible to the user.

Zone list header

  • "Updated X ago" below the title (iPhone) and as a safe-area inset below the nav bar (iPad/Mac). Text localized for free via RelativeDateTimeFormatter.unitsStyle = .short — works in all 21 languages with no new keys. clock icon when the list is already synced with the server, clock.badge when it is an optimistic paint from cache and the refresh fetch has not finished yet.
  • New ZoneListViewModel.isFromCache flag — true during the cache paint, false after a successful fetch.

Silent refresh error policy

  • ZoneListViewModel.load() now always surfaces CloudflareAPIError.unauthorized and .forbidden errors, even if cache had been served. Previously they were logged and the stale list was kept; the user had no signal as to why the zones were out of date. Now the error screen is painted and the reauth banner appears.
  • Transient network errors (timeouts, no connection, 5xx) still follow log-and-keep as before — the cache is better than a spinner in offline flows.
  • Aligns the behavior with FlarePurge Windows 1.0.1.

Version

  • MARKETING_VERSION: 1.7.11.7.2
  • CURRENT_PROJECT_VERSION: 1011
  • Submitted to App Review after 1.7.1 is accepted (fix of the 2.1 rejection). Does not block or modify the 1.7.1 entitlements flow.

macOS & iOS 1.7.1

Mac resubmission after 2.1 rejection

Mac App Review rejection fix (Guideline 2.1 · "blank black screen on launch") + onboarding polish spotted in parallel. iOS does not change — the approved binary remains in effect until we upload this version.

Root cause fix of the Mac rejection

  • App Group with Team ID prefix on macOS. The Release entitlement shipped with group.com.colorvivo.flarepurge (iOS format). On the Mac App Store the sandbox requires TEAMID.group.com.colorvivo.flarepurge, and without the prefix the system treats UserDefaults(suiteName:) as access to another app's data → TCC prompt "wants to access data from other apps" on every launch. If the reviewer denied it (or the prompt blocked launch), the content did not hydrate and the result was a black window.
  • Release entitlements split by SDK in project.yml: - FlarePurge/Resources/FlarePurge.iOS.Release.entitlements (no prefix — preserves data for already-installed iOS users). - FlarePurge/Resources/FlarePurge.macOS.Release.entitlements (with $(TeamIdentifierPrefix)).
  • Constants.App.appGroupID is now #if os(macOS)99443VK46V.group.com.colorvivo.flarepurge, iOS keeps group.com.colorvivo.flarepurge.

Lazy CloudKit

  • FavoritesRepository no longer receives an eager CloudKitFavoritesDatabase(). It receives a factory and builds the CKContainer on first use (inside reconcile() / setFavorite). AppState.init no longer touches iCloud on launch — reduces the surface of TCC dialogs during the Mac sandbox launch.

Mac onboarding — resizing + button hierarchy

  • TokenWizardView.ExplainTokenStep.macBody was returning two sibling views (ScrollView + HStack) with no explicit container → the TupleView made the buttons disappear on resize. Wrapped in VStack(spacing: 0) with ScrollView at maxHeight: .infinity and the button bar pinned to the bottom.
  • Prominence swap: "I already have an API key" becomes primary orange + defaultAction (the expected action from the user coming from the Cloudflare wizard), "Create token on Cloudflare" becomes secondary outlined (help).
  • FlarePurgeApp WindowGroup: defaultSize lowered from 1440×900960×680 (sensible size for onboarding, still comfortable once authenticated). Added frame(minWidth: 520, maxWidth: .infinity, minHeight: 480, maxHeight: .infinity) + windowResizability(.contentMinSize) → the window can now shrink in height.

Deployment target

  • project.yml Mac floor stays at macOS 14.0. Decision #5 of the plan (macOS 13 Ventura) is overridden by the dependency on @Observable (Observation framework, macOS 14+). Also reflected in CloudflareKit/Package.swift.

Version

  • MARKETING_VERSION: 1.7.01.7.1
  • CURRENT_PROJECT_VERSION: 910

macOS & iOS 1.7.0

build 9 · TestFlight candidate

Visual consistency pass in light/dark and localization of zone states.

Adaptive tokens (iOS + Mac)

  • FPColor and FPColor.iOS were rewritten with Color.dyn(light:dark:), a helper that resolves the hex based on the UITraitCollection (iOS) or NSAppearance (Mac). Until now the tokens were pinned to dark mode, so the Light / System picker mixed a light Color(.systemBackground) with dark #1A1D23 cards. With adaptive tokens the UI looks clean in both modes without touching the view code.
  • Equivalent palettes: iOS light uses the iOS 17 "grouped insets" style (bg #F2F2F7, white cards, text #000), Mac light uses panel #FFFFFF over bg #F5F5F7. The Cloudflare orange (#F38020) is kept in both modes.
  • Semantic tokens and group dots also adaptive — slight darkening in light so active/pending have contrast over a white card.

Legibility bugs in light mode

  • SelectivePurgeView — the URL/Hosts segment had the active state with bg Color.white.opacity(0.08) which was invisible over white cards in light. It now uses adaptive FPColor.iOS.cardSoft + text in FPColor.iOS.text/muted.
  • IOSFloatingTabBar — hardcoded background Color(0x1C1C20)FPColor.iOS.bgElev.opacity(0.88). In light it renders a translucent white capsule, in dark it stays dark (native iOS).
  • iOS bulk toast — same treatment (FPColor.iOS.bgElev + FPColor.iOS.text).

Floating tab bar no longer covers content

  • The iOS content safeAreaInset went from 82 to 110pt. With 82pt the About view clipped the copyright and the NOT AFFILIATED WITH CLOUDFLARE disclaimer behind the tab bar. With 110pt everything is visible when scrolling.

Localized zone status

  • New ZoneStatusLocalization.swift helper in the app target that maps the raw API status ("active", "pending", …) to its localized version. We used to show zone.status.capitalized in 5 views, so in Spanish it showed "Active" instead of "Activo".
  • 7 new keys: zone.status.{active,pending,initializing,moved,deactivated,deleted,readonly} translated into all 21 languages.
  • Replaced in ZoneDetailView, ZoneRow, ZoneListView, ZoneTableView (Mac) and SelectivePurgeView.

Localization fixed

  • zoneList.favorites — in ES it said "Favoritas" (noun gender), changed to "Favoritos" per user preference. ES-MX too.
  • Hardcoded IOSOverline(text: "Favorites") in ZoneListViewString(localized: "zoneList.favorites"). That's why in the Spanish screenshot the word appeared in English even though the key was translated.

Multi-mode screenshot pipeline

  • DemoMode.forcedAppearance reads -FPDemoAppearance light|dark (launch arg). In production the argument doesn't exist, so the app respects the user's system unchanged.
  • make-screenshots.sh now iterates APPEARANCES="light dark" and calls xcrun simctl ui <device> appearance <mode> before each run so the simulator forces the system mode.
  • New 03-purge-confirm screenshot — tapping the "Purge all" CTA in the zone detail opens the confirmation sheet, which is now captured. The rest are renumbered: 04-selective-purge, 05-account-switcher, 06-settings, 07-about.
  • Demo fixtures updated to 9 realistic domains: colorvivo.com, flarepurge.com, agentready.md, revistacloud.com, cloudnews.tech, actualitecloud.com, password.es, spyonweb.net, noticias.madrid. Account label is now "colorvivo" (was "Color Vivo").

Version

  • MARKETING_VERSION: 1.6.11.7.0
  • CURRENT_PROJECT_VERSION: 89

macOS & iOS 1.6.1

bugfix pack after first testing

Fixes on top of the Mac redesign 1.5.0/1.6.0 found while testing on TestFlight.

Mac — zone table

  • Mac search now works — the native .searchable() was removed because it didn't focus in the NavigationSplitView. The new inline header has a real TextField bound directly to viewModel.searchText, with @FocusState + keyboardShortcut("f", .command) so ⌘F focuses the field.
  • Search is now global — previously, with "Favorites only" active, search was limited to that selection. When there is text in the search box, the app ignores the favorites toggle and searches across ALL zones (iOS-Mail-like).
  • New account filter in the toolbar — "Account" menu with .decrease.circle(.fill) chevron that lists each Cloudflare account + "All accounts". Only appears when there are ≥ 2 accounts.
  • Localized text — the Zones header, the N zones · sorted A–Z suffix (and its filtered variant N of M) are now localized strings in all 21 languages. Previously they always appeared in English.

Mac — Selective Purge

  • Bug: couldn't switch to the "Hostnames" tab — the Mac segmented button didn't have an explicit .contentShape(Rectangle()), so the clickable area was only the text. Added. Now both tabs respond.
  • When switching tabs, entries + draft + errorMessage are cleared to avoid confusion with entries from the other mode.
  • MonoTag eyebrow § Selective Purge localized.
  • Result toast distinguishes "Cache purged completely" vs "Cache purged selectively · N" depending on the type of purge that was run.

Missing localization fixed

  • Critical fix: account.verify was completely empty (the raw key was shown). Added EN+ES+19 languages: "Verify & add" / "Verificar y añadir".
  • 22 MonoTag literals on Mac now use String(localized:): - Sidebar inspector: § Ready - Zone detail: Zone ID · %@, %@'s Account - Settings: § General, § Appearance, § Feedback, API Accounts · N, Storage - About: Published by - Account purge: § Account · Purge, § Targets, · ~1 api call per zone - Selective purge: § Selective Purge, § Queued - Token wizard: § Add API key — dialog, § Create your Cloudflare token, § Token verified · name it - Required permissions card header
  • 483 new translations (23 keys × 21 languages) applied via scripts/translate_v1.6.1_fixes.py.

iOS — fixes from first testing

  • Keyboard can now be dismissedIOSSearchBar added @FocusState + .submitLabel(.search) + .onSubmit { focused = false }. On focus, an orange keyboard.chevron.compact.down button appears on the right to minimize the keyboard manually. The ScrollView uses .scrollDismissesKeyboard(.interactively) to dismiss it by dragging.
  • Purge an entire account on iOS (Mac parity) — new IOSFloatingBulkMenu component (56pt orange flame circle) next to the floating tab bar. Menu with "Purge all favorites (N)" + a "Purge an entire account" sub-section with each Cloudflare account and its count. Connects directly to AccountPurgeSheet.
  • Copy zone ID card removed from the iOS Zone Detail — it added no value inside the domain (the ID is already visible and copyable in the header via context menu + the mono accessory of ZoneMeta). The card was redundant.
  • Tab bar layout updated: the 2-tabs pill takes flexible width + the bulk circle aligned to the right, with consistent horizontal padding.

Mac — Refresh menu (replaces silent button)

  • The toolbar arrow.clockwise button was a silent Button that only reloaded the active account, with no visible feedback (which is why it seemed to do nothing). Converted to a Menu with: - "Reload {current account}" — shortcut ⌘R. The primary option. - "Reload all accounts (N)" — if there are ≥ 2 accounts. Iterates each account (switch → refresh → next), restoring the original active one at the end. - "Reload one" sub-section with a button per Cloudflare account; checkmark on the active one. To force a refetch without visually switching.
  • During the bulk refresh, the icon is replaced by an orange-tinted ProgressView.
  • Floating toast at the top of the main view with text "Reloaded {name}" or "N accounts reloaded" (mono capsule with blur + border, 2.5s).
  • iOS keeps the simple arrow.clockwise button (the iOS toolbar is more limited).

Build

  • Version stays at 1.6.1 (no bump) — these are fixes/improvements from the same cycle.
  • Mac + iOS Simulator both BUILD SUCCEEDED.

iOS — Tab bar with bulk in the center + Zone detail + About

  • "Purge N favorites" FAB (floating one that appeared above the tab bar) removed on iOS — it was redundant with the new bulk menu.
  • Bulk menu now in the center of the tab bar — 3-slot layout [Zones] · [🔥] · [Settings]. The center slot is a filled orange circle (48pt) with a white flame icon that triggers the menu. The menu uses native iOS scrolling if there are many accounts (Apple handles it automatically).
  • Menu respects order: Purge all favorites (N) always first, then Section("Purge an entire account") with each Cloudflare account.

Both — Zone detail with Plan + Added + abbreviated Name servers

  • Mac 4-col meta grid now shows: ACCOUNT / NAME SERVERS / PLAN / ADDED (previously ACCOUNT / NAME SERVERS / STATUS / TYPE with a Type: "—" placeholder). Uses the new Zone.planName + Zone.createdOn fields added to the model in 1.6.0.
  • Abbreviated name servers (both platforms) — now only the label before the first dot is shown (cara · nick instead of cara.ns.cloudflare.com). New Zone.nameServersShort helper shared between Mac and iOS.

About — "Made with ❤️ from Madrid and Herencia"

  • CIF removed from the "Published by" block on Mac (adds no value to the end user).
  • New line replaces the location/CIF: Made with ❤️ from Madrid and Herencia (Ciudad Real) — Spain. (translated into 21 languages).
  • On iOS the same line appears in the Settings About footer, above the Cloudflare disclaimer.

Support links → web home

  • The "Contact support" link that was previously mailto:support@flarepurge.com now points to https://flarepurge.com (home, not /support) on all surfaces (Mac About, Mac Settings About, iOS About). More flexible than a mailto — from the web it is then routed to a form/email as appropriate.
  • The "Not affiliated with Cloudflare, Inc." disclaimer was already present in the iOS Settings AboutView (added in 1.5.0), confirmed.

Translations — cleanup and full coverage

  • 213/213 translatable keys at 100% across the 21 supported languages. Verified with an automatic audit script (0 gaps).
  • tokenWizard.failure.generic completed in the 19 languages that were missing (previously only EN/ES/NL).
  • Symbols and literals (·, %@, +, , ⌘F, , Flare, Purge, Color Vivo Internet, SL, © 2026 COLOR VIVO INTERNET, SL, Minimum privilege.) marked with shouldTranslate: false — they are SwiftUI extraction artifacts that must not be translated.
  • Orphan key Madrid, España · CIF B13340724 removed (replaced by mac.about.madeWith).

Final build

  • MARKETING_VERSION 1.6.1, build 68 (we skipped 7 which was reserved for the previous re-archive).
  • Mac + iOS Simulator both BUILD SUCCEEDED.

macOS & iOS 1.6.0

in development

iOS redesign aligned with the handoff (FlarePurge iOS Spec.md + 6 artboards). Kicks off in parallel with 1.5.0 going up to TestFlight. Delivered in phases: this first batch brings tokens, atomic components, navigation refactor and the first screen redesigns.

Decisions made before starting

  • ✅ Selective Purge Tags + Prefix tabs out (Enterprise-only, consistent with the Mac's decision #9).
  • Zone.planName + Zone.createdOn added to the CloudflareKit model (backward-compatible, optional decoding).
  • ✅ Recent purges → volatile memory for now (option B; full SwiftData deferred to v1.7).
  • ✅ CSV export out of scope.
  • ✅ The Dark/Light/System picker is kept (consistent with Mac, ignores the spec's "dark-only" restriction).
  • ✅ Version bump to 1.6.0 for a new screen (Account switcher) + substantial navigation change.
  • ✅ Custom floating tab bar (not native TabView) for fidelity with the mockup.

Phase A — Infra + tokens (done)

  • CloudflareKit/Sources/CloudflareKit/Models/Zone.swift — new planName: String? and createdOn: Date? fields. Tolerant decoding with ISO8601 (with and without fractional seconds), backward-compatible with the existing on-disk cache.
  • App/DesignTokens.swift — new FPColor.iOS namespace (iOS-specific palette: #000 OLED bg, #1A1D23 card, #0E1014 bgElev, #C7CAD1 textDim, etc.). Different palette from the Mac one for OLED contrast and warmths. New FPRadiusIOS (card=18, container=20, iconChip=12, search=14).
  • MARKETING_VERSION 1.5.01.6.0, build 45.

Phase B — iOS atomic components (done)

New file Views/Components/IOSComponents.swift (14 types):

  • IOSGlobeIcon · globe with border+fill at color@40%/8%.
  • IOSPill(color, label, soft) · Active/OK/Draft pill, soft vs filled.
  • IOSStarIcon(filled, size) · yellow filled or mutedDim outline.
  • IOSChevron · mutedDim right arrow.
  • IOSOverline(text, color) · §CAPS uppercase 10pt tracking 0.8.
  • IOSMetaCell(label, value, mono) · overline + value (mono optional).
  • IOSCard(padding){} · 18pt radius card wrapper with border.
  • IOSSearchBar(text, placeholder) · visible inline search (not native .searchable).
  • IOSAccountPill(name, action) · top-right pill with circular accent avatar.
  • IOSRoundIconButton · 40pt round button.
  • IOSFloatingCTA(label, action) · orange pill with gradient + glow + flame.
  • IOSFloatingTabBar(active) · floating pill with blur, 2 icon+label tabs.
  • IOSPurgeGradientCTA(title, subtitle, action) · primary button gradient accent→accentHot with glow.
  • IOSActionCard(icon, iconColor, title, subtitle?, monoAccessory?, action) · secondary card with 44×44 icon chip.

Phase C (partial — checkpoint)

  • iOS MainTabView — full refactor for compact layout: ZStack with content + IOSFloatingTabBar overlay (pill with blur, bottom 18). Local activeTab state replaces the native TabView. Mac and iPad (regular/desktop) keep the legacy TabView.
  • AccountMenu adapted: on iOS it shows an IOSAccountPill that opens AccountSwitcherSheet; on Mac it keeps the native Menu.
  • AccountSwitcherSheet (new, Views/Main/AccountSwitcherSheet.swift) — .medium sheet with a "Switch account" overline title, rows with a flame avatar (accent when active) + label + mono zone count + accent checkmark, a separate "+ Add API key" row.
  • iOS ZoneListView — the round corner FAB replaced by IOSFloatingCTA (wide pill with gradient + glow) positioned above the floating tab bar. Bottom padding adjusted so it doesn't collide with the tab bar.
  • iOS ZoneDetailViewActionCards replaced by IOSPurgeGradientCTA (primary with gradient and glow) + IOSActionCard (selective) + a new "Copy zone ID" card with a mono preview of the id (uses UIPasteboard + success haptic).
  • iOS SettingsView — green hero card at the top "Tokens stay on this device / Stored in Keychain · No backend · No tracking". navigationBarTitleDisplayMode changed to .large for a prominent "Settings" title. Bottom safe area 120pt so it doesn't collide with the floating tab bar.

Localization

  • 2 new iOS-specific keys EN+ES: ios.tokens.stayOnDevice.title, ios.tokens.stayOnDevice.sub.

Following batches (applied in the same 1.6.0 cycle)

  • iOS ZoneListView full redesign — big title Zones 28/800 + mono count + inline IOSSearchBar + FAVORITES section as a card container + collapsible account groups with card + rows with IOSGlobeIcon + star toggle + chevron + context menu (favorite/purge/copy). Nav bar hidden on iOS. iPad/Mac keep the legacy List.
  • iOS Zone detail 2×2 meta gridIOSGlobeIcon 52 + title 24/800 + active IOSPill + star. Separator + 4 meta cells (Zone ID / Name servers / Plan / Added) leveraging the new Zone.planName + Zone.createdOn.
  • iOS Selective purge (mock6) — zone header card + custom URLs/Hosts segmented picker + mono hint "Paste up to 30 URLs" + numbered list (00, 01, 02…) with mono rows + an X button per entry + a final input row with placeholder + orange + button + mono counter N URLs · (30-N) remaining in this batch + Purge N CTA in the toolbar. Native Form removed on iOS.
  • iOS Add API key 1-step form (mock4) — new file AddAPIKeyIOSView.swift. Eyebrow § CREDENTIALS + h1 "Paste your token." + body + LABEL card + mono API TOKEN card with eye toggle + orange-bordered "Paste from clipboard" button + REQUIRED PERMISSIONS section with 3 rows. Native Cancel/Save toolbar. Bypasses the multistep TokenWizardView on iOS; Mac keeps the wizard. AddAccountSheet routes to the new view on iOS.

Localization

  • 11 new keys translated into full 21 languages (228 translations): ios.tokens.stayOnDevice.*, ios.zones.count.unit, ios.zone.copyId, ios.zone.meta.added, mac.zone.meta.zoneId, ios.selective.hint, ios.selective.remaining, ios.selective.purgeCount, ios.addKey.title, ios.addKey.body, action.save. Scripts persisted in scripts/translate_ios_keys.py.

Final polish (in the same 1.6.0 cycle)

  • iOS Settings icon chips larger (32px vs 28px on Mac) with a 16pt icon. Haptics tint changed from .pink.red (consistent with mock5). Haptics toggle with .tint(.orange) on iOS.
  • Recent purges section in iOS Zone Detail — new PurgeHistoryStore singleton @MainActor @Observable in memory (cap 20 events, no persistence). Automatic record on every purge (total or selective, success or failure). UI shows the last 3 events of the current zone with a tinted flame icon, title by kind (Everything / N URLs / N hosts), relative mono timestamp and an IOSPill OK/Failed.

Final v1.6.0 polish (done)

  • iOS empty statesEmptyStateView redesigned: 96pt circular hero with an orange blur halo + inner tinted circle + accent stroke, 40pt accent icon, title 22/800, body 14pt, CTA as an orange pill with glow. Mac keeps its previous layout.
  • Tinted pull-to-refresh.tint(FPColor.accent) applied in iOS ZoneListView so the native pull-to-refresh spinner renders in brand orange instead of the system blue.

Final 1.6.0 build

  • Mac + iOS Simulator both BUILD SUCCEEDED.
  • Ready for archive + upload to TestFlight.

Build

  • Mac + iOS Simulator both BUILD SUCCEEDED.

macOS & iOS 1.5.0

Complete visual redesign of the Mac client aligned with the official handoff (FlarePurge Mac Spec.md + 6 artboards). UI changes only: no logic, no endpoints, no new permissions. iOS is left intact via #if os(macOS) in the shared views.

New design system

  • App/DesignTokens.swift — tokens ported 1:1 from the spec: FPColor (surfaces, text, accent, semantic, group palette), FPRadius, FPSpacing, FPFont (SF Pro Display/Text + SF Mono).
  • New reusable components: - MonoTag — uppercase mono eyebrow with tracking (port of mac-shared.jsx). - FPDot — dot indicator with optional glow ring. - FPStatusPill — uppercase mono capsule for status. - PermissionRow + PermissionCard — the 3-permissions card with a green "Minimum privilege" callout. - MacStatusBar — bottom mono strip ● connected · api.cloudflare.com / tokens never leave this device. - PurgeActionCard.primary variant (orange tile + orange-fill button with #120A00 text + glow) and .neutral (panel + ghost button). - SettingRow, SettingsCard, FPSelectChip, KeyboardChip — Settings primitives. - ApiKeyField, ApiKeyTextField, ApiKeyTokenField — form primitives with a mono label + hint + panel-soft input + reveal toggle.

UX polish (Mac)

  • Selective purge — full sheet redesign. The https://dominio.com/style.css placeholder is now in muted color (it was indistinguishable from real content), a custom Mac segmented picker with tiles, a panel input card + mono hint ⌘⏎ to add, an entries list as mono rows with a Mac-style X button, a bottom floating action bar with Cancel + orange "Purge selected" CTA, an error callout with the err token. Native Form removed on Mac; iOS keeps the original Form.
  • MacStatusBar — the account label removed from the footer (redundant with the one that already appears under the zone name when entering purge). Only ● connected · api.cloudflare.com / tokens never leave this device remains.
  • ZoneTableView — the "Status" column removed from the table (redundant with the green/yellow dot in front of each name). The dot now carries a .help() tooltip + accessibilityLabel with the status, so VoiceOver and hover still announce the state.
  • Bulk purge menu in the toolbar — the menu previously only showed a building.2 icon with no text, so it wasn't clear what it did. Now it is a Menu with an explicit "Bulk purge" label + flame.circle.fill icon: - Purge all favorites (N) — first entry if there is ≥1 favorite. Reuses AccountPurgeSheet with a synthetic "All favorites" target and the current favorites list. - Purge an entire account — a sub-section with an entry per detected Cloudflare account, including the number of affected zones in parentheses. - Help tooltip + accessibility label with the full description.

Redesigned (Mac)

  • About window (CustomAboutView) — hero with an orange shadow glow, bicolor wordmark Flare orange / Purge primary, a 6-row spec grid (Backend ✓ / Tracking ✓ / Token storage ✓ / Languages / Price / Built with), a "Published by" block with Color Vivo Internet, SL · Madrid, España · CIF B13340724, a links row with rgba(0,0,0,0.2) background, footer © 2026 COLOR VIVO INTERNET, SL / NOT AFFILIATED WITH CLOUDFLARE, INC..
  • Zone detail (ZoneDetailView macHeroCard) — eyebrow § ZONE + 30pt display title with an inline copyable mono Zone ID + FPStatusPill + subtitle {accountName}'s Account, a 4-column metadata row (account / name servers / status / plan), purge actions with PurgeActionCard primary + neutral, bottom MacStatusBar.
  • Token wizard — complete redesign of every step: - Welcome with the real AppIcon + orange shadow + bicolor wordmark + mono strap + 3 trust badges (KEYCHAIN / NO BACKEND / NO TRACKING) + orange-fill CTA. - ExplainToken with a MonoTag header + "Generate token on Cloudflare" callout with a path breadcrumb + PermissionCard + dual CTA (ghost "I already have it" + orange "Create token"). - PasteToken with a dashed dialog card (33% accent border) + ApiKeyTokenField. - LabelPrompt with a checkmark header + dashed dialog + account hint pill + ApiKeyTextField. - Validating with an orange glow around the spinner. - Success triple green glow, Failure double red glow, MissingScope double yellow glow with an inline PermissionCard.
  • Settings (PreferencesView) — General and Accounts redesign: - General: header with MonoTag + h1, Appearance (FPSelectChip) and Feedback (native Toggle accent tint) sections in panel cards. - Accounts: header § API ACCOUNTS · N + h1 + subtitle, per-account cards with a dot + label + FPStatusPill Active + ⋯ menu + a 3-col meta grid (Scope / Token masked mono / Storage with a green ✓), + Add API key as a dashed accent card.
  • Account purge sheet (AccountPurgeSheet.macConfirmContent) — Mock2 layout: eyebrow § ACCOUNT · PURGE, a large H1 with the account name in orange, a 2-col targets preview grid with mono panelSoft chips, a bottom sticky floating action bar with a dot + count + mono metadata + Cancel ghost + Purge primary orange-fill with glow.
  • Zone table header — Mac-only header strip with a Zones title + N · sorted A–Z mono tag (dynamic based on filters) + a panelSoft search hint box with a ⌘F chip.
  • Purge confirm sheet — flame hero with double glow + CANNOT BE UNDONE warning pill uppercase mono + buttons with keyboard shortcuts.
  • Main sidebar — account rows with a clean 7px dot (accent when active), InspectorPlaceholder with a flame + glow + § READY MonoTag.
  • Empty states (EmptyStateView) — icon with a hierarchical orange glow + consistent typography.
  • ContentViewFPColor.bg background during onboarding and the authenticating state (was system material), accent-tinted spinner.
  • AddAccountSheet — dark background + padding so the inner wizard looks like a dedicated window.

Unified palette

  • Migrated all hardcoded Color.green/.orange/.red/.yellow to FPColor.ok / .warn / .err / .accent tokens in: ZoneTableView, ZoneRow, AccountPurgeSheet progress, PurgeConfirmView, ZoneDetailView result cards, PurgeButton, StatusBadge, AccountRow iOS+Mac.

Typography

  • Removed Geist (external font). The whole system now uses SF Pro Display / SF Pro Text / SF Mono with the spec §1.2 scale.

Localization

  • 44 new keys translated into full 21 languages (836 translations): mac.about.spec.*, mac.about.disclaimer, mac.perm.*, mac.zone.meta.*, mac.status.*, mac.purge.*, mac.onboarding.trust.*, mac.welcome.strap, mac.accounts.*, prefs.appearance.footer, mac.explain.*, zoneList.searchHint, mac.bulk.*, mac.selective.*. Languages: EN, ES, ES-MX, CA, FR, PT-PT, IT, DE, NL, NB, SV, ZH-Hans, KO, JA, AR, RO, PL, TH, HU, EL, HE. Script persisted in scripts/translate_v1.5.0_keys.py for future regenerations or tweaks.

Minor polish (same 1.5.0 cycle)

  • FPToggle — custom 36×22 pill Toggle with orange fill when ON and a white handle with shadow (previously the native Toggle.switch was used). Applied in the PreferencesView haptics row.
  • Mac sidebar section headers — replaced Text() with a 10pt mono uppercase MonoTag with tracking for consistency with the spec's visual language.
  • § ZONES eyebrow added above the title in ZoneTableHeader to align with the eyebrow pattern in the rest of the screens.

Not touched (previous /autoplan decisions respected)

  • Groups + bulk multi-select screen + global shortcuts ⌘⌥1-9 → still deferred to v1.1.
  • SwiftUI menu bar popover → still deferred.
  • The handoff spec's macOS 14 floor ignored — still macOS 13 Ventura.
  • Cache-Tag + Prefix purge tabs not added.
  • Settings as a native window with a sidebar ignored — still a modal sheet.
  • The user's system/light/dark picker kept (the handoff asks for dark-only, we decided not to remove already-shipped functionality).
  • "Source on GitHub" link not added — private repo.
  • No ViewModel, AppState, Service or CloudflareKit touched.

Build

  • MARKETING_VERSION 1.0.01.5.0, CURRENT_PROJECT_VERSION 34.
  • XcodeGen regenerated. Mac + iOS Simulator build both green.
  • The previous pending build (1.0.0 (3)) becomes obsolete; upload 1.5.0 (4) directly.

macOS & iOS 1.0.0

First release. Universal Apple (iPhone · iPad · Mac), 100% free, zero-backend.

Added

  • Authentication with a Cloudflare API token via a guided five-step wizard (welcome → permissions explanation → paste token → validation → labeling) that detects missing scopes and offers clear recovery.
  • Multiple API accounts with an editable label; a single API key can cover several Cloudflare accounts.
  • Zone list with instant search, favorites pinned to the top and grouping by Cloudflare account when there is more than one.
  • Total purge and selective purge (URLs and hosts), with automatic URL batching at 30 per request (Cloudflare API limit).
  • Bulk purge on favorites via a concurrent TaskGroup with a limit of 8.
  • Swipe actions on iOS for favorites and quick direct purge.
  • Floating FAB on iPhone when there is ≥1 favorite: "Purge N favorites" in one tap.
  • Persistent inspector on iPad and Mac (3 columns): sidebar · list · live detail.
  • Native sortable table on Mac with Name / Status / Account / Last purge columns, selection synced with the inspector, context menu (favorites, open in inspector).
  • Standalone Mac Preferences window with a Settings scene + ⌘, shortcut and General / API Accounts / About tabs.
  • Favorites with iCloud sync via CloudKit Private DB (iCloud.com.colorvivo.flarepurge). Optimistic UI (instant toggle) + background sync. Reconcile on every zone load with union semantics between local and remote.
  • Haptics calibrated (light/medium/success/warning/error).
  • Accessibility: explicit VoiceOver labels, Dynamic Type, WCAG AA contrast, 44pt touch targets.
  • 21 languages: English, Spanish (ES + MX), Catalan, French, Portuguese (PT), Italian, German, Dutch, Norwegian, Swedish, Simplified Chinese, Korean, Japanese, Arabic, Romanian, Polish, Thai, Hungarian, Greek, Hebrew.
  • No third-party tracking or analytics.
  • Privacy manifest (PrivacyInfo.xcprivacy) with NSPrivacyTracking = false.
  • Cert pinning (SPKI placeholders ready to be replaced with the real ones before the first TestFlight).
  • CloudflareKit: isolated local Swift Package with 27 unit tests (APIClient, Auth, ZoneService, CacheService, Keychain, RateLimiter, CertificatePinning).

Architecture and build

  • Swift 5.9, SwiftUI, @Observable (Observation framework), iOS 17+ / iPadOS 17+ / macOS 14+.
  • Project generation with XcodeGen (project.yml).
  • String Catalogs (.xcstrings) as the single source of translations.
  • Separate entitlements: minimal for local development, full for release (App Group + Keychain sharing + iCloud CloudKit).

Security

  • Completed a full internal security audit (19 findings: 5 P0, 6 P1, 5 P2, 4 P3) and addressed them.
  • Cert pinning bypass fix in the onboarding flow: AuthViewModel.validate now uses the shared APIClient.makeSession(), guaranteeing uniform pinning.
  • project.yml now associates the Release entitlements (sandbox + App Group + iCloud + Keychain sharing) with the Release config (previously it was never applied to the archive).
  • Info.plist sanitized: added NSHumanReadableCopyright, LSApplicationCategoryType, an explicit NSAppTransportSecurity. Removed NSFaceIDUsageDescription (unused) and CFBundleURLTypes (no handler).
  • Privacy manifest cleaned up: removed NSPrivacyAccessedAPICategoryFileTimestamp (unused API).
  • SettingsView: removed the App Store link with the id0 placeholder.
  • 3 new CertificatePinningDelegate tests (27 green tests in CloudflareKit).

Deferred to v1.1+

  • Local history of purges (SwiftData + @Query). Initial design pulled for lacking a ModelContainer — to be fully reimplemented in the next version.
  • Opt-in diagnostics (MetricKit → own endpoint). Pulled until the flarepurge.com/diagnostics receiver is operational.
  • Remote kill switch (flarepurge.com/status.json). Pulled until the endpoint is published with an SPKI rotation policy.

Known notes

  • On ad-hoc signed macOS development builds, the system may ask for Keychain authorization the first time after a rebuild because the signature changes. With a stable Apple Developer Team this disappears.
  • Mac sortable table: column sorting works in memory over the filtered list.

完全な履歴は各アプリの公開リポジトリでもご覧いただけます。 GitHub で見る