wp-typia 0.22.8 → 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.8",
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.8",
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,7 +97,7 @@ var package_default = {
97
97
 
98
98
  // src/node-cli.ts
99
99
  import {
100
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES11,
100
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES12,
101
101
  createCliCommandError as createCliCommandError5,
102
102
  formatCliDiagnosticError,
103
103
  serializeCliDiagnosticError as serializeCliDiagnosticError2
@@ -929,80 +929,18 @@ function extractWpTypiaConfigOverride(argv) {
929
929
 
930
930
  // src/runtime-bridge.ts
931
931
  import {
932
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES7,
933
- createCliDiagnosticCodeError as createCliDiagnosticCodeError6
934
- } from "@wp-typia/project-tools/cli-diagnostics";
935
-
936
- // src/add-kind-registry.ts
937
- import {
938
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES5,
939
- createCliDiagnosticCodeError as createCliDiagnosticCodeError4
932
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES8,
933
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError7
940
934
  } from "@wp-typia/project-tools/cli-diagnostics";
941
935
 
942
936
  // src/add-kind-ids.ts
943
937
  import { ADD_KIND_IDS } from "@wp-typia/project-tools/cli-add-kind-ids";
944
938
 
945
- // src/cli-string-flags.ts
939
+ // src/add-kind-registry-shared.ts
946
940
  import {
947
941
  CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES4,
948
942
  createCliDiagnosticCodeError as createCliDiagnosticCodeError3
949
943
  } from "@wp-typia/project-tools/cli-diagnostics";
950
- function readOptionalCliStringFlagValue(flags, name, mode) {
951
- const value = flags[name];
952
- if (value === undefined || value === null) {
953
- return;
954
- }
955
- if (typeof value !== "string") {
956
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
957
- }
958
- const trimmed = value.trim();
959
- if (trimmed.length === 0) {
960
- if (mode === "strict") {
961
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, `\`--${name}\` requires a value.`);
962
- }
963
- return;
964
- }
965
- return mode === "strict" ? value : trimmed;
966
- }
967
- function readOptionalLooseStringFlag(flags, name) {
968
- return readOptionalCliStringFlagValue(flags, name, "loose");
969
- }
970
- function readOptionalStrictStringFlag(flags, name) {
971
- return readOptionalCliStringFlagValue(flags, name, "strict");
972
- }
973
- function requireStrictStringFlag(flags, name, message) {
974
- const value = readOptionalStrictStringFlag(flags, name);
975
- if (!value) {
976
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, message);
977
- }
978
- return value;
979
- }
980
- function readOptionalPairedStrictStringFlags(flags, leftName, rightName, message) {
981
- const leftValue = readOptionalStrictStringFlag(flags, leftName);
982
- const rightValue = readOptionalStrictStringFlag(flags, rightName);
983
- if (Boolean(leftValue) !== Boolean(rightValue)) {
984
- throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, message);
985
- }
986
- return [leftValue, rightValue];
987
- }
988
-
989
- // src/external-layer-prompt-options.ts
990
- function formatExternalLayerSelectHint(option) {
991
- const details = [
992
- option.description,
993
- option.extends.length > 0 ? `extends ${option.extends.join(", ")}` : undefined
994
- ].filter((value) => typeof value === "string" && value.length > 0);
995
- return details.length > 0 ? details.join(" · ") : undefined;
996
- }
997
- function toExternalLayerPromptOptions(options) {
998
- return options.map((option) => ({
999
- hint: formatExternalLayerSelectHint(option),
1000
- label: option.id,
1001
- value: option.id
1002
- }));
1003
- }
1004
-
1005
- // src/add-kind-registry.ts
1006
944
  var BLOCK_VISIBLE_FIELD_ORDER = [
1007
945
  "kind",
1008
946
  "name",
@@ -1062,7 +1000,7 @@ var NAME_NAMESPACE_VISIBLE_FIELDS = [
1062
1000
  ];
1063
1001
  function requireAddKindName(context, message) {
1064
1002
  if (!context.name) {
1065
- throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.MISSING_ARGUMENT, message);
1003
+ throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.MISSING_ARGUMENT, message);
1066
1004
  }
1067
1005
  return context.name;
1068
1006
  }
@@ -1084,509 +1022,618 @@ function isAddPersistenceTemplate(template) {
1084
1022
  function formatAddBlockTemplateIds(addRuntime) {
1085
1023
  return addRuntime.ADD_BLOCK_TEMPLATE_IDS.join(", ");
1086
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
+ }
1087
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
+ }
1088
1036
  if (context.addRuntime.isAddBlockTemplateId(templateId)) {
1089
1037
  return templateId;
1090
1038
  }
1091
- if (templateId === "query-loop") {
1092
- throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.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.");
1039
+ const mistypedAddBlockTemplateMessage = getMistypedAddBlockTemplateMessage(context.addRuntime, templateId);
1040
+ if (mistypedAddBlockTemplateMessage) {
1041
+ throw createCliDiagnosticCodeError3(CLI_DIAGNOSTIC_CODES4.UNKNOWN_TEMPLATE, mistypedAddBlockTemplateMessage);
1093
1042
  }
1094
- throw createCliDiagnosticCodeError4(CLI_DIAGNOSTIC_CODES5.UNKNOWN_TEMPLATE, `Unknown add-block template "${templateId}". Expected one of: ${formatAddBlockTemplateIds(context.addRuntime)}. Run \`wp-typia templates list\` to inspect available templates.`);
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.`);
1095
1044
  }
1096
- var ADD_KIND_REGISTRY = {
1097
- "admin-view": defineAddKindRegistryEntry({
1098
- completion: {
1099
- nextSteps: (values) => [
1100
- `Review src/admin-views/${values.adminViewSlug}/ and inc/admin-views/${values.adminViewSlug}.php.`,
1101
- "Run your workspace build or dev command to verify the generated DataViews admin screen."
1102
- ],
1103
- summaryLines: (values, projectDir) => [
1104
- `Admin view: ${values.adminViewSlug}`,
1105
- ...values.source ? [`Source: ${values.source}`] : [],
1106
- `Project directory: ${projectDir}`
1107
- ],
1108
- title: "Added DataViews admin screen"
1109
- },
1110
- description: "Add an opt-in DataViews-powered admin screen",
1111
- nameLabel: "Admin view name",
1112
- async prepareExecution(context) {
1113
- 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>].");
1114
- const source = readOptionalStrictStringFlag(context.flags, "source");
1115
- return createNamedExecutionPlan(context, {
1116
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAdminViewCommand({
1117
- adminViewName: name2,
1118
- cwd,
1119
- source
1120
- }),
1121
- getValues: (result) => ({
1122
- adminViewSlug: result.adminViewSlug,
1123
- ...result.source ? { source: result.source } : {}
1124
- }),
1125
- missingNameMessage: "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].",
1126
- name
1127
- });
1128
- },
1129
- sortOrder: 10,
1130
- supportsDryRun: true,
1131
- usage: "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]",
1132
- visibleFieldNames: () => NAME_SOURCE_VISIBLE_FIELDS
1133
- }),
1134
- "binding-source": defineAddKindRegistryEntry({
1135
- completion: {
1136
- nextSteps: (values) => [
1137
- `Review src/bindings/${values.bindingSourceSlug}/server.php and src/bindings/${values.bindingSourceSlug}/editor.ts.`,
1138
- ...values.blockSlug && values.attributeName ? [
1139
- `Review src/blocks/${values.blockSlug}/block.json for the ${values.attributeName} bindable attribute.`
1140
- ] : [],
1141
- "Run your workspace build or dev command to verify the binding source hooks and editor registration."
1142
- ],
1143
- summaryLines: (values, projectDir) => [
1144
- `Binding source: ${values.bindingSourceSlug}`,
1145
- ...values.blockSlug && values.attributeName ? [`Target: ${values.blockSlug}.${values.attributeName}`] : [],
1146
- `Project directory: ${projectDir}`
1147
- ],
1148
- title: "Added binding source"
1149
- },
1150
- description: "Add a shared block bindings source",
1151
- nameLabel: "Binding source name",
1152
- async prepareExecution(context) {
1153
- 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>].");
1154
- const [blockName, attributeName] = readOptionalPairedStrictStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
1155
- return createNamedExecutionPlan(context, {
1156
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBindingSourceCommand({
1157
- attributeName,
1158
- bindingSourceName: name2,
1159
- blockName,
1160
- cwd
1161
- }),
1162
- getValues: (result) => ({
1163
- ...result.attributeName ? { attributeName: result.attributeName } : {},
1164
- ...result.blockSlug ? { blockSlug: result.blockSlug } : {},
1165
- bindingSourceSlug: result.bindingSourceSlug
1166
- }),
1167
- missingNameMessage: "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].",
1168
- name
1169
- });
1170
- },
1171
- sortOrder: 70,
1172
- supportsDryRun: true,
1173
- usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]",
1174
- visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS
1175
- }),
1176
- block: defineAddKindRegistryEntry({
1177
- completion: {
1178
- nextSteps: () => [
1179
- "Review the generated sources under src/blocks/ and the updated scripts/block-config.ts entry.",
1180
- "Run your workspace build or dev command to verify the new scaffolded block family."
1181
- ],
1182
- summaryLines: (values, projectDir) => [
1183
- `Blocks: ${values.blockSlugs}`,
1184
- `Template family: ${values.templateId}`,
1185
- `Project directory: ${projectDir}`
1186
- ],
1187
- title: "Added workspace block"
1188
- },
1189
- description: "Add a real block slice",
1190
- hiddenStringSubmitFields: ["external-layer-id", "external-layer-source"],
1191
- nameLabel: "Block name",
1192
- async prepareExecution(context) {
1193
- const name = requireAddKindName(context, "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]");
1194
- const externalLayerId = readOptionalStrictStringFlag(context.flags, "external-layer-id");
1195
- const externalLayerSource = readOptionalStrictStringFlag(context.flags, "external-layer-source");
1196
- const shouldPromptForLayerSelection = Boolean(externalLayerSource) && !Boolean(externalLayerId) && context.isInteractiveSession;
1197
- const selectPrompt = shouldPromptForLayerSelection ? await context.getOrCreatePrompt() : undefined;
1198
- const alternateRenderTargets = readOptionalStrictStringFlag(context.flags, "alternate-render-targets");
1199
- const dataStorageMode = readOptionalStrictStringFlag(context.flags, "data-storage");
1200
- const innerBlocksPreset = readOptionalStrictStringFlag(context.flags, "inner-blocks-preset");
1201
- const persistencePolicy = readOptionalStrictStringFlag(context.flags, "persistence-policy");
1202
- const requestedTemplateId = readOptionalStrictStringFlag(context.flags, "template");
1203
- let resolvedTemplateId = requestedTemplateId ? assertAddBlockTemplateId(context, requestedTemplateId) : undefined;
1204
- if (!resolvedTemplateId && context.isInteractiveSession) {
1205
- const templatePrompt = await context.getOrCreatePrompt();
1206
- resolvedTemplateId = await templatePrompt.select("Select a block template", context.addRuntime.ADD_BLOCK_TEMPLATE_IDS.map((templateId) => ({
1207
- hint: `Scaffold the ${templateId} block family`,
1208
- label: templateId,
1209
- value: templateId
1210
- })), 1);
1211
- }
1212
- resolvedTemplateId ??= "basic";
1213
- return createNamedExecutionPlan(context, {
1214
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockCommand({
1215
- alternateRenderTargets,
1216
- blockName: name2,
1217
- cwd,
1218
- dataStorageMode,
1219
- externalLayerId,
1220
- externalLayerSource,
1221
- innerBlocksPreset,
1222
- persistencePolicy,
1223
- selectExternalLayerId: selectPrompt ? (options) => selectPrompt.select("Select an external layer", toExternalLayerPromptOptions(options), 1) : undefined,
1224
- templateId: resolvedTemplateId
1225
- }),
1226
- getValues: (result) => ({
1227
- blockSlugs: result.blockSlugs.join(", "),
1228
- templateId: result.templateId
1229
- }),
1230
- getWarnings: (result) => result.warnings,
1231
- missingNameMessage: "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]",
1232
- name,
1233
- warnLine: context.warnLine
1234
- });
1235
- },
1236
- sortOrder: 20,
1237
- supportsDryRun: true,
1238
- 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]",
1239
- visibleFieldNames: ({ template }) => BLOCK_VISIBLE_FIELD_ORDER.filter((fieldName) => {
1240
- if (fieldName === "alternate-render-targets") {
1241
- return isAddPersistenceTemplate(template);
1242
- }
1243
- if (fieldName === "inner-blocks-preset") {
1244
- return template === "compound";
1245
- }
1246
- if (fieldName === "data-storage" || fieldName === "persistence-policy") {
1247
- return isAddPersistenceTemplate(template);
1248
- }
1249
- return true;
1250
- })
1251
- }),
1252
- ability: defineAddKindRegistryEntry({
1253
- completion: {
1254
- nextSteps: (values) => [
1255
- `Review src/abilities/${values.abilitySlug}/ and inc/abilities/${values.abilitySlug}.php.`,
1256
- "Run `wp-typia sync` or `npm run sync-abilities -- --check` and then your workspace build/dev command to verify the generated workflow ability."
1257
- ],
1258
- summaryLines: (values, projectDir) => [
1259
- `Ability: ${values.abilitySlug}`,
1260
- `Project directory: ${projectDir}`
1261
- ],
1262
- title: "Added workflow ability"
1263
- },
1264
- description: "Add a typed server/client workflow ability scaffold",
1265
- nameLabel: "Ability name",
1266
- async prepareExecution(context) {
1267
- return createNamedExecutionPlan(context, {
1268
- execute: ({ cwd, name }) => context.addRuntime.runAddAbilityCommand({
1269
- abilityName: name,
1270
- cwd
1271
- }),
1272
- getValues: (result) => ({
1273
- abilitySlug: result.abilitySlug
1274
- }),
1275
- getWarnings: (result) => result.warnings,
1276
- missingNameMessage: "`wp-typia add ability` requires <name>. Usage: wp-typia add ability <name>.",
1277
- warnLine: context.warnLine
1278
- });
1279
- },
1280
- sortOrder: 90,
1281
- supportsDryRun: true,
1282
- usage: "wp-typia add ability <name> [--dry-run]",
1283
- visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1284
- }),
1285
- "editor-plugin": defineAddKindRegistryEntry({
1286
- completion: {
1287
- nextSteps: (values) => [
1288
- `Review src/editor-plugins/${values.editorPluginSlug}/.`,
1289
- "Run your workspace build or dev command to verify the new editor plugin registration."
1290
- ],
1291
- summaryLines: (values, projectDir) => [
1292
- `Editor plugin: ${values.editorPluginSlug}`,
1293
- `Slot: ${values.slot}`,
1294
- `Project directory: ${projectDir}`
1295
- ],
1296
- title: "Added editor plugin"
1297
- },
1298
- description: "Add a slot-aware document editor extension shell",
1299
- nameLabel: "Editor plugin name",
1300
- async prepareExecution(context) {
1301
- const name = requireAddKindName(context, "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].");
1302
- const slot = readOptionalStrictStringFlag(context.flags, "slot");
1303
- return createNamedExecutionPlan(context, {
1304
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddEditorPluginCommand({
1305
- cwd,
1306
- editorPluginName: name2,
1307
- slot
1308
- }),
1309
- getValues: (result) => ({
1310
- editorPluginSlug: result.editorPluginSlug,
1311
- slot: result.slot
1312
- }),
1313
- missingNameMessage: "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].",
1314
- name
1315
- });
1316
- },
1317
- sortOrder: 120,
1318
- supportsDryRun: true,
1319
- usage: "wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>] [--dry-run]",
1320
- visibleFieldNames: () => NAME_SLOT_VISIBLE_FIELDS
1321
- }),
1322
- "hooked-block": defineAddKindRegistryEntry({
1323
- completion: {
1324
- nextSteps: (values) => [
1325
- `Review src/blocks/${values.blockSlug}/block.json for the new blockHooks entry.`,
1326
- "Run your workspace build or dev command to verify the updated hooked-block metadata."
1327
- ],
1328
- summaryLines: (values, projectDir) => [
1329
- `Block: ${values.blockSlug}`,
1330
- `Anchor: ${values.anchorBlockName}`,
1331
- `Position: ${values.position}`,
1332
- `Project directory: ${projectDir}`
1333
- ],
1334
- title: "Added blockHooks metadata"
1335
- },
1336
- description: "Add block.json hook metadata to an existing block",
1337
- nameLabel: "Target block",
1338
- async prepareExecution(context) {
1339
- 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>.");
1340
- const anchorBlockName = requireStrictStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
1341
- const position = requireStrictStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
1342
- return createNamedExecutionPlan(context, {
1343
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddHookedBlockCommand({
1344
- anchorBlockName,
1345
- blockName: name2,
1346
- cwd,
1347
- position
1348
- }),
1349
- getValues: (result) => ({
1350
- anchorBlockName: result.anchorBlockName,
1351
- blockSlug: result.blockSlug,
1352
- position: result.position
1353
- }),
1354
- 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>.",
1355
- name
1356
- });
1357
- },
1358
- sortOrder: 110,
1359
- supportsDryRun: true,
1360
- usage: "wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild> [--dry-run]",
1361
- visibleFieldNames: () => NAME_ANCHOR_POSITION_VISIBLE_FIELDS
1362
- }),
1363
- pattern: defineAddKindRegistryEntry({
1364
- completion: {
1365
- nextSteps: (values) => [
1366
- `Review src/patterns/${values.patternSlug}.php.`,
1367
- "Run your workspace build or dev command to verify the new pattern registration."
1368
- ],
1369
- summaryLines: (values, projectDir) => [
1370
- `Pattern: ${values.patternSlug}`,
1371
- `Project directory: ${projectDir}`
1372
- ],
1373
- title: "Added workspace pattern"
1374
- },
1375
- description: "Add a PHP block pattern shell",
1376
- nameLabel: "Pattern name",
1377
- async prepareExecution(context) {
1378
- return createNamedExecutionPlan(context, {
1379
- execute: ({ cwd, name }) => context.addRuntime.runAddPatternCommand({
1380
- cwd,
1381
- patternName: name
1382
- }),
1383
- getValues: (result) => ({
1384
- patternSlug: result.patternSlug
1385
- }),
1386
- missingNameMessage: "`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>."
1387
- });
1388
- },
1389
- sortOrder: 60,
1390
- supportsDryRun: true,
1391
- usage: "wp-typia add pattern <name> [--dry-run]",
1392
- visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
1393
- }),
1394
- style: defineAddKindRegistryEntry({
1395
- completion: {
1396
- nextSteps: (values) => [
1397
- `Review src/blocks/${values.blockSlug}/styles/${values.styleSlug}.ts.`,
1398
- "Run your workspace build or dev command to verify the new block style registration."
1399
- ],
1400
- summaryLines: (values, projectDir) => [
1401
- `Block style: ${values.styleSlug}`,
1402
- `Target block: ${values.blockSlug}`,
1403
- `Project directory: ${projectDir}`
1404
- ],
1405
- title: "Added block style"
1406
- },
1407
- description: "Add a Block Styles registration to an existing block",
1408
- nameLabel: "Style name",
1409
- async prepareExecution(context) {
1410
- const name = requireAddKindName(context, "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.");
1411
- const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
1412
- return createNamedExecutionPlan(context, {
1413
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockStyleCommand({
1414
- blockName: blockSlug,
1415
- cwd,
1416
- styleName: name2
1417
- }),
1418
- getValues: (result) => ({
1419
- blockSlug: result.blockSlug,
1420
- styleSlug: result.styleSlug
1421
- }),
1422
- missingNameMessage: "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.",
1423
- name
1424
- });
1425
- },
1426
- sortOrder: 40,
1427
- supportsDryRun: true,
1428
- usage: "wp-typia add style <name> --block <block-slug> [--dry-run]",
1429
- visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
1430
- }),
1431
- transform: defineAddKindRegistryEntry({
1432
- completion: {
1433
- nextSteps: (values) => [
1434
- `Review src/blocks/${values.blockSlug}/transforms/${values.transformSlug}.ts.`,
1435
- "Run your workspace build or dev command to verify the new block transform registration."
1436
- ],
1437
- summaryLines: (values, projectDir) => [
1438
- `Block transform: ${values.transformSlug}`,
1439
- `From: ${values.fromBlockName}`,
1440
- `To: ${values.toBlockName}`,
1441
- `Project directory: ${projectDir}`
1442
- ],
1443
- title: "Added block transform"
1444
- },
1445
- description: "Add a block-to-block transform into a workspace block",
1446
- nameLabel: "Transform name",
1447
- async prepareExecution(context) {
1448
- 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>.");
1449
- const fromBlockName = requireStrictStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
1450
- const toBlockName = requireStrictStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
1451
- return createNamedExecutionPlan(context, {
1452
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddBlockTransformCommand({
1453
- cwd,
1454
- fromBlockName,
1455
- toBlockName,
1456
- transformName: name2
1457
- }),
1458
- getValues: (result) => ({
1459
- blockSlug: result.blockSlug,
1460
- fromBlockName: result.fromBlockName,
1461
- toBlockName: result.toBlockName,
1462
- transformSlug: result.transformSlug
1463
- }),
1464
- missingNameMessage: "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.",
1465
- name
1466
- });
1467
- },
1468
- sortOrder: 50,
1469
- supportsDryRun: true,
1470
- usage: "wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]",
1471
- visibleFieldNames: () => NAME_FROM_TO_VISIBLE_FIELDS
1472
- }),
1473
- "rest-resource": defineAddKindRegistryEntry({
1474
- completion: {
1475
- nextSteps: (values) => [
1476
- `Review src/rest/${values.restResourceSlug}/ and inc/rest/${values.restResourceSlug}.php.`,
1477
- "Run your workspace build or dev command to verify the generated REST resource contract."
1478
- ],
1479
- summaryLines: (values, projectDir) => [
1480
- `REST resource: ${values.restResourceSlug}`,
1481
- `Namespace: ${values.namespace}`,
1482
- `Methods: ${values.methods}`,
1483
- `Project directory: ${projectDir}`
1484
- ],
1485
- title: "Added plugin-level REST resource"
1486
- },
1487
- description: "Add a plugin-level typed REST resource",
1488
- nameLabel: "REST resource name",
1489
- async prepareExecution(context) {
1490
- 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>].");
1491
- const methods = readOptionalStrictStringFlag(context.flags, "methods");
1492
- const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
1493
- return createNamedExecutionPlan(context, {
1494
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddRestResourceCommand({
1495
- cwd,
1496
- methods,
1497
- namespace,
1498
- restResourceName: name2
1499
- }),
1500
- getValues: (result) => ({
1501
- methods: result.methods.join(", "),
1502
- namespace: result.namespace,
1503
- restResourceSlug: result.restResourceSlug
1504
- }),
1505
- missingNameMessage: "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].",
1506
- name
1507
- });
1508
- },
1509
- sortOrder: 80,
1510
- supportsDryRun: true,
1511
- usage: "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]",
1512
- visibleFieldNames: () => NAME_NAMESPACE_METHODS_VISIBLE_FIELDS
1513
- }),
1514
- "ai-feature": defineAddKindRegistryEntry({
1515
- completion: {
1516
- nextSteps: (values) => [
1517
- `Review src/ai-features/${values.aiFeatureSlug}/ and inc/ai-features/${values.aiFeatureSlug}.php.`,
1518
- "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."
1519
- ],
1520
- summaryLines: (values, projectDir) => [
1521
- `AI feature: ${values.aiFeatureSlug}`,
1522
- `Namespace: ${values.namespace}`,
1523
- `Project directory: ${projectDir}`
1524
- ],
1525
- title: "Added server-only AI feature"
1526
- },
1527
- description: "Add a server-owned WordPress AI feature endpoint",
1528
- nameLabel: "AI feature name",
1529
- async prepareExecution(context) {
1530
- const name = requireAddKindName(context, "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].");
1531
- const namespace = readOptionalStrictStringFlag(context.flags, "namespace");
1532
- return createNamedExecutionPlan(context, {
1533
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAiFeatureCommand({
1534
- aiFeatureName: name2,
1535
- cwd,
1536
- namespace
1537
- }),
1538
- getValues: (result) => ({
1539
- aiFeatureSlug: result.aiFeatureSlug,
1540
- namespace: result.namespace
1541
- }),
1542
- getWarnings: (result) => result.warnings,
1543
- missingNameMessage: "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].",
1544
- name,
1545
- warnLine: context.warnLine
1546
- });
1547
- },
1548
- sortOrder: 100,
1549
- supportsDryRun: true,
1550
- usage: "wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]",
1551
- visibleFieldNames: () => NAME_NAMESPACE_VISIBLE_FIELDS
1552
- }),
1553
- variation: defineAddKindRegistryEntry({
1554
- completion: {
1555
- nextSteps: (values) => [
1556
- `Review src/blocks/${values.blockSlug}/variations/${values.variationSlug}.ts.`,
1557
- "Run your workspace build or dev command to pick up the new variation."
1558
- ],
1559
- summaryLines: (values, projectDir) => [
1560
- `Variation: ${values.variationSlug}`,
1561
- `Target block: ${values.blockSlug}`,
1562
- `Project directory: ${projectDir}`
1563
- ],
1564
- title: "Added workspace variation"
1565
- },
1566
- description: "Add a variation to an existing block",
1567
- nameLabel: "Variation name",
1568
- async prepareExecution(context) {
1569
- const name = requireAddKindName(context, "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
1570
- const blockSlug = requireStrictStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
1571
- return createNamedExecutionPlan(context, {
1572
- execute: ({ cwd, name: name2 }) => context.addRuntime.runAddVariationCommand({
1573
- blockName: blockSlug,
1574
- cwd,
1575
- variationName: name2
1576
- }),
1577
- getValues: (result) => ({
1578
- blockSlug: result.blockSlug,
1579
- variationSlug: result.variationSlug
1580
- }),
1581
- missingNameMessage: "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>",
1582
- name
1583
- });
1584
- },
1585
- sortOrder: 30,
1586
- supportsDryRun: true,
1587
- usage: "wp-typia add variation <name> --block <block-slug> [--dry-run]",
1588
- visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
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;
1589
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
1590
1637
  };
1591
1638
  function isAddKindId(value) {
1592
1639
  return typeof value === "string" && ADD_KIND_IDS.includes(value);
@@ -1612,6 +1659,27 @@ function supportsAddKindDryRun(kind) {
1612
1659
  return ADD_KIND_REGISTRY[kind].supportsDryRun;
1613
1660
  }
1614
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
  }
@@ -2483,16 +2567,16 @@ async function executeAddCommand({
2483
2567
  const addRuntime = await loadCliAddRuntime();
2484
2568
  const isInteractiveSession = interactive ?? isInteractiveTerminal();
2485
2569
  if (!kind) {
2486
- if (emitOutput) {
2570
+ if (shouldPrintMissingAddKindHelp({ emitOutput })) {
2487
2571
  printLine(addRuntime.formatAddHelpText());
2488
2572
  }
2489
- 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());
2490
2574
  }
2491
2575
  if (!isAddKindId(kind)) {
2492
- 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()}.`);
2493
2577
  }
2494
2578
  if (dryRun && !supportsAddKindDryRun(kind)) {
2495
- 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.`);
2496
2580
  }
2497
2581
  const executionContext = {
2498
2582
  addRuntime,
@@ -2538,22 +2622,22 @@ async function executeTemplatesCommand({ flags }, printLine = console.log) {
2538
2622
  const subcommand = flags.subcommand ?? "list";
2539
2623
  if (subcommand === "list") {
2540
2624
  for (const template of listTemplates()) {
2541
- printBlock([formatTemplateSummary(template), formatTemplateFeatures(template)], printLine);
2625
+ printBlock(printLine, [formatTemplateSummary(template), formatTemplateFeatures(template)]);
2542
2626
  }
2543
2627
  return;
2544
2628
  }
2545
2629
  if (subcommand === "inspect") {
2546
2630
  if (!flags.id) {
2547
- 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>.");
2548
2632
  }
2549
2633
  const template = getTemplateById(flags.id);
2550
2634
  if (!template) {
2551
- throw createCliDiagnosticCodeError6(CLI_DIAGNOSTIC_CODES7.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
2635
+ throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `Unknown template "${flags.id}".`);
2552
2636
  }
2553
- printBlock([formatTemplateDetails(template)], printLine);
2637
+ printBlock(printLine, [formatTemplateDetails(template)]);
2554
2638
  return;
2555
2639
  }
2556
- 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.`);
2557
2641
  }
2558
2642
  async function executeInitCommand({ apply, cwd, packageManager, projectDir }, options = {}) {
2559
2643
  try {
@@ -2643,8 +2727,8 @@ async function executeMigrateCommand({
2643
2727
  // src/command-contract.ts
2644
2728
  import path4 from "node:path";
2645
2729
  import {
2646
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES8,
2647
- createCliDiagnosticCodeError as createCliDiagnosticCodeError7
2730
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES9,
2731
+ createCliDiagnosticCodeError as createCliDiagnosticCodeError8
2648
2732
  } from "@wp-typia/project-tools/cli-diagnostics";
2649
2733
 
2650
2734
  // src/command-registry.ts
@@ -2915,10 +2999,10 @@ function looksLikeStructuredProjectInput(value) {
2915
2999
  function assertPositionalAliasProjectDir(projectDir) {
2916
3000
  const normalizedProjectDir = path4.normalize(projectDir).replace(/[\\/]+$/u, "") || path4.normalize(projectDir);
2917
3001
  if (normalizedProjectDir === "." || normalizedProjectDir === "..") {
2918
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `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.`);
2919
3003
  }
2920
3004
  if (looksLikeStructuredProjectInput(projectDir)) {
2921
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, `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}\`.`);
2922
3006
  }
2923
3007
  }
2924
3008
  function normalizeWpTypiaArgv(argv) {
@@ -2932,7 +3016,7 @@ function normalizeWpTypiaArgv(argv) {
2932
3016
  return argv;
2933
3017
  }
2934
3018
  if (firstPositional === "migrations") {
2935
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.INVALID_ARGUMENT, "`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.");
2936
3020
  }
2937
3021
  if (isReservedTopLevelCommandName(firstPositional)) {
2938
3022
  assertStringOptionValues(argv);
@@ -2940,7 +3024,7 @@ function normalizeWpTypiaArgv(argv) {
2940
3024
  }
2941
3025
  if (positionalIndexes.length > 1) {
2942
3026
  const extraPositionals = positionalIndexes.slice(1).map((index) => argv[index]).filter((value) => typeof value === "string" && value.length > 0);
2943
- throw createCliDiagnosticCodeError7(CLI_DIAGNOSTIC_CODES8.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(", ")}.`);
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(", ")}.`);
2944
3028
  }
2945
3029
  assertPositionalAliasProjectDir(firstPositional);
2946
3030
  const normalizedArgv = [
@@ -2954,7 +3038,7 @@ function normalizeWpTypiaArgv(argv) {
2954
3038
 
2955
3039
  // src/node-fallback/dispatchers/add.ts
2956
3040
  import {
2957
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES9,
3041
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES10,
2958
3042
  createCliCommandError as createCliCommandError3
2959
3043
  } from "@wp-typia/project-tools/cli-diagnostics";
2960
3044
  async function dispatchNodeFallbackAdd({
@@ -2964,16 +3048,14 @@ async function dispatchNodeFallbackAdd({
2964
3048
  printLine
2965
3049
  }) {
2966
3050
  if (!positionals[1]) {
2967
- if (mergedFlags.format !== "json") {
3051
+ if (shouldPrintMissingAddKindHelp({ format: mergedFlags.format })) {
2968
3052
  const { formatAddHelpText } = await import("@wp-typia/project-tools/cli-add");
2969
3053
  printLine(formatAddHelpText());
2970
3054
  }
2971
3055
  throw createCliCommandError3({
2972
- code: CLI_DIAGNOSTIC_CODES9.MISSING_ARGUMENT,
3056
+ code: CLI_DIAGNOSTIC_CODES10.MISSING_ARGUMENT,
2973
3057
  command: "add",
2974
- detailLines: [
2975
- `\`wp-typia add\` requires <kind>. Usage: wp-typia add ${formatAddKindUsagePlaceholder()} ...`
2976
- ]
3058
+ detailLines: buildMissingAddKindDetailLines()
2977
3059
  });
2978
3060
  }
2979
3061
  if (mergedFlags.format === "json") {
@@ -3012,7 +3094,7 @@ async function dispatchNodeFallbackAdd({
3012
3094
 
3013
3095
  // src/node-fallback/dispatchers/create.ts
3014
3096
  import {
3015
- CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES10,
3097
+ CLI_DIAGNOSTIC_CODES as CLI_DIAGNOSTIC_CODES11,
3016
3098
  createCliCommandError as createCliCommandError4
3017
3099
  } from "@wp-typia/project-tools/cli-diagnostics";
3018
3100
  async function dispatchNodeFallbackCreate({
@@ -3024,12 +3106,9 @@ async function dispatchNodeFallbackCreate({
3024
3106
  const projectDir = positionals[1];
3025
3107
  if (!projectDir) {
3026
3108
  throw createCliCommandError4({
3027
- code: CLI_DIAGNOSTIC_CODES10.MISSING_ARGUMENT,
3109
+ code: CLI_DIAGNOSTIC_CODES11.MISSING_ARGUMENT,
3028
3110
  command: "create",
3029
- detailLines: [
3030
- "`wp-typia create` requires <project-dir>.",
3031
- "`--dry-run` still needs a logical project directory name because wp-typia derives slugs, package names, and planned file paths from it."
3032
- ]
3111
+ detailLines: buildMissingCreateProjectDirDetailLines()
3033
3112
  });
3034
3113
  }
3035
3114
  let completion;
@@ -3064,13 +3143,8 @@ var NODE_FALLBACK_RUNTIME_SUMMARY_LINES = [
3064
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}`,
3065
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."
3066
3145
  ];
3067
- function printBlock2(printLine, lines) {
3068
- for (const line of lines) {
3069
- printLine(line);
3070
- }
3071
- }
3072
3146
  function renderGeneralHelp(printLine) {
3073
- printBlock2(printLine, [
3147
+ printBlock(printLine, [
3074
3148
  `wp-typia ${package_default.version}`,
3075
3149
  "",
3076
3150
  "Canonical CLI package for wp-typia scaffolding and project workflows.",
@@ -3088,7 +3162,7 @@ function renderGeneralHelp(printLine) {
3088
3162
  ]);
3089
3163
  }
3090
3164
  function renderNodeFallbackCommandHelp(printLine, config) {
3091
- printBlock2(printLine, [
3165
+ printBlock(printLine, [
3092
3166
  config.heading,
3093
3167
  "",
3094
3168
  ...NODE_FALLBACK_RUNTIME_SUMMARY_LINES,
@@ -3226,7 +3300,7 @@ function renderTemplatesJson(flags, subcommand) {
3226
3300
  const templateId = flags.id;
3227
3301
  if (!templateId) {
3228
3302
  throw createCliCommandError5({
3229
- code: CLI_DIAGNOSTIC_CODES11.MISSING_ARGUMENT,
3303
+ code: CLI_DIAGNOSTIC_CODES12.MISSING_ARGUMENT,
3230
3304
  command: "templates",
3231
3305
  detailLines: ["`wp-typia templates inspect` requires <template-id>."]
3232
3306
  });
@@ -3234,7 +3308,7 @@ function renderTemplatesJson(flags, subcommand) {
3234
3308
  const template = getTemplateById(templateId);
3235
3309
  if (!template) {
3236
3310
  throw createCliCommandError5({
3237
- code: CLI_DIAGNOSTIC_CODES11.INVALID_ARGUMENT,
3311
+ code: CLI_DIAGNOSTIC_CODES12.INVALID_ARGUMENT,
3238
3312
  command: "templates",
3239
3313
  detailLines: [`Unknown template "${templateId}".`]
3240
3314
  });
@@ -3245,7 +3319,7 @@ function renderTemplatesJson(flags, subcommand) {
3245
3319
  }
3246
3320
  function renderUnsupportedCommand(command) {
3247
3321
  throw createCliCommandError5({
3248
- code: CLI_DIAGNOSTIC_CODES11.UNSUPPORTED_COMMAND,
3322
+ code: CLI_DIAGNOSTIC_CODES12.UNSUPPORTED_COMMAND,
3249
3323
  command,
3250
3324
  detailLines: [
3251
3325
  [
@@ -3271,7 +3345,7 @@ async function renderDoctorJson() {
3271
3345
  }, null, 2));
3272
3346
  if (checks.some((check) => check.status === "fail")) {
3273
3347
  throw createCliCommandError6({
3274
- code: CLI_DIAGNOSTIC_CODES11.DOCTOR_CHECK_FAILED,
3348
+ code: CLI_DIAGNOSTIC_CODES12.DOCTOR_CHECK_FAILED,
3275
3349
  command: "doctor",
3276
3350
  detailLines: getDoctorFailureDetailLines(checks),
3277
3351
  summary: "One or more doctor checks failed."
@@ -3361,7 +3435,7 @@ var NODE_FALLBACK_COMMAND_DISPATCHERS = {
3361
3435
  const resolvedSubcommand = templateId ? "inspect" : subcommand ?? "list";
3362
3436
  if (resolvedSubcommand !== "list" && resolvedSubcommand !== "inspect") {
3363
3437
  throw createCliCommandError5({
3364
- code: CLI_DIAGNOSTIC_CODES11.INVALID_COMMAND,
3438
+ code: CLI_DIAGNOSTIC_CODES12.INVALID_COMMAND,
3365
3439
  command: "templates",
3366
3440
  detailLines: [
3367
3441
  `Unknown templates subcommand "${resolvedSubcommand}". Expected list or inspect.`
@@ -3469,4 +3543,4 @@ export {
3469
3543
  hasFlagBeforeTerminator
3470
3544
  };
3471
3545
 
3472
- //# debugId=8C4AF690141E04CA64756E2164756E21
3546
+ //# debugId=B5CA87A93189F22464756E2164756E21