@shin1ohno/sage 0.2.4 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/http-server-with-config.d.ts +38 -0
- package/dist/cli/http-server-with-config.d.ts.map +1 -0
- package/dist/cli/http-server-with-config.js +458 -0
- package/dist/cli/http-server-with-config.js.map +1 -0
- package/dist/cli/http-server.d.ts +74 -0
- package/dist/cli/http-server.d.ts.map +1 -0
- package/dist/cli/http-server.js +407 -0
- package/dist/cli/http-server.js.map +1 -0
- package/dist/cli/jwt-middleware.d.ts +36 -0
- package/dist/cli/jwt-middleware.d.ts.map +1 -0
- package/dist/cli/jwt-middleware.js +99 -0
- package/dist/cli/jwt-middleware.js.map +1 -0
- package/dist/cli/main-entry.d.ts +41 -0
- package/dist/cli/main-entry.d.ts.map +1 -0
- package/dist/cli/main-entry.js +80 -0
- package/dist/cli/main-entry.js.map +1 -0
- package/dist/cli/mcp-handler.d.ts +56 -0
- package/dist/cli/mcp-handler.d.ts.map +1 -0
- package/dist/cli/mcp-handler.js +2189 -0
- package/dist/cli/mcp-handler.js.map +1 -0
- package/dist/cli/parser.d.ts +43 -0
- package/dist/cli/parser.d.ts.map +1 -0
- package/dist/cli/parser.js +162 -0
- package/dist/cli/parser.js.map +1 -0
- package/dist/cli/remote-config-loader.d.ts +85 -0
- package/dist/cli/remote-config-loader.d.ts.map +1 -0
- package/dist/cli/remote-config-loader.js +129 -0
- package/dist/cli/remote-config-loader.js.map +1 -0
- package/dist/cli/secret-auth.d.ts +47 -0
- package/dist/cli/secret-auth.d.ts.map +1 -0
- package/dist/cli/secret-auth.js +165 -0
- package/dist/cli/secret-auth.js.map +1 -0
- package/dist/cli/sse-stream-handler.d.ts +45 -0
- package/dist/cli/sse-stream-handler.d.ts.map +1 -0
- package/dist/cli/sse-stream-handler.js +125 -0
- package/dist/cli/sse-stream-handler.js.map +1 -0
- package/dist/index.js +885 -209
- package/dist/index.js.map +1 -1
- package/dist/integrations/calendar-event-creator.d.ts +152 -0
- package/dist/integrations/calendar-event-creator.d.ts.map +1 -0
- package/dist/integrations/calendar-event-creator.js +507 -0
- package/dist/integrations/calendar-event-creator.js.map +1 -0
- package/dist/integrations/calendar-event-deleter.d.ts +137 -0
- package/dist/integrations/calendar-event-deleter.d.ts.map +1 -0
- package/dist/integrations/calendar-event-deleter.js +378 -0
- package/dist/integrations/calendar-event-deleter.js.map +1 -0
- package/dist/integrations/calendar-event-response.d.ts +213 -0
- package/dist/integrations/calendar-event-response.d.ts.map +1 -0
- package/dist/integrations/calendar-event-response.js +560 -0
- package/dist/integrations/calendar-event-response.js.map +1 -0
- package/dist/integrations/calendar-service.d.ts +85 -10
- package/dist/integrations/calendar-service.d.ts.map +1 -1
- package/dist/integrations/calendar-service.js +317 -35
- package/dist/integrations/calendar-service.js.map +1 -1
- package/dist/oauth/client-store.d.ts +36 -0
- package/dist/oauth/client-store.d.ts.map +1 -0
- package/dist/oauth/client-store.js +104 -0
- package/dist/oauth/client-store.js.map +1 -0
- package/dist/oauth/code-store.d.ts +48 -0
- package/dist/oauth/code-store.d.ts.map +1 -0
- package/dist/oauth/code-store.js +89 -0
- package/dist/oauth/code-store.js.map +1 -0
- package/dist/oauth/index.d.ts +13 -0
- package/dist/oauth/index.d.ts.map +1 -0
- package/dist/oauth/index.js +21 -0
- package/dist/oauth/index.js.map +1 -0
- package/dist/oauth/oauth-handler.d.ts +101 -0
- package/dist/oauth/oauth-handler.d.ts.map +1 -0
- package/dist/oauth/oauth-handler.js +577 -0
- package/dist/oauth/oauth-handler.js.map +1 -0
- package/dist/oauth/oauth-server.d.ts +165 -0
- package/dist/oauth/oauth-server.d.ts.map +1 -0
- package/dist/oauth/oauth-server.js +489 -0
- package/dist/oauth/oauth-server.js.map +1 -0
- package/dist/oauth/pkce.d.ts +48 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/pkce.js +106 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/oauth/refresh-token-store.d.ts +45 -0
- package/dist/oauth/refresh-token-store.d.ts.map +1 -0
- package/dist/oauth/refresh-token-store.js +98 -0
- package/dist/oauth/refresh-token-store.js.map +1 -0
- package/dist/oauth/token-service.d.ts +46 -0
- package/dist/oauth/token-service.d.ts.map +1 -0
- package/dist/oauth/token-service.js +199 -0
- package/dist/oauth/token-service.js.map +1 -0
- package/dist/oauth/types.d.ts +264 -0
- package/dist/oauth/types.d.ts.map +1 -0
- package/dist/oauth/types.js +37 -0
- package/dist/oauth/types.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/manifest.json +12 -20
- package/package.json +1 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar Event Creator Service
|
|
3
|
+
* Handles creating calendar events via EventKit
|
|
4
|
+
* Requirements: 18.1-18.11
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Event creation with title, dates, location, notes
|
|
8
|
+
* - Custom calendar selection
|
|
9
|
+
* - Alarm configuration
|
|
10
|
+
* - All-day event detection
|
|
11
|
+
*/
|
|
12
|
+
import { retryWithBackoff, isRetryableError } from '../utils/retry.js';
|
|
13
|
+
/**
|
|
14
|
+
* Default retry options for calendar operations
|
|
15
|
+
*/
|
|
16
|
+
const RETRY_OPTIONS = {
|
|
17
|
+
maxAttempts: 3,
|
|
18
|
+
initialDelay: 500,
|
|
19
|
+
maxDelay: 5000,
|
|
20
|
+
shouldRetry: isRetryableError,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Parse alarm string to seconds offset
|
|
24
|
+
* Format: -[number][unit] where unit is m (minutes), h (hours), d (days), w (weeks)
|
|
25
|
+
* Requirement: 18.4
|
|
26
|
+
*
|
|
27
|
+
* @param alarmStr - Alarm string (e.g., "-15m", "-1h", "-1d")
|
|
28
|
+
* @returns Offset in seconds (negative) or null if invalid
|
|
29
|
+
*/
|
|
30
|
+
export function parseAlarmString(alarmStr) {
|
|
31
|
+
if (!alarmStr || typeof alarmStr !== 'string') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const match = alarmStr.match(/^-(\d+)([mhdw])$/);
|
|
35
|
+
if (!match) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const value = parseInt(match[1], 10);
|
|
39
|
+
const unit = match[2];
|
|
40
|
+
switch (unit) {
|
|
41
|
+
case 'm': // minutes
|
|
42
|
+
return -value * 60;
|
|
43
|
+
case 'h': // hours
|
|
44
|
+
return -value * 60 * 60;
|
|
45
|
+
case 'd': // days
|
|
46
|
+
return -value * 24 * 60 * 60;
|
|
47
|
+
case 'w': // weeks
|
|
48
|
+
return -value * 7 * 24 * 60 * 60;
|
|
49
|
+
default:
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Calendar Event Creator Service
|
|
55
|
+
* Creates calendar events via EventKit on macOS
|
|
56
|
+
*/
|
|
57
|
+
export class CalendarEventCreatorService {
|
|
58
|
+
runAppleScript = null;
|
|
59
|
+
/**
|
|
60
|
+
* Detect current platform
|
|
61
|
+
*/
|
|
62
|
+
async detectPlatform() {
|
|
63
|
+
if (typeof process !== 'undefined' && process.platform === 'darwin') {
|
|
64
|
+
return {
|
|
65
|
+
platform: 'macos',
|
|
66
|
+
hasEventKitAccess: true,
|
|
67
|
+
supportsEventCreation: true,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
platform: 'unknown',
|
|
72
|
+
hasEventKitAccess: false,
|
|
73
|
+
supportsEventCreation: false,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Check if EventKit is available for event creation
|
|
78
|
+
*/
|
|
79
|
+
async isEventKitAvailable() {
|
|
80
|
+
const platform = await this.detectPlatform();
|
|
81
|
+
return platform.hasEventKitAccess;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Create a calendar event
|
|
85
|
+
* Requirement: 18.1
|
|
86
|
+
*/
|
|
87
|
+
async createEvent(request) {
|
|
88
|
+
// Validate input
|
|
89
|
+
const validationError = this.validateRequest(request);
|
|
90
|
+
if (validationError) {
|
|
91
|
+
return {
|
|
92
|
+
success: false,
|
|
93
|
+
error: validationError,
|
|
94
|
+
message: 'イベントの作成に失敗しました',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
// Check platform availability
|
|
99
|
+
const isAvailable = await this.isEventKitAvailable();
|
|
100
|
+
if (!isAvailable) {
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
error: 'カレンダー統合がこのプラットフォームで利用できません。macOSで実行してください。',
|
|
104
|
+
message: 'イベントの作成に失敗しました',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Create event via EventKit
|
|
108
|
+
const result = await this.createEventViaEventKit(request);
|
|
109
|
+
if (result.success) {
|
|
110
|
+
result.message = this.generateSuccessMessage(result);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
error: `EventKitエラー: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
118
|
+
message: 'イベントの作成に失敗しました',
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Validate create event request
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
validateRequest(request) {
|
|
127
|
+
// Check title
|
|
128
|
+
if (!request.title || request.title.trim() === '') {
|
|
129
|
+
return '無効なタイトル: タイトルが空です';
|
|
130
|
+
}
|
|
131
|
+
// Check startDate format
|
|
132
|
+
if (!this.isValidDateTime(request.startDate)) {
|
|
133
|
+
return `無効な開始日時: ${request.startDate}。ISO 8601形式を使用してください。`;
|
|
134
|
+
}
|
|
135
|
+
// Check endDate format
|
|
136
|
+
if (!this.isValidDateTime(request.endDate)) {
|
|
137
|
+
return `無効な終了日時: ${request.endDate}。ISO 8601形式を使用してください。`;
|
|
138
|
+
}
|
|
139
|
+
// Check date range
|
|
140
|
+
const startDate = new Date(request.startDate);
|
|
141
|
+
const endDate = new Date(request.endDate);
|
|
142
|
+
if (endDate < startDate) {
|
|
143
|
+
return '終了日時は開始日時より後である必要があります。';
|
|
144
|
+
}
|
|
145
|
+
// Validate alarms if provided
|
|
146
|
+
if (request.alarms) {
|
|
147
|
+
for (const alarm of request.alarms) {
|
|
148
|
+
if (parseAlarmString(alarm) === null) {
|
|
149
|
+
return `無効なアラーム形式: ${alarm}。例: -15m, -1h, -1d`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if datetime string is valid
|
|
157
|
+
* @internal
|
|
158
|
+
*/
|
|
159
|
+
isValidDateTime(dateStr) {
|
|
160
|
+
if (!dateStr) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
const date = new Date(dateStr);
|
|
164
|
+
return !isNaN(date.getTime());
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Check if event is all-day based on start and end times
|
|
168
|
+
* Requirement: 18.7
|
|
169
|
+
*/
|
|
170
|
+
isAllDayEvent(startDate, endDate) {
|
|
171
|
+
// Check if both times are midnight in their specified timezone
|
|
172
|
+
// Parse the time portion from the ISO string directly to avoid timezone conversion issues
|
|
173
|
+
const startMidnight = this.isMidnightInOriginalTimezone(startDate);
|
|
174
|
+
const endMidnight = this.isMidnightInOriginalTimezone(endDate);
|
|
175
|
+
return startMidnight && endMidnight;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if a date string represents midnight in its original timezone
|
|
179
|
+
* This avoids issues with JavaScript Date converting to local timezone
|
|
180
|
+
*/
|
|
181
|
+
isMidnightInOriginalTimezone(dateStr) {
|
|
182
|
+
if (!dateStr)
|
|
183
|
+
return false;
|
|
184
|
+
// Date-only format (e.g., "2025-01-01") is always considered midnight
|
|
185
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
// Extract time portion from ISO 8601 string
|
|
189
|
+
// Formats: "2025-01-01T00:00:00", "2025-01-01T00:00:00Z", "2025-01-01T00:00:00+09:00"
|
|
190
|
+
const timeMatch = dateStr.match(/T(\d{2}):(\d{2}):(\d{2})/);
|
|
191
|
+
if (timeMatch) {
|
|
192
|
+
const hours = parseInt(timeMatch[1], 10);
|
|
193
|
+
const minutes = parseInt(timeMatch[2], 10);
|
|
194
|
+
const seconds = parseInt(timeMatch[3], 10);
|
|
195
|
+
return hours === 0 && minutes === 0 && seconds === 0;
|
|
196
|
+
}
|
|
197
|
+
// Fallback: use Date object (less reliable across timezones)
|
|
198
|
+
const date = new Date(dateStr);
|
|
199
|
+
return date.getHours() === 0 && date.getMinutes() === 0 && date.getSeconds() === 0;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Parse date/time string to components
|
|
203
|
+
* Parses the date string in its original timezone, not converting to local time
|
|
204
|
+
*/
|
|
205
|
+
parseDateTimeComponents(dateStr) {
|
|
206
|
+
if (!dateStr) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
// Try to parse ISO 8601 format directly to preserve original timezone
|
|
210
|
+
// Formats: "2025-01-01", "2025-01-01T10:00:00", "2025-01-01T10:00:00Z", "2025-01-01T10:00:00+09:00"
|
|
211
|
+
// Date-only format: "2025-01-01"
|
|
212
|
+
const dateOnlyMatch = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
213
|
+
if (dateOnlyMatch) {
|
|
214
|
+
return {
|
|
215
|
+
year: parseInt(dateOnlyMatch[1], 10),
|
|
216
|
+
month: parseInt(dateOnlyMatch[2], 10),
|
|
217
|
+
day: parseInt(dateOnlyMatch[3], 10),
|
|
218
|
+
hours: 0,
|
|
219
|
+
minutes: 0,
|
|
220
|
+
seconds: 0,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
// DateTime format: "2025-01-01T10:00:00" with optional timezone
|
|
224
|
+
const dateTimeMatch = dateStr.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/);
|
|
225
|
+
if (dateTimeMatch) {
|
|
226
|
+
return {
|
|
227
|
+
year: parseInt(dateTimeMatch[1], 10),
|
|
228
|
+
month: parseInt(dateTimeMatch[2], 10),
|
|
229
|
+
day: parseInt(dateTimeMatch[3], 10),
|
|
230
|
+
hours: parseInt(dateTimeMatch[4], 10),
|
|
231
|
+
minutes: parseInt(dateTimeMatch[5], 10),
|
|
232
|
+
seconds: parseInt(dateTimeMatch[6], 10),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
// Fallback: use Date object (less reliable across timezones)
|
|
236
|
+
const date = new Date(dateStr);
|
|
237
|
+
if (isNaN(date.getTime())) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
year: date.getFullYear(),
|
|
242
|
+
month: date.getMonth() + 1,
|
|
243
|
+
day: date.getDate(),
|
|
244
|
+
hours: date.getHours(),
|
|
245
|
+
minutes: date.getMinutes(),
|
|
246
|
+
seconds: date.getSeconds(),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Build AppleScriptObjC script for creating event via EventKit
|
|
251
|
+
* Requirement: 18.6
|
|
252
|
+
*/
|
|
253
|
+
buildCreateEventScript(request) {
|
|
254
|
+
const startComponents = this.parseDateTimeComponents(request.startDate);
|
|
255
|
+
const endComponents = this.parseDateTimeComponents(request.endDate);
|
|
256
|
+
if (!startComponents || !endComponents) {
|
|
257
|
+
throw new Error('Invalid date components');
|
|
258
|
+
}
|
|
259
|
+
const isAllDay = this.isAllDayEvent(request.startDate, request.endDate);
|
|
260
|
+
const escapedTitle = request.title.replace(/"/g, '\\"');
|
|
261
|
+
const escapedLocation = request.location?.replace(/"/g, '\\"') || '';
|
|
262
|
+
const escapedNotes = request.notes?.replace(/"/g, '\\"') || '';
|
|
263
|
+
// Build alarms section
|
|
264
|
+
let alarmsSection = '';
|
|
265
|
+
if (request.alarms && request.alarms.length > 0) {
|
|
266
|
+
const alarmOffsets = request.alarms
|
|
267
|
+
.map(a => parseAlarmString(a))
|
|
268
|
+
.filter((a) => a !== null);
|
|
269
|
+
if (alarmOffsets.length > 0) {
|
|
270
|
+
alarmsSection = alarmOffsets
|
|
271
|
+
.map(offset => `
|
|
272
|
+
set newAlarm to current application's EKAlarm's alarmWithRelativeOffset:${offset}
|
|
273
|
+
theEvent's addAlarm:newAlarm`)
|
|
274
|
+
.join('\n');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Build calendar selection section
|
|
278
|
+
let calendarSection = `
|
|
279
|
+
set targetCalendar to theStore's defaultCalendarForNewEvents()
|
|
280
|
+
if targetCalendar is missing value then
|
|
281
|
+
return "ERROR:デフォルトカレンダーが設定されていません"
|
|
282
|
+
end if`;
|
|
283
|
+
if (request.calendarName) {
|
|
284
|
+
const escapedCalendarName = request.calendarName.replace(/"/g, '\\"');
|
|
285
|
+
calendarSection = `
|
|
286
|
+
set targetCalendar to missing value
|
|
287
|
+
set allCalendars to theStore's calendarsForEntityType:0
|
|
288
|
+
repeat with aCal in allCalendars
|
|
289
|
+
if ((aCal's title()) as text) is equal to "${escapedCalendarName}" then
|
|
290
|
+
set targetCalendar to aCal
|
|
291
|
+
exit repeat
|
|
292
|
+
end if
|
|
293
|
+
end repeat
|
|
294
|
+
|
|
295
|
+
if targetCalendar is missing value then
|
|
296
|
+
return "ERROR:指定されたカレンダーが見つかりません: ${escapedCalendarName}"
|
|
297
|
+
end if
|
|
298
|
+
|
|
299
|
+
set canModify to (targetCalendar's allowsContentModifications()) as boolean
|
|
300
|
+
if not canModify then
|
|
301
|
+
return "ERROR:読み取り専用カレンダーには書き込めません: ${escapedCalendarName}"
|
|
302
|
+
end if`;
|
|
303
|
+
}
|
|
304
|
+
// Build location section
|
|
305
|
+
let locationSection = '';
|
|
306
|
+
if (request.location) {
|
|
307
|
+
locationSection = `
|
|
308
|
+
theEvent's setLocation:"${escapedLocation}"`;
|
|
309
|
+
}
|
|
310
|
+
// Build notes section
|
|
311
|
+
let notesSection = '';
|
|
312
|
+
if (request.notes) {
|
|
313
|
+
notesSection = `
|
|
314
|
+
theEvent's setNotes:"${escapedNotes}"`;
|
|
315
|
+
}
|
|
316
|
+
return `
|
|
317
|
+
use AppleScript version "2.7"
|
|
318
|
+
use framework "Foundation"
|
|
319
|
+
use framework "EventKit"
|
|
320
|
+
use scripting additions
|
|
321
|
+
|
|
322
|
+
-- Create EventKit store
|
|
323
|
+
set theStore to current application's EKEventStore's alloc()'s init()
|
|
324
|
+
|
|
325
|
+
-- Request calendar access
|
|
326
|
+
theStore's requestFullAccessToEventsWithCompletion:(missing value)
|
|
327
|
+
delay 0.5
|
|
328
|
+
|
|
329
|
+
-- Check access
|
|
330
|
+
set accessStatus to current application's EKEventStore's authorizationStatusForEntityType:0
|
|
331
|
+
if accessStatus is not 3 then
|
|
332
|
+
return "ERROR:カレンダーへのアクセス権限がありません"
|
|
333
|
+
end if
|
|
334
|
+
|
|
335
|
+
${calendarSection}
|
|
336
|
+
|
|
337
|
+
-- Build start date
|
|
338
|
+
set startDate to current date
|
|
339
|
+
set year of startDate to ${startComponents.year}
|
|
340
|
+
set month of startDate to ${startComponents.month}
|
|
341
|
+
set day of startDate to ${startComponents.day}
|
|
342
|
+
set hours of startDate to ${startComponents.hours}
|
|
343
|
+
set minutes of startDate to ${startComponents.minutes}
|
|
344
|
+
set seconds of startDate to ${startComponents.seconds}
|
|
345
|
+
|
|
346
|
+
-- Build end date
|
|
347
|
+
set endDate to current date
|
|
348
|
+
set year of endDate to ${endComponents.year}
|
|
349
|
+
set month of endDate to ${endComponents.month}
|
|
350
|
+
set day of endDate to ${endComponents.day}
|
|
351
|
+
set hours of endDate to ${endComponents.hours}
|
|
352
|
+
set minutes of endDate to ${endComponents.minutes}
|
|
353
|
+
set seconds of endDate to ${endComponents.seconds}
|
|
354
|
+
|
|
355
|
+
-- Convert AppleScript dates to NSDate
|
|
356
|
+
set startNSDate to current application's NSDate's dateWithTimeIntervalSince1970:((startDate - (date "Thursday, January 1, 1970 at 9:00:00")) / 1)
|
|
357
|
+
set endNSDate to current application's NSDate's dateWithTimeIntervalSince1970:((endDate - (date "Thursday, January 1, 1970 at 9:00:00")) / 1)
|
|
358
|
+
|
|
359
|
+
-- Create new event
|
|
360
|
+
set theEvent to current application's EKEvent's eventWithEventStore:theStore
|
|
361
|
+
theEvent's setTitle:"${escapedTitle}"
|
|
362
|
+
theEvent's setStartDate:startNSDate
|
|
363
|
+
theEvent's setEndDate:endNSDate
|
|
364
|
+
theEvent's setCalendar:targetCalendar
|
|
365
|
+
theEvent's setAllDay:${isAllDay}
|
|
366
|
+
${locationSection}
|
|
367
|
+
${notesSection}
|
|
368
|
+
${alarmsSection}
|
|
369
|
+
|
|
370
|
+
-- Save event
|
|
371
|
+
set saveSuccess to theStore's saveEvent:theEvent span:0 |error|:(missing value)
|
|
372
|
+
|
|
373
|
+
if saveSuccess then
|
|
374
|
+
set eventId to (theEvent's eventIdentifier()) as text
|
|
375
|
+
set calendarName to (targetCalendar's title()) as text
|
|
376
|
+
return "SUCCESS|" & eventId & "|" & calendarName
|
|
377
|
+
else
|
|
378
|
+
return "ERROR:イベントの保存に失敗しました"
|
|
379
|
+
end if`;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Create event via EventKit
|
|
383
|
+
* @internal
|
|
384
|
+
*/
|
|
385
|
+
async createEventViaEventKit(request) {
|
|
386
|
+
try {
|
|
387
|
+
// Lazy load run-applescript
|
|
388
|
+
if (!this.runAppleScript) {
|
|
389
|
+
const module = await import('run-applescript');
|
|
390
|
+
this.runAppleScript = module.runAppleScript;
|
|
391
|
+
}
|
|
392
|
+
const script = this.buildCreateEventScript(request);
|
|
393
|
+
// Use retry with exponential backoff
|
|
394
|
+
const result = await retryWithBackoff(async () => {
|
|
395
|
+
return await this.runAppleScript(script);
|
|
396
|
+
}, {
|
|
397
|
+
...RETRY_OPTIONS,
|
|
398
|
+
onRetry: (error, attempt) => {
|
|
399
|
+
console.error(`EventKit create event retry attempt ${attempt}: ${error.message}`);
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
return this.parseCreateEventResult(result, request);
|
|
403
|
+
}
|
|
404
|
+
catch (error) {
|
|
405
|
+
return {
|
|
406
|
+
success: false,
|
|
407
|
+
error: `EventKitエラー: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
408
|
+
message: 'イベントの作成に失敗しました',
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Parse create event result
|
|
414
|
+
* @internal
|
|
415
|
+
*/
|
|
416
|
+
parseCreateEventResult(result, request) {
|
|
417
|
+
if (result.startsWith('ERROR:')) {
|
|
418
|
+
return {
|
|
419
|
+
success: false,
|
|
420
|
+
error: result.replace('ERROR:', ''),
|
|
421
|
+
message: 'イベントの作成に失敗しました',
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (result.startsWith('SUCCESS|')) {
|
|
425
|
+
const parts = result.split('|');
|
|
426
|
+
const eventId = parts[1];
|
|
427
|
+
const calendarName = parts[2] || request.calendarName || 'Calendar';
|
|
428
|
+
return {
|
|
429
|
+
success: true,
|
|
430
|
+
eventId,
|
|
431
|
+
title: request.title,
|
|
432
|
+
startDate: request.startDate,
|
|
433
|
+
endDate: request.endDate,
|
|
434
|
+
calendarName,
|
|
435
|
+
isAllDay: this.isAllDayEvent(request.startDate, request.endDate),
|
|
436
|
+
message: '',
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
success: false,
|
|
441
|
+
error: '予期しない応答形式',
|
|
442
|
+
message: 'イベントの作成に失敗しました',
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Generate success message
|
|
447
|
+
* Requirement: 18.10
|
|
448
|
+
*/
|
|
449
|
+
generateSuccessMessage(result) {
|
|
450
|
+
if (!result.success) {
|
|
451
|
+
return 'イベントの作成に失敗しました';
|
|
452
|
+
}
|
|
453
|
+
if (result.isAllDay) {
|
|
454
|
+
return `カレンダーに「${result.title}」を作成しました(${this.formatDateOnly(result.startDate)}〜${this.formatDateOnly(result.endDate)} 終日)`;
|
|
455
|
+
}
|
|
456
|
+
const startTime = this.formatTime(result.startDate);
|
|
457
|
+
const endTime = this.formatTime(result.endDate);
|
|
458
|
+
const dateStr = this.formatDateOnly(result.startDate);
|
|
459
|
+
return `カレンダーに「${result.title}」を作成しました(${dateStr} ${startTime}-${endTime})`;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Format date string to YYYY-MM-DD
|
|
463
|
+
* Parses ISO string directly to preserve original timezone
|
|
464
|
+
* @internal
|
|
465
|
+
*/
|
|
466
|
+
formatDateOnly(dateStr) {
|
|
467
|
+
if (!dateStr)
|
|
468
|
+
return '';
|
|
469
|
+
// Handle date-only format (YYYY-MM-DD)
|
|
470
|
+
const dateOnlyMatch = dateStr.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
471
|
+
if (dateOnlyMatch) {
|
|
472
|
+
return dateOnlyMatch[1];
|
|
473
|
+
}
|
|
474
|
+
// Fallback to Date object
|
|
475
|
+
const date = new Date(dateStr);
|
|
476
|
+
if (isNaN(date.getTime())) {
|
|
477
|
+
return dateStr;
|
|
478
|
+
}
|
|
479
|
+
const year = date.getFullYear();
|
|
480
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
481
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
482
|
+
return `${year}-${month}-${day}`;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Format time string to HH:mm
|
|
486
|
+
* Parses ISO string directly to preserve original timezone
|
|
487
|
+
* @internal
|
|
488
|
+
*/
|
|
489
|
+
formatTime(dateStr) {
|
|
490
|
+
if (!dateStr)
|
|
491
|
+
return '';
|
|
492
|
+
// Extract time from ISO 8601 format (e.g., "2025-01-01T14:00:00+09:00")
|
|
493
|
+
const timeMatch = dateStr.match(/T(\d{2}):(\d{2})/);
|
|
494
|
+
if (timeMatch) {
|
|
495
|
+
return `${timeMatch[1]}:${timeMatch[2]}`;
|
|
496
|
+
}
|
|
497
|
+
// Fallback to Date object
|
|
498
|
+
const date = new Date(dateStr);
|
|
499
|
+
if (isNaN(date.getTime())) {
|
|
500
|
+
return '';
|
|
501
|
+
}
|
|
502
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
503
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
504
|
+
return `${hours}:${minutes}`;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
//# sourceMappingURL=calendar-event-creator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-event-creator.js","sourceRoot":"","sources":["../../src/integrations/calendar-event-creator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar Event Deleter Service
|
|
3
|
+
* Handles deleting calendar events via EventKit
|
|
4
|
+
* Requirements: 19.1-19.12
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Single event deletion by ID
|
|
8
|
+
* - Batch event deletion
|
|
9
|
+
* - Calendar-specific deletion
|
|
10
|
+
* - UUID extraction from full IDs
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Platform information for calendar event deletion
|
|
14
|
+
*/
|
|
15
|
+
export interface CalendarDeleterPlatformInfo {
|
|
16
|
+
platform: 'macos' | 'ios' | 'ipados' | 'web' | 'unknown';
|
|
17
|
+
hasEventKitAccess: boolean;
|
|
18
|
+
supportsEventDeletion: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Request to delete a calendar event
|
|
22
|
+
* Requirement: 19.2, 19.3
|
|
23
|
+
*/
|
|
24
|
+
export interface DeleteCalendarEventRequest {
|
|
25
|
+
/** Required: Event ID (UUID or full ID with calendar prefix) */
|
|
26
|
+
eventId: string;
|
|
27
|
+
/** Optional: Calendar name (searches all calendars if not specified) */
|
|
28
|
+
calendarName?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Request to delete multiple calendar events
|
|
32
|
+
* Requirement: 19.10
|
|
33
|
+
*/
|
|
34
|
+
export interface DeleteCalendarEventsBatchRequest {
|
|
35
|
+
/** Required: Array of event IDs */
|
|
36
|
+
eventIds: string[];
|
|
37
|
+
/** Optional: Calendar name (searches all calendars if not specified) */
|
|
38
|
+
calendarName?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Result of calendar event deletion
|
|
42
|
+
* Requirement: 19.7, 19.9
|
|
43
|
+
*/
|
|
44
|
+
export interface DeleteCalendarEventResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
eventId: string;
|
|
47
|
+
title?: string;
|
|
48
|
+
calendarName?: string;
|
|
49
|
+
error?: string;
|
|
50
|
+
message: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Result of batch calendar event deletion
|
|
54
|
+
* Requirement: 19.10, 19.11
|
|
55
|
+
*/
|
|
56
|
+
export interface DeleteCalendarEventsBatchResult {
|
|
57
|
+
success: boolean;
|
|
58
|
+
totalCount: number;
|
|
59
|
+
successCount: number;
|
|
60
|
+
failedCount: number;
|
|
61
|
+
results: DeleteCalendarEventResult[];
|
|
62
|
+
message: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Extract UUID from event ID
|
|
66
|
+
* Requirement: 19.4, 19.5
|
|
67
|
+
*
|
|
68
|
+
* @param eventId - Full event ID or UUID
|
|
69
|
+
* @returns UUID part of the event ID
|
|
70
|
+
*/
|
|
71
|
+
export declare function extractEventUid(eventId: string): string;
|
|
72
|
+
/**
|
|
73
|
+
* Calendar Event Deleter Service
|
|
74
|
+
* Deletes calendar events via EventKit on macOS
|
|
75
|
+
*/
|
|
76
|
+
export declare class CalendarEventDeleterService {
|
|
77
|
+
private runAppleScript;
|
|
78
|
+
/**
|
|
79
|
+
* Detect current platform
|
|
80
|
+
*/
|
|
81
|
+
detectPlatform(): Promise<CalendarDeleterPlatformInfo>;
|
|
82
|
+
/**
|
|
83
|
+
* Check if EventKit is available for event deletion
|
|
84
|
+
*/
|
|
85
|
+
isEventKitAvailable(): Promise<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* Validate delete event request
|
|
88
|
+
* Requirement: 19.2
|
|
89
|
+
*/
|
|
90
|
+
validateRequest(request: DeleteCalendarEventRequest): string | null;
|
|
91
|
+
/**
|
|
92
|
+
* Validate batch delete request
|
|
93
|
+
* Requirement: 19.10
|
|
94
|
+
*/
|
|
95
|
+
validateBatchRequest(request: DeleteCalendarEventsBatchRequest): string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Delete a calendar event
|
|
98
|
+
* Requirement: 19.1
|
|
99
|
+
*/
|
|
100
|
+
deleteEvent(request: DeleteCalendarEventRequest): Promise<DeleteCalendarEventResult>;
|
|
101
|
+
/**
|
|
102
|
+
* Delete multiple calendar events
|
|
103
|
+
* Requirement: 19.10
|
|
104
|
+
*/
|
|
105
|
+
deleteEventsBatch(request: DeleteCalendarEventsBatchRequest): Promise<DeleteCalendarEventsBatchResult>;
|
|
106
|
+
/**
|
|
107
|
+
* Build AppleScriptObjC script for deleting event via EventKit
|
|
108
|
+
* Requirement: 19.6
|
|
109
|
+
*/
|
|
110
|
+
buildDeleteEventScript(eventId: string, calendarName?: string): string;
|
|
111
|
+
/**
|
|
112
|
+
* Delete event via EventKit
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
private deleteEventViaEventKit;
|
|
116
|
+
/**
|
|
117
|
+
* Parse delete event result
|
|
118
|
+
* Requirement: 19.7
|
|
119
|
+
*/
|
|
120
|
+
parseDeleteEventResult(result: string, eventId: string): DeleteCalendarEventResult;
|
|
121
|
+
/**
|
|
122
|
+
* Generate success message for single deletion
|
|
123
|
+
* Requirement: 19.9
|
|
124
|
+
*/
|
|
125
|
+
generateSuccessMessage(result: DeleteCalendarEventResult): string;
|
|
126
|
+
/**
|
|
127
|
+
* Generate summary message for batch deletion
|
|
128
|
+
* Requirement: 19.11
|
|
129
|
+
*/
|
|
130
|
+
generateBatchSummaryMessage(result: DeleteCalendarEventsBatchResult): string;
|
|
131
|
+
/**
|
|
132
|
+
* Delay helper for rate limiting
|
|
133
|
+
* @internal
|
|
134
|
+
*/
|
|
135
|
+
private delay;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=calendar-event-deleter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-event-deleter.d.ts","sourceRoot":"","sources":["../../src/integrations/calendar-event-deleter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IACzD,iBAAiB,EAAE,OAAO,CAAC;IAC3B,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,gCAAgC;IAC/C,mCAAmC;IACnC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;;GAGG;AACH,qBAAa,2BAA2B;IACtC,OAAO,CAAC,cAAc,CAAsD;IAE5E;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,2BAA2B,CAAC;IAgB5D;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAK7C;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,GAAG,IAAI;IAOnE;;;OAGG;IACH,oBAAoB,CAAC,OAAO,EAAE,gCAAgC,GAAG,MAAM,GAAG,IAAI;IAc9E;;;OAGG;IACG,WAAW,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA0C1F;;;OAGG;IACG,iBAAiB,CAAC,OAAO,EAAE,gCAAgC,GAAG,OAAO,CAAC,+BAA+B,CAAC;IAsD5G;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM;IAgFtE;;;OAGG;YACW,sBAAsB;IAmCpC;;;OAGG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,yBAAyB;IAiClF;;;OAGG;IACH,sBAAsB,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM;IAYjE;;;OAGG;IACH,2BAA2B,CAAC,MAAM,EAAE,+BAA+B,GAAG,MAAM;IAY5E;;;OAGG;IACH,OAAO,CAAC,KAAK;CAGd"}
|