contextforge-mcp 0.1.55 → 0.1.57

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 CHANGED
@@ -71,14 +71,14 @@ function logTool(toolName, details) {
71
71
  memory_link_project: "šŸ”—",
72
72
  memory_unlink_project: "šŸ”“",
73
73
  memory_current_project: "šŸ“",
74
- issues_list: "šŸ“‹",
75
- issues_start: "ā–¶ļø",
76
- issues_resolve: "āœ…",
77
- issues_what_next: "šŸŽÆ",
78
- issues_create: "āž•",
79
- issues_assign: "šŸ‘¤",
80
- issues_resolve_by_name: "āœ…",
81
- issues_delete: "šŸ—‘ļø",
74
+ tasks_list: "šŸ“‹",
75
+ tasks_start: "ā–¶ļø",
76
+ tasks_resolve: "āœ…",
77
+ tasks_what_next: "šŸŽÆ",
78
+ tasks_create: "āž•",
79
+ tasks_assign: "šŸ‘¤",
80
+ tasks_resolve_by_name: "āœ…",
81
+ tasks_delete: "šŸ—‘ļø",
82
82
  collaborators_list: "šŸ‘„",
83
83
  project_share: "šŸ”—",
84
84
  };
@@ -912,10 +912,10 @@ const TOOLS = [
912
912
  required: [],
913
913
  },
914
914
  },
915
- // ============ Issues (Task Management) ============
915
+ // ============ Tasks (Task Management) ============
916
916
  {
917
- name: "issues_list",
918
- description: 'List issues assigned to you. Shows pending issues by default. Use status "all" to see everything, or "resolved" for completed issues.',
917
+ name: "tasks_list",
918
+ description: 'List tasks assigned to you. Shows pending tasks by default. Use status "all" to see everything, or "resolved" for completed tasks.',
919
919
  inputSchema: {
920
920
  type: "object",
921
921
  properties: {
@@ -931,75 +931,75 @@ const TOOLS = [
931
931
  scope: {
932
932
  type: "string",
933
933
  enum: ["mine", "all"],
934
- description: '"mine" shows only issues assigned to or created by you (default), "all" shows all issues in your organization/shared projects',
934
+ description: '"mine" shows only tasks assigned to or created by you (default), "all" shows all tasks in your organization/shared projects',
935
935
  },
936
936
  limit: {
937
937
  type: "number",
938
- description: "Maximum number of issues (1-100, default: 20)",
938
+ description: "Maximum number of tasks (1-100, default: 20)",
939
939
  },
940
940
  },
941
941
  required: [],
942
942
  },
943
943
  },
944
944
  {
945
- name: "issues_start",
946
- description: 'Mark an issue as "in_progress". Use this when you start working on an issue.',
945
+ name: "tasks_start",
946
+ description: 'Mark a task as "in_progress". Use this when you start working on a task.',
947
947
  inputSchema: {
948
948
  type: "object",
949
949
  properties: {
950
950
  issue_id: {
951
951
  type: "string",
952
- description: "Issue UUID to start working on",
952
+ description: "Task UUID to start working on",
953
953
  },
954
954
  },
955
955
  required: ["issue_id"],
956
956
  },
957
957
  },
958
958
  {
959
- name: "issues_resolve",
960
- description: 'Mark an issue as "resolved". Use this when you finish working on an issue.',
959
+ name: "tasks_resolve",
960
+ description: 'Mark a task as "resolved". Use this when you finish working on a task.',
961
961
  inputSchema: {
962
962
  type: "object",
963
963
  properties: {
964
964
  issue_id: {
965
965
  type: "string",
966
- description: "Issue UUID to mark as resolved",
966
+ description: "Task UUID to mark as resolved",
967
967
  },
968
968
  },
969
969
  required: ["issue_id"],
970
970
  },
971
971
  },
972
972
  {
973
- name: "issues_what_next",
974
- description: "Get a recommendation of what issue to work on next, based on priority and due dates. Use this when you want to know what task to focus on.",
973
+ name: "tasks_what_next",
974
+ description: "Get a recommendation of what task to work on next, based on priority and due dates. Use this when you want to know what task to focus on.",
975
975
  inputSchema: {
976
976
  type: "object",
977
977
  properties: {},
978
978
  required: [],
979
979
  },
980
980
  },
981
- // ============ Issues - Create & Assign ============
981
+ // ============ Tasks - Create & Assign ============
982
982
  {
983
- name: "issues_create",
984
- description: "Create a new issue in a project. Optionally assign it to a collaborator by their email.",
983
+ name: "tasks_create",
984
+ description: "Create a new task in a project. Optionally assign it to a collaborator by their email.",
985
985
  inputSchema: {
986
986
  type: "object",
987
987
  properties: {
988
988
  title: {
989
989
  type: "string",
990
- description: "Title of the issue",
990
+ description: "Title of the task",
991
991
  },
992
992
  description: {
993
993
  type: "string",
994
- description: "Detailed description of the issue (optional)",
994
+ description: "Detailed description of the task (optional)",
995
995
  },
996
996
  project_id: {
997
997
  type: "string",
998
- description: "Project UUID to create the issue in",
998
+ description: "Project UUID to create the task in",
999
999
  },
1000
1000
  project_name: {
1001
1001
  type: "string",
1002
- description: "Project name to create the issue in (alternative to project_id)",
1002
+ description: "Project name to create the task in (alternative to project_id)",
1003
1003
  },
1004
1004
  priority: {
1005
1005
  type: "string",
@@ -1008,7 +1008,7 @@ const TOOLS = [
1008
1008
  },
1009
1009
  assignee_email: {
1010
1010
  type: "string",
1011
- description: "Email of a collaborator to assign this issue to (optional)",
1011
+ description: "Email of a collaborator to assign this task to (optional)",
1012
1012
  },
1013
1013
  due_date: {
1014
1014
  type: "string",
@@ -1019,59 +1019,112 @@ const TOOLS = [
1019
1019
  items: { type: "string" },
1020
1020
  description: "Tags for categorization (optional)",
1021
1021
  },
1022
+ space_id: {
1023
+ type: "string",
1024
+ description: "Space UUID to link this task to (optional)",
1025
+ },
1022
1026
  },
1023
1027
  required: ["title"],
1024
1028
  },
1025
1029
  },
1026
1030
  {
1027
- name: "issues_assign",
1028
- description: "Assign an issue to a collaborator by their email address.",
1031
+ name: "tasks_update",
1032
+ description: "Update a task's title, description, status, priority, tags, due date, or assignee. Provide issue_id or short_id to identify the task, plus one or more fields to update.",
1033
+ inputSchema: {
1034
+ type: "object",
1035
+ properties: {
1036
+ issue_id: {
1037
+ type: "string",
1038
+ description: "Task UUID (optional if short_id is provided)",
1039
+ },
1040
+ short_id: {
1041
+ type: "string",
1042
+ description: 'Short ID of the task (e.g., "4w3123") - alternative to issue_id',
1043
+ },
1044
+ title: {
1045
+ type: "string",
1046
+ description: "New title for the task",
1047
+ },
1048
+ description: {
1049
+ type: "string",
1050
+ description: "New description for the task",
1051
+ },
1052
+ status: {
1053
+ type: "string",
1054
+ enum: ["pending", "in_progress", "resolved"],
1055
+ description: "New status for the task",
1056
+ },
1057
+ priority: {
1058
+ type: "string",
1059
+ enum: ["low", "medium", "high", "urgent"],
1060
+ description: "New priority level",
1061
+ },
1062
+ tags: {
1063
+ type: "array",
1064
+ items: { type: "string" },
1065
+ description: "New tags (replaces existing tags)",
1066
+ },
1067
+ due_date: {
1068
+ type: "string",
1069
+ description: "New due date in ISO format, or null to clear",
1070
+ },
1071
+ assignee_email: {
1072
+ type: "string",
1073
+ description: "Email of a collaborator to assign this task to",
1074
+ },
1075
+ },
1076
+ required: [],
1077
+ },
1078
+ },
1079
+ {
1080
+ name: "tasks_assign",
1081
+ description: "Assign a task to a collaborator by their email address.",
1029
1082
  inputSchema: {
1030
1083
  type: "object",
1031
1084
  properties: {
1032
1085
  issue_id: {
1033
1086
  type: "string",
1034
- description: "Issue UUID to assign (optional if short_id or issue_title is provided)",
1087
+ description: "Task UUID to assign (optional if short_id or issue_title is provided)",
1035
1088
  },
1036
1089
  short_id: {
1037
1090
  type: "string",
1038
- description: 'Short ID of the issue (e.g., "4w3123") - easier to reference than full UUID',
1091
+ description: 'Short ID of the task (e.g., "4w3123") - easier to reference than full UUID',
1039
1092
  },
1040
1093
  issue_title: {
1041
1094
  type: "string",
1042
- description: "Issue title to search for (optional if issue_id or short_id is provided)",
1095
+ description: "Task title to search for (optional if issue_id or short_id is provided)",
1043
1096
  },
1044
1097
  assignee_email: {
1045
1098
  type: "string",
1046
- description: "Email of the collaborator to assign the issue to",
1099
+ description: "Email of the collaborator to assign the task to",
1047
1100
  },
1048
1101
  },
1049
1102
  required: ["assignee_email"],
1050
1103
  },
1051
1104
  },
1052
1105
  {
1053
- name: "issues_resolve_by_name",
1054
- description: "Resolve an issue by searching for it by title. Use this when you only know the issue name.",
1106
+ name: "tasks_resolve_by_name",
1107
+ description: "Resolve a task by searching for it by title. Use this when you only know the task name.",
1055
1108
  inputSchema: {
1056
1109
  type: "object",
1057
1110
  properties: {
1058
1111
  title: {
1059
1112
  type: "string",
1060
- description: "Issue title to search for (partial match)",
1113
+ description: "Task title to search for (partial match)",
1061
1114
  },
1062
1115
  },
1063
1116
  required: ["title"],
1064
1117
  },
1065
1118
  },
1066
1119
  {
1067
- name: "issues_delete",
1068
- description: "Delete an issue by ID or short_id. This performs a soft delete (sets deleted_at timestamp).",
1120
+ name: "tasks_delete",
1121
+ description: "Delete a task by ID or short_id. This performs a soft delete (sets deleted_at timestamp).",
1069
1122
  inputSchema: {
1070
1123
  type: "object",
1071
1124
  properties: {
1072
1125
  issue_id: {
1073
1126
  type: "string",
1074
- description: "Issue UUID or short_id (6 alphanumeric characters)",
1127
+ description: "Task UUID or short_id (6 alphanumeric characters)",
1075
1128
  },
1076
1129
  },
1077
1130
  required: ["issue_id"],
@@ -1080,7 +1133,7 @@ const TOOLS = [
1080
1133
  // ============ Collaborators ============
1081
1134
  {
1082
1135
  name: "collaborators_list",
1083
- description: "List collaborators on a shared project. Shows who has access and what issues are assigned to them.",
1136
+ description: "List collaborators on a shared project. Shows who has access and what tasks are assigned to them.",
1084
1137
  inputSchema: {
1085
1138
  type: "object",
1086
1139
  properties: {
@@ -2080,21 +2133,21 @@ async function main() {
2080
2133
  ],
2081
2134
  };
2082
2135
  }
2083
- // ============ Issues (Task Management) ============
2084
- case "issues_list": {
2136
+ // ============ Tasks (Task Management) ============
2137
+ case "tasks_list": {
2085
2138
  const status = args?.status; // API defaults to 'pending' if not specified
2086
2139
  const projectId = args?.project_id;
2087
2140
  const scope = args?.scope || "mine";
2088
2141
  const limit = args?.limit || 20;
2089
- logTool(name, scope === "all" ? "all issues" : status || "pending");
2090
- const result = await apiClient.listIssues({
2142
+ logTool(name, scope === "all" ? "all tasks" : status || "pending");
2143
+ const result = await apiClient.listTasks({
2091
2144
  status,
2092
2145
  project_id: projectId,
2093
2146
  scope,
2094
2147
  limit,
2095
2148
  });
2096
2149
  const elapsed = Date.now() - startTime;
2097
- logSuccess(`Found ${result.issues?.length || 0} issue(s) in ${elapsed}ms`);
2150
+ logSuccess(`Found ${result.issues?.length || 0} task(s) in ${elapsed}ms`);
2098
2151
  const issues = result.issues || [];
2099
2152
  const issueCount = issues.length;
2100
2153
  if (issueCount === 0) {
@@ -2102,11 +2155,16 @@ async function main() {
2102
2155
  content: [
2103
2156
  {
2104
2157
  type: "text",
2105
- text: "šŸ“‹ No issues found",
2158
+ text: "šŸ“‹ No tasks found",
2106
2159
  },
2107
2160
  ],
2108
2161
  };
2109
2162
  }
2163
+ // Derive dashboard base URL from API URL
2164
+ const apiUrl = process.env.CONTEXTFORGE_API_URL || "";
2165
+ const dashboardBaseUrl = apiUrl.includes("localhost") || apiUrl.includes("127.0.0.1")
2166
+ ? "http://localhost:3001"
2167
+ : "https://contextforge.dev";
2110
2168
  // Format each issue as a readable line
2111
2169
  const issueLines = issues.map((i) => {
2112
2170
  const statusEmoji = i.status === "pending"
@@ -2127,9 +2185,10 @@ async function main() {
2127
2185
  const createdBy = i.created_by_email
2128
2186
  ? `\n āœļø Created by: ${i.created_by_email}`
2129
2187
  : "";
2130
- return `[${i.short_id}] ${i.title}\n ${statusEmoji} ${i.status} | ${priorityLabel} ${i.priority} | šŸ“ ${i.project?.name || "No project"}${resolvedBy}${createdBy}`;
2188
+ const taskUrl = `\n šŸ”— ${dashboardBaseUrl}/dashboard/tasks/${i.id}`;
2189
+ return `[${i.short_id}] ${i.title}\n ${statusEmoji} ${i.status} | ${priorityLabel} ${i.priority} | šŸ“ ${i.project?.name || "No project"}${resolvedBy}${createdBy}${taskUrl}`;
2131
2190
  });
2132
- const responseText = `šŸ“‹ Found ${issueCount} issue${issueCount === 1 ? "" : "s"}\n\n${issueLines.join("\n\n")}\n\nšŸ’” Use issues_start <issue_id> to begin working on an issue`;
2191
+ const responseText = `šŸ“‹ Found ${issueCount} task${issueCount === 1 ? "" : "s"}\n\n${issueLines.join("\n\n")}\n\nšŸ’” Use tasks_start <issue_id> to begin working on a task`;
2133
2192
  return {
2134
2193
  content: [
2135
2194
  {
@@ -2139,13 +2198,13 @@ async function main() {
2139
2198
  ],
2140
2199
  };
2141
2200
  }
2142
- case "issues_start": {
2201
+ case "tasks_start": {
2143
2202
  const issueId = args?.issue_id;
2144
2203
  if (!issueId) {
2145
2204
  throw new Error("issue_id is required");
2146
2205
  }
2147
2206
  logTool(name, issueId);
2148
- const result = await apiClient.updateIssueStatus(issueId, "in_progress");
2207
+ const result = await apiClient.updateTaskStatus(issueId, "in_progress");
2149
2208
  const elapsed = Date.now() - startTime;
2150
2209
  logSuccess(`Started working on "${result.issue?.title}" in ${elapsed}ms`);
2151
2210
  return {
@@ -2154,7 +2213,7 @@ async function main() {
2154
2213
  type: "text",
2155
2214
  text: formatResponse({
2156
2215
  message: `ā–¶ļø Now working on: ${result.issue?.title}`,
2157
- hint: "Use issues_resolve when you complete this issue",
2216
+ hint: "Use tasks_resolve when you complete this task",
2158
2217
  details: {
2159
2218
  id: result.issue?.id,
2160
2219
  description: result.issue?.description,
@@ -2164,13 +2223,13 @@ async function main() {
2164
2223
  ],
2165
2224
  };
2166
2225
  }
2167
- case "issues_resolve": {
2226
+ case "tasks_resolve": {
2168
2227
  const issueId = args?.issue_id;
2169
2228
  if (!issueId) {
2170
2229
  throw new Error("issue_id is required");
2171
2230
  }
2172
2231
  logTool(name, issueId);
2173
- const result = await apiClient.updateIssueStatus(issueId, "resolved");
2232
+ const result = await apiClient.updateTaskStatus(issueId, "resolved");
2174
2233
  const elapsed = Date.now() - startTime;
2175
2234
  logSuccess(`Resolved "${result.issue?.title}" in ${elapsed}ms`);
2176
2235
  return {
@@ -2178,29 +2237,29 @@ async function main() {
2178
2237
  {
2179
2238
  type: "text",
2180
2239
  text: formatResponse({
2181
- message: `āœ… Issue resolved: ${result.issue?.title}`,
2182
- hint: "Use issues_what_next to see your next task",
2240
+ message: `āœ… Task resolved: ${result.issue?.title}`,
2241
+ hint: "Use tasks_what_next to see your next task",
2183
2242
  }),
2184
2243
  },
2185
2244
  ],
2186
2245
  };
2187
2246
  }
2188
- case "issues_what_next": {
2247
+ case "tasks_what_next": {
2189
2248
  logTool(name);
2190
- const result = await apiClient.getNextIssue();
2249
+ const result = await apiClient.getNextTask();
2191
2250
  const elapsed = Date.now() - startTime;
2192
2251
  if (!result.issue) {
2193
- logInfo(`No pending issues in ${elapsed}ms`);
2252
+ logInfo(`No pending tasks in ${elapsed}ms`);
2194
2253
  return {
2195
2254
  content: [
2196
2255
  {
2197
2256
  type: "text",
2198
- text: "šŸŽ‰ No pending issues assigned to you. Great job!\n\nšŸ’” Check with your team lead for new tasks",
2257
+ text: "šŸŽ‰ No pending tasks assigned to you. Great job!\n\nšŸ’” Check with your team lead for new tasks",
2199
2258
  },
2200
2259
  ],
2201
2260
  };
2202
2261
  }
2203
- logSuccess(`Next issue: "${result.issue.title}" in ${elapsed}ms`);
2262
+ logSuccess(`Next task: "${result.issue.title}" in ${elapsed}ms`);
2204
2263
  const priorityEmoji = result.issue.priority === "urgent"
2205
2264
  ? "šŸ”“"
2206
2265
  : result.issue.priority === "high"
@@ -2218,12 +2277,12 @@ async function main() {
2218
2277
  content: [
2219
2278
  {
2220
2279
  type: "text",
2221
- text: `šŸŽÆ Next recommended issue:\n\n[${result.issue.short_id || result.issue.id.slice(0, 6)}] ${result.issue.title}\n${priorityEmoji} ${result.issue.priority} | šŸ“ ${result.issue.project?.name || "No project"}${dueDate}${desc}\n\nšŸ“Š ${result.pending_count || 0} pending issues remaining\n\nšŸ’” Use issues_start ${result.issue.id} to begin working`,
2280
+ text: `šŸŽÆ Next recommended task:\n\n[${result.issue.short_id || result.issue.id.slice(0, 6)}] ${result.issue.title}\n${priorityEmoji} ${result.issue.priority} | šŸ“ ${result.issue.project?.name || "No project"}${dueDate}${desc}\n\nšŸ“Š ${result.pending_count || 0} pending tasks remaining\n\nšŸ’” Use tasks_start ${result.issue.id} to begin working`,
2222
2281
  },
2223
2282
  ],
2224
2283
  };
2225
2284
  }
2226
- case "issues_create": {
2285
+ case "tasks_create": {
2227
2286
  const title = args?.title;
2228
2287
  const description = args?.description;
2229
2288
  const projectId = args?.project_id;
@@ -2232,11 +2291,12 @@ async function main() {
2232
2291
  const assigneeEmail = args?.assignee_email;
2233
2292
  const dueDate = args?.due_date;
2234
2293
  const tags = args?.tags;
2294
+ const spaceId = args?.space_id;
2235
2295
  if (!title) {
2236
2296
  throw new Error("title is required");
2237
2297
  }
2238
2298
  logTool(name, `"${title}"`);
2239
- const result = await apiClient.createIssue({
2299
+ const result = await apiClient.createTask({
2240
2300
  title,
2241
2301
  description,
2242
2302
  project_id: projectId,
@@ -2245,18 +2305,19 @@ async function main() {
2245
2305
  assignee_email: assigneeEmail,
2246
2306
  due_date: dueDate,
2247
2307
  tags,
2308
+ space_id: spaceId,
2248
2309
  });
2249
2310
  const elapsed = Date.now() - startTime;
2250
- logSuccess(`Created issue "${result.issue?.title}" in ${elapsed}ms`);
2311
+ logSuccess(`Created task "${result.issue?.title}" in ${elapsed}ms`);
2251
2312
  return {
2252
2313
  content: [
2253
2314
  {
2254
2315
  type: "text",
2255
2316
  text: formatResponse({
2256
- message: `āž• Issue created: [${result.issue?.short_id}] ${result.issue?.title}`,
2317
+ message: `āž• Task created: [${result.issue?.short_id}] ${result.issue?.title}`,
2257
2318
  hint: assigneeEmail
2258
2319
  ? `Assigned to ${assigneeEmail}`
2259
- : "Use issues_assign to assign this issue to a collaborator",
2320
+ : "Use tasks_assign to assign this task to a collaborator",
2260
2321
  details: {
2261
2322
  id: result.issue?.short_id,
2262
2323
  title: result.issue?.title,
@@ -2268,7 +2329,7 @@ async function main() {
2268
2329
  ],
2269
2330
  };
2270
2331
  }
2271
- case "issues_assign": {
2332
+ case "tasks_assign": {
2272
2333
  const issueId = args?.issue_id;
2273
2334
  const shortId = args?.short_id;
2274
2335
  const issueTitle = args?.issue_title;
@@ -2280,7 +2341,7 @@ async function main() {
2280
2341
  throw new Error("Either issue_id, short_id, or issue_title is required");
2281
2342
  }
2282
2343
  logTool(name, `→ ${assigneeEmail}`);
2283
- const result = await apiClient.assignIssue({
2344
+ const result = await apiClient.assignTask({
2284
2345
  issue_id: issueId,
2285
2346
  short_id: shortId,
2286
2347
  issue_title: issueTitle,
@@ -2292,18 +2353,18 @@ async function main() {
2292
2353
  content: [
2293
2354
  {
2294
2355
  type: "text",
2295
- text: `šŸ‘¤ Issue assigned!\n\n[${result.issue?.short_id || result.issue?.id?.slice(0, 6)}] ${result.issue?.title}\nšŸ“§ Assigned to: ${assigneeEmail}\n\nšŸ’” The collaborator can now see this issue with issues_list`,
2356
+ text: `šŸ‘¤ Task assigned!\n\n[${result.issue?.short_id || result.issue?.id?.slice(0, 6)}] ${result.issue?.title}\nšŸ“§ Assigned to: ${assigneeEmail}\n\nšŸ’” The collaborator can now see this task with tasks_list`,
2296
2357
  },
2297
2358
  ],
2298
2359
  };
2299
2360
  }
2300
- case "issues_resolve_by_name": {
2361
+ case "tasks_resolve_by_name": {
2301
2362
  const title = args?.title;
2302
2363
  if (!title) {
2303
2364
  throw new Error("title is required");
2304
2365
  }
2305
2366
  logTool(name, `"${title}"`);
2306
- const result = await apiClient.resolveIssueByName(title);
2367
+ const result = await apiClient.resolveTaskByName(title);
2307
2368
  const elapsed = Date.now() - startTime;
2308
2369
  logSuccess(`Resolved "${result.issue?.title}" in ${elapsed}ms`);
2309
2370
  return {
@@ -2311,29 +2372,81 @@ async function main() {
2311
2372
  {
2312
2373
  type: "text",
2313
2374
  text: formatResponse({
2314
- message: `āœ… Issue resolved: ${result.issue?.title}`,
2315
- hint: "Use issues_what_next to see your next task",
2375
+ message: `āœ… Task resolved: ${result.issue?.title}`,
2376
+ hint: "Use tasks_what_next to see your next task",
2316
2377
  }),
2317
2378
  },
2318
2379
  ],
2319
2380
  };
2320
2381
  }
2321
- case "issues_delete": {
2382
+ case "tasks_delete": {
2322
2383
  const issueId = args?.issue_id;
2323
2384
  if (!issueId) {
2324
2385
  throw new Error("issue_id is required");
2325
2386
  }
2326
2387
  logTool(name, issueId);
2327
- const result = await apiClient.deleteIssue(issueId);
2388
+ const result = await apiClient.deleteTask(issueId);
2389
+ const elapsed = Date.now() - startTime;
2390
+ logSuccess(`Deleted task "${result.title}" in ${elapsed}ms`);
2391
+ return {
2392
+ content: [
2393
+ {
2394
+ type: "text",
2395
+ text: formatResponse({
2396
+ message: `šŸ—‘ļø Task deleted: [${result.short_id}] ${result.title}`,
2397
+ hint: "The task has been soft-deleted and will no longer appear in listings",
2398
+ }),
2399
+ },
2400
+ ],
2401
+ };
2402
+ }
2403
+ case "tasks_update": {
2404
+ const issueId = args?.issue_id;
2405
+ const shortId = args?.short_id;
2406
+ if (!issueId && !shortId) {
2407
+ throw new Error("Either issue_id or short_id is required");
2408
+ }
2409
+ const updateFields = {};
2410
+ if (args?.title !== undefined)
2411
+ updateFields.title = args.title;
2412
+ if (args?.description !== undefined)
2413
+ updateFields.description = args.description;
2414
+ if (args?.status !== undefined)
2415
+ updateFields.status = args.status;
2416
+ if (args?.priority !== undefined)
2417
+ updateFields.priority = args.priority;
2418
+ if (args?.tags !== undefined)
2419
+ updateFields.tags = args.tags;
2420
+ if (args?.due_date !== undefined)
2421
+ updateFields.due_date = args.due_date;
2422
+ if (args?.assignee_email !== undefined)
2423
+ updateFields.assignee_email = args.assignee_email;
2424
+ if (Object.keys(updateFields).length === 0) {
2425
+ throw new Error("At least one field to update is required (title, description, status, priority, tags, due_date, assignee_email)");
2426
+ }
2427
+ logTool(name, shortId || issueId);
2428
+ const result = await apiClient.updateTask({
2429
+ issue_id: issueId,
2430
+ short_id: shortId,
2431
+ ...updateFields,
2432
+ });
2328
2433
  const elapsed = Date.now() - startTime;
2329
- logSuccess(`Deleted issue "${result.title}" in ${elapsed}ms`);
2434
+ const updatedFieldNames = Object.keys(updateFields).join(", ");
2435
+ logSuccess(`Updated task "${result.issue?.title}" (${updatedFieldNames}) in ${elapsed}ms`);
2330
2436
  return {
2331
2437
  content: [
2332
2438
  {
2333
2439
  type: "text",
2334
2440
  text: formatResponse({
2335
- message: `šŸ—‘ļø Issue deleted: [${result.short_id}] ${result.title}`,
2336
- hint: "The issue has been soft-deleted and will no longer appear in listings",
2441
+ message: `āœļø Task updated: [${result.issue?.short_id}] ${result.issue?.title}`,
2442
+ hint: `Updated fields: ${updatedFieldNames}`,
2443
+ details: {
2444
+ id: result.issue?.short_id,
2445
+ title: result.issue?.title,
2446
+ status: result.issue?.status,
2447
+ priority: result.issue?.priority,
2448
+ project: result.issue?.project?.name,
2449
+ },
2337
2450
  }),
2338
2451
  },
2339
2452
  ],
@@ -2362,14 +2475,14 @@ async function main() {
2362
2475
  };
2363
2476
  }
2364
2477
  const collabLines = collaborators.map((c) => {
2365
- const issueStats = `${c.issues_count || 0} issues (${c.issues_pending || 0} pending, ${c.issues_in_progress || 0} in progress)`;
2478
+ const issueStats = `${c.issues_count || 0} tasks (${c.issues_pending || 0} pending, ${c.issues_in_progress || 0} in progress)`;
2366
2479
  return `šŸ“§ ${c.email}\n šŸ“Š ${issueStats}`;
2367
2480
  });
2368
2481
  return {
2369
2482
  content: [
2370
2483
  {
2371
2484
  type: "text",
2372
- text: `šŸ‘„ ${collabCount} collaborator${collabCount === 1 ? "" : "s"} on "${result.project?.name || "this project"}"\n\n${collabLines.join("\n\n")}\n\nšŸ’” Use issues_create or issues_assign to assign tasks`,
2485
+ text: `šŸ‘„ ${collabCount} collaborator${collabCount === 1 ? "" : "s"} on "${result.project?.name || "this project"}"\n\n${collabLines.join("\n\n")}\n\nšŸ’” Use tasks_create or tasks_assign to assign tasks`,
2373
2486
  },
2374
2487
  ],
2375
2488
  };