@open-sunsama/mcp 1.0.0

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.
@@ -0,0 +1,456 @@
1
+ /**
2
+ * MCP Tools for Time Block Management
3
+ *
4
+ * Time blocks represent scheduled chunks of focused work time on your calendar.
5
+ * They can optionally be linked to tasks to track what you're working on.
6
+ */
7
+ import { z } from "zod";
8
+ /**
9
+ * Format a time block for display with human-readable information
10
+ */
11
+ function formatTimeBlock(block) {
12
+ const lines = [
13
+ `Time Block: ${block.title}`,
14
+ `ID: ${block.id}`,
15
+ `Date: ${block.date}`,
16
+ `Time: ${block.startTime} - ${block.endTime} (${block.durationMins} mins)`,
17
+ ];
18
+ if (block.description) {
19
+ lines.push(`Description: ${block.description}`);
20
+ }
21
+ if (block.taskId) {
22
+ lines.push(`Linked Task ID: ${block.taskId}`);
23
+ if (block.task) {
24
+ lines.push(`Linked Task: ${block.task.title}`);
25
+ }
26
+ }
27
+ if (block.color) {
28
+ lines.push(`Color: ${block.color}`);
29
+ }
30
+ lines.push(`Created: ${block.createdAt}`);
31
+ lines.push(`Updated: ${block.updatedAt}`);
32
+ return lines.join("\n");
33
+ }
34
+ /**
35
+ * Format multiple time blocks as a schedule view
36
+ */
37
+ function formatSchedule(blocks, date) {
38
+ if (blocks.length === 0) {
39
+ return `No time blocks scheduled for ${date}`;
40
+ }
41
+ // Sort by start time
42
+ const sorted = [...blocks].sort((a, b) => a.startTime.localeCompare(b.startTime));
43
+ const lines = [`Schedule for ${date}:`, "─".repeat(40)];
44
+ for (const block of sorted) {
45
+ const taskInfo = block.taskId
46
+ ? ` [Task: ${block.task?.title || block.taskId}]`
47
+ : "";
48
+ lines.push(`${block.startTime} - ${block.endTime}: ${block.title}${taskInfo}`);
49
+ if (block.description) {
50
+ lines.push(` └─ ${block.description}`);
51
+ }
52
+ }
53
+ // Calculate total scheduled time
54
+ const totalMins = sorted.reduce((sum, b) => sum + b.durationMins, 0);
55
+ const hours = Math.floor(totalMins / 60);
56
+ const mins = totalMins % 60;
57
+ lines.push("─".repeat(40));
58
+ lines.push(`Total: ${blocks.length} blocks, ${hours}h ${mins}m scheduled`);
59
+ return lines.join("\n");
60
+ }
61
+ /**
62
+ * Creates a success response for MCP tools
63
+ */
64
+ function successResponse(text) {
65
+ return {
66
+ content: [{ type: "text", text }],
67
+ };
68
+ }
69
+ /**
70
+ * Creates an error response for MCP tools
71
+ */
72
+ function errorResponse(message) {
73
+ return {
74
+ content: [{ type: "text", text: `Error: ${message}` }],
75
+ isError: true,
76
+ };
77
+ }
78
+ /**
79
+ * Register all time block MCP tools
80
+ */
81
+ export function registerTimeBlockTools(server, apiClient) {
82
+ // List time blocks with optional filters
83
+ server.tool("list_time_blocks", `List time blocks from your calendar with optional filters.
84
+
85
+ Use this tool to:
86
+ - View all time blocks for a specific date (use 'date' parameter)
87
+ - View time blocks across a date range (use 'from' and 'to' parameters)
88
+ - Find all time blocks linked to a specific task (use 'taskId' parameter)
89
+ - Browse through paginated results (use 'page' and 'limit' parameters)
90
+
91
+ Time blocks represent scheduled chunks of focused work time. They can be
92
+ linked to tasks to track what work is being done during that time.
93
+
94
+ Returns a list of time blocks with their details including title, date,
95
+ start/end times, duration, description, color, and any linked task info.`, {
96
+ date: z
97
+ .string()
98
+ .optional()
99
+ .describe("Filter by specific date in YYYY-MM-DD format (e.g., '2024-01-15'). Cannot be used with from/to."),
100
+ from: z
101
+ .string()
102
+ .optional()
103
+ .describe("Start of date range in YYYY-MM-DD format. Must be used with 'to' parameter."),
104
+ to: z
105
+ .string()
106
+ .optional()
107
+ .describe("End of date range in YYYY-MM-DD format. Must be used with 'from' parameter."),
108
+ taskId: z
109
+ .string()
110
+ .optional()
111
+ .describe("Filter to only show time blocks linked to this specific task ID"),
112
+ page: z
113
+ .number()
114
+ .int()
115
+ .positive()
116
+ .optional()
117
+ .describe("Page number for pagination (default: 1)"),
118
+ limit: z
119
+ .number()
120
+ .int()
121
+ .positive()
122
+ .max(100)
123
+ .optional()
124
+ .describe("Number of results per page (default: 50, max: 100)"),
125
+ }, async (input) => {
126
+ try {
127
+ const response = await apiClient.listTimeBlocks({
128
+ date: input.date,
129
+ from: input.from,
130
+ to: input.to,
131
+ taskId: input.taskId,
132
+ page: input.page,
133
+ limit: input.limit,
134
+ });
135
+ if (!response.success) {
136
+ return errorResponse(response.error?.message || "Failed to list time blocks");
137
+ }
138
+ const blocks = response.data || [];
139
+ if (blocks.length === 0) {
140
+ return successResponse("No time blocks found matching your criteria.");
141
+ }
142
+ let result = blocks.map((b) => formatTimeBlock(b)).join("\n\n---\n\n");
143
+ if (response.meta) {
144
+ result += `\n\n---\nPage ${response.meta.page} of ${response.meta.totalPages} (${response.meta.total} total blocks)`;
145
+ }
146
+ return successResponse(result);
147
+ }
148
+ catch (error) {
149
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
150
+ }
151
+ });
152
+ // Get a specific time block by ID
153
+ server.tool("get_time_block", `Get detailed information about a specific time block by its ID.
154
+
155
+ Use this tool when you need to:
156
+ - View the full details of a time block
157
+ - Check if a time block exists
158
+ - See what task is linked to a time block
159
+ - Get the exact timing and duration of a scheduled block
160
+
161
+ Returns complete time block information including title, date, start/end times,
162
+ duration in minutes, description, color, and linked task details if any.`, {
163
+ id: z.string().describe("The unique ID of the time block to retrieve"),
164
+ }, async (input) => {
165
+ try {
166
+ const response = await apiClient.getTimeBlock(input.id);
167
+ if (!response.success) {
168
+ return errorResponse(response.error?.message || "Time block not found");
169
+ }
170
+ return successResponse(formatTimeBlock(response.data));
171
+ }
172
+ catch (error) {
173
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
174
+ }
175
+ });
176
+ // Create a new time block
177
+ server.tool("create_time_block", `Create a new time block to schedule focused work time on your calendar.
178
+
179
+ Use this tool to:
180
+ - Schedule a block of time for focused work
181
+ - Plan your day by creating time-boxed sessions
182
+ - Reserve time for specific activities or tasks
183
+ - Create recurring work sessions (one at a time)
184
+
185
+ Time blocks help you:
186
+ - Protect time for deep work
187
+ - Visualize your day's schedule
188
+ - Track how you spend your time
189
+ - Link work sessions to specific tasks
190
+
191
+ The time block will appear on your calendar for the specified date and time.
192
+ You can optionally link it to an existing task to track what you'll work on.`, {
193
+ title: z
194
+ .string()
195
+ .min(1)
196
+ .max(200)
197
+ .describe("Title of the time block (e.g., 'Deep work session', 'Team standup', 'Code review')"),
198
+ date: z
199
+ .string()
200
+ .describe("Date for the time block in YYYY-MM-DD format (e.g., '2024-01-15')"),
201
+ startTime: z
202
+ .string()
203
+ .describe("Start time in 24-hour HH:MM format (e.g., '09:00', '14:30')"),
204
+ endTime: z
205
+ .string()
206
+ .describe("End time in 24-hour HH:MM format (e.g., '11:00', '16:00'). Must be after startTime."),
207
+ taskId: z
208
+ .string()
209
+ .optional()
210
+ .describe("Optional: ID of a task to link to this time block. Links the scheduled time to specific work."),
211
+ description: z
212
+ .string()
213
+ .max(1000)
214
+ .optional()
215
+ .describe("Optional: Additional notes or context for this time block"),
216
+ color: z
217
+ .string()
218
+ .optional()
219
+ .describe("Optional: Hex color code for visual distinction (e.g., '#3B82F6' for blue, '#10B981' for green)"),
220
+ }, async (input) => {
221
+ try {
222
+ // Validate time format
223
+ const timeRegex = /^([01]\d|2[0-3]):([0-5]\d)$/;
224
+ if (!timeRegex.test(input.startTime)) {
225
+ return errorResponse(`Invalid start time format '${input.startTime}'. Use HH:MM 24-hour format (e.g., '09:00', '14:30')`);
226
+ }
227
+ if (!timeRegex.test(input.endTime)) {
228
+ return errorResponse(`Invalid end time format '${input.endTime}'. Use HH:MM 24-hour format (e.g., '11:00', '16:00')`);
229
+ }
230
+ // Validate date format
231
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
232
+ if (!dateRegex.test(input.date)) {
233
+ return errorResponse(`Invalid date format '${input.date}'. Use YYYY-MM-DD format (e.g., '2024-01-15')`);
234
+ }
235
+ // Validate end time is after start time
236
+ if (input.endTime <= input.startTime) {
237
+ return errorResponse(`End time (${input.endTime}) must be after start time (${input.startTime})`);
238
+ }
239
+ // Validate color format if provided
240
+ if (input.color && !/^#[0-9A-Fa-f]{6}$/.test(input.color)) {
241
+ return errorResponse(`Invalid color format '${input.color}'. Use 6-digit hex code (e.g., '#3B82F6')`);
242
+ }
243
+ const response = await apiClient.createTimeBlock({
244
+ title: input.title,
245
+ date: input.date,
246
+ startTime: input.startTime,
247
+ endTime: input.endTime,
248
+ taskId: input.taskId,
249
+ description: input.description,
250
+ color: input.color,
251
+ });
252
+ if (!response.success) {
253
+ return errorResponse(response.error?.message || "Failed to create time block");
254
+ }
255
+ return successResponse(`Time block created successfully!\n\n${formatTimeBlock(response.data)}`);
256
+ }
257
+ catch (error) {
258
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
259
+ }
260
+ });
261
+ // Update an existing time block
262
+ server.tool("update_time_block", `Update an existing time block's details.
263
+
264
+ Use this tool to:
265
+ - Reschedule a time block to a different time or date
266
+ - Change the title or description
267
+ - Update the color for visual organization
268
+ - Link or unlink a task (use link_task_to_time_block for just that)
269
+
270
+ Only provide the fields you want to change. Omitted fields will remain unchanged.
271
+ To clear optional fields (description, color, taskId), pass null explicitly.`, {
272
+ id: z.string().describe("The unique ID of the time block to update"),
273
+ title: z
274
+ .string()
275
+ .min(1)
276
+ .max(200)
277
+ .optional()
278
+ .describe("New title for the time block"),
279
+ date: z
280
+ .string()
281
+ .optional()
282
+ .describe("New date in YYYY-MM-DD format (e.g., '2024-01-15')"),
283
+ startTime: z
284
+ .string()
285
+ .optional()
286
+ .describe("New start time in HH:MM 24-hour format (e.g., '09:00')"),
287
+ endTime: z
288
+ .string()
289
+ .optional()
290
+ .describe("New end time in HH:MM 24-hour format (e.g., '11:00')"),
291
+ taskId: z
292
+ .string()
293
+ .nullable()
294
+ .optional()
295
+ .describe("Task ID to link, or null to unlink. Omit to keep current link."),
296
+ description: z
297
+ .string()
298
+ .max(1000)
299
+ .nullable()
300
+ .optional()
301
+ .describe("New description, or null to clear"),
302
+ color: z
303
+ .string()
304
+ .nullable()
305
+ .optional()
306
+ .describe("New hex color (e.g., '#3B82F6'), or null to clear"),
307
+ }, async (input) => {
308
+ try {
309
+ const { id, ...updates } = input;
310
+ // Validate time formats if provided
311
+ const timeRegex = /^([01]\d|2[0-3]):([0-5]\d)$/;
312
+ if (updates.startTime && !timeRegex.test(updates.startTime)) {
313
+ return errorResponse(`Invalid start time format '${updates.startTime}'. Use HH:MM 24-hour format`);
314
+ }
315
+ if (updates.endTime && !timeRegex.test(updates.endTime)) {
316
+ return errorResponse(`Invalid end time format '${updates.endTime}'. Use HH:MM 24-hour format`);
317
+ }
318
+ // Validate date format if provided
319
+ if (updates.date && !/^\d{4}-\d{2}-\d{2}$/.test(updates.date)) {
320
+ return errorResponse(`Invalid date format '${updates.date}'. Use YYYY-MM-DD format`);
321
+ }
322
+ // Validate color format if provided
323
+ if (updates.color !== null &&
324
+ updates.color !== undefined &&
325
+ !/^#[0-9A-Fa-f]{6}$/.test(updates.color)) {
326
+ return errorResponse(`Invalid color format '${updates.color}'. Use 6-digit hex code (e.g., '#3B82F6')`);
327
+ }
328
+ // Build update payload, only including defined fields
329
+ const updateData = {};
330
+ if (updates.title !== undefined)
331
+ updateData.title = updates.title;
332
+ if (updates.date !== undefined)
333
+ updateData.date = updates.date;
334
+ if (updates.startTime !== undefined)
335
+ updateData.startTime = updates.startTime;
336
+ if (updates.endTime !== undefined)
337
+ updateData.endTime = updates.endTime;
338
+ if (updates.taskId !== undefined)
339
+ updateData.taskId = updates.taskId;
340
+ if (updates.description !== undefined)
341
+ updateData.description = updates.description;
342
+ if (updates.color !== undefined)
343
+ updateData.color = updates.color;
344
+ if (Object.keys(updateData).length === 0) {
345
+ return errorResponse("No updates provided. Please provide at least one field to update.");
346
+ }
347
+ const response = await apiClient.updateTimeBlock(id, updateData);
348
+ if (!response.success) {
349
+ return errorResponse(response.error?.message || "Failed to update time block");
350
+ }
351
+ return successResponse(`Time block updated successfully!\n\n${formatTimeBlock(response.data)}`);
352
+ }
353
+ catch (error) {
354
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
355
+ }
356
+ });
357
+ // Delete a time block
358
+ server.tool("delete_time_block", `Delete a time block from your calendar.
359
+
360
+ Use this tool to:
361
+ - Remove a scheduled time block that's no longer needed
362
+ - Clear a time slot that was cancelled
363
+ - Delete mistakenly created time blocks
364
+
365
+ This action is permanent. The time block will be removed from your schedule.
366
+ Any linked task will NOT be deleted, only the link will be removed.`, {
367
+ id: z.string().describe("The unique ID of the time block to delete"),
368
+ }, async (input) => {
369
+ try {
370
+ const response = await apiClient.deleteTimeBlock(input.id);
371
+ if (!response.success) {
372
+ return errorResponse(response.error?.message || "Failed to delete time block");
373
+ }
374
+ return successResponse(`Time block deleted successfully. (ID: ${input.id})`);
375
+ }
376
+ catch (error) {
377
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
378
+ }
379
+ });
380
+ // Link or unlink a task to a time block
381
+ server.tool("link_task_to_time_block", `Link a task to a time block, or unlink a task from a time block.
382
+
383
+ Use this tool to:
384
+ - Connect a scheduled time block to a specific task you'll work on
385
+ - Track which task you're dedicating time to
386
+ - Unlink a task if the time block is for something else
387
+
388
+ When a task is linked to a time block:
389
+ - The calendar shows what you'll be working on
390
+ - You can see which tasks have dedicated time slots
391
+ - Time tracking becomes more meaningful
392
+
393
+ To unlink a task, pass null as the taskId.`, {
394
+ timeBlockId: z
395
+ .string()
396
+ .describe("The ID of the time block to link/unlink"),
397
+ taskId: z
398
+ .string()
399
+ .nullable()
400
+ .describe("The task ID to link to this time block, or null to unlink the current task"),
401
+ }, async (input) => {
402
+ try {
403
+ const response = await apiClient.updateTimeBlock(input.timeBlockId, {
404
+ taskId: input.taskId,
405
+ });
406
+ if (!response.success) {
407
+ return errorResponse(response.error?.message || "Failed to update time block");
408
+ }
409
+ const action = input.taskId ? "linked" : "unlinked";
410
+ return successResponse(`Task ${action} successfully!\n\n${formatTimeBlock(response.data)}`);
411
+ }
412
+ catch (error) {
413
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
414
+ }
415
+ });
416
+ // Get schedule for a specific day (convenience tool)
417
+ server.tool("get_schedule_for_day", `Get all time blocks for a specific day, formatted as a schedule view.
418
+
419
+ This is a convenience tool that:
420
+ - Fetches all time blocks for the given date
421
+ - Sorts them chronologically
422
+ - Formats them as a readable daily schedule
423
+ - Shows total scheduled time
424
+
425
+ Use this tool to:
426
+ - See your schedule for today or any other day
427
+ - Review how your day is organized
428
+ - Check for gaps in your schedule
429
+ - Get an overview before planning
430
+
431
+ The schedule shows times, titles, and linked tasks in an easy-to-read format.`, {
432
+ date: z
433
+ .string()
434
+ .describe("The date to get the schedule for in YYYY-MM-DD format (e.g., '2024-01-15')"),
435
+ }, async (input) => {
436
+ try {
437
+ // Validate date format
438
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(input.date)) {
439
+ return errorResponse(`Invalid date format '${input.date}'. Use YYYY-MM-DD format (e.g., '2024-01-15')`);
440
+ }
441
+ const response = await apiClient.listTimeBlocks({
442
+ date: input.date,
443
+ limit: 100, // Get all blocks for the day
444
+ });
445
+ if (!response.success) {
446
+ return errorResponse(response.error?.message || "Failed to get schedule");
447
+ }
448
+ const blocks = response.data || [];
449
+ return successResponse(formatSchedule(blocks, input.date));
450
+ }
451
+ catch (error) {
452
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
453
+ }
454
+ });
455
+ }
456
+ //# sourceMappingURL=time-blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-blocks.js","sourceRoot":"","sources":["../../src/tools/time-blocks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * MCP tools for user profile management
3
+ * Provides tools for viewing and updating user profile information
4
+ */
5
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import type { ApiClient } from "../lib/api-client.js";
7
+ /**
8
+ * Register all user-related tools with the MCP server
9
+ */
10
+ export declare function registerUserTools(server: McpServer, apiClient: ApiClient): void;
11
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/tools/user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,sBAAsB,CAAC;AA6C7E;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,SAAS,GACnB,IAAI,CAiJN"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * MCP tools for user profile management
3
+ * Provides tools for viewing and updating user profile information
4
+ */
5
+ import { z } from "zod";
6
+ /**
7
+ * Format user profile for display
8
+ */
9
+ function formatUserProfile(user) {
10
+ const lines = [
11
+ `Name: ${user.name || "(not set)"}`,
12
+ `Email: ${user.email}`,
13
+ `Timezone: ${user.timezone}`,
14
+ `Avatar URL: ${user.avatarUrl || "(not set)"}`,
15
+ `Account created: ${new Date(user.createdAt).toLocaleDateString()}`,
16
+ `Last updated: ${new Date(user.updatedAt).toLocaleDateString()}`,
17
+ ];
18
+ if (user.preferences) {
19
+ lines.push("");
20
+ lines.push("Preferences:");
21
+ lines.push(` Theme mode: ${user.preferences.themeMode}`);
22
+ lines.push(` Color theme: ${user.preferences.colorTheme}`);
23
+ lines.push(` Font family: ${user.preferences.fontFamily}`);
24
+ }
25
+ return lines.join("\n");
26
+ }
27
+ /**
28
+ * Creates a success response for MCP tools
29
+ */
30
+ function successResponse(text) {
31
+ return {
32
+ content: [{ type: "text", text }],
33
+ };
34
+ }
35
+ /**
36
+ * Creates an error response for MCP tools
37
+ */
38
+ function errorResponse(message) {
39
+ return {
40
+ content: [{ type: "text", text: `Error: ${message}` }],
41
+ isError: true,
42
+ };
43
+ }
44
+ /**
45
+ * Register all user-related tools with the MCP server
46
+ */
47
+ export function registerUserTools(server, apiClient) {
48
+ // Get current user profile
49
+ server.tool("get_user_profile", "Get the current authenticated user's profile information. Returns the user's name, email, timezone, avatar URL, and preferences (theme mode, color theme, font family). This is useful for personalizing interactions or understanding the user's settings.", {}, async () => {
50
+ try {
51
+ const response = await apiClient.getMe();
52
+ if (!response.success) {
53
+ return errorResponse(response.error?.message || "Failed to fetch user profile");
54
+ }
55
+ const user = response.data;
56
+ const formattedProfile = formatUserProfile(user);
57
+ return successResponse(`User Profile:\n\n${formattedProfile}\n\nUser ID: ${user.id}`);
58
+ }
59
+ catch (error) {
60
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
61
+ }
62
+ });
63
+ // Update user profile
64
+ server.tool("update_user_profile", "Update the current user's profile information. You can update the user's display name, timezone, avatar URL, and preferences (theme mode, color theme, font family). At least one field must be provided. The timezone should be a valid IANA timezone identifier (e.g., 'America/New_York', 'Europe/London', 'Asia/Tokyo').", {
65
+ name: z
66
+ .string()
67
+ .optional()
68
+ .describe("The user's display name. This is shown in the UI and can be any string"),
69
+ timezone: z
70
+ .string()
71
+ .optional()
72
+ .describe("The user's timezone as an IANA timezone identifier (e.g., 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'UTC'). Used for scheduling and displaying times"),
73
+ avatarUrl: z
74
+ .string()
75
+ .nullable()
76
+ .optional()
77
+ .describe("URL to the user's avatar image. Set to null to remove the avatar"),
78
+ themeMode: z
79
+ .enum(["light", "dark", "system"])
80
+ .optional()
81
+ .describe("UI theme mode preference. 'light' for light theme, 'dark' for dark theme, 'system' to follow system settings"),
82
+ colorTheme: z
83
+ .string()
84
+ .optional()
85
+ .describe("Color theme/accent color for the UI (e.g., 'blue', 'green', 'purple')"),
86
+ fontFamily: z
87
+ .string()
88
+ .optional()
89
+ .describe("Font family preference for the UI (e.g., 'Inter', 'SF Pro', 'Roboto')"),
90
+ }, async (input) => {
91
+ try {
92
+ // Build update data
93
+ const updateData = {};
94
+ // Handle direct fields
95
+ if (input.name !== undefined) {
96
+ updateData.name = input.name;
97
+ }
98
+ if (input.timezone !== undefined) {
99
+ updateData.timezone = input.timezone;
100
+ }
101
+ if (input.avatarUrl !== undefined) {
102
+ updateData.avatarUrl = input.avatarUrl;
103
+ }
104
+ // Handle preferences
105
+ const preferences = {};
106
+ if (input.themeMode !== undefined) {
107
+ preferences.themeMode = input.themeMode;
108
+ }
109
+ if (input.colorTheme !== undefined) {
110
+ preferences.colorTheme = input.colorTheme;
111
+ }
112
+ if (input.fontFamily !== undefined) {
113
+ preferences.fontFamily = input.fontFamily;
114
+ }
115
+ if (Object.keys(preferences).length > 0) {
116
+ updateData.preferences = preferences;
117
+ }
118
+ // Check if at least one field is provided
119
+ if (Object.keys(updateData).length === 0) {
120
+ return errorResponse("At least one field must be provided to update the profile");
121
+ }
122
+ const response = await apiClient.updateMe(updateData);
123
+ if (!response.success) {
124
+ return errorResponse(response.error?.message || "Failed to update user profile");
125
+ }
126
+ const user = response.data;
127
+ const updatedFields = [];
128
+ if (input.name !== undefined)
129
+ updatedFields.push("name");
130
+ if (input.timezone !== undefined)
131
+ updatedFields.push("timezone");
132
+ if (input.avatarUrl !== undefined)
133
+ updatedFields.push("avatarUrl");
134
+ if (input.themeMode !== undefined)
135
+ updatedFields.push("themeMode");
136
+ if (input.colorTheme !== undefined)
137
+ updatedFields.push("colorTheme");
138
+ if (input.fontFamily !== undefined)
139
+ updatedFields.push("fontFamily");
140
+ return successResponse(`Successfully updated user profile (fields: ${updatedFields.join(", ")}):\n\n${formatUserProfile(user)}`);
141
+ }
142
+ catch (error) {
143
+ return errorResponse(error instanceof Error ? error.message : "Unknown error");
144
+ }
145
+ });
146
+ }
147
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/tools/user.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,SAAS,iBAAiB,CAAC,IAAU;IACnC,MAAM,KAAK,GAAa;QACtB,SAAS,IAAI,CAAC,IAAI,IAAI,WAAW,EAAE;QACnC,UAAU,IAAI,CAAC,KAAK,EAAE;QACtB,aAAa,IAAI,CAAC,QAAQ,EAAE;QAC5B,eAAe,IAAI,CAAC,SAAS,IAAI,WAAW,EAAE;QAC9C,oBAAoB,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,EAAE;QACnE,iBAAiB,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,EAAE;KACjE,CAAC;IAEF,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAiB,EACjB,SAAoB;IAEpB,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,6PAA6P,EAC7P,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YAEzC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,8BAA8B,CAC1D,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAK,CAAC;YAC5B,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAEjD,OAAO,eAAe,CACpB,oBAAoB,gBAAgB,gBAAgB,IAAI,CAAC,EAAE,EAAE,CAC9D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,sBAAsB;IACtB,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,8TAA8T,EAC9T;QACE,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wEAAwE,CACzE;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,+JAA+J,CAChK;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,EAAE;aACV,QAAQ,CACP,kEAAkE,CACnE;QACH,SAAS,EAAE,CAAC;aACT,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;aACjC,QAAQ,EAAE;aACV,QAAQ,CACP,8GAA8G,CAC/G;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,uEAAuE,CACxE;QACH,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,uEAAuE,CACxE;KACJ,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,oBAAoB;YACpB,MAAM,UAAU,GAKZ,EAAE,CAAC;YAEP,uBAAuB;YACvB,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,UAAU,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YAC/B,CAAC;YACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACjC,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YACvC,CAAC;YACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAClC,UAAU,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YACzC,CAAC;YAED,qBAAqB;YACrB,MAAM,WAAW,GAA6B,EAAE,CAAC;YACjD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAClC,WAAW,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YAC1C,CAAC;YACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACnC,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YAC5C,CAAC;YACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACnC,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YAC5C,CAAC;YAED,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxC,UAAU,CAAC,WAAW,GAAG,WAAW,CAAC;YACvC,CAAC;YAED,0CAA0C;YAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzC,OAAO,aAAa,CAClB,2DAA2D,CAC5D,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAEtD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,+BAA+B,CAC3D,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAK,CAAC;YAC5B,MAAM,aAAa,GAAa,EAAE,CAAC;YAEnC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACjE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACnE,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACrE,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAErE,OAAO,eAAe,CACpB,8CAA8C,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAAE,CACzG,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}