- GroupFilterViewModel now tracks lastToggledGroupId (the single group
most recently toggled to a non-empty selection), since toggling a
group with subgroups expands selectedGroupIds to include the whole
subtree, breaking the previous count==1 check used to infer the
active filter group.
- VaultViewModel exposes lastToggledGroupId, forwarded from
GroupFilterViewModel by VaultRootView (ContentView.swift), and
EntryListView.defaultGroupId now reads it instead of the broken
selectedGroupIds.count == 1 check, so the add-entry sheet defaults
new entries into the group actually being filtered by, not silently
back to root.
- EntryListView's search toggle button now clears vm.searchQuery when
hiding the search bar, so a hidden bar can no longer keep filtering
the list invisibly.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf
Replaces group-drilling navigation with a flat, filterable/searchable
entry list backed by VaultViewModel.displayedEntries. SearchView's
role is fully absorbed by EntryListView's .searchable() modifier.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf
Adds an eye-icon toggle to the master password field (UnlockView) so
users can verify what they typed before submitting.
Also maps KDBX4's ERROR_HEADER_HASH_VERIFICATION_FAILED -- surfaced
via the header HMAC check, which is password-derived -- to
KDBXError.invalidPassword alongside the existing
passwordAndOrKeyfileWrong check. KeePassKit uses this same error code
for both a wrong password/keyfile and genuine file corruption (it
doesn't distinguish the two), so the message hedges: "Incorrect
password, or this vault file is corrupted." Found while testing
against a real KDBX4 vault, which was surfacing this as a raw,
unreadable NSError string before the previous commit's LocalizedError
fix, and as *no* friendly message at all before this one (the error
code wasn't in the recognized set yet).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf
Completes Phase 4 (Task 17) -- ContentView now routes between UnlockView
and the vault UI (NavigationStack on iOS, 3-column NavigationSplitView on
macOS) instead of the leftover SwiftData template, finally resolving the
long-standing "cannot find type Item" build break. Vault locks on
scene-background (iOS) / resign-active (macOS).
Fixes two more real bugs surfaced now that everything actually links
together: EntryEditViewModel.save's dismiss closure needed @escaping
(used inside Task {}), and UnlockView's UTType(filenameExtension:)
needed `import UniformTypeIdentifiers`.
Also restores MyPass.entitlements, which had regressed to an empty
App Group array with Keychain Sharing missing entirely since the
"wire up AutoFill extension target" commit -- likely clobbered by
Xcode reconciling capabilities at some point without a rebuild in
between to catch it. Verified clean `xcodebuild` on both iOS Simulator
and macOS destinations, and `swift test` still passes all 18 tests.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf
Also fixes real bugs found while making Phase 4 build clean on both
platforms:
- FileBookmarkService used .withSecurityScope unconditionally, but
that bookmark option is macOS-only -- iOS grants scoped access
automatically once the user picks a file. Now conditional per platform.
- EntryEditViewModel's groupId was non-optional with no default, but
EntryDetailView's edit-sheet call site (Task 14) has no group
reference to pass -- only the "add new entry" path actually needs
it, so groupId is now optional and validated at save time instead.
- Missing `import Combine` in EntryDetailView (Timer.publish/autoconnect)
and UnlockViewModel/VaultViewModel/EntryEditViewModel (@Published).
- GroupBrowserView's `group: Group` property collided with SwiftUI's
own Group view type -- qualified as MyPassCore.Group.
- EntryEditView's .keyboardType(.URL) and .navigationBarTitleDisplayMode
are iOS-only APIs, guarded with #if os(iOS) for the macOS build.
Verified clean (aside from the known, expected ContentView.swift/Item
breakage) on both iOS Simulator and macOS destinations.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf