github flythenimbus/bramble 0.2.0-desktop
Desktop 0.2.0

4 hours ago

Features

  • check for updates from the menu, and say who wrote this
  • offer an update in a native dialog on launch
  • update the app in place from a signed GitHub release
  • flip UI flags at runtime from a shortcut, so a signed build can be tested
  • put rotation behind a build-time flag, off by default
  • rotate the vault's secret, with every consequence stated first
  • open the highlighted entry from the panel, and separate the disconnect verbs
  • fill the browser from the panel
  • Enter copies the highlighted result's password
  • send the hotkey to the vault window when locked
  • search the vault from the panel and pick a result
  • make Enter the fill action in the panel
  • show the panel's shortcuts under the search field
  • offer to carry a vault's entries into the shared one
  • connect a browser in one code and one click
  • let a browser claim the sync invite over the link
  • sync with the desktop app over the link, not the relay
  • hold the desktop link open so sync can arrive unprompted
  • sync with browsers on this machine over the link, not the relay
  • carry sync frames over the browser link
  • compare pairing emoji instead of twelve digits
  • admit the joiner in the process, not the window
  • keep the vault in step with its group after enrollment
  • run device-sync enrollment in the webview
  • give this device a sync identity
  • expose the sync host's crypto, and skip the native WebRTC bridge
  • ask the desktop app what it holds
  • carry queries over the established session
  • index the vault for the browser link
  • bundle the proxy so the browser link works from a real app
  • link to the Bramble desktop app
  • show a pairing code in Settings
  • install the native-messaging host manifest
  • add the native-messaging proxy
  • serve the browser pairing handshake over a local socket
  • keep the pairing key in the OS credential store
  • pair with a browser extension over an allowlisted static key
  • expose the Noise handshake to the native build
  • outlive the main window, and leave the Dock with it
  • add the spotlight panel shell
  • let the single-column screens fill the window
  • fix the window at 600x580, and name the scripts by verb
  • scaffold the Tauri 2 app on the shared Rust core
  • validate the expiry and security code too
  • validate the card number against a zod schema
  • copy a card's expiry and CVV from the row menu
  • add an MDX blog, starting with the one-month write-up
  • tag iOS releases, still without a GitHub release
  • port the portable vault to iOS and Android
  • read a .bramble export back in, merging into the vault
  • export the selection as a .bramble file
  • bulk-select entries in the list, with delete
  • seal a portable vault under a file-only key
  • mark logins that hold a passkey in the list
  • keep the last few passwords a login rotated away from
  • choose the destination vault for an inbound transfer
  • reachable UI for OS credential transfer (phase 3)
  • credential exchange plugin, plists and token handoff (phase 2)
  • CXF 1.0 mapper, both directions (phase 1)
  • import passkeys from Bitwarden JSON
  • expose passkey key import across platforms
  • convert imported P-256 PKCS#8 keys
  • copy the verification code from the list row's copy menu
  • link the Matrix room from the header and footer
  • add well-known delegation files for federation
  • recover a vault whose entries won't decrypt, from a verified snapshot
  • write KeePass .kdbx files under a user-chosen password
  • read Apple Passwords and Google Password Manager CSVs
  • iOS one-time-code AutoFill, behind the keyboard-suggestions opt-in
  • unlock iOS with the device passcode
  • offer the password suggestion even when the vault is locked
  • suggestion-only prompt on signup, tokenized light/dark colors
  • offer the strong-password suggestion on change forms
  • suggest a strong password on signup forms
  • build android in the reproducible container, sign on host
  • prepare F-Droid inclusion, commit build numbers to source
  • add Buttondown newsletter signup form
  • collapsible stats row on home, sticky
  • graceful spinner fallback for slow lazy-route loads
  • plain divider + "Create another vault" on single-vault unlock
  • Astro + Starwind landing site on shared @vault/theme
  • bolder, wider on-page picker
  • make QR scan the primary Join experience on mobile
  • wire back navigation - Android hardware back (#15) + setup-shell back button
  • restore the QR-code scanner in the mobile Join flow
  • always offer the "Join a device" tab
  • active-vault-aware Android autofill + per-vault biometric
  • per-vault biometric unlock (core + iOS)
  • show 'Join a device' in the setup shell on a fresh device
  • render 'Restore from backup' inline as a tab, not a page swap
  • unify first-run 'open existing vault' with the multi-vault restore flow
  • hide 'Create new vault' on unlock when multiple vaults exist
  • join a P2P mesh from the setup shell (join = add a vault)
  • per-vault VEK inc 6 - atomicity guard + lock-to-picker
  • per-vault VEK inc 5 - hand the VEK to enrollment explicitly
  • per-vault VEK inc 4 - tag the background consumers
  • per-vault VEK inc 3 - scoped view adapter + create binding
  • per-vault VEK inc 2 - the seam flip (offscreen + background)
  • per-vault VEK inc 1 - inert threading (schemas + vek-store)
  • forward the inviter's recovery slot to joiners (shared group recovery code)
  • restore .bramble backups from the Add-a-vault screen
  • scheduled backups cover every vault, not just the primary
  • vault name inline on the home header + on the unlock screen
  • always show the active vault's name in the header
  • show the active vault's name in the header
  • per-vault device sync (extension)
  • share the active vault id with the background (multiple vaults phase 2)
  • vault name input in General; delete moves to its own re-auth-gated section
  • drop create/switch buttons from the settings vault section
  • settings vault section acts on the current vault only
  • inline recovery-code and switch-vault links with a dot separator
  • per-vault picker cards + context-aware setup screen (multiple vaults)
  • settings vault list + switch vault (multiple vaults phase 1)
  • add 'choose a different vault' link on the unlock screen
  • create parallel vaults + launch-time vault picker (multiple vaults phase 1)
  • thread active vault id through VaultProvider (multiple vaults phase 0)
  • vault registry + id-aware blob storage (multiple vaults phase 0)
  • show/hide toggle on every password field
  • separate "lock on screen lock" toggle + fix locked-prompt desync
  • single-instance pop-out window (no tabs permission)
  • accept patch/minor/major bump keywords
  • Monero first + Lightning/on-chain toggle on the BTC card
  • add the Bitcoin (Lightning) donation card
  • replace "Total entries" with source-code links
  • wire the real Monero donation address
  • Support / donations section (Bitcoin + Monero)
  • "Last synced" timestamp in the Sync settings (extension + mobile)
  • live-refresh target status on background writes
  • keep-last-N retention control in the target form
  • enable .bramble backup restore
  • open a .bramble file from the "Open existing vault" screen
  • rename the "Data" tab to "Backups"
  • sort the generic "Other" tiles last
  • single alphabetical provider grid
  • drop the Google Drive tile; Dropbox is the only OAuth provider
  • configure the Dropbox app key + add files.metadata.read scope
  • OAuth one-click providers (Dropbox), Phase 2
  • automatic scheduled backups in the background
  • accept a full bucket URL and show target errors in full
  • persist the active tab in route search params
  • restore a .bramble backup (extension-only for now)
  • wire manual backup end-to-end
  • S3 + WebDAV storage clients and backup orchestrator
  • cloud backup settings UI
  • auto-publish to the Chrome Web Store on release chromium
  • macOS "touch your YubiKey" banner before each age decrypt
  • "Immediate" auto-lock that locks when the last view closes
  • carry Bitwarden URI match detection into subdomainMatch
  • broadcast on local write so a change pushes immediately
  • Phase 3 hardening (A2 doc, B3 DAL SSRF, B4 clock-skew)
  • password-authority admission producer (iOS + Android)
  • password-authority admission producer (extension)
  • cross-language feature flags for the phase-1 -> phase-2 rollout
  • password-derived admission signing key (Item A)
  • admission gate (verify side) closes rogue-injection (Item A)
  • sticky roster tombstones close the B1 re-add resurrection
  • mirror sync status to the persistent host/background console
  • reset sync state on new-vault creation
  • activate roster signing on the extension (Item A #3b)
  • sign this device's own roster entry at enrollment (Item A #3b, core)
  • verify gossiped rosters before merge (Item A #3b, verify half)
  • TOFU roster verification kernel (Item A #3a)
  • Ed25519 device-key signer for roster mutations (Item A #2)
  • roster-entry signing foundation; defer group-key rotation
  • fail loud when an unverified caller supplies a browser clientDataHash (B2)
  • verify native-app autofill domains via Digital Asset Links
  • export an encrypted .bramble vault backup
  • store the vault in chrome.storage.local, drop the FSA backend
  • restore the popup route on reopen while unlocked
  • declare data_collection_permissions (required: none)
  • attach buildable source to the AMO listed submission
  • Firefox ships listed to AMO; GitHub release carries source only
  • metadata:firefox pushes by default, --dry-run to preview
  • metadata:firefox pushes the localized AMO listing
  • translate web store listings (Chrome + AMO) from the repo
  • passkey provider via MAIN-world content-script transport
  • relay-forward transport as a negotiated WebRTC fallback
  • Firefox WebRTC host iframe — probe increment (option a step 1)
  • request persistent storage so the only vault copy isn't evicted (Firefox port, phase 5)
  • float current-site matches to the top of the list
  • search, filter, sort, and lifecycle timestamps for the vault list
  • attach SHA256SUMS to chromium releases (parity with android)
  • registration (create) + pending handoff (step 3)
  • assertion flow - sign in with a stored passkey (step 2b)
  • vault passkey read + W3C response JSON builder (step 2a)
  • register a Credential Manager provider (skeleton)
  • finalize Bramble AAGUID; TODO to register it in the community list
  • make a freshly-created passkey usable without opening the app
  • register (create) passkeys + persist via a pending handoff
  • assert stored passkeys (sign-in) in the credential provider
  • surface stored passkeys to the OS credential store
  • passkey rows in the login item edit + view
  • get-time passkey picker for multiple accounts
  • confirmation toast when the provider saves a passkey
  • account picker when saving a passkey to an ambiguous domain
  • differentiate save-passkey card for an existing login
  • pause passkey proxy during Bramble's own WebAuthn unlock
  • Settings toggle for the passkey provider (General)
  • save-passkey corner prompt + create/get wiring
  • webAuthenticationProxy passkey handler (orchestration)
  • passkey provider vault logic (find + placement)
  • WebAuthn JSON helpers for the passkey provider
  • expose passkey crypto through TS adapter + transports
  • passkey authenticator crypto + entry model (provider role)
  • black splash with Bramble logo lockup, no white flash
  • full internationalization across all targets
  • modality-aware copy in the biometric Settings row
  • label biometric unlock by modality (Face ID vs Touch ID)
  • enforce matching master password when enrolling a device
  • add ios release lane (versioning + TestFlight, build-tagged)
  • native iOS WebRTC data channel via webrtc-rs
  • surface transport status + state for on-device diagnosis
  • native sync crypto on Android too (uniffi handshake/nostr)
  • native iOS sync crypto so pairing works under Lockdown Mode
  • per-device remove (revoke) with roster propagation
  • stop streaming transport status into the Settings log box
  • pre-fill + space the ICE/relay settings; tolerate more ICE shapes
  • TURN relay + state-aware device UI, with relay diagnostics
  • add Android system AutofillService at iOS parity
  • build, sign, and publish Android APKs via release android
  • add Android app launcher icon
  • source app version natively and add per-target version bumping
  • add ios:metadata script; lane pushes screenshots when present
  • target the project marketing version in the metadata lane
  • iOS autofill domain filtering + QuickType opt-in
  • Android native crypto (uniffi Kotlin NativeCrypto plugin)
  • "Immediately" auto-lock option (mobile default) replaces keep-unlocked toggle
  • opt-in "keep autofill unlocked" window (15 min, off by default)
  • autofill authenticates before revealing entries; encrypt the bundle
  • autofill master-password unlock in the extension + passcode cache
  • native iOS crypto + real autofill provider via shared uniffi core
  • set the iOS app icon from icon/ios
  • auto-resolve JDK 21 for android run/dev scripts
  • iOS autofill credential-provider probe (Phase 3 go/no-go: GO)
  • hide security-key unlock on mobile; biometric takes its slot
  • re-probe biometric availability when Settings opens
  • native BiometricVault plugin (iOS + Android) + adapter
  • device-local biometric unlock seam (optional Platform.biometric)
  • secure-storage substrate; move sync device keypair to Keychain/Keystore
  • buffer recent sync status so the panel shows current state on open
  • ongoing roster sync (continuous merge after enrollment)
  • show status log + explicit success message on join
  • hide pop-out affordance (supportsPopOut capability)
  • route Settings import to in-app ImportShell with close-to-app
  • camera QR scanning (getUserMedia + jsQR) for sync pairing + TOTP
  • wire P2P sync enrollment (in-webview, via @core/sync/transport)
  • inactivity auto-lock honoring autoLockMinutes (not lock-on-pause)
  • lock vault on app background (lifecycle pause)
  • streamline vault setup screen (hide file-location, pill tabs, compact)
  • in-app vault setup navigation + safe-area insets
  • upgrade Capacitor 7 -> 8 (SPM iOS project)
  • scaffold Capacitor platform-mobile POC (Phase 0 walking skeleton)
  • cap message size and subscriptions per connection
  • default to hosted relay, fold URL under Advanced
  • cloudflare worker relay; reorganize into node/ + cf-worker/
  • cross-device P2P vault sync, with architecture, crypto, and UX hardening
  • build, sign, and publish releases locally for CWS verified uploads
  • support logins inside open shadow DOM (web components)
  • inject content script in all frames for iframed logins (e.g. Apple ID); add reddit fixture/tests + screenshot seed
  • gate release on lint + tests so a failure blocks the release
  • tag releases as - with " Extension " name
  • tagged-release workflow + platform-aware version-bump script
  • theme-aware monochrome icon, light/dark/system selector, and entry-detail header actions
  • harden the autofill UI behind an extension-origin iframe
  • replace placeholder Shield logo with Bramble glyph
  • Chrome toolbar/install icons + icon source bundle
  • KeePass KDBX4 import — key files + WASM-side decrypt
  • webauthn unlock with hmac-secret + 26 crypto/policy tests
  • corner-prompt save/update card for captured logins
  • a login can cover multiple websites (url:string → urls:string[])
  • show the OpenSSH SHA-256 fingerprint on SSH-key entries
  • lock the vault when the OS locks the screen (idle.onStateChanged)
  • declare a lock-vault keyboard command (unbound by default)
  • import from 1password, bitwarden, keepass and proton pass
  • harden TOTP autofill and skip auto-submit on captchas
  • typed entry modes with cards, notes, ssh keys + custom-field autofill
  • retain state on pop-out, react to background locks, ui polish

Bug Fixes

  • hide the desktop link where the browser cannot do it
  • make a universal build actually produce a universal app
  • make --universal actually release a universal build
  • serve a valid update manifest before the first release
  • arm nothing when no desktop app is paired
  • reconnect the pipe and the relay after either drops
  • say whether the vault on screen is the one the desktop app shares
  • keep the vault and its metadata owner-only
  • say which vault a desktop connect will leave you in
  • three faults the first real pairing surfaced
  • let the release build reach the sync relay
  • let cargo run in this crate without a staged sidecar
  • make a broken pairing key visible instead of silent
  • read the pairing key once, not per connection
  • scan this package for Tailwind classes, and collapse the panel
  • give the app icon the macOS shape
  • place the relayed picker in document, not viewport, coordinates
  • host the picker in the top frame for hosted-fields checkouts
  • translate the vault errors the UI renders
  • make the session guards fail loudly instead of silently
  • stop a superseded session from firing sync, backup and pop-out work
  • make VEK install and removal transactional and fail closed
  • bind the decrypted index to the vault session that built it
  • deliver picker secrets on the requesting document's own channel
  • keep app URIs out of the web hostname index
  • say why a scanned QR was rejected instead of "none found"
  • detect one-time-code and identifier fields beyond English
  • capture logins on formless SPA submits
  • keep a revealed secret inside its detail row
  • say when a connection attempt fails without spending the invite
  • restore a backup when the device has no vault yet
  • stop dropping passkeys whose user handle exceeds 64 bytes
  • translate ICU plurals instead of rejecting them
  • actually show the passkey marker, and cover the seam
  • tell Nextcloud users which URL the WebDAV field wants
  • say which passkey field was rejected, and why
  • stop re-importing the same file from duplicating everything
  • converge the inviter's pairing prompt on the host, not one event
  • let mobile pickers select .1pux, .kdbx and the other containers
  • don't blame the user's data when the converter is missing
  • re-export hexToBytes for the Bitwarden passkey importer
  • wait for the pending-transfer peek before claiming
  • ask for the destination vault on the condition that actually holds
  • route to the import screen at a cold launch, not just on the event
  • land on the preview, and stop advising a file cleanup
  • passkey keys are PKCS#8 on the wire, raw scalars at rest
  • register CredentialExchangePlugin with the bridge
  • say why a transfer is unavailable instead of hiding it
  • erase the provider mirror and biometric item on delete
  • close GHSA-x4f5-4wq4-c6c8, a live pairing code grants the whole vault
  • repair the escaped braces in the well-known client file
  • revive the picker's iframe renderer under use_dynamic_url
  • close the unlock pop-out and drop the stale locked row
  • patch brace-expansion and postcss advisories
  • build metadata paths from REPO, not dir
  • stop gym littering the repo root with build artifacts
  • keep the export path out of the ffi build
  • require an explicitly captured VEK to send an enrollment bundle
  • refuse a blind blob write when several vaults are registered
  • verify the loaded key before overwriting a vault's entries
  • record the active vault before the VEK swap, clear it on delete
  • bind a mobile roster session to one vault for its lifetime
  • stop Xcode re-stamping the build number at export
  • stop the AutoFill unlock flashing "Keychain status -25308"
  • re-translate fastlane metadata when the English source changes
  • build the one-time-code identities inside the iOS 17 guard
  • refuse blind blob writes, reap ghost vault records
  • stop stranding ghost vaults, and land merges in the right one
  • stop later list rows painting over an open row menu
  • restore current-site matching in the detached pop-out
  • close the TextField notch when focus is on an adornment button
  • don't lose an "Unlock & save" capture, and confirm it with a toast
  • refresh the dropdown after click-to-unlock (issue b)
  • signups offer a NEW login, not update an existing one
  • sign android without v1 or realignment for reproducibility
  • container Node from nodejs.org binary, not apt
  • commit Cargo.lock and pin std paths to the canonical form
  • make Rust output independent of the checkout host
  • scan rules for the remaining generated binaries
  • satisfy the source scanner after the Rust cross-compile
  • bump buildserver Node to 22.23.1 for rolldown's engine floor
  • prebuild runs in one shell, so cd must not compound
  • match fdroiddata CI rewritemeta formatting
  • clear tar/sharp/shell-quote/fast-uri advisories; prune stale overrides
  • drop public/_redirects (caused /support redirect loop)
  • update brace-expansion to 5.0.7 (CVE-2025-5889)
  • converge racing no-registry migrations on one vault id
  • show a loader while decrypting, not an empty-vault flash
  • 2FA verification-code fields no longer misdetected as CVV
  • corner card / picker box model survives host-page CSS resets
  • omit ambient cookies so WebDAV uploads authenticate
  • override adm-zip to 0.6.0 (GHSA-xcpc-8h2w-3j85)
  • refresh the on-page picker after unlock (#20)
  • no white flash before the theme resolves
  • stop hiding the "Keyboard suggestions" toggle behind a keyboard probe (#19)
  • drive Android back through the router, not window.history
  • show the real per-vault sync panel on mobile (drop the stale "primary vault" gate)
  • use the extension's segmented tabs on mobile (drop the rough pill variant)
  • disconnect removes the ACTIVE vault's namespaced group, not flat sync.group
  • push the ACTIVE vault's password slot to iOS autofill
  • target the active vault in sync + persist active-vault; scope the migration
  • add the joiner to the roster in the enroll host, not just the popup
  • per-vault VEK - locking is a clean slate (single-view UX)
  • joining a group provisions a fresh recovery code for the device
  • 'Back up now' backs up the active vault, into its own folder
  • keep Firefox's event page alive during enrollment
  • start ongoing sync as soon as a vault's group exists
  • land on the unlocked vault's home, not the picker
  • restore never overwrites an existing vault (adds a new one)
  • scope the sync panel to the primary vault (stopgap)
  • restore the unlocked vault on reopen instead of the picker
  • use the shared TextField for the vault-name input
  • make the vault picker scroll when there are many vaults
  • keep unlock-screen links at text-xs
  • suppress OS autofill + smart keyboard on password fields
  • hide biometric unlock when OS biometry is off
  • obvious tab scroll chevrons + working BTC toggle size
  • move DerivedData off /tmp to a repo-local path
  • accept v2 uploadState SUCCEEDED (not v1.1 SUCCESS)
  • upload verified CRX via the CWS REST API v2
  • upload the signed .crx to CWS (Verified CRX Uploads)
  • strip manifest key from the CWS package
  • one YubiKey touch for chromium (decrypt both CWS secrets together)
  • secretFromKeychain returns string | undefined, not null
  • smaller BTC method toggle, placed below the QR
  • pin donation copy buttons to the card bottom
  • lay the donation cards in a row
  • stop "Last synced" flickering between "now" and "N seconds ago"
  • add a dot separator between the GitHub and Codeberg links
  • format dates with the active app locale, not the browser default
  • run the OAuth connect in the background service worker
  • keep saved credentials when editing a provider
  • browser passkey allow-list + fail-loud on declined create
  • make Face ID biometric unlock reliable (keychain group + presence check)
  • recovery-code Download saves via the native share sheet
  • resolve Keychain access group from the signed entitlement (-34018)
  • chunk the vault across Noise frames so large vaults sync
  • clear all sync state on new-vault creation
  • prune the mesh known-set on peer close so bounced peers reconnect
  • mint a fresh device id on join so a revoked device can rejoin
  • model multiple runtime.onMessage listeners in the bg harness
  • render multi-candidate update-login prompt as markup, not text
  • accept extension pages hosted in a tab (popout regression)
  • sender-gate crypto/sync host and corner-update origin (A3, A4)
  • enforce revocation on inbound frames and reap on gossip
  • verify the privileged caller before signing a passkey clientDataHash
  • only trust webDomain from a verified browser for autofill
  • enforce device revocation on a live roster-sync session
  • reject future-dated HLC stamps from remote peers (revocation integrity)
  • scope autofill fill and corner prompt to the requesting frame
  • keep the vault unlocked across the import file picker
  • bump web-ext 8.10.0 -> 10.4.0 to clear dev-dep advisories
  • give a clear error for an encrypted Bitwarden export
  • suppress native autofill on fields the picker takes over
  • await hydration in the webAuthn proxy listeners
  • make background passkey vault reads FSA-safe
  • decode TOTP QR in the offscreen host, not the service worker
  • cache the VEK on security-key unlock
  • set the AMO category on listed submissions
  • set the GPLv3 license on listed AMO submissions
  • resolve web-ext signed .xpi basename against artifactsDir
  • pass amoBaseUrl to web-ext sign (8.x makes it required)
  • close the unlock window after a locked passkey unlock
  • wrap content scripts in an IIFE so they don't clobber each other's globals
  • keep-alive alarm so background sync survives event-page suspension
  • localize manifest via _locales (default_locale + MSG)
  • Firefox testing round 1 (popup close, FSA/security-key/theme gating, sync log)
  • set Firefox gecko id to firefox@bramble.app
  • gate passkey provider off on Firefox (Firefox port, phase 4)
  • preserve \n/\t escapes; escape stray quotes in it/es strings
  • escape backslash in strings.xml encoder (CodeQL #30)
  • sync screenshots instead of overwrite to stop duplicates
  • replace deprecated kSecUseOperationPrompt with LAContext
  • squash duplicate toasts (same message + variant)
  • sign in with a single unlock (bridge list->sign)
  • use a freshly-created passkey before the app drains it
  • sign the browser-provided clientDataHash (fixes sign-in)
  • empty save toast - use i18n._(msg) not the useLingui macro
  • rename usePendingPasskeys to .tsx so its lingui macro is transformed
  • registration response needs response.publicKey (SPKI)
  • set BE+BS backup flags on synced passkeys
  • registration response needs authenticatorData + publicKeyAlgorithm
  • attach a new passkey to the right account by username
  • route background passkey crypto through the offscreen
  • render the passkey card account row as markup, not text
  • resolve passkey request origin from the active tab
  • generate notes from conventional commits, not PRs
  • skip keychain access group on iOS Simulator for biometric VEK
  • run build-crypto-ffi.sh under the macOS system bash (3.2)
  • release script
  • hide security-key pairing option on mobile
  • native iOS QR scanner for pairing/TOTP codes
  • clean up helper copy and gate platform-specific rows
  • trim App Store subtitle to the 30-char limit
  • harden QuickType identity-store population
  • flatten the 1024 marketing app icon (remove alpha)
  • fastlane uses a monotonic timestamp build number (race-free)
  • keep-autofill-unlocked window reuses the auto-lock timeout
  • autofill unlock shows the device's biometry (Face ID / Touch ID) + passcode
  • autofill UI matches the app auth screen + list (logo, card, padding)
  • autofill biometric via Keychain prompt + visible error alerts
  • autofill persists while locked, app-styled list, biometric hint
  • autofill App Group JSON + extension Face ID, fastlane internal DerivedData
  • add AutoFill entitlement to the main app target (App Store validation)
  • inset safe area at #root so screens keep their own padding
  • lock viewport scale to stop WKWebView rendering content off-screen
  • sort imports to satisfy biome ci
  • re-tag an already-bumped version instead of failing on an empty commit
  • disable happy-dom resource loading so fixture fetches don't fail CI
  • clear unconditionally instead of reading it back
  • cap untrusted KDBX Argon2 params to prevent OOM/hang on import

Performance

  • virtualize the entry list
  • code-split non-first-paint routes to shrink the initial bundle
  • batch native decrypt so a large vault opens in one bridge call
  • decrypt the whole vault in one offscreen round-trip
  • lazy-load jsqr to halve the service-worker bundle
  • code-split the import flow into an on-demand chunk

Refactors

  • drop the link's Test button and site probe
  • let a session take its peers from somewhere other than the relay
  • share the file-picker row and the notched field outline
  • fold three duplicated helpers into single homes
  • one ES256 constant, shared by both import paths
  • one PKCS#8 conversion, in the Rust core
  • group the three suites under e2e/ and document them in one place
  • group Import & backup by whose format it is
  • move the iOS lanes to the repo-root fastlane/
  • finish the Button sweep - ErrorBoundary + BackupSection
  • add a shared cva Button and adopt it across the app
  • delete the dead inline-capability probe + trim comments
  • drop the always-true restore capability
  • namespace every vault by id via a one-time copy migration
  • remove the dead primaryId, fall back to the legacy/default vault
  • drop the Settings 'Join with a pairing code' path
  • single verified delete path (useVault.deleteVault)
  • rename/remove act only on the active vault (never another)
  • central localized date formatter; picker shows 'Created on Jan 13, 2026'
  • rename passkeyProvider capability -> passkeyProviderToggle
  • central per-target capability registry
  • use cn() for dynamic classNames
  • validate OAuth token responses with zod
  • extract the scheduled-run orchestration to core
  • support multiple backup targets
  • split sections into scrollable tabs
  • drop reducible as unknown as casts across TS (20 -> 5)
  • switch dispatch + drop wasm-view double casts
  • rip out dead FSA / file-picker code
  • transport-select the crypto+sync host (Firefox port, phase 2)
  • cross-browser api shim for chrome.* (Firefox port, phase 1)
  • split vault context into state + actions; share prefs provider
  • centralized reusable Toast (success/error/info)
  • rename packages/crypto-wasm to packages/core-rust
  • resolve the Keychain team prefix at runtime
  • dedupe shared autofill identifiers + tidy native plugins
  • SwiftUI autofill UI styled from the app design tokens
  • share the wasm->CryptoAdapter mapping via buildCryptoAdapter (mobile + offscreen) + unit test
  • hoist VaultCrypto type to @core/wasm; split mobile vault-session lifecycle off the crypto adapter
  • extract EntriesBlobStore as the one entries-format writer; build VaultSyncPort over it
  • move pure P2P transport/host modules from extension to core
  • rename manifests/chrome dir to chromium for accurate cross-browser naming
  • move content-only detection into content/
  • rename folder entry index.ts to match its folder name
  • move entries into background/ and content/, point vite at them
  • decompose content-script into concern modules under content/
  • split background into concern modules under background/
  • replace onMessage if-chain with a typed handler registry
  • extract card-brand and ssh key-type helpers to util
  • lean on tanstack router for route guards + ui fixes

Documentation

  • the bundling gap is closed
  • record the browser link, and that pairing needs signing
  • design extension unlock delegation as operation delegation
  • write out the extension pairing's security model
  • bring the port plan up to what was actually built
  • plan the Tauri 2 desktop app
  • record the versions carrying the xm22 transport fix
  • rewrite the GHSA-xm22 audit as a record, not a plan
  • publish the GHSA-xm22 transport audit
  • keep the contributed single-pass field-inventory plan
  • release notes for the bulk-selection work, and translate them
  • name why browser passkeys fail, and allow-list Vivaldi
  • cover the portable vault, and correct what .bramble now means
  • release notes for the next build, and translate them
  • say plainly how long a superseded password is kept
  • map every reason a passkey is skipped on import
  • release notes for 1.5.0, and translate them
  • export verified on device, including a passkey sign-in
  • mark phase 3 done, phase 4 is the device pass
  • fold the phase 1 result back into the plan
  • plan credential exchange on iOS, with the wire-format probe
  • record the versions carrying the pairing fix
  • release notes for 1.4.3
  • add CONTRIBUTING.md with the contribution requirements
  • add Matrix chat badge
  • rewrite the 1.4.2 store copy and re-translate
  • record the mobile hardening for issue #27
  • note the AutoFill unlock fix in the release notes
  • trim the release notes to what's actually new
  • note the one-time-code AutoFill in the release notes
  • retarget recipe to 0.9.1, enable reproducible builds
  • add device-sync (P2P mesh) section to the support page
  • privacy reflects backups + passkeys; clean /support + /privacy
  • release notes for multi-vault + device sync since 1.2.0
  • record the no-registry migration convergence guard
  • refresh the gallery, add six new shots
  • device-verification status (2026-07-18)
  • record the phase-1 ship date + a phase-2 flip checklist
  • reconcile status after biometric/autofill/join/restore work
  • correct the stale perVaultSync comment (mobile now targets the active vault)
  • mobile Tier 1 core landed (active-vault + per-vault sync)
  • Firefox multi-vault is done, not pending (survey + user testing)
  • add mobile multi-vault Tier 1 to the backlog
  • record the setup-shell UX (create/restore/join tabs)
  • record host-side enrolled-roster fix for Firefox inviter
  • Settings join removed (follow-up done)
  • mark join-from-setup landed; note the Settings-join follow-up
  • mark per-vault VEK landed; call out join=add-a-vault as the next gap
  • per-vault VEK design (supersedes single-VEK + primary vault)
  • record the sync-panel stopgap ahead of increment 3
  • note picker cards + context-aware setup screen
  • mark multiple-vaults phase 1 complete (create + picker + management)
  • mark multiple-vaults phase 1 create + picker landed
  • mark multiple-vaults phase 0 complete; clarify migration staging vs release cadence
  • plan for multiple vaults
  • add Bitcoin donations (Lightning + on-chain), 3-col table
  • cloud backups shipped (Dropbox + S3 + WebDAV)
  • record the MEGA + Proton Drive evaluations (both deferred)
  • Dropbox OAuth verified on Chromium + Firefox
  • refresh roadmap to cloud backups + multiple vaults
  • record the built revocation/admission state + this session's decisions
  • add admin-authority (server-free) re-admit variant to revocation note
  • mark B2 pending Android device testing; flag IronFox/Vanadium
  • note the CRYPTO_* router path A3 gate found during implementation
  • add sec-audit-7726 recheck+fix plan with execution risks
  • design note for roster signing and group-key rotation
  • add iOS App Store link
  • tighten the cloud-like convenience bullet to match the others
  • add cloud-storage-backups design note
  • backups section and cloud-manager updates
  • add a Screenshots section (thumbnail grid)
  • add app screenshots
  • add Chrome Web Store listing copy (en + translations)
  • rename kdbx-import.md -> encrypted-import.md; add Bitwarden section
  • correct the durability note
  • add the encrypted-export feature to the Firefox listing
  • reflect chrome.storage.local backend; drop false claims
  • reflect the chrome.storage.local vault backend (FSA retired)
  • correct conflict-loser section to match code (loser dropped, history unbuilt)
  • Firefox ships listed on AMO (release-signing + firefox-port)
  • current state (passkey verified, i18n done); export/import is what's left
  • add Status section + specifics for passkey provider & security-key unlock
  • mark relay-forward hardening implemented (timeout, reaper, epoch room, padding)
  • decide relay-forward transport + privacy hardening
  • correct the WebRTC-in-event-page assumption (RTCPeerConnection absent in FF background)
  • fix Vivaldi typo; move file attachments + iframe/shadow-DOM autofill to shipped
  • broaden README to mobile + passkeys, add passkeys to iOS store metadata
  • correct passkey + P2P sync findings
  • Android provider built (assertion + registration), compile-verified
  • Android dep check — androidx.credentials is Play-Services-free
  • mark iOS provider device-verified (register + sign-in on webauthn.io)
  • document the seamless-create refinements (foreground drain + immediate-use bridge)
  • mark iOS provider built (assertion + registration + handoff)
  • record the device-verified registration-response field set
  • spec item edit (passkey row below TOTP + remove) and view badge
  • update phased route with shipped status
  • plan passkey-provider role across extension + mobile
  • native iOS WebRTC sync, ipa slimming, Android autofill done
  • mark TURN, configurable relays, and device management as built
  • update privacy policy for iOS app + P2P sync
  • add Bramble support page + set App Store privacy/support URLs
  • record build 204423099 (iOS autofill filtering + QuickType opt-in)
  • iOS autofill working on device; refresh status + next steps
  • refresh 'Next steps' handoff after autofill confirmation
  • autofill confirmed end-to-end on real hardware (TestFlight)
  • autofill probe confirmed on real device (OS discovers the provider)
  • iOS Lockdown Mode disables JIT -> WASM crypto fails on device
  • add a consolidated 'Next steps (where to resume)' section
  • record iOS verification, security-key hiding, mobile test harness
  • record biometric unlock (OS-gated) in port plan + dev guide
  • bring mobile-port.md up to date with what's built (status, plan markers, answered questions)
  • TODO for device management UI + revocation
  • add development guide + sim:reset script
  • add README with run instructions and live-reload gotcha
  • switch mobile-port plan from Tauri to Capacitor
  • add security policy and point README to it
  • note Firefox storage.local durability (unlimitedStorage, uninstall, eviction)
  • add P2P device-to-device vault sync design
  • add Firefox-port feasibility findings
  • disclose the optional HIBP breach check; tighten wording
  • collapse to a single unstyled privacy-policy page
  • add static site to host the Web Store privacy policy
  • add design docs and function docblocks
  • PLAN — multi-URL logins and the legacy-url normalizer

Other

  • build(android): build releases on macOS, drop the F-Droid container
  • build(desktop): build universal everywhere, not just for a release
  • test(desktop): give the desktop tests room for the first import
  • build(desktop): release universal by default
  • test(desktop): make the update smoke server usable in practice
  • build(desktop): skip notarization for the local update test build
  • build(desktop): cut releases with pnpm release desktop <version>
  • test(desktop): serve a fake update locally to exercise the update path
  • build(desktop): notarize with the App Store Connect key iOS already uses
  • build(desktop): unlock the updater key with the YubiKey, like every other release key
  • chore(i18n): translate the desktop strings and restore catalog ordering
  • chore(desktop): take the signing identity from .env.local
  • chore(desktop): add run:desktop, and sign build:desktop by default
  • test(desktop): cover the reconnect path, and add an extension stand-in
  • test(desktop): cover the storage layer, and make it testable
  • test(autofill): cover nesting, scrolling and COEP for the relayed picker
  • chore(deps): patch the nanoid zero-size loop advisory
  • chore(deps): patch the js-yaml omap CPU advisory
  • test(sync): bound flushUntil in real time so it survives a loaded machine
  • test(e2e): move the transport-race gate under e2e/extension
  • test(e2e): record four more login shapes, and make the recorder headed
  • chore(e2e): add --skip to the HAR recorder, and measure the size tradeoff
  • test(e2e): replay skanetrafiken from a HAR to verify capture on the real app
  • chore(deps): patch undici, brace-expansion, and fast-uri advisories
  • chore(git): ignore docs/private for pre-disclosure security notes
  • test(sync): stop one test paying the module-load cost for the whole file
  • test(export): cover the .bramble round trip end to end, and fix the id collision it found
  • build(release): let android signing be retried without rebuilding
  • test(e2e): import the kdbx round-trip into a second vault
  • style(sync): cut the comment blobs down to one-liners
  • test(extension): pin the duplicated html escaper against its original
  • test: share the vault mount harness and the chrome storage-area fake
  • test(fixtures): a Bitwarden export with passkeys, for manual import testing
  • Revert "chore(ios): temporary diagnostics for the passkey bundle handoff"
  • chore: delete dead code found in a repo-wide sweep
  • chore(ios): read the provider diagnostic on-device, no Mac needed
  • chore(ios): temporary diagnostics for the passkey bundle handoff
  • test(autofill): cover the picker's iframe renderer end to end
  • chore: remove Codeberg links from the website and About screen
  • ci: run the extension e2e suite, opt-in per PR via an e2e label
  • test(android): pair the extension with the shipped app on a real device
  • test(sync): assert the joiner can read the inviter's data, not just pair
  • test(sync): pair the extension and the mobile app over a real relay
  • test(android): drive the shipped app on-device over CDP via adb
  • test(mobile): integration-test the issue #27 corruption with real crypto
  • test(e2e): cover KDBX export through the real extension
  • test(import): flesh out the CSV import fixtures
  • chore(website): drop dead parentHandler state from the Starwind Tabs handler
  • i18n(extension): translate the suggestion strings, fix + gate the tooling
  • chore(fdroid): install rustup from Debian apt (maintainer request)
  • chore(fdroid): AuthorName flythenimbus
  • chore(fdroid): retarget recipe to 0.9.5
  • chore(fdroid): retarget recipe to 0.9.4 (commit as full hash)
  • build(fdroid): reproducible Android build container matching F-Droid
  • chore(fdroid): retarget recipe to 0.9.3
  • chore(fdroid): retarget recipe to 0.9.2
  • chore(ios): point App Store privacy/support URLs at bramble.sh
  • ci(website): deploy to Cloudflare Pages via wrangler + API token
  • ci(website): deploy to Cloudflare Pages instead of GitHub Actions
  • chore(scripts): dev runs chrome + firefox + website together
  • chore(docs): new fable security audit
  • chore(website): add CNAME for the bramble.sh custom domain
  • test(e2e): picker refreshes after unlock without refocusing (#20)
  • test(e2e): guard lock-pref persistence across a browser restart
  • test(vaults): pin the createVault sync-reset guard; retire the stale "still open" note
  • test(e2e): end-to-end namespacing-migration test; fix stale registry after lazy migration
  • chore(ext): add a Firefox dev watch (dev:firefox)
  • a11y(ui): raise the vault-name contrast to text-foreground/70
  • test(e2e): per-vault sync isolation (tier 2, increment 4)
  • test(e2e): create + lock + unlock vault flow (tier 2, increment 3)
  • test(e2e): playwright setup + extension loading (tier 2, increments 1-2)
  • test(vault): per-vault sync unit coverage (tier 0)
  • docs+feat(sync): phase 2 design + per-vault sync-key helper
  • chore(i18n): vault-name + delete-reauth strings
  • chore(i18n): current-vault settings strings
  • chore(i18n): 'Created on {0}' string
  • chore(i18n): extract + translate add-a-vault / picker strings
  • chore(i18n): extract + translate vault management strings
  • chore(i18n): translate vault picker strings (de, es, fr, it, pt-BR)
  • chore(i18n): extract + compile vault picker strings
  • chore(readme): remove status section
  • chore(ios): App Store release notes for this update
  • chore(i18n): translate "lock on screen lock" settings strings
  • build(chromium): pin the CWS public key for a stable unpacked ID
  • chore: local nextcloud compose for backup testing
  • ci(codeql): advanced setup so Swift gets scanned
  • chore(ios): update App Store release notes for the Face ID + P2P hardening update
  • chore(mobile): link @capacitor/share into the native projects (cap sync)
  • chore(i18n): translate the 3 device-authorization strings (de/es/fr/it/pt-BR)
  • test(sync): grow screenshot seed to 1100 items for large-vault repro
  • chore(ios): bump marketing version to 1.1.0
  • chore(scripts): per-platform mobile version bump (bump:ios / bump:android)
  • style(sync): move signOwnEntry helper below the import block
  • ci: name the job 'CI' so branch protection can require it
  • test: cover the legacy FSA->local migration and vault export
  • i18n(store): Firefox listing translations (de hand-polished, es/fr/it/pt-BR first pass)
  • i18n: translate the content-script UI via _locales + browser.i18n
  • i18n: translate the 12 missing vault-list strings (de/es/fr/it/pt-BR)
  • polish(ext): explain what unlocking is for on the locked passkey card
  • polish(ext): passkey rows act on click; chevron instead of checkmark
  • polish(ext): passkey card — Bramble glyph, account list, gradient bg
  • polish(ext): passkey corner card gets a key-glyph badge in the header
  • chore: reconcile pnpm-lock after rebase onto main
  • build(release): firefox bundle + AMO-signed .xpi release pipeline
  • harden(sync): epoch-rotating sync room so the relay can't link a group across time
  • harden(sync): reap stale relay peers (liveness for the connectionless transport)
  • harden(sync): relay-forward handshake timeout + payload size padding
  • chore(ext): remove throwaway FF WebRTC-context probes + sync-frame iframe
  • chore(ext): probe content-script + page-main-world WebRTC contexts (Firefox)
  • chore(ext): surface an RTCPeerConnection probe in the Device-sync panel (Firefox diag)
  • build(ext): output Chromium build to dist-chromium (symmetry with dist-firefox)
  • chore(ext): rename build/bundle -> build:chromium/bundle:chromium
  • build(ext): Firefox manifest + TARGET build wiring (Firefox port, phase 3)
  • chore(ios): make app iPhone-only (drops 13-inch iPad screenshot requirement)
  • chore(ios/metadata): add 7th App Store screenshot, reorder to sequence
  • i18n(extension): localize manifest description + lock command via Chrome _locales
  • chore(i18n): translate passkey strings (web catalogs + iOS String Catalog)
  • test(extension): cover the passkey ceremony flow (incl. the account picker)
  • i18n(passkeys): extract + compile the passkey provider setting strings
  • chore(ios): add App Store screenshots (en-US, 6.5")
  • test(core-rust): serialize the global-VEK-slot round-trip tests
  • build(ios): drop webrtc from the autofill extension binary
  • chore(settings): hide debug sync status log
  • chore(mobile): set App Store category to Productivity / Utilities
  • chore(mobile): manage App Review info in ASC, not fastlane
  • chore(mobile): optimize App Store subtitle + keywords (no title overlap)
  • chore(mobile): scaffold App Store Connect metadata (en-US) + deliver lane
  • chore: update .gitignore to ignore app bundles
  • chore(mobile): commit shared Xcode schemes, gitignore android .idea
  • chore(mobile): fastlane lanes for iOS TestFlight + IPA builds
  • chore(mobile): declare ITSAppUsesNonExemptEncryption=false
  • test: stand up mobile test harness + cover biometric paths
  • style(mobile): inset setup pills from edges + black active border
  • style(mobile): full-width, larger Create vault button
  • style(mobile): wider pill gap + thicker active border on setup tabs
  • chore(mobile): auto-target newest iPhone sim for cap run (skip picker)
  • chore(mobile): make dev:* the live-reload scripts, bundled run under run:*
  • chore(mobile): rename mobile:build script to core:build
  • chore(mobile): add live-reload dev scripts
  • build(mobile): commit generated iOS + Android native projects
  • test: migrate DOM test environment from happy-dom to jsdom
  • build(deps): bump esbuild, ws, wrangler for security advisories
  • ci: set least-privilege GITHUB_TOKEN permissions
  • chore(lint): migrate biome config to 2.5.0 and apply safe fixes
  • build: block commits/releases on type errors (pre-commit + release gate)
  • chore(build): migrate from bun to node/pnpm
  • chore(dev): local/CI lint parity hook + bump to Node 24 LTS
  • add web store link
  • chore(fixtures): repassword kdbx imports to 123456, add keyfile variant, fix key-file label spacing
  • chore: add tag:delete script to remove a tag locally and from all remotes
  • chore(biome): exclude import fixtures folder
  • test(fixtures): add sample import files for every supported provider
  • release: set extension version to 1.0 for the initial Web Store submission
  • build(ext): add 'bundle' script (build + zip dist to bramble.zip)
  • ci: deploy only website/ to GitHub Pages via Actions
  • style(manifest): biome-format permissions array (one line after activeTab drop)
  • chore(manifest): drop redundant activeTab, add use_dynamic_url to WAR
  • test(crypto): add an ignored benchmark for the vault Argon2id cost
  • test(bg): move the chrome-mock harness to src/test/
  • test(bg): add handler unit tests for the background modules (73 tests)
  • update readme
  • ci: exclude vendored icon/ export from biome
  • add monero qr code image
  • style: biome format fixes for ci
  • recovery codes, optional master password, and settings cleanup
  • test: extract detection helpers, add 10 real-world site fixtures, fix bmo card-vs-login bug
  • ci: pin wasm-pack version and cache cargo deps between runs
  • ci: pin Rust to rust-toolchain.toml and add a WASM verify gate
  • brand: rename app to Bramble
  • chore: centralize the user-facing brand on the manifest, swap Vault→Titanpass
  • ui: show real extension version in Settings (was hardcoded 0.0.1)
  • security: make HIBP breach check opt-in, with a clearer disclosure (L6)
  • security: stop persisting the decrypted autofill index (M2)
  • security: gate every autofill on user focus, never on page load (M1)
  • chore: prune unused shadcn/Radix UI scaffold and supporting deps (M6b)
  • data-integrity: snapshot-and-recover writes + verify-after-rotate (H1, H2)
  • security: quick-wins audit batch (M3, M4, M5, M6a, L2, L3, L4, L5, L7)
  • move to multi-key vault slots, full rotation on password change
  • wire settings, clipboard auto-clear, hibp checks, per-entry overrides
  • add crud elements and manage window size
  • update plan
  • implement autofill in website fields
  • implement vault crypto, vault creation and loading
  • set up fe arch: screens, router, rhf
  • wire up ui
  • initial commit

Don't miss a new bramble release

NewReleases is sending notifications on new releases.