@doist/todoist-ai 4.1.0 → 4.5.1
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 +405 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -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 +80 -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 +52 -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-completed-tasks.test.js +136 -2
- 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 +122 -3
- package/dist/tools/__tests__/find-tasks.test.js +258 -11
- package/dist/tools/__tests__/get-overview.test.js +1 -1
- package/dist/tools/__tests__/update-sections.test.js +1 -0
- package/dist/tools/__tests__/update-tasks.test.js +6 -6
- package/dist/tools/__tests__/user-info.test.d.ts +2 -0
- package/dist/tools/__tests__/user-info.test.d.ts.map +1 -0
- package/dist/tools/__tests__/user-info.test.js +139 -0
- package/dist/tools/add-comments.d.ts +28 -5
- 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 +46 -2
- 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 +14 -2
- 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 +16 -10
- package/dist/tools/add-tasks.d.ts.map +1 -1
- package/dist/tools/add-tasks.js +49 -3
- package/dist/tools/find-comments.d.ts +27 -4
- package/dist/tools/find-comments.d.ts.map +1 -1
- package/dist/tools/find-completed-tasks.d.ts +12 -4
- package/dist/tools/find-completed-tasks.d.ts.map +1 -1
- package/dist/tools/find-completed-tasks.js +20 -4
- 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 +8 -0
- package/dist/tools/find-tasks-by-date.d.ts.map +1 -1
- package/dist/tools/find-tasks-by-date.js +19 -2
- package/dist/tools/find-tasks.d.ts +13 -2
- package/dist/tools/find-tasks.d.ts.map +1 -1
- package/dist/tools/find-tasks.js +172 -23
- 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 +25 -2
- package/dist/tools/update-comments.d.ts.map +1 -1
- package/dist/tools/update-comments.js +1 -1
- package/dist/tools/update-projects.d.ts +46 -2
- package/dist/tools/update-projects.d.ts.map +1 -1
- package/dist/tools/update-sections.d.ts +14 -2
- 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 +16 -10
- package/dist/tools/update-tasks.d.ts.map +1 -1
- package/dist/tools/update-tasks.js +32 -9
- package/dist/tools/user-info.d.ts +44 -0
- package/dist/tools/user-info.d.ts.map +1 -0
- package/dist/tools/user-info.js +142 -0
- 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/labels.d.ts +10 -0
- package/dist/utils/labels.d.ts.map +1 -0
- package/dist/utils/labels.js +18 -0
- 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 +3 -0
- package/dist/utils/tool-names.d.ts +3 -0
- package/dist/utils/tool-names.d.ts.map +1 -1
- package/dist/utils/tool-names.js +4 -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 +7 -7
package/dist/tools/find-tasks.js
CHANGED
|
@@ -2,14 +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 { generateLabelsFilter, LabelsSchema } from '../utils/labels.js';
|
|
5
6
|
import { generateTaskNextSteps, getDateString, previewTasks, summarizeList, } from '../utils/response-builders.js';
|
|
6
7
|
import { ToolNames } from '../utils/tool-names.js';
|
|
8
|
+
import { resolveUserNameToId } from '../utils/user-resolver.js';
|
|
7
9
|
const { FIND_COMPLETED_TASKS, ADD_TASKS } = ToolNames;
|
|
8
10
|
const ArgsSchema = {
|
|
9
11
|
searchText: z.string().optional().describe('The text to search for in tasks.'),
|
|
10
12
|
projectId: z.string().optional().describe('Find tasks in this project.'),
|
|
11
13
|
sectionId: z.string().optional().describe('Find tasks in this section.'),
|
|
12
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.'),
|
|
13
19
|
limit: z
|
|
14
20
|
.number()
|
|
15
21
|
.int()
|
|
@@ -21,16 +27,36 @@ const ArgsSchema = {
|
|
|
21
27
|
.string()
|
|
22
28
|
.optional()
|
|
23
29
|
.describe('The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters).'),
|
|
30
|
+
...LabelsSchema,
|
|
24
31
|
};
|
|
25
32
|
const findTasks = {
|
|
26
33
|
name: ToolNames.FIND_TASKS,
|
|
27
|
-
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.',
|
|
28
35
|
parameters: ArgsSchema,
|
|
29
36
|
async execute(args, client) {
|
|
30
|
-
const { searchText, projectId, sectionId, parentId, limit, cursor } = args;
|
|
37
|
+
const { searchText, projectId, sectionId, parentId, responsibleUser, limit, cursor, labels, labelsOperator, } = args;
|
|
31
38
|
// Validate at least one filter is provided
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
const hasLabels = labels && labels.length > 0;
|
|
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
|
+
}
|
|
34
60
|
}
|
|
35
61
|
// If using container-based filtering, use direct API
|
|
36
62
|
if (projectId || sectionId || parentId) {
|
|
@@ -46,47 +72,108 @@ const findTasks = {
|
|
|
46
72
|
taskParams.parentId = parentId;
|
|
47
73
|
const { results, nextCursor } = await client.getTasks(taskParams);
|
|
48
74
|
const mappedTasks = results.map(mapTask);
|
|
49
|
-
//
|
|
50
|
-
|
|
75
|
+
// Apply search text filter
|
|
76
|
+
let filteredTasks = searchText
|
|
51
77
|
? mappedTasks.filter((task) => task.content.toLowerCase().includes(searchText.toLowerCase()) ||
|
|
52
78
|
task.description?.toLowerCase().includes(searchText.toLowerCase()))
|
|
53
79
|
: mappedTasks;
|
|
80
|
+
// Apply responsibleUid filter
|
|
81
|
+
if (resolvedAssigneeId) {
|
|
82
|
+
filteredTasks = filteredTasks.filter((task) => task.responsibleUid === resolvedAssigneeId);
|
|
83
|
+
}
|
|
84
|
+
// Apply label filter
|
|
85
|
+
if (labels && labels.length > 0) {
|
|
86
|
+
filteredTasks =
|
|
87
|
+
labelsOperator === 'and'
|
|
88
|
+
? filteredTasks.filter((task) => labels.every((label) => task.labels.includes(label)))
|
|
89
|
+
: filteredTasks.filter((task) => labels.some((label) => task.labels.includes(label)));
|
|
90
|
+
}
|
|
54
91
|
const textContent = generateTextContent({
|
|
55
|
-
tasks:
|
|
92
|
+
tasks: filteredTasks,
|
|
56
93
|
args,
|
|
57
94
|
nextCursor,
|
|
58
95
|
isContainerSearch: true,
|
|
96
|
+
assigneeDisplayName,
|
|
59
97
|
});
|
|
60
98
|
return getToolOutput({
|
|
61
99
|
textContent,
|
|
62
100
|
structuredContent: {
|
|
63
|
-
tasks:
|
|
101
|
+
tasks: filteredTasks,
|
|
64
102
|
nextCursor,
|
|
65
|
-
totalCount:
|
|
103
|
+
totalCount: filteredTasks.length,
|
|
66
104
|
hasMore: Boolean(nextCursor),
|
|
67
105
|
appliedFilters: args,
|
|
68
106
|
},
|
|
69
107
|
});
|
|
70
108
|
}
|
|
71
|
-
//
|
|
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)
|
|
137
|
+
let query = '';
|
|
138
|
+
// Add search text component
|
|
139
|
+
if (searchText) {
|
|
140
|
+
query = `search: ${searchText}`;
|
|
141
|
+
}
|
|
142
|
+
// Add labels component
|
|
143
|
+
const labelsFilter = generateLabelsFilter(labels, labelsOperator);
|
|
144
|
+
if (labelsFilter.length > 0) {
|
|
145
|
+
if (query.length > 0) {
|
|
146
|
+
query += ` & ${labelsFilter}`;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
query = labelsFilter;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Execute filter query
|
|
72
153
|
const result = await getTasksByFilter({
|
|
73
154
|
client,
|
|
74
|
-
query
|
|
155
|
+
query,
|
|
75
156
|
cursor: args.cursor,
|
|
76
157
|
limit: args.limit,
|
|
77
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
|
+
}
|
|
78
164
|
const textContent = generateTextContent({
|
|
79
|
-
tasks
|
|
165
|
+
tasks,
|
|
80
166
|
args,
|
|
81
167
|
nextCursor: result.nextCursor,
|
|
82
168
|
isContainerSearch: false,
|
|
169
|
+
assigneeDisplayName,
|
|
83
170
|
});
|
|
84
171
|
return getToolOutput({
|
|
85
172
|
textContent,
|
|
86
173
|
structuredContent: {
|
|
87
|
-
tasks
|
|
174
|
+
tasks,
|
|
88
175
|
nextCursor: result.nextCursor,
|
|
89
|
-
totalCount:
|
|
176
|
+
totalCount: tasks.length,
|
|
90
177
|
hasMore: Boolean(result.nextCursor),
|
|
91
178
|
appliedFilters: args,
|
|
92
179
|
},
|
|
@@ -119,9 +206,9 @@ function getContainerZeroReasonHints(args) {
|
|
|
119
206
|
}
|
|
120
207
|
return [];
|
|
121
208
|
}
|
|
122
|
-
function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
209
|
+
function generateTextContent({ tasks, args, nextCursor, isContainerSearch, assigneeDisplayName, }) {
|
|
123
210
|
// Generate subject and filter descriptions based on search type
|
|
124
|
-
let subject;
|
|
211
|
+
let subject = 'Tasks';
|
|
125
212
|
const filterHints = [];
|
|
126
213
|
const zeroReasonHints = [];
|
|
127
214
|
if (isContainerSearch) {
|
|
@@ -146,19 +233,81 @@ function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
|
146
233
|
subject += ` matching "${args.searchText}"`;
|
|
147
234
|
filterHints.push(`containing "${args.searchText}"`);
|
|
148
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
|
+
}
|
|
242
|
+
// Add label filter information
|
|
243
|
+
if (args.labels && args.labels.length > 0) {
|
|
244
|
+
const labelText = args.labels
|
|
245
|
+
.map((label) => `@${label}`)
|
|
246
|
+
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
247
|
+
filterHints.push(`labels: ${labelText}`);
|
|
248
|
+
}
|
|
149
249
|
// Container-specific zero result hints
|
|
150
250
|
if (tasks.length === 0) {
|
|
151
251
|
zeroReasonHints.push(...getContainerZeroReasonHints(args));
|
|
152
252
|
}
|
|
153
253
|
}
|
|
154
254
|
else {
|
|
155
|
-
// Text
|
|
156
|
-
|
|
157
|
-
|
|
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
|
+
}
|
|
271
|
+
if (args.searchText) {
|
|
272
|
+
subject = `Search results for ${subjectParts.join(' ')}`;
|
|
273
|
+
filterHints.push(`matching "${args.searchText}"`);
|
|
274
|
+
}
|
|
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) {
|
|
279
|
+
const labelText = args.labels
|
|
280
|
+
.map((label) => `@${label}`)
|
|
281
|
+
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
282
|
+
subject = `Tasks with labels: ${labelText}`;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
subject = `Tasks ${subjectParts.join(' ')}`;
|
|
286
|
+
}
|
|
287
|
+
// Add filter hints
|
|
288
|
+
if (args.responsibleUser) {
|
|
289
|
+
filterHints.push(`assigned to ${displayName}`);
|
|
290
|
+
}
|
|
291
|
+
if (args.labels && args.labels.length > 0) {
|
|
292
|
+
const labelText = args.labels
|
|
293
|
+
.map((label) => `@${label}`)
|
|
294
|
+
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
295
|
+
filterHints.push(`labels: ${labelText}`);
|
|
296
|
+
}
|
|
158
297
|
if (tasks.length === 0) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
+
}
|
|
162
311
|
}
|
|
163
312
|
}
|
|
164
313
|
// Generate contextual next steps
|
|
@@ -174,7 +323,7 @@ function generateTextContent({ tasks, args, nextCursor, isContainerSearch, }) {
|
|
|
174
323
|
limit: args.limit,
|
|
175
324
|
nextCursor: nextCursor ?? undefined,
|
|
176
325
|
filterHints,
|
|
177
|
-
previewLines: previewTasks(tasks),
|
|
326
|
+
previewLines: previewTasks(tasks, Math.min(tasks.length, args.limit)),
|
|
178
327
|
zeroReasonHints,
|
|
179
328
|
nextSteps,
|
|
180
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"}
|