wp-typia 0.23.1 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,7 +30,11 @@ var ADD_OPTION_METADATA = {
30
30
  type: "string"
31
31
  },
32
32
  block: {
33
- description: "Target block slug for variation, style, and end-to-end binding-source workflows.",
33
+ description: "Target block slug/name for variation, core-variation, style, and end-to-end binding-source workflows.",
34
+ type: "string"
35
+ },
36
+ "catalog-title": {
37
+ description: "Human-readable title for typed pattern catalog entries; defaults to the pattern slug title.",
34
38
  type: "string"
35
39
  },
36
40
  "controller-class": {
@@ -62,6 +66,10 @@ var ADD_OPTION_METADATA = {
62
66
  description: "Source full block name (namespace/block) for transform workflows.",
63
67
  type: "string"
64
68
  },
69
+ "from-post-meta": {
70
+ description: "Alias for --post-meta when backing a binding-source scaffold from a typed post-meta contract.",
71
+ type: "string"
72
+ },
65
73
  "inner-blocks-preset": {
66
74
  description: "Compound-only InnerBlocks preset (freeform, ordered, horizontal, locked-structure).",
67
75
  type: "string"
@@ -80,6 +88,10 @@ var ADD_OPTION_METADATA = {
80
88
  description: "WordPress meta key for post-meta workflows; defaults to _<phpPrefix>_<name>.",
81
89
  type: "string"
82
90
  },
91
+ "meta-path": {
92
+ description: "Top-level post-meta field used as the default binding-source field when --post-meta or --from-post-meta is provided.",
93
+ type: "string"
94
+ },
83
95
  method: {
84
96
  description: "HTTP method for manual REST contract workflows (GET, POST, PUT, PATCH, or DELETE).",
85
97
  type: "string"
@@ -100,6 +112,10 @@ var ADD_OPTION_METADATA = {
100
112
  description: "WordPress post type key for post-meta workflows.",
101
113
  type: "string"
102
114
  },
115
+ "post-meta": {
116
+ description: "Typed post-meta contract slug used to back a binding-source scaffold.",
117
+ type: "string"
118
+ },
103
119
  "persistence-policy": {
104
120
  description: "Persistence write policy for persistence-capable templates.",
105
121
  type: "string"
@@ -129,6 +145,14 @@ var ADD_OPTION_METADATA = {
129
145
  description: "REST route pattern relative to the namespace; generated resources use it for item routes and manual/provider contracts may use it as an alias for --path.",
130
146
  type: "string"
131
147
  },
148
+ scope: {
149
+ description: "Pattern catalog scope for pattern workflows (full or section).",
150
+ type: "string"
151
+ },
152
+ "section-role": {
153
+ description: "Typed section role for section-scoped pattern catalog entries.",
154
+ type: "string"
155
+ },
132
156
  "secret-field": {
133
157
  description: "Write-only request body field for manual settings REST contracts; requires --manual and a request body, typically generated by POST, PUT, or PATCH.",
134
158
  type: "string"
@@ -165,6 +189,20 @@ var ADD_OPTION_METADATA = {
165
189
  description: "Optional built-in block family for the new block; interactive flows let you choose it when omitted and non-interactive runs default to basic.",
166
190
  type: "string"
167
191
  },
192
+ "thumbnail-url": {
193
+ description: "Optional thumbnail URL or relative path for typed pattern catalog entries.",
194
+ type: "string"
195
+ },
196
+ tags: {
197
+ description: "Comma-separated tags for typed pattern catalog entries; may be repeated.",
198
+ repeatable: true,
199
+ type: "string"
200
+ },
201
+ tag: {
202
+ description: "Repeatable singular tag for typed pattern catalog entries.",
203
+ repeatable: true,
204
+ type: "string"
205
+ },
168
206
  type: {
169
207
  description: "Exported TypeScript type or interface name for standalone contract workflows.",
170
208
  type: "string"
@@ -427,10 +465,19 @@ function buildCommandOptionParser(...metadataMaps) {
427
465
  }
428
466
  return {
429
467
  booleanOptionNames: new Set(collectOptionNamesByType(metadata, "boolean")),
468
+ repeatableOptionNames: new Set(Object.entries(metadata).filter(([, option]) => option.repeatable).map(([name]) => name)),
430
469
  shortFlagMap: new Map(Object.entries(metadata).flatMap(([name, option]) => option.short ? [[option.short, { name, type: option.type }]] : [])),
431
470
  stringOptionNames: new Set(collectOptionNamesByType(metadata, "string"))
432
471
  };
433
472
  }
473
+ function assignParsedOptionValue(flags, options) {
474
+ if (!options.parser.repeatableOptionNames.has(options.name)) {
475
+ flags[options.name] = options.value;
476
+ return;
477
+ }
478
+ const current = flags[options.name];
479
+ flags[options.name] = Array.isArray(current) ? [...current, options.value] : current === undefined ? [options.value] : [current, options.value];
480
+ }
434
481
  function buildArgvWalkerRoutingMetadata(...metadataMaps) {
435
482
  const parser = buildCommandOptionParser(...metadataMaps);
436
483
  return {
@@ -472,7 +519,11 @@ function extractKnownOptionValuesFromArgv(argv, options) {
472
519
  if (!next || next.startsWith("-")) {
473
520
  throw createMissingOptionValueError(arg);
474
521
  }
475
- flags[shortFlag.name] = next;
522
+ assignParsedOptionValue(flags, {
523
+ name: shortFlag.name,
524
+ parser: options.parser,
525
+ value: next
526
+ });
476
527
  index += 1;
477
528
  continue;
478
529
  }
@@ -497,14 +548,22 @@ function extractKnownOptionValuesFromArgv(argv, options) {
497
548
  if (!inlineValue) {
498
549
  throw createMissingOptionValueError(`--${rawName}`);
499
550
  }
500
- flags[rawName] = inlineValue;
551
+ assignParsedOptionValue(flags, {
552
+ name: rawName,
553
+ parser: options.parser,
554
+ value: inlineValue
555
+ });
501
556
  continue;
502
557
  }
503
558
  const next = argv[index + 1];
504
559
  if (!next || next.startsWith("-")) {
505
560
  throw createMissingOptionValueError(`--${rawName}`);
506
561
  }
507
- flags[rawName] = next;
562
+ assignParsedOptionValue(flags, {
563
+ name: rawName,
564
+ parser: options.parser,
565
+ value: next
566
+ });
508
567
  index += 1;
509
568
  continue;
510
569
  }
@@ -544,7 +603,11 @@ function parseCommandArgvWithMetadata(argv, options) {
544
603
  if (!next || next.startsWith("-")) {
545
604
  throw createMissingOptionValueError(arg);
546
605
  }
547
- flags[shortFlag.name] = next;
606
+ assignParsedOptionValue(flags, {
607
+ name: shortFlag.name,
608
+ parser: options.parser,
609
+ value: next
610
+ });
548
611
  index += 1;
549
612
  continue;
550
613
  }
@@ -564,14 +627,22 @@ function parseCommandArgvWithMetadata(argv, options) {
564
627
  if (!inlineValue) {
565
628
  throw createMissingOptionValueError(`--${rawName}`);
566
629
  }
567
- flags[rawName] = inlineValue;
630
+ assignParsedOptionValue(flags, {
631
+ name: rawName,
632
+ parser: options.parser,
633
+ value: inlineValue
634
+ });
568
635
  continue;
569
636
  }
570
637
  const next = argv[index + 1];
571
638
  if (!next || next.startsWith("-")) {
572
639
  throw createMissingOptionValueError(`--${rawName}`);
573
640
  }
574
- flags[rawName] = next;
641
+ assignParsedOptionValue(flags, {
642
+ name: rawName,
643
+ parser: options.parser,
644
+ value: next
645
+ });
575
646
  index += 1;
576
647
  continue;
577
648
  }
@@ -599,6 +670,10 @@ function resolveCommandOptionValues(metadata, options) {
599
670
  resolved[name] = Boolean(value ?? false);
600
671
  continue;
601
672
  }
673
+ if (descriptor.repeatable && Array.isArray(value)) {
674
+ resolved[name] = value.every((item) => typeof item === "string") ? value.join(",") : undefined;
675
+ continue;
676
+ }
602
677
  resolved[name] = typeof value === "string" ? value : undefined;
603
678
  }
604
679
  return resolved;
@@ -756,10 +831,19 @@ var WP_TYPIA_CONFIG_SOURCES = [
756
831
  ".wp-typiarc",
757
832
  ".wp-typiarc.json"
758
833
  ];
834
+ var wordpressVersionSchema = z2.string().regex(/^\d+\.\d+(?:\.\d+)?$/u, 'expected dotted numeric WordPress version such as "6.7" or "6.7.1"');
759
835
  var wpTypiaSchemaSourceSchema = z2.object({
760
836
  namespace: z2.string(),
761
837
  path: z2.string()
762
838
  }).strict();
839
+ var wordpressCompatibilityConfigSchema = z2.object({
840
+ minVersion: wordpressVersionSchema.optional(),
841
+ testedVersions: z2.array(wordpressVersionSchema).optional()
842
+ }).strict();
843
+ var blockApiCompatibilityConfigSchema = z2.object({
844
+ allowUnknownFutureKeys: z2.boolean().optional(),
845
+ strict: z2.boolean().optional()
846
+ }).strict();
763
847
  var createConfigSchema = z2.object({
764
848
  "alternate-render-targets": z2.string().optional(),
765
849
  "inner-blocks-preset": z2.string().optional(),
@@ -799,8 +883,10 @@ var mcpConfigSchema = z2.object({
799
883
  }).strict();
800
884
  var wpTypiaUserConfigSchema = z2.object({
801
885
  add: addConfigSchema.optional(),
886
+ compatibility: blockApiCompatibilityConfigSchema.optional(),
802
887
  create: createConfigSchema.optional(),
803
- mcp: mcpConfigSchema.optional()
888
+ mcp: mcpConfigSchema.optional(),
889
+ wordpress: wordpressCompatibilityConfigSchema.optional()
804
890
  }).strict();
805
891
  function formatIssuePath(issuePath) {
806
892
  if (issuePath.length === 0) {
@@ -917,8 +1003,8 @@ function extractWpTypiaConfigOverride(argv) {
917
1003
 
918
1004
  // src/runtime-bridge-add.ts
919
1005
  import {
920
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES7,
921
- createCliDiagnosticCodeError as createCliDiagnosticCodeError6
1006
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES9,
1007
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError8
922
1008
  } from "@wp-typia/project-tools/cli-diagnostics";
923
1009
 
924
1010
  // src/add-kind-ids.ts
@@ -959,11 +1045,13 @@ var NAME_TYPE_VISIBLE_FIELDS = [
959
1045
  "name",
960
1046
  "type"
961
1047
  ];
962
- var NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS = [
1048
+ var NAME_BLOCK_ATTRIBUTE_POST_META_VISIBLE_FIELDS = [
963
1049
  "kind",
964
1050
  "name",
965
1051
  "block",
966
- "attribute"
1052
+ "attribute",
1053
+ "post-meta",
1054
+ "meta-path"
967
1055
  ];
968
1056
  var NAME_BLOCK_VISIBLE_FIELDS = [
969
1057
  "kind",
@@ -1216,7 +1304,7 @@ var aiFeatureAddKindEntry = defineAddKindRegistryEntry({
1216
1304
  });
1217
1305
 
1218
1306
  // src/add-kinds/binding-source.ts
1219
- var BINDING_SOURCE_MISSING_NAME_MESSAGE = "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].";
1307
+ var BINDING_SOURCE_MISSING_NAME_MESSAGE = "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--from-post-meta <post-meta> --meta-path <field>].";
1220
1308
  var bindingSourceAddKindEntry = defineAddKindRegistryEntry({
1221
1309
  completion: {
1222
1310
  nextSteps: (values) => [
@@ -1224,11 +1312,18 @@ var bindingSourceAddKindEntry = defineAddKindRegistryEntry({
1224
1312
  ...values.blockSlug && values.attributeName ? [
1225
1313
  `Review src/blocks/${values.blockSlug}/block.json for the ${values.attributeName} bindable attribute.`
1226
1314
  ] : [],
1315
+ ...values.postMetaSlug ? [
1316
+ `Run wp-typia sync-rest --check after editing ${values.schemaFile}.`
1317
+ ] : [],
1227
1318
  "Run your workspace build or dev command to verify the binding source hooks and editor registration."
1228
1319
  ],
1229
1320
  summaryLines: (values, projectDir) => [
1230
1321
  `Binding source: ${values.bindingSourceSlug}`,
1231
1322
  ...values.blockSlug && values.attributeName ? [`Target: ${values.blockSlug}.${values.attributeName}`] : [],
1323
+ ...values.postMetaSlug ? [
1324
+ `Post meta: ${values.postMetaSlug}`,
1325
+ `Meta field: ${values.metaPath}`
1326
+ ] : [],
1232
1327
  `Project directory: ${projectDir}`
1233
1328
  ],
1234
1329
  title: "Added binding source"
@@ -1238,17 +1333,26 @@ var bindingSourceAddKindEntry = defineAddKindRegistryEntry({
1238
1333
  async prepareExecution(context) {
1239
1334
  const name = requireAddKindName(context, BINDING_SOURCE_MISSING_NAME_MESSAGE);
1240
1335
  const [blockName, attributeName] = readOptionalPairedStrictStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
1336
+ const postMetaName = readOptionalDashedOrCamelStringFlag(context.flags, "from-post-meta", "fromPostMeta") ?? readOptionalDashedOrCamelStringFlag(context.flags, "post-meta", "postMeta");
1337
+ const metaPath = readOptionalDashedOrCamelStringFlag(context.flags, "meta-path", "metaPath");
1241
1338
  return createNamedExecutionPlan(context, {
1242
1339
  execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBindingSourceCommand({
1243
1340
  attributeName,
1244
1341
  bindingSourceName: name2,
1245
1342
  blockName,
1246
- cwd
1343
+ cwd,
1344
+ metaPath,
1345
+ postMetaName
1247
1346
  }),
1248
1347
  getValues: (result) => ({
1249
1348
  ...result.attributeName ? { attributeName: result.attributeName } : {},
1250
1349
  ...result.blockSlug ? { blockSlug: result.blockSlug } : {},
1251
- bindingSourceSlug: result.bindingSourceSlug
1350
+ bindingSourceSlug: result.bindingSourceSlug,
1351
+ ...result.metaKey ? { metaKey: result.metaKey } : {},
1352
+ ...result.metaPath ? { metaPath: result.metaPath } : {},
1353
+ ...result.postMetaSlug ? { postMetaSlug: result.postMetaSlug } : {},
1354
+ ...result.postType ? { postType: result.postType } : {},
1355
+ ...result.schemaFile ? { schemaFile: result.schemaFile } : {}
1252
1356
  }),
1253
1357
  missingNameMessage: BINDING_SOURCE_MISSING_NAME_MESSAGE,
1254
1358
  name,
@@ -1257,8 +1361,8 @@ var bindingSourceAddKindEntry = defineAddKindRegistryEntry({
1257
1361
  },
1258
1362
  sortOrder: 70,
1259
1363
  supportsDryRun: true,
1260
- usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]",
1261
- visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS
1364
+ usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--from-post-meta|--post-meta <post-meta> [--meta-path <field>]] [--dry-run]",
1365
+ visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_POST_META_VISIBLE_FIELDS
1262
1366
  });
1263
1367
 
1264
1368
  // src/external-layer-prompt-options.ts
@@ -1400,6 +1504,79 @@ var contractAddKindEntry = defineAddKindRegistryEntry({
1400
1504
  visibleFieldNames: () => NAME_TYPE_VISIBLE_FIELDS
1401
1505
  });
1402
1506
 
1507
+ // src/add-kinds/core-variation.ts
1508
+ import {
1509
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES6,
1510
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError5
1511
+ } from "@wp-typia/project-tools/cli-diagnostics";
1512
+ var CORE_VARIATION_MISSING_NAME_MESSAGE = "`wp-typia add core-variation` requires <name>. Usage: wp-typia add core-variation <block-name> <name> or wp-typia add core-variation <name> --block <namespace/block>.";
1513
+ var CORE_VARIATION_MISSING_BLOCK_MESSAGE = "`wp-typia add core-variation` requires <block-name>. Usage: wp-typia add core-variation <block-name> <name> or wp-typia add core-variation <name> --block <namespace/block>.";
1514
+ function resolveCoreVariationInputs(context) {
1515
+ const positionalTargetBlockName = context.positionalArgs?.[1];
1516
+ const positionalVariationName = context.positionalArgs?.[2];
1517
+ if (positionalVariationName) {
1518
+ if (!positionalTargetBlockName) {
1519
+ throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.MISSING_ARGUMENT, CORE_VARIATION_MISSING_BLOCK_MESSAGE);
1520
+ }
1521
+ return {
1522
+ targetBlockName: positionalTargetBlockName,
1523
+ variationName: positionalVariationName
1524
+ };
1525
+ }
1526
+ if (context.name?.includes("/") && !readOptionalStrictStringFlag(context.flags, "block")) {
1527
+ throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.MISSING_ARGUMENT, CORE_VARIATION_MISSING_NAME_MESSAGE);
1528
+ }
1529
+ const variationName = requireAddKindName(context, CORE_VARIATION_MISSING_NAME_MESSAGE);
1530
+ const targetBlockName = readOptionalStrictStringFlag(context.flags, "block");
1531
+ if (!targetBlockName) {
1532
+ throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.MISSING_ARGUMENT, CORE_VARIATION_MISSING_BLOCK_MESSAGE);
1533
+ }
1534
+ return {
1535
+ targetBlockName,
1536
+ variationName
1537
+ };
1538
+ }
1539
+ var coreVariationAddKindEntry = defineAddKindRegistryEntry({
1540
+ completion: {
1541
+ nextSteps: (values) => [
1542
+ `Review ${values.variationFile}.`,
1543
+ "Run your workspace build or dev command to verify the editor-side variation registration."
1544
+ ],
1545
+ summaryLines: (values, projectDir) => [
1546
+ `Core variation: ${values.variationSlug}`,
1547
+ `Target block: ${values.targetBlockName}`,
1548
+ `Project directory: ${projectDir}`
1549
+ ],
1550
+ title: "Added core block variation"
1551
+ },
1552
+ description: "Add an editor-side variation for an existing core or external block",
1553
+ nameLabel: "Variation name",
1554
+ async prepareExecution(context) {
1555
+ const { targetBlockName, variationName } = resolveCoreVariationInputs(context);
1556
+ return createNamedExecutionPlan(context, {
1557
+ execute: ({ cwd, name }) => context.addRuntime.runAddCoreVariationCommand({
1558
+ cwd,
1559
+ targetBlockName,
1560
+ variationName: name
1561
+ }),
1562
+ getValues: (result) => ({
1563
+ targetBlockName: result.targetBlockName,
1564
+ variationFile: result.variationFile,
1565
+ variationSlug: result.variationSlug
1566
+ }),
1567
+ getWarnings: (result) => result.warnings,
1568
+ missingNameMessage: CORE_VARIATION_MISSING_NAME_MESSAGE,
1569
+ name: variationName,
1570
+ warnLine: context.warnLine
1571
+ });
1572
+ },
1573
+ sortOrder: 25,
1574
+ supportsDryRun: true,
1575
+ usage: `wp-typia add core-variation <block-name> <name> [--dry-run]
1576
+ Alias: wp-typia add core-variation <name> --block <namespace/block> [--dry-run]`,
1577
+ visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
1578
+ });
1579
+
1403
1580
  // src/add-kinds/editor-plugin.ts
1404
1581
  var EDITOR_PLUGIN_MISSING_NAME_MESSAGE = "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].";
1405
1582
  var editorPluginAddKindEntry = defineAddKindRegistryEntry({
@@ -1542,35 +1719,79 @@ var PATTERN_MISSING_NAME_MESSAGE = "`wp-typia add pattern` requires <name>. Usag
1542
1719
  var patternAddKindEntry = defineAddKindRegistryEntry({
1543
1720
  completion: {
1544
1721
  nextSteps: (values) => [
1545
- `Review src/patterns/${values.patternSlug}.php.`,
1722
+ `Review ${values.contentFile}.`,
1546
1723
  "Run your workspace build or dev command to verify the new pattern registration."
1547
1724
  ],
1548
1725
  summaryLines: (values, projectDir) => [
1549
1726
  `Pattern: ${values.patternSlug}`,
1727
+ `Content file: ${values.contentFile}`,
1550
1728
  `Project directory: ${projectDir}`
1551
1729
  ],
1552
1730
  title: "Added workspace pattern"
1553
1731
  },
1554
1732
  description: "Add a PHP block pattern shell",
1733
+ hiddenStringSubmitFields: [
1734
+ "catalog-title",
1735
+ "scope",
1736
+ "section-role",
1737
+ "tag",
1738
+ "tags",
1739
+ "thumbnail-url"
1740
+ ],
1555
1741
  nameLabel: "Pattern name",
1556
1742
  async prepareExecution(context) {
1557
- return createNamedExecutionPlan(context, {
1558
- execute: ({ cwd, name }) => context.addRuntime.runAddPatternCommand({
1743
+ const name = requireAddKindName(context, PATTERN_MISSING_NAME_MESSAGE);
1744
+ const scope = typeof context.flags.scope === "string" ? context.flags.scope : undefined;
1745
+ const sectionRole = typeof context.flags["section-role"] === "string" ? context.flags["section-role"] : undefined;
1746
+ const catalogTitle = typeof context.flags["catalog-title"] === "string" ? context.flags["catalog-title"] : undefined;
1747
+ const tags = normalizePatternTagFlags(context.flags.tags, context.flags.tag);
1748
+ const thumbnailUrl = typeof context.flags["thumbnail-url"] === "string" ? context.flags["thumbnail-url"] : undefined;
1749
+ return {
1750
+ execute: (cwd) => context.addRuntime.runAddPatternCommand({
1751
+ catalogTitle,
1559
1752
  cwd,
1560
- patternName: name
1753
+ patternScope: scope,
1754
+ patternName: name,
1755
+ sectionRole,
1756
+ tags,
1757
+ thumbnailUrl
1561
1758
  }),
1562
1759
  getValues: (result) => ({
1563
- patternSlug: result.patternSlug
1760
+ contentFile: result.contentFile,
1761
+ patternSlug: result.patternSlug,
1762
+ patternScope: result.patternScope,
1763
+ ...result.sectionRole ? { sectionRole: result.sectionRole } : {}
1564
1764
  }),
1565
- missingNameMessage: PATTERN_MISSING_NAME_MESSAGE,
1566
1765
  warnLine: context.warnLine
1567
- });
1766
+ };
1568
1767
  },
1569
1768
  sortOrder: 60,
1570
1769
  supportsDryRun: true,
1571
- usage: "wp-typia add pattern <name> [--dry-run]",
1770
+ usage: "wp-typia add pattern <name> [--scope <full|section>] [--section-role <role>] [--catalog-title <title>] [--tags <tag,...>|--tag <tag>...] [--thumbnail-url <url>] [--dry-run]",
1572
1771
  visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1573
1772
  });
1773
+ function collectStringFlagValues(value) {
1774
+ if (typeof value === "string") {
1775
+ return [value];
1776
+ }
1777
+ if (Array.isArray(value)) {
1778
+ return value.filter((item) => typeof item === "string");
1779
+ }
1780
+ return [];
1781
+ }
1782
+ function normalizePatternTagFlags(tagsFlag, tagFlag) {
1783
+ const tags = [
1784
+ ...collectStringFlagValues(tagsFlag),
1785
+ ...collectStringFlagValues(tagFlag)
1786
+ ];
1787
+ if (tags.length === 0) {
1788
+ return;
1789
+ }
1790
+ if (tags.length === 1) {
1791
+ return tags[0];
1792
+ }
1793
+ return tags;
1794
+ }
1574
1795
 
1575
1796
  // src/add-kinds/post-meta.ts
1576
1797
  var POST_META_MISSING_NAME_MESSAGE = "`wp-typia add post-meta` requires <name>. Usage: wp-typia add post-meta <name> --post-type <post-type> [--type <ExportedTypeName>] [--meta-key <meta-key>].";
@@ -1634,6 +1855,10 @@ var postMetaAddKindEntry = defineAddKindRegistryEntry({
1634
1855
  });
1635
1856
 
1636
1857
  // src/add-kinds/rest-resource.ts
1858
+ import {
1859
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES7,
1860
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError6
1861
+ } from "@wp-typia/project-tools/cli-diagnostics";
1637
1862
  var REST_RESOURCE_GENERATED_USAGE = "Generated: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--route-pattern <route-pattern>] [--permission-callback <callback>] [--controller-class <ClassName>] [--controller-extends <BaseClass>] [--dry-run]";
1638
1863
  var REST_RESOURCE_MANUAL_USAGE = "Manual: wp-typia add rest-resource <name> --manual [--namespace <vendor/v1>] [--method <GET|POST|PUT|PATCH|DELETE>] [--auth <public|authenticated|public-write-protected>] [--path <route-pattern>|--route-pattern <route-pattern>] [--permission-callback <callback>] [--controller-class <ClassName>] [--controller-extends <BaseClass>] [--query-type <Type>] [--body-type <Type>] [--response-type <Type>] [--secret-field <field>] [--secret-state-field|--secret-has-value-field <field>] [--secret-preserve-on-empty <true|false>] [--dry-run]";
1639
1864
  var REST_RESOURCE_USAGE = `${REST_RESOURCE_GENERATED_USAGE}
@@ -1644,6 +1869,31 @@ var REST_RESOURCE_MISSING_NAME_MESSAGE = [
1644
1869
  ` ${REST_RESOURCE_MANUAL_USAGE}`
1645
1870
  ].join(`
1646
1871
  `);
1872
+ var SECRET_PRESERVE_ON_EMPTY_TRUE_VALUES = new Set(["1", "true", "yes"]);
1873
+ var SECRET_PRESERVE_ON_EMPTY_FALSE_VALUES = new Set(["0", "false", "no"]);
1874
+ function readOptionalSecretPreserveOnEmptyFlag(flags) {
1875
+ const value = flags["secret-preserve-on-empty"] ?? flags.secretPreserveOnEmpty;
1876
+ if (value === undefined || value === null) {
1877
+ return;
1878
+ }
1879
+ if (typeof value === "boolean") {
1880
+ return value;
1881
+ }
1882
+ if (typeof value !== "string") {
1883
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.MISSING_ARGUMENT, "`--secret-preserve-on-empty` requires a value.");
1884
+ }
1885
+ const normalized = value.trim().toLowerCase();
1886
+ if (normalized.length === 0) {
1887
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.MISSING_ARGUMENT, "`--secret-preserve-on-empty` requires a value.");
1888
+ }
1889
+ if (SECRET_PRESERVE_ON_EMPTY_TRUE_VALUES.has(normalized)) {
1890
+ return true;
1891
+ }
1892
+ if (SECRET_PRESERVE_ON_EMPTY_FALSE_VALUES.has(normalized)) {
1893
+ return false;
1894
+ }
1895
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_ARGUMENT, "Manual REST contract --secret-preserve-on-empty must be true or false.");
1896
+ }
1647
1897
  var restResourceAddKindEntry = defineAddKindRegistryEntry({
1648
1898
  completion: {
1649
1899
  nextSteps: (values) => values.mode === "manual" ? [
@@ -1715,7 +1965,7 @@ var restResourceAddKindEntry = defineAddKindRegistryEntry({
1715
1965
  const secretFieldName = readOptionalDashedOrCamelStringFlag(context.flags, "secret-field", "secretField");
1716
1966
  const secretHasValueFieldName = readOptionalDashedOrCamelStringFlag(context.flags, "secret-has-value-field", "secretHasValueField");
1717
1967
  const secretMaskedResponseFieldName = readOptionalDashedOrCamelStringFlag(context.flags, "secret-masked-response-field", "secretMaskedResponseField");
1718
- const secretPreserveOnEmpty = readOptionalDashedOrCamelStringFlag(context.flags, "secret-preserve-on-empty", "secretPreserveOnEmpty");
1968
+ const secretPreserveOnEmpty = readOptionalSecretPreserveOnEmptyFlag(context.flags);
1719
1969
  const secretStateFieldName = readOptionalDashedOrCamelStringFlag(context.flags, "secret-state-field", "secretStateField");
1720
1970
  return createNamedExecutionPlan(context, {
1721
1971
  execute: ({ cwd, name: name2 }) => context.addRuntime.runAddRestResourceCommand({
@@ -1900,6 +2150,7 @@ var ADD_KIND_REGISTRY = {
1900
2150
  "admin-view": adminViewAddKindEntry,
1901
2151
  block: blockAddKindEntry,
1902
2152
  "integration-env": integrationEnvAddKindEntry,
2153
+ "core-variation": coreVariationAddKindEntry,
1903
2154
  variation: variationAddKindEntry,
1904
2155
  style: styleAddKindEntry,
1905
2156
  transform: transformAddKindEntry,
@@ -2295,7 +2546,7 @@ function buildStructuredInitSuccessPayload(plan) {
2295
2546
  // package.json
2296
2547
  var package_default = {
2297
2548
  name: "wp-typia",
2298
- version: "0.23.1",
2549
+ version: "0.24.1",
2299
2550
  description: "Canonical CLI package for wp-typia scaffolding and project workflows",
2300
2551
  packageManager: "bun@1.3.11",
2301
2552
  type: "module",
@@ -2365,7 +2616,7 @@ var package_default = {
2365
2616
  "@bunli/tui": "0.6.0",
2366
2617
  "@bunli/utils": "0.6.0",
2367
2618
  "@wp-typia/api-client": "^0.4.5",
2368
- "@wp-typia/project-tools": "0.23.1",
2619
+ "@wp-typia/project-tools": "0.24.1",
2369
2620
  "better-result": "^2.7.0",
2370
2621
  react: "^19.2.5",
2371
2622
  "react-dom": "^19.2.5",
@@ -2394,8 +2645,8 @@ import {
2394
2645
  parsePackageManagerField
2395
2646
  } from "@wp-typia/project-tools/package-managers";
2396
2647
  import {
2397
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES6,
2398
- createCliDiagnosticCodeError as createCliDiagnosticCodeError5
2648
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES8,
2649
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError7
2399
2650
  } from "@wp-typia/project-tools/cli-diagnostics";
2400
2651
  var LOOSE_CREATE_COMPLETION_PACKAGE_MANAGER_PATTERN = new RegExp(`^(?:corepack\\s+)?(${PACKAGE_MANAGER_IDS.map(escapeRegExp).join("|")})(?=$|[@:/+\\s])`, "iu");
2401
2652
  function parseCreateCompletionPackageManager(packageManager) {
@@ -2413,7 +2664,7 @@ function resolveCreateCompletionPackageManager(packageManager) {
2413
2664
  if (parsedPackageManager) {
2414
2665
  return parsedPackageManager;
2415
2666
  }
2416
- throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.INVALID_ARGUMENT, `Unsupported package manager "${packageManager}" in create completion payload. Expected one of: ${PACKAGE_MANAGER_IDS.join(", ")}.`);
2667
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `Unsupported package manager "${packageManager}" in create completion payload. Expected one of: ${PACKAGE_MANAGER_IDS.join(", ")}.`);
2417
2668
  }
2418
2669
  function formatCreateProgressLine(payload, markerOptions) {
2419
2670
  return formatOutputMarker("progress", `${payload.title}: ${payload.detail}`, markerOptions);
@@ -2659,6 +2910,7 @@ async function executeAddCommand({
2659
2910
  interactive,
2660
2911
  kind,
2661
2912
  name,
2913
+ positionalArgs,
2662
2914
  printLine = console.log,
2663
2915
  prompt,
2664
2916
  warnLine = console.warn
@@ -2672,13 +2924,13 @@ async function executeAddCommand({
2672
2924
  if (shouldPrintMissingAddKindHelp({ emitOutput })) {
2673
2925
  printLine(addRuntime.formatAddHelpText());
2674
2926
  }
2675
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.MISSING_ARGUMENT, formatMissingAddKindDetailLine());
2927
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.MISSING_ARGUMENT, formatMissingAddKindDetailLine());
2676
2928
  }
2677
2929
  if (!isAddKindId(kind)) {
2678
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_COMMAND, `Unknown add kind "${kind}". Expected one of: ${formatAddKindList()}.`);
2930
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_COMMAND, `Unknown add kind "${kind}". Expected one of: ${formatAddKindList()}.`);
2679
2931
  }
2680
2932
  if (dryRun && !supportsAddKindDryRun(kind)) {
2681
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_ARGUMENT, `\`wp-typia add ${kind}\` does not support \`--dry-run\` yet.`);
2933
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_ARGUMENT, `\`wp-typia add ${kind}\` does not support \`--dry-run\` yet.`);
2682
2934
  }
2683
2935
  const executionContext = {
2684
2936
  addRuntime,
@@ -2694,6 +2946,7 @@ async function executeAddCommand({
2694
2946
  },
2695
2947
  isInteractiveSession,
2696
2948
  name,
2949
+ positionalArgs,
2697
2950
  warnLine
2698
2951
  };
2699
2952
  return await executePlannedAddKind(kind, executionContext, {
@@ -2931,8 +3184,8 @@ async function executeMigrateCommand({
2931
3184
  }
2932
3185
  // src/runtime-bridge-templates.ts
2933
3186
  import {
2934
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES8,
2935
- createCliDiagnosticCodeError as createCliDiagnosticCodeError7
3187
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES10,
3188
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError9
2936
3189
  } from "@wp-typia/project-tools/cli-diagnostics";
2937
3190
  var loadCliTemplatesRuntime2 = () => import("@wp-typia/project-tools/cli-templates");
2938
3191
  async function executeTemplatesCommand({ flags }, printLine = console.log) {
@@ -2952,24 +3205,24 @@ async function executeTemplatesCommand({ flags }, printLine = console.log) {
2952
3205
  }
2953
3206
  if (subcommand === "inspect") {
2954
3207
  if (!flags.id) {
2955
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.MISSING_ARGUMENT, "`wp-typia templates inspect` requires <template-id>.");
3208
+ throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.MISSING_ARGUMENT, "`wp-typia templates inspect` requires <template-id>.");
2956
3209
  }
2957
3210
  const template = getTemplateById(flags.id);
2958
3211
  if (!template) {
2959
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
3212
+ throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
2960
3213
  }
2961
3214
  printBlock(printLine, [formatTemplateDetails(template)]);
2962
3215
  return;
2963
3216
  }
2964
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_COMMAND, `Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
3217
+ throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.INVALID_COMMAND, `Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
2965
3218
  }
2966
3219
  // src/runtime-bridge-sync.ts
2967
3220
  import { spawnSync } from "node:child_process";
2968
3221
  import fs3 from "node:fs";
2969
3222
  import path4 from "node:path";
2970
3223
  import {
2971
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES9,
2972
- createCliDiagnosticCodeError as createCliDiagnosticCodeError8
3224
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES11,
3225
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError10
2973
3226
  } from "@wp-typia/project-tools/cli-diagnostics";
2974
3227
  import {
2975
3228
  formatInstallCommand,
@@ -2990,10 +3243,10 @@ function resolveSyncExecutionTarget(subcommand) {
2990
3243
  if (subcommand === "ai") {
2991
3244
  return "ai";
2992
3245
  }
2993
- throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_COMMAND, `Unknown sync subcommand "${subcommand}". Expected one of: "ai".`);
3246
+ throw createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.INVALID_COMMAND, `Unknown sync subcommand "${subcommand}". Expected one of: "ai".`);
2994
3247
  }
2995
3248
  function getSyncRootError(cwd) {
2996
- return createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.OUTSIDE_PROJECT_ROOT, `No generated wp-typia project root was found at ${cwd}. Run \`wp-typia sync\` from a scaffolded project or official workspace root that already contains generated sync scripts. If you expected this directory to work, cd into the scaffold root first or rerun the scaffold before syncing.`);
3249
+ return createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.OUTSIDE_PROJECT_ROOT, `No generated wp-typia project root was found at ${cwd}. Run \`wp-typia sync\` from a scaffolded project or official workspace root that already contains generated sync scripts. If you expected this directory to work, cd into the scaffold root first or rerun the scaffold before syncing.`);
2997
3250
  }
2998
3251
  function readSyncPackageJson(packageJsonPath) {
2999
3252
  const source = fs3.readFileSync(packageJsonPath, "utf8");
@@ -3001,7 +3254,7 @@ function readSyncPackageJson(packageJsonPath) {
3001
3254
  return JSON.parse(source);
3002
3255
  } catch (error) {
3003
3256
  const message = error instanceof Error ? error.message : String(error);
3004
- throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_ARGUMENT, `Unable to parse ${packageJsonPath}: ${message}`, error instanceof Error ? { cause: error } : undefined);
3257
+ throw createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.INVALID_ARGUMENT, `Unable to parse ${packageJsonPath}: ${message}`, error instanceof Error ? { cause: error } : undefined);
3005
3258
  }
3006
3259
  }
3007
3260
  function resolveSyncProjectContext(cwd) {
@@ -3068,7 +3321,7 @@ function assertSyncDependenciesInstalled(project, target) {
3068
3321
  if (markerDir) {
3069
3322
  return;
3070
3323
  }
3071
- throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.DEPENDENCIES_NOT_INSTALLED, `Project dependencies have not been installed yet. Run \`${formatInstallCommand(project.packageManager)}\` from the project root before \`wp-typia sync\`. The generated sync scripts rely on local tools such as \`tsx\`.`);
3324
+ throw createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.DEPENDENCIES_NOT_INSTALLED, `Project dependencies have not been installed yet. Run \`${formatInstallCommand(project.packageManager)}\` from the project root before \`wp-typia sync\`. The generated sync scripts rely on local tools such as \`tsx\`.`);
3072
3325
  }
3073
3326
  function getPackageManagerRunInvocation(packageManager, scriptName, extraArgs) {
3074
3327
  switch (packageManager) {
@@ -3106,7 +3359,7 @@ function buildSyncPlannedCommands(project, extraArgs, target) {
3106
3359
  if (target === "ai") {
3107
3360
  const syncAiCommand2 = createSyncPlannedCommand(project, "sync-ai", extraArgs);
3108
3361
  if (!syncAiCommand2) {
3109
- throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define a \`sync-ai\` script for \`wp-typia sync ai\`.`);
3362
+ throw createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define a \`sync-ai\` script for \`wp-typia sync ai\`.`);
3110
3363
  }
3111
3364
  return [syncAiCommand2];
3112
3365
  }
@@ -3115,7 +3368,7 @@ function buildSyncPlannedCommands(project, extraArgs, target) {
3115
3368
  }
3116
3369
  const syncTypesCommand = createSyncPlannedCommand(project, "sync-types", extraArgs);
3117
3370
  if (!syncTypesCommand) {
3118
- throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define either a \`sync\` or \`sync-types\` script.`);
3371
+ throw createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define either a \`sync\` or \`sync-types\` script.`);
3119
3372
  }
3120
3373
  const plannedCommands = [syncTypesCommand];
3121
3374
  const syncRestCommand = createSyncPlannedCommand(project, "sync-rest", extraArgs);
@@ -3139,7 +3392,7 @@ function runProjectScript(project, plannedCommand, options) {
3139
3392
  const stderr = options.captureOutput && typeof result.stderr === "string" ? result.stderr : undefined;
3140
3393
  const stdout = options.captureOutput && typeof result.stdout === "string" ? result.stdout : undefined;
3141
3394
  if (result.error || result.status !== 0) {
3142
- throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.COMMAND_EXECUTION, `\`${plannedCommand.displayCommand}\` failed.`, {
3395
+ throw createCliDiagnosticCodeError10(CLI_DIAGNOSTIC_CODES11.COMMAND_EXECUTION, `\`${plannedCommand.displayCommand}\` failed.`, {
3143
3396
  cause: result.error ?? (stderr ? new Error(stderr.trim()) : undefined)
3144
3397
  });
3145
3398
  }
@@ -3181,8 +3434,8 @@ async function executeSyncCommand({
3181
3434
  // src/command-contract.ts
3182
3435
  import path5 from "node:path";
3183
3436
  import {
3184
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES10,
3185
- createCliDiagnosticCodeError as createCliDiagnosticCodeError9
3437
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES12,
3438
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError11
3186
3439
  } from "@wp-typia/project-tools/cli-diagnostics";
3187
3440
 
3188
3441
  // src/command-registry.ts
@@ -3453,10 +3706,10 @@ function looksLikeStructuredProjectInput(value) {
3453
3706
  function assertPositionalAliasProjectDir(projectDir) {
3454
3707
  const normalizedProjectDir = path5.normalize(projectDir).replace(/[\\/]+$/u, "") || path5.normalize(projectDir);
3455
3708
  if (normalizedProjectDir === "." || normalizedProjectDir === "..") {
3456
- throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.INVALID_ARGUMENT, `The positional alias does not scaffold into \`${projectDir}\`. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` with an explicit child directory instead.`);
3709
+ throw createCliDiagnosticCodeError11(CLI_DIAGNOSTIC_CODES12.INVALID_ARGUMENT, `The positional alias does not scaffold into \`${projectDir}\`. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` with an explicit child directory instead.`);
3457
3710
  }
3458
3711
  if (looksLikeStructuredProjectInput(projectDir)) {
3459
- throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.INVALID_ARGUMENT, `The positional alias only accepts unambiguous local project directories. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for \`${projectDir}\`.`);
3712
+ throw createCliDiagnosticCodeError11(CLI_DIAGNOSTIC_CODES12.INVALID_ARGUMENT, `The positional alias only accepts unambiguous local project directories. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for \`${projectDir}\`.`);
3460
3713
  }
3461
3714
  }
3462
3715
  function normalizeWpTypiaArgv(argv) {
@@ -3470,7 +3723,7 @@ function normalizeWpTypiaArgv(argv) {
3470
3723
  return argv;
3471
3724
  }
3472
3725
  if (firstPositional === "migrations") {
3473
- throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.INVALID_ARGUMENT, "`wp-typia migrations` was removed in favor of `wp-typia migrate`. Use `wp-typia migrate <subcommand>` instead.");
3726
+ throw createCliDiagnosticCodeError11(CLI_DIAGNOSTIC_CODES12.INVALID_ARGUMENT, "`wp-typia migrations` was removed in favor of `wp-typia migrate`. Use `wp-typia migrate <subcommand>` instead.");
3474
3727
  }
3475
3728
  if (isReservedTopLevelCommandName(firstPositional)) {
3476
3729
  assertStringOptionValues(argv);
@@ -3478,7 +3731,7 @@ function normalizeWpTypiaArgv(argv) {
3478
3731
  }
3479
3732
  if (positionalIndexes.length > 1) {
3480
3733
  const extraPositionals = positionalIndexes.slice(1).map((index) => argv[index]).filter((value) => typeof value === "string" && value.length > 0);
3481
- throw createCliDiagnosticCodeError9(CLI_DIAGNOSTIC_CODES10.INVALID_ARGUMENT, `The positional alias only accepts a single project directory. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for scaffold invocations with additional positional arguments, or check the command spelling if you meant another top-level command. Extra positional arguments: ${extraPositionals.map((value) => `\`${value}\``).join(", ")}.`);
3734
+ throw createCliDiagnosticCodeError11(CLI_DIAGNOSTIC_CODES12.INVALID_ARGUMENT, `The positional alias only accepts a single project directory. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for scaffold invocations with additional positional arguments, or check the command spelling if you meant another top-level command. Extra positional arguments: ${extraPositionals.map((value) => `\`${value}\``).join(", ")}.`);
3482
3735
  }
3483
3736
  assertPositionalAliasProjectDir(firstPositional);
3484
3737
  const normalizedArgv = [
@@ -3492,7 +3745,7 @@ function normalizeWpTypiaArgv(argv) {
3492
3745
 
3493
3746
  // src/node-fallback/doctor.ts
3494
3747
  import {
3495
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES11,
3748
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES13,
3496
3749
  createCliCommandError as createCliCommandError2
3497
3750
  } from "@wp-typia/project-tools/cli-diagnostics";
3498
3751
  async function renderNodeFallbackDoctorJson(cwd, exitPolicy, printLine) {
@@ -3509,7 +3762,7 @@ async function renderNodeFallbackDoctorJson(cwd, exitPolicy, printLine) {
3509
3762
  }, null, 2));
3510
3763
  if (summary.exitCode === 1) {
3511
3764
  throw createCliCommandError2({
3512
- code: CLI_DIAGNOSTIC_CODES11.DOCTOR_CHECK_FAILED,
3765
+ code: CLI_DIAGNOSTIC_CODES13.DOCTOR_CHECK_FAILED,
3513
3766
  command: "doctor",
3514
3767
  detailLines: getDoctorExitFailureDetailLines(checks, { exitPolicy }),
3515
3768
  summary: "One or more doctor checks failed."
@@ -3531,9 +3784,15 @@ async function dispatchNodeFallbackDoctor({
3531
3784
 
3532
3785
  // src/node-fallback/dispatchers/add.ts
3533
3786
  import {
3534
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES12,
3787
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES14,
3535
3788
  createCliCommandError as createCliCommandError3
3536
3789
  } from "@wp-typia/project-tools/cli-diagnostics";
3790
+ function resolveNodeFallbackAddName(positionals) {
3791
+ if (positionals[1] === "core-variation" && positionals[3]) {
3792
+ return positionals[3];
3793
+ }
3794
+ return positionals[2];
3795
+ }
3537
3796
  async function dispatchNodeFallbackAdd({
3538
3797
  cwd,
3539
3798
  mergedFlags,
@@ -3547,11 +3806,14 @@ async function dispatchNodeFallbackAdd({
3547
3806
  printLine(formatAddHelpText());
3548
3807
  }
3549
3808
  throw createCliCommandError3({
3550
- code: CLI_DIAGNOSTIC_CODES12.MISSING_ARGUMENT,
3809
+ code: CLI_DIAGNOSTIC_CODES14.MISSING_ARGUMENT,
3551
3810
  command: "add",
3552
3811
  detailLines: buildMissingAddKindDetailLines()
3553
3812
  });
3554
3813
  }
3814
+ const kind = positionals[1];
3815
+ const name = resolveNodeFallbackAddName(positionals);
3816
+ const positionalArgs = positionals.slice(1);
3555
3817
  if (mergedFlags.format === "json") {
3556
3818
  let completion;
3557
3819
  try {
@@ -3560,8 +3822,9 @@ async function dispatchNodeFallbackAdd({
3560
3822
  emitOutput: false,
3561
3823
  flags: mergedFlags,
3562
3824
  interactive: false,
3563
- kind: positionals[1],
3564
- name: positionals[2],
3825
+ kind,
3826
+ name,
3827
+ positionalArgs,
3565
3828
  printLine,
3566
3829
  warnLine
3567
3830
  });
@@ -3573,8 +3836,8 @@ async function dispatchNodeFallbackAdd({
3573
3836
  }
3574
3837
  printLine(JSON.stringify(buildStructuredCompletionSuccessPayload("add", completion, {
3575
3838
  dryRun: Boolean(mergedFlags["dry-run"]),
3576
- kind: positionals[1],
3577
- name: positionals[2],
3839
+ kind,
3840
+ name,
3578
3841
  projectDir: extractCompletionProjectDir(completion) ?? cwd
3579
3842
  }), null, 2));
3580
3843
  return;
@@ -3583,8 +3846,9 @@ async function dispatchNodeFallbackAdd({
3583
3846
  cwd,
3584
3847
  flags: mergedFlags,
3585
3848
  interactive: undefined,
3586
- kind: positionals[1],
3587
- name: positionals[2],
3849
+ kind,
3850
+ name,
3851
+ positionalArgs,
3588
3852
  printLine,
3589
3853
  warnLine
3590
3854
  });
@@ -3592,7 +3856,7 @@ async function dispatchNodeFallbackAdd({
3592
3856
 
3593
3857
  // src/node-fallback/dispatchers/create.ts
3594
3858
  import {
3595
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES13,
3859
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES15,
3596
3860
  createCliCommandError as createCliCommandError4
3597
3861
  } from "@wp-typia/project-tools/cli-diagnostics";
3598
3862
  async function dispatchNodeFallbackCreate({
@@ -3605,7 +3869,7 @@ async function dispatchNodeFallbackCreate({
3605
3869
  const projectDir = positionals[1];
3606
3870
  if (!projectDir) {
3607
3871
  throw createCliCommandError4({
3608
- code: CLI_DIAGNOSTIC_CODES13.MISSING_ARGUMENT,
3872
+ code: CLI_DIAGNOSTIC_CODES15.MISSING_ARGUMENT,
3609
3873
  command: "create",
3610
3874
  detailLines: buildMissingCreateProjectDirDetailLines()
3611
3875
  });
@@ -3638,7 +3902,7 @@ async function dispatchNodeFallbackCreate({
3638
3902
 
3639
3903
  // src/node-fallback/errors.ts
3640
3904
  import {
3641
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES14,
3905
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES16,
3642
3906
  createCliCommandError as createCliCommandError6,
3643
3907
  formatCliDiagnosticError,
3644
3908
  isCliDiagnosticError,
@@ -3756,18 +4020,18 @@ var NODE_FALLBACK_HELP_RENDERERS = Object.fromEntries(Object.entries(NODE_FALLBA
3756
4020
  // src/node-fallback/errors.ts
3757
4021
  function createNodeFallbackNoCommandCliError() {
3758
4022
  return createCliCommandError6({
3759
- code: CLI_DIAGNOSTIC_CODES14.INVALID_COMMAND,
4023
+ code: CLI_DIAGNOSTIC_CODES16.INVALID_COMMAND,
3760
4024
  command: "wp-typia",
3761
4025
  detailLines: [NODE_FALLBACK_NO_COMMAND_REASON_LINE],
3762
4026
  summary: "No command was provided."
3763
4027
  });
3764
4028
  }
3765
4029
  function isNodeFallbackNoCommandCliDiagnostic(error) {
3766
- return isCliDiagnosticError(error) && error.code === CLI_DIAGNOSTIC_CODES14.INVALID_COMMAND && error.command === "wp-typia" && error.detailLines.includes(NODE_FALLBACK_NO_COMMAND_REASON_LINE);
4030
+ return isCliDiagnosticError(error) && error.code === CLI_DIAGNOSTIC_CODES16.INVALID_COMMAND && error.command === "wp-typia" && error.detailLines.includes(NODE_FALLBACK_NO_COMMAND_REASON_LINE);
3767
4031
  }
3768
4032
  function throwUnsupportedNodeFallbackCommand(command) {
3769
4033
  throw createCliCommandError6({
3770
- code: CLI_DIAGNOSTIC_CODES14.UNSUPPORTED_COMMAND,
4034
+ code: CLI_DIAGNOSTIC_CODES16.UNSUPPORTED_COMMAND,
3771
4035
  command,
3772
4036
  detailLines: [
3773
4037
  [
@@ -3803,7 +4067,7 @@ async function handleNodeFallbackEntrypointError(error, argv) {
3803
4067
 
3804
4068
  // src/node-fallback/templates.ts
3805
4069
  import {
3806
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES15,
4070
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES17,
3807
4071
  createCliCommandError as createCliCommandError7
3808
4072
  } from "@wp-typia/project-tools/cli-diagnostics";
3809
4073
  import {
@@ -3820,7 +4084,7 @@ function renderNodeFallbackTemplatesJson(printLine, flags, subcommand) {
3820
4084
  const templateId = flags.id;
3821
4085
  if (!templateId) {
3822
4086
  throw createCliCommandError7({
3823
- code: CLI_DIAGNOSTIC_CODES15.MISSING_ARGUMENT,
4087
+ code: CLI_DIAGNOSTIC_CODES17.MISSING_ARGUMENT,
3824
4088
  command: "templates",
3825
4089
  detailLines: ["`wp-typia templates inspect` requires <template-id>."]
3826
4090
  });
@@ -3828,7 +4092,7 @@ function renderNodeFallbackTemplatesJson(printLine, flags, subcommand) {
3828
4092
  const template = getTemplateById(templateId);
3829
4093
  if (!template) {
3830
4094
  throw createCliCommandError7({
3831
- code: CLI_DIAGNOSTIC_CODES15.INVALID_ARGUMENT,
4095
+ code: CLI_DIAGNOSTIC_CODES17.INVALID_ARGUMENT,
3832
4096
  command: "templates",
3833
4097
  detailLines: [`Unknown template "${templateId}".`]
3834
4098
  });
@@ -3847,7 +4111,7 @@ async function dispatchNodeFallbackTemplates({
3847
4111
  const resolvedSubcommand = subcommand ?? (templateId ? "inspect" : "list");
3848
4112
  if (resolvedSubcommand !== "list" && resolvedSubcommand !== "inspect") {
3849
4113
  throw createCliCommandError7({
3850
- code: CLI_DIAGNOSTIC_CODES15.INVALID_COMMAND,
4114
+ code: CLI_DIAGNOSTIC_CODES17.INVALID_COMMAND,
3851
4115
  command: "templates",
3852
4116
  detailLines: [
3853
4117
  `Unknown templates subcommand "${resolvedSubcommand}". Expected list or inspect.`
@@ -4105,4 +4369,4 @@ export {
4105
4369
  hasFlagBeforeTerminator
4106
4370
  };
4107
4371
 
4108
- //# debugId=7520561D7D1BD35A64756E2164756E21
4372
+ //# debugId=9C14F1C0B8D6AB4264756E2164756E21