@doist/todoist-ai 4.9.2 → 4.9.3

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 CHANGED
@@ -328,18 +328,20 @@ declare const tools: {
328
328
  parameters: {
329
329
  labels: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString, "many">>;
330
330
  labelsOperator: import("zod").ZodOptional<import("zod").ZodEnum<["and", "or"]>>;
331
- startDate: import("zod").ZodString;
331
+ startDate: import("zod").ZodOptional<import("zod").ZodString>;
332
+ overdueOption: import("zod").ZodOptional<import("zod").ZodEnum<["overdue-only", "include-overdue", "exclude-overdue"]>>;
332
333
  daysCount: import("zod").ZodDefault<import("zod").ZodNumber>;
333
334
  limit: import("zod").ZodDefault<import("zod").ZodNumber>;
334
335
  cursor: import("zod").ZodOptional<import("zod").ZodString>;
335
336
  };
336
337
  execute(args: {
337
338
  limit: number;
338
- startDate: string;
339
339
  daysCount: number;
340
340
  labels?: string[] | undefined;
341
341
  cursor?: string | undefined;
342
342
  labelsOperator?: "and" | "or" | undefined;
343
+ startDate?: string | undefined;
344
+ overdueOption?: "overdue-only" | "include-overdue" | "exclude-overdue" | undefined;
343
345
  }, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
344
346
  content: {
345
347
  type: "text";
@@ -366,11 +368,12 @@ declare const tools: {
366
368
  hasMore: boolean;
367
369
  appliedFilters: {
368
370
  limit: number;
369
- startDate: string;
370
371
  daysCount: number;
371
372
  labels?: string[] | undefined;
372
373
  cursor?: string | undefined;
373
374
  labelsOperator?: "and" | "or" | undefined;
375
+ startDate?: string | undefined;
376
+ overdueOption?: "overdue-only" | "include-overdue" | "exclude-overdue" | undefined;
374
377
  };
375
378
  };
376
379
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -20,18 +20,19 @@ const mockTodoistApi = {
20
20
  const mockTodoistUser = createMockUser();
21
21
  // Mock date-fns functions to make tests deterministic
22
22
  jest.mock('date-fns', () => ({
23
- addDays: jest.fn(() => new Date('2025-08-16')), // Return predictable end date
23
+ addDays: jest.fn((date, amount) => {
24
+ const d = new Date(date);
25
+ d.setDate(d.getDate() + amount);
26
+ return d;
27
+ }),
24
28
  formatISO: jest.fn((date, options) => {
25
29
  if (typeof date === 'string') {
26
30
  return date; // Return string dates as-is
27
31
  }
28
- if (options &&
29
- typeof options === 'object' &&
30
- 'representation' in options &&
31
- options.representation === 'date') {
32
- return '2025-08-15'; // Return predictable date for 'today'
32
+ if (options?.representation === 'date') {
33
+ return date.toISOString().split('T')[0];
33
34
  }
34
- return '2025-08-16'; // Return predictable end date
35
+ return date.toISOString();
35
36
  }),
36
37
  }));
37
38
  const { FIND_TASKS_BY_DATE, UPDATE_TASKS } = ToolNames;
@@ -46,6 +47,23 @@ describe(`${FIND_TASKS_BY_DATE} tool`, () => {
46
47
  jest.restoreAllMocks();
47
48
  });
48
49
  describe('listing tasks by date range', () => {
50
+ it('only returns tasks for the startDate when daysCount is 1', async () => {
51
+ const mockTasks = [
52
+ createMappedTask({ content: 'Task for specific date', dueDate: '2025-08-20' }),
53
+ ];
54
+ const mockResponse = { tasks: mockTasks, nextCursor: null };
55
+ mockGetTasksByFilter.mockResolvedValue(mockResponse);
56
+ const result = await findTasksByDate.execute({ startDate: '2025-08-20', limit: 50, daysCount: 1 }, mockTodoistApi);
57
+ // Verify the query uses daysCount=1 by checking the end date calculation
58
+ expect(mockGetTasksByFilter).toHaveBeenCalledWith({
59
+ client: mockTodoistApi,
60
+ query: '(due after: 2025-08-20 | due: 2025-08-20) & due before: 2025-08-21',
61
+ cursor: undefined,
62
+ limit: 50,
63
+ });
64
+ const textContent = extractTextContent(result);
65
+ expect(textContent).toMatchSnapshot();
66
+ });
49
67
  it('should get tasks for today when startDate is "today" (includes overdue)', async () => {
50
68
  const mockTasks = [createMappedTask({ content: 'Today task', dueDate: '2025-08-15' })];
51
69
  const mockResponse = { tasks: mockTasks, nextCursor: null };
@@ -375,7 +393,7 @@ describe(`${FIND_TASKS_BY_DATE} tool`, () => {
375
393
  ];
376
394
  const mockResponse = { tasks: mockTasks, nextCursor: null };
377
395
  mockGetTasksByFilter.mockResolvedValue(mockResponse);
378
- const result = await findTasksByDate.execute({ startDate: 'overdue', daysCount: 1, limit: 50 }, mockTodoistApi);
396
+ const result = await findTasksByDate.execute({ overdueOption: 'overdue-only', daysCount: 1, limit: 50 }, mockTodoistApi);
379
397
  const structuredContent = extractStructuredContent(result);
380
398
  // Should only return tasks 1 and 2, not task 3
381
399
  expect(structuredContent.tasks).toHaveLength(2);
@@ -5,18 +5,20 @@ declare const findTasksByDate: {
5
5
  parameters: {
6
6
  labels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
7
  labelsOperator: z.ZodOptional<z.ZodEnum<["and", "or"]>>;
8
- startDate: z.ZodString;
8
+ startDate: z.ZodOptional<z.ZodString>;
9
+ overdueOption: z.ZodOptional<z.ZodEnum<["overdue-only", "include-overdue", "exclude-overdue"]>>;
9
10
  daysCount: z.ZodDefault<z.ZodNumber>;
10
11
  limit: z.ZodDefault<z.ZodNumber>;
11
12
  cursor: z.ZodOptional<z.ZodString>;
12
13
  };
13
14
  execute(args: {
14
15
  limit: number;
15
- startDate: string;
16
16
  daysCount: number;
17
17
  labels?: string[] | undefined;
18
18
  cursor?: string | undefined;
19
19
  labelsOperator?: "and" | "or" | undefined;
20
+ startDate?: string | undefined;
21
+ overdueOption?: "overdue-only" | "include-overdue" | "exclude-overdue" | undefined;
20
22
  }, client: import("@doist/todoist-api-typescript").TodoistApi): Promise<{
21
23
  content: {
22
24
  type: "text";
@@ -43,11 +45,12 @@ declare const findTasksByDate: {
43
45
  hasMore: boolean;
44
46
  appliedFilters: {
45
47
  limit: number;
46
- startDate: string;
47
48
  daysCount: number;
48
49
  labels?: string[] | undefined;
49
50
  cursor?: string | undefined;
50
51
  labelsOperator?: "and" | "or" | undefined;
52
+ startDate?: string | undefined;
53
+ overdueOption?: "overdue-only" | "include-overdue" | "exclude-overdue" | undefined;
51
54
  };
52
55
  };
53
56
  } | {
@@ -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;AA0CvB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DqB,CAAA;AAoE1C,OAAO,EAAE,eAAe,EAAE,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;AAmDvB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEqB,CAAA;AAwF1C,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -10,14 +10,19 @@ const ArgsSchema = {
10
10
  startDate: z
11
11
  .string()
12
12
  .regex(/^(\d{4}-\d{2}-\d{2}|today)$/)
13
+ .optional()
13
14
  .describe("The start date to get the tasks for. Format: YYYY-MM-DD or 'today'."),
15
+ overdueOption: z
16
+ .enum(['overdue-only', 'include-overdue', 'exclude-overdue'])
17
+ .optional()
18
+ .describe("How to handle overdue tasks. 'overdue-only' to get only overdue tasks, 'include-overdue' to include overdue tasks along with tasks for the specified date(s), and 'exclude-overdue' to exclude overdue tasks. Default is 'include-overdue'."),
14
19
  daysCount: z
15
20
  .number()
16
21
  .int()
17
22
  .min(1)
18
23
  .max(30)
19
24
  .default(1)
20
- .describe('The number of days to get the tasks for, starting from the start date.'),
25
+ .describe('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.'),
21
26
  limit: z
22
27
  .number()
23
28
  .int()
@@ -36,14 +41,22 @@ const findTasksByDate = {
36
41
  description: "Get tasks by date range. Use startDate 'today' to get today's tasks including overdue items, or provide a specific date/date range.",
37
42
  parameters: ArgsSchema,
38
43
  async execute(args, client) {
44
+ if (!args.startDate && args.overdueOption !== 'overdue-only') {
45
+ throw new Error('Either startDate must be provided or overdueOption must be set to overdue-only');
46
+ }
39
47
  let query = '';
40
48
  const todoistUser = await client.getUser();
41
- if (args.startDate === 'today') {
42
- query = 'today | overdue';
49
+ if (args.overdueOption === 'overdue-only') {
50
+ query = 'overdue';
43
51
  }
44
- else {
52
+ else if (args.startDate === 'today') {
53
+ // For 'today', include overdue unless explicitly excluded
54
+ query = args.overdueOption === 'exclude-overdue' ? 'today' : 'today | overdue';
55
+ }
56
+ else if (args.startDate) {
57
+ // For specific dates, never include overdue tasks
45
58
  const startDate = args.startDate;
46
- const endDate = addDays(startDate, args.daysCount + 1);
59
+ const endDate = addDays(startDate, args.daysCount);
47
60
  const endDateStr = formatISO(endDate, { representation: 'date' });
48
61
  query = `(due after: ${startDate} | due: ${startDate}) & due before: ${endDateStr}`;
49
62
  }
@@ -87,11 +100,18 @@ const findTasksByDate = {
87
100
  function generateTextContent({ tasks, args, nextCursor, }) {
88
101
  // Generate filter description
89
102
  const filterHints = [];
90
- if (args.startDate === 'today') {
91
- filterHints.push(`today + overdue tasks${args.daysCount > 1 ? ` + ${args.daysCount - 1} more days` : ''}`);
103
+ if (args.overdueOption === 'overdue-only') {
104
+ filterHints.push('overdue tasks only');
92
105
  }
93
- else {
94
- filterHints.push(`${args.startDate}${args.daysCount > 1 ? ` to ${getDateString(addDays(args.startDate, args.daysCount))}` : ''}`);
106
+ else if (args.startDate === 'today') {
107
+ const overdueText = args.overdueOption === 'exclude-overdue' ? '' : ' + overdue tasks';
108
+ filterHints.push(`today${overdueText}${args.daysCount > 1 ? ` + ${args.daysCount - 1} more days` : ''}`);
109
+ }
110
+ else if (args.startDate) {
111
+ const dateRange = args.daysCount > 1
112
+ ? ` to ${getDateString(addDays(args.startDate, args.daysCount))}`
113
+ : '';
114
+ filterHints.push(`${args.startDate}${dateRange}`);
95
115
  }
96
116
  // Add label filter information
97
117
  if (args.labels && args.labels.length > 0) {
@@ -101,12 +121,29 @@ function generateTextContent({ tasks, args, nextCursor, }) {
101
121
  filterHints.push(`labels: ${labelText}`);
102
122
  }
103
123
  // Generate subject description
104
- const subject = args.startDate === 'today' ? `Today's tasks + overdue` : `Tasks for ${args.startDate}`;
124
+ let subject = '';
125
+ if (args.overdueOption === 'overdue-only') {
126
+ subject = 'Overdue tasks';
127
+ }
128
+ else if (args.startDate === 'today') {
129
+ subject =
130
+ args.overdueOption === 'exclude-overdue' ? `Today's tasks` : `Today's tasks + overdue`;
131
+ }
132
+ else if (args.startDate) {
133
+ subject = `Tasks for ${args.startDate}`;
134
+ }
135
+ else {
136
+ subject = 'Tasks';
137
+ }
105
138
  // Generate helpful suggestions for empty results
106
139
  const zeroReasonHints = [];
107
140
  if (tasks.length === 0) {
108
- if (args.startDate === 'today') {
109
- zeroReasonHints.push('Great job! No tasks for today or overdue');
141
+ if (args.overdueOption === 'overdue-only') {
142
+ zeroReasonHints.push('Great job! No overdue tasks');
143
+ }
144
+ else if (args.startDate === 'today') {
145
+ const overdueNote = args.overdueOption === 'exclude-overdue' ? '' : ' or overdue';
146
+ zeroReasonHints.push(`Great job! No tasks for today${overdueNote}`);
110
147
  }
111
148
  else {
112
149
  zeroReasonHints.push("Expand date range with larger 'daysCount'");
@@ -116,10 +153,12 @@ function generateTextContent({ tasks, args, nextCursor, }) {
116
153
  // Generate contextual next steps
117
154
  const now = new Date();
118
155
  const todayStr = getDateString(now);
156
+ const hasOverdue = args.overdueOption === 'overdue-only' ||
157
+ args.startDate === 'today' ||
158
+ tasks.some((task) => task.dueDate && new Date(task.dueDate) < now);
119
159
  const nextSteps = generateTaskNextSteps('listed', tasks, {
120
160
  hasToday: args.startDate === 'today' || tasks.some((task) => task.dueDate === todayStr),
121
- hasOverdue: args.startDate === 'today' ||
122
- tasks.some((task) => task.dueDate && new Date(task.dueDate) < now),
161
+ hasOverdue,
123
162
  });
124
163
  return summarizeList({
125
164
  subject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/todoist-ai",
3
- "version": "4.9.2",
3
+ "version": "4.9.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",