planflow-mcp 0.1.0 → 0.1.2
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 +840 -65
- 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
|
-
|
|
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
|
|
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 =
|
|
120
|
-
apiToken:
|
|
121
|
-
apiUrl:
|
|
122
|
-
userId:
|
|
123
|
-
userEmail:
|
|
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
|
|
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
|
}
|
|
@@ -390,11 +1136,33 @@ var ApiClient = class {
|
|
|
390
1136
|
// ============================================================
|
|
391
1137
|
// Project Endpoints
|
|
392
1138
|
// ============================================================
|
|
1139
|
+
/**
|
|
1140
|
+
* List all organizations for the authenticated user
|
|
1141
|
+
*/
|
|
1142
|
+
async listOrganizations() {
|
|
1143
|
+
const response = await this.request("GET", "/organizations");
|
|
1144
|
+
return response.organizations;
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* Get the user's default organization (first one they own or are a member of)
|
|
1148
|
+
*/
|
|
1149
|
+
async getDefaultOrganization() {
|
|
1150
|
+
const orgs = await this.listOrganizations();
|
|
1151
|
+
return orgs.find((o) => o.role === "owner") || orgs[0] || null;
|
|
1152
|
+
}
|
|
393
1153
|
/**
|
|
394
1154
|
* List all projects for the authenticated user
|
|
395
1155
|
*/
|
|
396
|
-
async listProjects() {
|
|
397
|
-
|
|
1156
|
+
async listProjects(organizationId) {
|
|
1157
|
+
let orgId = organizationId;
|
|
1158
|
+
if (!orgId) {
|
|
1159
|
+
const defaultOrg = await this.getDefaultOrganization();
|
|
1160
|
+
if (!defaultOrg) {
|
|
1161
|
+
throw new ApiError("No organization found. Please create an organization first.", 400);
|
|
1162
|
+
}
|
|
1163
|
+
orgId = defaultOrg.id;
|
|
1164
|
+
}
|
|
1165
|
+
const response = await this.request("GET", `/projects?organizationId=${orgId}`);
|
|
398
1166
|
return response.projects;
|
|
399
1167
|
}
|
|
400
1168
|
/**
|
|
@@ -689,8 +1457,8 @@ function formatKeyValue(pairs) {
|
|
|
689
1457
|
}
|
|
690
1458
|
|
|
691
1459
|
// src/tools/login.ts
|
|
692
|
-
var LoginInputSchema =
|
|
693
|
-
token:
|
|
1460
|
+
var LoginInputSchema = z3.object({
|
|
1461
|
+
token: z3.string().min(1, "API token is required")
|
|
694
1462
|
});
|
|
695
1463
|
var loginTool = {
|
|
696
1464
|
name: "planflow_login",
|
|
@@ -759,8 +1527,8 @@ Please check your internet connection and try again.`
|
|
|
759
1527
|
};
|
|
760
1528
|
|
|
761
1529
|
// src/tools/logout.ts
|
|
762
|
-
import { z as
|
|
763
|
-
var LogoutInputSchema =
|
|
1530
|
+
import { z as z4 } from "zod";
|
|
1531
|
+
var LogoutInputSchema = z4.object({});
|
|
764
1532
|
var logoutTool = {
|
|
765
1533
|
name: "planflow_logout",
|
|
766
1534
|
description: `Log out from PlanFlow and clear stored credentials.
|
|
@@ -812,8 +1580,8 @@ Please try again or manually delete the config file at:
|
|
|
812
1580
|
};
|
|
813
1581
|
|
|
814
1582
|
// src/tools/whoami.ts
|
|
815
|
-
import { z as
|
|
816
|
-
var WhoamiInputSchema =
|
|
1583
|
+
import { z as z5 } from "zod";
|
|
1584
|
+
var WhoamiInputSchema = z5.object({});
|
|
817
1585
|
function formatDate(date) {
|
|
818
1586
|
const d = typeof date === "string" ? new Date(date) : date;
|
|
819
1587
|
return d.toLocaleDateString("en-US", {
|
|
@@ -896,8 +1664,8 @@ Please try again or check your connection.`
|
|
|
896
1664
|
};
|
|
897
1665
|
|
|
898
1666
|
// src/tools/projects.ts
|
|
899
|
-
import { z as
|
|
900
|
-
var ProjectsInputSchema =
|
|
1667
|
+
import { z as z6 } from "zod";
|
|
1668
|
+
var ProjectsInputSchema = z6.object({});
|
|
901
1669
|
function formatDate2(date) {
|
|
902
1670
|
const d = typeof date === "string" ? new Date(date) : date;
|
|
903
1671
|
return d.toLocaleDateString("en-US", {
|
|
@@ -999,10 +1767,10 @@ Please try again or check your connection.`
|
|
|
999
1767
|
};
|
|
1000
1768
|
|
|
1001
1769
|
// src/tools/create.ts
|
|
1002
|
-
import { z as
|
|
1003
|
-
var CreateInputSchema =
|
|
1004
|
-
name:
|
|
1005
|
-
description:
|
|
1770
|
+
import { z as z7 } from "zod";
|
|
1771
|
+
var CreateInputSchema = z7.object({
|
|
1772
|
+
name: z7.string().min(1, "Project name is required").max(255, "Project name must be at most 255 characters"),
|
|
1773
|
+
description: z7.string().max(1e3, "Description must be at most 1000 characters").optional()
|
|
1006
1774
|
});
|
|
1007
1775
|
function formatDate3(date) {
|
|
1008
1776
|
const d = typeof date === "string" ? new Date(date) : date;
|
|
@@ -1046,9 +1814,16 @@ Returns:
|
|
|
1046
1814
|
}
|
|
1047
1815
|
try {
|
|
1048
1816
|
const client = getApiClient();
|
|
1817
|
+
const defaultOrg = await client.getDefaultOrganization();
|
|
1818
|
+
if (!defaultOrg) {
|
|
1819
|
+
return createErrorResult(
|
|
1820
|
+
"\u274C No organization found.\n\nPlease create an organization first at:\n https://planflow.tools/dashboard/team"
|
|
1821
|
+
);
|
|
1822
|
+
}
|
|
1049
1823
|
const project = await client.createProject({
|
|
1050
1824
|
name: input.name,
|
|
1051
|
-
description: input.description
|
|
1825
|
+
description: input.description,
|
|
1826
|
+
organizationId: defaultOrg.id
|
|
1052
1827
|
});
|
|
1053
1828
|
logger.info("Successfully created project", { projectId: project.id });
|
|
1054
1829
|
const output = [
|
|
@@ -1101,11 +1876,11 @@ Please try again or check your connection.`
|
|
|
1101
1876
|
};
|
|
1102
1877
|
|
|
1103
1878
|
// src/tools/sync.ts
|
|
1104
|
-
import { z as
|
|
1105
|
-
var SyncInputSchema =
|
|
1106
|
-
projectId:
|
|
1107
|
-
direction:
|
|
1108
|
-
content:
|
|
1879
|
+
import { z as z8 } from "zod";
|
|
1880
|
+
var SyncInputSchema = z8.object({
|
|
1881
|
+
projectId: z8.string().uuid("Invalid project ID format"),
|
|
1882
|
+
direction: z8.enum(["push", "pull"]),
|
|
1883
|
+
content: z8.string().optional()
|
|
1109
1884
|
// Required for push, ignored for pull
|
|
1110
1885
|
});
|
|
1111
1886
|
function formatDate4(date) {
|
|
@@ -1261,10 +2036,10 @@ async function executePull(client, projectId) {
|
|
|
1261
2036
|
}
|
|
1262
2037
|
|
|
1263
2038
|
// src/tools/task-list.ts
|
|
1264
|
-
import { z as
|
|
1265
|
-
var TaskListInputSchema =
|
|
1266
|
-
projectId:
|
|
1267
|
-
status:
|
|
2039
|
+
import { z as z9 } from "zod";
|
|
2040
|
+
var TaskListInputSchema = z9.object({
|
|
2041
|
+
projectId: z9.string().uuid("Project ID must be a valid UUID"),
|
|
2042
|
+
status: z9.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]).optional().describe("Filter tasks by status")
|
|
1268
2043
|
});
|
|
1269
2044
|
function truncate2(str, maxLength) {
|
|
1270
2045
|
if (!str) return "-";
|
|
@@ -1434,11 +2209,11 @@ Please try again or check your connection.`
|
|
|
1434
2209
|
};
|
|
1435
2210
|
|
|
1436
2211
|
// src/tools/task-update.ts
|
|
1437
|
-
import { z as
|
|
1438
|
-
var TaskUpdateInputSchema =
|
|
1439
|
-
projectId:
|
|
1440
|
-
taskId:
|
|
1441
|
-
status:
|
|
2212
|
+
import { z as z10 } from "zod";
|
|
2213
|
+
var TaskUpdateInputSchema = z10.object({
|
|
2214
|
+
projectId: z10.string().uuid("Project ID must be a valid UUID"),
|
|
2215
|
+
taskId: z10.string().describe('Task ID (e.g., "T1.1", "T2.3")'),
|
|
2216
|
+
status: z10.enum(["TODO", "IN_PROGRESS", "DONE", "BLOCKED"]).describe("New status for the task")
|
|
1442
2217
|
});
|
|
1443
2218
|
function getStatusEmoji2(status) {
|
|
1444
2219
|
switch (status) {
|
|
@@ -1622,9 +2397,9 @@ Please try again or check your connection.`
|
|
|
1622
2397
|
};
|
|
1623
2398
|
|
|
1624
2399
|
// src/tools/task-next.ts
|
|
1625
|
-
import { z as
|
|
1626
|
-
var TaskNextInputSchema =
|
|
1627
|
-
projectId:
|
|
2400
|
+
import { z as z11 } from "zod";
|
|
2401
|
+
var TaskNextInputSchema = z11.object({
|
|
2402
|
+
projectId: z11.string().uuid("Project ID must be a valid UUID")
|
|
1628
2403
|
});
|
|
1629
2404
|
function getComplexityIndicator3(complexity) {
|
|
1630
2405
|
switch (complexity) {
|
|
@@ -2023,13 +2798,13 @@ Please try again or check your connection.`
|
|
|
2023
2798
|
};
|
|
2024
2799
|
|
|
2025
2800
|
// src/tools/notifications.ts
|
|
2026
|
-
import { z as
|
|
2027
|
-
var NotificationsInputSchema =
|
|
2028
|
-
action:
|
|
2029
|
-
projectId:
|
|
2030
|
-
notificationId:
|
|
2031
|
-
unreadOnly:
|
|
2032
|
-
limit:
|
|
2801
|
+
import { z as z12 } from "zod";
|
|
2802
|
+
var NotificationsInputSchema = z12.object({
|
|
2803
|
+
action: z12.enum(["list", "read", "read-all"]).default("list").describe("Action to perform: list, read (mark one as read), or read-all"),
|
|
2804
|
+
projectId: z12.string().uuid("Project ID must be a valid UUID").optional().describe("Filter notifications by project (optional)"),
|
|
2805
|
+
notificationId: z12.string().uuid("Notification ID must be a valid UUID").optional().describe('Notification ID to mark as read (required for "read" action)'),
|
|
2806
|
+
unreadOnly: z12.boolean().default(true).describe("Only show unread notifications (default: true)"),
|
|
2807
|
+
limit: z12.number().int().min(1).max(100).default(20).describe("Maximum number of notifications to fetch (default: 20)")
|
|
2033
2808
|
});
|
|
2034
2809
|
function getTypeEmoji(type) {
|
|
2035
2810
|
switch (type) {
|
|
@@ -2230,11 +3005,11 @@ Please try again or check your connection.`
|
|
|
2230
3005
|
};
|
|
2231
3006
|
|
|
2232
3007
|
// src/tools/activity.ts
|
|
2233
|
-
import { z as
|
|
2234
|
-
var ActivityInputSchema =
|
|
2235
|
-
projectId:
|
|
2236
|
-
taskId:
|
|
2237
|
-
action:
|
|
3008
|
+
import { z as z13 } from "zod";
|
|
3009
|
+
var ActivityInputSchema = z13.object({
|
|
3010
|
+
projectId: z13.string().uuid("Project ID must be a valid UUID").describe("Project ID to get activity for"),
|
|
3011
|
+
taskId: z13.string().optional().describe('Optional: Filter activity for a specific task (e.g., "T1.1")'),
|
|
3012
|
+
action: z13.enum([
|
|
2238
3013
|
"task_created",
|
|
2239
3014
|
"task_updated",
|
|
2240
3015
|
"task_deleted",
|
|
@@ -2251,8 +3026,8 @@ var ActivityInputSchema = z12.object({
|
|
|
2251
3026
|
"member_removed",
|
|
2252
3027
|
"member_role_changed"
|
|
2253
3028
|
]).optional().describe("Optional: Filter by action type"),
|
|
2254
|
-
entityType:
|
|
2255
|
-
limit:
|
|
3029
|
+
entityType: z13.enum(["task", "comment", "project", "member", "invitation"]).optional().describe("Optional: Filter by entity type"),
|
|
3030
|
+
limit: z13.number().int().min(1).max(100).default(20).describe("Maximum number of activities to fetch (default: 20)")
|
|
2256
3031
|
});
|
|
2257
3032
|
function getActionEmoji(action) {
|
|
2258
3033
|
switch (action) {
|
|
@@ -2492,10 +3267,10 @@ Please try again or check your connection.`
|
|
|
2492
3267
|
};
|
|
2493
3268
|
|
|
2494
3269
|
// src/tools/comments.ts
|
|
2495
|
-
import { z as
|
|
2496
|
-
var CommentsInputSchema =
|
|
2497
|
-
projectId:
|
|
2498
|
-
taskId:
|
|
3270
|
+
import { z as z14 } from "zod";
|
|
3271
|
+
var CommentsInputSchema = z14.object({
|
|
3272
|
+
projectId: z14.string().uuid("Project ID must be a valid UUID").describe("Project ID containing the task"),
|
|
3273
|
+
taskId: z14.string().describe('Task ID to view comments for (e.g., "T1.1")')
|
|
2499
3274
|
});
|
|
2500
3275
|
function formatRelativeTime3(dateString) {
|
|
2501
3276
|
const date = new Date(dateString);
|
|
@@ -2642,12 +3417,12 @@ Please try again or check your connection.`
|
|
|
2642
3417
|
};
|
|
2643
3418
|
|
|
2644
3419
|
// src/tools/comment.ts
|
|
2645
|
-
import { z as
|
|
2646
|
-
var CommentInputSchema =
|
|
2647
|
-
projectId:
|
|
2648
|
-
taskId:
|
|
2649
|
-
content:
|
|
2650
|
-
parentId:
|
|
3420
|
+
import { z as z15 } from "zod";
|
|
3421
|
+
var CommentInputSchema = z15.object({
|
|
3422
|
+
projectId: z15.string().uuid("Project ID must be a valid UUID").describe("Project ID containing the task"),
|
|
3423
|
+
taskId: z15.string().describe('Task ID to add comment to (e.g., "T1.1")'),
|
|
3424
|
+
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)"),
|
|
3425
|
+
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
3426
|
});
|
|
2652
3427
|
function formatAuthorName2(name, email) {
|
|
2653
3428
|
if (name) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "planflow-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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
|
|
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": {
|