@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
|
@@ -2,6 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { getToolOutput } from '../mcp-helpers.js';
|
|
3
3
|
import { mapTask } from '../tool-helpers.js';
|
|
4
4
|
import { ApiLimits } from '../utils/constants.js';
|
|
5
|
+
import { generateLabelsFilter, LabelsSchema } from '../utils/labels.js';
|
|
5
6
|
import { previewTasks, summarizeList } from '../utils/response-builders.js';
|
|
6
7
|
import { ToolNames } from '../utils/tool-names.js';
|
|
7
8
|
const { FIND_TASKS_BY_DATE, GET_OVERVIEW } = ToolNames;
|
|
@@ -35,16 +36,24 @@ const ArgsSchema = {
|
|
|
35
36
|
.string()
|
|
36
37
|
.optional()
|
|
37
38
|
.describe('The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters).'),
|
|
39
|
+
...LabelsSchema,
|
|
38
40
|
};
|
|
39
41
|
const findCompletedTasks = {
|
|
40
42
|
name: ToolNames.FIND_COMPLETED_TASKS,
|
|
41
43
|
description: 'Get completed tasks.',
|
|
42
44
|
parameters: ArgsSchema,
|
|
43
45
|
async execute(args, client) {
|
|
44
|
-
const { getBy, ...rest } = args;
|
|
46
|
+
const { getBy, labels, labelsOperator, ...rest } = args;
|
|
47
|
+
const labelsFilter = generateLabelsFilter(labels, labelsOperator);
|
|
45
48
|
const { items, nextCursor } = getBy === 'completion'
|
|
46
|
-
? await client.getCompletedTasksByCompletionDate(
|
|
47
|
-
|
|
49
|
+
? await client.getCompletedTasksByCompletionDate({
|
|
50
|
+
...rest,
|
|
51
|
+
...(labelsFilter ? { filterQuery: labelsFilter, filterLang: 'en' } : {}),
|
|
52
|
+
})
|
|
53
|
+
: await client.getCompletedTasksByDueDate({
|
|
54
|
+
...rest,
|
|
55
|
+
...(labelsFilter ? { filterQuery: labelsFilter, filterLang: 'en' } : {}),
|
|
56
|
+
});
|
|
48
57
|
const mappedTasks = items.map(mapTask);
|
|
49
58
|
const textContent = generateTextContent({
|
|
50
59
|
tasks: mappedTasks,
|
|
@@ -78,6 +87,13 @@ function generateTextContent({ tasks, args, nextCursor, }) {
|
|
|
78
87
|
filterHints.push(`parent: ${args.parentId}`);
|
|
79
88
|
if (args.workspaceId)
|
|
80
89
|
filterHints.push(`workspace: ${args.workspaceId}`);
|
|
90
|
+
// Add label filter information
|
|
91
|
+
if (args.labels && args.labels.length > 0) {
|
|
92
|
+
const labelText = args.labels
|
|
93
|
+
.map((label) => `@${label}`)
|
|
94
|
+
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
95
|
+
filterHints.push(`labels: ${labelText}`);
|
|
96
|
+
}
|
|
81
97
|
// Generate helpful suggestions for empty results
|
|
82
98
|
const zeroReasonHints = [];
|
|
83
99
|
if (tasks.length === 0) {
|
|
@@ -104,7 +120,7 @@ function generateTextContent({ tasks, args, nextCursor, }) {
|
|
|
104
120
|
limit: args.limit,
|
|
105
121
|
nextCursor: nextCursor ?? undefined,
|
|
106
122
|
filterHints,
|
|
107
|
-
previewLines: previewTasks(tasks),
|
|
123
|
+
previewLines: previewTasks(tasks, Math.min(tasks.length, args.limit)),
|
|
108
124
|
zeroReasonHints,
|
|
109
125
|
nextSteps,
|
|
110
126
|
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type ProjectCollaborator } from '../utils/user-resolver.js';
|
|
3
|
+
declare const findProjectCollaborators: {
|
|
4
|
+
name: "find-project-collaborators";
|
|
5
|
+
description: string;
|
|
6
|
+
parameters: {
|
|
7
|
+
projectId: z.ZodString;
|
|
8
|
+
searchTerm: z.ZodOptional<z.ZodString>;
|
|
9
|
+
};
|
|
10
|
+
execute(args: {
|
|
11
|
+
projectId: string;
|
|
12
|
+
searchTerm?: string | undefined;
|
|
13
|
+
}, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
|
|
14
|
+
content: {
|
|
15
|
+
type: "text";
|
|
16
|
+
text: string;
|
|
17
|
+
}[];
|
|
18
|
+
structuredContent: {
|
|
19
|
+
collaborators: never[];
|
|
20
|
+
projectInfo: {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
isShared: boolean;
|
|
24
|
+
};
|
|
25
|
+
totalCount: number;
|
|
26
|
+
appliedFilters: {
|
|
27
|
+
projectId: string;
|
|
28
|
+
searchTerm?: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
} | {
|
|
32
|
+
content: ({
|
|
33
|
+
type: "text";
|
|
34
|
+
text: string;
|
|
35
|
+
mimeType?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
type: "text";
|
|
38
|
+
mimeType: string;
|
|
39
|
+
text: string;
|
|
40
|
+
})[];
|
|
41
|
+
structuredContent?: undefined;
|
|
42
|
+
} | {
|
|
43
|
+
content: {
|
|
44
|
+
type: "text";
|
|
45
|
+
text: string;
|
|
46
|
+
}[];
|
|
47
|
+
structuredContent: {
|
|
48
|
+
collaborators: ProjectCollaborator[];
|
|
49
|
+
projectInfo: {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
isShared: boolean;
|
|
53
|
+
};
|
|
54
|
+
totalCount: number;
|
|
55
|
+
totalAvailable: number;
|
|
56
|
+
appliedFilters: {
|
|
57
|
+
projectId: string;
|
|
58
|
+
searchTerm?: string | undefined;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
}>;
|
|
62
|
+
};
|
|
63
|
+
export { findProjectCollaborators };
|
|
64
|
+
//# sourceMappingURL=find-project-collaborators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-project-collaborators.d.ts","sourceRoot":"","sources":["../../src/tools/find-project-collaborators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,OAAO,EAAE,KAAK,mBAAmB,EAAgB,MAAM,2BAA2B,CAAA;AAclF,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FY,CAAA;AAwE1C,OAAO,EAAE,wBAAwB,EAAE,CAAA"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getToolOutput } from '../mcp-helpers.js';
|
|
3
|
+
import { summarizeList } from '../utils/response-builders.js';
|
|
4
|
+
import { ToolNames } from '../utils/tool-names.js';
|
|
5
|
+
import { userResolver } from '../utils/user-resolver.js';
|
|
6
|
+
const { FIND_PROJECTS, ADD_TASKS, UPDATE_TASKS } = ToolNames;
|
|
7
|
+
const ArgsSchema = {
|
|
8
|
+
projectId: z.string().min(1).describe('The ID of the project to search for collaborators in.'),
|
|
9
|
+
searchTerm: z
|
|
10
|
+
.string()
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('Search for a collaborator by name or email (partial and case insensitive match). If omitted, all collaborators in the project are returned.'),
|
|
13
|
+
};
|
|
14
|
+
const findProjectCollaborators = {
|
|
15
|
+
name: ToolNames.FIND_PROJECT_COLLABORATORS,
|
|
16
|
+
description: 'Search for collaborators by name or other criteria in a project.',
|
|
17
|
+
parameters: ArgsSchema,
|
|
18
|
+
async execute(args, client) {
|
|
19
|
+
const { projectId, searchTerm } = args;
|
|
20
|
+
// First, validate that the project exists and get basic info
|
|
21
|
+
let projectName = projectId;
|
|
22
|
+
let project;
|
|
23
|
+
try {
|
|
24
|
+
project = await client.getProject(projectId);
|
|
25
|
+
if (!project) {
|
|
26
|
+
throw new Error(`Project with ID "${projectId}" not found or not accessible`);
|
|
27
|
+
}
|
|
28
|
+
projectName = project.name;
|
|
29
|
+
if (!project.isShared) {
|
|
30
|
+
const textContent = `Project "${projectName}" is not shared and has no collaborators.\n\n**Next steps:**\n• Share the project to enable collaboration\n• Use ${ADD_TASKS} and ${UPDATE_TASKS} for assignment features once shared`;
|
|
31
|
+
return getToolOutput({
|
|
32
|
+
textContent,
|
|
33
|
+
structuredContent: {
|
|
34
|
+
collaborators: [],
|
|
35
|
+
projectInfo: {
|
|
36
|
+
id: projectId,
|
|
37
|
+
name: projectName,
|
|
38
|
+
isShared: false,
|
|
39
|
+
},
|
|
40
|
+
totalCount: 0,
|
|
41
|
+
appliedFilters: args,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw new Error(`Failed to access project "${projectId}": ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
48
|
+
}
|
|
49
|
+
// Get collaborators for the project
|
|
50
|
+
const allCollaborators = await userResolver.getProjectCollaborators(client, projectId);
|
|
51
|
+
if (allCollaborators.length === 0) {
|
|
52
|
+
const textContent = `Project "${projectName}" has no collaborators or collaborator data is not accessible.\n\n**Next steps:**\n• Check project sharing settings\n• Ensure you have permission to view collaborators\n• Try refreshing or re-sharing the project`;
|
|
53
|
+
return getToolOutput({
|
|
54
|
+
textContent,
|
|
55
|
+
structuredContent: {
|
|
56
|
+
collaborators: [],
|
|
57
|
+
projectInfo: {
|
|
58
|
+
id: projectId,
|
|
59
|
+
name: projectName,
|
|
60
|
+
isShared: true,
|
|
61
|
+
},
|
|
62
|
+
totalCount: 0,
|
|
63
|
+
appliedFilters: args,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// Filter collaborators if search term provided
|
|
68
|
+
let filteredCollaborators = allCollaborators;
|
|
69
|
+
if (searchTerm) {
|
|
70
|
+
const searchLower = searchTerm.toLowerCase().trim();
|
|
71
|
+
filteredCollaborators = allCollaborators.filter((collaborator) => collaborator.name.toLowerCase().includes(searchLower) ||
|
|
72
|
+
collaborator.email.toLowerCase().includes(searchLower));
|
|
73
|
+
}
|
|
74
|
+
const textContent = generateTextContent({
|
|
75
|
+
collaborators: filteredCollaborators,
|
|
76
|
+
projectName,
|
|
77
|
+
searchTerm,
|
|
78
|
+
totalAvailable: allCollaborators.length,
|
|
79
|
+
});
|
|
80
|
+
return getToolOutput({
|
|
81
|
+
textContent,
|
|
82
|
+
structuredContent: {
|
|
83
|
+
collaborators: filteredCollaborators,
|
|
84
|
+
projectInfo: {
|
|
85
|
+
id: projectId,
|
|
86
|
+
name: projectName,
|
|
87
|
+
isShared: true,
|
|
88
|
+
},
|
|
89
|
+
totalCount: filteredCollaborators.length,
|
|
90
|
+
totalAvailable: allCollaborators.length,
|
|
91
|
+
appliedFilters: args,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
function generateTextContent({ collaborators, projectName, searchTerm, totalAvailable, }) {
|
|
97
|
+
const subject = searchTerm
|
|
98
|
+
? `Project collaborators matching "${searchTerm}"`
|
|
99
|
+
: 'Project collaborators';
|
|
100
|
+
const filterHints = [];
|
|
101
|
+
if (searchTerm) {
|
|
102
|
+
filterHints.push(`matching "${searchTerm}"`);
|
|
103
|
+
}
|
|
104
|
+
filterHints.push(`in project "${projectName}"`);
|
|
105
|
+
let previewLines = [];
|
|
106
|
+
if (collaborators.length > 0) {
|
|
107
|
+
previewLines = collaborators.slice(0, 10).map((collaborator) => {
|
|
108
|
+
const displayName = collaborator.name || 'Unknown Name';
|
|
109
|
+
const email = collaborator.email || 'No email';
|
|
110
|
+
return `• ${displayName} (${email}) - ID: ${collaborator.id}`;
|
|
111
|
+
});
|
|
112
|
+
if (collaborators.length > 10) {
|
|
113
|
+
previewLines.push(`... and ${collaborators.length - 10} more`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const zeroReasonHints = [];
|
|
117
|
+
if (collaborators.length === 0) {
|
|
118
|
+
if (searchTerm) {
|
|
119
|
+
zeroReasonHints.push(`No collaborators match "${searchTerm}"`);
|
|
120
|
+
zeroReasonHints.push('Try a broader search term or check spelling');
|
|
121
|
+
if (totalAvailable > 0) {
|
|
122
|
+
zeroReasonHints.push(`${totalAvailable} collaborators available without filter`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
zeroReasonHints.push('Project has no collaborators');
|
|
127
|
+
zeroReasonHints.push('Share the project to add collaborators');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const nextSteps = [];
|
|
131
|
+
if (collaborators.length > 0) {
|
|
132
|
+
nextSteps.push(`Use ${ADD_TASKS} with responsibleUser to assign new tasks`);
|
|
133
|
+
nextSteps.push(`Use ${UPDATE_TASKS} with responsibleUser to reassign existing tasks`);
|
|
134
|
+
nextSteps.push('Use collaborator names, emails, or IDs for assignments');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
nextSteps.push(`Use ${FIND_PROJECTS} to find other projects`);
|
|
138
|
+
if (searchTerm && totalAvailable > 0) {
|
|
139
|
+
nextSteps.push('Try searching without filters to see all collaborators');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return summarizeList({
|
|
143
|
+
subject,
|
|
144
|
+
count: collaborators.length,
|
|
145
|
+
filterHints,
|
|
146
|
+
previewLines: previewLines.join('\n'),
|
|
147
|
+
zeroReasonHints,
|
|
148
|
+
nextSteps,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
export { findProjectCollaborators };
|
|
@@ -3,6 +3,8 @@ declare const findTasksByDate: {
|
|
|
3
3
|
name: "find-tasks-by-date";
|
|
4
4
|
description: string;
|
|
5
5
|
parameters: {
|
|
6
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
labelsOperator: z.ZodOptional<z.ZodEnum<["and", "or"]>>;
|
|
6
8
|
startDate: z.ZodString;
|
|
7
9
|
daysCount: z.ZodDefault<z.ZodNumber>;
|
|
8
10
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
@@ -12,7 +14,9 @@ declare const findTasksByDate: {
|
|
|
12
14
|
limit: number;
|
|
13
15
|
startDate: string;
|
|
14
16
|
daysCount: number;
|
|
17
|
+
labels?: string[] | undefined;
|
|
15
18
|
cursor?: string | undefined;
|
|
19
|
+
labelsOperator?: "and" | "or" | undefined;
|
|
16
20
|
}, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
|
|
17
21
|
content: {
|
|
18
22
|
type: "text";
|
|
@@ -31,6 +35,8 @@ declare const findTasksByDate: {
|
|
|
31
35
|
parentId: string | null;
|
|
32
36
|
labels: string[];
|
|
33
37
|
duration: string | null;
|
|
38
|
+
responsibleUid: string | null;
|
|
39
|
+
assignedByUid: string | null;
|
|
34
40
|
}[];
|
|
35
41
|
nextCursor: string | null;
|
|
36
42
|
totalCount: number;
|
|
@@ -39,7 +45,9 @@ declare const findTasksByDate: {
|
|
|
39
45
|
limit: number;
|
|
40
46
|
startDate: string;
|
|
41
47
|
daysCount: number;
|
|
48
|
+
labels?: string[] | undefined;
|
|
42
49
|
cursor?: string | undefined;
|
|
50
|
+
labelsOperator?: "and" | "or" | undefined;
|
|
43
51
|
};
|
|
44
52
|
};
|
|
45
53
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-tasks-by-date.d.ts","sourceRoot":"","sources":["../../src/tools/find-tasks-by-date.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"find-tasks-by-date.d.ts","sourceRoot":"","sources":["../../src/tools/find-tasks-by-date.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA8CvB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDqB,CAAA;AAyE1C,OAAO,EAAE,eAAe,EAAE,CAAA"}
|
|
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
import { getToolOutput } from '../mcp-helpers.js';
|
|
4
4
|
import { getTasksByFilter } from '../tool-helpers.js';
|
|
5
5
|
import { ApiLimits } from '../utils/constants.js';
|
|
6
|
+
import { generateLabelsFilter, LabelsSchema } from '../utils/labels.js';
|
|
6
7
|
import { generateTaskNextSteps, getDateString, previewTasks, summarizeList, } from '../utils/response-builders.js';
|
|
7
8
|
import { ToolNames } from '../utils/tool-names.js';
|
|
8
9
|
const ArgsSchema = {
|
|
@@ -28,13 +29,14 @@ const ArgsSchema = {
|
|
|
28
29
|
.string()
|
|
29
30
|
.optional()
|
|
30
31
|
.describe('The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters).'),
|
|
32
|
+
...LabelsSchema,
|
|
31
33
|
};
|
|
32
34
|
const findTasksByDate = {
|
|
33
35
|
name: ToolNames.FIND_TASKS_BY_DATE,
|
|
34
36
|
description: "Get tasks by date range or overdue tasks. Use startDate 'overdue' for overdue tasks, or provide a date/date range.",
|
|
35
37
|
parameters: ArgsSchema,
|
|
36
38
|
async execute(args, client) {
|
|
37
|
-
let query;
|
|
39
|
+
let query = '';
|
|
38
40
|
if (args.startDate === 'overdue') {
|
|
39
41
|
query = 'overdue';
|
|
40
42
|
}
|
|
@@ -46,6 +48,14 @@ const findTasksByDate = {
|
|
|
46
48
|
const endDateStr = formatISO(endDate, { representation: 'date' });
|
|
47
49
|
query = `(due after: ${startDate} | due: ${startDate}) & due before: ${endDateStr}`;
|
|
48
50
|
}
|
|
51
|
+
const labelsFilter = generateLabelsFilter(args.labels, args.labelsOperator);
|
|
52
|
+
if (labelsFilter.length > 0) {
|
|
53
|
+
// If there is already a query, we need to append the & operator first
|
|
54
|
+
if (query.length > 0)
|
|
55
|
+
query += ' & ';
|
|
56
|
+
// Add the labels to the filter
|
|
57
|
+
query += `(${labelsFilter})`;
|
|
58
|
+
}
|
|
49
59
|
const result = await getTasksByFilter({
|
|
50
60
|
client,
|
|
51
61
|
query,
|
|
@@ -81,6 +91,13 @@ function generateTextContent({ tasks, args, nextCursor, }) {
|
|
|
81
91
|
else {
|
|
82
92
|
filterHints.push(`${args.startDate}${args.daysCount > 1 ? ` to ${getDateString(addDays(args.startDate, args.daysCount))}` : ''}`);
|
|
83
93
|
}
|
|
94
|
+
// Add label filter information
|
|
95
|
+
if (args.labels && args.labels.length > 0) {
|
|
96
|
+
const labelText = args.labels
|
|
97
|
+
.map((label) => `@${label}`)
|
|
98
|
+
.join(args.labelsOperator === 'and' ? ' & ' : ' | ');
|
|
99
|
+
filterHints.push(`labels: ${labelText}`);
|
|
100
|
+
}
|
|
84
101
|
// Generate subject description
|
|
85
102
|
const subject = args.startDate === 'overdue'
|
|
86
103
|
? 'Overdue tasks'
|
|
@@ -113,7 +130,7 @@ function generateTextContent({ tasks, args, nextCursor, }) {
|
|
|
113
130
|
limit: args.limit,
|
|
114
131
|
nextCursor: nextCursor ?? undefined,
|
|
115
132
|
filterHints,
|
|
116
|
-
previewLines: previewTasks(tasks),
|
|
133
|
+
previewLines: previewTasks(tasks, Math.min(tasks.length, args.limit)),
|
|
117
134
|
zeroReasonHints,
|
|
118
135
|
nextSteps,
|
|
119
136
|
});
|
|
@@ -3,19 +3,25 @@ declare const findTasks: {
|
|
|
3
3
|
name: "find-tasks";
|
|
4
4
|
description: string;
|
|
5
5
|
parameters: {
|
|
6
|
+
labels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
labelsOperator: z.ZodOptional<z.ZodEnum<["and", "or"]>>;
|
|
6
8
|
searchText: z.ZodOptional<z.ZodString>;
|
|
7
9
|
projectId: z.ZodOptional<z.ZodString>;
|
|
8
10
|
sectionId: z.ZodOptional<z.ZodString>;
|
|
9
11
|
parentId: z.ZodOptional<z.ZodString>;
|
|
12
|
+
responsibleUser: z.ZodOptional<z.ZodString>;
|
|
10
13
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
11
14
|
cursor: z.ZodOptional<z.ZodString>;
|
|
12
15
|
};
|
|
13
16
|
execute(args: {
|
|
14
17
|
limit: number;
|
|
15
|
-
parentId?: string | undefined;
|
|
16
18
|
projectId?: string | undefined;
|
|
19
|
+
parentId?: string | undefined;
|
|
17
20
|
sectionId?: string | undefined;
|
|
21
|
+
labels?: string[] | undefined;
|
|
18
22
|
cursor?: string | undefined;
|
|
23
|
+
responsibleUser?: string | undefined;
|
|
24
|
+
labelsOperator?: "and" | "or" | undefined;
|
|
19
25
|
searchText?: string | undefined;
|
|
20
26
|
}, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
|
|
21
27
|
content: {
|
|
@@ -35,16 +41,21 @@ declare const findTasks: {
|
|
|
35
41
|
parentId: string | null;
|
|
36
42
|
labels: string[];
|
|
37
43
|
duration: string | null;
|
|
44
|
+
responsibleUid: string | null;
|
|
45
|
+
assignedByUid: string | null;
|
|
38
46
|
}[];
|
|
39
47
|
nextCursor: string | null;
|
|
40
48
|
totalCount: number;
|
|
41
49
|
hasMore: boolean;
|
|
42
50
|
appliedFilters: {
|
|
43
51
|
limit: number;
|
|
44
|
-
parentId?: string | undefined;
|
|
45
52
|
projectId?: string | undefined;
|
|
53
|
+
parentId?: string | undefined;
|
|
46
54
|
sectionId?: string | undefined;
|
|
55
|
+
labels?: string[] | undefined;
|
|
47
56
|
cursor?: string | undefined;
|
|
57
|
+
responsibleUser?: string | undefined;
|
|
58
|
+
labelsOperator?: "and" | "or" | undefined;
|
|
48
59
|
searchText?: string | undefined;
|
|
49
60
|
};
|
|
50
61
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/find-tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"find-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/find-tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA2CvB,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgM2B,CAAA;AA2K1C,OAAO,EAAE,SAAS,EAAE,CAAA"}
|