@griffinwork40/clickup-mcp-server 1.1.4 → 1.1.5

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.
Files changed (97) hide show
  1. package/dist/schemas.d.ts +33 -0
  2. package/dist/schemas.d.ts.map +1 -0
  3. package/dist/schemas.js +34 -0
  4. package/dist/schemas.js.map +1 -0
  5. package/dist/server.d.ts +10 -0
  6. package/dist/server.d.ts.map +1 -0
  7. package/dist/server.js +56 -0
  8. package/dist/server.js.map +1 -0
  9. package/dist/tools/comments.d.ts +10 -0
  10. package/dist/tools/comments.d.ts.map +1 -0
  11. package/dist/tools/comments.js +123 -0
  12. package/dist/tools/comments.js.map +1 -0
  13. package/dist/tools/custom-fields.d.ts +10 -0
  14. package/dist/tools/custom-fields.d.ts.map +1 -0
  15. package/dist/tools/custom-fields.js +68 -0
  16. package/dist/tools/custom-fields.js.map +1 -0
  17. package/dist/tools/hierarchy.d.ts +10 -0
  18. package/dist/tools/hierarchy.d.ts.map +1 -0
  19. package/dist/tools/hierarchy.js +188 -0
  20. package/dist/tools/hierarchy.js.map +1 -0
  21. package/dist/tools/index.d.ts +13 -0
  22. package/dist/tools/index.d.ts.map +1 -0
  23. package/dist/tools/index.js +13 -0
  24. package/dist/tools/index.js.map +1 -0
  25. package/dist/tools/lists.d.ts +10 -0
  26. package/dist/tools/lists.d.ts.map +1 -0
  27. package/dist/tools/lists.js +148 -0
  28. package/dist/tools/lists.js.map +1 -0
  29. package/dist/tools/tasks-analytics.d.ts +10 -0
  30. package/dist/tools/tasks-analytics.d.ts.map +1 -0
  31. package/dist/tools/tasks-analytics.js +160 -0
  32. package/dist/tools/tasks-analytics.js.map +1 -0
  33. package/dist/tools/tasks-get.d.ts +10 -0
  34. package/dist/tools/tasks-get.d.ts.map +1 -0
  35. package/dist/tools/tasks-get.js +209 -0
  36. package/dist/tools/tasks-get.js.map +1 -0
  37. package/dist/tools/tasks-read.d.ts +10 -0
  38. package/dist/tools/tasks-read.d.ts.map +1 -0
  39. package/dist/tools/tasks-read.js +379 -0
  40. package/dist/tools/tasks-read.js.map +1 -0
  41. package/dist/tools/tasks-search.d.ts +10 -0
  42. package/dist/tools/tasks-search.d.ts.map +1 -0
  43. package/dist/tools/tasks-search.js +176 -0
  44. package/dist/tools/tasks-search.js.map +1 -0
  45. package/dist/tools/tasks-write.d.ts +10 -0
  46. package/dist/tools/tasks-write.d.ts.map +1 -0
  47. package/dist/tools/tasks-write.js +232 -0
  48. package/dist/tools/tasks-write.js.map +1 -0
  49. package/dist/tools/time-tracking.d.ts +10 -0
  50. package/dist/tools/time-tracking.d.ts.map +1 -0
  51. package/dist/tools/time-tracking.js +180 -0
  52. package/dist/tools/time-tracking.js.map +1 -0
  53. package/dist/utils/api-client.d.ts +17 -0
  54. package/dist/utils/api-client.d.ts.map +1 -0
  55. package/dist/utils/api-client.js +77 -0
  56. package/dist/utils/api-client.js.map +1 -0
  57. package/dist/utils/csv-export.d.ts +29 -0
  58. package/dist/utils/csv-export.d.ts.map +1 -0
  59. package/dist/utils/csv-export.js +204 -0
  60. package/dist/utils/csv-export.js.map +1 -0
  61. package/dist/utils/custom-fields.d.ts +25 -0
  62. package/dist/utils/custom-fields.d.ts.map +1 -0
  63. package/dist/utils/custom-fields.js +132 -0
  64. package/dist/utils/custom-fields.js.map +1 -0
  65. package/dist/utils/data-processing.d.ts +10 -0
  66. package/dist/utils/data-processing.d.ts.map +1 -0
  67. package/dist/utils/data-processing.js +18 -0
  68. package/dist/utils/data-processing.js.map +1 -0
  69. package/dist/utils/formatters/base.d.ts +21 -0
  70. package/dist/utils/formatters/base.d.ts.map +1 -0
  71. package/dist/utils/formatters/base.js +30 -0
  72. package/dist/utils/formatters/base.js.map +1 -0
  73. package/dist/utils/formatters/entities.d.ts +34 -0
  74. package/dist/utils/formatters/entities.d.ts.map +1 -0
  75. package/dist/utils/formatters/entities.js +146 -0
  76. package/dist/utils/formatters/entities.js.map +1 -0
  77. package/dist/utils/formatters/index.d.ts +6 -0
  78. package/dist/utils/formatters/index.d.ts.map +1 -0
  79. package/dist/utils/formatters/index.js +6 -0
  80. package/dist/utils/formatters/index.js.map +1 -0
  81. package/dist/utils/index.d.ts +13 -0
  82. package/dist/utils/index.d.ts.map +1 -0
  83. package/dist/utils/index.js +21 -0
  84. package/dist/utils/index.js.map +1 -0
  85. package/dist/utils/task-analytics.d.ts +14 -0
  86. package/dist/utils/task-analytics.d.ts.map +1 -0
  87. package/dist/utils/task-analytics.js +67 -0
  88. package/dist/utils/task-analytics.js.map +1 -0
  89. package/dist/utils/task-counter.d.ts +24 -0
  90. package/dist/utils/task-counter.d.ts.map +1 -0
  91. package/dist/utils/task-counter.js +52 -0
  92. package/dist/utils/task-counter.js.map +1 -0
  93. package/dist/utils/truncation.d.ts +14 -0
  94. package/dist/utils/truncation.d.ts.map +1 -0
  95. package/dist/utils/truncation.js +124 -0
  96. package/dist/utils/truncation.js.map +1 -0
  97. package/package.json +5 -5
@@ -0,0 +1,204 @@
1
+ /**
2
+ * CSV export utilities for ClickUp MCP server.
3
+ * Export tasks to CSV format with custom field support.
4
+ */
5
+ import { MAX_LIMIT } from "../constants.js";
6
+ import { makeApiRequest } from "./api-client.js";
7
+ import { filterTasksByStatus } from "./task-analytics.js";
8
+ import { extractCustomFieldValue, getCustomField } from "./custom-fields.js";
9
+ /**
10
+ * Escape CSV fields to handle commas, quotes, and newlines
11
+ */
12
+ export function escapeCSV(value) {
13
+ if (value === null || value === undefined)
14
+ return '';
15
+ const stringValue = String(value);
16
+ // If contains comma, quote, or newline, wrap in quotes and escape quotes
17
+ if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
18
+ return `"${stringValue.replace(/"/g, '""')}"`;
19
+ }
20
+ return stringValue;
21
+ }
22
+ /**
23
+ * Convert task to CSV row array
24
+ */
25
+ export function taskToCSVRow(task, fieldOrder) {
26
+ const row = [];
27
+ for (const fieldName of fieldOrder) {
28
+ let value = '';
29
+ // Standard fields
30
+ if (fieldName === 'Task ID') {
31
+ value = task.id;
32
+ }
33
+ else if (fieldName === 'Name') {
34
+ value = task.name;
35
+ }
36
+ else if (fieldName === 'Status') {
37
+ value = task.status?.status || '';
38
+ }
39
+ else if (fieldName === 'Date Created') {
40
+ value = task.date_created ? new Date(parseInt(task.date_created)).toISOString() : '';
41
+ }
42
+ else if (fieldName === 'Date Updated') {
43
+ value = task.date_updated ? new Date(parseInt(task.date_updated)).toISOString() : '';
44
+ }
45
+ else if (fieldName === 'URL') {
46
+ value = task.url || '';
47
+ }
48
+ else if (fieldName === 'Assignees') {
49
+ value = task.assignees?.map(a => a.username || a.email).join('; ') || '';
50
+ }
51
+ else if (fieldName === 'Creator') {
52
+ value = task.creator?.username || task.creator?.email || '';
53
+ }
54
+ else if (fieldName === 'Due Date') {
55
+ value = task.due_date ? new Date(parseInt(task.due_date)).toISOString() : '';
56
+ }
57
+ else if (fieldName === 'Priority') {
58
+ value = task.priority?.priority || '';
59
+ }
60
+ else if (fieldName === 'Description') {
61
+ value = task.description || task.text_content || '';
62
+ }
63
+ else if (fieldName === 'Tags') {
64
+ value = task.tags?.map(t => t.name).join('; ') || '';
65
+ }
66
+ else if (fieldName === 'phone_number') {
67
+ // Combined phone number field for ElevenLabs compatibility
68
+ // First check if a real phone_number custom field exists
69
+ const realPhoneNumberField = task.custom_fields?.find(f => f.name === 'phone_number');
70
+ if (realPhoneNumberField && (realPhoneNumberField.value !== null && realPhoneNumberField.value !== undefined && realPhoneNumberField.value !== '')) {
71
+ // Use the real phone_number field value (already normalized)
72
+ value = extractCustomFieldValue(realPhoneNumberField);
73
+ }
74
+ else {
75
+ // No real phone_number field, use synthetic logic
76
+ // Priority: Personal Phone > Biz Phone number > first phone field found
77
+ const personalPhone = getCustomField(task, 'Personal Phone');
78
+ const bizPhone = getCustomField(task, 'Biz Phone number');
79
+ if (personalPhone) {
80
+ value = personalPhone;
81
+ }
82
+ else if (bizPhone) {
83
+ value = bizPhone;
84
+ }
85
+ else {
86
+ // Try to find any phone field
87
+ const phoneFields = task.custom_fields?.filter(f => f.type === 'phone' ||
88
+ f.type === 'phone_number' ||
89
+ (typeof f.name === 'string' && /phone/i.test(f.name))) || [];
90
+ if (phoneFields.length > 0) {
91
+ value = extractCustomFieldValue(phoneFields[0]);
92
+ }
93
+ }
94
+ }
95
+ }
96
+ else {
97
+ // Custom field
98
+ value = getCustomField(task, fieldName);
99
+ }
100
+ row.push(escapeCSV(value));
101
+ }
102
+ return row;
103
+ }
104
+ /**
105
+ * Export tasks to CSV format
106
+ */
107
+ export async function exportTasksToCSV(listId, options = {}) {
108
+ const { archived = false, include_closed = false, statuses, custom_fields, include_standard_fields = true, add_phone_number_column = false } = options;
109
+ const limit = MAX_LIMIT;
110
+ let offset = 0;
111
+ let allTasks = [];
112
+ let hasMore = true;
113
+ // Step 1: Fetch all tasks with pagination
114
+ while (hasMore) {
115
+ const queryParams = {
116
+ archived,
117
+ include_closed,
118
+ page: Math.floor(offset / limit),
119
+ limit: limit // FIX: Actually send limit to API
120
+ };
121
+ try {
122
+ const data = await makeApiRequest(`list/${listId}/task`, "GET", undefined, queryParams);
123
+ const tasks = data.tasks || [];
124
+ allTasks.push(...tasks);
125
+ hasMore = tasks.length === limit;
126
+ offset += limit;
127
+ }
128
+ catch (error) {
129
+ throw error;
130
+ }
131
+ }
132
+ // Step 2: Filter by status if specified
133
+ if (statuses && statuses.length > 0) {
134
+ allTasks = filterTasksByStatus(allTasks, statuses);
135
+ }
136
+ if (allTasks.length === 0) {
137
+ return ''; // Return empty CSV if no tasks
138
+ }
139
+ // Note: The list endpoint already returns custom fields with values,
140
+ // so we don't need to fetch individual task details!
141
+ // Step 3: Build field order and headers
142
+ const standardFields = [
143
+ 'Task ID',
144
+ 'Name',
145
+ 'Status',
146
+ 'Date Created',
147
+ 'Date Updated',
148
+ 'URL',
149
+ 'Assignees',
150
+ 'Creator',
151
+ 'Due Date',
152
+ 'Priority',
153
+ 'Description',
154
+ 'Tags'
155
+ ];
156
+ // Collect all custom field names from tasks
157
+ const allCustomFieldNames = new Set();
158
+ for (const task of allTasks) {
159
+ if (task.custom_fields) {
160
+ for (const field of task.custom_fields) {
161
+ allCustomFieldNames.add(field.name);
162
+ }
163
+ }
164
+ }
165
+ // Determine which custom fields to include
166
+ const customFieldsToInclude = custom_fields && custom_fields.length > 0
167
+ ? custom_fields.filter(name => allCustomFieldNames.has(name))
168
+ : Array.from(allCustomFieldNames);
169
+ // Build field order
170
+ const fieldOrder = [];
171
+ if (include_standard_fields) {
172
+ fieldOrder.push(...standardFields);
173
+ }
174
+ fieldOrder.push(...customFieldsToInclude);
175
+ // Add phone_number column if requested (for ElevenLabs compatibility)
176
+ if (add_phone_number_column) {
177
+ // Check if phone_number already exists (e.g., as a real custom field)
178
+ const phoneNumberIdx = fieldOrder.indexOf('phone_number');
179
+ if (phoneNumberIdx === -1) {
180
+ // phone_number doesn't exist, add our synthetic one
181
+ // Find Email index to insert after it
182
+ const emailIdx = fieldOrder.indexOf('Email');
183
+ if (emailIdx >= 0) {
184
+ fieldOrder.splice(emailIdx + 1, 0, 'phone_number');
185
+ }
186
+ else {
187
+ // If no Email field, add at the end
188
+ fieldOrder.push('phone_number');
189
+ }
190
+ }
191
+ // If phone_number already exists, use the existing one (no duplicate needed)
192
+ }
193
+ // Step 4: Build CSV
194
+ const csvRows = [];
195
+ // Headers
196
+ csvRows.push(fieldOrder.map(escapeCSV).join(','));
197
+ // Data rows
198
+ for (const task of allTasks) {
199
+ const row = taskToCSVRow(task, fieldOrder);
200
+ csvRows.push(row.join(','));
201
+ }
202
+ return csvRows.join('\n');
203
+ }
204
+ //# sourceMappingURL=csv-export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-export.js","sourceRoot":"","sources":["../../src/utils/csv-export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Custom field utilities for ClickUp MCP server.
3
+ * Handle custom field extraction and phone number normalization.
4
+ */
5
+ import type { ClickUpTask, ClickUpCustomField } from "../types.js";
6
+ /**
7
+ * Normalize phone number to E.164 format
8
+ * E.164 format: ^\+?[1-9]\d{1,14}$
9
+ * Rules:
10
+ * - Optional + at the start
11
+ * - Must start with digit 1-9 (not 0)
12
+ * - Followed by 1-14 digits only
13
+ * - NO spaces, dashes, parentheses, dots, or other characters
14
+ * - NO extensions
15
+ */
16
+ export declare function normalizePhoneToE164(phone: string | null | undefined): string;
17
+ /**
18
+ * Extract value from a custom field based on its type
19
+ */
20
+ export declare function extractCustomFieldValue(field: ClickUpCustomField): string;
21
+ /**
22
+ * Get custom field value by name (prefers field with value if multiple exist)
23
+ */
24
+ export declare function getCustomField(task: ClickUpTask, fieldName: string, preferredType?: string): string;
25
+ //# sourceMappingURL=custom-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-fields.d.ts","sourceRoot":"","sources":["../../src/utils/custom-fields.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEnE;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CA0D7E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAgCzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBnG"}
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Custom field utilities for ClickUp MCP server.
3
+ * Handle custom field extraction and phone number normalization.
4
+ */
5
+ /**
6
+ * Normalize phone number to E.164 format
7
+ * E.164 format: ^\+?[1-9]\d{1,14}$
8
+ * Rules:
9
+ * - Optional + at the start
10
+ * - Must start with digit 1-9 (not 0)
11
+ * - Followed by 1-14 digits only
12
+ * - NO spaces, dashes, parentheses, dots, or other characters
13
+ * - NO extensions
14
+ */
15
+ export function normalizePhoneToE164(phone) {
16
+ if (!phone)
17
+ return '';
18
+ let normalized = String(phone).trim();
19
+ if (!normalized)
20
+ return '';
21
+ // Remove extensions (x206, ext 123, extension 456, etc.)
22
+ // Match: x, ext, extension followed by optional space and digits
23
+ normalized = normalized.replace(/\s*(?:x|ext|extension)\s*\d+/i, '');
24
+ // Check if it starts with + (preserve it)
25
+ const hasPlus = normalized.startsWith('+');
26
+ if (hasPlus) {
27
+ normalized = normalized.substring(1);
28
+ }
29
+ // Remove all non-digit characters
30
+ normalized = normalized.replace(/\D/g, '');
31
+ // If empty after cleaning, return empty
32
+ if (!normalized)
33
+ return '';
34
+ // If number starts with 0, it's invalid for E.164 (must start with 1-9)
35
+ if (normalized.startsWith('0')) {
36
+ return '';
37
+ }
38
+ // Check if it already has a country code (starts with 1-9 and has 10+ digits)
39
+ // If it's 10 digits and starts with 1, assume it's US/Canada with country code
40
+ // If it's 10 digits and doesn't start with 1, assume it's missing country code
41
+ // If it's 11 digits and starts with 1, it already has country code
42
+ // If it's more than 11 digits, assume it already has country code
43
+ if (normalized.length === 10) {
44
+ // 10 digits without country code - add +1 for US/Canada
45
+ normalized = '1' + normalized;
46
+ }
47
+ else if (normalized.length === 11 && normalized.startsWith('1')) {
48
+ // Already has US/Canada country code
49
+ // Keep as is
50
+ }
51
+ else if (normalized.length < 10) {
52
+ // Too short to be a valid phone number
53
+ return '';
54
+ }
55
+ else if (normalized.length > 15) {
56
+ // Too long for E.164 (max 15 digits after country code)
57
+ return '';
58
+ }
59
+ // Add + prefix
60
+ normalized = '+' + normalized;
61
+ // Validate E.164 format: ^\+?[1-9]\d{1,14}$
62
+ // We already have the +, so check: [1-9]\d{1,14}
63
+ const e164Regex = /^\+[1-9]\d{1,14}$/;
64
+ if (!e164Regex.test(normalized)) {
65
+ return '';
66
+ }
67
+ return normalized;
68
+ }
69
+ /**
70
+ * Extract value from a custom field based on its type
71
+ */
72
+ export function extractCustomFieldValue(field) {
73
+ if (!field || field.value === null || field.value === undefined || field.value === '')
74
+ return '';
75
+ // Check if this is a phone number field (by type or name)
76
+ const isPhoneField = field.type === 'phone' ||
77
+ field.type === 'phone_number' ||
78
+ (typeof field.name === 'string' && /phone/i.test(field.name));
79
+ // Handle different field types
80
+ if (field.type === 'email' || field.type === 'url' || field.type === 'text' || field.type === 'short_text') {
81
+ const value = String(field.value).trim();
82
+ // Normalize if it's a phone field
83
+ return isPhoneField ? normalizePhoneToE164(value) : value;
84
+ }
85
+ else if (field.type === 'phone' || field.type === 'phone_number') {
86
+ return normalizePhoneToE164(field.value);
87
+ }
88
+ else if (field.type === 'number' || field.type === 'currency') {
89
+ return String(field.value);
90
+ }
91
+ else if (field.type === 'date') {
92
+ return new Date(parseInt(field.value)).toISOString().split('T')[0];
93
+ }
94
+ else if (field.type === 'dropdown') {
95
+ return field.value?.label || field.value?.name || String(field.value || '');
96
+ }
97
+ else if (field.type === 'labels') {
98
+ return Array.isArray(field.value) ? field.value.map((v) => v.label || v.name || v).join('; ') : '';
99
+ }
100
+ else if (field.type === 'checklist') {
101
+ return Array.isArray(field.value) ? field.value.map((item) => item.name).join('; ') : '';
102
+ }
103
+ else if (field.type === 'checkbox') {
104
+ return field.value ? 'Yes' : 'No';
105
+ }
106
+ // Default: return trimmed string, normalize if it's a phone field
107
+ const value = String(field.value || '').trim();
108
+ return isPhoneField ? normalizePhoneToE164(value) : value;
109
+ }
110
+ /**
111
+ * Get custom field value by name (prefers field with value if multiple exist)
112
+ */
113
+ export function getCustomField(task, fieldName, preferredType) {
114
+ if (!task.custom_fields)
115
+ return '';
116
+ // Find all fields with matching name
117
+ const matchingFields = task.custom_fields.filter(f => f.name === fieldName);
118
+ if (matchingFields.length === 0)
119
+ return '';
120
+ // If preferred type specified, try that first
121
+ if (preferredType) {
122
+ const typedField = matchingFields.find(f => f.type === preferredType && f.value);
123
+ if (typedField) {
124
+ return extractCustomFieldValue(typedField);
125
+ }
126
+ }
127
+ // Prefer field with a value
128
+ const fieldWithValue = matchingFields.find(f => f.value !== null && f.value !== undefined && f.value !== '');
129
+ const field = fieldWithValue || matchingFields[0];
130
+ return extractCustomFieldValue(field);
131
+ }
132
+ //# sourceMappingURL=custom-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-fields.js","sourceRoot":"","sources":["../../src/utils/custom-fields.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Data processing utilities for ClickUp MCP server.
3
+ * Handle pagination and response metadata extraction.
4
+ */
5
+ import type { PaginationInfo } from "../types.js";
6
+ /**
7
+ * Extract pagination information from response
8
+ */
9
+ export declare function getPagination(total: number | undefined, count: number, offset: number, limit: number): PaginationInfo;
10
+ //# sourceMappingURL=data-processing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-processing.d.ts","sourceRoot":"","sources":["../../src/utils/data-processing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,cAAc,CAUhB"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Data processing utilities for ClickUp MCP server.
3
+ * Handle pagination and response metadata extraction.
4
+ */
5
+ /**
6
+ * Extract pagination information from response
7
+ */
8
+ export function getPagination(total, count, offset, limit) {
9
+ const hasMore = total ? (offset + count < total) : count === limit;
10
+ return {
11
+ total,
12
+ count,
13
+ offset,
14
+ has_more: hasMore,
15
+ next_offset: hasMore ? offset + count : undefined
16
+ };
17
+ }
18
+ //# sourceMappingURL=data-processing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-processing.js","sourceRoot":"","sources":["../../src/utils/data-processing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAyB,EACzB,KAAa,EACb,MAAc,EACd,KAAa;IAEb,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC;IAEnE,OAAO;QACL,KAAK;QACL,KAAK;QACL,MAAM;QACN,QAAQ,EAAE,OAAO;QACjB,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS;KAClD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Base formatting utilities for ClickUp MCP server.
3
+ * Simple, reusable formatting primitives used by other formatters.
4
+ */
5
+ import type { TruncationInfo } from "../../types.js";
6
+ /**
7
+ * Format a timestamp as human-readable date
8
+ */
9
+ export declare function formatDate(timestamp: string | number | undefined): string;
10
+ /**
11
+ * Format priority value as human-readable string
12
+ */
13
+ export declare function formatPriority(priority?: {
14
+ priority: string;
15
+ color: string;
16
+ }): string;
17
+ /**
18
+ * Format truncation information as text
19
+ */
20
+ export declare function formatTruncationInfo(truncation: TruncationInfo | null): string;
21
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/utils/formatters/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAKzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAGrF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CAI9E"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Base formatting utilities for ClickUp MCP server.
3
+ * Simple, reusable formatting primitives used by other formatters.
4
+ */
5
+ /**
6
+ * Format a timestamp as human-readable date
7
+ */
8
+ export function formatDate(timestamp) {
9
+ if (!timestamp)
10
+ return "Not set";
11
+ const date = new Date(typeof timestamp === "string" ? parseInt(timestamp) : timestamp);
12
+ return date.toISOString().replace("T", " ").substring(0, 19) + " UTC";
13
+ }
14
+ /**
15
+ * Format priority value as human-readable string
16
+ */
17
+ export function formatPriority(priority) {
18
+ if (!priority)
19
+ return "None";
20
+ return priority.priority;
21
+ }
22
+ /**
23
+ * Format truncation information as text
24
+ */
25
+ export function formatTruncationInfo(truncation) {
26
+ if (!truncation)
27
+ return "";
28
+ return `\n\n---\n\u26a0\ufe0f ${truncation.truncation_message}`;
29
+ }
30
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/utils/formatters/base.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,SAAsC;IAC/D,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAEjC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACvF,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAA8C;IAC3E,IAAI,CAAC,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC7B,OAAO,QAAQ,CAAC,QAAQ,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAiC;IACpE,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAE3B,OAAO,yBAAyB,UAAU,CAAC,kBAAkB,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Entity formatters for ClickUp MCP server.
3
+ * Format ClickUp entities (tasks, lists, spaces, etc.) as markdown.
4
+ */
5
+ import type { ClickUpTask, ClickUpList, ClickUpSpace, ClickUpFolder, ClickUpComment, ClickUpTimeEntry } from "../../types.js";
6
+ /**
7
+ * Format a task as markdown (full detail)
8
+ */
9
+ export declare function formatTaskMarkdown(task: ClickUpTask): string;
10
+ /**
11
+ * Format a task as compact markdown (essential fields only)
12
+ */
13
+ export declare function formatTaskCompact(task: ClickUpTask): string;
14
+ /**
15
+ * Format a list as markdown
16
+ */
17
+ export declare function formatListMarkdown(list: ClickUpList): string;
18
+ /**
19
+ * Format a space as markdown
20
+ */
21
+ export declare function formatSpaceMarkdown(space: ClickUpSpace): string;
22
+ /**
23
+ * Format a folder as markdown
24
+ */
25
+ export declare function formatFolderMarkdown(folder: ClickUpFolder): string;
26
+ /**
27
+ * Format a comment as markdown
28
+ */
29
+ export declare function formatCommentMarkdown(comment: ClickUpComment): string;
30
+ /**
31
+ * Format a time entry as markdown
32
+ */
33
+ export declare function formatTimeEntryMarkdown(entry: ClickUpTimeEntry): string;
34
+ //# sourceMappingURL=entities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../../src/utils/formatters/entities.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAGxB;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAkC5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAM3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAwB5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAkB/D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAqBlE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAWrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CA2BvE"}