wp-typia 0.22.7 → 0.22.9

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.
@@ -3,7 +3,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "wp-typia",
6
- version: "0.22.7",
6
+ version: "0.22.9",
7
7
  description: "Canonical CLI package for wp-typia scaffolding and project workflows",
8
8
  packageManager: "bun@1.3.11",
9
9
  type: "module",
@@ -73,7 +73,7 @@ var package_default = {
73
73
  "@bunli/tui": "0.6.0",
74
74
  "@bunli/utils": "0.6.0",
75
75
  "@wp-typia/api-client": "^0.4.5",
76
- "@wp-typia/project-tools": "0.22.7",
76
+ "@wp-typia/project-tools": "0.22.9",
77
77
  "better-result": "^2.7.0",
78
78
  react: "^19.2.5",
79
79
  "react-dom": "^19.2.5",
@@ -97,8 +97,8 @@ var package_default = {
97
97
 
98
98
  // src/node-cli.ts
99
99
  import {
100
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES8,
101
- createCliCommandError as createCliCommandError3,
100
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES12,
101
+ createCliCommandError as createCliCommandError5,
102
102
  formatCliDiagnosticError,
103
103
  serializeCliDiagnosticError as serializeCliDiagnosticError2
104
104
  } from "@wp-typia/project-tools/cli-diagnostics";
@@ -754,693 +754,14 @@ import {
754
754
  listTemplates
755
755
  } from "@wp-typia/project-tools/cli-templates";
756
756
 
757
- // src/add-kind-registry.ts
758
- import {
759
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES4,
760
- createCliDiagnosticCodeError as createCliDiagnosticCodeError3
761
- } from "@wp-typia/project-tools/cli-diagnostics";
762
-
763
- // src/add-kind-ids.ts
764
- import { ADD_KIND_IDS } from "@wp-typia/project-tools/cli-add-kind-ids";
765
-
766
- // src/cli-string-flags.ts
767
- import {
768
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES3,
769
- createCliDiagnosticCodeError as createCliDiagnosticCodeError2
770
- } from "@wp-typia/project-tools/cli-diagnostics";
771
- function readOptionalCliStringFlagValue(flags, name, mode) {
772
- const value = flags[name];
773
- if (value === undefined || value === null) {
774
- return;
775
- }
776
- if (typeof value !== "string") {
777
- throw createCliDiagnosticCodeError2(CLI_DIAGNOSTIC_CODES3.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
778
- }
779
- const trimmed = value.trim();
780
- if (trimmed.length === 0) {
781
- if (mode === "strict") {
782
- throw createCliDiagnosticCodeError2(CLI_DIAGNOSTIC_CODES3.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
783
- }
784
- return;
785
- }
786
- return mode === "strict" ? value : trimmed;
787
- }
788
- function readOptionalLooseStringFlag(flags, name) {
789
- return readOptionalCliStringFlagValue(flags, name, "loose");
790
- }
791
- function readOptionalStrictStringFlag(flags, name) {
792
- return readOptionalCliStringFlagValue(flags, name, "strict");
793
- }
794
- function requireStrictStringFlag(flags, name, message) {
795
- const value = readOptionalStrictStringFlag(flags, name);
796
- if (!value) {
797
- throw createCliDiagnosticCodeError2(CLI_DIAGNOSTIC_CODES3.MISSING_ARGUMENT, message);
798
- }
799
- return value;
800
- }
801
- function readOptionalPairedStrictStringFlags(flags, leftName, rightName, message) {
802
- const leftValue = readOptionalStrictStringFlag(flags, leftName);
803
- const rightValue = readOptionalStrictStringFlag(flags, rightName);
804
- if (Boolean(leftValue) !== Boolean(rightValue)) {
805
- throw createCliDiagnosticCodeError2(CLI_DIAGNOSTIC_CODES3.MISSING_ARGUMENT, message);
806
- }
807
- return [leftValue, rightValue];
808
- }
809
-
810
- // src/external-layer-prompt-options.ts
811
- function formatExternalLayerSelectHint(option) {
812
- const details = [
813
- option.description,
814
- option.extends.length > 0 ? `extends ${option.extends.join(", ")}` : undefined
815
- ].filter((value) => typeof value === "string" && value.length > 0);
816
- return details.length > 0 ? details.join(" · ") : undefined;
817
- }
818
- function toExternalLayerPromptOptions(options) {
819
- return options.map((option) => ({
820
- hint: formatExternalLayerSelectHint(option),
821
- label: option.id,
822
- value: option.id
823
- }));
824
- }
825
-
826
- // src/add-kind-registry.ts
827
- var BLOCK_VISIBLE_FIELD_ORDER = [
828
- "kind",
829
- "name",
830
- "template",
831
- "alternate-render-targets",
832
- "inner-blocks-preset",
833
- "data-storage",
834
- "persistence-policy"
835
- ];
836
- var NAME_ONLY_VISIBLE_FIELDS = [
837
- "kind",
838
- "name"
839
- ];
840
- var NAME_SOURCE_VISIBLE_FIELDS = [
841
- "kind",
842
- "name",
843
- "source"
844
- ];
845
- var NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS = [
846
- "kind",
847
- "name",
848
- "block",
849
- "attribute"
850
- ];
851
- var NAME_BLOCK_VISIBLE_FIELDS = [
852
- "kind",
853
- "name",
854
- "block"
855
- ];
856
- var NAME_SLOT_VISIBLE_FIELDS = [
857
- "kind",
858
- "name",
859
- "slot"
860
- ];
861
- var NAME_ANCHOR_POSITION_VISIBLE_FIELDS = [
862
- "kind",
863
- "name",
864
- "anchor",
865
- "position"
866
- ];
867
- var NAME_FROM_TO_VISIBLE_FIELDS = [
868
- "kind",
869
- "name",
870
- "from",
871
- "to"
872
- ];
873
- var NAME_NAMESPACE_METHODS_VISIBLE_FIELDS = [
874
- "kind",
875
- "name",
876
- "namespace",
877
- "methods"
878
- ];
879
- var NAME_NAMESPACE_VISIBLE_FIELDS = [
880
- "kind",
881
- "name",
882
- "namespace"
883
- ];
884
- function requireAddKindName(context, message) {
885
- if (!context.name) {
886
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, message);
887
- }
888
- return context.name;
889
- }
890
- function defineAddKindRegistryEntry(entry) {
891
- return entry;
892
- }
893
- function createNamedExecutionPlan(context, options) {
894
- const name = options.name ?? requireAddKindName(context, options.missingNameMessage);
895
- return {
896
- execute: (cwd) => options.execute({ cwd, name }),
897
- getValues: options.getValues,
898
- ...options.getWarnings ? { getWarnings: options.getWarnings } : {},
899
- ...options.warnLine ? { warnLine: options.warnLine } : {}
900
- };
901
- }
902
- function isAddPersistenceTemplate(template) {
903
- return template === "persistence" || template === "compound";
904
- }
905
- function formatAddBlockTemplateIds(addRuntime) {
906
- return addRuntime.ADD_BLOCK_TEMPLATE_IDS.join(", ");
907
- }
908
- function assertAddBlockTemplateId(context, templateId) {
909
- if (context.addRuntime.isAddBlockTemplateId(templateId)) {
910
- return templateId;
911
- }
912
- if (templateId === "query-loop") {
913
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.INVALID_ARGUMENT, "`wp-typia add block --template query-loop` is not supported. Query Loop is a create-time `core/query` variation scaffold, so use `wp-typia create <project-dir> --template query-loop` instead.");
914
- }
915
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.UNKNOWN_TEMPLATE, `Unknown add-block template "${templateId}". Expected one of: ${formatAddBlockTemplateIds(context.addRuntime)}. Run \`wp-typia templates list\` to inspect available templates.`);
916
- }
917
- var ADD_KIND_REGISTRY = {
918
- "admin-view": defineAddKindRegistryEntry({
919
- completion: {
920
- nextSteps: (values) => [
921
- `Review src/admin-views/${values.adminViewSlug}/ and inc/admin-views/${values.adminViewSlug}.php.`,
922
- "Run your workspace build or dev command to verify the generated DataViews admin screen."
923
- ],
924
- summaryLines: (values, projectDir) => [
925
- `Admin view: ${values.adminViewSlug}`,
926
- ...values.source ? [`Source: ${values.source}`] : [],
927
- `Project directory: ${projectDir}`
928
- ],
929
- title: "Added DataViews admin screen"
930
- },
931
- description: "Add an opt-in DataViews-powered admin screen",
932
- nameLabel: "Admin view name",
933
- async prepareExecution(context) {
934
- const name = requireAddKindName(context, "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].");
935
- const source = readOptionalStrictStringFlag(context.flags, "source");
936
- return createNamedExecutionPlan(context, {
937
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAdminViewCommand({
938
- adminViewName: name2,
939
- cwd,
940
- source
941
- }),
942
- getValues: (result) => ({
943
- adminViewSlug: result.adminViewSlug,
944
- ...result.source ? { source: result.source } : {}
945
- }),
946
- missingNameMessage: "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].",
947
- name
948
- });
949
- },
950
- sortOrder: 10,
951
- supportsDryRun: true,
952
- usage: "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]",
953
- visibleFieldNames: () => NAME_SOURCE_VISIBLE_FIELDS
954
- }),
955
- "binding-source": defineAddKindRegistryEntry({
956
- completion: {
957
- nextSteps: (values) => [
958
- `Review src/bindings/${values.bindingSourceSlug}/server.php and src/bindings/${values.bindingSourceSlug}/editor.ts.`,
959
- ...values.blockSlug && values.attributeName ? [
960
- `Review src/blocks/${values.blockSlug}/block.json for the ${values.attributeName} bindable attribute.`
961
- ] : [],
962
- "Run your workspace build or dev command to verify the binding source hooks and editor registration."
963
- ],
964
- summaryLines: (values, projectDir) => [
965
- `Binding source: ${values.bindingSourceSlug}`,
966
- ...values.blockSlug && values.attributeName ? [`Target: ${values.blockSlug}.${values.attributeName}`] : [],
967
- `Project directory: ${projectDir}`
968
- ],
969
- title: "Added binding source"
970
- },
971
- description: "Add a shared block bindings source",
972
- nameLabel: "Binding source name",
973
- async prepareExecution(context) {
974
- const name = requireAddKindName(context, "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].");
975
- const [blockName, attributeName] = readOptionalPairedStrictStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
976
- return createNamedExecutionPlan(context, {
977
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBindingSourceCommand({
978
- attributeName,
979
- bindingSourceName: name2,
980
- blockName,
981
- cwd
982
- }),
983
- getValues: (result) => ({
984
- ...result.attributeName ? { attributeName: result.attributeName } : {},
985
- ...result.blockSlug ? { blockSlug: result.blockSlug } : {},
986
- bindingSourceSlug: result.bindingSourceSlug
987
- }),
988
- missingNameMessage: "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].",
989
- name
990
- });
991
- },
992
- sortOrder: 70,
993
- supportsDryRun: true,
994
- usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]",
995
- visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS
996
- }),
997
- block: defineAddKindRegistryEntry({
998
- completion: {
999
- nextSteps: () => [
1000
- "Review the generated sources under src/blocks/ and the updated scripts/block-config.ts entry.",
1001
- "Run your workspace build or dev command to verify the new scaffolded block family."
1002
- ],
1003
- summaryLines: (values, projectDir) => [
1004
- `Blocks: ${values.blockSlugs}`,
1005
- `Template family: ${values.templateId}`,
1006
- `Project directory: ${projectDir}`
1007
- ],
1008
- title: "Added workspace block"
1009
- },
1010
- description: "Add a real block slice",
1011
- hiddenStringSubmitFields: ["external-layer-id", "external-layer-source"],
1012
- nameLabel: "Block name",
1013
- async prepareExecution(context) {
1014
- const name = requireAddKindName(context, "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]");
1015
- const externalLayerId = readOptionalStrictStringFlag(context.flags, "external-layer-id");
1016
- const externalLayerSource = readOptionalStrictStringFlag(context.flags, "external-layer-source");
1017
- const shouldPromptForLayerSelection = Boolean(externalLayerSource) && !Boolean(externalLayerId) && context.isInteractiveSession;
1018
- const selectPrompt = shouldPromptForLayerSelection ? await context.getOrCreatePrompt() : undefined;
1019
- const alternateRenderTargets = readOptionalStrictStringFlag(context.flags, "alternate-render-targets");
1020
- const dataStorageMode = readOptionalStrictStringFlag(context.flags, "data-storage");
1021
- const innerBlocksPreset = readOptionalStrictStringFlag(context.flags, "inner-blocks-preset");
1022
- const persistencePolicy = readOptionalStrictStringFlag(context.flags, "persistence-policy");
1023
- const requestedTemplateId = readOptionalStrictStringFlag(context.flags, "template");
1024
- let resolvedTemplateId = requestedTemplateId ? assertAddBlockTemplateId(context, requestedTemplateId) : undefined;
1025
- if (!resolvedTemplateId && context.isInteractiveSession) {
1026
- const templatePrompt = await context.getOrCreatePrompt();
1027
- resolvedTemplateId = await templatePrompt.select("Select a block template", context.addRuntime.ADD_BLOCK_TEMPLATE_IDS.map((templateId) => ({
1028
- hint: `Scaffold the ${templateId} block family`,
1029
- label: templateId,
1030
- value: templateId
1031
- })), 1);
1032
- }
1033
- resolvedTemplateId ??= "basic";
1034
- return createNamedExecutionPlan(context, {
1035
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockCommand({
1036
- alternateRenderTargets,
1037
- blockName: name2,
1038
- cwd,
1039
- dataStorageMode,
1040
- externalLayerId,
1041
- externalLayerSource,
1042
- innerBlocksPreset,
1043
- persistencePolicy,
1044
- selectExternalLayerId: selectPrompt ? (options) => selectPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
1045
- templateId: resolvedTemplateId
1046
- }),
1047
- getValues: (result) => ({
1048
- blockSlugs: result.blockSlugs.join(", "),
1049
- templateId: result.templateId
1050
- }),
1051
- getWarnings: (result) => result.warnings,
1052
- missingNameMessage: "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]",
1053
- name,
1054
- warnLine: context.warnLine
1055
- });
1056
- },
1057
- sortOrder: 20,
1058
- supportsDryRun: true,
1059
- usage: "wp-typia add block <name> [--template <basic|interactivity|persistence|compound>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]",
1060
- visibleFieldNames: ({ template }) => BLOCK_VISIBLE_FIELD_ORDER.filter((fieldName) => {
1061
- if (fieldName === "alternate-render-targets") {
1062
- return isAddPersistenceTemplate(template);
1063
- }
1064
- if (fieldName === "inner-blocks-preset") {
1065
- return template === "compound";
1066
- }
1067
- if (fieldName === "data-storage" || fieldName === "persistence-policy") {
1068
- return isAddPersistenceTemplate(template);
1069
- }
1070
- return true;
1071
- })
1072
- }),
1073
- ability: defineAddKindRegistryEntry({
1074
- completion: {
1075
- nextSteps: (values) => [
1076
- `Review src/abilities/${values.abilitySlug}/ and inc/abilities/${values.abilitySlug}.php.`,
1077
- "Run `wp-typia sync` or `npm run sync-abilities -- --check` and then your workspace build/dev command to verify the generated workflow ability."
1078
- ],
1079
- summaryLines: (values, projectDir) => [
1080
- `Ability: ${values.abilitySlug}`,
1081
- `Project directory: ${projectDir}`
1082
- ],
1083
- title: "Added workflow ability"
1084
- },
1085
- description: "Add a typed server/client workflow ability scaffold",
1086
- nameLabel: "Ability name",
1087
- async prepareExecution(context) {
1088
- return createNamedExecutionPlan(context, {
1089
- execute: ({ cwd, name }) => context.addRuntime.runAddAbilityCommand({
1090
- abilityName: name,
1091
- cwd
1092
- }),
1093
- getValues: (result) => ({
1094
- abilitySlug: result.abilitySlug
1095
- }),
1096
- getWarnings: (result) => result.warnings,
1097
- missingNameMessage: "`wp-typia add ability` requires <name>. Usage: wp-typia add ability <name>.",
1098
- warnLine: context.warnLine
1099
- });
1100
- },
1101
- sortOrder: 90,
1102
- supportsDryRun: true,
1103
- usage: "wp-typia add ability <name> [--dry-run]",
1104
- visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1105
- }),
1106
- "editor-plugin": defineAddKindRegistryEntry({
1107
- completion: {
1108
- nextSteps: (values) => [
1109
- `Review src/editor-plugins/${values.editorPluginSlug}/.`,
1110
- "Run your workspace build or dev command to verify the new editor plugin registration."
1111
- ],
1112
- summaryLines: (values, projectDir) => [
1113
- `Editor plugin: ${values.editorPluginSlug}`,
1114
- `Slot: ${values.slot}`,
1115
- `Project directory: ${projectDir}`
1116
- ],
1117
- title: "Added editor plugin"
1118
- },
1119
- description: "Add a slot-aware document editor extension shell",
1120
- nameLabel: "Editor plugin name",
1121
- async prepareExecution(context) {
1122
- const name = requireAddKindName(context, "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].");
1123
- const slot = readOptionalStrictStringFlag(context.flags, "slot");
1124
- return createNamedExecutionPlan(context, {
1125
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddEditorPluginCommand({
1126
- cwd,
1127
- editorPluginName: name2,
1128
- slot
1129
- }),
1130
- getValues: (result) => ({
1131
- editorPluginSlug: result.editorPluginSlug,
1132
- slot: result.slot
1133
- }),
1134
- missingNameMessage: "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].",
1135
- name
1136
- });
1137
- },
1138
- sortOrder: 120,
1139
- supportsDryRun: true,
1140
- usage: "wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>] [--dry-run]",
1141
- visibleFieldNames: () => NAME_SLOT_VISIBLE_FIELDS
1142
- }),
1143
- "hooked-block": defineAddKindRegistryEntry({
1144
- completion: {
1145
- nextSteps: (values) => [
1146
- `Review src/blocks/${values.blockSlug}/block.json for the new blockHooks entry.`,
1147
- "Run your workspace build or dev command to verify the updated hooked-block metadata."
1148
- ],
1149
- summaryLines: (values, projectDir) => [
1150
- `Block: ${values.blockSlug}`,
1151
- `Anchor: ${values.anchorBlockName}`,
1152
- `Position: ${values.position}`,
1153
- `Project directory: ${projectDir}`
1154
- ],
1155
- title: "Added blockHooks metadata"
1156
- },
1157
- description: "Add block.json hook metadata to an existing block",
1158
- nameLabel: "Target block",
1159
- async prepareExecution(context) {
1160
- const name = requireAddKindName(context, "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.");
1161
- const anchorBlockName = requireStrictStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
1162
- const position = requireStrictStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
1163
- return createNamedExecutionPlan(context, {
1164
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddHookedBlockCommand({
1165
- anchorBlockName,
1166
- blockName: name2,
1167
- cwd,
1168
- position
1169
- }),
1170
- getValues: (result) => ({
1171
- anchorBlockName: result.anchorBlockName,
1172
- blockSlug: result.blockSlug,
1173
- position: result.position
1174
- }),
1175
- missingNameMessage: "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.",
1176
- name
1177
- });
1178
- },
1179
- sortOrder: 110,
1180
- supportsDryRun: true,
1181
- usage: "wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild> [--dry-run]",
1182
- visibleFieldNames: () => NAME_ANCHOR_POSITION_VISIBLE_FIELDS
1183
- }),
1184
- pattern: defineAddKindRegistryEntry({
1185
- completion: {
1186
- nextSteps: (values) => [
1187
- `Review src/patterns/${values.patternSlug}.php.`,
1188
- "Run your workspace build or dev command to verify the new pattern registration."
1189
- ],
1190
- summaryLines: (values, projectDir) => [
1191
- `Pattern: ${values.patternSlug}`,
1192
- `Project directory: ${projectDir}`
1193
- ],
1194
- title: "Added workspace pattern"
1195
- },
1196
- description: "Add a PHP block pattern shell",
1197
- nameLabel: "Pattern name",
1198
- async prepareExecution(context) {
1199
- return createNamedExecutionPlan(context, {
1200
- execute: ({ cwd, name }) => context.addRuntime.runAddPatternCommand({
1201
- cwd,
1202
- patternName: name
1203
- }),
1204
- getValues: (result) => ({
1205
- patternSlug: result.patternSlug
1206
- }),
1207
- missingNameMessage: "`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>."
1208
- });
1209
- },
1210
- sortOrder: 60,
1211
- supportsDryRun: true,
1212
- usage: "wp-typia add pattern <name> [--dry-run]",
1213
- visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1214
- }),
1215
- style: defineAddKindRegistryEntry({
1216
- completion: {
1217
- nextSteps: (values) => [
1218
- `Review src/blocks/${values.blockSlug}/styles/${values.styleSlug}.ts.`,
1219
- "Run your workspace build or dev command to verify the new block style registration."
1220
- ],
1221
- summaryLines: (values, projectDir) => [
1222
- `Block style: ${values.styleSlug}`,
1223
- `Target block: ${values.blockSlug}`,
1224
- `Project directory: ${projectDir}`
1225
- ],
1226
- title: "Added block style"
1227
- },
1228
- description: "Add a Block Styles registration to an existing block",
1229
- nameLabel: "Style name",
1230
- async prepareExecution(context) {
1231
- const name = requireAddKindName(context, "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.");
1232
- const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
1233
- return createNamedExecutionPlan(context, {
1234
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockStyleCommand({
1235
- blockName: blockSlug,
1236
- cwd,
1237
- styleName: name2
1238
- }),
1239
- getValues: (result) => ({
1240
- blockSlug: result.blockSlug,
1241
- styleSlug: result.styleSlug
1242
- }),
1243
- missingNameMessage: "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.",
1244
- name
1245
- });
1246
- },
1247
- sortOrder: 40,
1248
- supportsDryRun: true,
1249
- usage: "wp-typia add style <name> --block <block-slug> [--dry-run]",
1250
- visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
1251
- }),
1252
- transform: defineAddKindRegistryEntry({
1253
- completion: {
1254
- nextSteps: (values) => [
1255
- `Review src/blocks/${values.blockSlug}/transforms/${values.transformSlug}.ts.`,
1256
- "Run your workspace build or dev command to verify the new block transform registration."
1257
- ],
1258
- summaryLines: (values, projectDir) => [
1259
- `Block transform: ${values.transformSlug}`,
1260
- `From: ${values.fromBlockName}`,
1261
- `To: ${values.toBlockName}`,
1262
- `Project directory: ${projectDir}`
1263
- ],
1264
- title: "Added block transform"
1265
- },
1266
- description: "Add a block-to-block transform into a workspace block",
1267
- nameLabel: "Transform name",
1268
- async prepareExecution(context) {
1269
- const name = requireAddKindName(context, "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.");
1270
- const fromBlockName = requireStrictStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
1271
- const toBlockName = requireStrictStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
1272
- return createNamedExecutionPlan(context, {
1273
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockTransformCommand({
1274
- cwd,
1275
- fromBlockName,
1276
- toBlockName,
1277
- transformName: name2
1278
- }),
1279
- getValues: (result) => ({
1280
- blockSlug: result.blockSlug,
1281
- fromBlockName: result.fromBlockName,
1282
- toBlockName: result.toBlockName,
1283
- transformSlug: result.transformSlug
1284
- }),
1285
- missingNameMessage: "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.",
1286
- name
1287
- });
1288
- },
1289
- sortOrder: 50,
1290
- supportsDryRun: true,
1291
- usage: "wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]",
1292
- visibleFieldNames: () => NAME_FROM_TO_VISIBLE_FIELDS
1293
- }),
1294
- "rest-resource": defineAddKindRegistryEntry({
1295
- completion: {
1296
- nextSteps: (values) => [
1297
- `Review src/rest/${values.restResourceSlug}/ and inc/rest/${values.restResourceSlug}.php.`,
1298
- "Run your workspace build or dev command to verify the generated REST resource contract."
1299
- ],
1300
- summaryLines: (values, projectDir) => [
1301
- `REST resource: ${values.restResourceSlug}`,
1302
- `Namespace: ${values.namespace}`,
1303
- `Methods: ${values.methods}`,
1304
- `Project directory: ${projectDir}`
1305
- ],
1306
- title: "Added plugin-level REST resource"
1307
- },
1308
- description: "Add a plugin-level typed REST resource",
1309
- nameLabel: "REST resource name",
1310
- async prepareExecution(context) {
1311
- const name = requireAddKindName(context, "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].");
1312
- const methods = readOptionalStrictStringFlag(context.flags, "methods");
1313
- const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
1314
- return createNamedExecutionPlan(context, {
1315
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddRestResourceCommand({
1316
- cwd,
1317
- methods,
1318
- namespace,
1319
- restResourceName: name2
1320
- }),
1321
- getValues: (result) => ({
1322
- methods: result.methods.join(", "),
1323
- namespace: result.namespace,
1324
- restResourceSlug: result.restResourceSlug
1325
- }),
1326
- missingNameMessage: "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].",
1327
- name
1328
- });
1329
- },
1330
- sortOrder: 80,
1331
- supportsDryRun: true,
1332
- usage: "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]",
1333
- visibleFieldNames: () => NAME_NAMESPACE_METHODS_VISIBLE_FIELDS
1334
- }),
1335
- "ai-feature": defineAddKindRegistryEntry({
1336
- completion: {
1337
- nextSteps: (values) => [
1338
- `Review src/ai-features/${values.aiFeatureSlug}/ and inc/ai-features/${values.aiFeatureSlug}.php.`,
1339
- "Run `wp-typia sync-rest` and `wp-typia sync ai` or your workspace build/dev command to verify the generated REST artifacts and AI schema."
1340
- ],
1341
- summaryLines: (values, projectDir) => [
1342
- `AI feature: ${values.aiFeatureSlug}`,
1343
- `Namespace: ${values.namespace}`,
1344
- `Project directory: ${projectDir}`
1345
- ],
1346
- title: "Added server-only AI feature"
1347
- },
1348
- description: "Add a server-owned WordPress AI feature endpoint",
1349
- nameLabel: "AI feature name",
1350
- async prepareExecution(context) {
1351
- const name = requireAddKindName(context, "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].");
1352
- const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
1353
- return createNamedExecutionPlan(context, {
1354
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAiFeatureCommand({
1355
- aiFeatureName: name2,
1356
- cwd,
1357
- namespace
1358
- }),
1359
- getValues: (result) => ({
1360
- aiFeatureSlug: result.aiFeatureSlug,
1361
- namespace: result.namespace
1362
- }),
1363
- getWarnings: (result) => result.warnings,
1364
- missingNameMessage: "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].",
1365
- name,
1366
- warnLine: context.warnLine
1367
- });
1368
- },
1369
- sortOrder: 100,
1370
- supportsDryRun: true,
1371
- usage: "wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]",
1372
- visibleFieldNames: () => NAME_NAMESPACE_VISIBLE_FIELDS
1373
- }),
1374
- variation: defineAddKindRegistryEntry({
1375
- completion: {
1376
- nextSteps: (values) => [
1377
- `Review src/blocks/${values.blockSlug}/variations/${values.variationSlug}.ts.`,
1378
- "Run your workspace build or dev command to pick up the new variation."
1379
- ],
1380
- summaryLines: (values, projectDir) => [
1381
- `Variation: ${values.variationSlug}`,
1382
- `Target block: ${values.blockSlug}`,
1383
- `Project directory: ${projectDir}`
1384
- ],
1385
- title: "Added workspace variation"
1386
- },
1387
- description: "Add a variation to an existing block",
1388
- nameLabel: "Variation name",
1389
- async prepareExecution(context) {
1390
- const name = requireAddKindName(context, "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
1391
- const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
1392
- return createNamedExecutionPlan(context, {
1393
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddVariationCommand({
1394
- blockName: blockSlug,
1395
- cwd,
1396
- variationName: name2
1397
- }),
1398
- getValues: (result) => ({
1399
- blockSlug: result.blockSlug,
1400
- variationSlug: result.variationSlug
1401
- }),
1402
- missingNameMessage: "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>",
1403
- name
1404
- });
1405
- },
1406
- sortOrder: 30,
1407
- supportsDryRun: true,
1408
- usage: "wp-typia add variation <name> --block <block-slug> [--dry-run]",
1409
- visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
1410
- })
1411
- };
1412
- function isAddKindId(value) {
1413
- return typeof value === "string" && ADD_KIND_IDS.includes(value);
1414
- }
1415
- async function getAddKindExecutionPlan(kind, context) {
1416
- return ADD_KIND_REGISTRY[kind].prepareExecution(context);
1417
- }
1418
- function buildAddKindCompletionDetails(kind, options) {
1419
- const descriptor = ADD_KIND_REGISTRY[kind].completion;
1420
- return {
1421
- nextSteps: descriptor.nextSteps(options.values),
1422
- summaryLines: descriptor.summaryLines(options.values, options.projectDir),
1423
- title: descriptor.title
1424
- };
1425
- }
1426
- function formatAddKindList() {
1427
- return ADD_KIND_IDS.join(", ");
1428
- }
1429
- function formatAddKindUsagePlaceholder() {
1430
- return `<${ADD_KIND_IDS.join("|")}>`;
1431
- }
1432
- function supportsAddKindDryRun(kind) {
1433
- return ADD_KIND_REGISTRY[kind].supportsDryRun;
1434
- }
1435
-
1436
757
  // src/config.ts
1437
758
  import fs from "node:fs/promises";
1438
759
  import os from "node:os";
1439
760
  import path from "node:path";
1440
761
  import { isPlainObject as isRecord } from "@wp-typia/api-client/runtime-primitives";
1441
762
  import {
1442
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES5,
1443
- createCliDiagnosticCodeError as createCliDiagnosticCodeError4
763
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES3,
764
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError2
1444
765
  } from "@wp-typia/project-tools/cli-diagnostics";
1445
766
  import { z as z2 } from "zod";
1446
767
  var WP_TYPIA_CONFIG_SOURCES = [
@@ -1514,7 +835,7 @@ function validateWpTypiaUserConfig(value, source) {
1514
835
  return result.data;
1515
836
  }
1516
837
  const issueLines = result.error.issues.map(formatConfigValidationIssue);
1517
- throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.INVALID_ARGUMENT, [
838
+ throw createCliDiagnosticCodeError2(CLI_DIAGNOSTIC_CODES3.INVALID_ARGUMENT, [
1518
839
  `Invalid wp-typia config at ${source}.`,
1519
840
  ...issueLines.map((line) => `- ${line}`)
1520
841
  ].join(`
@@ -1549,7 +870,7 @@ async function readJsonFile(filePath) {
1549
870
  return JSON.parse(source);
1550
871
  } catch (error) {
1551
872
  const message = error instanceof Error ? error.message : String(error);
1552
- throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.INVALID_ARGUMENT, `Unable to parse ${filePath}: ${message}`, error instanceof Error ? { cause: error } : undefined);
873
+ throw createCliDiagnosticCodeError2(CLI_DIAGNOSTIC_CODES3.INVALID_ARGUMENT, `Unable to parse ${filePath}: ${message}`, error instanceof Error ? { cause: error } : undefined);
1553
874
  }
1554
875
  }
1555
876
  async function readWpTypiaConfigFile(filePath) {
@@ -1606,12 +927,759 @@ function extractWpTypiaConfigOverride(argv) {
1606
927
  };
1607
928
  }
1608
929
 
1609
- // src/runtime-bridge.ts
1610
- import {
1611
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES7,
1612
- createCliDiagnosticCodeError as createCliDiagnosticCodeError6
1613
- } from "@wp-typia/project-tools/cli-diagnostics";
1614
-
930
+ // src/runtime-bridge.ts
931
+ import {
932
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES8,
933
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError7
934
+ } from "@wp-typia/project-tools/cli-diagnostics";
935
+
936
+ // src/add-kind-ids.ts
937
+ import { ADD_KIND_IDS } from "@wp-typia/project-tools/cli-add-kind-ids";
938
+
939
+ // src/add-kind-registry-shared.ts
940
+ import {
941
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES4,
942
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError3
943
+ } from "@wp-typia/project-tools/cli-diagnostics";
944
+ var BLOCK_VISIBLE_FIELD_ORDER = [
945
+ "kind",
946
+ "name",
947
+ "template",
948
+ "alternate-render-targets",
949
+ "inner-blocks-preset",
950
+ "data-storage",
951
+ "persistence-policy"
952
+ ];
953
+ var NAME_ONLY_VISIBLE_FIELDS = [
954
+ "kind",
955
+ "name"
956
+ ];
957
+ var NAME_SOURCE_VISIBLE_FIELDS = [
958
+ "kind",
959
+ "name",
960
+ "source"
961
+ ];
962
+ var NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS = [
963
+ "kind",
964
+ "name",
965
+ "block",
966
+ "attribute"
967
+ ];
968
+ var NAME_BLOCK_VISIBLE_FIELDS = [
969
+ "kind",
970
+ "name",
971
+ "block"
972
+ ];
973
+ var NAME_SLOT_VISIBLE_FIELDS = [
974
+ "kind",
975
+ "name",
976
+ "slot"
977
+ ];
978
+ var NAME_ANCHOR_POSITION_VISIBLE_FIELDS = [
979
+ "kind",
980
+ "name",
981
+ "anchor",
982
+ "position"
983
+ ];
984
+ var NAME_FROM_TO_VISIBLE_FIELDS = [
985
+ "kind",
986
+ "name",
987
+ "from",
988
+ "to"
989
+ ];
990
+ var NAME_NAMESPACE_METHODS_VISIBLE_FIELDS = [
991
+ "kind",
992
+ "name",
993
+ "namespace",
994
+ "methods"
995
+ ];
996
+ var NAME_NAMESPACE_VISIBLE_FIELDS = [
997
+ "kind",
998
+ "name",
999
+ "namespace"
1000
+ ];
1001
+ function requireAddKindName(context, message) {
1002
+ if (!context.name) {
1003
+ throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, message);
1004
+ }
1005
+ return context.name;
1006
+ }
1007
+ function defineAddKindRegistryEntry(entry) {
1008
+ return entry;
1009
+ }
1010
+ function createNamedExecutionPlan(context, options) {
1011
+ const name = options.name ?? requireAddKindName(context, options.missingNameMessage);
1012
+ return {
1013
+ execute: (cwd) => options.execute({ cwd, name }),
1014
+ getValues: options.getValues,
1015
+ ...options.getWarnings ? { getWarnings: options.getWarnings } : {},
1016
+ ...options.warnLine ? { warnLine: options.warnLine } : {}
1017
+ };
1018
+ }
1019
+ function isAddPersistenceTemplate(template) {
1020
+ return template === "persistence" || template === "compound";
1021
+ }
1022
+ function formatAddBlockTemplateIds(addRuntime) {
1023
+ return addRuntime.ADD_BLOCK_TEMPLATE_IDS.join(", ");
1024
+ }
1025
+ function getMistypedAddBlockTemplateMessage(addRuntime, templateId) {
1026
+ const suggestion = addRuntime.suggestAddBlockTemplateId(templateId);
1027
+ if (!suggestion) {
1028
+ return null;
1029
+ }
1030
+ return `Unknown add-block template "${templateId}". Did you mean "${suggestion}"? Use \`--template ${suggestion}\`, or run \`wp-typia templates list\` to inspect available templates.`;
1031
+ }
1032
+ function assertAddBlockTemplateId(context, templateId) {
1033
+ if (templateId === "query-loop") {
1034
+ throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.INVALID_ARGUMENT, "`wp-typia add block --template query-loop` is not supported. Query Loop is a create-time `core/query` variation scaffold, so use `wp-typia create <project-dir> --template query-loop` instead.");
1035
+ }
1036
+ if (context.addRuntime.isAddBlockTemplateId(templateId)) {
1037
+ return templateId;
1038
+ }
1039
+ const mistypedAddBlockTemplateMessage = getMistypedAddBlockTemplateMessage(context.addRuntime, templateId);
1040
+ if (mistypedAddBlockTemplateMessage) {
1041
+ throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.UNKNOWN_TEMPLATE, mistypedAddBlockTemplateMessage);
1042
+ }
1043
+ throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.UNKNOWN_TEMPLATE, `Unknown add-block template "${templateId}". Expected one of: ${formatAddBlockTemplateIds(context.addRuntime)}. Run \`wp-typia templates list\` to inspect available templates.`);
1044
+ }
1045
+
1046
+ // src/add-kinds/ability.ts
1047
+ var abilityAddKindEntry = defineAddKindRegistryEntry({
1048
+ completion: {
1049
+ nextSteps: (values) => [
1050
+ `Review src/abilities/${values.abilitySlug}/ and inc/abilities/${values.abilitySlug}.php.`,
1051
+ "Run `wp-typia sync` or `npm run sync-abilities -- --check` and then your workspace build/dev command to verify the generated workflow ability."
1052
+ ],
1053
+ summaryLines: (values, projectDir) => [
1054
+ `Ability: ${values.abilitySlug}`,
1055
+ `Project directory: ${projectDir}`
1056
+ ],
1057
+ title: "Added workflow ability"
1058
+ },
1059
+ description: "Add a typed server/client workflow ability scaffold",
1060
+ nameLabel: "Ability name",
1061
+ async prepareExecution(context) {
1062
+ return createNamedExecutionPlan(context, {
1063
+ execute: ({ cwd, name }) => context.addRuntime.runAddAbilityCommand({
1064
+ abilityName: name,
1065
+ cwd
1066
+ }),
1067
+ getValues: (result) => ({
1068
+ abilitySlug: result.abilitySlug
1069
+ }),
1070
+ getWarnings: (result) => result.warnings,
1071
+ missingNameMessage: "`wp-typia add ability` requires <name>. Usage: wp-typia add ability <name>.",
1072
+ warnLine: context.warnLine
1073
+ });
1074
+ },
1075
+ sortOrder: 90,
1076
+ supportsDryRun: true,
1077
+ usage: "wp-typia add ability <name> [--dry-run]",
1078
+ visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1079
+ });
1080
+
1081
+ // src/cli-string-flags.ts
1082
+ import {
1083
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES5,
1084
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError4
1085
+ } from "@wp-typia/project-tools/cli-diagnostics";
1086
+ function readOptionalCliStringFlagValue(flags, name, mode) {
1087
+ const value = flags[name];
1088
+ if (value === undefined || value === null) {
1089
+ return;
1090
+ }
1091
+ if (typeof value !== "string") {
1092
+ throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
1093
+ }
1094
+ const trimmed = value.trim();
1095
+ if (trimmed.length === 0) {
1096
+ if (mode === "strict") {
1097
+ throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
1098
+ }
1099
+ return;
1100
+ }
1101
+ return mode === "strict" ? value : trimmed;
1102
+ }
1103
+ function readOptionalLooseStringFlag(flags, name) {
1104
+ return readOptionalCliStringFlagValue(flags, name, "loose");
1105
+ }
1106
+ function readOptionalStrictStringFlag(flags, name) {
1107
+ return readOptionalCliStringFlagValue(flags, name, "strict");
1108
+ }
1109
+ function requireStrictStringFlag(flags, name, message) {
1110
+ const value = readOptionalStrictStringFlag(flags, name);
1111
+ if (!value) {
1112
+ throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.MISSING_ARGUMENT, message);
1113
+ }
1114
+ return value;
1115
+ }
1116
+ function readOptionalPairedStrictStringFlags(flags, leftName, rightName, message) {
1117
+ const leftValue = readOptionalStrictStringFlag(flags, leftName);
1118
+ const rightValue = readOptionalStrictStringFlag(flags, rightName);
1119
+ if (Boolean(leftValue) !== Boolean(rightValue)) {
1120
+ throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.MISSING_ARGUMENT, message);
1121
+ }
1122
+ return [leftValue, rightValue];
1123
+ }
1124
+
1125
+ // src/add-kinds/admin-view.ts
1126
+ var adminViewAddKindEntry = defineAddKindRegistryEntry({
1127
+ completion: {
1128
+ nextSteps: (values) => [
1129
+ `Review src/admin-views/${values.adminViewSlug}/ and inc/admin-views/${values.adminViewSlug}.php.`,
1130
+ "Run your workspace build or dev command to verify the generated DataViews admin screen."
1131
+ ],
1132
+ summaryLines: (values, projectDir) => [
1133
+ `Admin view: ${values.adminViewSlug}`,
1134
+ ...values.source ? [`Source: ${values.source}`] : [],
1135
+ `Project directory: ${projectDir}`
1136
+ ],
1137
+ title: "Added DataViews admin screen"
1138
+ },
1139
+ description: "Add an opt-in DataViews-powered admin screen",
1140
+ nameLabel: "Admin view name",
1141
+ async prepareExecution(context) {
1142
+ const name = requireAddKindName(context, "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].");
1143
+ const source = readOptionalStrictStringFlag(context.flags, "source");
1144
+ return createNamedExecutionPlan(context, {
1145
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAdminViewCommand({
1146
+ adminViewName: name2,
1147
+ cwd,
1148
+ source
1149
+ }),
1150
+ getValues: (result) => ({
1151
+ adminViewSlug: result.adminViewSlug,
1152
+ ...result.source ? { source: result.source } : {}
1153
+ }),
1154
+ missingNameMessage: "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].",
1155
+ name
1156
+ });
1157
+ },
1158
+ sortOrder: 10,
1159
+ supportsDryRun: true,
1160
+ usage: "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]",
1161
+ visibleFieldNames: () => NAME_SOURCE_VISIBLE_FIELDS
1162
+ });
1163
+
1164
+ // src/add-kinds/ai-feature.ts
1165
+ var aiFeatureAddKindEntry = defineAddKindRegistryEntry({
1166
+ completion: {
1167
+ nextSteps: (values) => [
1168
+ `Review src/ai-features/${values.aiFeatureSlug}/ and inc/ai-features/${values.aiFeatureSlug}.php.`,
1169
+ "Run `wp-typia sync-rest` and `wp-typia sync ai` or your workspace build/dev command to verify the generated REST artifacts and AI schema."
1170
+ ],
1171
+ summaryLines: (values, projectDir) => [
1172
+ `AI feature: ${values.aiFeatureSlug}`,
1173
+ `Namespace: ${values.namespace}`,
1174
+ `Project directory: ${projectDir}`
1175
+ ],
1176
+ title: "Added server-only AI feature"
1177
+ },
1178
+ description: "Add a server-owned WordPress AI feature endpoint",
1179
+ nameLabel: "AI feature name",
1180
+ async prepareExecution(context) {
1181
+ const name = requireAddKindName(context, "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].");
1182
+ const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
1183
+ return createNamedExecutionPlan(context, {
1184
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAiFeatureCommand({
1185
+ aiFeatureName: name2,
1186
+ cwd,
1187
+ namespace
1188
+ }),
1189
+ getValues: (result) => ({
1190
+ aiFeatureSlug: result.aiFeatureSlug,
1191
+ namespace: result.namespace
1192
+ }),
1193
+ getWarnings: (result) => result.warnings,
1194
+ missingNameMessage: "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].",
1195
+ name,
1196
+ warnLine: context.warnLine
1197
+ });
1198
+ },
1199
+ sortOrder: 100,
1200
+ supportsDryRun: true,
1201
+ usage: "wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]",
1202
+ visibleFieldNames: () => NAME_NAMESPACE_VISIBLE_FIELDS
1203
+ });
1204
+
1205
+ // src/add-kinds/binding-source.ts
1206
+ var bindingSourceAddKindEntry = defineAddKindRegistryEntry({
1207
+ completion: {
1208
+ nextSteps: (values) => [
1209
+ `Review src/bindings/${values.bindingSourceSlug}/server.php and src/bindings/${values.bindingSourceSlug}/editor.ts.`,
1210
+ ...values.blockSlug && values.attributeName ? [
1211
+ `Review src/blocks/${values.blockSlug}/block.json for the ${values.attributeName} bindable attribute.`
1212
+ ] : [],
1213
+ "Run your workspace build or dev command to verify the binding source hooks and editor registration."
1214
+ ],
1215
+ summaryLines: (values, projectDir) => [
1216
+ `Binding source: ${values.bindingSourceSlug}`,
1217
+ ...values.blockSlug && values.attributeName ? [`Target: ${values.blockSlug}.${values.attributeName}`] : [],
1218
+ `Project directory: ${projectDir}`
1219
+ ],
1220
+ title: "Added binding source"
1221
+ },
1222
+ description: "Add a shared block bindings source",
1223
+ nameLabel: "Binding source name",
1224
+ async prepareExecution(context) {
1225
+ const name = requireAddKindName(context, "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].");
1226
+ const [blockName, attributeName] = readOptionalPairedStrictStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
1227
+ return createNamedExecutionPlan(context, {
1228
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBindingSourceCommand({
1229
+ attributeName,
1230
+ bindingSourceName: name2,
1231
+ blockName,
1232
+ cwd
1233
+ }),
1234
+ getValues: (result) => ({
1235
+ ...result.attributeName ? { attributeName: result.attributeName } : {},
1236
+ ...result.blockSlug ? { blockSlug: result.blockSlug } : {},
1237
+ bindingSourceSlug: result.bindingSourceSlug
1238
+ }),
1239
+ missingNameMessage: "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].",
1240
+ name
1241
+ });
1242
+ },
1243
+ sortOrder: 70,
1244
+ supportsDryRun: true,
1245
+ usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]",
1246
+ visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS
1247
+ });
1248
+
1249
+ // src/external-layer-prompt-options.ts
1250
+ function formatExternalLayerSelectHint(option) {
1251
+ const details = [
1252
+ option.description,
1253
+ option.extends.length > 0 ? `extends ${option.extends.join(", ")}` : undefined
1254
+ ].filter((value) => typeof value === "string" && value.length > 0);
1255
+ return details.length > 0 ? details.join(" · ") : undefined;
1256
+ }
1257
+ function toExternalLayerPromptOptions(options) {
1258
+ return options.map((option) => ({
1259
+ hint: formatExternalLayerSelectHint(option),
1260
+ label: option.id,
1261
+ value: option.id
1262
+ }));
1263
+ }
1264
+
1265
+ // src/add-kinds/block.ts
1266
+ var blockAddKindEntry = defineAddKindRegistryEntry({
1267
+ completion: {
1268
+ nextSteps: () => [
1269
+ "Review the generated sources under src/blocks/ and the updated scripts/block-config.ts entry.",
1270
+ "Run your workspace build or dev command to verify the new scaffolded block family."
1271
+ ],
1272
+ summaryLines: (values, projectDir) => [
1273
+ `Blocks: ${values.blockSlugs}`,
1274
+ `Template family: ${values.templateId}`,
1275
+ `Project directory: ${projectDir}`
1276
+ ],
1277
+ title: "Added workspace block"
1278
+ },
1279
+ description: "Add a real block slice",
1280
+ hiddenStringSubmitFields: ["external-layer-id", "external-layer-source"],
1281
+ nameLabel: "Block name",
1282
+ async prepareExecution(context) {
1283
+ const name = requireAddKindName(context, "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]");
1284
+ const externalLayerId = readOptionalStrictStringFlag(context.flags, "external-layer-id");
1285
+ const externalLayerSource = readOptionalStrictStringFlag(context.flags, "external-layer-source");
1286
+ const shouldPromptForLayerSelection = Boolean(externalLayerSource) && !Boolean(externalLayerId) && context.isInteractiveSession;
1287
+ const selectPrompt = shouldPromptForLayerSelection ? await context.getOrCreatePrompt() : undefined;
1288
+ const alternateRenderTargets = readOptionalStrictStringFlag(context.flags, "alternate-render-targets");
1289
+ const dataStorageMode = readOptionalStrictStringFlag(context.flags, "data-storage");
1290
+ const innerBlocksPreset = readOptionalStrictStringFlag(context.flags, "inner-blocks-preset");
1291
+ const persistencePolicy = readOptionalStrictStringFlag(context.flags, "persistence-policy");
1292
+ const requestedTemplateId = readOptionalStrictStringFlag(context.flags, "template");
1293
+ let resolvedTemplateId = requestedTemplateId ? assertAddBlockTemplateId(context, requestedTemplateId) : undefined;
1294
+ if (!resolvedTemplateId && context.isInteractiveSession) {
1295
+ const templatePrompt = await context.getOrCreatePrompt();
1296
+ resolvedTemplateId = await templatePrompt.select("Select a block template", context.addRuntime.ADD_BLOCK_TEMPLATE_IDS.map((templateId) => ({
1297
+ hint: `Scaffold the ${templateId} block family`,
1298
+ label: templateId,
1299
+ value: templateId
1300
+ })), 1);
1301
+ }
1302
+ resolvedTemplateId ??= "basic";
1303
+ return createNamedExecutionPlan(context, {
1304
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockCommand({
1305
+ alternateRenderTargets,
1306
+ blockName: name2,
1307
+ cwd,
1308
+ dataStorageMode,
1309
+ externalLayerId,
1310
+ externalLayerSource,
1311
+ innerBlocksPreset,
1312
+ persistencePolicy,
1313
+ selectExternalLayerId: selectPrompt ? (options) => selectPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
1314
+ templateId: resolvedTemplateId
1315
+ }),
1316
+ getValues: (result) => ({
1317
+ blockSlugs: result.blockSlugs.join(", "),
1318
+ templateId: result.templateId
1319
+ }),
1320
+ getWarnings: (result) => result.warnings,
1321
+ missingNameMessage: "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]",
1322
+ name,
1323
+ warnLine: context.warnLine
1324
+ });
1325
+ },
1326
+ sortOrder: 20,
1327
+ supportsDryRun: true,
1328
+ usage: "wp-typia add block <name> [--template <basic|interactivity|persistence|compound>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]",
1329
+ visibleFieldNames: ({ template }) => BLOCK_VISIBLE_FIELD_ORDER.filter((fieldName) => {
1330
+ if (fieldName === "alternate-render-targets") {
1331
+ return isAddPersistenceTemplate(template);
1332
+ }
1333
+ if (fieldName === "inner-blocks-preset") {
1334
+ return template === "compound";
1335
+ }
1336
+ if (fieldName === "data-storage" || fieldName === "persistence-policy") {
1337
+ return isAddPersistenceTemplate(template);
1338
+ }
1339
+ return true;
1340
+ })
1341
+ });
1342
+
1343
+ // src/add-kinds/editor-plugin.ts
1344
+ var editorPluginAddKindEntry = defineAddKindRegistryEntry({
1345
+ completion: {
1346
+ nextSteps: (values) => [
1347
+ `Review src/editor-plugins/${values.editorPluginSlug}/.`,
1348
+ "Run your workspace build or dev command to verify the new editor plugin registration."
1349
+ ],
1350
+ summaryLines: (values, projectDir) => [
1351
+ `Editor plugin: ${values.editorPluginSlug}`,
1352
+ `Slot: ${values.slot}`,
1353
+ `Project directory: ${projectDir}`
1354
+ ],
1355
+ title: "Added editor plugin"
1356
+ },
1357
+ description: "Add a slot-aware document editor extension shell",
1358
+ nameLabel: "Editor plugin name",
1359
+ async prepareExecution(context) {
1360
+ const name = requireAddKindName(context, "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].");
1361
+ const slot = readOptionalStrictStringFlag(context.flags, "slot");
1362
+ return createNamedExecutionPlan(context, {
1363
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddEditorPluginCommand({
1364
+ cwd,
1365
+ editorPluginName: name2,
1366
+ slot
1367
+ }),
1368
+ getValues: (result) => ({
1369
+ editorPluginSlug: result.editorPluginSlug,
1370
+ slot: result.slot
1371
+ }),
1372
+ missingNameMessage: "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].",
1373
+ name
1374
+ });
1375
+ },
1376
+ sortOrder: 120,
1377
+ supportsDryRun: true,
1378
+ usage: "wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>] [--dry-run]",
1379
+ visibleFieldNames: () => NAME_SLOT_VISIBLE_FIELDS
1380
+ });
1381
+
1382
+ // src/add-kinds/hooked-block.ts
1383
+ var hookedBlockAddKindEntry = defineAddKindRegistryEntry({
1384
+ completion: {
1385
+ nextSteps: (values) => [
1386
+ `Review src/blocks/${values.blockSlug}/block.json for the new blockHooks entry.`,
1387
+ "Run your workspace build or dev command to verify the updated hooked-block metadata."
1388
+ ],
1389
+ summaryLines: (values, projectDir) => [
1390
+ `Block: ${values.blockSlug}`,
1391
+ `Anchor: ${values.anchorBlockName}`,
1392
+ `Position: ${values.position}`,
1393
+ `Project directory: ${projectDir}`
1394
+ ],
1395
+ title: "Added blockHooks metadata"
1396
+ },
1397
+ description: "Add block.json hook metadata to an existing block",
1398
+ nameLabel: "Target block",
1399
+ async prepareExecution(context) {
1400
+ const name = requireAddKindName(context, "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.");
1401
+ const anchorBlockName = requireStrictStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
1402
+ const position = requireStrictStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
1403
+ return createNamedExecutionPlan(context, {
1404
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddHookedBlockCommand({
1405
+ anchorBlockName,
1406
+ blockName: name2,
1407
+ cwd,
1408
+ position
1409
+ }),
1410
+ getValues: (result) => ({
1411
+ anchorBlockName: result.anchorBlockName,
1412
+ blockSlug: result.blockSlug,
1413
+ position: result.position
1414
+ }),
1415
+ missingNameMessage: "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.",
1416
+ name
1417
+ });
1418
+ },
1419
+ sortOrder: 110,
1420
+ supportsDryRun: true,
1421
+ usage: "wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild> [--dry-run]",
1422
+ visibleFieldNames: () => NAME_ANCHOR_POSITION_VISIBLE_FIELDS
1423
+ });
1424
+
1425
+ // src/add-kinds/pattern.ts
1426
+ var patternAddKindEntry = defineAddKindRegistryEntry({
1427
+ completion: {
1428
+ nextSteps: (values) => [
1429
+ `Review src/patterns/${values.patternSlug}.php.`,
1430
+ "Run your workspace build or dev command to verify the new pattern registration."
1431
+ ],
1432
+ summaryLines: (values, projectDir) => [
1433
+ `Pattern: ${values.patternSlug}`,
1434
+ `Project directory: ${projectDir}`
1435
+ ],
1436
+ title: "Added workspace pattern"
1437
+ },
1438
+ description: "Add a PHP block pattern shell",
1439
+ nameLabel: "Pattern name",
1440
+ async prepareExecution(context) {
1441
+ return createNamedExecutionPlan(context, {
1442
+ execute: ({ cwd, name }) => context.addRuntime.runAddPatternCommand({
1443
+ cwd,
1444
+ patternName: name
1445
+ }),
1446
+ getValues: (result) => ({
1447
+ patternSlug: result.patternSlug
1448
+ }),
1449
+ missingNameMessage: "`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>."
1450
+ });
1451
+ },
1452
+ sortOrder: 60,
1453
+ supportsDryRun: true,
1454
+ usage: "wp-typia add pattern <name> [--dry-run]",
1455
+ visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1456
+ });
1457
+
1458
+ // src/add-kinds/rest-resource.ts
1459
+ var restResourceAddKindEntry = defineAddKindRegistryEntry({
1460
+ completion: {
1461
+ nextSteps: (values) => [
1462
+ `Review src/rest/${values.restResourceSlug}/ and inc/rest/${values.restResourceSlug}.php.`,
1463
+ "Run your workspace build or dev command to verify the generated REST resource contract."
1464
+ ],
1465
+ summaryLines: (values, projectDir) => [
1466
+ `REST resource: ${values.restResourceSlug}`,
1467
+ `Namespace: ${values.namespace}`,
1468
+ `Methods: ${values.methods}`,
1469
+ `Project directory: ${projectDir}`
1470
+ ],
1471
+ title: "Added plugin-level REST resource"
1472
+ },
1473
+ description: "Add a plugin-level typed REST resource",
1474
+ nameLabel: "REST resource name",
1475
+ async prepareExecution(context) {
1476
+ const name = requireAddKindName(context, "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>].");
1477
+ const methods = readOptionalStrictStringFlag(context.flags, "methods");
1478
+ const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
1479
+ return createNamedExecutionPlan(context, {
1480
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddRestResourceCommand({
1481
+ cwd,
1482
+ methods,
1483
+ namespace,
1484
+ restResourceName: name2
1485
+ }),
1486
+ getValues: (result) => ({
1487
+ methods: result.methods.join(", "),
1488
+ namespace: result.namespace,
1489
+ restResourceSlug: result.restResourceSlug
1490
+ }),
1491
+ missingNameMessage: "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>].",
1492
+ name
1493
+ });
1494
+ },
1495
+ sortOrder: 80,
1496
+ supportsDryRun: true,
1497
+ usage: "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]",
1498
+ visibleFieldNames: () => NAME_NAMESPACE_METHODS_VISIBLE_FIELDS
1499
+ });
1500
+
1501
+ // src/add-kinds/style.ts
1502
+ var styleAddKindEntry = defineAddKindRegistryEntry({
1503
+ completion: {
1504
+ nextSteps: (values) => [
1505
+ `Review src/blocks/${values.blockSlug}/styles/${values.styleSlug}.ts.`,
1506
+ "Run your workspace build or dev command to verify the new block style registration."
1507
+ ],
1508
+ summaryLines: (values, projectDir) => [
1509
+ `Block style: ${values.styleSlug}`,
1510
+ `Target block: ${values.blockSlug}`,
1511
+ `Project directory: ${projectDir}`
1512
+ ],
1513
+ title: "Added block style"
1514
+ },
1515
+ description: "Add a Block Styles registration to an existing block",
1516
+ nameLabel: "Style name",
1517
+ async prepareExecution(context) {
1518
+ const name = requireAddKindName(context, "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.");
1519
+ const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
1520
+ return createNamedExecutionPlan(context, {
1521
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockStyleCommand({
1522
+ blockName: blockSlug,
1523
+ cwd,
1524
+ styleName: name2
1525
+ }),
1526
+ getValues: (result) => ({
1527
+ blockSlug: result.blockSlug,
1528
+ styleSlug: result.styleSlug
1529
+ }),
1530
+ missingNameMessage: "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.",
1531
+ name
1532
+ });
1533
+ },
1534
+ sortOrder: 40,
1535
+ supportsDryRun: true,
1536
+ usage: "wp-typia add style <name> --block <block-slug> [--dry-run]",
1537
+ visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
1538
+ });
1539
+
1540
+ // src/add-kinds/transform.ts
1541
+ var transformAddKindEntry = defineAddKindRegistryEntry({
1542
+ completion: {
1543
+ nextSteps: (values) => [
1544
+ `Review src/blocks/${values.blockSlug}/transforms/${values.transformSlug}.ts.`,
1545
+ "Run your workspace build or dev command to verify the new block transform registration."
1546
+ ],
1547
+ summaryLines: (values, projectDir) => [
1548
+ `Block transform: ${values.transformSlug}`,
1549
+ `From: ${values.fromBlockName}`,
1550
+ `To: ${values.toBlockName}`,
1551
+ `Project directory: ${projectDir}`
1552
+ ],
1553
+ title: "Added block transform"
1554
+ },
1555
+ description: "Add a block-to-block transform into a workspace block",
1556
+ nameLabel: "Transform name",
1557
+ async prepareExecution(context) {
1558
+ const name = requireAddKindName(context, "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.");
1559
+ const fromBlockName = requireStrictStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
1560
+ const toBlockName = requireStrictStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
1561
+ return createNamedExecutionPlan(context, {
1562
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockTransformCommand({
1563
+ cwd,
1564
+ fromBlockName,
1565
+ toBlockName,
1566
+ transformName: name2
1567
+ }),
1568
+ getValues: (result) => ({
1569
+ blockSlug: result.blockSlug,
1570
+ fromBlockName: result.fromBlockName,
1571
+ toBlockName: result.toBlockName,
1572
+ transformSlug: result.transformSlug
1573
+ }),
1574
+ missingNameMessage: "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.",
1575
+ name
1576
+ });
1577
+ },
1578
+ sortOrder: 50,
1579
+ supportsDryRun: true,
1580
+ usage: "wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]",
1581
+ visibleFieldNames: () => NAME_FROM_TO_VISIBLE_FIELDS
1582
+ });
1583
+
1584
+ // src/add-kinds/variation.ts
1585
+ var variationAddKindEntry = defineAddKindRegistryEntry({
1586
+ completion: {
1587
+ nextSteps: (values) => [
1588
+ `Review src/blocks/${values.blockSlug}/variations/${values.variationSlug}.ts.`,
1589
+ "Run your workspace build or dev command to pick up the new variation."
1590
+ ],
1591
+ summaryLines: (values, projectDir) => [
1592
+ `Variation: ${values.variationSlug}`,
1593
+ `Target block: ${values.blockSlug}`,
1594
+ `Project directory: ${projectDir}`
1595
+ ],
1596
+ title: "Added workspace variation"
1597
+ },
1598
+ description: "Add a variation to an existing block",
1599
+ nameLabel: "Variation name",
1600
+ async prepareExecution(context) {
1601
+ const name = requireAddKindName(context, "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
1602
+ const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
1603
+ return createNamedExecutionPlan(context, {
1604
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddVariationCommand({
1605
+ blockName: blockSlug,
1606
+ cwd,
1607
+ variationName: name2
1608
+ }),
1609
+ getValues: (result) => ({
1610
+ blockSlug: result.blockSlug,
1611
+ variationSlug: result.variationSlug
1612
+ }),
1613
+ missingNameMessage: "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>",
1614
+ name
1615
+ });
1616
+ },
1617
+ sortOrder: 30,
1618
+ supportsDryRun: true,
1619
+ usage: "wp-typia add variation <name> --block <block-slug> [--dry-run]",
1620
+ visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
1621
+ });
1622
+
1623
+ // src/add-kind-registry.ts
1624
+ var ADD_KIND_REGISTRY = {
1625
+ "admin-view": adminViewAddKindEntry,
1626
+ block: blockAddKindEntry,
1627
+ variation: variationAddKindEntry,
1628
+ style: styleAddKindEntry,
1629
+ transform: transformAddKindEntry,
1630
+ pattern: patternAddKindEntry,
1631
+ "binding-source": bindingSourceAddKindEntry,
1632
+ "rest-resource": restResourceAddKindEntry,
1633
+ ability: abilityAddKindEntry,
1634
+ "ai-feature": aiFeatureAddKindEntry,
1635
+ "hooked-block": hookedBlockAddKindEntry,
1636
+ "editor-plugin": editorPluginAddKindEntry
1637
+ };
1638
+ function isAddKindId(value) {
1639
+ return typeof value === "string" && ADD_KIND_IDS.includes(value);
1640
+ }
1641
+ async function getAddKindExecutionPlan(kind, context) {
1642
+ return ADD_KIND_REGISTRY[kind].prepareExecution(context);
1643
+ }
1644
+ function buildAddKindCompletionDetails(kind, options) {
1645
+ const descriptor = ADD_KIND_REGISTRY[kind].completion;
1646
+ return {
1647
+ nextSteps: descriptor.nextSteps(options.values),
1648
+ summaryLines: descriptor.summaryLines(options.values, options.projectDir),
1649
+ title: descriptor.title
1650
+ };
1651
+ }
1652
+ function formatAddKindList() {
1653
+ return ADD_KIND_IDS.join(", ");
1654
+ }
1655
+ function formatAddKindUsagePlaceholder() {
1656
+ return `<${ADD_KIND_IDS.join("|")}>`;
1657
+ }
1658
+ function supportsAddKindDryRun(kind) {
1659
+ return ADD_KIND_REGISTRY[kind].supportsDryRun;
1660
+ }
1661
+
1662
+ // src/cli-error-messages.ts
1663
+ var MISSING_CREATE_PROJECT_DIR_DETAIL_LINES = [
1664
+ "`wp-typia create` requires <project-dir>.",
1665
+ "`--dry-run` still needs a logical project directory name because wp-typia derives slugs, package names, and planned file paths from it."
1666
+ ];
1667
+ function formatMissingAddKindDetailLine() {
1668
+ return `\`wp-typia add\` requires <kind>. Usage: wp-typia add ${formatAddKindUsagePlaceholder()} ...`;
1669
+ }
1670
+ function buildMissingAddKindDetailLines() {
1671
+ return [formatMissingAddKindDetailLine()];
1672
+ }
1673
+ function shouldPrintMissingAddKindHelp(options) {
1674
+ if (typeof options.emitOutput === "boolean") {
1675
+ return options.emitOutput;
1676
+ }
1677
+ return options.format !== "json";
1678
+ }
1679
+ function buildMissingCreateProjectDirDetailLines() {
1680
+ return [...MISSING_CREATE_PROJECT_DIR_DETAIL_LINES];
1681
+ }
1682
+
1615
1683
  // src/runtime-bridge-add-dry-run.ts
1616
1684
  import fs2 from "node:fs";
1617
1685
  import { promises as fsp } from "node:fs";
@@ -1741,9 +1809,15 @@ async function simulateWorkspaceAddDryRun({
1741
1809
 
1742
1810
  // src/runtime-bridge-output.ts
1743
1811
  import {
1812
+ PACKAGE_MANAGER_IDS,
1744
1813
  formatPackageExecCommand,
1745
- inferPackageManagerId
1814
+ inferPackageManagerId,
1815
+ parsePackageManagerField
1746
1816
  } from "@wp-typia/project-tools/package-managers";
1817
+ import {
1818
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES6,
1819
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError5
1820
+ } from "@wp-typia/project-tools/cli-diagnostics";
1747
1821
 
1748
1822
  // src/output-markers.ts
1749
1823
  var UNICODE_OUTPUT_MARKERS = {
@@ -1823,6 +1897,13 @@ function stripLeadingOutputMarker(text, kind) {
1823
1897
  return text.replace(new RegExp(`^(?:${markerPattern})\\s*`, "u"), "");
1824
1898
  }
1825
1899
 
1900
+ // src/print-block.ts
1901
+ function printBlock(printLine, lines) {
1902
+ for (const line of lines) {
1903
+ printLine(line);
1904
+ }
1905
+ }
1906
+
1826
1907
  // src/runtime-bridge-output.ts
1827
1908
  function printCompletionPayload(payload, options = {}) {
1828
1909
  const printLine = options.printLine ?? console.log;
@@ -1865,6 +1946,13 @@ function extractPlannedFiles(payload) {
1865
1946
  return toNonEmptyArray(files);
1866
1947
  }
1867
1948
  var PROJECT_DIRECTORY_SUMMARY_PREFIX = "Project directory: ";
1949
+ function resolveCreateCompletionPackageManager(packageManager) {
1950
+ const parsedPackageManager = parsePackageManagerField(packageManager);
1951
+ if (parsedPackageManager) {
1952
+ return parsedPackageManager;
1953
+ }
1954
+ throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.INVALID_ARGUMENT, `Unsupported package manager "${packageManager}" in create completion payload. Expected one of: ${PACKAGE_MANAGER_IDS.join(", ")}.`);
1955
+ }
1868
1956
  function extractCompletionProjectDir(completion) {
1869
1957
  const projectDir = completion?.summaryLines?.find((line) => line.startsWith(PROJECT_DIRECTORY_SUMMARY_PREFIX))?.slice(PROJECT_DIRECTORY_SUMMARY_PREFIX.length).trim();
1870
1958
  return projectDir && projectDir.length > 0 ? projectDir : undefined;
@@ -1921,8 +2009,9 @@ function formatCreateProgressLine(payload, markerOptions) {
1921
2009
  return formatOutputMarker("progress", `${payload.title}: ${payload.detail}`, markerOptions);
1922
2010
  }
1923
2011
  function buildCreateCompletionPayload(flow, markerOptions) {
2012
+ const packageManager = resolveCreateCompletionPackageManager(flow.packageManager);
1924
2013
  const verificationSteps = [
1925
- formatPackageExecCommand(flow.packageManager, `wp-typia@${package_default.version}`, "doctor"),
2014
+ formatPackageExecCommand(packageManager, `wp-typia@${package_default.version}`, "doctor"),
1926
2015
  ...flow.optionalOnboarding.steps
1927
2016
  ];
1928
2017
  return {
@@ -2044,11 +2133,6 @@ function buildSyncDryRunPayload(options, markerOptions) {
2044
2133
  title: formatOutputMarker("dryRun", `Dry run for wp-typia sync${targetSuffix}`, markerOptions)
2045
2134
  };
2046
2135
  }
2047
- function printBlock(lines, printLine) {
2048
- for (const line of lines) {
2049
- printLine(line);
2050
- }
2051
- }
2052
2136
 
2053
2137
  // src/runtime-capabilities.ts
2054
2138
  function isInteractiveTerminal({
@@ -2063,8 +2147,8 @@ import { spawnSync } from "node:child_process";
2063
2147
  import fs3 from "node:fs";
2064
2148
  import path3 from "node:path";
2065
2149
  import {
2066
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES6,
2067
- createCliDiagnosticCodeError as createCliDiagnosticCodeError5
2150
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES7,
2151
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError6
2068
2152
  } from "@wp-typia/project-tools/cli-diagnostics";
2069
2153
  import {
2070
2154
  formatInstallCommand,
@@ -2085,10 +2169,10 @@ function resolveSyncExecutionTarget(subcommand) {
2085
2169
  if (subcommand === "ai") {
2086
2170
  return "ai";
2087
2171
  }
2088
- throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.INVALID_COMMAND, `Unknown sync subcommand "${subcommand}". Expected one of: "ai".`);
2172
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_COMMAND, `Unknown sync subcommand "${subcommand}". Expected one of: "ai".`);
2089
2173
  }
2090
2174
  function getSyncRootError(cwd) {
2091
- return createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.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.`);
2175
+ return createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.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.`);
2092
2176
  }
2093
2177
  function resolveSyncProjectContext(cwd) {
2094
2178
  const packageJsonPath = path3.join(cwd, "package.json");
@@ -2154,7 +2238,7 @@ function assertSyncDependenciesInstalled(project, target) {
2154
2238
  if (markerDir) {
2155
2239
  return;
2156
2240
  }
2157
- throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.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\`.`);
2241
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.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\`.`);
2158
2242
  }
2159
2243
  function getPackageManagerRunInvocation(packageManager, scriptName, extraArgs) {
2160
2244
  switch (packageManager) {
@@ -2192,7 +2276,7 @@ function buildSyncPlannedCommands(project, extraArgs, target) {
2192
2276
  if (target === "ai") {
2193
2277
  const syncAiCommand2 = createSyncPlannedCommand(project, "sync-ai", extraArgs);
2194
2278
  if (!syncAiCommand2) {
2195
- throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define a \`sync-ai\` script for \`wp-typia sync ai\`.`);
2279
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define a \`sync-ai\` script for \`wp-typia sync ai\`.`);
2196
2280
  }
2197
2281
  return [syncAiCommand2];
2198
2282
  }
@@ -2201,7 +2285,7 @@ function buildSyncPlannedCommands(project, extraArgs, target) {
2201
2285
  }
2202
2286
  const syncTypesCommand = createSyncPlannedCommand(project, "sync-types", extraArgs);
2203
2287
  if (!syncTypesCommand) {
2204
- throw createCliDiagnosticCodeError5(CLI_DIAGNOSTIC_CODES6.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define either a \`sync\` or \`sync-types\` script.`);
2288
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.CONFIGURATION_MISSING, `Expected ${project.packageJsonPath} to define either a \`sync\` or \`sync-types\` script.`);
2205
2289
  }
2206
2290
  const plannedCommands = [syncTypesCommand];
2207
2291
  const syncRestCommand = createSyncPlannedCommand(project, "sync-rest", extraArgs);
@@ -2225,7 +2309,7 @@ function runProjectScript(project, plannedCommand, options) {
2225
2309
  const stderr = options.captureOutput && typeof result.stderr === "string" ? result.stderr : undefined;
2226
2310
  const stdout = options.captureOutput && typeof result.stdout === "string" ? result.stdout : undefined;
2227
2311
  if (result.error || result.status !== 0) {
2228
- throw new Error(`\`${plannedCommand.displayCommand}\` failed.`, {
2312
+ throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.COMMAND_EXECUTION, `\`${plannedCommand.displayCommand}\` failed.`, {
2229
2313
  cause: result.error ?? (stderr ? new Error(stderr.trim()) : undefined)
2230
2314
  });
2231
2315
  }
@@ -2273,6 +2357,7 @@ var loadCliInitRuntime = () => import("@wp-typia/project-tools/cli-init");
2273
2357
  var loadCliPromptRuntime = () => import("@wp-typia/project-tools/cli-prompt");
2274
2358
  var loadCliScaffoldRuntime = () => import("@wp-typia/project-tools/cli-scaffold");
2275
2359
  var loadCliTemplatesRuntime = () => import("@wp-typia/project-tools/cli-templates");
2360
+ var loadCreateTemplateValidationRuntime = () => import("@wp-typia/project-tools/create-template-validation");
2276
2361
  var loadMigrationsRuntime = () => import("@wp-typia/project-tools/migrations");
2277
2362
  async function wrapCliCommandError(command, error) {
2278
2363
  const { createCliCommandError: createCliCommandError3 } = await loadCliDiagnosticsRuntime();
@@ -2386,20 +2471,24 @@ async function executeCreateCommand({
2386
2471
  prompt,
2387
2472
  warnLine = console.warn
2388
2473
  }) {
2389
- const [
2390
- { createReadlinePrompt },
2391
- { runScaffoldFlow },
2392
- { getTemplateSelectOptions }
2393
- ] = await Promise.all([
2394
- loadCliPromptRuntime(),
2395
- loadCliScaffoldRuntime(),
2396
- loadCliTemplatesRuntime()
2397
- ]);
2398
- const shouldPrompt = interactive ?? (!Boolean(flags.yes) && isInteractiveTerminal());
2399
- const activePrompt = shouldPrompt ? prompt ?? createReadlinePrompt() : undefined;
2400
- const shouldPromptForExternalLayerSelection = Boolean(activePrompt) && activePrompt !== prompt;
2401
- const effectiveYes = Boolean(flags.yes) || Boolean(flags["dry-run"]) && !Boolean(activePrompt);
2474
+ let activePrompt;
2402
2475
  try {
2476
+ const requestedTemplateId = readOptionalLooseStringFlag(flags, "template");
2477
+ const resolvedTemplateId = requestedTemplateId ? (await loadCreateTemplateValidationRuntime()).validateExplicitCreateTemplateId(requestedTemplateId) : undefined;
2478
+ const [
2479
+ { createReadlinePrompt },
2480
+ { runScaffoldFlow },
2481
+ { getTemplateSelectOptions }
2482
+ ] = await Promise.all([
2483
+ loadCliPromptRuntime(),
2484
+ loadCliScaffoldRuntime(),
2485
+ loadCliTemplatesRuntime()
2486
+ ]);
2487
+ const shouldPrompt = interactive ?? (!Boolean(flags.yes) && isInteractiveTerminal());
2488
+ activePrompt = shouldPrompt ? prompt ?? createReadlinePrompt() : undefined;
2489
+ const scaffoldPrompt = activePrompt;
2490
+ const shouldPromptForExternalLayerSelection = Boolean(scaffoldPrompt) && scaffoldPrompt !== prompt;
2491
+ const effectiveYes = Boolean(flags.yes) || Boolean(flags["dry-run"]) && !Boolean(scaffoldPrompt);
2403
2492
  const flow = await runScaffoldFlow({
2404
2493
  alternateRenderTargets: readOptionalLooseStringFlag(flags, "alternate-render-targets"),
2405
2494
  cwd,
@@ -2408,7 +2497,7 @@ async function executeCreateCommand({
2408
2497
  externalLayerId: readOptionalLooseStringFlag(flags, "external-layer-id"),
2409
2498
  externalLayerSource: readOptionalLooseStringFlag(flags, "external-layer-source"),
2410
2499
  innerBlocksPreset: readOptionalLooseStringFlag(flags, "inner-blocks-preset"),
2411
- isInteractive: Boolean(activePrompt),
2500
+ isInteractive: Boolean(scaffoldPrompt),
2412
2501
  namespace: readOptionalLooseStringFlag(flags, "namespace"),
2413
2502
  noInstall: Boolean(flags["no-install"]),
2414
2503
  packageManager: readOptionalLooseStringFlag(flags, "package-manager"),
@@ -2425,17 +2514,17 @@ async function executeCreateCommand({
2425
2514
  printLine(formatCreateProgressLine(payload2));
2426
2515
  }
2427
2516
  },
2428
- promptText: activePrompt ? (message, defaultValue, validate) => activePrompt.text(message, defaultValue, validate) : undefined,
2517
+ promptText: scaffoldPrompt ? (message, defaultValue, validate) => scaffoldPrompt.text(message, defaultValue, validate) : undefined,
2429
2518
  queryPostType: readOptionalLooseStringFlag(flags, "query-post-type"),
2430
- selectDataStorage: activePrompt ? () => activePrompt.select("Select a data storage mode", [...DATA_STORAGE_PROMPT_OPTIONS], 1) : undefined,
2431
- selectExternalLayerId: shouldPromptForExternalLayerSelection && activePrompt ? (options) => activePrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
2432
- selectPackageManager: activePrompt ? () => activePrompt.select("Select a package manager", [...PACKAGE_MANAGER_PROMPT_OPTIONS], 1) : undefined,
2433
- selectPersistencePolicy: activePrompt ? () => activePrompt.select("Select a persistence policy", [...PERSISTENCE_POLICY_PROMPT_OPTIONS], 1) : undefined,
2434
- selectTemplate: activePrompt ? () => activePrompt.select("Select a template", getTemplateSelectOptions(), 1) : undefined,
2435
- selectWithMigrationUi: activePrompt ? async () => await activePrompt.select("Enable migration UI support?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
2436
- selectWithTestPreset: activePrompt ? async () => await activePrompt.select("Include the Playwright test preset?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
2437
- selectWithWpEnv: activePrompt ? async () => await activePrompt.select("Include a local wp-env preset?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
2438
- templateId: readOptionalLooseStringFlag(flags, "template"),
2519
+ selectDataStorage: scaffoldPrompt ? () => scaffoldPrompt.select("Select a data storage mode", [...DATA_STORAGE_PROMPT_OPTIONS], 1) : undefined,
2520
+ selectExternalLayerId: shouldPromptForExternalLayerSelection && scaffoldPrompt ? (options) => scaffoldPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
2521
+ selectPackageManager: scaffoldPrompt ? () => scaffoldPrompt.select("Select a package manager", [...PACKAGE_MANAGER_PROMPT_OPTIONS], 1) : undefined,
2522
+ selectPersistencePolicy: scaffoldPrompt ? () => scaffoldPrompt.select("Select a persistence policy", [...PERSISTENCE_POLICY_PROMPT_OPTIONS], 1) : undefined,
2523
+ selectTemplate: scaffoldPrompt ? () => scaffoldPrompt.select("Select a template", getTemplateSelectOptions(), 1) : undefined,
2524
+ selectWithMigrationUi: scaffoldPrompt ? async () => await scaffoldPrompt.select("Enable migration UI support?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
2525
+ selectWithTestPreset: scaffoldPrompt ? async () => await scaffoldPrompt.select("Include the Playwright test preset?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
2526
+ selectWithWpEnv: scaffoldPrompt ? async () => await scaffoldPrompt.select("Include a local wp-env preset?", [...BOOLEAN_PROMPT_OPTIONS], 2) === "yes" : undefined,
2527
+ templateId: resolvedTemplateId,
2439
2528
  textDomain: readOptionalLooseStringFlag(flags, "text-domain"),
2440
2529
  variant: readOptionalLooseStringFlag(flags, "variant"),
2441
2530
  withMigrationUi: flags["with-migration-ui"],
@@ -2478,16 +2567,16 @@ async function executeAddCommand({
2478
2567
  const addRuntime = await loadCliAddRuntime();
2479
2568
  const isInteractiveSession = interactive ?? isInteractiveTerminal();
2480
2569
  if (!kind) {
2481
- if (emitOutput) {
2570
+ if (shouldPrintMissingAddKindHelp({ emitOutput })) {
2482
2571
  printLine(addRuntime.formatAddHelpText());
2483
2572
  }
2484
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.MISSING_ARGUMENT, `\`wp-typia add\` requires <kind>. Usage: wp-typia add ${formatAddKindUsagePlaceholder()} ...`);
2573
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.MISSING_ARGUMENT, formatMissingAddKindDetailLine());
2485
2574
  }
2486
2575
  if (!isAddKindId(kind)) {
2487
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_COMMAND, `Unknown add kind "${kind}". Expected one of: ${formatAddKindList()}.`);
2576
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_COMMAND, `Unknown add kind "${kind}". Expected one of: ${formatAddKindList()}.`);
2488
2577
  }
2489
2578
  if (dryRun && !supportsAddKindDryRun(kind)) {
2490
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_ARGUMENT, `\`wp-typia add ${kind}\` does not support \`--dry-run\` yet.`);
2579
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `\`wp-typia add ${kind}\` does not support \`--dry-run\` yet.`);
2491
2580
  }
2492
2581
  const executionContext = {
2493
2582
  addRuntime,
@@ -2533,22 +2622,22 @@ async function executeTemplatesCommand({ flags }, printLine = console.log) {
2533
2622
  const subcommand = flags.subcommand ?? "list";
2534
2623
  if (subcommand === "list") {
2535
2624
  for (const template of listTemplates()) {
2536
- printBlock([formatTemplateSummary(template), formatTemplateFeatures(template)], printLine);
2625
+ printBlock(printLine, [formatTemplateSummary(template), formatTemplateFeatures(template)]);
2537
2626
  }
2538
2627
  return;
2539
2628
  }
2540
2629
  if (subcommand === "inspect") {
2541
2630
  if (!flags.id) {
2542
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.MISSING_ARGUMENT, "`wp-typia templates inspect` requires <template-id>.");
2631
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.MISSING_ARGUMENT, "`wp-typia templates inspect` requires <template-id>.");
2543
2632
  }
2544
2633
  const template = getTemplateById(flags.id);
2545
2634
  if (!template) {
2546
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
2635
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
2547
2636
  }
2548
- printBlock([formatTemplateDetails(template)], printLine);
2637
+ printBlock(printLine, [formatTemplateDetails(template)]);
2549
2638
  return;
2550
2639
  }
2551
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_COMMAND, `Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
2640
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_COMMAND, `Unknown templates subcommand "${subcommand}". Expected list or inspect.`);
2552
2641
  }
2553
2642
  async function executeInitCommand({ apply, cwd, packageManager, projectDir }, options = {}) {
2554
2643
  try {
@@ -2637,6 +2726,10 @@ async function executeMigrateCommand({
2637
2726
 
2638
2727
  // src/command-contract.ts
2639
2728
  import path4 from "node:path";
2729
+ import {
2730
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES9,
2731
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError8
2732
+ } from "@wp-typia/project-tools/cli-diagnostics";
2640
2733
 
2641
2734
  // src/command-registry.ts
2642
2735
  var WP_TYPIA_CANONICAL_CREATE_USAGE = "wp-typia create <project-dir>";
@@ -2906,10 +2999,10 @@ function looksLikeStructuredProjectInput(value) {
2906
2999
  function assertPositionalAliasProjectDir(projectDir) {
2907
3000
  const normalizedProjectDir = path4.normalize(projectDir).replace(/[\\/]+$/u, "") || path4.normalize(projectDir);
2908
3001
  if (normalizedProjectDir === "." || normalizedProjectDir === "..") {
2909
- throw new Error(`The positional alias does not scaffold into \`${projectDir}\`. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` with an explicit child directory instead.`);
3002
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_ARGUMENT, `The positional alias does not scaffold into \`${projectDir}\`. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` with an explicit child directory instead.`);
2910
3003
  }
2911
3004
  if (looksLikeStructuredProjectInput(projectDir)) {
2912
- throw new Error(`The positional alias only accepts unambiguous local project directories. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for \`${projectDir}\`.`);
3005
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_ARGUMENT, `The positional alias only accepts unambiguous local project directories. Use \`${WP_TYPIA_CANONICAL_CREATE_USAGE}\` for \`${projectDir}\`.`);
2913
3006
  }
2914
3007
  }
2915
3008
  function normalizeWpTypiaArgv(argv) {
@@ -2923,7 +3016,7 @@ function normalizeWpTypiaArgv(argv) {
2923
3016
  return argv;
2924
3017
  }
2925
3018
  if (firstPositional === "migrations") {
2926
- throw new Error("`wp-typia migrations` was removed in favor of `wp-typia migrate`. Use `wp-typia migrate <subcommand>` instead.");
3019
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.INVALID_ARGUMENT, "`wp-typia migrations` was removed in favor of `wp-typia migrate`. Use `wp-typia migrate <subcommand>` instead.");
2927
3020
  }
2928
3021
  if (isReservedTopLevelCommandName(firstPositional)) {
2929
3022
  assertStringOptionValues(argv);
@@ -2931,7 +3024,7 @@ function normalizeWpTypiaArgv(argv) {
2931
3024
  }
2932
3025
  if (positionalIndexes.length > 1) {
2933
3026
  const extraPositionals = positionalIndexes.slice(1).map((index) => argv[index]).filter((value) => typeof value === "string" && value.length > 0);
2934
- throw new Error(`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(", ")}.`);
3027
+ throw createCliDiagnosticCodeError8(CLI_DIAGNOSTIC_CODES9.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(", ")}.`);
2935
3028
  }
2936
3029
  assertPositionalAliasProjectDir(firstPositional);
2937
3030
  const normalizedArgv = [
@@ -2943,82 +3036,115 @@ function normalizeWpTypiaArgv(argv) {
2943
3036
  return normalizedArgv;
2944
3037
  }
2945
3038
 
2946
- // src/node-cli.ts
2947
- var NODE_FALLBACK_OPTION_PARSER = buildCommandOptionParser(ALL_COMMAND_OPTION_METADATA);
2948
- var NODE_FALLBACK_BOOLEAN_OPTION_NAMES = ["help", "version"];
2949
- var STANDALONE_GUIDANCE_LINE = "Prefer not to install Bun? Use the standalone wp-typia binary from the GitHub release assets.";
2950
- var NODE_FALLBACK_RUNTIME_SUMMARY_LINES = [
2951
- "Runtime: Node fallback",
2952
- "Human-readable fallback for common non-interactive create/init/add/migrate flows, doctor, sync, templates, --help, and --version when Bun is unavailable.",
2953
- `Install Bun 1.3.11+ or use \`bunx wp-typia ...\` for the full Bunli/OpenTUI runtime and Bun-only command surfaces such as \`skills\`, \`completions\`, and \`mcp\`. ${STANDALONE_GUIDANCE_LINE}`,
2954
- "Output markers: WP_TYPIA_ASCII=1 forces ASCII markers, WP_TYPIA_ASCII=0 opts back into Unicode markers, and non-empty NO_COLOR requests ASCII markers when WP_TYPIA_ASCII is unset."
2955
- ];
2956
- var printLine = (line) => {
2957
- console.log(line);
2958
- };
2959
- function printBlock2(lines) {
2960
- for (const line of lines) {
2961
- printLine(line);
2962
- }
2963
- }
2964
- function hasFlagBeforeTerminator(argv, flag) {
2965
- for (const arg of argv) {
2966
- if (arg === "--") {
2967
- return false;
3039
+ // src/node-fallback/dispatchers/add.ts
3040
+ import {
3041
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES10,
3042
+ createCliCommandError as createCliCommandError3
3043
+ } from "@wp-typia/project-tools/cli-diagnostics";
3044
+ async function dispatchNodeFallbackAdd({
3045
+ cwd,
3046
+ mergedFlags,
3047
+ positionals,
3048
+ printLine
3049
+ }) {
3050
+ if (!positionals[1]) {
3051
+ if (shouldPrintMissingAddKindHelp({ format: mergedFlags.format })) {
3052
+ const { formatAddHelpText } = await import("@wp-typia/project-tools/cli-add");
3053
+ printLine(formatAddHelpText());
2968
3054
  }
2969
- if (arg === flag) {
2970
- return true;
3055
+ throw createCliCommandError3({
3056
+ code: CLI_DIAGNOSTIC_CODES10.MISSING_ARGUMENT,
3057
+ command: "add",
3058
+ detailLines: buildMissingAddKindDetailLines()
3059
+ });
3060
+ }
3061
+ if (mergedFlags.format === "json") {
3062
+ let completion;
3063
+ try {
3064
+ completion = await executeAddCommand({
3065
+ cwd,
3066
+ emitOutput: false,
3067
+ flags: mergedFlags,
3068
+ interactive: false,
3069
+ kind: positionals[1],
3070
+ name: positionals[2]
3071
+ });
3072
+ } catch (error) {
3073
+ throw createCliCommandError3({
3074
+ command: "add",
3075
+ error
3076
+ });
2971
3077
  }
3078
+ printLine(JSON.stringify(buildStructuredCompletionSuccessPayload("add", completion, {
3079
+ dryRun: Boolean(mergedFlags["dry-run"]),
3080
+ kind: positionals[1],
3081
+ name: positionals[2],
3082
+ projectDir: extractCompletionProjectDir(completion) ?? cwd
3083
+ }), null, 2));
3084
+ return;
2972
3085
  }
2973
- return false;
2974
- }
2975
- function parseGlobalFlags(argv) {
2976
- const { argv: nextArgv, flags } = extractKnownOptionValuesFromArgv(argv, {
2977
- optionNames: ["format", "id"],
2978
- parser: NODE_FALLBACK_OPTION_PARSER
3086
+ await executeAddCommand({
3087
+ cwd,
3088
+ flags: mergedFlags,
3089
+ interactive: undefined,
3090
+ kind: positionals[1],
3091
+ name: positionals[2]
2979
3092
  });
2980
- return {
2981
- argv: nextArgv,
2982
- flags: {
2983
- format: typeof flags.format === "string" ? flags.format : undefined,
2984
- id: typeof flags.id === "string" ? flags.id : undefined
2985
- }
2986
- };
2987
3093
  }
2988
- async function applyNodeFallbackConfigDefaults(command, subcommand, flags, configOverridePath, cwd) {
2989
- let config = await loadWpTypiaUserConfig(cwd);
2990
- if (configOverridePath) {
2991
- const overrideConfig = await loadWpTypiaUserConfigFromSource(cwd, configOverridePath);
2992
- config = mergeWpTypiaUserConfig(config, overrideConfig);
3094
+
3095
+ // src/node-fallback/dispatchers/create.ts
3096
+ import {
3097
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES11,
3098
+ createCliCommandError as createCliCommandError4
3099
+ } from "@wp-typia/project-tools/cli-diagnostics";
3100
+ async function dispatchNodeFallbackCreate({
3101
+ cwd,
3102
+ mergedFlags,
3103
+ positionals,
3104
+ printLine
3105
+ }) {
3106
+ const projectDir = positionals[1];
3107
+ if (!projectDir) {
3108
+ throw createCliCommandError4({
3109
+ code: CLI_DIAGNOSTIC_CODES11.MISSING_ARGUMENT,
3110
+ command: "create",
3111
+ detailLines: buildMissingCreateProjectDirDetailLines()
3112
+ });
2993
3113
  }
2994
- if (command === "create") {
2995
- return {
2996
- ...flags,
2997
- ...resolveCommandOptionValues(CREATE_OPTION_METADATA, {
2998
- defaults: getCreateDefaults(config),
2999
- flags
3000
- })
3001
- };
3114
+ let completion;
3115
+ try {
3116
+ completion = await executeCreateCommand({
3117
+ cwd,
3118
+ emitOutput: mergedFlags.format !== "json",
3119
+ flags: mergedFlags,
3120
+ interactive: mergedFlags.format === "json" ? false : undefined,
3121
+ projectDir
3122
+ });
3123
+ } catch (error) {
3124
+ throw createCliCommandError4({
3125
+ command: "create",
3126
+ error
3127
+ });
3002
3128
  }
3003
- if (command === "add" && subcommand === "block") {
3004
- return {
3005
- ...flags,
3006
- ...resolveCommandOptionValues(ADD_OPTION_METADATA, {
3007
- defaults: getAddBlockDefaults(config),
3008
- flags
3009
- })
3010
- };
3129
+ if (mergedFlags.format === "json") {
3130
+ printLine(JSON.stringify(buildStructuredCompletionSuccessPayload("create", completion, {
3131
+ dryRun: Boolean(mergedFlags["dry-run"]),
3132
+ projectDir: extractCompletionProjectDir(completion) ?? projectDir,
3133
+ template: typeof mergedFlags.template === "string" ? mergedFlags.template : undefined
3134
+ }), null, 2));
3011
3135
  }
3012
- return flags;
3013
- }
3014
- function parseArgv(argv) {
3015
- return parseCommandArgvWithMetadata(argv, {
3016
- extraBooleanOptionNames: NODE_FALLBACK_BOOLEAN_OPTION_NAMES,
3017
- parser: NODE_FALLBACK_OPTION_PARSER
3018
- });
3019
3136
  }
3020
- function renderGeneralHelp() {
3021
- printBlock2([
3137
+
3138
+ // src/node-fallback/help.ts
3139
+ var STANDALONE_GUIDANCE_LINE = "Prefer not to install Bun? Use the standalone wp-typia binary from the GitHub release assets.";
3140
+ var NODE_FALLBACK_RUNTIME_SUMMARY_LINES = [
3141
+ "Runtime: Node fallback",
3142
+ "Human-readable fallback for common non-interactive create/init/add/migrate flows, doctor, sync, templates, --help, and --version when Bun is unavailable.",
3143
+ `Install Bun 1.3.11+ or use \`bunx wp-typia ...\` for the full Bunli/OpenTUI runtime and Bun-only command surfaces such as \`skills\`, \`completions\`, and \`mcp\`. ${STANDALONE_GUIDANCE_LINE}`,
3144
+ "Output markers: WP_TYPIA_ASCII=1 forces ASCII markers, WP_TYPIA_ASCII=0 opts back into Unicode markers, and non-empty NO_COLOR requests ASCII markers when WP_TYPIA_ASCII is unset."
3145
+ ];
3146
+ function renderGeneralHelp(printLine) {
3147
+ printBlock(printLine, [
3022
3148
  `wp-typia ${package_default.version}`,
3023
3149
  "",
3024
3150
  "Canonical CLI package for wp-typia scaffolding and project workflows.",
@@ -3035,8 +3161,8 @@ function renderGeneralHelp() {
3035
3161
  `- ${WP_TYPIA_POSITIONAL_ALIAS_USAGE}`
3036
3162
  ]);
3037
3163
  }
3038
- function renderNodeFallbackCommandHelp(config) {
3039
- printBlock2([
3164
+ function renderNodeFallbackCommandHelp(printLine, config) {
3165
+ printBlock(printLine, [
3040
3166
  config.heading,
3041
3167
  "",
3042
3168
  ...NODE_FALLBACK_RUNTIME_SUMMARY_LINES,
@@ -3085,8 +3211,71 @@ var NODE_FALLBACK_COMMAND_HELP_CONFIG = {
3085
3211
  };
3086
3212
  var NODE_FALLBACK_HELP_RENDERERS = Object.fromEntries(Object.entries(NODE_FALLBACK_COMMAND_HELP_CONFIG).map(([command, config]) => [
3087
3213
  command,
3088
- () => renderNodeFallbackCommandHelp(config)
3214
+ (printLine) => renderNodeFallbackCommandHelp(printLine, config)
3089
3215
  ]));
3216
+
3217
+ // src/node-cli.ts
3218
+ var NODE_FALLBACK_OPTION_PARSER = buildCommandOptionParser(ALL_COMMAND_OPTION_METADATA);
3219
+ var NODE_FALLBACK_BOOLEAN_OPTION_NAMES = ["help", "version"];
3220
+ var printLine = (line) => {
3221
+ console.log(line);
3222
+ };
3223
+ function hasFlagBeforeTerminator(argv, flag) {
3224
+ for (const arg of argv) {
3225
+ if (arg === "--") {
3226
+ return false;
3227
+ }
3228
+ if (arg === flag) {
3229
+ return true;
3230
+ }
3231
+ }
3232
+ return false;
3233
+ }
3234
+ function parseGlobalFlags(argv) {
3235
+ const { argv: nextArgv, flags } = extractKnownOptionValuesFromArgv(argv, {
3236
+ optionNames: ["format", "id"],
3237
+ parser: NODE_FALLBACK_OPTION_PARSER
3238
+ });
3239
+ return {
3240
+ argv: nextArgv,
3241
+ flags: {
3242
+ format: typeof flags.format === "string" ? flags.format : undefined,
3243
+ id: typeof flags.id === "string" ? flags.id : undefined
3244
+ }
3245
+ };
3246
+ }
3247
+ async function applyNodeFallbackConfigDefaults(command, subcommand, flags, configOverridePath, cwd) {
3248
+ let config = await loadWpTypiaUserConfig(cwd);
3249
+ if (configOverridePath) {
3250
+ const overrideConfig = await loadWpTypiaUserConfigFromSource(cwd, configOverridePath);
3251
+ config = mergeWpTypiaUserConfig(config, overrideConfig);
3252
+ }
3253
+ if (command === "create") {
3254
+ return {
3255
+ ...flags,
3256
+ ...resolveCommandOptionValues(CREATE_OPTION_METADATA, {
3257
+ defaults: getCreateDefaults(config),
3258
+ flags
3259
+ })
3260
+ };
3261
+ }
3262
+ if (command === "add" && subcommand === "block") {
3263
+ return {
3264
+ ...flags,
3265
+ ...resolveCommandOptionValues(ADD_OPTION_METADATA, {
3266
+ defaults: getAddBlockDefaults(config),
3267
+ flags
3268
+ })
3269
+ };
3270
+ }
3271
+ return flags;
3272
+ }
3273
+ function parseArgv(argv) {
3274
+ return parseCommandArgvWithMetadata(argv, {
3275
+ extraBooleanOptionNames: NODE_FALLBACK_BOOLEAN_OPTION_NAMES,
3276
+ parser: NODE_FALLBACK_OPTION_PARSER
3277
+ });
3278
+ }
3090
3279
  function renderVersion(options = {}) {
3091
3280
  if (options.format === "json") {
3092
3281
  printLine(JSON.stringify({
@@ -3110,16 +3299,16 @@ function renderTemplatesJson(flags, subcommand) {
3110
3299
  }
3111
3300
  const templateId = flags.id;
3112
3301
  if (!templateId) {
3113
- throw createCliCommandError3({
3114
- code: CLI_DIAGNOSTIC_CODES8.MISSING_ARGUMENT,
3302
+ throw createCliCommandError5({
3303
+ code: CLI_DIAGNOSTIC_CODES12.MISSING_ARGUMENT,
3115
3304
  command: "templates",
3116
3305
  detailLines: ["`wp-typia templates inspect` requires <template-id>."]
3117
3306
  });
3118
3307
  }
3119
3308
  const template = getTemplateById(templateId);
3120
3309
  if (!template) {
3121
- throw createCliCommandError3({
3122
- code: CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT,
3310
+ throw createCliCommandError5({
3311
+ code: CLI_DIAGNOSTIC_CODES12.INVALID_ARGUMENT,
3123
3312
  command: "templates",
3124
3313
  detailLines: [`Unknown template "${templateId}".`]
3125
3314
  });
@@ -3129,8 +3318,8 @@ function renderTemplatesJson(flags, subcommand) {
3129
3318
  }, null, 2));
3130
3319
  }
3131
3320
  function renderUnsupportedCommand(command) {
3132
- throw createCliCommandError3({
3133
- code: CLI_DIAGNOSTIC_CODES8.UNSUPPORTED_COMMAND,
3321
+ throw createCliCommandError5({
3322
+ code: CLI_DIAGNOSTIC_CODES12.UNSUPPORTED_COMMAND,
3134
3323
  command,
3135
3324
  detailLines: [
3136
3325
  [
@@ -3145,7 +3334,7 @@ function renderUnsupportedCommand(command) {
3145
3334
  async function renderDoctorJson() {
3146
3335
  const [
3147
3336
  { getDoctorChecks },
3148
- { createCliCommandError: createCliCommandError4, getDoctorFailureDetailLines }
3337
+ { createCliCommandError: createCliCommandError6, getDoctorFailureDetailLines }
3149
3338
  ] = await Promise.all([
3150
3339
  import("@wp-typia/project-tools/cli-doctor"),
3151
3340
  import("@wp-typia/project-tools/cli-diagnostics")
@@ -3155,8 +3344,8 @@ async function renderDoctorJson() {
3155
3344
  checks
3156
3345
  }, null, 2));
3157
3346
  if (checks.some((check) => check.status === "fail")) {
3158
- throw createCliCommandError4({
3159
- code: CLI_DIAGNOSTIC_CODES8.DOCTOR_CHECK_FAILED,
3347
+ throw createCliCommandError6({
3348
+ code: CLI_DIAGNOSTIC_CODES12.DOCTOR_CHECK_FAILED,
3160
3349
  command: "doctor",
3161
3350
  detailLines: getDoctorFailureDetailLines(checks),
3162
3351
  summary: "One or more doctor checks failed."
@@ -3164,94 +3353,8 @@ async function renderDoctorJson() {
3164
3353
  }
3165
3354
  }
3166
3355
  var NODE_FALLBACK_COMMAND_DISPATCHERS = {
3167
- add: async ({
3168
- cwd,
3169
- mergedFlags,
3170
- positionals
3171
- }) => {
3172
- if (!positionals[1]) {
3173
- const { formatAddHelpText } = await import("@wp-typia/project-tools/cli-add");
3174
- printLine(formatAddHelpText());
3175
- throw createCliCommandError3({
3176
- code: CLI_DIAGNOSTIC_CODES8.MISSING_ARGUMENT,
3177
- command: "add",
3178
- detailLines: [
3179
- `\`wp-typia add\` requires <kind>. Usage: wp-typia add ${formatAddKindUsagePlaceholder()} ...`
3180
- ]
3181
- });
3182
- }
3183
- if (mergedFlags.format === "json") {
3184
- let completion;
3185
- try {
3186
- completion = await executeAddCommand({
3187
- cwd,
3188
- emitOutput: false,
3189
- flags: mergedFlags,
3190
- interactive: false,
3191
- kind: positionals[1],
3192
- name: positionals[2]
3193
- });
3194
- } catch (error) {
3195
- throw createCliCommandError3({
3196
- command: "add",
3197
- error
3198
- });
3199
- }
3200
- printLine(JSON.stringify(buildStructuredCompletionSuccessPayload("add", completion, {
3201
- dryRun: Boolean(mergedFlags["dry-run"]),
3202
- kind: positionals[1],
3203
- name: positionals[2],
3204
- projectDir: extractCompletionProjectDir(completion) ?? cwd
3205
- }), null, 2));
3206
- return;
3207
- }
3208
- await executeAddCommand({
3209
- cwd,
3210
- flags: mergedFlags,
3211
- interactive: undefined,
3212
- kind: positionals[1],
3213
- name: positionals[2]
3214
- });
3215
- },
3216
- create: async ({
3217
- cwd,
3218
- mergedFlags,
3219
- positionals
3220
- }) => {
3221
- const projectDir = positionals[1];
3222
- if (!projectDir) {
3223
- throw createCliCommandError3({
3224
- code: CLI_DIAGNOSTIC_CODES8.MISSING_ARGUMENT,
3225
- command: "create",
3226
- detailLines: [
3227
- "`wp-typia create` requires <project-dir>.",
3228
- "`--dry-run` still needs a logical project directory name because wp-typia derives slugs, package names, and planned file paths from it."
3229
- ]
3230
- });
3231
- }
3232
- let completion;
3233
- try {
3234
- completion = await executeCreateCommand({
3235
- cwd,
3236
- emitOutput: mergedFlags.format !== "json",
3237
- flags: mergedFlags,
3238
- interactive: mergedFlags.format === "json" ? false : undefined,
3239
- projectDir
3240
- });
3241
- } catch (error) {
3242
- throw createCliCommandError3({
3243
- command: "create",
3244
- error
3245
- });
3246
- }
3247
- if (mergedFlags.format === "json") {
3248
- printLine(JSON.stringify(buildStructuredCompletionSuccessPayload("create", completion, {
3249
- dryRun: Boolean(mergedFlags["dry-run"]),
3250
- projectDir: extractCompletionProjectDir(completion) ?? projectDir,
3251
- template: typeof mergedFlags.template === "string" ? mergedFlags.template : undefined
3252
- }), null, 2));
3253
- }
3254
- },
3356
+ add: dispatchNodeFallbackAdd,
3357
+ create: dispatchNodeFallbackCreate,
3255
3358
  doctor: async ({ cwd, mergedFlags }) => {
3256
3359
  if (mergedFlags.format === "json") {
3257
3360
  await renderDoctorJson();
@@ -3317,7 +3420,7 @@ var NODE_FALLBACK_COMMAND_DISPATCHERS = {
3317
3420
  }));
3318
3421
  }
3319
3422
  } catch (error) {
3320
- throw createCliCommandError3({
3423
+ throw createCliCommandError5({
3321
3424
  command: "sync",
3322
3425
  error
3323
3426
  });
@@ -3331,8 +3434,8 @@ var NODE_FALLBACK_COMMAND_DISPATCHERS = {
3331
3434
  const templateId = typeof mergedFlags.id === "string" ? mergedFlags.id : positionals[2];
3332
3435
  const resolvedSubcommand = templateId ? "inspect" : subcommand ?? "list";
3333
3436
  if (resolvedSubcommand !== "list" && resolvedSubcommand !== "inspect") {
3334
- throw createCliCommandError3({
3335
- code: CLI_DIAGNOSTIC_CODES8.INVALID_COMMAND,
3437
+ throw createCliCommandError5({
3438
+ code: CLI_DIAGNOSTIC_CODES12.INVALID_COMMAND,
3336
3439
  command: "templates",
3337
3440
  detailLines: [
3338
3441
  `Unknown templates subcommand "${resolvedSubcommand}". Expected list or inspect.`
@@ -3370,7 +3473,7 @@ async function runNodeCli(argv = process.argv.slice(2)) {
3370
3473
  const helpTarget = command === "help" ? subcommand : command;
3371
3474
  const versionRequested = hasFlagBeforeTerminator(cliArgv, "--version") || command === "version";
3372
3475
  if (cliArgv.length === 0) {
3373
- renderGeneralHelp();
3476
+ renderGeneralHelp(printLine);
3374
3477
  process.exitCode = 1;
3375
3478
  return;
3376
3479
  }
@@ -3378,18 +3481,18 @@ async function runNodeCli(argv = process.argv.slice(2)) {
3378
3481
  if (helpTarget) {
3379
3482
  const helpRenderer = NODE_FALLBACK_HELP_RENDERERS[helpTarget];
3380
3483
  if (helpRenderer) {
3381
- helpRenderer();
3484
+ helpRenderer(printLine);
3382
3485
  return;
3383
3486
  }
3384
3487
  if (helpTarget === "help" || helpTarget === "version") {
3385
- renderGeneralHelp();
3488
+ renderGeneralHelp(printLine);
3386
3489
  return;
3387
3490
  }
3388
3491
  } else {
3389
- renderGeneralHelp();
3492
+ renderGeneralHelp(printLine);
3390
3493
  return;
3391
3494
  }
3392
- renderGeneralHelp();
3495
+ renderGeneralHelp(printLine);
3393
3496
  return;
3394
3497
  }
3395
3498
  if (versionRequested) {
@@ -3404,7 +3507,8 @@ async function runNodeCli(argv = process.argv.slice(2)) {
3404
3507
  await commandDispatcher({
3405
3508
  cwd: process.cwd(),
3406
3509
  mergedFlags,
3407
- positionals
3510
+ positionals,
3511
+ printLine
3408
3512
  });
3409
3513
  return;
3410
3514
  }
@@ -3416,7 +3520,7 @@ async function runNodeCliEntrypoint(argv = process.argv.slice(2)) {
3416
3520
  await runNodeCli(argv);
3417
3521
  } catch (error) {
3418
3522
  if (prefersStructuredErrorOutput) {
3419
- const diagnostic = createCliCommandError3({
3523
+ const diagnostic = createCliCommandError5({
3420
3524
  command: resolveCanonicalCommandContext(argv),
3421
3525
  error
3422
3526
  });
@@ -3439,4 +3543,4 @@ export {
3439
3543
  hasFlagBeforeTerminator
3440
3544
  };
3441
3545
 
3442
- //# debugId=5D4E56BAE8A1432964756E2164756E21
3546
+ //# debugId=B5CA87A93189F22464756E2164756E21