@doist/todoist-mcp 12.5.2 → 12.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/dist/main-http.js +2 -2
- package/dist/main.js +1 -1
- package/dist/{mcp-server-Cgo8Mi4X.js → mcp-server-9sgQGVw_.js} +465 -515
- package/dist/mcp-server.d.ts +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/{require-valid-todoist-token-Cqt_drLE.js → require-valid-todoist-token-26-h3alF.js} +1 -1
- package/dist/tools/find-tasks-by-date.d.ts.map +1 -1
- package/package.json +2 -1
- package/scripts/eval-instructions.ts +415 -0
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { ResourceTemplate as Ds, McpServer as xs } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
-
import { createHash as
|
|
2
|
+
import { createHash as Rt, randomUUID as Pe } from "node:crypto";
|
|
3
3
|
import { readFileSync as As } from "node:fs";
|
|
4
|
-
import { dirname as Ut, join as
|
|
4
|
+
import { dirname as Ut, join as _e } from "node:path";
|
|
5
5
|
import { fileURLToPath as Es } from "node:url";
|
|
6
6
|
import { registerAppResource as Os, RESOURCE_MIME_TYPE as Lt, registerAppTool as Ps } from "@modelcontextprotocol/ext-apps/server";
|
|
7
|
-
import se, { ZodError as
|
|
8
|
-
import { AsyncLocalStorage as
|
|
7
|
+
import se, { ZodError as _s, z as s } from "zod";
|
|
8
|
+
import { AsyncLocalStorage as Rs } from "node:async_hooks";
|
|
9
9
|
import { createRequire as Us } from "node:module";
|
|
10
|
-
import { TodoistApi as Ls, isWorkspaceProject as
|
|
10
|
+
import { TodoistApi as Ls, isWorkspaceProject as ke, isPersonalProject as B, colors as Re, LOCATION_TRIGGERS as Nt, REMINDER_TYPES as Ns, createCommand as V, REMINDER_DELIVERY_SERVICES as Ms, HEALTH_STATUSES as Ge, getTaskUrl as Mt, getProjectUrl as Ft, WORKSPACE_ROLES as Fs, WORKSPACE_PLANS as Hs } from "@doist/todoist-sdk";
|
|
11
11
|
import { addDays as Ue, formatISO as lt } from "date-fns";
|
|
12
12
|
const ut = Ut(Es(import.meta.url)), Ws = [
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
_e(ut, "task-list", "index.html"),
|
|
14
|
+
_e(ut, "mcp-apps", "index.html")
|
|
15
15
|
], Bs = `<!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 zs() {
|
|
22
22
|
const e = [];
|
|
23
23
|
for (const t of Ws)
|
|
24
24
|
try {
|
|
@@ -28,7 +28,7 @@ function Ys() {
|
|
|
28
28
|
}
|
|
29
29
|
return console.error("Failed to load task list app HTML from any known path:", e), Bs;
|
|
30
30
|
}
|
|
31
|
-
const Ht =
|
|
31
|
+
const Ht = zs(), Ks = Rt("sha256").update(Ht).digest("hex").slice(0, 12), Le = `ui://todoist/task-list@${Ks}`, qs = "ui://todoist/task-list@{hash}", Ne = "Interactive task list widget", Ys = "https://ai.todoist.net", Me = {
|
|
32
32
|
ui: {
|
|
33
33
|
prefersBorder: !0,
|
|
34
34
|
csp: {
|
|
@@ -37,13 +37,13 @@ const Ht = Ys(), zs = _t("sha256").update(Ht).digest("hex").slice(0, 12), Le = `
|
|
|
37
37
|
resourceDomains: []
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
|
-
"openai/widgetDescription":
|
|
40
|
+
"openai/widgetDescription": Ne,
|
|
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": Ys
|
|
47
47
|
};
|
|
48
48
|
function pt(e) {
|
|
49
49
|
return {
|
|
@@ -52,28 +52,28 @@ function pt(e) {
|
|
|
52
52
|
uri: e,
|
|
53
53
|
mimeType: Lt,
|
|
54
54
|
text: Ht,
|
|
55
|
-
_meta:
|
|
55
|
+
_meta: Me
|
|
56
56
|
}
|
|
57
57
|
]
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
-
function
|
|
60
|
+
function Gs(e) {
|
|
61
61
|
Os(
|
|
62
62
|
e,
|
|
63
63
|
"todoist-task-list",
|
|
64
64
|
Le,
|
|
65
65
|
{
|
|
66
|
-
description:
|
|
67
|
-
_meta:
|
|
66
|
+
description: Ne,
|
|
67
|
+
_meta: Me
|
|
68
68
|
},
|
|
69
69
|
async () => pt(Le)
|
|
70
70
|
), e.registerResource(
|
|
71
71
|
"todoist-task-list-hash-fallback",
|
|
72
72
|
new Ds(qs, { list: void 0 }),
|
|
73
73
|
{
|
|
74
|
-
description: `${
|
|
74
|
+
description: `${Ne} compatibility fallback`,
|
|
75
75
|
mimeType: Lt,
|
|
76
|
-
_meta:
|
|
76
|
+
_meta: Me
|
|
77
77
|
},
|
|
78
78
|
async (t) => pt(t.toString())
|
|
79
79
|
);
|
|
@@ -111,7 +111,7 @@ function Vs(e) {
|
|
|
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
|
|
114
|
+
function R(e, t = 220) {
|
|
115
115
|
const r = Vs(e).replace(/\s+/g, " ").trim();
|
|
116
116
|
return r.length <= t ? r : `${r.slice(0, t - 3)}...`;
|
|
117
117
|
}
|
|
@@ -126,13 +126,13 @@ function xe(e) {
|
|
|
126
126
|
if (t?.[1])
|
|
127
127
|
return E(t[1]);
|
|
128
128
|
}
|
|
129
|
-
function
|
|
129
|
+
function G(e) {
|
|
130
130
|
const t = w(e);
|
|
131
131
|
if (t)
|
|
132
|
-
return
|
|
132
|
+
return R(t);
|
|
133
133
|
if (Array.isArray(e)) {
|
|
134
134
|
const n = e.map((a) => J(a) ? w(a.message) || w(a.error) : w(a)).filter((a) => !!a);
|
|
135
|
-
return n.length > 0 ?
|
|
135
|
+
return n.length > 0 ? R(n.slice(0, 2).join("; ")) : void 0;
|
|
136
136
|
}
|
|
137
137
|
if (!J(e))
|
|
138
138
|
return;
|
|
@@ -144,20 +144,20 @@ function K(e) {
|
|
|
144
144
|
w(e.description)
|
|
145
145
|
);
|
|
146
146
|
if (r)
|
|
147
|
-
return
|
|
147
|
+
return R(r);
|
|
148
148
|
const o = [];
|
|
149
149
|
for (const [n, a] of Object.entries(e)) {
|
|
150
150
|
const i = w(a);
|
|
151
151
|
if (i && (o.push(`${n}: ${i}`), o.length >= 2))
|
|
152
152
|
break;
|
|
153
153
|
}
|
|
154
|
-
return o.length > 0 ?
|
|
154
|
+
return o.length > 0 ? R(o.join("; ")) : void 0;
|
|
155
155
|
}
|
|
156
156
|
function Js(e) {
|
|
157
157
|
if (!e)
|
|
158
158
|
return [];
|
|
159
159
|
const t = /* @__PURE__ */ new Set(), r = (i) => {
|
|
160
|
-
i && t.add(
|
|
160
|
+
i && t.add(R(i, 120));
|
|
161
161
|
}, o = L(
|
|
162
162
|
w(e.field),
|
|
163
163
|
w(e.parameter),
|
|
@@ -297,24 +297,24 @@ function Ve(e) {
|
|
|
297
297
|
), d = [
|
|
298
298
|
w(n?.error),
|
|
299
299
|
w(n?.message),
|
|
300
|
-
|
|
300
|
+
G(n?.message),
|
|
301
301
|
w(t?.message),
|
|
302
302
|
w(r?.message),
|
|
303
303
|
e instanceof Error ? e.message : w(e)
|
|
304
304
|
].filter((h) => !!h), l = d.find((h) => !He(h)) || d[0], u = L(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
305
|
+
G(n?.errorExtra),
|
|
306
|
+
G(n?.error_extra),
|
|
307
|
+
G(n?.details),
|
|
308
|
+
G(n?.errorDetails),
|
|
309
|
+
G(n?.errors),
|
|
310
|
+
G(t?.details)
|
|
311
311
|
), p = Js(n);
|
|
312
312
|
return a !== void 0 || Zs(n) || c !== void 0 || i !== void 0 || (l ? He(l) : !1) ? {
|
|
313
313
|
statusCode: a,
|
|
314
314
|
code: i,
|
|
315
|
-
tag: c ?
|
|
316
|
-
message: l ?
|
|
317
|
-
details: u ?
|
|
315
|
+
tag: c ? R(c, 80) : void 0,
|
|
316
|
+
message: l ? R(l) : void 0,
|
|
317
|
+
details: u ? R(u) : void 0,
|
|
318
318
|
rawText: d,
|
|
319
319
|
fieldHints: p
|
|
320
320
|
} : null;
|
|
@@ -331,19 +331,19 @@ function sr(e) {
|
|
|
331
331
|
`);
|
|
332
332
|
}
|
|
333
333
|
function Bt(e) {
|
|
334
|
-
return e instanceof Error ?
|
|
334
|
+
return e instanceof Error ? R(e.message) : typeof e == "string" ? R(e) : "An unknown error occurred";
|
|
335
335
|
}
|
|
336
336
|
class ve extends Error {
|
|
337
337
|
constructor(t) {
|
|
338
338
|
super(t), this.name = "DueStringParseError";
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
|
-
class
|
|
341
|
+
class zt extends Error {
|
|
342
342
|
constructor(t) {
|
|
343
343
|
super(t), this.name = "BatchDueStringParseError";
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
|
-
function
|
|
346
|
+
function z(e) {
|
|
347
347
|
if (e instanceof ve)
|
|
348
348
|
return e.message;
|
|
349
349
|
const t = Ve(e);
|
|
@@ -366,12 +366,12 @@ function rr(e, {
|
|
|
366
366
|
return d !== r.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 !== r.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
368
|
function or(e) {
|
|
369
|
-
if (e instanceof
|
|
369
|
+
if (e instanceof _s || e instanceof ve || e instanceof zt)
|
|
370
370
|
return e.message;
|
|
371
371
|
const t = Ve(e);
|
|
372
372
|
return t ? sr(t) : Bt(e);
|
|
373
373
|
}
|
|
374
|
-
const nr = "12.5.
|
|
374
|
+
const nr = "12.5.3", ar = {
|
|
375
375
|
version: nr
|
|
376
376
|
}, C = {
|
|
377
377
|
/** Default limit for task listings */
|
|
@@ -407,7 +407,7 @@ const nr = "12.5.2", ar = {
|
|
|
407
407
|
}, fe = {
|
|
408
408
|
/** Maximum number of failures to show in detailed error messages */
|
|
409
409
|
MAX_FAILURES_SHOWN: 3
|
|
410
|
-
},
|
|
410
|
+
}, Kt = {
|
|
411
411
|
/** Maximum tasks accepted by one task create or update operation */
|
|
412
412
|
TASKS_PER_OPERATION: 25
|
|
413
413
|
}, Be = {
|
|
@@ -481,32 +481,32 @@ function qt() {
|
|
|
481
481
|
writes: mt(Be.WRITES)
|
|
482
482
|
};
|
|
483
483
|
}
|
|
484
|
-
const ht = /* @__PURE__ */ new Map(),
|
|
484
|
+
const ht = /* @__PURE__ */ new Map(), Yt = /* @__PURE__ */ new WeakMap();
|
|
485
485
|
let ft;
|
|
486
486
|
function ir() {
|
|
487
487
|
return ft ??= qt(), ft;
|
|
488
488
|
}
|
|
489
489
|
function cr(e) {
|
|
490
|
-
return
|
|
490
|
+
return Rt("sha256").update(e).digest("hex");
|
|
491
491
|
}
|
|
492
492
|
function dr(e, t) {
|
|
493
493
|
const r = cr(t);
|
|
494
494
|
let o = ht.get(r);
|
|
495
|
-
o || (o = qt(), ht.set(r, o)),
|
|
495
|
+
o || (o = qt(), ht.set(r, o)), Yt.set(e, o);
|
|
496
496
|
}
|
|
497
|
-
function
|
|
498
|
-
return
|
|
497
|
+
function Gt(e) {
|
|
498
|
+
return Yt.get(e) ?? ir();
|
|
499
499
|
}
|
|
500
500
|
function lr(e) {
|
|
501
|
-
return
|
|
501
|
+
return Gt(e).moves;
|
|
502
502
|
}
|
|
503
503
|
function ur(e) {
|
|
504
|
-
return
|
|
504
|
+
return Gt(e).writes;
|
|
505
505
|
}
|
|
506
|
-
const pr = "todoist-mcp", Je = ar.version, Vt = new
|
|
507
|
-
let
|
|
506
|
+
const pr = "todoist-mcp", Je = ar.version, Vt = new Rs(), bt = Us(import.meta.url);
|
|
507
|
+
let Te;
|
|
508
508
|
const mr = async () => {
|
|
509
|
-
const e = bt.resolve("@doist/todoist-sdk"), t =
|
|
509
|
+
const e = bt.resolve("@doist/todoist-sdk"), t = _e(Ut(e), "transport", "http-dispatcher.js");
|
|
510
510
|
return bt(t);
|
|
511
511
|
};
|
|
512
512
|
let hr = mr;
|
|
@@ -543,7 +543,7 @@ function yr(e, t) {
|
|
|
543
543
|
function gt() {
|
|
544
544
|
return new DOMException("The operation was aborted due to timeout", "TimeoutError");
|
|
545
545
|
}
|
|
546
|
-
function
|
|
546
|
+
function Tr(e, t) {
|
|
547
547
|
if (!e && t === void 0)
|
|
548
548
|
return {
|
|
549
549
|
signal: void 0,
|
|
@@ -581,17 +581,17 @@ function kr(e, t) {
|
|
|
581
581
|
}
|
|
582
582
|
};
|
|
583
583
|
}
|
|
584
|
-
async function
|
|
584
|
+
async function kr() {
|
|
585
585
|
if (wr())
|
|
586
|
-
return
|
|
587
|
-
throw
|
|
588
|
-
})),
|
|
586
|
+
return Te || (Te = hr().then((e) => e.getDefaultDispatcher()).catch((e) => {
|
|
587
|
+
throw Te = void 0, e;
|
|
588
|
+
})), Te;
|
|
589
589
|
}
|
|
590
590
|
function wr() {
|
|
591
591
|
return typeof process < "u" && !!process.versions?.node;
|
|
592
592
|
}
|
|
593
593
|
async function vr(e) {
|
|
594
|
-
const t = await
|
|
594
|
+
const t = await kr();
|
|
595
595
|
t !== void 0 && (e.dispatcher = t);
|
|
596
596
|
}
|
|
597
597
|
function Ir(e) {
|
|
@@ -605,10 +605,10 @@ function Ir(e) {
|
|
|
605
605
|
arrayBuffer: () => e.arrayBuffer()
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
|
-
function
|
|
608
|
+
function Sr(e = globalThis.fetch, t = {}) {
|
|
609
609
|
const r = e === globalThis.fetch, { enabled: o = !0, platform: n = "mcp", sessionId: a = Pe() } = t;
|
|
610
610
|
return async (i, c = {}) => {
|
|
611
|
-
const { timeout: d, headers: l, signal: u, ...p } = c, { signal: m, cleanup: h } =
|
|
611
|
+
const { timeout: d, headers: l, signal: u, ...p } = c, { signal: m, cleanup: h } = Tr(u, d);
|
|
612
612
|
try {
|
|
613
613
|
const y = {
|
|
614
614
|
...p,
|
|
@@ -623,12 +623,12 @@ function jr(e = globalThis.fetch, t = {}) {
|
|
|
623
623
|
}
|
|
624
624
|
};
|
|
625
625
|
}
|
|
626
|
-
function
|
|
626
|
+
function jr(e, {
|
|
627
627
|
baseUrl: t,
|
|
628
628
|
tracking: r
|
|
629
629
|
} = {}) {
|
|
630
630
|
const o = new Ls(e, {
|
|
631
|
-
customFetch:
|
|
631
|
+
customFetch: Sr(globalThis.fetch, r),
|
|
632
632
|
...t ? { baseUrl: t } : {}
|
|
633
633
|
});
|
|
634
634
|
return dr(o, e), o;
|
|
@@ -663,7 +663,7 @@ function Pr({
|
|
|
663
663
|
const n = Math.min(t * 2 ** e, r), a = Math.round(o() * n);
|
|
664
664
|
return Math.min(n, Math.max(xr, a));
|
|
665
665
|
}
|
|
666
|
-
function
|
|
666
|
+
function _r(e) {
|
|
667
667
|
return new Promise((t) => setTimeout(t, e));
|
|
668
668
|
}
|
|
669
669
|
async function O(e, t = {}) {
|
|
@@ -675,23 +675,23 @@ async function O(e, t = {}) {
|
|
|
675
675
|
} catch (d) {
|
|
676
676
|
if (i = d, c < r && Or(d)) {
|
|
677
677
|
const l = Pr({ attempt: c, baseDelayMs: o, maxDelayMs: n, random: a });
|
|
678
|
-
await
|
|
678
|
+
await _r(l);
|
|
679
679
|
continue;
|
|
680
680
|
}
|
|
681
681
|
throw d;
|
|
682
682
|
}
|
|
683
683
|
throw i;
|
|
684
684
|
}
|
|
685
|
-
function
|
|
685
|
+
function ze(e) {
|
|
686
686
|
if (e == null)
|
|
687
687
|
return e;
|
|
688
688
|
if (Array.isArray(e))
|
|
689
|
-
return e.map((t) =>
|
|
689
|
+
return e.map((t) => ze(t));
|
|
690
690
|
if (typeof e == "object") {
|
|
691
691
|
const t = {};
|
|
692
692
|
for (const [r, o] of Object.entries(e))
|
|
693
693
|
if (o !== null) {
|
|
694
|
-
const n =
|
|
694
|
+
const n = ze(o);
|
|
695
695
|
if (n !== null && typeof n == "object" && !Array.isArray(n) && Object.keys(n).length === 0)
|
|
696
696
|
continue;
|
|
697
697
|
t[r] = n;
|
|
@@ -769,14 +769,14 @@ const g = {
|
|
|
769
769
|
* Affects: find-project-collaborators, find-completed-tasks
|
|
770
770
|
*/
|
|
771
771
|
STRIP_EMAILS: "strip_emails"
|
|
772
|
-
},
|
|
772
|
+
}, Rr = process.env.USE_STRUCTURED_CONTENT === "true" || process.env.NODE_ENV === "test";
|
|
773
773
|
function Ur({
|
|
774
774
|
textContent: e,
|
|
775
775
|
structuredContent: t,
|
|
776
776
|
contentItems: r
|
|
777
777
|
}) {
|
|
778
|
-
const o =
|
|
779
|
-
return r && a.push(...r), !
|
|
778
|
+
const o = ze(t), n = {}, a = [];
|
|
779
|
+
return r && a.push(...r), !Rr && t && a.push({
|
|
780
780
|
type: "text",
|
|
781
781
|
text: JSON.stringify(o)
|
|
782
782
|
}), e && a.push({ type: "text", text: e }), a.length > 0 && (n.content = a), t && (n.structuredContent = o), n;
|
|
@@ -787,11 +787,11 @@ function Lr(e) {
|
|
|
787
787
|
isError: !0
|
|
788
788
|
};
|
|
789
789
|
}
|
|
790
|
-
const
|
|
791
|
-
function
|
|
790
|
+
const Nr = /* @__PURE__ */ new Set(["file"]);
|
|
791
|
+
function Mr(e) {
|
|
792
792
|
return !e || typeof e != "object" || Array.isArray(e) ? e : Object.fromEntries(
|
|
793
793
|
Object.entries(e).map(
|
|
794
|
-
([t, r]) =>
|
|
794
|
+
([t, r]) => Nr.has(t) && r !== void 0 ? [t, "[redacted]"] : [t, r]
|
|
795
795
|
)
|
|
796
796
|
);
|
|
797
797
|
}
|
|
@@ -811,24 +811,24 @@ const Br = [
|
|
|
811
811
|
g.FIND_PROJECT_COLLABORATORS,
|
|
812
812
|
g.FIND_COMPLETED_TASKS
|
|
813
813
|
];
|
|
814
|
-
function
|
|
814
|
+
function Ke(e) {
|
|
815
815
|
if (e == null)
|
|
816
816
|
return e;
|
|
817
817
|
if (Array.isArray(e))
|
|
818
|
-
return e.map((t) =>
|
|
818
|
+
return e.map((t) => Ke(t));
|
|
819
819
|
if (typeof e == "object") {
|
|
820
820
|
const t = {};
|
|
821
821
|
for (const [r, o] of Object.entries(e))
|
|
822
|
-
r !== "email" && (t[r] =
|
|
822
|
+
r !== "email" && (t[r] = Ke(o));
|
|
823
823
|
return t;
|
|
824
824
|
}
|
|
825
825
|
return e;
|
|
826
826
|
}
|
|
827
|
-
function
|
|
827
|
+
function zr(e) {
|
|
828
828
|
const t = /\s*\([^)]*@[^)]+\)/g, r = /\S+@\S+\.\S+/g;
|
|
829
829
|
return e.replace(t, "").replace(r, "[email hidden]");
|
|
830
830
|
}
|
|
831
|
-
function
|
|
831
|
+
function Kr({
|
|
832
832
|
tool: e,
|
|
833
833
|
server: t,
|
|
834
834
|
client: r,
|
|
@@ -840,9 +840,9 @@ function zr({
|
|
|
840
840
|
e.name,
|
|
841
841
|
() => O(() => a(d, r))
|
|
842
842
|
);
|
|
843
|
-
return n && (u && (u =
|
|
843
|
+
return n && (u && (u = zr(u)), p && (p = Ke(p))), Ur({ textContent: u, structuredContent: p, contentItems: m });
|
|
844
844
|
} catch (u) {
|
|
845
|
-
return console.error(`Error executing tool ${e.name}:`, { args:
|
|
845
|
+
return console.error(`Error executing tool ${e.name}:`, { args: Mr(d), error: u }), Lr(or(u));
|
|
846
846
|
}
|
|
847
847
|
}, c = {
|
|
848
848
|
description: e.description,
|
|
@@ -874,7 +874,7 @@ const qr = {
|
|
|
874
874
|
),
|
|
875
875
|
projectId: s.string().optional().describe("Optional project ID to scope the analysis to a specific project.")
|
|
876
876
|
};
|
|
877
|
-
function
|
|
877
|
+
function Yr(e, t = /* @__PURE__ */ new Date()) {
|
|
878
878
|
const r = (n) => n.toISOString().slice(0, 10), o = r(t);
|
|
879
879
|
switch (e) {
|
|
880
880
|
case "today":
|
|
@@ -921,7 +921,7 @@ function Gr(e, t = /* @__PURE__ */ new Date()) {
|
|
|
921
921
|
}
|
|
922
922
|
}
|
|
923
923
|
}
|
|
924
|
-
function
|
|
924
|
+
function Gr(e) {
|
|
925
925
|
const t = {
|
|
926
926
|
goals: `### Goal Tracking
|
|
927
927
|
- Compare tasks completed today vs the daily goal
|
|
@@ -953,7 +953,7 @@ function Kr(e) {
|
|
|
953
953
|
`) : t[e] ?? "";
|
|
954
954
|
}
|
|
955
955
|
function Vr(e) {
|
|
956
|
-
const { since: t, until: r, periodDescription: o } =
|
|
956
|
+
const { since: t, until: r, periodDescription: o } = Yr(e.period), n = e.projectId ? `
|
|
957
957
|
Scope this analysis to project ID: ${e.projectId}. Pass this projectId when calling find-completed-tasks and get-overview.` : "";
|
|
958
958
|
return `Analyze my Todoist productivity for ${o} (${t} to ${r}).${n}
|
|
959
959
|
|
|
@@ -974,7 +974,7 @@ ${e.focus === "overall" || e.focus === "projects" ? `4. **get-overview** — Get
|
|
|
974
974
|
|
|
975
975
|
Using the collected data, produce an analysis covering the following sections:
|
|
976
976
|
|
|
977
|
-
${
|
|
977
|
+
${Gr(e.focus)}
|
|
978
978
|
|
|
979
979
|
### Step 3: Format
|
|
980
980
|
|
|
@@ -1004,43 +1004,43 @@ const he = {
|
|
|
1004
1004
|
argsSchema: qr,
|
|
1005
1005
|
callback: Jr
|
|
1006
1006
|
};
|
|
1007
|
-
class
|
|
1007
|
+
class _ extends Error {
|
|
1008
1008
|
constructor(t, r) {
|
|
1009
1009
|
super(`Invalid duration format "${t}": ${r}`), this.name = "DurationParseError";
|
|
1010
1010
|
}
|
|
1011
1011
|
}
|
|
1012
1012
|
function Xt(e) {
|
|
1013
1013
|
if (!e || typeof e != "string")
|
|
1014
|
-
throw new
|
|
1014
|
+
throw new _(e, "Duration must be a non-empty string");
|
|
1015
1015
|
const t = e.trim().toLowerCase().replace(/\s+/g, "");
|
|
1016
1016
|
if (!t)
|
|
1017
|
-
throw new
|
|
1017
|
+
throw new _(e, "Duration must be a non-empty string");
|
|
1018
1018
|
const r = t.match(/^(?:(\d+(?:\.\d+)?)h)?(?:(\d+(?:\.\d+)?)m)?$/);
|
|
1019
1019
|
if (!r || !r[1] && !r[2])
|
|
1020
|
-
throw new
|
|
1020
|
+
throw new _(e, 'Use format like "2h", "30m", "2h30m", or "1.5h"');
|
|
1021
1021
|
let o = 0;
|
|
1022
1022
|
const [, n, a] = r;
|
|
1023
1023
|
if (n) {
|
|
1024
1024
|
const i = Number.parseFloat(n);
|
|
1025
1025
|
if (Number.isNaN(i) || i < 0)
|
|
1026
|
-
throw new
|
|
1026
|
+
throw new _(e, "Hours must be a positive number");
|
|
1027
1027
|
o += i * 60;
|
|
1028
1028
|
}
|
|
1029
1029
|
if (a) {
|
|
1030
1030
|
const i = Number.parseFloat(a);
|
|
1031
1031
|
if (Number.isNaN(i) || i < 0)
|
|
1032
|
-
throw new
|
|
1032
|
+
throw new _(e, "Minutes must be a positive number");
|
|
1033
1033
|
if (i % 1 !== 0)
|
|
1034
|
-
throw new
|
|
1034
|
+
throw new _(
|
|
1035
1035
|
e,
|
|
1036
1036
|
"Minutes must be a whole number (use decimal hours instead)"
|
|
1037
1037
|
);
|
|
1038
1038
|
o += i;
|
|
1039
1039
|
}
|
|
1040
1040
|
if (o = Math.round(o), o === 0)
|
|
1041
|
-
throw new
|
|
1041
|
+
throw new _(e, "Duration must be greater than 0 minutes");
|
|
1042
1042
|
if (o > 1440)
|
|
1043
|
-
throw new
|
|
1043
|
+
throw new _(e, "Duration cannot exceed 24 hours (1440 minutes)");
|
|
1044
1044
|
return { minutes: o };
|
|
1045
1045
|
}
|
|
1046
1046
|
function Xr(e) {
|
|
@@ -1194,7 +1194,7 @@ class ro {
|
|
|
1194
1194
|
const o = r === void 0 ? await this.getCacheScope(t) : r, n = this.getCacheKey(o, "all_collaborators"), a = n ? oe.get(n) : void 0;
|
|
1195
1195
|
if (a !== void 0) return a;
|
|
1196
1196
|
try {
|
|
1197
|
-
const c = (await
|
|
1197
|
+
const c = (await M({
|
|
1198
1198
|
apiMethod: t.getProjects.bind(t),
|
|
1199
1199
|
args: {}
|
|
1200
1200
|
})).filter((m) => m.isShared);
|
|
@@ -1264,19 +1264,19 @@ function no({
|
|
|
1264
1264
|
}) {
|
|
1265
1265
|
return t ? e.filter((n) => n.responsibleUid === t) : o === "unassignedOrMe" ? e.filter((n) => !n.responsibleUid || n.responsibleUid === r) : o === "assigned" ? e.filter((n) => n.responsibleUid && n.responsibleUid !== r) : e;
|
|
1266
1266
|
}
|
|
1267
|
-
function
|
|
1267
|
+
function N(e) {
|
|
1268
1268
|
return e?.toLowerCase() === "inbox";
|
|
1269
1269
|
}
|
|
1270
1270
|
async function de(e) {
|
|
1271
1271
|
const { projectId: t, user: r, client: o } = e;
|
|
1272
|
-
if (!
|
|
1272
|
+
if (!N(t))
|
|
1273
1273
|
return t;
|
|
1274
1274
|
const n = r || (o ? await o.getUser() : null);
|
|
1275
1275
|
if (!n)
|
|
1276
1276
|
throw new Error("Either user or client must be provided when resolving inbox project ID");
|
|
1277
1277
|
return n.inboxProjectId;
|
|
1278
1278
|
}
|
|
1279
|
-
async function
|
|
1279
|
+
async function M(e) {
|
|
1280
1280
|
const { apiMethod: t, args: r, limit: o = 100 } = e, n = [];
|
|
1281
1281
|
let a = null;
|
|
1282
1282
|
do {
|
|
@@ -1293,21 +1293,21 @@ function et(e) {
|
|
|
1293
1293
|
return /(?<!\\)(?:\\\\)*\*/.test(e) ? e : `*${e.replaceAll(/\\(?!\*)/g, "\\\\")}*`;
|
|
1294
1294
|
}
|
|
1295
1295
|
async function rs(e, t) {
|
|
1296
|
-
return
|
|
1296
|
+
return M({
|
|
1297
1297
|
apiMethod: e.searchProjects.bind(e),
|
|
1298
1298
|
args: { query: et(t) },
|
|
1299
1299
|
limit: C.PROJECTS_MAX
|
|
1300
1300
|
});
|
|
1301
1301
|
}
|
|
1302
1302
|
async function os(e) {
|
|
1303
|
-
return
|
|
1303
|
+
return M({
|
|
1304
1304
|
apiMethod: e.getProjects.bind(e),
|
|
1305
1305
|
args: {},
|
|
1306
1306
|
limit: C.PROJECTS_MAX
|
|
1307
1307
|
});
|
|
1308
1308
|
}
|
|
1309
1309
|
async function ao(e) {
|
|
1310
|
-
return
|
|
1310
|
+
return M({
|
|
1311
1311
|
apiMethod: e.getArchivedProjects.bind(e),
|
|
1312
1312
|
args: {},
|
|
1313
1313
|
limit: C.PROJECTS_MAX
|
|
@@ -1323,14 +1323,14 @@ function io(e) {
|
|
|
1323
1323
|
return new RegExp(r ? `^${n}$` : n, "iu");
|
|
1324
1324
|
}
|
|
1325
1325
|
async function co(e, t) {
|
|
1326
|
-
return
|
|
1326
|
+
return M({
|
|
1327
1327
|
apiMethod: e.searchLabels.bind(e),
|
|
1328
1328
|
args: { query: et(t) },
|
|
1329
1329
|
limit: C.LABELS_MAX
|
|
1330
1330
|
});
|
|
1331
1331
|
}
|
|
1332
1332
|
async function lo(e) {
|
|
1333
|
-
return
|
|
1333
|
+
return M({
|
|
1334
1334
|
apiMethod: e.getSharedLabels.bind(e),
|
|
1335
1335
|
args: {},
|
|
1336
1336
|
limit: C.LABELS_MAX
|
|
@@ -1338,7 +1338,7 @@ async function lo(e) {
|
|
|
1338
1338
|
}
|
|
1339
1339
|
async function uo(e, t, r) {
|
|
1340
1340
|
const o = et(t);
|
|
1341
|
-
return
|
|
1341
|
+
return M({
|
|
1342
1342
|
apiMethod: e.searchSections.bind(e),
|
|
1343
1343
|
args: r ? { query: o, projectId: r } : { query: o },
|
|
1344
1344
|
limit: C.SECTIONS_MAX
|
|
@@ -1376,8 +1376,8 @@ function Z(e) {
|
|
|
1376
1376
|
parentId: B(e) ? e.parentId ?? void 0 : void 0,
|
|
1377
1377
|
inboxProject: B(e) ? e.inboxProject ?? !1 : !1,
|
|
1378
1378
|
viewStyle: e.viewStyle,
|
|
1379
|
-
workspaceId:
|
|
1380
|
-
folderId:
|
|
1379
|
+
workspaceId: ke(e) ? e.workspaceId : void 0,
|
|
1380
|
+
folderId: ke(e) ? e.folderId ?? void 0 : void 0,
|
|
1381
1381
|
childOrder: e.childOrder,
|
|
1382
1382
|
isArchived: e.isArchived
|
|
1383
1383
|
};
|
|
@@ -1492,11 +1492,11 @@ function ns(e) {
|
|
|
1492
1492
|
).length, r = e.filter((o) => o.type === "location").length;
|
|
1493
1493
|
return { timeBasedCount: t, locationCount: r };
|
|
1494
1494
|
}
|
|
1495
|
-
const Ie =
|
|
1495
|
+
const Ie = Re.map((e) => e.key);
|
|
1496
1496
|
function ho(e) {
|
|
1497
1497
|
if (typeof e != "string") return;
|
|
1498
1498
|
const t = e.toLowerCase();
|
|
1499
|
-
return (
|
|
1499
|
+
return (Re.find((o) => o.key === t) ?? Re.find((o) => o.displayName.toLowerCase() === t))?.key;
|
|
1500
1500
|
}
|
|
1501
1501
|
const fo = `Color for the entity. Accepts a color key (e.g. "berry_red") or display name (e.g. "Berry Red"). Valid colors: ${Ie.join(", ")}. Unrecognized colors are omitted and charcoal will be used as the default.`, le = s.preprocess(ho, s.enum(Ie).optional()).describe(fo);
|
|
1502
1502
|
s.enum(Ie);
|
|
@@ -1539,7 +1539,7 @@ const ue = s.enum(Ie).optional().catch(void 0), F = s.object({
|
|
|
1539
1539
|
sectionOrder: s.number().describe("Ordering index within the project."),
|
|
1540
1540
|
description: s.string().optional().describe("Supports Markdown.")
|
|
1541
1541
|
});
|
|
1542
|
-
function
|
|
1542
|
+
function K({ id: e, name: t, sectionOrder: r, description: o }) {
|
|
1543
1543
|
return { id: e, name: t, sectionOrder: r, description: o ?? void 0 };
|
|
1544
1544
|
}
|
|
1545
1545
|
const bo = s.object({
|
|
@@ -1583,7 +1583,7 @@ const bo = s.object({
|
|
|
1583
1583
|
color: ue,
|
|
1584
1584
|
order: s.number().optional().catch(void 0).describe("Display order."),
|
|
1585
1585
|
isFavorite: s.boolean()
|
|
1586
|
-
}),
|
|
1586
|
+
}), To = s.object({
|
|
1587
1587
|
isRecurring: s.boolean(),
|
|
1588
1588
|
string: s.string().describe("Human-readable due string."),
|
|
1589
1589
|
date: s.string().describe("ISO 8601."),
|
|
@@ -1592,27 +1592,27 @@ const bo = s.object({
|
|
|
1592
1592
|
}), st = s.object({
|
|
1593
1593
|
id: s.string(),
|
|
1594
1594
|
taskId: s.string(),
|
|
1595
|
-
type: s.enum(
|
|
1595
|
+
type: s.enum(Ns),
|
|
1596
1596
|
minuteOffset: s.number().optional().describe("Minutes before due. Relative reminders only."),
|
|
1597
|
-
due:
|
|
1597
|
+
due: To.optional().describe("Absolute, and sometimes relative, reminders."),
|
|
1598
1598
|
name: s.string().optional().describe("Location name. Location reminders only."),
|
|
1599
1599
|
locLat: s.string().optional().describe("Location reminders only."),
|
|
1600
1600
|
locLong: s.string().optional().describe("Location reminders only."),
|
|
1601
|
-
locTrigger: s.enum(
|
|
1601
|
+
locTrigger: s.enum(Nt).optional().describe("Location reminders only."),
|
|
1602
1602
|
radius: s.number().optional().describe("Geofence radius in metres. Location reminders only."),
|
|
1603
1603
|
isUrgent: s.boolean().optional().describe("Relative and absolute reminders only.")
|
|
1604
1604
|
}), ee = s.object({
|
|
1605
1605
|
item: s.string().describe("Usually the ID of the item that failed."),
|
|
1606
1606
|
error: s.string(),
|
|
1607
1607
|
code: s.string().optional()
|
|
1608
|
-
}),
|
|
1608
|
+
}), ko = s.object({
|
|
1609
1609
|
taskId: s.string().optional().describe("The ID of the task to comment on."),
|
|
1610
1610
|
projectId: s.string().optional().describe(
|
|
1611
1611
|
'The ID of the project to comment on. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
1612
1612
|
),
|
|
1613
1613
|
content: s.string().min(1).describe("The content of the comment.")
|
|
1614
1614
|
}), wo = {
|
|
1615
|
-
comments: s.array(
|
|
1615
|
+
comments: s.array(ko).min(1).describe("The array of comments to add.")
|
|
1616
1616
|
}, vo = {
|
|
1617
1617
|
comments: s.array(ye).describe("The created comments."),
|
|
1618
1618
|
totalCount: s.number().describe("The total number of comments created."),
|
|
@@ -1635,7 +1635,7 @@ const bo = s.object({
|
|
|
1635
1635
|
`Comment ${l + 1}: Cannot provide both taskId and projectId. Choose one.`
|
|
1636
1636
|
);
|
|
1637
1637
|
}
|
|
1638
|
-
const n = r.some((l) =>
|
|
1638
|
+
const n = r.some((l) => N(l.projectId)) ? await t.getUser() : void 0, a = r.map(async ({ content: l, taskId: u, projectId: p }) => {
|
|
1639
1639
|
const m = await de({
|
|
1640
1640
|
projectId: p,
|
|
1641
1641
|
user: n,
|
|
@@ -1647,7 +1647,7 @@ const bo = s.object({
|
|
|
1647
1647
|
});
|
|
1648
1648
|
}), c = (await Promise.all(a)).map(ge);
|
|
1649
1649
|
return {
|
|
1650
|
-
textContent:
|
|
1650
|
+
textContent: So({ comments: c }),
|
|
1651
1651
|
structuredContent: {
|
|
1652
1652
|
comments: c,
|
|
1653
1653
|
totalCount: c.length,
|
|
@@ -1656,7 +1656,7 @@ const bo = s.object({
|
|
|
1656
1656
|
};
|
|
1657
1657
|
}
|
|
1658
1658
|
};
|
|
1659
|
-
function
|
|
1659
|
+
function So({ comments: e }) {
|
|
1660
1660
|
const t = e.filter((a) => a.taskId).length, r = e.filter((a) => a.projectId).length, o = [];
|
|
1661
1661
|
if (t > 0) {
|
|
1662
1662
|
const a = t > 1 ? "comments" : "comment";
|
|
@@ -1668,7 +1668,7 @@ function jo({ comments: e }) {
|
|
|
1668
1668
|
}
|
|
1669
1669
|
return o.length > 0 ? `Added ${o.join(" and ")}` : "No comments added";
|
|
1670
1670
|
}
|
|
1671
|
-
const
|
|
1671
|
+
const jo = {
|
|
1672
1672
|
search: s.string().optional().describe(
|
|
1673
1673
|
"Search for a filter by name (partial and case insensitive match). If omitted, all filters are returned."
|
|
1674
1674
|
)
|
|
@@ -1685,7 +1685,7 @@ const So = {
|
|
|
1685
1685
|
}, $o = {
|
|
1686
1686
|
name: g.FIND_FILTERS,
|
|
1687
1687
|
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").',
|
|
1688
|
-
parameters:
|
|
1688
|
+
parameters: jo,
|
|
1689
1689
|
outputSchema: Co,
|
|
1690
1690
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
1691
1691
|
async execute(e, t) {
|
|
@@ -1789,16 +1789,16 @@ ${l}`,
|
|
|
1789
1789
|
color: le,
|
|
1790
1790
|
order: s.number().int().optional().describe("The position of the label in the label list."),
|
|
1791
1791
|
isFavorite: s.boolean().optional().describe("Whether the label is a favorite. Defaults to false.")
|
|
1792
|
-
}),
|
|
1792
|
+
}), _o = {
|
|
1793
1793
|
labels: s.array(Po).min(1).describe("The array of labels to add.")
|
|
1794
|
-
},
|
|
1794
|
+
}, Ro = {
|
|
1795
1795
|
labels: s.array(pe).describe("The created labels."),
|
|
1796
1796
|
totalCount: s.number().describe("The total number of labels created.")
|
|
1797
1797
|
}, Uo = {
|
|
1798
1798
|
name: g.ADD_LABELS,
|
|
1799
1799
|
description: "Add one or more new personal labels.",
|
|
1800
|
-
parameters:
|
|
1801
|
-
outputSchema:
|
|
1800
|
+
parameters: _o,
|
|
1801
|
+
outputSchema: Ro,
|
|
1802
1802
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
|
|
1803
1803
|
async execute({ labels: e }, t) {
|
|
1804
1804
|
const r = await Promise.all(e.map((n) => t.addLabel(n)));
|
|
@@ -1826,7 +1826,7 @@ function ot(e, t, r = {}) {
|
|
|
1826
1826
|
i.push(d);
|
|
1827
1827
|
const l = 5;
|
|
1828
1828
|
if (n || a <= l) {
|
|
1829
|
-
const u =
|
|
1829
|
+
const u = Se(t, l);
|
|
1830
1830
|
if (u.length > 0) {
|
|
1831
1831
|
const p = a > l ? `, +${a - l} more` : "";
|
|
1832
1832
|
i.push(`Tasks:
|
|
@@ -1861,11 +1861,11 @@ function at(e, t) {
|
|
|
1861
1861
|
Failed (${t.length}) - address or drop these items:
|
|
1862
1862
|
${n}${a}`;
|
|
1863
1863
|
}
|
|
1864
|
-
function
|
|
1864
|
+
function No(e) {
|
|
1865
1865
|
const t = e.content || e.title || "Untitled", r = e.dueDate ? ` • due ${e.dueDate}` : "", o = e.priority ? ` • ${e.priority.toUpperCase()}` : "", n = e.projectName ? ` • ${e.projectName}` : "", a = e.id ? ` • id=${e.id}` : "";
|
|
1866
1866
|
return ` ${t}${r}${o}${n}${a}`;
|
|
1867
1867
|
}
|
|
1868
|
-
function
|
|
1868
|
+
function Mo(e) {
|
|
1869
1869
|
const t = ` (${e.color})`, r = e.isFavorite ? " • ⭐" : "", o = ` • id=${e.id}`;
|
|
1870
1870
|
return ` ${e.name}${t}${r}${o}`;
|
|
1871
1871
|
}
|
|
@@ -1873,8 +1873,8 @@ function Fo(e) {
|
|
|
1873
1873
|
const t = e.inboxProject ? " • Inbox" : "", r = e.isFavorite ? " • ⭐" : "", o = e.isShared ? " • Shared" : "", n = e.isArchived ? " • Archived" : "", a = e.viewStyle && e.viewStyle !== "list" ? ` • ${e.viewStyle}` : "", i = ` • id=${e.id}`;
|
|
1874
1874
|
return ` ${e.name}${t}${r}${o}${n}${a}${i}`;
|
|
1875
1875
|
}
|
|
1876
|
-
function
|
|
1877
|
-
const o = e.slice(0, t).map(
|
|
1876
|
+
function Se(e, t = 5) {
|
|
1877
|
+
const o = e.slice(0, t).map(No).join(`
|
|
1878
1878
|
`);
|
|
1879
1879
|
if (e.length > t) {
|
|
1880
1880
|
const n = e.length - t;
|
|
@@ -1968,7 +1968,7 @@ ${u}` + (d.length > 5 ? `
|
|
|
1968
1968
|
this.cache = null;
|
|
1969
1969
|
}
|
|
1970
1970
|
}
|
|
1971
|
-
const is = new Bo(),
|
|
1971
|
+
const is = new Bo(), zo = s.object({
|
|
1972
1972
|
name: s.string().min(1).describe("The name of the project."),
|
|
1973
1973
|
parentId: s.string().optional().describe("The ID of the parent project. If provided, creates this as a sub-project."),
|
|
1974
1974
|
isFavorite: s.boolean().optional().describe("Whether the project is a favorite. Defaults to false."),
|
|
@@ -1978,8 +1978,8 @@ const is = new Bo(), Yo = s.object({
|
|
|
1978
1978
|
workspace: s.string().trim().min(1).optional().describe(
|
|
1979
1979
|
"The workspace to create the project in. Accepts a workspace name or workspace ID. If not provided, creates a personal project. Use list-workspaces to see available workspaces."
|
|
1980
1980
|
)
|
|
1981
|
-
}),
|
|
1982
|
-
projects: s.array(
|
|
1981
|
+
}), Ko = {
|
|
1982
|
+
projects: s.array(zo).min(1).describe("The array of projects to add.")
|
|
1983
1983
|
}, qo = {
|
|
1984
1984
|
projects: s.array(Q).describe("The created projects."),
|
|
1985
1985
|
totalCount: s.number().describe("The total number of projects created."),
|
|
@@ -1989,10 +1989,10 @@ const is = new Bo(), Yo = s.object({
|
|
|
1989
1989
|
totalRequested: s.number().describe("The total number of projects requested."),
|
|
1990
1990
|
successCount: s.number().describe("The number of successfully created projects."),
|
|
1991
1991
|
failureCount: s.number().describe("The number of failed project creations.")
|
|
1992
|
-
},
|
|
1992
|
+
}, Yo = {
|
|
1993
1993
|
name: g.ADD_PROJECTS,
|
|
1994
1994
|
description: "Add one or more new projects.",
|
|
1995
|
-
parameters:
|
|
1995
|
+
parameters: Ko,
|
|
1996
1996
|
outputSchema: qo,
|
|
1997
1997
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
|
|
1998
1998
|
async execute({ projects: e }, t) {
|
|
@@ -2014,12 +2014,12 @@ const is = new Bo(), Yo = s.object({
|
|
|
2014
2014
|
n.forEach((l, u) => {
|
|
2015
2015
|
l.status === "fulfilled" ? a.push(l.value) : i.push({
|
|
2016
2016
|
item: e[u]?.name ?? `Project ${u + 1}`,
|
|
2017
|
-
error:
|
|
2017
|
+
error: z(l.reason)
|
|
2018
2018
|
});
|
|
2019
2019
|
});
|
|
2020
2020
|
const c = a.map(Z);
|
|
2021
2021
|
return {
|
|
2022
|
-
textContent:
|
|
2022
|
+
textContent: Go({ projects: a, failures: i }),
|
|
2023
2023
|
structuredContent: {
|
|
2024
2024
|
projects: c,
|
|
2025
2025
|
totalCount: c.length,
|
|
@@ -2031,7 +2031,7 @@ const is = new Bo(), Yo = s.object({
|
|
|
2031
2031
|
};
|
|
2032
2032
|
}
|
|
2033
2033
|
};
|
|
2034
|
-
function
|
|
2034
|
+
function Go({
|
|
2035
2035
|
projects: e,
|
|
2036
2036
|
failures: t
|
|
2037
2037
|
}) {
|
|
@@ -2040,18 +2040,18 @@ function Ko({
|
|
|
2040
2040
|
${o}` : "Added 0 projects";
|
|
2041
2041
|
return at(n, t);
|
|
2042
2042
|
}
|
|
2043
|
-
const we = 25,
|
|
2043
|
+
const we = 25, je = s.enum(Ms), cs = s.object({
|
|
2044
2044
|
date: s.string().optional().describe("Due date in YYYY-MM-DD format."),
|
|
2045
2045
|
string: s.string().optional().describe('Natural language due string, e.g. "tomorrow at 3pm".'),
|
|
2046
2046
|
timezone: s.string().optional().describe('Timezone for the reminder, e.g. "America/New_York".'),
|
|
2047
2047
|
lang: s.string().optional().describe('Language for parsing the due string, e.g. "en".')
|
|
2048
|
-
}), ds = s.enum(
|
|
2048
|
+
}), ds = s.enum(Nt), Ce = s.boolean().optional().describe("Whether this is an urgent reminder. Applies to relative and absolute reminders."), Vo = s.object({
|
|
2049
2049
|
type: s.literal("relative"),
|
|
2050
2050
|
taskId: s.string().min(1).describe("The ID of the task to set a reminder for."),
|
|
2051
2051
|
minuteOffset: s.number().int().min(0).describe(
|
|
2052
2052
|
"Minutes before the task due time to trigger the reminder. E.g., 30 for 30 minutes before, 60 for 1 hour before, 1440 for 1 day before."
|
|
2053
2053
|
),
|
|
2054
|
-
service:
|
|
2054
|
+
service: je.optional().describe(
|
|
2055
2055
|
'Delivery method: "email" or "push" notification. Defaults to push.'
|
|
2056
2056
|
),
|
|
2057
2057
|
isUrgent: Ce
|
|
@@ -2059,7 +2059,7 @@ const we = 25, Se = s.enum(Ns), cs = s.object({
|
|
|
2059
2059
|
type: s.literal("absolute"),
|
|
2060
2060
|
taskId: s.string().min(1).describe("The ID of the task to set a reminder for."),
|
|
2061
2061
|
due: cs.describe("The specific date/time for the reminder."),
|
|
2062
|
-
service:
|
|
2062
|
+
service: je.optional().describe(
|
|
2063
2063
|
'Delivery method: "email" or "push" notification. Defaults to push.'
|
|
2064
2064
|
),
|
|
2065
2065
|
isUrgent: Ce
|
|
@@ -2167,9 +2167,9 @@ const rn = s.object({
|
|
|
2167
2167
|
outputSchema: nn,
|
|
2168
2168
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
|
|
2169
2169
|
async execute({ sections: e }, t) {
|
|
2170
|
-
const r = e.some((c) =>
|
|
2170
|
+
const r = e.some((c) => N(c.projectId)) ? O(() => t.getUser()) : void 0, o = await Promise.allSettled(
|
|
2171
2171
|
e.map(async (c) => {
|
|
2172
|
-
const d =
|
|
2172
|
+
const d = N(c.projectId) ? await r : void 0, l = await de({
|
|
2173
2173
|
projectId: c.projectId,
|
|
2174
2174
|
user: d,
|
|
2175
2175
|
client: void 0
|
|
@@ -2180,12 +2180,12 @@ const rn = s.object({
|
|
|
2180
2180
|
return o.forEach((c, d) => {
|
|
2181
2181
|
c.status === "fulfilled" ? n.push(c.value) : a.push({
|
|
2182
2182
|
item: e[d]?.name ?? `Section ${d + 1}`,
|
|
2183
|
-
error:
|
|
2183
|
+
error: z(c.reason)
|
|
2184
2184
|
});
|
|
2185
2185
|
}), {
|
|
2186
2186
|
textContent: cn({ sections: n, failures: a }),
|
|
2187
2187
|
structuredContent: {
|
|
2188
|
-
sections: n.map(
|
|
2188
|
+
sections: n.map(K),
|
|
2189
2189
|
totalCount: n.length,
|
|
2190
2190
|
failures: a,
|
|
2191
2191
|
totalRequested: e.length,
|
|
@@ -2426,7 +2426,7 @@ const it = new dn();
|
|
|
2426
2426
|
function U(e) {
|
|
2427
2427
|
return s.string().transform((t) => t === "" ? void 0 : t).optional().describe(e);
|
|
2428
2428
|
}
|
|
2429
|
-
const
|
|
2429
|
+
const Tt = Kt.TASKS_PER_OPERATION, ln = s.object({
|
|
2430
2430
|
content: s.string().min(1).describe(
|
|
2431
2431
|
'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.'
|
|
2432
2432
|
),
|
|
@@ -2456,8 +2456,8 @@ const kt = zt.TASKS_PER_OPERATION, ln = s.object({
|
|
|
2456
2456
|
isUncompletable: s.boolean().optional().describe(
|
|
2457
2457
|
"Whether this task should be uncompletable (organizational header). Tasks with isUncompletable: true appear as organizational headers and cannot be completed."
|
|
2458
2458
|
)
|
|
2459
|
-
}),
|
|
2460
|
-
tasks: s.array(ln).min(1).max(
|
|
2459
|
+
}), kt = {
|
|
2460
|
+
tasks: s.array(ln).min(1).max(Tt).describe(`The array of tasks to add (max ${Tt}).`)
|
|
2461
2461
|
}, un = {
|
|
2462
2462
|
tasks: s.array(F).describe("The created tasks."),
|
|
2463
2463
|
totalCount: s.number().describe("The total number of tasks created."),
|
|
@@ -2468,11 +2468,11 @@ const kt = zt.TASKS_PER_OPERATION, ln = s.object({
|
|
|
2468
2468
|
}, pn = {
|
|
2469
2469
|
name: g.ADD_TASKS,
|
|
2470
2470
|
description: "Add one or more tasks to a project, section, or parent. Supports assignment to project collaborators.",
|
|
2471
|
-
parameters:
|
|
2471
|
+
parameters: kt,
|
|
2472
2472
|
outputSchema: un,
|
|
2473
2473
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
|
|
2474
2474
|
async execute(e, t) {
|
|
2475
|
-
const { tasks: r } = s.object(
|
|
2475
|
+
const { tasks: r } = s.object(kt).parse(e), o = /* @__PURE__ */ new Map();
|
|
2476
2476
|
r.forEach((m, h) => {
|
|
2477
2477
|
const y = mn(m), f = o.get(y);
|
|
2478
2478
|
f ? f.push({ task: m, index: h }) : o.set(y, [{ task: m, index: h }]);
|
|
@@ -2500,11 +2500,11 @@ const kt = zt.TASKS_PER_OPERATION, ln = s.object({
|
|
|
2500
2500
|
// Keep API error signals (status/code/tag) — `error.message`
|
|
2501
2501
|
// alone collapses e.g. a full-project rejection into a bare
|
|
2502
2502
|
// "HTTP 403: Forbidden"
|
|
2503
|
-
error:
|
|
2503
|
+
error: z(h.reason)
|
|
2504
2504
|
}));
|
|
2505
2505
|
if (c.length === 0 && d.length > 0) {
|
|
2506
2506
|
const m = d.map((y) => `"${y.item}": ${y.error}`).join("; "), h = `All ${d.length} task(s) failed to create: ${m}`;
|
|
2507
|
-
throw l ? new
|
|
2507
|
+
throw l ? new zt(h) : new Error(h);
|
|
2508
2508
|
}
|
|
2509
2509
|
const u = c.map(P);
|
|
2510
2510
|
return {
|
|
@@ -2539,7 +2539,7 @@ async function hn(e, t, r) {
|
|
|
2539
2539
|
labels: u,
|
|
2540
2540
|
deadlineDate: p,
|
|
2541
2541
|
...m
|
|
2542
|
-
} = e, h =
|
|
2542
|
+
} = e, h = N(n) ? void 0 : n;
|
|
2543
2543
|
if (h) {
|
|
2544
2544
|
const f = await t.getProject(h);
|
|
2545
2545
|
if (f.isArchived)
|
|
@@ -2569,7 +2569,7 @@ async function hn(e, t, r) {
|
|
|
2569
2569
|
durationUnit: "minute"
|
|
2570
2570
|
};
|
|
2571
2571
|
} catch (f) {
|
|
2572
|
-
throw f instanceof
|
|
2572
|
+
throw f instanceof _ ? new Error(`Task "${e.content}": ${f.message}`) : f;
|
|
2573
2573
|
}
|
|
2574
2574
|
if (d) {
|
|
2575
2575
|
let f = h;
|
|
@@ -2580,10 +2580,10 @@ async function hn(e, t, r) {
|
|
|
2580
2580
|
throw new Error(`Task "${e.content}": Parent task "${i}" not found`);
|
|
2581
2581
|
}
|
|
2582
2582
|
else if (!f && a && (f = r.get(a), !f)) {
|
|
2583
|
-
const
|
|
2584
|
-
if (!
|
|
2583
|
+
const j = await t.getSection(a);
|
|
2584
|
+
if (!j)
|
|
2585
2585
|
throw new Error(`Task "${e.content}": Section "${a}" not found`);
|
|
2586
|
-
f =
|
|
2586
|
+
f = j.projectId, r.set(a, j.projectId);
|
|
2587
2587
|
}
|
|
2588
2588
|
if (!f)
|
|
2589
2589
|
throw new Error(
|
|
@@ -2595,9 +2595,9 @@ async function hn(e, t, r) {
|
|
|
2595
2595
|
d
|
|
2596
2596
|
);
|
|
2597
2597
|
if (!v.isValid) {
|
|
2598
|
-
const
|
|
2598
|
+
const j = v.error?.message || "Assignment validation failed", A = v.error?.suggestions?.join(". ") || "";
|
|
2599
2599
|
throw new Error(
|
|
2600
|
-
`Task "${e.content}": ${
|
|
2600
|
+
`Task "${e.content}": ${j}${A ? `. ${A}` : ""}`
|
|
2601
2601
|
);
|
|
2602
2602
|
}
|
|
2603
2603
|
y.assigneeId = v.resolvedUser?.userId;
|
|
@@ -2620,7 +2620,7 @@ function fn({
|
|
|
2620
2620
|
}) {
|
|
2621
2621
|
const o = /* @__PURE__ */ new Set();
|
|
2622
2622
|
for (const a of r.tasks)
|
|
2623
|
-
a.projectId && !
|
|
2623
|
+
a.projectId && !N(a.projectId) ? o.add("projects") : a.sectionId ? o.add("sections") : a.parentId ? o.add("subtasks") : o.add("inbox");
|
|
2624
2624
|
let n = "";
|
|
2625
2625
|
if (o.size === 1) {
|
|
2626
2626
|
const a = Array.from(o)[0];
|
|
@@ -2645,7 +2645,7 @@ const bn = {
|
|
|
2645
2645
|
}, gn = {
|
|
2646
2646
|
projectId: s.string().describe("The project ID."),
|
|
2647
2647
|
health: s.object({
|
|
2648
|
-
status: s.enum(
|
|
2648
|
+
status: s.enum(Ge).describe("The health status after triggering analysis."),
|
|
2649
2649
|
isStale: s.boolean().describe("Whether the health data is still stale after the request."),
|
|
2650
2650
|
updateInProgress: s.boolean().describe("Whether an analysis update is currently in progress.")
|
|
2651
2651
|
}).describe("The health response returned after triggering analysis."),
|
|
@@ -2677,9 +2677,9 @@ ${n}`,
|
|
|
2677
2677
|
}
|
|
2678
2678
|
};
|
|
2679
2679
|
}
|
|
2680
|
-
}, kn = {
|
|
2681
|
-
ids: s.array(s.string().min(1)).min(1).describe("The IDs of the tasks to complete.")
|
|
2682
2680
|
}, Tn = {
|
|
2681
|
+
ids: s.array(s.string().min(1)).min(1).describe("The IDs of the tasks to complete.")
|
|
2682
|
+
}, kn = {
|
|
2683
2683
|
completed: s.array(s.string()).describe("The IDs of successfully completed tasks."),
|
|
2684
2684
|
failures: s.array(ee).describe("Failed task completions with error details."),
|
|
2685
2685
|
totalRequested: s.number().describe("The total number of tasks requested to complete."),
|
|
@@ -2688,8 +2688,8 @@ ${n}`,
|
|
|
2688
2688
|
}, wn = {
|
|
2689
2689
|
name: g.COMPLETE_TASKS,
|
|
2690
2690
|
description: "Complete one or more tasks by their IDs.",
|
|
2691
|
-
parameters:
|
|
2692
|
-
outputSchema:
|
|
2691
|
+
parameters: Tn,
|
|
2692
|
+
outputSchema: kn,
|
|
2693
2693
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
|
|
2694
2694
|
async execute(e, t) {
|
|
2695
2695
|
const r = [], o = [];
|
|
@@ -2744,23 +2744,23 @@ const ls = [
|
|
|
2744
2744
|
], In = {
|
|
2745
2745
|
type: s.enum(ls).describe("The type of entity to delete."),
|
|
2746
2746
|
id: s.string().min(1).describe("The ID of the entity to delete.")
|
|
2747
|
-
},
|
|
2747
|
+
}, Sn = {
|
|
2748
2748
|
deletedEntity: s.object({
|
|
2749
2749
|
type: s.enum(ls).describe("The type of deleted entity."),
|
|
2750
2750
|
id: s.string().describe("The ID of the deleted entity.")
|
|
2751
2751
|
}).describe("Information about the deleted entity."),
|
|
2752
2752
|
success: s.boolean().describe("Whether the deletion was successful.")
|
|
2753
|
-
},
|
|
2753
|
+
}, jn = {
|
|
2754
2754
|
name: g.DELETE_OBJECT,
|
|
2755
2755
|
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.",
|
|
2756
2756
|
parameters: In,
|
|
2757
|
-
outputSchema:
|
|
2757
|
+
outputSchema: Sn,
|
|
2758
2758
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !0 },
|
|
2759
2759
|
async execute(e, t) {
|
|
2760
2760
|
switch (e.type) {
|
|
2761
2761
|
case "project": {
|
|
2762
2762
|
const r = await t.getProject(e.id);
|
|
2763
|
-
if (
|
|
2763
|
+
if (ke(r) && !r.isArchived)
|
|
2764
2764
|
throw new Error(
|
|
2765
2765
|
`Workspace project "${r.name}" must be archived before it can be deleted. Archive the project first, then delete it.`
|
|
2766
2766
|
);
|
|
@@ -2903,7 +2903,7 @@ async function Pn(e, t) {
|
|
|
2903
2903
|
childrenError: a ? `Could not check ${a} of ${r.length} subtasks for subtasks of their own; those are reported as hasChildren=false.` : void 0
|
|
2904
2904
|
};
|
|
2905
2905
|
}
|
|
2906
|
-
async function
|
|
2906
|
+
async function _n(e, t) {
|
|
2907
2907
|
if (!B(t))
|
|
2908
2908
|
return { childCount: 0, children: [] };
|
|
2909
2909
|
const r = await os(e), o = /* @__PURE__ */ new Map();
|
|
@@ -2936,7 +2936,7 @@ function It(e, t) {
|
|
|
2936
2936
|
const r = t.hasMoreChildren ? "+" : "", o = t.childrenError ? " (partial)" : "";
|
|
2937
2937
|
return ` • ${e}=${t.childCount}${r}${o}`;
|
|
2938
2938
|
}
|
|
2939
|
-
const ps = ["task", "project", "comment", "section"],
|
|
2939
|
+
const ps = ["task", "project", "comment", "section"], Rn = {
|
|
2940
2940
|
type: s.enum(ps).describe("The type of object to fetch."),
|
|
2941
2941
|
id: s.string().min(1).describe("The unique ID of the object to fetch."),
|
|
2942
2942
|
includeChildren: s.boolean().optional().describe(
|
|
@@ -2950,7 +2950,7 @@ const ps = ["task", "project", "comment", "section"], _n = {
|
|
|
2950
2950
|
}, Ln = {
|
|
2951
2951
|
name: g.FETCH_OBJECT,
|
|
2952
2952
|
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.",
|
|
2953
|
-
parameters:
|
|
2953
|
+
parameters: Rn,
|
|
2954
2954
|
outputSchema: Un,
|
|
2955
2955
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
2956
2956
|
async execute(e, t) {
|
|
@@ -2973,7 +2973,7 @@ const ps = ["task", "project", "comment", "section"], _n = {
|
|
|
2973
2973
|
};
|
|
2974
2974
|
}
|
|
2975
2975
|
case "project": {
|
|
2976
|
-
const a = await t.getProject(o), i = Z(a), c = n ? await vt(() =>
|
|
2976
|
+
const a = await t.getProject(o), i = Z(a), c = n ? await vt(() => _n(t, a)) : {};
|
|
2977
2977
|
return {
|
|
2978
2978
|
textContent: `Found project: ${i.name} • id=${i.id} • color=${i.color} • viewStyle=${i.viewStyle}${It("subProjects", c)}`,
|
|
2979
2979
|
structuredContent: {
|
|
@@ -2999,7 +2999,7 @@ const ps = ["task", "project", "comment", "section"], _n = {
|
|
|
2999
2999
|
const a = await t.getSection(o);
|
|
3000
3000
|
if (!a)
|
|
3001
3001
|
throw new Error(`Section ${o} not found.`);
|
|
3002
|
-
const i =
|
|
3002
|
+
const i = K(a);
|
|
3003
3003
|
return {
|
|
3004
3004
|
textContent: `Found section: ${i.name} • id=${i.id}`,
|
|
3005
3005
|
structuredContent: {
|
|
@@ -3016,11 +3016,11 @@ const ps = ["task", "project", "comment", "section"], _n = {
|
|
|
3016
3016
|
);
|
|
3017
3017
|
}
|
|
3018
3018
|
}
|
|
3019
|
-
},
|
|
3019
|
+
}, Nn = {
|
|
3020
3020
|
id: s.string().min(1).describe(
|
|
3021
3021
|
'A unique identifier for the document in the format "task:{id}" or "project:{id}".'
|
|
3022
3022
|
)
|
|
3023
|
-
},
|
|
3023
|
+
}, Mn = {
|
|
3024
3024
|
id: s.string().describe("The ID of the fetched document."),
|
|
3025
3025
|
title: s.string().describe("The title of the document."),
|
|
3026
3026
|
text: s.string().describe("The text content of the document."),
|
|
@@ -3029,8 +3029,8 @@ const ps = ["task", "project", "comment", "section"], _n = {
|
|
|
3029
3029
|
}, Fn = {
|
|
3030
3030
|
name: g.FETCH,
|
|
3031
3031
|
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}".',
|
|
3032
|
-
parameters:
|
|
3033
|
-
outputSchema:
|
|
3032
|
+
parameters: Nn,
|
|
3033
|
+
outputSchema: Mn,
|
|
3034
3034
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
3035
3035
|
async execute(e, t) {
|
|
3036
3036
|
const { id: r } = e, [o, n] = r.split(":", 2);
|
|
@@ -3049,7 +3049,7 @@ Labels: ${c.labels.join(", ")}`), a = {
|
|
|
3049
3049
|
id: `task:${c.id}`,
|
|
3050
3050
|
title: c.content,
|
|
3051
3051
|
text: d.join(""),
|
|
3052
|
-
url:
|
|
3052
|
+
url: Mt(c.id),
|
|
3053
3053
|
metadata: {
|
|
3054
3054
|
priority: c.priority,
|
|
3055
3055
|
projectId: c.projectId,
|
|
@@ -3091,7 +3091,7 @@ Favorite: Yes`), a = {
|
|
|
3091
3091
|
};
|
|
3092
3092
|
}
|
|
3093
3093
|
}, Hn = s.union([s.iso.date(), s.iso.datetime({ offset: !0 })]);
|
|
3094
|
-
function
|
|
3094
|
+
function St(e) {
|
|
3095
3095
|
return U(e).pipe(Hn.optional());
|
|
3096
3096
|
}
|
|
3097
3097
|
const Wn = {
|
|
@@ -3111,10 +3111,10 @@ const Wn = {
|
|
|
3111
3111
|
projectId: s.string().optional().describe("Filter events by parent project ID."),
|
|
3112
3112
|
taskId: s.string().optional().describe("Filter events by parent task ID (for subtask events)."),
|
|
3113
3113
|
initiatorId: s.string().optional().describe("Filter by the user ID who initiated the event."),
|
|
3114
|
-
dateFrom:
|
|
3114
|
+
dateFrom: St(
|
|
3115
3115
|
`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.`
|
|
3116
3116
|
),
|
|
3117
|
-
dateTo:
|
|
3117
|
+
dateTo: St(
|
|
3118
3118
|
'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.'
|
|
3119
3119
|
),
|
|
3120
3120
|
limit: s.number().int().min(1).max(C.ACTIVITY_MAX).default(C.ACTIVITY_DEFAULT).describe("Maximum number of activity events to return."),
|
|
@@ -3125,7 +3125,7 @@ const Wn = {
|
|
|
3125
3125
|
totalCount: s.number().describe("The total number of events in this page."),
|
|
3126
3126
|
hasMore: s.boolean(),
|
|
3127
3127
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3128
|
-
},
|
|
3128
|
+
}, zn = {
|
|
3129
3129
|
name: g.FIND_ACTIVITY,
|
|
3130
3130
|
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. Track task completions, updates, deletions, project changes, and more with flexible filtering. Activity history availability and retention depend on the user plan.',
|
|
3131
3131
|
parameters: Wn,
|
|
@@ -3150,7 +3150,7 @@ const Wn = {
|
|
|
3150
3150
|
r && n ? m.objectEventTypes = `${r}:${n}` : r ? m.objectEventTypes = `${r}:` : n && (m.objectEventTypes = `:${n}`), o && o !== "remove" && (m.objectId = o), a && (m.parentProjectId = a), i && (m.parentItemId = i), c && (m.initiatorId = c), d && (m.dateFrom = d), l && (m.dateTo = l);
|
|
3151
3151
|
const { results: h, nextCursor: y } = await t.getActivityLogs(m), f = h.map(po);
|
|
3152
3152
|
return {
|
|
3153
|
-
textContent:
|
|
3153
|
+
textContent: Kn({ events: f, args: e, nextCursor: y }),
|
|
3154
3154
|
structuredContent: {
|
|
3155
3155
|
events: f,
|
|
3156
3156
|
nextCursor: y ?? void 0,
|
|
@@ -3161,7 +3161,7 @@ const Wn = {
|
|
|
3161
3161
|
};
|
|
3162
3162
|
}
|
|
3163
3163
|
};
|
|
3164
|
-
function
|
|
3164
|
+
function Kn({
|
|
3165
3165
|
events: e,
|
|
3166
3166
|
args: t,
|
|
3167
3167
|
nextCursor: r
|
|
@@ -3187,7 +3187,7 @@ function zn({
|
|
|
3187
3187
|
});
|
|
3188
3188
|
}
|
|
3189
3189
|
function qn(e, t = 10) {
|
|
3190
|
-
const o = e.slice(0, t).map(
|
|
3190
|
+
const o = e.slice(0, t).map(Yn).join(`
|
|
3191
3191
|
`);
|
|
3192
3192
|
if (e.length > t) {
|
|
3193
3193
|
const n = e.length - t;
|
|
@@ -3196,8 +3196,8 @@ function qn(e, t = 10) {
|
|
|
3196
3196
|
}
|
|
3197
3197
|
return o;
|
|
3198
3198
|
}
|
|
3199
|
-
function
|
|
3200
|
-
const t =
|
|
3199
|
+
function Yn(e) {
|
|
3200
|
+
const t = Gn(e.eventDate), r = `${e.eventType} ${e.objectType}`;
|
|
3201
3201
|
let o = "";
|
|
3202
3202
|
if (e.extraData) {
|
|
3203
3203
|
const c = e.extraData.content || e.extraData.name || e.extraData.last_content;
|
|
@@ -3206,7 +3206,7 @@ function Gn(e) {
|
|
|
3206
3206
|
const n = e.objectId ? ` • id=${e.objectId}` : "", a = e.initiatorId ? ` • by=${e.initiatorId}` : " • system", i = e.parentProjectId ? ` • project=${e.parentProjectId}` : "";
|
|
3207
3207
|
return ` [${t}] ${r}${o}${n}${a}${i}`;
|
|
3208
3208
|
}
|
|
3209
|
-
function
|
|
3209
|
+
function Gn(e) {
|
|
3210
3210
|
try {
|
|
3211
3211
|
const t = new Date(e), r = t.toLocaleDateString("en-US", { month: "short", timeZone: "UTC" }), o = t.toLocaleDateString("en-US", { day: "numeric", timeZone: "UTC" }), n = t.toLocaleTimeString("en-US", {
|
|
3212
3212
|
hour: "2-digit",
|
|
@@ -3334,7 +3334,7 @@ function ea(e, t) {
|
|
|
3334
3334
|
const r = new Date(e.getTime() + t * 60 * 1e3);
|
|
3335
3335
|
return ms(r);
|
|
3336
3336
|
}
|
|
3337
|
-
function
|
|
3337
|
+
function jt(e, t) {
|
|
3338
3338
|
const [r, o, n] = e.split("-"), a = Number(r), i = Number(o), c = Number(n);
|
|
3339
3339
|
if (!Number.isFinite(a) || !Number.isFinite(i) || !Number.isFinite(c))
|
|
3340
3340
|
throw new Error(`Invalid date format: ${e}. Expected YYYY-MM-DD.`);
|
|
@@ -3359,9 +3359,9 @@ function ra({
|
|
|
3359
3359
|
userGmtOffset: r,
|
|
3360
3360
|
now: o = /* @__PURE__ */ new Date()
|
|
3361
3361
|
}) {
|
|
3362
|
-
const n = Qn(r), a = ea(o, n), i = sa - 1, c = t ?? (e ?
|
|
3362
|
+
const n = Qn(r), a = ea(o, n), i = sa - 1, c = t ?? (e ? jt(e, i) : a);
|
|
3363
3363
|
return {
|
|
3364
|
-
since: e ??
|
|
3364
|
+
since: e ?? jt(c, -i),
|
|
3365
3365
|
until: c
|
|
3366
3366
|
};
|
|
3367
3367
|
}
|
|
@@ -3413,15 +3413,15 @@ const oa = {
|
|
|
3413
3413
|
const y = await t.getUser(), f = y.tzInfo?.gmtString || "+00:00", v = await de({
|
|
3414
3414
|
projectId: d,
|
|
3415
3415
|
user: y
|
|
3416
|
-
}),
|
|
3416
|
+
}), j = ra({
|
|
3417
3417
|
since: a,
|
|
3418
3418
|
until: i,
|
|
3419
3419
|
userGmtOffset: f
|
|
3420
|
-
}), A = `${
|
|
3420
|
+
}), A = `${j.since}T00:00:00${f}`, k = `${j.until}T23:59:59${f}`, I = new Date(A).toISOString(), x = new Date(k).toISOString(), T = {
|
|
3421
3421
|
...e,
|
|
3422
|
-
since:
|
|
3423
|
-
until:
|
|
3424
|
-
}, { items: b, nextCursor:
|
|
3422
|
+
since: j.since,
|
|
3423
|
+
until: j.until
|
|
3424
|
+
}, { items: b, nextCursor: S } = r === "completion" ? await t.getCompletedTasksByCompletionDate({
|
|
3425
3425
|
...l,
|
|
3426
3426
|
projectId: v,
|
|
3427
3427
|
since: I,
|
|
@@ -3437,16 +3437,16 @@ const oa = {
|
|
|
3437
3437
|
return {
|
|
3438
3438
|
textContent: ia({
|
|
3439
3439
|
tasks: $,
|
|
3440
|
-
args:
|
|
3441
|
-
nextCursor:
|
|
3440
|
+
args: T,
|
|
3441
|
+
nextCursor: S,
|
|
3442
3442
|
assigneeEmail: p
|
|
3443
3443
|
}),
|
|
3444
3444
|
structuredContent: {
|
|
3445
3445
|
tasks: $,
|
|
3446
|
-
nextCursor:
|
|
3446
|
+
nextCursor: S ?? void 0,
|
|
3447
3447
|
totalCount: $.length,
|
|
3448
|
-
hasMore: !!
|
|
3449
|
-
appliedFilters:
|
|
3448
|
+
hasMore: !!S,
|
|
3449
|
+
appliedFilters: T
|
|
3450
3450
|
}
|
|
3451
3451
|
};
|
|
3452
3452
|
}
|
|
@@ -3473,7 +3473,7 @@ function ia({
|
|
|
3473
3473
|
limit: t.limit,
|
|
3474
3474
|
nextCursor: r ?? void 0,
|
|
3475
3475
|
filterHints: i,
|
|
3476
|
-
previewLines:
|
|
3476
|
+
previewLines: Se(e, Math.min(e.length, t.limit)),
|
|
3477
3477
|
zeroReasonHints: c
|
|
3478
3478
|
});
|
|
3479
3479
|
}
|
|
@@ -3529,7 +3529,7 @@ function ua({
|
|
|
3529
3529
|
}) {
|
|
3530
3530
|
const n = t.searchText ? `All labels matching "${t.searchText}"` : "Labels", a = [];
|
|
3531
3531
|
t.searchText && a.push(`searchText: "${t.searchText}"`);
|
|
3532
|
-
const i = 10, d = e.slice(0, i).map(
|
|
3532
|
+
const i = 10, d = e.slice(0, i).map(Mo).join(`
|
|
3533
3533
|
`), l = e.length - i, u = l > 0 ? `${d}
|
|
3534
3534
|
…and ${l} more` : d, p = [];
|
|
3535
3535
|
e.length === 0 && (t.searchText ? (p.push("Try broader search terms"), p.push("Check spelling"), p.push("Remove searchText to see all labels")) : p.push("No personal labels created yet"));
|
|
@@ -3741,17 +3741,17 @@ const { ADD_PROJECTS: Ct } = g, ga = {
|
|
|
3741
3741
|
archivedStatus: s.enum(["active", "archived", "all"]).optional().describe(
|
|
3742
3742
|
"Which projects to return by archive status: 'active' (default, non-archived only), 'archived' (archived only), or 'all' (both active and archived). Each project includes an isArchived field. Archived projects can be deleted via the delete-object tool (type: 'project')."
|
|
3743
3743
|
)
|
|
3744
|
-
},
|
|
3744
|
+
}, Ta = {
|
|
3745
3745
|
projects: s.array(Q).describe("The found projects."),
|
|
3746
3746
|
nextCursor: s.string().optional(),
|
|
3747
3747
|
totalCount: s.number().describe("The total number of projects in this page."),
|
|
3748
3748
|
hasMore: s.boolean(),
|
|
3749
3749
|
appliedFilters: s.record(s.string(), s.unknown())
|
|
3750
|
-
},
|
|
3750
|
+
}, ka = {
|
|
3751
3751
|
name: g.FIND_PROJECTS,
|
|
3752
3752
|
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.",
|
|
3753
3753
|
parameters: ya,
|
|
3754
|
-
outputSchema:
|
|
3754
|
+
outputSchema: Ta,
|
|
3755
3755
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
3756
3756
|
async execute(e, t) {
|
|
3757
3757
|
const { searchText: r } = e, o = e.archivedStatus ?? "active";
|
|
@@ -3813,7 +3813,7 @@ const va = {
|
|
|
3813
3813
|
searchType: s.string().describe('The search type used: "task", "reminder", or "location_reminder".'),
|
|
3814
3814
|
searchId: s.string().describe("The ID used for the search."),
|
|
3815
3815
|
totalCount: s.number().describe("Total reminders in this response.")
|
|
3816
|
-
},
|
|
3816
|
+
}, Sa = {
|
|
3817
3817
|
name: g.FIND_REMINDERS,
|
|
3818
3818
|
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.",
|
|
3819
3819
|
parameters: va,
|
|
@@ -3853,17 +3853,17 @@ const va = {
|
|
|
3853
3853
|
}
|
|
3854
3854
|
if (r) {
|
|
3855
3855
|
const [i, c] = await Promise.all([
|
|
3856
|
-
|
|
3856
|
+
M({
|
|
3857
3857
|
apiMethod: (p) => t.getReminders(p),
|
|
3858
3858
|
args: { taskId: r }
|
|
3859
3859
|
}),
|
|
3860
|
-
|
|
3860
|
+
M({
|
|
3861
3861
|
apiMethod: (p) => t.getLocationReminders(p),
|
|
3862
3862
|
args: { taskId: r }
|
|
3863
3863
|
})
|
|
3864
3864
|
]), l = [...i, ...c].map(be);
|
|
3865
3865
|
return {
|
|
3866
|
-
textContent:
|
|
3866
|
+
textContent: ja(l, r),
|
|
3867
3867
|
structuredContent: {
|
|
3868
3868
|
reminders: l,
|
|
3869
3869
|
searchType: "task",
|
|
@@ -3875,7 +3875,7 @@ const va = {
|
|
|
3875
3875
|
throw new Error("One of taskId, reminderId, or locationReminderId must be provided.");
|
|
3876
3876
|
}
|
|
3877
3877
|
};
|
|
3878
|
-
function
|
|
3878
|
+
function ja(e, t) {
|
|
3879
3879
|
if (e.length === 0)
|
|
3880
3880
|
return `No reminders found for task ${t}`;
|
|
3881
3881
|
const { timeBasedCount: r, locationCount: o } = ns(e), n = [];
|
|
@@ -3915,7 +3915,7 @@ const { ADD_SECTIONS: Ca } = g, $a = {
|
|
|
3915
3915
|
e.searchText ? o = await uo(t, e.searchText, r) : o = (await t.getSections({
|
|
3916
3916
|
projectId: r
|
|
3917
3917
|
})).results;
|
|
3918
|
-
const n = o.map(
|
|
3918
|
+
const n = o.map(K);
|
|
3919
3919
|
return {
|
|
3920
3920
|
textContent: Aa({
|
|
3921
3921
|
sections: n,
|
|
@@ -3946,11 +3946,13 @@ function Aa({
|
|
|
3946
3946
|
zeroReasonHints: o
|
|
3947
3947
|
});
|
|
3948
3948
|
}
|
|
3949
|
-
function
|
|
3949
|
+
function Ts(e) {
|
|
3950
3950
|
return /* @__PURE__ */ new Date(`${e}T00:00:00`);
|
|
3951
3951
|
}
|
|
3952
3952
|
const Ea = {
|
|
3953
|
-
startDate: s.string().regex(/^(\d{4}-\d{2}-\d{2}|today)$/).optional().describe(
|
|
3953
|
+
startDate: s.string().regex(/^(\d{4}-\d{2}-\d{2}|today)$/).optional().describe(
|
|
3954
|
+
"The start date to get the tasks for. Format: YYYY-MM-DD, or 'today', which by default also includes overdue tasks."
|
|
3955
|
+
),
|
|
3954
3956
|
overdueOption: s.enum(["overdue-only", "include-overdue", "exclude-overdue"]).optional().describe(
|
|
3955
3957
|
"How to handle overdue tasks. 'overdue-only' to get only overdue tasks, 'include-overdue' to include overdue tasks along with tasks for the specified date(s), and 'exclude-overdue' to exclude overdue tasks. Default is 'include-overdue'."
|
|
3956
3958
|
),
|
|
@@ -3996,7 +3998,7 @@ const Ea = {
|
|
|
3996
3998
|
} else
|
|
3997
3999
|
a = e.overdueOption === "exclude-overdue" ? "today" : "(today | overdue)";
|
|
3998
4000
|
else if (e.startDate) {
|
|
3999
|
-
const p = e.startDate, m = Ue(
|
|
4001
|
+
const p = e.startDate, m = Ue(Ts(p), e.daysCount), h = lt(m, { representation: "date" });
|
|
4000
4002
|
a = `(due after: ${p} | due: ${p}) & due before: ${h}`;
|
|
4001
4003
|
}
|
|
4002
4004
|
const i = dt(e.labels, e.labelsOperator);
|
|
@@ -4014,7 +4016,7 @@ const Ea = {
|
|
|
4014
4016
|
limit: e.limit
|
|
4015
4017
|
});
|
|
4016
4018
|
return {
|
|
4017
|
-
textContent:
|
|
4019
|
+
textContent: _a({ tasks: d, args: e, nextCursor: l, assigneeEmail: n }),
|
|
4018
4020
|
structuredContent: {
|
|
4019
4021
|
tasks: d,
|
|
4020
4022
|
nextCursor: l ?? void 0,
|
|
@@ -4025,7 +4027,7 @@ const Ea = {
|
|
|
4025
4027
|
};
|
|
4026
4028
|
}
|
|
4027
4029
|
};
|
|
4028
|
-
function
|
|
4030
|
+
function _a({
|
|
4029
4031
|
tasks: e,
|
|
4030
4032
|
args: t,
|
|
4031
4033
|
nextCursor: r,
|
|
@@ -4040,7 +4042,7 @@ function Ra({
|
|
|
4040
4042
|
`today${c}${t.daysCount > 1 ? ` + ${t.daysCount - 1} more days` : ""}`
|
|
4041
4043
|
);
|
|
4042
4044
|
} else if (t.startDate) {
|
|
4043
|
-
const c = t.daysCount > 1 ? ` to ${ie(Ue(
|
|
4045
|
+
const c = t.daysCount > 1 ? ` to ${ie(Ue(Ts(t.startDate), t.daysCount))}` : "";
|
|
4044
4046
|
n.push(`${t.startDate}${c}`);
|
|
4045
4047
|
}
|
|
4046
4048
|
if (t.labels && t.labels.length > 0) {
|
|
@@ -4071,17 +4073,17 @@ function Ra({
|
|
|
4071
4073
|
limit: t.limit,
|
|
4072
4074
|
nextCursor: r ?? void 0,
|
|
4073
4075
|
filterHints: n,
|
|
4074
|
-
previewLines:
|
|
4076
|
+
previewLines: Se(e, Math.min(e.length, t.limit)),
|
|
4075
4077
|
zeroReasonHints: i
|
|
4076
4078
|
});
|
|
4077
4079
|
}
|
|
4078
|
-
const
|
|
4080
|
+
const Ra = 300 * 1e3;
|
|
4079
4081
|
class Ua {
|
|
4080
4082
|
constructor() {
|
|
4081
4083
|
this.cache = null;
|
|
4082
4084
|
}
|
|
4083
4085
|
async getFilters(t) {
|
|
4084
|
-
if (this.cache && Date.now() - this.cache.timestamp <
|
|
4086
|
+
if (this.cache && Date.now() - this.cache.timestamp < Ra)
|
|
4085
4087
|
return this.cache.filters;
|
|
4086
4088
|
const o = ((await t.sync({
|
|
4087
4089
|
resourceTypes: ["filters"],
|
|
@@ -4138,7 +4140,7 @@ ${u}` + (d.length > 5 ? `
|
|
|
4138
4140
|
this.cache = null;
|
|
4139
4141
|
}
|
|
4140
4142
|
}
|
|
4141
|
-
const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g,
|
|
4143
|
+
const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Na = {
|
|
4142
4144
|
searchText: s.string().optional().describe("The text to search for in tasks."),
|
|
4143
4145
|
projectId: s.string().optional().describe(
|
|
4144
4146
|
'Find tasks in this project. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
|
|
@@ -4160,7 +4162,7 @@ const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Ma = {
|
|
|
4160
4162
|
"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."
|
|
4161
4163
|
),
|
|
4162
4164
|
...ct
|
|
4163
|
-
},
|
|
4165
|
+
}, Ma = {
|
|
4164
4166
|
tasks: s.array(F).describe("The found tasks."),
|
|
4165
4167
|
nextCursor: s.string().optional(),
|
|
4166
4168
|
totalCount: s.number().describe("The total number of tasks in this page."),
|
|
@@ -4169,8 +4171,8 @@ const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Ma = {
|
|
|
4169
4171
|
}, Fa = {
|
|
4170
4172
|
name: g.FIND_TASKS,
|
|
4171
4173
|
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.",
|
|
4172
|
-
parameters:
|
|
4173
|
-
outputSchema:
|
|
4174
|
+
parameters: Na,
|
|
4175
|
+
outputSchema: Ma,
|
|
4174
4176
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
4175
4177
|
async execute(e, t) {
|
|
4176
4178
|
const {
|
|
@@ -4201,14 +4203,14 @@ const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Ma = {
|
|
|
4201
4203
|
);
|
|
4202
4204
|
let v = m;
|
|
4203
4205
|
h && (v = (await La.resolveFilter(t, h)).filterQuery);
|
|
4204
|
-
const
|
|
4206
|
+
const j = await Qe(t, i), A = j?.userId, k = j?.email;
|
|
4205
4207
|
if (o || n || a) {
|
|
4206
4208
|
const D = {
|
|
4207
4209
|
limit: d,
|
|
4208
4210
|
cursor: l ?? null
|
|
4209
4211
|
};
|
|
4210
4212
|
o && (D.projectId = await de({ projectId: o, user: y })), n && (D.sectionId = n), a && (D.parentId = a);
|
|
4211
|
-
const { results: me, nextCursor:
|
|
4213
|
+
const { results: me, nextCursor: Y } = await t.getTasks(D), $e = me.map(P);
|
|
4212
4214
|
let H = r ? $e.filter(
|
|
4213
4215
|
(te) => te.content.toLowerCase().includes(r.toLowerCase()) || te.description?.toLowerCase().includes(r.toLowerCase())
|
|
4214
4216
|
) : $e;
|
|
@@ -4225,38 +4227,38 @@ const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Ma = {
|
|
|
4225
4227
|
textContent: Ee({
|
|
4226
4228
|
tasks: H,
|
|
4227
4229
|
args: e,
|
|
4228
|
-
nextCursor:
|
|
4230
|
+
nextCursor: Y,
|
|
4229
4231
|
isContainerSearch: !0,
|
|
4230
|
-
assigneeEmail:
|
|
4232
|
+
assigneeEmail: k
|
|
4231
4233
|
}),
|
|
4232
4234
|
structuredContent: {
|
|
4233
4235
|
tasks: H,
|
|
4234
|
-
nextCursor:
|
|
4236
|
+
nextCursor: Y ?? void 0,
|
|
4235
4237
|
totalCount: H.length,
|
|
4236
|
-
hasMore: !!
|
|
4238
|
+
hasMore: !!Y,
|
|
4237
4239
|
appliedFilters: e
|
|
4238
4240
|
}
|
|
4239
4241
|
};
|
|
4240
4242
|
}
|
|
4241
4243
|
if (A && !r && !f && !v) {
|
|
4242
4244
|
const { results: D, nextCursor: me } = await t.getTasksByFilter({
|
|
4243
|
-
query: `assigned to: ${
|
|
4245
|
+
query: `assigned to: ${k}`,
|
|
4244
4246
|
lang: "en",
|
|
4245
4247
|
limit: d,
|
|
4246
4248
|
cursor: l ?? null
|
|
4247
|
-
}),
|
|
4249
|
+
}), Y = D.map(P);
|
|
4248
4250
|
return {
|
|
4249
4251
|
textContent: Ee({
|
|
4250
|
-
tasks:
|
|
4252
|
+
tasks: Y,
|
|
4251
4253
|
args: e,
|
|
4252
4254
|
nextCursor: me,
|
|
4253
4255
|
isContainerSearch: !1,
|
|
4254
|
-
assigneeEmail:
|
|
4256
|
+
assigneeEmail: k
|
|
4255
4257
|
}),
|
|
4256
4258
|
structuredContent: {
|
|
4257
|
-
tasks:
|
|
4259
|
+
tasks: Y,
|
|
4258
4260
|
nextCursor: me ?? void 0,
|
|
4259
|
-
totalCount:
|
|
4261
|
+
totalCount: Y.length,
|
|
4260
4262
|
hasMore: !!me,
|
|
4261
4263
|
appliedFilters: e
|
|
4262
4264
|
}
|
|
@@ -4268,12 +4270,12 @@ const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Ma = {
|
|
|
4268
4270
|
if (I = ce(I, x), !(h && !i && !c)) {
|
|
4269
4271
|
const D = ss({
|
|
4270
4272
|
resolvedAssigneeId: A,
|
|
4271
|
-
assigneeEmail:
|
|
4273
|
+
assigneeEmail: k,
|
|
4272
4274
|
responsibleUserFiltering: c
|
|
4273
4275
|
});
|
|
4274
4276
|
I = ce(I, D);
|
|
4275
4277
|
}
|
|
4276
|
-
const { tasks: b, nextCursor:
|
|
4278
|
+
const { tasks: b, nextCursor: S } = await tt({
|
|
4277
4279
|
client: t,
|
|
4278
4280
|
query: I,
|
|
4279
4281
|
cursor: e.cursor,
|
|
@@ -4283,15 +4285,15 @@ const La = new Ua(), { FIND_COMPLETED_TASKS: $t, ADD_TASKS: Dt } = g, Ma = {
|
|
|
4283
4285
|
textContent: Ee({
|
|
4284
4286
|
tasks: b,
|
|
4285
4287
|
args: e,
|
|
4286
|
-
nextCursor:
|
|
4288
|
+
nextCursor: S,
|
|
4287
4289
|
isContainerSearch: !1,
|
|
4288
|
-
assigneeEmail:
|
|
4290
|
+
assigneeEmail: k
|
|
4289
4291
|
}),
|
|
4290
4292
|
structuredContent: {
|
|
4291
4293
|
tasks: b,
|
|
4292
|
-
nextCursor:
|
|
4294
|
+
nextCursor: S ?? void 0,
|
|
4293
4295
|
totalCount: b.length,
|
|
4294
|
-
hasMore: !!
|
|
4296
|
+
hasMore: !!S,
|
|
4295
4297
|
appliedFilters: e
|
|
4296
4298
|
}
|
|
4297
4299
|
};
|
|
@@ -4357,7 +4359,7 @@ function Ee({
|
|
|
4357
4359
|
limit: t.limit,
|
|
4358
4360
|
nextCursor: r ?? void 0,
|
|
4359
4361
|
filterHints: i,
|
|
4360
|
-
previewLines:
|
|
4362
|
+
previewLines: Se(e, Math.min(e.length, t.limit)),
|
|
4361
4363
|
zeroReasonHints: c
|
|
4362
4364
|
});
|
|
4363
4365
|
}
|
|
@@ -4365,7 +4367,7 @@ const Wa = {
|
|
|
4365
4367
|
projectId: s.string().min(1).optional().describe(
|
|
4366
4368
|
"Optional project ID. If provided, shows detailed overview of that project. If omitted, shows overview of all projects."
|
|
4367
4369
|
)
|
|
4368
|
-
},
|
|
4370
|
+
}, ks = s.lazy(
|
|
4369
4371
|
() => s.object({
|
|
4370
4372
|
id: s.string().describe("The project ID."),
|
|
4371
4373
|
name: s.string().describe("The project name."),
|
|
@@ -4378,7 +4380,7 @@ const Wa = {
|
|
|
4378
4380
|
name: s.string()
|
|
4379
4381
|
})
|
|
4380
4382
|
),
|
|
4381
|
-
children: s.array(
|
|
4383
|
+
children: s.array(ks).describe("Nested child projects.")
|
|
4382
4384
|
})
|
|
4383
4385
|
), Ba = {
|
|
4384
4386
|
type: s.enum(["account_overview", "project_overview"]).describe("The type of overview returned."),
|
|
@@ -4399,7 +4401,7 @@ const Wa = {
|
|
|
4399
4401
|
name: s.string().describe("The inbox project name."),
|
|
4400
4402
|
sections: s.array(X).describe("Sections in the inbox project.")
|
|
4401
4403
|
}).nullable().optional().describe("Inbox information (account overview only)."),
|
|
4402
|
-
projects: s.array(s.lazy(() =>
|
|
4404
|
+
projects: s.array(s.lazy(() => ks)).optional().describe(
|
|
4403
4405
|
"List of projects with hierarchy, folders, and ordering (account overview only)."
|
|
4404
4406
|
),
|
|
4405
4407
|
project: s.object({
|
|
@@ -4414,7 +4416,7 @@ const Wa = {
|
|
|
4414
4416
|
tasksWithoutSection: s.number()
|
|
4415
4417
|
}).optional().describe("Statistics object (project overview only).")
|
|
4416
4418
|
};
|
|
4417
|
-
function
|
|
4419
|
+
function za(e) {
|
|
4418
4420
|
const t = {};
|
|
4419
4421
|
for (const n of e)
|
|
4420
4422
|
t[n.id] = {
|
|
@@ -4439,7 +4441,7 @@ function Ya(e) {
|
|
|
4439
4441
|
}
|
|
4440
4442
|
return o(r), r;
|
|
4441
4443
|
}
|
|
4442
|
-
async function
|
|
4444
|
+
async function Ka(e, t) {
|
|
4443
4445
|
const r = {};
|
|
4444
4446
|
return await Promise.all(
|
|
4445
4447
|
t.map(async (o) => {
|
|
@@ -4488,9 +4490,9 @@ function vs(e, t) {
|
|
|
4488
4490
|
id: e.id,
|
|
4489
4491
|
name: e.name,
|
|
4490
4492
|
parentId: B(e) ? e.parentId ?? void 0 : void 0,
|
|
4491
|
-
folderId:
|
|
4493
|
+
folderId: ke(e) ? e.folderId ?? void 0 : void 0,
|
|
4492
4494
|
childOrder: e.childOrder,
|
|
4493
|
-
sections: (t[e.id] || []).map(
|
|
4495
|
+
sections: (t[e.id] || []).map(K),
|
|
4494
4496
|
children: e.children.map(
|
|
4495
4497
|
(r) => vs(r, t)
|
|
4496
4498
|
)
|
|
@@ -4508,12 +4510,12 @@ async function qa(e, t) {
|
|
|
4508
4510
|
} while (o);
|
|
4509
4511
|
return r;
|
|
4510
4512
|
}
|
|
4511
|
-
async function
|
|
4513
|
+
async function Ya(e, t) {
|
|
4512
4514
|
const { results: r } = await e.getSections({ projectId: t });
|
|
4513
4515
|
return r;
|
|
4514
4516
|
}
|
|
4515
|
-
async function
|
|
4516
|
-
const { results: t } = await e.getProjects({}), r = t.find((p) => B(p) && p.inboxProject === !0), o = t.filter((p) => !B(p) || p.inboxProject !== !0), n =
|
|
4517
|
+
async function Ga(e) {
|
|
4518
|
+
const { results: t } = await e.getProjects({}), r = t.find((p) => B(p) && p.inboxProject === !0), o = t.filter((p) => !B(p) || p.inboxProject !== !0), n = za(o), a = t.map((p) => p.id), i = await Ka(e, a), c = ["# Personal Projects", ""];
|
|
4517
4519
|
if (r) {
|
|
4518
4520
|
c.push(`- Inbox Project: ${r.name} (id=${r.id})`);
|
|
4519
4521
|
for (const p of i[r.id] || [])
|
|
@@ -4536,7 +4538,7 @@ async function Ka(e) {
|
|
|
4536
4538
|
inbox: r ? {
|
|
4537
4539
|
id: r.id,
|
|
4538
4540
|
name: r.name,
|
|
4539
|
-
sections: (i[r.id] || []).map(
|
|
4541
|
+
sections: (i[r.id] || []).map(K)
|
|
4540
4542
|
} : null,
|
|
4541
4543
|
projects: n.map(
|
|
4542
4544
|
(p) => vs(p, i)
|
|
@@ -4553,7 +4555,7 @@ async function Ka(e) {
|
|
|
4553
4555
|
async function Va(e, t) {
|
|
4554
4556
|
const [r, o, n] = await Promise.all([
|
|
4555
4557
|
e.getProject(t),
|
|
4556
|
-
|
|
4558
|
+
Ya(e, t),
|
|
4557
4559
|
qa(e, t)
|
|
4558
4560
|
]), a = {};
|
|
4559
4561
|
for (const u of o)
|
|
@@ -4582,7 +4584,7 @@ async function Va(e, t) {
|
|
|
4582
4584
|
id: r.id,
|
|
4583
4585
|
name: r.name
|
|
4584
4586
|
},
|
|
4585
|
-
sections: o.map(
|
|
4587
|
+
sections: o.map(K),
|
|
4586
4588
|
tasks: n.map((u) => ({
|
|
4587
4589
|
...u,
|
|
4588
4590
|
children: []
|
|
@@ -4603,7 +4605,7 @@ const Ja = {
|
|
|
4603
4605
|
outputSchema: Ba,
|
|
4604
4606
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
4605
4607
|
async execute(e, t) {
|
|
4606
|
-
const r = e.projectId ? await Va(t, e.projectId) : await
|
|
4608
|
+
const r = e.projectId ? await Va(t, e.projectId) : await Ga(t);
|
|
4607
4609
|
return {
|
|
4608
4610
|
textContent: r.textContent,
|
|
4609
4611
|
structuredContent: r.structuredContent
|
|
@@ -4820,7 +4822,7 @@ const oi = {
|
|
|
4820
4822
|
progressPercent: s.number().describe("Completion percentage (0-100).")
|
|
4821
4823
|
}).describe("Project completion progress."),
|
|
4822
4824
|
health: s.object({
|
|
4823
|
-
status: s.enum(
|
|
4825
|
+
status: s.enum(Ge).describe("The overall health status of the project."),
|
|
4824
4826
|
description: s.string().nullable().optional().describe("Detailed description of the health assessment."),
|
|
4825
4827
|
descriptionSummary: s.string().nullable().optional().describe("Brief summary of the health assessment."),
|
|
4826
4828
|
taskRecommendations: s.array(ai).nullable().optional().describe("Specific recommendations for individual tasks."),
|
|
@@ -4936,7 +4938,7 @@ const ui = {
|
|
|
4936
4938
|
}, mi = s.object({
|
|
4937
4939
|
projectId: s.string().describe("The project ID."),
|
|
4938
4940
|
health: s.object({
|
|
4939
|
-
status: s.enum(
|
|
4941
|
+
status: s.enum(Ge).describe("The health status of the project."),
|
|
4940
4942
|
isStale: s.boolean().describe("Whether the health data is stale."),
|
|
4941
4943
|
updateInProgress: s.boolean().describe("Whether a health analysis update is in progress.")
|
|
4942
4944
|
}).nullable().describe("Health data for this project, if available."),
|
|
@@ -5030,16 +5032,16 @@ const yi = {
|
|
|
5030
5032
|
"Raw CSV template content, as produced by export-project-template. Provide either this or `templateId`, not both."
|
|
5031
5033
|
),
|
|
5032
5034
|
locale: s.string().optional().describe('Locale for the imported content when using `templateId`. Defaults to "en".')
|
|
5033
|
-
},
|
|
5035
|
+
}, Ti = {
|
|
5034
5036
|
sections: s.array(X).describe("Sections created by the import."),
|
|
5035
5037
|
tasks: s.array(F).describe("Tasks created by the import."),
|
|
5036
5038
|
comments: s.array(ye).describe("Comments created by the import."),
|
|
5037
5039
|
totalCount: s.number().describe("The total number of objects created by the import.")
|
|
5038
|
-
},
|
|
5040
|
+
}, ki = {
|
|
5039
5041
|
name: g.IMPORT_PROJECT_TEMPLATE,
|
|
5040
5042
|
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.",
|
|
5041
5043
|
parameters: yi,
|
|
5042
|
-
outputSchema:
|
|
5044
|
+
outputSchema: Ti,
|
|
5043
5045
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
|
|
5044
5046
|
async execute({ projectId: e, templateId: t, csvFileContent: r, locale: o }, n) {
|
|
5045
5047
|
if (!!t == !!r)
|
|
@@ -5054,7 +5056,7 @@ const yi = {
|
|
|
5054
5056
|
projectId: e,
|
|
5055
5057
|
file: r ?? "",
|
|
5056
5058
|
fileName: "template.csv"
|
|
5057
|
-
}), i = a.sections.map(
|
|
5059
|
+
}), i = a.sections.map(K), c = a.tasks.map(P), d = a.comments.map(ge), l = a.projects.length + i.length + c.length + d.length;
|
|
5058
5060
|
return {
|
|
5059
5061
|
textContent: wi({
|
|
5060
5062
|
projectId: e,
|
|
@@ -5089,12 +5091,12 @@ const vi = {}, Ii = {
|
|
|
5089
5091
|
isGuestAllowed: s.boolean().describe("Whether guests are allowed in the workspace."),
|
|
5090
5092
|
createdAt: s.string().optional().describe("The ISO 8601 timestamp when the workspace was created."),
|
|
5091
5093
|
creatorId: s.string().describe("The ID of the user who created the workspace.")
|
|
5092
|
-
},
|
|
5094
|
+
}, Si = {
|
|
5093
5095
|
type: s.literal("workspaces").describe("The type of the response."),
|
|
5094
5096
|
workspaces: s.array(s.object(Ii)).describe("List of workspaces."),
|
|
5095
5097
|
count: s.number().describe("The total number of workspaces.")
|
|
5096
5098
|
};
|
|
5097
|
-
async function
|
|
5099
|
+
async function ji(e) {
|
|
5098
5100
|
const r = (await e.getWorkspaces()).map((i) => ({
|
|
5099
5101
|
id: i.id,
|
|
5100
5102
|
name: i.name,
|
|
@@ -5129,10 +5131,10 @@ const Ci = {
|
|
|
5129
5131
|
name: g.LIST_WORKSPACES,
|
|
5130
5132
|
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.",
|
|
5131
5133
|
parameters: vi,
|
|
5132
|
-
outputSchema:
|
|
5134
|
+
outputSchema: Si,
|
|
5133
5135
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
5134
5136
|
async execute(e, t) {
|
|
5135
|
-
const r = await
|
|
5137
|
+
const r = await ji(t);
|
|
5136
5138
|
return {
|
|
5137
5139
|
textContent: r.textContent,
|
|
5138
5140
|
structuredContent: r.structuredContent
|
|
@@ -5175,37 +5177,37 @@ const Ci = {
|
|
|
5175
5177
|
if ((r === "assign" || r === "reassign") && !n)
|
|
5176
5178
|
throw new Error(`${r} operation requires responsibleUser parameter`);
|
|
5177
5179
|
const c = await Promise.allSettled(
|
|
5178
|
-
o.map(async (
|
|
5180
|
+
o.map(async (k) => {
|
|
5179
5181
|
try {
|
|
5180
|
-
return await t.getTask(
|
|
5182
|
+
return await t.getTask(k);
|
|
5181
5183
|
} catch {
|
|
5182
|
-
throw new Error(`Task ${
|
|
5184
|
+
throw new Error(`Task ${k} not found or not accessible`);
|
|
5183
5185
|
}
|
|
5184
5186
|
})
|
|
5185
5187
|
), d = [], l = [];
|
|
5186
|
-
for (let
|
|
5187
|
-
const I = c[
|
|
5188
|
+
for (let k = 0; k < c.length; k++) {
|
|
5189
|
+
const I = c[k];
|
|
5188
5190
|
I && I.status === "fulfilled" ? d.push(I.value) : I && I.status === "rejected" ? l.push({
|
|
5189
|
-
taskId: o[
|
|
5191
|
+
taskId: o[k] || "invalid-task-id",
|
|
5190
5192
|
success: !1,
|
|
5191
5193
|
error: I.reason?.message || "Task not accessible"
|
|
5192
5194
|
}) : l.push({
|
|
5193
|
-
taskId: o[
|
|
5195
|
+
taskId: o[k] || "invalid-task-id",
|
|
5194
5196
|
success: !1,
|
|
5195
5197
|
error: "Task not accessible"
|
|
5196
5198
|
});
|
|
5197
5199
|
}
|
|
5198
5200
|
if (d.length === 0) {
|
|
5199
|
-
const
|
|
5200
|
-
throw new Error(`All ${l.length} task(s) failed: ${
|
|
5201
|
+
const k = l.map((I) => `"${I.taskId}": ${I.error}`).join("; ");
|
|
5202
|
+
throw new Error(`All ${l.length} task(s) failed: ${k}`);
|
|
5201
5203
|
}
|
|
5202
5204
|
let u;
|
|
5203
5205
|
r === "reassign" && a && (u = (await W.resolveUser(t, a))?.userId || a);
|
|
5204
5206
|
const p = [];
|
|
5205
|
-
for (const
|
|
5206
|
-
r === "reassign" && u &&
|
|
5207
|
-
taskId:
|
|
5208
|
-
projectId:
|
|
5207
|
+
for (const k of d)
|
|
5208
|
+
r === "reassign" && u && k.responsibleUid !== u || p.push({
|
|
5209
|
+
taskId: k.id,
|
|
5210
|
+
projectId: k.projectId,
|
|
5209
5211
|
responsibleUid: n || ""
|
|
5210
5212
|
// Will be validated appropriately
|
|
5211
5213
|
});
|
|
@@ -5233,7 +5235,7 @@ const Ci = {
|
|
|
5233
5235
|
}
|
|
5234
5236
|
};
|
|
5235
5237
|
}
|
|
5236
|
-
const
|
|
5238
|
+
const k = d.map(async (b) => {
|
|
5237
5239
|
try {
|
|
5238
5240
|
return await t.updateTask(b.id, { assigneeId: null }), {
|
|
5239
5241
|
taskId: b.id,
|
|
@@ -5241,17 +5243,17 @@ const Ci = {
|
|
|
5241
5243
|
originalAssigneeId: b.responsibleUid ?? void 0,
|
|
5242
5244
|
newAssigneeId: void 0
|
|
5243
5245
|
};
|
|
5244
|
-
} catch (
|
|
5246
|
+
} catch (S) {
|
|
5245
5247
|
return {
|
|
5246
5248
|
taskId: b.id,
|
|
5247
5249
|
success: !1,
|
|
5248
|
-
error:
|
|
5250
|
+
error: S instanceof Error ? S.message : "Update failed",
|
|
5249
5251
|
originalAssigneeId: b.responsibleUid ?? void 0
|
|
5250
5252
|
};
|
|
5251
5253
|
}
|
|
5252
|
-
}), I = await Promise.all(
|
|
5254
|
+
}), I = await Promise.all(k), x = [...I, ...l];
|
|
5253
5255
|
if (x.length > 0 && x.every((b) => !b.success)) {
|
|
5254
|
-
const b = x.map((
|
|
5256
|
+
const b = x.map((S) => `"${S.taskId}": ${S.error}`).join("; ");
|
|
5255
5257
|
throw new Error(`All ${x.length} unassign operation(s) failed: ${b}`);
|
|
5256
5258
|
}
|
|
5257
5259
|
return {
|
|
@@ -5274,22 +5276,22 @@ const Ci = {
|
|
|
5274
5276
|
t,
|
|
5275
5277
|
p
|
|
5276
5278
|
), h = [], y = [];
|
|
5277
|
-
for (let
|
|
5278
|
-
const I = p[
|
|
5279
|
+
for (let k = 0; k < p.length; k++) {
|
|
5280
|
+
const I = p[k], x = m[k];
|
|
5279
5281
|
I && x?.isValid ? h.push({ assignment: I, validation: x }) : I?.taskId && y.push({
|
|
5280
5282
|
taskId: I.taskId,
|
|
5281
5283
|
success: !1,
|
|
5282
5284
|
error: x?.error?.message || "Validation failed"
|
|
5283
5285
|
});
|
|
5284
5286
|
}
|
|
5285
|
-
async function f(
|
|
5286
|
-
const x =
|
|
5287
|
+
async function f(k, I) {
|
|
5288
|
+
const x = k.filter(
|
|
5287
5289
|
(b) => b.assignment != null && b.validation != null
|
|
5288
5290
|
);
|
|
5289
5291
|
if (!I)
|
|
5290
|
-
return x.map(({ assignment: b, validation:
|
|
5292
|
+
return x.map(({ assignment: b, validation: S }) => {
|
|
5291
5293
|
const $ = d.find((D) => D.id === b.taskId);
|
|
5292
|
-
if (!b.taskId || !
|
|
5294
|
+
if (!b.taskId || !S.resolvedUser?.userId)
|
|
5293
5295
|
throw new Error(
|
|
5294
5296
|
"Invalid assignment or validation data - this should not happen"
|
|
5295
5297
|
);
|
|
@@ -5297,13 +5299,13 @@ const Ci = {
|
|
|
5297
5299
|
taskId: b.taskId,
|
|
5298
5300
|
success: !0,
|
|
5299
5301
|
originalAssigneeId: $?.responsibleUid ?? void 0,
|
|
5300
|
-
newAssigneeId:
|
|
5302
|
+
newAssigneeId: S.resolvedUser.userId
|
|
5301
5303
|
};
|
|
5302
5304
|
});
|
|
5303
|
-
const
|
|
5304
|
-
async ({ assignment: b, validation:
|
|
5305
|
+
const T = x.map(
|
|
5306
|
+
async ({ assignment: b, validation: S }) => {
|
|
5305
5307
|
const $ = d.find((D) => D.id === b.taskId);
|
|
5306
|
-
if (!b.taskId || !
|
|
5308
|
+
if (!b.taskId || !S.resolvedUser?.userId)
|
|
5307
5309
|
return {
|
|
5308
5310
|
taskId: b.taskId || "unknown-task",
|
|
5309
5311
|
success: !1,
|
|
@@ -5312,12 +5314,12 @@ const Ci = {
|
|
|
5312
5314
|
};
|
|
5313
5315
|
try {
|
|
5314
5316
|
return await t.updateTask(b.taskId, {
|
|
5315
|
-
assigneeId:
|
|
5317
|
+
assigneeId: S.resolvedUser.userId
|
|
5316
5318
|
}), {
|
|
5317
5319
|
taskId: b.taskId,
|
|
5318
5320
|
success: !0,
|
|
5319
5321
|
originalAssigneeId: $?.responsibleUid ?? void 0,
|
|
5320
|
-
newAssigneeId:
|
|
5322
|
+
newAssigneeId: S.resolvedUser.userId
|
|
5321
5323
|
};
|
|
5322
5324
|
} catch (D) {
|
|
5323
5325
|
return {
|
|
@@ -5329,25 +5331,25 @@ const Ci = {
|
|
|
5329
5331
|
}
|
|
5330
5332
|
}
|
|
5331
5333
|
);
|
|
5332
|
-
return Promise.all(
|
|
5334
|
+
return Promise.all(T);
|
|
5333
5335
|
}
|
|
5334
|
-
const v = await f(h, !i),
|
|
5335
|
-
if (
|
|
5336
|
-
const
|
|
5337
|
-
throw new Error(`All ${
|
|
5336
|
+
const v = await f(h, !i), j = [...v, ...y, ...l];
|
|
5337
|
+
if (j.length > 0 && j.every((k) => !k.success)) {
|
|
5338
|
+
const k = j.map((I) => `"${I.taskId}": ${I.error}`).join("; ");
|
|
5339
|
+
throw new Error(`All ${j.length} ${r} operation(s) failed: ${k}`);
|
|
5338
5340
|
}
|
|
5339
5341
|
return {
|
|
5340
5342
|
textContent: Oe({
|
|
5341
5343
|
operation: r,
|
|
5342
|
-
results:
|
|
5344
|
+
results: j,
|
|
5343
5345
|
dryRun: i
|
|
5344
5346
|
}),
|
|
5345
5347
|
structuredContent: {
|
|
5346
5348
|
operation: r,
|
|
5347
|
-
results:
|
|
5349
|
+
results: j,
|
|
5348
5350
|
totalRequested: o.length,
|
|
5349
|
-
successful: v.filter((
|
|
5350
|
-
failed:
|
|
5351
|
+
successful: v.filter((k) => k.success).length,
|
|
5352
|
+
failed: j.filter((k) => !k.success).length,
|
|
5351
5353
|
dryRun: i
|
|
5352
5354
|
}
|
|
5353
5355
|
};
|
|
@@ -5407,14 +5409,14 @@ function Oe({
|
|
|
5407
5409
|
const Pi = {
|
|
5408
5410
|
action: s.enum(["archive", "unarchive"]).describe("The action to perform on the project."),
|
|
5409
5411
|
projectId: s.string().min(1).describe("The ID of the project.")
|
|
5410
|
-
},
|
|
5412
|
+
}, _i = {
|
|
5411
5413
|
project: Q.describe("The updated project."),
|
|
5412
5414
|
success: s.boolean().describe("Whether the action was successful.")
|
|
5413
|
-
},
|
|
5415
|
+
}, Ri = {
|
|
5414
5416
|
name: g.PROJECT_MANAGEMENT,
|
|
5415
5417
|
description: "Archive or unarchive a project by its ID.",
|
|
5416
5418
|
parameters: Pi,
|
|
5417
|
-
outputSchema:
|
|
5419
|
+
outputSchema: _i,
|
|
5418
5420
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !0 },
|
|
5419
5421
|
async execute(e, t) {
|
|
5420
5422
|
const r = e.action === "archive" ? await t.archiveProject(e.projectId) : await t.unarchiveProject(e.projectId), o = Z(r);
|
|
@@ -5437,7 +5439,7 @@ const Pi = {
|
|
|
5437
5439
|
}, Li = {
|
|
5438
5440
|
project: Q.describe("The moved project."),
|
|
5439
5441
|
success: s.boolean().describe("Whether the move was successful.")
|
|
5440
|
-
},
|
|
5442
|
+
}, Ni = {
|
|
5441
5443
|
name: g.PROJECT_MOVE,
|
|
5442
5444
|
description: "Move a project between personal and workspace contexts.",
|
|
5443
5445
|
parameters: Ui,
|
|
@@ -5464,7 +5466,7 @@ const Pi = {
|
|
|
5464
5466
|
}
|
|
5465
5467
|
};
|
|
5466
5468
|
}
|
|
5467
|
-
}, Is = ["project", "section"],
|
|
5469
|
+
}, Is = ["project", "section"], Mi = {
|
|
5468
5470
|
type: s.enum(Is).describe(
|
|
5469
5471
|
'The type of entity to reorder. "project" reorders sibling projects within the same parent (and can move projects to a new parent). "section" reorders sections within the same project.'
|
|
5470
5472
|
),
|
|
@@ -5490,7 +5492,7 @@ const Pi = {
|
|
|
5490
5492
|
}, Hi = {
|
|
5491
5493
|
name: g.REORDER_OBJECTS,
|
|
5492
5494
|
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.',
|
|
5493
|
-
parameters:
|
|
5495
|
+
parameters: Mi,
|
|
5494
5496
|
outputSchema: Fi,
|
|
5495
5497
|
annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !0 },
|
|
5496
5498
|
async execute(e, t) {
|
|
@@ -5560,15 +5562,15 @@ const Pi = {
|
|
|
5560
5562
|
)
|
|
5561
5563
|
}), Bi = {
|
|
5562
5564
|
tasks: s.array(Wi).min(1).describe("The tasks to reschedule with their new dates.")
|
|
5563
|
-
},
|
|
5565
|
+
}, zi = {
|
|
5564
5566
|
tasks: s.array(F).describe("The rescheduled tasks."),
|
|
5565
5567
|
totalCount: s.number().describe("The total number of tasks rescheduled."),
|
|
5566
5568
|
rescheduledTaskIds: s.array(s.string()).describe("The IDs of the rescheduled tasks.")
|
|
5567
|
-
},
|
|
5569
|
+
}, Ki = {
|
|
5568
5570
|
name: g.RESCHEDULE_TASKS,
|
|
5569
5571
|
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.",
|
|
5570
5572
|
parameters: Bi,
|
|
5571
|
-
outputSchema:
|
|
5573
|
+
outputSchema: zi,
|
|
5572
5574
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
|
|
5573
5575
|
async execute(e, t) {
|
|
5574
5576
|
const { tasks: r } = e, n = (await Promise.all(
|
|
@@ -5619,9 +5621,9 @@ function qi(e, t) {
|
|
|
5619
5621
|
}
|
|
5620
5622
|
return e;
|
|
5621
5623
|
}
|
|
5622
|
-
const
|
|
5624
|
+
const Yi = {
|
|
5623
5625
|
query: s.string().min(1).describe("The search query string to find tasks and projects.")
|
|
5624
|
-
},
|
|
5626
|
+
}, Gi = {
|
|
5625
5627
|
results: s.array(
|
|
5626
5628
|
s.object({
|
|
5627
5629
|
id: s.string().describe("The ID of the result."),
|
|
@@ -5633,8 +5635,8 @@ const Gi = {
|
|
|
5633
5635
|
}, Vi = {
|
|
5634
5636
|
name: g.SEARCH,
|
|
5635
5637
|
description: "Search across tasks and projects in Todoist. Returns a list of relevant results with IDs, titles, and URLs.",
|
|
5636
|
-
parameters:
|
|
5637
|
-
outputSchema:
|
|
5638
|
+
parameters: Yi,
|
|
5639
|
+
outputSchema: Gi,
|
|
5638
5640
|
annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
|
|
5639
5641
|
async execute(e, t) {
|
|
5640
5642
|
const { query: r } = e, [o, n] = await Promise.all([
|
|
@@ -5650,7 +5652,7 @@ const Gi = {
|
|
|
5650
5652
|
a.push({
|
|
5651
5653
|
id: `task:${i.id}`,
|
|
5652
5654
|
title: i.content,
|
|
5653
|
-
url:
|
|
5655
|
+
url: Mt(i.id)
|
|
5654
5656
|
});
|
|
5655
5657
|
for (const i of n)
|
|
5656
5658
|
a.push({
|
|
@@ -5895,7 +5897,7 @@ const uc = s.object({
|
|
|
5895
5897
|
const { labels: r } = e, o = await Promise.all(
|
|
5896
5898
|
r.map(async (u) => {
|
|
5897
5899
|
if (u.labelType === "personal") {
|
|
5898
|
-
const m =
|
|
5900
|
+
const m = Tc(u);
|
|
5899
5901
|
if (m !== null) return { kind: "skipped", reason: m };
|
|
5900
5902
|
const { id: h, labelType: y, ...f } = u;
|
|
5901
5903
|
return { kind: "updated", label: await t.updateLabel(h, f) };
|
|
@@ -5954,14 +5956,14 @@ function yc({
|
|
|
5954
5956
|
return c.join(`
|
|
5955
5957
|
`);
|
|
5956
5958
|
}
|
|
5957
|
-
function
|
|
5959
|
+
function Tc({
|
|
5958
5960
|
id: e,
|
|
5959
5961
|
labelType: t,
|
|
5960
5962
|
...r
|
|
5961
5963
|
}) {
|
|
5962
5964
|
return Object.values(r).every((n) => n === void 0) ? "no-fields" : null;
|
|
5963
5965
|
}
|
|
5964
|
-
const
|
|
5966
|
+
const kc = s.object({
|
|
5965
5967
|
id: s.string().min(1).describe("The ID of the project to update."),
|
|
5966
5968
|
name: s.string().min(1).optional().describe("The new name of the project."),
|
|
5967
5969
|
isFavorite: s.boolean().optional().describe("Whether the project is a favorite."),
|
|
@@ -5977,7 +5979,7 @@ const Tc = s.object({
|
|
|
5977
5979
|
).optional(),
|
|
5978
5980
|
color: le
|
|
5979
5981
|
}), wc = {
|
|
5980
|
-
projects: s.array(
|
|
5982
|
+
projects: s.array(kc).min(1).describe("The projects to update.")
|
|
5981
5983
|
}, vc = {
|
|
5982
5984
|
projects: s.array(Q).describe("The updated projects."),
|
|
5983
5985
|
totalCount: s.number().describe("The total number of projects updated."),
|
|
@@ -5999,7 +6001,7 @@ const Tc = s.object({
|
|
|
5999
6001
|
async execute(e, t) {
|
|
6000
6002
|
const { projects: r } = e, o = await Promise.allSettled(
|
|
6001
6003
|
r.map(async (l) => {
|
|
6002
|
-
const u =
|
|
6004
|
+
const u = jc(l);
|
|
6003
6005
|
if (u !== null) return { kind: "skipped", reason: u };
|
|
6004
6006
|
const { id: p, ...m } = l;
|
|
6005
6007
|
return { kind: "updated", project: await O(() => t.updateProject(p, m)) };
|
|
@@ -6010,14 +6012,14 @@ const Tc = s.object({
|
|
|
6010
6012
|
if (u.status === "rejected") {
|
|
6011
6013
|
a.push({
|
|
6012
6014
|
item: r[l]?.id ?? `Project ${l + 1}`,
|
|
6013
|
-
error:
|
|
6015
|
+
error: z(u.reason)
|
|
6014
6016
|
});
|
|
6015
6017
|
continue;
|
|
6016
6018
|
}
|
|
6017
6019
|
u.value.kind === "updated" ? n.push(Z(u.value.project)) : u.value.reason === "no-fields" ? i++ : c++;
|
|
6018
6020
|
}
|
|
6019
6021
|
return {
|
|
6020
|
-
textContent:
|
|
6022
|
+
textContent: Sc({
|
|
6021
6023
|
projects: n,
|
|
6022
6024
|
skippedNoFields: i,
|
|
6023
6025
|
skippedNoValidValues: c,
|
|
@@ -6037,7 +6039,7 @@ const Tc = s.object({
|
|
|
6037
6039
|
};
|
|
6038
6040
|
}
|
|
6039
6041
|
};
|
|
6040
|
-
function
|
|
6042
|
+
function Sc({
|
|
6041
6043
|
projects: e,
|
|
6042
6044
|
skippedNoFields: t,
|
|
6043
6045
|
skippedNoValidValues: r,
|
|
@@ -6050,7 +6052,7 @@ function jc({
|
|
|
6050
6052
|
return t > 0 && c.push(`${t} skipped - no changes`), r > 0 && c.push(`${r} skipped - no valid field values`), c.length > 0 && (i += ` (${c.join(", ")})`), n > 0 && (i += `:
|
|
6051
6053
|
${a}`), at(i, o);
|
|
6052
6054
|
}
|
|
6053
|
-
function
|
|
6055
|
+
function jc({ id: e, ...t }) {
|
|
6054
6056
|
const r = Object.values(t);
|
|
6055
6057
|
return r.length === 0 ? "no-fields" : r.every((o) => o === void 0) ? "no-valid-values" : null;
|
|
6056
6058
|
}
|
|
@@ -6058,13 +6060,13 @@ const Cc = s.object({
|
|
|
6058
6060
|
type: s.literal("relative"),
|
|
6059
6061
|
id: s.string().min(1).describe("The ID of the relative reminder to update."),
|
|
6060
6062
|
minuteOffset: s.number().int().min(0).optional().describe("New minute offset before task due time."),
|
|
6061
|
-
service:
|
|
6063
|
+
service: je.optional().describe('New delivery method: "email" or "push".'),
|
|
6062
6064
|
isUrgent: Ce
|
|
6063
6065
|
}), $c = s.object({
|
|
6064
6066
|
type: s.literal("absolute"),
|
|
6065
6067
|
id: s.string().min(1).describe("The ID of the absolute reminder to update."),
|
|
6066
6068
|
due: cs.optional().describe("New due date/time for the reminder."),
|
|
6067
|
-
service:
|
|
6069
|
+
service: je.optional().describe('New delivery method: "email" or "push".'),
|
|
6068
6070
|
isUrgent: Ce
|
|
6069
6071
|
}), Dc = s.object({
|
|
6070
6072
|
type: s.literal("location"),
|
|
@@ -6141,17 +6143,17 @@ const Cc = s.object({
|
|
|
6141
6143
|
).optional()
|
|
6142
6144
|
}).refine((e) => e.name !== void 0 || e.description !== void 0, {
|
|
6143
6145
|
message: 'Provide at least one of "name" or "description" to update.'
|
|
6144
|
-
}),
|
|
6146
|
+
}), _c = {
|
|
6145
6147
|
sections: s.array(Pc).min(1).describe("The sections to update.")
|
|
6146
|
-
},
|
|
6148
|
+
}, Rc = {
|
|
6147
6149
|
sections: s.array(X).describe("The updated sections."),
|
|
6148
6150
|
totalCount: s.number().describe("The total number of sections updated."),
|
|
6149
6151
|
updatedSectionIds: s.array(s.string()).describe("The IDs of the updated sections.")
|
|
6150
6152
|
}, Uc = {
|
|
6151
6153
|
name: g.UPDATE_SECTIONS,
|
|
6152
6154
|
description: "Update multiple existing sections with new values.",
|
|
6153
|
-
parameters:
|
|
6154
|
-
outputSchema:
|
|
6155
|
+
parameters: _c,
|
|
6156
|
+
outputSchema: Rc,
|
|
6155
6157
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
|
|
6156
6158
|
async execute({ sections: e }, t) {
|
|
6157
6159
|
const r = await Promise.all(
|
|
@@ -6168,7 +6170,7 @@ const Cc = s.object({
|
|
|
6168
6170
|
sections: r
|
|
6169
6171
|
}),
|
|
6170
6172
|
structuredContent: {
|
|
6171
|
-
sections: r.map(
|
|
6173
|
+
sections: r.map(K),
|
|
6172
6174
|
totalCount: r.length,
|
|
6173
6175
|
updatedSectionIds: r.map((n) => n.id)
|
|
6174
6176
|
}
|
|
@@ -6181,13 +6183,13 @@ function Lc({ sections: e }) {
|
|
|
6181
6183
|
return `Updated ${t} section${t === 1 ? "" : "s"}:
|
|
6182
6184
|
${r}`;
|
|
6183
6185
|
}
|
|
6184
|
-
function
|
|
6186
|
+
function Ss(e, t) {
|
|
6185
6187
|
return t.projectId !== void 0 ? e.projectId === t.projectId && !e.sectionId && !e.parentId : t.sectionId !== void 0 ? e.sectionId === t.sectionId && !e.parentId : e.parentId === t.parentId;
|
|
6186
6188
|
}
|
|
6187
|
-
function
|
|
6189
|
+
function Nc(e, t) {
|
|
6188
6190
|
return t.projectId !== void 0 ? e.projectId === t.projectId : t.sectionId !== void 0 ? e.sectionId === t.sectionId : e.parentId === t.parentId;
|
|
6189
6191
|
}
|
|
6190
|
-
function
|
|
6192
|
+
function Mc(e) {
|
|
6191
6193
|
return e.projectId !== void 0 ? `project:${e.projectId}` : e.sectionId !== void 0 ? `section:${e.sectionId}` : `parent:${e.parentId}`;
|
|
6192
6194
|
}
|
|
6193
6195
|
function Fc(e) {
|
|
@@ -6204,7 +6206,7 @@ function Hc({
|
|
|
6204
6206
|
return { redundantMoveSkipped: !1 };
|
|
6205
6207
|
let n = o, a = !1;
|
|
6206
6208
|
if (r) {
|
|
6207
|
-
const i = o.length === 1 ? (c) =>
|
|
6209
|
+
const i = o.length === 1 ? (c) => Ss(r, c) : (c) => Nc(r, c);
|
|
6208
6210
|
n = o.filter((c) => !i(c)), a = n.length < o.length;
|
|
6209
6211
|
}
|
|
6210
6212
|
if (n.length === 0)
|
|
@@ -6260,9 +6262,9 @@ const Wc = s.object({
|
|
|
6260
6262
|
isUncompletable: s.boolean().optional().describe(
|
|
6261
6263
|
"Whether this task should be uncompletable (organizational header). Tasks with isUncompletable: true appear as organizational headers and cannot be completed."
|
|
6262
6264
|
)
|
|
6263
|
-
}), Bc = (e) => !!(e.projectId || e.sectionId || e.parentId),
|
|
6264
|
-
tasks: s.array(Wc).min(1).max(
|
|
6265
|
-
},
|
|
6265
|
+
}), Bc = (e) => !!(e.projectId || e.sectionId || e.parentId), js = (e) => Object.keys(e).length > 0, zc = ["remove", "no date"], Kc = ["remove", "no date", "no deadline"], qc = "no date", Ye = Kt.TASKS_PER_OPERATION, Ot = {
|
|
6266
|
+
tasks: s.array(Wc).min(1).max(Ye).describe(`The tasks to update (max ${Ye}).`)
|
|
6267
|
+
}, Yc = {
|
|
6266
6268
|
tasks: s.array(F).describe("The updated tasks."),
|
|
6267
6269
|
totalCount: s.number().describe("The total number of tasks updated."),
|
|
6268
6270
|
updatedTaskIds: s.array(s.string()).describe("The IDs of the updated tasks."),
|
|
@@ -6277,111 +6279,111 @@ const Wc = s.object({
|
|
|
6277
6279
|
"Moves not performed because the task was already in the requested destination. A non-zero count means container fields were sent that did not need to be."
|
|
6278
6280
|
)
|
|
6279
6281
|
}).describe("Summary of operations performed.")
|
|
6280
|
-
},
|
|
6282
|
+
}, Gc = {
|
|
6281
6283
|
name: g.UPDATE_TASKS,
|
|
6282
6284
|
description: "Update existing tasks including content, dates, priorities, and assignments. Send only the fields that change.",
|
|
6283
6285
|
parameters: Ot,
|
|
6284
|
-
outputSchema:
|
|
6286
|
+
outputSchema: Yc,
|
|
6285
6287
|
annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
|
|
6286
6288
|
async execute(e, t) {
|
|
6287
|
-
const { tasks: r } = s.object(Ot).parse(e), o = r.map(() => ({ kind: "skipped" })), n = (
|
|
6288
|
-
o[
|
|
6289
|
-
}, a = (
|
|
6290
|
-
n(
|
|
6291
|
-
}, i = r.map((
|
|
6292
|
-
i.map(({ task:
|
|
6289
|
+
const { tasks: r } = s.object(Ot).parse(e), o = r.map(() => ({ kind: "skipped" })), n = (T, b) => {
|
|
6290
|
+
o[T] = { kind: "failed", error: b };
|
|
6291
|
+
}, a = (T, b) => {
|
|
6292
|
+
n(T, z(b));
|
|
6293
|
+
}, i = r.map((T, b) => ({ task: T, index: b })).filter(({ task: T }) => rd(T)), c = await Jc(
|
|
6294
|
+
i.map(({ task: T }) => T),
|
|
6293
6295
|
t
|
|
6294
6296
|
), d = await Promise.allSettled(
|
|
6295
|
-
i.map(({ task:
|
|
6297
|
+
i.map(({ task: T, index: b }) => ed({ task: T, index: b, client: t, inbox: c }))
|
|
6296
6298
|
), l = [];
|
|
6297
|
-
for (const [
|
|
6298
|
-
const
|
|
6299
|
-
b.status === "fulfilled" ? l.push(b.value) : a(
|
|
6299
|
+
for (const [T, b] of d.entries()) {
|
|
6300
|
+
const S = i[T]?.index ?? T;
|
|
6301
|
+
b.status === "fulfilled" ? l.push(b.value) : a(S, b.reason);
|
|
6300
6302
|
}
|
|
6301
6303
|
const u = await Cs({
|
|
6302
6304
|
client: t,
|
|
6303
6305
|
ids: [
|
|
6304
6306
|
...new Set(
|
|
6305
|
-
l.filter((
|
|
6307
|
+
l.filter((T) => Bc(T.moveRequest)).map((T) => T.id)
|
|
6306
6308
|
)
|
|
6307
6309
|
]
|
|
6308
6310
|
}), p = [];
|
|
6309
|
-
for (const
|
|
6311
|
+
for (const T of l)
|
|
6310
6312
|
try {
|
|
6311
6313
|
const b = Hc({
|
|
6312
|
-
taskId:
|
|
6313
|
-
request:
|
|
6314
|
-
current: u.get(
|
|
6314
|
+
taskId: T.id,
|
|
6315
|
+
request: T.moveRequest,
|
|
6316
|
+
current: u.get(T.id)
|
|
6315
6317
|
});
|
|
6316
|
-
|
|
6318
|
+
T.redundantMoveSkipped = b.redundantMoveSkipped, b.move && p.push({ item: T, move: b.move });
|
|
6317
6319
|
} catch (b) {
|
|
6318
|
-
a(
|
|
6320
|
+
a(T.index, b), T.failed = !0;
|
|
6319
6321
|
}
|
|
6320
|
-
const m = /* @__PURE__ */ new Map(), h = [], y = (
|
|
6321
|
-
const b =
|
|
6322
|
+
const m = /* @__PURE__ */ new Map(), h = [], y = (T) => {
|
|
6323
|
+
const b = T.filter((S) => !S.failed);
|
|
6322
6324
|
b.length !== 0 && h.push(
|
|
6323
6325
|
Qc({
|
|
6324
6326
|
client: t,
|
|
6325
6327
|
items: b,
|
|
6326
|
-
onUpdated: (
|
|
6327
|
-
o[
|
|
6328
|
+
onUpdated: (S, $) => {
|
|
6329
|
+
o[S.index] = { kind: "updated", task: $ };
|
|
6328
6330
|
},
|
|
6329
|
-
onFailed: (
|
|
6330
|
-
const D = m.get(
|
|
6331
|
+
onFailed: (S, $) => {
|
|
6332
|
+
const D = m.get(S.index);
|
|
6331
6333
|
if (D && "task" in D) {
|
|
6332
|
-
o[
|
|
6334
|
+
o[S.index] = {
|
|
6333
6335
|
kind: "partial",
|
|
6334
6336
|
task: D.task,
|
|
6335
|
-
error: `Move applied; field update failed: ${
|
|
6337
|
+
error: `Move applied; field update failed: ${z($)}`
|
|
6336
6338
|
};
|
|
6337
6339
|
return;
|
|
6338
6340
|
}
|
|
6339
|
-
a(
|
|
6341
|
+
a(S.index, $);
|
|
6340
6342
|
}
|
|
6341
6343
|
})
|
|
6342
6344
|
);
|
|
6343
|
-
}, f = new Set(p.map(({ item:
|
|
6344
|
-
y(l.filter((
|
|
6345
|
+
}, f = new Set(p.map(({ item: T }) => T.index));
|
|
6346
|
+
y(l.filter((T) => !f.has(T.index))), await Xc({
|
|
6345
6347
|
client: t,
|
|
6346
6348
|
moving: p,
|
|
6347
6349
|
results: m,
|
|
6348
|
-
onResolved: (
|
|
6350
|
+
onResolved: (T) => {
|
|
6349
6351
|
const b = [];
|
|
6350
|
-
for (const { item:
|
|
6351
|
-
const $ = m.get(
|
|
6352
|
+
for (const { item: S } of T) {
|
|
6353
|
+
const $ = m.get(S.index);
|
|
6352
6354
|
if ($ && "error" in $) {
|
|
6353
|
-
n(
|
|
6355
|
+
n(S.index, $.error), S.failed = !0;
|
|
6354
6356
|
continue;
|
|
6355
6357
|
}
|
|
6356
|
-
b.push(
|
|
6358
|
+
b.push(S);
|
|
6357
6359
|
}
|
|
6358
6360
|
y(b);
|
|
6359
6361
|
}
|
|
6360
6362
|
}), await Promise.all(h);
|
|
6361
|
-
for (const
|
|
6362
|
-
if (
|
|
6363
|
+
for (const T of l) {
|
|
6364
|
+
if (T.failed || js(T.updateArgs))
|
|
6363
6365
|
continue;
|
|
6364
|
-
const b = m.get(
|
|
6365
|
-
b && "task" in b && (o[
|
|
6366
|
+
const b = m.get(T.index);
|
|
6367
|
+
b && "task" in b && (o[T.index] = { kind: "updated", task: b.task });
|
|
6366
6368
|
}
|
|
6367
|
-
const { updatedTasks: v, failures:
|
|
6369
|
+
const { updatedTasks: v, failures: j, skippedCount: A } = Vc({ tasks: r, outcomes: o }), k = l.filter((T) => T.redundantMoveSkipped).length, I = v.map(P);
|
|
6368
6370
|
return {
|
|
6369
6371
|
textContent: sd({
|
|
6370
6372
|
tasks: I,
|
|
6371
|
-
failures:
|
|
6373
|
+
failures: j,
|
|
6372
6374
|
skippedCount: A,
|
|
6373
|
-
redundantMovesSkipped:
|
|
6375
|
+
redundantMovesSkipped: k
|
|
6374
6376
|
}),
|
|
6375
6377
|
structuredContent: {
|
|
6376
6378
|
tasks: I,
|
|
6377
6379
|
totalCount: I.length,
|
|
6378
|
-
updatedTaskIds: v.map((
|
|
6379
|
-
failures:
|
|
6380
|
+
updatedTaskIds: v.map((T) => T.id),
|
|
6381
|
+
failures: j,
|
|
6380
6382
|
appliedOperations: {
|
|
6381
6383
|
updateCount: I.length,
|
|
6382
6384
|
skippedCount: A,
|
|
6383
|
-
failureCount:
|
|
6384
|
-
redundantMovesSkipped:
|
|
6385
|
+
failureCount: j.length,
|
|
6386
|
+
redundantMovesSkipped: k
|
|
6385
6387
|
}
|
|
6386
6388
|
}
|
|
6387
6389
|
};
|
|
@@ -6405,7 +6407,7 @@ function Vc({ tasks: e, outcomes: t }) {
|
|
|
6405
6407
|
return { updatedTasks: r, failures: o, skippedCount: n };
|
|
6406
6408
|
}
|
|
6407
6409
|
async function Jc(e, t) {
|
|
6408
|
-
if (!e.some((r) =>
|
|
6410
|
+
if (!e.some((r) => N(r.projectId)))
|
|
6409
6411
|
return {};
|
|
6410
6412
|
try {
|
|
6411
6413
|
return { projectId: (await O(() => t.getUser())).inboxProjectId };
|
|
@@ -6423,7 +6425,7 @@ async function Cs({
|
|
|
6423
6425
|
try {
|
|
6424
6426
|
const o = new Set(t), n = {
|
|
6425
6427
|
ids: t.join(","),
|
|
6426
|
-
limit:
|
|
6428
|
+
limit: Ye
|
|
6427
6429
|
}, { results: a } = await O(() => e.getTasks(n));
|
|
6428
6430
|
for (const i of a)
|
|
6429
6431
|
o.has(i.id) && r.set(i.id, i);
|
|
@@ -6441,7 +6443,7 @@ async function Xc({
|
|
|
6441
6443
|
return;
|
|
6442
6444
|
const n = /* @__PURE__ */ new Map();
|
|
6443
6445
|
for (const c of t) {
|
|
6444
|
-
const d =
|
|
6446
|
+
const d = Mc(c.move), l = n.get(d);
|
|
6445
6447
|
l ? l.push(c) : n.set(d, [c]);
|
|
6446
6448
|
}
|
|
6447
6449
|
const a = lr(e), i = [];
|
|
@@ -6465,7 +6467,7 @@ async function Xc({
|
|
|
6465
6467
|
o(y), h.length > 0 && i.push({ group: h, destination: l });
|
|
6466
6468
|
} catch (p) {
|
|
6467
6469
|
if (u) {
|
|
6468
|
-
r.set(u.item.index, { error:
|
|
6470
|
+
r.set(u.item.index, { error: z(p) }), o(c);
|
|
6469
6471
|
continue;
|
|
6470
6472
|
}
|
|
6471
6473
|
i.push({ group: c, destination: l, error: p });
|
|
@@ -6484,10 +6486,10 @@ async function Zc({
|
|
|
6484
6486
|
}) {
|
|
6485
6487
|
const o = [...new Set(t.flatMap(({ group: a }) => a.map(({ item: i }) => i.id)))], n = await Cs({ client: e, ids: o });
|
|
6486
6488
|
for (const { group: a, destination: i, error: c } of t) {
|
|
6487
|
-
const d = c === void 0 ? "Task not returned by the move" :
|
|
6489
|
+
const d = c === void 0 ? "Task not returned by the move" : z(c);
|
|
6488
6490
|
for (const { item: l } of a) {
|
|
6489
6491
|
const u = n.get(l.id);
|
|
6490
|
-
if (u &&
|
|
6492
|
+
if (u && Ss(u, i)) {
|
|
6491
6493
|
r.set(l.index, { task: u });
|
|
6492
6494
|
continue;
|
|
6493
6495
|
}
|
|
@@ -6503,7 +6505,7 @@ async function Qc({
|
|
|
6503
6505
|
}) {
|
|
6504
6506
|
const n = ur(e);
|
|
6505
6507
|
await Promise.all(
|
|
6506
|
-
t.filter((a) =>
|
|
6508
|
+
t.filter((a) => js(a.updateArgs)).map(async (a) => {
|
|
6507
6509
|
try {
|
|
6508
6510
|
const i = await n(
|
|
6509
6511
|
() => O(() => e.updateTask(a.id, a.updateArgs))
|
|
@@ -6534,31 +6536,31 @@ async function ed({
|
|
|
6534
6536
|
deadlineDate: h,
|
|
6535
6537
|
...y
|
|
6536
6538
|
} = e;
|
|
6537
|
-
if (
|
|
6539
|
+
if (N(a) && o.error !== void 0)
|
|
6538
6540
|
throw o.error;
|
|
6539
|
-
const f =
|
|
6541
|
+
const f = N(a) ? o.projectId : a;
|
|
6540
6542
|
let v = {
|
|
6541
6543
|
...y,
|
|
6542
6544
|
...m !== void 0 && { labels: m }
|
|
6543
6545
|
};
|
|
6544
6546
|
p && (v.priority = Zt(p));
|
|
6545
|
-
const
|
|
6547
|
+
const j = Pt(
|
|
6546
6548
|
d,
|
|
6547
|
-
|
|
6549
|
+
zc,
|
|
6548
6550
|
qc
|
|
6549
6551
|
);
|
|
6550
|
-
|
|
6551
|
-
const A = Pt(h,
|
|
6552
|
+
j !== void 0 && (v = { ...v, dueString: j });
|
|
6553
|
+
const A = Pt(h, Kc, null);
|
|
6552
6554
|
if (A !== void 0 && (v = { ...v, deadlineDate: A }), l)
|
|
6553
6555
|
try {
|
|
6554
|
-
const { minutes:
|
|
6556
|
+
const { minutes: k } = Xt(l);
|
|
6555
6557
|
v = {
|
|
6556
6558
|
...v,
|
|
6557
|
-
duration:
|
|
6559
|
+
duration: k,
|
|
6558
6560
|
durationUnit: "minute"
|
|
6559
6561
|
};
|
|
6560
|
-
} catch (
|
|
6561
|
-
throw
|
|
6562
|
+
} catch (k) {
|
|
6563
|
+
throw k instanceof _ ? new Error(`Task ${n}: ${k.message}`) : k;
|
|
6562
6564
|
}
|
|
6563
6565
|
return u !== void 0 && (v = {
|
|
6564
6566
|
...v,
|
|
@@ -6736,7 +6738,7 @@ const hd = {
|
|
|
6736
6738
|
structuredContent: r.structuredContent
|
|
6737
6739
|
};
|
|
6738
6740
|
}
|
|
6739
|
-
},
|
|
6741
|
+
}, _t = 10 * 1024 * 1024, fd = /* @__PURE__ */ new Set([
|
|
6740
6742
|
"image/png",
|
|
6741
6743
|
"image/jpeg",
|
|
6742
6744
|
"image/gif",
|
|
@@ -6768,10 +6770,10 @@ const hd = {
|
|
|
6768
6770
|
function yd(e) {
|
|
6769
6771
|
return fd.has(e) ? "image" : bd.has(e) || e.startsWith("text/") ? "text" : "binary";
|
|
6770
6772
|
}
|
|
6771
|
-
function
|
|
6773
|
+
function Td(e) {
|
|
6772
6774
|
return (e.split(";")[0] ?? e).trim().toLowerCase();
|
|
6773
6775
|
}
|
|
6774
|
-
function
|
|
6776
|
+
function kd(e) {
|
|
6775
6777
|
try {
|
|
6776
6778
|
const t = new URL(e).pathname, r = t.lastIndexOf(".");
|
|
6777
6779
|
if (r === -1) return;
|
|
@@ -6803,13 +6805,13 @@ const vd = {
|
|
|
6803
6805
|
idempotentHint: !0
|
|
6804
6806
|
},
|
|
6805
6807
|
async execute({ fileUrl: e }, t) {
|
|
6806
|
-
const r = await t.viewAttachment(e), o = r.headers["content-length"], n = o ? Number.parseInt(o, 10) : void 0, a = wd(e), i = r.headers["content-type"], c = i ?
|
|
6807
|
-
if (n && n >
|
|
6808
|
+
const r = await t.viewAttachment(e), o = r.headers["content-length"], n = o ? Number.parseInt(o, 10) : void 0, a = wd(e), i = r.headers["content-type"], c = i ? Td(i) : void 0, d = c && c !== "application/octet-stream" ? c : kd(e) ?? c ?? "application/octet-stream";
|
|
6809
|
+
if (n && n > _t)
|
|
6808
6810
|
return {
|
|
6809
6811
|
textContent: `Attachment "${a ?? e}" is too large to display inline (${(n / 1024 / 1024).toFixed(1)}MB, limit is 10MB). File type: ${d}`
|
|
6810
6812
|
};
|
|
6811
6813
|
const l = Buffer.from(await r.arrayBuffer()), u = l.byteLength;
|
|
6812
|
-
if (u >
|
|
6814
|
+
if (u > _t)
|
|
6813
6815
|
return {
|
|
6814
6816
|
textContent: `Attachment "${a ?? e}" is too large to display inline (${(u / 1024 / 1024).toFixed(1)}MB, limit is 10MB). File type: ${d}`
|
|
6815
6817
|
};
|
|
@@ -6833,29 +6835,29 @@ const vd = {
|
|
|
6833
6835
|
contentItems: m
|
|
6834
6836
|
};
|
|
6835
6837
|
}
|
|
6836
|
-
},
|
|
6838
|
+
}, Sd = {
|
|
6837
6839
|
...Pa,
|
|
6838
6840
|
_meta: {
|
|
6839
6841
|
ui: {
|
|
6840
6842
|
resourceUri: Le
|
|
6841
6843
|
}
|
|
6842
6844
|
}
|
|
6843
|
-
},
|
|
6845
|
+
}, jd = {
|
|
6844
6846
|
// Task management tools
|
|
6845
6847
|
addTasks: pn,
|
|
6846
6848
|
completeTasks: wn,
|
|
6847
6849
|
uncompleteTasks: Zi,
|
|
6848
|
-
updateTasks:
|
|
6849
|
-
rescheduleTasks:
|
|
6850
|
+
updateTasks: Gc,
|
|
6851
|
+
rescheduleTasks: Ki,
|
|
6850
6852
|
findTasks: Fa,
|
|
6851
|
-
findTasksByDate:
|
|
6853
|
+
findTasksByDate: Sd,
|
|
6852
6854
|
findCompletedTasks: aa,
|
|
6853
6855
|
// Project management tools
|
|
6854
|
-
addProjects:
|
|
6856
|
+
addProjects: Yo,
|
|
6855
6857
|
updateProjects: Ic,
|
|
6856
|
-
findProjects:
|
|
6857
|
-
projectManagement:
|
|
6858
|
-
projectMove:
|
|
6858
|
+
findProjects: ka,
|
|
6859
|
+
projectManagement: Ri,
|
|
6860
|
+
projectMove: Ni,
|
|
6859
6861
|
// Section management tools
|
|
6860
6862
|
addSections: an,
|
|
6861
6863
|
updateSections: Uc,
|
|
@@ -6866,7 +6868,7 @@ const vd = {
|
|
|
6866
6868
|
updateComments: rc,
|
|
6867
6869
|
// Reminder management tools
|
|
6868
6870
|
addReminders: tn,
|
|
6869
|
-
findReminders:
|
|
6871
|
+
findReminders: Sa,
|
|
6870
6872
|
updateReminders: Oc,
|
|
6871
6873
|
// Attachment tools
|
|
6872
6874
|
viewAttachment: Id,
|
|
@@ -6879,7 +6881,7 @@ const vd = {
|
|
|
6879
6881
|
addFilters: Oo,
|
|
6880
6882
|
updateFilters: cc,
|
|
6881
6883
|
// Activity and audit tools
|
|
6882
|
-
findActivity:
|
|
6884
|
+
findActivity: zn,
|
|
6883
6885
|
getProductivityStats: Qa,
|
|
6884
6886
|
// Health and insights tools
|
|
6885
6887
|
getProjectHealth: ui,
|
|
@@ -6888,7 +6890,7 @@ const vd = {
|
|
|
6888
6890
|
getWorkspaceInsights: fi,
|
|
6889
6891
|
// General tools
|
|
6890
6892
|
getOverview: Ja,
|
|
6891
|
-
deleteObject:
|
|
6893
|
+
deleteObject: jn,
|
|
6892
6894
|
fetchObject: Ln,
|
|
6893
6895
|
reorderObjects: Hi,
|
|
6894
6896
|
userInfo: hd,
|
|
@@ -6897,13 +6899,13 @@ const vd = {
|
|
|
6897
6899
|
manageAssignments: Oi,
|
|
6898
6900
|
// Template tools
|
|
6899
6901
|
exportProjectTemplate: Dn,
|
|
6900
|
-
importProjectTemplate:
|
|
6902
|
+
importProjectTemplate: ki,
|
|
6901
6903
|
// Workspace tools
|
|
6902
6904
|
listWorkspaces: Ci,
|
|
6903
6905
|
// OpenAI MCP tools
|
|
6904
6906
|
search: Vi,
|
|
6905
6907
|
fetch: Fn
|
|
6906
|
-
}, Cd = Object.values(
|
|
6908
|
+
}, Cd = Object.values(jd), $d = `
|
|
6907
6909
|
## Todoist Task and Project Management Tools
|
|
6908
6910
|
|
|
6909
6911
|
You have access to comprehensive Todoist management tools for personal productivity and team collaboration. Use these tools to help users manage tasks, projects, sections, comments, and assignments effectively.
|
|
@@ -6915,95 +6917,43 @@ You have access to comprehensive Todoist management tools for personal productiv
|
|
|
6915
6917
|
- Bulk assignment operations for team workflows
|
|
6916
6918
|
- Get overviews and insights about workload and progress
|
|
6917
6919
|
|
|
6918
|
-
###
|
|
6919
|
-
|
|
6920
|
-
**Task Management:**
|
|
6921
|
-
- **add-tasks**: Create tasks (max 25 per call) with content, description, priority (\`p1\`, \`p2\`, \`p3\`, \`p4\` strings only; \`p1\` highest and \`p4\` lowest/default; integers are not accepted), dueString (natural language like "tomorrow", "next Friday", "2024-12-25"; also use natural language for recurrences and do not prefix them with \`recurring\`), deadlineDate (ISO 8601 format like "2025-12-31" for immovable constraints), duration (formats like "2h", "90m", "2h30m"), and assignments to project collaborators
|
|
6922
|
-
- **update-tasks**: Modify existing tasks - get task IDs from search results first, only include fields that need changes. Supports priority updates using \`p1\`/\`p2\`/\`p3\`/\`p4\` string values (\`p1\` highest, \`p4\` lowest/default; integers are not accepted), due date updates via dueString and due date removal via "dueString: remove", plus deadlineDate (ISO 8601 format like "2025-12-31") updates and removals via "deadlineDate: remove". **IMPORTANT: Do NOT use update-tasks to reschedule/move task dates — use reschedule-tasks instead.** update-tasks replaces the entire due string which destroys recurrence patterns on recurring tasks. Never echo back a task's existing projectId/sectionId/parentId — those fields are treated as a move.
|
|
6923
|
-
- **reschedule-tasks**: **Always use this tool when moving/rescheduling task due dates to a different date.** This tool preserves recurring schedules and existing time-of-day. Accepts YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS. Works for both recurring and non-recurring tasks. Do NOT use update-tasks for rescheduling.
|
|
6924
|
-
- **complete-tasks**: Mark tasks as done using task IDs
|
|
6925
|
-
- **uncomplete-tasks**: Reopen completed tasks using task IDs
|
|
6926
|
-
- **find-tasks**: Search by text, project/section/parent container, responsible user, labels, a raw Todoist \`filter\` string (e.g. "today", "p1", "##Work", "(today | overdue) & p1"), or a saved filter by ID or name (\`filterIdOrName\`). Requires at least one search parameter. \`filter\`/\`filterIdOrName\` cannot be combined with projectId/sectionId/parentId, and \`filter\` and \`filterIdOrName\` are mutually exclusive.
|
|
6927
|
-
- **find-tasks-by-date**: Get tasks by date range (startDate: YYYY-MM-DD or 'today' which includes overdue tasks) or specific day counts
|
|
6928
|
-
- **find-completed-tasks**: View completed tasks by completion date or original due date; if since/until are omitted, defaults to the last 7 days (returns all collaborators unless filtered). For a history of actual task-completion events, including recurring task occurrences, use find-activity instead.
|
|
6929
|
-
|
|
6930
|
-
**Project & Organization:**
|
|
6931
|
-
- **add-projects/update-projects/find-projects**: Manage project lifecycle with names, descriptions (Markdown), favorites, view styles (list/board/calendar), and workspace assignment for new projects (by name or ID). find-projects returns active projects by default; pass archivedStatus ('archived' or 'all') to include archived projects. Every returned project includes an isArchived field
|
|
6932
|
-
- **project-management**: Archive or unarchive projects by ID
|
|
6933
|
-
- To delete a project (active or archived), use **delete-object** with type "project". Note: workspace projects must be archived first; personal projects can be deleted regardless
|
|
6934
|
-
- **project-move**: Move projects between personal and workspace contexts
|
|
6935
|
-
- **add-sections/update-sections/find-sections**: Organize tasks within projects using sections
|
|
6936
|
-
- **get-overview**: Get comprehensive Markdown overview of entire account or specific project with task hierarchies. Project data includes parentId (sub-projects), folderId (workspace folder membership), and childOrder (sibling ordering)
|
|
6937
|
-
- **list-workspaces**: Get all workspaces for the user with details like plan type, role, and settings
|
|
6938
|
-
|
|
6939
|
-
**Reminders:**
|
|
6940
|
-
- **add-reminders**: Create reminders for tasks. Three types: "relative" (minutes before due), "absolute" (specific date/time), or "location" (geofence-triggered). Each reminder must specify a taskId.
|
|
6941
|
-
- **find-reminders**: Find reminders by task ID (returns both time-based and location reminders), or get a specific reminder by ID (use reminderId for time-based, locationReminderId for location-based).
|
|
6942
|
-
- **update-reminders**: Update existing reminders. Must specify the reminder type ("relative", "absolute", or "location") and ID.
|
|
6943
|
-
- Relative and absolute reminders support an **isUrgent** flag to mark a reminder as urgent.
|
|
6944
|
-
- Reminders can be deleted using **delete-object** with type "reminder" (time-based) or "location_reminder" (location-based).
|
|
6945
|
-
|
|
6946
|
-
**Collaboration & Comments:**
|
|
6947
|
-
- **add-comments/update-comments/find-comments**: Manage task and project discussions
|
|
6948
|
-
- **view-attachment**: View file attachments from comments. Pass the fileUrl from a comment's fileAttachment. Returns images inline, text files as text, and binary files as embedded resources.
|
|
6949
|
-
- **find-project-collaborators**: Look up Todoist users (collaborators, teammates) by name or email to get their user ID — use for "find/who is X" questions or any time you need to resolve a person's name to an ID. By default searches collaborators of every shared project the authenticated user can access (plus the authenticated user themselves). An empty result means the person is not a collaborator on any shared project, not that they do not exist. Pass projectId to scope to a single project
|
|
6950
|
-
- **manage-assignments**: Bulk assign/unassign/reassign up to 50 tasks with atomic operations and dry-run validation
|
|
6951
|
-
|
|
6952
|
-
**Filters:**
|
|
6953
|
-
- **find-filters**: List all personal filters or search by name; filters are saved task views using query syntax
|
|
6954
|
-
- **add-filters**: Create personal filters with name, query (e.g. "today & p1"), color, and favorite flag
|
|
6955
|
-
- **update-filters**: Modify existing filters' name, query, color, or favorite status
|
|
6956
|
-
|
|
6957
|
-
**Templates:**
|
|
6958
|
-
- **export-project-template**: Export a project as a Todoist template — CSV content (format "file") or a shareable link (format "url"). Prefer "url" for large projects. To read a project's contents rather than export it, use find-tasks.
|
|
6959
|
-
- **import-project-template**: Add a template's tasks, sections and comments to an existing project. Source it with templateId (a gallery slug like "product-launch", a personal template ID like "UT_28Ex...", or a full Todoist template URL) or with csvFileContent (CSV from export-project-template). Templates cannot be listed through this server, so only use the ID or URL the user gave you. Gallery templates work for any account; personal templates only for the account that saved them. For "start a new project from this template", call add-projects first and import into the new project. Imports write immediately and cannot be undone.
|
|
6920
|
+
### Choosing between tools
|
|
6960
6921
|
|
|
6961
|
-
|
|
6962
|
-
- **find-activity**: Retrieve activity logs to monitor and audit changes. Shows events from all users by default; use initiatorId to filter by specific user. Filter by object type (task/project/comment), event type (added/updated/deleted/completed/uncompleted/archived/unarchived/shared/left), objects (objectId, projectId, taskId), and an inclusive dateFrom/exclusive dateTo range. For “what did I complete?” or “what got done?” questions, including recurring task occurrences, use objectType="task", eventType="completed", and the requested date range. Activity history retention depends on the user plan.
|
|
6963
|
-
- **get-productivity-stats**: Get comprehensive productivity statistics including daily/weekly completion breakdowns, goal streaks (current, last, max), karma score and trends, and historical karma data. No parameters required.
|
|
6922
|
+
What each tool does and how to fill its parameters is in the tool's own description and input schema. This section covers only what those cannot: which tool to reach for, and how tools relate to each other.
|
|
6964
6923
|
|
|
6965
|
-
**
|
|
6966
|
-
- **get-project-health**: Get comprehensive health assessment for a project including completion progress (completed/active counts, percentage), health status (EXCELLENT/ON_TRACK/AT_RISK/CRITICAL), description, and task-level recommendations. Use includeContext=true for detailed metrics (overdue tasks, weekly activity, avg completion time) and full task data. Health data may be stale — check isStale flag.
|
|
6967
|
-
- **get-project-activity-stats**: Get daily and optional weekly activity statistics for a project over a configurable time window (1-12 weeks). Useful for identifying activity trends.
|
|
6968
|
-
- **analyze-project-health**: Trigger a new health analysis for a project. Use when health data is stale. The analysis may take time — use get-project-health afterward to see updated results.
|
|
6969
|
-
- **get-workspace-insights**: Get aggregated health and progress insights across all projects in a workspace. Accepts workspace name or ID, with optional project ID filtering.
|
|
6924
|
+
**Dates**
|
|
6970
6925
|
|
|
6971
|
-
**
|
|
6972
|
-
-
|
|
6973
|
-
-
|
|
6974
|
-
- **reorder-objects**: 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
|
|
6975
|
-
- **user-info**: Get user details including timezone, goals, and plan information
|
|
6926
|
+
- To move a task to a different date use **reschedule-tasks**, never **update-tasks**. update-tasks replaces the whole due string, which destroys recurrence on recurring tasks.
|
|
6927
|
+
- Never send a task's existing projectId, sectionId or parentId back to **update-tasks** — those fields are treated as a move.
|
|
6928
|
+
- All dates respect the user's timezone.
|
|
6976
6929
|
|
|
6977
|
-
|
|
6930
|
+
**Finding things**
|
|
6978
6931
|
|
|
6979
|
-
|
|
6932
|
+
- For "what did I complete?", use **find-activity** with objectType="task" and eventType="completed". It reports completion events, including each occurrence of a recurring task. **find-completed-tasks** lists completed tasks, which is not the same question.
|
|
6933
|
+
- To resolve a person's name or email to a user ID, or to answer "who is X?", use **find-project-collaborators** with just a searchTerm. It covers every shared project you can access plus yourself, so an empty result means they collaborate on none of them — not that they do not exist.
|
|
6934
|
+
- Before assigning work to someone, call **find-project-collaborators** again with the target projectId. Resolving an ID only proves they collaborate on *some* project you can see; assignment fails unless they collaborate on that one.
|
|
6935
|
+
- To find out whether a task hides subtasks, use **fetch-object** with includeChildren rather than a speculative **find-tasks** call.
|
|
6936
|
+
- Filter tasks by label **name**. Label IDs are only for **delete-object** and **update-labels**. Shared labels can be renamed but not recoloured, reordered or favourited.
|
|
6980
6937
|
|
|
6981
|
-
|
|
6938
|
+
**Deleting and archiving**
|
|
6982
6939
|
|
|
6983
|
-
|
|
6940
|
+
- **delete-object** removes every object type; there is no per-type delete tool. Reminders use type "reminder", location reminders "location_reminder".
|
|
6941
|
+
- A workspace project must be archived with **project-management** before it can be deleted. A personal project can be deleted directly.
|
|
6984
6942
|
|
|
6985
|
-
|
|
6943
|
+
**Templates**
|
|
6986
6944
|
|
|
6987
|
-
|
|
6945
|
+
- Templates cannot be listed through this server, so only use an ID or URL the user gave you. To start a new project from one, call **add-projects** first and import into it. Imports write immediately and cannot be undone.
|
|
6988
6946
|
|
|
6989
|
-
|
|
6947
|
+
**Project health**
|
|
6990
6948
|
|
|
6991
|
-
|
|
6949
|
+
- Health data may be stale — check the isStale flag, and call **analyze-project-health** to refresh it before reading again.
|
|
6992
6950
|
|
|
6993
|
-
|
|
6951
|
+
**Batches**
|
|
6994
6952
|
|
|
6995
|
-
|
|
6953
|
+
- Prefer a batch tool over one call per item.
|
|
6954
|
+
- Where a batch tool returns per-item \`failures\` alongside successes, one failure does not undo the rest: never retry the whole batch, re-send only the items whose failure reason is fixable. **reschedule-tasks** is the exception — it has no per-item failures and throws if any task fails, so retry it as a whole.
|
|
6996
6955
|
|
|
6997
|
-
|
|
6998
|
-
- **Team Assignment**: find-project-collaborators → add-tasks with responsibleUser → manage-assignments for bulk changes
|
|
6999
|
-
- **User Lookup**: find-project-collaborators with just a searchTerm (no projectId) to resolve a name or email to a Todoist user ID across all shared-project collaborators you can access
|
|
7000
|
-
- **Task Search**: find-tasks with multiple filters → update-tasks or complete-tasks based on results
|
|
7001
|
-
- **Project Organization**: add-projects → add-sections → add-tasks with projectId and sectionId
|
|
7002
|
-
- **Completion History**: find-activity with objectType="task", eventType="completed", dateFrom, and dateTo to report what was actually completed in a period, including recurring task occurrences; use initiatorId for one collaborator
|
|
7003
|
-
- **Progress Reviews**: find-completed-tasks (defaults to last 7 days; optionally use explicit date ranges) → get-overview for project summaries
|
|
7004
|
-
- **Activity Auditing**: find-activity with event/object filters to track changes, monitor team activity, or investigate specific actions
|
|
7005
|
-
- **Productivity Analysis**: Use the productivity-analysis prompt for comprehensive analysis combining user-info, get-productivity-stats, and find-completed-tasks data into actionable insights
|
|
7006
|
-
- **Project Health Reviews**: get-project-health → analyze-project-health if stale → get-project-health with includeContext=true for detailed metrics → get-workspace-insights for cross-project overview
|
|
6956
|
+
Use the **productivity-analysis** prompt for a combined productivity review — it pulls together user-info, get-productivity-stats and find-completed-tasks.
|
|
7007
6957
|
|
|
7008
6958
|
Always provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.
|
|
7009
6959
|
`;
|
|
@@ -7021,11 +6971,11 @@ function Hd({
|
|
|
7021
6971
|
},
|
|
7022
6972
|
instructions: $d
|
|
7023
6973
|
}
|
|
7024
|
-
), n =
|
|
7025
|
-
|
|
6974
|
+
), n = jr(e, { baseUrl: t });
|
|
6975
|
+
Gs(o);
|
|
7026
6976
|
const a = { server: o, client: n, features: r };
|
|
7027
6977
|
for (const i of Cd)
|
|
7028
|
-
|
|
6978
|
+
Kr({ tool: i, ...a });
|
|
7029
6979
|
return o.registerPrompt(
|
|
7030
6980
|
he.name,
|
|
7031
6981
|
{
|
|
@@ -7044,14 +6994,14 @@ export {
|
|
|
7044
6994
|
ui as D,
|
|
7045
6995
|
fi as E,
|
|
7046
6996
|
Fd as F,
|
|
7047
|
-
|
|
6997
|
+
ki as G,
|
|
7048
6998
|
Ci as H,
|
|
7049
6999
|
Oi as I,
|
|
7050
|
-
|
|
7051
|
-
|
|
7000
|
+
Ri as J,
|
|
7001
|
+
Ni as K,
|
|
7052
7002
|
Cd as L,
|
|
7053
7003
|
Hi as M,
|
|
7054
|
-
|
|
7004
|
+
Ki as N,
|
|
7055
7005
|
Vi as O,
|
|
7056
7006
|
Zi as P,
|
|
7057
7007
|
rc as Q,
|
|
@@ -7060,34 +7010,34 @@ export {
|
|
|
7060
7010
|
Ic as T,
|
|
7061
7011
|
Oc as U,
|
|
7062
7012
|
Uc as V,
|
|
7063
|
-
|
|
7013
|
+
Gc as W,
|
|
7064
7014
|
hd as X,
|
|
7065
7015
|
Id as Y,
|
|
7066
|
-
|
|
7016
|
+
jr as Z,
|
|
7067
7017
|
br as _,
|
|
7068
7018
|
Io as a,
|
|
7069
7019
|
Oo as b,
|
|
7070
7020
|
Uo as c,
|
|
7071
|
-
|
|
7021
|
+
Yo as d,
|
|
7072
7022
|
tn as e,
|
|
7073
7023
|
an as f,
|
|
7074
7024
|
Hd as g,
|
|
7075
7025
|
pn as h,
|
|
7076
7026
|
yn as i,
|
|
7077
7027
|
wn as j,
|
|
7078
|
-
|
|
7028
|
+
jn as k,
|
|
7079
7029
|
Dn as l,
|
|
7080
7030
|
Fn as m,
|
|
7081
7031
|
Ln as n,
|
|
7082
|
-
|
|
7032
|
+
zn as o,
|
|
7083
7033
|
Xn as p,
|
|
7084
7034
|
aa as q,
|
|
7085
7035
|
$o as r,
|
|
7086
7036
|
la as s,
|
|
7087
|
-
|
|
7037
|
+
jd as t,
|
|
7088
7038
|
ha as u,
|
|
7089
|
-
|
|
7090
|
-
|
|
7039
|
+
ka as v,
|
|
7040
|
+
Sa as w,
|
|
7091
7041
|
xa as x,
|
|
7092
7042
|
Fa as y,
|
|
7093
7043
|
Pa as z
|