roadmap-skill 0.2.0 → 0.2.4
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 +500 -369
- package/dist/index.js.map +1 -1
- package/dist/web/app/assets/main-DE1dRfHs.js +9 -0
- package/dist/web/app/index.html +38 -0
- package/dist/web/server.js +526 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -276,6 +276,9 @@ var ProjectStorage = class {
|
|
|
276
276
|
if (filters.searchText && !task.title.toLowerCase().includes(filters.searchText.toLowerCase()) && !task.description.toLowerCase().includes(filters.searchText.toLowerCase())) {
|
|
277
277
|
continue;
|
|
278
278
|
}
|
|
279
|
+
if (filters.includeCompleted === false && task.status === "done") {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
279
282
|
results.push({ task, project: data.project });
|
|
280
283
|
}
|
|
281
284
|
} catch {
|
|
@@ -284,6 +287,58 @@ var ProjectStorage = class {
|
|
|
284
287
|
}
|
|
285
288
|
return results;
|
|
286
289
|
}
|
|
290
|
+
async exportAllData() {
|
|
291
|
+
await this.ensureDirectory();
|
|
292
|
+
const fs3 = await import("fs/promises");
|
|
293
|
+
const files = await fs3.readdir(this.storageDir);
|
|
294
|
+
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
295
|
+
const projects = [];
|
|
296
|
+
for (const file of jsonFiles) {
|
|
297
|
+
try {
|
|
298
|
+
const filePath = path3.join(this.storageDir, file);
|
|
299
|
+
const data = await readJsonFile(filePath);
|
|
300
|
+
projects.push(data);
|
|
301
|
+
} catch {
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
version: 1,
|
|
307
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
308
|
+
projects
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
async importAllData(data) {
|
|
312
|
+
await this.ensureDirectory();
|
|
313
|
+
let imported = 0;
|
|
314
|
+
let errors = 0;
|
|
315
|
+
const errorDetails = [];
|
|
316
|
+
if (!data.projects || !Array.isArray(data.projects)) {
|
|
317
|
+
throw new Error("Invalid backup data: projects array is required");
|
|
318
|
+
}
|
|
319
|
+
for (const projectData of data.projects) {
|
|
320
|
+
try {
|
|
321
|
+
if (!projectData.project || !projectData.project.id) {
|
|
322
|
+
errors++;
|
|
323
|
+
errorDetails.push("Skipping invalid project: missing project or id");
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const filePath = this.getFilePath(projectData.project.id);
|
|
327
|
+
await writeJsonFile(filePath, projectData);
|
|
328
|
+
imported++;
|
|
329
|
+
} catch (error) {
|
|
330
|
+
errors++;
|
|
331
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
332
|
+
errorDetails.push(`Failed to import project ${projectData.project?.id || "unknown"}: ${errorMessage}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
success: errors === 0,
|
|
337
|
+
imported,
|
|
338
|
+
errors,
|
|
339
|
+
errorDetails
|
|
340
|
+
};
|
|
341
|
+
}
|
|
287
342
|
};
|
|
288
343
|
var storage = new ProjectStorage();
|
|
289
344
|
|
|
@@ -508,7 +563,8 @@ var listTasksTool = {
|
|
|
508
563
|
tags: z2.array(z2.string()).optional(),
|
|
509
564
|
assignee: z2.string().optional(),
|
|
510
565
|
dueBefore: z2.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
|
511
|
-
dueAfter: z2.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
|
|
566
|
+
dueAfter: z2.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
|
|
567
|
+
includeCompleted: z2.boolean().optional()
|
|
512
568
|
}),
|
|
513
569
|
async execute(input) {
|
|
514
570
|
try {
|
|
@@ -519,7 +575,8 @@ var listTasksTool = {
|
|
|
519
575
|
tags: input.tags,
|
|
520
576
|
assignee: input.assignee,
|
|
521
577
|
dueBefore: input.dueBefore,
|
|
522
|
-
dueAfter: input.dueAfter
|
|
578
|
+
dueAfter: input.dueAfter,
|
|
579
|
+
includeCompleted: input.includeCompleted
|
|
523
580
|
});
|
|
524
581
|
return {
|
|
525
582
|
success: true,
|
|
@@ -1020,170 +1077,227 @@ init_esm_shims();
|
|
|
1020
1077
|
import express from "express";
|
|
1021
1078
|
import * as path4 from "path";
|
|
1022
1079
|
function createServer(port = 7860) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
});
|
|
1033
|
-
app.get("/api/projects/:id", async (req, res) => {
|
|
1034
|
-
try {
|
|
1035
|
-
const project = await storage.readProject(req.params.id);
|
|
1036
|
-
if (!project) {
|
|
1037
|
-
res.status(404).json({ error: "Project not found" });
|
|
1038
|
-
return;
|
|
1080
|
+
return new Promise((resolve, reject) => {
|
|
1081
|
+
const app = express();
|
|
1082
|
+
app.use(express.json());
|
|
1083
|
+
app.get("/api/projects", async (_req, res) => {
|
|
1084
|
+
try {
|
|
1085
|
+
const projects = await storage.listProjects();
|
|
1086
|
+
res.json(projects);
|
|
1087
|
+
} catch (error) {
|
|
1088
|
+
res.status(500).json({ error: error.message });
|
|
1039
1089
|
}
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
res.status(500).json({ error: error.message });
|
|
1052
|
-
}
|
|
1053
|
-
});
|
|
1054
|
-
app.post("/api/projects", async (req, res) => {
|
|
1055
|
-
try {
|
|
1056
|
-
const project = await storage.createProject(req.body);
|
|
1057
|
-
res.json({ success: true, data: project });
|
|
1058
|
-
} catch (error) {
|
|
1059
|
-
res.status(500).json({ error: error.message });
|
|
1060
|
-
}
|
|
1061
|
-
});
|
|
1062
|
-
app.put("/api/projects", async (req, res) => {
|
|
1063
|
-
try {
|
|
1064
|
-
const { projectId, ...updateData } = req.body;
|
|
1065
|
-
const project = await storage.updateProject(projectId, updateData);
|
|
1066
|
-
res.json({ success: true, data: project });
|
|
1067
|
-
} catch (error) {
|
|
1068
|
-
res.status(500).json({ error: error.message });
|
|
1069
|
-
}
|
|
1070
|
-
});
|
|
1071
|
-
app.delete("/api/projects", async (req, res) => {
|
|
1072
|
-
try {
|
|
1073
|
-
const { projectId } = req.query;
|
|
1074
|
-
await storage.deleteProject(projectId);
|
|
1075
|
-
res.json({ success: true });
|
|
1076
|
-
} catch (error) {
|
|
1077
|
-
res.status(500).json({ error: error.message });
|
|
1078
|
-
}
|
|
1079
|
-
});
|
|
1080
|
-
app.post("/api/tasks", async (req, res) => {
|
|
1081
|
-
try {
|
|
1082
|
-
const { projectId, ...taskData } = req.body;
|
|
1083
|
-
const projectData = await storage.readProject(projectId);
|
|
1084
|
-
if (!projectData) {
|
|
1085
|
-
res.status(404).json({ error: "Project not found" });
|
|
1086
|
-
return;
|
|
1090
|
+
});
|
|
1091
|
+
app.get("/api/projects/:id", async (req, res) => {
|
|
1092
|
+
try {
|
|
1093
|
+
const project = await storage.readProject(req.params.id);
|
|
1094
|
+
if (!project) {
|
|
1095
|
+
res.status(404).json({ error: "Project not found" });
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
res.json(project);
|
|
1099
|
+
} catch (error) {
|
|
1100
|
+
res.status(500).json({ error: error.message });
|
|
1087
1101
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
updatedAt: now,
|
|
1100
|
-
completedAt: null
|
|
1101
|
-
};
|
|
1102
|
-
projectData.tasks.push(task);
|
|
1103
|
-
projectData.project.updatedAt = now;
|
|
1104
|
-
const filePath = storage.getFilePath(projectId);
|
|
1105
|
-
const { writeJsonFile: writeJsonFile2 } = await Promise.resolve().then(() => (init_file_helpers(), file_helpers_exports));
|
|
1106
|
-
await writeJsonFile2(filePath, projectData);
|
|
1107
|
-
res.json({ success: true, data: task });
|
|
1108
|
-
} catch (error) {
|
|
1109
|
-
res.status(500).json({ error: error.message });
|
|
1110
|
-
}
|
|
1111
|
-
});
|
|
1112
|
-
app.put("/api/tasks", async (req, res) => {
|
|
1113
|
-
try {
|
|
1114
|
-
const { projectId, taskId, ...updateData } = req.body;
|
|
1115
|
-
const projectData = await storage.readProject(projectId);
|
|
1116
|
-
if (!projectData) {
|
|
1117
|
-
res.status(404).json({ error: "Project not found" });
|
|
1118
|
-
return;
|
|
1102
|
+
});
|
|
1103
|
+
app.get("/api/tasks", async (req, res) => {
|
|
1104
|
+
try {
|
|
1105
|
+
const filters = { ...req.query };
|
|
1106
|
+
if (filters.includeCompleted !== void 0) {
|
|
1107
|
+
filters.includeCompleted = filters.includeCompleted === "true";
|
|
1108
|
+
}
|
|
1109
|
+
const tasks = await storage.searchTasks(filters);
|
|
1110
|
+
res.json(tasks);
|
|
1111
|
+
} catch (error) {
|
|
1112
|
+
res.status(500).json({ error: error.message });
|
|
1119
1113
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1114
|
+
});
|
|
1115
|
+
app.post("/api/projects", async (req, res) => {
|
|
1116
|
+
try {
|
|
1117
|
+
const project = await storage.createProject(req.body);
|
|
1118
|
+
res.json({ success: true, data: project });
|
|
1119
|
+
} catch (error) {
|
|
1120
|
+
res.status(500).json({ error: error.message });
|
|
1124
1121
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
...
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1122
|
+
});
|
|
1123
|
+
app.put("/api/projects", async (req, res) => {
|
|
1124
|
+
try {
|
|
1125
|
+
const { projectId, ...updateData } = req.body;
|
|
1126
|
+
const project = await storage.updateProject(projectId, updateData);
|
|
1127
|
+
res.json({ success: true, data: project });
|
|
1128
|
+
} catch (error) {
|
|
1129
|
+
res.status(500).json({ error: error.message });
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
app.delete("/api/projects", async (req, res) => {
|
|
1133
|
+
try {
|
|
1134
|
+
const { projectId } = req.query;
|
|
1135
|
+
await storage.deleteProject(projectId);
|
|
1136
|
+
res.json({ success: true });
|
|
1137
|
+
} catch (error) {
|
|
1138
|
+
res.status(500).json({ error: error.message });
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
app.post("/api/tasks", async (req, res) => {
|
|
1142
|
+
try {
|
|
1143
|
+
const { projectId, ...taskData } = req.body;
|
|
1144
|
+
const projectData = await storage.readProject(projectId);
|
|
1145
|
+
if (!projectData) {
|
|
1146
|
+
res.status(404).json({ error: "Project not found" });
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1150
|
+
const task = {
|
|
1151
|
+
id: `task_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
|
|
1152
|
+
projectId,
|
|
1153
|
+
...taskData,
|
|
1154
|
+
status: taskData.status || "todo",
|
|
1155
|
+
priority: taskData.priority || "medium",
|
|
1156
|
+
tags: taskData.tags || [],
|
|
1157
|
+
dueDate: taskData.dueDate || null,
|
|
1158
|
+
assignee: taskData.assignee || null,
|
|
1159
|
+
createdAt: now,
|
|
1160
|
+
updatedAt: now,
|
|
1161
|
+
completedAt: null
|
|
1162
|
+
};
|
|
1163
|
+
projectData.tasks.push(task);
|
|
1164
|
+
projectData.project.updatedAt = now;
|
|
1165
|
+
const filePath = storage.getFilePath(projectId);
|
|
1166
|
+
const { writeJsonFile: writeJsonFile2 } = await Promise.resolve().then(() => (init_file_helpers(), file_helpers_exports));
|
|
1167
|
+
await writeJsonFile2(filePath, projectData);
|
|
1168
|
+
res.json({ success: true, data: task });
|
|
1169
|
+
} catch (error) {
|
|
1170
|
+
res.status(500).json({ error: error.message });
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
app.put("/api/tasks", async (req, res) => {
|
|
1174
|
+
try {
|
|
1175
|
+
const { projectId, taskId, ...updateData } = req.body;
|
|
1176
|
+
const projectData = await storage.readProject(projectId);
|
|
1177
|
+
if (!projectData) {
|
|
1178
|
+
res.status(404).json({ error: "Project not found" });
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);
|
|
1182
|
+
if (taskIndex === -1) {
|
|
1183
|
+
res.status(404).json({ error: "Task not found" });
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1186
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1187
|
+
const existingTask = projectData.tasks[taskIndex];
|
|
1188
|
+
const updatedTask = {
|
|
1189
|
+
...existingTask,
|
|
1190
|
+
...updateData,
|
|
1191
|
+
id: existingTask.id,
|
|
1192
|
+
projectId: existingTask.projectId,
|
|
1193
|
+
createdAt: existingTask.createdAt,
|
|
1194
|
+
updatedAt: now,
|
|
1195
|
+
completedAt: updateData.status === "done" && existingTask.status !== "done" ? now : updateData.status && updateData.status !== "done" ? null : existingTask.completedAt
|
|
1196
|
+
};
|
|
1197
|
+
projectData.tasks[taskIndex] = updatedTask;
|
|
1198
|
+
projectData.project.updatedAt = now;
|
|
1199
|
+
const filePath = storage.getFilePath(projectId);
|
|
1200
|
+
const { writeJsonFile: writeJsonFile2 } = await Promise.resolve().then(() => (init_file_helpers(), file_helpers_exports));
|
|
1201
|
+
await writeJsonFile2(filePath, projectData);
|
|
1202
|
+
res.json({ success: true, data: updatedTask });
|
|
1203
|
+
} catch (error) {
|
|
1204
|
+
res.status(500).json({ error: error.message });
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
app.delete("/api/tasks", async (req, res) => {
|
|
1208
|
+
try {
|
|
1209
|
+
const { projectId, taskId } = req.query;
|
|
1210
|
+
const projectData = await storage.readProject(projectId);
|
|
1211
|
+
if (!projectData) {
|
|
1212
|
+
res.status(404).json({ error: "Project not found" });
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
const taskIndex = projectData.tasks.findIndex((t) => t.id === taskId);
|
|
1216
|
+
if (taskIndex === -1) {
|
|
1217
|
+
res.status(404).json({ error: "Task not found" });
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
projectData.tasks.splice(taskIndex, 1);
|
|
1221
|
+
projectData.project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1222
|
+
const filePath = storage.getFilePath(projectId);
|
|
1223
|
+
const { writeJsonFile: writeJsonFile2 } = await Promise.resolve().then(() => (init_file_helpers(), file_helpers_exports));
|
|
1224
|
+
await writeJsonFile2(filePath, projectData);
|
|
1225
|
+
res.json({ success: true });
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
res.status(500).json({ error: error.message });
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
app.get("/api/backup", async (_req, res) => {
|
|
1231
|
+
try {
|
|
1232
|
+
const backup = await storage.exportAllData();
|
|
1233
|
+
const filename = `roadmap-skill-backup-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.json`;
|
|
1234
|
+
res.setHeader("Content-Type", "application/json");
|
|
1235
|
+
res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
|
|
1236
|
+
res.json(backup);
|
|
1237
|
+
} catch (error) {
|
|
1238
|
+
res.status(500).json({ error: error.message });
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
app.post("/api/backup", async (req, res) => {
|
|
1242
|
+
try {
|
|
1243
|
+
const result = await storage.importAllData(req.body);
|
|
1244
|
+
res.json(result);
|
|
1245
|
+
} catch (error) {
|
|
1246
|
+
res.status(400).json({
|
|
1247
|
+
success: false,
|
|
1248
|
+
error: error.message
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
const distPath = path4.join(process.cwd(), "dist", "web", "app");
|
|
1253
|
+
app.use(express.static(distPath));
|
|
1254
|
+
app.get("*", (req, res) => {
|
|
1255
|
+
if (req.path.startsWith("/api")) {
|
|
1256
|
+
res.status(404).json({ error: "API not found" });
|
|
1152
1257
|
return;
|
|
1153
1258
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1259
|
+
res.sendFile(path4.join(distPath, "index.html"));
|
|
1260
|
+
});
|
|
1261
|
+
const server = app.listen(port, "127.0.0.1");
|
|
1262
|
+
server.once("listening", () => {
|
|
1263
|
+
console.log(`Web interface server running at http://localhost:${port}`);
|
|
1264
|
+
resolve(server);
|
|
1265
|
+
});
|
|
1266
|
+
server.once("error", (error) => {
|
|
1267
|
+
if (error.code === "EADDRINUSE") {
|
|
1268
|
+
reject(new Error(`Port ${port} is already in use`));
|
|
1157
1269
|
return;
|
|
1158
1270
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
const filePath = storage.getFilePath(projectId);
|
|
1162
|
-
const { writeJsonFile: writeJsonFile2 } = await Promise.resolve().then(() => (init_file_helpers(), file_helpers_exports));
|
|
1163
|
-
await writeJsonFile2(filePath, projectData);
|
|
1164
|
-
res.json({ success: true });
|
|
1165
|
-
} catch (error) {
|
|
1166
|
-
res.status(500).json({ error: error.message });
|
|
1167
|
-
}
|
|
1168
|
-
});
|
|
1169
|
-
const distPath = path4.join(process.cwd(), "dist", "web", "app");
|
|
1170
|
-
app.use(express.static(distPath));
|
|
1171
|
-
app.get("*", (req, res) => {
|
|
1172
|
-
if (req.path.startsWith("/api")) {
|
|
1173
|
-
res.status(404).json({ error: "API not found" });
|
|
1174
|
-
return;
|
|
1175
|
-
}
|
|
1176
|
-
res.sendFile(path4.join(distPath, "index.html"));
|
|
1177
|
-
});
|
|
1178
|
-
const server = app.listen(port, "0.0.0.0", () => {
|
|
1179
|
-
console.log(`Web interface server running at http://0.0.0.0:${port}`);
|
|
1271
|
+
reject(error);
|
|
1272
|
+
});
|
|
1180
1273
|
});
|
|
1181
|
-
return server;
|
|
1182
1274
|
}
|
|
1183
1275
|
|
|
1184
1276
|
// src/tools/web-tools.ts
|
|
1185
1277
|
import open from "open";
|
|
1186
1278
|
var activeServer = null;
|
|
1279
|
+
var activePort = null;
|
|
1280
|
+
function getServerPort(server) {
|
|
1281
|
+
const address = server.address();
|
|
1282
|
+
if (address && typeof address === "object" && "port" in address) {
|
|
1283
|
+
return typeof address.port === "number" ? address.port : null;
|
|
1284
|
+
}
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1287
|
+
async function closeServer(server) {
|
|
1288
|
+
await new Promise((resolve, reject) => {
|
|
1289
|
+
server.close((error) => {
|
|
1290
|
+
if (error) {
|
|
1291
|
+
reject(error);
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
resolve();
|
|
1295
|
+
});
|
|
1296
|
+
const forceCloseServer = server;
|
|
1297
|
+
forceCloseServer.closeIdleConnections?.();
|
|
1298
|
+
forceCloseServer.closeAllConnections?.();
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1187
1301
|
async function openBrowser(url) {
|
|
1188
1302
|
try {
|
|
1189
1303
|
await open(url);
|
|
@@ -1204,20 +1318,34 @@ var openWebInterfaceTool = {
|
|
|
1204
1318
|
}
|
|
1205
1319
|
},
|
|
1206
1320
|
async execute(args) {
|
|
1321
|
+
const requestedPort = args.port || 7860;
|
|
1207
1322
|
if (activeServer) {
|
|
1323
|
+
const runningPort = getServerPort(activeServer) ?? activePort;
|
|
1324
|
+
if (runningPort !== requestedPort) {
|
|
1325
|
+
throw new Error(`Web interface is already running on port ${runningPort ?? "unknown"}. Please close it before opening a different port.`);
|
|
1326
|
+
}
|
|
1327
|
+
const url2 = `http://localhost:${runningPort ?? requestedPort}`;
|
|
1328
|
+
await openBrowser(url2);
|
|
1208
1329
|
return {
|
|
1209
1330
|
message: "Web interface is already running",
|
|
1210
|
-
url:
|
|
1331
|
+
url: url2
|
|
1211
1332
|
};
|
|
1212
1333
|
}
|
|
1213
|
-
const
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1334
|
+
const url = `http://localhost:${requestedPort}`;
|
|
1335
|
+
try {
|
|
1336
|
+
activeServer = await createServer(requestedPort);
|
|
1337
|
+
activePort = requestedPort;
|
|
1338
|
+
await openBrowser(url);
|
|
1339
|
+
return {
|
|
1340
|
+
message: "Web interface started successfully and opened in browser",
|
|
1341
|
+
url
|
|
1342
|
+
};
|
|
1343
|
+
} catch (error) {
|
|
1344
|
+
activeServer = null;
|
|
1345
|
+
activePort = null;
|
|
1346
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1347
|
+
throw new Error(`Failed to start web interface: ${errorMessage}`);
|
|
1348
|
+
}
|
|
1221
1349
|
}
|
|
1222
1350
|
};
|
|
1223
1351
|
var closeWebInterfaceTool = {
|
|
@@ -1231,12 +1359,15 @@ var closeWebInterfaceTool = {
|
|
|
1231
1359
|
if (!activeServer) {
|
|
1232
1360
|
return { message: "Web interface is not running" };
|
|
1233
1361
|
}
|
|
1234
|
-
|
|
1235
|
-
activeServer
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
}
|
|
1239
|
-
})
|
|
1362
|
+
try {
|
|
1363
|
+
await closeServer(activeServer);
|
|
1364
|
+
activeServer = null;
|
|
1365
|
+
activePort = null;
|
|
1366
|
+
return { message: "Web interface stopped" };
|
|
1367
|
+
} catch (error) {
|
|
1368
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1369
|
+
throw new Error(`Failed to stop web interface: ${errorMessage}`);
|
|
1370
|
+
}
|
|
1240
1371
|
}
|
|
1241
1372
|
};
|
|
1242
1373
|
|
|
@@ -1650,115 +1781,115 @@ init_esm_shims();
|
|
|
1650
1781
|
var projectPrompts = [
|
|
1651
1782
|
{
|
|
1652
1783
|
name: "recommendNextTasks",
|
|
1653
|
-
description: "
|
|
1784
|
+
description: "Intelligently recommend the next priority tasks based on urgency, due dates, and project status",
|
|
1654
1785
|
arguments: [
|
|
1655
1786
|
{
|
|
1656
1787
|
name: "projectId",
|
|
1657
|
-
description: "
|
|
1788
|
+
description: "Specific project ID (optional; if not provided, analyze all projects)",
|
|
1658
1789
|
required: false
|
|
1659
1790
|
},
|
|
1660
1791
|
{
|
|
1661
1792
|
name: "limit",
|
|
1662
|
-
description: "
|
|
1793
|
+
description: "Number of tasks to recommend (default: 3)",
|
|
1663
1794
|
required: false
|
|
1664
1795
|
}
|
|
1665
1796
|
]
|
|
1666
1797
|
},
|
|
1667
1798
|
{
|
|
1668
1799
|
name: "autoPrioritize",
|
|
1669
|
-
description: "
|
|
1800
|
+
description: "Automatically analyze tasks and intelligently adjust priorities, considering due dates, dependencies, and project importance",
|
|
1670
1801
|
arguments: [
|
|
1671
1802
|
{
|
|
1672
1803
|
name: "projectId",
|
|
1673
|
-
description: "
|
|
1804
|
+
description: "Specific project ID (optional; if not provided, analyze all projects)",
|
|
1674
1805
|
required: false
|
|
1675
1806
|
}
|
|
1676
1807
|
]
|
|
1677
1808
|
},
|
|
1678
1809
|
{
|
|
1679
1810
|
name: "enhanceTaskDetails",
|
|
1680
|
-
description: "
|
|
1811
|
+
description: "Intelligently enhance task details, including description, acceptance criteria, subtasks, and required resources",
|
|
1681
1812
|
arguments: [
|
|
1682
1813
|
{
|
|
1683
1814
|
name: "taskId",
|
|
1684
|
-
description: "
|
|
1815
|
+
description: "Task ID to be enhanced",
|
|
1685
1816
|
required: true
|
|
1686
1817
|
}
|
|
1687
1818
|
]
|
|
1688
1819
|
},
|
|
1689
1820
|
{
|
|
1690
1821
|
name: "quickCapture",
|
|
1691
|
-
description: "
|
|
1822
|
+
description: "Quickly capture ideas/tasks, auto-categorize and suggest priorities",
|
|
1692
1823
|
arguments: [
|
|
1693
1824
|
{
|
|
1694
1825
|
name: "idea",
|
|
1695
|
-
description: "
|
|
1826
|
+
description: "Idea or task description to be captured",
|
|
1696
1827
|
required: true
|
|
1697
1828
|
},
|
|
1698
1829
|
{
|
|
1699
1830
|
name: "projectId",
|
|
1700
|
-
description: "
|
|
1831
|
+
description: "Target project ID (optional)",
|
|
1701
1832
|
required: false
|
|
1702
1833
|
}
|
|
1703
1834
|
]
|
|
1704
1835
|
}
|
|
1705
1836
|
];
|
|
1706
1837
|
function getRecommendNextTasksPrompt(projectId, limit) {
|
|
1707
|
-
const context = projectId ?
|
|
1838
|
+
const context = projectId ? `Analyze tasks for project ${projectId}` : "Analyze tasks for all active projects";
|
|
1708
1839
|
const taskLimit = limit ? parseInt(limit, 10) : 3;
|
|
1709
1840
|
return {
|
|
1710
|
-
description: "
|
|
1841
|
+
description: "Intelligent Task Recommendation Assistant",
|
|
1711
1842
|
messages: [
|
|
1712
1843
|
{
|
|
1713
1844
|
role: "user",
|
|
1714
1845
|
content: {
|
|
1715
1846
|
type: "text",
|
|
1716
|
-
text: `${context}
|
|
1847
|
+
text: `${context}, please recommend the ${taskLimit} tasks I should prioritize next.
|
|
1717
1848
|
|
|
1718
|
-
##
|
|
1849
|
+
## Recommendation Logic (sorted by priority):
|
|
1719
1850
|
|
|
1720
|
-
### 1.
|
|
1721
|
-
-
|
|
1722
|
-
-
|
|
1851
|
+
### 1. Urgent and Important (Critical priority + Near due date)
|
|
1852
|
+
- Critical tasks due today or tomorrow
|
|
1853
|
+
- Overdue high-priority tasks
|
|
1723
1854
|
|
|
1724
|
-
### 2.
|
|
1725
|
-
-
|
|
1726
|
-
-
|
|
1855
|
+
### 2. High-Value Tasks (High priority + Clear due date)
|
|
1856
|
+
- High priority tasks due this week
|
|
1857
|
+
- Critical path tasks blocking other work
|
|
1727
1858
|
|
|
1728
|
-
### 3.
|
|
1729
|
-
-
|
|
1730
|
-
-
|
|
1859
|
+
### 3. Quick Wins (Medium priority + Short estimated time)
|
|
1860
|
+
- Medium tasks completable in 1-2 hours
|
|
1861
|
+
- Tasks that can significantly boost project progress
|
|
1731
1862
|
|
|
1732
|
-
### 4.
|
|
1733
|
-
-
|
|
1734
|
-
-
|
|
1863
|
+
### 4. Planned Work
|
|
1864
|
+
- Tasks marked "in-progress" but not yet completed
|
|
1865
|
+
- Normal priority tasks due soon
|
|
1735
1866
|
|
|
1736
|
-
##
|
|
1867
|
+
## Please perform the following steps:
|
|
1737
1868
|
|
|
1738
|
-
1.
|
|
1739
|
-
2.
|
|
1740
|
-
3.
|
|
1741
|
-
4.
|
|
1742
|
-
5.
|
|
1869
|
+
1. **List all pending tasks** (status = todo or in-progress)
|
|
1870
|
+
2. **Filter high-priority tasks**: critical and high
|
|
1871
|
+
3. **Check due dates**: Identify tasks due soon or overdue
|
|
1872
|
+
4. **Analyze blocking relationships**: Identify tasks blocking others
|
|
1873
|
+
5. **Generate recommendation list**: Provide ${taskLimit} tasks to prioritize with reasons
|
|
1743
1874
|
|
|
1744
|
-
##
|
|
1875
|
+
## Output Format:
|
|
1745
1876
|
|
|
1746
|
-
###
|
|
1747
|
-
1.
|
|
1748
|
-
-
|
|
1749
|
-
-
|
|
1877
|
+
### Immediate Action (Critical)
|
|
1878
|
+
1. **Task Name** (Project Name)
|
|
1879
|
+
- Reason: [Why this task is most urgent]
|
|
1880
|
+
- Suggested Action: [What specifically to do]
|
|
1750
1881
|
|
|
1751
|
-
###
|
|
1752
|
-
2.
|
|
1753
|
-
-
|
|
1754
|
-
-
|
|
1882
|
+
### Today's Focus (High)
|
|
1883
|
+
2. **Task Name** (Project Name)
|
|
1884
|
+
- Reason: [Why this task is important]
|
|
1885
|
+
- Suggested Action: [What specifically to do]
|
|
1755
1886
|
|
|
1756
|
-
###
|
|
1757
|
-
3.
|
|
1758
|
-
-
|
|
1759
|
-
-
|
|
1887
|
+
### Follow-up
|
|
1888
|
+
3. **Task Name** (Project Name)
|
|
1889
|
+
- Reason: [Why this should be done next]
|
|
1890
|
+
- Suggested Action: [What specifically to do]
|
|
1760
1891
|
|
|
1761
|
-
|
|
1892
|
+
Please use the list_tasks tool to fetch task data, then provide intelligent recommendations.
|
|
1762
1893
|
|
|
1763
1894
|
## Important Reminder
|
|
1764
1895
|
When you start working on recommended tasks, please:
|
|
@@ -1773,71 +1904,71 @@ Keep task status synchronized with actual progress!`
|
|
|
1773
1904
|
};
|
|
1774
1905
|
}
|
|
1775
1906
|
function getAutoPrioritizePrompt(projectId) {
|
|
1776
|
-
const context = projectId ?
|
|
1907
|
+
const context = projectId ? `Analyze task priorities for project ${projectId}` : "Analyze task priorities for all projects";
|
|
1777
1908
|
return {
|
|
1778
|
-
description: "
|
|
1909
|
+
description: "Intelligent Priority Optimization Assistant",
|
|
1779
1910
|
messages: [
|
|
1780
1911
|
{
|
|
1781
1912
|
role: "user",
|
|
1782
1913
|
content: {
|
|
1783
1914
|
type: "text",
|
|
1784
|
-
text: `${context}
|
|
1785
|
-
|
|
1786
|
-
##
|
|
1787
|
-
|
|
1788
|
-
###
|
|
1789
|
-
- [ ]
|
|
1790
|
-
- [ ]
|
|
1791
|
-
- [ ]
|
|
1792
|
-
- [ ]
|
|
1793
|
-
|
|
1794
|
-
###
|
|
1795
|
-
- [ ]
|
|
1796
|
-
- [ ]
|
|
1797
|
-
- [ ]
|
|
1798
|
-
- [ ]
|
|
1799
|
-
|
|
1800
|
-
###
|
|
1801
|
-
- [ ]
|
|
1802
|
-
- [ ]
|
|
1803
|
-
- [ ]
|
|
1804
|
-
|
|
1805
|
-
###
|
|
1806
|
-
-
|
|
1807
|
-
-
|
|
1808
|
-
-
|
|
1809
|
-
|
|
1810
|
-
##
|
|
1811
|
-
|
|
1812
|
-
1.
|
|
1813
|
-
2.
|
|
1814
|
-
-
|
|
1815
|
-
-
|
|
1816
|
-
-
|
|
1817
|
-
3.
|
|
1818
|
-
4.
|
|
1819
|
-
|
|
1820
|
-
##
|
|
1821
|
-
|
|
1822
|
-
###
|
|
1823
|
-
|
|
|
1824
|
-
|
|
1825
|
-
| XXX | high \u2192 critical |
|
|
1826
|
-
|
|
1827
|
-
###
|
|
1828
|
-
|
|
|
1829
|
-
|
|
1830
|
-
| XXX | medium \u2192 high |
|
|
1831
|
-
|
|
1832
|
-
###
|
|
1833
|
-
|
|
|
1834
|
-
|
|
1835
|
-
| XXX | high \u2192 medium |
|
|
1836
|
-
|
|
1837
|
-
###
|
|
1838
|
-
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1915
|
+
text: `${context}, please automatically analyze and suggest priority adjustments.
|
|
1916
|
+
|
|
1917
|
+
## Priority Adjustment Rules:
|
|
1918
|
+
|
|
1919
|
+
### Conditions to Upgrade to Critical:
|
|
1920
|
+
- [ ] Due within 48 hours and not completed
|
|
1921
|
+
- [ ] Blocking other high/critical tasks
|
|
1922
|
+
- [ ] On project critical path and behind schedule
|
|
1923
|
+
- [ ] Has external dependencies (e.g., clients, partners) and time is tight
|
|
1924
|
+
|
|
1925
|
+
### Conditions to Upgrade to High:
|
|
1926
|
+
- [ ] Due within 1 week
|
|
1927
|
+
- [ ] Prerequisite for important milestone
|
|
1928
|
+
- [ ] Stuck in "in-progress" state for too long (over 3 days)
|
|
1929
|
+
- [ ] Affects work of multiple team members
|
|
1930
|
+
|
|
1931
|
+
### Conditions to Downgrade to Medium/Low:
|
|
1932
|
+
- [ ] Due date is far away (>2 weeks) and no dependencies
|
|
1933
|
+
- [ ] "Nice to have" feature rather than core functionality
|
|
1934
|
+
- [ ] Not needed in current phase, can be postponed
|
|
1935
|
+
|
|
1936
|
+
### Other Considerations:
|
|
1937
|
+
- **Overall project progress**: Tasks for behind-schedule projects should be prioritized higher
|
|
1938
|
+
- **Resource availability**: If resources are tight, focus on highest priority
|
|
1939
|
+
- **Risk factors**: High-risk tasks should be addressed earlier
|
|
1940
|
+
|
|
1941
|
+
## Please perform the following steps:
|
|
1942
|
+
|
|
1943
|
+
1. **Get all tasks**: Use list_tasks to fetch task list
|
|
1944
|
+
2. **Analyze each task**:
|
|
1945
|
+
- Check gap between due date and current date
|
|
1946
|
+
- Identify task dependency relationships
|
|
1947
|
+
- Evaluate overall project health
|
|
1948
|
+
3. **Generate adjustment suggestions**: List tasks needing priority changes with reasons
|
|
1949
|
+
4. **Batch update**: Use batch_update_tasks to execute priority adjustments
|
|
1950
|
+
|
|
1951
|
+
## Output Format:
|
|
1952
|
+
|
|
1953
|
+
### Suggested Upgrade to Critical
|
|
1954
|
+
| Task | Current Priority | Suggested Priority | Reason |
|
|
1955
|
+
|------|-----------------|-------------------|--------|
|
|
1956
|
+
| XXX | high \u2192 critical | Due tomorrow |
|
|
1957
|
+
|
|
1958
|
+
### Suggested Upgrade to High
|
|
1959
|
+
| Task | Current Priority | Suggested Priority | Reason |
|
|
1960
|
+
|------|-----------------|-------------------|--------|
|
|
1961
|
+
| XXX | medium \u2192 high | Blocking follow-up tasks |
|
|
1962
|
+
|
|
1963
|
+
### Suggested Downgrade
|
|
1964
|
+
| Task | Current Priority | Suggested Priority | Reason |
|
|
1965
|
+
|------|-----------------|-------------------|--------|
|
|
1966
|
+
| XXX | high \u2192 medium | Can be postponed |
|
|
1967
|
+
|
|
1968
|
+
### Keep Unchanged (Priorities are reasonable)
|
|
1969
|
+
- List tasks with reasonable priority settings
|
|
1970
|
+
|
|
1971
|
+
Please provide analysis results, then execute batch update after user confirmation.`
|
|
1841
1972
|
}
|
|
1842
1973
|
}
|
|
1843
1974
|
]
|
|
@@ -1845,139 +1976,139 @@ function getAutoPrioritizePrompt(projectId) {
|
|
|
1845
1976
|
}
|
|
1846
1977
|
function getEnhanceTaskDetailsPrompt(taskId) {
|
|
1847
1978
|
return {
|
|
1848
|
-
description: "
|
|
1979
|
+
description: "Task Detail Enhancement Assistant",
|
|
1849
1980
|
messages: [
|
|
1850
1981
|
{
|
|
1851
1982
|
role: "user",
|
|
1852
1983
|
content: {
|
|
1853
1984
|
type: "text",
|
|
1854
|
-
text:
|
|
1855
|
-
|
|
1856
|
-
##
|
|
1857
|
-
|
|
1858
|
-
### 1.
|
|
1859
|
-
-
|
|
1860
|
-
-
|
|
1861
|
-
-
|
|
1862
|
-
|
|
1863
|
-
### 2.
|
|
1864
|
-
|
|
1865
|
-
- [ ]
|
|
1866
|
-
- [ ]
|
|
1867
|
-
- [ ]
|
|
1868
|
-
- [ ]
|
|
1869
|
-
|
|
1870
|
-
### 3.
|
|
1871
|
-
-
|
|
1872
|
-
-
|
|
1873
|
-
-
|
|
1874
|
-
|
|
1875
|
-
### 4.
|
|
1876
|
-
-
|
|
1877
|
-
-
|
|
1878
|
-
-
|
|
1879
|
-
|
|
1880
|
-
### 5.
|
|
1881
|
-
|
|
1882
|
-
-
|
|
1883
|
-
-
|
|
1884
|
-
-
|
|
1885
|
-
|
|
1886
|
-
##
|
|
1887
|
-
|
|
1888
|
-
1.
|
|
1889
|
-
2.
|
|
1890
|
-
3.
|
|
1891
|
-
-
|
|
1892
|
-
-
|
|
1893
|
-
-
|
|
1894
|
-
-
|
|
1895
|
-
4.
|
|
1896
|
-
|
|
1897
|
-
##
|
|
1985
|
+
text: `Please help me enhance the details for task ${taskId}.
|
|
1986
|
+
|
|
1987
|
+
## Enhancement Content:
|
|
1988
|
+
|
|
1989
|
+
### 1. Detailed Description
|
|
1990
|
+
- Specific content and background of the task
|
|
1991
|
+
- Why this task needs to be done
|
|
1992
|
+
- Expected business or technical value
|
|
1993
|
+
|
|
1994
|
+
### 2. Acceptance Criteria (Definition of Done)
|
|
1995
|
+
List clear completion standards, for example:
|
|
1996
|
+
- [ ] Feature implemented and locally tested
|
|
1997
|
+
- [ ] Code passes Code Review
|
|
1998
|
+
- [ ] Related documentation updated
|
|
1999
|
+
- [ ] Unit test coverage > 80%
|
|
2000
|
+
|
|
2001
|
+
### 3. Technical/Implementation Details
|
|
2002
|
+
- Tech stack or modules involved
|
|
2003
|
+
- Files that may need modification
|
|
2004
|
+
- Potential challenges or considerations
|
|
2005
|
+
|
|
2006
|
+
### 4. Related Resources
|
|
2007
|
+
- Related documentation links
|
|
2008
|
+
- Reference implementations or example code
|
|
2009
|
+
- People to consult
|
|
2010
|
+
|
|
2011
|
+
### 5. Subtask Suggestions (if needed)
|
|
2012
|
+
If the task is complex, suggest breaking it down:
|
|
2013
|
+
- Subtask 1: ...
|
|
2014
|
+
- Subtask 2: ...
|
|
2015
|
+
- Subtask 3: ...
|
|
2016
|
+
|
|
2017
|
+
## Please perform the following steps:
|
|
2018
|
+
|
|
2019
|
+
1. **Get task info**: Use get_task to view current task details
|
|
2020
|
+
2. **Get project context**: Use get_project to understand project background
|
|
2021
|
+
3. **Analyze task type**:
|
|
2022
|
+
- If development task: Add technical details, code locations
|
|
2023
|
+
- If design task: Add design specs, review criteria
|
|
2024
|
+
- If documentation task: Add doc structure, references
|
|
2025
|
+
- If testing task: Add test scenarios, coverage scope
|
|
2026
|
+
4. **Generate enhancement content**: Use update_task to update task description
|
|
2027
|
+
|
|
2028
|
+
## Updated task should include:
|
|
1898
2029
|
|
|
1899
2030
|
\`\`\`
|
|
1900
|
-
##
|
|
1901
|
-
[
|
|
1902
|
-
|
|
1903
|
-
##
|
|
1904
|
-
- [ ] [
|
|
1905
|
-
- [ ] [
|
|
1906
|
-
- [ ] [
|
|
1907
|
-
|
|
1908
|
-
##
|
|
1909
|
-
-
|
|
1910
|
-
-
|
|
1911
|
-
-
|
|
1912
|
-
|
|
1913
|
-
##
|
|
1914
|
-
-
|
|
1915
|
-
-
|
|
2031
|
+
## Background
|
|
2032
|
+
[Task background and purpose]
|
|
2033
|
+
|
|
2034
|
+
## Acceptance Criteria
|
|
2035
|
+
- [ ] [Standard 1]
|
|
2036
|
+
- [ ] [Standard 2]
|
|
2037
|
+
- [ ] [Standard 3]
|
|
2038
|
+
|
|
2039
|
+
## Technical Details
|
|
2040
|
+
- Modules: [module name]
|
|
2041
|
+
- Key files: [file path]
|
|
2042
|
+
- Notes: [important reminders]
|
|
2043
|
+
|
|
2044
|
+
## Related Resources
|
|
2045
|
+
- Documentation: [link]
|
|
2046
|
+
- References: [link]
|
|
1916
2047
|
\`\`\`
|
|
1917
2048
|
|
|
1918
|
-
|
|
2049
|
+
Please fetch task info first, then provide detailed enhancement suggestions.`
|
|
1919
2050
|
}
|
|
1920
2051
|
}
|
|
1921
2052
|
]
|
|
1922
2053
|
};
|
|
1923
2054
|
}
|
|
1924
2055
|
function getQuickCapturePrompt(idea, projectId) {
|
|
1925
|
-
const projectContext = projectId ?
|
|
2056
|
+
const projectContext = projectId ? `Add to project ${projectId}` : "Auto-select the most suitable project";
|
|
1926
2057
|
return {
|
|
1927
|
-
description: "
|
|
2058
|
+
description: "Quick Capture Assistant",
|
|
1928
2059
|
messages: [
|
|
1929
2060
|
{
|
|
1930
2061
|
role: "user",
|
|
1931
2062
|
content: {
|
|
1932
2063
|
type: "text",
|
|
1933
|
-
text:
|
|
2064
|
+
text: `I want to quickly capture an idea/task: "${idea}"
|
|
1934
2065
|
|
|
1935
2066
|
${projectContext}
|
|
1936
2067
|
|
|
1937
|
-
##
|
|
2068
|
+
## Please help me complete the following steps:
|
|
1938
2069
|
|
|
1939
|
-
### 1.
|
|
1940
|
-
|
|
1941
|
-
-
|
|
1942
|
-
-
|
|
1943
|
-
-
|
|
1944
|
-
-
|
|
2070
|
+
### 1. Task Information Extraction
|
|
2071
|
+
Extract from description:
|
|
2072
|
+
- **Task Title**: Concise and clear title (start with verb)
|
|
2073
|
+
- **Task Description**: Add context and details
|
|
2074
|
+
- **Task Type**: bug / feature / refactor / docs / chore
|
|
2075
|
+
- **Estimated Priority**: critical / high / medium / low (based on urgency in description)
|
|
1945
2076
|
|
|
1946
|
-
### 2.
|
|
1947
|
-
|
|
1948
|
-
-
|
|
1949
|
-
-
|
|
1950
|
-
-
|
|
2077
|
+
### 2. Project Recommendation (if no project specified)
|
|
2078
|
+
If user didn't specify a project, please:
|
|
2079
|
+
- List all active projects
|
|
2080
|
+
- Analyze which project the task content is most relevant to
|
|
2081
|
+
- Recommend the most suitable project
|
|
1951
2082
|
|
|
1952
|
-
### 3.
|
|
1953
|
-
|
|
1954
|
-
-
|
|
1955
|
-
-
|
|
1956
|
-
-
|
|
2083
|
+
### 3. Tag Suggestions
|
|
2084
|
+
Suggest relevant tags:
|
|
2085
|
+
- Type tags: bug, feature, refactor, docs
|
|
2086
|
+
- Priority tags: urgent, important
|
|
2087
|
+
- Domain tags: frontend, backend, design, testing (if applicable)
|
|
1957
2088
|
|
|
1958
|
-
### 4.
|
|
1959
|
-
|
|
2089
|
+
### 4. Generate Task
|
|
2090
|
+
Use create_task to create the task
|
|
1960
2091
|
|
|
1961
2092
|
### 5. Status Recommendation
|
|
1962
2093
|
After creating the task, if you start working on it immediately, consider setting the status to in-progress. Use update_task to keep progress updated during work, and mark as done when completed.
|
|
1963
2094
|
|
|
1964
|
-
##
|
|
2095
|
+
## Example:
|
|
1965
2096
|
|
|
1966
|
-
|
|
2097
|
+
**Input**: "User reported login page doesn't display correctly on mobile"
|
|
1967
2098
|
|
|
1968
|
-
|
|
1969
|
-
-
|
|
1970
|
-
-
|
|
1971
|
-
-
|
|
1972
|
-
-
|
|
1973
|
-
-
|
|
1974
|
-
-
|
|
2099
|
+
**Output**:
|
|
2100
|
+
- Title: Fix login page mobile responsiveness issue
|
|
2101
|
+
- Description: User reported the login page displays abnormally on mobile devices, need to check responsive layout.
|
|
2102
|
+
- Type: Bug
|
|
2103
|
+
- Priority: High (affects user experience)
|
|
2104
|
+
- Suggested Tags: bug, frontend, mobile
|
|
2105
|
+
- Recommended Project: [Recommend if there's a web project]
|
|
1975
2106
|
|
|
1976
|
-
##
|
|
2107
|
+
## Current Idea Analysis:
|
|
1977
2108
|
|
|
1978
|
-
|
|
2109
|
+
Idea: "${idea}"
|
|
1979
2110
|
|
|
1980
|
-
|
|
2111
|
+
Please analyze and generate task suggestions. After user confirmation, execute create_task to create the task.`
|
|
1981
2112
|
}
|
|
1982
2113
|
}
|
|
1983
2114
|
]
|
|
@@ -2027,7 +2158,7 @@ function createServer2() {
|
|
|
2027
2158
|
const server = new Server(
|
|
2028
2159
|
{
|
|
2029
2160
|
name: "roadmap-skill",
|
|
2030
|
-
version: "0.2.
|
|
2161
|
+
version: "0.2.1"
|
|
2031
2162
|
},
|
|
2032
2163
|
{
|
|
2033
2164
|
capabilities: {
|