Changelog
Last updated: Sep 27, 2026
Every released version of R2Explorer. These notes are the app's own changelog — the same file that ships with the source — so this page cannot drift from what was actually released.
1.9.0 Latest
Added
- About and Pro in Settings. Settings moves onto swift-support-kit's sidebar: General, Accounts, Uploads, About and Pro. R2Explorer had no About at all; it now shows the version, the device details with a copy button, and the support links. Pro lists what the unlock gates, with Mirror/Sync, Benchmark and Move to R2 listed on the Mac only, where their menu lives
- Jurisdictions. A Cloudflare R2 connection now has a Jurisdiction: Default, European Union, United States (new at Cloudflare on 2026-08-17) or FedRAMP. A bucket created in a jurisdiction was invisible before: Cloudflare lists and serves it only with
cf-r2-jurisdictionon the REST API, or on its own S3 host (<account>.eu.r2.cloudflarestorage.com), and the app sent neither. Checked against a live EU bucket: without the header, the list leaves it out and a direct read answers "The specified bucket does not exist". One jurisdiction per connection, as one S3 host per connection; Duplicate makes the second one. Move to R2 takes the connection's jurisdiction and loses its own picker, which could name a jurisdiction the bucket was not in.fedramp-highis left out: it has no changelog entry and no documented S3 host. A connection edited on an older build, which drops the key it does not know, falls back to Default
Fixed
- Accounts with more than 1,000 buckets showed only the first 1,000, with nothing to say the list was cut. Both Cloudflare bucket lists asked for one page at the API's
per_pageceiling and stopped there; they now follow the cursor to the last page. The S3 bucket list is unchanged - Bulk delete no longer counts refused objects as deleted. S3's
DeleteObjectsanswers HTTP 200 even when it refuses keys (object lock, a per-key permission) and reports them inside the body, which nothing read, so Delete and Empty Bucket reported objects gone that were still in the bucket. The Cloudflare REST delete had the same gap: it lists the keys it deleted, and the rest were never compared. Both now finish every batch, count only what was deleted, and the delete sheet lists each refused key. Rename, Mirror/Sync and Benchmark, which delete through the same call, now report the failure too - iCloud connection sync no longer drops a connection. Two devices that each added one before seeing the other's pushed the same revision; iCloud kept one copy, and the other addition vanished everywhere at the next edit. Sync is now a three-way merge by connection id, so both survive, and a deletion still reaches every device, including one made by an older build
- Duplicating a Sign in with Cloudflare connection produced a copy with no credential: the duplicate dropped its credential kind and fell back to a pasted token that did not exist
- A false "Failed to load objects" after leaving a folder before its listing finished. The cancelled listing wrote its error into the folder the user had moved to, which was most visible on the ~1s-per-request Cloudflare REST connection
- Keys with leading or trailing spaces. The listing trimmed them, so the app held a key naming an object that does not exist, and every download, rename or delete of it missed
- A token Cloudflare refuses for a few seconds after minting is resent on a backoff instead of failing the request. It happens on every account of a grant but the first, and before this the refusal stuck until the token expired
- The Mac's download and upload panels crashed when no window was key, for example with a popover open
- A Pro purchase waiting for Ask to Buy was shown in red, as an error. It is now a note on the paywall and on Settings ▸ Pro, cleared when the purchase goes through (swift-support-kit 1.15.0's
notesslot) - Cancelling a benchmark left its test objects in the bucket. Cancel cancelled the task the cleanup ran in, so the delete was refused before it was sent and the failure was swallowed: up to 26 objects of up to 10 MB stayed under
__benchmark__/, billed. Cleanup now runs outside the cancelled task, and a cleanup that fails says so on the result - A rename that stopped half-way could lose track of its copies. When one copy failed or the user cancelled, the copies still in flight could land after the app had stopped listening, and they were missing from the orphan list the recovery offers to delete. Every copy already sent is now waited for and counted
- Deleting a failed rename's orphans closed the sheet at once and only logged a failure. The sheet now stays open until the delete finishes, and a failure shows the copies that are still there so it can be retried
- A cancelled rename can delete its orphaned copies too. It listed them, but only a failed rename offered to remove them
- The cost scan could report fewer list operations than it made. Pages were counted in UI updates that could still be queued when the scan returned, so "This scan used N list operations" could come out low. Each page is now counted as the scanner reports it
- A malformed bucket list over S3 showed as a short list, not an error. The parser's error callback had the wrong signature and was never called, so a truncated response listed whatever buckets had parsed before it broke off
- A refusal Cloudflare sent with HTTP 200 was taken as success. Its API can answer 200 with
"success": false; creating or deleting a bucket, uploading or deleting an object over Sign in with Cloudflare, and listing all read only the status, so a refused write was reported done and a refused listing came back empty. They now show Cloudflare's message - Text files that were not UTF-8 showed "Preview not available". A CSV exported on Windows (Windows-1252) or a UTF-16 log is now previewed
- A failed purchase's error came back on the next paywall, opened by some other locked action, so a fresh paywall looked like it had already failed
- Create Bucket checks the name as you type. It promised 3–63 lowercase letters, numbers and hyphens but checked only the length, so any other mistake came back as a server error. S3 connections also accept dots, as S3 does
- Downloading into a folder no longer replaces files without asking. On the Mac, a file already at the same path was deleted to make room. It now asks first: Replace, Skip Existing, or Cancel
- The cost month follows Cloudflare's billing month, in UTC. It started at local midnight, so east of UTC the first hours of a month were projected from the end of the last one, and west of it the month ended early. The monitor's "not re-checked since" also turns over at UTC midnight now, when the day count behind the projection changes
- Compare after cancelling a Compare did nothing. Cancel closed the sheet but left the sync waiting for the cancelled listing to unwind, and a Compare started meanwhile was ignored, or reset by the old one when it finished
- iCloud sync could still drop a connection on a fresh iCloud. A device that had only ever seen an empty iCloud kept no record of it, so its first sync after another device's first push had nothing to merge against and pushed its own list over the other's additions. Both now survive
Changed
- Sign in with Cloudflare stays in the app on the Mac. It opens in a window inside R2Explorer, as it already did on iPhone and iPad, instead of in your default browser
- New Connection asks for the account first. Sign in, or paste an API token: the token is checked against the account's buckets before you go on, and the Account ID is optional, since R2Explorer finds the token's own account. Editing a connection no longer shows its token. It says when the token is not on this device, and Replace Token or Account… puts a new one in its place
- Settings ▸ Accounts lists API tokens beside sign-ins, once per account with how many connections use it, and can remove one. Sign Out asks first and names every other account the same sign-in covers
- The Mac object table re-sorts and reloads only when its rows change, rather than on every selection change, which cost a full pass per click on a large listing
1.8.1
Added
- R2Explorer on iPhone and iPad. The port has existed since 1.6.0 and had never shipped; this is the release that makes it real. The scope is the object browser, connections, Cost & Budget, the Cost & Catalog Monitor, Data Catalog, Settings, Help and the paywall. Mirror/Sync, Benchmark and Move to R2 stay macOS-only: they are long-running transfer jobs that want a window to sit in front of, and Benchmark additionally refuses the REST object plane, which is exactly what an OAuth-only phone connection has. Importing from
~/.awsis macOS-only for good, not pending: iOS has no Unix home directory and the Files browser hides dotfile directories, so no document picker can reach the file - Sign in with Cloudflare on iOS, through
ASWebAuthenticationSessionand a registered https callback. The loopback redirect macOS uses cannot work here and never could:openURLbackgrounds the app, and a suspended app'sNWListenerstops accepting, so the redirect completes its handshake into the kernel backlog and is never read, ending in.timedOutafter a wait that does not advance while suspended. The session presents in-process and never backgrounds the app, so there is no race left to lose - Sign in with Cloudflare from Settings, on both platforms. It used to live only in the add-connection sheet, on the reasoning that signing in should produce something. That does not survive a grant that expires or is revoked from the Cloudflare dashboard: the connections already exist, and the only way back was to start adding a connection nobody wanted just to reach the button. Settings doubles as the re-authorize path for an account connected without the optional scopes
- Cost & Budget and Data Catalog are reachable on iOS. Both were macOS-only, and both were in the iOS store screenshots, which
ScreenshotDirectorstages by setting their state directly: the harness had photographed two sheets no iOS user could open. Both are the read-only half of their feature, which is the half a phone is for - Bulk Download and Delete on iOS.
ObjectListTable_iOSgained edit-mode multi-selection, wired to theonDownloadMultipleandonDeleteMultiplecallbacksObjectBrowserViewhad always passed it and nothing had ever called, so Parallel Delete — which the store listing sells — existed on iOS only as an unreachable closure
Changed
- The iOS object browser's action bar is a menu. Download/Upload/New Folder/Delete as one bordered
HStackcompressed each title to a character per line at iPhone width, rendering as four overlapping 200pt columns of letters. Compact width now shows Refresh plus an Add menu; Download and Delete move to edit mode's own bottom bar, and the preview toggle is dropped, since it only ever gated the macOS split view - Every sheet sizes itself per platform through
platformSheetFrame. Seventeen carried a frame drawn for a Mac window, up tominWidth: 640against a 393pt iPhone, which compiles perfectly and pins content off the edge of a phone. The paywall and the add-connection sheet were both on that list: the first screen a new iOS user sees and the one that takes their money - Touch targets are sized for a finger, and the copy says "tap" where it used to say "click"
- Help, the diagnostics report and the paywall no longer call the device a Mac
- Token and Keychain handling moved to
swift-cloudflare-kit, shared with D1Explorer, along with the OAuth flow and the account store
Fixed
- Autocorrect and autocapitalisation are off on identifier fields. iOS would helpfully capitalise an access key id
- Cost, status and selection labels no longer wrap on iPhone
- The catalog maintenance steppers sit on their own rows instead of being squeezed beside their labels
1.8.0
Added
- Sign in with Cloudflare: a connection to R2 no longer needs an API token created by hand.
CloudflareOAuthruns the authorization code flow with PKCE against Cloudflare's endpoint and takes the redirect on a loopback listener, so nothing is typed into the app and no custom URL scheme is registered. The grant yields a bearer token forapi.cloudflare.com, which is enough for buckets, the Data Catalog, Sippy and the analytics behind month-to-date cost. One refresh token is kept per *account*, shared by every connection to it - A Cloudflare REST object plane (
CloudflareRESTObjectClient), so a signed-in connection with no S3 keys can still browse and edit objects. It covers list, get, put, delete and bulk delete in a single request. It cannot copy, which is why rename is unavailable on it; it has no multipart, so a singlePUTcaps at 300 MB; it ignoresRangeand answersHEADwith 405 ObjectStorageClient.capabilitiesreplacesisR2as the way to ask what a backend can do.CloudflareRESTObjectClient*is* R2 and supports neither server-side copy nor multipart, so the two had stopped agreeing- The New/Edit Connection sheet and three Connection Doctor rows now explain why adding R2 API keys to a signed-in account is worth doing, with the actual per-request cost, and link to the R2 Overview page where *Manage R2 API Tokens* lives
Changed
- Bucket Benchmark refuses to run on a connection without S3 keys. It would have timed
api.cloudflare.comrather than R2, and its 10 MB profile is multipart on SigV4 but a singlePUThere, so the number would have been real and meant something else entirely - Connection Doctor's rows that ask for an Access Key ID and Secret point at R2's own token page rather than the account-wide API tokens page they shared with the management-token rows
- The connection sheet no longer claims S3 keys are required for object operations. That stopped being true when the REST fallback landed
- The app is arm64-only. macOS 26 is already required, which is well above the macOS 13 floor Apple allows for dropping Intel from a universal Mac App Store app, so no machine that could run R2Explorer loses it
1.7.1
Added
- Help ▸ Send Feedback opens a short form on r2-explorer.mgcrea.io. Nothing is sent from the app: it hands your browser a web address and stops, and the four facts that address carries are ordinary text fields on the page you can edit or empty before sending: app version, macOS version, your Mac's model identifier, and your language. No bucket names, no object keys, no account id. The Help menu keeps the public issue tracker alongside it, which stays the first-class option here because this app's users already have a GitHub account
- R2Explorer may ask you to rate it after an upload succeeds, at most once per version and never in a session where the upgrade sheet appeared. The ask sits after the batch loop inside the
doblock, so an upload that threw partway through never counts as the success being asked about
1.7.0
Added
- Smart Filter: the object browser had no search or filter of any kind. It now has a filter field that narrows the listing as you type, plus a *Search all* action that lists every object in the bucket so a filter can span folders — explicit rather than automatic, because it spends real list operations. With *Interpret filter phrases on-device* switched on in Settings, a phrase of two or more words can be handed to Apple's on-device model on ⏎, which turns it into extension, size, recency and folder conditions. Those arrive as chips you can read and remove individually: a generated filter is a guess, and the app already refuses to run the commands it writes for the same reason. Everything below the model is a pure function with its own tests; the model only chooses parameters and never sees an object, a bucket name, a file body or a credential. Free, on both platforms. Off by default.
- Move to R2: Cloudflare's Sippy incremental migration, from the bucket context menu on any R2 bucket. Sippy copies an object from your old provider the first time something asks R2 for it, so a migration needs no bulk copy and no cutover window; what it will not do is move objects nobody requests, which is why the sheet leads with advice rather than a form. The migration advisor asks what you are actually trying to do and recommends Sippy or Super Slurper accordingly, refusing to suggest Super Slurper for an Azure source because Cloudflare does not support that pairing. Supports Amazon S3, Google Cloud Storage, Azure Blob (account key or SAS token) and generic S3-compatible sources. Reading current Sippy status, the advisor, and the
wranglerstatus commands are free; configuring a source, generating the enable command, enabling it live from the app, and disabling it are Pro. - Data Catalog billing in the Cost & Catalog Monitor: catalog operations, compaction volume, and free-tier burn-down per connection, read from Cloudflare's catalog analytics datasets. Cloudflare switched catalog billing on for non-enterprise accounts on 2026-08-03, which turned "is my catalog configured well" into "what is my catalog costing me" — the monitor now answers both in the same sweep. Usage counts, the free-tier gauge and failed maintenance jobs are free; the month-end projection is Pro, matching how the R2 cost rows already split.
- Failed maintenance job reporting, per warehouse and outside the paywall. A compaction or snapshot-expiration job that fails is a data-shape problem rather than a billing one, so it warns in the same place the Data Catalog Safety Guard already warns, not behind an upsell.
Changed
- The App Store screenshot set swaps the bucket benchmark for Smart Filter. The set is capped at ten and was full; the benchmark was the least likely of the ten to decide a download. It remains a shipped Pro feature and keeps its Settings, Help and changelog coverage — it is the screenshot and the store description bullet that went, not the capability.
- The app icon is now an Icon Composer bundle rendered from a single vector master, so the Dock icon, the App Store tile and the website's favicons all come from one file instead of three hand-kept copies.
- Monitor report exports gained
catalog_operations,catalog_mtd_usdandcatalog_failed_jobscolumns, pluscatalog_projected_usdwhen Pro is unlocked. As with the existing projection columns, the Pro column is omitted from a locked export rather than blanked, so nothing implies a number exists and was withheld.
1.6.0
Added
- Connection Doctor: a per-connection diagnostic sheet, from the sidebar context menu or the bucket-list toolbar. Where Test Connection reports one row per credential plane, the Doctor goes on to say *what to do about it*: a check can now carry a remediation link and hint pointing at the exact Cloudflare dashboard page or Settings toggle that fixes it, rather than only naming the problem. Covers the API token, Management and Object (S3) APIs, Data Catalog, Analytics, the endpoint, folder access and project data for local connections, iCloud sync state, and Cloudflare budget alerts. Every check is a read, run live each time and never persisted, so the sheet cannot go stale and cannot leak credentials into storage
- Cost & Catalog Monitor: one sheet that answers, across every connection at once, what your R2 spend and Data Catalog state are *and when you last actually asked*. Opened from the bucket-list toolbar or ⇧⌘M. Monitoring is opt-in per connection and off by default, because every check costs a real Cloudflare analytics query: nothing refreshes on a timer, Refresh All sweeps sequentially and can be cancelled mid-run, and opening the sheet only fills in connections that have never been checked rather than re-billing ones that already have a reading. Every card carries the timestamp of its reading. A reading older than four hours, or taken on an earlier calendar day, counts as stale and is *downgraded* rather than shown as current: failures soften to warnings and each message is prefixed with when it was taken, so a two-day-old projection can never paint a connection red. Free covers the sheet, the toggles, Refresh All, month-to-date cost, Data Catalog presence, and the whole freshness and staleness apparatus. Pro adds the projection and budget rows, catalog maintenance grading, deep readiness refresh (capped at five catalog buckets per run, and it says so), and the report export
- Monitor report export (Pro): copy the sweep as Markdown, CSV, or TSV, reusing the existing cost-report formats. The Markdown summary spells out each reading's freshness in words, including whether a re-check failed; the CSV and TSV carry
connection, checked_at, freshness, month_to_date_usd, plusprojected_usdandbudget_usd. Timestamps are UTC ISO-8601 so an export survives crossing time zones - iCloud connections sync: the connections list mirrors across your Macs through
NSUbiquitousKeyValueStore, behind a *Sync connections via iCloud* Settings toggle (on by default) kept separate from the existing iCloud Keychain credential sync, since the two answer different questions. R2 and S3 connections sync; local wrangler connections stay device-specific, because a path only means something on the machine it was made on. Reconciliation is last-writer-wins by revision, and demo/screenshot mode is excluded so fixture data can never reach a real iCloud store
Changed
- The Cost & Catalog Monitor's toolbar entry point moved from the connections sidebar to the bucket list, alongside the new Connection Doctor button, so the two diagnostics sit together. ⇧⌘M is unchanged
KeychainHelpernow distinguishes a missing credential from a Keychain read that was *refused*, because a locked keybag needs different advice than a missing token, and can report whether a stored item is flagged for iCloud Keychain sync- The sidebar budget badge now ages out. Previously an over-budget badge stayed red for the rest of the session; every cost entry now records when it was fetched, the sidebar re-reads on a 30-second tick, and a stale entry degrades to an orange clock rather than staying red. Tooltips gained the reading's timestamp in both states, so the badge says how old its own claim is
- The bucket list refreshes a stale cost glance instead of fetching at most once per connection per session. A manual Refresh on a day-old glance now re-reads it, so the month-to-date captions and the sidebar badge no longer freeze at whatever the first visit of the session happened to find
- Deleting a connection now also clears its monitored preference and its monitor record, alongside the budget and cost-cache entries it already cleared
1.5.0
Added
- Cost & Budget Inspector: account-wide R2 usage and cost, opened from the bucket-list toolbar. The Overview is free and shows month-to-date usage and spend per bucket, read from Cloudflare's analytics API. Pro adds a *Projection & Budget* pane: a projected month-end total, an optional monthly budget per connection, and a badge next to the connection name once the projection runs near or past it. The verdict is held in memory only, never persisted, so a connection can never be badged red on a stale projection from a previous launch
- Month-to-date cost on bucket rows: each bucket row carries its own spend-so-far caption, cached per connection and refreshed once per session so the figure costs no extra Class A operations. The month-to-date number is free; the projected month-end figure beside it appears only under Pro
- Bucket sorting: order the bucket list by name, by month-to-date cost, or by the order the provider returned (now an explicit *Default* choice). The cost sort uses the free month-to-date figure, so it works without Pro, and buckets with no cost figure sort alphabetically after every priced bucket instead of changing position on each re-sort. Persisted across launches
- R2 SQL queries (Pro): a *Query* tab on the Data Catalog sheet that turns the catalog you are already browsing into ready-to-run R2 SQL. Pick a namespace and table from what the catalog actually reported, and it generates
SHOW NAMESPACES,SHOW TABLES IN,DESCRIBE, a sampledSELECT, and itsEXPLAINplan, each copyable as bare SQL for Cloudflare's dashboard editor or wrapped as awrangler r2 sql queryinvocation for your own terminal. R2Explorer never runs them: it is sandboxed and cannot launch processes - AWS IAM Identity Center (SSO) import:
~/.awsprofiles that sign in through IAM Identity Center are recognized and labelled. A profile that needs an external refresh, whether through SSO orcredential_process, now offers the exact commands to run (aws sso login, thenaws configure export-credentials) instead of only explaining why it cannot be imported. Combined with the STS session-token signing added in 1.4.1, the exported temporary credentials connect as-is - Dedicated analytics API token per connection: Cloudflare's R2 API tokens cannot carry *Account Analytics · Read*, so a connection that passes every other health check can still be unable to read cost. A connection can now store an optional second token just for analytics, kept under its own Keychain key. A general account token scoped for both R2 and Analytics still only has to be entered once. Test Connection gains an Analytics API row that warns rather than fails, because analytics is an optional capability layered on an otherwise-working connection
- Measured usage fallback: for connections analytics cannot serve (S3, local, or an under-scoped R2 token), cost can be totalled by walking the bucket instead. Storage only, since operation counts are not knowable this way, and never automatic: listing itself costs Class A operations, so each run is something you opt into
- Cost report export: copy a priced breakdown as Markdown, CSV, or TSV, mirroring the existing Data Catalog and benchmark exports
Changed
- The bucket list header now carries the sort menu and a compact create-bucket button, so both sit with the list they act on instead of in the toolbar. The create button is Pro-gated like the toolbar action it mirrors, and says so in its tooltip when Pro is locked
- R2Explorer Pro is now a $5.99 launch price. Anyone who already owns Pro keeps it, and an unlock bought at the launch price covers every future update
Fixed
[sso-session]blocks in~/.aws/configare no longer read as importable profiles. Every IAM Identity Center configuration contains at least one, so the profile picker was showing a phantom entry that could never be imported, and keys inside that block could attach themselves to whichever profile preceded it- The connection sheet can no longer grow taller than the window
- The App Store listing's privacy URL points at the live host
1.4.1
Added
- Data Catalog Safety Guard (R2 connections): when a bucket has R2 Data Catalog enabled, R2Explorer warns before an out-of-band object mutation (delete, Empty Bucket, rename, upload, or mirror/sync into that bucket), because adding, changing, or deleting objects outside the catalog can leave Iceberg tables pointing at files that no longer exist. The warning is advisory, never a hard block: it explains the risk, offers to open the Data Catalog or copy identifying details, and always lets you proceed. It appears once per bucket per session, and only when the catalog status is actually known, so it never implies a bucket is catalog-free when it could not be checked. Reads its answer from a per-connection catalog lookup, so it does not add a network round-trip to your deletes
- STS session-token signing (S3 connections): sign requests with the session token from temporary AWS credentials, so a connection imported from an
~/.awsprofile that uses short-lived credentials works instead of failing to authenticate
Changed
- Data Catalog token guidance now distinguishes a query token (read-only: R2 Data Catalog Read and R2 Storage Read) from a maintenance token (read-write), reflecting Cloudflare's July 2026 support for read-only Data Catalog API tokens. Query clients like DuckDB, PyIceberg, and R2 SQL no longer need write access they will not use. The readiness panel, the generated
wranglercommands, and the exported shell script all read this guidance from one source, so they can no longer drift
1.4.0
Added
- R2 Data Catalog inspection (R2 connections): a Data Catalog item in the bucket context menu showing catalog status, maintenance configuration, namespaces, and per-namespace table counts. Free, like the rest of the read-only surface
- Data Catalog Maintenance Workbench (Pro): two new tabs on the Data Catalog sheet. - *Readiness* grades the catalog against the maintenance tasks Cloudflare expects you to run (compaction, snapshot expiration, and the API token they need), and says what each gap costs. The headline case: compaction on with expiration off means you store both the original small files and their compacted replacements, indefinitely - *Commands* generates the exact
wrangler r2 bucket catalogcommands to close those gaps, scoped to the catalog or a single table, with the destructive ones quarantined in a Danger zone. R2Explorer never runs them: it is sandboxed and cannot launch processes, so they are generated to copy and run in your own terminal - Readiness and the command set export as Markdown or a shell script - Connection health diagnostics: Test Connection now reports one row per credential plane instead of a single pass/fail, so an R2 token that is valid but missing R2 scope reads differently from one that is simply wrong, and an unreachable S3 endpoint is distinguished from a permission failure
- AWS profile import: read
~/.aws/configand~/.aws/credentialsand prefill a connection from a named profile. Profiles that usecredential_processor session tokens are detected and clearly explained rather than silently half-imported - Benchmark report export: copy results as Markdown, CSV, or TSV, with the endpoint, region, and provider recorded alongside the numbers so a pasted report says which bucket it came from
- Empty Bucket (Pro): a bucket context-menu action that deletes every object in a bucket while keeping the bucket itself, driving the existing delete progress sheet
Changed
- Data Catalog reads coalesce the maintenance-configs endpoint over the catalog body, so the panel reports the authoritative configuration
- Toolbar: the Help button moved after Refresh, and every toolbar control gained a tooltip
Fixed
- The Pro price is shown only once StoreKit resolves it. It previously fell back to a hardcoded
$4.99, which showed a USD figure to users in other storefronts; the paywall and Settings now read "Unlock Pro" until the real localized price arrives - The Empty Bucket sheet is guarded against a stale coordinator and a mismatched selection, so it can no longer act on the wrong bucket
1.3.2
Added
- New Local connection type for local
wrangler dev/ Miniflare projects: browse and edit a project's R2 buckets and objects straight from.wrangler/state/v3/r2on disk, with no credentials required - Folder picker in the connection sheet with a security-scoped bookmark so local access persists across launches, plus a Test Connection that reports the discovered bucket count
1.3.1
Fixed
- Stream browser downloads to disk and persist the custom Downloads folder across launches via a security-scoped bookmark
- Surface Keychain write failures on connection add/update instead of leaving the connection in an inconsistent state
- Return the sync planner to idle when the planning phase is cancelled
- Skip the grandfather check in non-production StoreKit environments so TestFlight and sandbox builds no longer accidentally hand Pro to reviewers and testers
Added
SupportLinkshelper centralising GitHub and issue-tracker URLs
Changed
- R2 management API error-body decode failures are now logged via
os.Loggerinstead of being silently swallowed - File preview pane debug output moved from
print()toos.Logger INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NOset so App Store Connect skips the export-compliance prompt on every TestFlight build
1.3.0
Changed
- R2Explorer is now free to download; read operations (browse, list, download, preview) stay free for everyone
- Write operations (upload, delete, rename, create/delete bucket, mirror/sync, benchmark) require a one-time $4.99 R2Explorer Pro in-app purchase
- Every buyer of R2Explorer 1.2.2 or earlier is grandfathered to Pro silently on first launch via
AppTransaction.originalAppVersion
Added
- Settings pane "Pro" tab with unlock status, in-place purchase, and Restore Purchases
- Paywall sheet presented when attempting a locked action, with product price, feature list, and Restore Purchases
1.2.2
Added
- Rename files and folders from the context menu: safe copy-then-delete with overwrite confirmation, live progress for folder renames, typed "RENAME" gate for jobs over 500 objects, and orphan rollback on partial failure
1.2.0
Added
- Bucket Benchmark feature: right-click any bucket to run upload, download, TTFB, and list tests (1 KB – 10 MB), view latency percentiles (min/avg/p50/p95/max) and throughput, and copy results to clipboard
1.1.0
Added
- Bucket Mirror / Sync feature with cross-connection support and live byte-level progress
- Folder and multi-select deletion progress modal
- Delete concurrency setting (1–16, default 4)
- ⌘R keyboard shortcut to refresh the file view
Improved
- Parallel delete batches with provider-aware chunk sizing
- Download progress reporting during sync transfers
- Sync progress layout stability
- Reliable cancel for sync transfers
Fixed
- Path traversal vulnerability in folder downloads
- Progress starvation in delete and sync operations
- Bucket-create error state handling
- Confirm-delete preference now properly honored