UNPKG

omnifocus-mcp

Version:

Model Context Protocol (MCP) server that integrates with OmniFocus for AI assistant interaction

78 lines (77 loc) 3.36 kB
/** * Version 2 of date formatting utilities that work around AppleScript restrictions * Dates must be constructed outside of tell blocks */ /** * Generate AppleScript to construct a date variable outside tell blocks * @param isoDateString - ISO format date string * @param varName - Name for the date variable * @returns AppleScript code to construct the date */ export function createDateOutsideTellBlock(isoDateString, varName) { // Date-only strings (YYYY-MM-DD) are interpreted as UTC by new Date(), // which shifts the calendar day in timezones behind UTC. Append T00:00:00 // to force local-time interpretation so "2026-04-10" means April 10th local. const normalized = /^\d{4}-\d{2}-\d{2}$/.test(isoDateString) ? isoDateString + 'T00:00:00' : isoDateString; const date = new Date(normalized); // Check if the date is valid if (isNaN(date.getTime())) { throw new Error(`Invalid date string: ${isoDateString}`); } // Extract date components (always local time after normalization) const year = date.getFullYear(); const month = date.getMonth() + 1; // JavaScript months are 0-indexed const day = date.getDate(); const hours = date.getHours(); const minutes = date.getMinutes(); const seconds = date.getSeconds(); // Generate AppleScript to construct date outside tell blocks. // // `set day to 1` FIRST is load-bearing, not tidiness (issue #91). This scaffolds // off `current date`, so the intermediate date carries *today's* day-of-month. // Setting the month while that day is out of range for the target month makes // AppleScript roll the date forward, and the later `set day` cannot undo it: // // today = Jul 31, target = Nov 1 // set month to 11 -> Nov 31 is invalid -> rolls to Dec 1 // set day to 1 -> already 1, no-op -> stays Dec 1 (a month late) // // Normalizing the day to 1 up front makes every intermediate valid in every // month, so year/month/day can then be set without rollover. This silently // corrupted any date written on the 29th-31st toward a shorter month. return `copy current date to ${varName} set day of ${varName} to 1 set year of ${varName} to ${year} set month of ${varName} to ${month} set day of ${varName} to ${day} set hours of ${varName} to ${hours} set minutes of ${varName} to ${minutes} set seconds of ${varName} to ${seconds}`; } /** * Generate date assignment that works with AppleScript restrictions */ export function generateDateAssignmentV2(objectName, propertyName, isoDateString) { if (isoDateString === undefined) { return null; // No date change requested } if (isoDateString === '') { // Clear the date return { preScript: '', assignmentScript: `set ${propertyName} of ${objectName} to missing value` }; } // Generate unique variable name const varName = `dateVar${Math.random().toString(36).substr(2, 9)}`; // Generate the date construction (outside tell blocks) const preScript = createDateOutsideTellBlock(isoDateString, varName); // Generate the assignment (inside tell blocks) const assignmentScript = `set ${propertyName} of ${objectName} to ${varName}`; return { preScript, assignmentScript }; }