/** * Local calendar integration service. * * macOS: uses `osascript` (AppleScript) for calendar operations * - Triggers the native OS permission dialog automatically on first use * - Shows a native confirmation dialog before adding any event * * Linux: generates a temporary .ics file and opens it with `xdg-open` * - Universal — works with GNOME Calendar, KDE Organizer, Thunderbird, etc. * - No confirmation dialog (xdg-open hands off to the desktop app) */ export interface SavedAttachment { filename: string; localPath: string; fileUrl: string; mimeType: string; size: number; } export interface LocalCalendarEventInput { title: string; start: Date; end: Date; location?: string; /** Pre-built rich notes string (from buildCalendarNotes). */ notes?: string; /** Primary meeting URL (Zoom/Teams/Meet etc). */ url?: string; /** Label for the meeting URL provider, e.g. "Zoom". */ urlLabel?: string; /** Minutes before event to show an alert (default: 15). */ alarmMinutes?: number; allDay?: boolean; attendeeCount?: number; /** Already-saved attachment list (for dialog count display). */ savedAttachments?: SavedAttachment[]; /** Pending (not-yet-saved) attachment metadata for dialog display. */ pendingAttachments?: { filename: string; mimeType: string; size: number; }[]; dialIn?: string; meetingId?: string; passcode?: string; conferenceProvider?: string; /** ICS UID for duplicate detection */ icsUid?: string; } export type AddEventStatus = 'added' | 'cancelled' | 'timed_out' | 'no_display' | 'duplicate'; export interface AddEventResult { status: AddEventStatus; eventId?: string; calendarName?: string; message: string; /** Populated when status is 'duplicate' */ duplicate?: { eventId: string; calendarName: string; }; } export interface ExistingEventResult { found: boolean; eventId?: string; calendarName?: string; start?: string; } export interface CalendarInfo { id: string; name: string; } export interface CalendarEventSummary { id: string; title: string; start: string; end: string; location?: string; calendar: string; } export interface ListEventsOptions { /** Filter events whose title contains this substring (case-insensitive). */ title?: string; /** Only return events on or after this date (ISO 8601). */ from?: string; /** Only return events on or before this date (ISO 8601). */ to?: string; /** Restrict to a specific calendar by name. */ calendarName?: string; /** Maximum number of results (default 20). */ limit?: number; } export interface PermissionResult { granted: boolean; platform: string; instructions: string[]; } /** @internal Exported for testing. */ export declare function escapeAS(s: string): string; /** * Emit AppleScript lines that set an existing date variable to a specific * point in time by assigning each component (year, month, day, hours, minutes, * seconds) individually. * * Uses the JS Date's **local-time** getters so the resulting AppleScript date * matches the system timezone — the same timezone Calendar.app operates in. * * This replaces the previous approach of converting to Unix epoch via * `date -j … '+%s'` and coercing `(number) as date`, which fails on macOS * because AppleScript cannot coerce large integers to dates (error -1700). * * @internal Exported for testing. */ export declare function dateToAppleScriptLines(varName: string, d: Date): string[]; export default class LocalCalendarService { private readonly platform; checkPermissions(): Promise; listCalendars(): Promise; /** Check all calendars for an existing event matching by ICS UID or title+startDate. */ findExistingEvent(title: string, start: Date, icsUid?: string): Promise; addEvent(event: LocalCalendarEventInput, calendarName?: string, opts?: { confirm?: boolean; skipDuplicateCheck?: boolean; }): Promise; /** List calendar events matching the given filters. */ listEvents(opts?: ListEventsOptions): Promise; } //# sourceMappingURL=local-calendar.service.d.ts.map