@doist/todoist-ai 4.17.0 → 4.17.2
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/filter-helpers.d.ts +1 -1
- package/dist/filter-helpers.d.ts.map +1 -1
- package/dist/index.d.ts +390 -584
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/main.js +1 -1
- package/dist/mcp-helpers.d.ts +1 -37
- package/dist/mcp-helpers.d.ts.map +1 -1
- package/dist/{mcp-server-BADReNAy.js → mcp-server-BSQxi0xQ.js} +1067 -1070
- package/dist/todoist-tool.d.ts +6 -2
- package/dist/todoist-tool.d.ts.map +1 -1
- package/dist/tool-helpers.d.ts +49 -20
- package/dist/tool-helpers.d.ts.map +1 -1
- package/dist/tools/add-comments.d.ts +49 -38
- package/dist/tools/add-comments.d.ts.map +1 -1
- package/dist/tools/add-projects.d.ts +10 -22
- package/dist/tools/add-projects.d.ts.map +1 -1
- package/dist/tools/add-sections.d.ts +1 -15
- package/dist/tools/add-sections.d.ts.map +1 -1
- package/dist/tools/add-tasks.d.ts +33 -47
- package/dist/tools/add-tasks.d.ts.map +1 -1
- package/dist/tools/complete-tasks.d.ts +3 -17
- package/dist/tools/complete-tasks.d.ts.map +1 -1
- package/dist/tools/delete-object.d.ts +2 -16
- package/dist/tools/delete-object.d.ts.map +1 -1
- package/dist/tools/fetch.d.ts +3 -8
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/find-activity.d.ts +15 -29
- package/dist/tools/find-activity.d.ts.map +1 -1
- package/dist/tools/find-comments.d.ts +51 -40
- package/dist/tools/find-comments.d.ts.map +1 -1
- package/dist/tools/find-completed-tasks.d.ts +29 -43
- package/dist/tools/find-completed-tasks.d.ts.map +1 -1
- package/dist/tools/find-project-collaborators.d.ts +20 -20
- package/dist/tools/find-project-collaborators.d.ts.map +1 -1
- package/dist/tools/find-projects.d.ts +7 -21
- package/dist/tools/find-projects.d.ts.map +1 -1
- package/dist/tools/find-sections.d.ts +1 -15
- package/dist/tools/find-sections.d.ts.map +1 -1
- package/dist/tools/find-tasks-by-date.d.ts +27 -41
- package/dist/tools/find-tasks-by-date.d.ts.map +1 -1
- package/dist/tools/find-tasks.d.ts +29 -43
- package/dist/tools/find-tasks.d.ts.map +1 -1
- package/dist/tools/get-overview.d.ts +9 -16
- package/dist/tools/get-overview.d.ts.map +1 -1
- package/dist/tools/manage-assignments.d.ts +5 -19
- package/dist/tools/manage-assignments.d.ts.map +1 -1
- package/dist/tools/search.d.ts +11 -7
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/update-comments.d.ts +49 -38
- package/dist/tools/update-comments.d.ts.map +1 -1
- package/dist/tools/update-projects.d.ts +7 -19
- package/dist/tools/update-projects.d.ts.map +1 -1
- package/dist/tools/update-sections.d.ts +1 -15
- package/dist/tools/update-sections.d.ts.map +1 -1
- package/dist/tools/update-tasks.d.ts +33 -47
- package/dist/tools/update-tasks.d.ts.map +1 -1
- package/dist/tools/user-info.d.ts +1 -15
- package/dist/tools/user-info.d.ts.map +1 -1
- package/dist/utils/output-schemas.d.ts +60 -32
- package/dist/utils/output-schemas.d.ts.map +1 -1
- package/dist/utils/sanitize-data.d.ts +3 -2
- package/dist/utils/sanitize-data.d.ts.map +1 -1
- package/dist/utils/test-helpers.d.ts +1 -33
- package/dist/utils/test-helpers.d.ts.map +1 -1
- package/package.json +13 -13
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getTaskUrl as he, getProjectUrl as me, TodoistApi as
|
|
2
|
-
import { McpServer as
|
|
1
|
+
import { getTaskUrl as he, getProjectUrl as me, TodoistApi as De } from "@doist/todoist-api-typescript";
|
|
2
|
+
import { McpServer as xe } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import F, { z as s } from "zod";
|
|
4
|
-
import { addDays as fe, formatISO as
|
|
4
|
+
import { addDays as fe, formatISO as Ae } from "date-fns";
|
|
5
5
|
function X(e) {
|
|
6
6
|
if (e == null)
|
|
7
7
|
return e;
|
|
@@ -12,7 +12,7 @@ function X(e) {
|
|
|
12
12
|
for (const [o, n] of Object.entries(e))
|
|
13
13
|
if (n !== null) {
|
|
14
14
|
const r = X(n);
|
|
15
|
-
if (
|
|
15
|
+
if (r !== null && typeof r == "object" && !Array.isArray(r) && Object.keys(r).length === 0)
|
|
16
16
|
continue;
|
|
17
17
|
t[o] = r;
|
|
18
18
|
}
|
|
@@ -20,42 +20,40 @@ function X(e) {
|
|
|
20
20
|
}
|
|
21
21
|
return e;
|
|
22
22
|
}
|
|
23
|
-
const
|
|
24
|
-
function
|
|
23
|
+
const Ue = process.env.USE_STRUCTURED_CONTENT === "true" || process.env.NODE_ENV === "test";
|
|
24
|
+
function Pe({
|
|
25
25
|
textContent: e,
|
|
26
26
|
structuredContent: t
|
|
27
27
|
}) {
|
|
28
|
-
const o = X(t);
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{ type: "text", mimeType: "application/json", text: n }
|
|
39
|
-
]
|
|
40
|
-
};
|
|
28
|
+
const o = X(t), n = {};
|
|
29
|
+
if (e && (n.content = [{ type: "text", text: e }]), t && (n.structuredContent = o), !Ue && t) {
|
|
30
|
+
const r = JSON.stringify(o);
|
|
31
|
+
n.content || (n.content = []), n.content.push({
|
|
32
|
+
type: "text",
|
|
33
|
+
mimeType: "application/json",
|
|
34
|
+
text: r
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return n;
|
|
41
38
|
}
|
|
42
|
-
function
|
|
39
|
+
function Ee(e) {
|
|
43
40
|
return {
|
|
44
41
|
content: [{ type: "text", text: e }],
|
|
45
42
|
isError: !0
|
|
46
43
|
};
|
|
47
44
|
}
|
|
48
|
-
function
|
|
45
|
+
function I(e, t, o) {
|
|
49
46
|
const n = async (r, i) => {
|
|
50
47
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
const { textContent: c, structuredContent: a } = await e.execute(
|
|
49
|
+
r,
|
|
50
|
+
o
|
|
51
|
+
);
|
|
52
|
+
return Pe({ textContent: c, structuredContent: a });
|
|
53
|
+
} catch (c) {
|
|
54
|
+
console.error(`Error executing tool ${e.name}:`, { args: r, error: c });
|
|
55
|
+
const a = c instanceof Error ? c.message : "An unknown error occurred";
|
|
56
|
+
return Ee(a);
|
|
59
57
|
}
|
|
60
58
|
};
|
|
61
59
|
t.registerTool(
|
|
@@ -68,273 +66,52 @@ function w(e, t, o) {
|
|
|
68
66
|
n
|
|
69
67
|
);
|
|
70
68
|
}
|
|
71
|
-
|
|
72
|
-
id: s.string().describe("The unique ID of the task."),
|
|
73
|
-
content: s.string().describe("The task title/content."),
|
|
74
|
-
description: s.string().describe("The task description."),
|
|
75
|
-
dueDate: s.string().optional().describe("The due date of the task (ISO 8601 format)."),
|
|
76
|
-
recurring: s.union([s.boolean(), s.string()]).describe("Whether the task is recurring, or the recurrence string."),
|
|
77
|
-
deadlineDate: s.string().optional().describe("The deadline date of the task (ISO 8601 format)."),
|
|
78
|
-
priority: s.number().describe("The priority level (1-4, where 1 is highest priority)."),
|
|
79
|
-
projectId: s.string().describe("The ID of the project this task belongs to."),
|
|
80
|
-
sectionId: s.string().optional().describe("The ID of the section this task belongs to."),
|
|
81
|
-
parentId: s.string().optional().describe("The ID of the parent task (for subtasks)."),
|
|
82
|
-
labels: s.array(s.string()).describe("The labels attached to this task."),
|
|
83
|
-
duration: s.string().optional().describe('The duration of the task (e.g., "2h30m").'),
|
|
84
|
-
responsibleUid: s.string().optional().describe("The UID of the user responsible for this task."),
|
|
85
|
-
assignedByUid: s.string().optional().describe("The UID of the user who assigned this task."),
|
|
86
|
-
checked: s.boolean().describe("Whether the task is checked/completed."),
|
|
87
|
-
completedAt: s.string().optional().describe("When the task was completed (ISO 8601 format).")
|
|
88
|
-
}), ee = s.object({
|
|
89
|
-
id: s.string().describe("The unique ID of the project."),
|
|
90
|
-
name: s.string().describe("The name of the project."),
|
|
91
|
-
color: s.string().describe("The color of the project."),
|
|
92
|
-
isFavorite: s.boolean().describe("Whether the project is marked as favorite."),
|
|
93
|
-
isShared: s.boolean().describe("Whether the project is shared."),
|
|
94
|
-
parentId: s.string().optional().describe("The ID of the parent project (for sub-projects)."),
|
|
95
|
-
inboxProject: s.boolean().describe("Whether this is the inbox project."),
|
|
96
|
-
viewStyle: s.string().describe("The view style of the project (list, board, calendar).")
|
|
97
|
-
}), te = s.object({
|
|
98
|
-
id: s.string().describe("The unique ID of the section."),
|
|
99
|
-
name: s.string().describe("The name of the section.")
|
|
100
|
-
}), Ee = s.object({
|
|
101
|
-
resourceType: s.string().describe("The type of resource."),
|
|
102
|
-
fileName: s.string().optional().describe("The name of the file."),
|
|
103
|
-
fileSize: s.number().optional().describe("The size of the file in bytes."),
|
|
104
|
-
fileType: s.string().optional().describe("The MIME type of the file."),
|
|
105
|
-
fileUrl: s.string().optional().describe("The URL to access the file."),
|
|
106
|
-
fileDuration: s.number().optional().describe("The duration in milliseconds (for audio/video files)."),
|
|
107
|
-
uploadState: s.enum(["pending", "completed"]).optional().describe("The upload state of the file.")
|
|
108
|
-
}), se = s.object({
|
|
109
|
-
id: s.string().describe("The unique ID of the comment."),
|
|
110
|
-
taskId: s.string().optional().describe("The ID of the task this comment belongs to."),
|
|
111
|
-
projectId: s.string().optional().describe("The ID of the project this comment belongs to."),
|
|
112
|
-
content: s.string().describe("The content of the comment."),
|
|
113
|
-
postedAt: s.string().describe("When the comment was posted (ISO 8601 format)."),
|
|
114
|
-
attachment: Ee.optional().describe("File attachment information, if any.")
|
|
115
|
-
}), Oe = s.object({
|
|
116
|
-
id: s.string().describe("The unique ID of the activity event."),
|
|
117
|
-
objectType: s.string().describe("The type of object this event relates to (task, project, etc)."),
|
|
118
|
-
objectId: s.string().describe("The ID of the object this event relates to."),
|
|
119
|
-
eventType: s.string().describe("The type of event (added, updated, deleted, completed, etc)."),
|
|
120
|
-
eventDate: s.string().describe("When the event occurred (ISO 8601 format)."),
|
|
121
|
-
parentProjectId: s.string().optional().describe("The ID of the parent project."),
|
|
122
|
-
parentItemId: s.string().optional().describe("The ID of the parent item."),
|
|
123
|
-
initiatorId: s.string().optional().describe("The ID of the user who initiated this event."),
|
|
124
|
-
extraData: s.record(s.unknown()).describe("Additional event data.")
|
|
125
|
-
}), _e = s.object({
|
|
126
|
-
id: s.string().describe("The unique ID of the user."),
|
|
127
|
-
name: s.string().describe("The full name of the user."),
|
|
128
|
-
email: s.string().describe("The email address of the user.")
|
|
129
|
-
}), Ne = s.object({
|
|
130
|
-
item: s.string().describe("The item that failed (usually an ID or identifier)."),
|
|
131
|
-
error: s.string().describe("The error message."),
|
|
132
|
-
code: s.string().optional().describe("The error code, if available.")
|
|
133
|
-
}), y = {
|
|
134
|
-
// Task management tools
|
|
135
|
-
ADD_TASKS: "add-tasks",
|
|
136
|
-
COMPLETE_TASKS: "complete-tasks",
|
|
137
|
-
UPDATE_TASKS: "update-tasks",
|
|
138
|
-
FIND_TASKS: "find-tasks",
|
|
139
|
-
FIND_TASKS_BY_DATE: "find-tasks-by-date",
|
|
140
|
-
FIND_COMPLETED_TASKS: "find-completed-tasks",
|
|
141
|
-
// Project management tools
|
|
142
|
-
ADD_PROJECTS: "add-projects",
|
|
143
|
-
UPDATE_PROJECTS: "update-projects",
|
|
144
|
-
FIND_PROJECTS: "find-projects",
|
|
145
|
-
// Section management tools
|
|
146
|
-
ADD_SECTIONS: "add-sections",
|
|
147
|
-
UPDATE_SECTIONS: "update-sections",
|
|
148
|
-
FIND_SECTIONS: "find-sections",
|
|
149
|
-
// Comment management tools
|
|
150
|
-
ADD_COMMENTS: "add-comments",
|
|
151
|
-
UPDATE_COMMENTS: "update-comments",
|
|
152
|
-
FIND_COMMENTS: "find-comments",
|
|
153
|
-
// Assignment and collaboration tools
|
|
154
|
-
FIND_PROJECT_COLLABORATORS: "find-project-collaborators",
|
|
155
|
-
MANAGE_ASSIGNMENTS: "manage-assignments",
|
|
156
|
-
// Activity and audit tools
|
|
157
|
-
FIND_ACTIVITY: "find-activity",
|
|
158
|
-
// General tools
|
|
159
|
-
GET_OVERVIEW: "get-overview",
|
|
160
|
-
DELETE_OBJECT: "delete-object",
|
|
161
|
-
USER_INFO: "user-info",
|
|
162
|
-
// OpenAI MCP tools
|
|
163
|
-
SEARCH: "search",
|
|
164
|
-
FETCH: "fetch"
|
|
165
|
-
}, Me = s.object({
|
|
166
|
-
taskId: s.string().optional().describe("The ID of the task to comment on."),
|
|
167
|
-
projectId: s.string().optional().describe(
|
|
168
|
-
'The ID of the project to comment on. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
169
|
-
),
|
|
170
|
-
content: s.string().min(1).describe("The content of the comment.")
|
|
171
|
-
}), Fe = {
|
|
172
|
-
comments: s.array(Me).min(1).describe("The array of comments to add.")
|
|
173
|
-
}, Re = {
|
|
174
|
-
comments: s.array(se).describe("The created comments."),
|
|
175
|
-
totalCount: s.number().describe("The total number of comments created."),
|
|
176
|
-
addedCommentIds: s.array(s.string()).describe("The IDs of the added comments.")
|
|
177
|
-
}, Le = {
|
|
178
|
-
name: y.ADD_COMMENTS,
|
|
179
|
-
description: "Add multiple comments to tasks or projects. Each comment must specify either taskId or projectId.",
|
|
180
|
-
parameters: Fe,
|
|
181
|
-
outputSchema: Re,
|
|
182
|
-
async execute(e, t) {
|
|
183
|
-
const { comments: o } = e;
|
|
184
|
-
for (const [d, l] of o.entries()) {
|
|
185
|
-
if (!l.taskId && !l.projectId)
|
|
186
|
-
throw new Error(
|
|
187
|
-
`Comment ${d + 1}: Either taskId or projectId must be provided.`
|
|
188
|
-
);
|
|
189
|
-
if (l.taskId && l.projectId)
|
|
190
|
-
throw new Error(
|
|
191
|
-
`Comment ${d + 1}: Cannot provide both taskId and projectId. Choose one.`
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
const r = o.some((d) => d.projectId === "inbox") ? await t.getUser() : null, i = o.map(async ({ content: d, taskId: l, projectId: u }) => {
|
|
195
|
-
const p = u === "inbox" && r ? r.inboxProjectId : u;
|
|
196
|
-
return await t.addComment({
|
|
197
|
-
content: d,
|
|
198
|
-
...l ? { taskId: l } : { projectId: p }
|
|
199
|
-
});
|
|
200
|
-
}), a = await Promise.all(i), c = Be({ comments: a });
|
|
201
|
-
return T({
|
|
202
|
-
textContent: c,
|
|
203
|
-
structuredContent: {
|
|
204
|
-
comments: a,
|
|
205
|
-
totalCount: a.length,
|
|
206
|
-
addedCommentIds: a.map((d) => d.id)
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
function Be({ comments: e }) {
|
|
212
|
-
const t = e.filter((i) => i.taskId).length, o = e.filter((i) => i.projectId).length, n = [];
|
|
213
|
-
if (t > 0) {
|
|
214
|
-
const i = t > 1 ? "comments" : "comment";
|
|
215
|
-
n.push(`${t} task ${i}`);
|
|
216
|
-
}
|
|
217
|
-
if (o > 0) {
|
|
218
|
-
const i = o > 1 ? "comments" : "comment";
|
|
219
|
-
n.push(`${o} project ${i}`);
|
|
220
|
-
}
|
|
221
|
-
return n.length > 0 ? `Added ${n.join(" and ")}` : "No comments added";
|
|
222
|
-
}
|
|
223
|
-
const We = s.object({
|
|
224
|
-
name: s.string().min(1).describe("The name of the project."),
|
|
225
|
-
parentId: s.string().optional().describe("The ID of the parent project. If provided, creates this as a sub-project."),
|
|
226
|
-
isFavorite: s.boolean().optional().describe("Whether the project is a favorite. Defaults to false."),
|
|
227
|
-
viewStyle: s.enum(["list", "board", "calendar"]).optional().describe('The project view style. Defaults to "list".')
|
|
228
|
-
}), Ye = {
|
|
229
|
-
projects: s.array(We).min(1).describe("The array of projects to add.")
|
|
230
|
-
}, Ke = {
|
|
231
|
-
projects: s.array(ee).describe("The created projects."),
|
|
232
|
-
totalCount: s.number().describe("The total number of projects created.")
|
|
233
|
-
}, ze = {
|
|
234
|
-
name: y.ADD_PROJECTS,
|
|
235
|
-
description: "Add one or more new projects.",
|
|
236
|
-
parameters: Ye,
|
|
237
|
-
outputSchema: Ke,
|
|
238
|
-
async execute({ projects: e }, t) {
|
|
239
|
-
const o = await Promise.all(e.map((r) => t.addProject(r))), n = Ve({ projects: o });
|
|
240
|
-
return T({
|
|
241
|
-
textContent: n,
|
|
242
|
-
structuredContent: {
|
|
243
|
-
projects: o,
|
|
244
|
-
totalCount: o.length
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
function Ve({ projects: e }) {
|
|
250
|
-
const t = e.length, o = e.map((r) => `• ${r.name} (id=${r.id})`).join(`
|
|
251
|
-
`);
|
|
252
|
-
return `Added ${t} project${t === 1 ? "" : "s"}:
|
|
253
|
-
${o}`;
|
|
254
|
-
}
|
|
255
|
-
const He = s.object({
|
|
256
|
-
name: s.string().min(1).describe("The name of the section."),
|
|
257
|
-
projectId: s.string().min(1).describe(
|
|
258
|
-
'The ID of the project to add the section to. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
259
|
-
)
|
|
260
|
-
}), Ge = {
|
|
261
|
-
sections: s.array(He).min(1).describe("The array of sections to add.")
|
|
262
|
-
}, qe = {
|
|
263
|
-
sections: s.array(te).describe("The created sections."),
|
|
264
|
-
totalCount: s.number().describe("The total number of sections created.")
|
|
265
|
-
}, Je = {
|
|
266
|
-
name: y.ADD_SECTIONS,
|
|
267
|
-
description: "Add one or more new sections to projects.",
|
|
268
|
-
parameters: Ge,
|
|
269
|
-
outputSchema: qe,
|
|
270
|
-
async execute({ sections: e }, t) {
|
|
271
|
-
const n = e.some((c) => c.projectId === "inbox") ? await t.getUser() : null, r = e.map((c) => ({
|
|
272
|
-
...c,
|
|
273
|
-
projectId: c.projectId === "inbox" && n ? n.inboxProjectId : c.projectId
|
|
274
|
-
})), i = await Promise.all(
|
|
275
|
-
r.map((c) => t.addSection(c))
|
|
276
|
-
), a = Xe({ sections: i });
|
|
277
|
-
return T({
|
|
278
|
-
textContent: a,
|
|
279
|
-
structuredContent: {
|
|
280
|
-
sections: i,
|
|
281
|
-
totalCount: i.length
|
|
282
|
-
}
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
function Xe({ sections: e }) {
|
|
287
|
-
const t = e.length, o = e.map((r) => `• ${r.name} (id=${r.id}, projectId=${r.projectId})`).join(`
|
|
288
|
-
`);
|
|
289
|
-
return `Added ${t} section${t === 1 ? "" : "s"}:
|
|
290
|
-
${o}`;
|
|
291
|
-
}
|
|
292
|
-
class P extends Error {
|
|
69
|
+
class U extends Error {
|
|
293
70
|
constructor(t, o) {
|
|
294
71
|
super(`Invalid duration format "${t}": ${o}`), this.name = "DurationParseError";
|
|
295
72
|
}
|
|
296
73
|
}
|
|
297
74
|
function be(e) {
|
|
298
75
|
if (!e || typeof e != "string")
|
|
299
|
-
throw new
|
|
76
|
+
throw new U(e, "Duration must be a non-empty string");
|
|
300
77
|
const t = e.trim().toLowerCase().replace(/\s+/g, "");
|
|
301
78
|
if (!t)
|
|
302
|
-
throw new
|
|
79
|
+
throw new U(e, "Duration must be a non-empty string");
|
|
303
80
|
const o = t.match(/^(?:(\d+(?:\.\d+)?)h)?(?:(\d+(?:\.\d+)?)m)?$/);
|
|
304
81
|
if (!o || !o[1] && !o[2])
|
|
305
|
-
throw new
|
|
82
|
+
throw new U(e, 'Use format like "2h", "30m", "2h30m", or "1.5h"');
|
|
306
83
|
let n = 0;
|
|
307
84
|
const [, r, i] = o;
|
|
308
85
|
if (r) {
|
|
309
|
-
const
|
|
310
|
-
if (Number.isNaN(
|
|
311
|
-
throw new
|
|
312
|
-
n +=
|
|
86
|
+
const c = Number.parseFloat(r);
|
|
87
|
+
if (Number.isNaN(c) || c < 0)
|
|
88
|
+
throw new U(e, "Hours must be a positive number");
|
|
89
|
+
n += c * 60;
|
|
313
90
|
}
|
|
314
91
|
if (i) {
|
|
315
|
-
const
|
|
316
|
-
if (Number.isNaN(
|
|
317
|
-
throw new
|
|
318
|
-
if (
|
|
319
|
-
throw new
|
|
92
|
+
const c = Number.parseFloat(i);
|
|
93
|
+
if (Number.isNaN(c) || c < 0)
|
|
94
|
+
throw new U(e, "Minutes must be a positive number");
|
|
95
|
+
if (c % 1 !== 0)
|
|
96
|
+
throw new U(
|
|
320
97
|
e,
|
|
321
98
|
"Minutes must be a whole number (use decimal hours instead)"
|
|
322
99
|
);
|
|
323
|
-
n +=
|
|
100
|
+
n += c;
|
|
324
101
|
}
|
|
325
102
|
if (n = Math.round(n), n === 0)
|
|
326
|
-
throw new
|
|
103
|
+
throw new U(e, "Duration must be greater than 0 minutes");
|
|
327
104
|
if (n > 1440)
|
|
328
|
-
throw new
|
|
105
|
+
throw new U(e, "Duration cannot exceed 24 hours (1440 minutes)");
|
|
329
106
|
return { minutes: n };
|
|
330
107
|
}
|
|
331
|
-
function
|
|
108
|
+
function Oe(e) {
|
|
332
109
|
if (e <= 0) return "0m";
|
|
333
110
|
const t = Math.floor(e / 60), o = e % 60;
|
|
334
111
|
return t === 0 ? `${o}m` : o === 0 ? `${t}h` : `${t}h${o}m`;
|
|
335
112
|
}
|
|
336
|
-
const
|
|
337
|
-
class
|
|
113
|
+
const A = /* @__PURE__ */ new Map(), R = /* @__PURE__ */ new Map(), G = 300 * 1e3;
|
|
114
|
+
class _e {
|
|
338
115
|
/**
|
|
339
116
|
* Resolve a user name or ID to a user ID by looking up collaborators across all shared projects.
|
|
340
117
|
* Supports exact name matches, partial matches, and email matches.
|
|
@@ -342,39 +119,39 @@ class Qe {
|
|
|
342
119
|
async resolveUser(t, o) {
|
|
343
120
|
if (!o || o.trim().length === 0)
|
|
344
121
|
return null;
|
|
345
|
-
const n = o.trim(), r =
|
|
122
|
+
const n = o.trim(), r = A.get(n);
|
|
346
123
|
if (r && Date.now() - r.timestamp < G)
|
|
347
124
|
return r.result;
|
|
348
125
|
if (/^[0-9]+$/.test(n) || /^[a-f0-9-]{8,}$/i.test(n) && n.includes("-") || /^[a-z0-9_]{6,}$/i.test(n) && !/^[a-z]+[\s-]/.test(n) && /[0-9_]/.test(n)) {
|
|
349
126
|
const i = { userId: n, displayName: n, email: n };
|
|
350
|
-
return
|
|
127
|
+
return A.set(n, { result: i, timestamp: Date.now() }), i;
|
|
351
128
|
}
|
|
352
129
|
try {
|
|
353
130
|
const i = await this.getAllCollaborators(t);
|
|
354
131
|
if (i.length === 0)
|
|
355
|
-
return
|
|
356
|
-
const
|
|
357
|
-
let
|
|
358
|
-
if (
|
|
359
|
-
const l = { userId:
|
|
360
|
-
return
|
|
132
|
+
return A.set(n, { result: null, timestamp: Date.now() }), null;
|
|
133
|
+
const c = o.toLowerCase().trim();
|
|
134
|
+
let a = i.find((l) => l.name.toLowerCase() === c);
|
|
135
|
+
if (a) {
|
|
136
|
+
const l = { userId: a.id, displayName: a.name, email: a.email };
|
|
137
|
+
return A.set(n, { result: l, timestamp: Date.now() }), l;
|
|
361
138
|
}
|
|
362
|
-
if (
|
|
363
|
-
const l = { userId:
|
|
364
|
-
return
|
|
139
|
+
if (a = i.find((l) => l.email.toLowerCase() === c), a) {
|
|
140
|
+
const l = { userId: a.id, displayName: a.name, email: a.email };
|
|
141
|
+
return A.set(n, { result: l, timestamp: Date.now() }), l;
|
|
365
142
|
}
|
|
366
|
-
if (
|
|
367
|
-
const l = { userId:
|
|
368
|
-
return
|
|
143
|
+
if (a = i.find((l) => l.name.toLowerCase().includes(c)), a) {
|
|
144
|
+
const l = { userId: a.id, displayName: a.name, email: a.email };
|
|
145
|
+
return A.set(n, { result: l, timestamp: Date.now() }), l;
|
|
369
146
|
}
|
|
370
|
-
if (
|
|
371
|
-
const l = { userId:
|
|
372
|
-
return
|
|
147
|
+
if (a = i.find((l) => l.email.toLowerCase().includes(c)), a) {
|
|
148
|
+
const l = { userId: a.id, displayName: a.name, email: a.email };
|
|
149
|
+
return A.set(n, { result: l, timestamp: Date.now() }), l;
|
|
373
150
|
}
|
|
374
151
|
const d = null;
|
|
375
|
-
return
|
|
152
|
+
return A.set(n, { result: d, timestamp: Date.now() }), d;
|
|
376
153
|
} catch {
|
|
377
|
-
return
|
|
154
|
+
return A.set(n, { result: null, timestamp: Date.now() }), null;
|
|
378
155
|
}
|
|
379
156
|
}
|
|
380
157
|
/**
|
|
@@ -395,11 +172,11 @@ class Qe {
|
|
|
395
172
|
if (r && Date.now() - r.timestamp < G)
|
|
396
173
|
return r.result;
|
|
397
174
|
try {
|
|
398
|
-
const i = await t.getProjectCollaborators(o),
|
|
175
|
+
const i = await t.getProjectCollaborators(o), a = (Array.isArray(i) ? i : i.results || []).filter((d) => d?.id && d.name && d.email);
|
|
399
176
|
return R.set(n, {
|
|
400
|
-
result:
|
|
177
|
+
result: a,
|
|
401
178
|
timestamp: Date.now()
|
|
402
|
-
}),
|
|
179
|
+
}), a;
|
|
403
180
|
} catch {
|
|
404
181
|
return [];
|
|
405
182
|
}
|
|
@@ -417,17 +194,17 @@ class Qe {
|
|
|
417
194
|
const u = [];
|
|
418
195
|
return R.set(o, { result: u, timestamp: Date.now() }), u;
|
|
419
196
|
}
|
|
420
|
-
const
|
|
197
|
+
const c = [], a = /* @__PURE__ */ new Set(), d = i.map(
|
|
421
198
|
(u) => this.getProjectCollaborators(t, u.id)
|
|
422
199
|
), l = await Promise.allSettled(d);
|
|
423
200
|
for (const u of l)
|
|
424
201
|
if (u.status === "fulfilled")
|
|
425
202
|
for (const p of u.value)
|
|
426
|
-
p && !
|
|
203
|
+
p && !a.has(p.id) && (c.push(p), a.add(p.id));
|
|
427
204
|
return R.set(o, {
|
|
428
|
-
result:
|
|
205
|
+
result: c,
|
|
429
206
|
timestamp: Date.now()
|
|
430
|
-
}),
|
|
207
|
+
}), c;
|
|
431
208
|
} catch {
|
|
432
209
|
return [];
|
|
433
210
|
}
|
|
@@ -436,28 +213,28 @@ class Qe {
|
|
|
436
213
|
* Clear all caches - useful for testing
|
|
437
214
|
*/
|
|
438
215
|
clearCache() {
|
|
439
|
-
|
|
216
|
+
A.clear(), R.clear();
|
|
440
217
|
}
|
|
441
218
|
}
|
|
442
|
-
const _ = new
|
|
443
|
-
async function
|
|
219
|
+
const _ = new _e();
|
|
220
|
+
async function Ne(e, t) {
|
|
444
221
|
return _.resolveUser(e, t);
|
|
445
222
|
}
|
|
446
223
|
const ge = ["assigned", "unassignedOrMe", "all"];
|
|
447
|
-
async function
|
|
224
|
+
async function Q(e, t) {
|
|
448
225
|
if (!t)
|
|
449
226
|
return;
|
|
450
|
-
const o = await
|
|
227
|
+
const o = await Ne(e, t);
|
|
451
228
|
if (!o)
|
|
452
229
|
throw new Error(
|
|
453
230
|
`Could not find user: "${t}". Make sure the user is a collaborator on a shared project.`
|
|
454
231
|
);
|
|
455
232
|
return { userId: o.userId, email: o.email };
|
|
456
233
|
}
|
|
457
|
-
function
|
|
234
|
+
function K(e, t) {
|
|
458
235
|
return t.length === 0 ? e : e.length === 0 ? t : `${e} & ${t}`;
|
|
459
236
|
}
|
|
460
|
-
function
|
|
237
|
+
function Me({
|
|
461
238
|
resolvedAssigneeId: e,
|
|
462
239
|
assigneeEmail: t,
|
|
463
240
|
responsibleUserFiltering: o = "unassignedOrMe"
|
|
@@ -475,7 +252,7 @@ function ce({
|
|
|
475
252
|
function B(e) {
|
|
476
253
|
return "inboxProject" in e;
|
|
477
254
|
}
|
|
478
|
-
function
|
|
255
|
+
function Fe(e, t, o, n) {
|
|
479
256
|
const r = [t, o, n].filter(Boolean);
|
|
480
257
|
if (r.length > 1)
|
|
481
258
|
throw new Error(
|
|
@@ -500,14 +277,14 @@ function O(e) {
|
|
|
500
277
|
deadlineDate: e.deadline?.date,
|
|
501
278
|
priority: e.priority,
|
|
502
279
|
projectId: e.projectId,
|
|
503
|
-
sectionId: e.sectionId,
|
|
504
|
-
parentId: e.parentId,
|
|
280
|
+
sectionId: e.sectionId ?? void 0,
|
|
281
|
+
parentId: e.parentId ?? void 0,
|
|
505
282
|
labels: e.labels,
|
|
506
|
-
duration: e.duration ?
|
|
507
|
-
responsibleUid: e.responsibleUid,
|
|
508
|
-
assignedByUid: e.assignedByUid,
|
|
283
|
+
duration: e.duration ? Oe(e.duration.amount) : void 0,
|
|
284
|
+
responsibleUid: e.responsibleUid ?? void 0,
|
|
285
|
+
assignedByUid: e.assignedByUid ?? void 0,
|
|
509
286
|
checked: e.checked,
|
|
510
|
-
completedAt: e.completedAt
|
|
287
|
+
completedAt: e.completedAt ?? void 0
|
|
511
288
|
};
|
|
512
289
|
}
|
|
513
290
|
function Te(e) {
|
|
@@ -517,25 +294,49 @@ function Te(e) {
|
|
|
517
294
|
color: e.color,
|
|
518
295
|
isFavorite: e.isFavorite,
|
|
519
296
|
isShared: e.isShared,
|
|
520
|
-
parentId: B(e) ? e.parentId ??
|
|
297
|
+
parentId: B(e) ? e.parentId ?? void 0 : void 0,
|
|
521
298
|
inboxProject: B(e) ? e.inboxProject ?? !1 : !1,
|
|
522
299
|
viewStyle: e.viewStyle
|
|
523
300
|
};
|
|
524
301
|
}
|
|
525
|
-
function
|
|
302
|
+
function ee(e) {
|
|
526
303
|
return {
|
|
527
304
|
id: e.id,
|
|
305
|
+
taskId: e.taskId ?? void 0,
|
|
306
|
+
projectId: e.projectId ?? void 0,
|
|
307
|
+
content: e.content,
|
|
308
|
+
postedAt: e.postedAt,
|
|
309
|
+
postedUid: e.postedUid ?? void 0,
|
|
310
|
+
fileAttachment: e.fileAttachment ? {
|
|
311
|
+
resourceType: e.fileAttachment.resourceType,
|
|
312
|
+
fileName: e.fileAttachment.fileName ?? void 0,
|
|
313
|
+
fileSize: e.fileAttachment.fileSize ?? void 0,
|
|
314
|
+
fileType: e.fileAttachment.fileType ?? void 0,
|
|
315
|
+
fileUrl: e.fileAttachment.fileUrl ?? void 0,
|
|
316
|
+
fileDuration: e.fileAttachment.fileDuration ?? void 0,
|
|
317
|
+
uploadState: e.fileAttachment.uploadState ?? void 0,
|
|
318
|
+
url: e.fileAttachment.url ?? void 0,
|
|
319
|
+
title: e.fileAttachment.title ?? void 0,
|
|
320
|
+
image: e.fileAttachment.image ?? void 0,
|
|
321
|
+
imageWidth: e.fileAttachment.imageWidth ?? void 0,
|
|
322
|
+
imageHeight: e.fileAttachment.imageHeight ?? void 0
|
|
323
|
+
} : void 0
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function Re(e) {
|
|
327
|
+
return {
|
|
328
|
+
id: e.id ?? void 0,
|
|
528
329
|
objectType: e.objectType,
|
|
529
330
|
objectId: e.objectId,
|
|
530
331
|
eventType: e.eventType,
|
|
531
332
|
eventDate: e.eventDate,
|
|
532
|
-
parentProjectId: e.parentProjectId,
|
|
533
|
-
parentItemId: e.parentItemId,
|
|
534
|
-
initiatorId: e.initiatorId,
|
|
535
|
-
extraData: e.extraData
|
|
333
|
+
parentProjectId: e.parentProjectId ?? void 0,
|
|
334
|
+
parentItemId: e.parentItemId ?? void 0,
|
|
335
|
+
initiatorId: e.initiatorId ?? void 0,
|
|
336
|
+
extraData: e.extraData ?? void 0
|
|
536
337
|
};
|
|
537
338
|
}
|
|
538
|
-
const
|
|
339
|
+
const Le = F.object({
|
|
539
340
|
httpStatusCode: F.number(),
|
|
540
341
|
responseData: F.object({
|
|
541
342
|
error: F.string(),
|
|
@@ -543,7 +344,7 @@ const nt = F.object({
|
|
|
543
344
|
errorTag: F.string()
|
|
544
345
|
})
|
|
545
346
|
});
|
|
546
|
-
async function
|
|
347
|
+
async function te({
|
|
547
348
|
client: e,
|
|
548
349
|
query: t,
|
|
549
350
|
limit: o,
|
|
@@ -553,14 +354,245 @@ async function ne({
|
|
|
553
354
|
const { results: r, nextCursor: i } = await e.getTasksByFilter({ query: t, cursor: n, limit: o });
|
|
554
355
|
return { tasks: r.map(O), nextCursor: i };
|
|
555
356
|
} catch (r) {
|
|
556
|
-
const i =
|
|
357
|
+
const i = Le.safeParse(r);
|
|
557
358
|
if (!i.success)
|
|
558
359
|
throw r;
|
|
559
|
-
const { responseData:
|
|
560
|
-
throw
|
|
561
|
-
`${
|
|
360
|
+
const { responseData: c } = i.data;
|
|
361
|
+
throw c.errorTag === "INVALID_SEARCH_QUERY" ? new Error(`Invalid filter query: ${t}`) : new Error(
|
|
362
|
+
`${c.error} (tag: ${c.errorTag}, code: ${c.errorCode})`
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
const W = s.object({
|
|
367
|
+
id: s.string().describe("The unique ID of the task."),
|
|
368
|
+
content: s.string().describe("The task title/content."),
|
|
369
|
+
description: s.string().describe("The task description."),
|
|
370
|
+
dueDate: s.string().optional().describe("The due date of the task (ISO 8601 format)."),
|
|
371
|
+
recurring: s.union([s.boolean(), s.string()]).describe("Whether the task is recurring, or the recurrence string."),
|
|
372
|
+
deadlineDate: s.string().optional().describe("The deadline date of the task (ISO 8601 format)."),
|
|
373
|
+
priority: s.number().describe("The priority level (1-4, where 1 is highest priority)."),
|
|
374
|
+
projectId: s.string().describe("The ID of the project this task belongs to."),
|
|
375
|
+
sectionId: s.string().optional().describe("The ID of the section this task belongs to."),
|
|
376
|
+
parentId: s.string().optional().describe("The ID of the parent task (for subtasks)."),
|
|
377
|
+
labels: s.array(s.string()).optional().describe("The labels attached to this task."),
|
|
378
|
+
duration: s.string().optional().describe('The duration of the task (e.g., "2h30m").'),
|
|
379
|
+
responsibleUid: s.string().optional().describe("The UID of the user responsible for this task."),
|
|
380
|
+
assignedByUid: s.string().optional().describe("The UID of the user who assigned this task."),
|
|
381
|
+
checked: s.boolean().describe("Whether the task is checked/completed."),
|
|
382
|
+
completedAt: s.string().optional().describe("When the task was completed (ISO 8601 format).")
|
|
383
|
+
}), se = s.object({
|
|
384
|
+
id: s.string().describe("The unique ID of the project."),
|
|
385
|
+
name: s.string().describe("The name of the project."),
|
|
386
|
+
color: s.string().describe("The color of the project."),
|
|
387
|
+
isFavorite: s.boolean().describe("Whether the project is marked as favorite."),
|
|
388
|
+
isShared: s.boolean().describe("Whether the project is shared."),
|
|
389
|
+
parentId: s.string().optional().describe("The ID of the parent project (for sub-projects)."),
|
|
390
|
+
inboxProject: s.boolean().describe("Whether this is the inbox project."),
|
|
391
|
+
viewStyle: s.string().describe("The view style of the project (list, board, calendar).")
|
|
392
|
+
}), oe = s.object({
|
|
393
|
+
id: s.string().describe("The unique ID of the section."),
|
|
394
|
+
name: s.string().describe("The name of the section.")
|
|
395
|
+
}), Be = s.object({
|
|
396
|
+
resourceType: s.string().describe("The type of resource (file, url, image, etc)."),
|
|
397
|
+
fileName: s.string().optional().describe("The name of the file."),
|
|
398
|
+
fileSize: s.number().optional().describe("The size of the file in bytes."),
|
|
399
|
+
fileType: s.string().optional().describe("The MIME type of the file."),
|
|
400
|
+
fileUrl: s.string().optional().describe("The URL to access the file."),
|
|
401
|
+
fileDuration: s.number().optional().describe("The duration in milliseconds (for audio/video files)."),
|
|
402
|
+
uploadState: s.enum(["pending", "completed"]).optional().describe("The upload state of the file."),
|
|
403
|
+
url: s.string().optional().describe("The URL for link/url resource types."),
|
|
404
|
+
title: s.string().optional().describe("The title for link/url resource types."),
|
|
405
|
+
image: s.string().optional().describe("The image URL for image resource types."),
|
|
406
|
+
imageWidth: s.number().optional().describe("The width of the image in pixels."),
|
|
407
|
+
imageHeight: s.number().optional().describe("The height of the image in pixels.")
|
|
408
|
+
}), ne = s.object({
|
|
409
|
+
id: s.string().describe("The unique ID of the comment."),
|
|
410
|
+
taskId: s.string().optional().describe("The ID of the task this comment belongs to."),
|
|
411
|
+
projectId: s.string().optional().describe("The ID of the project this comment belongs to."),
|
|
412
|
+
content: s.string().describe("The content of the comment."),
|
|
413
|
+
postedAt: s.string().describe("When the comment was posted (ISO 8601 format)."),
|
|
414
|
+
postedUid: s.string().optional().describe("The UID of the user who posted this comment."),
|
|
415
|
+
fileAttachment: Be.optional().describe("File attachment information, if any.")
|
|
416
|
+
}), We = s.object({
|
|
417
|
+
id: s.string().optional().describe("The unique ID of the activity event."),
|
|
418
|
+
objectType: s.string().describe("The type of object this event relates to (task, project, etc)."),
|
|
419
|
+
objectId: s.string().describe("The ID of the object this event relates to."),
|
|
420
|
+
eventType: s.string().describe("The type of event (added, updated, deleted, completed, etc)."),
|
|
421
|
+
eventDate: s.string().describe("When the event occurred (ISO 8601 format)."),
|
|
422
|
+
parentProjectId: s.string().optional().describe("The ID of the parent project."),
|
|
423
|
+
parentItemId: s.string().optional().describe("The ID of the parent item."),
|
|
424
|
+
initiatorId: s.string().optional().describe("The ID of the user who initiated this event."),
|
|
425
|
+
extraData: s.record(s.unknown()).optional().describe("Additional event data.")
|
|
426
|
+
}), Ye = s.object({
|
|
427
|
+
id: s.string().describe("The unique ID of the user."),
|
|
428
|
+
name: s.string().describe("The full name of the user."),
|
|
429
|
+
email: s.string().describe("The email address of the user.")
|
|
430
|
+
}), ze = s.object({
|
|
431
|
+
item: s.string().describe("The item that failed (usually an ID or identifier)."),
|
|
432
|
+
error: s.string().describe("The error message."),
|
|
433
|
+
code: s.string().optional().describe("The error code, if available.")
|
|
434
|
+
}), g = {
|
|
435
|
+
// Task management tools
|
|
436
|
+
ADD_TASKS: "add-tasks",
|
|
437
|
+
COMPLETE_TASKS: "complete-tasks",
|
|
438
|
+
UPDATE_TASKS: "update-tasks",
|
|
439
|
+
FIND_TASKS: "find-tasks",
|
|
440
|
+
FIND_TASKS_BY_DATE: "find-tasks-by-date",
|
|
441
|
+
FIND_COMPLETED_TASKS: "find-completed-tasks",
|
|
442
|
+
// Project management tools
|
|
443
|
+
ADD_PROJECTS: "add-projects",
|
|
444
|
+
UPDATE_PROJECTS: "update-projects",
|
|
445
|
+
FIND_PROJECTS: "find-projects",
|
|
446
|
+
// Section management tools
|
|
447
|
+
ADD_SECTIONS: "add-sections",
|
|
448
|
+
UPDATE_SECTIONS: "update-sections",
|
|
449
|
+
FIND_SECTIONS: "find-sections",
|
|
450
|
+
// Comment management tools
|
|
451
|
+
ADD_COMMENTS: "add-comments",
|
|
452
|
+
UPDATE_COMMENTS: "update-comments",
|
|
453
|
+
FIND_COMMENTS: "find-comments",
|
|
454
|
+
// Assignment and collaboration tools
|
|
455
|
+
FIND_PROJECT_COLLABORATORS: "find-project-collaborators",
|
|
456
|
+
MANAGE_ASSIGNMENTS: "manage-assignments",
|
|
457
|
+
// Activity and audit tools
|
|
458
|
+
FIND_ACTIVITY: "find-activity",
|
|
459
|
+
// General tools
|
|
460
|
+
GET_OVERVIEW: "get-overview",
|
|
461
|
+
DELETE_OBJECT: "delete-object",
|
|
462
|
+
USER_INFO: "user-info",
|
|
463
|
+
// OpenAI MCP tools
|
|
464
|
+
SEARCH: "search",
|
|
465
|
+
FETCH: "fetch"
|
|
466
|
+
}, Ke = s.object({
|
|
467
|
+
taskId: s.string().optional().describe("The ID of the task to comment on."),
|
|
468
|
+
projectId: s.string().optional().describe(
|
|
469
|
+
'The ID of the project to comment on. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
470
|
+
),
|
|
471
|
+
content: s.string().min(1).describe("The content of the comment.")
|
|
472
|
+
}), He = {
|
|
473
|
+
comments: s.array(Ke).min(1).describe("The array of comments to add.")
|
|
474
|
+
}, Ve = {
|
|
475
|
+
comments: s.array(ne).describe("The created comments."),
|
|
476
|
+
totalCount: s.number().describe("The total number of comments created."),
|
|
477
|
+
addedCommentIds: s.array(s.string()).describe("The IDs of the added comments.")
|
|
478
|
+
}, Ge = {
|
|
479
|
+
name: g.ADD_COMMENTS,
|
|
480
|
+
description: "Add multiple comments to tasks or projects. Each comment must specify either taskId or projectId.",
|
|
481
|
+
parameters: He,
|
|
482
|
+
outputSchema: Ve,
|
|
483
|
+
async execute(e, t) {
|
|
484
|
+
const { comments: o } = e;
|
|
485
|
+
for (const [l, u] of o.entries()) {
|
|
486
|
+
if (!u.taskId && !u.projectId)
|
|
487
|
+
throw new Error(
|
|
488
|
+
`Comment ${l + 1}: Either taskId or projectId must be provided.`
|
|
489
|
+
);
|
|
490
|
+
if (u.taskId && u.projectId)
|
|
491
|
+
throw new Error(
|
|
492
|
+
`Comment ${l + 1}: Cannot provide both taskId and projectId. Choose one.`
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
const r = o.some((l) => l.projectId === "inbox") ? await t.getUser() : null, i = o.map(async ({ content: l, taskId: u, projectId: p }) => {
|
|
496
|
+
const b = p === "inbox" && r ? r.inboxProjectId : p;
|
|
497
|
+
return await t.addComment({
|
|
498
|
+
content: l,
|
|
499
|
+
...u ? { taskId: u } : { projectId: b }
|
|
500
|
+
});
|
|
501
|
+
}), a = (await Promise.all(i)).map(ee);
|
|
502
|
+
return {
|
|
503
|
+
textContent: qe({ comments: a }),
|
|
504
|
+
structuredContent: {
|
|
505
|
+
comments: a,
|
|
506
|
+
totalCount: a.length,
|
|
507
|
+
addedCommentIds: a.map((l) => l.id)
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
function qe({ comments: e }) {
|
|
513
|
+
const t = e.filter((i) => i.taskId).length, o = e.filter((i) => i.projectId).length, n = [];
|
|
514
|
+
if (t > 0) {
|
|
515
|
+
const i = t > 1 ? "comments" : "comment";
|
|
516
|
+
n.push(`${t} task ${i}`);
|
|
517
|
+
}
|
|
518
|
+
if (o > 0) {
|
|
519
|
+
const i = o > 1 ? "comments" : "comment";
|
|
520
|
+
n.push(`${o} project ${i}`);
|
|
521
|
+
}
|
|
522
|
+
return n.length > 0 ? `Added ${n.join(" and ")}` : "No comments added";
|
|
523
|
+
}
|
|
524
|
+
const Je = s.object({
|
|
525
|
+
name: s.string().min(1).describe("The name of the project."),
|
|
526
|
+
parentId: s.string().optional().describe("The ID of the parent project. If provided, creates this as a sub-project."),
|
|
527
|
+
isFavorite: s.boolean().optional().describe("Whether the project is a favorite. Defaults to false."),
|
|
528
|
+
viewStyle: s.enum(["list", "board", "calendar"]).optional().describe('The project view style. Defaults to "list".')
|
|
529
|
+
}), Xe = {
|
|
530
|
+
projects: s.array(Je).min(1).describe("The array of projects to add.")
|
|
531
|
+
}, Ze = {
|
|
532
|
+
projects: s.array(se).describe("The created projects."),
|
|
533
|
+
totalCount: s.number().describe("The total number of projects created.")
|
|
534
|
+
}, Qe = {
|
|
535
|
+
name: g.ADD_PROJECTS,
|
|
536
|
+
description: "Add one or more new projects.",
|
|
537
|
+
parameters: Xe,
|
|
538
|
+
outputSchema: Ze,
|
|
539
|
+
async execute({ projects: e }, t) {
|
|
540
|
+
const o = await Promise.all(e.map((i) => t.addProject(i))), n = et({ projects: o }), r = o.map((i) => ({
|
|
541
|
+
...i,
|
|
542
|
+
parentId: "parentId" in i ? i.parentId ?? void 0 : void 0,
|
|
543
|
+
inboxProject: "inboxProject" in i ? i.inboxProject : !1
|
|
544
|
+
}));
|
|
545
|
+
return {
|
|
546
|
+
textContent: n,
|
|
547
|
+
structuredContent: {
|
|
548
|
+
projects: r,
|
|
549
|
+
totalCount: r.length
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
function et({ projects: e }) {
|
|
555
|
+
const t = e.length, o = e.map((r) => `• ${r.name} (id=${r.id})`).join(`
|
|
556
|
+
`);
|
|
557
|
+
return `Added ${t} project${t === 1 ? "" : "s"}:
|
|
558
|
+
${o}`;
|
|
559
|
+
}
|
|
560
|
+
const tt = s.object({
|
|
561
|
+
name: s.string().min(1).describe("The name of the section."),
|
|
562
|
+
projectId: s.string().min(1).describe(
|
|
563
|
+
'The ID of the project to add the section to. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
564
|
+
)
|
|
565
|
+
}), st = {
|
|
566
|
+
sections: s.array(tt).min(1).describe("The array of sections to add.")
|
|
567
|
+
}, ot = {
|
|
568
|
+
sections: s.array(oe).describe("The created sections."),
|
|
569
|
+
totalCount: s.number().describe("The total number of sections created.")
|
|
570
|
+
}, nt = {
|
|
571
|
+
name: g.ADD_SECTIONS,
|
|
572
|
+
description: "Add one or more new sections to projects.",
|
|
573
|
+
parameters: st,
|
|
574
|
+
outputSchema: ot,
|
|
575
|
+
async execute({ sections: e }, t) {
|
|
576
|
+
const n = e.some((a) => a.projectId === "inbox") ? await t.getUser() : null, r = e.map((a) => ({
|
|
577
|
+
...a,
|
|
578
|
+
projectId: a.projectId === "inbox" && n ? n.inboxProjectId : a.projectId
|
|
579
|
+
})), i = await Promise.all(
|
|
580
|
+
r.map((a) => t.addSection(a))
|
|
562
581
|
);
|
|
582
|
+
return {
|
|
583
|
+
textContent: rt({ sections: i }),
|
|
584
|
+
structuredContent: {
|
|
585
|
+
sections: i,
|
|
586
|
+
totalCount: i.length
|
|
587
|
+
}
|
|
588
|
+
};
|
|
563
589
|
}
|
|
590
|
+
};
|
|
591
|
+
function rt({ sections: e }) {
|
|
592
|
+
const t = e.length, o = e.map((r) => `• ${r.name} (id=${r.id}, projectId=${r.projectId})`).join(`
|
|
593
|
+
`);
|
|
594
|
+
return `Added ${t} section${t === 1 ? "" : "s"}:
|
|
595
|
+
${o}`;
|
|
564
596
|
}
|
|
565
597
|
const L = {
|
|
566
598
|
USER_NOT_FOUND: "USER_NOT_FOUND",
|
|
@@ -571,13 +603,13 @@ const L = {
|
|
|
571
603
|
PROJECT_NOT_FOUND: "PROJECT_NOT_FOUND",
|
|
572
604
|
TASK_NOT_FOUND: "TASK_NOT_FOUND"
|
|
573
605
|
};
|
|
574
|
-
class
|
|
606
|
+
class it {
|
|
575
607
|
/**
|
|
576
608
|
* Validate a single assignment operation
|
|
577
609
|
*/
|
|
578
610
|
async validateAssignment(t, o) {
|
|
579
|
-
const { taskId: n, projectId: r, responsibleUid: i } = o,
|
|
580
|
-
if (!
|
|
611
|
+
const { taskId: n, projectId: r, responsibleUid: i } = o, c = await _.resolveUser(t, i);
|
|
612
|
+
if (!c)
|
|
581
613
|
return {
|
|
582
614
|
isValid: !1,
|
|
583
615
|
taskId: n,
|
|
@@ -593,16 +625,16 @@ class rt {
|
|
|
593
625
|
}
|
|
594
626
|
};
|
|
595
627
|
try {
|
|
596
|
-
const
|
|
597
|
-
if (!
|
|
628
|
+
const a = await t.getProject(r);
|
|
629
|
+
if (!a.isShared)
|
|
598
630
|
return {
|
|
599
631
|
isValid: !1,
|
|
600
632
|
taskId: n,
|
|
601
633
|
projectId: r,
|
|
602
|
-
resolvedUser:
|
|
634
|
+
resolvedUser: c,
|
|
603
635
|
error: {
|
|
604
636
|
type: L.PROJECT_NOT_SHARED,
|
|
605
|
-
message: `Project "${
|
|
637
|
+
message: `Project "${a.name}" is not shared`,
|
|
606
638
|
suggestions: [
|
|
607
639
|
"Share the project with collaborators before assigning tasks",
|
|
608
640
|
"Only shared projects support task assignments"
|
|
@@ -612,16 +644,16 @@ class rt {
|
|
|
612
644
|
if (!await _.validateProjectCollaborator(
|
|
613
645
|
t,
|
|
614
646
|
r,
|
|
615
|
-
|
|
647
|
+
c.userId
|
|
616
648
|
))
|
|
617
649
|
return {
|
|
618
650
|
isValid: !1,
|
|
619
651
|
taskId: n,
|
|
620
652
|
projectId: r,
|
|
621
|
-
resolvedUser:
|
|
653
|
+
resolvedUser: c,
|
|
622
654
|
error: {
|
|
623
655
|
type: L.USER_NOT_COLLABORATOR,
|
|
624
|
-
message: `User "${
|
|
656
|
+
message: `User "${c.displayName}" is not a collaborator on project "${a.name}"`,
|
|
625
657
|
suggestions: [
|
|
626
658
|
"Invite the user to collaborate on this project first",
|
|
627
659
|
"Check if the user has been removed from the project",
|
|
@@ -637,7 +669,7 @@ class rt {
|
|
|
637
669
|
isValid: !1,
|
|
638
670
|
taskId: n,
|
|
639
671
|
projectId: r,
|
|
640
|
-
resolvedUser:
|
|
672
|
+
resolvedUser: c,
|
|
641
673
|
error: {
|
|
642
674
|
type: L.TASK_NOT_FOUND,
|
|
643
675
|
message: `Task "${n}" not found or not accessible`,
|
|
@@ -653,14 +685,14 @@ class rt {
|
|
|
653
685
|
isValid: !0,
|
|
654
686
|
taskId: n,
|
|
655
687
|
projectId: r,
|
|
656
|
-
resolvedUser:
|
|
688
|
+
resolvedUser: c
|
|
657
689
|
};
|
|
658
690
|
} catch {
|
|
659
691
|
return {
|
|
660
692
|
isValid: !1,
|
|
661
693
|
taskId: n,
|
|
662
694
|
projectId: r,
|
|
663
|
-
resolvedUser:
|
|
695
|
+
resolvedUser: c,
|
|
664
696
|
error: {
|
|
665
697
|
type: L.PERMISSION_DENIED,
|
|
666
698
|
message: "Permission denied or API error occurred",
|
|
@@ -728,9 +760,9 @@ class rt {
|
|
|
728
760
|
*/
|
|
729
761
|
async getAssignmentEligibility(t, o, n, r) {
|
|
730
762
|
const i = [];
|
|
731
|
-
let
|
|
763
|
+
let c = !1, a;
|
|
732
764
|
try {
|
|
733
|
-
|
|
765
|
+
a = await t.getProject(o);
|
|
734
766
|
} catch {
|
|
735
767
|
return {
|
|
736
768
|
canAssign: !1,
|
|
@@ -743,36 +775,36 @@ class rt {
|
|
|
743
775
|
};
|
|
744
776
|
}
|
|
745
777
|
const d = await _.getProjectCollaborators(t, o), l = {
|
|
746
|
-
name:
|
|
747
|
-
isShared:
|
|
778
|
+
name: a.name,
|
|
779
|
+
isShared: a.isShared,
|
|
748
780
|
collaboratorCount: d.length
|
|
749
781
|
};
|
|
750
|
-
if (!
|
|
782
|
+
if (!a.isShared)
|
|
751
783
|
return i.push("Share this project to enable task assignments"), { canAssign: !1, projectInfo: l, recommendations: i };
|
|
752
784
|
const u = await _.resolveUser(t, n);
|
|
753
785
|
if (!u)
|
|
754
786
|
return i.push("User not found - check spelling or invite to a shared project"), { canAssign: !1, projectInfo: l, recommendations: i };
|
|
755
|
-
const p = d.some((
|
|
787
|
+
const p = d.some((y) => y.id === u.userId), b = {
|
|
756
788
|
resolvedName: u.displayName,
|
|
757
789
|
isCollaborator: p
|
|
758
790
|
};
|
|
759
791
|
if (!p)
|
|
760
792
|
return i.push(
|
|
761
|
-
`Invite ${u.displayName} to collaborate on project "${
|
|
793
|
+
`Invite ${u.displayName} to collaborate on project "${a.name}"`
|
|
762
794
|
), { canAssign: !1, projectInfo: l, userInfo: b, recommendations: i };
|
|
763
795
|
let m;
|
|
764
796
|
if (r && r.length > 0) {
|
|
765
|
-
let
|
|
766
|
-
for (const
|
|
797
|
+
let y = 0, k = 0;
|
|
798
|
+
for (const w of r)
|
|
767
799
|
try {
|
|
768
|
-
await t.getTask(
|
|
800
|
+
await t.getTask(w), y++;
|
|
769
801
|
} catch {
|
|
770
|
-
|
|
802
|
+
k++;
|
|
771
803
|
}
|
|
772
|
-
m = { accessibleTasks:
|
|
804
|
+
m = { accessibleTasks: y, inaccessibleTasks: k }, k > 0 && i.push(`${k} task(s) are not accessible`);
|
|
773
805
|
}
|
|
774
|
-
return
|
|
775
|
-
canAssign:
|
|
806
|
+
return c = !0, i.push(`Ready to assign tasks to ${u.displayName}`), {
|
|
807
|
+
canAssign: c,
|
|
776
808
|
projectInfo: l,
|
|
777
809
|
userInfo: b,
|
|
778
810
|
taskInfo: m,
|
|
@@ -780,16 +812,16 @@ class rt {
|
|
|
780
812
|
};
|
|
781
813
|
}
|
|
782
814
|
}
|
|
783
|
-
const re = new
|
|
815
|
+
const re = new it(), at = ["p1", "p2", "p3", "p4"], ye = s.enum(at, {
|
|
784
816
|
description: "Task priority: p1 (highest), p2 (high), p3 (medium), p4 (lowest/default)"
|
|
785
817
|
});
|
|
786
818
|
function Ie(e) {
|
|
787
819
|
return { p1: 4, p2: 3, p3: 2, p4: 1 }[e];
|
|
788
820
|
}
|
|
789
|
-
function
|
|
821
|
+
function ct(e) {
|
|
790
822
|
return { 4: "P1", 3: "P2", 2: "P3", 1: "P4" }[e] || "";
|
|
791
823
|
}
|
|
792
|
-
const
|
|
824
|
+
const $ = {
|
|
793
825
|
/** Default limit for task listings */
|
|
794
826
|
TASKS_DEFAULT: 10,
|
|
795
827
|
/** Maximum limit for task search and list operations */
|
|
@@ -816,27 +848,27 @@ const v = {
|
|
|
816
848
|
/** Maximum number of failures to show in detailed error messages */
|
|
817
849
|
MAX_FAILURES_SHOWN: 3
|
|
818
850
|
};
|
|
819
|
-
function
|
|
851
|
+
function dt(e = /* @__PURE__ */ new Date()) {
|
|
820
852
|
return e.toISOString().split("T")[0] ?? "";
|
|
821
853
|
}
|
|
822
854
|
function ke(e, t, o = {}) {
|
|
823
|
-
const { context: n, showDetails: r = !1 } = o, i = t.length,
|
|
824
|
-
|
|
855
|
+
const { context: n, showDetails: r = !1 } = o, i = t.length, c = [], d = `${e} ${i} ${i === 1 ? "task" : "tasks"}${n ? ` ${n}` : ""}.`;
|
|
856
|
+
c.push(d);
|
|
825
857
|
const l = 5;
|
|
826
858
|
if (r || i <= l) {
|
|
827
|
-
const u =
|
|
859
|
+
const u = H(t, l);
|
|
828
860
|
if (u.length > 0) {
|
|
829
861
|
const p = i > l ? `, +${i - l} more` : "";
|
|
830
|
-
|
|
862
|
+
c.push(`Tasks:
|
|
831
863
|
${u}${p}.`);
|
|
832
864
|
}
|
|
833
865
|
}
|
|
834
|
-
return
|
|
866
|
+
return c.join(`
|
|
835
867
|
`);
|
|
836
868
|
}
|
|
837
|
-
function
|
|
838
|
-
const { action: t, success: o, total: n, successItems: r, failures: i } = e,
|
|
839
|
-
if (
|
|
869
|
+
function lt(e) {
|
|
870
|
+
const { action: t, success: o, total: n, successItems: r, failures: i } = e, c = [], a = `${t}: ${o}/${n} successful.`;
|
|
871
|
+
if (c.push(a), r?.length && r.length <= 5 && c.push(`Completed:
|
|
840
872
|
${r.map((d) => ` ${d}`).join(`
|
|
841
873
|
`)}.`), i?.length) {
|
|
842
874
|
const d = i.length, l = `Failed (${d}):
|
|
@@ -844,21 +876,21 @@ ${i.slice(0, q.MAX_FAILURES_SHOWN).map((u) => ` ${u.item} (Error: ${u.error}$
|
|
|
844
876
|
`
|
|
845
877
|
`
|
|
846
878
|
)}${d > q.MAX_FAILURES_SHOWN ? `, +${d - q.MAX_FAILURES_SHOWN} more` : ""}.`;
|
|
847
|
-
|
|
879
|
+
c.push(l);
|
|
848
880
|
}
|
|
849
|
-
return
|
|
881
|
+
return c.join(`
|
|
850
882
|
`);
|
|
851
883
|
}
|
|
852
|
-
function
|
|
853
|
-
const t = e.content || e.title || "Untitled", o = e.dueDate ? ` • due ${e.dueDate}` : "", n = e.priority ? ` • ${
|
|
884
|
+
function ut(e) {
|
|
885
|
+
const t = e.content || e.title || "Untitled", o = e.dueDate ? ` • due ${e.dueDate}` : "", n = e.priority ? ` • ${ct(e.priority)}` : "", r = e.projectName ? ` • ${e.projectName}` : "", i = e.id ? ` • id=${e.id}` : "";
|
|
854
886
|
return ` ${t}${o}${n}${r}${i}`;
|
|
855
887
|
}
|
|
856
|
-
function
|
|
888
|
+
function pt(e) {
|
|
857
889
|
const t = e.inboxProject ? " • Inbox" : "", o = e.isFavorite ? " • ⭐" : "", n = e.isShared ? " • Shared" : "", r = e.viewStyle && e.viewStyle !== "list" ? ` • ${e.viewStyle}` : "", i = ` • id=${e.id}`;
|
|
858
890
|
return ` ${e.name}${t}${o}${n}${r}${i}`;
|
|
859
891
|
}
|
|
860
|
-
function
|
|
861
|
-
const n = e.slice(0, t).map(
|
|
892
|
+
function H(e, t = 5) {
|
|
893
|
+
const n = e.slice(0, t).map(ut).join(`
|
|
862
894
|
`);
|
|
863
895
|
if (e.length > t) {
|
|
864
896
|
const r = e.length - t;
|
|
@@ -874,12 +906,12 @@ function N({
|
|
|
874
906
|
nextCursor: n,
|
|
875
907
|
filterHints: r,
|
|
876
908
|
previewLines: i,
|
|
877
|
-
zeroReasonHints:
|
|
878
|
-
nextSteps:
|
|
909
|
+
zeroReasonHints: c,
|
|
910
|
+
nextSteps: a
|
|
879
911
|
}) {
|
|
880
912
|
const d = [], l = `${e}: ${t}${typeof o == "number" ? ` (limit ${o})` : ""}${n ? ", more available" : ""}.`;
|
|
881
913
|
return d.push(l), r?.length && d.push(`Filter: ${r.join("; ")}.`), i?.length && d.push(`Preview:
|
|
882
|
-
${i}`), !t &&
|
|
914
|
+
${i}`), !t && c?.length && d.push(`No results. ${c.join("; ")}.`), (a?.length || n) && d.push(we(a || [], n)), d.join(`
|
|
883
915
|
`);
|
|
884
916
|
}
|
|
885
917
|
function we(e, t) {
|
|
@@ -888,7 +920,7 @@ function we(e, t) {
|
|
|
888
920
|
${o.map((r) => `- ${r}`).join(`
|
|
889
921
|
`)}`;
|
|
890
922
|
}
|
|
891
|
-
const
|
|
923
|
+
const ht = s.object({
|
|
892
924
|
content: s.string().min(1).describe(
|
|
893
925
|
'The task name/title. Should be concise and actionable (e.g., "Review PR #123", "Call dentist"). For longer content, use the description field instead. Supports Markdown.'
|
|
894
926
|
),
|
|
@@ -914,38 +946,38 @@ const pt = s.object({
|
|
|
914
946
|
responsibleUser: s.string().optional().describe(
|
|
915
947
|
"Assign task to this user. Can be a user ID, name, or email address. User must be a collaborator on the target project."
|
|
916
948
|
)
|
|
917
|
-
}),
|
|
918
|
-
tasks: s.array(
|
|
919
|
-
},
|
|
949
|
+
}), mt = {
|
|
950
|
+
tasks: s.array(ht).min(1).describe("The array of tasks to add.")
|
|
951
|
+
}, ft = {
|
|
920
952
|
tasks: s.array(W).describe("The created tasks."),
|
|
921
953
|
totalCount: s.number().describe("The total number of tasks created.")
|
|
922
|
-
},
|
|
923
|
-
name:
|
|
954
|
+
}, bt = {
|
|
955
|
+
name: g.ADD_TASKS,
|
|
924
956
|
description: "Add one or more tasks to a project, section, or parent. Supports assignment to project collaborators.",
|
|
925
|
-
parameters:
|
|
926
|
-
outputSchema:
|
|
957
|
+
parameters: mt,
|
|
958
|
+
outputSchema: ft,
|
|
927
959
|
async execute({ tasks: e }, t) {
|
|
928
|
-
const o = e.map((
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
960
|
+
const o = e.map((c) => gt(c, t)), r = (await Promise.all(o)).map(O);
|
|
961
|
+
return {
|
|
962
|
+
textContent: Tt({
|
|
963
|
+
tasks: r,
|
|
964
|
+
args: { tasks: e }
|
|
965
|
+
}),
|
|
934
966
|
structuredContent: {
|
|
935
967
|
tasks: r,
|
|
936
968
|
totalCount: r.length
|
|
937
969
|
}
|
|
938
|
-
}
|
|
970
|
+
};
|
|
939
971
|
}
|
|
940
972
|
};
|
|
941
|
-
async function
|
|
973
|
+
async function gt(e, t) {
|
|
942
974
|
const {
|
|
943
975
|
duration: o,
|
|
944
976
|
projectId: n,
|
|
945
977
|
sectionId: r,
|
|
946
978
|
parentId: i,
|
|
947
|
-
responsibleUser:
|
|
948
|
-
priority:
|
|
979
|
+
responsibleUser: c,
|
|
980
|
+
priority: a,
|
|
949
981
|
labels: d,
|
|
950
982
|
deadlineDate: l,
|
|
951
983
|
...u
|
|
@@ -960,7 +992,7 @@ async function bt(e, t) {
|
|
|
960
992
|
labels: d,
|
|
961
993
|
deadlineDate: l
|
|
962
994
|
};
|
|
963
|
-
if (
|
|
995
|
+
if (a && (b.priority = Ie(a)), c && !p && !r && !i)
|
|
964
996
|
throw new Error(
|
|
965
997
|
`Task "${e.content}": Cannot assign tasks without specifying project context. Please specify a projectId, sectionId, or parentId.`
|
|
966
998
|
);
|
|
@@ -973,9 +1005,9 @@ async function bt(e, t) {
|
|
|
973
1005
|
durationUnit: "minute"
|
|
974
1006
|
};
|
|
975
1007
|
} catch (m) {
|
|
976
|
-
throw m instanceof
|
|
1008
|
+
throw m instanceof U ? new Error(`Task "${e.content}": ${m.message}`) : m;
|
|
977
1009
|
}
|
|
978
|
-
if (
|
|
1010
|
+
if (c) {
|
|
979
1011
|
let m = p;
|
|
980
1012
|
if (!m && i)
|
|
981
1013
|
try {
|
|
@@ -991,22 +1023,22 @@ async function bt(e, t) {
|
|
|
991
1023
|
throw new Error(
|
|
992
1024
|
`Task "${e.content}": Cannot determine target project for assignment validation`
|
|
993
1025
|
);
|
|
994
|
-
const
|
|
1026
|
+
const y = await re.validateTaskCreationAssignment(
|
|
995
1027
|
t,
|
|
996
1028
|
m,
|
|
997
|
-
|
|
1029
|
+
c
|
|
998
1030
|
);
|
|
999
|
-
if (!
|
|
1000
|
-
const
|
|
1031
|
+
if (!y.isValid) {
|
|
1032
|
+
const k = y.error?.message || "Assignment validation failed", w = y.error?.suggestions?.join(". ") || "";
|
|
1001
1033
|
throw new Error(
|
|
1002
|
-
`Task "${e.content}": ${
|
|
1034
|
+
`Task "${e.content}": ${k}${w ? `. ${w}` : ""}`
|
|
1003
1035
|
);
|
|
1004
1036
|
}
|
|
1005
|
-
b.assigneeId =
|
|
1037
|
+
b.assigneeId = y.resolvedUser?.userId;
|
|
1006
1038
|
}
|
|
1007
1039
|
return await t.addTask(b);
|
|
1008
1040
|
}
|
|
1009
|
-
function
|
|
1041
|
+
function Tt({
|
|
1010
1042
|
tasks: e,
|
|
1011
1043
|
args: t
|
|
1012
1044
|
}) {
|
|
@@ -1023,38 +1055,37 @@ function gt({
|
|
|
1023
1055
|
showDetails: !0
|
|
1024
1056
|
});
|
|
1025
1057
|
}
|
|
1026
|
-
const
|
|
1058
|
+
const yt = {
|
|
1027
1059
|
ids: s.array(s.string().min(1)).min(1).describe("The IDs of the tasks to complete.")
|
|
1028
|
-
},
|
|
1060
|
+
}, It = {
|
|
1029
1061
|
completed: s.array(s.string()).describe("The IDs of successfully completed tasks."),
|
|
1030
|
-
failures: s.array(
|
|
1062
|
+
failures: s.array(ze).describe("Failed task completions with error details."),
|
|
1031
1063
|
totalRequested: s.number().describe("The total number of tasks requested to complete."),
|
|
1032
1064
|
successCount: s.number().describe("The number of successfully completed tasks."),
|
|
1033
1065
|
failureCount: s.number().describe("The number of failed task completions.")
|
|
1034
|
-
},
|
|
1035
|
-
name:
|
|
1066
|
+
}, kt = {
|
|
1067
|
+
name: g.COMPLETE_TASKS,
|
|
1036
1068
|
description: "Complete one or more tasks by their IDs.",
|
|
1037
|
-
parameters:
|
|
1038
|
-
outputSchema:
|
|
1069
|
+
parameters: yt,
|
|
1070
|
+
outputSchema: It,
|
|
1039
1071
|
async execute(e, t) {
|
|
1040
1072
|
const o = [], n = [];
|
|
1041
1073
|
for (const i of e.ids)
|
|
1042
1074
|
try {
|
|
1043
1075
|
await t.closeTask(i), o.push(i);
|
|
1044
|
-
} catch (
|
|
1045
|
-
const
|
|
1076
|
+
} catch (c) {
|
|
1077
|
+
const a = c instanceof Error ? c.message : "Unknown error";
|
|
1046
1078
|
n.push({
|
|
1047
1079
|
item: i,
|
|
1048
|
-
error:
|
|
1080
|
+
error: a
|
|
1049
1081
|
});
|
|
1050
1082
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
textContent: r,
|
|
1083
|
+
return {
|
|
1084
|
+
textContent: wt({
|
|
1085
|
+
completed: o,
|
|
1086
|
+
failures: n,
|
|
1087
|
+
args: e
|
|
1088
|
+
}),
|
|
1058
1089
|
structuredContent: {
|
|
1059
1090
|
completed: o,
|
|
1060
1091
|
failures: n,
|
|
@@ -1062,15 +1093,15 @@ const Tt = {
|
|
|
1062
1093
|
successCount: o.length,
|
|
1063
1094
|
failureCount: n.length
|
|
1064
1095
|
}
|
|
1065
|
-
}
|
|
1096
|
+
};
|
|
1066
1097
|
}
|
|
1067
1098
|
};
|
|
1068
|
-
function
|
|
1099
|
+
function wt({
|
|
1069
1100
|
completed: e,
|
|
1070
1101
|
failures: t,
|
|
1071
1102
|
args: o
|
|
1072
1103
|
}) {
|
|
1073
|
-
return
|
|
1104
|
+
return lt({
|
|
1074
1105
|
action: "Completed tasks",
|
|
1075
1106
|
success: e.length,
|
|
1076
1107
|
total: o.ids.length,
|
|
@@ -1078,20 +1109,20 @@ function kt({
|
|
|
1078
1109
|
failures: t
|
|
1079
1110
|
});
|
|
1080
1111
|
}
|
|
1081
|
-
const
|
|
1112
|
+
const jt = {
|
|
1082
1113
|
type: s.enum(["project", "section", "task", "comment"]).describe("The type of entity to delete."),
|
|
1083
1114
|
id: s.string().min(1).describe("The ID of the entity to delete.")
|
|
1084
|
-
},
|
|
1115
|
+
}, vt = {
|
|
1085
1116
|
deletedEntity: s.object({
|
|
1086
1117
|
type: s.enum(["project", "section", "task", "comment"]).describe("The type of deleted entity."),
|
|
1087
1118
|
id: s.string().describe("The ID of the deleted entity.")
|
|
1088
1119
|
}).describe("Information about the deleted entity."),
|
|
1089
1120
|
success: s.boolean().describe("Whether the deletion was successful.")
|
|
1090
|
-
},
|
|
1091
|
-
name:
|
|
1121
|
+
}, Ct = {
|
|
1122
|
+
name: g.DELETE_OBJECT,
|
|
1092
1123
|
description: "Delete a project, section, task, or comment by its ID.",
|
|
1093
|
-
parameters:
|
|
1094
|
-
outputSchema:
|
|
1124
|
+
parameters: jt,
|
|
1125
|
+
outputSchema: vt,
|
|
1095
1126
|
async execute(e, t) {
|
|
1096
1127
|
switch (e.type) {
|
|
1097
1128
|
case "project":
|
|
@@ -1107,100 +1138,81 @@ const wt = {
|
|
|
1107
1138
|
await t.deleteComment(e.id);
|
|
1108
1139
|
break;
|
|
1109
1140
|
}
|
|
1110
|
-
|
|
1111
|
-
type: e.
|
|
1112
|
-
id: e.id
|
|
1113
|
-
});
|
|
1114
|
-
return T({
|
|
1115
|
-
textContent: o,
|
|
1141
|
+
return {
|
|
1142
|
+
textContent: `Deleted ${e.type}: id=${e.id}`,
|
|
1116
1143
|
structuredContent: {
|
|
1117
|
-
deletedEntity: {
|
|
1118
|
-
type: e.type,
|
|
1119
|
-
id: e.id
|
|
1120
|
-
},
|
|
1144
|
+
deletedEntity: { type: e.type, id: e.id },
|
|
1121
1145
|
success: !0
|
|
1122
1146
|
}
|
|
1123
|
-
}
|
|
1147
|
+
};
|
|
1124
1148
|
}
|
|
1125
|
-
}
|
|
1126
|
-
function St({
|
|
1127
|
-
type: e,
|
|
1128
|
-
id: t
|
|
1129
|
-
}) {
|
|
1130
|
-
return `Deleted ${e}: id=${t}`;
|
|
1131
|
-
}
|
|
1132
|
-
const Ct = {
|
|
1149
|
+
}, St = {
|
|
1133
1150
|
id: s.string().min(1).describe(
|
|
1134
1151
|
'A unique identifier for the document in the format "task:{id}" or "project:{id}".'
|
|
1135
1152
|
)
|
|
1136
|
-
},
|
|
1153
|
+
}, $t = {
|
|
1137
1154
|
id: s.string().describe("The ID of the fetched document."),
|
|
1138
1155
|
title: s.string().describe("The title of the document."),
|
|
1139
1156
|
text: s.string().describe("The text content of the document."),
|
|
1140
1157
|
url: s.string().describe("The URL of the document."),
|
|
1141
1158
|
metadata: s.record(s.unknown()).optional().describe("Additional metadata about the document.")
|
|
1142
1159
|
}, Dt = {
|
|
1143
|
-
name:
|
|
1160
|
+
name: g.FETCH,
|
|
1144
1161
|
description: 'Fetch the full contents of a task or project by its ID. The ID should be in the format "task:{id}" or "project:{id}".',
|
|
1145
|
-
parameters:
|
|
1146
|
-
outputSchema:
|
|
1162
|
+
parameters: St,
|
|
1163
|
+
outputSchema: $t,
|
|
1147
1164
|
async execute(e, t) {
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
d.description && l.push(`
|
|
1165
|
+
const { id: o } = e, [n, r] = o.split(":", 2);
|
|
1166
|
+
if (!r || n !== "task" && n !== "project")
|
|
1167
|
+
throw new Error(
|
|
1168
|
+
'Invalid ID format. Expected "task:{id}" or "project:{id}". Example: "task:8485093748" or "project:6cfCcrrCFg2xP94Q"'
|
|
1169
|
+
);
|
|
1170
|
+
let i;
|
|
1171
|
+
if (n === "task") {
|
|
1172
|
+
const c = await t.getTask(r), a = O(c), d = [a.content];
|
|
1173
|
+
a.description && d.push(`
|
|
1158
1174
|
|
|
1159
|
-
Description: ${
|
|
1160
|
-
Due: ${
|
|
1161
|
-
Labels: ${
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1175
|
+
Description: ${a.description}`), a.dueDate && d.push(`
|
|
1176
|
+
Due: ${a.dueDate}`), a.labels.length > 0 && d.push(`
|
|
1177
|
+
Labels: ${a.labels.join(", ")}`), i = {
|
|
1178
|
+
id: `task:${a.id}`,
|
|
1179
|
+
title: a.content,
|
|
1180
|
+
text: d.join(""),
|
|
1181
|
+
url: he(a.id),
|
|
1182
|
+
metadata: {
|
|
1183
|
+
priority: a.priority,
|
|
1184
|
+
projectId: a.projectId,
|
|
1185
|
+
sectionId: a.sectionId,
|
|
1186
|
+
parentId: a.parentId,
|
|
1187
|
+
recurring: a.recurring,
|
|
1188
|
+
duration: a.duration,
|
|
1189
|
+
responsibleUid: a.responsibleUid,
|
|
1190
|
+
assignedByUid: a.assignedByUid,
|
|
1191
|
+
checked: a.checked,
|
|
1192
|
+
completedAt: a.completedAt
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
} else {
|
|
1196
|
+
const c = await t.getProject(r), a = Te(c), d = [a.name];
|
|
1197
|
+
a.isShared && d.push(`
|
|
1182
1198
|
|
|
1183
|
-
Shared project`),
|
|
1199
|
+
Shared project`), a.isFavorite && d.push(`
|
|
1184
1200
|
Favorite: Yes`), i = {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
}
|
|
1199
|
-
return { content: [{ type: "text", text: JSON.stringify(i) }] };
|
|
1200
|
-
} catch (o) {
|
|
1201
|
-
const n = o instanceof Error ? o.message : "An unknown error occurred";
|
|
1202
|
-
return Q(n);
|
|
1201
|
+
id: `project:${a.id}`,
|
|
1202
|
+
title: a.name,
|
|
1203
|
+
text: d.join(""),
|
|
1204
|
+
url: me(a.id),
|
|
1205
|
+
metadata: {
|
|
1206
|
+
color: a.color,
|
|
1207
|
+
isFavorite: a.isFavorite,
|
|
1208
|
+
isShared: a.isShared,
|
|
1209
|
+
parentId: a.parentId,
|
|
1210
|
+
inboxProject: a.inboxProject,
|
|
1211
|
+
viewStyle: a.viewStyle
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1203
1214
|
}
|
|
1215
|
+
return { textContent: JSON.stringify(i) };
|
|
1204
1216
|
}
|
|
1205
1217
|
}, xt = {
|
|
1206
1218
|
objectType: s.enum(["task", "project", "comment"]).optional().describe("Type of object to filter by."),
|
|
@@ -1219,40 +1231,36 @@ Favorite: Yes`), i = {
|
|
|
1219
1231
|
projectId: s.string().optional().describe("Filter events by parent project ID."),
|
|
1220
1232
|
taskId: s.string().optional().describe("Filter events by parent task ID (for subtask events)."),
|
|
1221
1233
|
initiatorId: s.string().optional().describe("Filter by the user ID who initiated the event."),
|
|
1222
|
-
limit: s.number().int().min(1).max(
|
|
1234
|
+
limit: s.number().int().min(1).max($.ACTIVITY_MAX).default($.ACTIVITY_DEFAULT).describe("Maximum number of activity events to return."),
|
|
1223
1235
|
cursor: s.string().optional().describe("Pagination cursor for retrieving the next page of results.")
|
|
1224
1236
|
}, At = {
|
|
1225
|
-
events: s.array(
|
|
1237
|
+
events: s.array(We).describe("The activity events."),
|
|
1226
1238
|
nextCursor: s.string().optional().describe("Cursor for the next page of results."),
|
|
1227
1239
|
totalCount: s.number().describe("The total number of events in this page."),
|
|
1228
1240
|
hasMore: s.boolean().describe("Whether there are more results available."),
|
|
1229
1241
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1230
1242
|
}, Ut = {
|
|
1231
|
-
name:
|
|
1243
|
+
name: g.FIND_ACTIVITY,
|
|
1232
1244
|
description: "Retrieve recent activity logs to monitor and audit changes in Todoist. Shows events from all users by default (use initiatorId to filter by specific user). Track task completions, updates, deletions, project changes, and more with flexible filtering. Note: Date-based filtering is not supported by the Todoist API.",
|
|
1233
1245
|
parameters: xt,
|
|
1234
1246
|
outputSchema: At,
|
|
1235
1247
|
async execute(e, t) {
|
|
1236
|
-
const { objectType: o, objectId: n, eventType: r, projectId: i, taskId:
|
|
1248
|
+
const { objectType: o, objectId: n, eventType: r, projectId: i, taskId: c, initiatorId: a, limit: d, cursor: l } = e, u = {
|
|
1237
1249
|
limit: d,
|
|
1238
1250
|
cursor: l ?? null
|
|
1239
1251
|
};
|
|
1240
|
-
o && (u.objectType = o), n && n !== "remove" && (u.objectId = n), r && (u.eventType = r), i && (u.parentProjectId = i),
|
|
1241
|
-
const { results: p, nextCursor: b } = await t.getActivityLogs(u), m = p.map(
|
|
1242
|
-
|
|
1243
|
-
args: e,
|
|
1244
|
-
nextCursor: b
|
|
1245
|
-
});
|
|
1246
|
-
return T({
|
|
1247
|
-
textContent: k,
|
|
1252
|
+
o && (u.objectType = o), n && n !== "remove" && (u.objectId = n), r && (u.eventType = r), i && (u.parentProjectId = i), c && (u.parentItemId = c), a && (u.initiatorId = a);
|
|
1253
|
+
const { results: p, nextCursor: b } = await t.getActivityLogs(u), m = p.map(Re);
|
|
1254
|
+
return {
|
|
1255
|
+
textContent: Pt({ events: m, args: e, nextCursor: b }),
|
|
1248
1256
|
structuredContent: {
|
|
1249
1257
|
events: m,
|
|
1250
|
-
nextCursor: b,
|
|
1258
|
+
nextCursor: b ?? void 0,
|
|
1251
1259
|
totalCount: m.length,
|
|
1252
1260
|
hasMore: !!b,
|
|
1253
1261
|
appliedFilters: e
|
|
1254
1262
|
}
|
|
1255
|
-
}
|
|
1263
|
+
};
|
|
1256
1264
|
}
|
|
1257
1265
|
};
|
|
1258
1266
|
function Pt({
|
|
@@ -1263,21 +1271,21 @@ function Pt({
|
|
|
1263
1271
|
let n = "Activity events";
|
|
1264
1272
|
const r = [];
|
|
1265
1273
|
if (t.eventType && r.push(`${t.eventType}`), t.objectType) {
|
|
1266
|
-
const
|
|
1267
|
-
r.push(
|
|
1274
|
+
const a = t.objectType === "task" ? "tasks" : `${t.objectType}s`;
|
|
1275
|
+
r.push(a);
|
|
1268
1276
|
}
|
|
1269
1277
|
r.length > 0 && (n = `Activity: ${r.join(" ")}`);
|
|
1270
1278
|
const i = [];
|
|
1271
1279
|
t.objectId && i.push(`object ID: ${t.objectId}`), t.projectId && i.push(`project: ${t.projectId}`), t.taskId && i.push(`task: ${t.taskId}`), t.initiatorId && i.push(`initiator: ${t.initiatorId}`);
|
|
1272
|
-
const
|
|
1273
|
-
return e.length === 0 && (
|
|
1280
|
+
const c = [];
|
|
1281
|
+
return e.length === 0 && (c.push("No activity events match the specified filters"), c.push("Note: Activity logs only show recent events"), t.eventType && c.push(`Try removing the eventType filter (${t.eventType})`), t.objectType && c.push(`Try removing the objectType filter (${t.objectType})`), (t.objectId || t.projectId || t.taskId) && c.push("Verify the object ID is correct")), N({
|
|
1274
1282
|
subject: n,
|
|
1275
1283
|
count: e.length,
|
|
1276
1284
|
limit: t.limit,
|
|
1277
1285
|
nextCursor: o ?? void 0,
|
|
1278
1286
|
filterHints: i,
|
|
1279
1287
|
previewLines: Et(e, Math.min(e.length, t.limit)),
|
|
1280
|
-
zeroReasonHints:
|
|
1288
|
+
zeroReasonHints: c
|
|
1281
1289
|
});
|
|
1282
1290
|
}
|
|
1283
1291
|
function Et(e, t = 10) {
|
|
@@ -1294,11 +1302,11 @@ function Ot(e) {
|
|
|
1294
1302
|
const t = _t(e.eventDate), o = `${e.eventType} ${e.objectType}`;
|
|
1295
1303
|
let n = "";
|
|
1296
1304
|
if (e.extraData) {
|
|
1297
|
-
const
|
|
1298
|
-
|
|
1305
|
+
const a = e.extraData.content || e.extraData.name || e.extraData.last_content;
|
|
1306
|
+
a && typeof a == "string" && (n = ` • "${a.length > 50 ? `${a.substring(0, 47)}...` : a}"`);
|
|
1299
1307
|
}
|
|
1300
|
-
const r = e.objectId ? ` • id=${e.objectId}` : "", i = e.initiatorId ? ` • by=${e.initiatorId}` : " • system",
|
|
1301
|
-
return ` [${t}] ${o}${n}${r}${i}${
|
|
1308
|
+
const r = e.objectId ? ` • id=${e.objectId}` : "", i = e.initiatorId ? ` • by=${e.initiatorId}` : " • system", c = e.parentProjectId ? ` • project=${e.parentProjectId}` : "";
|
|
1309
|
+
return ` [${t}] ${o}${n}${r}${i}${c}`;
|
|
1302
1310
|
}
|
|
1303
1311
|
function _t(e) {
|
|
1304
1312
|
try {
|
|
@@ -1320,13 +1328,13 @@ const Nt = {
|
|
|
1320
1328
|
),
|
|
1321
1329
|
commentId: s.string().optional().describe("Get a specific comment by ID."),
|
|
1322
1330
|
cursor: s.string().optional().describe("Pagination cursor for retrieving more results."),
|
|
1323
|
-
limit: s.number().int().min(1).max(
|
|
1331
|
+
limit: s.number().int().min(1).max($.COMMENTS_MAX).optional().describe("Maximum number of comments to return")
|
|
1324
1332
|
}, Mt = {
|
|
1325
|
-
comments: s.array(
|
|
1333
|
+
comments: s.array(ne).describe("The found comments."),
|
|
1326
1334
|
nextCursor: s.string().optional().describe("Cursor for the next page of results."),
|
|
1327
1335
|
totalCount: s.number().describe("The total number of comments in this page.")
|
|
1328
1336
|
}, Ft = {
|
|
1329
|
-
name:
|
|
1337
|
+
name: g.FIND_COMMENTS,
|
|
1330
1338
|
description: "Find comments by task, project, or get a specific comment by ID. Exactly one of taskId, projectId, or commentId must be provided.",
|
|
1331
1339
|
parameters: Nt,
|
|
1332
1340
|
outputSchema: Mt,
|
|
@@ -1339,43 +1347,43 @@ const Nt = {
|
|
|
1339
1347
|
"Cannot provide multiple search parameters. Choose one of: taskId, projectId, or commentId."
|
|
1340
1348
|
);
|
|
1341
1349
|
const n = e.projectId === "inbox" ? (await t.getUser()).inboxProjectId : e.projectId;
|
|
1342
|
-
let r
|
|
1350
|
+
let r = !1, i = null, c;
|
|
1343
1351
|
if (e.commentId)
|
|
1344
|
-
|
|
1352
|
+
c = [await t.getComment(e.commentId)];
|
|
1345
1353
|
else if (e.taskId) {
|
|
1346
|
-
const
|
|
1354
|
+
const l = await t.getComments({
|
|
1347
1355
|
taskId: e.taskId,
|
|
1348
1356
|
cursor: e.cursor || null,
|
|
1349
|
-
limit: e.limit ||
|
|
1357
|
+
limit: e.limit || $.COMMENTS_DEFAULT
|
|
1350
1358
|
});
|
|
1351
|
-
|
|
1359
|
+
c = l.results, r = l.nextCursor !== null, i = l.nextCursor;
|
|
1352
1360
|
} else if (n) {
|
|
1353
|
-
const
|
|
1361
|
+
const l = await t.getComments({
|
|
1354
1362
|
projectId: n,
|
|
1355
1363
|
cursor: e.cursor || null,
|
|
1356
|
-
limit: e.limit ||
|
|
1364
|
+
limit: e.limit || $.COMMENTS_DEFAULT
|
|
1357
1365
|
});
|
|
1358
|
-
|
|
1366
|
+
c = l.results, r = l.nextCursor !== null, i = l.nextCursor;
|
|
1359
1367
|
} else
|
|
1360
1368
|
throw new Error("Invalid state: no search parameter provided");
|
|
1361
|
-
const
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1369
|
+
const a = c.map(ee);
|
|
1370
|
+
return {
|
|
1371
|
+
textContent: Rt({
|
|
1372
|
+
comments: a,
|
|
1373
|
+
searchType: e.commentId ? "single" : e.taskId ? "task" : "project",
|
|
1374
|
+
searchId: e.commentId || e.taskId || e.projectId || "",
|
|
1375
|
+
hasMore: r,
|
|
1376
|
+
nextCursor: i
|
|
1377
|
+
}),
|
|
1370
1378
|
structuredContent: {
|
|
1371
|
-
comments:
|
|
1379
|
+
comments: a,
|
|
1372
1380
|
searchType: e.commentId ? "single" : e.taskId ? "task" : "project",
|
|
1373
1381
|
searchId: e.commentId || e.taskId || e.projectId || "",
|
|
1374
|
-
hasMore:
|
|
1375
|
-
nextCursor:
|
|
1376
|
-
totalCount:
|
|
1382
|
+
hasMore: r,
|
|
1383
|
+
nextCursor: i ?? void 0,
|
|
1384
|
+
totalCount: a.length
|
|
1377
1385
|
}
|
|
1378
|
-
}
|
|
1386
|
+
};
|
|
1379
1387
|
}
|
|
1380
1388
|
};
|
|
1381
1389
|
function Rt({
|
|
@@ -1389,18 +1397,18 @@ function Rt({
|
|
|
1389
1397
|
return `No comments found for ${t}${t !== "single" ? ` ${o}` : ""}`;
|
|
1390
1398
|
let i;
|
|
1391
1399
|
if (t === "single") {
|
|
1392
|
-
const
|
|
1393
|
-
if (!
|
|
1400
|
+
const c = e[0];
|
|
1401
|
+
if (!c)
|
|
1394
1402
|
return "Comment not found";
|
|
1395
|
-
i = `Found comment${
|
|
1403
|
+
i = `Found comment${c.fileAttachment !== void 0 ? ` • Has attachment: ${c.fileAttachment?.fileName || "file"}` : ""} • id=${c.id}`;
|
|
1396
1404
|
} else {
|
|
1397
|
-
const
|
|
1398
|
-
i = `Found ${e.length} ${d} for ${t} ${o}${
|
|
1405
|
+
const c = e.filter((l) => l.fileAttachment !== void 0).length, a = c > 0 ? ` (${c} with attachments)` : "", d = e.length === 1 ? "comment" : "comments";
|
|
1406
|
+
i = `Found ${e.length} ${d} for ${t} ${o}${a}`, n && (i += " • More available");
|
|
1399
1407
|
}
|
|
1400
1408
|
if (r) {
|
|
1401
|
-
const
|
|
1409
|
+
const c = we([], r);
|
|
1402
1410
|
return `${i}
|
|
1403
|
-
${
|
|
1411
|
+
${c}`;
|
|
1404
1412
|
}
|
|
1405
1413
|
return i;
|
|
1406
1414
|
}
|
|
@@ -1430,7 +1438,7 @@ const Bt = {
|
|
|
1430
1438
|
responsibleUser: s.string().optional().describe(
|
|
1431
1439
|
"Find tasks assigned to this user. Can be a user ID, name, or email address. Defaults to all collaborators when omitted."
|
|
1432
1440
|
),
|
|
1433
|
-
limit: s.number().int().min(1).max(
|
|
1441
|
+
limit: s.number().int().min(1).max($.COMPLETED_TASKS_MAX).default($.COMPLETED_TASKS_DEFAULT).describe("The maximum number of tasks to return."),
|
|
1434
1442
|
cursor: s.string().optional().describe(
|
|
1435
1443
|
"The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters)."
|
|
1436
1444
|
),
|
|
@@ -1442,77 +1450,77 @@ const Bt = {
|
|
|
1442
1450
|
hasMore: s.boolean().describe("Whether there are more results available."),
|
|
1443
1451
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1444
1452
|
}, Yt = {
|
|
1445
|
-
name:
|
|
1453
|
+
name: g.FIND_COMPLETED_TASKS,
|
|
1446
1454
|
description: "Get completed tasks (includes all collaborators by default—use responsibleUser to narrow).",
|
|
1447
1455
|
parameters: Bt,
|
|
1448
1456
|
outputSchema: Wt,
|
|
1449
1457
|
async execute(e, t) {
|
|
1450
|
-
const { getBy: o, labels: n, labelsOperator: r, since: i, until:
|
|
1458
|
+
const { getBy: o, labels: n, labelsOperator: r, since: i, until: c, responsibleUser: a, projectId: d, ...l } = e, u = await Q(t, a), p = u?.email;
|
|
1451
1459
|
let m = ae(n, r);
|
|
1452
|
-
u && p && (m =
|
|
1453
|
-
const
|
|
1460
|
+
u && p && (m = K(m, `assigned to: ${p}`));
|
|
1461
|
+
const y = await t.getUser(), k = y.tzInfo?.gmtString || "+00:00", w = d === "inbox" ? y.inboxProjectId : d, D = `${i}T00:00:00${k}`, P = `${c}T23:59:59${k}`, h = new Date(D).toISOString(), T = new Date(P).toISOString(), { items: C, nextCursor: v } = o === "completion" ? await t.getCompletedTasksByCompletionDate({
|
|
1454
1462
|
...l,
|
|
1455
|
-
projectId:
|
|
1463
|
+
projectId: w,
|
|
1456
1464
|
since: h,
|
|
1457
|
-
until:
|
|
1465
|
+
until: T,
|
|
1458
1466
|
...m ? { filterQuery: m, filterLang: "en" } : {}
|
|
1459
1467
|
}) : await t.getCompletedTasksByDueDate({
|
|
1460
1468
|
...l,
|
|
1461
|
-
projectId:
|
|
1469
|
+
projectId: w,
|
|
1462
1470
|
since: h,
|
|
1463
|
-
until:
|
|
1471
|
+
until: T,
|
|
1464
1472
|
...m ? { filterQuery: m, filterLang: "en" } : {}
|
|
1465
|
-
}), f = C.map(O)
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
+
}), f = C.map(O);
|
|
1474
|
+
return {
|
|
1475
|
+
textContent: zt({
|
|
1476
|
+
tasks: f,
|
|
1477
|
+
args: e,
|
|
1478
|
+
nextCursor: v,
|
|
1479
|
+
assigneeEmail: p
|
|
1480
|
+
}),
|
|
1473
1481
|
structuredContent: {
|
|
1474
1482
|
tasks: f,
|
|
1475
|
-
nextCursor:
|
|
1483
|
+
nextCursor: v ?? void 0,
|
|
1476
1484
|
totalCount: f.length,
|
|
1477
|
-
hasMore: !!
|
|
1485
|
+
hasMore: !!v,
|
|
1478
1486
|
appliedFilters: e
|
|
1479
1487
|
}
|
|
1480
|
-
}
|
|
1488
|
+
};
|
|
1481
1489
|
}
|
|
1482
1490
|
};
|
|
1483
|
-
function
|
|
1491
|
+
function zt({
|
|
1484
1492
|
tasks: e,
|
|
1485
1493
|
args: t,
|
|
1486
1494
|
nextCursor: o,
|
|
1487
1495
|
assigneeEmail: n
|
|
1488
1496
|
}) {
|
|
1489
|
-
const r = t.getBy === "completion" ? "completed" : "due", i = `Completed tasks (by ${r} date)`,
|
|
1490
|
-
if (
|
|
1497
|
+
const r = t.getBy === "completion" ? "completed" : "due", i = `Completed tasks (by ${r} date)`, c = [];
|
|
1498
|
+
if (c.push(`${r} date: ${t.since} to ${t.until}`), t.projectId && c.push(`project: ${t.projectId}`), t.sectionId && c.push(`section: ${t.sectionId}`), t.parentId && c.push(`parent: ${t.parentId}`), t.workspaceId && c.push(`workspace: ${t.workspaceId}`), t.labels && t.labels.length > 0) {
|
|
1491
1499
|
const d = t.labels.map((l) => `@${l}`).join(t.labelsOperator === "and" ? " & " : " | ");
|
|
1492
|
-
|
|
1500
|
+
c.push(`labels: ${d}`);
|
|
1493
1501
|
}
|
|
1494
1502
|
if (t.responsibleUser) {
|
|
1495
1503
|
const d = n || t.responsibleUser;
|
|
1496
|
-
|
|
1504
|
+
c.push(`assigned to: ${d}`);
|
|
1497
1505
|
}
|
|
1498
|
-
const
|
|
1499
|
-
return e.length === 0 && (
|
|
1506
|
+
const a = [];
|
|
1507
|
+
return e.length === 0 && (a.push("No tasks completed in this date range"), a.push("Try expanding the date range"), (t.projectId || t.sectionId || t.parentId) && a.push("Try removing project/section/parent filters"), t.getBy === "due" && a.push('Try switching to "completion" date instead')), N({
|
|
1500
1508
|
subject: i,
|
|
1501
1509
|
count: e.length,
|
|
1502
1510
|
limit: t.limit,
|
|
1503
1511
|
nextCursor: o ?? void 0,
|
|
1504
|
-
filterHints:
|
|
1505
|
-
previewLines:
|
|
1506
|
-
zeroReasonHints:
|
|
1512
|
+
filterHints: c,
|
|
1513
|
+
previewLines: H(e, Math.min(e.length, t.limit)),
|
|
1514
|
+
zeroReasonHints: a
|
|
1507
1515
|
});
|
|
1508
1516
|
}
|
|
1509
|
-
const { FIND_PROJECTS:
|
|
1517
|
+
const { FIND_PROJECTS: Kt, ADD_TASKS: je, UPDATE_TASKS: ve } = g, Ht = {
|
|
1510
1518
|
projectId: s.string().min(1).describe("The ID of the project to search for collaborators in."),
|
|
1511
1519
|
searchTerm: s.string().optional().describe(
|
|
1512
1520
|
"Search for a collaborator by name or email (partial and case insensitive match). If omitted, all collaborators in the project are returned."
|
|
1513
1521
|
)
|
|
1514
|
-
},
|
|
1515
|
-
collaborators: s.array(
|
|
1522
|
+
}, Vt = {
|
|
1523
|
+
collaborators: s.array(Ye).describe("The found collaborators."),
|
|
1516
1524
|
projectInfo: s.object({
|
|
1517
1525
|
id: s.string().describe("The project ID."),
|
|
1518
1526
|
name: s.string().describe("The project name."),
|
|
@@ -1522,24 +1530,23 @@ const { FIND_PROJECTS: zt, ADD_TASKS: je, UPDATE_TASKS: $e } = y, Vt = {
|
|
|
1522
1530
|
totalAvailable: s.number().optional().describe("The total number of available collaborators in the project."),
|
|
1523
1531
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1524
1532
|
}, Gt = {
|
|
1525
|
-
name:
|
|
1533
|
+
name: g.FIND_PROJECT_COLLABORATORS,
|
|
1526
1534
|
description: "Search for collaborators by name or other criteria in a project.",
|
|
1527
|
-
parameters:
|
|
1528
|
-
outputSchema:
|
|
1535
|
+
parameters: Ht,
|
|
1536
|
+
outputSchema: Vt,
|
|
1529
1537
|
async execute(e, t) {
|
|
1530
1538
|
const { projectId: o, searchTerm: n } = e;
|
|
1531
1539
|
let r = o, i;
|
|
1532
1540
|
try {
|
|
1533
1541
|
if (i = await t.getProject(o), !i)
|
|
1534
1542
|
throw new Error(`Project with ID "${o}" not found or not accessible`);
|
|
1535
|
-
if (r = i.name, !i.isShared)
|
|
1536
|
-
|
|
1543
|
+
if (r = i.name, !i.isShared)
|
|
1544
|
+
return {
|
|
1545
|
+
textContent: `Project "${r}" is not shared and has no collaborators.
|
|
1537
1546
|
|
|
1538
1547
|
**Next steps:**
|
|
1539
1548
|
• Share the project to enable collaboration
|
|
1540
|
-
• Use ${je} and ${
|
|
1541
|
-
return T({
|
|
1542
|
-
textContent: l,
|
|
1549
|
+
• Use ${je} and ${ve} for assignment features once shared`,
|
|
1543
1550
|
structuredContent: {
|
|
1544
1551
|
collaborators: [],
|
|
1545
1552
|
projectInfo: {
|
|
@@ -1550,23 +1557,21 @@ const { FIND_PROJECTS: zt, ADD_TASKS: je, UPDATE_TASKS: $e } = y, Vt = {
|
|
|
1550
1557
|
totalCount: 0,
|
|
1551
1558
|
appliedFilters: e
|
|
1552
1559
|
}
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1560
|
+
};
|
|
1555
1561
|
} catch (l) {
|
|
1556
1562
|
throw new Error(
|
|
1557
1563
|
`Failed to access project "${o}": ${l instanceof Error ? l.message : "Unknown error"}`
|
|
1558
1564
|
);
|
|
1559
1565
|
}
|
|
1560
|
-
const
|
|
1561
|
-
if (
|
|
1562
|
-
|
|
1566
|
+
const c = await _.getProjectCollaborators(t, o);
|
|
1567
|
+
if (c.length === 0)
|
|
1568
|
+
return {
|
|
1569
|
+
textContent: `Project "${r}" has no collaborators or collaborator data is not accessible.
|
|
1563
1570
|
|
|
1564
1571
|
**Next steps:**
|
|
1565
1572
|
• Check project sharing settings
|
|
1566
1573
|
• Ensure you have permission to view collaborators
|
|
1567
|
-
• Try refreshing or re-sharing the project
|
|
1568
|
-
return T({
|
|
1569
|
-
textContent: l,
|
|
1574
|
+
• Try refreshing or re-sharing the project`,
|
|
1570
1575
|
structuredContent: {
|
|
1571
1576
|
collaborators: [],
|
|
1572
1577
|
projectInfo: {
|
|
@@ -1577,35 +1582,33 @@ const { FIND_PROJECTS: zt, ADD_TASKS: je, UPDATE_TASKS: $e } = y, Vt = {
|
|
|
1577
1582
|
totalCount: 0,
|
|
1578
1583
|
appliedFilters: e
|
|
1579
1584
|
}
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
let c = a;
|
|
1585
|
+
};
|
|
1586
|
+
let a = c;
|
|
1583
1587
|
if (n) {
|
|
1584
1588
|
const l = n.toLowerCase().trim();
|
|
1585
|
-
|
|
1589
|
+
a = c.filter(
|
|
1586
1590
|
(u) => u.name.toLowerCase().includes(l) || u.email.toLowerCase().includes(l)
|
|
1587
1591
|
);
|
|
1588
1592
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
textContent: d,
|
|
1593
|
+
return {
|
|
1594
|
+
textContent: qt({
|
|
1595
|
+
collaborators: a,
|
|
1596
|
+
projectName: r,
|
|
1597
|
+
searchTerm: n,
|
|
1598
|
+
totalAvailable: c.length
|
|
1599
|
+
}),
|
|
1597
1600
|
structuredContent: {
|
|
1598
|
-
collaborators:
|
|
1601
|
+
collaborators: a,
|
|
1599
1602
|
projectInfo: {
|
|
1600
1603
|
id: o,
|
|
1601
1604
|
name: r,
|
|
1602
1605
|
isShared: !0
|
|
1603
1606
|
},
|
|
1604
|
-
totalCount:
|
|
1605
|
-
totalAvailable:
|
|
1607
|
+
totalCount: a.length,
|
|
1608
|
+
totalAvailable: c.length,
|
|
1606
1609
|
appliedFilters: e
|
|
1607
1610
|
}
|
|
1608
|
-
}
|
|
1611
|
+
};
|
|
1609
1612
|
}
|
|
1610
1613
|
};
|
|
1611
1614
|
function qt({
|
|
@@ -1616,40 +1619,40 @@ function qt({
|
|
|
1616
1619
|
}) {
|
|
1617
1620
|
const r = o ? `Project collaborators matching "${o}"` : "Project collaborators", i = [];
|
|
1618
1621
|
o && i.push(`matching "${o}"`), i.push(`in project "${t}"`);
|
|
1619
|
-
let
|
|
1620
|
-
e.length > 0 && (
|
|
1622
|
+
let c = [];
|
|
1623
|
+
e.length > 0 && (c = e.slice(0, 10).map((l) => {
|
|
1621
1624
|
const u = l.name || "Unknown Name", p = l.email || "No email";
|
|
1622
1625
|
return `• ${u} (${p}) - ID: ${l.id}`;
|
|
1623
|
-
}), e.length > 10 &&
|
|
1624
|
-
const
|
|
1625
|
-
e.length === 0 && (o ? (
|
|
1626
|
+
}), e.length > 10 && c.push(`... and ${e.length - 10} more`));
|
|
1627
|
+
const a = [];
|
|
1628
|
+
e.length === 0 && (o ? (a.push(`No collaborators match "${o}"`), a.push("Try a broader search term or check spelling"), n > 0 && a.push(`${n} collaborators available without filter`)) : (a.push("Project has no collaborators"), a.push("Share the project to add collaborators")));
|
|
1626
1629
|
const d = [];
|
|
1627
|
-
return e.length > 0 ? (d.push(`Use ${je} with responsibleUser to assign new tasks`), d.push(`Use ${
|
|
1630
|
+
return e.length > 0 ? (d.push(`Use ${je} with responsibleUser to assign new tasks`), d.push(`Use ${ve} with responsibleUser to reassign existing tasks`), d.push("Use collaborator names, emails, or IDs for assignments")) : (d.push(`Use ${Kt} to find other projects`), o && n > 0 && d.push("Try searching without filters to see all collaborators")), N({
|
|
1628
1631
|
subject: r,
|
|
1629
1632
|
count: e.length,
|
|
1630
1633
|
filterHints: i,
|
|
1631
|
-
previewLines:
|
|
1634
|
+
previewLines: c.join(`
|
|
1632
1635
|
`),
|
|
1633
|
-
zeroReasonHints:
|
|
1636
|
+
zeroReasonHints: a,
|
|
1634
1637
|
nextSteps: d
|
|
1635
1638
|
});
|
|
1636
1639
|
}
|
|
1637
|
-
const { ADD_PROJECTS: Jt } =
|
|
1640
|
+
const { ADD_PROJECTS: Jt } = g, Xt = {
|
|
1638
1641
|
search: s.string().optional().describe(
|
|
1639
1642
|
"Search for a project by name (partial and case insensitive match). If omitted, all projects are returned."
|
|
1640
1643
|
),
|
|
1641
|
-
limit: s.number().int().min(1).max(
|
|
1644
|
+
limit: s.number().int().min(1).max($.PROJECTS_MAX).default($.PROJECTS_DEFAULT).describe("The maximum number of projects to return."),
|
|
1642
1645
|
cursor: s.string().optional().describe(
|
|
1643
1646
|
"The cursor to get the next page of projects (cursor is obtained from the previous call to this tool, with the same parameters)."
|
|
1644
1647
|
)
|
|
1645
1648
|
}, Zt = {
|
|
1646
|
-
projects: s.array(
|
|
1649
|
+
projects: s.array(se).describe("The found projects."),
|
|
1647
1650
|
nextCursor: s.string().optional().describe("Cursor for the next page of results."),
|
|
1648
1651
|
totalCount: s.number().describe("The total number of projects in this page."),
|
|
1649
1652
|
hasMore: s.boolean().describe("Whether there are more results available."),
|
|
1650
1653
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1651
1654
|
}, Qt = {
|
|
1652
|
-
name:
|
|
1655
|
+
name: g.FIND_PROJECTS,
|
|
1653
1656
|
description: "List all projects or search for projects by name. If search parameter is omitted, all projects are returned.",
|
|
1654
1657
|
parameters: Xt,
|
|
1655
1658
|
outputSchema: Zt,
|
|
@@ -1657,21 +1660,17 @@ const { ADD_PROJECTS: Jt } = y, Xt = {
|
|
|
1657
1660
|
const { results: o, nextCursor: n } = await t.getProjects({
|
|
1658
1661
|
limit: e.limit,
|
|
1659
1662
|
cursor: e.cursor ?? null
|
|
1660
|
-
}), r = e.search ? e.search.toLowerCase() : void 0,
|
|
1661
|
-
return
|
|
1662
|
-
textContent: es({
|
|
1663
|
-
projects: a,
|
|
1664
|
-
args: e,
|
|
1665
|
-
nextCursor: n
|
|
1666
|
-
}),
|
|
1663
|
+
}), r = e.search ? e.search.toLowerCase() : void 0, c = (r ? o.filter((a) => a.name.toLowerCase().includes(r)) : o).map(Te);
|
|
1664
|
+
return {
|
|
1665
|
+
textContent: es({ projects: c, args: e, nextCursor: n }),
|
|
1667
1666
|
structuredContent: {
|
|
1668
|
-
projects:
|
|
1669
|
-
nextCursor: n,
|
|
1670
|
-
totalCount:
|
|
1667
|
+
projects: c,
|
|
1668
|
+
nextCursor: n ?? void 0,
|
|
1669
|
+
totalCount: c.length,
|
|
1671
1670
|
hasMore: !!n,
|
|
1672
1671
|
appliedFilters: e
|
|
1673
1672
|
}
|
|
1674
|
-
}
|
|
1673
|
+
};
|
|
1675
1674
|
}
|
|
1676
1675
|
};
|
|
1677
1676
|
function es({
|
|
@@ -1681,9 +1680,9 @@ function es({
|
|
|
1681
1680
|
}) {
|
|
1682
1681
|
const n = t.search ? `Projects matching "${t.search}"` : "Projects", r = [];
|
|
1683
1682
|
t.search && r.push(`search: "${t.search}"`);
|
|
1684
|
-
const i = 10,
|
|
1685
|
-
`), d = e.length - i, l = d > 0 ? `${
|
|
1686
|
-
…and ${d} more` :
|
|
1683
|
+
const i = 10, a = e.slice(0, i).map(pt).join(`
|
|
1684
|
+
`), d = e.length - i, l = d > 0 ? `${a}
|
|
1685
|
+
…and ${d} more` : a, u = [];
|
|
1687
1686
|
return e.length === 0 && (t.search ? (u.push("Try broader search terms"), u.push("Check spelling"), u.push("Remove search to see all projects")) : (u.push("No projects created yet"), u.push(`Use ${Jt} to create a project`))), N({
|
|
1688
1687
|
subject: n,
|
|
1689
1688
|
count: e.length,
|
|
@@ -1694,7 +1693,7 @@ function es({
|
|
|
1694
1693
|
zeroReasonHints: u
|
|
1695
1694
|
});
|
|
1696
1695
|
}
|
|
1697
|
-
const { ADD_SECTIONS: ts } =
|
|
1696
|
+
const { ADD_SECTIONS: ts } = g, ss = {
|
|
1698
1697
|
projectId: s.string().min(1).describe(
|
|
1699
1698
|
'The ID of the project to search sections in. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
1700
1699
|
),
|
|
@@ -1702,33 +1701,30 @@ const { ADD_SECTIONS: ts } = y, ss = {
|
|
|
1702
1701
|
"Search for a section by name (partial and case insensitive match). If omitted, all sections in the project are returned."
|
|
1703
1702
|
)
|
|
1704
1703
|
}, os = {
|
|
1705
|
-
sections: s.array(
|
|
1704
|
+
sections: s.array(oe).describe("The found sections."),
|
|
1706
1705
|
totalCount: s.number().describe("The total number of sections found."),
|
|
1707
1706
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1708
1707
|
}, ns = {
|
|
1709
|
-
name:
|
|
1708
|
+
name: g.FIND_SECTIONS,
|
|
1710
1709
|
description: "Search for sections by name or other criteria in a project.",
|
|
1711
1710
|
parameters: ss,
|
|
1712
1711
|
outputSchema: os,
|
|
1713
1712
|
async execute(e, t) {
|
|
1714
1713
|
const o = e.projectId === "inbox" ? (await t.getUser()).inboxProjectId : e.projectId, { results: n } = await t.getSections({
|
|
1715
1714
|
projectId: o
|
|
1716
|
-
}), r = e.search ? e.search.toLowerCase() : void 0,
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
});
|
|
1724
|
-
return T({
|
|
1725
|
-
textContent: c,
|
|
1715
|
+
}), r = e.search ? e.search.toLowerCase() : void 0, c = (r ? n.filter((d) => d.name.toLowerCase().includes(r)) : n).map(({ id: d, name: l }) => ({ id: d, name: l }));
|
|
1716
|
+
return {
|
|
1717
|
+
textContent: rs({
|
|
1718
|
+
sections: c,
|
|
1719
|
+
projectId: e.projectId,
|
|
1720
|
+
search: e.search
|
|
1721
|
+
}),
|
|
1726
1722
|
structuredContent: {
|
|
1727
|
-
sections:
|
|
1728
|
-
totalCount:
|
|
1723
|
+
sections: c,
|
|
1724
|
+
totalCount: c.length,
|
|
1729
1725
|
appliedFilters: e
|
|
1730
1726
|
}
|
|
1731
|
-
}
|
|
1727
|
+
};
|
|
1732
1728
|
}
|
|
1733
1729
|
};
|
|
1734
1730
|
function rs({
|
|
@@ -1738,7 +1734,7 @@ function rs({
|
|
|
1738
1734
|
}) {
|
|
1739
1735
|
const n = [];
|
|
1740
1736
|
o ? (n.push("Try broader search terms"), n.push("Check spelling"), n.push("Remove search to see all sections")) : (n.push("Project has no sections yet"), n.push(`Use ${ts} to create sections`));
|
|
1741
|
-
const r = o ? `Sections in project ${t} matching "${o}"` : `Sections in project ${t}`, i = e.length > 0 ? e.map((
|
|
1737
|
+
const r = o ? `Sections in project ${t} matching "${o}"` : `Sections in project ${t}`, i = e.length > 0 ? e.map((c) => ` ${c.name} • id=${c.id}`).join(`
|
|
1742
1738
|
`) : void 0;
|
|
1743
1739
|
return N({
|
|
1744
1740
|
subject: r,
|
|
@@ -1747,7 +1743,7 @@ function rs({
|
|
|
1747
1743
|
zeroReasonHints: n
|
|
1748
1744
|
});
|
|
1749
1745
|
}
|
|
1750
|
-
const { FIND_COMPLETED_TASKS: de, ADD_TASKS: le } =
|
|
1746
|
+
const { FIND_COMPLETED_TASKS: de, ADD_TASKS: le } = g, is = {
|
|
1751
1747
|
searchText: s.string().optional().describe("The text to search for in tasks."),
|
|
1752
1748
|
projectId: s.string().optional().describe(
|
|
1753
1749
|
'Find tasks in this project. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
@@ -1758,7 +1754,7 @@ const { FIND_COMPLETED_TASKS: de, ADD_TASKS: le } = y, is = {
|
|
|
1758
1754
|
responsibleUserFiltering: s.enum(ge).optional().describe(
|
|
1759
1755
|
'How to filter by responsible user when responsibleUser is not provided. "assigned" = only tasks assigned to others; "unassignedOrMe" = only unassigned tasks or tasks assigned to me; "all" = all tasks regardless of assignment. Default value will be `unassignedOrMe`.'
|
|
1760
1756
|
),
|
|
1761
|
-
limit: s.number().int().min(1).max(
|
|
1757
|
+
limit: s.number().int().min(1).max($.TASKS_MAX).default($.TASKS_DEFAULT).describe("The maximum number of tasks to return."),
|
|
1762
1758
|
cursor: s.string().optional().describe(
|
|
1763
1759
|
"The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters)."
|
|
1764
1760
|
),
|
|
@@ -1770,7 +1766,7 @@ const { FIND_COMPLETED_TASKS: de, ADD_TASKS: le } = y, is = {
|
|
|
1770
1766
|
hasMore: s.boolean().describe("Whether there are more results available."),
|
|
1771
1767
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1772
1768
|
}, cs = {
|
|
1773
|
-
name:
|
|
1769
|
+
name: g.FIND_TASKS,
|
|
1774
1770
|
description: "Find tasks by text search, or by project/section/parent container/responsible user. At least one filter must be provided.",
|
|
1775
1771
|
parameters: is,
|
|
1776
1772
|
outputSchema: as,
|
|
@@ -1780,111 +1776,109 @@ const { FIND_COMPLETED_TASKS: de, ADD_TASKS: le } = y, is = {
|
|
|
1780
1776
|
projectId: n,
|
|
1781
1777
|
sectionId: r,
|
|
1782
1778
|
parentId: i,
|
|
1783
|
-
responsibleUser:
|
|
1784
|
-
responsibleUserFiltering:
|
|
1779
|
+
responsibleUser: c,
|
|
1780
|
+
responsibleUserFiltering: a,
|
|
1785
1781
|
limit: d,
|
|
1786
1782
|
cursor: l,
|
|
1787
1783
|
labels: u,
|
|
1788
1784
|
labelsOperator: p
|
|
1789
1785
|
} = e, b = await t.getUser(), m = u && u.length > 0;
|
|
1790
|
-
if (!o && !n && !r && !i && !
|
|
1786
|
+
if (!o && !n && !r && !i && !c && !m)
|
|
1791
1787
|
throw new Error(
|
|
1792
1788
|
"At least one filter must be provided: searchText, projectId, sectionId, parentId, responsibleUser, or labels"
|
|
1793
1789
|
);
|
|
1794
|
-
const
|
|
1790
|
+
const y = await Q(t, c), k = y?.userId, w = y?.email;
|
|
1795
1791
|
if (n || r || i) {
|
|
1796
|
-
const
|
|
1792
|
+
const f = {
|
|
1797
1793
|
limit: d,
|
|
1798
1794
|
cursor: l ?? null
|
|
1799
1795
|
};
|
|
1800
|
-
n && (
|
|
1801
|
-
const { results:
|
|
1802
|
-
let
|
|
1796
|
+
n && (f.projectId = n === "inbox" ? b.inboxProjectId : n), r && (f.sectionId = r), i && (f.parentId = i);
|
|
1797
|
+
const { results: j, nextCursor: S } = await t.getTasks(f), x = j.map(O);
|
|
1798
|
+
let E = o ? x.filter(
|
|
1803
1799
|
(M) => M.content.toLowerCase().includes(o.toLowerCase()) || M.description?.toLowerCase().includes(o.toLowerCase())
|
|
1804
|
-
) :
|
|
1805
|
-
|
|
1806
|
-
tasks:
|
|
1807
|
-
resolvedAssigneeId:
|
|
1800
|
+
) : x;
|
|
1801
|
+
return E = ce({
|
|
1802
|
+
tasks: E,
|
|
1803
|
+
resolvedAssigneeId: k,
|
|
1808
1804
|
currentUserId: b.id,
|
|
1809
|
-
responsibleUserFiltering:
|
|
1810
|
-
}), u && u.length > 0 && (
|
|
1811
|
-
(M) => u.every((
|
|
1812
|
-
) :
|
|
1813
|
-
(M) => u.some((
|
|
1814
|
-
))
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
return T({
|
|
1823
|
-
textContent: De,
|
|
1805
|
+
responsibleUserFiltering: a
|
|
1806
|
+
}), u && u.length > 0 && (E = p === "and" ? E.filter(
|
|
1807
|
+
(M) => u.every((V) => M.labels.includes(V))
|
|
1808
|
+
) : E.filter(
|
|
1809
|
+
(M) => u.some((V) => M.labels.includes(V))
|
|
1810
|
+
)), {
|
|
1811
|
+
textContent: J({
|
|
1812
|
+
tasks: E,
|
|
1813
|
+
args: e,
|
|
1814
|
+
nextCursor: S,
|
|
1815
|
+
isContainerSearch: !0,
|
|
1816
|
+
assigneeEmail: w
|
|
1817
|
+
}),
|
|
1824
1818
|
structuredContent: {
|
|
1825
|
-
tasks:
|
|
1826
|
-
nextCursor:
|
|
1827
|
-
totalCount:
|
|
1828
|
-
hasMore:
|
|
1819
|
+
tasks: E,
|
|
1820
|
+
nextCursor: S ?? void 0,
|
|
1821
|
+
totalCount: E.length,
|
|
1822
|
+
hasMore: !!S,
|
|
1829
1823
|
appliedFilters: e
|
|
1830
1824
|
}
|
|
1831
|
-
}
|
|
1825
|
+
};
|
|
1832
1826
|
}
|
|
1833
|
-
if (
|
|
1834
|
-
const
|
|
1835
|
-
query: `assigned to: ${
|
|
1827
|
+
if (k && !o && !m) {
|
|
1828
|
+
const { results: f, nextCursor: j } = await t.getTasksByFilter({
|
|
1829
|
+
query: `assigned to: ${w}`,
|
|
1836
1830
|
lang: "en",
|
|
1837
1831
|
limit: d,
|
|
1838
1832
|
cursor: l ?? null
|
|
1839
|
-
}),
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1833
|
+
}), S = f.map(O);
|
|
1834
|
+
return {
|
|
1835
|
+
textContent: J({
|
|
1836
|
+
tasks: S,
|
|
1837
|
+
args: e,
|
|
1838
|
+
nextCursor: j,
|
|
1839
|
+
isContainerSearch: !1,
|
|
1840
|
+
assigneeEmail: w
|
|
1841
|
+
}),
|
|
1848
1842
|
structuredContent: {
|
|
1849
|
-
tasks:
|
|
1850
|
-
nextCursor:
|
|
1851
|
-
totalCount:
|
|
1852
|
-
hasMore: !!
|
|
1843
|
+
tasks: S,
|
|
1844
|
+
nextCursor: j ?? void 0,
|
|
1845
|
+
totalCount: S.length,
|
|
1846
|
+
hasMore: !!j,
|
|
1853
1847
|
appliedFilters: e
|
|
1854
1848
|
}
|
|
1855
|
-
}
|
|
1849
|
+
};
|
|
1856
1850
|
}
|
|
1857
|
-
let
|
|
1858
|
-
o && (
|
|
1859
|
-
const
|
|
1860
|
-
|
|
1861
|
-
const h = await
|
|
1851
|
+
let D = "";
|
|
1852
|
+
o && (D = `search: ${o}`);
|
|
1853
|
+
const P = ae(u, p);
|
|
1854
|
+
D = K(D, P);
|
|
1855
|
+
const { tasks: h, nextCursor: T } = await te({
|
|
1862
1856
|
client: t,
|
|
1863
|
-
query:
|
|
1857
|
+
query: D,
|
|
1864
1858
|
cursor: e.cursor,
|
|
1865
1859
|
limit: e.limit
|
|
1866
|
-
}),
|
|
1867
|
-
tasks: h
|
|
1868
|
-
resolvedAssigneeId:
|
|
1860
|
+
}), C = ce({
|
|
1861
|
+
tasks: h,
|
|
1862
|
+
resolvedAssigneeId: k,
|
|
1869
1863
|
currentUserId: b.id,
|
|
1870
|
-
responsibleUserFiltering:
|
|
1871
|
-
}), C = J({
|
|
1872
|
-
tasks: I,
|
|
1873
|
-
args: e,
|
|
1874
|
-
nextCursor: h.nextCursor,
|
|
1875
|
-
isContainerSearch: !1,
|
|
1876
|
-
assigneeEmail: S
|
|
1864
|
+
responsibleUserFiltering: a
|
|
1877
1865
|
});
|
|
1878
|
-
return
|
|
1879
|
-
textContent:
|
|
1866
|
+
return {
|
|
1867
|
+
textContent: J({
|
|
1868
|
+
tasks: C,
|
|
1869
|
+
args: e,
|
|
1870
|
+
nextCursor: T,
|
|
1871
|
+
isContainerSearch: !1,
|
|
1872
|
+
assigneeEmail: w
|
|
1873
|
+
}),
|
|
1880
1874
|
structuredContent: {
|
|
1881
|
-
tasks:
|
|
1882
|
-
nextCursor:
|
|
1883
|
-
totalCount:
|
|
1884
|
-
hasMore: !!
|
|
1875
|
+
tasks: C,
|
|
1876
|
+
nextCursor: T ?? void 0,
|
|
1877
|
+
totalCount: h.length,
|
|
1878
|
+
hasMore: !!T,
|
|
1885
1879
|
appliedFilters: e
|
|
1886
1880
|
}
|
|
1887
|
-
}
|
|
1881
|
+
};
|
|
1888
1882
|
}
|
|
1889
1883
|
};
|
|
1890
1884
|
function ds(e) {
|
|
@@ -1912,33 +1906,33 @@ function J({
|
|
|
1912
1906
|
assigneeEmail: r
|
|
1913
1907
|
}) {
|
|
1914
1908
|
let i = "Tasks";
|
|
1915
|
-
const
|
|
1909
|
+
const c = [], a = [];
|
|
1916
1910
|
if (n) {
|
|
1917
|
-
if (t.projectId ? (i = "Tasks in project",
|
|
1911
|
+
if (t.projectId ? (i = "Tasks in project", c.push(`in project ${t.projectId}`)) : t.sectionId ? (i = "Tasks in section", c.push(`in section ${t.sectionId}`)) : t.parentId ? (i = "Subtasks", c.push(`subtasks of ${t.parentId}`)) : i = "Tasks", t.searchText && (i += ` matching "${t.searchText}"`, c.push(`containing "${t.searchText}"`)), t.responsibleUser) {
|
|
1918
1912
|
const d = r || t.responsibleUser;
|
|
1919
|
-
i += ` assigned to ${d}`,
|
|
1913
|
+
i += ` assigned to ${d}`, c.push(`assigned to ${d}`);
|
|
1920
1914
|
}
|
|
1921
1915
|
if (t.labels && t.labels.length > 0) {
|
|
1922
1916
|
const d = t.labels.map((l) => `@${l}`).join(t.labelsOperator === "and" ? " & " : " | ");
|
|
1923
|
-
|
|
1917
|
+
c.push(`labels: ${d}`);
|
|
1924
1918
|
}
|
|
1925
|
-
e.length === 0 &&
|
|
1919
|
+
e.length === 0 && a.push(...ds(t));
|
|
1926
1920
|
} else {
|
|
1927
1921
|
const d = r || t.responsibleUser, l = [];
|
|
1928
1922
|
if (t.searchText && l.push(`"${t.searchText}"`), t.responsibleUser && l.push(`assigned to ${d}`), t.labels && t.labels.length > 0) {
|
|
1929
1923
|
const u = t.labels.map((p) => `@${p}`).join(t.labelsOperator === "and" ? " & " : " | ");
|
|
1930
1924
|
l.push(`with labels: ${u}`);
|
|
1931
1925
|
}
|
|
1932
|
-
if (t.searchText ? (i = `Search results for ${l.join(" ")}`,
|
|
1926
|
+
if (t.searchText ? (i = `Search results for ${l.join(" ")}`, c.push(`matching "${t.searchText}"`)) : t.responsibleUser && (!t.labels || t.labels.length === 0) ? i = `Tasks assigned to ${d}` : t.labels && t.labels.length > 0 && !t.responsibleUser ? i = `Tasks with labels: ${t.labels.map((p) => `@${p}`).join(t.labelsOperator === "and" ? " & " : " | ")}` : i = `Tasks ${l.join(" ")}`, t.responsibleUser && c.push(`assigned to ${d}`), t.labels && t.labels.length > 0) {
|
|
1933
1927
|
const u = t.labels.map((p) => `@${p}`).join(t.labelsOperator === "and" ? " & " : " | ");
|
|
1934
|
-
|
|
1928
|
+
c.push(`labels: ${u}`);
|
|
1935
1929
|
}
|
|
1936
1930
|
if (e.length === 0) {
|
|
1937
1931
|
if (t.responsibleUser) {
|
|
1938
1932
|
const u = r || t.responsibleUser;
|
|
1939
|
-
|
|
1933
|
+
a.push(`No tasks assigned to ${u}`), a.push("Check if the user name is correct"), a.push(`Check completed tasks with ${de}`);
|
|
1940
1934
|
}
|
|
1941
|
-
t.searchText && (
|
|
1935
|
+
t.searchText && (a.push("Try broader search terms"), a.push("Verify spelling and try partial words"), t.responsibleUser || a.push(`Check completed tasks with ${de}`));
|
|
1942
1936
|
}
|
|
1943
1937
|
}
|
|
1944
1938
|
return N({
|
|
@@ -1946,9 +1940,9 @@ function J({
|
|
|
1946
1940
|
count: e.length,
|
|
1947
1941
|
limit: t.limit,
|
|
1948
1942
|
nextCursor: o ?? void 0,
|
|
1949
|
-
filterHints:
|
|
1950
|
-
previewLines:
|
|
1951
|
-
zeroReasonHints:
|
|
1943
|
+
filterHints: c,
|
|
1944
|
+
previewLines: H(e, Math.min(e.length, t.limit)),
|
|
1945
|
+
zeroReasonHints: a
|
|
1952
1946
|
});
|
|
1953
1947
|
}
|
|
1954
1948
|
const ls = {
|
|
@@ -1959,7 +1953,7 @@ const ls = {
|
|
|
1959
1953
|
daysCount: s.number().int().min(1).max(30).default(1).describe(
|
|
1960
1954
|
"The number of days to get the tasks for, starting from the start date. Default is 1 which means only tasks for the start date."
|
|
1961
1955
|
),
|
|
1962
|
-
limit: s.number().int().min(1).max(
|
|
1956
|
+
limit: s.number().int().min(1).max($.TASKS_MAX).default($.TASKS_DEFAULT).describe("The maximum number of tasks to return."),
|
|
1963
1957
|
cursor: s.string().optional().describe(
|
|
1964
1958
|
"The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters)."
|
|
1965
1959
|
),
|
|
@@ -1975,7 +1969,7 @@ const ls = {
|
|
|
1975
1969
|
hasMore: s.boolean().describe("Whether there are more results available."),
|
|
1976
1970
|
appliedFilters: s.record(s.unknown()).describe("The filters that were applied to the search.")
|
|
1977
1971
|
}, ps = {
|
|
1978
|
-
name:
|
|
1972
|
+
name: g.FIND_TASKS_BY_DATE,
|
|
1979
1973
|
description: "Get tasks by date range. Use startDate 'today' to get today's tasks including overdue items, or provide a specific date/date range.",
|
|
1980
1974
|
parameters: ls,
|
|
1981
1975
|
outputSchema: us,
|
|
@@ -1984,45 +1978,40 @@ const ls = {
|
|
|
1984
1978
|
throw new Error(
|
|
1985
1979
|
"Either startDate must be provided or overdueOption must be set to overdue-only"
|
|
1986
1980
|
);
|
|
1987
|
-
const o = await
|
|
1981
|
+
const o = await Q(t, e.responsibleUser), n = o?.userId, r = o?.email;
|
|
1988
1982
|
let i = "";
|
|
1989
1983
|
if (e.overdueOption === "overdue-only")
|
|
1990
1984
|
i = "overdue";
|
|
1991
1985
|
else if (e.startDate === "today")
|
|
1992
1986
|
i = e.overdueOption === "exclude-overdue" ? "today" : "(today | overdue)";
|
|
1993
1987
|
else if (e.startDate) {
|
|
1994
|
-
const p = e.startDate, b = fe(p, e.daysCount), m =
|
|
1988
|
+
const p = e.startDate, b = fe(p, e.daysCount), m = Ae(b, { representation: "date" });
|
|
1995
1989
|
i = `(due after: ${p} | due: ${p}) & due before: ${m}`;
|
|
1996
1990
|
}
|
|
1997
|
-
const
|
|
1998
|
-
|
|
1999
|
-
const
|
|
1991
|
+
const c = ae(e.labels, e.labelsOperator);
|
|
1992
|
+
c.length > 0 && (i = K(i, `(${c})`));
|
|
1993
|
+
const a = Me({
|
|
2000
1994
|
resolvedAssigneeId: n,
|
|
2001
1995
|
assigneeEmail: r,
|
|
2002
1996
|
responsibleUserFiltering: e.responsibleUserFiltering
|
|
2003
1997
|
});
|
|
2004
|
-
i =
|
|
2005
|
-
const d = await
|
|
1998
|
+
i = K(i, a);
|
|
1999
|
+
const { tasks: d, nextCursor: l } = await te({
|
|
2006
2000
|
client: t,
|
|
2007
2001
|
query: i,
|
|
2008
2002
|
cursor: e.cursor,
|
|
2009
2003
|
limit: e.limit
|
|
2010
|
-
}), l = d.tasks, u = hs({
|
|
2011
|
-
tasks: l,
|
|
2012
|
-
args: e,
|
|
2013
|
-
nextCursor: d.nextCursor,
|
|
2014
|
-
assigneeEmail: r
|
|
2015
2004
|
});
|
|
2016
|
-
return
|
|
2017
|
-
textContent:
|
|
2005
|
+
return {
|
|
2006
|
+
textContent: hs({ tasks: d, args: e, nextCursor: l, assigneeEmail: r }),
|
|
2018
2007
|
structuredContent: {
|
|
2019
|
-
tasks:
|
|
2020
|
-
nextCursor:
|
|
2021
|
-
totalCount:
|
|
2022
|
-
hasMore: !!
|
|
2008
|
+
tasks: d,
|
|
2009
|
+
nextCursor: l ?? void 0,
|
|
2010
|
+
totalCount: d.length,
|
|
2011
|
+
hasMore: !!l,
|
|
2023
2012
|
appliedFilters: e
|
|
2024
2013
|
}
|
|
2025
|
-
}
|
|
2014
|
+
};
|
|
2026
2015
|
}
|
|
2027
2016
|
};
|
|
2028
2017
|
function hs({
|
|
@@ -2035,44 +2024,44 @@ function hs({
|
|
|
2035
2024
|
if (t.overdueOption === "overdue-only")
|
|
2036
2025
|
r.push("overdue tasks only");
|
|
2037
2026
|
else if (t.startDate === "today") {
|
|
2038
|
-
const
|
|
2027
|
+
const a = t.overdueOption === "exclude-overdue" ? "" : " + overdue tasks";
|
|
2039
2028
|
r.push(
|
|
2040
|
-
`today${
|
|
2029
|
+
`today${a}${t.daysCount > 1 ? ` + ${t.daysCount - 1} more days` : ""}`
|
|
2041
2030
|
);
|
|
2042
2031
|
} else if (t.startDate) {
|
|
2043
|
-
const
|
|
2044
|
-
r.push(`${t.startDate}${
|
|
2032
|
+
const a = t.daysCount > 1 ? ` to ${dt(fe(t.startDate, t.daysCount))}` : "";
|
|
2033
|
+
r.push(`${t.startDate}${a}`);
|
|
2045
2034
|
}
|
|
2046
2035
|
if (t.labels && t.labels.length > 0) {
|
|
2047
|
-
const
|
|
2048
|
-
r.push(`labels: ${
|
|
2036
|
+
const a = t.labels.map((d) => `@${d}`).join(t.labelsOperator === "and" ? " & " : " | ");
|
|
2037
|
+
r.push(`labels: ${a}`);
|
|
2049
2038
|
}
|
|
2050
2039
|
if (t.responsibleUser) {
|
|
2051
|
-
const
|
|
2052
|
-
r.push(`assigned to: ${
|
|
2040
|
+
const a = n || t.responsibleUser;
|
|
2041
|
+
r.push(`assigned to: ${a}`);
|
|
2053
2042
|
}
|
|
2054
2043
|
let i = "";
|
|
2055
2044
|
if (t.overdueOption === "overdue-only" ? i = "Overdue tasks" : t.startDate === "today" ? i = t.overdueOption === "exclude-overdue" ? "Today's tasks" : "Today's tasks + overdue" : t.startDate ? i = `Tasks for ${t.startDate}` : i = "Tasks", t.responsibleUser) {
|
|
2056
|
-
const
|
|
2057
|
-
i += ` assigned to ${
|
|
2045
|
+
const a = n || t.responsibleUser;
|
|
2046
|
+
i += ` assigned to ${a}`;
|
|
2058
2047
|
}
|
|
2059
|
-
const
|
|
2048
|
+
const c = [];
|
|
2060
2049
|
if (e.length === 0)
|
|
2061
2050
|
if (t.overdueOption === "overdue-only")
|
|
2062
|
-
|
|
2051
|
+
c.push("Great job! No overdue tasks");
|
|
2063
2052
|
else if (t.startDate === "today") {
|
|
2064
|
-
const
|
|
2065
|
-
|
|
2053
|
+
const a = t.overdueOption === "exclude-overdue" ? "" : " or overdue";
|
|
2054
|
+
c.push(`Great job! No tasks for today${a}`);
|
|
2066
2055
|
} else
|
|
2067
|
-
|
|
2056
|
+
c.push("Expand date range with larger 'daysCount'"), c.push("Check today's tasks with startDate='today'");
|
|
2068
2057
|
return N({
|
|
2069
2058
|
subject: i,
|
|
2070
2059
|
count: e.length,
|
|
2071
2060
|
limit: t.limit,
|
|
2072
2061
|
nextCursor: o ?? void 0,
|
|
2073
2062
|
filterHints: r,
|
|
2074
|
-
previewLines:
|
|
2075
|
-
zeroReasonHints:
|
|
2063
|
+
previewLines: H(e, Math.min(e.length, t.limit)),
|
|
2064
|
+
zeroReasonHints: c
|
|
2076
2065
|
});
|
|
2077
2066
|
}
|
|
2078
2067
|
const ms = {
|
|
@@ -2082,7 +2071,7 @@ const ms = {
|
|
|
2082
2071
|
}, fs = {
|
|
2083
2072
|
type: s.enum(["account_overview", "project_overview"]).describe("The type of overview returned."),
|
|
2084
2073
|
totalProjects: s.number().optional().describe("Total number of projects (account overview only)."),
|
|
2085
|
-
totalTasks: s.number().describe("Total number of tasks."),
|
|
2074
|
+
totalTasks: s.number().optional().describe("Total number of tasks."),
|
|
2086
2075
|
totalSections: s.number().optional().describe("Total number of sections (project overview only)."),
|
|
2087
2076
|
tasksWithoutSection: s.number().optional().describe("Number of tasks not in any section (project overview only)."),
|
|
2088
2077
|
projectInfo: s.object({
|
|
@@ -2090,7 +2079,15 @@ const ms = {
|
|
|
2090
2079
|
name: s.string(),
|
|
2091
2080
|
isShared: s.boolean(),
|
|
2092
2081
|
isFavorite: s.boolean()
|
|
2093
|
-
}).optional().describe("Project information (project overview only).")
|
|
2082
|
+
}).optional().describe("Project information (project overview only)."),
|
|
2083
|
+
// Additional fields that exist in structured outputs
|
|
2084
|
+
hasNestedProjects: s.boolean().optional().describe("Whether account has nested projects (account overview only)."),
|
|
2085
|
+
inbox: s.any().optional().describe("Inbox information (account overview only)."),
|
|
2086
|
+
projects: s.array(s.any()).optional().describe("List of projects (account overview only)."),
|
|
2087
|
+
project: s.any().optional().describe("Project details (project overview only)."),
|
|
2088
|
+
sections: s.array(s.any()).optional().describe("List of sections (project overview only)."),
|
|
2089
|
+
tasks: s.array(s.any()).optional().describe("List of tasks (project overview only)."),
|
|
2090
|
+
stats: s.any().optional().describe("Statistics object (project overview only).")
|
|
2094
2091
|
};
|
|
2095
2092
|
function bs(e) {
|
|
2096
2093
|
const t = {};
|
|
@@ -2105,13 +2102,13 @@ function bs(e) {
|
|
|
2105
2102
|
const i = t[r.id];
|
|
2106
2103
|
if (i)
|
|
2107
2104
|
if (B(r) && r.parentId) {
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2105
|
+
const c = t[r.parentId];
|
|
2106
|
+
c ? c.children.push(i) : o.push(i);
|
|
2110
2107
|
} else
|
|
2111
2108
|
o.push(i);
|
|
2112
2109
|
}
|
|
2113
2110
|
function n(r) {
|
|
2114
|
-
r.sort((i,
|
|
2111
|
+
r.sort((i, c) => i.childOrder - c.childOrder);
|
|
2115
2112
|
for (const i of r)
|
|
2116
2113
|
n(i.children);
|
|
2117
2114
|
}
|
|
@@ -2126,14 +2123,14 @@ async function gs(e, t) {
|
|
|
2126
2123
|
})
|
|
2127
2124
|
), o;
|
|
2128
2125
|
}
|
|
2129
|
-
function
|
|
2126
|
+
function Ce(e, t, o = "") {
|
|
2130
2127
|
const n = [];
|
|
2131
2128
|
n.push(`${o}- Project: ${e.name} (id=${e.id})`);
|
|
2132
2129
|
const r = t[e.id] || [];
|
|
2133
2130
|
for (const i of r)
|
|
2134
2131
|
n.push(`${o} - Section: ${i.name} (id=${i.id})`);
|
|
2135
2132
|
for (const i of e.children)
|
|
2136
|
-
n.push(...
|
|
2133
|
+
n.push(...Ce(i, t, `${o} `));
|
|
2137
2134
|
return n;
|
|
2138
2135
|
}
|
|
2139
2136
|
function ue(e) {
|
|
@@ -2156,18 +2153,18 @@ function ue(e) {
|
|
|
2156
2153
|
function Z(e, t = "") {
|
|
2157
2154
|
const o = [];
|
|
2158
2155
|
for (const n of e) {
|
|
2159
|
-
const r = `id=${n.id}`, i = n.dueDate ? `; due=${n.dueDate}` : "",
|
|
2160
|
-
o.push(`${t}- ${r}${i}${
|
|
2156
|
+
const r = `id=${n.id}`, i = n.dueDate ? `; due=${n.dueDate}` : "", c = `; content=${n.content}`;
|
|
2157
|
+
o.push(`${t}- ${r}${i}${c}`), n.children.length > 0 && o.push(...Z(n.children, `${t} `));
|
|
2161
2158
|
}
|
|
2162
2159
|
return o;
|
|
2163
2160
|
}
|
|
2164
|
-
function
|
|
2161
|
+
function Se(e, t) {
|
|
2165
2162
|
return {
|
|
2166
2163
|
id: e.id,
|
|
2167
2164
|
name: e.name,
|
|
2168
2165
|
parentId: B(e) ? e.parentId ?? null : null,
|
|
2169
2166
|
sections: t[e.id] || [],
|
|
2170
|
-
children: e.children.map((o) =>
|
|
2167
|
+
children: e.children.map((o) => Se(o, t))
|
|
2171
2168
|
};
|
|
2172
2169
|
}
|
|
2173
2170
|
async function Ts(e, t) {
|
|
@@ -2175,7 +2172,7 @@ async function Ts(e, t) {
|
|
|
2175
2172
|
do {
|
|
2176
2173
|
const { results: r, nextCursor: i } = await e.getTasks({
|
|
2177
2174
|
projectId: t,
|
|
2178
|
-
limit:
|
|
2175
|
+
limit: $.TASKS_BATCH_SIZE,
|
|
2179
2176
|
cursor: n ?? void 0
|
|
2180
2177
|
});
|
|
2181
2178
|
o = o.concat(r.map(O)), n = i ?? void 0;
|
|
@@ -2187,37 +2184,37 @@ async function ys(e, t) {
|
|
|
2187
2184
|
return o;
|
|
2188
2185
|
}
|
|
2189
2186
|
async function Is(e) {
|
|
2190
|
-
const { results: t } = await e.getProjects({}), o = t.find((p) => B(p) && p.inboxProject === !0), n = t.filter((p) => !B(p) || p.inboxProject !== !0), r = bs(n), i = t.map((p) => p.id),
|
|
2187
|
+
const { results: t } = await e.getProjects({}), o = t.find((p) => B(p) && p.inboxProject === !0), n = t.filter((p) => !B(p) || p.inboxProject !== !0), r = bs(n), i = t.map((p) => p.id), c = await gs(e, i), a = ["# Personal Projects", ""];
|
|
2191
2188
|
if (o) {
|
|
2192
|
-
|
|
2193
|
-
for (const p of
|
|
2194
|
-
|
|
2189
|
+
a.push(`- Inbox Project: ${o.name} (id=${o.id})`);
|
|
2190
|
+
for (const p of c[o.id] || [])
|
|
2191
|
+
a.push(` - Section: ${p.name} (id=${p.id})`);
|
|
2195
2192
|
}
|
|
2196
2193
|
if (r.length)
|
|
2197
2194
|
for (const p of r)
|
|
2198
|
-
|
|
2195
|
+
a.push(...Ce(p, c));
|
|
2199
2196
|
else
|
|
2200
|
-
|
|
2201
|
-
|
|
2197
|
+
a.push("_No projects found._");
|
|
2198
|
+
a.push("");
|
|
2202
2199
|
const d = r.some((p) => p.children.length > 0);
|
|
2203
|
-
d &&
|
|
2200
|
+
d && a.push(
|
|
2204
2201
|
"_Note: Indentation indicates that a project is a sub-project of the one above it. This allows for organizing projects hierarchically, with parent projects containing related sub-projects._",
|
|
2205
2202
|
""
|
|
2206
2203
|
);
|
|
2207
|
-
const l =
|
|
2204
|
+
const l = a.join(`
|
|
2208
2205
|
`), u = {
|
|
2209
2206
|
type: "account_overview",
|
|
2210
2207
|
inbox: o ? {
|
|
2211
2208
|
id: o.id,
|
|
2212
2209
|
name: o.name,
|
|
2213
|
-
sections:
|
|
2210
|
+
sections: c[o.id] || []
|
|
2214
2211
|
} : null,
|
|
2215
2212
|
projects: r.map(
|
|
2216
|
-
(p) =>
|
|
2213
|
+
(p) => Se(p, c)
|
|
2217
2214
|
),
|
|
2218
2215
|
totalProjects: t.length,
|
|
2219
2216
|
totalSections: i.reduce(
|
|
2220
|
-
(p, b) => p + (
|
|
2217
|
+
(p, b) => p + (c[b]?.length || 0),
|
|
2221
2218
|
0
|
|
2222
2219
|
),
|
|
2223
2220
|
hasNestedProjects: d
|
|
@@ -2228,24 +2225,24 @@ async function ks(e, t) {
|
|
|
2228
2225
|
const o = await e.getProject(t), n = await ys(e, t), r = await Ts(e, t), i = {};
|
|
2229
2226
|
for (const u of n)
|
|
2230
2227
|
i[u.id] = [];
|
|
2231
|
-
const
|
|
2228
|
+
const c = [];
|
|
2232
2229
|
for (const u of r)
|
|
2233
|
-
(u.sectionId ? i[u.sectionId] ??
|
|
2234
|
-
const
|
|
2235
|
-
if (
|
|
2236
|
-
|
|
2237
|
-
const u = ue(
|
|
2238
|
-
|
|
2230
|
+
(u.sectionId ? i[u.sectionId] ?? c : c).push(u);
|
|
2231
|
+
const a = [`# ${o.name}`];
|
|
2232
|
+
if (c.length > 0) {
|
|
2233
|
+
a.push("");
|
|
2234
|
+
const u = ue(c);
|
|
2235
|
+
a.push(...Z(u));
|
|
2239
2236
|
}
|
|
2240
2237
|
for (const u of n) {
|
|
2241
|
-
|
|
2238
|
+
a.push(""), a.push(`## ${u.name}`);
|
|
2242
2239
|
const p = i[u.id];
|
|
2243
2240
|
if (!p?.length)
|
|
2244
2241
|
continue;
|
|
2245
2242
|
const b = ue(p);
|
|
2246
|
-
|
|
2243
|
+
a.push(...Z(b));
|
|
2247
2244
|
}
|
|
2248
|
-
const d =
|
|
2245
|
+
const d = a.join(`
|
|
2249
2246
|
`), l = {
|
|
2250
2247
|
type: "project_overview",
|
|
2251
2248
|
project: {
|
|
@@ -2261,26 +2258,26 @@ async function ks(e, t) {
|
|
|
2261
2258
|
stats: {
|
|
2262
2259
|
totalTasks: r.length,
|
|
2263
2260
|
totalSections: n.length,
|
|
2264
|
-
tasksWithoutSection:
|
|
2261
|
+
tasksWithoutSection: c.length
|
|
2265
2262
|
}
|
|
2266
2263
|
};
|
|
2267
2264
|
return { textContent: d, structuredContent: l };
|
|
2268
2265
|
}
|
|
2269
2266
|
const ws = {
|
|
2270
|
-
name:
|
|
2267
|
+
name: g.GET_OVERVIEW,
|
|
2271
2268
|
description: "Get a Markdown overview. If no projectId is provided, shows all projects with hierarchy and sections (useful for navigation). If projectId is provided, shows detailed overview of that specific project including all tasks grouped by sections.",
|
|
2272
2269
|
parameters: ms,
|
|
2273
2270
|
outputSchema: fs,
|
|
2274
2271
|
async execute(e, t) {
|
|
2275
2272
|
const o = e.projectId ? await ks(t, e.projectId) : await Is(t);
|
|
2276
|
-
return
|
|
2273
|
+
return {
|
|
2277
2274
|
textContent: o.textContent,
|
|
2278
2275
|
structuredContent: o.structuredContent
|
|
2279
|
-
}
|
|
2276
|
+
};
|
|
2280
2277
|
}
|
|
2281
|
-
}, { FIND_TASKS: js, FIND_PROJECT_COLLABORATORS: pe, UPDATE_TASKS:
|
|
2278
|
+
}, { FIND_TASKS: js, FIND_PROJECT_COLLABORATORS: pe, UPDATE_TASKS: vs } = g, Cs = 50, Ss = {
|
|
2282
2279
|
operation: s.enum(["assign", "unassign", "reassign"]).describe("The assignment operation to perform."),
|
|
2283
|
-
taskIds: s.array(s.string()).min(1).max(
|
|
2280
|
+
taskIds: s.array(s.string()).min(1).max(Cs).describe("The IDs of the tasks to operate on (max 50)."),
|
|
2284
2281
|
responsibleUser: s.string().optional().describe(
|
|
2285
2282
|
"The user to assign tasks to. Can be user ID, name, or email. Required for assign and reassign operations."
|
|
2286
2283
|
),
|
|
@@ -2288,7 +2285,7 @@ const ws = {
|
|
|
2288
2285
|
"For reassign operations: the current assignee to reassign from. Can be user ID, name, or email. Optional - if not provided, reassigns from any current assignee."
|
|
2289
2286
|
),
|
|
2290
2287
|
dryRun: s.boolean().optional().default(!1).describe("If true, validates operations without executing them.")
|
|
2291
|
-
},
|
|
2288
|
+
}, $s = {
|
|
2292
2289
|
results: s.array(
|
|
2293
2290
|
s.object({
|
|
2294
2291
|
taskId: s.string().describe("The ID of the task."),
|
|
@@ -2303,17 +2300,17 @@ const ws = {
|
|
|
2303
2300
|
succeeded: s.number().describe("Number of successful operations."),
|
|
2304
2301
|
failed: s.number().describe("Number of failed operations."),
|
|
2305
2302
|
dryRun: s.boolean().describe("Whether this was a dry run.")
|
|
2306
|
-
}).describe("Summary of the operation.")
|
|
2303
|
+
}).optional().describe("Summary of the operation.")
|
|
2307
2304
|
}, Ds = {
|
|
2308
|
-
name:
|
|
2305
|
+
name: g.MANAGE_ASSIGNMENTS,
|
|
2309
2306
|
description: "Bulk assignment operations for multiple tasks. Supports assign, unassign, and reassign operations with atomic rollback on failures.",
|
|
2310
|
-
parameters:
|
|
2311
|
-
outputSchema:
|
|
2307
|
+
parameters: Ss,
|
|
2308
|
+
outputSchema: $s,
|
|
2312
2309
|
async execute(e, t) {
|
|
2313
|
-
const { operation: o, taskIds: n, responsibleUser: r, fromAssigneeUser: i, dryRun:
|
|
2310
|
+
const { operation: o, taskIds: n, responsibleUser: r, fromAssigneeUser: i, dryRun: c } = e;
|
|
2314
2311
|
if ((o === "assign" || o === "reassign") && !r)
|
|
2315
2312
|
throw new Error(`${o} operation requires responsibleUser parameter`);
|
|
2316
|
-
const
|
|
2313
|
+
const a = await Promise.allSettled(
|
|
2317
2314
|
n.map(async (h) => {
|
|
2318
2315
|
try {
|
|
2319
2316
|
return await t.getTask(h);
|
|
@@ -2322,36 +2319,34 @@ const ws = {
|
|
|
2322
2319
|
}
|
|
2323
2320
|
})
|
|
2324
2321
|
), d = [], l = [];
|
|
2325
|
-
for (let h = 0; h <
|
|
2326
|
-
const
|
|
2327
|
-
|
|
2322
|
+
for (let h = 0; h < a.length; h++) {
|
|
2323
|
+
const T = a[h];
|
|
2324
|
+
T && T.status === "fulfilled" ? d.push(T.value) : T && T.status === "rejected" ? l.push({
|
|
2328
2325
|
taskId: n[h] || "invalid-task-id",
|
|
2329
2326
|
success: !1,
|
|
2330
|
-
error:
|
|
2327
|
+
error: T.reason?.message || "Task not accessible"
|
|
2331
2328
|
}) : l.push({
|
|
2332
2329
|
taskId: n[h] || "invalid-task-id",
|
|
2333
2330
|
success: !1,
|
|
2334
2331
|
error: "Task not accessible"
|
|
2335
2332
|
});
|
|
2336
2333
|
}
|
|
2337
|
-
if (d.length === 0)
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
textContent: h,
|
|
2334
|
+
if (d.length === 0)
|
|
2335
|
+
return {
|
|
2336
|
+
textContent: Y({
|
|
2337
|
+
operation: o,
|
|
2338
|
+
results: l,
|
|
2339
|
+
dryRun: c
|
|
2340
|
+
}),
|
|
2345
2341
|
structuredContent: {
|
|
2346
2342
|
operation: o,
|
|
2347
2343
|
results: l,
|
|
2348
2344
|
totalRequested: n.length,
|
|
2349
2345
|
successful: 0,
|
|
2350
2346
|
failed: l.length,
|
|
2351
|
-
dryRun:
|
|
2347
|
+
dryRun: c
|
|
2352
2348
|
}
|
|
2353
|
-
}
|
|
2354
|
-
}
|
|
2349
|
+
};
|
|
2355
2350
|
let u;
|
|
2356
2351
|
o === "reassign" && i && (u = (await _.resolveUser(t, i))?.userId || i);
|
|
2357
2352
|
const p = [];
|
|
@@ -2363,19 +2358,19 @@ const ws = {
|
|
|
2363
2358
|
// Will be validated appropriately
|
|
2364
2359
|
});
|
|
2365
2360
|
if (o === "unassign") {
|
|
2366
|
-
if (
|
|
2367
|
-
const f = d.map((
|
|
2368
|
-
taskId:
|
|
2361
|
+
if (c) {
|
|
2362
|
+
const f = d.map((S) => ({
|
|
2363
|
+
taskId: S.id,
|
|
2369
2364
|
success: !0,
|
|
2370
|
-
originalAssigneeId:
|
|
2371
|
-
newAssigneeId:
|
|
2372
|
-
}))
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2365
|
+
originalAssigneeId: S.responsibleUid ?? void 0,
|
|
2366
|
+
newAssigneeId: void 0
|
|
2367
|
+
}));
|
|
2368
|
+
return {
|
|
2369
|
+
textContent: Y({
|
|
2370
|
+
operation: o,
|
|
2371
|
+
results: f,
|
|
2372
|
+
dryRun: !0
|
|
2373
|
+
}),
|
|
2379
2374
|
structuredContent: {
|
|
2380
2375
|
operation: o,
|
|
2381
2376
|
results: f,
|
|
@@ -2384,118 +2379,118 @@ const ws = {
|
|
|
2384
2379
|
failed: l.length,
|
|
2385
2380
|
dryRun: !0
|
|
2386
2381
|
}
|
|
2387
|
-
}
|
|
2382
|
+
};
|
|
2388
2383
|
}
|
|
2389
2384
|
const h = d.map(async (f) => {
|
|
2390
2385
|
try {
|
|
2391
2386
|
return await t.updateTask(f.id, { assigneeId: null }), {
|
|
2392
2387
|
taskId: f.id,
|
|
2393
2388
|
success: !0,
|
|
2394
|
-
originalAssigneeId: f.responsibleUid,
|
|
2395
|
-
newAssigneeId:
|
|
2389
|
+
originalAssigneeId: f.responsibleUid ?? void 0,
|
|
2390
|
+
newAssigneeId: void 0
|
|
2396
2391
|
};
|
|
2397
|
-
} catch (
|
|
2392
|
+
} catch (j) {
|
|
2398
2393
|
return {
|
|
2399
2394
|
taskId: f.id,
|
|
2400
2395
|
success: !1,
|
|
2401
|
-
error:
|
|
2402
|
-
originalAssigneeId: f.responsibleUid
|
|
2396
|
+
error: j instanceof Error ? j.message : "Update failed",
|
|
2397
|
+
originalAssigneeId: f.responsibleUid ?? void 0
|
|
2403
2398
|
};
|
|
2404
2399
|
}
|
|
2405
|
-
}),
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2400
|
+
}), T = await Promise.all(h), C = [...T, ...l];
|
|
2401
|
+
return {
|
|
2402
|
+
textContent: Y({
|
|
2403
|
+
operation: o,
|
|
2404
|
+
results: C,
|
|
2405
|
+
dryRun: !1
|
|
2406
|
+
}),
|
|
2412
2407
|
structuredContent: {
|
|
2413
2408
|
operation: o,
|
|
2414
2409
|
results: C,
|
|
2415
2410
|
totalRequested: n.length,
|
|
2416
|
-
successful:
|
|
2411
|
+
successful: T.filter((f) => f.success).length,
|
|
2417
2412
|
failed: C.filter((f) => !f.success).length,
|
|
2418
2413
|
dryRun: !1
|
|
2419
2414
|
}
|
|
2420
|
-
}
|
|
2415
|
+
};
|
|
2421
2416
|
}
|
|
2422
2417
|
const b = await re.validateBulkAssignment(
|
|
2423
2418
|
t,
|
|
2424
2419
|
p
|
|
2425
|
-
), m = [],
|
|
2420
|
+
), m = [], y = [];
|
|
2426
2421
|
for (let h = 0; h < p.length; h++) {
|
|
2427
|
-
const
|
|
2428
|
-
|
|
2429
|
-
taskId:
|
|
2422
|
+
const T = p[h], C = b[h];
|
|
2423
|
+
T && C && C.isValid ? m.push({ assignment: T, validation: C }) : T?.taskId && y.push({
|
|
2424
|
+
taskId: T.taskId,
|
|
2430
2425
|
success: !1,
|
|
2431
2426
|
error: C?.error?.message || "Validation failed"
|
|
2432
2427
|
});
|
|
2433
2428
|
}
|
|
2434
|
-
async function
|
|
2429
|
+
async function k(h, T) {
|
|
2435
2430
|
const C = h.filter(
|
|
2436
2431
|
(f) => f.assignment != null && f.validation != null
|
|
2437
2432
|
);
|
|
2438
|
-
if (!
|
|
2439
|
-
return C.map(({ assignment: f, validation:
|
|
2440
|
-
const
|
|
2441
|
-
if (!f.taskId ||
|
|
2433
|
+
if (!T)
|
|
2434
|
+
return C.map(({ assignment: f, validation: j }) => {
|
|
2435
|
+
const S = d.find((x) => x.id === f.taskId);
|
|
2436
|
+
if (!f.taskId || !j.resolvedUser?.userId)
|
|
2442
2437
|
throw new Error(
|
|
2443
2438
|
"Invalid assignment or validation data - this should not happen"
|
|
2444
2439
|
);
|
|
2445
2440
|
return {
|
|
2446
2441
|
taskId: f.taskId,
|
|
2447
2442
|
success: !0,
|
|
2448
|
-
originalAssigneeId:
|
|
2449
|
-
newAssigneeId:
|
|
2443
|
+
originalAssigneeId: S?.responsibleUid ?? void 0,
|
|
2444
|
+
newAssigneeId: j.resolvedUser.userId
|
|
2450
2445
|
};
|
|
2451
2446
|
});
|
|
2452
|
-
const
|
|
2453
|
-
async ({ assignment: f, validation:
|
|
2454
|
-
const
|
|
2455
|
-
if (!f.taskId ||
|
|
2447
|
+
const v = C.map(
|
|
2448
|
+
async ({ assignment: f, validation: j }) => {
|
|
2449
|
+
const S = d.find((x) => x.id === f.taskId);
|
|
2450
|
+
if (!f.taskId || !j.resolvedUser?.userId)
|
|
2456
2451
|
return {
|
|
2457
2452
|
taskId: f.taskId || "unknown-task",
|
|
2458
2453
|
success: !1,
|
|
2459
2454
|
error: "Invalid assignment data - missing task ID or resolved user",
|
|
2460
|
-
originalAssigneeId:
|
|
2455
|
+
originalAssigneeId: S?.responsibleUid ?? void 0
|
|
2461
2456
|
};
|
|
2462
2457
|
try {
|
|
2463
2458
|
return await t.updateTask(f.taskId, {
|
|
2464
|
-
assigneeId:
|
|
2459
|
+
assigneeId: j.resolvedUser.userId
|
|
2465
2460
|
}), {
|
|
2466
2461
|
taskId: f.taskId,
|
|
2467
2462
|
success: !0,
|
|
2468
|
-
originalAssigneeId:
|
|
2469
|
-
newAssigneeId:
|
|
2463
|
+
originalAssigneeId: S?.responsibleUid ?? void 0,
|
|
2464
|
+
newAssigneeId: j.resolvedUser.userId
|
|
2470
2465
|
};
|
|
2471
|
-
} catch (
|
|
2466
|
+
} catch (x) {
|
|
2472
2467
|
return {
|
|
2473
2468
|
taskId: f.taskId,
|
|
2474
2469
|
success: !1,
|
|
2475
|
-
error:
|
|
2476
|
-
originalAssigneeId:
|
|
2470
|
+
error: x instanceof Error ? x.message : "Update failed",
|
|
2471
|
+
originalAssigneeId: S?.responsibleUid ?? void 0
|
|
2477
2472
|
};
|
|
2478
2473
|
}
|
|
2479
2474
|
}
|
|
2480
2475
|
);
|
|
2481
|
-
return Promise.all(
|
|
2476
|
+
return Promise.all(v);
|
|
2482
2477
|
}
|
|
2483
|
-
const
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2478
|
+
const w = await k(m, !c), D = [...w, ...y, ...l];
|
|
2479
|
+
return {
|
|
2480
|
+
textContent: Y({
|
|
2481
|
+
operation: o,
|
|
2482
|
+
results: D,
|
|
2483
|
+
dryRun: c
|
|
2484
|
+
}),
|
|
2490
2485
|
structuredContent: {
|
|
2491
2486
|
operation: o,
|
|
2492
|
-
results:
|
|
2487
|
+
results: D,
|
|
2493
2488
|
totalRequested: n.length,
|
|
2494
|
-
successful:
|
|
2495
|
-
failed:
|
|
2496
|
-
dryRun:
|
|
2489
|
+
successful: w.filter((h) => h.success).length,
|
|
2490
|
+
failed: D.filter((h) => !h.success).length,
|
|
2491
|
+
dryRun: c
|
|
2497
2492
|
}
|
|
2498
|
-
}
|
|
2493
|
+
};
|
|
2499
2494
|
}
|
|
2500
2495
|
};
|
|
2501
2496
|
function Y({
|
|
@@ -2503,51 +2498,51 @@ function Y({
|
|
|
2503
2498
|
results: t,
|
|
2504
2499
|
dryRun: o
|
|
2505
2500
|
}) {
|
|
2506
|
-
const n = t.filter((d) => d.success), r = t.filter((d) => !d.success), i = o ? "would be" : "were",
|
|
2501
|
+
const n = t.filter((d) => d.success), r = t.filter((d) => !d.success), i = o ? "would be" : "were", c = {
|
|
2507
2502
|
assign: "assigned",
|
|
2508
2503
|
unassign: "unassigned",
|
|
2509
2504
|
reassign: "reassigned"
|
|
2510
2505
|
}[e];
|
|
2511
|
-
let
|
|
2506
|
+
let a = `**${o ? "Dry Run: " : ""}Bulk ${e} operation**
|
|
2512
2507
|
|
|
2513
2508
|
`;
|
|
2514
2509
|
if (n.length > 0) {
|
|
2515
|
-
|
|
2510
|
+
a += `**${n.length} task${n.length === 1 ? "" : "s"} ${i} successfully ${c}**
|
|
2516
2511
|
`;
|
|
2517
2512
|
const d = n.slice(0, 5);
|
|
2518
2513
|
for (const l of d) {
|
|
2519
2514
|
let u = "";
|
|
2520
|
-
e === "unassign" ? u = " (unassigned from previous assignee)" : l.newAssigneeId && (u = ` → ${l.newAssigneeId}`),
|
|
2515
|
+
e === "unassign" ? u = " (unassigned from previous assignee)" : l.newAssigneeId && (u = ` → ${l.newAssigneeId}`), a += ` • Task ${l.taskId}${u}
|
|
2521
2516
|
`;
|
|
2522
2517
|
}
|
|
2523
|
-
n.length > 5 && (
|
|
2524
|
-
`),
|
|
2518
|
+
n.length > 5 && (a += ` • ... and ${n.length - 5} more
|
|
2519
|
+
`), a += `
|
|
2525
2520
|
`;
|
|
2526
2521
|
}
|
|
2527
2522
|
if (r.length > 0) {
|
|
2528
|
-
|
|
2523
|
+
a += `**${r.length} task${r.length === 1 ? "" : "s"} failed**
|
|
2529
2524
|
`;
|
|
2530
2525
|
const d = r.slice(0, 5);
|
|
2531
2526
|
for (const l of d)
|
|
2532
|
-
|
|
2527
|
+
a += ` • Task ${l.taskId}: ${l.error}
|
|
2533
2528
|
`;
|
|
2534
|
-
r.length > 5 && (
|
|
2535
|
-
`),
|
|
2529
|
+
r.length > 5 && (a += ` • ... and ${r.length - 5} more failures
|
|
2530
|
+
`), a += `
|
|
2536
2531
|
`;
|
|
2537
2532
|
}
|
|
2538
|
-
return !o && n.length > 0 ? (
|
|
2539
|
-
`,
|
|
2540
|
-
`,
|
|
2541
|
-
`, r.length > 0 && (
|
|
2542
|
-
`)) : o ? (
|
|
2543
|
-
`,
|
|
2544
|
-
`, n.length > 0 && (
|
|
2545
|
-
`), r.length > 0 && (
|
|
2546
|
-
`)) : n.length === 0 && (
|
|
2547
|
-
`,
|
|
2548
|
-
`,
|
|
2549
|
-
`,
|
|
2550
|
-
`),
|
|
2533
|
+
return !o && n.length > 0 ? (a += `**Next steps:**
|
|
2534
|
+
`, a += `• Use ${js} with responsibleUser to see ${e === "unassign" ? "unassigned" : "newly assigned"} tasks
|
|
2535
|
+
`, a += `• Use ${vs} for individual assignment changes
|
|
2536
|
+
`, r.length > 0 && (a += `• Check failed tasks and use ${pe} to verify collaborator access
|
|
2537
|
+
`)) : o ? (a += `**To execute:**
|
|
2538
|
+
`, a += `• Remove dryRun parameter and run again to execute changes
|
|
2539
|
+
`, n.length > 0 && (a += `• ${n.length} task${n.length === 1 ? "" : "s"} ready for ${e} operation
|
|
2540
|
+
`), r.length > 0 && (a += `• Fix ${r.length} validation error${r.length === 1 ? "" : "s"} before executing
|
|
2541
|
+
`)) : n.length === 0 && (a += `**Suggestions:**
|
|
2542
|
+
`, a += `• Use ${pe} to find valid assignees
|
|
2543
|
+
`, a += `• Check task IDs and assignee permissions
|
|
2544
|
+
`, a += `• Use dryRun=true to validate before executing
|
|
2545
|
+
`), a;
|
|
2551
2546
|
}
|
|
2552
2547
|
const xs = {
|
|
2553
2548
|
query: s.string().min(1).describe("The search query string to find tasks and projects.")
|
|
@@ -2561,40 +2556,38 @@ const xs = {
|
|
|
2561
2556
|
).describe("The search results."),
|
|
2562
2557
|
totalCount: s.number().describe("Total number of results found.")
|
|
2563
2558
|
}, Us = {
|
|
2564
|
-
name:
|
|
2559
|
+
name: g.SEARCH,
|
|
2565
2560
|
description: "Search across tasks and projects in Todoist. Returns a list of relevant results with IDs, titles, and URLs.",
|
|
2566
2561
|
parameters: xs,
|
|
2567
2562
|
outputSchema: As,
|
|
2568
2563
|
async execute(e, t) {
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
return Q(n);
|
|
2597
|
-
}
|
|
2564
|
+
const { query: o } = e, [n, r] = await Promise.all([
|
|
2565
|
+
te({
|
|
2566
|
+
client: t,
|
|
2567
|
+
query: `search: ${o}`,
|
|
2568
|
+
limit: $.TASKS_MAX,
|
|
2569
|
+
cursor: void 0
|
|
2570
|
+
}),
|
|
2571
|
+
t.getProjects({ limit: $.PROJECTS_MAX })
|
|
2572
|
+
]), i = o.toLowerCase(), c = r.results.filter(
|
|
2573
|
+
(d) => d.name.toLowerCase().includes(i)
|
|
2574
|
+
), a = [];
|
|
2575
|
+
for (const d of n.tasks)
|
|
2576
|
+
a.push({
|
|
2577
|
+
id: `task:${d.id}`,
|
|
2578
|
+
title: d.content,
|
|
2579
|
+
url: he(d.id)
|
|
2580
|
+
});
|
|
2581
|
+
for (const d of c)
|
|
2582
|
+
a.push({
|
|
2583
|
+
id: `project:${d.id}`,
|
|
2584
|
+
title: d.name,
|
|
2585
|
+
url: me(d.id)
|
|
2586
|
+
});
|
|
2587
|
+
return {
|
|
2588
|
+
textContent: JSON.stringify({ results: a }),
|
|
2589
|
+
structuredContent: { results: a, totalCount: a.length }
|
|
2590
|
+
};
|
|
2598
2591
|
}
|
|
2599
2592
|
}, Ps = s.object({
|
|
2600
2593
|
id: s.string().min(1).describe("The ID of the comment to update."),
|
|
@@ -2602,32 +2595,32 @@ const xs = {
|
|
|
2602
2595
|
}), Es = {
|
|
2603
2596
|
comments: s.array(Ps).min(1).describe("The comments to update.")
|
|
2604
2597
|
}, Os = {
|
|
2605
|
-
comments: s.array(
|
|
2598
|
+
comments: s.array(ne).describe("The updated comments."),
|
|
2606
2599
|
totalCount: s.number().describe("The total number of comments updated."),
|
|
2607
2600
|
updatedCommentIds: s.array(s.string()).describe("The IDs of the updated comments."),
|
|
2608
2601
|
appliedOperations: s.object({
|
|
2609
2602
|
updateCount: s.number().describe("The number of comments updated.")
|
|
2610
2603
|
}).describe("Summary of operations performed.")
|
|
2611
2604
|
}, _s = {
|
|
2612
|
-
name:
|
|
2605
|
+
name: g.UPDATE_COMMENTS,
|
|
2613
2606
|
description: "Update multiple existing comments with new content.",
|
|
2614
2607
|
parameters: Es,
|
|
2615
2608
|
outputSchema: Os,
|
|
2616
2609
|
async execute(e, t) {
|
|
2617
|
-
const { comments: o } = e, n = o.map(async (a) => await t.updateComment(a.id, { content: a.content })),
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2610
|
+
const { comments: o } = e, n = o.map(async (a) => await t.updateComment(a.id, { content: a.content })), i = (await Promise.all(n)).map(ee);
|
|
2611
|
+
return {
|
|
2612
|
+
textContent: Ns({
|
|
2613
|
+
comments: i
|
|
2614
|
+
}),
|
|
2622
2615
|
structuredContent: {
|
|
2623
|
-
comments:
|
|
2624
|
-
totalCount:
|
|
2625
|
-
updatedCommentIds:
|
|
2616
|
+
comments: i,
|
|
2617
|
+
totalCount: i.length,
|
|
2618
|
+
updatedCommentIds: i.map((a) => a.id),
|
|
2626
2619
|
appliedOperations: {
|
|
2627
|
-
updateCount:
|
|
2620
|
+
updateCount: i.length
|
|
2628
2621
|
}
|
|
2629
2622
|
}
|
|
2630
|
-
}
|
|
2623
|
+
};
|
|
2631
2624
|
}
|
|
2632
2625
|
};
|
|
2633
2626
|
function Ns({ comments: e }) {
|
|
@@ -2650,7 +2643,7 @@ const Ms = s.object({
|
|
|
2650
2643
|
}), Fs = {
|
|
2651
2644
|
projects: s.array(Ms).min(1).describe("The projects to update.")
|
|
2652
2645
|
}, Rs = {
|
|
2653
|
-
projects: s.array(
|
|
2646
|
+
projects: s.array(se).describe("The updated projects."),
|
|
2654
2647
|
totalCount: s.number().describe("The total number of projects updated."),
|
|
2655
2648
|
updatedProjectIds: s.array(s.string()).describe("The IDs of the updated projects."),
|
|
2656
2649
|
appliedOperations: s.object({
|
|
@@ -2658,45 +2651,49 @@ const Ms = s.object({
|
|
|
2658
2651
|
skippedCount: s.number().describe("The number of projects skipped (no changes).")
|
|
2659
2652
|
}).describe("Summary of operations performed.")
|
|
2660
2653
|
}, Ls = {
|
|
2661
|
-
name:
|
|
2654
|
+
name: g.UPDATE_PROJECTS,
|
|
2662
2655
|
description: "Update multiple existing projects with new values.",
|
|
2663
2656
|
parameters: Fs,
|
|
2664
2657
|
outputSchema: Rs,
|
|
2665
2658
|
async execute(e, t) {
|
|
2666
|
-
const { projects: o } = e, n = o.map(async (
|
|
2667
|
-
if (!Ws(
|
|
2659
|
+
const { projects: o } = e, n = o.map(async (c) => {
|
|
2660
|
+
if (!Ws(c))
|
|
2668
2661
|
return;
|
|
2669
|
-
const { id:
|
|
2670
|
-
return await t.updateProject(
|
|
2662
|
+
const { id: a, ...d } = c;
|
|
2663
|
+
return await t.updateProject(a, d);
|
|
2671
2664
|
}), r = (await Promise.all(n)).filter(
|
|
2672
|
-
(
|
|
2673
|
-
)
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2665
|
+
(c) => c !== void 0
|
|
2666
|
+
).map((c) => ({
|
|
2667
|
+
...c,
|
|
2668
|
+
parentId: "parentId" in c ? c.parentId ?? void 0 : void 0,
|
|
2669
|
+
inboxProject: "inboxProject" in c ? c.inboxProject : !1
|
|
2670
|
+
}));
|
|
2671
|
+
return {
|
|
2672
|
+
textContent: Bs({
|
|
2673
|
+
projects: r,
|
|
2674
|
+
args: e
|
|
2675
|
+
}),
|
|
2679
2676
|
structuredContent: {
|
|
2680
2677
|
projects: r,
|
|
2681
2678
|
totalCount: r.length,
|
|
2682
|
-
updatedProjectIds: r.map((
|
|
2679
|
+
updatedProjectIds: r.map((c) => c.id),
|
|
2683
2680
|
appliedOperations: {
|
|
2684
2681
|
updateCount: r.length,
|
|
2685
2682
|
skippedCount: o.length - r.length
|
|
2686
2683
|
}
|
|
2687
2684
|
}
|
|
2688
|
-
}
|
|
2685
|
+
};
|
|
2689
2686
|
}
|
|
2690
2687
|
};
|
|
2691
2688
|
function Bs({
|
|
2692
2689
|
projects: e,
|
|
2693
2690
|
args: t
|
|
2694
2691
|
}) {
|
|
2695
|
-
const o = t.projects.length, n = e.length, r = o - n, i = e.length,
|
|
2692
|
+
const o = t.projects.length, n = e.length, r = o - n, i = e.length, c = e.map((d) => `• ${d.name} (id=${d.id})`).join(`
|
|
2696
2693
|
`);
|
|
2697
|
-
let
|
|
2698
|
-
return r > 0 && (
|
|
2699
|
-
${
|
|
2694
|
+
let a = `Updated ${i} project${i === 1 ? "" : "s"}`;
|
|
2695
|
+
return r > 0 && (a += ` (${r} skipped - no changes)`), i > 0 && (a += `:
|
|
2696
|
+
${c}`), a;
|
|
2700
2697
|
}
|
|
2701
2698
|
function Ws({ id: e, ...t }) {
|
|
2702
2699
|
return Object.keys(t).length > 0;
|
|
@@ -2704,34 +2701,34 @@ function Ws({ id: e, ...t }) {
|
|
|
2704
2701
|
const Ys = s.object({
|
|
2705
2702
|
id: s.string().min(1).describe("The ID of the section to update."),
|
|
2706
2703
|
name: s.string().min(1).describe("The new name of the section.")
|
|
2707
|
-
}),
|
|
2704
|
+
}), zs = {
|
|
2708
2705
|
sections: s.array(Ys).min(1).describe("The sections to update.")
|
|
2709
|
-
},
|
|
2710
|
-
sections: s.array(
|
|
2706
|
+
}, Ks = {
|
|
2707
|
+
sections: s.array(oe).describe("The updated sections."),
|
|
2711
2708
|
totalCount: s.number().describe("The total number of sections updated."),
|
|
2712
2709
|
updatedSectionIds: s.array(s.string()).describe("The IDs of the updated sections.")
|
|
2713
|
-
},
|
|
2714
|
-
name:
|
|
2710
|
+
}, Hs = {
|
|
2711
|
+
name: g.UPDATE_SECTIONS,
|
|
2715
2712
|
description: "Update multiple existing sections with new values.",
|
|
2716
|
-
parameters:
|
|
2717
|
-
outputSchema:
|
|
2713
|
+
parameters: zs,
|
|
2714
|
+
outputSchema: Ks,
|
|
2718
2715
|
async execute({ sections: e }, t) {
|
|
2719
2716
|
const o = await Promise.all(
|
|
2720
2717
|
e.map((r) => t.updateSection(r.id, { name: r.name }))
|
|
2721
|
-
)
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2718
|
+
);
|
|
2719
|
+
return {
|
|
2720
|
+
textContent: Vs({
|
|
2721
|
+
sections: o
|
|
2722
|
+
}),
|
|
2726
2723
|
structuredContent: {
|
|
2727
2724
|
sections: o,
|
|
2728
2725
|
totalCount: o.length,
|
|
2729
2726
|
updatedSectionIds: o.map((r) => r.id)
|
|
2730
2727
|
}
|
|
2731
|
-
}
|
|
2728
|
+
};
|
|
2732
2729
|
}
|
|
2733
2730
|
};
|
|
2734
|
-
function
|
|
2731
|
+
function Vs({ sections: e }) {
|
|
2735
2732
|
const t = e.length, o = e.map((r) => `• ${r.name} (id=${r.id}, projectId=${r.projectId})`).join(`
|
|
2736
2733
|
`);
|
|
2737
2734
|
return `Updated ${t} section${t === 1 ? "" : "s"}:
|
|
@@ -2776,13 +2773,13 @@ const Gs = s.object({
|
|
|
2776
2773
|
skippedCount: s.number().describe("The number of tasks skipped (no changes).")
|
|
2777
2774
|
}).describe("Summary of operations performed.")
|
|
2778
2775
|
}, Xs = {
|
|
2779
|
-
name:
|
|
2776
|
+
name: g.UPDATE_TASKS,
|
|
2780
2777
|
description: "Update existing tasks including content, dates, priorities, and assignments.",
|
|
2781
2778
|
parameters: qs,
|
|
2782
2779
|
outputSchema: Js,
|
|
2783
2780
|
async execute(e, t) {
|
|
2784
|
-
const { tasks: o } = e, n = o.map(async (
|
|
2785
|
-
if (!Qs(
|
|
2781
|
+
const { tasks: o } = e, n = o.map(async (a) => {
|
|
2782
|
+
if (!Qs(a))
|
|
2786
2783
|
return;
|
|
2787
2784
|
const {
|
|
2788
2785
|
id: d,
|
|
@@ -2791,67 +2788,67 @@ const Gs = s.object({
|
|
|
2791
2788
|
parentId: p,
|
|
2792
2789
|
duration: b,
|
|
2793
2790
|
responsibleUser: m,
|
|
2794
|
-
priority:
|
|
2795
|
-
labels:
|
|
2796
|
-
deadlineDate:
|
|
2797
|
-
...
|
|
2798
|
-
} =
|
|
2799
|
-
let
|
|
2800
|
-
l === "inbox" && (
|
|
2791
|
+
priority: y,
|
|
2792
|
+
labels: k,
|
|
2793
|
+
deadlineDate: w,
|
|
2794
|
+
...D
|
|
2795
|
+
} = a;
|
|
2796
|
+
let P = l;
|
|
2797
|
+
l === "inbox" && (P = (await t.getUser()).inboxProjectId);
|
|
2801
2798
|
let h = {
|
|
2802
|
-
...
|
|
2803
|
-
...
|
|
2799
|
+
...D,
|
|
2800
|
+
...k !== void 0 && { labels: k }
|
|
2804
2801
|
};
|
|
2805
|
-
if (
|
|
2802
|
+
if (y && (h.priority = Ie(y)), w !== void 0 && (w === null || w === "remove" ? h = { ...h, deadlineDate: null } : h = { ...h, deadlineDate: w }), b)
|
|
2806
2803
|
try {
|
|
2807
|
-
const { minutes:
|
|
2804
|
+
const { minutes: v } = be(b);
|
|
2808
2805
|
h = {
|
|
2809
2806
|
...h,
|
|
2810
|
-
duration:
|
|
2807
|
+
duration: v,
|
|
2811
2808
|
durationUnit: "minute"
|
|
2812
2809
|
};
|
|
2813
|
-
} catch (
|
|
2814
|
-
throw
|
|
2810
|
+
} catch (v) {
|
|
2811
|
+
throw v instanceof U ? new Error(`Task ${d}: ${v.message}`) : v;
|
|
2815
2812
|
}
|
|
2816
2813
|
if (m !== void 0)
|
|
2817
2814
|
if (m === null || m === "unassign")
|
|
2818
2815
|
h = { ...h, assigneeId: null };
|
|
2819
2816
|
else {
|
|
2820
|
-
const
|
|
2817
|
+
const v = await re.validateTaskUpdateAssignment(
|
|
2821
2818
|
t,
|
|
2822
2819
|
d,
|
|
2823
2820
|
m
|
|
2824
2821
|
);
|
|
2825
|
-
if (!
|
|
2826
|
-
const f =
|
|
2822
|
+
if (!v.isValid) {
|
|
2823
|
+
const f = v.error?.message || "Assignment validation failed", j = v.error?.suggestions?.join(". ") || "";
|
|
2827
2824
|
throw new Error(
|
|
2828
|
-
`Task ${d}: ${f}${
|
|
2825
|
+
`Task ${d}: ${f}${j ? `. ${j}` : ""}`
|
|
2829
2826
|
);
|
|
2830
2827
|
}
|
|
2831
|
-
h = { ...h, assigneeId:
|
|
2828
|
+
h = { ...h, assigneeId: v.resolvedUser?.userId };
|
|
2832
2829
|
}
|
|
2833
|
-
if (!
|
|
2830
|
+
if (!P && !u && !p)
|
|
2834
2831
|
return await t.updateTask(d, h);
|
|
2835
|
-
const
|
|
2832
|
+
const T = Fe(d, P, u, p), C = await t.moveTask(d, T);
|
|
2836
2833
|
return Object.keys(h).length > 0 ? await t.updateTask(d, h) : C;
|
|
2837
2834
|
}), r = (await Promise.all(n)).filter(
|
|
2838
|
-
(
|
|
2839
|
-
), i = r.map(O)
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2835
|
+
(a) => a !== void 0
|
|
2836
|
+
), i = r.map(O);
|
|
2837
|
+
return {
|
|
2838
|
+
textContent: Zs({
|
|
2839
|
+
tasks: i,
|
|
2840
|
+
args: e
|
|
2841
|
+
}),
|
|
2845
2842
|
structuredContent: {
|
|
2846
2843
|
tasks: i,
|
|
2847
2844
|
totalCount: i.length,
|
|
2848
|
-
updatedTaskIds: r.map((
|
|
2845
|
+
updatedTaskIds: r.map((a) => a.id),
|
|
2849
2846
|
appliedOperations: {
|
|
2850
2847
|
updateCount: i.length,
|
|
2851
2848
|
skippedCount: o.length - i.length
|
|
2852
2849
|
}
|
|
2853
2850
|
}
|
|
2854
|
-
}
|
|
2851
|
+
};
|
|
2855
2852
|
}
|
|
2856
2853
|
};
|
|
2857
2854
|
function Zs({
|
|
@@ -2903,7 +2900,7 @@ function ro(e) {
|
|
|
2903
2900
|
function io(e) {
|
|
2904
2901
|
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][e === 7 ? 0 : e] ?? "Unknown";
|
|
2905
2902
|
}
|
|
2906
|
-
function
|
|
2903
|
+
function z(e) {
|
|
2907
2904
|
return e.toISOString().split("T")[0] ?? "";
|
|
2908
2905
|
}
|
|
2909
2906
|
function ao(e) {
|
|
@@ -2913,11 +2910,11 @@ function ao(e) {
|
|
|
2913
2910
|
return !1;
|
|
2914
2911
|
}
|
|
2915
2912
|
}
|
|
2916
|
-
function
|
|
2913
|
+
function $e(e) {
|
|
2917
2914
|
return ao(e) ? e : "UTC";
|
|
2918
2915
|
}
|
|
2919
2916
|
function co(e, t) {
|
|
2920
|
-
const o =
|
|
2917
|
+
const o = $e(t);
|
|
2921
2918
|
return e.toLocaleString("en-US", {
|
|
2922
2919
|
timeZone: o,
|
|
2923
2920
|
year: "numeric",
|
|
@@ -2930,7 +2927,7 @@ function co(e, t) {
|
|
|
2930
2927
|
});
|
|
2931
2928
|
}
|
|
2932
2929
|
async function lo(e) {
|
|
2933
|
-
const t = await e.getUser(), o = t.tzInfo?.timezone ?? "UTC", n =
|
|
2930
|
+
const t = await e.getUser(), o = t.tzInfo?.timezone ?? "UTC", n = $e(o), r = /* @__PURE__ */ new Date(), i = co(r, n), c = t.startDay ?? 1, a = io(c), d = so(t), l = new Date(r.toLocaleString("en-US", { timeZone: n })), u = oo(l, c), p = no(u), b = ro(l), y = [
|
|
2934
2931
|
"# User Information",
|
|
2935
2932
|
"",
|
|
2936
2933
|
`**User ID:** ${t.id}`,
|
|
@@ -2940,10 +2937,10 @@ async function lo(e) {
|
|
|
2940
2937
|
`**Current Local Time:** ${i}`,
|
|
2941
2938
|
"",
|
|
2942
2939
|
"## Week Settings",
|
|
2943
|
-
`**Week Start Day:** ${
|
|
2940
|
+
`**Week Start Day:** ${a} (${c})`,
|
|
2944
2941
|
`**Current Week:** Week ${b}`,
|
|
2945
|
-
`**Week Start Date:** ${
|
|
2946
|
-
`**Week End Date:** ${
|
|
2942
|
+
`**Week Start Date:** ${z(u)}`,
|
|
2943
|
+
`**Week End Date:** ${z(p)}`,
|
|
2947
2944
|
"",
|
|
2948
2945
|
"## Daily Progress",
|
|
2949
2946
|
`**Completed Today:** ${t.completedToday}`,
|
|
@@ -2953,16 +2950,16 @@ async function lo(e) {
|
|
|
2953
2950
|
"## Account Info",
|
|
2954
2951
|
`**Plan:** ${d}`
|
|
2955
2952
|
].join(`
|
|
2956
|
-
`),
|
|
2953
|
+
`), k = {
|
|
2957
2954
|
type: "user_info",
|
|
2958
2955
|
userId: t.id,
|
|
2959
2956
|
fullName: t.fullName,
|
|
2960
2957
|
timezone: n,
|
|
2961
2958
|
currentLocalTime: i,
|
|
2962
|
-
startDay:
|
|
2963
|
-
startDayName:
|
|
2964
|
-
weekStartDate:
|
|
2965
|
-
weekEndDate:
|
|
2959
|
+
startDay: c,
|
|
2960
|
+
startDayName: a,
|
|
2961
|
+
weekStartDate: z(u),
|
|
2962
|
+
weekEndDate: z(p),
|
|
2966
2963
|
currentWeekNumber: b,
|
|
2967
2964
|
completedToday: t.completedToday,
|
|
2968
2965
|
dailyGoal: t.dailyGoal,
|
|
@@ -2970,19 +2967,19 @@ async function lo(e) {
|
|
|
2970
2967
|
email: t.email,
|
|
2971
2968
|
plan: d
|
|
2972
2969
|
};
|
|
2973
|
-
return { textContent:
|
|
2970
|
+
return { textContent: y, structuredContent: k };
|
|
2974
2971
|
}
|
|
2975
2972
|
const uo = {
|
|
2976
|
-
name:
|
|
2973
|
+
name: g.USER_INFO,
|
|
2977
2974
|
description: "Get comprehensive user information including user ID, full name, email, timezone with current local time, week start day preferences, current week dates, daily/weekly goal progress, and user plan (Free/Pro/Business).",
|
|
2978
2975
|
parameters: eo,
|
|
2979
2976
|
outputSchema: to,
|
|
2980
2977
|
async execute(e, t) {
|
|
2981
2978
|
const o = await lo(t);
|
|
2982
|
-
return
|
|
2979
|
+
return {
|
|
2983
2980
|
textContent: o.textContent,
|
|
2984
2981
|
structuredContent: o.structuredContent
|
|
2985
|
-
}
|
|
2982
|
+
};
|
|
2986
2983
|
}
|
|
2987
2984
|
}, po = `
|
|
2988
2985
|
## Todoist Task and Project Management Tools
|
|
@@ -3052,8 +3049,8 @@ You have access to comprehensive Todoist management tools for personal productiv
|
|
|
3052
3049
|
|
|
3053
3050
|
Always provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.
|
|
3054
3051
|
`;
|
|
3055
|
-
function
|
|
3056
|
-
const o = new
|
|
3052
|
+
function To({ todoistApiKey: e, baseUrl: t }) {
|
|
3053
|
+
const o = new xe(
|
|
3057
3054
|
{ name: "todoist-mcp-server", version: "0.1.0" },
|
|
3058
3055
|
{
|
|
3059
3056
|
capabilities: {
|
|
@@ -3061,32 +3058,32 @@ function go({ todoistApiKey: e, baseUrl: t }) {
|
|
|
3061
3058
|
},
|
|
3062
3059
|
instructions: po
|
|
3063
3060
|
}
|
|
3064
|
-
), n = new
|
|
3065
|
-
return
|
|
3061
|
+
), n = new De(e, t);
|
|
3062
|
+
return I(bt, o, n), I(kt, o, n), I(Xs, o, n), I(cs, o, n), I(ps, o, n), I(Yt, o, n), I(Qe, o, n), I(Ls, o, n), I(Qt, o, n), I(nt, o, n), I(Hs, o, n), I(ns, o, n), I(Ge, o, n), I(Ft, o, n), I(_s, o, n), I(Ut, o, n), I(ws, o, n), I(Ct, o, n), I(uo, o, n), I(Gt, o, n), I(Ds, o, n), I(Us, o, n), I(Dt, o, n), o;
|
|
3066
3063
|
}
|
|
3067
3064
|
export {
|
|
3068
3065
|
Gt as a,
|
|
3069
3066
|
ws as b,
|
|
3070
3067
|
Ut as c,
|
|
3071
|
-
|
|
3068
|
+
Ct as d,
|
|
3072
3069
|
Ft as e,
|
|
3073
3070
|
Dt as f,
|
|
3074
|
-
|
|
3071
|
+
To as g,
|
|
3075
3072
|
_s as h,
|
|
3076
|
-
|
|
3073
|
+
Ge as i,
|
|
3077
3074
|
ns as j,
|
|
3078
|
-
|
|
3079
|
-
|
|
3075
|
+
Hs as k,
|
|
3076
|
+
nt as l,
|
|
3080
3077
|
Ds as m,
|
|
3081
3078
|
Qt as n,
|
|
3082
3079
|
Ls as o,
|
|
3083
|
-
|
|
3080
|
+
Qe as p,
|
|
3084
3081
|
Yt as q,
|
|
3085
3082
|
ps as r,
|
|
3086
3083
|
Us as s,
|
|
3087
3084
|
cs as t,
|
|
3088
3085
|
uo as u,
|
|
3089
3086
|
Xs as v,
|
|
3090
|
-
|
|
3091
|
-
|
|
3087
|
+
kt as w,
|
|
3088
|
+
bt as x
|
|
3092
3089
|
};
|