@classroomio/mcp 0.0.3 → 0.0.5

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 (3) hide show
  1. package/README.md +104 -6
  2. package/dist/index.js +922 -252
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -40,12 +40,61 @@ var ClassroomIoApiClient = class {
40
40
  method: "GET"
41
41
  });
42
42
  }
43
+ async listOrganizationCourses(query = {}) {
44
+ const searchParams = new URLSearchParams();
45
+ if (query.tags) searchParams.set("tags", query.tags);
46
+ const querySuffix = searchParams.toString() ? `?${searchParams.toString()}` : "";
47
+ return this.request(`/organization/courses${querySuffix}`, {
48
+ method: "GET"
49
+ });
50
+ }
51
+ async listCourseExercises(courseId, query = {}) {
52
+ const searchParams = new URLSearchParams();
53
+ if (query.lessonId) searchParams.set("lessonId", query.lessonId);
54
+ if (query.sectionId) searchParams.set("sectionId", query.sectionId);
55
+ const querySuffix = searchParams.toString() ? `?${searchParams.toString()}` : "";
56
+ return this.request(`/course/${courseId}/exercise${querySuffix}`, {
57
+ method: "GET"
58
+ });
59
+ }
60
+ async getCourseExercise(courseId, exerciseId) {
61
+ return this.request(`/course/${courseId}/exercise/${exerciseId}`, {
62
+ method: "GET"
63
+ });
64
+ }
65
+ async createCourseExercise(courseId, payload) {
66
+ return this.request(`/course/${courseId}/exercise`, {
67
+ method: "POST",
68
+ body: {
69
+ ...payload,
70
+ courseId
71
+ }
72
+ });
73
+ }
74
+ async createCourseExerciseFromTemplate(courseId, payload) {
75
+ return this.request(`/course/${courseId}/exercise/from-template`, {
76
+ method: "POST",
77
+ body: payload
78
+ });
79
+ }
80
+ async updateCourseExercise(courseId, exerciseId, payload) {
81
+ return this.request(`/course/${courseId}/exercise/${exerciseId}`, {
82
+ method: "PUT",
83
+ body: payload
84
+ });
85
+ }
43
86
  async updateCourseDraft(draftId, payload) {
44
87
  return this.request(`/organization/course-import/drafts/${draftId}`, {
45
88
  method: "PUT",
46
89
  body: payload
47
90
  });
48
91
  }
92
+ async tagCourseDraft(draftId, payload) {
93
+ return this.request(`/organization/course-import/drafts/${draftId}/tags`, {
94
+ method: "PUT",
95
+ body: payload
96
+ });
97
+ }
49
98
  async publishCourseDraft(draftId, payload) {
50
99
  return this.request(`/organization/course-import/drafts/${draftId}/publish`, {
51
100
  method: "POST",
@@ -58,6 +107,15 @@ var ClassroomIoApiClient = class {
58
107
  body: payload
59
108
  });
60
109
  }
110
+ async tagCourses(payload) {
111
+ return this.request(
112
+ "/organization/tags/courses/assign",
113
+ {
114
+ method: "PUT",
115
+ body: payload
116
+ }
117
+ );
118
+ }
61
119
  async request(path, options) {
62
120
  const response = await fetch(new URL(path, this.config.CLASSROOMIO_API_URL), {
63
121
  method: options.method,
@@ -96,11 +154,318 @@ function getConfig(env = process.env) {
96
154
  return ZConfig.parse(env);
97
155
  }
98
156
 
99
- // ../utils/dist/validation/course-import/course-import.js
157
+ // ../utils/dist/validation/tag/tag.js
158
+ import * as z2 from "zod";
159
+ var TAG_COLOR_OPTIONS = [
160
+ "#EF4444",
161
+ "#F97316",
162
+ "#F59E0B",
163
+ "#84CC16",
164
+ "#22C55E",
165
+ "#14B8A6",
166
+ "#06B6D4",
167
+ "#3B82F6",
168
+ "#8B5CF6",
169
+ "#EC4899"
170
+ ];
171
+ var ZTagColor = z2.enum(TAG_COLOR_OPTIONS);
172
+ var ZTagGroupParam = z2.object({
173
+ groupId: z2.uuid()
174
+ });
175
+ var ZTagGroupCreate = z2.object({
176
+ name: z2.string().min(1).max(80),
177
+ description: z2.string().max(240).optional(),
178
+ order: z2.number().int().min(0).optional()
179
+ });
180
+ var ZTagGroupUpdate = ZTagGroupCreate.partial().refine((value) => Object.keys(value).length > 0, {
181
+ message: "At least one field is required"
182
+ });
183
+ var ZTagParam = z2.object({
184
+ tagId: z2.uuid()
185
+ });
186
+ var ZTagCreate = z2.object({
187
+ name: z2.string().min(1).max(80),
188
+ description: z2.string().max(240).optional(),
189
+ groupId: z2.uuid(),
190
+ color: ZTagColor
191
+ });
192
+ var ZTagUpdate = z2.object({
193
+ name: z2.string().min(1).max(80).optional(),
194
+ description: z2.string().max(240).optional(),
195
+ groupId: z2.uuid().optional(),
196
+ color: ZTagColor.optional()
197
+ }).refine((value) => Object.keys(value).length > 0, {
198
+ message: "At least one field is required"
199
+ });
200
+ var ZCourseTagParam = z2.object({
201
+ courseId: z2.uuid()
202
+ });
203
+ var ZCourseTagAssignment = z2.object({
204
+ tagIds: z2.array(z2.uuid()).max(100).default([])
205
+ });
206
+ var ZAutomationTagMode = z2.enum(["merge", "replace"]).default("merge");
207
+ var ZAutomationTagName = z2.string().trim().min(1).max(80);
208
+ var ZAutomationDraftTagParam = z2.object({
209
+ draftId: z2.string().uuid()
210
+ });
211
+ var ZAutomationDraftTagAssignment = z2.object({
212
+ tagNames: z2.array(ZAutomationTagName).min(1).max(100),
213
+ mode: ZAutomationTagMode,
214
+ groupName: z2.string().trim().min(1).max(80).optional()
215
+ });
216
+ var ZAutomationCourseTagAssignment = ZAutomationDraftTagAssignment.extend({
217
+ courseIds: z2.array(z2.string().uuid()).min(1).max(100)
218
+ });
219
+
220
+ // ../utils/dist/validation/organization/organization.js
100
221
  import * as z3 from "zod";
101
222
 
102
- // ../utils/dist/validation/course/course.js
103
- import * as z2 from "zod";
223
+ // ../utils/dist/constants/org.js
224
+ var blockedSubdomain = [
225
+ "academy",
226
+ "app",
227
+ "apps",
228
+ "blog",
229
+ "build",
230
+ "campaign",
231
+ "church",
232
+ "cloud",
233
+ "community",
234
+ "conference",
235
+ "course",
236
+ "courses",
237
+ "demo",
238
+ "dev",
239
+ "forum",
240
+ "group",
241
+ "groups",
242
+ "help",
243
+ "launch",
244
+ "launchweek",
245
+ "mobile",
246
+ "play",
247
+ "prod",
248
+ "production",
249
+ "schools",
250
+ "stage",
251
+ "staging",
252
+ "support",
253
+ "teacher",
254
+ "teachers",
255
+ "tech",
256
+ "training"
257
+ ];
258
+
259
+ // ../utils/dist/constants/content.js
260
+ var ContentType;
261
+ (function(ContentType2) {
262
+ ContentType2["Section"] = "SECTION";
263
+ ContentType2["Lesson"] = "LESSON";
264
+ ContentType2["Exercise"] = "EXERCISE";
265
+ })(ContentType || (ContentType = {}));
266
+
267
+ // ../utils/dist/validation/organization/organization.js
268
+ var ZGetOrganizations = z3.object({
269
+ siteName: z3.string().min(1).optional(),
270
+ customDomain: z3.string().min(1).optional(),
271
+ isCustomDomainVerified: z3.boolean().optional()
272
+ });
273
+ var ZGetCoursesBySiteName = z3.object({
274
+ siteName: z3.string().min(1),
275
+ tags: z3.string().optional()
276
+ });
277
+ var ZGetOrganizationCoursesQuery = z3.object({
278
+ tags: z3.string().optional()
279
+ });
280
+ var ZGetOrgSetup = z3.object({
281
+ siteName: z3.string().min(1)
282
+ });
283
+ var ZCreateOrgPlan = z3.object({
284
+ orgId: z3.uuid(),
285
+ planName: z3.enum(["EARLY_ADOPTER", "ENTERPRISE", "BASIC"]),
286
+ subscriptionId: z3.string().min(1),
287
+ triggeredBy: z3.number().int().positive(),
288
+ payload: z3.record(z3.string(), z3.unknown())
289
+ });
290
+ var ZUpdateOrgPlan = z3.object({
291
+ subscriptionId: z3.string().min(1),
292
+ payload: z3.record(z3.string(), z3.unknown())
293
+ });
294
+ var ZCancelOrgPlan = z3.object({
295
+ subscriptionId: z3.string().min(1),
296
+ payload: z3.record(z3.string(), z3.unknown())
297
+ });
298
+ var ZCreateOrganization = z3.object({
299
+ name: z3.string().min(5).refine((val) => !/^[-]|[-]$/.test(val), {
300
+ message: "Organization name cannot start or end with a hyphen"
301
+ }),
302
+ siteName: z3.string().min(5).refine((val) => !/^[-]|[-]$/.test(val), {
303
+ message: "Site name cannot start or end with a hyphen"
304
+ }).refine((val) => !blockedSubdomain.includes(val), {
305
+ message: "Sitename already exists."
306
+ })
307
+ });
308
+ var ZUpdateOrganization = z3.object({
309
+ name: z3.string().min(5).refine((val) => !/^[-]|[-]$/.test(val), {
310
+ message: "Organization name cannot start or end with a hyphen"
311
+ }).optional(),
312
+ avatarUrl: z3.url().optional(),
313
+ theme: z3.string().optional(),
314
+ landingpage: z3.record(z3.string(), z3.unknown()).optional(),
315
+ siteName: z3.string().min(1).optional(),
316
+ customDomain: z3.string().nullable().optional(),
317
+ isCustomDomainVerified: z3.boolean().optional(),
318
+ customization: z3.record(z3.string(), z3.unknown()).optional(),
319
+ disableSignup: z3.boolean().optional(),
320
+ disableSignupMessage: z3.string().optional(),
321
+ disableEmailPassword: z3.boolean().optional(),
322
+ disableGoogleAuth: z3.boolean().optional(),
323
+ /** Nested settings (stored in organization.settings JSONB). signup.inviteOnly = true means invite-only signup. */
324
+ settings: z3.object({
325
+ signup: z3.object({
326
+ inviteOnly: z3.boolean().optional()
327
+ }).optional()
328
+ }).optional()
329
+ });
330
+ var ZInviteTeamMembers = z3.object({
331
+ emails: z3.array(z3.string().email()).min(1).max(50),
332
+ roleId: z3.number().int().positive()
333
+ });
334
+ var ZRemoveTeamMember = z3.object({
335
+ memberId: z3.coerce.number().int().positive()
336
+ });
337
+ var ZGetUserAnalytics = z3.object({
338
+ userId: z3.uuid()
339
+ });
340
+
341
+ // ../utils/dist/validation/organization/quiz.js
342
+ import * as z4 from "zod";
343
+ var ZQuizGetParam = z4.object({
344
+ orgId: z4.uuid(),
345
+ quizId: z4.uuid()
346
+ });
347
+ var ZQuizListParam = z4.object({
348
+ orgId: z4.uuid()
349
+ });
350
+ var ZQuizCreate = z4.object({
351
+ title: z4.string().min(1),
352
+ questions: z4.array(z4.any()).optional(),
353
+ timelimit: z4.string().optional(),
354
+ theme: z4.string().optional()
355
+ });
356
+ var ZQuizUpdate = z4.object({
357
+ title: z4.string().min(1).optional(),
358
+ questions: z4.array(z4.any()).optional(),
359
+ timelimit: z4.string().optional(),
360
+ theme: z4.string().optional()
361
+ });
362
+
363
+ // ../utils/dist/validation/organization/exercise.js
364
+ import * as z5 from "zod";
365
+ var ZLMSExercisesParam = z5.object({
366
+ orgId: z5.uuid()
367
+ });
368
+
369
+ // ../utils/dist/validation/organization/invite.js
370
+ import * as z6 from "zod";
371
+ var ZOrganizationInviteTokenParam = z6.object({
372
+ token: z6.string().min(10).max(512)
373
+ });
374
+
375
+ // ../utils/dist/validation/organization/sso.js
376
+ import * as z7 from "zod";
377
+ var SSO_PROVIDERS = ["OKTA", "GOOGLE_WORKSPACE", "AUTH0"];
378
+ var ZCreateSsoConnection = z7.object({
379
+ provider: z7.enum(SSO_PROVIDERS),
380
+ displayName: z7.string().min(1, "Display name is required"),
381
+ issuer: z7.url("Must be a valid URL"),
382
+ domain: z7.string().min(1, "Domain is required").regex(/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/, "Invalid domain format"),
383
+ clientId: z7.string().min(1, "Client ID is required"),
384
+ clientSecret: z7.string().min(1, "Client secret is required"),
385
+ scopes: z7.string().default("openid profile email")
386
+ });
387
+ var ZUpdateSsoConnection = z7.object({
388
+ displayName: z7.string().min(1).optional(),
389
+ issuer: z7.url().optional(),
390
+ domain: z7.string().optional(),
391
+ clientId: z7.string().optional(),
392
+ clientSecret: z7.string().optional(),
393
+ scopes: z7.string().optional(),
394
+ isActive: z7.boolean().optional()
395
+ });
396
+ var ZUpdateSsoPolicy = z7.object({
397
+ forceSso: z7.boolean().optional(),
398
+ autoJoinSsoDomains: z7.boolean().optional(),
399
+ breakGlassEnabled: z7.boolean().optional(),
400
+ defaultRoleId: z7.number().int().positive().optional(),
401
+ roleMapping: z7.record(z7.string(), z7.number()).optional()
402
+ });
403
+ var ZSsoDiscoveryQuery = z7.object({
404
+ email: z7.email("Valid email is required")
405
+ });
406
+ var ZGetSsoConfig = z7.object({
407
+ orgId: z7.uuid()
408
+ });
409
+
410
+ // ../utils/dist/validation/organization/login-link.js
411
+ import { z as z8 } from "zod";
412
+ var ZLoginLinkQuery = z8.object({
413
+ token: z8.string().min(1),
414
+ redirect: z8.string().optional()
415
+ });
416
+ var ZLoginLinkPayload = z8.object({
417
+ sub: z8.uuid(),
418
+ email: z8.email(),
419
+ type: z8.literal("login-link")
420
+ });
421
+
422
+ // ../utils/dist/validation/organization/token-auth.js
423
+ import { z as z9 } from "zod";
424
+ var ZTokenExchangeQuery = z9.object({
425
+ token: z9.string().min(1),
426
+ redirect: z9.string().optional()
427
+ });
428
+ var ZTokenExchangePayload = z9.object({
429
+ sub: z9.string(),
430
+ email: z9.email(),
431
+ name: z9.string().optional(),
432
+ avatar: z9.url().optional(),
433
+ iat: z9.number(),
434
+ exp: z9.number()
435
+ });
436
+
437
+ // ../utils/dist/validation/organization/automation-key.js
438
+ import { z as z10 } from "zod";
439
+ var ZOrganizationApiKeyType = z10.enum(["mcp", "api", "zapier"]);
440
+ var ZOrganizationApiKeyScope = z10.enum([
441
+ "course_import:draft:create",
442
+ "course_import:draft:read",
443
+ "course_import:draft:update",
444
+ "course_import:draft:publish",
445
+ "course:read",
446
+ "course:tag:write",
447
+ "course:exercise:read",
448
+ "course:exercise:write",
449
+ "public_api:*"
450
+ ]);
451
+ var ZListOrganizationApiKeysQuery = z10.object({
452
+ type: ZOrganizationApiKeyType.optional()
453
+ });
454
+ var ZOrganizationAutomationUsageQuery = z10.object({
455
+ type: ZOrganizationApiKeyType.default("mcp")
456
+ });
457
+ var ZCreateOrganizationApiKey = z10.object({
458
+ type: ZOrganizationApiKeyType,
459
+ label: z10.string().min(1).max(120).optional(),
460
+ expiresAt: z10.string().datetime().optional(),
461
+ scopes: z10.array(ZOrganizationApiKeyScope).min(1).optional()
462
+ });
463
+ var ZOrganizationApiKeyParam = z10.object({
464
+ keyId: z10.string().uuid()
465
+ });
466
+
467
+ // ../utils/dist/validation/exercise/exercise.js
468
+ import * as z11 from "zod";
104
469
 
105
470
  // ../question-types/dist/question-type-keys.js
106
471
  var QUESTION_TYPE_KEY = {
@@ -444,226 +809,384 @@ var ALLOWED_DOCUMENT_TYPES = [
444
809
  "application/msword"
445
810
  // .doc
446
811
  ];
812
+ var QUESTION_TYPE = QUESTION_TYPE_IDS;
813
+
814
+ // ../utils/dist/validation/exercise/exercise.js
815
+ var QUESTION_VALIDATION_RULES = {
816
+ [QUESTION_TYPE.RADIO]: [
817
+ (question) => {
818
+ const options = question.options || [];
819
+ if (options.length > 0 && options.length < 2) {
820
+ return "Options must have at least 2 items for RADIO/CHECKBOX questions";
821
+ }
822
+ return null;
823
+ },
824
+ (question) => {
825
+ const options = question.options || [];
826
+ if (options.length > 0 && !options.some((opt) => opt.isCorrect === true)) {
827
+ return "Please mark an option as the correct answer";
828
+ }
829
+ return null;
830
+ }
831
+ ],
832
+ [QUESTION_TYPE.CHECKBOX]: [
833
+ (question) => {
834
+ const options = question.options || [];
835
+ if (options.length > 0 && options.length < 2) {
836
+ return "Options must have at least 2 items for RADIO/CHECKBOX questions";
837
+ }
838
+ return null;
839
+ },
840
+ (question) => {
841
+ const options = question.options || [];
842
+ if (options.length > 0 && !options.some((opt) => opt.isCorrect === true)) {
843
+ return "Please mark an option as the correct answer";
844
+ }
845
+ return null;
846
+ }
847
+ ],
848
+ [QUESTION_TYPE.TRUE_FALSE]: [
849
+ (question) => {
850
+ const options = question.options || [];
851
+ if (options.length > 0 && options.length < 2) {
852
+ return "True/False questions need both True and False options";
853
+ }
854
+ return null;
855
+ },
856
+ (question) => {
857
+ const options = question.options || [];
858
+ if (options.length > 0 && !options.some((opt) => opt.isCorrect === true)) {
859
+ return "Please mark an option as the correct answer";
860
+ }
861
+ return null;
862
+ }
863
+ ],
864
+ [QUESTION_TYPE.TEXTAREA]: []
865
+ };
866
+ var ZExerciseUpdateQuestionBase = z11.object({
867
+ id: z11.number().int().optional(),
868
+ question: z11.string().min(1),
869
+ questionTypeId: z11.number().int().min(1).optional(),
870
+ // Added to support question type updates
871
+ points: z11.number().int().min(0).optional(),
872
+ order: z11.number().int().min(0).optional(),
873
+ settings: z11.record(z11.string(), z11.unknown()).optional(),
874
+ deletedAt: z11.string().optional(),
875
+ // Marks question as deleted
876
+ options: z11.array(z11.object({
877
+ id: z11.number().int().optional(),
878
+ label: z11.string().min(1),
879
+ isCorrect: z11.boolean(),
880
+ settings: z11.record(z11.string(), z11.unknown()).optional(),
881
+ deletedAt: z11.string().optional()
882
+ // Marks option as deleted
883
+ })).optional()
884
+ });
885
+ function validateQuestionOptions(question, ctx) {
886
+ if (question.deletedAt)
887
+ return;
888
+ const rules = QUESTION_VALIDATION_RULES[question.questionTypeId ?? -1] ?? [];
889
+ for (const rule of rules) {
890
+ const message = rule(question);
891
+ if (!message)
892
+ continue;
893
+ ctx.addIssue({
894
+ code: "custom",
895
+ message,
896
+ path: ["options"]
897
+ });
898
+ }
899
+ }
900
+ var ZExerciseUpdateQuestion = ZExerciseUpdateQuestionBase.superRefine(validateQuestionOptions);
901
+ var ZExerciseCreate = z11.object({
902
+ title: z11.string().min(1),
903
+ description: z11.string().optional(),
904
+ lessonId: z11.string().optional(),
905
+ sectionId: z11.string().optional(),
906
+ order: z11.number().int().optional(),
907
+ courseId: z11.string().min(1),
908
+ dueBy: z11.string().optional(),
909
+ questions: z11.array(z11.object({
910
+ question: z11.string().min(1),
911
+ questionTypeId: z11.number().int().min(1).optional(),
912
+ points: z11.number().int().min(0).optional(),
913
+ settings: z11.record(z11.string(), z11.unknown()).optional(),
914
+ options: z11.array(z11.object({
915
+ label: z11.string().min(1),
916
+ isCorrect: z11.boolean(),
917
+ settings: z11.record(z11.string(), z11.unknown()).optional()
918
+ })).min(2)
919
+ })).optional()
920
+ });
921
+ var ZExerciseUpdate = z11.object({
922
+ title: z11.string().min(1).optional(),
923
+ description: z11.string().optional(),
924
+ lessonId: z11.string().optional(),
925
+ sectionId: z11.string().optional(),
926
+ order: z11.number().int().optional(),
927
+ isUnlocked: z11.boolean().optional(),
928
+ dueBy: z11.string().optional(),
929
+ // Changed from iso.datetime() to string to match frontend format
930
+ questions: z11.array(ZExerciseUpdateQuestion).optional()
931
+ });
932
+ var ZExerciseGetParam = z11.object({
933
+ exerciseId: z11.string().min(1)
934
+ });
935
+ var ZExerciseListQuery = z11.object({
936
+ lessonId: z11.string().optional(),
937
+ sectionId: z11.string().optional()
938
+ });
939
+ var ZExerciseSubmissionCreate = z11.object({
940
+ exerciseId: z11.string().min(1),
941
+ answers: z11.array(z11.object({
942
+ questionId: z11.number().int(),
943
+ optionId: z11.number().int().optional(),
944
+ answer: z11.string().optional()
945
+ })).min(1)
946
+ });
947
+ var ZExerciseFromTemplate = z11.object({
948
+ lessonId: z11.string().optional(),
949
+ sectionId: z11.string().optional(),
950
+ order: z11.number().int().optional(),
951
+ templateId: z11.number().int().min(1)
952
+ });
953
+
954
+ // ../utils/dist/validation/course-import/course-import.js
955
+ import * as z13 from "zod";
447
956
 
448
957
  // ../utils/dist/validation/course/course.js
449
- var ZCourseClone = z2.object({
450
- title: z2.string().min(1),
451
- description: z2.string().optional(),
452
- slug: z2.string().min(1),
453
- organizationId: z2.string().min(1)
454
- });
455
- var ZCourseCloneParam = z2.object({
456
- courseId: z2.string().min(1)
457
- });
458
- var ZCourseGetParam = z2.object({
459
- courseId: z2.string().min(1)
460
- });
461
- var ZCourseGetQuery = z2.object({
462
- slug: z2.string().optional()
463
- });
464
- var ZCourseGetBySlugParam = z2.object({
465
- slug: z2.string().min(1)
466
- });
467
- var ZCourseEnrollParam = z2.object({
468
- courseId: z2.string().min(1)
469
- });
470
- var ZCourseEnrollBody = z2.object({
471
- inviteToken: z2.string().min(1).optional()
472
- });
473
- var ZCourseDownloadParam = z2.object({
474
- courseId: z2.string().min(1)
475
- });
476
- var ZCertificateDownload = z2.object({
477
- theme: z2.string().min(1),
478
- studentName: z2.string().min(1),
479
- courseName: z2.string().min(1),
480
- courseDescription: z2.string().min(1),
481
- orgName: z2.string().min(1),
482
- orgLogoUrl: z2.string().url().optional(),
483
- facilitator: z2.string().optional()
484
- });
485
- var ZCourseDownloadContent = z2.object({
486
- courseTitle: z2.string().min(1),
487
- orgName: z2.string().min(1),
488
- orgTheme: z2.string().min(1),
489
- lessons: z2.array(z2.object({
490
- lessonTitle: z2.string().min(1),
491
- lessonNumber: z2.string().min(1),
492
- lessonNote: z2.string(),
493
- slideUrl: z2.string().url().optional(),
494
- video: z2.array(z2.string().url()).optional()
958
+ import * as z12 from "zod";
959
+ var ZCourseClone = z12.object({
960
+ title: z12.string().min(1),
961
+ description: z12.string().optional(),
962
+ slug: z12.string().min(1),
963
+ organizationId: z12.string().min(1)
964
+ });
965
+ var ZCourseCloneParam = z12.object({
966
+ courseId: z12.string().min(1)
967
+ });
968
+ var ZCourseGetParam = z12.object({
969
+ courseId: z12.string().min(1)
970
+ });
971
+ var ZCourseGetQuery = z12.object({
972
+ slug: z12.string().optional()
973
+ });
974
+ var ZCourseGetBySlugParam = z12.object({
975
+ slug: z12.string().min(1)
976
+ });
977
+ var ZCourseEnrollParam = z12.object({
978
+ courseId: z12.string().min(1)
979
+ });
980
+ var ZCourseEnrollBody = z12.object({
981
+ inviteToken: z12.string().min(1).optional()
982
+ });
983
+ var ZCourseDownloadParam = z12.object({
984
+ courseId: z12.string().min(1)
985
+ });
986
+ var ZCertificateDownload = z12.object({
987
+ theme: z12.string().min(1),
988
+ studentName: z12.string().min(1),
989
+ courseName: z12.string().min(1),
990
+ courseDescription: z12.string().min(1),
991
+ orgName: z12.string().min(1),
992
+ orgLogoUrl: z12.string().url().optional(),
993
+ facilitator: z12.string().optional()
994
+ });
995
+ var ZCourseDownloadContent = z12.object({
996
+ courseTitle: z12.string().min(1),
997
+ orgName: z12.string().min(1),
998
+ orgTheme: z12.string().min(1),
999
+ lessons: z12.array(z12.object({
1000
+ lessonTitle: z12.string().min(1),
1001
+ lessonNumber: z12.string().min(1),
1002
+ lessonNote: z12.string(),
1003
+ slideUrl: z12.string().url().optional(),
1004
+ video: z12.array(z12.string().url()).optional()
495
1005
  }))
496
1006
  });
497
- var ZLessonDownloadContent = z2.object({
498
- title: z2.string().min(1),
499
- number: z2.string().min(1),
500
- orgName: z2.string().min(1),
501
- note: z2.string(),
502
- slideUrl: z2.string().url().optional(),
503
- video: z2.array(z2.string().url()).optional(),
504
- courseTitle: z2.string().min(1)
505
- });
506
- var ZCoursePresignUrlUpload = z2.object({
507
- fileName: z2.string().min(1),
508
- fileType: z2.enum(ALLOWED_CONTENT_TYPES)
509
- });
510
- var ZCourseDocumentPresignUrlUpload = z2.object({
511
- fileName: z2.string().min(1),
512
- fileType: z2.enum(ALLOWED_DOCUMENT_TYPES)
513
- });
514
- var ZCourseDownloadPresignedUrl = z2.object({
515
- keys: z2.array(z2.string().min(1)).min(1)
516
- });
517
- var ZCourseContentUpdateItem = z2.object({
518
- id: z2.string().min(1),
519
- type: z2.enum(["LESSON", "EXERCISE"]),
520
- isUnlocked: z2.boolean().optional(),
521
- order: z2.number().int().min(0).optional(),
522
- sectionId: z2.string().nullable().optional()
523
- });
524
- var ZCourseContentUpdate = z2.object({
525
- items: z2.array(ZCourseContentUpdateItem).min(1)
526
- });
527
- var ZCourseContentDeleteItem = z2.object({
528
- id: z2.string().min(1),
529
- type: z2.enum(["LESSON", "EXERCISE"])
530
- });
531
- var ZCourseContentDelete = z2.object({
532
- sectionId: z2.string().min(1).optional(),
533
- items: z2.array(ZCourseContentDeleteItem).min(1).optional()
1007
+ var ZLessonDownloadContent = z12.object({
1008
+ title: z12.string().min(1),
1009
+ number: z12.string().min(1),
1010
+ orgName: z12.string().min(1),
1011
+ note: z12.string(),
1012
+ slideUrl: z12.string().url().optional(),
1013
+ video: z12.array(z12.string().url()).optional(),
1014
+ courseTitle: z12.string().min(1)
1015
+ });
1016
+ var ZCoursePresignUrlUpload = z12.object({
1017
+ fileName: z12.string().min(1),
1018
+ fileType: z12.enum(ALLOWED_CONTENT_TYPES)
1019
+ });
1020
+ var ZCourseDocumentPresignUrlUpload = z12.object({
1021
+ fileName: z12.string().min(1),
1022
+ fileType: z12.enum(ALLOWED_DOCUMENT_TYPES)
1023
+ });
1024
+ var ZCourseDownloadPresignedUrl = z12.object({
1025
+ keys: z12.array(z12.string().min(1)).min(1)
1026
+ });
1027
+ var ZCourseContentUpdateItem = z12.object({
1028
+ id: z12.string().min(1),
1029
+ type: z12.enum(["LESSON", "EXERCISE"]),
1030
+ isUnlocked: z12.boolean().optional(),
1031
+ order: z12.number().int().min(0).optional(),
1032
+ sectionId: z12.string().nullable().optional()
1033
+ });
1034
+ var ZCourseContentUpdate = z12.object({
1035
+ items: z12.array(ZCourseContentUpdateItem).min(1)
1036
+ });
1037
+ var ZCourseContentDeleteItem = z12.object({
1038
+ id: z12.string().min(1),
1039
+ type: z12.enum(["LESSON", "EXERCISE"])
1040
+ });
1041
+ var ZCourseContentDelete = z12.object({
1042
+ sectionId: z12.string().min(1).optional(),
1043
+ items: z12.array(ZCourseContentDeleteItem).min(1).optional()
534
1044
  }).refine((data) => Boolean(data.sectionId) !== Boolean(data.items), {
535
1045
  message: "Provide either sectionId or items",
536
1046
  path: ["sectionId"]
537
1047
  });
538
- var ZCourseCreate = z2.object({
539
- title: z2.string().min(1),
540
- description: z2.string().min(1),
541
- type: z2.enum(["LIVE_CLASS", "SELF_PACED"]),
542
- organizationId: z2.string().min(1)
543
- });
544
- var ZCourseMetadata = z2.object({
545
- requirements: z2.string().optional(),
546
- description: z2.string().optional(),
547
- goals: z2.string().optional(),
548
- videoUrl: z2.string().optional(),
549
- showDiscount: z2.boolean().optional(),
550
- discount: z2.number().optional(),
551
- paymentLink: z2.string().optional(),
552
- reward: z2.object({
553
- show: z2.boolean(),
554
- description: z2.string()
1048
+ var ZCourseCreate = z12.object({
1049
+ title: z12.string().min(1),
1050
+ description: z12.string().min(1),
1051
+ type: z12.enum(["LIVE_CLASS", "SELF_PACED"]),
1052
+ organizationId: z12.string().min(1)
1053
+ });
1054
+ var ZCourseMetadata = z12.object({
1055
+ requirements: z12.string().optional(),
1056
+ description: z12.string().optional(),
1057
+ goals: z12.string().optional(),
1058
+ videoUrl: z12.string().optional(),
1059
+ showDiscount: z12.boolean().optional(),
1060
+ discount: z12.number().optional(),
1061
+ paymentLink: z12.string().optional(),
1062
+ reward: z12.object({
1063
+ show: z12.boolean(),
1064
+ description: z12.string()
555
1065
  }).optional(),
556
- instructor: z2.object({
557
- name: z2.string(),
558
- role: z2.string(),
559
- coursesNo: z2.number(),
560
- description: z2.string(),
561
- imgUrl: z2.string()
1066
+ instructor: z12.object({
1067
+ name: z12.string(),
1068
+ role: z12.string(),
1069
+ coursesNo: z12.number(),
1070
+ description: z12.string(),
1071
+ imgUrl: z12.string()
562
1072
  }).optional(),
563
- certificate: z2.object({
564
- templateUrl: z2.string()
1073
+ certificate: z12.object({
1074
+ templateUrl: z12.string()
565
1075
  }).optional(),
566
- reviews: z2.array(z2.object({
567
- id: z2.number(),
568
- hide: z2.boolean(),
569
- name: z2.string(),
570
- avatar_url: z2.string(),
571
- rating: z2.number(),
572
- created_at: z2.number(),
573
- description: z2.string()
1076
+ reviews: z12.array(z12.object({
1077
+ id: z12.number(),
1078
+ hide: z12.boolean(),
1079
+ name: z12.string(),
1080
+ avatar_url: z12.string(),
1081
+ rating: z12.number(),
1082
+ created_at: z12.number(),
1083
+ description: z12.string()
574
1084
  })).optional(),
575
- lessonTabsOrder: z2.array(z2.object({
576
- id: z2.union([z2.literal(1), z2.literal(2), z2.literal(3), z2.literal(4)]),
577
- name: z2.string()
1085
+ lessonTabsOrder: z12.array(z12.object({
1086
+ id: z12.union([z12.literal(1), z12.literal(2), z12.literal(3), z12.literal(4)]),
1087
+ name: z12.string()
578
1088
  })).optional(),
579
- grading: z2.boolean().optional(),
580
- lessonDownload: z2.boolean().optional(),
581
- allowNewStudent: z2.boolean(),
582
- sectionDisplay: z2.record(z2.string(), z2.boolean()).optional(),
583
- isContentGroupingEnabled: z2.boolean().optional()
584
- });
585
- var ZCourseUpdate = z2.object({
586
- title: z2.string().min(1).optional(),
587
- description: z2.string().min(1).optional(),
588
- type: z2.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
589
- logo: z2.string().optional(),
590
- slug: z2.string().optional(),
591
- isPublished: z2.boolean().optional(),
592
- overview: z2.string().optional(),
1089
+ grading: z12.boolean().optional(),
1090
+ lessonDownload: z12.boolean().optional(),
1091
+ allowNewStudent: z12.boolean(),
1092
+ sectionDisplay: z12.record(z12.string(), z12.boolean()).optional(),
1093
+ isContentGroupingEnabled: z12.boolean().optional()
1094
+ });
1095
+ var ZCourseUpdate = z12.object({
1096
+ title: z12.string().min(1).optional(),
1097
+ description: z12.string().min(1).optional(),
1098
+ type: z12.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
1099
+ logo: z12.string().optional(),
1100
+ slug: z12.string().optional(),
1101
+ isPublished: z12.boolean().optional(),
1102
+ overview: z12.string().optional(),
593
1103
  metadata: ZCourseMetadata.optional(),
594
- isCertificateDownloadable: z2.boolean().optional(),
595
- certificateTheme: z2.string().optional(),
596
- tagIds: z2.array(z2.uuid()).max(100).optional()
1104
+ isCertificateDownloadable: z12.boolean().optional(),
1105
+ certificateTheme: z12.string().optional(),
1106
+ tagIds: z12.array(z12.uuid()).max(100).optional()
597
1107
  });
598
- var ZCourseUpdateParam = z2.object({
599
- courseId: z2.string().min(1)
1108
+ var ZCourseUpdateParam = z12.object({
1109
+ courseId: z12.string().min(1)
600
1110
  });
601
- var ZCourseDeleteParam = z2.object({
602
- courseId: z2.string().min(1)
1111
+ var ZCourseDeleteParam = z12.object({
1112
+ courseId: z12.string().min(1)
603
1113
  });
604
- var ZCourseProgressParam = z2.object({
605
- courseId: z2.string().min(1)
1114
+ var ZCourseProgressParam = z12.object({
1115
+ courseId: z12.string().min(1)
606
1116
  });
607
- var ZCourseProgressQuery = z2.object({
608
- profileId: z2.string().uuid()
1117
+ var ZCourseProgressQuery = z12.object({
1118
+ profileId: z12.string().uuid()
609
1119
  });
610
- var ZCourseUserAnalyticsParam = z2.object({
611
- courseId: z2.string().min(1),
612
- userId: z2.string().uuid()
1120
+ var ZCourseUserAnalyticsParam = z12.object({
1121
+ courseId: z12.string().min(1),
1122
+ userId: z12.string().uuid()
613
1123
  });
614
1124
 
615
1125
  // ../utils/dist/validation/course-import/course-import.js
616
- var ZSupportedLocale = z3.enum(["en", "hi", "fr", "pt", "de", "vi", "ru", "es", "pl", "da"]);
617
- var ZCourseImportWarning = z3.object({
618
- code: z3.string().min(1),
619
- message: z3.string().min(1),
620
- severity: z3.enum(["info", "warning", "error"])
621
- });
622
- var ZCourseImportSourceReference = z3.object({
623
- type: z3.enum(["prompt", "pdf", "course"]),
624
- label: z3.string().min(1),
625
- pageStart: z3.number().int().min(1).optional(),
626
- pageEnd: z3.number().int().min(1).optional()
627
- });
628
- var ZCourseImportDraftCourse = z3.object({
629
- title: z3.string().min(1),
630
- description: z3.string().min(1),
631
- type: z3.enum(["LIVE_CLASS", "SELF_PACED"]),
1126
+ var ZSupportedLocale = z13.enum(["en", "hi", "fr", "pt", "de", "vi", "ru", "es", "pl", "da"]);
1127
+ var ZCourseImportWarning = z13.object({
1128
+ code: z13.string().min(1),
1129
+ message: z13.string().min(1),
1130
+ severity: z13.enum(["info", "warning", "error"])
1131
+ });
1132
+ var ZCourseImportSourceReference = z13.object({
1133
+ type: z13.enum(["prompt", "pdf", "course"]),
1134
+ label: z13.string().min(1),
1135
+ pageStart: z13.number().int().min(1).optional(),
1136
+ pageEnd: z13.number().int().min(1).optional()
1137
+ });
1138
+ var ZCourseImportDraftCourse = z13.object({
1139
+ title: z13.string().min(1),
1140
+ description: z13.string().min(1),
1141
+ type: z13.enum(["LIVE_CLASS", "SELF_PACED"]),
632
1142
  locale: ZSupportedLocale.default("en"),
633
1143
  metadata: ZCourseMetadata.optional()
634
1144
  });
635
- var ZCourseImportDraftSection = z3.object({
636
- externalId: z3.string().min(1),
637
- title: z3.string().min(1),
638
- order: z3.number().int().min(0)
639
- });
640
- var ZCourseImportDraftLesson = z3.object({
641
- externalId: z3.string().min(1),
642
- sectionExternalId: z3.string().min(1),
643
- title: z3.string().min(1),
644
- order: z3.number().int().min(0),
645
- isUnlocked: z3.boolean().optional(),
646
- public: z3.boolean().optional()
647
- });
648
- var ZCourseImportDraftLessonLanguage = z3.object({
649
- lessonExternalId: z3.string().min(1),
1145
+ var ZCourseImportDraftSection = z13.object({
1146
+ externalId: z13.string().min(1),
1147
+ title: z13.string().min(1),
1148
+ order: z13.number().int().min(0)
1149
+ });
1150
+ var ZCourseImportDraftLesson = z13.object({
1151
+ externalId: z13.string().min(1),
1152
+ sectionExternalId: z13.string().min(1),
1153
+ title: z13.string().min(1),
1154
+ order: z13.number().int().min(0),
1155
+ isUnlocked: z13.boolean().optional(),
1156
+ public: z13.boolean().optional()
1157
+ });
1158
+ var ZCourseImportDraftLessonLanguage = z13.object({
1159
+ lessonExternalId: z13.string().min(1),
650
1160
  locale: ZSupportedLocale,
651
- content: z3.string().min(1)
1161
+ content: z13.string().min(1)
652
1162
  });
653
- var ZCourseImportDraftPayload = z3.object({
1163
+ var ZCourseImportDraftPayload = z13.object({
654
1164
  course: ZCourseImportDraftCourse,
655
- sections: z3.array(ZCourseImportDraftSection).min(1),
656
- lessons: z3.array(ZCourseImportDraftLesson).min(1),
657
- lessonLanguages: z3.array(ZCourseImportDraftLessonLanguage).min(1),
658
- exercises: z3.array(z3.record(z3.string(), z3.unknown())).optional(),
659
- sourceReferences: z3.array(ZCourseImportSourceReference).optional(),
660
- warnings: z3.array(ZCourseImportWarning).default([])
1165
+ tags: z13.array(z13.string().trim().min(1).max(80)).max(100).default([]),
1166
+ sections: z13.array(ZCourseImportDraftSection).min(1),
1167
+ lessons: z13.array(ZCourseImportDraftLesson).min(1),
1168
+ lessonLanguages: z13.array(ZCourseImportDraftLessonLanguage).min(1),
1169
+ exercises: z13.array(z13.record(z13.string(), z13.unknown())).optional(),
1170
+ sourceReferences: z13.array(ZCourseImportSourceReference).optional(),
1171
+ warnings: z13.array(ZCourseImportWarning).default([])
661
1172
  }).superRefine((value, ctx) => {
1173
+ const normalizedTags = /* @__PURE__ */ new Set();
1174
+ value.tags.forEach((tag, index) => {
1175
+ const tagKey = tag.trim().toLowerCase();
1176
+ if (normalizedTags.has(tagKey)) {
1177
+ ctx.addIssue({
1178
+ code: z13.ZodIssueCode.custom,
1179
+ path: ["tags", index],
1180
+ message: "Draft tags must be unique"
1181
+ });
1182
+ }
1183
+ normalizedTags.add(tagKey);
1184
+ });
662
1185
  const sectionIds = /* @__PURE__ */ new Set();
663
1186
  value.sections.forEach((section, index) => {
664
1187
  if (sectionIds.has(section.externalId)) {
665
1188
  ctx.addIssue({
666
- code: z3.ZodIssueCode.custom,
1189
+ code: z13.ZodIssueCode.custom,
667
1190
  path: ["sections", index, "externalId"],
668
1191
  message: "Section externalId must be unique"
669
1192
  });
@@ -674,7 +1197,7 @@ var ZCourseImportDraftPayload = z3.object({
674
1197
  value.lessons.forEach((lesson, index) => {
675
1198
  if (lessonIds.has(lesson.externalId)) {
676
1199
  ctx.addIssue({
677
- code: z3.ZodIssueCode.custom,
1200
+ code: z13.ZodIssueCode.custom,
678
1201
  path: ["lessons", index, "externalId"],
679
1202
  message: "Lesson externalId must be unique"
680
1203
  });
@@ -682,7 +1205,7 @@ var ZCourseImportDraftPayload = z3.object({
682
1205
  lessonIds.add(lesson.externalId);
683
1206
  if (!sectionIds.has(lesson.sectionExternalId)) {
684
1207
  ctx.addIssue({
685
- code: z3.ZodIssueCode.custom,
1208
+ code: z13.ZodIssueCode.custom,
686
1209
  path: ["lessons", index, "sectionExternalId"],
687
1210
  message: "Lesson sectionExternalId must reference an existing section"
688
1211
  });
@@ -691,52 +1214,76 @@ var ZCourseImportDraftPayload = z3.object({
691
1214
  value.lessonLanguages.forEach((lessonLanguage, index) => {
692
1215
  if (!lessonIds.has(lessonLanguage.lessonExternalId)) {
693
1216
  ctx.addIssue({
694
- code: z3.ZodIssueCode.custom,
1217
+ code: z13.ZodIssueCode.custom,
695
1218
  path: ["lessonLanguages", index, "lessonExternalId"],
696
1219
  message: "Lesson language must reference an existing lesson"
697
1220
  });
698
1221
  }
699
1222
  });
700
1223
  });
701
- var ZCourseImportDraftCreate = z3.object({
702
- sourceType: z3.enum(["prompt", "pdf", "course"]),
703
- idempotencyKey: z3.string().min(1).optional(),
704
- summary: z3.record(z3.string(), z3.unknown()).optional(),
705
- sourceArtifacts: z3.array(z3.record(z3.string(), z3.unknown())).optional(),
1224
+ var ZCourseImportDraftCreate = z13.object({
1225
+ sourceType: z13.enum(["prompt", "pdf", "course"]),
1226
+ idempotencyKey: z13.string().min(1).optional(),
1227
+ summary: z13.record(z13.string(), z13.unknown()).optional(),
1228
+ sourceArtifacts: z13.array(z13.record(z13.string(), z13.unknown())).optional(),
706
1229
  draft: ZCourseImportDraftPayload
707
1230
  });
708
- var ZCourseImportCourseParam = z3.object({
709
- courseId: z3.string().min(1)
1231
+ var ZCourseImportCourseParam = z13.object({
1232
+ courseId: z13.string().min(1)
710
1233
  });
711
- var ZCourseImportDraftCreateFromCourse = z3.object({
712
- courseId: z3.string().min(1),
713
- idempotencyKey: z3.string().min(1).optional(),
714
- summary: z3.record(z3.string(), z3.unknown()).optional(),
715
- sourceArtifacts: z3.array(z3.record(z3.string(), z3.unknown())).optional()
1234
+ var ZCourseImportDraftCreateFromCourse = z13.object({
1235
+ courseId: z13.string().min(1),
1236
+ idempotencyKey: z13.string().min(1).optional(),
1237
+ summary: z13.record(z13.string(), z13.unknown()).optional(),
1238
+ sourceArtifacts: z13.array(z13.record(z13.string(), z13.unknown())).optional()
716
1239
  });
717
- var ZCourseImportDraftGetParam = z3.object({
718
- draftId: z3.string().uuid()
1240
+ var ZCourseImportDraftGetParam = z13.object({
1241
+ draftId: z13.string().uuid()
719
1242
  });
720
- var ZCourseImportDraftUpdate = z3.object({
721
- summary: z3.record(z3.string(), z3.unknown()).optional(),
722
- sourceArtifacts: z3.array(z3.record(z3.string(), z3.unknown())).optional(),
723
- warnings: z3.array(ZCourseImportWarning).optional(),
1243
+ var ZCourseImportDraftUpdate = z13.object({
1244
+ summary: z13.record(z13.string(), z13.unknown()).optional(),
1245
+ sourceArtifacts: z13.array(z13.record(z13.string(), z13.unknown())).optional(),
1246
+ warnings: z13.array(ZCourseImportWarning).optional(),
724
1247
  draft: ZCourseImportDraftPayload.optional()
725
1248
  });
726
- var ZCourseImportDraftPublish = z3.object({
727
- title: z3.string().min(1).optional(),
728
- description: z3.string().min(1).optional(),
729
- type: z3.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
730
- metadata: ZCourseMetadata.optional()
1249
+ var ZCourseImportDraftPublish = z13.object({
1250
+ title: z13.string().min(1).optional(),
1251
+ description: z13.string().min(1).optional(),
1252
+ type: z13.enum(["LIVE_CLASS", "SELF_PACED"]).optional(),
1253
+ metadata: ZCourseMetadata.optional(),
1254
+ bannerImageUrl: z13.string().url().optional(),
1255
+ bannerImageQuery: z13.string().min(1).max(120).optional(),
1256
+ generateBannerImage: z13.boolean().optional()
731
1257
  });
732
1258
  var ZCourseImportDraftPublishToCourse = ZCourseImportDraftPublish.extend({
733
- courseId: z3.string().min(1)
1259
+ courseId: z13.string().min(1)
734
1260
  });
735
1261
 
736
1262
  // src/tools/course-drafts.ts
737
1263
  var ZUpdateCourseDraftToolInput = ZCourseImportDraftUpdate.extend({
738
1264
  draftId: ZCourseImportDraftGetParam.shape.draftId
739
1265
  });
1266
+ var ZTagCourseDraftToolInput = ZAutomationDraftTagAssignment.extend({
1267
+ draftId: ZAutomationDraftTagParam.shape.draftId
1268
+ });
1269
+ var ZListCourseExercisesToolInput = ZExerciseListQuery.extend({
1270
+ courseId: ZCourseImportCourseParam.shape.courseId
1271
+ });
1272
+ var ZGetCourseExerciseToolInput = ZExerciseGetParam.extend({
1273
+ courseId: ZCourseImportCourseParam.shape.courseId
1274
+ });
1275
+ var ZCreateCourseExerciseToolInput = ZExerciseCreate.omit({
1276
+ courseId: true
1277
+ }).extend({
1278
+ courseId: ZCourseImportCourseParam.shape.courseId
1279
+ });
1280
+ var ZCreateCourseExerciseFromTemplateToolInput = ZExerciseFromTemplate.extend({
1281
+ courseId: ZCourseImportCourseParam.shape.courseId
1282
+ });
1283
+ var ZUpdateCourseExerciseToolInput = ZExerciseUpdate.extend({
1284
+ courseId: ZCourseImportCourseParam.shape.courseId,
1285
+ exerciseId: ZExerciseGetParam.shape.exerciseId
1286
+ });
740
1287
  var ZPublishCourseDraftToolInput = ZCourseImportDraftPublish.extend({
741
1288
  draftId: ZCourseImportDraftGetParam.shape.draftId
742
1289
  });
@@ -745,47 +1292,170 @@ var ZPublishCourseDraftToExistingCourseToolInput = ZCourseImportDraftPublishToCo
745
1292
  });
746
1293
  var createCourseDraftShape = ZCourseImportDraftCreate.shape;
747
1294
  var createCourseDraftFromCourseShape = ZCourseImportDraftCreateFromCourse.shape;
1295
+ var listOrganizationCoursesShape = ZGetOrganizationCoursesQuery.shape;
748
1296
  var getCourseStructureShape = ZCourseImportCourseParam.shape;
749
1297
  var getCourseDraftShape = ZCourseImportDraftGetParam.shape;
750
1298
  var updateCourseDraftShape = ZUpdateCourseDraftToolInput.shape;
1299
+ var tagCourseDraftShape = ZTagCourseDraftToolInput.shape;
1300
+ var listCourseExercisesShape = ZListCourseExercisesToolInput.shape;
1301
+ var getCourseExerciseShape = ZGetCourseExerciseToolInput.shape;
1302
+ var createCourseExerciseShape = ZCreateCourseExerciseToolInput.shape;
1303
+ var createCourseExerciseFromTemplateShape = ZCreateCourseExerciseFromTemplateToolInput.shape;
1304
+ var updateCourseExerciseShape = ZUpdateCourseExerciseToolInput.shape;
751
1305
  var publishCourseDraftShape = ZPublishCourseDraftToolInput.shape;
752
1306
  var publishCourseDraftToExistingCourseShape = ZPublishCourseDraftToExistingCourseToolInput.shape;
1307
+ var tagCoursesShape = ZAutomationCourseTagAssignment.shape;
753
1308
  function registerCourseDraftTools(server, apiClient) {
754
- server.tool("get_course_structure", getCourseStructureShape, async (args) => {
755
- const { courseId } = ZCourseImportCourseParam.parse(args);
756
- const result = await apiClient.getCourseStructure(courseId);
757
- return jsonContent(result);
758
- });
759
- server.tool("create_course_draft", createCourseDraftShape, async (args) => {
760
- const payload = ZCourseImportDraftCreate.parse(args);
761
- const result = await apiClient.createCourseDraft(payload);
762
- return jsonContent(result);
763
- });
764
- server.tool("create_course_draft_from_course", createCourseDraftFromCourseShape, async (args) => {
765
- const payload = ZCourseImportDraftCreateFromCourse.parse(args);
766
- const result = await apiClient.createCourseDraftFromCourse(payload);
767
- return jsonContent(result);
768
- });
769
- server.tool("get_course_draft", getCourseDraftShape, async (args) => {
770
- const { draftId } = ZCourseImportDraftGetParam.parse(args);
771
- const result = await apiClient.getCourseDraft(draftId);
772
- return jsonContent(result);
773
- });
774
- server.tool("update_course_draft", updateCourseDraftShape, async (args) => {
775
- const { draftId, ...payload } = ZUpdateCourseDraftToolInput.parse(args);
776
- const result = await apiClient.updateCourseDraft(draftId, payload);
777
- return jsonContent(result);
778
- });
779
- server.tool("publish_course_draft", publishCourseDraftShape, async (args) => {
780
- const { draftId, ...payload } = ZPublishCourseDraftToolInput.parse(args);
781
- const result = await apiClient.publishCourseDraft(draftId, payload);
782
- return jsonContent(result);
783
- });
784
- server.tool("publish_course_draft_to_existing_course", publishCourseDraftToExistingCourseShape, async (args) => {
785
- const { draftId, ...payload } = ZPublishCourseDraftToExistingCourseToolInput.parse(args);
786
- const result = await apiClient.publishCourseDraftToExistingCourse(draftId, payload);
787
- return jsonContent(result);
788
- });
1309
+ server.tool(
1310
+ "list_org_courses",
1311
+ "List all courses in the authenticated organization. Use this when the user refers to a course by name and you need to discover the available course IDs first.",
1312
+ listOrganizationCoursesShape,
1313
+ async (args) => {
1314
+ const query = ZGetOrganizationCoursesQuery.parse(args);
1315
+ const result = await apiClient.listOrganizationCourses(query);
1316
+ return jsonContent(result);
1317
+ }
1318
+ );
1319
+ server.tool(
1320
+ "get_course_structure",
1321
+ "Read the current live course structure. Use this before creating a fresh draft for post-publish edits.",
1322
+ getCourseStructureShape,
1323
+ async (args) => {
1324
+ const { courseId } = ZCourseImportCourseParam.parse(args);
1325
+ const result = await apiClient.getCourseStructure(courseId);
1326
+ return jsonContent(result);
1327
+ }
1328
+ );
1329
+ server.tool(
1330
+ "create_course_draft",
1331
+ "Create a new unpublished course draft from structured course JSON. Use this before the first publish.",
1332
+ createCourseDraftShape,
1333
+ async (args) => {
1334
+ const payload = ZCourseImportDraftCreate.parse(args);
1335
+ const result = await apiClient.createCourseDraft(payload);
1336
+ return jsonContent(result);
1337
+ }
1338
+ );
1339
+ server.tool(
1340
+ "create_course_draft_from_course",
1341
+ "Create a fresh draft from an existing live course. Use this after a course has already been published and the user wants more changes.",
1342
+ createCourseDraftFromCourseShape,
1343
+ async (args) => {
1344
+ const payload = ZCourseImportDraftCreateFromCourse.parse(args);
1345
+ const result = await apiClient.createCourseDraftFromCourse(payload);
1346
+ return jsonContent(result);
1347
+ }
1348
+ );
1349
+ server.tool(
1350
+ "get_course_draft",
1351
+ "Fetch an existing draft. Draft responses include status and publishedCourseId so you can decide whether to keep editing the draft or seed a fresh one from the live course.",
1352
+ getCourseDraftShape,
1353
+ async (args) => {
1354
+ const { draftId } = ZCourseImportDraftGetParam.parse(args);
1355
+ const result = await apiClient.getCourseDraft(draftId);
1356
+ return jsonContent(result);
1357
+ }
1358
+ );
1359
+ server.tool(
1360
+ "list_course_exercises",
1361
+ "List exercises for a live course, optionally filtered by lessonId or sectionId.",
1362
+ listCourseExercisesShape,
1363
+ async (args) => {
1364
+ const { courseId, ...query } = ZListCourseExercisesToolInput.parse(args);
1365
+ const result = await apiClient.listCourseExercises(courseId, query);
1366
+ return jsonContent(result);
1367
+ }
1368
+ );
1369
+ server.tool(
1370
+ "get_course_exercise",
1371
+ "Fetch a single exercise from a live course, including its questions and options.",
1372
+ getCourseExerciseShape,
1373
+ async (args) => {
1374
+ const { courseId, exerciseId } = ZGetCourseExerciseToolInput.parse(args);
1375
+ const result = await apiClient.getCourseExercise(courseId, exerciseId);
1376
+ return jsonContent(result);
1377
+ }
1378
+ );
1379
+ server.tool(
1380
+ "create_course_exercise",
1381
+ "Create a new exercise directly on a live course. Use this for adding exercises after a course has already been published.",
1382
+ createCourseExerciseShape,
1383
+ async (args) => {
1384
+ const { courseId, ...payload } = ZCreateCourseExerciseToolInput.parse(args);
1385
+ const result = await apiClient.createCourseExercise(courseId, payload);
1386
+ return jsonContent(result);
1387
+ }
1388
+ );
1389
+ server.tool(
1390
+ "create_course_exercise_from_template",
1391
+ "Create a new exercise on a live course from an existing template.",
1392
+ createCourseExerciseFromTemplateShape,
1393
+ async (args) => {
1394
+ const { courseId, ...payload } = ZCreateCourseExerciseFromTemplateToolInput.parse(args);
1395
+ const result = await apiClient.createCourseExerciseFromTemplate(courseId, payload);
1396
+ return jsonContent(result);
1397
+ }
1398
+ );
1399
+ server.tool(
1400
+ "update_course_exercise",
1401
+ "Update an existing exercise on a live course, including questions and options.",
1402
+ updateCourseExerciseShape,
1403
+ async (args) => {
1404
+ const { courseId, exerciseId, ...payload } = ZUpdateCourseExerciseToolInput.parse(args);
1405
+ const result = await apiClient.updateCourseExercise(courseId, exerciseId, payload);
1406
+ return jsonContent(result);
1407
+ }
1408
+ );
1409
+ server.tool(
1410
+ "update_course_draft",
1411
+ "Update an unpublished draft. If the draft is already published, do not keep editing it blindly; create a fresh draft from the live course first.",
1412
+ updateCourseDraftShape,
1413
+ async (args) => {
1414
+ const { draftId, ...payload } = ZUpdateCourseDraftToolInput.parse(args);
1415
+ const result = await apiClient.updateCourseDraft(draftId, payload);
1416
+ return jsonContent(result);
1417
+ }
1418
+ );
1419
+ server.tool(
1420
+ "tag_course_draft",
1421
+ "Attach human-readable tags to a draft before publish. The tags are stored on the draft and applied during publish.",
1422
+ tagCourseDraftShape,
1423
+ async (args) => {
1424
+ const { draftId, ...payload } = ZTagCourseDraftToolInput.parse(args);
1425
+ const result = await apiClient.tagCourseDraft(draftId, payload);
1426
+ return jsonContent(result);
1427
+ }
1428
+ );
1429
+ server.tool(
1430
+ "publish_course_draft",
1431
+ "Publish an unpublished draft as a new live course. The result includes courseId and courseUrl. After publish, future major edits should usually start from a fresh draft created from the live course.",
1432
+ publishCourseDraftShape,
1433
+ async (args) => {
1434
+ const { draftId, ...payload } = ZPublishCourseDraftToolInput.parse(args);
1435
+ const result = await apiClient.publishCourseDraft(draftId, payload);
1436
+ return jsonContent(result);
1437
+ }
1438
+ );
1439
+ server.tool(
1440
+ "publish_course_draft_to_existing_course",
1441
+ "Apply a fresh draft back onto an existing live course. Use this after reading the live course and creating a new draft from it.",
1442
+ publishCourseDraftToExistingCourseShape,
1443
+ async (args) => {
1444
+ const { draftId, ...payload } = ZPublishCourseDraftToExistingCourseToolInput.parse(args);
1445
+ const result = await apiClient.publishCourseDraftToExistingCourse(draftId, payload);
1446
+ return jsonContent(result);
1447
+ }
1448
+ );
1449
+ server.tool(
1450
+ "tag_courses",
1451
+ "Assign tags directly to one or more live courses by name. Default mode is merge, so existing tags are preserved unless replace is requested.",
1452
+ tagCoursesShape,
1453
+ async (args) => {
1454
+ const payload = ZAutomationCourseTagAssignment.parse(args);
1455
+ const result = await apiClient.tagCourses(payload);
1456
+ return jsonContent(result);
1457
+ }
1458
+ );
789
1459
  }
790
1460
  function jsonContent(data) {
791
1461
  return {