@doist/todoist-mcp 12.6.0 → 13.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +3 -3
- package/dist/main-http.js +3 -3
- package/dist/main.js +2 -2
- package/dist/mcp-helpers.d.ts +1 -1
- package/dist/mcp-helpers.d.ts.map +1 -1
- package/dist/{mcp-server-D_To1yun.js → mcp-server-CcPMZbuy.js} +429 -439
- package/dist/mcp-server.d.ts +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/prompts/productivity-analysis.d.ts +6 -6
- package/dist/prompts/productivity-analysis.d.ts.map +1 -1
- package/dist/{require-valid-todoist-token-Bq33Qbug.js → require-valid-todoist-token-B36dR_PT.js} +1 -1
- package/dist/todoist-tool.d.ts +1 -1
- package/dist/todoist-tool.d.ts.map +1 -1
- package/dist/tool-registry.d.ts +10 -10
- package/dist/tools/find-completed-tasks.d.ts +3 -3
- package/dist/tools/find-tasks-by-date.d.ts +4 -4
- package/dist/tools/find-tasks.d.ts +3 -3
- package/dist/tools/import-project-template.d.ts.map +1 -1
- package/dist/tools/view-attachment.d.ts +1 -1
- package/dist/tools/view-attachment.d.ts.map +1 -1
- package/dist/utils/labels.d.ts +1 -1
- package/package.json +5 -3
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { ResourceTemplate as As, McpServer as Es } from "@modelcontextprotocol/
|
|
2
|
-
import { createHash as
|
|
1
|
+
import { ResourceTemplate as As, McpServer as Es } from "@modelcontextprotocol/server";
|
|
2
|
+
import { createHash as Lt, randomUUID as Pe } from "node:crypto";
|
|
3
3
|
import { readFileSync as Os } from "node:fs";
|
|
4
|
-
import { dirname as
|
|
4
|
+
import { dirname as Nt, join as _e } from "node:path";
|
|
5
5
|
import { fileURLToPath as Ps } from "node:url";
|
|
6
|
-
import {
|
|
7
|
-
import se, { ZodError as
|
|
8
|
-
import { AsyncLocalStorage as
|
|
9
|
-
import { createRequire as
|
|
10
|
-
import { TodoistApi as
|
|
11
|
-
import { addDays as
|
|
12
|
-
const
|
|
13
|
-
_e(
|
|
14
|
-
_e(
|
|
15
|
-
],
|
|
6
|
+
import { RESOURCE_MIME_TYPE as Ue } from "@modelcontextprotocol/ext-apps/server";
|
|
7
|
+
import se, { ZodError as _s, z as s } from "zod";
|
|
8
|
+
import { AsyncLocalStorage as Us } from "node:async_hooks";
|
|
9
|
+
import { createRequire as Rs } from "node:module";
|
|
10
|
+
import { TodoistApi as Ls, isWorkspaceProject as ke, isPersonalProject as B, colors as Re, LOCATION_TRIGGERS as Mt, REMINDER_TYPES as Ns, createCommand as V, REMINDER_DELIVERY_SERVICES as Ms, HEALTH_STATUSES as Ve, getTaskUrl as Ft, getProjectUrl as Ht, parseTodoistUrl as Fs, WORKSPACE_ROLES as Hs, WORKSPACE_PLANS as Ws } from "@doist/todoist-sdk";
|
|
11
|
+
import { addDays as Le, formatISO as ut } from "date-fns";
|
|
12
|
+
const pt = Nt(Ps(import.meta.url)), Bs = [
|
|
13
|
+
_e(pt, "task-list", "index.html"),
|
|
14
|
+
_e(pt, "mcp-apps", "index.html")
|
|
15
|
+
], zs = `<!doctype html>
|
|
16
16
|
<html>
|
|
17
17
|
<body>
|
|
18
18
|
<p>Task list app is missing. Run "npm run build" to generate it.</p>
|
|
19
19
|
</body>
|
|
20
20
|
</html>`;
|
|
21
|
-
function
|
|
21
|
+
function Ks() {
|
|
22
22
|
const e = [];
|
|
23
|
-
for (const t of
|
|
23
|
+
for (const t of Bs)
|
|
24
24
|
try {
|
|
25
25
|
return Os(t, "utf-8");
|
|
26
26
|
} catch (o) {
|
|
27
27
|
e.push(o);
|
|
28
28
|
}
|
|
29
|
-
return console.error("Failed to load task list app HTML from any known path:", e),
|
|
29
|
+
return console.error("Failed to load task list app HTML from any known path:", e), zs;
|
|
30
30
|
}
|
|
31
|
-
const Wt =
|
|
31
|
+
const Wt = Ks(), Ys = Lt("sha256").update(Wt).digest("hex").slice(0, 12), Ne = `ui://todoist/task-list@${Ys}`, qs = "ui://todoist/task-list@{hash}", Me = "Interactive task list widget", Gs = "https://ai.todoist.net", Fe = {
|
|
32
32
|
ui: {
|
|
33
33
|
prefersBorder: !0,
|
|
34
34
|
csp: {
|
|
@@ -37,51 +37,51 @@ const Wt = Ys(), qs = Ut("sha256").update(Wt).digest("hex").slice(0, 12), Le = `
|
|
|
37
37
|
resourceDomains: []
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
-
"openai/widgetDescription":
|
|
40
|
+
"openai/widgetDescription": Me,
|
|
41
41
|
"openai/widgetPrefersBorder": !0,
|
|
42
42
|
"openai/widgetCSP": {
|
|
43
43
|
connect_domains: [],
|
|
44
44
|
resource_domains: []
|
|
45
45
|
},
|
|
46
|
-
"openai/widgetDomain":
|
|
46
|
+
"openai/widgetDomain": Gs
|
|
47
47
|
};
|
|
48
|
-
function
|
|
48
|
+
function ht(e) {
|
|
49
49
|
return {
|
|
50
50
|
contents: [
|
|
51
51
|
{
|
|
52
52
|
uri: e,
|
|
53
|
-
mimeType:
|
|
53
|
+
mimeType: Ue,
|
|
54
54
|
text: Wt,
|
|
55
|
-
_meta:
|
|
55
|
+
_meta: Fe
|
|
56
56
|
}
|
|
57
57
|
]
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
e,
|
|
60
|
+
function Vs(e) {
|
|
61
|
+
e.registerResource(
|
|
63
62
|
"todoist-task-list",
|
|
64
|
-
|
|
63
|
+
Ne,
|
|
65
64
|
{
|
|
66
|
-
description:
|
|
67
|
-
|
|
65
|
+
description: Me,
|
|
66
|
+
mimeType: Ue,
|
|
67
|
+
_meta: Fe
|
|
68
68
|
},
|
|
69
|
-
async () =>
|
|
69
|
+
async () => ht(Ne)
|
|
70
70
|
), e.registerResource(
|
|
71
71
|
"todoist-task-list-hash-fallback",
|
|
72
|
-
new As(
|
|
72
|
+
new As(qs, { list: void 0 }),
|
|
73
73
|
{
|
|
74
|
-
description: `${
|
|
75
|
-
mimeType:
|
|
76
|
-
_meta:
|
|
74
|
+
description: `${Me} compatibility fallback`,
|
|
75
|
+
mimeType: Ue,
|
|
76
|
+
_meta: Fe
|
|
77
77
|
},
|
|
78
|
-
async (t) =>
|
|
78
|
+
async (t) => ht(t.toString())
|
|
79
79
|
);
|
|
80
80
|
}
|
|
81
81
|
function J(e) {
|
|
82
82
|
return typeof e == "object" && e !== null;
|
|
83
83
|
}
|
|
84
|
-
function
|
|
84
|
+
function He(...e) {
|
|
85
85
|
return e.find(J);
|
|
86
86
|
}
|
|
87
87
|
function L(...e) {
|
|
@@ -105,17 +105,17 @@ function oe(e) {
|
|
|
105
105
|
const t = E(e);
|
|
106
106
|
return t !== void 0 ? t : w(e);
|
|
107
107
|
}
|
|
108
|
-
function
|
|
108
|
+
function Js(e) {
|
|
109
109
|
return e.replace(/\b(Bearer)\s+[A-Za-z0-9._~+/=-]+/gi, "$1 [REDACTED]").replace(
|
|
110
110
|
/\b(token|api[_-]?key|authorization)\s*[:=]\s*["']?[A-Za-z0-9._~+/=-]{6,}["']?/gi,
|
|
111
111
|
"$1: [REDACTED]"
|
|
112
112
|
).replace(/([?&](?:token|api[_-]?key|authorization)=)[^&\s]+/gi, "$1[REDACTED]").replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g, "[REDACTED]");
|
|
113
113
|
}
|
|
114
|
-
function
|
|
115
|
-
const o =
|
|
114
|
+
function U(e, t = 220) {
|
|
115
|
+
const o = Js(e).replace(/\s+/g, " ").trim();
|
|
116
116
|
return o.length <= t ? o : `${o.slice(0, t - 3)}...`;
|
|
117
117
|
}
|
|
118
|
-
function
|
|
118
|
+
function We(e) {
|
|
119
119
|
const t = e.trim();
|
|
120
120
|
return /\bHTTP\s*\d{3}\b/i.test(t) || /\bstatus code \d{3}\b/i.test(t) || /^bad request$/i.test(t) || /^unauthorized$/i.test(t) || /^forbidden$/i.test(t) || /^not found$/i.test(t);
|
|
121
121
|
}
|
|
@@ -129,10 +129,10 @@ function xe(e) {
|
|
|
129
129
|
function G(e) {
|
|
130
130
|
const t = w(e);
|
|
131
131
|
if (t)
|
|
132
|
-
return
|
|
132
|
+
return U(t);
|
|
133
133
|
if (Array.isArray(e)) {
|
|
134
134
|
const n = e.map((i) => J(i) ? w(i.message) || w(i.error) : w(i)).filter((i) => !!i);
|
|
135
|
-
return n.length > 0 ?
|
|
135
|
+
return n.length > 0 ? U(n.slice(0, 2).join("; ")) : void 0;
|
|
136
136
|
}
|
|
137
137
|
if (!J(e))
|
|
138
138
|
return;
|
|
@@ -144,20 +144,20 @@ function G(e) {
|
|
|
144
144
|
w(e.description)
|
|
145
145
|
);
|
|
146
146
|
if (o)
|
|
147
|
-
return
|
|
147
|
+
return U(o);
|
|
148
148
|
const r = [];
|
|
149
149
|
for (const [n, i] of Object.entries(e)) {
|
|
150
150
|
const a = w(i);
|
|
151
151
|
if (a && (r.push(`${n}: ${a}`), r.length >= 2))
|
|
152
152
|
break;
|
|
153
153
|
}
|
|
154
|
-
return r.length > 0 ?
|
|
154
|
+
return r.length > 0 ? U(r.join("; ")) : void 0;
|
|
155
155
|
}
|
|
156
|
-
function
|
|
156
|
+
function Xs(e) {
|
|
157
157
|
if (!e)
|
|
158
158
|
return [];
|
|
159
159
|
const t = /* @__PURE__ */ new Set(), o = (a) => {
|
|
160
|
-
a && t.add(
|
|
160
|
+
a && t.add(U(a, 120));
|
|
161
161
|
}, r = L(
|
|
162
162
|
w(e.field),
|
|
163
163
|
w(e.parameter),
|
|
@@ -165,7 +165,7 @@ function Zs(e) {
|
|
|
165
165
|
w(e.path)
|
|
166
166
|
);
|
|
167
167
|
o(r);
|
|
168
|
-
const n =
|
|
168
|
+
const n = He(
|
|
169
169
|
e.details,
|
|
170
170
|
e.errorDetails,
|
|
171
171
|
e.errorExtra,
|
|
@@ -216,7 +216,7 @@ function Zs(e) {
|
|
|
216
216
|
}
|
|
217
217
|
return Array.from(t).slice(0, 3);
|
|
218
218
|
}
|
|
219
|
-
const
|
|
219
|
+
const Zs = [
|
|
220
220
|
"error",
|
|
221
221
|
"error_code",
|
|
222
222
|
"error_tag",
|
|
@@ -227,41 +227,41 @@ const Qs = [
|
|
|
227
227
|
"httpCode",
|
|
228
228
|
"errorExtra"
|
|
229
229
|
];
|
|
230
|
-
function
|
|
231
|
-
return e ?
|
|
230
|
+
function Qs(e) {
|
|
231
|
+
return e ? Zs.some((t) => e[t] !== void 0) : !1;
|
|
232
232
|
}
|
|
233
|
-
const
|
|
233
|
+
const Be = {
|
|
234
234
|
MAX_ITEMS_LIMIT_REACHED: "This project has reached the maximum number of active tasks per project (subtasks count toward it; completed tasks do not). The cap is the same on every Todoist plan — upgrading will not raise it — and it is not an authentication or permission problem. Complete, delete, or move existing tasks out of the project, or add the task to a different project, then retry.",
|
|
235
235
|
USER_CANNOT_VIEW_TEMPLATE: "This template exists but belongs to another account. Personal templates are private to whoever saved them, and a link to one cannot be used by anyone else. Use a public gallery template instead, or ask the owner to export it with export-project-template and share the CSV."
|
|
236
236
|
};
|
|
237
|
-
function
|
|
237
|
+
function eo(...e) {
|
|
238
238
|
for (const t of e) {
|
|
239
239
|
if (!t)
|
|
240
240
|
continue;
|
|
241
|
-
const o = t.toUpperCase(), r = Object.keys(
|
|
241
|
+
const o = t.toUpperCase(), r = Object.keys(Be).find(
|
|
242
242
|
(n) => o.includes(n)
|
|
243
243
|
);
|
|
244
244
|
if (r)
|
|
245
|
-
return
|
|
245
|
+
return Be[r];
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
function
|
|
248
|
+
function to(e) {
|
|
249
249
|
if (e.tag) {
|
|
250
|
-
const t =
|
|
250
|
+
const t = Be[e.tag.toUpperCase()];
|
|
251
251
|
if (t)
|
|
252
252
|
return t;
|
|
253
253
|
}
|
|
254
|
-
return
|
|
254
|
+
return eo(...e.rawText ?? [], e.message, e.details);
|
|
255
255
|
}
|
|
256
|
-
function
|
|
257
|
-
const t =
|
|
256
|
+
function so(e) {
|
|
257
|
+
const t = to(e);
|
|
258
258
|
if (t)
|
|
259
259
|
return t;
|
|
260
260
|
const { statusCode: o } = e, r = e.fieldHints.length > 0;
|
|
261
261
|
return o === 401 ? "Authentication failed. Verify your API token, then retry." : o === 403 ? "Access denied. Retrying the same request will not help. If it's a scope/access problem (for example, insufficient token scope), use a token or account with the required access. Otherwise, change the request or target instead." : o === 404 ? "Confirm the referenced IDs exist and are accessible, then retry." : o === 429 ? "Rate limit reached. Wait briefly and retry." : o !== void 0 && o >= 500 ? "Todoist API may be temporarily unavailable. Retry shortly." : r ? "Fix the field hints above and retry." : o === 400 || o === 422 ? "Check parameter values and formats, then retry." : "Check the request parameters and retry.";
|
|
262
262
|
}
|
|
263
|
-
function
|
|
264
|
-
const t = J(e) ? e : void 0, o = e instanceof Error && J(e.cause) ? e.cause : void 0, r =
|
|
263
|
+
function Je(e) {
|
|
264
|
+
const t = J(e) ? e : void 0, o = e instanceof Error && J(e.cause) ? e.cause : void 0, r = He(t?.response, o?.response), n = He(
|
|
265
265
|
t?.responseData,
|
|
266
266
|
r?.data,
|
|
267
267
|
t?.data,
|
|
@@ -301,20 +301,20 @@ function Ve(e) {
|
|
|
301
301
|
w(t?.message),
|
|
302
302
|
w(o?.message),
|
|
303
303
|
e instanceof Error ? e.message : w(e)
|
|
304
|
-
].filter((m) => !!m), l = d.find((m) => !
|
|
304
|
+
].filter((m) => !!m), l = d.find((m) => !We(m)) || d[0], p = L(
|
|
305
305
|
G(n?.errorExtra),
|
|
306
306
|
G(n?.error_extra),
|
|
307
307
|
G(n?.details),
|
|
308
308
|
G(n?.errorDetails),
|
|
309
309
|
G(n?.errors),
|
|
310
310
|
G(t?.details)
|
|
311
|
-
), u =
|
|
312
|
-
return i !== void 0 ||
|
|
311
|
+
), u = Xs(n);
|
|
312
|
+
return i !== void 0 || Qs(n) || c !== void 0 || a !== void 0 || (l ? We(l) : !1) ? {
|
|
313
313
|
statusCode: i,
|
|
314
314
|
code: a,
|
|
315
|
-
tag: c ?
|
|
316
|
-
message: l ?
|
|
317
|
-
details: p ?
|
|
315
|
+
tag: c ? U(c, 80) : void 0,
|
|
316
|
+
message: l ? U(l) : void 0,
|
|
317
|
+
details: p ? U(p) : void 0,
|
|
318
318
|
rawText: d,
|
|
319
319
|
fieldHints: u
|
|
320
320
|
} : null;
|
|
@@ -323,15 +323,15 @@ function Bt(e) {
|
|
|
323
323
|
const t = [];
|
|
324
324
|
return e.statusCode !== void 0 && t.push(`HTTP ${e.statusCode}`), e.code !== void 0 && t.push(`code ${e.code}`), e.tag && t.push(`tag ${e.tag}`), t;
|
|
325
325
|
}
|
|
326
|
-
function
|
|
326
|
+
function oo(e) {
|
|
327
327
|
const t = Bt(e), o = [
|
|
328
328
|
t.length > 0 ? `Todoist API request failed (${t.join(", ")}).` : "Todoist API request failed."
|
|
329
329
|
];
|
|
330
|
-
return e.message && o.push(`Message: ${e.message}`), e.details && e.details !== e.message && o.push(`Details: ${e.details}`), e.fieldHints.length > 0 && o.push(`Field hints: ${e.fieldHints.join("; ")}`), o.push(`Try next: ${
|
|
330
|
+
return e.message && o.push(`Message: ${e.message}`), e.details && e.details !== e.message && o.push(`Details: ${e.details}`), e.fieldHints.length > 0 && o.push(`Field hints: ${e.fieldHints.join("; ")}`), o.push(`Try next: ${so(e)}`), o.join(`
|
|
331
331
|
`);
|
|
332
332
|
}
|
|
333
333
|
function zt(e) {
|
|
334
|
-
return e instanceof Error ?
|
|
334
|
+
return e instanceof Error ? U(e.message) : typeof e == "string" ? U(e) : "An unknown error occurred";
|
|
335
335
|
}
|
|
336
336
|
class ve extends Error {
|
|
337
337
|
constructor(t) {
|
|
@@ -346,33 +346,33 @@ class Kt extends Error {
|
|
|
346
346
|
function z(e) {
|
|
347
347
|
if (e instanceof ve)
|
|
348
348
|
return e.message;
|
|
349
|
-
const t =
|
|
349
|
+
const t = Je(e);
|
|
350
350
|
if (!t)
|
|
351
351
|
return zt(e);
|
|
352
|
-
const o = Bt(t), r = t.message && !(o.length > 0 &&
|
|
352
|
+
const o = Bt(t), r = t.message && !(o.length > 0 && We(t.message)) ? t.message : "Todoist API request failed";
|
|
353
353
|
return o.length > 0 ? `${r} (${o.join(", ")})` : r;
|
|
354
354
|
}
|
|
355
|
-
function
|
|
355
|
+
function ro(e, {
|
|
356
356
|
taskContent: t,
|
|
357
357
|
dueString: o,
|
|
358
358
|
deadlineDate: r
|
|
359
359
|
}) {
|
|
360
360
|
if (!o)
|
|
361
361
|
return;
|
|
362
|
-
const n =
|
|
362
|
+
const n = Je(e), a = n?.tag?.toUpperCase() === "INVALID_DUE_STRING", c = !r && /^invalid date format\.?$/i.test(n?.message ?? "");
|
|
363
363
|
if (!a && !c)
|
|
364
364
|
return;
|
|
365
365
|
const d = o.trim().replace(/^recurring(?:\s+|$)/i, "").trim();
|
|
366
366
|
return d !== o.trim() && d ? `Task "${t}" wasn't created because \`dueString\` could not be parsed. Use Todoist recurrence syntax, for example \`${d}\`; don't prefix it with \`recurring\`. Change only \`dueString\` and retry.` : d !== o.trim() ? `Task "${t}" wasn't created because \`dueString\` could not be parsed. Use a complete Todoist recurrence expression; \`recurring\` alone is not valid. Change only \`dueString\` and retry.` : `Task "${t}" wasn't created because \`dueString\` could not be parsed. Change only \`dueString\` and retry.`;
|
|
367
367
|
}
|
|
368
|
-
function
|
|
369
|
-
if (e instanceof
|
|
368
|
+
function no(e) {
|
|
369
|
+
if (e instanceof _s || e instanceof ve || e instanceof Kt)
|
|
370
370
|
return e.message;
|
|
371
|
-
const t =
|
|
372
|
-
return t ?
|
|
371
|
+
const t = Je(e);
|
|
372
|
+
return t ? oo(t) : zt(e);
|
|
373
373
|
}
|
|
374
|
-
const
|
|
375
|
-
version:
|
|
374
|
+
const io = "13.1.0", ao = {
|
|
375
|
+
version: io
|
|
376
376
|
}, C = {
|
|
377
377
|
/** Default limit for task listings */
|
|
378
378
|
TASKS_DEFAULT: 10,
|
|
@@ -412,7 +412,7 @@ const ao = "12.6.0", co = {
|
|
|
412
412
|
}, Yt = {
|
|
413
413
|
/** Maximum tasks accepted by one task create or update operation */
|
|
414
414
|
TASKS_PER_OPERATION: 25
|
|
415
|
-
},
|
|
415
|
+
}, ze = {
|
|
416
416
|
/**
|
|
417
417
|
* In-flight task-move requests per account, per process.
|
|
418
418
|
*
|
|
@@ -436,7 +436,7 @@ const ao = "12.6.0", co = {
|
|
|
436
436
|
*/
|
|
437
437
|
QUEUE_WAIT_MS: 3e4
|
|
438
438
|
};
|
|
439
|
-
function
|
|
439
|
+
function mt(e, { queueTimeoutMs: t = ze.QUEUE_WAIT_MS } = {}) {
|
|
440
440
|
if (!Number.isInteger(e) || e < 1)
|
|
441
441
|
throw new Error(
|
|
442
442
|
`maxConcurrent must be a positive integer, received ${String(e)}`
|
|
@@ -479,73 +479,73 @@ function ht(e, { queueTimeoutMs: t = Be.QUEUE_WAIT_MS } = {}) {
|
|
|
479
479
|
}
|
|
480
480
|
function qt() {
|
|
481
481
|
return {
|
|
482
|
-
moves:
|
|
483
|
-
writes:
|
|
482
|
+
moves: mt(ze.TASK_MOVES),
|
|
483
|
+
writes: mt(ze.WRITES)
|
|
484
484
|
};
|
|
485
485
|
}
|
|
486
|
-
const
|
|
487
|
-
let
|
|
488
|
-
function
|
|
489
|
-
return
|
|
486
|
+
const ft = /* @__PURE__ */ new Map(), Gt = /* @__PURE__ */ new WeakMap();
|
|
487
|
+
let bt;
|
|
488
|
+
function co() {
|
|
489
|
+
return bt ??= qt(), bt;
|
|
490
490
|
}
|
|
491
|
-
function
|
|
492
|
-
return
|
|
491
|
+
function lo(e) {
|
|
492
|
+
return Lt("sha256").update(e).digest("hex");
|
|
493
493
|
}
|
|
494
|
-
function
|
|
495
|
-
const o =
|
|
496
|
-
let r =
|
|
497
|
-
r || (r = qt(),
|
|
494
|
+
function uo(e, t) {
|
|
495
|
+
const o = lo(t);
|
|
496
|
+
let r = ft.get(o);
|
|
497
|
+
r || (r = qt(), ft.set(o, r)), Gt.set(e, r);
|
|
498
498
|
}
|
|
499
499
|
function Vt(e) {
|
|
500
|
-
return Gt.get(e) ??
|
|
500
|
+
return Gt.get(e) ?? co();
|
|
501
501
|
}
|
|
502
|
-
function
|
|
502
|
+
function po(e) {
|
|
503
503
|
return Vt(e).moves;
|
|
504
504
|
}
|
|
505
|
-
function
|
|
505
|
+
function ho(e) {
|
|
506
506
|
return Vt(e).writes;
|
|
507
507
|
}
|
|
508
|
-
const
|
|
508
|
+
const mo = "todoist-mcp", Xe = ao.version, Jt = new Us(), gt = Rs(import.meta.url);
|
|
509
509
|
let Te;
|
|
510
|
-
const
|
|
511
|
-
const e =
|
|
512
|
-
return
|
|
510
|
+
const fo = async () => {
|
|
511
|
+
const e = gt.resolve("@doist/todoist-sdk"), t = _e(Nt(e), "transport", "http-dispatcher.js");
|
|
512
|
+
return gt(t);
|
|
513
513
|
};
|
|
514
|
-
let
|
|
515
|
-
function
|
|
516
|
-
return `${
|
|
514
|
+
let bo = fo;
|
|
515
|
+
function go() {
|
|
516
|
+
return `${mo}/${Xe}`;
|
|
517
517
|
}
|
|
518
518
|
function Xt(e) {
|
|
519
519
|
return e.trim().toLowerCase();
|
|
520
520
|
}
|
|
521
|
-
function
|
|
521
|
+
function yo(e, t) {
|
|
522
522
|
return Jt.run(Xt(e), t);
|
|
523
523
|
}
|
|
524
|
-
function
|
|
524
|
+
function To({
|
|
525
525
|
label: e,
|
|
526
526
|
platform: t = "mcp",
|
|
527
527
|
sessionId: o = Pe()
|
|
528
528
|
} = {}) {
|
|
529
529
|
const r = e ? Xt(e) : Jt.getStore();
|
|
530
530
|
return {
|
|
531
|
-
"User-Agent":
|
|
531
|
+
"User-Agent": go(),
|
|
532
532
|
"doist-platform": t,
|
|
533
|
-
"doist-version":
|
|
533
|
+
"doist-version": Xe,
|
|
534
534
|
"request-id": Pe(),
|
|
535
535
|
"session-id": o,
|
|
536
536
|
"mcp-tool": r ?? "unknown"
|
|
537
537
|
};
|
|
538
538
|
}
|
|
539
|
-
function
|
|
539
|
+
function ko(e, t) {
|
|
540
540
|
const o = new Headers(e);
|
|
541
|
-
for (const [r, n] of Object.entries(
|
|
541
|
+
for (const [r, n] of Object.entries(To(t)))
|
|
542
542
|
o.set(r, n);
|
|
543
543
|
return Object.fromEntries(o.entries());
|
|
544
544
|
}
|
|
545
|
-
function
|
|
545
|
+
function yt() {
|
|
546
546
|
return new DOMException("The operation was aborted due to timeout", "TimeoutError");
|
|
547
547
|
}
|
|
548
|
-
function
|
|
548
|
+
function wo(e, t) {
|
|
549
549
|
if (!e && t === void 0)
|
|
550
550
|
return {
|
|
551
551
|
signal: void 0,
|
|
@@ -553,7 +553,7 @@ function vo(e, t) {
|
|
|
553
553
|
}
|
|
554
554
|
};
|
|
555
555
|
if (!e && t !== void 0) {
|
|
556
|
-
const a = new AbortController(), c = setTimeout(() => a.abort(
|
|
556
|
+
const a = new AbortController(), c = setTimeout(() => a.abort(yt()), t);
|
|
557
557
|
return {
|
|
558
558
|
signal: a.signal,
|
|
559
559
|
cleanup: () => clearTimeout(c)
|
|
@@ -574,7 +574,7 @@ function vo(e, t) {
|
|
|
574
574
|
const a = () => n(e.reason);
|
|
575
575
|
e.addEventListener("abort", a, { once: !0 }), r.push(() => e.removeEventListener("abort", a));
|
|
576
576
|
}
|
|
577
|
-
const i = setTimeout(() => n(
|
|
577
|
+
const i = setTimeout(() => n(yt()), t);
|
|
578
578
|
return r.push(() => clearTimeout(i)), {
|
|
579
579
|
signal: o.signal,
|
|
580
580
|
cleanup: () => {
|
|
@@ -583,20 +583,20 @@ function vo(e, t) {
|
|
|
583
583
|
}
|
|
584
584
|
};
|
|
585
585
|
}
|
|
586
|
-
async function
|
|
587
|
-
if (
|
|
588
|
-
return Te || (Te =
|
|
586
|
+
async function vo() {
|
|
587
|
+
if (Io())
|
|
588
|
+
return Te || (Te = bo().then((e) => e.getDefaultDispatcher()).catch((e) => {
|
|
589
589
|
throw Te = void 0, e;
|
|
590
590
|
})), Te;
|
|
591
591
|
}
|
|
592
|
-
function
|
|
592
|
+
function Io() {
|
|
593
593
|
return typeof process < "u" && !!process.versions?.node;
|
|
594
594
|
}
|
|
595
|
-
async function
|
|
596
|
-
const t = await
|
|
595
|
+
async function So(e) {
|
|
596
|
+
const t = await vo();
|
|
597
597
|
t !== void 0 && (e.dispatcher = t);
|
|
598
598
|
}
|
|
599
|
-
function
|
|
599
|
+
function jo(e) {
|
|
600
600
|
return {
|
|
601
601
|
ok: e.ok,
|
|
602
602
|
status: e.status,
|
|
@@ -607,36 +607,36 @@ function Co(e) {
|
|
|
607
607
|
arrayBuffer: () => e.arrayBuffer()
|
|
608
608
|
};
|
|
609
609
|
}
|
|
610
|
-
function
|
|
610
|
+
function Co(e = globalThis.fetch, t = {}) {
|
|
611
611
|
const o = e === globalThis.fetch, { enabled: r = !0, platform: n = "mcp", sessionId: i = Pe() } = t;
|
|
612
612
|
return async (a, c = {}) => {
|
|
613
|
-
const { timeout: d, headers: l, signal: p, ...u } = c, { signal: h, cleanup: m } =
|
|
613
|
+
const { timeout: d, headers: l, signal: p, ...u } = c, { signal: h, cleanup: m } = wo(p, d);
|
|
614
614
|
try {
|
|
615
|
-
const
|
|
615
|
+
const g = {
|
|
616
616
|
...u,
|
|
617
617
|
signal: h,
|
|
618
|
-
...r ? { headers:
|
|
618
|
+
...r ? { headers: ko(l, { platform: n, sessionId: i }) } : l !== void 0 ? { headers: l } : {}
|
|
619
619
|
};
|
|
620
|
-
o && await
|
|
621
|
-
const f = await e(a,
|
|
622
|
-
return
|
|
620
|
+
o && await So(g);
|
|
621
|
+
const f = await e(a, g);
|
|
622
|
+
return jo(f);
|
|
623
623
|
} finally {
|
|
624
624
|
m();
|
|
625
625
|
}
|
|
626
626
|
};
|
|
627
627
|
}
|
|
628
|
-
function
|
|
628
|
+
function $o(e, {
|
|
629
629
|
baseUrl: t,
|
|
630
630
|
tracking: o
|
|
631
631
|
} = {}) {
|
|
632
|
-
const r = new
|
|
633
|
-
customFetch:
|
|
632
|
+
const r = new Ls(e, {
|
|
633
|
+
customFetch: Co(globalThis.fetch, o),
|
|
634
634
|
...t ? { baseUrl: t } : {}
|
|
635
635
|
});
|
|
636
|
-
return
|
|
636
|
+
return uo(r, e), r;
|
|
637
637
|
}
|
|
638
|
-
const
|
|
639
|
-
function
|
|
638
|
+
const Do = 2, xo = 500, Ao = 2e3, Eo = 50, Oo = /* @__PURE__ */ new Set([502, 503, 504]);
|
|
639
|
+
function Po(e) {
|
|
640
640
|
if (e == null || typeof e != "object")
|
|
641
641
|
return;
|
|
642
642
|
const t = e;
|
|
@@ -652,9 +652,9 @@ function _o(e) {
|
|
|
652
652
|
return Number(o[1]);
|
|
653
653
|
}
|
|
654
654
|
}
|
|
655
|
-
function
|
|
656
|
-
const t =
|
|
657
|
-
return t !== void 0 &&
|
|
655
|
+
function _o(e) {
|
|
656
|
+
const t = Po(e);
|
|
657
|
+
return t !== void 0 && Oo.has(t);
|
|
658
658
|
}
|
|
659
659
|
function Uo({
|
|
660
660
|
attempt: e,
|
|
@@ -663,37 +663,37 @@ function Uo({
|
|
|
663
663
|
random: r = Math.random
|
|
664
664
|
}) {
|
|
665
665
|
const n = Math.min(t * 2 ** e, o), i = Math.round(r() * n);
|
|
666
|
-
return Math.min(n, Math.max(
|
|
666
|
+
return Math.min(n, Math.max(Eo, i));
|
|
667
667
|
}
|
|
668
|
-
function
|
|
668
|
+
function Ro(e) {
|
|
669
669
|
return new Promise((t) => setTimeout(t, e));
|
|
670
670
|
}
|
|
671
671
|
async function O(e, t = {}) {
|
|
672
|
-
const o = t.maxRetries ??
|
|
672
|
+
const o = t.maxRetries ?? Do, r = t.baseDelayMs ?? xo, n = t.maxDelayMs ?? Ao, i = t.random;
|
|
673
673
|
let a;
|
|
674
674
|
for (let c = 0; c <= o; c++)
|
|
675
675
|
try {
|
|
676
676
|
return await e();
|
|
677
677
|
} catch (d) {
|
|
678
|
-
if (a = d, c < o &&
|
|
678
|
+
if (a = d, c < o && _o(d)) {
|
|
679
679
|
const l = Uo({ attempt: c, baseDelayMs: r, maxDelayMs: n, random: i });
|
|
680
|
-
await
|
|
680
|
+
await Ro(l);
|
|
681
681
|
continue;
|
|
682
682
|
}
|
|
683
683
|
throw d;
|
|
684
684
|
}
|
|
685
685
|
throw a;
|
|
686
686
|
}
|
|
687
|
-
function
|
|
687
|
+
function Ke(e) {
|
|
688
688
|
if (e == null)
|
|
689
689
|
return e;
|
|
690
690
|
if (Array.isArray(e))
|
|
691
|
-
return e.map((t) =>
|
|
691
|
+
return e.map((t) => Ke(t));
|
|
692
692
|
if (typeof e == "object") {
|
|
693
693
|
const t = {};
|
|
694
694
|
for (const [o, r] of Object.entries(e))
|
|
695
695
|
if (r !== null) {
|
|
696
|
-
const n =
|
|
696
|
+
const n = Ke(r);
|
|
697
697
|
if (n !== null && typeof n == "object" && !Array.isArray(n) && Object.keys(n).length === 0)
|
|
698
698
|
continue;
|
|
699
699
|
t[o] = n;
|
|
@@ -702,7 +702,7 @@ function ze(e) {
|
|
|
702
702
|
}
|
|
703
703
|
return e;
|
|
704
704
|
}
|
|
705
|
-
const
|
|
705
|
+
const y = {
|
|
706
706
|
// Task management tools
|
|
707
707
|
ADD_TASKS: "add-tasks",
|
|
708
708
|
COMPLETE_TASKS: "complete-tasks",
|
|
@@ -771,57 +771,61 @@ const g = {
|
|
|
771
771
|
* Affects: find-project-collaborators, find-completed-tasks
|
|
772
772
|
*/
|
|
773
773
|
STRIP_EMAILS: "strip_emails"
|
|
774
|
-
},
|
|
775
|
-
function
|
|
774
|
+
}, Lo = process.env.USE_STRUCTURED_CONTENT === "true" || process.env.NODE_ENV === "test";
|
|
775
|
+
function No({
|
|
776
776
|
textContent: e,
|
|
777
777
|
structuredContent: t,
|
|
778
778
|
contentItems: o
|
|
779
779
|
}) {
|
|
780
|
-
const r =
|
|
781
|
-
return o && i.push(...o), !
|
|
780
|
+
const r = Ke(t), n = {}, i = [];
|
|
781
|
+
return o && i.push(...o), !Lo && t && i.push({
|
|
782
782
|
type: "text",
|
|
783
783
|
text: JSON.stringify(r)
|
|
784
784
|
}), e && i.push({ type: "text", text: e }), i.length > 0 && (n.content = i), t && (n.structuredContent = r), n;
|
|
785
785
|
}
|
|
786
|
-
function
|
|
786
|
+
function Mo(e) {
|
|
787
787
|
return {
|
|
788
788
|
content: [{ type: "text", text: e }],
|
|
789
789
|
isError: !0
|
|
790
790
|
};
|
|
791
791
|
}
|
|
792
|
-
const
|
|
793
|
-
function
|
|
792
|
+
const Fo = /* @__PURE__ */ new Set(["file"]);
|
|
793
|
+
function Ho(e) {
|
|
794
794
|
return !e || typeof e != "object" || Array.isArray(e) ? e : Object.fromEntries(
|
|
795
795
|
Object.entries(e).map(
|
|
796
|
-
([t, o]) =>
|
|
796
|
+
([t, o]) => Fo.has(t) && o !== void 0 ? [t, "[redacted]"] : [t, o]
|
|
797
797
|
)
|
|
798
798
|
);
|
|
799
799
|
}
|
|
800
|
-
function
|
|
800
|
+
function Wo(e) {
|
|
801
801
|
return { ...{
|
|
802
|
-
title: `Todoist: ${
|
|
802
|
+
title: `Todoist: ${Bo(e.name)}`,
|
|
803
803
|
openWorldHint: !1
|
|
804
804
|
}, ...e.annotations };
|
|
805
805
|
}
|
|
806
|
-
function
|
|
806
|
+
function Bo(e) {
|
|
807
807
|
return e.split("-").filter(Boolean).map((t) => `${t.charAt(0).toUpperCase()}${t.slice(1)}`).join(" ");
|
|
808
808
|
}
|
|
809
|
-
function
|
|
809
|
+
function zo(e) {
|
|
810
810
|
return e ? typeof e["ui/resourceUri"] == "string" ? !0 : typeof e.ui == "object" && e.ui !== null : !1;
|
|
811
811
|
}
|
|
812
|
+
function Ko(e) {
|
|
813
|
+
const t = typeof e.ui == "object" && e.ui !== null ? e.ui : void 0, o = t?.resourceUri, r = e["ui/resourceUri"];
|
|
814
|
+
return typeof o == "string" && typeof r != "string" ? { ...e, "ui/resourceUri": o } : typeof r == "string" && typeof o != "string" ? { ...e, ui: { ...t, resourceUri: r } } : e;
|
|
815
|
+
}
|
|
812
816
|
const Yo = [
|
|
813
|
-
|
|
814
|
-
|
|
817
|
+
y.FIND_PROJECT_COLLABORATORS,
|
|
818
|
+
y.FIND_COMPLETED_TASKS
|
|
815
819
|
];
|
|
816
|
-
function
|
|
820
|
+
function Ye(e) {
|
|
817
821
|
if (e == null)
|
|
818
822
|
return e;
|
|
819
823
|
if (Array.isArray(e))
|
|
820
|
-
return e.map((t) =>
|
|
824
|
+
return e.map((t) => Ye(t));
|
|
821
825
|
if (typeof e == "object") {
|
|
822
826
|
const t = {};
|
|
823
827
|
for (const [o, r] of Object.entries(e))
|
|
824
|
-
o !== "email" && (t[o] =
|
|
828
|
+
o !== "email" && (t[o] = Ye(r));
|
|
825
829
|
return t;
|
|
826
830
|
}
|
|
827
831
|
return e;
|
|
@@ -836,38 +840,26 @@ function Go({
|
|
|
836
840
|
client: o,
|
|
837
841
|
features: r = []
|
|
838
842
|
}) {
|
|
839
|
-
const n = r.some((
|
|
843
|
+
const n = r.some((p) => p.name === "strip_emails") && Yo.includes(e.name), i = e.execute, a = s.object(e.parameters), c = e.outputSchema ? s.object(e.outputSchema) : void 0, d = async (p, u) => {
|
|
840
844
|
try {
|
|
841
|
-
let { textContent:
|
|
845
|
+
let { textContent: h, structuredContent: m, contentItems: g } = await yo(
|
|
842
846
|
e.name,
|
|
843
|
-
() => O(() => i(
|
|
847
|
+
() => O(() => i(p, o))
|
|
844
848
|
);
|
|
845
|
-
return n && (
|
|
846
|
-
} catch (
|
|
847
|
-
return console.error(`Error executing tool ${e.name}:`, { args:
|
|
849
|
+
return n && (h && (h = qo(h)), m && (m = Ye(m))), No({ textContent: h, structuredContent: m, contentItems: g });
|
|
850
|
+
} catch (h) {
|
|
851
|
+
return console.error(`Error executing tool ${e.name}:`, { args: Ho(p), error: h }), Mo(no(h));
|
|
848
852
|
}
|
|
849
|
-
},
|
|
853
|
+
}, l = {
|
|
850
854
|
description: e.description,
|
|
851
|
-
inputSchema:
|
|
852
|
-
...
|
|
853
|
-
annotations:
|
|
854
|
-
...e._meta ? { _meta: e._meta } : {}
|
|
855
|
+
inputSchema: a,
|
|
856
|
+
...c ? { outputSchema: c } : {},
|
|
857
|
+
annotations: Wo(e),
|
|
858
|
+
...e._meta ? { _meta: zo(e._meta) ? Ko(e._meta) : e._meta } : {}
|
|
855
859
|
};
|
|
856
|
-
|
|
857
|
-
Rs(
|
|
858
|
-
t,
|
|
859
|
-
e.name,
|
|
860
|
-
{
|
|
861
|
-
...c,
|
|
862
|
-
_meta: e._meta
|
|
863
|
-
},
|
|
864
|
-
a
|
|
865
|
-
);
|
|
866
|
-
return;
|
|
867
|
-
}
|
|
868
|
-
t.registerTool(e.name, c, a);
|
|
860
|
+
t.registerTool(e.name, l, d);
|
|
869
861
|
}
|
|
870
|
-
const Vo = {
|
|
862
|
+
const Vo = s.object({
|
|
871
863
|
period: s.enum(["today", "7d", "14d", "30d", "this-week", "this-month"]).default("7d").describe(
|
|
872
864
|
'Time period for the analysis. "today" analyzes the current day, "7d"/"14d"/"30d" analyze the last N days, "this-week" and "this-month" analyze the current week or month.'
|
|
873
865
|
),
|
|
@@ -875,7 +867,7 @@ const Vo = {
|
|
|
875
867
|
'Focus area for the analysis. "overall" provides a comprehensive report covering all areas. Other values focus on a specific aspect.'
|
|
876
868
|
),
|
|
877
869
|
projectId: s.string().optional().describe("Optional project ID to scope the analysis to a specific project.")
|
|
878
|
-
};
|
|
870
|
+
});
|
|
879
871
|
function Jo(e, t = /* @__PURE__ */ new Date()) {
|
|
880
872
|
const o = (n) => n.toISOString().slice(0, 10), r = o(t);
|
|
881
873
|
switch (e) {
|
|
@@ -1050,7 +1042,7 @@ function er(e) {
|
|
|
1050
1042
|
const t = Math.floor(e / 60), o = e % 60;
|
|
1051
1043
|
return t === 0 ? `${o}m` : o === 0 ? `${t}h` : `${t}h${o}m`;
|
|
1052
1044
|
}
|
|
1053
|
-
const tr = ["p1", "p2", "p3", "p4"],
|
|
1045
|
+
const tr = ["p1", "p2", "p3", "p4"], Ze = 'Task priority as a string: "p1" (highest), "p2" (high), "p3" (medium), or "p4" (lowest/default). Integers like 1, 2, 3, or 4 are not accepted.', Qe = s.enum(tr).describe(Ze);
|
|
1054
1046
|
function Qt(e) {
|
|
1055
1047
|
return { p1: 4, p2: 3, p3: 2, p4: 1 }[e];
|
|
1056
1048
|
}
|
|
@@ -1259,7 +1251,7 @@ async function cr(e, t) {
|
|
|
1259
1251
|
return n;
|
|
1260
1252
|
}
|
|
1261
1253
|
const ss = ["assigned", "unassignedOrMe", "all"];
|
|
1262
|
-
async function
|
|
1254
|
+
async function et(e, t) {
|
|
1263
1255
|
if (!t)
|
|
1264
1256
|
return;
|
|
1265
1257
|
const o = await ar(e, t);
|
|
@@ -1312,13 +1304,13 @@ async function F(e) {
|
|
|
1312
1304
|
} while (i !== null);
|
|
1313
1305
|
return n;
|
|
1314
1306
|
}
|
|
1315
|
-
function
|
|
1307
|
+
function tt(e) {
|
|
1316
1308
|
return /(?<!\\)(?:\\\\)*\*/.test(e) ? e : `*${e.replaceAll(/\\(?!\*)/g, "\\\\")}*`;
|
|
1317
1309
|
}
|
|
1318
1310
|
async function rs(e, t) {
|
|
1319
1311
|
return F({
|
|
1320
1312
|
apiMethod: e.searchProjects.bind(e),
|
|
1321
|
-
args: { query:
|
|
1313
|
+
args: { query: tt(t) },
|
|
1322
1314
|
limit: C.PROJECTS_MAX
|
|
1323
1315
|
});
|
|
1324
1316
|
}
|
|
@@ -1348,7 +1340,7 @@ function ur(e) {
|
|
|
1348
1340
|
async function pr(e, t) {
|
|
1349
1341
|
return F({
|
|
1350
1342
|
apiMethod: e.searchLabels.bind(e),
|
|
1351
|
-
args: { query:
|
|
1343
|
+
args: { query: tt(t) },
|
|
1352
1344
|
limit: C.LABELS_MAX
|
|
1353
1345
|
});
|
|
1354
1346
|
}
|
|
@@ -1360,7 +1352,7 @@ async function hr(e) {
|
|
|
1360
1352
|
});
|
|
1361
1353
|
}
|
|
1362
1354
|
async function mr(e, t, o) {
|
|
1363
|
-
const r =
|
|
1355
|
+
const r = tt(t);
|
|
1364
1356
|
return F({
|
|
1365
1357
|
apiMethod: e.searchSections.bind(e),
|
|
1366
1358
|
args: o ? { query: r, projectId: o } : { query: r },
|
|
@@ -1451,7 +1443,7 @@ const br = se.object({
|
|
|
1451
1443
|
errorTag: se.string()
|
|
1452
1444
|
})
|
|
1453
1445
|
});
|
|
1454
|
-
async function
|
|
1446
|
+
async function st({
|
|
1455
1447
|
client: e,
|
|
1456
1448
|
query: t,
|
|
1457
1449
|
limit: o,
|
|
@@ -1470,7 +1462,7 @@ async function tt({
|
|
|
1470
1462
|
);
|
|
1471
1463
|
}
|
|
1472
1464
|
}
|
|
1473
|
-
function
|
|
1465
|
+
function Tt(e) {
|
|
1474
1466
|
return {
|
|
1475
1467
|
isRecurring: e.isRecurring,
|
|
1476
1468
|
string: e.string,
|
|
@@ -1490,13 +1482,13 @@ function be(e) {
|
|
|
1490
1482
|
return {
|
|
1491
1483
|
...t,
|
|
1492
1484
|
minuteOffset: e.minuteOffset,
|
|
1493
|
-
due: e.due ?
|
|
1485
|
+
due: e.due ? Tt(e.due) : void 0,
|
|
1494
1486
|
isUrgent: e.isUrgent
|
|
1495
1487
|
};
|
|
1496
1488
|
case "absolute":
|
|
1497
1489
|
return {
|
|
1498
1490
|
...t,
|
|
1499
|
-
due:
|
|
1491
|
+
due: Tt(e.due),
|
|
1500
1492
|
isUrgent: e.isUrgent
|
|
1501
1493
|
};
|
|
1502
1494
|
case "location":
|
|
@@ -1523,14 +1515,14 @@ function gr(e) {
|
|
|
1523
1515
|
async function yr(e, t, o) {
|
|
1524
1516
|
const r = await Tr(e, t);
|
|
1525
1517
|
if (r)
|
|
1526
|
-
return
|
|
1518
|
+
return kt(
|
|
1527
1519
|
[...r.uidsToNotify ?? [], r.postedUid],
|
|
1528
1520
|
o
|
|
1529
1521
|
);
|
|
1530
1522
|
if (!t.taskId)
|
|
1531
1523
|
return [];
|
|
1532
1524
|
const n = await e.getTask(t.taskId);
|
|
1533
|
-
return
|
|
1525
|
+
return kt([n.responsibleUid, n.assignedByUid, n.addedByUid], o);
|
|
1534
1526
|
}
|
|
1535
1527
|
async function Tr(e, t) {
|
|
1536
1528
|
let o, r = null;
|
|
@@ -1545,7 +1537,7 @@ async function Tr(e, t) {
|
|
|
1545
1537
|
} while (r);
|
|
1546
1538
|
return o;
|
|
1547
1539
|
}
|
|
1548
|
-
function
|
|
1540
|
+
function kt(e, t) {
|
|
1549
1541
|
const o = /* @__PURE__ */ new Set();
|
|
1550
1542
|
for (const r of e)
|
|
1551
1543
|
r && r !== t && o.add(r);
|
|
@@ -1566,7 +1558,7 @@ const ue = s.enum(Ie).optional().catch(void 0), H = s.object({
|
|
|
1566
1558
|
dueDate: s.string().optional().describe("ISO 8601."),
|
|
1567
1559
|
recurring: s.union([s.boolean(), s.string()]).describe("False when not recurring, otherwise the recurrence string."),
|
|
1568
1560
|
deadlineDate: s.string().optional().describe("ISO 8601."),
|
|
1569
|
-
priority:
|
|
1561
|
+
priority: Qe.describe("p1 is highest, p4 lowest."),
|
|
1570
1562
|
projectId: s.string(),
|
|
1571
1563
|
sectionId: s.string().optional(),
|
|
1572
1564
|
parentId: s.string().optional(),
|
|
@@ -1649,10 +1641,10 @@ const vr = s.object({
|
|
|
1649
1641
|
date: s.string().describe("ISO 8601."),
|
|
1650
1642
|
datetime: s.string().optional().describe("ISO 8601."),
|
|
1651
1643
|
timezone: s.string().optional()
|
|
1652
|
-
}),
|
|
1644
|
+
}), ot = s.object({
|
|
1653
1645
|
id: s.string(),
|
|
1654
1646
|
taskId: s.string(),
|
|
1655
|
-
type: s.enum(
|
|
1647
|
+
type: s.enum(Ns),
|
|
1656
1648
|
minuteOffset: s.number().optional().describe("Minutes before due. Relative reminders only."),
|
|
1657
1649
|
due: jr.optional().describe("Absolute, and sometimes relative, reminders."),
|
|
1658
1650
|
name: s.string().optional().describe("Location name. Location reminders only."),
|
|
@@ -1681,7 +1673,7 @@ const vr = s.object({
|
|
|
1681
1673
|
totalCount: s.number().describe("The total number of comments created."),
|
|
1682
1674
|
addedCommentIds: s.array(s.string()).describe("The IDs of the added comments.")
|
|
1683
1675
|
}, xr = {
|
|
1684
|
-
name:
|
|
1676
|
+
name: y.ADD_COMMENTS,
|
|
1685
1677
|
description: "Add multiple comments to tasks or projects, optionally notifying collaborators. Each comment must specify either taskId or projectId.",
|
|
1686
1678
|
parameters: $r,
|
|
1687
1679
|
outputSchema: Dr,
|
|
@@ -1772,7 +1764,7 @@ const Or = {
|
|
|
1772
1764
|
search: s.string().optional().describe(
|
|
1773
1765
|
"Search for a filter by name (partial and case insensitive match). If omitted, all filters are returned."
|
|
1774
1766
|
)
|
|
1775
|
-
},
|
|
1767
|
+
}, rt = s.object({
|
|
1776
1768
|
id: s.string().describe("The unique ID of the filter."),
|
|
1777
1769
|
name: s.string().describe("The name of the filter."),
|
|
1778
1770
|
query: s.string().describe('The filter query string (e.g. "today & p1", "#Work & overdue").'),
|
|
@@ -1780,10 +1772,10 @@ const Or = {
|
|
|
1780
1772
|
isFavorite: s.boolean().describe("Whether the filter is marked as favorite."),
|
|
1781
1773
|
itemOrder: s.number().describe("The display order of the filter.")
|
|
1782
1774
|
}), Pr = {
|
|
1783
|
-
filters: s.array(
|
|
1775
|
+
filters: s.array(rt).describe("The found filters."),
|
|
1784
1776
|
totalCount: s.number().describe("The total number of filters returned.")
|
|
1785
1777
|
}, _r = {
|
|
1786
|
-
name:
|
|
1778
|
+
name: y.FIND_FILTERS,
|
|
1787
1779
|
description: 'List all personal filters or search for filters by name. Filters are saved custom views that use query syntax to organize tasks (e.g. "today & p1", "#Work & overdue").',
|
|
1788
1780
|
parameters: Or,
|
|
1789
1781
|
outputSchema: Pr,
|
|
@@ -1804,7 +1796,7 @@ const Or = {
|
|
|
1804
1796
|
itemOrder: a.itemOrder
|
|
1805
1797
|
}));
|
|
1806
1798
|
return {
|
|
1807
|
-
textContent:
|
|
1799
|
+
textContent: Ur({ filters: n, search: e.search }),
|
|
1808
1800
|
structuredContent: {
|
|
1809
1801
|
filters: n,
|
|
1810
1802
|
totalCount: n.length
|
|
@@ -1812,13 +1804,13 @@ const Or = {
|
|
|
1812
1804
|
};
|
|
1813
1805
|
}
|
|
1814
1806
|
};
|
|
1815
|
-
function
|
|
1807
|
+
function Ur({
|
|
1816
1808
|
filters: e,
|
|
1817
1809
|
search: t
|
|
1818
1810
|
}) {
|
|
1819
1811
|
const o = t ? `Filters matching "${t}"` : "Filters";
|
|
1820
1812
|
if (e.length === 0) {
|
|
1821
|
-
const n = t ? ["Try broader search terms", "Check spelling", "Remove search to see all filters"] : ["No filters created yet", `Use ${
|
|
1813
|
+
const n = t ? ["Try broader search terms", "Check spelling", "Remove search to see all filters"] : ["No filters created yet", `Use ${y.ADD_FILTERS} to create a filter`];
|
|
1822
1814
|
return `${o}: 0 found
|
|
1823
1815
|
|
|
1824
1816
|
Suggestions:
|
|
@@ -1833,7 +1825,7 @@ ${n.map((i) => `- ${i}`).join(`
|
|
|
1833
1825
|
return r.join(`
|
|
1834
1826
|
`);
|
|
1835
1827
|
}
|
|
1836
|
-
const
|
|
1828
|
+
const Rr = s.object({
|
|
1837
1829
|
name: s.string().min(1).describe("The name of the filter."),
|
|
1838
1830
|
query: s.string().min(1).describe(
|
|
1839
1831
|
'The filter query string. Examples: "today & p1", "#Work & overdue", "@email & today", "(p1 | p2) & !assigned". Operators: | (OR), & (AND), ! (NOT), () grouping, , (multiple queries).'
|
|
@@ -1841,12 +1833,12 @@ const Ur = s.object({
|
|
|
1841
1833
|
color: le,
|
|
1842
1834
|
isFavorite: s.boolean().optional().describe("Whether to mark the filter as a favorite. Defaults to false.")
|
|
1843
1835
|
}), Lr = {
|
|
1844
|
-
filters: s.array(
|
|
1836
|
+
filters: s.array(Rr).min(1).describe("The array of filters to add.")
|
|
1845
1837
|
}, Nr = {
|
|
1846
|
-
filters: s.array(
|
|
1838
|
+
filters: s.array(rt).describe("The created filters."),
|
|
1847
1839
|
totalCount: s.number().describe("The total number of filters created.")
|
|
1848
1840
|
}, Mr = {
|
|
1849
|
-
name:
|
|
1841
|
+
name: y.ADD_FILTERS,
|
|
1850
1842
|
description: "Add one or more new personal filters. Filters are saved custom views using query syntax to organize tasks.",
|
|
1851
1843
|
parameters: Lr,
|
|
1852
1844
|
outputSchema: Nr,
|
|
@@ -1862,11 +1854,11 @@ const Ur = s.object({
|
|
|
1862
1854
|
},
|
|
1863
1855
|
r[h]
|
|
1864
1856
|
)), a = (await t.sync({ commands: n })).tempIdMapping ?? {}, c = e.map((u, h) => {
|
|
1865
|
-
const m = r[h],
|
|
1866
|
-
if (!
|
|
1857
|
+
const m = r[h], g = m !== void 0 ? a[m] : void 0;
|
|
1858
|
+
if (!g) return null;
|
|
1867
1859
|
const f = u.color !== void 0 ? ue.parse(u.color) : void 0;
|
|
1868
1860
|
return {
|
|
1869
|
-
id:
|
|
1861
|
+
id: g,
|
|
1870
1862
|
name: u.name,
|
|
1871
1863
|
query: u.query,
|
|
1872
1864
|
color: f,
|
|
@@ -1895,7 +1887,7 @@ ${l}`,
|
|
|
1895
1887
|
labels: s.array(pe).describe("The created labels."),
|
|
1896
1888
|
totalCount: s.number().describe("The total number of labels created.")
|
|
1897
1889
|
}, Br = {
|
|
1898
|
-
name:
|
|
1890
|
+
name: y.ADD_LABELS,
|
|
1899
1891
|
description: "Add one or more new personal labels.",
|
|
1900
1892
|
parameters: Hr,
|
|
1901
1893
|
outputSchema: Wr,
|
|
@@ -1921,7 +1913,7 @@ function ae(e = /* @__PURE__ */ new Date()) {
|
|
|
1921
1913
|
const t = e.getFullYear(), o = String(e.getMonth() + 1).padStart(2, "0"), r = String(e.getDate()).padStart(2, "0");
|
|
1922
1914
|
return `${t}-${o}-${r}`;
|
|
1923
1915
|
}
|
|
1924
|
-
function
|
|
1916
|
+
function nt(e, t, o = {}) {
|
|
1925
1917
|
const { context: r, showDetails: n = !1 } = o, i = t.length, a = [], d = `${e} ${i} ${i === 1 ? "task" : "tasks"}${r ? ` ${r}` : ""}.`;
|
|
1926
1918
|
a.push(d);
|
|
1927
1919
|
const l = 5;
|
|
@@ -1936,7 +1928,7 @@ ${p}${u}.`);
|
|
|
1936
1928
|
return a.join(`
|
|
1937
1929
|
`);
|
|
1938
1930
|
}
|
|
1939
|
-
function
|
|
1931
|
+
function it(e) {
|
|
1940
1932
|
const { action: t, success: o, total: r, successItems: n, successLabel: i = "Completed", failures: a } = e, c = [], d = `${t}: ${o}/${r} successful.`;
|
|
1941
1933
|
if (c.push(d), n?.length && n.length <= 5 && c.push(`${i}:
|
|
1942
1934
|
${n.map((l) => ` ${l}`).join(`
|
|
@@ -1951,7 +1943,7 @@ ${a.slice(0, fe.MAX_FAILURES_SHOWN).map((u) => ` ${u.item} (Error: ${u.error}
|
|
|
1951
1943
|
return c.join(`
|
|
1952
1944
|
`);
|
|
1953
1945
|
}
|
|
1954
|
-
function
|
|
1946
|
+
function at(e, t) {
|
|
1955
1947
|
if (t.length === 0)
|
|
1956
1948
|
return e;
|
|
1957
1949
|
const o = t.slice(0, fe.MAX_FAILURES_SHOWN), r = t.length - o.length, n = o.map((a) => ` ${a.item}: ${a.error}`).join(`
|
|
@@ -2090,7 +2082,7 @@ const ds = new Jr(), Xr = s.object({
|
|
|
2090
2082
|
successCount: s.number().describe("The number of successfully created projects."),
|
|
2091
2083
|
failureCount: s.number().describe("The number of failed project creations.")
|
|
2092
2084
|
}, en = {
|
|
2093
|
-
name:
|
|
2085
|
+
name: y.ADD_PROJECTS,
|
|
2094
2086
|
description: "Add one or more new projects.",
|
|
2095
2087
|
parameters: Zr,
|
|
2096
2088
|
outputSchema: Qr,
|
|
@@ -2138,9 +2130,9 @@ function tn({
|
|
|
2138
2130
|
const o = e.length, r = e.map((i) => `• ${i.name} (id=${i.id})`).join(`
|
|
2139
2131
|
`), n = o > 0 ? `Added ${o} project${o === 1 ? "" : "s"}:
|
|
2140
2132
|
${r}` : "Added 0 projects";
|
|
2141
|
-
return
|
|
2133
|
+
return at(n, t);
|
|
2142
2134
|
}
|
|
2143
|
-
const we = 25, je = s.enum(
|
|
2135
|
+
const we = 25, je = s.enum(Ms), ls = s.object({
|
|
2144
2136
|
date: s.string().optional().describe("Due date in YYYY-MM-DD format."),
|
|
2145
2137
|
string: s.string().optional().describe('Natural language due string, e.g. "tomorrow at 3pm".'),
|
|
2146
2138
|
timezone: s.string().optional().describe('Timezone for the reminder, e.g. "America/New_York".'),
|
|
@@ -2182,11 +2174,11 @@ const we = 25, je = s.enum(Hs), ls = s.object({
|
|
|
2182
2174
|
`Array of reminders to create (max ${we}). Each reminder must specify a type: "relative" (minutes before due), "absolute" (specific date/time), or "location" (geofence trigger).`
|
|
2183
2175
|
)
|
|
2184
2176
|
}, cn = {
|
|
2185
|
-
reminders: s.array(
|
|
2177
|
+
reminders: s.array(ot).describe("The created reminders."),
|
|
2186
2178
|
totalCount: s.number().describe("Total number of reminders created."),
|
|
2187
2179
|
addedReminderIds: s.array(s.string()).describe("IDs of the created reminders.")
|
|
2188
2180
|
}, dn = {
|
|
2189
|
-
name:
|
|
2181
|
+
name: y.ADD_REMINDERS,
|
|
2190
2182
|
description: 'Add reminders to tasks. Supports three types: "relative" (minutes before due), "absolute" (specific date/time), or "location" (geofence-triggered). Each reminder must specify a taskId.',
|
|
2191
2183
|
parameters: an,
|
|
2192
2184
|
outputSchema: cn,
|
|
@@ -2261,7 +2253,7 @@ const un = s.object({
|
|
|
2261
2253
|
successCount: s.number().describe("The number of successfully created sections."),
|
|
2262
2254
|
failureCount: s.number().describe("The number of failed section creations.")
|
|
2263
2255
|
}, mn = {
|
|
2264
|
-
name:
|
|
2256
|
+
name: y.ADD_SECTIONS,
|
|
2265
2257
|
description: "Add one or more new sections to projects.",
|
|
2266
2258
|
parameters: pn,
|
|
2267
2259
|
outputSchema: hn,
|
|
@@ -2302,7 +2294,7 @@ function fn({
|
|
|
2302
2294
|
const o = e.length, r = e.map((i) => `• ${i.name} (id=${i.id}, projectId=${i.projectId})`).join(`
|
|
2303
2295
|
`), n = o > 0 ? `Added ${o} section${o === 1 ? "" : "s"}:
|
|
2304
2296
|
${r}` : "Added 0 sections";
|
|
2305
|
-
return
|
|
2297
|
+
return at(n, t);
|
|
2306
2298
|
}
|
|
2307
2299
|
const ne = {
|
|
2308
2300
|
USER_NOT_FOUND: "USER_NOT_FOUND",
|
|
@@ -2494,7 +2486,7 @@ class bn {
|
|
|
2494
2486
|
const p = await N.resolveUser(t, r);
|
|
2495
2487
|
if (!p)
|
|
2496
2488
|
return i.push("User not found - check spelling or invite to a shared project"), { canAssign: !1, projectInfo: l, recommendations: i };
|
|
2497
|
-
const u = d.some((
|
|
2489
|
+
const u = d.some((g) => g.id === p.userId), h = {
|
|
2498
2490
|
resolvedName: p.displayName,
|
|
2499
2491
|
isCollaborator: u
|
|
2500
2492
|
};
|
|
@@ -2504,14 +2496,14 @@ class bn {
|
|
|
2504
2496
|
), { canAssign: !1, projectInfo: l, userInfo: h, recommendations: i };
|
|
2505
2497
|
let m;
|
|
2506
2498
|
if (n && n.length > 0) {
|
|
2507
|
-
let
|
|
2499
|
+
let g = 0, f = 0;
|
|
2508
2500
|
for (const v of n)
|
|
2509
2501
|
try {
|
|
2510
|
-
await t.getTask(v),
|
|
2502
|
+
await t.getTask(v), g++;
|
|
2511
2503
|
} catch {
|
|
2512
2504
|
f++;
|
|
2513
2505
|
}
|
|
2514
|
-
m = { accessibleTasks:
|
|
2506
|
+
m = { accessibleTasks: g, inaccessibleTasks: f }, f > 0 && i.push(`${f} task(s) are not accessible`);
|
|
2515
2507
|
}
|
|
2516
2508
|
return a = !0, i.push(`Ready to assign tasks to ${p.displayName}`), {
|
|
2517
2509
|
canAssign: a,
|
|
@@ -2522,42 +2514,42 @@ class bn {
|
|
|
2522
2514
|
};
|
|
2523
2515
|
}
|
|
2524
2516
|
}
|
|
2525
|
-
const
|
|
2526
|
-
function
|
|
2517
|
+
const ct = new bn();
|
|
2518
|
+
function R(e) {
|
|
2527
2519
|
return s.string().transform((t) => t === "" ? void 0 : t).optional().describe(e);
|
|
2528
2520
|
}
|
|
2529
|
-
const
|
|
2521
|
+
const wt = Yt.TASKS_PER_OPERATION, gn = s.object({
|
|
2530
2522
|
content: s.string().min(1).describe(
|
|
2531
2523
|
'The task name/title. Should be concise and actionable (e.g., "Review PR #123", "Call dentist"). For longer content, use the description field instead. Supports Markdown.'
|
|
2532
2524
|
),
|
|
2533
|
-
description:
|
|
2525
|
+
description: R(
|
|
2534
2526
|
"Additional details, notes, or context for the task. Use this for longer content rather than putting it in the task name. Supports Markdown."
|
|
2535
2527
|
),
|
|
2536
|
-
priority:
|
|
2537
|
-
dueString:
|
|
2528
|
+
priority: Qe.optional().describe(Ze),
|
|
2529
|
+
dueString: R(
|
|
2538
2530
|
'The due date for the task, in natural language. Also use natural language for recurrences; do not prefix it with "recurring".'
|
|
2539
2531
|
),
|
|
2540
|
-
deadlineDate:
|
|
2532
|
+
deadlineDate: R(
|
|
2541
2533
|
'The deadline date for the task in ISO 8601 format (YYYY-MM-DD, e.g., "2025-12-31"). Deadlines are immovable constraints shown with a different indicator than due dates.'
|
|
2542
2534
|
),
|
|
2543
|
-
duration:
|
|
2535
|
+
duration: R(
|
|
2544
2536
|
'The duration of the task. Use format: "2h" (hours), "90m" (minutes), "2h30m" (combined), or "1.5h" (decimal hours). Max 24h.'
|
|
2545
2537
|
),
|
|
2546
2538
|
labels: s.array(s.string()).optional().describe("The labels to attach to the task."),
|
|
2547
|
-
projectId:
|
|
2539
|
+
projectId: R(
|
|
2548
2540
|
'The project ID to add this task to. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
2549
2541
|
),
|
|
2550
|
-
sectionId:
|
|
2551
|
-
parentId:
|
|
2542
|
+
sectionId: R("The section ID to add this task to."),
|
|
2543
|
+
parentId: R("The parent task ID (for subtasks)."),
|
|
2552
2544
|
order: s.number().optional().describe("Position of the task among sibling tasks under the same parent/section."),
|
|
2553
|
-
responsibleUser:
|
|
2545
|
+
responsibleUser: R(
|
|
2554
2546
|
'Assign task to this user. Can be "me" (assigns to current user), a user ID, name, or email address. User must be a collaborator on the target project.'
|
|
2555
2547
|
),
|
|
2556
2548
|
isUncompletable: s.boolean().optional().describe(
|
|
2557
2549
|
"Whether this task should be uncompletable (organizational header). Tasks with isUncompletable: true appear as organizational headers and cannot be completed."
|
|
2558
2550
|
)
|
|
2559
|
-
}),
|
|
2560
|
-
tasks: s.array(gn).min(1).max(
|
|
2551
|
+
}), vt = {
|
|
2552
|
+
tasks: s.array(gn).min(1).max(wt).describe(`The array of tasks to add (max ${wt}).`)
|
|
2561
2553
|
}, yn = {
|
|
2562
2554
|
tasks: s.array(H).describe("The created tasks."),
|
|
2563
2555
|
totalCount: s.number().describe("The total number of tasks created."),
|
|
@@ -2566,23 +2558,23 @@ const kt = Yt.TASKS_PER_OPERATION, gn = s.object({
|
|
|
2566
2558
|
successCount: s.number().describe("The number of successfully created tasks."),
|
|
2567
2559
|
failureCount: s.number().describe("The number of failed task creations.")
|
|
2568
2560
|
}, Tn = {
|
|
2569
|
-
name:
|
|
2561
|
+
name: y.ADD_TASKS,
|
|
2570
2562
|
description: "Add one or more tasks to a project, section, or parent. Supports assignment to project collaborators.",
|
|
2571
|
-
parameters:
|
|
2563
|
+
parameters: vt,
|
|
2572
2564
|
outputSchema: yn,
|
|
2573
2565
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
|
|
2574
2566
|
async execute(e, t) {
|
|
2575
|
-
const { tasks: o } = s.object(
|
|
2567
|
+
const { tasks: o } = s.object(vt).parse(e), r = /* @__PURE__ */ new Map();
|
|
2576
2568
|
o.forEach((h, m) => {
|
|
2577
|
-
const
|
|
2578
|
-
f ? f.push({ task: h, index: m }) : r.set(
|
|
2569
|
+
const g = kn(h), f = r.get(g);
|
|
2570
|
+
f ? f.push({ task: h, index: m }) : r.set(g, [{ task: h, index: m }]);
|
|
2579
2571
|
});
|
|
2580
2572
|
const n = /* @__PURE__ */ new Map(), a = (await Promise.all(
|
|
2581
2573
|
[...r.values()].map(async (h) => {
|
|
2582
2574
|
const m = [];
|
|
2583
|
-
for (const { task:
|
|
2575
|
+
for (const { task: g, index: f } of h)
|
|
2584
2576
|
try {
|
|
2585
|
-
const v = await wn(
|
|
2577
|
+
const v = await wn(g, t, n);
|
|
2586
2578
|
m.push({ index: f, result: { status: "fulfilled", value: v } });
|
|
2587
2579
|
} catch (v) {
|
|
2588
2580
|
m.push({
|
|
@@ -2603,7 +2595,7 @@ const kt = Yt.TASKS_PER_OPERATION, gn = s.object({
|
|
|
2603
2595
|
error: z(m.reason)
|
|
2604
2596
|
}));
|
|
2605
2597
|
if (c.length === 0 && d.length > 0) {
|
|
2606
|
-
const h = d.map((
|
|
2598
|
+
const h = d.map((g) => `"${g.item}": ${g.error}`).join("; "), m = `All ${d.length} task(s) failed to create: ${h}`;
|
|
2607
2599
|
throw l ? new Kt(m) : new Error(m);
|
|
2608
2600
|
}
|
|
2609
2601
|
const p = c.map(P);
|
|
@@ -2647,7 +2639,7 @@ async function wn(e, t, o) {
|
|
|
2647
2639
|
`Task "${e.content}": Cannot create task in archived project "${f.name}"`
|
|
2648
2640
|
);
|
|
2649
2641
|
}
|
|
2650
|
-
let
|
|
2642
|
+
let g = {
|
|
2651
2643
|
...h,
|
|
2652
2644
|
projectId: m,
|
|
2653
2645
|
sectionId: i,
|
|
@@ -2656,15 +2648,15 @@ async function wn(e, t, o) {
|
|
|
2656
2648
|
labels: p,
|
|
2657
2649
|
deadlineDate: u
|
|
2658
2650
|
};
|
|
2659
|
-
if (l && (
|
|
2651
|
+
if (l && (g.priority = Qt(l)), d && !m && !i && !a)
|
|
2660
2652
|
throw new Error(
|
|
2661
2653
|
`Task "${e.content}": Cannot assign tasks without specifying project context. Please specify a projectId, sectionId, or parentId.`
|
|
2662
2654
|
);
|
|
2663
2655
|
if (r)
|
|
2664
2656
|
try {
|
|
2665
2657
|
const { minutes: f } = Zt(r);
|
|
2666
|
-
|
|
2667
|
-
...
|
|
2658
|
+
g = {
|
|
2659
|
+
...g,
|
|
2668
2660
|
duration: f,
|
|
2669
2661
|
durationUnit: "minute"
|
|
2670
2662
|
};
|
|
@@ -2689,7 +2681,7 @@ async function wn(e, t, o) {
|
|
|
2689
2681
|
throw new Error(
|
|
2690
2682
|
`Task "${e.content}": Cannot determine target project for assignment validation`
|
|
2691
2683
|
);
|
|
2692
|
-
const v = await
|
|
2684
|
+
const v = await ct.validateTaskCreationAssignment(
|
|
2693
2685
|
t,
|
|
2694
2686
|
f,
|
|
2695
2687
|
d
|
|
@@ -2700,12 +2692,12 @@ async function wn(e, t, o) {
|
|
|
2700
2692
|
`Task "${e.content}": ${j}${A ? `. ${A}` : ""}`
|
|
2701
2693
|
);
|
|
2702
2694
|
}
|
|
2703
|
-
|
|
2695
|
+
g.assigneeId = v.resolvedUser?.userId;
|
|
2704
2696
|
}
|
|
2705
2697
|
try {
|
|
2706
|
-
return await t.addTask(
|
|
2698
|
+
return await t.addTask(g);
|
|
2707
2699
|
} catch (f) {
|
|
2708
|
-
const v =
|
|
2700
|
+
const v = ro(f, {
|
|
2709
2701
|
taskContent: e.content,
|
|
2710
2702
|
dueString: e.dueString,
|
|
2711
2703
|
deadlineDate: e.deadlineDate
|
|
@@ -2726,14 +2718,14 @@ function vn({
|
|
|
2726
2718
|
const i = Array.from(r)[0];
|
|
2727
2719
|
n = i === "inbox" ? "" : `to ${i}`;
|
|
2728
2720
|
} else r.size > 1 && (n = "to multiple contexts");
|
|
2729
|
-
return t.length > 0 ?
|
|
2721
|
+
return t.length > 0 ? it({
|
|
2730
2722
|
action: `Added tasks${n ? ` ${n}` : ""}`,
|
|
2731
2723
|
success: e.length,
|
|
2732
2724
|
total: o.tasks.length,
|
|
2733
2725
|
successItems: e.map((i) => i.content ?? "Untitled"),
|
|
2734
2726
|
successLabel: "Created",
|
|
2735
2727
|
failures: t
|
|
2736
|
-
}) :
|
|
2728
|
+
}) : nt("Added", e, {
|
|
2737
2729
|
context: n,
|
|
2738
2730
|
showDetails: !0
|
|
2739
2731
|
});
|
|
@@ -2745,13 +2737,13 @@ const In = {
|
|
|
2745
2737
|
}, Sn = {
|
|
2746
2738
|
projectId: s.string().describe("The project ID."),
|
|
2747
2739
|
health: s.object({
|
|
2748
|
-
status: s.enum(
|
|
2740
|
+
status: s.enum(Ve).describe("The health status after triggering analysis."),
|
|
2749
2741
|
isStale: s.boolean().describe("Whether the health data is still stale after the request."),
|
|
2750
2742
|
updateInProgress: s.boolean().describe("Whether an analysis update is currently in progress.")
|
|
2751
2743
|
}).describe("The health response returned after triggering analysis."),
|
|
2752
2744
|
message: s.string().describe("A human-readable message about the analysis status.")
|
|
2753
2745
|
}, jn = {
|
|
2754
|
-
name:
|
|
2746
|
+
name: y.ANALYZE_PROJECT_HEALTH,
|
|
2755
2747
|
description: "Trigger a new health analysis for a project. Use this when the health data is stale or you want a fresh assessment. The analysis may take time to complete — use get-project-health afterward to see updated results.",
|
|
2756
2748
|
parameters: In,
|
|
2757
2749
|
outputSchema: Sn,
|
|
@@ -2786,7 +2778,7 @@ ${n}`,
|
|
|
2786
2778
|
successCount: s.number().describe("The number of successfully completed tasks."),
|
|
2787
2779
|
failureCount: s.number().describe("The number of failed task completions.")
|
|
2788
2780
|
}, Dn = {
|
|
2789
|
-
name:
|
|
2781
|
+
name: y.COMPLETE_TASKS,
|
|
2790
2782
|
description: "Complete one or more tasks by their IDs.",
|
|
2791
2783
|
parameters: Cn,
|
|
2792
2784
|
outputSchema: $n,
|
|
@@ -2824,7 +2816,7 @@ function xn({
|
|
|
2824
2816
|
failures: t,
|
|
2825
2817
|
args: o
|
|
2826
2818
|
}) {
|
|
2827
|
-
return
|
|
2819
|
+
return it({
|
|
2828
2820
|
action: "Completed tasks",
|
|
2829
2821
|
success: e.length,
|
|
2830
2822
|
total: o.ids.length,
|
|
@@ -2851,7 +2843,7 @@ const ps = [
|
|
|
2851
2843
|
}).describe("Information about the deleted entity."),
|
|
2852
2844
|
success: s.boolean().describe("Whether the deletion was successful.")
|
|
2853
2845
|
}, On = {
|
|
2854
|
-
name:
|
|
2846
|
+
name: y.DELETE_OBJECT,
|
|
2855
2847
|
description: "Delete a project, section, task, comment, label, filter, reminder, or location_reminder by its ID. Projects can be deleted whether active or archived (find archived ones via find-projects with archivedStatus); note a workspace project must be archived before it can be deleted, while personal projects can be deleted regardless.",
|
|
2856
2848
|
parameters: An,
|
|
2857
2849
|
outputSchema: En,
|
|
@@ -2899,7 +2891,7 @@ const ps = [
|
|
|
2899
2891
|
}
|
|
2900
2892
|
};
|
|
2901
2893
|
}
|
|
2902
|
-
},
|
|
2894
|
+
}, It = 5, hs = ["file", "url"], Pn = {
|
|
2903
2895
|
projectId: s.string().min(1).describe("The ID of the project to export as a template."),
|
|
2904
2896
|
format: s.enum(hs).default("file").describe(
|
|
2905
2897
|
'How to return the template. "file" returns the CSV content, which can be passed straight back to import-project-template. "url" returns a shareable download link instead, and is the better choice for large projects because it does not return the whole file.'
|
|
@@ -2913,8 +2905,8 @@ const ps = [
|
|
|
2913
2905
|
lineCount: s.number().optional().describe('Number of rows in the exported CSV. Only present when format is "file".'),
|
|
2914
2906
|
fileName: s.string().optional().describe('The generated template file name. Only present when format is "url".'),
|
|
2915
2907
|
fileUrl: s.string().optional().describe('The shareable download URL. Only present when format is "url".')
|
|
2916
|
-
},
|
|
2917
|
-
name:
|
|
2908
|
+
}, Un = {
|
|
2909
|
+
name: y.EXPORT_PROJECT_TEMPLATE,
|
|
2918
2910
|
description: "Export an existing project as a Todoist template, either as CSV content or as a shareable URL. Use it to duplicate a project, share its structure, or hand the CSV to import-project-template. To read a project rather than export it, use find-tasks instead — it returns structured tasks rather than raw CSV. Nothing is modified.",
|
|
2919
2911
|
parameters: Pn,
|
|
2920
2912
|
outputSchema: _n,
|
|
@@ -2938,14 +2930,14 @@ ${c}`,
|
|
|
2938
2930
|
return {
|
|
2939
2931
|
// The full CSV already ships in structuredContent; a preview here keeps a large
|
|
2940
2932
|
// project from being spelled out twice in the response.
|
|
2941
|
-
textContent:
|
|
2933
|
+
textContent: Rn({ projectId: e, lines: i }),
|
|
2942
2934
|
structuredContent: { format: t, content: n, lineCount: i.length }
|
|
2943
2935
|
};
|
|
2944
2936
|
}
|
|
2945
2937
|
};
|
|
2946
|
-
function
|
|
2947
|
-
const o = `Exported project (id=${e}) as a template file (${t.length} row${t.length === 1 ? "" : "s"}).`, r = t.slice(0,
|
|
2948
|
-
`), n = t.length -
|
|
2938
|
+
function Rn({ projectId: e, lines: t }) {
|
|
2939
|
+
const o = `Exported project (id=${e}) as a template file (${t.length} row${t.length === 1 ? "" : "s"}).`, r = t.slice(0, It).join(`
|
|
2940
|
+
`), n = t.length - It;
|
|
2949
2941
|
return n > 0 ? `${o}
|
|
2950
2942
|
|
|
2951
2943
|
${r}
|
|
@@ -3023,14 +3015,14 @@ async function Hn(e, t) {
|
|
|
3023
3015
|
hasMoreChildren: n.length > i.length ? !0 : void 0
|
|
3024
3016
|
};
|
|
3025
3017
|
}
|
|
3026
|
-
async function
|
|
3018
|
+
async function St(e) {
|
|
3027
3019
|
try {
|
|
3028
3020
|
return await e();
|
|
3029
3021
|
} catch (t) {
|
|
3030
3022
|
return { childrenError: t instanceof Error ? t.message : String(t) };
|
|
3031
3023
|
}
|
|
3032
3024
|
}
|
|
3033
|
-
function
|
|
3025
|
+
function jt(e, t) {
|
|
3034
3026
|
if (t.childCount === void 0)
|
|
3035
3027
|
return t.childrenError ? ` • ${e}=unavailable` : "";
|
|
3036
3028
|
const o = t.hasMoreChildren ? "+" : "", r = t.childrenError ? " (partial)" : "";
|
|
@@ -3048,7 +3040,7 @@ const ms = ["task", "project", "comment", "section"], Wn = {
|
|
|
3048
3040
|
object: s.union([H, Q, ye, X]).describe("The fetched object data."),
|
|
3049
3041
|
...Mn
|
|
3050
3042
|
}, zn = {
|
|
3051
|
-
name:
|
|
3043
|
+
name: y.FETCH_OBJECT,
|
|
3052
3044
|
description: "Fetch a single task, project, comment, or section by its ID. Use this when you have a specific object ID and want to retrieve its full details. Set includeChildren to also get its direct subtasks or sub-projects.",
|
|
3053
3045
|
parameters: Wn,
|
|
3054
3046
|
outputSchema: Bn,
|
|
@@ -3060,10 +3052,10 @@ const ms = ["task", "project", "comment", "section"], Wn = {
|
|
|
3060
3052
|
case "task": {
|
|
3061
3053
|
const [i, a] = await Promise.all([
|
|
3062
3054
|
t.getTask(r),
|
|
3063
|
-
n ?
|
|
3055
|
+
n ? St(() => Fn(t, r)) : Promise.resolve({})
|
|
3064
3056
|
]), c = P(i);
|
|
3065
3057
|
return {
|
|
3066
|
-
textContent: `Found task: ${c.content} • id=${c.id} • priority=${c.priority} • project=${c.projectId}${
|
|
3058
|
+
textContent: `Found task: ${c.content} • id=${c.id} • priority=${c.priority} • project=${c.projectId}${jt("subtasks", a)}`,
|
|
3067
3059
|
structuredContent: {
|
|
3068
3060
|
type: o,
|
|
3069
3061
|
id: r,
|
|
@@ -3073,9 +3065,9 @@ const ms = ["task", "project", "comment", "section"], Wn = {
|
|
|
3073
3065
|
};
|
|
3074
3066
|
}
|
|
3075
3067
|
case "project": {
|
|
3076
|
-
const i = await t.getProject(r), a = Z(i), c = n ? await
|
|
3068
|
+
const i = await t.getProject(r), a = Z(i), c = n ? await St(() => Hn(t, i)) : {};
|
|
3077
3069
|
return {
|
|
3078
|
-
textContent: `Found project: ${a.name} • id=${a.id} • color=${a.color} • viewStyle=${a.viewStyle}${
|
|
3070
|
+
textContent: `Found project: ${a.name} • id=${a.id} • color=${a.color} • viewStyle=${a.viewStyle}${jt("subProjects", c)}`,
|
|
3079
3071
|
structuredContent: {
|
|
3080
3072
|
type: o,
|
|
3081
3073
|
id: r,
|
|
@@ -3127,7 +3119,7 @@ const ms = ["task", "project", "comment", "section"], Wn = {
|
|
|
3127
3119
|
url: s.string().describe("The URL of the document."),
|
|
3128
3120
|
metadata: s.record(s.string(), s.unknown()).optional().describe("Additional metadata about the document.")
|
|
3129
3121
|
}, qn = {
|
|
3130
|
-
name:
|
|
3122
|
+
name: y.FETCH,
|
|
3131
3123
|
description: 'Fetch the full contents of a task or project by its ID. The ID should be in the format "task:{id}" or "project:{id}".',
|
|
3132
3124
|
parameters: Kn,
|
|
3133
3125
|
outputSchema: Yn,
|
|
@@ -3191,8 +3183,8 @@ Favorite: Yes`), i = {
|
|
|
3191
3183
|
};
|
|
3192
3184
|
}
|
|
3193
3185
|
}, Gn = s.union([s.iso.date(), s.iso.datetime({ offset: !0 })]);
|
|
3194
|
-
function
|
|
3195
|
-
return
|
|
3186
|
+
function Ct(e) {
|
|
3187
|
+
return R(e).pipe(Gn.optional());
|
|
3196
3188
|
}
|
|
3197
3189
|
const Vn = {
|
|
3198
3190
|
objectType: s.enum(["task", "project", "comment"]).optional().describe("Type of object to filter by."),
|
|
@@ -3213,10 +3205,10 @@ const Vn = {
|
|
|
3213
3205
|
initiatorId: s.string().optional().describe(
|
|
3214
3206
|
'Filter by the user ID who initiated the event. A first-person question ("what did I complete") needs this: without it the results cover every collaborator. Get the ID from user-info when you do not already have it.'
|
|
3215
3207
|
),
|
|
3216
|
-
dateFrom:
|
|
3208
|
+
dateFrom: Ct(
|
|
3217
3209
|
`Inclusive start of the activity range, as an ISO 8601 date or date-time. For all events on one local calendar day, use that day's start, for example "2026-08-02T00:00:00-04:00". Natural-language dates such as "tomorrow" are not supported.`
|
|
3218
3210
|
),
|
|
3219
|
-
dateTo:
|
|
3211
|
+
dateTo: Ct(
|
|
3220
3212
|
'Exclusive end of the activity range, as an ISO 8601 date or date-time. For all events on 2026-08-02, use "2026-08-03T00:00:00-04:00". Natural-language dates such as "tomorrow" are not supported.'
|
|
3221
3213
|
),
|
|
3222
3214
|
limit: s.number().int().min(1).max(C.ACTIVITY_MAX).default(C.ACTIVITY_DEFAULT).describe("Maximum number of activity events to return."),
|
|
@@ -3228,7 +3220,7 @@ const Vn = {
|
|
|
3228
3220
|
hasMore: s.boolean(),
|
|
3229
3221
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3230
3222
|
}, Xn = {
|
|
3231
|
-
name:
|
|
3223
|
+
name: y.FIND_ACTIVITY,
|
|
3232
3224
|
description: `Retrieve activity logs to monitor and audit changes in Todoist. Shows events from all users by default (use initiatorId to filter by specific user). To answer what someone completed in a period, including recurring task occurrences, use objectType "task", eventType "completed", and dateFrom/dateTo. For a first-person question ("what did I get done"), also set initiatorId to the current user from user-info, or the answer includes collaborators' completions. Track task completions, updates, deletions, project changes, and more with flexible filtering. Activity history availability and retention depend on the user plan.`,
|
|
3233
3225
|
parameters: Vn,
|
|
3234
3226
|
outputSchema: Jn,
|
|
@@ -3250,14 +3242,14 @@ const Vn = {
|
|
|
3250
3242
|
cursor: u ?? null
|
|
3251
3243
|
};
|
|
3252
3244
|
o && n ? h.objectEventTypes = `${o}:${n}` : o ? h.objectEventTypes = `${o}:` : n && (h.objectEventTypes = `:${n}`), r && r !== "remove" && (h.objectId = r), i && (h.parentProjectId = i), a && (h.parentItemId = a), c && (h.initiatorId = c), d && (h.dateFrom = d), l && (h.dateTo = l);
|
|
3253
|
-
const { results: m, nextCursor:
|
|
3245
|
+
const { results: m, nextCursor: g } = await t.getActivityLogs(h), f = m.map(fr);
|
|
3254
3246
|
return {
|
|
3255
|
-
textContent: Zn({ events: f, args: e, nextCursor:
|
|
3247
|
+
textContent: Zn({ events: f, args: e, nextCursor: g }),
|
|
3256
3248
|
structuredContent: {
|
|
3257
3249
|
events: f,
|
|
3258
|
-
nextCursor:
|
|
3250
|
+
nextCursor: g ?? void 0,
|
|
3259
3251
|
totalCount: f.length,
|
|
3260
|
-
hasMore: !!
|
|
3252
|
+
hasMore: !!g,
|
|
3261
3253
|
appliedFilters: e
|
|
3262
3254
|
}
|
|
3263
3255
|
};
|
|
@@ -3339,7 +3331,7 @@ const si = {
|
|
|
3339
3331
|
nextCursor: s.string().optional(),
|
|
3340
3332
|
totalCount: s.number().describe("The total number of comments in this page.")
|
|
3341
3333
|
}, ri = {
|
|
3342
|
-
name:
|
|
3334
|
+
name: y.FIND_COMMENTS,
|
|
3343
3335
|
description: "Find comments by task, project, or get a specific comment by ID. Exactly one of taskId, projectId, or commentId must be provided.",
|
|
3344
3336
|
parameters: si,
|
|
3345
3337
|
outputSchema: oi,
|
|
@@ -3436,20 +3428,20 @@ function ai(e, t) {
|
|
|
3436
3428
|
const o = new Date(e.getTime() + t * 60 * 1e3);
|
|
3437
3429
|
return fs(o);
|
|
3438
3430
|
}
|
|
3439
|
-
function
|
|
3431
|
+
function $t(e, t) {
|
|
3440
3432
|
const [o, r, n] = e.split("-"), i = Number(o), a = Number(r), c = Number(n);
|
|
3441
3433
|
if (!Number.isFinite(i) || !Number.isFinite(a) || !Number.isFinite(c))
|
|
3442
3434
|
throw new Error(`Invalid date format: ${e}. Expected YYYY-MM-DD.`);
|
|
3443
3435
|
const d = new Date(Date.UTC(i, a - 1, c));
|
|
3444
3436
|
return d.setUTCDate(d.getUTCDate() + t), fs(d);
|
|
3445
3437
|
}
|
|
3446
|
-
const ci = ["and", "or"],
|
|
3438
|
+
const ci = ["and", "or"], dt = {
|
|
3447
3439
|
labels: s.string().array().optional().describe("The labels to filter the tasks by"),
|
|
3448
3440
|
labelsOperator: s.enum(ci).optional().describe(
|
|
3449
3441
|
'The operator to use when filtering by labels. This will dictate whether a task has all labels, or some of them. Default is "or".'
|
|
3450
3442
|
)
|
|
3451
3443
|
};
|
|
3452
|
-
function
|
|
3444
|
+
function lt(e = [], t = "or") {
|
|
3453
3445
|
if (e.length === 0) return "";
|
|
3454
3446
|
const o = t === "and" ? " & " : " | ";
|
|
3455
3447
|
return `(${e.map((i) => i.startsWith("@") ? i : `@${i}`).join(` ${o} `)})`;
|
|
@@ -3461,9 +3453,9 @@ function li({
|
|
|
3461
3453
|
userGmtOffset: o,
|
|
3462
3454
|
now: r = /* @__PURE__ */ new Date()
|
|
3463
3455
|
}) {
|
|
3464
|
-
const n = ii(o), i = ai(r, n), a = di - 1, c = t ?? (e ?
|
|
3456
|
+
const n = ii(o), i = ai(r, n), a = di - 1, c = t ?? (e ? $t(e, a) : i);
|
|
3465
3457
|
return {
|
|
3466
|
-
since: e ??
|
|
3458
|
+
since: e ?? $t(c, -a),
|
|
3467
3459
|
until: c
|
|
3468
3460
|
};
|
|
3469
3461
|
}
|
|
@@ -3490,7 +3482,7 @@ const ui = {
|
|
|
3490
3482
|
cursor: s.string().optional().describe(
|
|
3491
3483
|
"The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters)."
|
|
3492
3484
|
),
|
|
3493
|
-
...
|
|
3485
|
+
...dt
|
|
3494
3486
|
}, pi = {
|
|
3495
3487
|
tasks: s.array(H).describe("The found completed tasks."),
|
|
3496
3488
|
nextCursor: s.string().optional(),
|
|
@@ -3498,7 +3490,7 @@ const ui = {
|
|
|
3498
3490
|
hasMore: s.boolean(),
|
|
3499
3491
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3500
3492
|
}, hi = {
|
|
3501
|
-
name:
|
|
3493
|
+
name: y.FIND_COMPLETED_TASKS,
|
|
3502
3494
|
description: 'Get completed tasks in a date range. For "what did I complete/get done" questions, use find-activity instead — it reports completion events, including every occurrence of a recurring task, which this tool does not. since/until are optional and default to a 7-day window when omitted. Includes all collaborators by default. Person-specific queries (summaries, plans, reports) require responsibleUser.',
|
|
3503
3495
|
parameters: ui,
|
|
3504
3496
|
outputSchema: pi,
|
|
@@ -3509,12 +3501,12 @@ const ui = {
|
|
|
3509
3501
|
throw new Error(
|
|
3510
3502
|
"Cursor pagination requires explicit since and until. Reuse structuredContent.appliedFilters.since and structuredContent.appliedFilters.until from the previous page."
|
|
3511
3503
|
);
|
|
3512
|
-
const p = await
|
|
3513
|
-
let m =
|
|
3504
|
+
const p = await et(t, c), u = p?.email;
|
|
3505
|
+
let m = lt(r, n);
|
|
3514
3506
|
p && u && (m = ce(m, `assigned to: ${u}`));
|
|
3515
|
-
const
|
|
3507
|
+
const g = await t.getUser(), f = g.tzInfo?.gmtString || "+00:00", v = await de({
|
|
3516
3508
|
projectId: d,
|
|
3517
|
-
user:
|
|
3509
|
+
user: g
|
|
3518
3510
|
}), j = li({
|
|
3519
3511
|
since: i,
|
|
3520
3512
|
until: a,
|
|
@@ -3597,7 +3589,7 @@ const fi = {
|
|
|
3597
3589
|
),
|
|
3598
3590
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3599
3591
|
}, gi = {
|
|
3600
|
-
name:
|
|
3592
|
+
name: y.FIND_LABELS,
|
|
3601
3593
|
description: "List personal labels and shared labels. Personal labels have full metadata (id, name, color, order, isFavorite) and support pagination and name search (partial, case insensitive). Shared labels are labels used on tasks shared with you — they are returned as names only (no IDs or metadata). When searching, all matching personal labels are fetched across all pages and returned as a single result set (limit and cursor are ignored). When not searching, personal labels are returned with pagination.",
|
|
3602
3594
|
parameters: fi,
|
|
3603
3595
|
outputSchema: bi,
|
|
@@ -3648,7 +3640,7 @@ No shared labels.`;
|
|
|
3648
3640
|
zeroReasonHints: u
|
|
3649
3641
|
}) + h;
|
|
3650
3642
|
}
|
|
3651
|
-
const { FIND_PROJECTS: bs, ADD_TASKS: gs, UPDATE_TASKS: ys } =
|
|
3643
|
+
const { FIND_PROJECTS: bs, ADD_TASKS: gs, UPDATE_TASKS: ys } = y, Ti = {
|
|
3652
3644
|
projectId: s.string().min(1).optional().describe(
|
|
3653
3645
|
'Optional. If provided, searches only collaborators of this project. If omitted, searches across the collaborators of all shared projects the authenticated user can access (plus the authenticated user themselves) — use this for general "find a user" / "who is X" lookups.'
|
|
3654
3646
|
),
|
|
@@ -3666,7 +3658,7 @@ const { FIND_PROJECTS: bs, ADD_TASKS: gs, UPDATE_TASKS: ys } = g, Ti = {
|
|
|
3666
3658
|
totalAvailable: s.number().optional().describe("The total number of available users before the search filter was applied."),
|
|
3667
3659
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3668
3660
|
}, wi = {
|
|
3669
|
-
name:
|
|
3661
|
+
name: y.FIND_PROJECT_COLLABORATORS,
|
|
3670
3662
|
description: `Find Todoist users (collaborators, teammates) by name or email to look up their user ID. Use this whenever the user asks to find, look up, or identify a person — e.g. "find Carrie's user ID", "who is Ernesto", "look up a user". When projectId is omitted, searches across the collaborators of every shared project the authenticated user has access to, plus the authenticated user themselves — an empty result means the person is not a collaborator on any project you share with them, not necessarily that they do not exist in Todoist. When projectId is provided, searches only that project. Partial, case-insensitive match on name and email.`,
|
|
3671
3663
|
parameters: Ti,
|
|
3672
3664
|
outputSchema: ki,
|
|
@@ -3828,7 +3820,7 @@ function ks({
|
|
|
3828
3820
|
nextSteps: p
|
|
3829
3821
|
});
|
|
3830
3822
|
}
|
|
3831
|
-
const { ADD_PROJECTS:
|
|
3823
|
+
const { ADD_PROJECTS: Dt } = y, Si = {
|
|
3832
3824
|
active: "projects",
|
|
3833
3825
|
archived: "archived projects",
|
|
3834
3826
|
all: "projects (active and archived)"
|
|
@@ -3850,7 +3842,7 @@ const { ADD_PROJECTS: $t } = g, Si = {
|
|
|
3850
3842
|
hasMore: s.boolean(),
|
|
3851
3843
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3852
3844
|
}, $i = {
|
|
3853
|
-
name:
|
|
3845
|
+
name: y.FIND_PROJECTS,
|
|
3854
3846
|
description: "List all projects or search for projects by name. By default only active projects are returned; use archivedStatus ('archived' or 'all') to include archived projects. When searching or when archivedStatus is 'all', all matching projects are returned (pagination is ignored). Otherwise projects are returned with pagination.",
|
|
3855
3847
|
parameters: ji,
|
|
3856
3848
|
outputSchema: Ci,
|
|
@@ -3894,7 +3886,7 @@ function Di({
|
|
|
3894
3886
|
const a = 10, d = e.slice(0, a).map(qr).join(`
|
|
3895
3887
|
`), l = e.length - a, p = l > 0 ? `${d}
|
|
3896
3888
|
…and ${l} more` : d, u = [];
|
|
3897
|
-
return e.length === 0 && (t.searchText ? (u.push("Try broader search terms"), u.push("Check spelling"), u.push("Remove searchText to see all projects")) : t.archivedStatus === "archived" ? (u.push("No archived projects"), u.push("Use archivedStatus: 'all' to also see active projects")) : t.archivedStatus === "all" ? (u.push("No projects created yet"), u.push(`Use ${
|
|
3889
|
+
return e.length === 0 && (t.searchText ? (u.push("Try broader search terms"), u.push("Check spelling"), u.push("Remove searchText to see all projects")) : t.archivedStatus === "archived" ? (u.push("No archived projects"), u.push("Use archivedStatus: 'all' to also see active projects")) : t.archivedStatus === "all" ? (u.push("No projects created yet"), u.push(`Use ${Dt} to create a project`)) : (u.push("No active projects"), u.push("Use archivedStatus: 'all' to include archived projects"), u.push(`Use ${Dt} to create a project`))), Y({
|
|
3898
3890
|
subject: n,
|
|
3899
3891
|
count: e.length,
|
|
3900
3892
|
limit: t.searchText || t.archivedStatus === "all" ? void 0 : t.limit,
|
|
@@ -3911,12 +3903,12 @@ const xi = {
|
|
|
3911
3903
|
reminderId: s.string().optional().describe("Get a specific time-based reminder (relative or absolute) by its ID."),
|
|
3912
3904
|
locationReminderId: s.string().optional().describe("Get a specific location reminder by its ID.")
|
|
3913
3905
|
}, Ai = {
|
|
3914
|
-
reminders: s.array(
|
|
3906
|
+
reminders: s.array(ot).describe("The found reminders (time-based and location)."),
|
|
3915
3907
|
searchType: s.string().describe('The search type used: "task", "reminder", or "location_reminder".'),
|
|
3916
3908
|
searchId: s.string().describe("The ID used for the search."),
|
|
3917
3909
|
totalCount: s.number().describe("Total reminders in this response.")
|
|
3918
3910
|
}, Ei = {
|
|
3919
|
-
name:
|
|
3911
|
+
name: y.FIND_REMINDERS,
|
|
3920
3912
|
description: "Find reminders by task ID (returns all reminder types), or get a specific reminder by its ID. Use reminderId for time-based reminders and locationReminderId for location reminders.",
|
|
3921
3913
|
parameters: xi,
|
|
3922
3914
|
outputSchema: Ai,
|
|
@@ -3991,22 +3983,22 @@ function Oi(e, t) {
|
|
|
3991
3983
|
}
|
|
3992
3984
|
return `Found ${n.join(" and ")} for task ${t}`;
|
|
3993
3985
|
}
|
|
3994
|
-
const { ADD_SECTIONS: Pi } =
|
|
3986
|
+
const { ADD_SECTIONS: Pi } = y, _i = {
|
|
3995
3987
|
projectId: s.string().min(1).describe(
|
|
3996
3988
|
'The ID of the project to search sections in. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
3997
3989
|
),
|
|
3998
3990
|
searchText: s.string().optional().describe(
|
|
3999
3991
|
'Search for a section by name (partial and case insensitive match). Supports wildcards (e.g. "work*" for prefix match). Use "\\*" for a literal asterisk. If omitted, all sections in the project are returned.'
|
|
4000
3992
|
)
|
|
4001
|
-
},
|
|
3993
|
+
}, Ui = {
|
|
4002
3994
|
sections: s.array(X).describe("The found sections."),
|
|
4003
3995
|
totalCount: s.number().describe("The total number of sections found."),
|
|
4004
3996
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
4005
|
-
},
|
|
4006
|
-
name:
|
|
3997
|
+
}, Ri = {
|
|
3998
|
+
name: y.FIND_SECTIONS,
|
|
4007
3999
|
description: "Search for sections by name or other criteria in a project. When searching, uses server-side search to avoid fetching all sections.",
|
|
4008
4000
|
parameters: _i,
|
|
4009
|
-
outputSchema:
|
|
4001
|
+
outputSchema: Ui,
|
|
4010
4002
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
4011
4003
|
async execute(e, t) {
|
|
4012
4004
|
const o = await de({
|
|
@@ -4071,7 +4063,7 @@ const Ni = {
|
|
|
4071
4063
|
responsibleUserFiltering: s.enum(ss).optional().describe(
|
|
4072
4064
|
"Filter when responsibleUser is omitted. 'assigned'=assigned to others; 'unassignedOrMe'=unassigned+mine; 'all'=everyone. Default: 'unassignedOrMe'."
|
|
4073
4065
|
),
|
|
4074
|
-
...
|
|
4066
|
+
...dt
|
|
4075
4067
|
}, Mi = {
|
|
4076
4068
|
tasks: s.array(H).describe("The found tasks."),
|
|
4077
4069
|
nextCursor: s.string().optional(),
|
|
@@ -4079,7 +4071,7 @@ const Ni = {
|
|
|
4079
4071
|
hasMore: s.boolean(),
|
|
4080
4072
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
4081
4073
|
}, Fi = {
|
|
4082
|
-
name:
|
|
4074
|
+
name: y.FIND_TASKS_BY_DATE,
|
|
4083
4075
|
description: "Get tasks by date range. startDate='today' includes overdue items. Default responsibleUserFiltering='unassignedOrMe' excludes others' tasks. Person-specific queries (summaries, plans, reports) require responsibleUser.",
|
|
4084
4076
|
parameters: Ni,
|
|
4085
4077
|
outputSchema: Mi,
|
|
@@ -4089,21 +4081,21 @@ const Ni = {
|
|
|
4089
4081
|
throw new Error(
|
|
4090
4082
|
"Either startDate must be provided or overdueOption must be set to overdue-only"
|
|
4091
4083
|
);
|
|
4092
|
-
const o = await
|
|
4084
|
+
const o = await et(t, e.responsibleUser), r = o?.userId, n = o?.email;
|
|
4093
4085
|
let i = "";
|
|
4094
4086
|
if (e.overdueOption === "overdue-only")
|
|
4095
4087
|
i = "overdue";
|
|
4096
4088
|
else if (e.startDate === "today")
|
|
4097
4089
|
if (e.daysCount > 1) {
|
|
4098
|
-
const u = /* @__PURE__ */ new Date(), h = ae(u), m =
|
|
4090
|
+
const u = /* @__PURE__ */ new Date(), h = ae(u), m = Le(u, e.daysCount), g = ut(m, { representation: "date" }), f = `(due after: ${h} | due: ${h}) & due before: ${g}`;
|
|
4099
4091
|
i = e.overdueOption === "exclude-overdue" ? f : `(${f} | overdue)`;
|
|
4100
4092
|
} else
|
|
4101
4093
|
i = e.overdueOption === "exclude-overdue" ? "today" : "(today | overdue)";
|
|
4102
4094
|
else if (e.startDate) {
|
|
4103
|
-
const u = e.startDate, h =
|
|
4095
|
+
const u = e.startDate, h = Le(ws(u), e.daysCount), m = ut(h, { representation: "date" });
|
|
4104
4096
|
i = `(due after: ${u} | due: ${u}) & due before: ${m}`;
|
|
4105
4097
|
}
|
|
4106
|
-
const a =
|
|
4098
|
+
const a = lt(e.labels, e.labelsOperator);
|
|
4107
4099
|
a.length > 0 && (i = ce(i, `(${a})`));
|
|
4108
4100
|
const c = os({
|
|
4109
4101
|
resolvedAssigneeId: r,
|
|
@@ -4111,7 +4103,7 @@ const Ni = {
|
|
|
4111
4103
|
responsibleUserFiltering: e.responsibleUserFiltering
|
|
4112
4104
|
});
|
|
4113
4105
|
i = ce(i, c);
|
|
4114
|
-
const { tasks: d, nextCursor: l } = await
|
|
4106
|
+
const { tasks: d, nextCursor: l } = await st({
|
|
4115
4107
|
client: t,
|
|
4116
4108
|
query: i,
|
|
4117
4109
|
cursor: e.cursor,
|
|
@@ -4144,7 +4136,7 @@ function Hi({
|
|
|
4144
4136
|
`today${c}${t.daysCount > 1 ? ` + ${t.daysCount - 1} more days` : ""}`
|
|
4145
4137
|
);
|
|
4146
4138
|
} else if (t.startDate) {
|
|
4147
|
-
const c = t.daysCount > 1 ? ` to ${ae(
|
|
4139
|
+
const c = t.daysCount > 1 ? ` to ${ae(Le(ws(t.startDate), t.daysCount))}` : "";
|
|
4148
4140
|
n.push(`${t.startDate}${c}`);
|
|
4149
4141
|
}
|
|
4150
4142
|
if (t.labels && t.labels.length > 0) {
|
|
@@ -4242,7 +4234,7 @@ ${p}` + (d.length > 5 ? `
|
|
|
4242
4234
|
this.cache = null;
|
|
4243
4235
|
}
|
|
4244
4236
|
}
|
|
4245
|
-
const zi = new Bi(), { FIND_COMPLETED_TASKS:
|
|
4237
|
+
const zi = new Bi(), { FIND_COMPLETED_TASKS: xt, ADD_TASKS: At } = y, Ki = {
|
|
4246
4238
|
searchText: s.string().optional().describe("The text to search for in tasks."),
|
|
4247
4239
|
projectId: s.string().optional().describe(
|
|
4248
4240
|
'Find tasks in this project. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
@@ -4263,7 +4255,7 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4263
4255
|
filterIdOrName: s.string().optional().describe(
|
|
4264
4256
|
"The ID or name of a saved Todoist filter. The filter's query will be fetched and used to find tasks. Cannot be used with the `filter` parameter, projectId, sectionId, or parentId."
|
|
4265
4257
|
),
|
|
4266
|
-
...
|
|
4258
|
+
...dt
|
|
4267
4259
|
}, Yi = {
|
|
4268
4260
|
tasks: s.array(H).describe("The found tasks."),
|
|
4269
4261
|
nextCursor: s.string().optional(),
|
|
@@ -4271,7 +4263,7 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4271
4263
|
hasMore: s.boolean(),
|
|
4272
4264
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
4273
4265
|
}, qi = {
|
|
4274
|
-
name:
|
|
4266
|
+
name: y.FIND_TASKS,
|
|
4275
4267
|
description: "Find tasks by text search, project/section/parent container, responsible user, labels, a raw Todoist filter string, or a saved filter by ID or name (filterIdOrName). At least one filter must be provided.",
|
|
4276
4268
|
parameters: Ki,
|
|
4277
4269
|
outputSchema: Yi,
|
|
@@ -4290,7 +4282,7 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4290
4282
|
labelsOperator: u,
|
|
4291
4283
|
filter: h,
|
|
4292
4284
|
filterIdOrName: m
|
|
4293
|
-
} = e,
|
|
4285
|
+
} = e, g = await t.getUser(), f = p && p.length > 0;
|
|
4294
4286
|
if (!o && !r && !n && !i && !a && !f && !h && !m)
|
|
4295
4287
|
throw new Error(
|
|
4296
4288
|
"At least one filter must be provided: searchText, projectId, sectionId, parentId, responsibleUser, labels, filter, or filterIdOrName"
|
|
@@ -4305,13 +4297,13 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4305
4297
|
);
|
|
4306
4298
|
let v = h;
|
|
4307
4299
|
m && (v = (await zi.resolveFilter(t, m)).filterQuery);
|
|
4308
|
-
const j = await
|
|
4300
|
+
const j = await et(t, a), A = j?.userId, k = j?.email;
|
|
4309
4301
|
if (r || n || i) {
|
|
4310
4302
|
const D = {
|
|
4311
4303
|
limit: d,
|
|
4312
4304
|
cursor: l ?? null
|
|
4313
4305
|
};
|
|
4314
|
-
r && (D.projectId = await de({ projectId: r, user:
|
|
4306
|
+
r && (D.projectId = await de({ projectId: r, user: g })), n && (D.sectionId = n), i && (D.parentId = i);
|
|
4315
4307
|
const { results: he, nextCursor: q } = await t.getTasks(D), $e = he.map(P);
|
|
4316
4308
|
let W = o ? $e.filter(
|
|
4317
4309
|
(te) => te.content.toLowerCase().includes(o.toLowerCase()) || te.description?.toLowerCase().includes(o.toLowerCase())
|
|
@@ -4319,7 +4311,7 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4319
4311
|
return W = dr({
|
|
4320
4312
|
tasks: W,
|
|
4321
4313
|
resolvedAssigneeId: A,
|
|
4322
|
-
currentUserId:
|
|
4314
|
+
currentUserId: g.id,
|
|
4323
4315
|
responsibleUserFiltering: c
|
|
4324
4316
|
}), p && p.length > 0 && (W = u === "and" ? W.filter(
|
|
4325
4317
|
(te) => p.every((De) => te.labels.includes(De))
|
|
@@ -4368,7 +4360,7 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4368
4360
|
}
|
|
4369
4361
|
let I = v ? `(${v})` : "";
|
|
4370
4362
|
o && (I = ce(I, `search: ${o}`));
|
|
4371
|
-
const x =
|
|
4363
|
+
const x = lt(p, u);
|
|
4372
4364
|
if (I = ce(I, x), !(m && !a && !c)) {
|
|
4373
4365
|
const D = os({
|
|
4374
4366
|
resolvedAssigneeId: A,
|
|
@@ -4377,7 +4369,7 @@ const zi = new Bi(), { FIND_COMPLETED_TASKS: Dt, ADD_TASKS: xt } = g, Ki = {
|
|
|
4377
4369
|
});
|
|
4378
4370
|
I = ce(I, D);
|
|
4379
4371
|
}
|
|
4380
|
-
const { tasks: b, nextCursor: S } = await
|
|
4372
|
+
const { tasks: b, nextCursor: S } = await st({
|
|
4381
4373
|
client: t,
|
|
4382
4374
|
query: I,
|
|
4383
4375
|
cursor: e.cursor,
|
|
@@ -4406,7 +4398,7 @@ function Gi(e) {
|
|
|
4406
4398
|
const t = [
|
|
4407
4399
|
e.searchText ? "No tasks in project match search" : "Project has no tasks yet"
|
|
4408
4400
|
];
|
|
4409
|
-
return e.searchText || t.push(`Use ${
|
|
4401
|
+
return e.searchText || t.push(`Use ${At} to create tasks`), t;
|
|
4410
4402
|
}
|
|
4411
4403
|
if (e.sectionId) {
|
|
4412
4404
|
const t = [e.searchText ? "No tasks in section match search" : "Section is empty"];
|
|
@@ -4414,7 +4406,7 @@ function Gi(e) {
|
|
|
4414
4406
|
}
|
|
4415
4407
|
if (e.parentId) {
|
|
4416
4408
|
const t = [e.searchText ? "No subtasks match search" : "No subtasks created yet"];
|
|
4417
|
-
return e.searchText || t.push(`Use ${
|
|
4409
|
+
return e.searchText || t.push(`Use ${At} with parentId to add subtasks`), t;
|
|
4418
4410
|
}
|
|
4419
4411
|
return [];
|
|
4420
4412
|
}
|
|
@@ -4450,9 +4442,9 @@ function Ee({
|
|
|
4450
4442
|
if (e.length === 0) {
|
|
4451
4443
|
if (t.responsibleUser) {
|
|
4452
4444
|
const p = n || t.responsibleUser;
|
|
4453
|
-
c.push(`No tasks assigned to ${p}`), c.push("Check if the user name is correct"), c.push(`Check completed tasks with ${
|
|
4445
|
+
c.push(`No tasks assigned to ${p}`), c.push("Check if the user name is correct"), c.push(`Check completed tasks with ${xt}`);
|
|
4454
4446
|
}
|
|
4455
|
-
t.searchText && (c.push("Try broader search terms"), c.push("Verify spelling and try partial words"), t.responsibleUser || c.push(`Check completed tasks with ${
|
|
4447
|
+
t.searchText && (c.push("Try broader search terms"), c.push("Verify spelling and try partial words"), t.responsibleUser || c.push(`Check completed tasks with ${xt}`));
|
|
4456
4448
|
}
|
|
4457
4449
|
}
|
|
4458
4450
|
return Y({
|
|
@@ -4562,7 +4554,7 @@ function Is(e, t, o = "") {
|
|
|
4562
4554
|
r.push(...Is(i, t, `${o} `));
|
|
4563
4555
|
return r;
|
|
4564
4556
|
}
|
|
4565
|
-
function
|
|
4557
|
+
function Et(e) {
|
|
4566
4558
|
const t = {};
|
|
4567
4559
|
for (const r of e)
|
|
4568
4560
|
t[r.id] = { ...r, children: [] };
|
|
@@ -4579,11 +4571,11 @@ function At(e) {
|
|
|
4579
4571
|
}
|
|
4580
4572
|
return o;
|
|
4581
4573
|
}
|
|
4582
|
-
function
|
|
4574
|
+
function qe(e, t = "") {
|
|
4583
4575
|
const o = [];
|
|
4584
4576
|
for (const r of e) {
|
|
4585
4577
|
const n = `id=${r.id}`, i = r.dueDate ? `; due=${r.dueDate}` : "", a = `; content=${r.content}`;
|
|
4586
|
-
o.push(`${t}- ${n}${i}${a}`), r.children.length > 0 && o.push(...
|
|
4578
|
+
o.push(`${t}- ${n}${i}${a}`), r.children.length > 0 && o.push(...qe(r.children, `${t} `));
|
|
4587
4579
|
}
|
|
4588
4580
|
return o;
|
|
4589
4581
|
}
|
|
@@ -4668,16 +4660,16 @@ async function sa(e, t) {
|
|
|
4668
4660
|
const c = [`# ${o.name}`];
|
|
4669
4661
|
if (a.length > 0) {
|
|
4670
4662
|
c.push("");
|
|
4671
|
-
const p =
|
|
4672
|
-
c.push(...
|
|
4663
|
+
const p = Et(a);
|
|
4664
|
+
c.push(...qe(p));
|
|
4673
4665
|
}
|
|
4674
4666
|
for (const p of r) {
|
|
4675
4667
|
c.push(""), c.push(`## ${p.name}`);
|
|
4676
4668
|
const u = i[p.id];
|
|
4677
4669
|
if (!u?.length)
|
|
4678
4670
|
continue;
|
|
4679
|
-
const h =
|
|
4680
|
-
c.push(...
|
|
4671
|
+
const h = Et(u);
|
|
4672
|
+
c.push(...qe(h));
|
|
4681
4673
|
}
|
|
4682
4674
|
const d = c.join(`
|
|
4683
4675
|
`), l = {
|
|
@@ -4701,7 +4693,7 @@ async function sa(e, t) {
|
|
|
4701
4693
|
return { textContent: d, structuredContent: l };
|
|
4702
4694
|
}
|
|
4703
4695
|
const oa = {
|
|
4704
|
-
name:
|
|
4696
|
+
name: y.GET_OVERVIEW,
|
|
4705
4697
|
description: "Get a Markdown overview. If no projectId is provided, shows all projects with hierarchy and sections (useful for navigation). If projectId is provided, shows detailed overview of that specific project including all tasks grouped by sections.",
|
|
4706
4698
|
parameters: Vi,
|
|
4707
4699
|
outputSchema: Ji,
|
|
@@ -4717,7 +4709,7 @@ const oa = {
|
|
|
4717
4709
|
count: s.number().describe("Number of consecutive periods in this streak."),
|
|
4718
4710
|
start: s.string().describe("Start date of the streak."),
|
|
4719
4711
|
end: s.string().describe("End date of the streak.")
|
|
4720
|
-
}),
|
|
4712
|
+
}), Ot = s.object({
|
|
4721
4713
|
id: s.string().describe("Project ID."),
|
|
4722
4714
|
completed: s.number().describe("Number of tasks completed in this project.")
|
|
4723
4715
|
}), na = {
|
|
@@ -4726,7 +4718,7 @@ const oa = {
|
|
|
4726
4718
|
s.object({
|
|
4727
4719
|
date: s.string().describe("Date string (YYYY-MM-DD)."),
|
|
4728
4720
|
totalCompleted: s.number().describe("Total tasks completed on this day."),
|
|
4729
|
-
items: s.array(
|
|
4721
|
+
items: s.array(Ot).describe("Per-project completion breakdown for this day.")
|
|
4730
4722
|
})
|
|
4731
4723
|
).describe("Daily completion breakdown (most recent days)."),
|
|
4732
4724
|
weekItems: s.array(
|
|
@@ -4734,7 +4726,7 @@ const oa = {
|
|
|
4734
4726
|
from: s.string().describe("Start date of the week."),
|
|
4735
4727
|
to: s.string().describe("End date of the week."),
|
|
4736
4728
|
totalCompleted: s.number().describe("Total tasks completed in this week."),
|
|
4737
|
-
items: s.array(
|
|
4729
|
+
items: s.array(Ot).describe("Per-project completion breakdown for this week.")
|
|
4738
4730
|
})
|
|
4739
4731
|
).describe("Weekly completion breakdown (most recent weeks)."),
|
|
4740
4732
|
goals: s.object({
|
|
@@ -4770,7 +4762,7 @@ const oa = {
|
|
|
4770
4762
|
).describe("Recent karma change events with reasons."),
|
|
4771
4763
|
projectColors: s.record(s.string(), s.string()).describe("Map of project ID to color key.")
|
|
4772
4764
|
}, ia = {
|
|
4773
|
-
name:
|
|
4765
|
+
name: y.GET_PRODUCTIVITY_STATS,
|
|
4774
4766
|
description: 'Get comprehensive productivity statistics including daily/weekly completion breakdowns, goal streaks (current, last, max), karma score and trends, and historical karma data. Useful for productivity analysis and tracking goal progress. Reports counts, streaks and karma only, never the tasks themselves — for "what did I complete", use find-activity.',
|
|
4775
4767
|
parameters: ra,
|
|
4776
4768
|
outputSchema: na,
|
|
@@ -4876,7 +4868,7 @@ function la(e, t) {
|
|
|
4876
4868
|
`);
|
|
4877
4869
|
}
|
|
4878
4870
|
const ua = {
|
|
4879
|
-
name:
|
|
4871
|
+
name: y.GET_PROJECT_ACTIVITY_STATS,
|
|
4880
4872
|
description: "Get daily and optional weekly task completion counts for a project over a configurable time window (1-12 weeks). Useful for identifying completion trends and patterns.",
|
|
4881
4873
|
parameters: ca,
|
|
4882
4874
|
outputSchema: da,
|
|
@@ -4921,7 +4913,7 @@ const ua = {
|
|
|
4921
4913
|
progressPercent: s.number().describe("Completion percentage (0-100).")
|
|
4922
4914
|
}).describe("Project completion progress."),
|
|
4923
4915
|
health: s.object({
|
|
4924
|
-
status: s.enum(
|
|
4916
|
+
status: s.enum(Ve).describe("The overall health status of the project."),
|
|
4925
4917
|
description: s.string().optional().describe("Detailed description of the health assessment."),
|
|
4926
4918
|
descriptionSummary: s.string().optional().describe("Brief summary of the health assessment."),
|
|
4927
4919
|
isStale: s.boolean().describe("Whether the health data is stale and may need refreshing."),
|
|
@@ -4977,7 +4969,7 @@ function ba(e, { progress: t, health: o, context: r }) {
|
|
|
4977
4969
|
`);
|
|
4978
4970
|
}
|
|
4979
4971
|
const ga = {
|
|
4980
|
-
name:
|
|
4972
|
+
name: y.GET_PROJECT_HEALTH,
|
|
4981
4973
|
description: "Get a comprehensive health assessment for a project including completion progress, health status (EXCELLENT, ON_TRACK, AT_RISK, CRITICAL), and optional detailed context with project metrics and task-level data. Use includeContext=true for that full detail.",
|
|
4982
4974
|
parameters: pa,
|
|
4983
4975
|
outputSchema: ma,
|
|
@@ -5033,7 +5025,7 @@ const ga = {
|
|
|
5033
5025
|
}, Ta = s.object({
|
|
5034
5026
|
projectId: s.string().describe("The project ID."),
|
|
5035
5027
|
health: s.object({
|
|
5036
|
-
status: s.enum(
|
|
5028
|
+
status: s.enum(Ve).describe("The health status of the project."),
|
|
5037
5029
|
isStale: s.boolean().describe("Whether the health data is stale."),
|
|
5038
5030
|
updateInProgress: s.boolean().describe("Whether a health analysis update is in progress.")
|
|
5039
5031
|
}).optional().describe("Health data for this project. Omitted when the project has none."),
|
|
@@ -5047,7 +5039,7 @@ const ga = {
|
|
|
5047
5039
|
workspaceName: s.string().describe("The resolved workspace name."),
|
|
5048
5040
|
projectInsights: s.array(Ta).describe("Health and progress insights for each project in the workspace.")
|
|
5049
5041
|
}, wa = {
|
|
5050
|
-
name:
|
|
5042
|
+
name: y.GET_WORKSPACE_INSIGHTS,
|
|
5051
5043
|
description: "Get aggregated health and progress insights across all projects in a workspace. Accepts workspace name or ID, with optional project ID filtering. Useful for a cross-project health overview.",
|
|
5052
5044
|
parameters: ya,
|
|
5053
5045
|
outputSchema: ka,
|
|
@@ -5104,13 +5096,11 @@ function va(e) {
|
|
|
5104
5096
|
throw new Error(
|
|
5105
5097
|
`"${o.hostname}" is not a Todoist domain. Pass a todoist.com template URL or the template ID itself.`
|
|
5106
5098
|
);
|
|
5107
|
-
|
|
5108
|
-
|
|
5099
|
+
o.hostname = "todoist.com";
|
|
5100
|
+
const r = Fs(o.toString());
|
|
5101
|
+
if (r?.type !== "template")
|
|
5109
5102
|
throw new Error(`"${t}" is not a Todoist template URL.`);
|
|
5110
|
-
|
|
5111
|
-
if (!i)
|
|
5112
|
-
throw new Error(`Could not read a template ID from "${t}".`);
|
|
5113
|
-
return i;
|
|
5103
|
+
return r.id;
|
|
5114
5104
|
}
|
|
5115
5105
|
function Ia(e) {
|
|
5116
5106
|
const t = e.toLowerCase();
|
|
@@ -5131,7 +5121,7 @@ const Sa = {
|
|
|
5131
5121
|
comments: s.array(ye).describe("Comments created by the import."),
|
|
5132
5122
|
totalCount: s.number().describe("The total number of objects created by the import.")
|
|
5133
5123
|
}, Ca = {
|
|
5134
|
-
name:
|
|
5124
|
+
name: y.IMPORT_PROJECT_TEMPLATE,
|
|
5135
5125
|
description: "Import a template into an existing project, adding its tasks, sections and comments to whatever is already there. Source it by template ID/URL or by passing CSV content from export-project-template. To start a new project from a template, create the project with add-projects first, then import into it. This writes immediately and cannot be undone, so only run it against a project the user named.",
|
|
5136
5126
|
parameters: Sa,
|
|
5137
5127
|
outputSchema: ja,
|
|
@@ -5178,8 +5168,8 @@ function $a({
|
|
|
5178
5168
|
const Da = {}, xa = {
|
|
5179
5169
|
id: s.string().describe("The unique identifier for the workspace."),
|
|
5180
5170
|
name: s.string().describe("The name of the workspace."),
|
|
5181
|
-
plan: s.enum(
|
|
5182
|
-
role: s.enum(
|
|
5171
|
+
plan: s.enum(Ws).describe("The workspace plan type."),
|
|
5172
|
+
role: s.enum(Hs).optional().describe("The user's role in the workspace, if available."),
|
|
5183
5173
|
isLinkSharingEnabled: s.boolean().describe("Whether link sharing is enabled for the workspace."),
|
|
5184
5174
|
isGuestAllowed: s.boolean().describe("Whether guests are allowed in the workspace."),
|
|
5185
5175
|
createdAt: s.string().optional().describe("The ISO 8601 timestamp when the workspace was created."),
|
|
@@ -5221,7 +5211,7 @@ async function Ea(e) {
|
|
|
5221
5211
|
return { textContent: n, structuredContent: i };
|
|
5222
5212
|
}
|
|
5223
5213
|
const Oa = {
|
|
5224
|
-
name:
|
|
5214
|
+
name: y.LIST_WORKSPACES,
|
|
5225
5215
|
description: "Get all workspaces for the authenticated user. Returns workspace details including ID, name, plan type (STARTER/BUSINESS), user role (ADMIN/MEMBER/GUEST), link sharing settings, guest permissions, creation date, and creator ID.",
|
|
5226
5216
|
parameters: Da,
|
|
5227
5217
|
outputSchema: Aa,
|
|
@@ -5233,9 +5223,9 @@ const Oa = {
|
|
|
5233
5223
|
structuredContent: o.structuredContent
|
|
5234
5224
|
};
|
|
5235
5225
|
}
|
|
5236
|
-
}, { FIND_TASKS: Pa, FIND_PROJECT_COLLABORATORS:
|
|
5226
|
+
}, { FIND_TASKS: Pa, FIND_PROJECT_COLLABORATORS: Pt, UPDATE_TASKS: _a } = y, Ua = 50, Ra = {
|
|
5237
5227
|
operation: s.enum(["assign", "unassign", "reassign"]).describe("The assignment operation to perform."),
|
|
5238
|
-
taskIds: s.array(s.string()).min(1).max(
|
|
5228
|
+
taskIds: s.array(s.string()).min(1).max(Ua).describe("The IDs of the tasks to operate on (max 50)."),
|
|
5239
5229
|
responsibleUser: s.string().optional().describe(
|
|
5240
5230
|
'The user to assign tasks to. Can be "me" (assigns to current user), a user ID, name, or email. Required for assign and reassign operations.'
|
|
5241
5231
|
),
|
|
@@ -5260,9 +5250,9 @@ const Oa = {
|
|
|
5260
5250
|
dryRun: s.boolean().describe("Whether this was a dry run.")
|
|
5261
5251
|
}).optional().describe("Summary of the operation.")
|
|
5262
5252
|
}, Na = {
|
|
5263
|
-
name:
|
|
5253
|
+
name: y.MANAGE_ASSIGNMENTS,
|
|
5264
5254
|
description: "Bulk assignment operations for multiple tasks. Supports assign, unassign, and reassign operations with atomic rollback on failures.",
|
|
5265
|
-
parameters:
|
|
5255
|
+
parameters: Ra,
|
|
5266
5256
|
outputSchema: La,
|
|
5267
5257
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
|
|
5268
5258
|
async execute(e, t) {
|
|
@@ -5365,13 +5355,13 @@ const Oa = {
|
|
|
5365
5355
|
}
|
|
5366
5356
|
};
|
|
5367
5357
|
}
|
|
5368
|
-
const h = await
|
|
5358
|
+
const h = await ct.validateBulkAssignment(
|
|
5369
5359
|
t,
|
|
5370
5360
|
u
|
|
5371
|
-
), m = [],
|
|
5361
|
+
), m = [], g = [];
|
|
5372
5362
|
for (let k = 0; k < u.length; k++) {
|
|
5373
5363
|
const I = u[k], x = h[k];
|
|
5374
|
-
I && x?.isValid ? m.push({ assignment: I, validation: x }) : I?.taskId &&
|
|
5364
|
+
I && x?.isValid ? m.push({ assignment: I, validation: x }) : I?.taskId && g.push({
|
|
5375
5365
|
taskId: I.taskId,
|
|
5376
5366
|
success: !1,
|
|
5377
5367
|
error: x?.error?.message || "Validation failed"
|
|
@@ -5426,7 +5416,7 @@ const Oa = {
|
|
|
5426
5416
|
);
|
|
5427
5417
|
return Promise.all(T);
|
|
5428
5418
|
}
|
|
5429
|
-
const v = await f(m, !a), j = [...v, ...
|
|
5419
|
+
const v = await f(m, !a), j = [...v, ...g, ...l];
|
|
5430
5420
|
if (j.length > 0 && j.every((k) => !k.success)) {
|
|
5431
5421
|
const k = j.map((I) => `"${I.taskId}": ${I.error}`).join("; ");
|
|
5432
5422
|
throw new Error(`All ${j.length} ${o} operation(s) failed: ${k}`);
|
|
@@ -5488,13 +5478,13 @@ function Oe({
|
|
|
5488
5478
|
return !o && r.length > 0 ? (c += `**Next steps:**
|
|
5489
5479
|
`, c += `• Use ${Pa} with responsibleUser to see ${e === "unassign" ? "unassigned" : "newly assigned"} tasks
|
|
5490
5480
|
`, c += `• Use ${_a} for individual assignment changes
|
|
5491
|
-
`, n.length > 0 && (c += `• Check failed tasks and use ${
|
|
5481
|
+
`, n.length > 0 && (c += `• Check failed tasks and use ${Pt} to verify collaborator access
|
|
5492
5482
|
`)) : o ? (c += `**To execute:**
|
|
5493
5483
|
`, c += `• Remove dryRun parameter and run again to execute changes
|
|
5494
5484
|
`, r.length > 0 && (c += `• ${r.length} task${r.length === 1 ? "" : "s"} ready for ${e} operation
|
|
5495
5485
|
`), n.length > 0 && (c += `• Fix ${n.length} validation error${n.length === 1 ? "" : "s"} before executing
|
|
5496
5486
|
`)) : r.length === 0 && (c += `**Suggestions:**
|
|
5497
|
-
`, c += `• Use ${
|
|
5487
|
+
`, c += `• Use ${Pt} to find valid assignees
|
|
5498
5488
|
`, c += `• Check task IDs and assignee permissions
|
|
5499
5489
|
`, c += `• Use dryRun=true to validate before executing
|
|
5500
5490
|
`), c;
|
|
@@ -5506,7 +5496,7 @@ const Ma = {
|
|
|
5506
5496
|
project: Q.describe("The updated project."),
|
|
5507
5497
|
success: s.boolean().describe("Whether the action was successful.")
|
|
5508
5498
|
}, Ha = {
|
|
5509
|
-
name:
|
|
5499
|
+
name: y.PROJECT_MANAGEMENT,
|
|
5510
5500
|
description: "Archive or unarchive a project by its ID.",
|
|
5511
5501
|
parameters: Ma,
|
|
5512
5502
|
outputSchema: Fa,
|
|
@@ -5533,7 +5523,7 @@ const Ma = {
|
|
|
5533
5523
|
project: Q.describe("The moved project."),
|
|
5534
5524
|
success: s.boolean().describe("Whether the move was successful.")
|
|
5535
5525
|
}, za = {
|
|
5536
|
-
name:
|
|
5526
|
+
name: y.PROJECT_MOVE,
|
|
5537
5527
|
description: "Move a project between personal and workspace contexts.",
|
|
5538
5528
|
parameters: Wa,
|
|
5539
5529
|
outputSchema: Ba,
|
|
@@ -5583,7 +5573,7 @@ const Ma = {
|
|
|
5583
5573
|
affectedIds: s.array(s.string()).describe("The IDs of all affected entities."),
|
|
5584
5574
|
success: s.boolean().describe("Whether the operation was successful.")
|
|
5585
5575
|
}, qa = {
|
|
5586
|
-
name:
|
|
5576
|
+
name: y.REORDER_OBJECTS,
|
|
5587
5577
|
description: 'Reorder sibling projects or sections, and optionally move projects to a new parent. For projects: set order to reorder siblings, and/or set parentId to move under a new parent (use "root" for top level). For sections: set order to reorder within a project.',
|
|
5588
5578
|
parameters: Ka,
|
|
5589
5579
|
outputSchema: Ya,
|
|
@@ -5660,7 +5650,7 @@ const Ma = {
|
|
|
5660
5650
|
totalCount: s.number().describe("The total number of tasks rescheduled."),
|
|
5661
5651
|
rescheduledTaskIds: s.array(s.string()).describe("The IDs of the rescheduled tasks.")
|
|
5662
5652
|
}, Xa = {
|
|
5663
|
-
name:
|
|
5653
|
+
name: y.RESCHEDULE_TASKS,
|
|
5664
5654
|
description: "Reschedule tasks to new dates while preserving recurring schedules. Unlike update-tasks (which replaces the entire due string and can wipe recurrence), this tool changes only the date, keeping recurrence patterns intact. Use this when moving recurring tasks to a different date without altering their repeat pattern.",
|
|
5665
5655
|
parameters: Va,
|
|
5666
5656
|
outputSchema: Ja,
|
|
@@ -5696,7 +5686,7 @@ const Ma = {
|
|
|
5696
5686
|
}
|
|
5697
5687
|
const i = await Promise.all(o.map((d) => t.getTask(d.id))), a = i.map(P);
|
|
5698
5688
|
return {
|
|
5699
|
-
textContent:
|
|
5689
|
+
textContent: nt("Rescheduled", a, {
|
|
5700
5690
|
showDetails: a.length <= 5
|
|
5701
5691
|
}),
|
|
5702
5692
|
structuredContent: {
|
|
@@ -5726,14 +5716,14 @@ const Qa = {
|
|
|
5726
5716
|
).describe("The search results."),
|
|
5727
5717
|
totalCount: s.number().describe("Total number of results found.")
|
|
5728
5718
|
}, tc = {
|
|
5729
|
-
name:
|
|
5719
|
+
name: y.SEARCH,
|
|
5730
5720
|
description: "Search across tasks and projects in Todoist. Returns a list of relevant results with IDs, titles, and URLs.",
|
|
5731
5721
|
parameters: Qa,
|
|
5732
5722
|
outputSchema: ec,
|
|
5733
5723
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
5734
5724
|
async execute(e, t) {
|
|
5735
5725
|
const { query: o } = e, [r, n] = await Promise.all([
|
|
5736
|
-
|
|
5726
|
+
st({
|
|
5737
5727
|
client: t,
|
|
5738
5728
|
query: `search: ${o}`,
|
|
5739
5729
|
limit: C.TASKS_MAX,
|
|
@@ -5767,7 +5757,7 @@ const Qa = {
|
|
|
5767
5757
|
successCount: s.number().describe("The number of successfully uncompleted tasks."),
|
|
5768
5758
|
failureCount: s.number().describe("The number of failed task uncompletions.")
|
|
5769
5759
|
}, rc = {
|
|
5770
|
-
name:
|
|
5760
|
+
name: y.UNCOMPLETE_TASKS,
|
|
5771
5761
|
description: "Uncomplete (reopen) one or more completed tasks by their IDs.",
|
|
5772
5762
|
parameters: sc,
|
|
5773
5763
|
outputSchema: oc,
|
|
@@ -5805,7 +5795,7 @@ function nc({
|
|
|
5805
5795
|
failures: t,
|
|
5806
5796
|
args: o
|
|
5807
5797
|
}) {
|
|
5808
|
-
return
|
|
5798
|
+
return it({
|
|
5809
5799
|
action: "Uncompleted tasks",
|
|
5810
5800
|
success: e.length,
|
|
5811
5801
|
total: o.ids.length,
|
|
@@ -5827,7 +5817,7 @@ const ic = s.object({
|
|
|
5827
5817
|
updateCount: s.number().describe("The number of comments updated.")
|
|
5828
5818
|
}).describe("Summary of operations performed.")
|
|
5829
5819
|
}, dc = {
|
|
5830
|
-
name:
|
|
5820
|
+
name: y.UPDATE_COMMENTS,
|
|
5831
5821
|
description: "Update multiple existing comments with new content.",
|
|
5832
5822
|
parameters: ac,
|
|
5833
5823
|
outputSchema: cc,
|
|
@@ -5872,7 +5862,7 @@ const uc = s.object({
|
|
|
5872
5862
|
}), pc = {
|
|
5873
5863
|
filters: s.array(uc).min(1).describe("The filters to update.")
|
|
5874
5864
|
}, hc = {
|
|
5875
|
-
filters: s.array(
|
|
5865
|
+
filters: s.array(rt).describe("The updated filters."),
|
|
5876
5866
|
totalCount: s.number().describe("The total number of filters updated."),
|
|
5877
5867
|
updatedFilterIds: s.array(s.string()).describe("The IDs of the updated filters."),
|
|
5878
5868
|
appliedOperations: s.object({
|
|
@@ -5880,7 +5870,7 @@ const uc = s.object({
|
|
|
5880
5870
|
skippedCount: s.number().describe("The number of filters skipped (no changes).")
|
|
5881
5871
|
}).describe("Summary of operations performed.")
|
|
5882
5872
|
}, mc = {
|
|
5883
|
-
name:
|
|
5873
|
+
name: y.UPDATE_FILTERS,
|
|
5884
5874
|
description: "Update one or more existing personal filters with new values.",
|
|
5885
5875
|
parameters: pc,
|
|
5886
5876
|
outputSchema: hc,
|
|
@@ -5901,11 +5891,11 @@ const uc = s.object({
|
|
|
5901
5891
|
}
|
|
5902
5892
|
};
|
|
5903
5893
|
const a = r.map((h) => {
|
|
5904
|
-
const { id: m, color:
|
|
5894
|
+
const { id: m, color: g, ...f } = h;
|
|
5905
5895
|
return V("filter_update", {
|
|
5906
5896
|
id: m,
|
|
5907
5897
|
...f,
|
|
5908
|
-
...
|
|
5898
|
+
...g !== void 0 ? { color: g } : {}
|
|
5909
5899
|
});
|
|
5910
5900
|
});
|
|
5911
5901
|
await t.sync({ commands: a });
|
|
@@ -5981,7 +5971,7 @@ const gc = s.object({
|
|
|
5981
5971
|
skippedCount: s.number().describe("Number of operations skipped (no changes or shared label not found).")
|
|
5982
5972
|
}).describe("Summary of operations performed.")
|
|
5983
5973
|
}, Ic = {
|
|
5984
|
-
name:
|
|
5974
|
+
name: y.UPDATE_LABELS,
|
|
5985
5975
|
description: "Update one or more existing labels. Personal labels (identified by ID) can have their name, color, order, and favorite flag updated. Shared labels (identified by name) can only be renamed.",
|
|
5986
5976
|
parameters: kc,
|
|
5987
5977
|
outputSchema: vc,
|
|
@@ -5992,7 +5982,7 @@ const gc = s.object({
|
|
|
5992
5982
|
if (p.labelType === "personal") {
|
|
5993
5983
|
const h = jc(p);
|
|
5994
5984
|
if (h !== null) return { kind: "skipped", reason: h };
|
|
5995
|
-
const { id: m, labelType:
|
|
5985
|
+
const { id: m, labelType: g, ...f } = p;
|
|
5996
5986
|
return { kind: "updated", label: await t.updateLabel(m, f) };
|
|
5997
5987
|
}
|
|
5998
5988
|
return await t.renameSharedLabel({
|
|
@@ -6086,7 +6076,7 @@ const Cc = s.object({
|
|
|
6086
6076
|
failureCount: s.number().describe("The number of projects that failed to update.")
|
|
6087
6077
|
}).describe("Summary of operations performed.")
|
|
6088
6078
|
}, xc = {
|
|
6089
|
-
name:
|
|
6079
|
+
name: y.UPDATE_PROJECTS,
|
|
6090
6080
|
description: "Update multiple existing projects with new values.",
|
|
6091
6081
|
parameters: $c,
|
|
6092
6082
|
outputSchema: Dc,
|
|
@@ -6143,7 +6133,7 @@ function Ac({
|
|
|
6143
6133
|
let a = `Updated ${n} project${n === 1 ? "" : "s"}`;
|
|
6144
6134
|
const c = [];
|
|
6145
6135
|
return t > 0 && c.push(`${t} skipped - no changes`), o > 0 && c.push(`${o} skipped - no valid field values`), c.length > 0 && (a += ` (${c.join(", ")})`), n > 0 && (a += `:
|
|
6146
|
-
${i}`),
|
|
6136
|
+
${i}`), at(a, r);
|
|
6147
6137
|
}
|
|
6148
6138
|
function Ec({ id: e, ...t }) {
|
|
6149
6139
|
const o = Object.values(t);
|
|
@@ -6171,22 +6161,22 @@ const Oc = s.object({
|
|
|
6171
6161
|
'New trigger condition: "on_enter" or "on_leave".'
|
|
6172
6162
|
),
|
|
6173
6163
|
radius: s.number().int().optional().describe("New radius in meters.")
|
|
6174
|
-
}),
|
|
6164
|
+
}), Uc = s.discriminatedUnion("type", [
|
|
6175
6165
|
Oc,
|
|
6176
6166
|
Pc,
|
|
6177
6167
|
_c
|
|
6178
|
-
]),
|
|
6179
|
-
reminders: s.array(
|
|
6168
|
+
]), Rc = {
|
|
6169
|
+
reminders: s.array(Uc).min(1).max(we).describe(
|
|
6180
6170
|
`Array of reminders to update (max ${we}). Each must include the reminder type and ID. Only include fields that need to change.`
|
|
6181
6171
|
)
|
|
6182
6172
|
}, Lc = {
|
|
6183
|
-
reminders: s.array(
|
|
6173
|
+
reminders: s.array(ot).describe("The updated reminders."),
|
|
6184
6174
|
totalCount: s.number().describe("Total reminders updated."),
|
|
6185
6175
|
updatedReminderIds: s.array(s.string()).describe("IDs of updated reminders.")
|
|
6186
6176
|
}, Nc = {
|
|
6187
|
-
name:
|
|
6177
|
+
name: y.UPDATE_REMINDERS,
|
|
6188
6178
|
description: 'Update existing reminders. Each reminder must specify its type ("relative", "absolute", or "location") and ID. Only include fields that need to change.',
|
|
6189
|
-
parameters:
|
|
6179
|
+
parameters: Rc,
|
|
6190
6180
|
outputSchema: Lc,
|
|
6191
6181
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !0 },
|
|
6192
6182
|
async execute(e, t) {
|
|
@@ -6243,7 +6233,7 @@ const Oc = s.object({
|
|
|
6243
6233
|
totalCount: s.number().describe("The total number of sections updated."),
|
|
6244
6234
|
updatedSectionIds: s.array(s.string()).describe("The IDs of the updated sections.")
|
|
6245
6235
|
}, Wc = {
|
|
6246
|
-
name:
|
|
6236
|
+
name: y.UPDATE_SECTIONS,
|
|
6247
6237
|
description: "Update multiple existing sections with new values.",
|
|
6248
6238
|
parameters: Fc,
|
|
6249
6239
|
outputSchema: Hc,
|
|
@@ -6326,7 +6316,7 @@ const Gc = s.object({
|
|
|
6326
6316
|
),
|
|
6327
6317
|
parentId: s.string().optional().describe("Make the task a subtask of this task ID. Omit unless the parent should change."),
|
|
6328
6318
|
order: s.number().optional().describe("The new order of the task within its parent/section."),
|
|
6329
|
-
priority:
|
|
6319
|
+
priority: Qe.optional().describe(Ze),
|
|
6330
6320
|
dueString: s.preprocess(
|
|
6331
6321
|
// Keep accepting legacy null while exposing a Gemini-compatible string schema.
|
|
6332
6322
|
(e) => e === null ? "remove" : e,
|
|
@@ -6355,8 +6345,8 @@ const Gc = s.object({
|
|
|
6355
6345
|
isUncompletable: s.boolean().optional().describe(
|
|
6356
6346
|
"Whether this task should be uncompletable (organizational header). Tasks with isUncompletable: true appear as organizational headers and cannot be completed."
|
|
6357
6347
|
)
|
|
6358
|
-
}), Vc = (e) => !!(e.projectId || e.sectionId || e.parentId), $s = (e) => Object.keys(e).length > 0, Jc = ["remove", "no date"], Xc = ["remove", "no date", "no deadline"], Zc = "no date",
|
|
6359
|
-
tasks: s.array(Gc).min(1).max(
|
|
6348
|
+
}), Vc = (e) => !!(e.projectId || e.sectionId || e.parentId), $s = (e) => Object.keys(e).length > 0, Jc = ["remove", "no date"], Xc = ["remove", "no date", "no deadline"], Zc = "no date", Ge = Yt.TASKS_PER_OPERATION, _t = {
|
|
6349
|
+
tasks: s.array(Gc).min(1).max(Ge).describe(`The tasks to update (max ${Ge}).`)
|
|
6360
6350
|
}, Qc = {
|
|
6361
6351
|
tasks: s.array(H).describe("The updated tasks."),
|
|
6362
6352
|
totalCount: s.number().describe("The total number of tasks updated."),
|
|
@@ -6373,13 +6363,13 @@ const Gc = s.object({
|
|
|
6373
6363
|
)
|
|
6374
6364
|
}).describe("Summary of operations performed.")
|
|
6375
6365
|
}, ed = {
|
|
6376
|
-
name:
|
|
6366
|
+
name: y.UPDATE_TASKS,
|
|
6377
6367
|
description: "Update existing tasks including content, dates, priorities, and assignments. Send only the fields that change.",
|
|
6378
|
-
parameters:
|
|
6368
|
+
parameters: _t,
|
|
6379
6369
|
outputSchema: Qc,
|
|
6380
6370
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
|
|
6381
6371
|
async execute(e, t) {
|
|
6382
|
-
const { tasks: o } = s.object(
|
|
6372
|
+
const { tasks: o } = s.object(_t).parse(e), r = o.map(() => ({ kind: "skipped" })), n = (T, b) => {
|
|
6383
6373
|
r[T] = { kind: "failed", error: b };
|
|
6384
6374
|
}, i = (T, b) => {
|
|
6385
6375
|
n(T, z(b));
|
|
@@ -6412,7 +6402,7 @@ const Gc = s.object({
|
|
|
6412
6402
|
} catch (b) {
|
|
6413
6403
|
i(T.index, b), T.failed = !0;
|
|
6414
6404
|
}
|
|
6415
|
-
const h = /* @__PURE__ */ new Map(), m = [],
|
|
6405
|
+
const h = /* @__PURE__ */ new Map(), m = [], g = (T) => {
|
|
6416
6406
|
const b = T.filter((S) => !S.failed);
|
|
6417
6407
|
b.length !== 0 && m.push(
|
|
6418
6408
|
nd({
|
|
@@ -6436,7 +6426,7 @@ const Gc = s.object({
|
|
|
6436
6426
|
})
|
|
6437
6427
|
);
|
|
6438
6428
|
}, f = new Set(u.map(({ item: T }) => T.index));
|
|
6439
|
-
|
|
6429
|
+
g(l.filter((T) => !f.has(T.index))), await od({
|
|
6440
6430
|
client: t,
|
|
6441
6431
|
moving: u,
|
|
6442
6432
|
results: h,
|
|
@@ -6450,7 +6440,7 @@ const Gc = s.object({
|
|
|
6450
6440
|
}
|
|
6451
6441
|
b.push(S);
|
|
6452
6442
|
}
|
|
6453
|
-
|
|
6443
|
+
g(b);
|
|
6454
6444
|
}
|
|
6455
6445
|
}), await Promise.all(m);
|
|
6456
6446
|
for (const T of l) {
|
|
@@ -6518,7 +6508,7 @@ async function Ds({
|
|
|
6518
6508
|
try {
|
|
6519
6509
|
const r = new Set(t), n = {
|
|
6520
6510
|
ids: t.join(","),
|
|
6521
|
-
limit:
|
|
6511
|
+
limit: Ge
|
|
6522
6512
|
}, { results: i } = await O(() => e.getTasks(n));
|
|
6523
6513
|
for (const a of i)
|
|
6524
6514
|
r.has(a.id) && o.set(a.id, a);
|
|
@@ -6539,7 +6529,7 @@ async function od({
|
|
|
6539
6529
|
const d = Kc(c.move), l = n.get(d);
|
|
6540
6530
|
l ? l.push(c) : n.set(d, [c]);
|
|
6541
6531
|
}
|
|
6542
|
-
const i =
|
|
6532
|
+
const i = po(e), a = [];
|
|
6543
6533
|
for (const c of n.values()) {
|
|
6544
6534
|
const d = [...new Set(c.map(({ item: u }) => u.id))], l = c[0]?.move, p = c.length === 1 ? c[0] : void 0;
|
|
6545
6535
|
try {
|
|
@@ -6552,12 +6542,12 @@ async function od({
|
|
|
6552
6542
|
}
|
|
6553
6543
|
const u = await i(
|
|
6554
6544
|
() => O(() => e.moveTasks(d, l))
|
|
6555
|
-
), h = new Map(u.map((f) => [f.id, f])), m = [],
|
|
6545
|
+
), h = new Map(u.map((f) => [f.id, f])), m = [], g = [];
|
|
6556
6546
|
for (const f of c) {
|
|
6557
6547
|
const v = h.get(f.item.id);
|
|
6558
|
-
v ? (o.set(f.item.index, { task: v }),
|
|
6548
|
+
v ? (o.set(f.item.index, { task: v }), g.push(f)) : m.push(f);
|
|
6559
6549
|
}
|
|
6560
|
-
r(
|
|
6550
|
+
r(g), m.length > 0 && a.push({ group: m, destination: l });
|
|
6561
6551
|
} catch (u) {
|
|
6562
6552
|
if (p) {
|
|
6563
6553
|
o.set(p.item.index, { error: z(u) }), r(c);
|
|
@@ -6596,7 +6586,7 @@ async function nd({
|
|
|
6596
6586
|
onUpdated: o,
|
|
6597
6587
|
onFailed: r
|
|
6598
6588
|
}) {
|
|
6599
|
-
const n =
|
|
6589
|
+
const n = ho(e);
|
|
6600
6590
|
await Promise.all(
|
|
6601
6591
|
t.filter((i) => $s(i.updateArgs)).map(async (i) => {
|
|
6602
6592
|
try {
|
|
@@ -6627,23 +6617,23 @@ async function id({
|
|
|
6627
6617
|
priority: u,
|
|
6628
6618
|
labels: h,
|
|
6629
6619
|
deadlineDate: m,
|
|
6630
|
-
...
|
|
6620
|
+
...g
|
|
6631
6621
|
} = e;
|
|
6632
6622
|
if (M(i) && r.error !== void 0)
|
|
6633
6623
|
throw r.error;
|
|
6634
6624
|
const f = M(i) ? r.projectId : i;
|
|
6635
6625
|
let v = {
|
|
6636
|
-
...
|
|
6626
|
+
...g,
|
|
6637
6627
|
...h !== void 0 && { labels: h }
|
|
6638
6628
|
};
|
|
6639
6629
|
u && (v.priority = Qt(u));
|
|
6640
|
-
const j =
|
|
6630
|
+
const j = Ut(
|
|
6641
6631
|
d,
|
|
6642
6632
|
Jc,
|
|
6643
6633
|
Zc
|
|
6644
6634
|
);
|
|
6645
6635
|
j !== void 0 && (v = { ...v, dueString: j });
|
|
6646
|
-
const A =
|
|
6636
|
+
const A = Ut(m, Xc, null);
|
|
6647
6637
|
if (A !== void 0 && (v = { ...v, deadlineDate: A }), l)
|
|
6648
6638
|
try {
|
|
6649
6639
|
const { minutes: k } = Zt(l);
|
|
@@ -6674,7 +6664,7 @@ async function id({
|
|
|
6674
6664
|
async function ad(e, t, o) {
|
|
6675
6665
|
if (o === null || o === "unassign")
|
|
6676
6666
|
return null;
|
|
6677
|
-
const r = await
|
|
6667
|
+
const r = await ct.validateTaskUpdateAssignment(
|
|
6678
6668
|
e,
|
|
6679
6669
|
t,
|
|
6680
6670
|
o
|
|
@@ -6693,7 +6683,7 @@ function cd({
|
|
|
6693
6683
|
}) {
|
|
6694
6684
|
const n = [];
|
|
6695
6685
|
o > 0 && n.push(`${o} skipped - no changes`), r > 0 && n.push(`${r} already in requested destination`), t.length > 0 && n.push(`${t.length} failed`);
|
|
6696
|
-
const i = n.length > 0 ? ` (${n.join(", ")})` : "", a =
|
|
6686
|
+
const i = n.length > 0 ? ` (${n.join(", ")})` : "", a = nt("Updated", e, {
|
|
6697
6687
|
context: i,
|
|
6698
6688
|
showDetails: e.length <= 5
|
|
6699
6689
|
});
|
|
@@ -6709,7 +6699,7 @@ ${l}${p}`;
|
|
|
6709
6699
|
function dd({ id: e, ...t }) {
|
|
6710
6700
|
return Object.keys(t).length > 0;
|
|
6711
6701
|
}
|
|
6712
|
-
function
|
|
6702
|
+
function Ut(e, t, o) {
|
|
6713
6703
|
if (e === void 0)
|
|
6714
6704
|
return e;
|
|
6715
6705
|
if (e === null)
|
|
@@ -6776,7 +6766,7 @@ function yd(e, t) {
|
|
|
6776
6766
|
});
|
|
6777
6767
|
}
|
|
6778
6768
|
async function Td(e) {
|
|
6779
|
-
const t = await e.getUser(), o = t.tzInfo?.timezone ?? "UTC", r = xs(o), n = /* @__PURE__ */ new Date(), i = yd(n, r), a = t.startDay ?? 1, c = bd(a), d = pd(t), l = new Date(n.toLocaleString("en-US", { timeZone: r })), p = hd(l, a), u = md(p), h = fd(l),
|
|
6769
|
+
const t = await e.getUser(), o = t.tzInfo?.timezone ?? "UTC", r = xs(o), n = /* @__PURE__ */ new Date(), i = yd(n, r), a = t.startDay ?? 1, c = bd(a), d = pd(t), l = new Date(n.toLocaleString("en-US", { timeZone: r })), p = hd(l, a), u = md(p), h = fd(l), g = [
|
|
6780
6770
|
"# User Information",
|
|
6781
6771
|
"",
|
|
6782
6772
|
`**User ID:** ${t.id}`,
|
|
@@ -6816,10 +6806,10 @@ async function Td(e) {
|
|
|
6816
6806
|
email: t.email,
|
|
6817
6807
|
plan: d
|
|
6818
6808
|
};
|
|
6819
|
-
return { textContent:
|
|
6809
|
+
return { textContent: g, structuredContent: f };
|
|
6820
6810
|
}
|
|
6821
6811
|
const kd = {
|
|
6822
|
-
name:
|
|
6812
|
+
name: y.USER_INFO,
|
|
6823
6813
|
description: "Get comprehensive user information including user ID, full name, email, timezone with current local time, week start day preferences, current week dates, daily/weekly goal progress, and user plan (Free/Pro/Business).",
|
|
6824
6814
|
parameters: ld,
|
|
6825
6815
|
outputSchema: ud,
|
|
@@ -6889,7 +6879,7 @@ const Dd = {
|
|
|
6889
6879
|
"The URL of the attachment file to view. Get this from the fileUrl field in a comment's fileAttachment."
|
|
6890
6880
|
)
|
|
6891
6881
|
}, xd = {
|
|
6892
|
-
name:
|
|
6882
|
+
name: y.VIEW_ATTACHMENT,
|
|
6893
6883
|
description: "View a file attachment from a Todoist comment. Pass the fileUrl from a comment's fileAttachment field. Supports images (returned inline), text files (returned as text), and binary files like PDFs (returned as embedded resources).",
|
|
6894
6884
|
parameters: Dd,
|
|
6895
6885
|
annotations: {
|
|
@@ -6932,7 +6922,7 @@ const Dd = {
|
|
|
6932
6922
|
...Fi,
|
|
6933
6923
|
_meta: {
|
|
6934
6924
|
ui: {
|
|
6935
|
-
resourceUri:
|
|
6925
|
+
resourceUri: Ne
|
|
6936
6926
|
}
|
|
6937
6927
|
}
|
|
6938
6928
|
}, Ed = {
|
|
@@ -6954,7 +6944,7 @@ const Dd = {
|
|
|
6954
6944
|
// Section management tools
|
|
6955
6945
|
addSections: mn,
|
|
6956
6946
|
updateSections: Wc,
|
|
6957
|
-
findSections:
|
|
6947
|
+
findSections: Ri,
|
|
6958
6948
|
// Comment management tools
|
|
6959
6949
|
addComments: xr,
|
|
6960
6950
|
findComments: ri,
|
|
@@ -6991,7 +6981,7 @@ const Dd = {
|
|
|
6991
6981
|
findProjectCollaborators: wi,
|
|
6992
6982
|
manageAssignments: Na,
|
|
6993
6983
|
// Template tools
|
|
6994
|
-
exportProjectTemplate:
|
|
6984
|
+
exportProjectTemplate: Un,
|
|
6995
6985
|
importProjectTemplate: Ca,
|
|
6996
6986
|
// Workspace tools
|
|
6997
6987
|
listWorkspaces: Oa,
|
|
@@ -7061,7 +7051,7 @@ function qd({
|
|
|
7061
7051
|
features: o = []
|
|
7062
7052
|
}) {
|
|
7063
7053
|
const r = new Es(
|
|
7064
|
-
{ name: "todoist-mcp-server", version:
|
|
7054
|
+
{ name: "todoist-mcp-server", version: Xe },
|
|
7065
7055
|
{
|
|
7066
7056
|
capabilities: {
|
|
7067
7057
|
tools: { listChanged: !0 },
|
|
@@ -7069,8 +7059,8 @@ function qd({
|
|
|
7069
7059
|
},
|
|
7070
7060
|
instructions: Pd
|
|
7071
7061
|
}
|
|
7072
|
-
), n =
|
|
7073
|
-
|
|
7062
|
+
), n = $o(e, { baseUrl: t });
|
|
7063
|
+
Vs(r);
|
|
7074
7064
|
const i = { server: r, client: n, features: o };
|
|
7075
7065
|
for (const a of Od)
|
|
7076
7066
|
Go({ tool: a, ...i });
|
|
@@ -7085,7 +7075,7 @@ function qd({
|
|
|
7085
7075
|
), r;
|
|
7086
7076
|
}
|
|
7087
7077
|
export {
|
|
7088
|
-
|
|
7078
|
+
Po as $,
|
|
7089
7079
|
oa as A,
|
|
7090
7080
|
ia as B,
|
|
7091
7081
|
ua as C,
|
|
@@ -7111,8 +7101,8 @@ export {
|
|
|
7111
7101
|
ed as W,
|
|
7112
7102
|
kd as X,
|
|
7113
7103
|
xd as Y,
|
|
7114
|
-
|
|
7115
|
-
|
|
7104
|
+
$o as Z,
|
|
7105
|
+
yo as _,
|
|
7116
7106
|
xr as a,
|
|
7117
7107
|
Mr as b,
|
|
7118
7108
|
Br as c,
|
|
@@ -7124,7 +7114,7 @@ export {
|
|
|
7124
7114
|
jn as i,
|
|
7125
7115
|
Dn as j,
|
|
7126
7116
|
On as k,
|
|
7127
|
-
|
|
7117
|
+
Un as l,
|
|
7128
7118
|
qn as m,
|
|
7129
7119
|
zn as n,
|
|
7130
7120
|
Xn as o,
|
|
@@ -7136,7 +7126,7 @@ export {
|
|
|
7136
7126
|
wi as u,
|
|
7137
7127
|
$i as v,
|
|
7138
7128
|
Ei as w,
|
|
7139
|
-
|
|
7129
|
+
Ri as x,
|
|
7140
7130
|
qi as y,
|
|
7141
7131
|
Fi as z
|
|
7142
7132
|
};
|