@doist/todoist-ai 8.8.5 → 8.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { colors as $e, LOCATION_TRIGGERS as lt, REMINDER_TYPES as _t, createCommand as z, REMINDER_DELIVERY_SERVICES as Nt, HEALTH_STATUSES as Ue, getTaskUrl as ut, getProjectUrl as pt, WORKSPACE_ROLES as Lt, WORKSPACE_PLANS as Mt, TodoistApi as Ft } from "@doist/todoist-sdk";
1
+ import { isWorkspaceProject as ue, isPersonalProject as re, colors as De, LOCATION_TRIGGERS as lt, REMINDER_TYPES as Ut, createCommand as z, REMINDER_DELIVERY_SERVICES as Nt, HEALTH_STATUSES as Re, getTaskUrl as ut, getProjectUrl as pt, WORKSPACE_ROLES as Lt, WORKSPACE_PLANS as Mt, TodoistApi as Ft } from "@doist/todoist-sdk";
2
2
  import { McpServer as Ht } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { createHash as Wt } from "node:crypto";
4
4
  import { readFileSync as Bt } from "node:fs";
@@ -6,7 +6,7 @@ import { dirname as zt, join as Ve } from "node:path";
6
6
  import { fileURLToPath as Yt } from "node:url";
7
7
  import { registerAppResource as Gt, RESOURCE_MIME_TYPE as qt, registerAppTool as Kt } from "@modelcontextprotocol/ext-apps/server";
8
8
  import J, { ZodError as Vt, z as s } from "zod";
9
- import { addDays as De, formatISO as Je } from "date-fns";
9
+ import { addDays as xe, formatISO as Je } from "date-fns";
10
10
  const Xe = zt(Yt(import.meta.url)), Jt = [
11
11
  Ve(Xe, "task-list", "index.html"),
12
12
  Ve(Xe, "mcp-apps", "index.html")
@@ -26,7 +26,7 @@ function Zt() {
26
26
  }
27
27
  return console.error("Failed to load task list app HTML from any known path:", e), Xt;
28
28
  }
29
- const mt = Zt(), Qt = Wt("sha256").update(mt).digest("hex").slice(0, 12), xe = `ui://todoist/task-list@${Qt}`, ht = "Interactive task list widget", es = "https://ai.todoist.net", Ze = {
29
+ const mt = Zt(), Qt = Wt("sha256").update(mt).digest("hex").slice(0, 12), Ae = `ui://todoist/task-list@${Qt}`, ht = "Interactive task list widget", es = "https://ai.todoist.net", Ze = {
30
30
  ui: {
31
31
  prefersBorder: !0,
32
32
  csp: {
@@ -47,7 +47,7 @@ function ts(e) {
47
47
  Gt(
48
48
  e,
49
49
  "todoist-task-list",
50
- xe,
50
+ Ae,
51
51
  {
52
52
  description: ht,
53
53
  _meta: Ze
@@ -55,7 +55,7 @@ function ts(e) {
55
55
  async () => ({
56
56
  contents: [
57
57
  {
58
- uri: xe,
58
+ uri: Ae,
59
59
  mimeType: qt,
60
60
  text: mt,
61
61
  _meta: Ze
@@ -67,10 +67,10 @@ function ts(e) {
67
67
  function Y(e) {
68
68
  return typeof e == "object" && e !== null;
69
69
  }
70
- function Ae(...e) {
70
+ function Ee(...e) {
71
71
  return e.find(Y);
72
72
  }
73
- function _(...e) {
73
+ function U(...e) {
74
74
  return e.find((t) => t !== void 0);
75
75
  }
76
76
  function E(e) {
@@ -105,7 +105,7 @@ function Qe(e) {
105
105
  const t = e.trim();
106
106
  return /\bHTTP\s*\d{3}\b/i.test(t) || /\bstatus code \d{3}\b/i.test(t) || /^bad request$/i.test(t) || /^unauthorized$/i.test(t) || /^forbidden$/i.test(t) || /^not found$/i.test(t);
107
107
  }
108
- function Ie(e) {
108
+ function ve(e) {
109
109
  if (!e)
110
110
  return;
111
111
  const t = e.match(/\b(?:HTTP|status code)\s*[:#-]?\s*(\d{3})\b/i);
@@ -122,7 +122,7 @@ function W(e) {
122
122
  }
123
123
  if (!Y(e))
124
124
  return;
125
- const r = _(
125
+ const r = U(
126
126
  y(e.detail),
127
127
  y(e.details),
128
128
  y(e.message),
@@ -144,21 +144,21 @@ function rs(e) {
144
144
  return [];
145
145
  const t = /* @__PURE__ */ new Set(), r = (i) => {
146
146
  i && t.add(P(i, 120));
147
- }, o = _(
147
+ }, o = U(
148
148
  y(e.field),
149
149
  y(e.parameter),
150
150
  y(e.param),
151
151
  y(e.path)
152
152
  );
153
153
  r(o);
154
- const n = Ae(
154
+ const n = Ee(
155
155
  e.details,
156
156
  e.errorDetails,
157
157
  e.errorExtra,
158
158
  e.error_extra
159
159
  );
160
160
  if (n) {
161
- const i = _(
161
+ const i = U(
162
162
  y(n.field),
163
163
  y(n.parameter),
164
164
  y(n.param),
@@ -174,13 +174,13 @@ function rs(e) {
174
174
  r(y(i));
175
175
  continue;
176
176
  }
177
- const c = _(
177
+ const c = U(
178
178
  y(i.field),
179
179
  y(i.parameter),
180
180
  y(i.param),
181
181
  y(i.path),
182
182
  y(i.name)
183
- ), d = _(
183
+ ), d = U(
184
184
  y(i.message),
185
185
  y(i.error),
186
186
  y(i.detail),
@@ -220,13 +220,13 @@ function as(e, t) {
220
220
  return e === 401 || e === 403 ? "Verify your API token and access permissions, then retry." : e === 404 ? "Confirm the referenced IDs exist and are accessible, then retry." : e === 429 ? "Rate limit reached. Wait briefly and retry." : e !== void 0 && e >= 500 ? "Todoist API may be temporarily unavailable. Retry shortly." : t ? "Fix the field hints above and retry." : e === 400 || e === 422 ? "Check parameter values and formats, then retry." : "Check the request parameters and retry.";
221
221
  }
222
222
  function is(e) {
223
- const t = Y(e) ? e : void 0, r = e instanceof Error && Y(e.cause) ? e.cause : void 0, o = Ae(t?.response, r?.response), n = Ae(
223
+ const t = Y(e) ? e : void 0, r = e instanceof Error && Y(e.cause) ? e.cause : void 0, o = Ee(t?.response, r?.response), n = Ee(
224
224
  t?.responseData,
225
225
  o?.data,
226
226
  t?.data,
227
227
  r?.responseData,
228
228
  r?.data
229
- ), a = _(
229
+ ), a = U(
230
230
  E(t?.httpStatusCode),
231
231
  E(t?.statusCode),
232
232
  E(t?.status),
@@ -236,17 +236,17 @@ function is(e) {
236
236
  E(n?.status),
237
237
  E(n?.httpCode),
238
238
  E(n?.http_code),
239
- Ie(y(t?.message)),
240
- Ie(y(r?.message)),
241
- Ie(typeof e == "string" ? e : void 0)
242
- ), i = _(
239
+ ve(y(t?.message)),
240
+ ve(y(r?.message)),
241
+ ve(typeof e == "string" ? e : void 0)
242
+ ), i = U(
243
243
  X(n?.errorCode),
244
244
  X(n?.error_code),
245
245
  X(n?.code),
246
246
  X(t?.errorCode),
247
247
  X(t?.error_code),
248
248
  X(t?.code)
249
- ), c = _(
249
+ ), c = U(
250
250
  y(n?.errorTag),
251
251
  y(n?.error_tag),
252
252
  y(n?.tag),
@@ -260,7 +260,7 @@ function is(e) {
260
260
  y(t?.message),
261
261
  y(r?.message),
262
262
  e instanceof Error ? e.message : y(e)
263
- ].filter((h) => !!h), l = d.find((h) => !Qe(h)) || d[0], u = _(
263
+ ].filter((h) => !!h), l = d.find((h) => !Qe(h)) || d[0], u = U(
264
264
  W(n?.errorExtra),
265
265
  W(n?.error_extra),
266
266
  W(n?.details),
@@ -343,16 +343,16 @@ async function ks(e, t = {}) {
343
343
  }
344
344
  throw a;
345
345
  }
346
- function Ee(e) {
346
+ function Oe(e) {
347
347
  if (e == null)
348
348
  return e;
349
349
  if (Array.isArray(e))
350
- return e.map((t) => Ee(t));
350
+ return e.map((t) => Oe(t));
351
351
  if (typeof e == "object") {
352
352
  const t = {};
353
353
  for (const [r, o] of Object.entries(e))
354
354
  if (o !== null) {
355
- const n = Ee(o);
355
+ const n = Oe(o);
356
356
  if (n !== null && typeof n == "object" && !Array.isArray(n) && Object.keys(n).length === 0)
357
357
  continue;
358
358
  t[r] = n;
@@ -420,7 +420,7 @@ const f = {
420
420
  // OpenAI MCP tools
421
421
  SEARCH: "search",
422
422
  FETCH: "fetch"
423
- }, Ri = {
423
+ }, _i = {
424
424
  /**
425
425
  * Strips email addresses from tool outputs that expose user data.
426
426
  * Affects: find-project-collaborators, find-completed-tasks
@@ -432,7 +432,7 @@ function ws({
432
432
  structuredContent: t,
433
433
  contentItems: r
434
434
  }) {
435
- const o = Ee(t), n = {}, a = [];
435
+ const o = Oe(t), n = {}, a = [];
436
436
  if (e && a.push({ type: "text", text: e }), r && a.push(...r), a.length > 0 && (n.content = a), t && (n.structuredContent = o), !Ts && t) {
437
437
  const i = JSON.stringify(o);
438
438
  n.content || (n.content = []), n.content.push({
@@ -464,15 +464,15 @@ const Cs = [
464
464
  f.FIND_PROJECT_COLLABORATORS,
465
465
  f.FIND_COMPLETED_TASKS
466
466
  ];
467
- function Oe(e) {
467
+ function Pe(e) {
468
468
  if (e == null)
469
469
  return e;
470
470
  if (Array.isArray(e))
471
- return e.map((t) => Oe(t));
471
+ return e.map((t) => Pe(t));
472
472
  if (typeof e == "object") {
473
473
  const t = {};
474
474
  for (const [r, o] of Object.entries(e))
475
- r !== "email" && (t[r] = Oe(o));
475
+ r !== "email" && (t[r] = Pe(o));
476
476
  return t;
477
477
  }
478
478
  return e;
@@ -492,7 +492,7 @@ function k({
492
492
  let { textContent: l, structuredContent: u, contentItems: p } = await ks(
493
493
  () => e.execute(c, r)
494
494
  );
495
- return n && (l && (l = $s(l)), u && (u = Oe(u))), ws({ textContent: l, structuredContent: u, contentItems: p });
495
+ return n && (l && (l = $s(l)), u && (u = Pe(u))), ws({ textContent: l, structuredContent: u, contentItems: p });
496
496
  } catch (l) {
497
497
  return console.error(`Error executing tool ${e.name}:`, { args: c, error: l }), Is(ls(l));
498
498
  }
@@ -684,7 +684,7 @@ const ie = {
684
684
  LABELS_DEFAULT: 50,
685
685
  /** Maximum limit for label listings */
686
686
  LABELS_MAX: 200
687
- }, ve = {
687
+ }, je = {
688
688
  /** Maximum number of failures to show in detailed error messages */
689
689
  MAX_FAILURES_SHOWN: 3
690
690
  };
@@ -732,14 +732,14 @@ function Ps(e) {
732
732
  const t = Math.floor(e / 60), r = e % 60;
733
733
  return t === 0 ? `${r}m` : r === 0 ? `${t}h` : `${t}h${r}m`;
734
734
  }
735
- const Rs = ["p1", "p2", "p3", "p4"], _e = 'Task priority as a string: "p1" (highest), "p2" (high), "p3" (medium), or "p4" (lowest/default). Integers like 1, 2, 3, or 4 are not accepted.', Ne = s.enum(Rs).describe(_e);
735
+ const _s = ["p1", "p2", "p3", "p4"], Ue = 'Task priority as a string: "p1" (highest), "p2" (high), "p3" (medium), or "p4" (lowest/default). Integers like 1, 2, 3, or 4 are not accepted.', Ne = s.enum(_s).describe(Ue);
736
736
  function bt(e) {
737
737
  return { p1: 4, p2: 3, p3: 2, p4: 1 }[e];
738
738
  }
739
- function Us(e) {
739
+ function Rs(e) {
740
740
  return { 4: "p1", 3: "p2", 2: "p3", 1: "p4" }[e];
741
741
  }
742
- const A = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new Map(), je = 300 * 1e3, _s = "me";
742
+ const A = /* @__PURE__ */ new Map(), Z = /* @__PURE__ */ new Map(), Se = 300 * 1e3, Us = "me";
743
743
  class Ns {
744
744
  /**
745
745
  * Resolve a user name or ID to a user ID by looking up collaborators across all shared projects.
@@ -749,9 +749,9 @@ class Ns {
749
749
  if (!r || r.trim().length === 0)
750
750
  return null;
751
751
  const o = r.trim(), n = A.get(o);
752
- if (n && Date.now() - n.timestamp < je)
752
+ if (n && Date.now() - n.timestamp < Se)
753
753
  return n.result;
754
- if (o.toLowerCase() === _s)
754
+ if (o.toLowerCase() === Us)
755
755
  try {
756
756
  const a = await t.getUser();
757
757
  return {
@@ -825,7 +825,7 @@ class Ns {
825
825
  */
826
826
  async getProjectCollaborators(t, r) {
827
827
  const o = `project_${r}`, n = Z.get(o);
828
- if (n && Date.now() - n.timestamp < je)
828
+ if (n && Date.now() - n.timestamp < Se)
829
829
  return n.result;
830
830
  try {
831
831
  const a = await t.getProjectCollaborators(r), c = (Array.isArray(a) ? a : a.results || []).filter((d) => d?.id && d.name && d.email);
@@ -842,7 +842,7 @@ class Ns {
842
842
  */
843
843
  async getAllCollaborators(t) {
844
844
  const r = "all_collaborators", o = Z.get(r);
845
- if (o && Date.now() - o.timestamp < je)
845
+ if (o && Date.now() - o.timestamp < Se)
846
846
  return o.result;
847
847
  try {
848
848
  const { results: n } = await t.getProjects({}), a = n.filter((u) => u.isShared);
@@ -905,12 +905,6 @@ function Ms({
905
905
  }) {
906
906
  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;
907
907
  }
908
- function re(e) {
909
- return "inboxProject" in e;
910
- }
911
- function Pe(e) {
912
- return "workspaceId" in e;
913
- }
914
908
  function de(e) {
915
909
  return e?.toLowerCase() === "inbox";
916
910
  }
@@ -983,7 +977,7 @@ function Bs(e, t, r, o) {
983
977
  if (o) return { parentId: o };
984
978
  throw new Error("Unexpected error: No valid move parameter found");
985
979
  }
986
- function R(e) {
980
+ function _(e) {
987
981
  return {
988
982
  id: e.id,
989
983
  content: e.content,
@@ -991,7 +985,7 @@ function R(e) {
991
985
  dueDate: e.due?.date,
992
986
  recurring: e.due?.isRecurring && e.due.string ? e.due.string : !1,
993
987
  deadlineDate: e.deadline?.date,
994
- priority: Us(e.priority) ?? "p4",
988
+ priority: Rs(e.priority) ?? "p4",
995
989
  projectId: e.projectId,
996
990
  sectionId: e.sectionId ?? void 0,
997
991
  parentId: e.parentId ?? void 0,
@@ -1013,12 +1007,12 @@ function q(e) {
1013
1007
  parentId: re(e) ? e.parentId ?? void 0 : void 0,
1014
1008
  inboxProject: re(e) ? e.inboxProject ?? !1 : !1,
1015
1009
  viewStyle: e.viewStyle,
1016
- workspaceId: Pe(e) ? e.workspaceId : void 0,
1017
- folderId: Pe(e) ? e.folderId ?? void 0 : void 0,
1010
+ workspaceId: ue(e) ? e.workspaceId : void 0,
1011
+ folderId: ue(e) ? e.folderId ?? void 0 : void 0,
1018
1012
  childOrder: e.childOrder
1019
1013
  };
1020
1014
  }
1021
- function pe(e) {
1015
+ function me(e) {
1022
1016
  return {
1023
1017
  id: e.id,
1024
1018
  taskId: e.taskId ?? void 0,
@@ -1071,7 +1065,7 @@ async function Fe({
1071
1065
  }) {
1072
1066
  try {
1073
1067
  const { results: n, nextCursor: a } = await e.getTasksByFilter({ query: t, cursor: o, limit: r });
1074
- return { tasks: n.map(R), nextCursor: a };
1068
+ return { tasks: n.map(_), nextCursor: a };
1075
1069
  } catch (n) {
1076
1070
  const a = Ys.safeParse(n);
1077
1071
  if (!a.success)
@@ -1128,15 +1122,15 @@ function Tt(e) {
1128
1122
  ).length, r = e.filter((o) => o.type === "location").length;
1129
1123
  return { timeBasedCount: t, locationCount: r };
1130
1124
  }
1131
- const me = $e.map((e) => e.key);
1125
+ const he = De.map((e) => e.key);
1132
1126
  function Gs(e) {
1133
1127
  if (typeof e != "string") return;
1134
1128
  const t = e.toLowerCase();
1135
- return ($e.find((o) => o.key === t) ?? $e.find((o) => o.displayName.toLowerCase() === t))?.key;
1129
+ return (De.find((o) => o.key === t) ?? De.find((o) => o.displayName.toLowerCase() === t))?.key;
1136
1130
  }
1137
- const qs = `Color for the entity. Accepts a color key (e.g. "berry_red") or display name (e.g. "Berry Red"). Valid colors: ${me.join(", ")}. Unrecognized colors are omitted and charcoal will be used as the default.`, le = s.preprocess(Gs, s.enum(me).optional()).describe(qs);
1138
- s.enum(me).describe("The color key of the entity.");
1139
- const ne = s.enum(me).optional().catch(void 0).describe("The color key of the entity."), K = s.object({
1131
+ const qs = `Color for the entity. Accepts a color key (e.g. "berry_red") or display name (e.g. "Berry Red"). Valid colors: ${he.join(", ")}. Unrecognized colors are omitted and charcoal will be used as the default.`, le = s.preprocess(Gs, s.enum(he).optional()).describe(qs);
1132
+ s.enum(he).describe("The color key of the entity.");
1133
+ const ne = s.enum(he).optional().catch(void 0).describe("The color key of the entity."), K = s.object({
1140
1134
  id: s.string().describe("The unique ID of the task."),
1141
1135
  content: s.string().describe("The task title/content."),
1142
1136
  description: s.string().describe("The task description."),
@@ -1170,7 +1164,7 @@ const ne = s.enum(me).optional().catch(void 0).describe("The color key of the en
1170
1164
  ),
1171
1165
  folderId: s.string().optional().describe("The ID of the folder this project belongs to (workspace projects only)."),
1172
1166
  childOrder: s.number().describe("The ordering index of the project among its siblings.")
1173
- }), he = s.object({
1167
+ }), fe = s.object({
1174
1168
  id: s.string().describe("The unique ID of the section."),
1175
1169
  name: s.string().describe("The name of the section.")
1176
1170
  }), Ks = s.object({
@@ -1186,7 +1180,7 @@ const ne = s.enum(me).optional().catch(void 0).describe("The color key of the en
1186
1180
  image: s.string().optional().describe("The image URL for image resource types."),
1187
1181
  imageWidth: s.number().optional().describe("The width of the image in pixels."),
1188
1182
  imageHeight: s.number().optional().describe("The height of the image in pixels.")
1189
- }), fe = s.object({
1183
+ }), be = s.object({
1190
1184
  id: s.string().describe("The unique ID of the comment."),
1191
1185
  taskId: s.string().optional().describe("The ID of the task this comment belongs to."),
1192
1186
  projectId: s.string().optional().describe("The ID of the project this comment belongs to."),
@@ -1208,7 +1202,7 @@ const ne = s.enum(me).optional().catch(void 0).describe("The color key of the en
1208
1202
  id: s.string().describe("The unique ID of the user."),
1209
1203
  name: s.string().describe("The full name of the user."),
1210
1204
  email: s.string().describe("The email address of the user.")
1211
- }), be = s.object({
1205
+ }), ge = s.object({
1212
1206
  id: s.string().describe("The unique ID of the label."),
1213
1207
  name: s.string().describe("The name of the label."),
1214
1208
  color: ne,
@@ -1223,7 +1217,7 @@ const ne = s.enum(me).optional().catch(void 0).describe("The color key of the en
1223
1217
  }), He = s.object({
1224
1218
  id: s.string().describe("The unique ID of the reminder."),
1225
1219
  taskId: s.string().describe("The task ID this reminder belongs to."),
1226
- type: s.enum(_t).describe("The type of reminder: relative, absolute, or location."),
1220
+ type: s.enum(Ut).describe("The type of reminder: relative, absolute, or location."),
1227
1221
  minuteOffset: s.number().optional().describe("Minutes before due time to trigger (relative reminders only)."),
1228
1222
  due: Xs.optional().describe(
1229
1223
  "Due date info (absolute and sometimes relative reminders)."
@@ -1247,7 +1241,7 @@ const ne = s.enum(me).optional().catch(void 0).describe("The color key of the en
1247
1241
  }), Qs = {
1248
1242
  comments: s.array(Zs).min(1).describe("The array of comments to add.")
1249
1243
  }, er = {
1250
- comments: s.array(fe).describe("The created comments."),
1244
+ comments: s.array(be).describe("The created comments."),
1251
1245
  totalCount: s.number().describe("The total number of comments created."),
1252
1246
  addedCommentIds: s.array(s.string()).describe("The IDs of the added comments.")
1253
1247
  }, tr = {
@@ -1278,7 +1272,7 @@ const ne = s.enum(me).optional().catch(void 0).describe("The color key of the en
1278
1272
  content: l,
1279
1273
  ...u ? { taskId: u } : { projectId: m }
1280
1274
  });
1281
- }), c = (await Promise.all(a)).map(pe);
1275
+ }), c = (await Promise.all(a)).map(me);
1282
1276
  return {
1283
1277
  textContent: sr({ comments: c }),
1284
1278
  structuredContent: {
@@ -1425,7 +1419,7 @@ ${l}`,
1425
1419
  }), pr = {
1426
1420
  labels: s.array(ur).min(1).describe("The array of labels to add.")
1427
1421
  }, mr = {
1428
- labels: s.array(be).describe("The created labels."),
1422
+ labels: s.array(ge).describe("The created labels."),
1429
1423
  totalCount: s.number().describe("The total number of labels created.")
1430
1424
  }, hr = {
1431
1425
  name: f.ADD_LABELS,
@@ -1438,7 +1432,7 @@ ${l}`,
1438
1432
  return {
1439
1433
  textContent: fr({ labels: r }),
1440
1434
  structuredContent: {
1441
- labels: r.map((n) => be.parse(n)),
1435
+ labels: r.map((n) => ge.parse(n)),
1442
1436
  totalCount: r.length
1443
1437
  }
1444
1438
  };
@@ -1559,29 +1553,29 @@ function vr({ projects: e }) {
1559
1553
  return `Added ${t} project${t === 1 ? "" : "s"}:
1560
1554
  ${r}`;
1561
1555
  }
1562
- const ue = 25, ge = s.enum(Nt), It = s.object({
1556
+ const pe = 25, ye = s.enum(Nt), It = s.object({
1563
1557
  date: s.string().optional().describe("Due date in YYYY-MM-DD format."),
1564
1558
  string: s.string().optional().describe('Natural language due string, e.g. "tomorrow at 3pm".'),
1565
1559
  timezone: s.string().optional().describe('Timezone for the reminder, e.g. "America/New_York".'),
1566
1560
  lang: s.string().optional().describe('Language for parsing the due string, e.g. "en".')
1567
- }), vt = s.enum(lt), ye = s.boolean().optional().describe("Whether this is an urgent reminder. Applies to relative and absolute reminders."), jr = s.object({
1561
+ }), vt = s.enum(lt), ke = s.boolean().optional().describe("Whether this is an urgent reminder. Applies to relative and absolute reminders."), jr = s.object({
1568
1562
  type: s.literal("relative"),
1569
1563
  taskId: s.string().min(1).describe("The ID of the task to set a reminder for."),
1570
1564
  minuteOffset: s.number().int().min(0).describe(
1571
1565
  "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."
1572
1566
  ),
1573
- service: ge.optional().describe(
1567
+ service: ye.optional().describe(
1574
1568
  'Delivery method: "email" or "push" notification. Defaults to push.'
1575
1569
  ),
1576
- isUrgent: ye
1570
+ isUrgent: ke
1577
1571
  }), Sr = s.object({
1578
1572
  type: s.literal("absolute"),
1579
1573
  taskId: s.string().min(1).describe("The ID of the task to set a reminder for."),
1580
1574
  due: It.describe("The specific date/time for the reminder."),
1581
- service: ge.optional().describe(
1575
+ service: ye.optional().describe(
1582
1576
  'Delivery method: "email" or "push" notification. Defaults to push.'
1583
1577
  ),
1584
- isUrgent: ye
1578
+ isUrgent: ke
1585
1579
  }), Cr = s.object({
1586
1580
  type: s.literal("location"),
1587
1581
  taskId: s.string().min(1).describe("The ID of the task to set a reminder for."),
@@ -1597,8 +1591,8 @@ const ue = 25, ge = s.enum(Nt), It = s.object({
1597
1591
  Sr,
1598
1592
  Cr
1599
1593
  ]), Dr = {
1600
- reminders: s.array($r).min(1).max(ue).describe(
1601
- `Array of reminders to create (max ${ue}). Each reminder must specify a type: "relative" (minutes before due), "absolute" (specific date/time), or "location" (geofence trigger).`
1594
+ reminders: s.array($r).min(1).max(pe).describe(
1595
+ `Array of reminders to create (max ${pe}). Each reminder must specify a type: "relative" (minutes before due), "absolute" (specific date/time), or "location" (geofence trigger).`
1602
1596
  )
1603
1597
  }, xr = {
1604
1598
  reminders: s.array(He).describe("The created reminders."),
@@ -1669,14 +1663,14 @@ const Or = s.object({
1669
1663
  )
1670
1664
  }), Pr = {
1671
1665
  sections: s.array(Or).min(1).describe("The array of sections to add.")
1672
- }, Rr = {
1673
- sections: s.array(he).describe("The created sections."),
1666
+ }, _r = {
1667
+ sections: s.array(fe).describe("The created sections."),
1674
1668
  totalCount: s.number().describe("The total number of sections created.")
1675
- }, Ur = {
1669
+ }, Rr = {
1676
1670
  name: f.ADD_SECTIONS,
1677
1671
  description: "Add one or more new sections to projects.",
1678
1672
  parameters: Pr,
1679
- outputSchema: Rr,
1673
+ outputSchema: _r,
1680
1674
  annotations: { readOnlyHint: !1, destructiveHint: !1, idempotentHint: !1 },
1681
1675
  async execute({ sections: e }, t) {
1682
1676
  const o = e.some((c) => de(c.projectId)) ? await t.getUser() : void 0, n = await Promise.all(
@@ -1692,7 +1686,7 @@ const Or = s.object({
1692
1686
  n.map((c) => t.addSection(c))
1693
1687
  );
1694
1688
  return {
1695
- textContent: _r({ sections: a }),
1689
+ textContent: Ur({ sections: a }),
1696
1690
  structuredContent: {
1697
1691
  sections: a,
1698
1692
  totalCount: a.length
@@ -1700,7 +1694,7 @@ const Or = s.object({
1700
1694
  };
1701
1695
  }
1702
1696
  };
1703
- function _r({ sections: e }) {
1697
+ function Ur({ sections: e }) {
1704
1698
  const t = e.length, r = e.map((n) => `• ${n.name} (id=${n.id}, projectId=${n.projectId})`).join(`
1705
1699
  `);
1706
1700
  return `Added ${t} section${t === 1 ? "" : "s"}:
@@ -1934,7 +1928,7 @@ function Ye(e, t, r = {}) {
1934
1928
  i.push(d);
1935
1929
  const l = 5;
1936
1930
  if (n || a <= l) {
1937
- const u = ke(t, l);
1931
+ const u = Te(t, l);
1938
1932
  if (u.length > 0) {
1939
1933
  const p = a > l ? `, +${a - l} more` : "";
1940
1934
  i.push(`Tasks:
@@ -1950,10 +1944,10 @@ function Ge(e) {
1950
1944
  ${n.map((l) => ` ${l}`).join(`
1951
1945
  `)}.`), i?.length) {
1952
1946
  const l = i.length, u = `Failed (${l}):
1953
- ${i.slice(0, ve.MAX_FAILURES_SHOWN).map((p) => ` ${p.item} (Error: ${p.error}${p.code ? ` [${p.code}]` : ""})`).join(
1947
+ ${i.slice(0, je.MAX_FAILURES_SHOWN).map((p) => ` ${p.item} (Error: ${p.error}${p.code ? ` [${p.code}]` : ""})`).join(
1954
1948
  `
1955
1949
  `
1956
- )}${l > ve.MAX_FAILURES_SHOWN ? `, +${l - ve.MAX_FAILURES_SHOWN} more` : ""}.`;
1950
+ )}${l > je.MAX_FAILURES_SHOWN ? `, +${l - je.MAX_FAILURES_SHOWN} more` : ""}.`;
1957
1951
  c.push(u);
1958
1952
  }
1959
1953
  return c.join(`
@@ -1971,7 +1965,7 @@ function Fr(e) {
1971
1965
  const t = e.inboxProject ? " • Inbox" : "", r = e.isFavorite ? " • ⭐" : "", o = e.isShared ? " • Shared" : "", n = e.viewStyle && e.viewStyle !== "list" ? ` • ${e.viewStyle}` : "", a = ` • id=${e.id}`;
1972
1966
  return ` ${e.name}${t}${r}${o}${n}${a}`;
1973
1967
  }
1974
- function ke(e, t = 5) {
1968
+ function Te(e, t = 5) {
1975
1969
  const o = e.slice(0, t).map(Lr).join(`
1976
1970
  `);
1977
1971
  if (e.length > t) {
@@ -2009,7 +2003,7 @@ const tt = 25, Hr = s.object({
2009
2003
  description: s.string().optional().describe(
2010
2004
  "Additional details, notes, or context for the task. Use this for longer content rather than putting it in the task name. Supports Markdown."
2011
2005
  ),
2012
- priority: Ne.optional().describe(_e),
2006
+ priority: Ne.optional().describe(Ue),
2013
2007
  dueString: s.string().optional().describe("The due date for the task, in natural language."),
2014
2008
  deadlineDate: s.string().optional().describe(
2015
2009
  'The deadline date for the task in ISO 8601 format (YYYY-MM-DD, e.g., "2025-12-31"). Deadlines are immovable constraints shown with a different indicator than due dates.'
@@ -2076,7 +2070,7 @@ const tt = 25, Hr = s.object({
2076
2070
  const l = i.map((u) => `"${u.item}": ${u.error}`).join("; ");
2077
2071
  throw new Error(`All ${i.length} task(s) failed to create: ${l}`);
2078
2072
  }
2079
- const c = a.map(R);
2073
+ const c = a.map(_);
2080
2074
  return {
2081
2075
  textContent: qr({
2082
2076
  tasks: c,
@@ -2204,7 +2198,7 @@ const Kr = {
2204
2198
  }, Vr = {
2205
2199
  projectId: s.string().describe("The project ID."),
2206
2200
  health: s.object({
2207
- status: s.enum(Ue).describe("The health status after triggering analysis."),
2201
+ status: s.enum(Re).describe("The health status after triggering analysis."),
2208
2202
  isStale: s.boolean().describe("Whether the health data is still stale after the request."),
2209
2203
  updateInProgress: s.boolean().describe("Whether an analysis update is currently in progress.")
2210
2204
  }).describe("The health response returned after triggering analysis."),
@@ -2317,9 +2311,15 @@ const St = [
2317
2311
  annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !0 },
2318
2312
  async execute(e, t) {
2319
2313
  switch (e.type) {
2320
- case "project":
2314
+ case "project": {
2315
+ const r = await t.getProject(e.id);
2316
+ if (ue(r) && !r.isArchived)
2317
+ throw new Error(
2318
+ `Workspace project "${r.name}" must be archived before it can be deleted. Archive the project first, then delete it.`
2319
+ );
2321
2320
  await t.deleteProject(e.id);
2322
2321
  break;
2322
+ }
2323
2323
  case "section":
2324
2324
  await t.deleteSection(e.id);
2325
2325
  break;
@@ -2352,97 +2352,25 @@ const St = [
2352
2352
  }
2353
2353
  };
2354
2354
  }
2355
- }, oo = {
2356
- id: s.string().min(1).describe(
2357
- 'A unique identifier for the document in the format "task:{id}" or "project:{id}".'
2358
- )
2359
- }, no = {
2360
- id: s.string().describe("The ID of the fetched document."),
2361
- title: s.string().describe("The title of the document."),
2362
- text: s.string().describe("The text content of the document."),
2363
- url: s.string().describe("The URL of the document."),
2364
- metadata: s.record(s.string(), s.unknown()).optional().describe("Additional metadata about the document.")
2365
- }, ao = {
2366
- name: f.FETCH,
2367
- 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}".',
2368
- parameters: oo,
2369
- outputSchema: no,
2370
- annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
2371
- async execute(e, t) {
2372
- const { id: r } = e, [o, n] = r.split(":", 2);
2373
- if (!n || o !== "task" && o !== "project")
2374
- throw new Error(
2375
- 'Invalid ID format. Expected "task:{id}" or "project:{id}". Example: "task:8485093748" or "project:6cfCcrrCFg2xP94Q"'
2376
- );
2377
- let a;
2378
- if (o === "task") {
2379
- const i = await t.getTask(n), c = R(i), d = [c.content];
2380
- c.description && d.push(`
2381
-
2382
- Description: ${c.description}`), c.dueDate && d.push(`
2383
- Due: ${c.dueDate}`), c.labels.length > 0 && d.push(`
2384
- Labels: ${c.labels.join(", ")}`), a = {
2385
- id: `task:${c.id}`,
2386
- title: c.content,
2387
- text: d.join(""),
2388
- url: ut(c.id),
2389
- metadata: {
2390
- priority: c.priority,
2391
- projectId: c.projectId,
2392
- sectionId: c.sectionId,
2393
- parentId: c.parentId,
2394
- recurring: c.recurring,
2395
- duration: c.duration,
2396
- responsibleUid: c.responsibleUid,
2397
- assignedByUid: c.assignedByUid,
2398
- checked: c.checked,
2399
- completedAt: c.completedAt
2400
- }
2401
- };
2402
- } else {
2403
- const i = await t.getProject(n), c = q(i), d = [c.name];
2404
- c.isShared && d.push(`
2405
-
2406
- Shared project`), c.isFavorite && d.push(`
2407
- Favorite: Yes`), a = {
2408
- id: `project:${c.id}`,
2409
- title: c.name,
2410
- text: d.join(""),
2411
- url: pt(c.id),
2412
- metadata: {
2413
- color: c.color,
2414
- isFavorite: c.isFavorite,
2415
- isShared: c.isShared,
2416
- parentId: c.parentId,
2417
- inboxProject: c.inboxProject,
2418
- viewStyle: c.viewStyle
2419
- }
2420
- };
2421
- }
2422
- return {
2423
- textContent: JSON.stringify(a),
2424
- structuredContent: a
2425
- };
2426
- }
2427
- }, Ct = ["task", "project", "comment", "section"], io = {
2355
+ }, Ct = ["task", "project", "comment", "section"], oo = {
2428
2356
  type: s.enum(Ct).describe("The type of object to fetch."),
2429
2357
  id: s.string().min(1).describe("The unique ID of the object to fetch.")
2430
- }, co = {
2358
+ }, no = {
2431
2359
  type: s.enum(Ct).describe("The type of object fetched."),
2432
2360
  id: s.string().describe("The ID of the fetched object."),
2433
- object: s.union([K, ae, fe, he]).describe("The fetched object data.")
2434
- }, lo = {
2361
+ object: s.union([K, ae, be, fe]).describe("The fetched object data.")
2362
+ }, ao = {
2435
2363
  name: f.FETCH_OBJECT,
2436
2364
  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.",
2437
- parameters: io,
2438
- outputSchema: co,
2365
+ parameters: oo,
2366
+ outputSchema: no,
2439
2367
  annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
2440
2368
  async execute(e, t) {
2441
2369
  const { type: r, id: o } = e;
2442
2370
  try {
2443
2371
  switch (r) {
2444
2372
  case "task": {
2445
- const n = await t.getTask(o), a = R(n);
2373
+ const n = await t.getTask(o), a = _(n);
2446
2374
  return {
2447
2375
  textContent: `Found task: ${a.content} • id=${a.id} • priority=${a.priority} • project=${a.projectId}`,
2448
2376
  structuredContent: {
@@ -2464,7 +2392,7 @@ Favorite: Yes`), a = {
2464
2392
  };
2465
2393
  }
2466
2394
  case "comment": {
2467
- const n = await t.getComment(o), a = pe(n), i = a.content.length > 50 ? `${a.content.substring(0, 50)}...` : a.content;
2395
+ const n = await t.getComment(o), a = me(n), i = a.content.length > 50 ? `${a.content.substring(0, 50)}...` : a.content;
2468
2396
  return {
2469
2397
  textContent: `Found comment • id=${a.id} • content="${i}" • posted=${a.postedAt}`,
2470
2398
  structuredContent: {
@@ -2498,6 +2426,78 @@ Favorite: Yes`), a = {
2498
2426
  );
2499
2427
  }
2500
2428
  }
2429
+ }, io = {
2430
+ id: s.string().min(1).describe(
2431
+ 'A unique identifier for the document in the format "task:{id}" or "project:{id}".'
2432
+ )
2433
+ }, co = {
2434
+ id: s.string().describe("The ID of the fetched document."),
2435
+ title: s.string().describe("The title of the document."),
2436
+ text: s.string().describe("The text content of the document."),
2437
+ url: s.string().describe("The URL of the document."),
2438
+ metadata: s.record(s.string(), s.unknown()).optional().describe("Additional metadata about the document.")
2439
+ }, lo = {
2440
+ name: f.FETCH,
2441
+ 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}".',
2442
+ parameters: io,
2443
+ outputSchema: co,
2444
+ annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
2445
+ async execute(e, t) {
2446
+ const { id: r } = e, [o, n] = r.split(":", 2);
2447
+ if (!n || o !== "task" && o !== "project")
2448
+ throw new Error(
2449
+ 'Invalid ID format. Expected "task:{id}" or "project:{id}". Example: "task:8485093748" or "project:6cfCcrrCFg2xP94Q"'
2450
+ );
2451
+ let a;
2452
+ if (o === "task") {
2453
+ const i = await t.getTask(n), c = _(i), d = [c.content];
2454
+ c.description && d.push(`
2455
+
2456
+ Description: ${c.description}`), c.dueDate && d.push(`
2457
+ Due: ${c.dueDate}`), c.labels.length > 0 && d.push(`
2458
+ Labels: ${c.labels.join(", ")}`), a = {
2459
+ id: `task:${c.id}`,
2460
+ title: c.content,
2461
+ text: d.join(""),
2462
+ url: ut(c.id),
2463
+ metadata: {
2464
+ priority: c.priority,
2465
+ projectId: c.projectId,
2466
+ sectionId: c.sectionId,
2467
+ parentId: c.parentId,
2468
+ recurring: c.recurring,
2469
+ duration: c.duration,
2470
+ responsibleUid: c.responsibleUid,
2471
+ assignedByUid: c.assignedByUid,
2472
+ checked: c.checked,
2473
+ completedAt: c.completedAt
2474
+ }
2475
+ };
2476
+ } else {
2477
+ const i = await t.getProject(n), c = q(i), d = [c.name];
2478
+ c.isShared && d.push(`
2479
+
2480
+ Shared project`), c.isFavorite && d.push(`
2481
+ Favorite: Yes`), a = {
2482
+ id: `project:${c.id}`,
2483
+ title: c.name,
2484
+ text: d.join(""),
2485
+ url: pt(c.id),
2486
+ metadata: {
2487
+ color: c.color,
2488
+ isFavorite: c.isFavorite,
2489
+ isShared: c.isShared,
2490
+ parentId: c.parentId,
2491
+ inboxProject: c.inboxProject,
2492
+ viewStyle: c.viewStyle
2493
+ }
2494
+ };
2495
+ }
2496
+ return {
2497
+ textContent: JSON.stringify(a),
2498
+ structuredContent: a
2499
+ };
2500
+ }
2501
2501
  }, uo = {
2502
2502
  objectType: s.enum(["task", "project", "comment"]).optional().describe("Type of object to filter by."),
2503
2503
  objectId: s.string().optional().describe("Filter by specific object ID (task, project, or comment)."),
@@ -2615,7 +2615,7 @@ const yo = {
2615
2615
  cursor: s.string().optional().describe("Pagination cursor for retrieving more results."),
2616
2616
  limit: s.number().int().min(1).max(C.COMMENTS_MAX).optional().describe("Maximum number of comments to return")
2617
2617
  }, ko = {
2618
- comments: s.array(fe).describe("The found comments."),
2618
+ comments: s.array(be).describe("The found comments."),
2619
2619
  searchType: s.string().describe(
2620
2620
  'The type of search performed: "single" (comment ID), "task" (task ID), or "project" (project ID).'
2621
2621
  ),
@@ -2660,7 +2660,7 @@ const yo = {
2660
2660
  i = l.results, n = l.nextCursor !== null, a = l.nextCursor;
2661
2661
  } else
2662
2662
  throw new Error("Invalid state: no search parameter provided");
2663
- const c = i.map(pe);
2663
+ const c = i.map(me);
2664
2664
  return {
2665
2665
  textContent: wo({
2666
2666
  comments: c,
@@ -2804,7 +2804,7 @@ const $o = {
2804
2804
  since: a,
2805
2805
  until: i,
2806
2806
  userGmtOffset: I
2807
- }), N = `${$.since}T00:00:00${I}`, T = `${$.until}T23:59:59${I}`, b = new Date(N).toISOString(), S = new Date(T).toISOString(), U = {
2807
+ }), N = `${$.since}T00:00:00${I}`, T = `${$.until}T23:59:59${I}`, b = new Date(N).toISOString(), S = new Date(T).toISOString(), R = {
2808
2808
  ...e,
2809
2809
  since: $.since,
2810
2810
  until: $.until
@@ -2820,11 +2820,11 @@ const $o = {
2820
2820
  since: b,
2821
2821
  until: S,
2822
2822
  ...h ? { filterQuery: h, filterLang: "en" } : {}
2823
- }), v = w.map(R);
2823
+ }), v = w.map(_);
2824
2824
  return {
2825
2825
  textContent: Ao({
2826
2826
  tasks: v,
2827
- args: U,
2827
+ args: R,
2828
2828
  nextCursor: j,
2829
2829
  assigneeEmail: p
2830
2830
  }),
@@ -2833,7 +2833,7 @@ const $o = {
2833
2833
  nextCursor: j ?? void 0,
2834
2834
  totalCount: v.length,
2835
2835
  hasMore: !!j,
2836
- appliedFilters: U
2836
+ appliedFilters: R
2837
2837
  }
2838
2838
  };
2839
2839
  }
@@ -2860,7 +2860,7 @@ function Ao({
2860
2860
  limit: t.limit,
2861
2861
  nextCursor: r ?? void 0,
2862
2862
  filterHints: i,
2863
- previewLines: ke(e, Math.min(e.length, t.limit)),
2863
+ previewLines: Te(e, Math.min(e.length, t.limit)),
2864
2864
  zeroReasonHints: c
2865
2865
  });
2866
2866
  }
@@ -2873,7 +2873,7 @@ const Eo = {
2873
2873
  "The cursor to get the next page of labels (cursor is obtained from the previous call to this tool, with the same parameters). Ignored when searchText is provided."
2874
2874
  )
2875
2875
  }, Oo = {
2876
- labels: s.array(be).describe("The found personal labels."),
2876
+ labels: s.array(ge).describe("The found personal labels."),
2877
2877
  nextCursor: s.string().optional().describe("Cursor for the next page of results."),
2878
2878
  totalCount: s.number().describe("The total number of labels in this page."),
2879
2879
  hasMore: s.boolean().describe("Whether there are more results available."),
@@ -2896,9 +2896,9 @@ const Eo = {
2896
2896
  Hs(t)
2897
2897
  ]), { results: n, nextCursor: a } = r, i = e.searchText ? { searchText: e.searchText } : { limit: e.limit, cursor: e.cursor };
2898
2898
  return {
2899
- textContent: Ro({ labels: n, args: e, nextCursor: a, sharedLabels: o }),
2899
+ textContent: _o({ labels: n, args: e, nextCursor: a, sharedLabels: o }),
2900
2900
  structuredContent: {
2901
- labels: n.map((c) => be.parse(c)),
2901
+ labels: n.map((c) => ge.parse(c)),
2902
2902
  nextCursor: a ?? void 0,
2903
2903
  totalCount: n.length,
2904
2904
  hasMore: !!a,
@@ -2908,7 +2908,7 @@ const Eo = {
2908
2908
  };
2909
2909
  }
2910
2910
  };
2911
- function Ro({
2911
+ function _o({
2912
2912
  labels: e,
2913
2913
  args: t,
2914
2914
  nextCursor: r,
@@ -2933,7 +2933,7 @@ No shared labels.`;
2933
2933
  zeroReasonHints: p
2934
2934
  }) + m;
2935
2935
  }
2936
- const { FIND_PROJECTS: Uo, ADD_TASKS: Dt, UPDATE_TASKS: xt } = f, _o = {
2936
+ const { FIND_PROJECTS: Ro, ADD_TASKS: Dt, UPDATE_TASKS: xt } = f, Uo = {
2937
2937
  projectId: s.string().min(1).describe("The ID of the project to search for collaborators in."),
2938
2938
  searchTerm: s.string().optional().describe(
2939
2939
  "Search for a collaborator by name or email (partial and case insensitive match). If omitted, all collaborators in the project are returned."
@@ -2951,7 +2951,7 @@ const { FIND_PROJECTS: Uo, ADD_TASKS: Dt, UPDATE_TASKS: xt } = f, _o = {
2951
2951
  }, Lo = {
2952
2952
  name: f.FIND_PROJECT_COLLABORATORS,
2953
2953
  description: "Search for collaborators by name or other criteria in a project.",
2954
- parameters: _o,
2954
+ parameters: Uo,
2955
2955
  outputSchema: No,
2956
2956
  annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
2957
2957
  async execute(e, t) {
@@ -3047,7 +3047,7 @@ function Mo({
3047
3047
  const c = [];
3048
3048
  e.length === 0 && (r ? (c.push(`No collaborators match "${r}"`), c.push("Try a broader search term or check spelling"), o > 0 && c.push(`${o} collaborators available without filter`)) : (c.push("Project has no collaborators"), c.push("Share the project to add collaborators")));
3049
3049
  const d = [];
3050
- return e.length > 0 ? (d.push(`Use ${Dt} with responsibleUser to assign new tasks`), d.push(`Use ${xt} with responsibleUser to reassign existing tasks`), d.push("Use collaborator names, emails, or IDs for assignments")) : (d.push(`Use ${Uo} to find other projects`), r && o > 0 && d.push("Try searching without filters to see all collaborators")), F({
3050
+ return e.length > 0 ? (d.push(`Use ${Dt} with responsibleUser to assign new tasks`), d.push(`Use ${xt} with responsibleUser to reassign existing tasks`), d.push("Use collaborator names, emails, or IDs for assignments")) : (d.push(`Use ${Ro} to find other projects`), r && o > 0 && d.push("Try searching without filters to see all collaborators")), F({
3051
3051
  subject: n,
3052
3052
  count: e.length,
3053
3053
  filterHints: a,
@@ -3216,7 +3216,7 @@ const { ADD_SECTIONS: Vo } = f, Jo = {
3216
3216
  'Search for a section by name (partial and case insensitive match). Supports wildcards (e.g. "work*" for prefix match). Use "\\*" for a literal asterisk. If omitted, all sections in the project are returned.'
3217
3217
  )
3218
3218
  }, Xo = {
3219
- sections: s.array(he).describe("The found sections."),
3219
+ sections: s.array(fe).describe("The found sections."),
3220
3220
  totalCount: s.number().describe("The total number of sections found."),
3221
3221
  appliedFilters: s.record(s.string(), s.unknown()).describe("The filters that were applied to the search.")
3222
3222
  }, Zo = {
@@ -3265,13 +3265,142 @@ function Qo({
3265
3265
  zeroReasonHints: o
3266
3266
  });
3267
3267
  }
3268
- const en = 300 * 1e3;
3269
- class tn {
3268
+ function At(e) {
3269
+ return /* @__PURE__ */ new Date(`${e}T00:00:00`);
3270
+ }
3271
+ const en = {
3272
+ startDate: s.string().regex(/^(\d{4}-\d{2}-\d{2}|today)$/).optional().describe("The start date to get the tasks for. Format: YYYY-MM-DD or 'today'."),
3273
+ overdueOption: s.enum(["overdue-only", "include-overdue", "exclude-overdue"]).optional().describe(
3274
+ "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'."
3275
+ ),
3276
+ daysCount: s.number().int().min(1).max(30).default(1).describe(
3277
+ "The number of days to get the tasks for, starting from the start date. Default is 1 which means only tasks for the start date."
3278
+ ),
3279
+ limit: s.number().int().min(1).max(C.TASKS_MAX).default(C.TASKS_DEFAULT).describe("The maximum number of tasks to return."),
3280
+ cursor: s.string().optional().describe(
3281
+ "The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters)."
3282
+ ),
3283
+ responsibleUser: s.string().optional().describe(
3284
+ "Filter tasks assigned to this user. User ID, name, or email. For personal queries (summaries, plans, reports), set to current user from user-info to exclude collaborators."
3285
+ ),
3286
+ responsibleUserFiltering: s.enum(gt).optional().describe(
3287
+ "Filter when responsibleUser is omitted. 'assigned'=assigned to others; 'unassignedOrMe'=unassigned+mine; 'all'=everyone. Default: 'unassignedOrMe'."
3288
+ ),
3289
+ ...qe
3290
+ }, tn = {
3291
+ tasks: s.array(K).describe("The found tasks."),
3292
+ nextCursor: s.string().optional().describe("Cursor for the next page of results."),
3293
+ totalCount: s.number().describe("The total number of tasks in this page."),
3294
+ hasMore: s.boolean().describe("Whether there are more results available."),
3295
+ appliedFilters: s.record(s.string(), s.unknown()).describe("The filters that were applied to the search.")
3296
+ }, sn = {
3297
+ name: f.FIND_TASKS_BY_DATE,
3298
+ description: "Get tasks by date range. startDate='today' includes overdue items. Default responsibleUserFiltering='unassignedOrMe' excludes others' tasks. Person-specific queries (summaries, plans, reports) require responsibleUser.",
3299
+ parameters: en,
3300
+ outputSchema: tn,
3301
+ annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
3302
+ async execute(e, t) {
3303
+ if (!e.startDate && e.overdueOption !== "overdue-only")
3304
+ throw new Error(
3305
+ "Either startDate must be provided or overdueOption must be set to overdue-only"
3306
+ );
3307
+ const r = await Le(t, e.responsibleUser), o = r?.userId, n = r?.email;
3308
+ let a = "";
3309
+ if (e.overdueOption === "overdue-only")
3310
+ a = "overdue";
3311
+ else if (e.startDate === "today")
3312
+ if (e.daysCount > 1) {
3313
+ const p = /* @__PURE__ */ new Date(), m = te(p), h = xe(p, e.daysCount), g = Je(h, { representation: "date" }), I = `(due after: ${m} | due: ${m}) & due before: ${g}`;
3314
+ a = e.overdueOption === "exclude-overdue" ? I : `(${I} | overdue)`;
3315
+ } else
3316
+ a = e.overdueOption === "exclude-overdue" ? "today" : "(today | overdue)";
3317
+ else if (e.startDate) {
3318
+ const p = e.startDate, m = xe(At(p), e.daysCount), h = Je(m, { representation: "date" });
3319
+ a = `(due after: ${p} | due: ${p}) & due before: ${h}`;
3320
+ }
3321
+ const i = Ke(e.labels, e.labelsOperator);
3322
+ i.length > 0 && (a = se(a, `(${i})`));
3323
+ const c = yt({
3324
+ resolvedAssigneeId: o,
3325
+ assigneeEmail: n,
3326
+ responsibleUserFiltering: e.responsibleUserFiltering
3327
+ });
3328
+ a = se(a, c);
3329
+ const { tasks: d, nextCursor: l } = await Fe({
3330
+ client: t,
3331
+ query: a,
3332
+ cursor: e.cursor,
3333
+ limit: e.limit
3334
+ });
3335
+ return {
3336
+ textContent: rn({ tasks: d, args: e, nextCursor: l, assigneeEmail: n }),
3337
+ structuredContent: {
3338
+ tasks: d,
3339
+ nextCursor: l ?? void 0,
3340
+ totalCount: d.length,
3341
+ hasMore: !!l,
3342
+ appliedFilters: e
3343
+ }
3344
+ };
3345
+ }
3346
+ };
3347
+ function rn({
3348
+ tasks: e,
3349
+ args: t,
3350
+ nextCursor: r,
3351
+ assigneeEmail: o
3352
+ }) {
3353
+ const n = [];
3354
+ if (t.overdueOption === "overdue-only")
3355
+ n.push("overdue tasks only");
3356
+ else if (t.startDate === "today") {
3357
+ const c = t.overdueOption === "exclude-overdue" ? "" : " + overdue tasks";
3358
+ n.push(
3359
+ `today${c}${t.daysCount > 1 ? ` + ${t.daysCount - 1} more days` : ""}`
3360
+ );
3361
+ } else if (t.startDate) {
3362
+ const c = t.daysCount > 1 ? ` to ${te(xe(At(t.startDate), t.daysCount))}` : "";
3363
+ n.push(`${t.startDate}${c}`);
3364
+ }
3365
+ if (t.labels && t.labels.length > 0) {
3366
+ const c = t.labels.map((d) => `@${d}`).join(t.labelsOperator === "and" ? " & " : " | ");
3367
+ n.push(`labels: ${c}`);
3368
+ }
3369
+ if (t.responsibleUser) {
3370
+ const c = o || t.responsibleUser;
3371
+ n.push(`assigned to: ${c}`);
3372
+ }
3373
+ let a = "";
3374
+ if (t.overdueOption === "overdue-only" ? a = "Overdue tasks" : t.startDate === "today" ? a = t.overdueOption === "exclude-overdue" ? "Today's tasks" : "Today's tasks + overdue" : t.startDate ? a = `Tasks for ${t.startDate}` : a = "Tasks", t.responsibleUser) {
3375
+ const c = o || t.responsibleUser;
3376
+ a += ` assigned to ${c}`;
3377
+ }
3378
+ const i = [];
3379
+ if (e.length === 0)
3380
+ if (t.overdueOption === "overdue-only")
3381
+ i.push("Great job! No overdue tasks");
3382
+ else if (t.startDate === "today") {
3383
+ const c = t.overdueOption === "exclude-overdue" ? "" : " or overdue";
3384
+ i.push(`Great job! No tasks for today${c}`);
3385
+ } else
3386
+ i.push("Expand date range with larger 'daysCount'"), i.push("Check today's tasks with startDate='today'");
3387
+ return F({
3388
+ subject: a,
3389
+ count: e.length,
3390
+ limit: t.limit,
3391
+ nextCursor: r ?? void 0,
3392
+ filterHints: n,
3393
+ previewLines: Te(e, Math.min(e.length, t.limit)),
3394
+ zeroReasonHints: i
3395
+ });
3396
+ }
3397
+ const on = 300 * 1e3;
3398
+ class nn {
3270
3399
  constructor() {
3271
3400
  this.cache = null;
3272
3401
  }
3273
3402
  async getFilters(t) {
3274
- if (this.cache && Date.now() - this.cache.timestamp < en)
3403
+ if (this.cache && Date.now() - this.cache.timestamp < on)
3275
3404
  return this.cache.filters;
3276
3405
  const o = ((await t.sync({
3277
3406
  resourceTypes: ["filters"],
@@ -3328,7 +3457,7 @@ ${u}` + (d.length > 5 ? `
3328
3457
  this.cache = null;
3329
3458
  }
3330
3459
  }
3331
- const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3460
+ const an = new nn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, cn = {
3332
3461
  searchText: s.string().optional().describe("The text to search for in tasks."),
3333
3462
  projectId: s.string().optional().describe(
3334
3463
  'Find tasks in this project. Project ID should be an ID string, or the text "inbox", for inbox tasks.'
@@ -3350,17 +3479,17 @@ const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3350
3479
  "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."
3351
3480
  ),
3352
3481
  ...qe
3353
- }, on = {
3482
+ }, dn = {
3354
3483
  tasks: s.array(K).describe("The found tasks."),
3355
3484
  nextCursor: s.string().optional().describe("Cursor for the next page of results."),
3356
3485
  totalCount: s.number().describe("The total number of tasks in this page."),
3357
3486
  hasMore: s.boolean().describe("Whether there are more results available."),
3358
3487
  appliedFilters: s.record(s.string(), s.unknown()).describe("The filters that were applied to the search.")
3359
- }, nn = {
3488
+ }, ln = {
3360
3489
  name: f.FIND_TASKS,
3361
3490
  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.",
3362
- parameters: rn,
3363
- outputSchema: on,
3491
+ parameters: cn,
3492
+ outputSchema: dn,
3364
3493
  annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
3365
3494
  async execute(e, t) {
3366
3495
  const {
@@ -3390,7 +3519,7 @@ const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3390
3519
  'The `filter`/`filterIdOrName` parameter cannot be combined with projectId, sectionId, or parentId. Use filter syntax instead (e.g. "##ProjectName").'
3391
3520
  );
3392
3521
  let D = m;
3393
- h && (D = (await sn.resolveFilter(t, h)).filterQuery);
3522
+ h && (D = (await an.resolveFilter(t, h)).filterQuery);
3394
3523
  const $ = await Le(t, i), N = $?.userId, T = $?.email;
3395
3524
  if (o || n || a) {
3396
3525
  const x = {
@@ -3398,21 +3527,21 @@ const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3398
3527
  cursor: l ?? null
3399
3528
  };
3400
3529
  o && (x.projectId = await G({ projectId: o, user: g })), n && (x.sectionId = n), a && (x.parentId = a);
3401
- const { results: L, nextCursor: H } = await t.getTasks(x), Te = L.map(R);
3402
- let M = r ? Te.filter(
3530
+ const { results: L, nextCursor: H } = await t.getTasks(x), we = L.map(_);
3531
+ let M = r ? we.filter(
3403
3532
  (V) => V.content.toLowerCase().includes(r.toLowerCase()) || V.description?.toLowerCase().includes(r.toLowerCase())
3404
- ) : Te;
3533
+ ) : we;
3405
3534
  return M = Ms({
3406
3535
  tasks: M,
3407
3536
  resolvedAssigneeId: N,
3408
3537
  currentUserId: g.id,
3409
3538
  responsibleUserFiltering: c
3410
3539
  }), u && u.length > 0 && (M = p === "and" ? M.filter(
3411
- (V) => u.every((we) => V.labels.includes(we))
3540
+ (V) => u.every((Ie) => V.labels.includes(Ie))
3412
3541
  ) : M.filter(
3413
- (V) => u.some((we) => V.labels.includes(we))
3542
+ (V) => u.some((Ie) => V.labels.includes(Ie))
3414
3543
  )), {
3415
- textContent: Se({
3544
+ textContent: Ce({
3416
3545
  tasks: M,
3417
3546
  args: e,
3418
3547
  nextCursor: H,
@@ -3434,9 +3563,9 @@ const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3434
3563
  lang: "en",
3435
3564
  limit: d,
3436
3565
  cursor: l ?? null
3437
- }), H = x.map(R);
3566
+ }), H = x.map(_);
3438
3567
  return {
3439
- textContent: Se({
3568
+ textContent: Ce({
3440
3569
  tasks: H,
3441
3570
  args: e,
3442
3571
  nextCursor: L,
@@ -3470,7 +3599,7 @@ const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3470
3599
  limit: e.limit
3471
3600
  });
3472
3601
  return {
3473
- textContent: Se({
3602
+ textContent: Ce({
3474
3603
  tasks: w,
3475
3604
  args: e,
3476
3605
  nextCursor: j,
@@ -3487,7 +3616,7 @@ const sn = new tn(), { FIND_COMPLETED_TASKS: rt, ADD_TASKS: ot } = f, rn = {
3487
3616
  };
3488
3617
  }
3489
3618
  };
3490
- function an(e) {
3619
+ function un(e) {
3491
3620
  if (e.projectId) {
3492
3621
  const t = [
3493
3622
  e.searchText ? "No tasks in project match search" : "Project has no tasks yet"
@@ -3504,7 +3633,7 @@ function an(e) {
3504
3633
  }
3505
3634
  return [];
3506
3635
  }
3507
- function Se({
3636
+ function Ce({
3508
3637
  tasks: e,
3509
3638
  args: t,
3510
3639
  nextCursor: r,
@@ -3522,7 +3651,7 @@ function Se({
3522
3651
  const d = t.labels.map((l) => `@${l}`).join(t.labelsOperator === "and" ? " & " : " | ");
3523
3652
  i.push(`labels: ${d}`);
3524
3653
  }
3525
- e.length === 0 && c.push(...an(t));
3654
+ e.length === 0 && c.push(...un(t));
3526
3655
  } else {
3527
3656
  const d = n || t.responsibleUser, l = [];
3528
3657
  if (t.filter && l.push(`filter: ${t.filter}`), t.searchText && l.push(`"${t.searchText}"`), t.responsibleUser && l.push(`assigned to ${d}`), t.labels && t.labels.length > 0) {
@@ -3547,139 +3676,10 @@ function Se({
3547
3676
  limit: t.limit,
3548
3677
  nextCursor: r ?? void 0,
3549
3678
  filterHints: i,
3550
- previewLines: ke(e, Math.min(e.length, t.limit)),
3679
+ previewLines: Te(e, Math.min(e.length, t.limit)),
3551
3680
  zeroReasonHints: c
3552
3681
  });
3553
3682
  }
3554
- function At(e) {
3555
- return /* @__PURE__ */ new Date(`${e}T00:00:00`);
3556
- }
3557
- const cn = {
3558
- startDate: s.string().regex(/^(\d{4}-\d{2}-\d{2}|today)$/).optional().describe("The start date to get the tasks for. Format: YYYY-MM-DD or 'today'."),
3559
- overdueOption: s.enum(["overdue-only", "include-overdue", "exclude-overdue"]).optional().describe(
3560
- "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'."
3561
- ),
3562
- daysCount: s.number().int().min(1).max(30).default(1).describe(
3563
- "The number of days to get the tasks for, starting from the start date. Default is 1 which means only tasks for the start date."
3564
- ),
3565
- limit: s.number().int().min(1).max(C.TASKS_MAX).default(C.TASKS_DEFAULT).describe("The maximum number of tasks to return."),
3566
- cursor: s.string().optional().describe(
3567
- "The cursor to get the next page of tasks (cursor is obtained from the previous call to this tool, with the same parameters)."
3568
- ),
3569
- responsibleUser: s.string().optional().describe(
3570
- "Filter tasks assigned to this user. User ID, name, or email. For personal queries (summaries, plans, reports), set to current user from user-info to exclude collaborators."
3571
- ),
3572
- responsibleUserFiltering: s.enum(gt).optional().describe(
3573
- "Filter when responsibleUser is omitted. 'assigned'=assigned to others; 'unassignedOrMe'=unassigned+mine; 'all'=everyone. Default: 'unassignedOrMe'."
3574
- ),
3575
- ...qe
3576
- }, dn = {
3577
- tasks: s.array(K).describe("The found tasks."),
3578
- nextCursor: s.string().optional().describe("Cursor for the next page of results."),
3579
- totalCount: s.number().describe("The total number of tasks in this page."),
3580
- hasMore: s.boolean().describe("Whether there are more results available."),
3581
- appliedFilters: s.record(s.string(), s.unknown()).describe("The filters that were applied to the search.")
3582
- }, ln = {
3583
- name: f.FIND_TASKS_BY_DATE,
3584
- description: "Get tasks by date range. startDate='today' includes overdue items. Default responsibleUserFiltering='unassignedOrMe' excludes others' tasks. Person-specific queries (summaries, plans, reports) require responsibleUser.",
3585
- parameters: cn,
3586
- outputSchema: dn,
3587
- annotations: { readOnlyHint: !0, destructiveHint: !1, idempotentHint: !0 },
3588
- async execute(e, t) {
3589
- if (!e.startDate && e.overdueOption !== "overdue-only")
3590
- throw new Error(
3591
- "Either startDate must be provided or overdueOption must be set to overdue-only"
3592
- );
3593
- const r = await Le(t, e.responsibleUser), o = r?.userId, n = r?.email;
3594
- let a = "";
3595
- if (e.overdueOption === "overdue-only")
3596
- a = "overdue";
3597
- else if (e.startDate === "today")
3598
- if (e.daysCount > 1) {
3599
- const p = /* @__PURE__ */ new Date(), m = te(p), h = De(p, e.daysCount), g = Je(h, { representation: "date" }), I = `(due after: ${m} | due: ${m}) & due before: ${g}`;
3600
- a = e.overdueOption === "exclude-overdue" ? I : `(${I} | overdue)`;
3601
- } else
3602
- a = e.overdueOption === "exclude-overdue" ? "today" : "(today | overdue)";
3603
- else if (e.startDate) {
3604
- const p = e.startDate, m = De(At(p), e.daysCount), h = Je(m, { representation: "date" });
3605
- a = `(due after: ${p} | due: ${p}) & due before: ${h}`;
3606
- }
3607
- const i = Ke(e.labels, e.labelsOperator);
3608
- i.length > 0 && (a = se(a, `(${i})`));
3609
- const c = yt({
3610
- resolvedAssigneeId: o,
3611
- assigneeEmail: n,
3612
- responsibleUserFiltering: e.responsibleUserFiltering
3613
- });
3614
- a = se(a, c);
3615
- const { tasks: d, nextCursor: l } = await Fe({
3616
- client: t,
3617
- query: a,
3618
- cursor: e.cursor,
3619
- limit: e.limit
3620
- });
3621
- return {
3622
- textContent: un({ tasks: d, args: e, nextCursor: l, assigneeEmail: n }),
3623
- structuredContent: {
3624
- tasks: d,
3625
- nextCursor: l ?? void 0,
3626
- totalCount: d.length,
3627
- hasMore: !!l,
3628
- appliedFilters: e
3629
- }
3630
- };
3631
- }
3632
- };
3633
- function un({
3634
- tasks: e,
3635
- args: t,
3636
- nextCursor: r,
3637
- assigneeEmail: o
3638
- }) {
3639
- const n = [];
3640
- if (t.overdueOption === "overdue-only")
3641
- n.push("overdue tasks only");
3642
- else if (t.startDate === "today") {
3643
- const c = t.overdueOption === "exclude-overdue" ? "" : " + overdue tasks";
3644
- n.push(
3645
- `today${c}${t.daysCount > 1 ? ` + ${t.daysCount - 1} more days` : ""}`
3646
- );
3647
- } else if (t.startDate) {
3648
- const c = t.daysCount > 1 ? ` to ${te(De(At(t.startDate), t.daysCount))}` : "";
3649
- n.push(`${t.startDate}${c}`);
3650
- }
3651
- if (t.labels && t.labels.length > 0) {
3652
- const c = t.labels.map((d) => `@${d}`).join(t.labelsOperator === "and" ? " & " : " | ");
3653
- n.push(`labels: ${c}`);
3654
- }
3655
- if (t.responsibleUser) {
3656
- const c = o || t.responsibleUser;
3657
- n.push(`assigned to: ${c}`);
3658
- }
3659
- let a = "";
3660
- if (t.overdueOption === "overdue-only" ? a = "Overdue tasks" : t.startDate === "today" ? a = t.overdueOption === "exclude-overdue" ? "Today's tasks" : "Today's tasks + overdue" : t.startDate ? a = `Tasks for ${t.startDate}` : a = "Tasks", t.responsibleUser) {
3661
- const c = o || t.responsibleUser;
3662
- a += ` assigned to ${c}`;
3663
- }
3664
- const i = [];
3665
- if (e.length === 0)
3666
- if (t.overdueOption === "overdue-only")
3667
- i.push("Great job! No overdue tasks");
3668
- else if (t.startDate === "today") {
3669
- const c = t.overdueOption === "exclude-overdue" ? "" : " or overdue";
3670
- i.push(`Great job! No tasks for today${c}`);
3671
- } else
3672
- i.push("Expand date range with larger 'daysCount'"), i.push("Check today's tasks with startDate='today'");
3673
- return F({
3674
- subject: a,
3675
- count: e.length,
3676
- limit: t.limit,
3677
- nextCursor: r ?? void 0,
3678
- filterHints: n,
3679
- previewLines: ke(e, Math.min(e.length, t.limit)),
3680
- zeroReasonHints: i
3681
- });
3682
- }
3683
3683
  const pn = {
3684
3684
  projectId: s.string().min(1).optional().describe(
3685
3685
  "Optional project ID. If provided, shows detailed overview of that project. If omitted, shows overview of all projects."
@@ -3804,11 +3804,11 @@ function nt(e) {
3804
3804
  }
3805
3805
  return r;
3806
3806
  }
3807
- function Re(e, t = "") {
3807
+ function _e(e, t = "") {
3808
3808
  const r = [];
3809
3809
  for (const o of e) {
3810
3810
  const n = `id=${o.id}`, a = o.dueDate ? `; due=${o.dueDate}` : "", i = `; content=${o.content}`;
3811
- r.push(`${t}- ${n}${a}${i}`), o.children.length > 0 && r.push(...Re(o.children, `${t} `));
3811
+ r.push(`${t}- ${n}${a}${i}`), o.children.length > 0 && r.push(..._e(o.children, `${t} `));
3812
3812
  }
3813
3813
  return r;
3814
3814
  }
@@ -3817,10 +3817,12 @@ function Pt(e, t) {
3817
3817
  id: e.id,
3818
3818
  name: e.name,
3819
3819
  parentId: re(e) ? e.parentId ?? void 0 : void 0,
3820
- folderId: Pe(e) ? e.folderId ?? void 0 : void 0,
3820
+ folderId: ue(e) ? e.folderId ?? void 0 : void 0,
3821
3821
  childOrder: e.childOrder,
3822
3822
  sections: t[e.id] || [],
3823
- children: e.children.map((r) => Pt(r, t))
3823
+ children: e.children.map(
3824
+ (r) => Pt(r, t)
3825
+ )
3824
3826
  };
3825
3827
  }
3826
3828
  async function bn(e, t) {
@@ -3831,7 +3833,7 @@ async function bn(e, t) {
3831
3833
  limit: C.TASKS_BATCH_SIZE,
3832
3834
  cursor: o ?? void 0
3833
3835
  });
3834
- r = r.concat(n.map(R)), o = a ?? void 0;
3836
+ r = r.concat(n.map(_)), o = a ?? void 0;
3835
3837
  } while (o);
3836
3838
  return r;
3837
3839
  }
@@ -3892,7 +3894,7 @@ async function kn(e, t) {
3892
3894
  if (i.length > 0) {
3893
3895
  c.push("");
3894
3896
  const u = nt(i);
3895
- c.push(...Re(u));
3897
+ c.push(..._e(u));
3896
3898
  }
3897
3899
  for (const u of o) {
3898
3900
  c.push(""), c.push(`## ${u.name}`);
@@ -3900,7 +3902,7 @@ async function kn(e, t) {
3900
3902
  if (!p?.length)
3901
3903
  continue;
3902
3904
  const m = nt(p);
3903
- c.push(...Re(m));
3905
+ c.push(..._e(m));
3904
3906
  }
3905
3907
  const d = c.join(`
3906
3908
  `), l = {
@@ -4147,7 +4149,7 @@ const Dn = {
4147
4149
  progressPercent: s.number().describe("Completion percentage (0-100).")
4148
4150
  }).describe("Project completion progress."),
4149
4151
  health: s.object({
4150
- status: s.enum(Ue).describe("The overall health status of the project."),
4152
+ status: s.enum(Re).describe("The overall health status of the project."),
4151
4153
  description: s.string().nullable().optional().describe("Detailed description of the health assessment."),
4152
4154
  descriptionSummary: s.string().nullable().optional().describe("Brief summary of the health assessment."),
4153
4155
  taskRecommendations: s.array(An).nullable().optional().describe("Specific recommendations for individual tasks."),
@@ -4185,7 +4187,7 @@ async function Pn(e, t, r) {
4185
4187
  ]);
4186
4188
  return { progress: o, health: n };
4187
4189
  }
4188
- function Rn(e, { progress: t, health: r, context: o }) {
4190
+ function _n(e, { progress: t, health: r, context: o }) {
4189
4191
  const n = [`# Project Health: ${e}`, ""];
4190
4192
  if (n.push(`**Status:** ${r.status}`), r.isStale && n.push("**Note:** Health data is stale and may not reflect recent changes."), r.updateInProgress && n.push("**Note:** A health analysis update is currently in progress."), r.updatedAt && n.push(`**Last Updated:** ${r.updatedAt}`), n.push(""), n.push("## Progress"), n.push(
4191
4193
  `**Completed:** ${t.completedCount} | **Active:** ${t.activeCount} | **Progress:** ${t.progressPercent}%`
@@ -4208,7 +4210,7 @@ function Rn(e, { progress: t, health: r, context: o }) {
4208
4210
  return n.join(`
4209
4211
  `);
4210
4212
  }
4211
- const Un = {
4213
+ const Rn = {
4212
4214
  name: f.GET_PROJECT_HEALTH,
4213
4215
  description: "Get a comprehensive health assessment for a project including completion progress, health status (EXCELLENT, ON_TRACK, AT_RISK, CRITICAL), and optional detailed context with project metrics and task-level recommendations. Use includeContext=true for full detail including task data.",
4214
4216
  parameters: xn,
@@ -4219,7 +4221,7 @@ const Un = {
4219
4221
  idempotentHint: !0
4220
4222
  },
4221
4223
  async execute(e, t) {
4222
- const { projectId: r, includeContext: o } = e, n = await Pn(t, r, o), a = n.context?.projectName ?? `Project ${r}`, i = Rn(a, n), c = n.context ? {
4224
+ const { projectId: r, includeContext: o } = e, n = await Pn(t, r, o), a = n.context?.projectName ?? `Project ${r}`, i = _n(a, n), c = n.context ? {
4223
4225
  projectDescription: n.context.projectDescription,
4224
4226
  projectMetrics: n.context.projectMetrics,
4225
4227
  tasks: n.context.tasks.map((d) => ({
@@ -4255,7 +4257,7 @@ const Un = {
4255
4257
  }
4256
4258
  };
4257
4259
  }
4258
- }, _n = {
4260
+ }, Un = {
4259
4261
  workspaceIdOrName: s.string().min(1).describe(
4260
4262
  "The workspace ID or name. Supports exact ID, exact name match (case-insensitive), or unique partial name match."
4261
4263
  ),
@@ -4263,7 +4265,7 @@ const Un = {
4263
4265
  }, Nn = s.object({
4264
4266
  projectId: s.string().describe("The project ID."),
4265
4267
  health: s.object({
4266
- status: s.enum(Ue).describe("The health status of the project."),
4268
+ status: s.enum(Re).describe("The health status of the project."),
4267
4269
  isStale: s.boolean().describe("Whether the health data is stale."),
4268
4270
  updateInProgress: s.boolean().describe("Whether a health analysis update is in progress.")
4269
4271
  }).nullable().describe("Health data for this project, if available."),
@@ -4280,7 +4282,7 @@ const Un = {
4280
4282
  }, Mn = {
4281
4283
  name: f.GET_WORKSPACE_INSIGHTS,
4282
4284
  description: "Get aggregated health and progress insights across all projects in a workspace. Accepts workspace name or ID, with optional project ID filtering. Useful for a cross-project health overview.",
4283
- parameters: _n,
4285
+ parameters: Un,
4284
4286
  outputSchema: Ln,
4285
4287
  annotations: {
4286
4288
  readOnlyHint: !0,
@@ -4459,7 +4461,7 @@ const zn = {
4459
4461
  newAssigneeId: void 0
4460
4462
  }));
4461
4463
  return {
4462
- textContent: Ce({
4464
+ textContent: $e({
4463
4465
  operation: r,
4464
4466
  results: w,
4465
4467
  dryRun: !0
@@ -4496,7 +4498,7 @@ const zn = {
4496
4498
  throw new Error(`All ${S.length} unassign operation(s) failed: ${w}`);
4497
4499
  }
4498
4500
  return {
4499
- textContent: Ce({
4501
+ textContent: $e({
4500
4502
  operation: r,
4501
4503
  results: S,
4502
4504
  dryRun: !1
@@ -4541,7 +4543,7 @@ const zn = {
4541
4543
  newAssigneeId: j.resolvedUser.userId
4542
4544
  };
4543
4545
  });
4544
- const U = S.map(
4546
+ const R = S.map(
4545
4547
  async ({ assignment: w, validation: j }) => {
4546
4548
  const v = d.find((x) => x.id === w.taskId);
4547
4549
  if (!w.taskId || !j.resolvedUser?.userId)
@@ -4570,7 +4572,7 @@ const zn = {
4570
4572
  }
4571
4573
  }
4572
4574
  );
4573
- return Promise.all(U);
4575
+ return Promise.all(R);
4574
4576
  }
4575
4577
  const D = await I(h, !i), $ = [...D, ...g, ...l];
4576
4578
  if ($.length > 0 && $.every((T) => !T.success)) {
@@ -4578,7 +4580,7 @@ const zn = {
4578
4580
  throw new Error(`All ${$.length} ${r} operation(s) failed: ${T}`);
4579
4581
  }
4580
4582
  return {
4581
- textContent: Ce({
4583
+ textContent: $e({
4582
4584
  operation: r,
4583
4585
  results: $,
4584
4586
  dryRun: i
@@ -4594,7 +4596,7 @@ const zn = {
4594
4596
  };
4595
4597
  }
4596
4598
  };
4597
- function Ce({
4599
+ function $e({
4598
4600
  operation: e,
4599
4601
  results: t,
4600
4602
  dryRun: r
@@ -4705,8 +4707,8 @@ const Xn = {
4705
4707
  }
4706
4708
  };
4707
4709
  }
4708
- }, Rt = ["project", "section"], ra = {
4709
- type: s.enum(Rt).describe(
4710
+ }, _t = ["project", "section"], ra = {
4711
+ type: s.enum(_t).describe(
4710
4712
  '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.'
4711
4713
  ),
4712
4714
  items: s.array(
@@ -4723,7 +4725,7 @@ const Xn = {
4723
4725
  "The items to reorder or move. Each item must have at least order or parentId. Items with parentId will be moved first, then items with order will be reordered. All items being reordered should be siblings for predictable results."
4724
4726
  )
4725
4727
  }, oa = {
4726
- type: s.enum(Rt).describe("The type of entity that was reordered/moved."),
4728
+ type: s.enum(_t).describe("The type of entity that was reordered/moved."),
4727
4729
  movedCount: s.number().describe("The number of entities moved to a new parent."),
4728
4730
  reorderedCount: s.number().describe("The number of entities reordered."),
4729
4731
  affectedIds: s.array(s.string()).describe("The IDs of all affected entities."),
@@ -4840,7 +4842,7 @@ const Xn = {
4840
4842
  const l = d instanceof Error ? d.message : String(d);
4841
4843
  throw new Error(`Reschedule failed: ${l}`);
4842
4844
  }
4843
- const a = await Promise.all(r.map((d) => t.getTask(d.id))), i = a.map(R);
4845
+ const a = await Promise.all(r.map((d) => t.getTask(d.id))), i = a.map(_);
4844
4846
  return {
4845
4847
  textContent: Ye("Rescheduled", i, {
4846
4848
  showDetails: i.length <= 5
@@ -4966,7 +4968,7 @@ const ya = s.object({
4966
4968
  }), ka = {
4967
4969
  comments: s.array(ya).min(1).describe("The comments to update.")
4968
4970
  }, Ta = {
4969
- comments: s.array(fe).describe("The updated comments."),
4971
+ comments: s.array(be).describe("The updated comments."),
4970
4972
  totalCount: s.number().describe("The total number of comments updated."),
4971
4973
  updatedCommentIds: s.array(s.string()).describe("The IDs of the updated comments."),
4972
4974
  appliedOperations: s.object({
@@ -4979,7 +4981,7 @@ const ya = s.object({
4979
4981
  outputSchema: Ta,
4980
4982
  annotations: { readOnlyHint: !1, destructiveHint: !0, idempotentHint: !1 },
4981
4983
  async execute(e, t) {
4982
- const { comments: r } = e, o = r.map(async (c) => await t.updateComment(c.id, { content: c.content })), a = (await Promise.all(o)).map(pe);
4984
+ const { comments: r } = e, o = r.map(async (c) => await t.updateComment(c.id, { content: c.content })), a = (await Promise.all(o)).map(me);
4983
4985
  return {
4984
4986
  textContent: Ia({
4985
4987
  comments: a
@@ -5092,8 +5094,7 @@ ${n}`;
5092
5094
  return o;
5093
5095
  }
5094
5096
  function Da({ id: e, ...t }) {
5095
- const r = Object.values(t);
5096
- return r.length === 0 || r.every((o) => o === void 0) ? "no-fields" : null;
5097
+ return Object.values(t).every((o) => o === void 0) ? "no-fields" : null;
5097
5098
  }
5098
5099
  const xa = s.object({
5099
5100
  id: s.string().min(1).describe("The ID of the project to update."),
@@ -5120,7 +5121,7 @@ const xa = s.object({
5120
5121
  async execute(e, t) {
5121
5122
  const { projects: r } = e, o = await Promise.all(
5122
5123
  r.map(async (d) => {
5123
- const l = Ra(d);
5124
+ const l = _a(d);
5124
5125
  if (l !== null) return { kind: "skipped", reason: l };
5125
5126
  const { id: u, ...p } = d;
5126
5127
  return { kind: "updated", project: await t.updateProject(u, p) };
@@ -5162,22 +5163,22 @@ function Pa({
5162
5163
  return t > 0 && i.push(`${t} skipped - no changes`), r > 0 && i.push(`${r} skipped - no valid field values`), i.length > 0 && (a += ` (${i.join(", ")})`), o > 0 && (a += `:
5163
5164
  ${n}`), a;
5164
5165
  }
5165
- function Ra({ id: e, ...t }) {
5166
+ function _a({ id: e, ...t }) {
5166
5167
  const r = Object.values(t);
5167
5168
  return r.length === 0 ? "no-fields" : r.every((o) => o === void 0) ? "no-valid-values" : null;
5168
5169
  }
5169
- const Ua = s.object({
5170
+ const Ra = s.object({
5170
5171
  type: s.literal("relative"),
5171
5172
  id: s.string().min(1).describe("The ID of the relative reminder to update."),
5172
5173
  minuteOffset: s.number().int().min(0).optional().describe("New minute offset before task due time."),
5173
- service: ge.optional().describe('New delivery method: "email" or "push".'),
5174
- isUrgent: ye
5175
- }), _a = s.object({
5174
+ service: ye.optional().describe('New delivery method: "email" or "push".'),
5175
+ isUrgent: ke
5176
+ }), Ua = s.object({
5176
5177
  type: s.literal("absolute"),
5177
5178
  id: s.string().min(1).describe("The ID of the absolute reminder to update."),
5178
5179
  due: It.optional().describe("New due date/time for the reminder."),
5179
- service: ge.optional().describe('New delivery method: "email" or "push".'),
5180
- isUrgent: ye
5180
+ service: ye.optional().describe('New delivery method: "email" or "push".'),
5181
+ isUrgent: ke
5181
5182
  }), Na = s.object({
5182
5183
  type: s.literal("location"),
5183
5184
  id: s.string().min(1).describe("The ID of the location reminder to update."),
@@ -5189,12 +5190,12 @@ const Ua = s.object({
5189
5190
  ),
5190
5191
  radius: s.number().int().optional().describe("New radius in meters.")
5191
5192
  }), La = s.discriminatedUnion("type", [
5193
+ Ra,
5192
5194
  Ua,
5193
- _a,
5194
5195
  Na
5195
5196
  ]), Ma = {
5196
- reminders: s.array(La).min(1).max(ue).describe(
5197
- `Array of reminders to update (max ${ue}). Each must include the reminder type and ID. Only include fields that need to change.`
5197
+ reminders: s.array(La).min(1).max(pe).describe(
5198
+ `Array of reminders to update (max ${pe}). Each must include the reminder type and ID. Only include fields that need to change.`
5198
5199
  )
5199
5200
  }, Fa = {
5200
5201
  reminders: s.array(He).describe("The updated reminders."),
@@ -5244,7 +5245,7 @@ const Ua = s.object({
5244
5245
  }), Ba = {
5245
5246
  sections: s.array(Wa).min(1).describe("The sections to update.")
5246
5247
  }, za = {
5247
- sections: s.array(he).describe("The updated sections."),
5248
+ sections: s.array(fe).describe("The updated sections."),
5248
5249
  totalCount: s.number().describe("The total number of sections updated."),
5249
5250
  updatedSectionIds: s.array(s.string()).describe("The IDs of the updated sections.")
5250
5251
  }, Ya = {
@@ -5289,7 +5290,7 @@ const qa = s.object({
5289
5290
  sectionId: s.string().optional().describe("The new section ID for the task."),
5290
5291
  parentId: s.string().optional().describe("The new parent task ID (for subtasks)."),
5291
5292
  order: s.number().optional().describe("The new order of the task within its parent/section."),
5292
- priority: Ne.optional().describe(_e),
5293
+ priority: Ne.optional().describe(Ue),
5293
5294
  dueString: s.preprocess(
5294
5295
  // Keep accepting legacy null while exposing a Gemini-compatible string schema.
5295
5296
  (e) => e === null ? "remove" : e,
@@ -5361,12 +5362,12 @@ const qa = s.object({
5361
5362
  Ja
5362
5363
  );
5363
5364
  S !== void 0 && (b = { ...b, dueString: S });
5364
- const U = ct(
5365
+ const R = ct(
5365
5366
  $,
5366
5367
  Va,
5367
5368
  null
5368
5369
  );
5369
- if (U !== void 0 && (b = { ...b, deadlineDate: U }), h)
5370
+ if (R !== void 0 && (b = { ...b, deadlineDate: R }), h)
5370
5371
  try {
5371
5372
  const { minutes: v } = ft(h);
5372
5373
  b = {
@@ -5400,7 +5401,7 @@ const qa = s.object({
5400
5401
  return Object.keys(b).length > 0 ? await t.updateTask(d, b) : j;
5401
5402
  }), n = (await Promise.all(o)).filter(
5402
5403
  (c) => c !== void 0
5403
- ), a = n.map(R);
5404
+ ), a = n.map(_);
5404
5405
  return {
5405
5406
  textContent: ei({
5406
5407
  tasks: a,
@@ -5482,11 +5483,11 @@ function di(e) {
5482
5483
  return !1;
5483
5484
  }
5484
5485
  }
5485
- function Ut(e) {
5486
+ function Rt(e) {
5486
5487
  return di(e) ? e : "UTC";
5487
5488
  }
5488
5489
  function li(e, t) {
5489
- const r = Ut(t);
5490
+ const r = Rt(t);
5490
5491
  return e.toLocaleString("en-US", {
5491
5492
  timeZone: r,
5492
5493
  year: "numeric",
@@ -5499,7 +5500,7 @@ function li(e, t) {
5499
5500
  });
5500
5501
  }
5501
5502
  async function ui(e) {
5502
- const t = await e.getUser(), r = t.tzInfo?.timezone ?? "UTC", o = Ut(r), n = /* @__PURE__ */ new Date(), a = li(n, o), i = t.startDay ?? 1, c = ci(i), d = oi(t), l = new Date(n.toLocaleString("en-US", { timeZone: o })), u = ni(l, i), p = ai(u), m = ii(l), g = [
5503
+ const t = await e.getUser(), r = t.tzInfo?.timezone ?? "UTC", o = Rt(r), n = /* @__PURE__ */ new Date(), a = li(n, o), i = t.startDay ?? 1, c = ci(i), d = oi(t), l = new Date(n.toLocaleString("en-US", { timeZone: o })), u = ni(l, i), p = ai(u), m = ii(l), g = [
5503
5504
  "# User Information",
5504
5505
  "",
5505
5506
  `**User ID:** ${t.id}`,
@@ -5773,7 +5774,7 @@ You have access to comprehensive Todoist management tools for personal productiv
5773
5774
 
5774
5775
  Always provide clear, actionable task titles and descriptions. Use the overview tools to give users context about their workload and project status.
5775
5776
  `;
5776
- function Ui({
5777
+ function Ri({
5777
5778
  todoistApiKey: e,
5778
5779
  baseUrl: t,
5779
5780
  features: r = []
@@ -5788,16 +5789,16 @@ function Ui({
5788
5789
  instructions: vi
5789
5790
  }
5790
5791
  ), n = new Ft(e, { baseUrl: t }), a = {
5791
- ...ln,
5792
+ ...sn,
5792
5793
  _meta: {
5793
5794
  ui: {
5794
- resourceUri: xe
5795
+ resourceUri: Ae
5795
5796
  }
5796
5797
  }
5797
5798
  };
5798
5799
  ts(o);
5799
5800
  const i = { server: o, client: n, features: r };
5800
- return k({ tool: zr, ...i }), k({ tool: Qr, ...i }), k({ tool: ba, ...i }), k({ tool: Qa, ...i }), k({ tool: da, ...i }), k({ tool: nn, ...i }), k({ tool: a, ...i }), k({ tool: xo, ...i }), k({ tool: Ir, ...i }), k({ tool: Oa, ...i }), k({ tool: Bo, ...i }), k({ tool: Qn, ...i }), k({ tool: sa, ...i }), k({ tool: Ur, ...i }), k({ tool: Ya, ...i }), k({ tool: Zo, ...i }), k({ tool: tr, ...i }), k({ tool: To, ...i }), k({ tool: wa, ...i }), k({ tool: Ar, ...i }), k({ tool: qo, ...i }), k({ tool: Ha, ...i }), k({ tool: Ii, ...i }), k({ tool: hr, ...i }), k({ tool: Po, ...i }), k({ tool: nr, ...i }), k({ tool: lr, ...i }), k({ tool: Ca, ...i }), k({ tool: mo, ...i }), k({ tool: vn, ...i }), k({ tool: Un, ...i }), k({ tool: Dn, ...i }), k({ tool: Jr, ...i }), k({ tool: Mn, ...i }), k({ tool: Tn, ...i }), k({ tool: ro, ...i }), k({ tool: lo, ...i }), k({ tool: na, ...i }), k({ tool: pi, ...i }), k({ tool: Lo, ...i }), k({ tool: Jn, ...i }), k({ tool: zn, ...i }), k({ tool: ma, ...i }), k({ tool: ao, ...i }), o.registerPrompt(
5801
+ return k({ tool: zr, ...i }), k({ tool: Qr, ...i }), k({ tool: ba, ...i }), k({ tool: Qa, ...i }), k({ tool: da, ...i }), k({ tool: ln, ...i }), k({ tool: a, ...i }), k({ tool: xo, ...i }), k({ tool: Ir, ...i }), k({ tool: Oa, ...i }), k({ tool: Bo, ...i }), k({ tool: Qn, ...i }), k({ tool: sa, ...i }), k({ tool: Rr, ...i }), k({ tool: Ya, ...i }), k({ tool: Zo, ...i }), k({ tool: tr, ...i }), k({ tool: To, ...i }), k({ tool: wa, ...i }), k({ tool: Ar, ...i }), k({ tool: qo, ...i }), k({ tool: Ha, ...i }), k({ tool: Ii, ...i }), k({ tool: hr, ...i }), k({ tool: Po, ...i }), k({ tool: nr, ...i }), k({ tool: lr, ...i }), k({ tool: Ca, ...i }), k({ tool: mo, ...i }), k({ tool: vn, ...i }), k({ tool: Rn, ...i }), k({ tool: Dn, ...i }), k({ tool: Jr, ...i }), k({ tool: Mn, ...i }), k({ tool: Tn, ...i }), k({ tool: ro, ...i }), k({ tool: ao, ...i }), k({ tool: na, ...i }), k({ tool: pi, ...i }), k({ tool: Lo, ...i }), k({ tool: Jn, ...i }), k({ tool: zn, ...i }), k({ tool: ma, ...i }), k({ tool: lo, ...i }), o.registerPrompt(
5801
5802
  ie.name,
5802
5803
  {
5803
5804
  title: ie.title,
@@ -5809,28 +5810,28 @@ function Ui({
5809
5810
  }
5810
5811
  export {
5811
5812
  Ya as A,
5812
- Ur as B,
5813
+ Rr as B,
5813
5814
  Bo as C,
5814
5815
  Oa as D,
5815
5816
  Ir as E,
5816
5817
  da as F,
5817
5818
  xo as G,
5818
- ln as H,
5819
- nn as I,
5819
+ sn as H,
5820
+ ln as I,
5820
5821
  Qa as J,
5821
5822
  ba as K,
5822
5823
  Qr as L,
5823
5824
  zr as M,
5824
- Ri as N,
5825
+ _i as N,
5825
5826
  Lo as a,
5826
5827
  Tn as b,
5827
5828
  Mn as c,
5828
5829
  ro as d,
5829
5830
  Jr as e,
5830
- ao as f,
5831
- Ui as g,
5831
+ lo as f,
5832
+ Ri as g,
5832
5833
  Dn as h,
5833
- Un as i,
5834
+ Rn as i,
5834
5835
  vn as j,
5835
5836
  mo as k,
5836
5837
  zn as l,