@roottale/cms-mcp 0.53.1 → 0.56.0

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 CHANGED
@@ -60,8 +60,13 @@ var AUTOMATION_TOOL_DEFINITIONS = [
60
60
  limit: numberProperty("1-100"),
61
61
  type: enumProperty(["post", "page"]),
62
62
  status: enumProperty(["draft", "published", "scheduled", "private"]),
63
- cursor: stringProperty("\uC774\uC804 \uC751\uB2F5\uC758 next_cursor")
63
+ cursor: stringProperty("\uC774\uC804 \uC751\uB2F5\uC758 next_cursor"),
64
+ modelKey: stringProperty("\uCF58\uD150\uCE20 \uBAA8\uB378 key")
64
65
  }),
66
+ tool("getManagedCmsPost", "\uD398\uC774\uC9C0\xB7\uAE00\xB7\uC815\uBCF4 \uD56D\uBAA9 \uD55C \uAC74\uC744 \uAD00\uB9AC\uC6A9 \uC6D0\uBB38\uC73C\uB85C \uC870\uD68C\uD569\uB2C8\uB2E4.", {
67
+ postId: stringProperty("\uD56D\uBAA9 ID"),
68
+ siteId: stringProperty("\uC0AC\uC774\uD2B8 ID")
69
+ }, ["postId"]),
65
70
  tool(
66
71
  "createCmsPost",
67
72
  "Tiptap bodyJson\uC73C\uB85C \uAE00 \uB610\uB294 \uD398\uC774\uC9C0\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4. \uAE30\uBCF8\uC740 \uCD08\uC548\uC774\uBA70 publish=true\uBA74 \uC989\uC2DC \uBC1C\uD589\uD569\uB2C8\uB2E4.",
@@ -76,7 +81,9 @@ var AUTOMATION_TOOL_DEFINITIONS = [
76
81
  publish: { type: "boolean" },
77
82
  scheduledAt: stringProperty("\uBBF8\uB798 ISO 8601 \uBC1C\uD589 \uC2DC\uAC01"),
78
83
  categoryIds: arrayProperty("\uCE74\uD14C\uACE0\uB9AC term id"),
79
- tagIds: arrayProperty("\uD0DC\uADF8 term id")
84
+ tagIds: arrayProperty("\uD0DC\uADF8 term id"),
85
+ modelKey: stringProperty("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
86
+ fieldValues: { type: "object", description: "\uBAA8\uB378 \uD544\uB4DC \uC6D0\uBB38 \uAC12" }
80
87
  },
81
88
  ["title", "slug", "bodyJson"]
82
89
  ),
@@ -88,7 +95,8 @@ var AUTOMATION_TOOL_DEFINITIONS = [
88
95
  bodyJson: { type: "object", description: "Tiptap \uBB38\uC11C JSON" },
89
96
  excerpt: nullableStringProperty("\uC694\uC57D"),
90
97
  featuredMediaId: nullableStringProperty("\uB300\uD45C \uC774\uBBF8\uC9C0 media id"),
91
- scheduledAt: nullableStringProperty("\uC608\uC57D \uC2DC\uAC01")
98
+ scheduledAt: nullableStringProperty("\uC608\uC57D \uC2DC\uAC01"),
99
+ fieldValues: { type: "object", description: "\uBAA8\uB378 \uD544\uB4DC \uC6D0\uBB38 \uAC12" }
92
100
  }, ["postId"]),
93
101
  tool("publishCmsPost", "\uCD08\uC548 \uB610\uB294 \uC608\uC57D \uAE00\uC744 \uC989\uC2DC \uBC1C\uD589\uD558\uACE0 \uC6F9\uD6C5\uC744 \uC804\uC1A1\uD569\uB2C8\uB2E4.", {
94
102
  postId: stringProperty("\uAE00 ID"),
@@ -98,6 +106,11 @@ var AUTOMATION_TOOL_DEFINITIONS = [
98
106
  postId: stringProperty("\uAE00 ID"),
99
107
  siteId: stringProperty("\uC0AC\uC774\uD2B8 ID")
100
108
  }, ["postId"]),
109
+ tool("deleteCmsPost", "\uD398\uC774\uC9C0\xB7\uAE00\xB7\uC815\uBCF4 \uD56D\uBAA9\uC744 \uD734\uC9C0\uD1B5\uC73C\uB85C \uBCF4\uB0B4\uAC70\uB098 \uC601\uAD6C \uC0AD\uC81C\uD569\uB2C8\uB2E4.", {
110
+ postId: stringProperty("\uD56D\uBAA9 ID"),
111
+ siteId: stringProperty("\uC0AC\uC774\uD2B8 ID"),
112
+ hard: { type: "boolean", description: "true\uBA74 \uC601\uAD6C \uC0AD\uC81C" }
113
+ }, ["postId"]),
101
114
  tool("setCmsPostTerms", "\uAE00\uC758 \uCE74\uD14C\uACE0\uB9AC \uB610\uB294 \uD0DC\uADF8 \uC5F0\uACB0\uC744 \uAD50\uCCB4\uD569\uB2C8\uB2E4.", {
102
115
  postId: stringProperty("\uAE00 ID"),
103
116
  siteId: stringProperty("\uC0AC\uC774\uD2B8 ID"),
@@ -192,7 +205,9 @@ var CreatePostInput = z.object({
192
205
  publish: z.boolean().optional(),
193
206
  scheduledAt: z.string().datetime({ offset: true }).optional(),
194
207
  categoryIds: z.array(z.string()).optional(),
195
- tagIds: z.array(z.string()).optional()
208
+ tagIds: z.array(z.string()).optional(),
209
+ modelKey: z.string().min(1).optional(),
210
+ fieldValues: z.record(z.string(), z.unknown()).optional()
196
211
  }).strict();
197
212
  var UpdatePostInput = z.object({
198
213
  postId: PostId,
@@ -202,15 +217,18 @@ var UpdatePostInput = z.object({
202
217
  bodyJson: z.record(z.string(), z.unknown()).optional(),
203
218
  excerpt: NullableText,
204
219
  featuredMediaId: z.string().nullable().optional(),
205
- scheduledAt: z.string().datetime({ offset: true }).nullable().optional()
220
+ scheduledAt: z.string().datetime({ offset: true }).nullable().optional(),
221
+ fieldValues: z.record(z.string(), z.unknown()).optional()
206
222
  }).strict();
207
223
  var PostLifecycleInput = z.object({ postId: PostId, siteId: SiteId }).strict();
224
+ var DeletePostInput = PostLifecycleInput.extend({ hard: z.boolean().optional() }).strict();
208
225
  var ListManagedPostsInput = z.object({
209
226
  siteId: SiteId,
210
227
  limit: z.number().int().min(1).max(100).optional(),
211
228
  type: z.enum(["post", "page"]).optional(),
212
229
  status: z.enum(["draft", "published", "scheduled", "private"]).optional(),
213
- cursor: z.string().optional()
230
+ cursor: z.string().optional(),
231
+ modelKey: z.string().min(1).optional()
214
232
  }).strict();
215
233
  var SetTermsInput = z.object({
216
234
  postId: PostId,
@@ -318,10 +336,19 @@ async function callAutomationTool(name, args) {
318
336
  limit: input.limit,
319
337
  type: input.type,
320
338
  status: input.status,
321
- cursor: input.cursor
339
+ cursor: input.cursor,
340
+ model_key: input.modelKey
322
341
  })
323
342
  });
324
343
  }
344
+ case "getManagedCmsPost": {
345
+ const input = PostLifecycleInput.parse(args);
346
+ return requestRootTaleApi({
347
+ method: "GET",
348
+ pathname: `/v1/cms/posts/${encodeURIComponent(input.postId)}`,
349
+ query: optionalQuery({ site_id: input.siteId })
350
+ });
351
+ }
325
352
  case "createCmsPost": {
326
353
  const input = CreatePostInput.parse(args);
327
354
  return requestRootTaleApi({
@@ -338,7 +365,9 @@ async function callAutomationTool(name, args) {
338
365
  publish: input.publish,
339
366
  scheduled_at: input.scheduledAt,
340
367
  category_ids: input.categoryIds,
341
- tag_ids: input.tagIds
368
+ tag_ids: input.tagIds,
369
+ model_key: input.modelKey,
370
+ field_values: input.fieldValues
342
371
  }
343
372
  });
344
373
  }
@@ -354,7 +383,8 @@ async function callAutomationTool(name, args) {
354
383
  body_json: input.bodyJson,
355
384
  excerpt: input.excerpt,
356
385
  featured_media_id: input.featuredMediaId,
357
- scheduled_at: input.scheduledAt
386
+ scheduled_at: input.scheduledAt,
387
+ field_values: input.fieldValues
358
388
  }
359
389
  });
360
390
  }
@@ -380,6 +410,17 @@ async function callAutomationTool(name, args) {
380
410
  }
381
411
  });
382
412
  }
413
+ case "deleteCmsPost": {
414
+ const input = DeletePostInput.parse(args);
415
+ return requestRootTaleApi({
416
+ method: "DELETE",
417
+ pathname: `/v1/cms/posts/${encodeURIComponent(input.postId)}`,
418
+ query: optionalQuery({
419
+ site_id: input.siteId,
420
+ hard: input.hard === void 0 ? void 0 : String(input.hard)
421
+ })
422
+ });
423
+ }
383
424
  case "listCmsMedia": {
384
425
  const input = ListMediaInput.parse(args);
385
426
  return requestRootTaleApi({
@@ -427,10 +468,516 @@ function assertNever(value) {
427
468
  throw new CmsAutomationError(`Unknown automation tool: ${String(value)}`);
428
469
  }
429
470
 
471
+ // src/management-definitions.ts
472
+ var string = (description) => ({ type: "string", description });
473
+ var number = (description) => ({ type: "number", description });
474
+ var boolean = (description) => ({ type: "boolean", description });
475
+ var object = (description) => ({ type: "object", description });
476
+ var nullableString = (description) => ({
477
+ type: ["string", "null"],
478
+ description
479
+ });
480
+ var enumValue = (values) => ({ type: "string", enum: values });
481
+ var strings = (description) => ({
482
+ type: "array",
483
+ items: { type: "string" },
484
+ description
485
+ });
486
+ var MANAGEMENT_TOOL_DEFINITIONS = [
487
+ tool2("listCmsContentModels", "\uD398\uC774\uC9C0\xB7\uAE00\xB7\uC815\uBCF4 \uCF58\uD150\uCE20 \uBAA8\uB378\uACFC \uC0AC\uC6A9\uB7C9\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {
488
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
489
+ state: enumValue(["active", "inactive"]),
490
+ preset: enumValue(["page", "article", "entity", "none"]),
491
+ source: enumValue(["code", "site"])
492
+ }),
493
+ tool2("getCmsContentModel", "\uCF58\uD150\uCE20 \uBAA8\uB378 \uD55C \uAC74\uC744 modelKey\uB85C \uC870\uD68C\uD569\uB2C8\uB2E4.", {
494
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
495
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
496
+ }, ["modelKey"]),
497
+ tool2("createCmsContentModel", "\uC0AC\uC774\uD2B8 \uC18C\uC720 article \uB610\uB294 entity \uBAA8\uB378\uC744 \uB9CC\uB4ED\uB2C8\uB2E4.", {
498
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
499
+ key: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
500
+ label: string("\uD45C\uC2DC \uC774\uB984"),
501
+ cardinality: enumValue(["singleton", "collection"]),
502
+ preset: { type: ["string", "null"], enum: ["article", "entity", null] },
503
+ presentation: object("\uD45C\uC2DC \uACBD\uB85C \uACC4\uC57D"),
504
+ publication: object("\uBC1C\uD589 \uC815\uCC45"),
505
+ compatibilityCollectionKey: nullableString("\uC774\uC804 collection key"),
506
+ definition: object("\uCD94\uAC00 \uBAA8\uB378 \uC815\uC758")
507
+ }, ["key", "label", "cardinality", "preset", "presentation"]),
508
+ tool2("updateCmsContentModel", "\uC0AC\uC774\uD2B8 \uBAA8\uB378\uC758 \uAD6C\uC870 \uB610\uB294 \uBAA8\uB378 \uC0C1\uD0DC\uB97C \uC218\uC815\uD569\uB2C8\uB2E4.", {
509
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
510
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
511
+ expectedUpdatedAt: string("\uD604\uC7AC updated_at"),
512
+ label: string("\uD45C\uC2DC \uC774\uB984"),
513
+ cardinality: enumValue(["singleton", "collection"]),
514
+ preset: { type: ["string", "null"], enum: ["article", "entity", null] },
515
+ state: enumValue(["active", "inactive"]),
516
+ presentation: object("\uD45C\uC2DC \uACBD\uB85C \uACC4\uC57D"),
517
+ publication: object("\uBC1C\uD589 \uC815\uCC45"),
518
+ compatibilityCollectionKey: nullableString("\uC774\uC804 collection key"),
519
+ definition: object("\uCD94\uAC00 \uBAA8\uB378 \uC815\uC758")
520
+ }, ["modelKey", "expectedUpdatedAt"]),
521
+ tool2("activateCmsContentModel", "\uCF58\uD150\uCE20 \uBAA8\uB378\uC744 \uD65C\uC131\uD654\uD569\uB2C8\uB2E4.", {
522
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
523
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
524
+ }, ["modelKey"]),
525
+ tool2("deactivateCmsContentModel", "\uCF58\uD150\uCE20 \uBAA8\uB378\uC744 \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4.", {
526
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
527
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
528
+ }, ["modelKey"]),
529
+ tool2("deleteCmsContentModel", "\uC0AC\uC6A9\uD558\uC9C0 \uC54A\uB294 \uC0AC\uC774\uD2B8 \uBAA8\uB378\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4.", {
530
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
531
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
532
+ }, ["modelKey"]),
533
+ tool2("listCmsFieldGroups", "\uBAA8\uB378\uC5D0 \uC5F0\uACB0\uB41C code\xB7site \uD544\uB4DC \uADF8\uB8F9\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {
534
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
535
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
536
+ }, ["modelKey"]),
537
+ tool2("getCmsFieldGroup", "\uD544\uB4DC \uADF8\uB8F9 \uD55C \uAC74\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {
538
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
539
+ groupKey: string("\uD544\uB4DC \uADF8\uB8F9 key"),
540
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
541
+ }, ["modelKey", "groupKey"]),
542
+ tool2("createCmsFieldGroup", "\uC0AC\uC774\uD2B8 \uC18C\uC720 \uD544\uB4DC \uADF8\uB8F9\uC744 \uB9CC\uB4ED\uB2C8\uB2E4.", {
543
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
544
+ groupKey: string("\uD544\uB4DC \uADF8\uB8F9 key"),
545
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
546
+ title: string("\uD45C\uC2DC \uC774\uB984"),
547
+ definition: object("\uD544\uB4DC \uC815\uC758")
548
+ }, ["modelKey", "groupKey", "title", "definition"]),
549
+ tool2("updateCmsFieldGroup", "\uC0AC\uC774\uD2B8 \uD544\uB4DC \uADF8\uB8F9\uC744 \uC218\uC815\uD569\uB2C8\uB2E4.", {
550
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
551
+ groupKey: string("\uD544\uB4DC \uADF8\uB8F9 key"),
552
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
553
+ expectedUpdatedAt: string("\uD604\uC7AC updated_at"),
554
+ title: string("\uD45C\uC2DC \uC774\uB984"),
555
+ active: boolean("\uD65C\uC131 \uC0C1\uD0DC"),
556
+ definition: object("\uD544\uB4DC \uC815\uC758")
557
+ }, ["modelKey", "groupKey", "expectedUpdatedAt"]),
558
+ tool2("activateCmsFieldGroup", "\uD544\uB4DC \uADF8\uB8F9\uC744 \uD65C\uC131\uD654\uD569\uB2C8\uB2E4.", {
559
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
560
+ groupKey: string("\uD544\uB4DC \uADF8\uB8F9 key"),
561
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
562
+ }, ["modelKey", "groupKey"]),
563
+ tool2("deactivateCmsFieldGroup", "\uD544\uB4DC \uADF8\uB8F9\uC744 \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4.", {
564
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
565
+ groupKey: string("\uD544\uB4DC \uADF8\uB8F9 key"),
566
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
567
+ }, ["modelKey", "groupKey"]),
568
+ tool2("deleteCmsFieldGroup", "\uC0AC\uC6A9\uD558\uC9C0 \uC54A\uB294 \uC0AC\uC774\uD2B8 \uD544\uB4DC \uADF8\uB8F9\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4.", {
569
+ modelKey: string("\uCF58\uD150\uCE20 \uBAA8\uB378 key"),
570
+ groupKey: string("\uD544\uB4DC \uADF8\uB8F9 key"),
571
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
572
+ }, ["modelKey", "groupKey"]),
573
+ tool2("listCmsExposureSlots", "\uC5F0\uACB0\uB41C FRONT\uAC00 \uC120\uC5B8\uD55C \uB178\uCD9C \uC2AC\uB86F\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {
574
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
575
+ }),
576
+ tool2("listCmsExposures", "\uCD08\uC548\xB7\uBC1C\uD589\xB7\uBCF4\uAD00 \uB178\uCD9C \uCEA0\uD398\uC778\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {
577
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
578
+ kind: enumValue(["banner", "popup"]),
579
+ status: enumValue(["draft", "published", "archived"])
580
+ }),
581
+ tool2("getCmsExposure", "\uB178\uCD9C \uCEA0\uD398\uC778 \uD55C \uAC74\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {
582
+ exposureId: string("\uB178\uCD9C \uCEA0\uD398\uC778 ID"),
583
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
584
+ }, ["exposureId"]),
585
+ tool2("createCmsExposure", "FRONT \uC2AC\uB86F \uACC4\uC57D\uC5D0 \uB9DE\uB294 \uB178\uCD9C \uCEA0\uD398\uC778 \uCD08\uC548\uC744 \uB9CC\uB4ED\uB2C8\uB2E4.", {
586
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
587
+ slotKey: string("\uB178\uCD9C \uC2AC\uB86F key"),
588
+ kind: enumValue(["banner", "popup"]),
589
+ content: object("\uB178\uCD9C \uCF58\uD150\uCE20"),
590
+ startsAt: nullableString("\uC2DC\uC791 ISO \uC2DC\uAC01"),
591
+ endsAt: nullableString("\uC885\uB8CC ISO \uC2DC\uAC01"),
592
+ targetPaths: strings("\uB300\uC0C1 \uACBD\uB85C"),
593
+ priority: number("\uC6B0\uC120\uC21C\uC704"),
594
+ repeat: enumValue(["always", "session", "day", "never"])
595
+ }, ["slotKey", "kind", "content", "startsAt", "endsAt", "targetPaths", "priority", "repeat"]),
596
+ tool2("updateCmsExposure", "\uB178\uCD9C \uCEA0\uD398\uC778\uC744 \uB099\uAD00\uC801 \uC7A0\uAE08\uC73C\uB85C \uC218\uC815\uD569\uB2C8\uB2E4.", {
597
+ exposureId: string("\uB178\uCD9C \uCEA0\uD398\uC778 ID"),
598
+ expectedVersion: number("\uD604\uC7AC version"),
599
+ siteId: string("\uC0AC\uC774\uD2B8 ID"),
600
+ slotKey: string("\uB178\uCD9C \uC2AC\uB86F key"),
601
+ kind: enumValue(["banner", "popup"]),
602
+ content: object("\uB178\uCD9C \uCF58\uD150\uCE20"),
603
+ startsAt: nullableString("\uC2DC\uC791 ISO \uC2DC\uAC01"),
604
+ endsAt: nullableString("\uC885\uB8CC ISO \uC2DC\uAC01"),
605
+ targetPaths: strings("\uB300\uC0C1 \uACBD\uB85C"),
606
+ priority: number("\uC6B0\uC120\uC21C\uC704"),
607
+ repeat: enumValue(["always", "session", "day", "never"])
608
+ }, ["exposureId", "expectedVersion", "slotKey", "kind", "content", "startsAt", "endsAt", "targetPaths", "priority", "repeat"]),
609
+ tool2("publishCmsExposure", "\uB178\uCD9C \uCEA0\uD398\uC778\uC744 \uBC1C\uD589\uD558\uACE0 \uACB9\uCE68 \uACBD\uACE0\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.", {
610
+ exposureId: string("\uB178\uCD9C \uCEA0\uD398\uC778 ID"),
611
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
612
+ }, ["exposureId"]),
613
+ tool2("archiveCmsExposure", "\uB178\uCD9C \uCEA0\uD398\uC778\uC744 \uBCF4\uAD00\uD569\uB2C8\uB2E4.", {
614
+ exposureId: string("\uB178\uCD9C \uCEA0\uD398\uC778 ID"),
615
+ siteId: string("\uC0AC\uC774\uD2B8 ID")
616
+ }, ["exposureId"])
617
+ ];
618
+ function isManagementToolName(name) {
619
+ return MANAGEMENT_TOOL_DEFINITIONS.some((definition) => definition.name === name);
620
+ }
621
+ function tool2(name, description, properties, required = []) {
622
+ return {
623
+ name,
624
+ description,
625
+ inputSchema: {
626
+ type: "object",
627
+ properties,
628
+ ...required.length > 0 && { required },
629
+ additionalProperties: false
630
+ }
631
+ };
632
+ }
633
+
634
+ // src/management-schemas.ts
635
+ import { z as z3 } from "zod";
636
+ var SiteId2 = z3.string().min(1).optional();
637
+ var Key = z3.string().min(1);
638
+ var DateTime = z3.string().datetime({ offset: true });
639
+ var JsonObject = z3.record(z3.string(), z3.unknown());
640
+ var ModelRefInput = z3.object({ modelKey: Key, siteId: SiteId2 }).strict();
641
+ var ListModelsInput = z3.object({
642
+ siteId: SiteId2,
643
+ state: z3.enum(["active", "inactive"]).optional(),
644
+ preset: z3.enum(["page", "article", "entity", "none"]).optional(),
645
+ source: z3.enum(["code", "site"]).optional()
646
+ }).strict();
647
+ var CreateModelInput = z3.object({
648
+ siteId: SiteId2,
649
+ key: Key,
650
+ label: z3.string().min(1),
651
+ cardinality: z3.enum(["singleton", "collection"]),
652
+ preset: z3.enum(["article", "entity"]).nullable(),
653
+ presentation: JsonObject,
654
+ publication: JsonObject.nullable().optional(),
655
+ compatibilityCollectionKey: z3.string().nullable().optional(),
656
+ definition: JsonObject.optional()
657
+ }).strict();
658
+ var UpdateModelInput = z3.object({
659
+ modelKey: Key,
660
+ siteId: SiteId2,
661
+ expectedUpdatedAt: DateTime,
662
+ label: z3.string().min(1).optional(),
663
+ cardinality: z3.enum(["singleton", "collection"]).optional(),
664
+ preset: z3.enum(["article", "entity"]).nullable().optional(),
665
+ state: z3.enum(["active", "inactive"]).optional(),
666
+ presentation: JsonObject.optional(),
667
+ publication: JsonObject.nullable().optional(),
668
+ compatibilityCollectionKey: z3.string().nullable().optional(),
669
+ definition: JsonObject.optional()
670
+ }).strict();
671
+ var FieldRefInput = z3.object({
672
+ modelKey: Key,
673
+ groupKey: Key,
674
+ siteId: SiteId2
675
+ }).strict();
676
+ var CreateFieldInput = FieldRefInput.extend({
677
+ title: z3.string().min(1),
678
+ definition: JsonObject
679
+ }).strict();
680
+ var UpdateFieldInput = FieldRefInput.extend({
681
+ expectedUpdatedAt: DateTime,
682
+ title: z3.string().min(1).optional(),
683
+ active: z3.boolean().optional(),
684
+ definition: JsonObject.optional()
685
+ }).strict();
686
+ var SiteInput = z3.object({ siteId: SiteId2 }).strict();
687
+ var ListExposuresInput = SiteInput.extend({
688
+ kind: z3.enum(["banner", "popup"]).optional(),
689
+ status: z3.enum(["draft", "published", "archived"]).optional()
690
+ }).strict();
691
+ var ExposureRefInput = z3.object({ exposureId: Key, siteId: SiteId2 }).strict();
692
+ var ExposureFields = {
693
+ slotKey: Key,
694
+ kind: z3.enum(["banner", "popup"]),
695
+ content: z3.object({
696
+ variant: Key,
697
+ eyebrow: z3.string().optional(),
698
+ title: z3.string().min(1),
699
+ description: z3.string().optional(),
700
+ assetUrl: z3.string().url().optional(),
701
+ assetAlt: z3.string().optional(),
702
+ linkLabel: z3.string().optional(),
703
+ linkUrl: z3.string().optional()
704
+ }).strict(),
705
+ startsAt: DateTime.nullable(),
706
+ endsAt: DateTime.nullable(),
707
+ targetPaths: z3.array(z3.string().startsWith("/")).min(1),
708
+ priority: z3.number().int().min(-1e3).max(1e3),
709
+ repeat: z3.enum(["always", "session", "day", "never"])
710
+ };
711
+ var CreateExposureInput = z3.object({ siteId: SiteId2, ...ExposureFields }).strict();
712
+ var UpdateExposureInput = z3.object({
713
+ exposureId: Key,
714
+ expectedVersion: z3.number().int().positive(),
715
+ siteId: SiteId2,
716
+ ...ExposureFields
717
+ }).strict();
718
+ var VersionResponse = z3.object({ version: z3.number().int().positive() }).passthrough();
719
+ var UpdatedAtResponse = z3.object({ updated_at: DateTime.nullable() }).passthrough();
720
+
721
+ // src/management-tools.ts
722
+ async function callManagementTool(name, args) {
723
+ switch (name) {
724
+ case "listCmsContentModels": {
725
+ const input = ListModelsInput.parse(args);
726
+ return get("/v1/cms/content-models", {
727
+ site_id: input.siteId,
728
+ state: input.state,
729
+ preset: input.preset,
730
+ source: input.source
731
+ });
732
+ }
733
+ case "getCmsContentModel": {
734
+ const input = ModelRefInput.parse(args);
735
+ return get(modelPath(input.modelKey), { site_id: input.siteId });
736
+ }
737
+ case "createCmsContentModel": {
738
+ const input = CreateModelInput.parse(args);
739
+ return requestRootTaleApi({
740
+ method: "POST",
741
+ pathname: "/v1/cms/content-models",
742
+ body: modelBody(input)
743
+ });
744
+ }
745
+ case "updateCmsContentModel": {
746
+ const input = UpdateModelInput.parse(args);
747
+ return requestRootTaleApi({
748
+ method: "PATCH",
749
+ pathname: modelPath(input.modelKey),
750
+ body: {
751
+ site_id: input.siteId,
752
+ expected_updated_at: input.expectedUpdatedAt,
753
+ label: input.label,
754
+ cardinality: input.cardinality,
755
+ preset: input.preset,
756
+ state: input.state,
757
+ presentation: input.presentation,
758
+ publication: input.publication,
759
+ compatibility_collection_key: input.compatibilityCollectionKey,
760
+ definition: input.definition
761
+ }
762
+ });
763
+ }
764
+ case "activateCmsContentModel":
765
+ case "deactivateCmsContentModel": {
766
+ const input = ModelRefInput.parse(args);
767
+ const current = UpdatedAtResponse.parse(
768
+ await get(modelPath(input.modelKey), { site_id: input.siteId })
769
+ );
770
+ if (!current.updated_at) throw new CmsAutomationError("\uBAA8\uB378 updated_at\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
771
+ return requestRootTaleApi({
772
+ method: "PATCH",
773
+ pathname: modelPath(input.modelKey),
774
+ body: {
775
+ site_id: input.siteId,
776
+ expected_updated_at: current.updated_at,
777
+ state: name === "activateCmsContentModel" ? "active" : "inactive"
778
+ }
779
+ });
780
+ }
781
+ case "deleteCmsContentModel": {
782
+ const input = ModelRefInput.parse(args);
783
+ const current = UpdatedAtResponse.parse(
784
+ await get(modelPath(input.modelKey), { site_id: input.siteId })
785
+ );
786
+ if (!current.updated_at) throw new CmsAutomationError("\uBAA8\uB378 updated_at\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
787
+ return requestRootTaleApi({
788
+ method: "DELETE",
789
+ pathname: modelPath(input.modelKey),
790
+ query: optionalQuery2({
791
+ site_id: input.siteId,
792
+ expected_updated_at: current.updated_at
793
+ })
794
+ });
795
+ }
796
+ case "listCmsFieldGroups": {
797
+ const input = ModelRefInput.parse(args);
798
+ return get(`${modelPath(input.modelKey)}/field-groups`, { site_id: input.siteId });
799
+ }
800
+ case "getCmsFieldGroup": {
801
+ const input = FieldRefInput.parse(args);
802
+ return get(fieldPath(input.modelKey, input.groupKey), { site_id: input.siteId });
803
+ }
804
+ case "createCmsFieldGroup": {
805
+ const input = CreateFieldInput.parse(args);
806
+ return requestRootTaleApi({
807
+ method: "POST",
808
+ pathname: `${modelPath(input.modelKey)}/field-groups`,
809
+ body: {
810
+ site_id: input.siteId,
811
+ key: input.groupKey,
812
+ title: input.title,
813
+ definition: input.definition
814
+ }
815
+ });
816
+ }
817
+ case "updateCmsFieldGroup": {
818
+ const input = UpdateFieldInput.parse(args);
819
+ return requestRootTaleApi({
820
+ method: "PATCH",
821
+ pathname: fieldPath(input.modelKey, input.groupKey),
822
+ body: {
823
+ site_id: input.siteId,
824
+ expected_updated_at: input.expectedUpdatedAt,
825
+ title: input.title,
826
+ active: input.active,
827
+ definition: input.definition
828
+ }
829
+ });
830
+ }
831
+ case "activateCmsFieldGroup":
832
+ case "deactivateCmsFieldGroup": {
833
+ const input = FieldRefInput.parse(args);
834
+ const current = UpdatedAtResponse.parse(
835
+ await get(fieldPath(input.modelKey, input.groupKey), { site_id: input.siteId })
836
+ );
837
+ if (!current.updated_at) {
838
+ throw new CmsAutomationError("code \uD544\uB4DC \uADF8\uB8F9\uC758 \uC0C1\uD0DC\uB294 API\uB85C \uBC14\uAFC0 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
839
+ }
840
+ return requestRootTaleApi({
841
+ method: "PATCH",
842
+ pathname: fieldPath(input.modelKey, input.groupKey),
843
+ body: {
844
+ site_id: input.siteId,
845
+ expected_updated_at: current.updated_at,
846
+ active: name === "activateCmsFieldGroup"
847
+ }
848
+ });
849
+ }
850
+ case "deleteCmsFieldGroup": {
851
+ const input = FieldRefInput.parse(args);
852
+ const current = UpdatedAtResponse.parse(
853
+ await get(fieldPath(input.modelKey, input.groupKey), { site_id: input.siteId })
854
+ );
855
+ if (!current.updated_at) {
856
+ throw new CmsAutomationError("code \uD544\uB4DC \uADF8\uB8F9\uC740 \uC0AD\uC81C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
857
+ }
858
+ return requestRootTaleApi({
859
+ method: "DELETE",
860
+ pathname: fieldPath(input.modelKey, input.groupKey),
861
+ query: optionalQuery2({
862
+ site_id: input.siteId,
863
+ expected_updated_at: current.updated_at
864
+ })
865
+ });
866
+ }
867
+ case "listCmsExposureSlots": {
868
+ const input = SiteInput.parse(args);
869
+ return get("/v1/cms/exposure-slots", { site_id: input.siteId });
870
+ }
871
+ case "listCmsExposures": {
872
+ const input = ListExposuresInput.parse(args);
873
+ return get("/v1/cms/exposures", {
874
+ site_id: input.siteId,
875
+ kind: input.kind,
876
+ status: input.status
877
+ });
878
+ }
879
+ case "getCmsExposure": {
880
+ const input = ExposureRefInput.parse(args);
881
+ return get(exposurePath(input.exposureId), { site_id: input.siteId });
882
+ }
883
+ case "createCmsExposure": {
884
+ const input = CreateExposureInput.parse(args);
885
+ return requestRootTaleApi({
886
+ method: "POST",
887
+ pathname: "/v1/cms/exposures",
888
+ body: exposureBody(input)
889
+ });
890
+ }
891
+ case "updateCmsExposure": {
892
+ const input = UpdateExposureInput.parse(args);
893
+ return requestRootTaleApi({
894
+ method: "PATCH",
895
+ pathname: exposurePath(input.exposureId),
896
+ body: {
897
+ ...exposureBody(input),
898
+ expected_version: input.expectedVersion
899
+ }
900
+ });
901
+ }
902
+ case "publishCmsExposure":
903
+ case "archiveCmsExposure": {
904
+ const input = ExposureRefInput.parse(args);
905
+ const current = VersionResponse.parse(
906
+ await get(exposurePath(input.exposureId), { site_id: input.siteId })
907
+ );
908
+ const action = name === "publishCmsExposure" ? "publish" : "archive";
909
+ return requestRootTaleApi({
910
+ method: "POST",
911
+ pathname: `${exposurePath(input.exposureId)}/${action}`,
912
+ body: { site_id: input.siteId, expected_version: current.version }
913
+ });
914
+ }
915
+ default:
916
+ return assertNever2(name);
917
+ }
918
+ }
919
+ function get(pathname, query) {
920
+ return requestRootTaleApi({ method: "GET", pathname, query: optionalQuery2(query) });
921
+ }
922
+ function modelPath(modelKey) {
923
+ return `/v1/cms/content-models/${encodeURIComponent(modelKey)}`;
924
+ }
925
+ function fieldPath(modelKey, groupKey) {
926
+ return `${modelPath(modelKey)}/field-groups/${encodeURIComponent(groupKey)}`;
927
+ }
928
+ function exposurePath(exposureId) {
929
+ return `/v1/cms/exposures/${encodeURIComponent(exposureId)}`;
930
+ }
931
+ function modelBody(input) {
932
+ return {
933
+ site_id: input.siteId,
934
+ key: input.key,
935
+ label: input.label,
936
+ cardinality: input.cardinality,
937
+ preset: input.preset,
938
+ presentation: input.presentation,
939
+ publication: input.publication,
940
+ compatibility_collection_key: input.compatibilityCollectionKey,
941
+ definition: input.definition
942
+ };
943
+ }
944
+ function exposureBody(input) {
945
+ return {
946
+ site_id: input.siteId,
947
+ slot_key: input.slotKey,
948
+ kind: input.kind,
949
+ content: {
950
+ variant: input.content.variant,
951
+ eyebrow: input.content.eyebrow,
952
+ title: input.content.title,
953
+ description: input.content.description,
954
+ asset_url: input.content.assetUrl,
955
+ asset_alt: input.content.assetAlt,
956
+ link_label: input.content.linkLabel,
957
+ link_url: input.content.linkUrl
958
+ },
959
+ starts_at: input.startsAt,
960
+ ends_at: input.endsAt,
961
+ target_paths: input.targetPaths,
962
+ priority: input.priority,
963
+ repeat: input.repeat
964
+ };
965
+ }
966
+ function optionalQuery2(values) {
967
+ return Object.fromEntries(
968
+ Object.entries(values).filter((entry) => entry[1] !== void 0)
969
+ );
970
+ }
971
+ function assertNever2(value) {
972
+ throw new CmsAutomationError(`Unknown management tool: ${String(value)}`);
973
+ }
974
+
430
975
  // src/cli.ts
431
976
  function createCmsCli() {
432
- const cli = new Command().name("roottale-cms").description("RootTale CMS \uAE00\xB7\uC378\uB124\uC77C\xB7\uBCF8\uBB38 \uC774\uBBF8\uC9C0 \uC790\uB3D9\uD654 CLI");
433
- registerPostCommands(cli);
977
+ const cli = new Command().name("roottale-cms").description("RootTale CMS \uC804\uCCB4 \uAD00\uB9AC \uC790\uB3D9\uD654 CLI");
978
+ registerManagementCommands(cli);
979
+ registerPostCommands(cli, "entries");
980
+ registerPostCommands(cli, "posts");
434
981
  registerMediaCommands(cli);
435
982
  return cli;
436
983
  }
@@ -448,21 +995,29 @@ async function runCmsCli(argv) {
448
995
  process.exitCode = 1;
449
996
  }
450
997
  }
451
- function registerPostCommands(cli) {
452
- const posts = cli.command("posts").description("CMS \uAE00 \uC790\uB3D9\uD654");
453
- posts.command("list").description("\uCD08\uC548\xB7\uC608\uC57D\xB7\uBC1C\uD589 \uAE00 \uBAA9\uB85D \uC870\uD68C").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--limit <number>", "\uC870\uD68C \uAC1C\uC218", integer, 20).option("--cursor <cursor>", "\uB2E4\uC74C \uD398\uC774\uC9C0 \uCEE4\uC11C").option("--type <type>", "post \uB610\uB294 page").option("--status <status>", "draft, published, scheduled, private").action(async (options) => {
998
+ function registerPostCommands(cli, name) {
999
+ const posts = cli.command(name).description(
1000
+ name === "entries" ? "\uD398\uC774\uC9C0\xB7\uAE00\xB7\uC815\uBCF4 \uD56D\uBAA9 \uAD00\uB9AC" : "CMS \uAE00 \uAD00\uB9AC(\uD638\uD658 \uBA85\uB839)"
1001
+ );
1002
+ posts.command("list").description("\uCD08\uC548\xB7\uC608\uC57D\xB7\uBC1C\uD589 \uAE00 \uBAA9\uB85D \uC870\uD68C").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--limit <number>", "\uC870\uD68C \uAC1C\uC218", integer, 20).option("--cursor <cursor>", "\uB2E4\uC74C \uD398\uC774\uC9C0 \uCEE4\uC11C").option("--type <type>", "post \uB610\uB294 page").option("--status <status>", "draft, published, scheduled, private").option("--model-key <key>", "\uCF58\uD150\uCE20 \uBAA8\uB378 key").action(async (options) => {
454
1003
  await run("listManagedCmsPosts", options);
455
1004
  });
456
- posts.command("create").description("Tiptap JSON \uBCF8\uBB38\uC73C\uB85C \uC0C8 \uAE00 \uC0DD\uC131").requiredOption("--title <title>", "\uAE00 \uC81C\uBAA9").requiredOption("--slug <slug>", "URL \uC2AC\uB7EC\uADF8").requiredOption("--body-file <path>", "Tiptap \uBCF8\uBB38 JSON \uD30C\uC77C").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--type <type>", "post \uB610\uB294 page", "post").option("--excerpt <text>", "\uC694\uC57D").option("--featured-media-id <id>", "\uC378\uB124\uC77C \uBBF8\uB514\uC5B4 ID").option("--publish", "\uC989\uC2DC \uBC1C\uD589").option("--scheduled-at <iso>", "\uC608\uC57D \uBC1C\uD589 ISO \uC2DC\uAC01").option("--category-ids <ids>", "\uC27C\uD45C\uB85C \uAD6C\uBD84\uD55C \uCE74\uD14C\uACE0\uB9AC ID").option("--tag-ids <ids>", "\uC27C\uD45C\uB85C \uAD6C\uBD84\uD55C \uD0DC\uADF8 ID").action(async (options) => {
1005
+ posts.command("get <post-id>").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").action(async (postId, options) => {
1006
+ await run("getManagedCmsPost", { postId, ...options });
1007
+ });
1008
+ posts.command("create").description("Tiptap JSON \uBCF8\uBB38\uC73C\uB85C \uC0C8 \uAE00 \uC0DD\uC131").requiredOption("--title <title>", "\uAE00 \uC81C\uBAA9").requiredOption("--slug <slug>", "URL \uC2AC\uB7EC\uADF8").requiredOption("--body-file <path>", "Tiptap \uBCF8\uBB38 JSON \uD30C\uC77C").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--type <type>", "post \uB610\uB294 page", "post").option("--excerpt <text>", "\uC694\uC57D").option("--featured-media-id <id>", "\uC378\uB124\uC77C \uBBF8\uB514\uC5B4 ID").option("--publish", "\uC989\uC2DC \uBC1C\uD589").option("--scheduled-at <iso>", "\uC608\uC57D \uBC1C\uD589 ISO \uC2DC\uAC01").option("--category-ids <ids>", "\uC27C\uD45C\uB85C \uAD6C\uBD84\uD55C \uCE74\uD14C\uACE0\uB9AC ID").option("--tag-ids <ids>", "\uC27C\uD45C\uB85C \uAD6C\uBD84\uD55C \uD0DC\uADF8 ID").option("--model-key <key>", "\uCF58\uD150\uCE20 \uBAA8\uB378 key").option("--field-values-file <path>", "\uBAA8\uB378 \uD544\uB4DC \uAC12 JSON \uD30C\uC77C").action(async (options) => {
457
1009
  await run("createCmsPost", {
458
1010
  ...options,
459
1011
  bodyJson: await readJsonObject(options.bodyFile),
460
1012
  categoryIds: commaSeparated(options.categoryIds),
461
1013
  tagIds: commaSeparated(options.tagIds),
462
- bodyFile: void 0
1014
+ modelKey: options.modelKey,
1015
+ fieldValues: options.fieldValuesFile ? await readJsonObject(options.fieldValuesFile) : void 0,
1016
+ bodyFile: void 0,
1017
+ fieldValuesFile: void 0
463
1018
  });
464
1019
  });
465
- posts.command("update").description("\uAE30\uC874 \uAE00\uC758 \uC77C\uBD80 \uD544\uB4DC \uC218\uC815").argument("<post-id>", "\uAE00 ID").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--title <title>", "\uAE00 \uC81C\uBAA9").option("--slug <slug>", "URL \uC2AC\uB7EC\uADF8").option("--body-file <path>", "Tiptap \uBCF8\uBB38 JSON \uD30C\uC77C").option("--excerpt <text>", "\uC694\uC57D").option("--featured-media-id <id>", "\uC378\uB124\uC77C \uBBF8\uB514\uC5B4 ID").option("--clear-featured-media", "\uC378\uB124\uC77C \uC5F0\uACB0 \uD574\uC81C").option("--scheduled-at <iso>", "\uC608\uC57D \uBC1C\uD589 ISO \uC2DC\uAC01").option("--clear-schedule", "\uC608\uC57D \uD574\uC81C").action(async (postId, options) => {
1020
+ posts.command("update").description("\uAE30\uC874 \uAE00\uC758 \uC77C\uBD80 \uD544\uB4DC \uC218\uC815").argument("<post-id>", "\uAE00 ID").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--title <title>", "\uAE00 \uC81C\uBAA9").option("--slug <slug>", "URL \uC2AC\uB7EC\uADF8").option("--body-file <path>", "Tiptap \uBCF8\uBB38 JSON \uD30C\uC77C").option("--excerpt <text>", "\uC694\uC57D").option("--featured-media-id <id>", "\uC378\uB124\uC77C \uBBF8\uB514\uC5B4 ID").option("--clear-featured-media", "\uC378\uB124\uC77C \uC5F0\uACB0 \uD574\uC81C").option("--scheduled-at <iso>", "\uC608\uC57D \uBC1C\uD589 ISO \uC2DC\uAC01").option("--clear-schedule", "\uC608\uC57D \uD574\uC81C").option("--field-values-file <path>", "\uBAA8\uB378 \uD544\uB4DC \uAC12 JSON \uD30C\uC77C").action(async (postId, options) => {
466
1021
  await run("updateCmsPost", {
467
1022
  postId,
468
1023
  siteId: options.siteId,
@@ -471,7 +1026,8 @@ function registerPostCommands(cli) {
471
1026
  bodyJson: options.bodyFile ? await readJsonObject(options.bodyFile) : void 0,
472
1027
  excerpt: options.excerpt,
473
1028
  featuredMediaId: options.clearFeaturedMedia ? null : options.featuredMediaId,
474
- scheduledAt: options.clearSchedule ? null : options.scheduledAt
1029
+ scheduledAt: options.clearSchedule ? null : options.scheduledAt,
1030
+ fieldValues: options.fieldValuesFile ? await readJsonObject(options.fieldValuesFile) : void 0
475
1031
  });
476
1032
  });
477
1033
  lifecycle(posts, "publish", "\uAE00\uC744 \uC989\uC2DC \uBC1C\uD589", "publishCmsPost");
@@ -484,6 +1040,53 @@ function registerPostCommands(cli) {
484
1040
  termIds: commaSeparated(options.termIds) ?? []
485
1041
  });
486
1042
  });
1043
+ posts.command("delete <post-id>").option("--site-id <id>", "\uC0AC\uC774\uD2B8 ID").option("--hard", "\uC601\uAD6C \uC0AD\uC81C").action(async (postId, options) => {
1044
+ await run("deleteCmsPost", { postId, ...options });
1045
+ });
1046
+ }
1047
+ function registerManagementCommands(cli) {
1048
+ const models = cli.command("models").description("\uD398\uC774\uC9C0\xB7\uAE00\xB7\uC815\uBCF4 \uBAA8\uB378 \uAD00\uB9AC");
1049
+ models.command("list").option("--site-id <id>").option("--state <state>").option("--preset <preset>").option("--source <source>").action(async (options) => runManagement("listCmsContentModels", options));
1050
+ models.command("get <model-key>").option("--site-id <id>").action(async (modelKey, options) => runManagement("getCmsContentModel", { modelKey, ...options }));
1051
+ inputCommand(models, "create", "createCmsContentModel");
1052
+ inputCommand(models, "update <model-key>", "updateCmsContentModel", "modelKey");
1053
+ refCommand(models, "activate <model-key>", "activateCmsContentModel", "modelKey");
1054
+ refCommand(models, "deactivate <model-key>", "deactivateCmsContentModel", "modelKey");
1055
+ refCommand(models, "delete <model-key>", "deleteCmsContentModel", "modelKey");
1056
+ const fields = cli.command("fields").description("\uBAA8\uB378\uBCC4 \uD544\uB4DC \uADF8\uB8F9 \uAD00\uB9AC");
1057
+ refCommand(fields, "list <model-key>", "listCmsFieldGroups", "modelKey");
1058
+ twoRefCommand(fields, "get <model-key> <group-key>", "getCmsFieldGroup");
1059
+ inputCommand(fields, "create <model-key>", "createCmsFieldGroup", "modelKey");
1060
+ inputCommand(fields, "update <model-key> <group-key>", "updateCmsFieldGroup", "modelKey", "groupKey");
1061
+ twoRefCommand(fields, "activate <model-key> <group-key>", "activateCmsFieldGroup");
1062
+ twoRefCommand(fields, "deactivate <model-key> <group-key>", "deactivateCmsFieldGroup");
1063
+ twoRefCommand(fields, "delete <model-key> <group-key>", "deleteCmsFieldGroup");
1064
+ const slots = cli.command("exposure-slots").description("FRONT \uB178\uCD9C \uC2AC\uB86F \uC870\uD68C");
1065
+ slots.command("list").option("--site-id <id>").action(async (options) => runManagement("listCmsExposureSlots", options));
1066
+ const exposures = cli.command("exposures").description("\uBC30\uB108\xB7\uD31D\uC5C5 \uCEA0\uD398\uC778 \uAD00\uB9AC");
1067
+ exposures.command("list").option("--site-id <id>").option("--kind <kind>").option("--status <status>").action(async (options) => runManagement("listCmsExposures", options));
1068
+ refCommand(exposures, "get <exposure-id>", "getCmsExposure", "exposureId");
1069
+ inputCommand(exposures, "create", "createCmsExposure");
1070
+ inputCommand(exposures, "update <exposure-id>", "updateCmsExposure", "exposureId");
1071
+ refCommand(exposures, "publish <exposure-id>", "publishCmsExposure", "exposureId");
1072
+ refCommand(exposures, "archive <exposure-id>", "archiveCmsExposure", "exposureId");
1073
+ }
1074
+ function refCommand(parent, syntax, toolName, key) {
1075
+ parent.command(syntax).option("--site-id <id>").action(async (value, options) => runManagement(toolName, { [key]: value, ...options }));
1076
+ }
1077
+ function twoRefCommand(parent, syntax, toolName) {
1078
+ parent.command(syntax).option("--site-id <id>").action(async (modelKey, groupKey, options) => runManagement(toolName, { modelKey, groupKey, ...options }));
1079
+ }
1080
+ function inputCommand(parent, syntax, toolName, firstKey, secondKey) {
1081
+ const command = parent.command(syntax).requiredOption("--input-file <path>", "\uC694\uCCAD JSON \uD30C\uC77C").option("--site-id <id>");
1082
+ command.action(async (...values) => {
1083
+ const options = values.at(-2);
1084
+ const input = await readJsonObject(options.inputFile);
1085
+ const refs = {};
1086
+ if (firstKey) refs[firstKey] = values[0];
1087
+ if (secondKey) refs[secondKey] = values[1];
1088
+ await runManagement(toolName, { ...input, ...refs, siteId: options.siteId });
1089
+ });
487
1090
  }
488
1091
  function registerMediaCommands(cli) {
489
1092
  const media = cli.command("media").description("CMS \uBBF8\uB514\uC5B4 \uC790\uB3D9\uD654");
@@ -513,6 +1116,14 @@ async function run(name, args) {
513
1116
  process.stdout.write(`${JSON.stringify(result, null, 2)}
514
1117
  `);
515
1118
  }
1119
+ async function runManagement(name, args) {
1120
+ const definedArgs = Object.fromEntries(
1121
+ Object.entries(args).filter(([, value]) => value !== void 0)
1122
+ );
1123
+ const result = await callManagementTool(name, definedArgs);
1124
+ process.stdout.write(`${JSON.stringify(result, null, 2)}
1125
+ `);
1126
+ }
516
1127
  async function readJsonObject(filePath) {
517
1128
  const parsed = JSON.parse(await readFile2(filePath, "utf8"));
518
1129
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -542,7 +1153,7 @@ import {
542
1153
  ListToolsRequestSchema,
543
1154
  McpError
544
1155
  } from "@modelcontextprotocol/sdk/types.js";
545
- import { z as z4 } from "zod";
1156
+ import { z as z5 } from "zod";
546
1157
 
547
1158
  // src/docs.ts
548
1159
  import { readdir, readFile as readFile3 } from "fs/promises";
@@ -625,7 +1236,7 @@ ${content}`;
625
1236
  }
626
1237
 
627
1238
  // src/seo-tools.ts
628
- import { z as z3 } from "zod";
1239
+ import { z as z4 } from "zod";
629
1240
 
630
1241
  // src/seo-definitions.ts
631
1242
  var DATE_RANGES = [
@@ -636,7 +1247,7 @@ var DATE_RANGES = [
636
1247
  "last_12_months"
637
1248
  ];
638
1249
  var SEO_TOOL_DEFINITIONS = [
639
- tool2(
1250
+ tool3(
640
1251
  "getTopSeoKeywords",
641
1252
  "Google Search Console\uC5D0\uC11C \uC0AC\uC774\uD2B8\uC758 \uC0C1\uC704 \uAC80\uC0C9\uC5B4\uC640 \uD074\uB9AD\xB7\uB178\uCD9C\xB7CTR\xB7\uD3C9\uADE0 \uC21C\uC704\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
642
1253
  {
@@ -645,7 +1256,7 @@ var SEO_TOOL_DEFINITIONS = [
645
1256
  limit: numberProperty2("1-100, \uAE30\uBCF8 25")
646
1257
  }
647
1258
  ),
648
- tool2(
1259
+ tool3(
649
1260
  "analyzeCmsPostSeo",
650
1261
  "ROOT-ADMIN\uACFC \uAC19\uC740 \uADDC\uCE59\uC73C\uB85C \uAE00\uC758 SEO\uC640 \uD55C\uAD6D\uC5B4 \uAC00\uB3C5\uC131\uC744 \uB2E4\uC2DC \uAC80\uC0AC\uD569\uB2C8\uB2E4. \uAE00\uC744 \uC218\uC815\uD558\uAC70\uB098 \uBC1C\uD589\uD558\uAE30 \uC804\uC5D0 \uC0AC\uC6A9\uD558\uC138\uC694.",
651
1262
  {
@@ -655,7 +1266,7 @@ var SEO_TOOL_DEFINITIONS = [
655
1266
  },
656
1267
  ["postId"]
657
1268
  ),
658
- tool2(
1269
+ tool3(
659
1270
  "getCmsPostSeoScores",
660
1271
  "\uBC1C\uD589\uB41C \uAE00\uC758 \uCD5C\uC2E0 SEO \uC810\uC218\uC640 \uB4F1\uAE09\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4. \uAC1C\uC120\uC774 \uD544\uC694\uD55C \uAE00\uC774\uB098 \uC9D1\uC911 \uD0A4\uC6CC\uB4DC\uAC00 \uC5C6\uB294 \uAE00\uC744 \uCC3E\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.",
661
1272
  {
@@ -672,7 +1283,7 @@ var SEO_TOOL_DEFINITIONS = [
672
1283
  function isSeoToolName(name) {
673
1284
  return SEO_TOOL_DEFINITIONS.some((definition) => definition.name === name);
674
1285
  }
675
- function tool2(name, description, properties, required = []) {
1286
+ function tool3(name, description, properties, required = []) {
676
1287
  return {
677
1288
  name,
678
1289
  description,
@@ -695,25 +1306,25 @@ function enumProperty2(values, description) {
695
1306
  }
696
1307
 
697
1308
  // src/seo-tools.ts
698
- var SiteIdInput = z3.object({ siteId: z3.string().optional() });
1309
+ var SiteIdInput = z4.object({ siteId: z4.string().optional() });
699
1310
  var TopKeywordsInput = SiteIdInput.extend({
700
- dateRange: z3.enum([
1311
+ dateRange: z4.enum([
701
1312
  "last_7_days",
702
1313
  "last_30_days",
703
1314
  "last_3_months",
704
1315
  "last_6_months",
705
1316
  "last_12_months"
706
1317
  ]).optional(),
707
- limit: z3.number().int().min(1).max(100).optional()
1318
+ limit: z4.number().int().min(1).max(100).optional()
708
1319
  }).strict();
709
1320
  var AnalyzePostInput = SiteIdInput.extend({
710
- postId: z3.string().min(1),
711
- focusKeyword: z3.string().max(200).optional()
1321
+ postId: z4.string().min(1),
1322
+ focusKeyword: z4.string().max(200).optional()
712
1323
  }).strict();
713
1324
  var ScoresInput = SiteIdInput.extend({
714
- limit: z3.number().int().min(1).max(100).optional(),
715
- type: z3.enum(["post", "page"]).optional(),
716
- seoFilter: z3.enum(["bad", "ok", "good", "empty_keyword"]).optional()
1325
+ limit: z4.number().int().min(1).max(100).optional(),
1326
+ type: z4.enum(["post", "page"]).optional(),
1327
+ seoFilter: z4.enum(["bad", "ok", "good", "empty_keyword"]).optional()
717
1328
  }).strict();
718
1329
  async function callSeoTool(name, args) {
719
1330
  switch (name) {
@@ -722,7 +1333,7 @@ async function callSeoTool(name, args) {
722
1333
  return requestRootTaleApi({
723
1334
  method: "GET",
724
1335
  pathname: "/v1/cms/seo/keywords",
725
- query: optionalQuery2({
1336
+ query: optionalQuery3({
726
1337
  site_id: input.siteId,
727
1338
  date_range: input.dateRange,
728
1339
  limit: input.limit
@@ -734,7 +1345,7 @@ async function callSeoTool(name, args) {
734
1345
  return requestRootTaleApi({
735
1346
  method: "GET",
736
1347
  pathname: `/v1/cms/seo/posts/${encodeURIComponent(input.postId)}/analysis`,
737
- query: optionalQuery2({
1348
+ query: optionalQuery3({
738
1349
  site_id: input.siteId,
739
1350
  focus_keyword: input.focusKeyword
740
1351
  })
@@ -745,7 +1356,7 @@ async function callSeoTool(name, args) {
745
1356
  return requestRootTaleApi({
746
1357
  method: "GET",
747
1358
  pathname: "/v1/cms/seo/scores",
748
- query: optionalQuery2({
1359
+ query: optionalQuery3({
749
1360
  site_id: input.siteId,
750
1361
  limit: input.limit,
751
1362
  type: input.type,
@@ -755,7 +1366,7 @@ async function callSeoTool(name, args) {
755
1366
  }
756
1367
  }
757
1368
  }
758
- function optionalQuery2(values) {
1369
+ function optionalQuery3(values) {
759
1370
  return Object.fromEntries(
760
1371
  Object.entries(values).filter(
761
1372
  (entry) => entry[1] !== void 0
@@ -764,15 +1375,15 @@ function optionalQuery2(values) {
764
1375
  }
765
1376
 
766
1377
  // src/tools.ts
767
- var ReadDocInput = z4.object({ path: z4.string().min(1) }).strict();
768
- var SearchDocsInput = z4.object({ query: z4.string().min(1) }).strict();
769
- var ListPostsInput = z4.object({
770
- limit: z4.number().int().min(1).max(100).optional(),
771
- type: z4.enum(["post", "page"]).optional(),
772
- cursor: z4.string().optional()
1378
+ var ReadDocInput = z5.object({ path: z5.string().min(1) }).strict();
1379
+ var SearchDocsInput = z5.object({ query: z5.string().min(1) }).strict();
1380
+ var ListPostsInput = z5.object({
1381
+ limit: z5.number().int().min(1).max(100).optional(),
1382
+ type: z5.enum(["post", "page"]).optional(),
1383
+ cursor: z5.string().optional()
773
1384
  }).strict();
774
- var GetPostInput = z4.object({ slugOrId: z4.string().min(1) }).strict();
775
- var GetSiteKnowledgeInput = z4.object({ siteId: z4.string().optional() }).strict();
1385
+ var GetPostInput = z5.object({ slugOrId: z5.string().min(1) }).strict();
1386
+ var GetSiteKnowledgeInput = z5.object({ siteId: z5.string().optional() }).strict();
776
1387
  var DOCUMENTATION_TOOL_DEFINITIONS = [
777
1388
  {
778
1389
  name: "listRootTaleDocs",
@@ -851,6 +1462,7 @@ var DOCUMENTATION_TOOL_DEFINITIONS = [
851
1462
  var TOOL_DEFINITIONS = [
852
1463
  ...DOCUMENTATION_TOOL_DEFINITIONS,
853
1464
  ...AUTOMATION_TOOL_DEFINITIONS,
1465
+ ...MANAGEMENT_TOOL_DEFINITIONS,
854
1466
  ...SEO_TOOL_DEFINITIONS
855
1467
  ];
856
1468
  function textResponse(text) {
@@ -874,6 +1486,9 @@ function registerTools(server) {
874
1486
  if (isSeoToolName(request.params.name)) {
875
1487
  return jsonResponse(await callSeoTool(request.params.name, args));
876
1488
  }
1489
+ if (isManagementToolName(request.params.name)) {
1490
+ return jsonResponse(await callManagementTool(request.params.name, args));
1491
+ }
877
1492
  switch (request.params.name) {
878
1493
  case "listRootTaleDocs":
879
1494
  return jsonResponse(await listDocs());
@@ -944,7 +1559,7 @@ function registerTools(server) {
944
1559
  }
945
1560
 
946
1561
  // src/server.ts
947
- var VERSION = true ? "0.53.1" : "dev";
1562
+ var VERSION = true ? "0.56.0" : "dev";
948
1563
  var SERVER_INSTRUCTIONS = `
949
1564
  roottale-cms-mcp\uB294 RootTale CMS\uB97C \uC678\uBD80 \uC0AC\uC774\uD2B8(\uC8FC\uB85C Next.js)\uC5D0 \uC5F0\uB3D9\uD558\uACE0
950
1565
  \uAE00\xB7\uC378\uB124\uC77C\xB7\uBCF8\uBB38 \uC774\uBBF8\uC9C0\uB97C \uC790\uB3D9\uD654\uD558\uAE30 \uC704\uD55C \uBB38\uC11C\xB7\uC608\uC2DC \uCF54\uB4DC\xB7API tool\uC744 \uC81C\uACF5\uD569\uB2C8\uB2E4.