@opsee/mcp-server 0.5.7 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,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 = [
@@ -162,6 +163,85 @@ export function formatMilestoneTaskList(milestoneTasks: MilestoneTask[]): string
162
163
  return header + milestoneTasks.map((mt, i) => `${i + 1}. ${formatMilestoneTask(mt)}`).join("\n\n");
163
164
  }
164
165
 
166
+ export function formatUser(u: User): string {
167
+ const lines = [`${u.fullName} (${u.email})`];
168
+ lines.push(` ID: ${u.id}`);
169
+ if (u.flattenedRoles?.length) lines.push(` Roles: ${u.flattenedRoles.join(", ")}`);
170
+ return lines.join("\n");
171
+ }
172
+
173
+ export function formatUserList(users: User[]): string {
174
+ if (users.length === 0) return "No users found.";
175
+ const header = `Found ${users.length} user(s):\n`;
176
+ return header + users.map((u, i) => `${i + 1}. ${formatUser(u)}`).join("\n\n");
177
+ }
178
+
179
+ export function formatLabel(l: Label): string {
180
+ const lines = [`${l.name}`];
181
+ lines.push(` Color: ${l.color}`);
182
+ if (l.description) lines.push(` Description: ${l.description}`);
183
+ lines.push(` Active: ${l.isActive ? "Yes" : "No"}`);
184
+ lines.push(` Project ID: ${l.projectId}`);
185
+ lines.push(` ID: ${l.id}`);
186
+ return lines.join("\n");
187
+ }
188
+
189
+ export function formatLabelList(labels: Label[]): string {
190
+ if (labels.length === 0) return "No labels found.";
191
+ const header = `Found ${labels.length} label(s):\n`;
192
+ return header + labels.map((l, i) => `${i + 1}. ${formatLabel(l)}`).join("\n\n");
193
+ }
194
+
195
+ export function formatTaskLabelList(taskLabels: TaskLabel[]): string {
196
+ if (taskLabels.length === 0) return "No labels attached to this task.";
197
+ const header = `Found ${taskLabels.length} label attachment(s):\n`;
198
+ return header + taskLabels.map((tl, i) => {
199
+ const labelName = tl.label?.name || `Label #${tl.labelId}`;
200
+ return `${i + 1}. ${labelName} (Label ID: ${tl.labelId} | TaskLabel ID: ${tl.id})`;
201
+ }).join("\n");
202
+ }
203
+
204
+ export function formatComment(c: Comment): string {
205
+ const lines = [];
206
+ const author = c.user?.fullName || `User #${c.userId}`;
207
+ const created = c.createdAt
208
+ ? new Date((typeof c.createdAt.seconds === "bigint" ? Number(c.createdAt.seconds) : c.createdAt.seconds) * 1000).toISOString()
209
+ : "—";
210
+ lines.push(`${author} @ ${created}${c.isInternal ? " [internal]" : ""}`);
211
+ lines.push(` ${c.content}`);
212
+ lines.push(` ID: ${c.id}`);
213
+ return lines.join("\n");
214
+ }
215
+
216
+ export function formatCommentList(comments: Comment[]): string {
217
+ if (comments.length === 0) return "No comments found.";
218
+ const header = `Found ${comments.length} comment(s):\n`;
219
+ return header + comments.map((c, i) => `${i + 1}. ${formatComment(c)}`).join("\n\n");
220
+ }
221
+
222
+ function taskDependencyTypeToString(t: TaskDependencyType): string {
223
+ switch (t) {
224
+ case TaskDependencyType.BLOCKS: return "BLOCKS";
225
+ case TaskDependencyType.BLOCKED_BY: return "BLOCKED_BY";
226
+ case TaskDependencyType.DUPLICATES: return "DUPLICATES";
227
+ case TaskDependencyType.RELATES_TO: return "RELATES_TO";
228
+ default: return "UNSPECIFIED";
229
+ }
230
+ }
231
+
232
+ export function formatTaskDependency(d: TaskDependency): string {
233
+ const typeStr = taskDependencyTypeToString(d.type);
234
+ const from = d.fromTask?.identifier || `Task #${d.fromTaskId}`;
235
+ const to = d.toTask?.identifier || `Task #${d.toTaskId}`;
236
+ return `${from} ${typeStr} ${to}\n ID: ${d.id}`;
237
+ }
238
+
239
+ export function formatTaskDependencyList(deps: TaskDependency[]): string {
240
+ if (deps.length === 0) return "No task dependencies found.";
241
+ return `Found ${deps.length} dependency(ies):\n` +
242
+ deps.map((d, i) => `${i + 1}. ${formatTaskDependency(d)}`).join("\n\n");
243
+ }
244
+
165
245
  export function formatError(error: unknown): string {
166
246
  if (error instanceof Error) {
167
247
  const msg = error.message;