@opsee/mcp-server 0.5.7 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -3
- package/gen/api/v1/acceptance_criterion_pb.d.ts +195 -0
- package/gen/api/v1/acceptance_criterion_pb.js +73 -0
- package/gen/api/v1/doc_template_pb.d.ts +244 -0
- package/gen/api/v1/doc_template_pb.js +77 -0
- package/gen/api/v1/models_pb.d.ts +163 -1
- package/gen/api/v1/models_pb.js +28 -2
- package/gen/api/v1/task_dependency_pb.d.ts +217 -0
- package/gen/api/v1/task_dependency_pb.js +74 -0
- package/gen/api/v1/task_pb.d.ts +54 -1
- package/gen/api/v1/task_pb.js +1 -1
- package/gen/api/v1/task_template_pb.d.ts +349 -0
- package/gen/api/v1/task_template_pb.js +77 -0
- package/package.json +1 -1
- package/src/__tests__/tools.test.ts +409 -3
- package/src/client/api.ts +18 -0
- package/src/server.ts +12 -0
- package/src/tools/acceptance-criteria.ts +127 -0
- package/src/tools/comments.ts +135 -0
- package/src/tools/cycles.ts +189 -1
- package/src/tools/docs.ts +1 -1
- package/src/tools/labels.ts +199 -0
- package/src/tools/milestones.ts +3 -3
- package/src/tools/notifications.ts +171 -0
- package/src/tools/task-dependencies.ts +138 -0
- package/src/tools/tasks.ts +364 -11
- package/src/tools/user.ts +41 -1
- package/src/tools/work-logs.ts +123 -0
- package/src/utils/format.ts +84 -1
package/src/utils/format.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Task, Project, Cycle, DocPage, DocSpace, Milestone, MilestoneTask } from "../../gen/api/v1/models_pb.js";
|
|
1
|
+
import type { Task, Project, Cycle, DocPage, DocSpace, Milestone, MilestoneTask, User, Label, TaskLabel, Comment, TaskDependency } from "../../gen/api/v1/models_pb.js";
|
|
2
|
+
import { TaskDependencyType } from "../../gen/api/v1/models_pb.js";
|
|
2
3
|
|
|
3
4
|
export function formatProject(p: Project): string {
|
|
4
5
|
const lines = [
|
|
@@ -32,6 +33,9 @@ export function formatTask(t: Task): string {
|
|
|
32
33
|
const cycle = t.cycle?.name || "None";
|
|
33
34
|
lines.push(` Assignee: ${assignee} | Cycle: ${cycle}`);
|
|
34
35
|
|
|
36
|
+
if (t.storyPoints) lines.push(` Story Points: ${t.storyPoints}`);
|
|
37
|
+
if (t.estimatedHours) lines.push(` Estimated Hours: ${t.estimatedHours}`);
|
|
38
|
+
|
|
35
39
|
if (t.description) {
|
|
36
40
|
const desc =
|
|
37
41
|
t.description.length > 200
|
|
@@ -162,6 +166,85 @@ export function formatMilestoneTaskList(milestoneTasks: MilestoneTask[]): string
|
|
|
162
166
|
return header + milestoneTasks.map((mt, i) => `${i + 1}. ${formatMilestoneTask(mt)}`).join("\n\n");
|
|
163
167
|
}
|
|
164
168
|
|
|
169
|
+
export function formatUser(u: User): string {
|
|
170
|
+
const lines = [`${u.fullName} (${u.email})`];
|
|
171
|
+
lines.push(` ID: ${u.id}`);
|
|
172
|
+
if (u.flattenedRoles?.length) lines.push(` Roles: ${u.flattenedRoles.join(", ")}`);
|
|
173
|
+
return lines.join("\n");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function formatUserList(users: User[]): string {
|
|
177
|
+
if (users.length === 0) return "No users found.";
|
|
178
|
+
const header = `Found ${users.length} user(s):\n`;
|
|
179
|
+
return header + users.map((u, i) => `${i + 1}. ${formatUser(u)}`).join("\n\n");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function formatLabel(l: Label): string {
|
|
183
|
+
const lines = [`${l.name}`];
|
|
184
|
+
lines.push(` Color: ${l.color}`);
|
|
185
|
+
if (l.description) lines.push(` Description: ${l.description}`);
|
|
186
|
+
lines.push(` Active: ${l.isActive ? "Yes" : "No"}`);
|
|
187
|
+
lines.push(` Project ID: ${l.projectId}`);
|
|
188
|
+
lines.push(` ID: ${l.id}`);
|
|
189
|
+
return lines.join("\n");
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export function formatLabelList(labels: Label[]): string {
|
|
193
|
+
if (labels.length === 0) return "No labels found.";
|
|
194
|
+
const header = `Found ${labels.length} label(s):\n`;
|
|
195
|
+
return header + labels.map((l, i) => `${i + 1}. ${formatLabel(l)}`).join("\n\n");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function formatTaskLabelList(taskLabels: TaskLabel[]): string {
|
|
199
|
+
if (taskLabels.length === 0) return "No labels attached to this task.";
|
|
200
|
+
const header = `Found ${taskLabels.length} label attachment(s):\n`;
|
|
201
|
+
return header + taskLabels.map((tl, i) => {
|
|
202
|
+
const labelName = tl.label?.name || `Label #${tl.labelId}`;
|
|
203
|
+
return `${i + 1}. ${labelName} (Label ID: ${tl.labelId} | TaskLabel ID: ${tl.id})`;
|
|
204
|
+
}).join("\n");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function formatComment(c: Comment): string {
|
|
208
|
+
const lines = [];
|
|
209
|
+
const author = c.user?.fullName || `User #${c.userId}`;
|
|
210
|
+
const created = c.createdAt
|
|
211
|
+
? new Date((typeof c.createdAt.seconds === "bigint" ? Number(c.createdAt.seconds) : c.createdAt.seconds) * 1000).toISOString()
|
|
212
|
+
: "—";
|
|
213
|
+
lines.push(`${author} @ ${created}${c.isInternal ? " [internal]" : ""}`);
|
|
214
|
+
lines.push(` ${c.content}`);
|
|
215
|
+
lines.push(` ID: ${c.id}`);
|
|
216
|
+
return lines.join("\n");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function formatCommentList(comments: Comment[]): string {
|
|
220
|
+
if (comments.length === 0) return "No comments found.";
|
|
221
|
+
const header = `Found ${comments.length} comment(s):\n`;
|
|
222
|
+
return header + comments.map((c, i) => `${i + 1}. ${formatComment(c)}`).join("\n\n");
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function taskDependencyTypeToString(t: TaskDependencyType): string {
|
|
226
|
+
switch (t) {
|
|
227
|
+
case TaskDependencyType.BLOCKS: return "BLOCKS";
|
|
228
|
+
case TaskDependencyType.BLOCKED_BY: return "BLOCKED_BY";
|
|
229
|
+
case TaskDependencyType.DUPLICATES: return "DUPLICATES";
|
|
230
|
+
case TaskDependencyType.RELATES_TO: return "RELATES_TO";
|
|
231
|
+
default: return "UNSPECIFIED";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function formatTaskDependency(d: TaskDependency): string {
|
|
236
|
+
const typeStr = taskDependencyTypeToString(d.type);
|
|
237
|
+
const from = d.fromTask?.identifier || `Task #${d.fromTaskId}`;
|
|
238
|
+
const to = d.toTask?.identifier || `Task #${d.toTaskId}`;
|
|
239
|
+
return `${from} ${typeStr} ${to}\n ID: ${d.id}`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function formatTaskDependencyList(deps: TaskDependency[]): string {
|
|
243
|
+
if (deps.length === 0) return "No task dependencies found.";
|
|
244
|
+
return `Found ${deps.length} dependency(ies):\n` +
|
|
245
|
+
deps.map((d, i) => `${i + 1}. ${formatTaskDependency(d)}`).join("\n\n");
|
|
246
|
+
}
|
|
247
|
+
|
|
165
248
|
export function formatError(error: unknown): string {
|
|
166
249
|
if (error instanceof Error) {
|
|
167
250
|
const msg = error.message;
|