@doist/todoist-ai 4.4.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +168 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -16
- package/dist/mcp-helpers.d.ts.map +1 -1
- package/dist/mcp-helpers.js +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +78 -17
- package/dist/tool-helpers.d.ts +4 -0
- package/dist/tool-helpers.d.ts.map +1 -1
- package/dist/tool-helpers.js +2 -0
- package/dist/tools/__tests__/add-projects.test.js +1 -1
- package/dist/tools/__tests__/add-sections.test.js +1 -1
- package/dist/tools/__tests__/add-tasks.test.js +182 -13
- package/dist/tools/__tests__/assignment-integration.test.d.ts +2 -0
- package/dist/tools/__tests__/assignment-integration.test.d.ts.map +1 -0
- package/dist/tools/__tests__/assignment-integration.test.js +415 -0
- package/dist/tools/__tests__/find-projects.test.js +1 -1
- package/dist/tools/__tests__/find-sections.test.js +1 -1
- package/dist/tools/__tests__/find-tasks-by-date.test.js +1 -1
- package/dist/tools/__tests__/find-tasks.test.js +3 -3
- package/dist/tools/__tests__/get-overview.test.js +1 -1
- package/dist/tools/__tests__/update-tasks.test.js +82 -6
- package/dist/tools/__tests__/user-info.test.js +1 -1
- package/dist/tools/add-comments.d.ts +3 -3
- package/dist/tools/add-comments.d.ts.map +1 -1
- package/dist/tools/add-comments.js +1 -1
- package/dist/tools/add-projects.d.ts.map +1 -1
- package/dist/tools/add-projects.js +1 -1
- package/dist/tools/add-sections.d.ts.map +1 -1
- package/dist/tools/add-sections.js +1 -1
- package/dist/tools/add-tasks.d.ts +17 -7
- package/dist/tools/add-tasks.d.ts.map +1 -1
- package/dist/tools/add-tasks.js +51 -4
- package/dist/tools/find-comments.d.ts +2 -2
- package/dist/tools/find-completed-tasks.d.ts +4 -2
- package/dist/tools/find-completed-tasks.d.ts.map +1 -1
- package/dist/tools/find-completed-tasks.js +2 -2
- package/dist/tools/find-project-collaborators.d.ts +64 -0
- package/dist/tools/find-project-collaborators.d.ts.map +1 -0
- package/dist/tools/find-project-collaborators.js +151 -0
- package/dist/tools/find-tasks-by-date.d.ts +2 -0
- package/dist/tools/find-tasks-by-date.d.ts.map +1 -1
- package/dist/tools/find-tasks-by-date.js +2 -2
- package/dist/tools/find-tasks.d.ts +7 -2
- package/dist/tools/find-tasks.d.ts.map +1 -1
- package/dist/tools/find-tasks.js +128 -33
- package/dist/tools/get-overview.d.ts +2 -2
- package/dist/tools/get-overview.d.ts.map +1 -1
- package/dist/tools/get-overview.js +1 -1
- package/dist/tools/manage-assignments.d.ts +52 -0
- package/dist/tools/manage-assignments.d.ts.map +1 -0
- package/dist/tools/manage-assignments.js +337 -0
- package/dist/tools/update-comments.d.ts.map +1 -1
- package/dist/tools/update-comments.js +1 -1
- package/dist/tools/update-sections.d.ts.map +1 -1
- package/dist/tools/update-sections.js +1 -1
- package/dist/tools/update-tasks.d.ts +17 -7
- package/dist/tools/update-tasks.d.ts.map +1 -1
- package/dist/tools/update-tasks.js +40 -10
- package/dist/utils/assignment-validator.d.ts +69 -0
- package/dist/utils/assignment-validator.d.ts.map +1 -0
- package/dist/utils/assignment-validator.js +253 -0
- package/dist/utils/duration-parser.d.ts +2 -2
- package/dist/utils/duration-parser.d.ts.map +1 -1
- package/dist/utils/priorities.d.ts +8 -0
- package/dist/utils/priorities.d.ts.map +1 -0
- package/dist/utils/priorities.js +15 -0
- package/dist/utils/response-builders.d.ts +2 -2
- package/dist/utils/response-builders.d.ts.map +1 -1
- package/dist/utils/response-builders.js +8 -1
- package/dist/utils/test-helpers.d.ts +2 -0
- package/dist/utils/test-helpers.d.ts.map +1 -1
- package/dist/utils/test-helpers.js +2 -0
- package/dist/utils/tool-names.d.ts +2 -0
- package/dist/utils/tool-names.d.ts.map +1 -1
- package/dist/utils/tool-names.js +3 -0
- package/dist/utils/user-resolver.d.ts +39 -0
- package/dist/utils/user-resolver.d.ts.map +1 -0
- package/dist/utils/user-resolver.js +179 -0
- package/package.json +6 -6
package/dist/tools/find-tasks.js
CHANGED
|
@@ -2,15 +2,20 @@ import { z } from 'zod';
|
|
|
2
2
|
import { getToolOutput } from '../mcp-helpers.js';
|
|
3
3
|
import { getTasksByFilter, mapTask } from '../tool-helpers.js';
|
|
4
4
|
import { ApiLimits } from '../utils/constants.js';
|
|
5
|
-
import {
|
|
5
|
+
import { generateLabelsFilter, LabelsSchema } from '../utils/labels.js';
|
|
6
6
|
import { generateTaskNextSteps, getDateString, previewTasks, summarizeList, } from '../utils/response-builders.js';
|
|
7
7
|
import { ToolNames } from '../utils/tool-names.js';
|
|
8
|
+
import { resolveUserNameToId } from '../utils/user-resolver.js';
|
|
8
9
|
const { FIND_COMPLETED_TASKS, ADD_TASKS } = ToolNames;
|
|
9
10
|
const ArgsSchema = {
|
|
10
11
|
searchText: z.string().optional().describe('The text to search for in tasks.'),
|
|
11
12
|
projectId: z.string().optional().describe('Find tasks in this project.'),
|
|
12
13
|
sectionId: z.string().optional().describe('Find tasks in this section.'),
|
|
13
14
|
parentId: z.string().optional().describe('Find subtasks of this parent task.'),
|
|
15
|
+
responsibleUser: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Find tasks assigned to this user. Can be a user ID, name, or email address.'),
|
|
14
19
|
limit: z
|
|
15
20
|
.number()
|
|
16
21
|
.int()
|
|
@@ -26,14 +31,32 @@ const ArgsSchema = {
|
|
|
26
31
|
};
|
|
27
32
|
const findTasks = {
|
|
28
33
|
name: ToolNames.FIND_TASKS,
|
|
29
|
-
description: 'Find tasks by text search, or by project/section/parent container. At least one filter must be provided.',
|
|
34
|
+
description: 'Find tasks by text search, or by project/section/parent container/responsible user. At least one filter must be provided.',
|
|
30
35
|
parameters: ArgsSchema,
|
|
31
36
|
async execute(args, client) {
|
|
32
|
-
const { searchText, projectId, sectionId, parentId, limit, cursor, labels, labelsOperator, } = args;
|
|
37
|
+
const { searchText, projectId, sectionId, parentId, responsibleUser, limit, cursor, labels, labelsOperator, } = args;
|
|
33
38
|
// Validate at least one filter is provided
|
|
34
39
|
const hasLabels = labels && labels.length > 0;
|
|
35
|
-
if (!searchText &&
|
|
36
|
-
|
|
40
|
+
if (!searchText &&
|
|
41
|
+
!projectId &&
|
|
42
|
+
!sectionId &&
|
|
43
|
+
!parentId &&
|
|
44
|
+
!responsibleUser &&
|
|
45
|
+
!hasLabels) {
|
|
46
|
+
throw new Error('At least one filter must be provided: searchText, projectId, sectionId, parentId, responsibleUser, or labels');
|
|
47
|
+
}
|
|
48
|
+
// Resolve assignee name to user ID if provided
|
|
49
|
+
let resolvedAssigneeId = responsibleUser;
|
|
50
|
+
let assigneeDisplayName;
|
|
51
|
+
if (responsibleUser) {
|
|
52
|
+
const resolved = await resolveUserNameToId(client, responsibleUser);
|
|
53
|
+
if (resolved) {
|
|
54
|
+
resolvedAssigneeId = resolved.userId;
|
|
55
|
+
assigneeDisplayName = resolved.displayName;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new Error(`Could not find user: "${responsibleUser}". Make sure the user is a collaborator on a shared project.`);
|
|
59
|
+
}
|
|
37
60
|
}
|
|
38
61
|
// If using container-based filtering, use direct API
|
|
39
62
|
if (projectId || sectionId || parentId) {
|
|
@@ -49,36 +72,68 @@ const findTasks = {
|
|
|
49
72
|
taskParams.parentId = parentId;
|
|
50
73
|
const { results, nextCursor } = await client.getTasks(taskParams);
|
|
51
74
|
const mappedTasks = results.map(mapTask);
|
|
52
|
-
//
|
|
53
|
-
let
|
|
75
|
+
// Apply search text filter
|
|
76
|
+
let filteredTasks = searchText
|
|
54
77
|
? mappedTasks.filter((task) => task.content.toLowerCase().includes(searchText.toLowerCase()) ||
|
|
55
78
|
task.description?.toLowerCase().includes(searchText.toLowerCase()))
|
|
56
79
|
: mappedTasks;
|
|
57
|
-
//
|
|
80
|
+
// Apply responsibleUid filter
|
|
81
|
+
if (resolvedAssigneeId) {
|
|
82
|
+
filteredTasks = filteredTasks.filter((task) => task.responsibleUid === resolvedAssigneeId);
|
|
83
|
+
}
|
|
84
|
+
// Apply label filter
|
|
58
85
|
if (labels && labels.length > 0) {
|
|
59
|
-
|
|
86
|
+
filteredTasks =
|
|
60
87
|
labelsOperator === 'and'
|
|
61
|
-
?
|
|
62
|
-
:
|
|
88
|
+
? filteredTasks.filter((task) => labels.every((label) => task.labels.includes(label)))
|
|
89
|
+
: filteredTasks.filter((task) => labels.some((label) => task.labels.includes(label)));
|
|
63
90
|
}
|
|
64
91
|
const textContent = generateTextContent({
|
|
65
|
-
tasks:
|
|
92
|
+
tasks: filteredTasks,
|
|
66
93
|
args,
|
|
67
94
|
nextCursor,
|
|
68
95
|
isContainerSearch: true,
|
|
96
|
+
assigneeDisplayName,
|
|
69
97
|
});
|
|
70
98
|
return getToolOutput({
|
|
71
99
|
textContent,
|
|
72
100
|
structuredContent: {
|
|
73
|
-
tasks:
|
|
101
|
+
tasks: filteredTasks,
|
|
74
102
|
nextCursor,
|
|
75
|
-
totalCount:
|
|
103
|
+
totalCount: filteredTasks.length,
|
|
76
104
|
hasMore: Boolean(nextCursor),
|
|
77
105
|
appliedFilters: args,
|
|
78
106
|
},
|
|
79
107
|
});
|
|
80
108
|
}
|
|
81
|
-
//
|
|
109
|
+
// If only responsibleUid is provided (without containers), use assignee filter
|
|
110
|
+
if (resolvedAssigneeId && !searchText && !hasLabels) {
|
|
111
|
+
const tasks = await client.getTasksByFilter({
|
|
112
|
+
query: `assigned to: ${assigneeDisplayName}`,
|
|
113
|
+
lang: 'en',
|
|
114
|
+
limit,
|
|
115
|
+
cursor: cursor ?? null,
|
|
116
|
+
});
|
|
117
|
+
const mappedTasks = tasks.results.map(mapTask);
|
|
118
|
+
const textContent = generateTextContent({
|
|
119
|
+
tasks: mappedTasks,
|
|
120
|
+
args,
|
|
121
|
+
nextCursor: tasks.nextCursor,
|
|
122
|
+
isContainerSearch: false,
|
|
123
|
+
assigneeDisplayName,
|
|
124
|
+
});
|
|
125
|
+
return getToolOutput({
|
|
126
|
+
textContent,
|
|
127
|
+
structuredContent: {
|
|
128
|
+
tasks: mappedTasks,
|
|
129
|
+
nextCursor: tasks.nextCursor,
|
|
130
|
+
totalCount: mappedTasks.length,
|
|
131
|
+
hasMore: Boolean(tasks.nextCursor),
|
|
132
|
+
appliedFilters: args,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Handle search text and/or labels using filter query (responsibleUid filtering done client-side)
|
|
82
137
|
let query = '';
|
|
83
138
|
// Add search text component
|
|
84
139
|
if (searchText) {
|
|
@@ -101,18 +156,24 @@ const findTasks = {
|
|
|
101
156
|
cursor: args.cursor,
|
|
102
157
|
limit: args.limit,
|
|
103
158
|
});
|
|
159
|
+
// Always filter by responsibleUid client-side (API doesn't reliably support responsibleUid filtering)
|
|
160
|
+
let tasks = result.tasks;
|
|
161
|
+
if (resolvedAssigneeId) {
|
|
162
|
+
tasks = result.tasks.filter((task) => task.responsibleUid === resolvedAssigneeId);
|
|
163
|
+
}
|
|
104
164
|
const textContent = generateTextContent({
|
|
105
|
-
tasks
|
|
165
|
+
tasks,
|
|
106
166
|
args,
|
|
107
167
|
nextCursor: result.nextCursor,
|
|
108
168
|
isContainerSearch: false,
|
|
169
|
+
assigneeDisplayName,
|
|
109
170
|
});
|
|
110
171
|
return getToolOutput({
|
|
111
172
|
textContent,
|
|
112
173
|
structuredContent: {
|
|
113
|
-
tasks
|
|
174
|
+
tasks,
|
|
114
175
|
nextCursor: result.nextCursor,
|
|
115
|
-
totalCount:
|
|
176
|
+
totalCount: tasks.length,
|
|
116
177
|
hasMore: Boolean(result.nextCursor),
|
|
117
178
|
appliedFilters: args,
|
|
118
179
|
},
|
|
@@ -145,9 +206,9 @@ function getContainerZeroReasonHints(args) {
|
|
|
145
206
|
}
|
|
146
207
|
return [];
|
|
147
208
|
}
|
|
148
|
-
function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
209
|
+
function generateTextContent({ tasks, args, nextCursor, isContainerSearch, assigneeDisplayName, }) {
|
|
149
210
|
// Generate subject and filter descriptions based on search type
|
|
150
|
-
let subject;
|
|
211
|
+
let subject = 'Tasks';
|
|
151
212
|
const filterHints = [];
|
|
152
213
|
const zeroReasonHints = [];
|
|
153
214
|
if (isContainerSearch) {
|
|
@@ -172,6 +233,12 @@ function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
|
172
233
|
subject += ` matching "${args.searchText}"`;
|
|
173
234
|
filterHints.push(`containing "${args.searchText}"`);
|
|
174
235
|
}
|
|
236
|
+
// Add responsibleUid filter if present
|
|
237
|
+
if (args.responsibleUser) {
|
|
238
|
+
const displayName = assigneeDisplayName || args.responsibleUser;
|
|
239
|
+
subject += ` assigned to ${displayName}`;
|
|
240
|
+
filterHints.push(`assigned to ${displayName}`);
|
|
241
|
+
}
|
|
175
242
|
// Add label filter information
|
|
176
243
|
if (args.labels && args.labels.length > 0) {
|
|
177
244
|
const labelText = args.labels
|
|
@@ -185,34 +252,62 @@ function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
|
185
252
|
}
|
|
186
253
|
}
|
|
187
254
|
else {
|
|
188
|
-
// Text
|
|
255
|
+
// Text, responsibleUid, or labels search
|
|
256
|
+
const displayName = assigneeDisplayName || args.responsibleUser;
|
|
257
|
+
// Build subject based on filters
|
|
258
|
+
const subjectParts = [];
|
|
259
|
+
if (args.searchText) {
|
|
260
|
+
subjectParts.push(`"${args.searchText}"`);
|
|
261
|
+
}
|
|
262
|
+
if (args.responsibleUser) {
|
|
263
|
+
subjectParts.push(`assigned to ${displayName}`);
|
|
264
|
+
}
|
|
265
|
+
if (args.labels && args.labels.length > 0) {
|
|
266
|
+
const labelText = args.labels
|
|
267
|
+
.map((label) => `@${label}`)
|
|
268
|
+
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
269
|
+
subjectParts.push(`with labels: ${labelText}`);
|
|
270
|
+
}
|
|
189
271
|
if (args.searchText) {
|
|
190
|
-
subject = `Search results for
|
|
272
|
+
subject = `Search results for ${subjectParts.join(' ')}`;
|
|
191
273
|
filterHints.push(`matching "${args.searchText}"`);
|
|
192
274
|
}
|
|
193
|
-
else if (args.
|
|
194
|
-
|
|
275
|
+
else if (args.responsibleUser && (!args.labels || args.labels.length === 0)) {
|
|
276
|
+
subject = `Tasks assigned to ${displayName}`;
|
|
277
|
+
}
|
|
278
|
+
else if (args.labels && args.labels.length > 0 && !args.responsibleUser) {
|
|
195
279
|
const labelText = args.labels
|
|
196
280
|
.map((label) => `@${label}`)
|
|
197
281
|
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
198
282
|
subject = `Tasks with labels: ${labelText}`;
|
|
199
|
-
filterHints.push(`labels: ${labelText}`);
|
|
200
283
|
}
|
|
201
284
|
else {
|
|
202
|
-
|
|
203
|
-
subject = 'Tasks';
|
|
285
|
+
subject = `Tasks ${subjectParts.join(' ')}`;
|
|
204
286
|
}
|
|
205
|
-
// Add
|
|
206
|
-
if (args.
|
|
287
|
+
// Add filter hints
|
|
288
|
+
if (args.responsibleUser) {
|
|
289
|
+
filterHints.push(`assigned to ${displayName}`);
|
|
290
|
+
}
|
|
291
|
+
if (args.labels && args.labels.length > 0) {
|
|
207
292
|
const labelText = args.labels
|
|
208
293
|
.map((label) => `@${label}`)
|
|
209
294
|
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
210
295
|
filterHints.push(`labels: ${labelText}`);
|
|
211
296
|
}
|
|
212
297
|
if (tasks.length === 0) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
298
|
+
if (args.responsibleUser) {
|
|
299
|
+
const displayName = assigneeDisplayName || args.responsibleUser;
|
|
300
|
+
zeroReasonHints.push(`No tasks assigned to ${displayName}`);
|
|
301
|
+
zeroReasonHints.push('Check if the user name is correct');
|
|
302
|
+
zeroReasonHints.push(`Check completed tasks with ${FIND_COMPLETED_TASKS}`);
|
|
303
|
+
}
|
|
304
|
+
if (args.searchText) {
|
|
305
|
+
zeroReasonHints.push('Try broader search terms');
|
|
306
|
+
zeroReasonHints.push('Verify spelling and try partial words');
|
|
307
|
+
if (!args.responsibleUser) {
|
|
308
|
+
zeroReasonHints.push(`Check completed tasks with ${FIND_COMPLETED_TASKS}`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
216
311
|
}
|
|
217
312
|
}
|
|
218
313
|
// Generate contextual next steps
|
|
@@ -228,7 +323,7 @@ function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
|
228
323
|
limit: args.limit,
|
|
229
324
|
nextCursor: nextCursor ?? undefined,
|
|
230
325
|
filterHints,
|
|
231
|
-
previewLines: previewTasks(tasks),
|
|
326
|
+
previewLines: previewTasks(tasks, Math.min(tasks.length, args.limit)),
|
|
232
327
|
zeroReasonHints,
|
|
233
328
|
nextSteps,
|
|
234
329
|
});
|
|
@@ -20,7 +20,7 @@ type AccountOverviewStructured = Record<string, unknown> & {
|
|
|
20
20
|
totalSections: number;
|
|
21
21
|
hasNestedProjects: boolean;
|
|
22
22
|
};
|
|
23
|
-
|
|
23
|
+
type ProjectOverviewStructured = Record<string, unknown> & {
|
|
24
24
|
type: 'project_overview';
|
|
25
25
|
project: {
|
|
26
26
|
id: string;
|
|
@@ -35,7 +35,7 @@ interface ProjectOverviewStructured extends Record<string, unknown> {
|
|
|
35
35
|
totalSections: number;
|
|
36
36
|
tasksWithoutSection: number;
|
|
37
37
|
};
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
39
|
declare const getOverview: {
|
|
40
40
|
name: "get-overview";
|
|
41
41
|
description: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-overview.d.ts","sourceRoot":"","sources":["../../src/tools/get-overview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,OAAO,
|
|
1
|
+
{"version":3,"file":"get-overview.d.ts","sourceRoot":"","sources":["../../src/tools/get-overview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,OAAO,EAAqB,OAAO,EAAgB,MAAM,oBAAoB,CAAA;AAgI7E,KAAK,gBAAgB,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAC/B,CAAA;AAED,KAAK,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACvD,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE;QACH,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,OAAO,EAAE,CAAA;KACtB,GAAG,IAAI,CAAA;IACR,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,OAAO,CAAA;CAC7B,CAAA;AAED,KAAK,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACvD,IAAI,EAAE,kBAAkB,CAAA;IACxB,OAAO,EAAE;QACL,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;KACf,CAAA;IACD,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,GAAG;QAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC,CAAA;IAChE,KAAK,EAAE;QACH,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;QACrB,mBAAmB,EAAE,MAAM,CAAA;KAC9B,CAAA;CACJ,CAAA;AA6JD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;CAeyB,CAAA;AAE1C,OAAO,EAAE,WAAW,EAAE,KAAK,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,CAAA"}
|
|
@@ -115,7 +115,7 @@ function buildProjectStructure(project, sectionsByProject) {
|
|
|
115
115
|
}
|
|
116
116
|
async function getAllTasksForProject(client, projectId) {
|
|
117
117
|
let allTasks = [];
|
|
118
|
-
let cursor
|
|
118
|
+
let cursor;
|
|
119
119
|
do {
|
|
120
120
|
const { results, nextCursor } = await client.getTasks({
|
|
121
121
|
projectId,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export type OperationResult = {
|
|
3
|
+
taskId: string;
|
|
4
|
+
success: boolean;
|
|
5
|
+
error?: string;
|
|
6
|
+
originalAssigneeId?: string | null;
|
|
7
|
+
newAssigneeId?: string | null;
|
|
8
|
+
};
|
|
9
|
+
declare const manageAssignments: {
|
|
10
|
+
name: "manage-assignments";
|
|
11
|
+
description: string;
|
|
12
|
+
parameters: {
|
|
13
|
+
operation: z.ZodEnum<["assign", "unassign", "reassign"]>;
|
|
14
|
+
taskIds: z.ZodArray<z.ZodString, "many">;
|
|
15
|
+
responsibleUser: z.ZodOptional<z.ZodString>;
|
|
16
|
+
fromAssigneeUser: z.ZodOptional<z.ZodString>;
|
|
17
|
+
dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
18
|
+
};
|
|
19
|
+
execute(args: {
|
|
20
|
+
operation: "assign" | "unassign" | "reassign";
|
|
21
|
+
taskIds: string[];
|
|
22
|
+
dryRun: boolean;
|
|
23
|
+
responsibleUser?: string | undefined;
|
|
24
|
+
fromAssigneeUser?: string | undefined;
|
|
25
|
+
}, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
|
|
26
|
+
content: {
|
|
27
|
+
type: "text";
|
|
28
|
+
text: string;
|
|
29
|
+
}[];
|
|
30
|
+
structuredContent: {
|
|
31
|
+
operation: "assign" | "unassign" | "reassign";
|
|
32
|
+
results: OperationResult[];
|
|
33
|
+
totalRequested: number;
|
|
34
|
+
successful: number;
|
|
35
|
+
failed: number;
|
|
36
|
+
dryRun: boolean;
|
|
37
|
+
};
|
|
38
|
+
} | {
|
|
39
|
+
content: ({
|
|
40
|
+
type: "text";
|
|
41
|
+
text: string;
|
|
42
|
+
mimeType?: undefined;
|
|
43
|
+
} | {
|
|
44
|
+
type: "text";
|
|
45
|
+
mimeType: string;
|
|
46
|
+
text: string;
|
|
47
|
+
})[];
|
|
48
|
+
structuredContent?: undefined;
|
|
49
|
+
}>;
|
|
50
|
+
};
|
|
51
|
+
export { manageAssignments };
|
|
52
|
+
//# sourceMappingURL=manage-assignments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manage-assignments.d.ts","sourceRoot":"","sources":["../../src/tools/manage-assignments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA4CvB,MAAM,MAAM,eAAe,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC,CAAA;AAED,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoRmB,CAAA;AAuF1C,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
|