cursor: replace stale-form hooks on wrapper migration
Commit
Self-review of the Windows fix found that cursor.InstallHooks appended a hook only when the exact command was absent, removing existing Entire hooks only under --force. Once the sh↔cmd.exe wrapper form can change between installs (the new UseWindowsProductionHooks behavior), a non-force reinstall after a probe-result flip left the stale sh-wrapped entry in place AND added the cmd.exe one — a dead duplicate that could double-fire (duplicate session-start/stop → duplicate checkpoints) if sh later worked at hook runtime.
Add syncEntireHook (mirroring codex's syncHookCommand): if the desired command is already present it's a no-op; otherwise any existing Entire hook of that type — in any wrapper form — is removed before appending, so a changed wrapper cleanly replaces the stale one without --force. Non-Entire entries are preserved. Add a migration regression test asserting no sh-based wrapper survives an sh→cmd.exe reinstall.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com Entire-Checkpoint: 01KXDHJ1CEY1DF00642NVQESRP