@zaclinley/dsh-mailharbor 0.22.2 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.zh.md +17 -17
- package/lib/client.js +1658 -1005
- package/lib/client.js.map +4 -4
- package/lib/index.js +290 -39
- package/lib/index.js.map +3 -3
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2951,7 +2951,17 @@ var ProjectStore = class {
|
|
|
2951
2951
|
parsed = null;
|
|
2952
2952
|
}
|
|
2953
2953
|
const projects = parsed !== null && typeof parsed === "object" && Array.isArray(parsed.projects) ? parsed.projects : [];
|
|
2954
|
-
this.cache = {
|
|
2954
|
+
this.cache = {
|
|
2955
|
+
version: 2,
|
|
2956
|
+
projects: projects.filter(isProject).map((project) => ({
|
|
2957
|
+
...project,
|
|
2958
|
+
status: project.status ?? "active",
|
|
2959
|
+
notes: Array.isArray(project.notes) ? project.notes : [],
|
|
2960
|
+
milestones: Array.isArray(project.milestones) ? project.milestones : [],
|
|
2961
|
+
activity: Array.isArray(project.activity) ? project.activity : [],
|
|
2962
|
+
sessionIds: Array.isArray(project.sessionIds) ? project.sessionIds : project.sessionId === "" ? [] : [project.sessionId]
|
|
2963
|
+
}))
|
|
2964
|
+
};
|
|
2955
2965
|
return this.cache;
|
|
2956
2966
|
}
|
|
2957
2967
|
flush() {
|
|
@@ -3006,6 +3016,89 @@ var ProjectStore = class {
|
|
|
3006
3016
|
this.flush();
|
|
3007
3017
|
return project;
|
|
3008
3018
|
}
|
|
3019
|
+
addNote(id, body, createdAt) {
|
|
3020
|
+
const project = this.get(id);
|
|
3021
|
+
if (project === void 0) return void 0;
|
|
3022
|
+
const note = {
|
|
3023
|
+
id: `note_${randomUUID2().slice(0, 8)}`,
|
|
3024
|
+
body,
|
|
3025
|
+
createdAt,
|
|
3026
|
+
taskIds: []
|
|
3027
|
+
};
|
|
3028
|
+
project.notes.unshift(note);
|
|
3029
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3030
|
+
this.flush();
|
|
3031
|
+
return project;
|
|
3032
|
+
}
|
|
3033
|
+
updateNote(id, noteId, body, createdAt) {
|
|
3034
|
+
const project = this.get(id);
|
|
3035
|
+
const note = project?.notes.find((item) => item.id === noteId);
|
|
3036
|
+
if (project === void 0 || note === void 0) return void 0;
|
|
3037
|
+
note.body = body;
|
|
3038
|
+
note.createdAt = createdAt;
|
|
3039
|
+
note.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3040
|
+
project.updatedAt = note.updatedAt;
|
|
3041
|
+
this.flush();
|
|
3042
|
+
return project;
|
|
3043
|
+
}
|
|
3044
|
+
removeNote(id, noteId) {
|
|
3045
|
+
const project = this.get(id);
|
|
3046
|
+
if (project === void 0) return void 0;
|
|
3047
|
+
project.notes = project.notes.filter((item) => item.id !== noteId);
|
|
3048
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3049
|
+
this.flush();
|
|
3050
|
+
return project;
|
|
3051
|
+
}
|
|
3052
|
+
linkNoteTasks(id, noteId, taskIds) {
|
|
3053
|
+
const project = this.get(id);
|
|
3054
|
+
const note = project?.notes.find((item) => item.id === noteId);
|
|
3055
|
+
if (project === void 0 || note === void 0) return void 0;
|
|
3056
|
+
note.taskIds = [.../* @__PURE__ */ new Set([...note.taskIds, ...taskIds])];
|
|
3057
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3058
|
+
this.flush();
|
|
3059
|
+
return project;
|
|
3060
|
+
}
|
|
3061
|
+
addMilestone(id, title, due) {
|
|
3062
|
+
const project = this.get(id);
|
|
3063
|
+
if (project === void 0) return void 0;
|
|
3064
|
+
project.milestones.push({
|
|
3065
|
+
id: `ms_${randomUUID2().slice(0, 8)}`,
|
|
3066
|
+
title,
|
|
3067
|
+
due,
|
|
3068
|
+
done: false
|
|
3069
|
+
});
|
|
3070
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3071
|
+
this.flush();
|
|
3072
|
+
return project;
|
|
3073
|
+
}
|
|
3074
|
+
updateMilestone(id, milestoneId, patch) {
|
|
3075
|
+
const project = this.get(id);
|
|
3076
|
+
const milestone = project?.milestones.find((item) => item.id === milestoneId);
|
|
3077
|
+
if (project === void 0 || milestone === void 0) return void 0;
|
|
3078
|
+
if (patch.title !== void 0) milestone.title = patch.title;
|
|
3079
|
+
if (patch.due !== void 0) milestone.due = patch.due;
|
|
3080
|
+
if (patch.done !== void 0) milestone.done = patch.done;
|
|
3081
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3082
|
+
this.flush();
|
|
3083
|
+
return project;
|
|
3084
|
+
}
|
|
3085
|
+
removeMilestone(id, milestoneId) {
|
|
3086
|
+
const project = this.get(id);
|
|
3087
|
+
if (project === void 0) return void 0;
|
|
3088
|
+
project.milestones = project.milestones.filter((item) => item.id !== milestoneId);
|
|
3089
|
+
project.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3090
|
+
this.flush();
|
|
3091
|
+
return project;
|
|
3092
|
+
}
|
|
3093
|
+
addActivity(id, text2, at = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
3094
|
+
const project = this.get(id);
|
|
3095
|
+
if (project === void 0) return void 0;
|
|
3096
|
+
project.activity.unshift({ id: `act_${randomUUID2().slice(0, 8)}`, at, text: text2 });
|
|
3097
|
+
if (project.activity.length > 100) project.activity.length = 100;
|
|
3098
|
+
project.updatedAt = at;
|
|
3099
|
+
this.flush();
|
|
3100
|
+
return project;
|
|
3101
|
+
}
|
|
3009
3102
|
remove(id) {
|
|
3010
3103
|
const data = this.load();
|
|
3011
3104
|
const index = data.projects.findIndex((project) => project.id === id);
|
|
@@ -3066,35 +3159,18 @@ async function createProject(options) {
|
|
|
3066
3159
|
} else {
|
|
3067
3160
|
warnings.push("\u5F53\u524D DSH \u7EC4\u5408\u6CA1\u6709 workspaceRegistry\uFF0C\u9879\u76EE\u76EE\u5F55\u5DF2\u521B\u5EFA\u4F46\u6CA1\u6709\u6CE8\u518C\u5230\u4FA7\u680F");
|
|
3068
3161
|
}
|
|
3069
|
-
|
|
3070
|
-
if (options.sessions !== void 0) {
|
|
3071
|
-
try {
|
|
3072
|
-
sessionId = randomUUID2();
|
|
3073
|
-
const session = options.sessions.create(sessionId, { meta: { cwd: path } });
|
|
3074
|
-
session.append(
|
|
3075
|
-
"user/message",
|
|
3076
|
-
{
|
|
3077
|
-
role: "user",
|
|
3078
|
-
content: [{ type: "text", text: `\u6211\u521B\u5EFA\u4E86\u4E00\u4E2A\u90AE\u4EF6\u9879\u76EE\u300C${name2}\u300D\u3002
|
|
3079
|
-
|
|
3080
|
-
${brief}` }],
|
|
3081
|
-
source: { kind: "user" }
|
|
3082
|
-
},
|
|
3083
|
-
{ surfaceOp: "append" }
|
|
3084
|
-
);
|
|
3085
|
-
} catch (error) {
|
|
3086
|
-
warnings.push(`\u4F1A\u8BDD\u521B\u5EFA\u5931\u8D25\uFF1A${error instanceof Error ? error.message : String(error)}`);
|
|
3087
|
-
sessionId = "";
|
|
3088
|
-
}
|
|
3089
|
-
} else {
|
|
3090
|
-
warnings.push("\u5F53\u524D DSH \u7EC4\u5408\u6CA1\u6709 sessions \u670D\u52A1\uFF0C\u672A\u521B\u5EFA\u9879\u76EE\u4F1A\u8BDD");
|
|
3091
|
-
}
|
|
3162
|
+
const sessionId = "";
|
|
3092
3163
|
const project = {
|
|
3093
3164
|
id,
|
|
3094
3165
|
name: name2,
|
|
3166
|
+
status: "active",
|
|
3167
|
+
notes: [],
|
|
3168
|
+
milestones: [],
|
|
3169
|
+
activity: [],
|
|
3095
3170
|
path,
|
|
3096
3171
|
workspaceId,
|
|
3097
3172
|
sessionId,
|
|
3173
|
+
sessionIds: sessionId === "" ? [] : [sessionId],
|
|
3098
3174
|
accountIds: [input.accountId],
|
|
3099
3175
|
messages: input.message === void 0 ? [] : [input.message],
|
|
3100
3176
|
threads: input.thread === void 0 ? [] : [input.thread],
|
|
@@ -3152,7 +3228,7 @@ ${conversation.trim()}
|
|
|
3152
3228
|
}
|
|
3153
3229
|
|
|
3154
3230
|
// src/host/version.ts
|
|
3155
|
-
var VERSION = "0.
|
|
3231
|
+
var VERSION = "0.24.0";
|
|
3156
3232
|
|
|
3157
3233
|
// src/host/api.ts
|
|
3158
3234
|
init_smtp();
|
|
@@ -3977,10 +4053,12 @@ function buildRouter(runtime) {
|
|
|
3977
4053
|
title: String(payload.title ?? ""),
|
|
3978
4054
|
notes: typeof payload.notes === "string" ? payload.notes : "",
|
|
3979
4055
|
due: typeof payload.due === "string" ? payload.due : "",
|
|
3980
|
-
status: typeof payload.status === "string" ? payload.status : "
|
|
4056
|
+
status: typeof payload.status === "string" ? payload.status : "TODO",
|
|
3981
4057
|
priority: Number(payload.priority ?? 0),
|
|
3982
4058
|
owner: typeof payload.owner === "string" ? payload.owner : "",
|
|
3983
4059
|
projectId: typeof payload.projectId === "string" ? payload.projectId : null,
|
|
4060
|
+
parentId: typeof payload.parentId === "string" && payload.parentId !== "" ? payload.parentId : null,
|
|
4061
|
+
waitingOn: typeof payload.waitingOn === "string" ? payload.waitingOn : "",
|
|
3984
4062
|
messageKey: typeof payload.messageKey === "string" ? payload.messageKey : "",
|
|
3985
4063
|
messageSubject: typeof payload.messageSubject === "string" ? payload.messageSubject : ""
|
|
3986
4064
|
});
|
|
@@ -3995,7 +4073,9 @@ function buildRouter(runtime) {
|
|
|
3995
4073
|
...typeof payload.status === "string" ? { status: payload.status } : {},
|
|
3996
4074
|
...typeof payload.priority === "number" ? { priority: payload.priority } : {},
|
|
3997
4075
|
...typeof payload.owner === "string" ? { owner: payload.owner } : {},
|
|
3998
|
-
...payload.projectId === null || typeof payload.projectId === "string" ? { projectId: payload.projectId } : {}
|
|
4076
|
+
...payload.projectId === null || typeof payload.projectId === "string" ? { projectId: payload.projectId } : {},
|
|
4077
|
+
...payload.parentId === null || typeof payload.parentId === "string" ? { parentId: payload.parentId } : {},
|
|
4078
|
+
...typeof payload.waitingOn === "string" ? { waitingOn: payload.waitingOn } : {}
|
|
3999
4079
|
});
|
|
4000
4080
|
return { task: taskView(task) };
|
|
4001
4081
|
});
|
|
@@ -4051,8 +4131,10 @@ function buildRouter(runtime) {
|
|
|
4051
4131
|
for (const task of runtime.tasks().list({ accountId: account.id })) {
|
|
4052
4132
|
const projectId = task.projectId ?? "";
|
|
4053
4133
|
if (projectId === "") continue;
|
|
4054
|
-
const entry = counts.get(projectId) ?? { total: 0, done: 0 };
|
|
4134
|
+
const entry = counts.get(projectId) ?? { total: 0, todo: 0, waiting: 0, done: 0 };
|
|
4055
4135
|
entry.total += 1;
|
|
4136
|
+
if (task.status === "TODO" || task.status === "IN-PROCESS") entry.todo += 1;
|
|
4137
|
+
if (task.status === "WAITING") entry.waiting += 1;
|
|
4056
4138
|
if (task.status === "COMPLETED") entry.done += 1;
|
|
4057
4139
|
counts.set(projectId, entry);
|
|
4058
4140
|
}
|
|
@@ -4060,7 +4142,13 @@ function buildRouter(runtime) {
|
|
|
4060
4142
|
return {
|
|
4061
4143
|
items: runtime.projects().list().map((project) => {
|
|
4062
4144
|
const stat = counts.get(project.id);
|
|
4063
|
-
return {
|
|
4145
|
+
return {
|
|
4146
|
+
...projectView(project),
|
|
4147
|
+
taskTotal: stat?.total ?? 0,
|
|
4148
|
+
taskTodo: stat?.todo ?? 0,
|
|
4149
|
+
taskWaiting: stat?.waiting ?? 0,
|
|
4150
|
+
taskDone: stat?.done ?? 0
|
|
4151
|
+
};
|
|
4064
4152
|
})
|
|
4065
4153
|
};
|
|
4066
4154
|
});
|
|
@@ -4110,12 +4198,131 @@ function buildRouter(runtime) {
|
|
|
4110
4198
|
});
|
|
4111
4199
|
router.patch("/projects/:id", async ({ params, body }) => {
|
|
4112
4200
|
const payload = await body();
|
|
4113
|
-
const
|
|
4114
|
-
if (
|
|
4115
|
-
|
|
4201
|
+
const patch = {};
|
|
4202
|
+
if (typeof payload.name === "string") {
|
|
4203
|
+
const name2 = payload.name.trim();
|
|
4204
|
+
if (name2 === "") throw new HttpError(400, "\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
4205
|
+
patch.name = name2;
|
|
4206
|
+
}
|
|
4207
|
+
if (typeof payload.status === "string") {
|
|
4208
|
+
const allowed = ["active", "paused", "done", "archived"];
|
|
4209
|
+
if (!allowed.includes(payload.status)) throw new HttpError(400, "\u9879\u76EE\u72B6\u6001\u4E0D\u6B63\u786E");
|
|
4210
|
+
patch.status = payload.status;
|
|
4211
|
+
}
|
|
4212
|
+
const project = runtime.projects().update(String(params.id ?? ""), patch);
|
|
4213
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4214
|
+
if (typeof patch.status === "string") {
|
|
4215
|
+
const labels = {
|
|
4216
|
+
active: "\u8FDB\u884C\u4E2D",
|
|
4217
|
+
paused: "\u6682\u505C",
|
|
4218
|
+
done: "\u5DF2\u5B8C\u6210",
|
|
4219
|
+
archived: "\u5DF2\u5F52\u6863"
|
|
4220
|
+
};
|
|
4221
|
+
runtime.projects().addActivity(project.id, `\u9879\u76EE\u72B6\u6001\u6539\u4E3A\u300C${labels[patch.status] ?? patch.status}\u300D`);
|
|
4222
|
+
}
|
|
4223
|
+
return { project: projectView(runtime.projects().get(project.id) ?? project) };
|
|
4224
|
+
});
|
|
4225
|
+
router.post("/projects/:id/milestones", async ({ params, body }) => {
|
|
4226
|
+
const payload = await body();
|
|
4227
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
4228
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4229
|
+
const title = String(payload.title ?? "").trim();
|
|
4230
|
+
if (title === "") throw new HttpError(400, "\u91CC\u7A0B\u7891\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
4231
|
+
const updated = runtime.projects().addMilestone(project.id, title, typeof payload.due === "string" ? payload.due : "");
|
|
4232
|
+
if (updated === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4233
|
+
runtime.projects().addActivity(project.id, `\u65B0\u589E\u91CC\u7A0B\u7891\u300C${title}\u300D`);
|
|
4234
|
+
return { project: projectView(runtime.projects().get(project.id) ?? updated) };
|
|
4235
|
+
});
|
|
4236
|
+
router.patch("/projects/:id/milestones/:milestoneId", async ({ params, body }) => {
|
|
4237
|
+
const payload = await body();
|
|
4238
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
4239
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4240
|
+
const milestone = project.milestones.find((item) => item.id === String(params.milestoneId ?? ""));
|
|
4241
|
+
if (milestone === void 0) throw new HttpError(404, "\u91CC\u7A0B\u7891\u4E0D\u5B58\u5728");
|
|
4242
|
+
const patch = {};
|
|
4243
|
+
if (typeof payload.title === "string") patch.title = payload.title.trim();
|
|
4244
|
+
if (typeof payload.due === "string") patch.due = payload.due;
|
|
4245
|
+
if (typeof payload.done === "boolean") patch.done = payload.done;
|
|
4246
|
+
const updated = runtime.projects().updateMilestone(project.id, milestone.id, patch);
|
|
4247
|
+
if (updated === void 0) throw new HttpError(404, "\u91CC\u7A0B\u7891\u4E0D\u5B58\u5728");
|
|
4248
|
+
if (patch.done !== void 0) {
|
|
4249
|
+
runtime.projects().addActivity(
|
|
4250
|
+
project.id,
|
|
4251
|
+
`\u91CC\u7A0B\u7891\u300C${patch.title ?? milestone.title}\u300D${patch.done ? "\u5DF2\u5B8C\u6210" : "\u91CD\u65B0\u6253\u5F00"}`
|
|
4252
|
+
);
|
|
4253
|
+
}
|
|
4254
|
+
return { project: projectView(runtime.projects().get(project.id) ?? updated) };
|
|
4255
|
+
});
|
|
4256
|
+
router.delete("/projects/:id/milestones/:milestoneId", ({ params }) => {
|
|
4257
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
4116
4258
|
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4259
|
+
const milestone = project.milestones.find((item) => item.id === String(params.milestoneId ?? ""));
|
|
4260
|
+
const updated = runtime.projects().removeMilestone(project.id, String(params.milestoneId ?? ""));
|
|
4261
|
+
if (updated === void 0) throw new HttpError(404, "\u91CC\u7A0B\u7891\u4E0D\u5B58\u5728");
|
|
4262
|
+
runtime.projects().addActivity(project.id, `\u5220\u9664\u91CC\u7A0B\u7891\u300C${milestone?.title ?? ""}\u300D`);
|
|
4263
|
+
return { project: projectView(runtime.projects().get(project.id) ?? updated) };
|
|
4264
|
+
});
|
|
4265
|
+
router.post("/projects/:id/notes", async ({ params, body }) => {
|
|
4266
|
+
const payload = await body();
|
|
4267
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
4268
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4269
|
+
const text2 = String(payload.body ?? "").trim();
|
|
4270
|
+
if (text2 === "") throw new HttpError(400, "\u8BB0\u5F55\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");
|
|
4271
|
+
const createdAt = typeof payload.createdAt === "string" && payload.createdAt !== "" ? payload.createdAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
4272
|
+
const updated = runtime.projects().addNote(project.id, text2, createdAt);
|
|
4273
|
+
runtime.projects().addActivity(project.id, "\u65B0\u589E\u4E00\u6761\u9879\u76EE\u8BB0\u5F55");
|
|
4274
|
+
return {
|
|
4275
|
+
project: updated === void 0 ? null : projectView(runtime.projects().get(project.id) ?? updated)
|
|
4276
|
+
};
|
|
4277
|
+
});
|
|
4278
|
+
router.patch("/projects/:id/notes/:noteId", async ({ params, body }) => {
|
|
4279
|
+
const payload = await body();
|
|
4280
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
4281
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4282
|
+
const text2 = String(payload.body ?? "").trim();
|
|
4283
|
+
if (text2 === "") throw new HttpError(400, "\u8BB0\u5F55\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");
|
|
4284
|
+
const createdAt = typeof payload.createdAt === "string" && payload.createdAt !== "" ? payload.createdAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
4285
|
+
const updated = runtime.projects().updateNote(project.id, String(params.noteId ?? ""), text2, createdAt);
|
|
4286
|
+
if (updated === void 0) throw new HttpError(404, "\u8BB0\u5F55\u4E0D\u5B58\u5728");
|
|
4287
|
+
return { project: projectView(updated) };
|
|
4288
|
+
});
|
|
4289
|
+
router.delete("/projects/:id/notes/:noteId", ({ params }) => {
|
|
4290
|
+
const project = runtime.projects().removeNote(String(params.id ?? ""), String(params.noteId ?? ""));
|
|
4291
|
+
if (project === void 0) throw new HttpError(404, "\u8BB0\u5F55\u4E0D\u5B58\u5728");
|
|
4117
4292
|
return { project: projectView(project) };
|
|
4118
4293
|
});
|
|
4294
|
+
router.post("/projects/:id/notes/convert", async ({ params, body }) => {
|
|
4295
|
+
const payload = await body();
|
|
4296
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
4297
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
4298
|
+
const noteIds = Array.isArray(payload.noteIds) ? payload.noteIds.filter((id) => typeof id === "string") : [];
|
|
4299
|
+
if (noteIds.length === 0) throw new HttpError(400, "\u8BF7\u9009\u62E9\u8981\u8F6C\u6362\u7684\u8BB0\u5F55");
|
|
4300
|
+
const accountId = typeof payload.accountId === "string" && payload.accountId !== "" ? payload.accountId : project.accountIds[0] ?? "";
|
|
4301
|
+
if (accountId === "") throw new HttpError(400, "\u9879\u76EE\u6CA1\u6709\u5173\u8054\u8D26\u53F7");
|
|
4302
|
+
const created = [];
|
|
4303
|
+
for (const noteId of noteIds) {
|
|
4304
|
+
const note = project.notes.find((item) => item.id === noteId);
|
|
4305
|
+
if (note === void 0) continue;
|
|
4306
|
+
const first = note.body.split("\n").map((line2) => line2.trim()).find((line2) => line2 !== "") ?? "\u9879\u76EE\u8BB0\u5F55";
|
|
4307
|
+
const title = first.replace(/^#+\s*/, "").slice(0, 120);
|
|
4308
|
+
const task = runtime.tasks().create({
|
|
4309
|
+
accountId,
|
|
4310
|
+
title,
|
|
4311
|
+
notes: `\u6765\u81EA\u9879\u76EE\u8BB0\u5F55 ${note.createdAt.slice(0, 10)}
|
|
4312
|
+
|
|
4313
|
+
${note.body}`,
|
|
4314
|
+
status: "TODO",
|
|
4315
|
+
projectId: project.id
|
|
4316
|
+
});
|
|
4317
|
+
runtime.projects().linkNoteTasks(project.id, note.id, [task.id]);
|
|
4318
|
+
created.push(taskView(task));
|
|
4319
|
+
}
|
|
4320
|
+
runtime.projects().addActivity(project.id, `\u5C06 ${String(created.length)} \u6761\u8BB0\u5F55\u8F6C\u4E3A\u4EFB\u52A1`);
|
|
4321
|
+
return {
|
|
4322
|
+
tasks: created,
|
|
4323
|
+
project: projectView(runtime.projects().get(project.id) ?? project)
|
|
4324
|
+
};
|
|
4325
|
+
});
|
|
4119
4326
|
router.delete("/projects/:id", async ({ params, url }) => {
|
|
4120
4327
|
const id = String(params.id ?? "");
|
|
4121
4328
|
const project = runtime.projects().get(id);
|
|
@@ -4365,10 +4572,12 @@ function taskView(task) {
|
|
|
4365
4572
|
id: task.id,
|
|
4366
4573
|
accountId: task.accountId,
|
|
4367
4574
|
projectId: task.projectId,
|
|
4575
|
+
parentId: task.parentId,
|
|
4368
4576
|
title: task.title,
|
|
4369
4577
|
notes: task.notes,
|
|
4370
4578
|
due: task.due,
|
|
4371
4579
|
status: task.status,
|
|
4580
|
+
waitingOn: task.waitingOn,
|
|
4372
4581
|
priority: task.priority,
|
|
4373
4582
|
owner: task.owner,
|
|
4374
4583
|
messageKey: task.messageKey,
|
|
@@ -4383,9 +4592,14 @@ function projectView(project) {
|
|
|
4383
4592
|
return {
|
|
4384
4593
|
id: project.id,
|
|
4385
4594
|
name: project.name,
|
|
4595
|
+
status: project.status,
|
|
4596
|
+
notes: project.notes.map((note) => ({ ...note, taskIds: [...note.taskIds] })),
|
|
4597
|
+
milestones: project.milestones.map((milestone) => ({ ...milestone })),
|
|
4598
|
+
activity: project.activity.map((event) => ({ ...event })),
|
|
4386
4599
|
path: project.path,
|
|
4387
4600
|
workspaceId: project.workspaceId,
|
|
4388
4601
|
sessionId: project.sessionId,
|
|
4602
|
+
sessionIds: [...project.sessionIds],
|
|
4389
4603
|
accountIds: [...project.accountIds],
|
|
4390
4604
|
messages: project.messages.map((message) => ({ ...message })),
|
|
4391
4605
|
threads: project.threads.map((thread) => ({ ...thread })),
|
|
@@ -5039,7 +5253,7 @@ import { randomUUID as randomUUID5 } from "node:crypto";
|
|
|
5039
5253
|
import { mkdirSync as mkdirSync9 } from "node:fs";
|
|
5040
5254
|
import { dirname as dirname5 } from "node:path";
|
|
5041
5255
|
import { DatabaseSync as DatabaseSync5 } from "node:sqlite";
|
|
5042
|
-
var STATUSES = /* @__PURE__ */ new Set(["
|
|
5256
|
+
var STATUSES = /* @__PURE__ */ new Set(["TODO", "IN-PROCESS", "WAITING", "COMPLETED", "CANCELLED"]);
|
|
5043
5257
|
function now() {
|
|
5044
5258
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5045
5259
|
}
|
|
@@ -5049,6 +5263,8 @@ function rowToTask(row) {
|
|
|
5049
5263
|
id: String(row.id),
|
|
5050
5264
|
accountId: String(row.account_id),
|
|
5051
5265
|
projectId: row.project_id === null || row.project_id === void 0 ? null : String(row.project_id),
|
|
5266
|
+
parentId: row.parent_id === null || row.parent_id === void 0 ? null : String(row.parent_id),
|
|
5267
|
+
waitingOn: String(row.waiting_on ?? ""),
|
|
5052
5268
|
calendarHref: row.calendar_href === null || row.calendar_href === void 0 ? null : String(row.calendar_href),
|
|
5053
5269
|
href: row.href === null || row.href === void 0 ? null : String(row.href),
|
|
5054
5270
|
etag: row.etag === null || row.etag === void 0 ? null : String(row.etag),
|
|
@@ -5069,8 +5285,9 @@ function rowToTask(row) {
|
|
|
5069
5285
|
};
|
|
5070
5286
|
}
|
|
5071
5287
|
function statusOf(value) {
|
|
5072
|
-
const text2 = String(value ?? "
|
|
5073
|
-
|
|
5288
|
+
const text2 = String(value ?? "TODO").toUpperCase();
|
|
5289
|
+
if (text2 === "NEEDS-ACTION") return "TODO";
|
|
5290
|
+
return STATUSES.has(text2) ? text2 : "TODO";
|
|
5074
5291
|
}
|
|
5075
5292
|
var TaskStore = class {
|
|
5076
5293
|
file;
|
|
@@ -5095,6 +5312,8 @@ var TaskStore = class {
|
|
|
5095
5312
|
id TEXT PRIMARY KEY,
|
|
5096
5313
|
account_id TEXT NOT NULL,
|
|
5097
5314
|
project_id TEXT,
|
|
5315
|
+
parent_id TEXT,
|
|
5316
|
+
waiting_on TEXT,
|
|
5098
5317
|
calendar_href TEXT,
|
|
5099
5318
|
href TEXT,
|
|
5100
5319
|
etag TEXT,
|
|
@@ -5124,6 +5343,14 @@ var TaskStore = class {
|
|
|
5124
5343
|
error TEXT
|
|
5125
5344
|
);
|
|
5126
5345
|
`);
|
|
5346
|
+
const columns = db.prepare("PRAGMA table_info(tasks)").all();
|
|
5347
|
+
if (!columns.some((column) => column.name === "parent_id")) {
|
|
5348
|
+
db.exec("ALTER TABLE tasks ADD COLUMN parent_id TEXT");
|
|
5349
|
+
}
|
|
5350
|
+
if (!columns.some((column) => column.name === "waiting_on")) {
|
|
5351
|
+
db.exec("ALTER TABLE tasks ADD COLUMN waiting_on TEXT");
|
|
5352
|
+
}
|
|
5353
|
+
db.exec("UPDATE tasks SET status = 'TODO' WHERE status = 'NEEDS-ACTION'");
|
|
5127
5354
|
this.db = db;
|
|
5128
5355
|
return db;
|
|
5129
5356
|
}
|
|
@@ -5163,16 +5390,26 @@ var TaskStore = class {
|
|
|
5163
5390
|
if (title === "") throw new Error("\u4EFB\u52A1\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A");
|
|
5164
5391
|
if (title.length > 300) throw new Error("\u4EFB\u52A1\u6807\u9898\u8FC7\u957F");
|
|
5165
5392
|
const status = statusOf(input.status);
|
|
5393
|
+
if (status === "WAITING" && String(input.waitingOn ?? "").trim() === "") {
|
|
5394
|
+
throw new Error("\u7B49\u5F85\u4E2D\u4EFB\u52A1\u9700\u8981\u586B\u5199\u7B49\u8C01/\u7B49\u4EC0\u4E48");
|
|
5395
|
+
}
|
|
5396
|
+
if (input.parentId !== void 0 && input.parentId !== null) {
|
|
5397
|
+
const parent = this.get(input.parentId);
|
|
5398
|
+
if (parent === void 0) throw new Error("\u7236\u4EFB\u52A1\u4E0D\u5B58\u5728");
|
|
5399
|
+
if (parent.parentId !== null) throw new Error("\u5B50\u4EFB\u52A1\u4E0B\u4E0D\u80FD\u518D\u5EFA\u5B50\u4EFB\u52A1");
|
|
5400
|
+
}
|
|
5166
5401
|
const id = `task_${randomUUID5()}`;
|
|
5167
5402
|
const stamp3 = now();
|
|
5168
5403
|
this.open().prepare(
|
|
5169
|
-
`INSERT INTO tasks (id, account_id, project_id, uid, title, notes, due, status,
|
|
5170
|
-
message_key, message_subject, completed_at, dirty, deleted, created_at, updated_at)
|
|
5171
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?, ?)`
|
|
5404
|
+
`INSERT INTO tasks (id, account_id, project_id, parent_id, waiting_on, uid, title, notes, due, status,
|
|
5405
|
+
priority, owner, message_key, message_subject, completed_at, dirty, deleted, created_at, updated_at)
|
|
5406
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?, ?)`
|
|
5172
5407
|
).run(
|
|
5173
5408
|
id,
|
|
5174
5409
|
input.accountId,
|
|
5175
5410
|
input.projectId ?? null,
|
|
5411
|
+
input.parentId ?? null,
|
|
5412
|
+
String(input.waitingOn ?? ""),
|
|
5176
5413
|
`${randomUUID5()}@dsh-mailharbor`,
|
|
5177
5414
|
title,
|
|
5178
5415
|
String(input.notes ?? ""),
|
|
@@ -5201,15 +5438,27 @@ var TaskStore = class {
|
|
|
5201
5438
|
priority: fields.priority === void 0 ? current.priority : Number(fields.priority),
|
|
5202
5439
|
owner: fields.owner === void 0 ? current.owner : String(fields.owner ?? ""),
|
|
5203
5440
|
projectId: fields.projectId === void 0 ? current.projectId : fields.projectId,
|
|
5441
|
+
parentId: fields.parentId === void 0 ? current.parentId : fields.parentId,
|
|
5442
|
+
waitingOn: fields.waitingOn === void 0 ? current.waitingOn : String(fields.waitingOn ?? ""),
|
|
5204
5443
|
messageKey: fields.messageKey === void 0 ? current.messageKey : String(fields.messageKey),
|
|
5205
5444
|
messageSubject: fields.messageSubject === void 0 ? current.messageSubject : String(fields.messageSubject)
|
|
5206
5445
|
};
|
|
5207
5446
|
if (next.title === "") throw new Error("\u4EFB\u52A1\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A");
|
|
5447
|
+
if (next.status === "WAITING" && next.waitingOn.trim() === "") {
|
|
5448
|
+
throw new Error("\u7B49\u5F85\u4E2D\u4EFB\u52A1\u9700\u8981\u586B\u5199\u7B49\u8C01/\u7B49\u4EC0\u4E48");
|
|
5449
|
+
}
|
|
5450
|
+
if (next.parentId !== null) {
|
|
5451
|
+
if (next.parentId === id) throw new Error("\u4EFB\u52A1\u4E0D\u80FD\u4F5C\u4E3A\u81EA\u5DF1\u7684\u5B50\u4EFB\u52A1");
|
|
5452
|
+
const parent = this.get(next.parentId);
|
|
5453
|
+
if (parent === void 0) throw new Error("\u7236\u4EFB\u52A1\u4E0D\u5B58\u5728");
|
|
5454
|
+
if (parent.parentId !== null) throw new Error("\u5B50\u4EFB\u52A1\u4E0B\u4E0D\u80FD\u518D\u5EFA\u5B50\u4EFB\u52A1");
|
|
5455
|
+
}
|
|
5208
5456
|
const stamp3 = now();
|
|
5209
5457
|
const completedAt = next.status === "COMPLETED" ? current.completedAt ?? stamp3 : null;
|
|
5210
5458
|
this.open().prepare(
|
|
5211
5459
|
`UPDATE tasks SET title = ?, notes = ?, due = ?, status = ?, priority = ?, owner = ?, project_id = ?,
|
|
5212
|
-
|
|
5460
|
+
parent_id = ?, waiting_on = ?, message_key = ?, message_subject = ?, completed_at = ?,
|
|
5461
|
+
dirty = 1, updated_at = ? WHERE id = ?`
|
|
5213
5462
|
).run(
|
|
5214
5463
|
next.title,
|
|
5215
5464
|
next.notes,
|
|
@@ -5218,6 +5467,8 @@ var TaskStore = class {
|
|
|
5218
5467
|
Math.max(0, Math.min(9, Number(next.priority) || 0)),
|
|
5219
5468
|
next.owner,
|
|
5220
5469
|
next.projectId,
|
|
5470
|
+
next.parentId,
|
|
5471
|
+
next.waitingOn,
|
|
5221
5472
|
next.messageKey,
|
|
5222
5473
|
next.messageSubject,
|
|
5223
5474
|
completedAt,
|