···7788## [Unreleased]
991010+### Added
1111+- Shared modal dialog helper (`src/lib/modal-dialog.ts`): promise-based `modalPrompt()` and `modalConfirm()` replace blocking `window.prompt()`/`window.confirm()`. Native builtins freeze the main thread, stalling Yjs awareness, streaming AI chats, and scheduled timers — the new modals keep the event loop running, respect theme/dark-mode, and support a `destructive` variant for dangerous actions (18 tests). (#109)
1212+1313+### Changed
1414+- Replaced 12 blocking `prompt()`/`confirm()` call sites with the new modal helpers: trash permanent-delete and empty-trash, version-panel name-and-restore, calendar event delete, sheets sheet-delete, landing folder delete, landing identity (Tailscale signed-in, change display name), docs toolbar (insert link, insert image, add comment), and the Forge Note button (#681).
1515+1616+### Removed
1717+- 9 orphaned context-menu builder helpers (`buildDocsTextItems`, `buildDocsLinkItems`, `buildDocsImageItems`, `buildDocsTableItems`, `buildSheetsCellItems`, `buildSheetsColumnHeaderItems`, `buildSheetsRowHeaderItems`, `buildSheetsContextItems`, plus the `SheetsContextTarget` type): returned menu arrays with 45 no-op `() => {}` handlers and were only referenced by tests — never wired into a real editor. (#109)
1818+1019## [0.49.0] — 2026-04-16
11201221### Added
+9-2
src/calendar/main.ts
···14611461 syncRemindersWithServer().catch(() => {});
14621462}
1463146314641464-function deleteEvent(): void {
14641464+async function deleteEvent(): Promise<void> {
14651465 if (!editingEventId) return;
14661466- if (!confirm('Delete this event?')) return;
14661466+ const { modalConfirm } = await import('../lib/modal-dialog.js');
14671467+ const ok = await modalConfirm({
14681468+ title: 'Delete event?',
14691469+ message: 'This event will be removed from the calendar.',
14701470+ okLabel: 'Delete',
14711471+ destructive: true,
14721472+ });
14731473+ if (!ok) return;
14671474 deleteEventFromYjs(editingEventId);
14681475 closeModal();
14691476}