Records why disabling "Clear the field before typing" still leaves the
password replaced: Tab selects the target field's content, so the keystrokes
overwrite it. Our code clears nothing — verified from the JS clear=0 through
both ClearFieldIfWanted guards. The toggle exists to avoid sending Ctrl+A
(terminals, remote desktops), not to preserve field content.
Filed as intentional so it isn't "fixed" later into appending a new password
onto the old one.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Section J fully green: no double minimise on the fill path, the clipboard
survives the copy path, and an app already on screen is not sent to the tray.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
J1 covers both bugs just fixed (lost keyboard focus after the tray restore,
and the coalesced cmd:// that swallowed the minimise). J2/J3 check the fill and
copy paths still return to the tray exactly once, J4 that an app which was
already on screen is not sent to the tray.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
I5 exercises the path the guard fix addresses (autofill minimises, then the
window is hidden to the tray, so MINIMIZEEND may never arrive). I6 is the
non-regression check on the tray and focus paths the hook could have touched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
I1/I2 validated (both directions survive Show desktop), plus the tray path and
how to read the [winstate] diagnostics.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Covers the swallowed-combo detection, the abandoned-capture timeout, and the
internal collision check that only works now that the capture releases our
own hotkeys.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every toast auto-dismissed after 2.8 s — fine for a success receipt, too
short to read AND act on an error. Errors and warnings now stay 10 s and can
be clicked away; success is unchanged.
The hotkey-conflict warning also needed a trace outside the toast: the ⚠ in
Settings only helps someone who opens the panel. A dot on the sidebar Settings
entry (plus a tooltip) is now the cue in the main UI that a combo is dead.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Also records the test pitfall: hook-based apps swallow the key without
failing RegisterHotKey, so they produce a dead hotkey with no marker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two gaps when Windows refuses a RegisterHotKey:
- the toast said "one or both hotkeys" — wrong since there are three autofill
combos, and it never said which one lost.
- Quick search and New entry failures were only written to the debug panel,
which is off in production: the hotkey silently did nothing with no clue why.
Delphi now exposes the per-slot registration outcome and the host accumulates
the failed combo names across all five hotkeys, emitting one notification for
the batch. A combo the user deliberately cleared (vk=0) is never listed.
JS names them: "Already used by another app: 2FA code — pick another combo in
Settings".
Registration stays best-effort per slot: one clash doesn't disarm the others.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
G1 (cancelled switch must not act on the still-open entry), G2 (Fix on an
entry deleted meanwhile), G3 (dashboard reflects import/sync/delete without
a manual Recompute).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
B14 (native dialogs must not stack a discard prompt) and a new section F
covering the export/import round-trip: favorite + pinned restored, foreign
CSV defaults, sync staying device-local, custom-icon provenance.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A pinned entry came back unpinned after export→import. Wider than pinned:
`favorite` was WRITTEN into the export/backup/sync containers but nothing
ever read it back — not parseEntriesFromJSON, not encryptImportEntry, not
the server INSERTs. So it was a write-only field, and a restore silently
dropped both flags. `pinned` wasn't in any container at all.
Wired the full round-trip:
- containers: export + auto-backup now carry `pinned` (favorite was there).
- parseEntriesFromJSON reads both back (absent → 0, e.g. foreign CSV).
- encryptImportEntry passes them through to the body.
- server create + bulk-import INSERTs write favorite/pinned
(GetValue<Boolean>(..., False) → 0 default). PUT still ignores them, so a
sync update can't clobber local flags.
Sync stays device-local as decided 2026-07-11: buildSyncSnapshot now OMITS
favorite explicitly (it was dead weight before; with the passthrough live,
leaving it in would have started propagating it). Commented so the intent
isn't re-broken.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Section E (E1-E7) covers the fixes that had none: reauth inline retry,
recovery setup + redeem on argon2id-v2, recovery commit-after-save, the
sessionStorage key removal, and a slideover regression guard after deleting
the dead entry modal. Dropped the now-done "legacy entry modal" item from the
remaining list.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A10b (editor icon preview), B11 (Esc closes the top modal, not the editor,
across all 11 modals), B12 (a static modal survives its Esc), B13 (toast /
busy-overlay clicks).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three static modals had no entry in the fallback Esc handler, so Esc over
them fell through and closed the editor behind (or did nothing when no
editor was open — reauth and the autofill picker could only be dismissed by
mouse).
Also scopes the stray-modal catch added in a95becd to [data-dynamic]. As
written it matched ANY open .modal, so an Esc over reauth / quick-search /
the autofill picker would have removed those static nodes from the DOM for
good, breaking the feature until restart. Only the runtime-built folder
modal carries the marker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The folder modal is built dynamically with no id in the fallback Esc
handler's modal list, so Esc fell straight through to the slideover close
and shut the editor behind it. The capture handler already bails on any
open .modal; mirror that in the fallback by closing a stray .modal before
reaching the slideover branch. Covers every dynamically-built modal, not
just this one.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Selecting an entry inserted the batch bar as a block above the grid, pushing
every row down ~60px — the list jumped under the cursor mid-click. The bar
now renders inside .content-header, to the right of "All items", and the
header reserves its height (min-height) so appearing and disappearing shifts
nothing at all.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Covers the four classes found this session (stale editor payload, editor
dismissed without the discard gate, missing withEncryptedMeta, view-blind
UI) with the surrounding cases, not just the ones reported.
Also fixes one more instance found while auditing: deleting a folder
reassigns its entries to All server-side, but an editor open on one of them
kept pointing at the deleted folder and re-created it on Save.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>