planflow-mcp 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/dist/index.js +808 -62
  2. package/package.json +2 -3
package/dist/index.js CHANGED
@@ -7,7 +7,753 @@ import {
7
7
  CallToolRequestSchema,
8
8
  ListToolsRequestSchema
9
9
  } from "@modelcontextprotocol/sdk/types.js";
10
- import { APP_NAME, APP_VERSION } from "@planflow/shared";
10
+
11
+ // ../shared/dist/index.js
12
+ import { z } from "zod";
13
+ var UserSchema = z.object({
14
+ id: z.string().uuid(),
15
+ email: z.string().email(),
16
+ name: z.string().min(1),
17
+ createdAt: z.date(),
18
+ updatedAt: z.date()
19
+ });
20
+ var RegisterRequestSchema = z.object({
21
+ email: z.string().email("Invalid email address"),
22
+ password: z.string().min(8, "Password must be at least 8 characters").max(72, "Password must be at most 72 characters"),
23
+ // bcrypt limit
24
+ name: z.string().min(1, "Name is required").max(100, "Name must be at most 100 characters")
25
+ });
26
+ var LoginRequestSchema = z.object({
27
+ email: z.string().email("Invalid email address"),
28
+ password: z.string().min(1, "Password is required")
29
+ });
30
+ var AuthResponseSchema = z.object({
31
+ user: UserSchema,
32
+ token: z.string(),
33
+ refreshToken: z.string(),
34
+ expiresIn: z.number(),
35
+ // seconds until access token expires
36
+ refreshExpiresIn: z.number()
37
+ // seconds until refresh token expires
38
+ });
39
+ var ForgotPasswordRequestSchema = z.object({
40
+ email: z.string().email("Invalid email address")
41
+ });
42
+ var RefreshTokenRequestSchema = z.object({
43
+ refreshToken: z.string().min(1, "Refresh token is required")
44
+ });
45
+ var TokenRefreshResponseSchema = z.object({
46
+ token: z.string(),
47
+ expiresIn: z.number()
48
+ });
49
+ var SessionSchema = z.object({
50
+ id: z.string().uuid(),
51
+ createdAt: z.date(),
52
+ expiresAt: z.date(),
53
+ isCurrent: z.boolean()
54
+ // true if this is the session making the request
55
+ });
56
+ var SessionsResponseSchema = z.object({
57
+ sessions: z.array(SessionSchema),
58
+ total: z.number()
59
+ });
60
+ var LogoutAllResponseSchema = z.object({
61
+ revokedCount: z.number(),
62
+ message: z.string()
63
+ });
64
+ var ProjectSchema = z.object({
65
+ id: z.string().uuid(),
66
+ name: z.string().min(1),
67
+ description: z.string().optional(),
68
+ userId: z.string().uuid(),
69
+ plan: z.string().optional(),
70
+ createdAt: z.date(),
71
+ updatedAt: z.date()
72
+ });
73
+ var CreateProjectRequestSchema = z.object({
74
+ name: z.string().min(1, "Project name is required").max(255, "Project name must be at most 255 characters"),
75
+ description: z.string().max(2e3, "Description must be at most 2000 characters").optional(),
76
+ plan: z.string().optional(),
77
+ organizationId: z.string().uuid("Invalid organization ID")
78
+ });
79
+ var UpdateProjectRequestSchema = z.object({
80
+ name: z.string().min(1, "Project name cannot be empty").max(255, "Project name must be at most 255 characters").optional(),
81
+ description: z.string().max(2e3, "Description must be at most 2000 characters").nullable().optional(),
82
+ plan: z.string().nullable().optional()
83
+ });
84
+ var TaskStatusSchema = z.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]);
85
+ var TaskComplexitySchema = z.enum(["Low", "Medium", "High"]);
86
+ var TaskSchema = z.object({
87
+ id: z.string().uuid(),
88
+ projectId: z.string().uuid(),
89
+ taskId: z.string(),
90
+ // e.g., "T1.1"
91
+ name: z.string().min(1),
92
+ description: z.string().optional(),
93
+ status: TaskStatusSchema,
94
+ complexity: TaskComplexitySchema,
95
+ estimatedHours: z.number().positive().optional(),
96
+ dependencies: z.array(z.string()).default([]),
97
+ createdAt: z.date(),
98
+ updatedAt: z.date()
99
+ });
100
+ var CreateTaskRequestSchema = z.object({
101
+ taskId: z.string().min(1, "Task ID is required"),
102
+ // e.g., "T1.1"
103
+ name: z.string().min(1, "Task name is required").max(255, "Task name must be at most 255 characters"),
104
+ description: z.string().max(2e3, "Description must be at most 2000 characters").optional(),
105
+ status: TaskStatusSchema.optional().default("TODO"),
106
+ complexity: TaskComplexitySchema.optional().default("Medium"),
107
+ estimatedHours: z.number().positive("Estimated hours must be positive").optional(),
108
+ dependencies: z.array(z.string()).default([])
109
+ });
110
+ var UpdateTaskRequestSchema = z.object({
111
+ taskId: z.string().min(1).optional(),
112
+ name: z.string().min(1).max(255).optional(),
113
+ description: z.string().max(2e3).nullable().optional(),
114
+ status: TaskStatusSchema.optional(),
115
+ complexity: TaskComplexitySchema.optional(),
116
+ estimatedHours: z.number().positive().nullable().optional(),
117
+ dependencies: z.array(z.string()).optional()
118
+ });
119
+ var BulkUpdateTasksRequestSchema = z.object({
120
+ tasks: z.array(
121
+ z.object({
122
+ id: z.string().uuid("Invalid task ID format"),
123
+ taskId: z.string().min(1).optional(),
124
+ name: z.string().min(1).max(255).optional(),
125
+ description: z.string().max(2e3).nullable().optional(),
126
+ status: TaskStatusSchema.optional(),
127
+ complexity: TaskComplexitySchema.optional(),
128
+ estimatedHours: z.number().positive().nullable().optional(),
129
+ dependencies: z.array(z.string()).optional()
130
+ })
131
+ ).min(1, "At least one task must be provided")
132
+ });
133
+ var BulkAssignTasksRequestSchema = z.object({
134
+ taskIds: z.array(z.string().uuid("Invalid task ID format")).min(1, "At least one task must be provided").max(100, "Maximum 100 tasks allowed"),
135
+ assigneeId: z.string().uuid("Invalid assignee ID format").nullable()
136
+ });
137
+ var BulkDeleteTasksRequestSchema = z.object({
138
+ taskIds: z.array(z.string().uuid("Invalid task ID format")).min(1, "At least one task must be provided").max(100, "Maximum 100 tasks allowed")
139
+ });
140
+ var BulkStatusUpdateRequestSchema = z.object({
141
+ taskIds: z.array(z.string().uuid("Invalid task ID format")).min(1, "At least one task must be provided").max(100, "Maximum 100 tasks allowed"),
142
+ status: TaskStatusSchema
143
+ });
144
+ var ApiTokenSchema = z.object({
145
+ id: z.string().uuid(),
146
+ userId: z.string().uuid(),
147
+ name: z.string().min(1),
148
+ lastUsedAt: z.date().nullable(),
149
+ expiresAt: z.date().nullable(),
150
+ isRevoked: z.boolean(),
151
+ createdAt: z.date()
152
+ });
153
+ var CreateApiTokenRequestSchema = z.object({
154
+ name: z.string().min(1, "Token name is required").max(100, "Token name must be at most 100 characters"),
155
+ expiresInDays: z.number().int().min(1, "Expiration must be at least 1 day").max(365, "Expiration must be at most 365 days").optional()
156
+ });
157
+ var UpdateProfileRequestSchema = z.object({
158
+ name: z.string().min(1, "Name is required").max(100, "Name must be at most 100 characters").optional(),
159
+ email: z.string().email("Invalid email address").optional()
160
+ });
161
+ var ChangePasswordRequestSchema = z.object({
162
+ currentPassword: z.string().min(1, "Current password is required"),
163
+ newPassword: z.string().min(8, "New password must be at least 8 characters").max(72, "New password must be at most 72 characters")
164
+ });
165
+ var SubscriptionTierSchema = z.enum(["free", "pro", "team", "enterprise"]);
166
+ var SubscriptionStatusSchema = z.enum(["active", "canceled", "past_due", "trialing"]);
167
+ var SubscriptionSchema = z.object({
168
+ id: z.string().uuid(),
169
+ userId: z.string().uuid(),
170
+ tier: SubscriptionTierSchema,
171
+ status: SubscriptionStatusSchema,
172
+ lemonSqueezyCustomerId: z.string().nullable(),
173
+ lemonSqueezySubscriptionId: z.string().nullable(),
174
+ currentPeriodStart: z.date().nullable(),
175
+ currentPeriodEnd: z.date().nullable(),
176
+ canceledAt: z.date().nullable(),
177
+ createdAt: z.date(),
178
+ updatedAt: z.date()
179
+ });
180
+ var CreateCheckoutRequestSchema = z.object({
181
+ tier: z.enum(["pro", "team"], {
182
+ required_error: "Tier is required",
183
+ invalid_type_error: 'Tier must be either "pro" or "team"'
184
+ })
185
+ });
186
+ var CheckoutResponseSchema = z.object({
187
+ checkoutUrl: z.string().url()
188
+ });
189
+ var ProjectLimitsSchema = z.object({
190
+ currentCount: z.number(),
191
+ maxProjects: z.number(),
192
+ // -1 = unlimited
193
+ canCreate: z.boolean(),
194
+ tier: SubscriptionTierSchema,
195
+ status: SubscriptionStatusSchema
196
+ });
197
+ var FeedbackCategorySchema = z.enum(["general", "bug", "feature", "usability", "performance"]);
198
+ var FeedbackSchema = z.object({
199
+ id: z.string().uuid(),
200
+ userId: z.string().uuid(),
201
+ category: FeedbackCategorySchema,
202
+ rating: z.number().int().min(1).max(5),
203
+ message: z.string(),
204
+ userAgent: z.string().nullable(),
205
+ pageUrl: z.string().nullable(),
206
+ createdAt: z.date()
207
+ });
208
+ var CreateFeedbackRequestSchema = z.object({
209
+ category: FeedbackCategorySchema.default("general"),
210
+ rating: z.number().int("Rating must be a whole number").min(1, "Rating must be at least 1").max(5, "Rating must be at most 5"),
211
+ message: z.string().min(10, "Please provide at least 10 characters of feedback").max(5e3, "Feedback must be at most 5000 characters"),
212
+ pageUrl: z.string().url().optional()
213
+ });
214
+ var OrgMemberRoleSchema = z.enum(["owner", "admin", "editor", "viewer"]);
215
+ var OrganizationSchema = z.object({
216
+ id: z.string().uuid(),
217
+ name: z.string().min(1),
218
+ slug: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
219
+ description: z.string().nullable().optional(),
220
+ createdBy: z.string().uuid(),
221
+ createdAt: z.date(),
222
+ updatedAt: z.date()
223
+ });
224
+ var OrganizationMemberSchema = z.object({
225
+ id: z.string().uuid(),
226
+ organizationId: z.string().uuid(),
227
+ userId: z.string().uuid(),
228
+ role: OrgMemberRoleSchema,
229
+ createdAt: z.date(),
230
+ updatedAt: z.date()
231
+ });
232
+ var CreateOrganizationRequestSchema = z.object({
233
+ name: z.string().min(1, "Organization name is required").max(255, "Organization name must be at most 255 characters"),
234
+ slug: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Slug must be lowercase alphanumeric with hyphens").max(255, "Slug must be at most 255 characters").optional(),
235
+ description: z.string().max(2e3, "Description must be at most 2000 characters").optional()
236
+ });
237
+ var UpdateOrganizationRequestSchema = z.object({
238
+ name: z.string().min(1, "Organization name cannot be empty").max(255, "Organization name must be at most 255 characters").optional(),
239
+ slug: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Slug must be lowercase alphanumeric with hyphens").max(255, "Slug must be at most 255 characters").optional(),
240
+ description: z.string().max(2e3, "Description must be at most 2000 characters").nullable().optional()
241
+ });
242
+ var CreateInvitationRequestSchema = z.object({
243
+ email: z.string().email("Invalid email address"),
244
+ role: z.enum(["admin", "editor", "viewer"]).optional().default("editor")
245
+ });
246
+ var InvitationSchema = z.object({
247
+ id: z.string().uuid(),
248
+ organizationId: z.string().uuid(),
249
+ email: z.string().email(),
250
+ role: OrgMemberRoleSchema,
251
+ invitedBy: z.string().uuid(),
252
+ token: z.string(),
253
+ expiresAt: z.date(),
254
+ acceptedAt: z.date().nullable(),
255
+ createdAt: z.date()
256
+ });
257
+ var UpdateMemberRoleRequestSchema = z.object({
258
+ role: z.enum(["admin", "editor", "viewer"], {
259
+ required_error: "Role is required",
260
+ invalid_type_error: "Role must be admin, editor, or viewer"
261
+ })
262
+ });
263
+ var ProjectMemberRoleSchema = z.enum(["owner", "editor", "viewer"]);
264
+ var ProjectMemberSchema = z.object({
265
+ id: z.string().uuid(),
266
+ projectId: z.string().uuid(),
267
+ userId: z.string().uuid(),
268
+ role: ProjectMemberRoleSchema,
269
+ invitedBy: z.string().uuid().nullable(),
270
+ createdAt: z.date(),
271
+ updatedAt: z.date()
272
+ });
273
+ var ProjectMemberWithUserSchema = ProjectMemberSchema.extend({
274
+ userName: z.string().nullable(),
275
+ userEmail: z.string().email()
276
+ });
277
+ var CreateProjectInvitationRequestSchema = z.object({
278
+ email: z.string().email("Invalid email address"),
279
+ role: z.enum(["editor", "viewer"]).optional().default("editor")
280
+ });
281
+ var ProjectInvitationSchema = z.object({
282
+ id: z.string().uuid(),
283
+ projectId: z.string().uuid(),
284
+ email: z.string().email(),
285
+ role: ProjectMemberRoleSchema,
286
+ invitedBy: z.string().uuid(),
287
+ token: z.string(),
288
+ expiresAt: z.date(),
289
+ acceptedAt: z.date().nullable(),
290
+ createdAt: z.date()
291
+ });
292
+ var ProjectInvitationWithDetailsSchema = ProjectInvitationSchema.extend({
293
+ inviterName: z.string().nullable(),
294
+ projectName: z.string(),
295
+ organizationName: z.string()
296
+ });
297
+ var UpdateProjectMemberRoleRequestSchema = z.object({
298
+ role: z.enum(["editor", "viewer"], {
299
+ required_error: "Role is required",
300
+ invalid_type_error: "Role must be editor or viewer"
301
+ })
302
+ });
303
+ var AssignTaskRequestSchema = z.object({
304
+ assigneeId: z.string().uuid("Invalid user ID format")
305
+ });
306
+ var TaskAssignmentSchema = z.object({
307
+ taskId: z.string(),
308
+ assigneeId: z.string().uuid().nullable(),
309
+ assignedBy: z.string().uuid().nullable(),
310
+ assignedAt: z.date().nullable()
311
+ });
312
+ var TaskWithAssigneeSchema = TaskSchema.extend({
313
+ assigneeId: z.string().uuid().nullable(),
314
+ assignedBy: z.string().uuid().nullable(),
315
+ assignedAt: z.date().nullable(),
316
+ assignee: z.object({
317
+ id: z.string().uuid(),
318
+ email: z.string().email(),
319
+ name: z.string().nullable()
320
+ }).nullable().optional()
321
+ });
322
+ var CommentSchema = z.object({
323
+ id: z.string().uuid(),
324
+ taskId: z.string().uuid(),
325
+ authorId: z.string().uuid(),
326
+ content: z.string().min(1),
327
+ parentId: z.string().uuid().nullable(),
328
+ mentions: z.array(z.string().uuid()).nullable(),
329
+ createdAt: z.date(),
330
+ updatedAt: z.date()
331
+ });
332
+ var CreateCommentRequestSchema = z.object({
333
+ content: z.string().min(1, "Comment content is required").max(1e4, "Comment must be at most 10000 characters"),
334
+ parentId: z.string().uuid("Invalid parent comment ID").optional(),
335
+ mentions: z.array(z.string().uuid("Invalid user ID in mentions")).optional()
336
+ });
337
+ var UpdateCommentRequestSchema = z.object({
338
+ content: z.string().min(1, "Comment content cannot be empty").max(1e4, "Comment must be at most 10000 characters").optional(),
339
+ mentions: z.array(z.string().uuid("Invalid user ID in mentions")).optional()
340
+ });
341
+ var CommentAuthorSchema = z.object({
342
+ id: z.string().uuid(),
343
+ email: z.string().email(),
344
+ name: z.string().nullable()
345
+ });
346
+ var CommentWithAuthorSchema = CommentSchema.extend({
347
+ author: CommentAuthorSchema
348
+ });
349
+ var ActivityActionSchema = z.enum([
350
+ "task_created",
351
+ "task_updated",
352
+ "task_deleted",
353
+ "task_status_changed",
354
+ "task_assigned",
355
+ "task_unassigned",
356
+ "comment_created",
357
+ "comment_updated",
358
+ "comment_deleted",
359
+ "project_created",
360
+ "project_updated",
361
+ "project_deleted",
362
+ "plan_updated",
363
+ "member_invited",
364
+ "member_joined",
365
+ "member_removed",
366
+ "member_role_changed",
367
+ "other"
368
+ ]);
369
+ var ActivityEntitySchema = z.enum([
370
+ "task",
371
+ "comment",
372
+ "project",
373
+ "organization",
374
+ "member",
375
+ "invitation"
376
+ ]);
377
+ var ActivityMetadataSchema = z.record(z.unknown()).optional();
378
+ var ActivityLogSchema = z.object({
379
+ id: z.string().uuid(),
380
+ action: ActivityActionSchema,
381
+ entityType: ActivityEntitySchema,
382
+ entityId: z.string().uuid().nullable(),
383
+ taskId: z.string().nullable(),
384
+ // Human-readable task ID like "T1.1"
385
+ actorId: z.string().uuid(),
386
+ organizationId: z.string().uuid().nullable(),
387
+ projectId: z.string().uuid().nullable(),
388
+ taskUuid: z.string().uuid().nullable(),
389
+ metadata: ActivityMetadataSchema,
390
+ description: z.string().nullable(),
391
+ createdAt: z.date()
392
+ });
393
+ var ActivityActorSchema = z.object({
394
+ id: z.string().uuid(),
395
+ email: z.string().email(),
396
+ name: z.string().nullable()
397
+ });
398
+ var ActivityLogWithActorSchema = ActivityLogSchema.extend({
399
+ actor: ActivityActorSchema
400
+ });
401
+ var ActivityLogQuerySchema = z.object({
402
+ limit: z.coerce.number().int().min(1).max(100).optional().default(50),
403
+ offset: z.coerce.number().int().min(0).optional().default(0),
404
+ action: ActivityActionSchema.optional(),
405
+ entityType: ActivityEntitySchema.optional(),
406
+ actorId: z.string().uuid().optional(),
407
+ taskId: z.string().optional()
408
+ // Human-readable task ID filter
409
+ });
410
+ var CreateActivityLogRequestSchema = z.object({
411
+ action: ActivityActionSchema,
412
+ entityType: ActivityEntitySchema,
413
+ entityId: z.string().uuid().optional(),
414
+ taskId: z.string().optional(),
415
+ organizationId: z.string().uuid().optional(),
416
+ projectId: z.string().uuid().optional(),
417
+ taskUuid: z.string().uuid().optional(),
418
+ metadata: ActivityMetadataSchema,
419
+ description: z.string().max(1e3).optional()
420
+ });
421
+ var WebSocketMessageSchema = z.object({
422
+ type: z.string(),
423
+ projectId: z.string().uuid(),
424
+ timestamp: z.string().datetime(),
425
+ data: z.record(z.unknown()).optional()
426
+ });
427
+ var WebSocketEventTypeSchema = z.enum([
428
+ "connected",
429
+ "task_updated",
430
+ "task_assigned",
431
+ "task_unassigned",
432
+ "tasks_synced",
433
+ "project_updated",
434
+ "ping",
435
+ "pong",
436
+ // Presence events (T5.9)
437
+ "presence_joined",
438
+ "presence_left",
439
+ "presence_updated",
440
+ "presence_list"
441
+ ]);
442
+ var WebSocketTaskDataSchema = z.object({
443
+ id: z.string().uuid(),
444
+ taskId: z.string(),
445
+ name: z.string(),
446
+ description: z.string().nullable(),
447
+ status: z.string(),
448
+ complexity: z.string().nullable(),
449
+ estimatedHours: z.number().nullable(),
450
+ dependencies: z.array(z.string()),
451
+ assigneeId: z.string().uuid().nullable().optional(),
452
+ assignedBy: z.string().uuid().nullable().optional(),
453
+ assignedAt: z.coerce.date().nullable().optional(),
454
+ createdAt: z.coerce.date(),
455
+ updatedAt: z.coerce.date()
456
+ });
457
+ var WebSocketUserInfoSchema = z.object({
458
+ id: z.string().uuid(),
459
+ email: z.string().email(),
460
+ name: z.string().nullable()
461
+ });
462
+ var ConnectedEventDataSchema = z.object({
463
+ userId: z.string().uuid(),
464
+ projectName: z.string()
465
+ });
466
+ var TaskUpdatedEventDataSchema = z.object({
467
+ task: WebSocketTaskDataSchema
468
+ });
469
+ var TaskAssignedEventDataSchema = z.object({
470
+ task: WebSocketTaskDataSchema,
471
+ assignee: WebSocketUserInfoSchema.nullable(),
472
+ assignedBy: WebSocketUserInfoSchema
473
+ });
474
+ var TaskUnassignedEventDataSchema = z.object({
475
+ task: WebSocketTaskDataSchema,
476
+ previousAssigneeId: z.string().uuid().nullable(),
477
+ unassignedBy: WebSocketUserInfoSchema
478
+ });
479
+ var TasksSyncedEventDataSchema = z.object({
480
+ tasksCount: z.number(),
481
+ completedCount: z.number(),
482
+ progress: z.number()
483
+ });
484
+ var ProjectUpdatedEventDataSchema = z.object({
485
+ updatedFields: z.object({
486
+ name: z.string().optional(),
487
+ description: z.string().nullable().optional(),
488
+ updatedAt: z.string().datetime()
489
+ })
490
+ });
491
+ var PresenceStatusSchema = z.enum(["online", "idle", "away"]);
492
+ var UserPresenceSchema = z.object({
493
+ userId: z.string().uuid(),
494
+ email: z.string().email(),
495
+ name: z.string().nullable(),
496
+ status: PresenceStatusSchema,
497
+ connectedAt: z.string().datetime(),
498
+ lastActiveAt: z.string().datetime()
499
+ });
500
+ var PresenceJoinedEventDataSchema = z.object({
501
+ user: UserPresenceSchema,
502
+ onlineCount: z.number().int().min(0)
503
+ });
504
+ var PresenceLeftEventDataSchema = z.object({
505
+ userId: z.string().uuid(),
506
+ onlineCount: z.number().int().min(0)
507
+ });
508
+ var PresenceUpdatedEventDataSchema = z.object({
509
+ userId: z.string().uuid(),
510
+ status: PresenceStatusSchema,
511
+ lastActiveAt: z.string().datetime()
512
+ });
513
+ var PresenceListEventDataSchema = z.object({
514
+ users: z.array(UserPresenceSchema),
515
+ onlineCount: z.number().int().min(0)
516
+ });
517
+ var NotificationTypeSchema = z.enum([
518
+ "mention",
519
+ "assignment",
520
+ "unassignment",
521
+ "comment",
522
+ "comment_reply",
523
+ "status_change",
524
+ "task_created",
525
+ "task_deleted",
526
+ "invitation",
527
+ "member_joined",
528
+ "member_removed",
529
+ "role_changed"
530
+ ]);
531
+ var NotificationSchema = z.object({
532
+ id: z.string().uuid(),
533
+ userId: z.string().uuid(),
534
+ type: NotificationTypeSchema,
535
+ title: z.string().min(1).max(255),
536
+ body: z.string().nullable(),
537
+ link: z.string().max(500).nullable(),
538
+ projectId: z.string().uuid().nullable(),
539
+ organizationId: z.string().uuid().nullable(),
540
+ actorId: z.string().uuid().nullable(),
541
+ taskId: z.string().nullable(),
542
+ readAt: z.date().nullable(),
543
+ createdAt: z.date()
544
+ });
545
+ var NotificationActorSchema = z.object({
546
+ id: z.string().uuid(),
547
+ email: z.string().email(),
548
+ name: z.string().nullable()
549
+ });
550
+ var NotificationWithActorSchema = NotificationSchema.extend({
551
+ actor: NotificationActorSchema.nullable()
552
+ });
553
+ var NotificationsQuerySchema = z.object({
554
+ limit: z.coerce.number().int().min(1).max(100).optional().default(50),
555
+ offset: z.coerce.number().int().min(0).optional().default(0),
556
+ unreadOnly: z.coerce.boolean().optional().default(false),
557
+ type: NotificationTypeSchema.optional(),
558
+ projectId: z.string().uuid().optional()
559
+ });
560
+ var MarkNotificationsReadRequestSchema = z.object({
561
+ notificationIds: z.array(z.string().uuid()).min(1).max(100)
562
+ });
563
+ var CreateNotificationRequestSchema = z.object({
564
+ userId: z.string().uuid(),
565
+ type: NotificationTypeSchema,
566
+ title: z.string().min(1).max(255),
567
+ body: z.string().max(2e3).optional(),
568
+ link: z.string().max(500).optional(),
569
+ projectId: z.string().uuid().optional(),
570
+ organizationId: z.string().uuid().optional(),
571
+ actorId: z.string().uuid().optional(),
572
+ taskId: z.string().optional()
573
+ });
574
+ var GitHubAuthorizationResponseSchema = z.object({
575
+ authorizationUrl: z.string().url(),
576
+ state: z.string()
577
+ });
578
+ var GitHubCallbackRequestSchema = z.object({
579
+ code: z.string().min(1, "Authorization code is required"),
580
+ state: z.string().min(1, "State token is required")
581
+ });
582
+ var GitHubIntegrationSchema = z.object({
583
+ id: z.string().uuid(),
584
+ githubId: z.string(),
585
+ githubUsername: z.string(),
586
+ githubEmail: z.string().nullable(),
587
+ githubAvatarUrl: z.string().nullable(),
588
+ githubName: z.string().nullable(),
589
+ grantedScopes: z.array(z.string()).nullable(),
590
+ isConnected: z.boolean(),
591
+ lastSyncAt: z.date().nullable(),
592
+ createdAt: z.date(),
593
+ updatedAt: z.date()
594
+ });
595
+ var GitHubUserInfoSchema = z.object({
596
+ id: z.number(),
597
+ login: z.string(),
598
+ name: z.string().nullable(),
599
+ email: z.string().nullable(),
600
+ avatar_url: z.string().nullable()
601
+ });
602
+ var GitHubRepositorySchema = z.object({
603
+ id: z.number(),
604
+ name: z.string(),
605
+ full_name: z.string(),
606
+ owner: z.object({
607
+ login: z.string(),
608
+ avatar_url: z.string().nullable()
609
+ }),
610
+ description: z.string().nullable(),
611
+ private: z.boolean(),
612
+ html_url: z.string().url(),
613
+ default_branch: z.string()
614
+ });
615
+ var GitHubIssueSchema = z.object({
616
+ id: z.number(),
617
+ number: z.number(),
618
+ title: z.string(),
619
+ body: z.string().nullable(),
620
+ state: z.enum(["open", "closed"]),
621
+ html_url: z.string().url(),
622
+ created_at: z.string().datetime(),
623
+ updated_at: z.string().datetime(),
624
+ closed_at: z.string().datetime().nullable(),
625
+ user: z.object({
626
+ login: z.string(),
627
+ avatar_url: z.string().nullable()
628
+ }),
629
+ labels: z.array(z.object({
630
+ id: z.number(),
631
+ name: z.string(),
632
+ color: z.string()
633
+ })),
634
+ assignees: z.array(z.object({
635
+ login: z.string(),
636
+ avatar_url: z.string().nullable()
637
+ }))
638
+ });
639
+ var TaskGitHubLinkSchema = z.object({
640
+ issueNumber: z.number(),
641
+ repository: z.string(),
642
+ // "owner/repo"
643
+ issueUrl: z.string().url(),
644
+ issueTitle: z.string(),
645
+ issueState: z.enum(["open", "closed"]),
646
+ linkedBy: z.string().uuid(),
647
+ linkedAt: z.date()
648
+ });
649
+ var LinkTaskToGitHubRequestSchema = z.object({
650
+ issueNumber: z.number().int().positive("Issue number must be positive"),
651
+ repository: z.string().regex(/^[^/]+\/[^/]+$/, 'Repository must be in format "owner/repo"')
652
+ });
653
+ var CreateGitHubIssueFromTaskRequestSchema = z.object({
654
+ repository: z.string().regex(/^[^/]+\/[^/]+$/, 'Repository must be in format "owner/repo"'),
655
+ labels: z.array(z.string()).optional(),
656
+ assignees: z.array(z.string()).optional()
657
+ });
658
+ var GitHubIssuesQuerySchema = z.object({
659
+ state: z.enum(["open", "closed", "all"]).optional().default("open"),
660
+ page: z.coerce.number().int().min(1).optional().default(1),
661
+ perPage: z.coerce.number().int().min(1).max(100).optional().default(30),
662
+ search: z.string().optional()
663
+ });
664
+ var TaskWithGitHubLinkSchema = TaskSchema.extend({
665
+ assigneeId: z.string().uuid().nullable(),
666
+ assignedBy: z.string().uuid().nullable(),
667
+ assignedAt: z.date().nullable(),
668
+ assignee: z.object({
669
+ id: z.string().uuid(),
670
+ email: z.string().email(),
671
+ name: z.string().nullable()
672
+ }).nullable().optional(),
673
+ githubIssueNumber: z.number().nullable(),
674
+ githubRepository: z.string().nullable(),
675
+ githubIssueUrl: z.string().nullable(),
676
+ githubIssueTitle: z.string().nullable(),
677
+ githubIssueState: z.enum(["open", "closed"]).nullable(),
678
+ githubLinkedBy: z.string().uuid().nullable(),
679
+ githubLinkedAt: z.date().nullable()
680
+ });
681
+ var GitHubPrStateSchema = z.enum(["open", "closed", "merged"]);
682
+ var GitHubPullRequestSchema = z.object({
683
+ id: z.number(),
684
+ number: z.number(),
685
+ title: z.string(),
686
+ body: z.string().nullable(),
687
+ state: GitHubPrStateSchema,
688
+ draft: z.boolean(),
689
+ html_url: z.string().url(),
690
+ created_at: z.string().datetime(),
691
+ updated_at: z.string().datetime(),
692
+ closed_at: z.string().datetime().nullable(),
693
+ merged_at: z.string().datetime().nullable(),
694
+ user: z.object({
695
+ login: z.string(),
696
+ avatar_url: z.string().nullable()
697
+ }),
698
+ head: z.object({
699
+ ref: z.string(),
700
+ // Branch name
701
+ sha: z.string()
702
+ }),
703
+ base: z.object({
704
+ ref: z.string(),
705
+ // Target branch (e.g., "main")
706
+ sha: z.string()
707
+ }),
708
+ labels: z.array(z.object({
709
+ id: z.number(),
710
+ name: z.string(),
711
+ color: z.string()
712
+ })),
713
+ assignees: z.array(z.object({
714
+ login: z.string(),
715
+ avatar_url: z.string().nullable()
716
+ })),
717
+ requested_reviewers: z.array(z.object({
718
+ login: z.string(),
719
+ avatar_url: z.string().nullable()
720
+ }))
721
+ });
722
+ var TaskGitHubPrLinkSchema = z.object({
723
+ prNumber: z.number(),
724
+ repository: z.string(),
725
+ // "owner/repo"
726
+ prUrl: z.string().url(),
727
+ prTitle: z.string(),
728
+ prState: GitHubPrStateSchema,
729
+ headBranch: z.string(),
730
+ baseBranch: z.string(),
731
+ linkedBy: z.string().uuid(),
732
+ linkedAt: z.date()
733
+ });
734
+ var LinkTaskToGitHubPrRequestSchema = z.object({
735
+ prNumber: z.number().int().positive("PR number must be positive"),
736
+ repository: z.string().regex(/^[^/]+\/[^/]+$/, 'Repository must be in format "owner/repo"')
737
+ });
738
+ var GitHubPullRequestsQuerySchema = z.object({
739
+ state: z.enum(["open", "closed", "all"]).optional().default("open"),
740
+ page: z.coerce.number().int().min(1).optional().default(1),
741
+ perPage: z.coerce.number().int().min(1).max(100).optional().default(30),
742
+ search: z.string().optional()
743
+ });
744
+ var TaskWithGitHubPrLinkSchema = TaskWithGitHubLinkSchema.extend({
745
+ githubPrNumber: z.number().nullable(),
746
+ githubPrRepository: z.string().nullable(),
747
+ githubPrUrl: z.string().nullable(),
748
+ githubPrTitle: z.string().nullable(),
749
+ githubPrState: GitHubPrStateSchema.nullable(),
750
+ githubPrBranch: z.string().nullable(),
751
+ githubPrBaseBranch: z.string().nullable(),
752
+ githubPrLinkedBy: z.string().uuid().nullable(),
753
+ githubPrLinkedAt: z.date().nullable()
754
+ });
755
+ var APP_NAME = "PlanFlow";
756
+ var APP_VERSION = "0.0.1";
11
757
 
12
758
  // src/errors.ts
13
759
  var PlanFlowError = class extends Error {
@@ -109,18 +855,18 @@ var Logger = class {
109
855
  var logger = new Logger();
110
856
 
111
857
  // src/tools/login.ts
112
- import { z as z2 } from "zod";
858
+ import { z as z3 } from "zod";
113
859
 
114
860
  // src/config.ts
115
861
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
116
862
  import { homedir } from "os";
117
863
  import { join } from "path";
118
- import { z } from "zod";
119
- var ConfigSchema = z.object({
120
- apiToken: z.string().optional(),
121
- apiUrl: z.string().url().default("https://api.planflow.tools"),
122
- userId: z.string().uuid().optional(),
123
- userEmail: z.string().email().optional()
864
+ import { z as z2 } from "zod";
865
+ var ConfigSchema = z2.object({
866
+ apiToken: z2.string().optional(),
867
+ apiUrl: z2.string().url().default("https://api.planflow.tools"),
868
+ userId: z2.string().uuid().optional(),
869
+ userEmail: z2.string().email().optional()
124
870
  });
125
871
  var DEFAULT_CONFIG = {
126
872
  apiUrl: "https://api.planflow.tools"
@@ -152,7 +898,7 @@ function loadConfig() {
152
898
  logger.debug("Loaded config from disk");
153
899
  return config;
154
900
  } catch (error) {
155
- if (error instanceof z.ZodError) {
901
+ if (error instanceof z2.ZodError) {
156
902
  logger.warn("Invalid config file, using defaults", { errors: error.errors });
157
903
  return DEFAULT_CONFIG;
158
904
  }
@@ -689,8 +1435,8 @@ function formatKeyValue(pairs) {
689
1435
  }
690
1436
 
691
1437
  // src/tools/login.ts
692
- var LoginInputSchema = z2.object({
693
- token: z2.string().min(1, "API token is required")
1438
+ var LoginInputSchema = z3.object({
1439
+ token: z3.string().min(1, "API token is required")
694
1440
  });
695
1441
  var loginTool = {
696
1442
  name: "planflow_login",
@@ -759,8 +1505,8 @@ Please check your internet connection and try again.`
759
1505
  };
760
1506
 
761
1507
  // src/tools/logout.ts
762
- import { z as z3 } from "zod";
763
- var LogoutInputSchema = z3.object({});
1508
+ import { z as z4 } from "zod";
1509
+ var LogoutInputSchema = z4.object({});
764
1510
  var logoutTool = {
765
1511
  name: "planflow_logout",
766
1512
  description: `Log out from PlanFlow and clear stored credentials.
@@ -812,8 +1558,8 @@ Please try again or manually delete the config file at:
812
1558
  };
813
1559
 
814
1560
  // src/tools/whoami.ts
815
- import { z as z4 } from "zod";
816
- var WhoamiInputSchema = z4.object({});
1561
+ import { z as z5 } from "zod";
1562
+ var WhoamiInputSchema = z5.object({});
817
1563
  function formatDate(date) {
818
1564
  const d = typeof date === "string" ? new Date(date) : date;
819
1565
  return d.toLocaleDateString("en-US", {
@@ -896,8 +1642,8 @@ Please try again or check your connection.`
896
1642
  };
897
1643
 
898
1644
  // src/tools/projects.ts
899
- import { z as z5 } from "zod";
900
- var ProjectsInputSchema = z5.object({});
1645
+ import { z as z6 } from "zod";
1646
+ var ProjectsInputSchema = z6.object({});
901
1647
  function formatDate2(date) {
902
1648
  const d = typeof date === "string" ? new Date(date) : date;
903
1649
  return d.toLocaleDateString("en-US", {
@@ -999,10 +1745,10 @@ Please try again or check your connection.`
999
1745
  };
1000
1746
 
1001
1747
  // src/tools/create.ts
1002
- import { z as z6 } from "zod";
1003
- var CreateInputSchema = z6.object({
1004
- name: z6.string().min(1, "Project name is required").max(255, "Project name must be at most 255 characters"),
1005
- description: z6.string().max(1e3, "Description must be at most 1000 characters").optional()
1748
+ import { z as z7 } from "zod";
1749
+ var CreateInputSchema = z7.object({
1750
+ name: z7.string().min(1, "Project name is required").max(255, "Project name must be at most 255 characters"),
1751
+ description: z7.string().max(1e3, "Description must be at most 1000 characters").optional()
1006
1752
  });
1007
1753
  function formatDate3(date) {
1008
1754
  const d = typeof date === "string" ? new Date(date) : date;
@@ -1101,11 +1847,11 @@ Please try again or check your connection.`
1101
1847
  };
1102
1848
 
1103
1849
  // src/tools/sync.ts
1104
- import { z as z7 } from "zod";
1105
- var SyncInputSchema = z7.object({
1106
- projectId: z7.string().uuid("Invalid project ID format"),
1107
- direction: z7.enum(["push", "pull"]),
1108
- content: z7.string().optional()
1850
+ import { z as z8 } from "zod";
1851
+ var SyncInputSchema = z8.object({
1852
+ projectId: z8.string().uuid("Invalid project ID format"),
1853
+ direction: z8.enum(["push", "pull"]),
1854
+ content: z8.string().optional()
1109
1855
  // Required for push, ignored for pull
1110
1856
  });
1111
1857
  function formatDate4(date) {
@@ -1261,10 +2007,10 @@ async function executePull(client, projectId) {
1261
2007
  }
1262
2008
 
1263
2009
  // src/tools/task-list.ts
1264
- import { z as z8 } from "zod";
1265
- var TaskListInputSchema = z8.object({
1266
- projectId: z8.string().uuid("Project ID must be a valid UUID"),
1267
- status: z8.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]).optional().describe("Filter tasks by status")
2010
+ import { z as z9 } from "zod";
2011
+ var TaskListInputSchema = z9.object({
2012
+ projectId: z9.string().uuid("Project ID must be a valid UUID"),
2013
+ status: z9.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]).optional().describe("Filter tasks by status")
1268
2014
  });
1269
2015
  function truncate2(str, maxLength) {
1270
2016
  if (!str) return "-";
@@ -1434,11 +2180,11 @@ Please try again or check your connection.`
1434
2180
  };
1435
2181
 
1436
2182
  // src/tools/task-update.ts
1437
- import { z as z9 } from "zod";
1438
- var TaskUpdateInputSchema = z9.object({
1439
- projectId: z9.string().uuid("Project ID must be a valid UUID"),
1440
- taskId: z9.string().describe('Task ID (e.g., "T1.1", "T2.3")'),
1441
- status: z9.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]).describe("New status for the task")
2183
+ import { z as z10 } from "zod";
2184
+ var TaskUpdateInputSchema = z10.object({
2185
+ projectId: z10.string().uuid("Project ID must be a valid UUID"),
2186
+ taskId: z10.string().describe('Task ID (e.g., "T1.1", "T2.3")'),
2187
+ status: z10.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]).describe("New status for the task")
1442
2188
  });
1443
2189
  function getStatusEmoji2(status) {
1444
2190
  switch (status) {
@@ -1622,9 +2368,9 @@ Please try again or check your connection.`
1622
2368
  };
1623
2369
 
1624
2370
  // src/tools/task-next.ts
1625
- import { z as z10 } from "zod";
1626
- var TaskNextInputSchema = z10.object({
1627
- projectId: z10.string().uuid("Project ID must be a valid UUID")
2371
+ import { z as z11 } from "zod";
2372
+ var TaskNextInputSchema = z11.object({
2373
+ projectId: z11.string().uuid("Project ID must be a valid UUID")
1628
2374
  });
1629
2375
  function getComplexityIndicator3(complexity) {
1630
2376
  switch (complexity) {
@@ -2023,13 +2769,13 @@ Please try again or check your connection.`
2023
2769
  };
2024
2770
 
2025
2771
  // src/tools/notifications.ts
2026
- import { z as z11 } from "zod";
2027
- var NotificationsInputSchema = z11.object({
2028
- action: z11.enum(["list", "read", "read-all"]).default("list").describe("Action to perform: list, read (mark one as read), or read-all"),
2029
- projectId: z11.string().uuid("Project ID must be a valid UUID").optional().describe("Filter notifications by project (optional)"),
2030
- notificationId: z11.string().uuid("Notification ID must be a valid UUID").optional().describe('Notification ID to mark as read (required for "read" action)'),
2031
- unreadOnly: z11.boolean().default(true).describe("Only show unread notifications (default: true)"),
2032
- limit: z11.number().int().min(1).max(100).default(20).describe("Maximum number of notifications to fetch (default: 20)")
2772
+ import { z as z12 } from "zod";
2773
+ var NotificationsInputSchema = z12.object({
2774
+ action: z12.enum(["list", "read", "read-all"]).default("list").describe("Action to perform: list, read (mark one as read), or read-all"),
2775
+ projectId: z12.string().uuid("Project ID must be a valid UUID").optional().describe("Filter notifications by project (optional)"),
2776
+ notificationId: z12.string().uuid("Notification ID must be a valid UUID").optional().describe('Notification ID to mark as read (required for "read" action)'),
2777
+ unreadOnly: z12.boolean().default(true).describe("Only show unread notifications (default: true)"),
2778
+ limit: z12.number().int().min(1).max(100).default(20).describe("Maximum number of notifications to fetch (default: 20)")
2033
2779
  });
2034
2780
  function getTypeEmoji(type) {
2035
2781
  switch (type) {
@@ -2230,11 +2976,11 @@ Please try again or check your connection.`
2230
2976
  };
2231
2977
 
2232
2978
  // src/tools/activity.ts
2233
- import { z as z12 } from "zod";
2234
- var ActivityInputSchema = z12.object({
2235
- projectId: z12.string().uuid("Project ID must be a valid UUID").describe("Project ID to get activity for"),
2236
- taskId: z12.string().optional().describe('Optional: Filter activity for a specific task (e.g., "T1.1")'),
2237
- action: z12.enum([
2979
+ import { z as z13 } from "zod";
2980
+ var ActivityInputSchema = z13.object({
2981
+ projectId: z13.string().uuid("Project ID must be a valid UUID").describe("Project ID to get activity for"),
2982
+ taskId: z13.string().optional().describe('Optional: Filter activity for a specific task (e.g., "T1.1")'),
2983
+ action: z13.enum([
2238
2984
  "task_created",
2239
2985
  "task_updated",
2240
2986
  "task_deleted",
@@ -2251,8 +2997,8 @@ var ActivityInputSchema = z12.object({
2251
2997
  "member_removed",
2252
2998
  "member_role_changed"
2253
2999
  ]).optional().describe("Optional: Filter by action type"),
2254
- entityType: z12.enum(["task", "comment", "project", "member", "invitation"]).optional().describe("Optional: Filter by entity type"),
2255
- limit: z12.number().int().min(1).max(100).default(20).describe("Maximum number of activities to fetch (default: 20)")
3000
+ entityType: z13.enum(["task", "comment", "project", "member", "invitation"]).optional().describe("Optional: Filter by entity type"),
3001
+ limit: z13.number().int().min(1).max(100).default(20).describe("Maximum number of activities to fetch (default: 20)")
2256
3002
  });
2257
3003
  function getActionEmoji(action) {
2258
3004
  switch (action) {
@@ -2492,10 +3238,10 @@ Please try again or check your connection.`
2492
3238
  };
2493
3239
 
2494
3240
  // src/tools/comments.ts
2495
- import { z as z13 } from "zod";
2496
- var CommentsInputSchema = z13.object({
2497
- projectId: z13.string().uuid("Project ID must be a valid UUID").describe("Project ID containing the task"),
2498
- taskId: z13.string().describe('Task ID to view comments for (e.g., "T1.1")')
3241
+ import { z as z14 } from "zod";
3242
+ var CommentsInputSchema = z14.object({
3243
+ projectId: z14.string().uuid("Project ID must be a valid UUID").describe("Project ID containing the task"),
3244
+ taskId: z14.string().describe('Task ID to view comments for (e.g., "T1.1")')
2499
3245
  });
2500
3246
  function formatRelativeTime3(dateString) {
2501
3247
  const date = new Date(dateString);
@@ -2642,12 +3388,12 @@ Please try again or check your connection.`
2642
3388
  };
2643
3389
 
2644
3390
  // src/tools/comment.ts
2645
- import { z as z14 } from "zod";
2646
- var CommentInputSchema = z14.object({
2647
- projectId: z14.string().uuid("Project ID must be a valid UUID").describe("Project ID containing the task"),
2648
- taskId: z14.string().describe('Task ID to add comment to (e.g., "T1.1")'),
2649
- content: z14.string().min(1, "Comment content is required").max(1e4, "Comment must be at most 10000 characters").describe("Comment content (supports @mentions like @user@email.com)"),
2650
- parentId: z14.string().uuid("Parent comment ID must be a valid UUID").optional().describe("Optional: Reply to a specific comment by providing its ID")
3391
+ import { z as z15 } from "zod";
3392
+ var CommentInputSchema = z15.object({
3393
+ projectId: z15.string().uuid("Project ID must be a valid UUID").describe("Project ID containing the task"),
3394
+ taskId: z15.string().describe('Task ID to add comment to (e.g., "T1.1")'),
3395
+ content: z15.string().min(1, "Comment content is required").max(1e4, "Comment must be at most 10000 characters").describe("Comment content (supports @mentions like @user@email.com)"),
3396
+ parentId: z15.string().uuid("Parent comment ID must be a valid UUID").optional().describe("Optional: Reply to a specific comment by providing its ID")
2651
3397
  });
2652
3398
  function formatAuthorName2(name, email) {
2653
3399
  if (name) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planflow-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "PlanFlow MCP Server for Claude Code - AI-native project management from your terminal",
5
5
  "author": "PlanFlow <hello@planflow.tools>",
6
6
  "license": "MIT",
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "scripts": {
55
55
  "dev": "tsx watch src/index.ts",
56
- "build": "tsup src/index.ts --format esm --dts --clean",
56
+ "build": "tsup",
57
57
  "start": "node dist/index.js",
58
58
  "lint": "eslint src/",
59
59
  "typecheck": "tsc --noEmit",
@@ -64,7 +64,6 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@modelcontextprotocol/sdk": "^1.0.0",
67
- "@planflow/shared": "workspace:*",
68
67
  "zod": "^3.23.0"
69
68
  },
70
69
  "devDependencies": {