@doist/todoist-mcp 13.10.0 → 13.10.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.
@@ -1,6 +1,6 @@
1
1
  import { McpServer } from '@modelcontextprotocol/server';
2
2
  import { FEATURE_NAMES, Feature, FeatureName, Features } from './mcp-helpers.js';
3
- export declare const instructions = "\n## Todoist Task and Project Management Tools\n\nYou have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.\n\n### Core Capabilities:\n- Create, update, complete, and search tasks with rich metadata (priorities, due dates, durations, assignments)\n- Manage projects and sections with flexible organization\n- Handle comments and collaboration features\n- Bulk assignment operations for team workflows\n- Get overviews and insights about workload and progress\n\n### Choosing between tools\n\nWhat each tool does and how to fill its parameters is in the tool's own description and input schema. This section covers only what those cannot: which tool to reach for, and how tools relate to each other.\n\n**Dates**\n\n- To move a task to a different date use **reschedule-tasks**, never **update-tasks**. update-tasks replaces the whole due string, which destroys recurrence on recurring tasks.\n- Never send a task's existing projectId, sectionId or parentId back to **update-tasks** \u2014 those fields are treated as a move.\n- All dates respect the user's timezone.\n- Todoist apps only display task durations under 24 hours. A longer one (\"36h\") or a day-based one (\"3d\") is stored and reported faithfully, but the apps show the task as having no duration \u2014 only set one when the user explicitly asks for it.\n\n**Finding things**\n\n- For \"what did I complete?\", call **user-info** for the asker's user ID, then **find-activity** with objectType=\"task\", eventType=\"completed\", initiatorId, and dateFrom/dateTo. Without initiatorId the answer covers every collaborator. find-activity reports completion events, including each occurrence of a recurring task; **find-completed-tasks** lists completed tasks, which is not the same question.\n- To resolve a person's name or email to a user ID, or to answer \"who is X?\", use **find-project-collaborators** with just a searchTerm. It covers every shared project you can access plus yourself, so an empty result means they collaborate on none of them \u2014 not that they do not exist.\n- Before assigning work to someone, call **find-project-collaborators** again with the target projectId. Resolving an ID only proves they collaborate on *some* project you can see; assignment fails unless they collaborate on that one.\n- To find out whether a task hides subtasks, use **fetch-object** with includeChildren rather than a speculative **find-tasks** call.\n- Filter tasks by label **name**. Label IDs are only for **delete-object** and **update-labels**. Shared labels can be renamed but not recoloured, reordered or favourited.\n\n**Comments**\n\n- Comments notify only the people **add-comments** is handed. When a comment mentions someone, name them in `notifyUsers` \u2014 writing \"@Ana\" in the text notifies nobody. Omit `notifyUsers` to notify whoever the Todoist apps would, or pass `[\"none\"]` to stay silent.\n- Notification cannot be sent when editing a comment, only when adding one.\n\n**Deleting and archiving**\n\n- **delete-object** removes every object type; there is no per-type delete tool. Reminders use type \"reminder\", location reminders \"location_reminder\".\n- A workspace project must be archived with **project-management** before it can be deleted. A personal project can be deleted directly.\n\n**Templates**\n\n- Templates cannot be listed through this server, so only use an ID or URL the user gave you. To start a new project from one, call **add-projects** first and import into it. Imports write immediately and cannot be undone.\n\n**Project health**\n\n- Health data may be stale \u2014 check the isStale flag, and call **analyze-project-health** to refresh it before reading again.\n\n**Batches**\n\n- Prefer a batch tool over one call per item.\n- Where a batch tool returns per-item `failures` alongside successes, one failure does not undo the rest: never retry the whole batch, re-send only the items whose failure reason is fixable. **reschedule-tasks** is the exception \u2014 it has no per-item failures and throws if any task fails, so retry it as a whole.\n\nUse the **productivity-analysis** prompt for a combined productivity review \u2014 it pulls together user-info, get-productivity-stats and find-completed-tasks.\n\nAlways provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.\n";
3
+ export declare const instructions = "\n## Todoist Task and Project Management Tools\n\nYou have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.\n\n### Core Capabilities:\n- Create, update, complete, and search tasks with rich metadata (priorities, due dates, durations, assignments)\n- Manage projects and sections with flexible organization\n- Handle comments and collaboration features\n- Bulk assignment operations for team workflows\n- Get overviews and insights about workload and progress\n\n### Choosing between tools\n\nWhat each tool does and how to fill its parameters is in the tool's own description and input schema. This section covers only what those cannot: which tool to reach for, and how tools relate to each other.\n\n**Dates**\n\n- To move a task to a different date or time use **reschedule-tasks**, never **update-tasks**. It also sets duration, for time-blocking. update-tasks replaces the whole due string, so it refuses a dueString on a recurring task unless replaceRecurrence is true.\n- Never send a task's existing projectId, sectionId or parentId back to **update-tasks** \u2014 those fields are treated as a move.\n- All dates respect the user's timezone.\n- Todoist apps only display task durations under 24 hours. A longer one (\"36h\") or a day-based one (\"3d\") is stored and reported faithfully, but the apps show the task as having no duration \u2014 only set one when the user explicitly asks for it.\n\n**Finding things**\n\n- For \"what did I complete?\", call **user-info** for the asker's user ID, then **find-activity** with objectType=\"task\", eventType=\"completed\", initiatorId, and dateFrom/dateTo. Without initiatorId the answer covers every collaborator. find-activity reports completion events, including each occurrence of a recurring task; **find-completed-tasks** lists completed tasks, which is not the same question.\n- To resolve a person's name or email to a user ID, or to answer \"who is X?\", use **find-project-collaborators** with just a searchTerm. It covers every shared project you can access plus yourself, so an empty result means they collaborate on none of them \u2014 not that they do not exist.\n- Before assigning work to someone, call **find-project-collaborators** again with the target projectId. Resolving an ID only proves they collaborate on *some* project you can see; assignment fails unless they collaborate on that one.\n- To find out whether a task hides subtasks, use **fetch-object** with includeChildren rather than a speculative **find-tasks** call.\n- Filter tasks by label **name**. Label IDs are only for **delete-object** and **update-labels**. Shared labels can be renamed but not recoloured, reordered or favourited.\n\n**Comments**\n\n- Comments notify only the people **add-comments** is handed. When a comment mentions someone, name them in `notifyUsers` \u2014 writing \"@Ana\" in the text notifies nobody. Omit `notifyUsers` to notify whoever the Todoist apps would, or pass `[\"none\"]` to stay silent.\n- Notification cannot be sent when editing a comment, only when adding one.\n\n**Deleting and archiving**\n\n- **delete-object** removes every object type; there is no per-type delete tool. Reminders use type \"reminder\", location reminders \"location_reminder\".\n- A workspace project must be archived with **project-management** before it can be deleted. A personal project can be deleted directly.\n\n**Templates**\n\n- Templates cannot be listed through this server, so only use an ID or URL the user gave you. To start a new project from one, call **add-projects** first and import into it. Imports write immediately and cannot be undone.\n\n**Project health**\n\n- Health data may be stale \u2014 check the isStale flag, and call **analyze-project-health** to refresh it before reading again.\n\n**Batches**\n\n- Prefer a batch tool over one call per item.\n- Where a batch tool returns per-item `failures` alongside successes, one failure does not undo the rest: never retry the whole batch, re-send only the items whose failure reason is fixable. **reschedule-tasks** is the exception \u2014 it has no per-item failures and throws if any task fails, so retry it as a whole.\n\nUse the **productivity-analysis** prompt for a combined productivity review \u2014 it pulls together user-info, get-productivity-stats and find-completed-tasks.\n\nAlways provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.\n";
4
4
  /**
5
5
  * Create the MCP server.
6
6
  * @param todoistApiKey - The API key for the todoist account.
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAExD,OAAO,EACH,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,QAAQ,EAEhB,MAAM,kBAAkB,CAAA;AAMzB,eAAO,MAAM,YAAY,i8IAyDxB,CAAA;AAgBD;;;;;;GAMG;AAEH,iBAAS,YAAY,CAAC,EAClB,aAAa,EACb,OAAO,EACP,QAAa,GAChB,EAAE;IACC,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACtB,aAmDA;AAED,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAExD,OAAO,EACH,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,QAAQ,EAEhB,MAAM,kBAAkB,CAAA;AAMzB,eAAO,MAAM,YAAY,qhJAyDxB,CAAA;AAgBD;;;;;;GAMG;AAEH,iBAAS,YAAY,CAAC,EAClB,aAAa,EACb,OAAO,EACP,QAAa,GAChB,EAAE;IACC,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACtB,aAmDA;AAED,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,YAAY,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
- import { $ as A, a0 as v, a1 as T } from "./mcp-server-3s9l5Skf.js";
1
+ import { $ as A, a0 as v, a1 as T } from "./mcp-server-cg7S50xk.js";
2
2
  const y = /* @__PURE__ */ new Set([401, 403]);
3
3
  function C(e) {
4
4
  const t = T(e);
@@ -226,6 +226,7 @@ declare const toolRegistry: {
226
226
  p4: "p4";
227
227
  }>>;
228
228
  dueString: import('zod').ZodOptional<import('zod').ZodPreprocess<import('zod').ZodString, unknown>>;
229
+ replaceRecurrence: import('zod').ZodOptional<import('zod').ZodBoolean>;
229
230
  deadlineDate: import('zod').ZodOptional<import('zod').ZodPreprocess<import('zod').ZodString, unknown>>;
230
231
  duration: import('zod').ZodOptional<import('zod').ZodString>;
231
232
  responsibleUser: import('zod').ZodOptional<import('zod').ZodPreprocess<import('zod').ZodString, unknown>>;
@@ -291,6 +292,7 @@ declare const toolRegistry: {
291
292
  order?: number | undefined;
292
293
  priority?: "p1" | "p2" | "p3" | "p4" | undefined;
293
294
  dueString?: string | undefined;
295
+ replaceRecurrence?: boolean | undefined;
294
296
  deadlineDate?: string | undefined;
295
297
  duration?: string | undefined;
296
298
  responsibleUser?: string | undefined;
@@ -343,6 +345,7 @@ declare const toolRegistry: {
343
345
  tasks: import('zod').ZodArray<import('zod').ZodObject<{
344
346
  id: import('zod').ZodString;
345
347
  date: import('zod').ZodString;
348
+ duration: import('zod').ZodOptional<import('zod').ZodString>;
346
349
  }, import('zod/v4/core').$strip>>;
347
350
  };
348
351
  outputSchema: {
@@ -384,6 +387,7 @@ declare const toolRegistry: {
384
387
  tasks: {
385
388
  id: string;
386
389
  date: string;
390
+ duration?: string | undefined;
387
391
  }[];
388
392
  }, client: import('@doist/todoist-sdk').TodoistApi): Promise<{
389
393
  textContent: string;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAkEvD;;;;;;;;;;GAUG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+EjB,CAAA;AAED;;;;;GAKG;AACH,QAAA,MAAM,eAAe,EAAE,SAAS,cAAc,EAAgC,CAAA;AAE9E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAkEvD;;;;;;;;;;GAUG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+EjB,CAAA;AAED;;;;;GAKG;AACH,QAAA,MAAM,eAAe,EAAE,SAAS,cAAc,EAAgC,CAAA;AAE9E,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"add-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/add-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA4BvB,QAAA,MAAM,uBAAuB,IAAkC,CAAA;AA4D/D,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAyDwB,MAAM;uBAAS,MAAM;;;;;;;CAyCI,CAAA;AA+L/D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAA"}
1
+ {"version":3,"file":"add-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/add-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAwBvB,QAAA,MAAM,uBAAuB,IAAkC,CAAA;AA4D/D,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAyDwB,MAAM;uBAAS,MAAM;;;;;;;CAyCI,CAAA;AAoL/D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAA"}
@@ -7,6 +7,7 @@ declare const rescheduleTasks: {
7
7
  tasks: z.ZodArray<z.ZodObject<{
8
8
  id: z.ZodString;
9
9
  date: z.ZodString;
10
+ duration: z.ZodOptional<z.ZodString>;
10
11
  }, z.core.$strip>>;
11
12
  };
12
13
  outputSchema: {
@@ -48,6 +49,7 @@ declare const rescheduleTasks: {
48
49
  tasks: {
49
50
  id: string;
50
51
  date: string;
52
+ duration?: string | undefined;
51
53
  }[];
52
54
  }, client: import('@doist/todoist-sdk').TodoistApi): Promise<{
53
55
  textContent: string;
@@ -1 +1 @@
1
- {"version":3,"file":"reschedule-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/reschedule-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA+BvB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuE0C,CAAA;AAE/D,iBAAS,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAU7F;AAED,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"reschedule-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/reschedule-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAoCvB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6E0C,CAAA;AAE/D,iBAAS,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAU7F;AAED,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAA"}
@@ -19,6 +19,7 @@ declare const updateTasks: {
19
19
  p4: "p4";
20
20
  }>>;
21
21
  dueString: z.ZodOptional<z.ZodPreprocess<z.ZodString, unknown>>;
22
+ replaceRecurrence: z.ZodOptional<z.ZodBoolean>;
22
23
  deadlineDate: z.ZodOptional<z.ZodPreprocess<z.ZodString, unknown>>;
23
24
  duration: z.ZodOptional<z.ZodString>;
24
25
  responsibleUser: z.ZodOptional<z.ZodPreprocess<z.ZodString, unknown>>;
@@ -84,6 +85,7 @@ declare const updateTasks: {
84
85
  order?: number | undefined;
85
86
  priority?: "p1" | "p2" | "p3" | "p4" | undefined;
86
87
  dueString?: string | undefined;
88
+ replaceRecurrence?: boolean | undefined;
87
89
  deadlineDate?: string | undefined;
88
90
  duration?: string | undefined;
89
91
  responsibleUser?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"update-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/update-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIR,UAAU,EAEb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAyLvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBA4MW,MAAM;uBAAS,MAAM;uBAAS,MAAM;;;;;;;;;;CARD,CAAA;AA+d/D,OAAO,EAAE,WAAW,EAAE,CAAA"}
1
+ {"version":3,"file":"update-tasks.d.ts","sourceRoot":"","sources":["../../src/tools/update-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIR,UAAU,EAEb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAiMvB,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAiOW,MAAM;uBAAS,MAAM;uBAAS,MAAM;;;;;;;;;;CARD,CAAA;AA0f/D,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -29,6 +29,11 @@ export declare function parseDuration(durationStr: string): ParsedDuration;
29
29
  * @param unit - The unit the amount is stored in
30
30
  * @returns Formatted duration string like "2h30m", "45m" or "3d"
31
31
  */
32
+ /**
33
+ * Parses one batch item's duration, prefixing a format error with `label` (e.g.
34
+ * `Task 123`) so the caller can report it against that item.
35
+ */
36
+ export declare function parseItemDuration(label: string, durationStr: string): ParsedDuration;
32
37
  export declare function formatDuration(amount: number, unit?: DurationUnit): string;
33
38
  export {};
34
39
  //# sourceMappingURL=duration-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"duration-parser.d.ts","sourceRoot":"","sources":["../../src/utils/duration-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,KAAK,cAAc,GAAG;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,0BAA0B,gXACgU,CAAA;AAIvW,qBAAa,kBAAmB,SAAQ,KAAK;gBAC7B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI5C;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CA0BjE;AAqFD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,YAAuB,GAAG,MAAM,CAmBpF"}
1
+ {"version":3,"file":"duration-parser.d.ts","sourceRoot":"","sources":["../../src/utils/duration-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,KAAK,cAAc,GAAG;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,YAAY,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,0BAA0B,gXACgU,CAAA;AAIvW,qBAAa,kBAAmB,SAAQ,KAAK;gBAC7B,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI5C;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CA0BjE;AAqFD;;;;;;;;;;;;GAYG;AACH;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CASpF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,YAAuB,GAAG,MAAM,CAmBpF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doist/todoist-mcp",
3
- "version": "13.10.0",
3
+ "version": "13.10.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -41,6 +41,8 @@
41
41
  "test": "vitest run",
42
42
  "test:watch": "vitest",
43
43
  "test:coverage": "vitest run --coverage",
44
+ "verify": "node .agents/scripts/verify.ts",
45
+ "review:worktree": "node .agents/scripts/review-worktree.ts",
44
46
  "build": "npm run build:lib && npm run build:apps",
45
47
  "build:lib": "vite build",
46
48
  "build:apps": "vite build --config src/mcp-apps/vite.config.ts",
@@ -56,13 +58,13 @@
56
58
  "tool:list": "tsx scripts/run-tool.ts --list",
57
59
  "eval": "tsx scripts/eval-instructions.ts",
58
60
  "test:executable": "npm run build && node scripts/test-executable.cjs",
59
- "type-check": "npx tsc --noEmit",
60
- "format:check": "oxlint src scripts && oxfmt --check",
61
- "format:fix": "oxlint src scripts --fix && oxfmt",
61
+ "type-check": "npx tsc --noEmit && npx tsc --noEmit -p .agents/scripts",
62
+ "format:check": "oxlint src scripts .agents/scripts && oxfmt --check",
63
+ "format:fix": "oxlint src scripts .agents/scripts --fix && oxfmt",
62
64
  "lint:schemas": "npm run build && npx tsx scripts/validate-schemas.ts",
63
- "check": "oxlint src scripts && oxfmt --check && npm run lint:schemas",
65
+ "check": "oxlint src scripts .agents/scripts && oxfmt --check && npm run lint:schemas",
64
66
  "prepublishOnly": "npm run build && npm test",
65
- "prepare": "husky"
67
+ "prepare": "lefthook install --reset-hooks-path"
66
68
  },
67
69
  "dependencies": {
68
70
  "@doist/todoist-sdk": "16.0.0",
@@ -95,8 +97,7 @@
95
97
  "concurrently": "9.2.5",
96
98
  "conventional-changelog-conventionalcommits": "9.3.1",
97
99
  "gpt-tokenizer": "3.4.0",
98
- "husky": "9.1.7",
99
- "lint-staged": "16.4.0",
100
+ "lefthook": "2.2.2",
100
101
  "morgan": "1.11.0",
101
102
  "nodemon": "3.1.14",
102
103
  "oxfmt": "0.55.0",
@@ -112,23 +113,5 @@
112
113
  "vite-plugin-dts": "4.5.4",
113
114
  "vite-plugin-singlefile": "2.3.4",
114
115
  "vitest": "4.1.12"
115
- },
116
- "lint-staged": {
117
- "*.{ts,tsx,js,jsx}": [
118
- "oxlint --fix",
119
- "oxfmt --no-error-on-unmatched-pattern"
120
- ],
121
- "*.{md,yml,yaml,css,json}": [
122
- "oxfmt --no-error-on-unmatched-pattern"
123
- ],
124
- "src/tools/!(*.test).ts": [
125
- "npm run lint:schemas"
126
- ],
127
- "src/index.ts": [
128
- "npm run lint:schemas"
129
- ],
130
- "scripts/validate-schemas.ts": [
131
- "npm run lint:schemas"
132
- ]
133
116
  }
134
117
  }
@@ -1,14 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync, writeFileSync } from 'node:fs'
3
3
 
4
- const [version, manifestPath = '.claude-plugin/plugin.json'] = process.argv.slice(2)
4
+ const [version, manifestPath] = process.argv.slice(2)
5
5
 
6
6
  if (!version) {
7
7
  console.error('Usage: bump-plugin-version.mjs <version> [manifestPath]')
8
8
  process.exit(1)
9
9
  }
10
10
 
11
- const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
12
- manifest.version = version
13
- writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 4)}\n`)
14
- console.log(`Updated ${manifestPath} to ${version}`)
11
+ const paths = manifestPath
12
+ ? [manifestPath]
13
+ : ['.claude-plugin/plugin.json', 'plugins/todoist/.claude-plugin/plugin.json']
14
+
15
+ for (const path of paths) {
16
+ const manifest = JSON.parse(readFileSync(path, 'utf8'))
17
+ manifest.version = version
18
+ writeFileSync(path, `${JSON.stringify(manifest, null, 4)}\n`)
19
+ console.log(`Updated ${path} to ${version}`)
20
+ }
@@ -87,6 +87,20 @@ const SCENARIOS: Scenario[] = [
87
87
  forbid: [ToolNames.UPDATE_TASKS],
88
88
  guards: 'instructions: reschedule-tasks vs update-tasks (recurrence loss)',
89
89
  },
90
+ {
91
+ // Doist/Issues#21505: time-blocking needs a time and a duration, and
92
+ // update-tasks used to be the only tool that set both.
93
+ id: 'time-block-recurring',
94
+ prompt: 'Block 10:00-10:15 today for task 6XG4Vw2c9J ("Give meds", repeats every day at 9:00).',
95
+ forbid: [ToolNames.UPDATE_TASKS],
96
+ check: (input) => {
97
+ const task = firstItem(input, 'tasks')
98
+ // Only the reschedule call carries a date; a lookup is fine.
99
+ if (!task || !('date' in task)) return null
100
+ return task.duration ? null : `rescheduled without a duration: ${JSON.stringify(task)}`
101
+ },
102
+ guards: 'reschedule-tasks duration: time-blocking a recurring task',
103
+ },
90
104
  {
91
105
  id: 'completed-via-activity',
92
106
  prompt: 'What did I actually get done last week?',