wp-typia 0.20.3 → 0.20.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35481,7 +35481,10 @@ function inferCliDiagnosticCode(options) {
35481
35481
  if (/requires <|requires --|requires a value/u.test(haystack)) {
35482
35482
  return CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT;
35483
35483
  }
35484
- if (/Unknown .*subcommand|Unknown add kind|Unknown template|removed in favor|does not support|The Bun-free fallback runtime does not support|The positional alias only accepts/u.test(haystack)) {
35484
+ if (/Unknown (?:add-block )?template\s+(?:"|\\")/u.test(haystack)) {
35485
+ return CLI_DIAGNOSTIC_CODES.UNKNOWN_TEMPLATE;
35486
+ }
35487
+ if (/Unknown .*subcommand|Unknown add kind|removed in favor|does not support|The Bun-free fallback runtime does not support|The positional alias only accepts/u.test(haystack)) {
35485
35488
  return haystack.includes("does not support") || haystack.includes("The Bun-free fallback runtime does not support") ? CLI_DIAGNOSTIC_CODES.UNSUPPORTED_COMMAND : CLI_DIAGNOSTIC_CODES.INVALID_COMMAND;
35486
35489
  }
35487
35490
  if (/Invalid |must start with|cannot hook|cannot nest|cannot use|cannot be|already defines|already exists|Expected one of/u.test(haystack)) {
@@ -35577,6 +35580,7 @@ var init_cli_diagnostics = __esm(() => {
35577
35580
  OUTSIDE_PROJECT_ROOT: "outside-project-root",
35578
35581
  TEMPLATE_SOURCE_TIMEOUT: "template-source-timeout",
35579
35582
  TEMPLATE_SOURCE_TOO_LARGE: "template-source-too-large",
35583
+ UNKNOWN_TEMPLATE: "unknown-template",
35580
35584
  UNSUPPORTED_COMMAND: "unsupported-command"
35581
35585
  };
35582
35586
  DEFAULT_CLI_FAILURE_SUMMARIES = {
@@ -223023,6 +223027,13 @@ import { promises as fsp13 } from "fs";
223023
223027
  import { createRequire as createRequire3 } from "module";
223024
223028
  import path43 from "path";
223025
223029
  import { spawnSync as spawnSync3 } from "child_process";
223030
+ function getUnknownNpmTemplateMessage(templateId) {
223031
+ return [
223032
+ `Unknown template "${templateId}". Expected one of: ${USER_FACING_TEMPLATE_IDS.join(", ")}.`,
223033
+ "Run `wp-typia templates list` to inspect available templates.",
223034
+ "If you meant an npm template package, verify the package name and configured npm registry."
223035
+ ].join(" ");
223036
+ }
223026
223037
  function selectRegistryVersion(metadata2, locator) {
223027
223038
  const distTags = isPlainObject3(metadata2["dist-tags"]) ? metadata2["dist-tags"] : {};
223028
223039
  const versions2 = isPlainObject3(metadata2.versions) ? metadata2.versions : {};
@@ -223061,6 +223072,9 @@ async function fetchNpmTemplateSource(locator) {
223061
223072
  label: metadataLabel
223062
223073
  });
223063
223074
  if (!metadataResponse.ok) {
223075
+ if (metadataResponse.status === 404) {
223076
+ throw new Error(getUnknownNpmTemplateMessage(locator.raw));
223077
+ }
223064
223078
  throw new Error(`Failed to fetch npm template metadata for ${locator.raw}: ${metadataResponse.status}`);
223065
223079
  }
223066
223080
  const metadata2 = await readJsonResponseWithLimit(metadataResponse, {
@@ -223253,7 +223267,7 @@ async function resolveTemplateSeed(locator, cwd) {
223253
223267
  }
223254
223268
  return fetchNpmTemplateSource(locator.locator);
223255
223269
  }
223256
- var import_semver;
223270
+ var import_semver, USER_FACING_TEMPLATE_IDS;
223257
223271
  var init_template_source_seeds = __esm(() => {
223258
223272
  init_index_min();
223259
223273
  init_external_template_guards();
@@ -223261,6 +223275,10 @@ var init_template_source_seeds = __esm(() => {
223261
223275
  init_object_utils();
223262
223276
  init_temp_roots();
223263
223277
  import_semver = __toESM(require_semver2(), 1);
223278
+ USER_FACING_TEMPLATE_IDS = [
223279
+ ...TEMPLATE_IDS,
223280
+ OFFICIAL_WORKSPACE_TEMPLATE_ALIAS
223281
+ ];
223264
223282
  });
223265
223283
 
223266
223284
  // ../wp-typia-project-tools/src/runtime/cli-validation.ts
@@ -228275,6 +228293,7 @@ var init_block_generator_service = __esm(() => {
228275
228293
 
228276
228294
  // ../wp-typia-project-tools/src/runtime/scaffold-answer-resolution.ts
228277
228295
  import { execSync as execSync4 } from "child_process";
228296
+ import path45 from "path";
228278
228297
  function detectAuthor() {
228279
228298
  try {
228280
228299
  return execSync4("git config user.name", {
@@ -228325,8 +228344,14 @@ function normalizeQueryPostType(value2) {
228325
228344
  function normalizeTemplateSelection(templateId) {
228326
228345
  return templateId === WORKSPACE_TEMPLATE_ALIAS ? OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE : templateId;
228327
228346
  }
228347
+ function looksLikeWindowsAbsoluteTemplatePath(templateId) {
228348
+ return /^[a-z]:[\\/]/iu.test(templateId) || /^\\\\[^\\]+\\[^\\]+/u.test(templateId);
228349
+ }
228350
+ function looksLikeExplicitNonNpmExternalTemplateLocator(templateId) {
228351
+ return path45.isAbsolute(templateId) || looksLikeWindowsAbsoluteTemplatePath(templateId) || templateId.startsWith("./") || templateId.startsWith("../") || templateId.startsWith("@") || templateId.startsWith("github:") || templateId.includes("/");
228352
+ }
228328
228353
  function looksLikeExplicitExternalTemplateLocator(templateId) {
228329
- return templateId.startsWith("./") || templateId.startsWith("../") || templateId.startsWith("/") || templateId.startsWith("@") || templateId.startsWith("github:") || templateId.includes("/");
228354
+ return looksLikeExplicitNonNpmExternalTemplateLocator(templateId) || parseNpmTemplateLocator(templateId) !== null;
228330
228355
  }
228331
228356
  function getEditDistance(left, right) {
228332
228357
  const previous = Array.from({ length: right.length + 1 }, (_3, index) => index);
@@ -228345,7 +228370,7 @@ function getEditDistance(left, right) {
228345
228370
  }
228346
228371
  function findMistypedBuiltInTemplateSuggestion(templateId) {
228347
228372
  const normalizedTemplateId = templateId.trim().toLowerCase();
228348
- if (normalizedTemplateId.length === 0 || looksLikeExplicitExternalTemplateLocator(normalizedTemplateId)) {
228373
+ if (normalizedTemplateId.length === 0 || looksLikeExplicitNonNpmExternalTemplateLocator(normalizedTemplateId)) {
228349
228374
  return null;
228350
228375
  }
228351
228376
  let bestCandidate = null;
@@ -228368,6 +228393,13 @@ function getMistypedBuiltInTemplateMessage(templateId) {
228368
228393
  const suggestionDescription = suggestion === WORKSPACE_TEMPLATE_ALIAS ? "official workspace scaffold" : "built-in scaffold";
228369
228394
  return `Unknown template "${templateId}". Did you mean "${suggestion}"? Use \`--template ${suggestion}\` for the ${suggestionDescription}, or pass a local path, \`github:owner/repo/path[#ref]\`, or an npm package spec for an external template.`;
228370
228395
  }
228396
+ function getUnknownTemplateMessage(templateId) {
228397
+ return [
228398
+ `Unknown template "${templateId}". Expected one of: ${USER_FACING_TEMPLATE_IDS2.join(", ")}.`,
228399
+ "Run `wp-typia templates list` to inspect available templates.",
228400
+ "Pass an explicit external template locator such as `./path`, `github:owner/repo/path[#ref]`, or `@scope/template` for custom templates."
228401
+ ].join(" ");
228402
+ }
228371
228403
  async function resolveTemplateId({
228372
228404
  templateId,
228373
228405
  yes = false,
@@ -228389,6 +228421,9 @@ async function resolveTemplateId({
228389
228421
  if (mistypedBuiltInTemplateMessage) {
228390
228422
  throw new Error(mistypedBuiltInTemplateMessage);
228391
228423
  }
228424
+ if (!looksLikeExplicitExternalTemplateLocator(normalizedTemplateId)) {
228425
+ throw new Error(getUnknownTemplateMessage(templateId));
228426
+ }
228392
228427
  return normalizedTemplateId;
228393
228428
  }
228394
228429
  if (yes) {
@@ -228429,7 +228464,7 @@ async function collectScaffoldAnswers({
228429
228464
  textDomain
228430
228465
  }) {
228431
228466
  const defaults = getDefaultAnswers(projectName, templateId);
228432
- if (yes) {
228467
+ if (yes || !isBuiltInTemplateId(templateId) && !promptText) {
228433
228468
  const identifiers2 = resolveScaffoldIdentifiers({
228434
228469
  namespace: namespace ?? defaults.namespace,
228435
228470
  phpPrefix,
@@ -228468,17 +228503,22 @@ async function collectScaffoldAnswers({
228468
228503
  title: await promptText("Block title", toTitleCase(identifiers.slug))
228469
228504
  };
228470
228505
  }
228471
- var WORKSPACE_TEMPLATE_ALIAS = "workspace", TEMPLATE_SELECTION_HINT, TEMPLATE_SUGGESTION_IDS, QUERY_POST_TYPE_RULE = 'Use lowercase, 1-20 chars, and only a-z, 0-9, "_" or "-".';
228506
+ var WORKSPACE_TEMPLATE_ALIAS = "workspace", TEMPLATE_SELECTION_HINT, TEMPLATE_SUGGESTION_IDS, QUERY_POST_TYPE_RULE = 'Use lowercase, 1-20 chars, and only a-z, 0-9, "_" or "-".', USER_FACING_TEMPLATE_IDS2;
228472
228507
  var init_scaffold_answer_resolution = __esm(() => {
228473
228508
  init_package_managers();
228474
228509
  init_scaffold_identifiers();
228475
228510
  init_template_registry();
228476
228511
  init_template_defaults();
228512
+ init_template_source_locators();
228477
228513
  TEMPLATE_SELECTION_HINT = `--template <${[
228478
228514
  ...TEMPLATE_IDS,
228479
228515
  WORKSPACE_TEMPLATE_ALIAS
228480
228516
  ].join("|")}|./path|github:owner/repo/path[#ref]|npm-package>`;
228481
228517
  TEMPLATE_SUGGESTION_IDS = [...TEMPLATE_IDS, WORKSPACE_TEMPLATE_ALIAS];
228518
+ USER_FACING_TEMPLATE_IDS2 = [
228519
+ ...TEMPLATE_IDS,
228520
+ WORKSPACE_TEMPLATE_ALIAS
228521
+ ];
228482
228522
  });
228483
228523
 
228484
228524
  // ../wp-typia-project-tools/src/runtime/scaffold-template-variables.ts
@@ -228665,7 +228705,7 @@ var init_scaffold_template_variables = __esm(() => {
228665
228705
  // ../wp-typia-project-tools/src/runtime/scaffold.ts
228666
228706
  import fs38 from "fs";
228667
228707
  import { promises as fsp14 } from "fs";
228668
- import path45 from "path";
228708
+ import path46 from "path";
228669
228709
  function isDataStorageMode(value2) {
228670
228710
  return DATA_STORAGE_MODES.includes(value2);
228671
228711
  }
@@ -228811,7 +228851,7 @@ async function scaffoldProject({
228811
228851
  phase: "finalize-project",
228812
228852
  title: "Finalizing scaffold output"
228813
228853
  });
228814
- const readmePath = path45.join(projectDir, "README.md");
228854
+ const readmePath = path46.join(projectDir, "README.md");
228815
228855
  if (!fs38.existsSync(readmePath)) {
228816
228856
  await fsp14.writeFile(readmePath, buildReadme(resolvedTemplateId, variables, resolvedPackageManager, {
228817
228857
  withMigrationUi: isBuiltInTemplate || isWorkspace ? withMigrationUi : false,
@@ -228819,7 +228859,7 @@ async function scaffoldProject({
228819
228859
  withWpEnv: isBuiltInTemplate ? withWpEnv : false
228820
228860
  }), "utf8");
228821
228861
  }
228822
- const gitignorePath = path45.join(projectDir, ".gitignore");
228862
+ const gitignorePath = path46.join(projectDir, ".gitignore");
228823
228863
  const existingGitignore = fs38.existsSync(gitignorePath) ? await fsp14.readFile(gitignorePath, "utf8") : "";
228824
228864
  await fsp14.writeFile(gitignorePath, mergeTextLines(buildGitignore(), existingGitignore), "utf8");
228825
228865
  await normalizePackageJson(projectDir, resolvedPackageManager);
@@ -228885,9 +228925,9 @@ var init_scaffold = __esm(() => {
228885
228925
  });
228886
228926
 
228887
228927
  // ../wp-typia-project-tools/src/runtime/cli-add-block-config.ts
228888
- import path46 from "path";
228928
+ import path47 from "path";
228889
228929
  function buildServerTemplateRoot(persistencePolicy) {
228890
- return path46.join(SHARED_WORKSPACE_TEMPLATE_ROOT, persistencePolicy === "public" ? "persistence-public" : "persistence-auth");
228930
+ return path47.join(SHARED_WORKSPACE_TEMPLATE_ROOT, persistencePolicy === "public" ? "persistence-public" : "persistence-auth");
228891
228931
  }
228892
228932
  function buildSingleBlockConfigEntry(variables) {
228893
228933
  return [
@@ -229037,7 +229077,7 @@ var init_cli_add_block_config = __esm(() => {
229037
229077
  // ../wp-typia-project-tools/src/runtime/cli-add-block-legacy-validator.ts
229038
229078
  import fs39 from "fs";
229039
229079
  import { promises as fsp15 } from "fs";
229040
- import path47 from "path";
229080
+ import path48 from "path";
229041
229081
  function ensureBlockConfigCanAddRestManifests(source) {
229042
229082
  const importLine = "import { defineEndpointManifest } from '@wp-typia/block-runtime/metadata-core';";
229043
229083
  if (REST_MANIFEST_IMPORT_PATTERN.test(source)) {
@@ -229139,22 +229179,22 @@ function renderLegacyManifestDefaultsWrapperSource() {
229139
229179
  `);
229140
229180
  }
229141
229181
  async function ensureLegacyCompoundValidatorManifestDefaultsWrapper(validatorPath) {
229142
- const validatorDir = path47.dirname(validatorPath);
229143
- const wrapperPath = path47.join(validatorDir, "manifest-defaults-document.ts");
229144
- const manifestPath = path47.join(validatorDir, "typia.manifest.json");
229182
+ const validatorDir = path48.dirname(validatorPath);
229183
+ const wrapperPath = path48.join(validatorDir, "manifest-defaults-document.ts");
229184
+ const manifestPath = path48.join(validatorDir, "typia.manifest.json");
229145
229185
  if (fs39.existsSync(wrapperPath) || !fs39.existsSync(manifestPath)) {
229146
229186
  return;
229147
229187
  }
229148
229188
  await fsp15.writeFile(wrapperPath, renderLegacyManifestDefaultsWrapperSource(), "utf8");
229149
229189
  }
229150
229190
  async function collectLegacyCompoundValidatorPaths(projectDir) {
229151
- const blocksDir = path47.join(projectDir, "src", "blocks");
229191
+ const blocksDir = path48.join(projectDir, "src", "blocks");
229152
229192
  if (!fs39.existsSync(blocksDir)) {
229153
229193
  return [];
229154
229194
  }
229155
229195
  const blockEntries = await fsp15.readdir(blocksDir, { withFileTypes: true });
229156
229196
  const validatorPaths = await Promise.all(blockEntries.filter((entry) => entry.isDirectory()).map(async (entry) => {
229157
- const validatorPath = path47.join(blocksDir, entry.name, "validators.ts");
229197
+ const validatorPath = path48.join(blocksDir, entry.name, "validators.ts");
229158
229198
  const validatorSource = await readOptionalFile(validatorPath);
229159
229199
  return isLegacyCompoundValidatorSource(validatorSource) ? validatorPath : null;
229160
229200
  }));
@@ -229162,14 +229202,14 @@ async function collectLegacyCompoundValidatorPaths(projectDir) {
229162
229202
  }
229163
229203
  async function ensureCompoundWorkspaceSupportFiles(projectDir, tempProjectDir, legacyValidatorPaths) {
229164
229204
  for (const fileName of COMPOUND_SHARED_SUPPORT_FILES) {
229165
- const sourcePath = path47.join(tempProjectDir, "src", fileName);
229205
+ const sourcePath = path48.join(tempProjectDir, "src", fileName);
229166
229206
  if (!fs39.existsSync(sourcePath)) {
229167
229207
  continue;
229168
229208
  }
229169
- const targetPath = path47.join(projectDir, "src", fileName);
229209
+ const targetPath = path48.join(projectDir, "src", fileName);
229170
229210
  const currentSource = await readOptionalFile(targetPath);
229171
229211
  if (fileName === "validator-toolkit.ts" ? shouldRefreshCompoundValidatorToolkit(currentSource) : currentSource === null) {
229172
- await fsp15.mkdir(path47.dirname(targetPath), { recursive: true });
229212
+ await fsp15.mkdir(path48.dirname(targetPath), { recursive: true });
229173
229213
  await fsp15.copyFile(sourcePath, targetPath);
229174
229214
  }
229175
229215
  }
@@ -229254,7 +229294,7 @@ var init_external_layer_selection = __esm(() => {
229254
229294
  // ../wp-typia-project-tools/src/runtime/cli-add-block.ts
229255
229295
  import fs40 from "fs";
229256
229296
  import { promises as fsp16 } from "fs";
229257
- import path48 from "path";
229297
+ import path49 from "path";
229258
229298
  import {
229259
229299
  syncBlockMetadata
229260
229300
  } from "@wp-typia/block-runtime/metadata-core";
@@ -229276,16 +229316,16 @@ ${source}`;
229276
229316
  });
229277
229317
  }
229278
229318
  async function copyTempDirectory(sourceDir, targetDir) {
229279
- await fsp16.mkdir(path48.dirname(targetDir), { recursive: true });
229319
+ await fsp16.mkdir(path49.dirname(targetDir), { recursive: true });
229280
229320
  await fsp16.cp(sourceDir, targetDir, { recursive: true });
229281
229321
  }
229282
229322
  async function addCollectionImportsForTemplate(projectDir, templateId, variables) {
229283
229323
  if (templateId === "compound") {
229284
- await ensureCollectionImport(path48.join(projectDir, "src", "blocks", variables.slugKebabCase, "index.tsx"));
229285
- await ensureCollectionImport(path48.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`, "index.tsx"));
229324
+ await ensureCollectionImport(path49.join(projectDir, "src", "blocks", variables.slugKebabCase, "index.tsx"));
229325
+ await ensureCollectionImport(path49.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`, "index.tsx"));
229286
229326
  return;
229287
229327
  }
229288
- await ensureCollectionImport(path48.join(projectDir, "src", "blocks", variables.slugKebabCase, "index.tsx"));
229328
+ await ensureCollectionImport(path49.join(projectDir, "src", "blocks", variables.slugKebabCase, "index.tsx"));
229289
229329
  }
229290
229330
  async function appendBlockConfigEntries(projectDir, entries, needsRestManifestImport) {
229291
229331
  await appendWorkspaceInventoryEntries(projectDir, {
@@ -229294,12 +229334,12 @@ async function appendBlockConfigEntries(projectDir, entries, needsRestManifestIm
229294
229334
  });
229295
229335
  }
229296
229336
  async function renderWorkspacePersistenceServerModule(projectDir, variables) {
229297
- const targetDir = path48.join(projectDir, "src", "blocks", variables.slugKebabCase);
229337
+ const targetDir = path49.join(projectDir, "src", "blocks", variables.slugKebabCase);
229298
229338
  const templateDir = buildServerTemplateRoot(variables.persistencePolicy);
229299
229339
  await copyInterpolatedDirectory(templateDir, targetDir, variables);
229300
229340
  }
229301
229341
  function hasInstalledWorkspaceDependencies(projectDir) {
229302
- return WORKSPACE_INSTALL_MARKERS.some((marker) => fs40.existsSync(path48.join(projectDir, marker)));
229342
+ return WORKSPACE_INSTALL_MARKERS.some((marker) => fs40.existsSync(path49.join(projectDir, marker)));
229303
229343
  }
229304
229344
  function assertWorkspaceDependenciesInstalled(workspace) {
229305
229345
  if (hasInstalledWorkspaceDependencies(workspace.projectDir)) {
@@ -229310,14 +229350,14 @@ function assertWorkspaceDependenciesInstalled(workspace) {
229310
229350
  async function copyScaffoldedBlockSlice(projectDir, templateId, tempProjectDir, variables, legacyValidatorPaths = []) {
229311
229351
  if (templateId === "compound") {
229312
229352
  await ensureCompoundWorkspaceSupportFiles(projectDir, tempProjectDir, legacyValidatorPaths);
229313
- await copyTempDirectory(path48.join(tempProjectDir, "src", "blocks", variables.slugKebabCase), path48.join(projectDir, "src", "blocks", variables.slugKebabCase));
229314
- await copyTempDirectory(path48.join(tempProjectDir, "src", "blocks", `${variables.slugKebabCase}-item`), path48.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`));
229353
+ await copyTempDirectory(path49.join(tempProjectDir, "src", "blocks", variables.slugKebabCase), path49.join(projectDir, "src", "blocks", variables.slugKebabCase));
229354
+ await copyTempDirectory(path49.join(tempProjectDir, "src", "blocks", `${variables.slugKebabCase}-item`), path49.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`));
229315
229355
  if (variables.compoundPersistenceEnabled === "true") {
229316
229356
  await renderWorkspacePersistenceServerModule(projectDir, variables);
229317
229357
  }
229318
229358
  return;
229319
229359
  }
229320
- await copyTempDirectory(path48.join(tempProjectDir, "src"), path48.join(projectDir, "src", "blocks", variables.slugKebabCase));
229360
+ await copyTempDirectory(path49.join(tempProjectDir, "src"), path49.join(projectDir, "src", "blocks", variables.slugKebabCase));
229321
229361
  if (templateId === "persistence") {
229322
229362
  await renderWorkspacePersistenceServerModule(projectDir, variables);
229323
229363
  }
@@ -229368,21 +229408,21 @@ async function assertAddBlockSupportsExternalLayerOutputs(options) {
229368
229408
  function collectWorkspaceBlockPaths(projectDir, templateId, variables) {
229369
229409
  if (templateId === "compound") {
229370
229410
  return [
229371
- path48.join(projectDir, "src", "blocks", variables.slugKebabCase),
229372
- path48.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`)
229411
+ path49.join(projectDir, "src", "blocks", variables.slugKebabCase),
229412
+ path49.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`)
229373
229413
  ];
229374
229414
  }
229375
- return [path48.join(projectDir, "src", "blocks", variables.slugKebabCase)];
229415
+ return [path49.join(projectDir, "src", "blocks", variables.slugKebabCase)];
229376
229416
  }
229377
229417
  function assertBlockTargetsDoNotExist(projectDir, templateId, variables) {
229378
229418
  for (const targetPath of collectWorkspaceBlockPaths(projectDir, templateId, variables)) {
229379
229419
  if (fs40.existsSync(targetPath)) {
229380
- throw new Error(`A block already exists at ${path48.relative(projectDir, targetPath)}. Choose a different name.`);
229420
+ throw new Error(`A block already exists at ${path49.relative(projectDir, targetPath)}. Choose a different name.`);
229381
229421
  }
229382
229422
  }
229383
229423
  }
229384
229424
  async function updateWorkspaceMigrationConfigIfPresent(projectDir, newBlocks) {
229385
- const configPath = path48.join(projectDir, "src", "migrations", "config.ts");
229425
+ const configPath = path49.join(projectDir, "src", "migrations", "config.ts");
229386
229426
  if (!fs40.existsSync(configPath)) {
229387
229427
  return;
229388
229428
  }
@@ -229403,10 +229443,10 @@ async function updateWorkspaceMigrationConfigIfPresent(projectDir, newBlocks) {
229403
229443
  }
229404
229444
  async function syncWorkspaceBlockMetadata(projectDir, slug, sourceTypeName, typesFile) {
229405
229445
  await syncBlockMetadata({
229406
- blockJsonFile: path48.join("src", "blocks", slug, "block.json"),
229407
- jsonSchemaFile: path48.join("src", "blocks", slug, "typia.schema.json"),
229408
- manifestFile: path48.join("src", "blocks", slug, "typia.manifest.json"),
229409
- openApiFile: path48.join("src", "blocks", slug, "typia.openapi.json"),
229446
+ blockJsonFile: path49.join("src", "blocks", slug, "block.json"),
229447
+ jsonSchemaFile: path49.join("src", "blocks", slug, "typia.schema.json"),
229448
+ manifestFile: path49.join("src", "blocks", slug, "typia.manifest.json"),
229449
+ openApiFile: path49.join("src", "blocks", slug, "typia.openapi.json"),
229410
229450
  projectRoot: projectDir,
229411
229451
  sourceTypeName,
229412
229452
  typesFile
@@ -229414,16 +229454,16 @@ async function syncWorkspaceBlockMetadata(projectDir, slug, sourceTypeName, type
229414
229454
  }
229415
229455
  async function syncWorkspacePersistenceArtifacts(projectDir, variables) {
229416
229456
  await syncPersistenceRestArtifacts({
229417
- apiTypesFile: path48.join("src", "blocks", variables.slugKebabCase, "api-types.ts"),
229418
- outputDir: path48.join("src", "blocks", variables.slugKebabCase),
229457
+ apiTypesFile: path49.join("src", "blocks", variables.slugKebabCase, "api-types.ts"),
229458
+ outputDir: path49.join("src", "blocks", variables.slugKebabCase),
229419
229459
  projectDir,
229420
229460
  variables
229421
229461
  });
229422
229462
  }
229423
229463
  async function syncWorkspaceAddedBlockArtifacts(projectDir, templateId, variables) {
229424
- await syncWorkspaceBlockMetadata(projectDir, variables.slugKebabCase, `${variables.pascalCase}Attributes`, path48.join("src", "blocks", variables.slugKebabCase, "types.ts"));
229464
+ await syncWorkspaceBlockMetadata(projectDir, variables.slugKebabCase, `${variables.pascalCase}Attributes`, path49.join("src", "blocks", variables.slugKebabCase, "types.ts"));
229425
229465
  if (templateId === "compound") {
229426
- await syncWorkspaceBlockMetadata(projectDir, `${variables.slugKebabCase}-item`, `${variables.pascalCase}ItemAttributes`, path48.join("src", "blocks", `${variables.slugKebabCase}-item`, "types.ts"));
229466
+ await syncWorkspaceBlockMetadata(projectDir, `${variables.slugKebabCase}-item`, `${variables.pascalCase}ItemAttributes`, path49.join("src", "blocks", `${variables.slugKebabCase}-item`, "types.ts"));
229427
229467
  }
229428
229468
  if (templateId === "persistence" || templateId === "compound" && variables.compoundPersistenceEnabled === "true") {
229429
229469
  await syncWorkspacePersistenceArtifacts(projectDir, variables);
@@ -229484,7 +229524,7 @@ async function runAddBlockCommand({
229484
229524
  throw new Error("`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.");
229485
229525
  }
229486
229526
  if (!isAddBlockTemplateId(templateId)) {
229487
- throw new Error(`Unknown add-block template "${templateId}". Expected one of: ${ADD_BLOCK_TEMPLATE_IDS.join(", ")}`);
229527
+ throw new Error(`Unknown add-block template "${templateId}". Expected one of: ${ADD_BLOCK_TEMPLATE_IDS.join(", ")}. Run \`wp-typia templates list\` to inspect available templates.`);
229488
229528
  }
229489
229529
  const resolvedTemplateId = templateId;
229490
229530
  assertPersistenceFlagsAllowed(resolvedTemplateId, {
@@ -229525,13 +229565,13 @@ async function runAddBlockCommand({
229525
229565
  path: tempRoot,
229526
229566
  cleanup: cleanupTempRoot
229527
229567
  } = await createManagedTempRoot("wp-typia-add-block-"));
229528
- const tempProjectDir = path48.join(tempRoot, normalizedSlug);
229529
- const blockConfigPath = path48.join(workspace.projectDir, "scripts", "block-config.ts");
229530
- const migrationConfigPath = path48.join(workspace.projectDir, "src", "migrations", "config.ts");
229568
+ const tempProjectDir = path49.join(tempRoot, normalizedSlug);
229569
+ const blockConfigPath = path49.join(workspace.projectDir, "scripts", "block-config.ts");
229570
+ const migrationConfigPath = path49.join(workspace.projectDir, "src", "migrations", "config.ts");
229531
229571
  const blockPhpPrefix = buildWorkspacePhpPrefix(workspace.workspace.phpPrefix, normalizedSlug);
229532
229572
  const migrationConfigSource = await readOptionalFile(migrationConfigPath);
229533
229573
  const migrationConfig = migrationConfigSource === null ? null : parseMigrationConfig(migrationConfigSource);
229534
- const compoundSupportPaths = resolvedTemplateId === "compound" ? COMPOUND_SHARED_SUPPORT_FILES.map((fileName) => path48.join(workspace.projectDir, "src", fileName)) : [];
229574
+ const compoundSupportPaths = resolvedTemplateId === "compound" ? COMPOUND_SHARED_SUPPORT_FILES.map((fileName) => path49.join(workspace.projectDir, "src", fileName)) : [];
229535
229575
  const legacyCompoundValidatorPaths = resolvedTemplateId === "compound" ? await collectLegacyCompoundValidatorPaths(workspace.projectDir) : [];
229536
229576
  const result = await (async () => {
229537
229577
  const scaffoldResult = await scaffoldProject({
@@ -229574,7 +229614,7 @@ async function runAddBlockCommand({
229574
229614
  ...compoundSupportPaths,
229575
229615
  ...legacyCompoundValidatorPaths
229576
229616
  ]),
229577
- snapshotDirs: migrationConfig === null ? [] : buildMigrationBlocks2(resolvedTemplateId, result.variables).map((block) => path48.join(workspace.projectDir, ...migrationConfig.snapshotDir.split("/"), migrationConfig.currentMigrationVersion, block.key)),
229617
+ snapshotDirs: migrationConfig === null ? [] : buildMigrationBlocks2(resolvedTemplateId, result.variables).map((block) => path49.join(workspace.projectDir, ...migrationConfig.snapshotDir.split("/"), migrationConfig.currentMigrationVersion, block.key)),
229578
229618
  targetPaths: collectWorkspaceBlockPaths(workspace.projectDir, resolvedTemplateId, result.variables)
229579
229619
  };
229580
229620
  try {
@@ -229584,7 +229624,7 @@ async function runAddBlockCommand({
229584
229624
  await syncWorkspaceAddedBlockArtifacts(workspace.projectDir, resolvedTemplateId, result.variables);
229585
229625
  await updateWorkspaceMigrationConfigIfPresent(workspace.projectDir, buildMigrationBlocks2(resolvedTemplateId, result.variables));
229586
229626
  return {
229587
- blockSlugs: collectWorkspaceBlockPaths(workspace.projectDir, resolvedTemplateId, result.variables).map((targetPath) => path48.basename(targetPath)),
229627
+ blockSlugs: collectWorkspaceBlockPaths(workspace.projectDir, resolvedTemplateId, result.variables).map((targetPath) => path49.basename(targetPath)),
229588
229628
  projectDir: workspace.projectDir,
229589
229629
  templateId: resolvedTemplateId,
229590
229630
  warnings: result.warnings
@@ -229628,7 +229668,7 @@ var init_cli_add_block = __esm(() => {
229628
229668
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-assets.ts
229629
229669
  import fs41 from "fs";
229630
229670
  import { promises as fsp17 } from "fs";
229631
- import path49 from "path";
229671
+ import path50 from "path";
229632
229672
  function escapeRegex3(value2) {
229633
229673
  return value2.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
229634
229674
  }
@@ -230010,7 +230050,7 @@ ${patternFunctions}
230010
230050
  }
230011
230051
  }
230012
230052
  if (!nextSource.includes(patternCategoryFunctionName) || !nextSource.includes(patternRegistrationFunctionName)) {
230013
- throw new Error(`Unable to inject pattern bootstrap functions into ${path49.basename(bootstrapPath)}.`);
230053
+ throw new Error(`Unable to inject pattern bootstrap functions into ${path50.basename(bootstrapPath)}.`);
230014
230054
  }
230015
230055
  if (!nextSource.includes(patternCategoryHook)) {
230016
230056
  nextSource = `${nextSource.trimEnd()}
@@ -230200,7 +230240,7 @@ ${snippet}
230200
230240
  if (missingReferences.length > 0) {
230201
230241
  const replacedSource = replacePhpFunctionDefinition(nextSource, enqueueFunctionName, enqueueFunction);
230202
230242
  if (!replacedSource) {
230203
- throw new Error(`Unable to repair ${path49.basename(bootstrapPath)} for ${enqueueFunctionName}.`);
230243
+ throw new Error(`Unable to repair ${path50.basename(bootstrapPath)} for ${enqueueFunctionName}.`);
230204
230244
  }
230205
230245
  nextSource = replacedSource;
230206
230246
  }
@@ -230212,7 +230252,7 @@ ${snippet}
230212
230252
  });
230213
230253
  }
230214
230254
  async function ensureEditorPluginBuildScriptAnchors(workspace) {
230215
- const buildScriptPath = path49.join(workspace.projectDir, "scripts", "build-workspace.mjs");
230255
+ const buildScriptPath = path50.join(workspace.projectDir, "scripts", "build-workspace.mjs");
230216
230256
  await patchFile(buildScriptPath, (source) => {
230217
230257
  if (/['"]src\/editor-plugins\/index\.(?:ts|js)['"]/u.test(source)) {
230218
230258
  return source;
@@ -230225,13 +230265,13 @@ async function ensureEditorPluginBuildScriptAnchors(workspace) {
230225
230265
  'src/editor-plugins/index.js',
230226
230266
  ]`);
230227
230267
  if (nextSource === source) {
230228
- throw new Error(`Unable to update ${path49.relative(workspace.projectDir, buildScriptPath)} for editor plugin shared entries.`);
230268
+ throw new Error(`Unable to update ${path50.relative(workspace.projectDir, buildScriptPath)} for editor plugin shared entries.`);
230229
230269
  }
230230
230270
  return nextSource;
230231
230271
  });
230232
230272
  }
230233
230273
  async function ensureEditorPluginWebpackAnchors(workspace) {
230234
- const webpackConfigPath = path49.join(workspace.projectDir, "webpack.config.js");
230274
+ const webpackConfigPath = path50.join(workspace.projectDir, "webpack.config.js");
230235
230275
  await patchFile(webpackConfigPath, (source) => {
230236
230276
  if (/['"]editor-plugins\/index['"]/u.test(source)) {
230237
230277
  return source;
@@ -230259,17 +230299,17 @@ async function ensureEditorPluginWebpackAnchors(workspace) {
230259
230299
  }`;
230260
230300
  const nextSource = source.replace(legacySharedEntriesBlockPattern, nextSharedEntriesBlock);
230261
230301
  if (nextSource === source) {
230262
- throw new Error(`Unable to update ${path49.relative(workspace.projectDir, webpackConfigPath)} for editor plugin shared entries.`);
230302
+ throw new Error(`Unable to update ${path50.relative(workspace.projectDir, webpackConfigPath)} for editor plugin shared entries.`);
230263
230303
  }
230264
230304
  return nextSource;
230265
230305
  });
230266
230306
  }
230267
230307
  function resolveBindingSourceRegistryPath(projectDir) {
230268
- const bindingsDir = path49.join(projectDir, "src", "bindings");
230269
- return [path49.join(bindingsDir, "index.ts"), path49.join(bindingsDir, "index.js")].find((candidatePath) => fs41.existsSync(candidatePath)) ?? path49.join(bindingsDir, "index.ts");
230308
+ const bindingsDir = path50.join(projectDir, "src", "bindings");
230309
+ return [path50.join(bindingsDir, "index.ts"), path50.join(bindingsDir, "index.js")].find((candidatePath) => fs41.existsSync(candidatePath)) ?? path50.join(bindingsDir, "index.ts");
230270
230310
  }
230271
230311
  async function writeBindingSourceRegistry(projectDir, bindingSourceSlug) {
230272
- const bindingsDir = path49.join(projectDir, "src", "bindings");
230312
+ const bindingsDir = path50.join(projectDir, "src", "bindings");
230273
230313
  const bindingsIndexPath = resolveBindingSourceRegistryPath(projectDir);
230274
230314
  await fsp17.mkdir(bindingsDir, { recursive: true });
230275
230315
  const existingBindingSourceSlugs = fs41.readdirSync(bindingsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -230277,11 +230317,11 @@ async function writeBindingSourceRegistry(projectDir, bindingSourceSlug) {
230277
230317
  await fsp17.writeFile(bindingsIndexPath, buildBindingSourceIndexSource(nextBindingSourceSlugs), "utf8");
230278
230318
  }
230279
230319
  function resolveEditorPluginRegistryPath(projectDir) {
230280
- const editorPluginsDir = path49.join(projectDir, "src", "editor-plugins");
230320
+ const editorPluginsDir = path50.join(projectDir, "src", "editor-plugins");
230281
230321
  return [
230282
- path49.join(editorPluginsDir, "index.ts"),
230283
- path49.join(editorPluginsDir, "index.js")
230284
- ].find((candidatePath) => fs41.existsSync(candidatePath)) ?? path49.join(editorPluginsDir, "index.ts");
230322
+ path50.join(editorPluginsDir, "index.ts"),
230323
+ path50.join(editorPluginsDir, "index.js")
230324
+ ].find((candidatePath) => fs41.existsSync(candidatePath)) ?? path50.join(editorPluginsDir, "index.ts");
230285
230325
  }
230286
230326
  function readEditorPluginRegistrySlugs(registryPath) {
230287
230327
  if (!fs41.existsSync(registryPath)) {
@@ -230291,7 +230331,7 @@ function readEditorPluginRegistrySlugs(registryPath) {
230291
230331
  return Array.from(source.matchAll(/^\s*import\s+['"]\.\/([^/'"]+)(?:\/index(?:\.[cm]?[jt]sx?)?)?['"];?\s*$/gmu)).map((match3) => match3[1]);
230292
230332
  }
230293
230333
  async function writeEditorPluginRegistry(projectDir, editorPluginSlug) {
230294
- const editorPluginsDir = path49.join(projectDir, "src", "editor-plugins");
230334
+ const editorPluginsDir = path50.join(projectDir, "src", "editor-plugins");
230295
230335
  const registryPath = resolveEditorPluginRegistryPath(projectDir);
230296
230336
  await fsp17.mkdir(editorPluginsDir, { recursive: true });
230297
230337
  const existingEditorPluginSlugs = readWorkspaceInventory(projectDir).editorPlugins.map((entry) => entry.slug);
@@ -230309,17 +230349,17 @@ async function runAddEditorPluginCommand({
230309
230349
  const resolvedSlot = assertValidEditorPluginSlot(slot);
230310
230350
  const inventory = readWorkspaceInventory(workspace.projectDir);
230311
230351
  assertEditorPluginDoesNotExist(workspace.projectDir, editorPluginSlug, inventory);
230312
- const blockConfigPath = path49.join(workspace.projectDir, "scripts", "block-config.ts");
230352
+ const blockConfigPath = path50.join(workspace.projectDir, "scripts", "block-config.ts");
230313
230353
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
230314
- const buildScriptPath = path49.join(workspace.projectDir, "scripts", "build-workspace.mjs");
230354
+ const buildScriptPath = path50.join(workspace.projectDir, "scripts", "build-workspace.mjs");
230315
230355
  const editorPluginsIndexPath = resolveEditorPluginRegistryPath(workspace.projectDir);
230316
- const webpackConfigPath = path49.join(workspace.projectDir, "webpack.config.js");
230317
- const editorPluginDir = path49.join(workspace.projectDir, "src", "editor-plugins", editorPluginSlug);
230318
- const entryFilePath = path49.join(editorPluginDir, "index.tsx");
230319
- const sidebarFilePath = path49.join(editorPluginDir, "Sidebar.tsx");
230320
- const dataFilePath = path49.join(editorPluginDir, "data.ts");
230321
- const typesFilePath = path49.join(editorPluginDir, "types.ts");
230322
- const styleFilePath = path49.join(editorPluginDir, "style.scss");
230356
+ const webpackConfigPath = path50.join(workspace.projectDir, "webpack.config.js");
230357
+ const editorPluginDir = path50.join(workspace.projectDir, "src", "editor-plugins", editorPluginSlug);
230358
+ const entryFilePath = path50.join(editorPluginDir, "index.tsx");
230359
+ const sidebarFilePath = path50.join(editorPluginDir, "Sidebar.tsx");
230360
+ const dataFilePath = path50.join(editorPluginDir, "data.ts");
230361
+ const typesFilePath = path50.join(editorPluginDir, "types.ts");
230362
+ const styleFilePath = path50.join(editorPluginDir, "style.scss");
230323
230363
  const mutationSnapshot = {
230324
230364
  fileSources: await snapshotWorkspaceFiles([
230325
230365
  blockConfigPath,
@@ -230365,16 +230405,16 @@ async function runAddPatternCommand({
230365
230405
  const patternSlug = assertValidGeneratedSlug("Pattern name", normalizeBlockSlug(patternName), "wp-typia add pattern <name>");
230366
230406
  const inventory = readWorkspaceInventory(workspace.projectDir);
230367
230407
  assertPatternDoesNotExist(workspace.projectDir, patternSlug, inventory);
230368
- const blockConfigPath = path49.join(workspace.projectDir, "scripts", "block-config.ts");
230408
+ const blockConfigPath = path50.join(workspace.projectDir, "scripts", "block-config.ts");
230369
230409
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
230370
- const patternFilePath = path49.join(workspace.projectDir, "src", "patterns", `${patternSlug}.php`);
230410
+ const patternFilePath = path50.join(workspace.projectDir, "src", "patterns", `${patternSlug}.php`);
230371
230411
  const mutationSnapshot = {
230372
230412
  fileSources: await snapshotWorkspaceFiles([blockConfigPath, bootstrapPath]),
230373
230413
  snapshotDirs: [],
230374
230414
  targetPaths: [patternFilePath]
230375
230415
  };
230376
230416
  try {
230377
- await fsp17.mkdir(path49.dirname(patternFilePath), { recursive: true });
230417
+ await fsp17.mkdir(path50.dirname(patternFilePath), { recursive: true });
230378
230418
  await ensurePatternBootstrapAnchors(workspace);
230379
230419
  await fsp17.writeFile(patternFilePath, buildPatternSource(patternSlug, workspace.workspace.namespace, workspace.workspace.textDomain), "utf8");
230380
230420
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
@@ -230397,12 +230437,12 @@ async function runAddBindingSourceCommand({
230397
230437
  const bindingSourceSlug = assertValidGeneratedSlug("Binding source name", normalizeBlockSlug(bindingSourceName), "wp-typia add binding-source <name>");
230398
230438
  const inventory = readWorkspaceInventory(workspace.projectDir);
230399
230439
  assertBindingSourceDoesNotExist(workspace.projectDir, bindingSourceSlug, inventory);
230400
- const blockConfigPath = path49.join(workspace.projectDir, "scripts", "block-config.ts");
230440
+ const blockConfigPath = path50.join(workspace.projectDir, "scripts", "block-config.ts");
230401
230441
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
230402
230442
  const bindingsIndexPath = resolveBindingSourceRegistryPath(workspace.projectDir);
230403
- const bindingSourceDir = path49.join(workspace.projectDir, "src", "bindings", bindingSourceSlug);
230404
- const serverFilePath = path49.join(bindingSourceDir, "server.php");
230405
- const editorFilePath = path49.join(bindingSourceDir, "editor.ts");
230443
+ const bindingSourceDir = path50.join(workspace.projectDir, "src", "bindings", bindingSourceSlug);
230444
+ const serverFilePath = path50.join(bindingSourceDir, "server.php");
230445
+ const editorFilePath = path50.join(bindingSourceDir, "editor.ts");
230406
230446
  const mutationSnapshot = {
230407
230447
  fileSources: await snapshotWorkspaceFiles([blockConfigPath, bootstrapPath, bindingsIndexPath]),
230408
230448
  snapshotDirs: [],
@@ -230434,7 +230474,7 @@ var init_cli_add_workspace_assets = __esm(() => {
230434
230474
  });
230435
230475
 
230436
230476
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest-anchors.ts
230437
- import path50 from "path";
230477
+ import path51 from "path";
230438
230478
  function escapeRegex4(value2) {
230439
230479
  return value2.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
230440
230480
  }
@@ -230485,7 +230525,7 @@ ${snippet}
230485
230525
  insertPhpSnippet(registerFunction);
230486
230526
  } else if (!nextSource.includes(REST_RESOURCE_SERVER_GLOB)) {
230487
230527
  throw new Error([
230488
- `Unable to patch ${path50.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
230528
+ `Unable to patch ${path51.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
230489
230529
  `The existing ${registerFunctionName}() definition does not include ${REST_RESOURCE_SERVER_GLOB}.`,
230490
230530
  "Restore the generated bootstrap shape or wire the REST resource loader manually before retrying."
230491
230531
  ].join(" "));
@@ -230499,7 +230539,7 @@ ${snippet}
230499
230539
  function assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
230500
230540
  if (!nextSource.includes(target) && !hasAnchor) {
230501
230541
  throw new Error([
230502
- `ensureRestResourceSyncScriptAnchors could not patch ${path50.basename(syncRestScriptPath)}.`,
230542
+ `ensureRestResourceSyncScriptAnchors could not patch ${path51.basename(syncRestScriptPath)}.`,
230503
230543
  `Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
230504
230544
  "Restore the generated template or add the REST_RESOURCES wiring manually before retrying."
230505
230545
  ].join(" "));
@@ -230514,7 +230554,7 @@ function replaceRequiredSyncRestSource(nextSource, target, anchor, replacement,
230514
230554
  return nextSource.replace(anchor, replacement);
230515
230555
  }
230516
230556
  async function ensureRestResourceSyncScriptAnchors(workspace) {
230517
- const syncRestScriptPath = path50.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
230557
+ const syncRestScriptPath = path51.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
230518
230558
  await patchFile(syncRestScriptPath, (source) => {
230519
230559
  let nextSource = source;
230520
230560
  const importAnchor = "import { BLOCKS, type WorkspaceBlockConfig } from './block-config';";
@@ -230636,7 +230676,7 @@ var init_cli_add_workspace_rest_anchors = __esm(() => {
230636
230676
  });
230637
230677
 
230638
230678
  // ../wp-typia-project-tools/src/runtime/rest-resource-artifacts.ts
230639
- import path51 from "path";
230679
+ import path52 from "path";
230640
230680
  import {
230641
230681
  defineEndpointManifest as defineEndpointManifest2,
230642
230682
  syncEndpointClient as syncEndpointClient2,
@@ -230772,8 +230812,8 @@ async function syncRestResourceArtifacts({
230772
230812
  const manifest = buildRestResourceEndpointManifest(variables, methods);
230773
230813
  for (const [baseName, contract] of Object.entries(manifest.contracts)) {
230774
230814
  await syncTypeSchemas2({
230775
- jsonSchemaFile: path51.join(outputDir, "api-schemas", `${baseName}.schema.json`),
230776
- openApiFile: path51.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
230815
+ jsonSchemaFile: path52.join(outputDir, "api-schemas", `${baseName}.schema.json`),
230816
+ openApiFile: path52.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
230777
230817
  projectRoot: projectDir,
230778
230818
  sourceTypeName: contract.sourceTypeName,
230779
230819
  typesFile
@@ -230781,7 +230821,7 @@ async function syncRestResourceArtifacts({
230781
230821
  }
230782
230822
  await syncRestOpenApi2({
230783
230823
  manifest,
230784
- openApiFile: path51.join(outputDir, "api.openapi.json"),
230824
+ openApiFile: path52.join(outputDir, "api.openapi.json"),
230785
230825
  projectRoot: projectDir,
230786
230826
  typesFile
230787
230827
  });
@@ -231186,7 +231226,7 @@ var init_cli_add_workspace_rest_source_emitters = __esm(() => {
231186
231226
 
231187
231227
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest.ts
231188
231228
  import { promises as fsp18 } from "fs";
231189
- import path52 from "path";
231229
+ import path53 from "path";
231190
231230
  function quotePhpString2(value2) {
231191
231231
  return `'${value2.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
231192
231232
  }
@@ -231619,16 +231659,15 @@ async function runAddRestResourceCommand({
231619
231659
  const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
231620
231660
  const inventory = readWorkspaceInventory(workspace.projectDir);
231621
231661
  assertRestResourceDoesNotExist(workspace.projectDir, restResourceSlug, inventory);
231622
- const blockConfigPath = path52.join(workspace.projectDir, "scripts", "block-config.ts");
231662
+ const blockConfigPath = path53.join(workspace.projectDir, "scripts", "block-config.ts");
231623
231663
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
231624
- const syncRestScriptPath = path52.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
231625
- const restResourceDir = path52.join(workspace.projectDir, "src", "rest", restResourceSlug);
231626
- const typesFilePath = path52.join(restResourceDir, "api-types.ts");
231627
- const validatorsFilePath = path52.join(restResourceDir, "api-validators.ts");
231628
- const apiFilePath = path52.join(restResourceDir, "api.ts");
231629
- const dataFilePath = path52.join(restResourceDir, "data.ts");
231630
- const clientFilePath = path52.join(restResourceDir, "api-client.ts");
231631
- const phpFilePath = path52.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
231664
+ const syncRestScriptPath = path53.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
231665
+ const restResourceDir = path53.join(workspace.projectDir, "src", "rest", restResourceSlug);
231666
+ const typesFilePath = path53.join(restResourceDir, "api-types.ts");
231667
+ const validatorsFilePath = path53.join(restResourceDir, "api-validators.ts");
231668
+ const apiFilePath = path53.join(restResourceDir, "api.ts");
231669
+ const dataFilePath = path53.join(restResourceDir, "data.ts");
231670
+ const phpFilePath = path53.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
231632
231671
  const mutationSnapshot = {
231633
231672
  fileSources: await snapshotWorkspaceFiles([
231634
231673
  blockConfigPath,
@@ -231640,7 +231679,7 @@ async function runAddRestResourceCommand({
231640
231679
  };
231641
231680
  try {
231642
231681
  await fsp18.mkdir(restResourceDir, { recursive: true });
231643
- await fsp18.mkdir(path52.dirname(phpFilePath), { recursive: true });
231682
+ await fsp18.mkdir(path53.dirname(phpFilePath), { recursive: true });
231644
231683
  await ensureRestResourceBootstrapAnchors(workspace);
231645
231684
  await ensureRestResourceSyncScriptAnchors(workspace);
231646
231685
  await fsp18.writeFile(typesFilePath, buildRestResourceTypesSource(restResourceSlug, resolvedMethods), "utf8");
@@ -231692,7 +231731,7 @@ var init_cli_add_workspace_rest = __esm(() => {
231692
231731
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability.ts
231693
231732
  import fs42 from "fs";
231694
231733
  import { promises as fsp19 } from "fs";
231695
- import path53 from "path";
231734
+ import path54 from "path";
231696
231735
  import { syncTypeSchemas as syncTypeSchemas3 } from "@wp-typia/block-runtime/metadata-core";
231697
231736
  function escapeRegex5(value2) {
231698
231737
  return value2.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
@@ -231700,6 +231739,50 @@ function escapeRegex5(value2) {
231700
231739
  function quotePhpString3(value2) {
231701
231740
  return `'${value2.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
231702
231741
  }
231742
+ function findPhpFunctionRange2(source, functionName) {
231743
+ const functionPattern = new RegExp(`function\\s+${escapeRegex5(functionName)}\\s*\\([^)]*\\)\\s*\\{`, "u");
231744
+ const match3 = functionPattern.exec(source);
231745
+ if (!match3) {
231746
+ return null;
231747
+ }
231748
+ const openingBraceIndex = match3.index + match3[0].length - 1;
231749
+ let depth = 0;
231750
+ for (let index = openingBraceIndex;index < source.length; index += 1) {
231751
+ const character = source[index];
231752
+ if (character === "{") {
231753
+ depth += 1;
231754
+ } else if (character === "}") {
231755
+ depth -= 1;
231756
+ if (depth === 0) {
231757
+ const end = index + 1;
231758
+ return {
231759
+ end,
231760
+ source: source.slice(match3.index, end),
231761
+ start: match3.index
231762
+ };
231763
+ }
231764
+ }
231765
+ }
231766
+ return null;
231767
+ }
231768
+ function replacePhpFunctionDefinition2(source, functionName, replacement) {
231769
+ const functionRange = findPhpFunctionRange2(source, functionName);
231770
+ if (!functionRange) {
231771
+ return source;
231772
+ }
231773
+ return `${source.slice(0, functionRange.start)}${replacement.trimStart()}${source.slice(functionRange.end)}`;
231774
+ }
231775
+ function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
231776
+ if (!existingVersion) {
231777
+ return requiredVersion;
231778
+ }
231779
+ const existingMinimum = import_semver2.default.minVersion(existingVersion);
231780
+ const requiredMinimum = import_semver2.default.minVersion(requiredVersion);
231781
+ if (!existingMinimum || !requiredMinimum) {
231782
+ return requiredVersion;
231783
+ }
231784
+ return import_semver2.default.gte(existingMinimum, requiredMinimum) ? existingVersion : requiredVersion;
231785
+ }
231703
231786
  function toPascalCaseFromAbilitySlug(abilitySlug) {
231704
231787
  return normalizeBlockSlug(abilitySlug).split("-").filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
231705
231788
  }
@@ -231769,7 +231852,14 @@ export interface ${pascalCase}AbilityOutput {
231769
231852
  function buildAbilityDataSource(abilitySlug) {
231770
231853
  const pascalCase = toPascalCaseFromAbilitySlug(abilitySlug);
231771
231854
  const abilityConstBase = abilitySlug.toUpperCase().replace(/[^A-Z0-9]+/gu, "_").replace(/_{2,}/gu, "_").replace(/^_|_$/gu, "");
231772
- return `import abilityConfig from './ability.config.json';
231855
+ return `import {
231856
+ executeAbility,
231857
+ getAbilities,
231858
+ getAbility as getRegisteredAbility,
231859
+ } from '@wordpress/abilities';
231860
+ import '@wordpress/core-abilities';
231861
+
231862
+ import abilityConfig from './ability.config.json';
231773
231863
 
231774
231864
  import type { ${pascalCase}AbilityInput, ${pascalCase}AbilityOutput } from './types';
231775
231865
 
@@ -231781,55 +231871,56 @@ interface WordPressAbilityDefinition {
231781
231871
  name?: string;
231782
231872
  }
231783
231873
 
231784
- interface WordPressAbilitiesClient {
231785
- executeAbility( name: string, input?: unknown ): Promise< unknown >;
231786
- getAbilities( args?: { category?: string } ): WordPressAbilityDefinition[];
231787
- getAbility( name: string ): WordPressAbilityDefinition | undefined;
231788
- }
231789
-
231790
- const ABILITY_CLIENT_UNAVAILABLE_MESSAGE =
231791
- 'The WordPress abilities client is unavailable on this screen. Ensure the Abilities API and @wordpress/core-abilities integration are loaded before using this scaffold.';
231792
-
231793
231874
  export const ${abilityConstBase}_ABILITY = abilityConfig;
231794
231875
  export const ${abilityConstBase}_ABILITY_CATEGORY = abilityConfig.category;
231795
231876
  export const ${abilityConstBase}_ABILITY_ID = abilityConfig.abilityId;
231796
231877
  export const ${abilityConstBase}_ABILITY_META = abilityConfig.meta;
231878
+ const ABILITY_DISCOVERY_POLL_INTERVAL_MS = 50;
231879
+ const ABILITY_DISCOVERY_TIMEOUT_MS = 5000;
231797
231880
 
231798
231881
  export type {
231799
231882
  ${pascalCase}AbilityInput,
231800
231883
  ${pascalCase}AbilityOutput,
231801
231884
  };
231802
231885
 
231803
- function resolveAbilitiesClient(): WordPressAbilitiesClient {
231804
- const runtime = globalThis as typeof globalThis & {
231805
- window?: {
231806
- wp?: {
231807
- abilities?: WordPressAbilitiesClient;
231808
- };
231809
- };
231810
- };
231811
- const client = runtime.window?.wp?.abilities;
231812
- if ( ! client ) {
231813
- throw new Error( ABILITY_CLIENT_UNAVAILABLE_MESSAGE );
231814
- }
231886
+ function sleep( milliseconds: number ): Promise< void > {
231887
+ return new Promise( ( resolve ) => {
231888
+ setTimeout( resolve, milliseconds );
231889
+ } );
231890
+ }
231815
231891
 
231816
- return client;
231892
+ async function waitFor${pascalCase}AbilityRegistration(): Promise< void > {
231893
+ const deadline = Date.now() + ABILITY_DISCOVERY_TIMEOUT_MS;
231894
+ while ( ! getRegisteredAbility( ${abilityConstBase}_ABILITY_ID ) ) {
231895
+ if ( Date.now() >= deadline ) {
231896
+ return;
231897
+ }
231898
+
231899
+ await sleep( ABILITY_DISCOVERY_POLL_INTERVAL_MS );
231900
+ }
231817
231901
  }
231818
231902
 
231819
- export function list${pascalCase}CategoryAbilities(): WordPressAbilityDefinition[] {
231820
- return resolveAbilitiesClient().getAbilities( {
231903
+ export async function list${pascalCase}CategoryAbilities(): Promise< WordPressAbilityDefinition[] > {
231904
+ await waitFor${pascalCase}AbilityRegistration();
231905
+
231906
+ return getAbilities( {
231821
231907
  category: ${abilityConstBase}_ABILITY_CATEGORY.slug,
231822
- } );
231908
+ } ) as WordPressAbilityDefinition[];
231823
231909
  }
231824
231910
 
231825
- export function get${pascalCase}Ability():
231911
+ export async function get${pascalCase}Ability(): Promise<
231826
231912
  | WordPressAbilityDefinition
231827
- | undefined {
231828
- return resolveAbilitiesClient().getAbility( ${abilityConstBase}_ABILITY_ID );
231913
+ | undefined
231914
+ > {
231915
+ await waitFor${pascalCase}AbilityRegistration();
231916
+
231917
+ return getRegisteredAbility( ${abilityConstBase}_ABILITY_ID ) as
231918
+ | WordPressAbilityDefinition
231919
+ | undefined;
231829
231920
  }
231830
231921
 
231831
- export function require${pascalCase}Ability(): WordPressAbilityDefinition {
231832
- const ability = get${pascalCase}Ability();
231922
+ export async function require${pascalCase}Ability(): Promise< WordPressAbilityDefinition > {
231923
+ const ability = await get${pascalCase}Ability();
231833
231924
  if ( ability ) {
231834
231925
  return ability;
231835
231926
  }
@@ -231845,7 +231936,9 @@ export function require${pascalCase}Ability(): WordPressAbilityDefinition {
231845
231936
  export async function run${pascalCase}Ability(
231846
231937
  input: ${pascalCase}AbilityInput
231847
231938
  ): Promise< ${pascalCase}AbilityOutput > {
231848
- return ( await resolveAbilitiesClient().executeAbility(
231939
+ await waitFor${pascalCase}AbilityRegistration();
231940
+
231941
+ return ( await executeAbility(
231849
231942
  ${abilityConstBase}_ABILITY_ID,
231850
231943
  input
231851
231944
  ) ) as ${pascalCase}AbilityOutput;
@@ -231857,8 +231950,8 @@ function buildAbilityClientSource(abilitySlug) {
231857
231950
  return `/**
231858
231951
  * Re-export the typed ${pascalCase} ability client helpers.
231859
231952
  *
231860
- * The underlying WordPress abilities client is expected to have been hydrated
231861
- * by the site's admin/editor bootstrap before these helpers execute.
231953
+ * The helper methods load the WordPress core abilities integration and wait for
231954
+ * this server-registered ability before reading or executing it.
231862
231955
  */
231863
231956
  export * from './data';
231864
231957
  `;
@@ -232158,8 +232251,8 @@ function buildAbilityRegistrySource(abilitySlugs) {
232158
232251
  `);
232159
232252
  }
232160
232253
  function resolveAbilityRegistryPath(projectDir) {
232161
- const abilitiesDir = path53.join(projectDir, "src", "abilities");
232162
- return [path53.join(abilitiesDir, "index.ts"), path53.join(abilitiesDir, "index.js")].find((candidatePath) => fs42.existsSync(candidatePath)) ?? path53.join(abilitiesDir, "index.ts");
232254
+ const abilitiesDir = path54.join(projectDir, "src", "abilities");
232255
+ return [path54.join(abilitiesDir, "index.ts"), path54.join(abilitiesDir, "index.js")].find((candidatePath) => fs42.existsSync(candidatePath)) ?? path54.join(abilitiesDir, "index.ts");
232163
232256
  }
232164
232257
  function readAbilityRegistrySlugs(registryPath) {
232165
232258
  if (!fs42.existsSync(registryPath)) {
@@ -232169,7 +232262,7 @@ function readAbilityRegistrySlugs(registryPath) {
232169
232262
  return Array.from(source.matchAll(/^\s*export\s+\*\s+from\s+['"]\.\/([^/'"]+)\/client['"];?\s*$/gmu)).map((match3) => match3[1]);
232170
232263
  }
232171
232264
  async function writeAbilityRegistry(projectDir, abilitySlug) {
232172
- const abilitiesDir = path53.join(projectDir, "src", "abilities");
232265
+ const abilitiesDir = path54.join(projectDir, "src", "abilities");
232173
232266
  const registryPath = resolveAbilityRegistryPath(projectDir);
232174
232267
  await fsp19.mkdir(abilitiesDir, { recursive: true });
232175
232268
  const existingAbilitySlugs = readWorkspaceInventory(projectDir).abilities.map((entry) => entry.slug);
@@ -232224,22 +232317,31 @@ function ${enqueueFunctionName}() {
232224
232317
  ? $asset['dependencies']
232225
232318
  : array();
232226
232319
 
232227
- foreach ( array( '${WP_CORE_ABILITIES_SCRIPT_HANDLE}', '${WP_ABILITIES_SCRIPT_HANDLE}' ) as $ability_dependency ) {
232228
- if (
232229
- function_exists( 'wp_script_is' ) &&
232230
- wp_script_is( $ability_dependency, 'registered' ) &&
232231
- ! in_array( $ability_dependency, $dependencies, true )
232232
- ) {
232320
+ foreach ( array( '${WP_CORE_ABILITIES_SCRIPT_MODULE_ID}', '${WP_ABILITIES_SCRIPT_MODULE_ID}' ) as $ability_dependency ) {
232321
+ $has_dependency = false;
232322
+ foreach ( $dependencies as $dependency ) {
232323
+ $dependency_id = is_array( $dependency ) && isset( $dependency['id'] )
232324
+ ? $dependency['id']
232325
+ : $dependency;
232326
+ if ( $dependency_id === $ability_dependency ) {
232327
+ $has_dependency = true;
232328
+ break;
232329
+ }
232330
+ }
232331
+ if ( ! $has_dependency ) {
232233
232332
  $dependencies[] = $ability_dependency;
232234
232333
  }
232235
232334
  }
232236
232335
 
232237
- wp_enqueue_script(
232336
+ if ( ! function_exists( 'wp_enqueue_script_module' ) ) {
232337
+ return;
232338
+ }
232339
+
232340
+ wp_enqueue_script_module(
232238
232341
  '${workspaceBaseName}-abilities',
232239
232342
  plugins_url( '${ABILITY_EDITOR_SCRIPT}', __FILE__ ),
232240
232343
  $dependencies,
232241
- isset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path ),
232242
- true
232344
+ isset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path )
232243
232345
  );
232244
232346
  }
232245
232347
  `;
@@ -232277,6 +232379,8 @@ ${snippet}
232277
232379
  }
232278
232380
  if (!hasPhpFunctionDefinition(enqueueFunctionName)) {
232279
232381
  insertPhpSnippet(enqueueFunction);
232382
+ } else if (!findPhpFunctionRange2(nextSource, enqueueFunctionName)?.source.includes("wp_enqueue_script_module")) {
232383
+ nextSource = replacePhpFunctionDefinition2(nextSource, enqueueFunctionName, enqueueFunction);
232280
232384
  }
232281
232385
  if (!nextSource.includes(loadHook)) {
232282
232386
  appendPhpSnippet(loadHook);
@@ -232291,21 +232395,27 @@ ${snippet}
232291
232395
  });
232292
232396
  }
232293
232397
  async function ensureAbilityPackageScripts(workspace) {
232294
- const packageJsonPath = path53.join(workspace.projectDir, "package.json");
232398
+ const packageJsonPath = path54.join(workspace.projectDir, "package.json");
232295
232399
  const packageJson = JSON.parse(await fsp19.readFile(packageJsonPath, "utf8"));
232296
232400
  const nextScripts = {
232297
232401
  ...packageJson.scripts ?? {},
232298
232402
  "sync-abilities": packageJson.scripts?.["sync-abilities"] ?? "tsx scripts/sync-abilities.ts"
232299
232403
  };
232300
- if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {})) {
232404
+ const nextDependencies = {
232405
+ ...packageJson.dependencies ?? {},
232406
+ [WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], WP_ABILITIES_PACKAGE_VERSION),
232407
+ [WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], WP_CORE_ABILITIES_PACKAGE_VERSION)
232408
+ };
232409
+ if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {}) && JSON.stringify(nextDependencies) === JSON.stringify(packageJson.dependencies ?? {})) {
232301
232410
  return;
232302
232411
  }
232303
232412
  packageJson.scripts = nextScripts;
232413
+ packageJson.dependencies = nextDependencies;
232304
232414
  await fsp19.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
232305
232415
  `, "utf8");
232306
232416
  }
232307
232417
  async function ensureAbilitySyncProjectAnchors(workspace) {
232308
- const syncProjectScriptPath = path53.join(workspace.projectDir, "scripts", "sync-project.ts");
232418
+ const syncProjectScriptPath = path54.join(workspace.projectDir, "scripts", "sync-project.ts");
232309
232419
  await patchFile(syncProjectScriptPath, (source) => {
232310
232420
  let nextSource = source;
232311
232421
  const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
@@ -232320,7 +232430,7 @@ async function ensureAbilitySyncProjectAnchors(workspace) {
232320
232430
  if (!nextSource.includes(syncAbilitiesConst)) {
232321
232431
  if (!nextSource.includes(syncRestConst)) {
232322
232432
  throw new Error([
232323
- `ensureAbilitySyncProjectAnchors could not patch ${path53.basename(syncProjectScriptPath)}.`,
232433
+ `ensureAbilitySyncProjectAnchors could not patch ${path54.basename(syncProjectScriptPath)}.`,
232324
232434
  "Missing the expected sync-rest script constant in scripts/sync-project.ts.",
232325
232435
  "Restore the generated template or wire sync-abilities manually before retrying."
232326
232436
  ].join(" "));
@@ -232331,7 +232441,7 @@ ${syncAbilitiesConst}`);
232331
232441
  if (!nextSource.includes("runSyncScript( syncAbilitiesScriptPath, options );")) {
232332
232442
  if (!syncRestBlockPattern.test(nextSource)) {
232333
232443
  throw new Error([
232334
- `ensureAbilitySyncProjectAnchors could not patch ${path53.basename(syncProjectScriptPath)}.`,
232444
+ `ensureAbilitySyncProjectAnchors could not patch ${path54.basename(syncProjectScriptPath)}.`,
232335
232445
  "Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
232336
232446
  "Restore the generated template or wire sync-abilities manually before retrying."
232337
232447
  ].join(" "));
@@ -232344,7 +232454,7 @@ ${syncAbilitiesBlock}`);
232344
232454
  });
232345
232455
  }
232346
232456
  async function ensureAbilityBuildScriptAnchors(workspace) {
232347
- const buildScriptPath = path53.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232457
+ const buildScriptPath = path54.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232348
232458
  await patchFile(buildScriptPath, (source) => {
232349
232459
  let nextSource = source;
232350
232460
  if (/['"]src\/abilities\/index\.(?:ts|js)['"]/u.test(nextSource)) {
@@ -232354,7 +232464,7 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
232354
232464
  const match3 = nextSource.match(sharedEntriesPattern);
232355
232465
  if (!match3 || !match3[2].includes("src/bindings/index.ts") || !match3[2].includes("src/editor-plugins/index.ts")) {
232356
232466
  throw new Error([
232357
- `ensureAbilityBuildScriptAnchors could not patch ${path53.basename(buildScriptPath)}.`,
232467
+ `ensureAbilityBuildScriptAnchors could not patch ${path54.basename(buildScriptPath)}.`,
232358
232468
  "Missing the expected shared editor entries array in scripts/build-workspace.mjs.",
232359
232469
  "Restore the generated template or wire abilities/index manually before retrying."
232360
232470
  ].join(" "));
@@ -232371,16 +232481,38 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
232371
232481
  });
232372
232482
  }
232373
232483
  async function ensureAbilityWebpackAnchors(workspace) {
232374
- const webpackConfigPath = path53.join(workspace.projectDir, "webpack.config.js");
232484
+ const webpackConfigPath = path54.join(workspace.projectDir, "webpack.config.js");
232375
232485
  await patchFile(webpackConfigPath, (source) => {
232376
232486
  if (/['"]abilities\/index['"]/u.test(source)) {
232377
232487
  return source;
232378
232488
  }
232489
+ const optionalModuleReturnPattern = /(function\s+getOptionalModuleEntries\s*\(\)\s*\{[\s\S]*?)(\n\treturn Object\.fromEntries\(\s*entries\s*\);\n\})/u;
232490
+ if (optionalModuleReturnPattern.test(source)) {
232491
+ return source.replace(optionalModuleReturnPattern, `$1
232492
+
232493
+ for ( const [ entryName, candidates ] of [
232494
+ [
232495
+ 'abilities/index',
232496
+ [ 'src/abilities/index.ts', 'src/abilities/index.js' ],
232497
+ ],
232498
+ ] ) {
232499
+ for ( const relativePath of candidates ) {
232500
+ const entryPath = path.resolve( process.cwd(), relativePath );
232501
+ if ( ! fs.existsSync( entryPath ) ) {
232502
+ continue;
232503
+ }
232504
+
232505
+ entries.push( [ entryName, entryPath ] );
232506
+ break;
232507
+ }
232508
+ }
232509
+ $2`);
232510
+ }
232379
232511
  const sharedEntriesPattern = /for\s*\(\s*const\s+\[\s*entryName\s*,\s*candidates\s*\]\s+of\s+\[([\s\S]*?)\]\s*\)\s*\{/u;
232380
232512
  const match3 = source.match(sharedEntriesPattern);
232381
232513
  if (!match3 || !match3[1].includes("bindings/index") || !match3[1].includes("editor-plugins/index")) {
232382
232514
  throw new Error([
232383
- `ensureAbilityWebpackAnchors could not patch ${path53.basename(webpackConfigPath)}.`,
232515
+ `ensureAbilityWebpackAnchors could not patch ${path54.basename(webpackConfigPath)}.`,
232384
232516
  "Missing the expected shared editor entries block in webpack.config.js.",
232385
232517
  "Restore the generated template or wire abilities/index manually before retrying."
232386
232518
  ].join(" "));
@@ -232410,20 +232542,20 @@ async function runAddAbilityCommand({
232410
232542
  const inventory = readWorkspaceInventory(workspace.projectDir);
232411
232543
  assertAbilityDoesNotExist(workspace.projectDir, abilitySlug, inventory);
232412
232544
  const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY);
232413
- const blockConfigPath = path53.join(workspace.projectDir, "scripts", "block-config.ts");
232545
+ const blockConfigPath = path54.join(workspace.projectDir, "scripts", "block-config.ts");
232414
232546
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
232415
- const buildScriptPath = path53.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232416
- const packageJsonPath = path53.join(workspace.projectDir, "package.json");
232417
- const syncAbilitiesScriptPath = path53.join(workspace.projectDir, "scripts", "sync-abilities.ts");
232418
- const syncProjectScriptPath = path53.join(workspace.projectDir, "scripts", "sync-project.ts");
232419
- const webpackConfigPath = path53.join(workspace.projectDir, "webpack.config.js");
232547
+ const buildScriptPath = path54.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232548
+ const packageJsonPath = path54.join(workspace.projectDir, "package.json");
232549
+ const syncAbilitiesScriptPath = path54.join(workspace.projectDir, "scripts", "sync-abilities.ts");
232550
+ const syncProjectScriptPath = path54.join(workspace.projectDir, "scripts", "sync-project.ts");
232551
+ const webpackConfigPath = path54.join(workspace.projectDir, "webpack.config.js");
232420
232552
  const abilitiesIndexPath = resolveAbilityRegistryPath(workspace.projectDir);
232421
- const abilityDir = path53.join(workspace.projectDir, "src", "abilities", abilitySlug);
232422
- const configFilePath = path53.join(abilityDir, "ability.config.json");
232423
- const typesFilePath = path53.join(abilityDir, "types.ts");
232424
- const dataFilePath = path53.join(abilityDir, "data.ts");
232425
- const clientFilePath = path53.join(abilityDir, "client.ts");
232426
- const phpFilePath = path53.join(workspace.projectDir, "inc", "abilities", `${abilitySlug}.php`);
232553
+ const abilityDir = path54.join(workspace.projectDir, "src", "abilities", abilitySlug);
232554
+ const configFilePath = path54.join(abilityDir, "ability.config.json");
232555
+ const typesFilePath = path54.join(abilityDir, "types.ts");
232556
+ const dataFilePath = path54.join(abilityDir, "data.ts");
232557
+ const clientFilePath = path54.join(abilityDir, "client.ts");
232558
+ const phpFilePath = path54.join(workspace.projectDir, "inc", "abilities", `${abilitySlug}.php`);
232427
232559
  const mutationSnapshot = {
232428
232560
  fileSources: await snapshotWorkspaceFiles([
232429
232561
  blockConfigPath,
@@ -232440,7 +232572,7 @@ async function runAddAbilityCommand({
232440
232572
  };
232441
232573
  try {
232442
232574
  await fsp19.mkdir(abilityDir, { recursive: true });
232443
- await fsp19.mkdir(path53.dirname(phpFilePath), { recursive: true });
232575
+ await fsp19.mkdir(path54.dirname(phpFilePath), { recursive: true });
232444
232576
  await ensureAbilityBootstrapAnchors(workspace);
232445
232577
  await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
232446
232578
  await ensureAbilityPackageScripts(workspace);
@@ -232479,12 +232611,13 @@ async function runAddAbilityCommand({
232479
232611
  throw error48;
232480
232612
  }
232481
232613
  }
232482
- var ABILITY_SERVER_GLOB = "/inc/abilities/*.php", ABILITY_EDITOR_SCRIPT = "build/abilities/index.js", ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php", ABILITY_REGISTRY_END_MARKER = "// wp-typia add ability entries end", ABILITY_REGISTRY_START_MARKER = "// wp-typia add ability entries start", WP_ABILITIES_SCRIPT_HANDLE = "wp-abilities", WP_CORE_ABILITIES_SCRIPT_HANDLE = "wp-core-abilities";
232614
+ var import_semver2, ABILITY_SERVER_GLOB = "/inc/abilities/*.php", ABILITY_EDITOR_SCRIPT = "build/abilities/index.js", ABILITY_EDITOR_ASSET = "build/abilities/index.asset.php", ABILITY_REGISTRY_END_MARKER = "// wp-typia add ability entries end", ABILITY_REGISTRY_START_MARKER = "// wp-typia add ability entries start", WP_ABILITIES_PACKAGE_VERSION = "^0.10.0", WP_CORE_ABILITIES_PACKAGE_VERSION = "^0.9.0", WP_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/abilities", WP_CORE_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/core-abilities";
232483
232615
  var init_cli_add_workspace_ability = __esm(() => {
232484
232616
  init_workspace_inventory();
232485
232617
  init_workspace_project();
232486
232618
  init_cli_add_shared();
232487
232619
  init_scaffold_compatibility();
232620
+ import_semver2 = __toESM(require_semver2(), 1);
232488
232621
  });
232489
232622
 
232490
232623
  // ../wp-typia-project-tools/src/runtime/schema-core.ts
@@ -232516,7 +232649,7 @@ var init_ai_artifacts = __esm(() => {
232516
232649
 
232517
232650
  // ../wp-typia-project-tools/src/runtime/ai-feature-artifacts.ts
232518
232651
  import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
232519
- import path54 from "path";
232652
+ import path55 from "path";
232520
232653
  import {
232521
232654
  defineEndpointManifest as defineEndpointManifest3,
232522
232655
  syncEndpointClient as syncEndpointClient3,
@@ -232529,7 +232662,7 @@ function normalizeGeneratedArtifactContent(content) {
232529
232662
  }
232530
232663
  async function reconcileGeneratedArtifact(options) {
232531
232664
  if (!options.check) {
232532
- await mkdir3(path54.dirname(options.filePath), {
232665
+ await mkdir3(path55.dirname(options.filePath), {
232533
232666
  recursive: true
232534
232667
  });
232535
232668
  await writeFile5(options.filePath, options.content, "utf8");
@@ -232601,8 +232734,8 @@ async function syncAiFeatureRestArtifacts({
232601
232734
  const manifest = buildAiFeatureEndpointManifest(variables);
232602
232735
  for (const [baseName, contract] of Object.entries(manifest.contracts)) {
232603
232736
  await syncTypeSchemas4({
232604
- jsonSchemaFile: path54.join(outputDir, "api-schemas", `${baseName}.schema.json`),
232605
- openApiFile: path54.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
232737
+ jsonSchemaFile: path55.join(outputDir, "api-schemas", `${baseName}.schema.json`),
232738
+ openApiFile: path55.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
232606
232739
  projectRoot: projectDir,
232607
232740
  sourceTypeName: contract.sourceTypeName,
232608
232741
  typesFile
@@ -232610,7 +232743,7 @@ async function syncAiFeatureRestArtifacts({
232610
232743
  }
232611
232744
  await syncRestOpenApi3({
232612
232745
  manifest,
232613
- openApiFile: path54.join(outputDir, "api.openapi.json"),
232746
+ openApiFile: path55.join(outputDir, "api.openapi.json"),
232614
232747
  projectRoot: projectDir,
232615
232748
  typesFile
232616
232749
  }, executionOptions);
@@ -232628,19 +232761,19 @@ async function syncAiFeatureSchemaArtifact({
232628
232761
  outputDir,
232629
232762
  projectDir
232630
232763
  }) {
232631
- const sourceSchemaPath = path54.join(projectDir, outputDir, "api-schemas", "feature-result.schema.json");
232764
+ const sourceSchemaPath = path55.join(projectDir, outputDir, "api-schemas", "feature-result.schema.json");
232632
232765
  const responseSchema = assertJsonObject(JSON.parse(await readFile5(sourceSchemaPath, "utf8")), sourceSchemaPath);
232633
232766
  const aiSchema = projectWordPressAiSchema(responseSchema);
232634
232767
  await reconcileGeneratedArtifact({
232635
232768
  check: check2,
232636
232769
  content: `${JSON.stringify(aiSchema, null, 2)}
232637
232770
  `,
232638
- filePath: path54.join(projectDir, aiSchemaFile),
232771
+ filePath: path55.join(projectDir, aiSchemaFile),
232639
232772
  label: "AI feature schema"
232640
232773
  });
232641
232774
  return {
232642
232775
  aiSchema,
232643
- aiSchemaPath: path54.join(projectDir, aiSchemaFile),
232776
+ aiSchemaPath: path55.join(projectDir, aiSchemaFile),
232644
232777
  check: check2,
232645
232778
  sourceSchemaPath
232646
232779
  };
@@ -232975,7 +233108,7 @@ var init_cli_add_workspace_ai_source_emitters = __esm(() => {
232975
233108
 
232976
233109
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai-anchors.ts
232977
233110
  import { promises as fsp20 } from "fs";
232978
- import path55 from "path";
233111
+ import path56 from "path";
232979
233112
  function escapeRegex6(value2) {
232980
233113
  return value2.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
232981
233114
  }
@@ -233026,7 +233159,7 @@ ${snippet}
233026
233159
  insertPhpSnippet(registerFunction);
233027
233160
  } else if (!nextSource.includes(AI_FEATURE_SERVER_GLOB)) {
233028
233161
  throw new Error([
233029
- `Unable to patch ${path55.basename(bootstrapPath)} in ensureAiFeatureBootstrapAnchors.`,
233162
+ `Unable to patch ${path56.basename(bootstrapPath)} in ensureAiFeatureBootstrapAnchors.`,
233030
233163
  `The existing ${registerFunctionName}() definition does not include ${AI_FEATURE_SERVER_GLOB}.`,
233031
233164
  "Restore the generated bootstrap shape or wire the AI feature loader manually before retrying."
233032
233165
  ].join(" "));
@@ -233038,7 +233171,7 @@ ${snippet}
233038
233171
  });
233039
233172
  }
233040
233173
  async function ensureAiFeaturePackageScripts(workspace) {
233041
- const packageJsonPath = path55.join(workspace.projectDir, "package.json");
233174
+ const packageJsonPath = path56.join(workspace.projectDir, "package.json");
233042
233175
  const packageJson = JSON.parse(await fsp20.readFile(packageJsonPath, "utf8"));
233043
233176
  const nextScripts = {
233044
233177
  ...packageJson.scripts ?? {},
@@ -233066,7 +233199,7 @@ async function ensureAiFeaturePackageScripts(workspace) {
233066
233199
  };
233067
233200
  }
233068
233201
  async function ensureAiFeatureSyncProjectAnchors(workspace) {
233069
- const syncProjectScriptPath = path55.join(workspace.projectDir, "scripts", "sync-project.ts");
233202
+ const syncProjectScriptPath = path56.join(workspace.projectDir, "scripts", "sync-project.ts");
233070
233203
  await patchFile(syncProjectScriptPath, (source) => {
233071
233204
  let nextSource = source;
233072
233205
  const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
@@ -233081,7 +233214,7 @@ async function ensureAiFeatureSyncProjectAnchors(workspace) {
233081
233214
  if (!nextSource.includes(syncAiConst)) {
233082
233215
  if (!nextSource.includes(syncRestConst)) {
233083
233216
  throw new Error([
233084
- `ensureAiFeatureSyncProjectAnchors could not patch ${path55.basename(syncProjectScriptPath)}.`,
233217
+ `ensureAiFeatureSyncProjectAnchors could not patch ${path56.basename(syncProjectScriptPath)}.`,
233085
233218
  "Missing the expected sync-rest script constant in scripts/sync-project.ts.",
233086
233219
  "Restore the generated template or wire sync-ai manually before retrying."
233087
233220
  ].join(" "));
@@ -233092,7 +233225,7 @@ ${syncAiConst}`);
233092
233225
  if (!nextSource.includes("runSyncScript( syncAiScriptPath, options );")) {
233093
233226
  if (!syncRestBlockPattern.test(nextSource)) {
233094
233227
  throw new Error([
233095
- `ensureAiFeatureSyncProjectAnchors could not patch ${path55.basename(syncProjectScriptPath)}.`,
233228
+ `ensureAiFeatureSyncProjectAnchors could not patch ${path56.basename(syncProjectScriptPath)}.`,
233096
233229
  "Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
233097
233230
  "Restore the generated template or wire sync-ai manually before retrying."
233098
233231
  ].join(" "));
@@ -233107,7 +233240,7 @@ ${syncAiBlock}`);
233107
233240
  function assertSyncRestAnchor2(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
233108
233241
  if (!nextSource.includes(target) && !hasAnchor) {
233109
233242
  throw new Error([
233110
- `ensureAiFeatureSyncRestAnchors could not patch ${path55.basename(syncRestScriptPath)}.`,
233243
+ `ensureAiFeatureSyncRestAnchors could not patch ${path56.basename(syncRestScriptPath)}.`,
233111
233244
  `Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
233112
233245
  "Restore the generated template or add the AI feature wiring manually before retrying."
233113
233246
  ].join(" "));
@@ -233122,7 +233255,7 @@ function replaceRequiredSyncRestSource2(nextSource, target, anchor, replacement,
233122
233255
  return nextSource.replace(anchor, replacement);
233123
233256
  }
233124
233257
  async function ensureAiFeatureSyncRestAnchors(workspace) {
233125
- const syncRestScriptPath = path55.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
233258
+ const syncRestScriptPath = path56.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
233126
233259
  await patchFile(syncRestScriptPath, (source) => {
233127
233260
  let nextSource = source;
233128
233261
  const importAnchor = [
@@ -233257,7 +233390,7 @@ var init_cli_add_workspace_ai_anchors = __esm(() => {
233257
233390
 
233258
233391
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai.ts
233259
233392
  import { promises as fsp21 } from "fs";
233260
- import path56 from "path";
233393
+ import path57 from "path";
233261
233394
  function quotePhpString4(value2) {
233262
233395
  return `'${value2.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
233263
233396
  }
@@ -233649,18 +233782,18 @@ async function runAddAiFeatureCommand({
233649
233782
  const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY);
233650
233783
  const inventory = readWorkspaceInventory(workspace.projectDir);
233651
233784
  assertAiFeatureDoesNotExist(workspace.projectDir, aiFeatureSlug, inventory);
233652
- const blockConfigPath = path56.join(workspace.projectDir, "scripts", "block-config.ts");
233785
+ const blockConfigPath = path57.join(workspace.projectDir, "scripts", "block-config.ts");
233653
233786
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
233654
- const packageJsonPath = path56.join(workspace.projectDir, "package.json");
233655
- const syncAiScriptPath = path56.join(workspace.projectDir, "scripts", "sync-ai-features.ts");
233656
- const syncProjectScriptPath = path56.join(workspace.projectDir, "scripts", "sync-project.ts");
233657
- const syncRestScriptPath = path56.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
233658
- const aiFeatureDir = path56.join(workspace.projectDir, "src", "ai-features", aiFeatureSlug);
233659
- const typesFilePath = path56.join(aiFeatureDir, "api-types.ts");
233660
- const validatorsFilePath = path56.join(aiFeatureDir, "api-validators.ts");
233661
- const apiFilePath = path56.join(aiFeatureDir, "api.ts");
233662
- const dataFilePath = path56.join(aiFeatureDir, "data.ts");
233663
- const phpFilePath = path56.join(workspace.projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
233787
+ const packageJsonPath = path57.join(workspace.projectDir, "package.json");
233788
+ const syncAiScriptPath = path57.join(workspace.projectDir, "scripts", "sync-ai-features.ts");
233789
+ const syncProjectScriptPath = path57.join(workspace.projectDir, "scripts", "sync-project.ts");
233790
+ const syncRestScriptPath = path57.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
233791
+ const aiFeatureDir = path57.join(workspace.projectDir, "src", "ai-features", aiFeatureSlug);
233792
+ const typesFilePath = path57.join(aiFeatureDir, "api-types.ts");
233793
+ const validatorsFilePath = path57.join(aiFeatureDir, "api-validators.ts");
233794
+ const apiFilePath = path57.join(aiFeatureDir, "api.ts");
233795
+ const dataFilePath = path57.join(aiFeatureDir, "data.ts");
233796
+ const phpFilePath = path57.join(workspace.projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
233664
233797
  const mutationSnapshot = {
233665
233798
  fileSources: await snapshotWorkspaceFiles([
233666
233799
  blockConfigPath,
@@ -233675,7 +233808,7 @@ async function runAddAiFeatureCommand({
233675
233808
  };
233676
233809
  try {
233677
233810
  await fsp21.mkdir(aiFeatureDir, { recursive: true });
233678
- await fsp21.mkdir(path56.dirname(phpFilePath), { recursive: true });
233811
+ await fsp21.mkdir(path57.dirname(phpFilePath), { recursive: true });
233679
233812
  await ensureAiFeatureBootstrapAnchors(workspace);
233680
233813
  await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
233681
233814
  const packageScriptChanges = await ensureAiFeaturePackageScripts(workspace);
@@ -233690,7 +233823,7 @@ async function runAddAiFeatureCommand({
233690
233823
  const pascalCase = toPascalCaseFromAiFeatureSlug(aiFeatureSlug);
233691
233824
  await syncAiFeatureRestArtifacts({
233692
233825
  clientFile: `src/ai-features/${aiFeatureSlug}/api-client.ts`,
233693
- outputDir: path56.join("src", "ai-features", aiFeatureSlug),
233826
+ outputDir: path57.join("src", "ai-features", aiFeatureSlug),
233694
233827
  projectDir: workspace.projectDir,
233695
233828
  typesFile: `src/ai-features/${aiFeatureSlug}/api-types.ts`,
233696
233829
  validatorsFile: `src/ai-features/${aiFeatureSlug}/api-validators.ts`,
@@ -233703,7 +233836,7 @@ async function runAddAiFeatureCommand({
233703
233836
  });
233704
233837
  await syncAiFeatureSchemaArtifact({
233705
233838
  aiSchemaFile: `src/ai-features/${aiFeatureSlug}/ai-schemas/feature-result.ai.schema.json`,
233706
- outputDir: path56.join("src", "ai-features", aiFeatureSlug),
233839
+ outputDir: path57.join("src", "ai-features", aiFeatureSlug),
233707
233840
  projectDir: workspace.projectDir
233708
233841
  });
233709
233842
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
@@ -233739,7 +233872,7 @@ var init_cli_add_workspace_ai = __esm(() => {
233739
233872
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace.ts
233740
233873
  import fs43 from "fs";
233741
233874
  import { promises as fsp22 } from "fs";
233742
- import path57 from "path";
233875
+ import path58 from "path";
233743
233876
  function buildVariationConfigEntry(blockSlug, variationSlug) {
233744
233877
  return [
233745
233878
  "\t{",
@@ -233840,14 +233973,14 @@ ${VARIATIONS_CALL_LINE}
233840
233973
  }
233841
233974
  }
233842
233975
  if (!nextSource.includes(VARIATIONS_CALL_LINE)) {
233843
- throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${path57.basename(blockIndexPath)}.`);
233976
+ throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${path58.basename(blockIndexPath)}.`);
233844
233977
  }
233845
233978
  return nextSource;
233846
233979
  });
233847
233980
  }
233848
233981
  async function writeVariationRegistry(projectDir, blockSlug, variationSlug) {
233849
- const variationsDir = path57.join(projectDir, "src", "blocks", blockSlug, "variations");
233850
- const variationsIndexPath = path57.join(variationsDir, "index.ts");
233982
+ const variationsDir = path58.join(projectDir, "src", "blocks", blockSlug, "variations");
233983
+ const variationsIndexPath = path58.join(variationsDir, "index.ts");
233851
233984
  await fsp22.mkdir(variationsDir, { recursive: true });
233852
233985
  const existingVariationSlugs = fs43.readdirSync(variationsDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
233853
233986
  const nextVariationSlugs = Array.from(new Set([...existingVariationSlugs, variationSlug])).sort();
@@ -233864,11 +233997,11 @@ async function runAddVariationCommand({
233864
233997
  const inventory = readWorkspaceInventory(workspace.projectDir);
233865
233998
  resolveWorkspaceBlock(inventory, blockSlug);
233866
233999
  assertVariationDoesNotExist(workspace.projectDir, blockSlug, variationSlug, inventory);
233867
- const blockConfigPath = path57.join(workspace.projectDir, "scripts", "block-config.ts");
233868
- const blockIndexPath = path57.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
233869
- const variationsDir = path57.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
233870
- const variationFilePath = path57.join(variationsDir, `${variationSlug}.ts`);
233871
- const variationsIndexPath = path57.join(variationsDir, "index.ts");
234000
+ const blockConfigPath = path58.join(workspace.projectDir, "scripts", "block-config.ts");
234001
+ const blockIndexPath = path58.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
234002
+ const variationsDir = path58.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
234003
+ const variationFilePath = path58.join(variationsDir, `${variationSlug}.ts`);
234004
+ const variationsIndexPath = path58.join(variationsDir, "index.ts");
233872
234005
  const mutationSnapshot = {
233873
234006
  fileSources: await snapshotWorkspaceFiles([
233874
234007
  blockConfigPath,
@@ -233913,7 +234046,7 @@ async function runAddHookedBlockCommand({
233913
234046
  throw new Error("`wp-typia add hooked-block` cannot hook a block relative to its own block name.");
233914
234047
  }
233915
234048
  const { blockJson, blockJsonPath } = readWorkspaceBlockJson(workspace.projectDir, blockSlug);
233916
- const blockJsonRelativePath = path57.relative(workspace.projectDir, blockJsonPath);
234049
+ const blockJsonRelativePath = path58.relative(workspace.projectDir, blockJsonPath);
233917
234050
  const blockHooks = getMutableBlockHooks(blockJson, blockJsonRelativePath);
233918
234051
  if (Object.prototype.hasOwnProperty.call(blockHooks, resolvedAnchorBlockName)) {
233919
234052
  throw new Error(`${blockJsonRelativePath} already defines a blockHooks entry for "${resolvedAnchorBlockName}".`);
@@ -233979,7 +234112,7 @@ import { execFileSync as execFileSync3 } from "child_process";
233979
234112
  import { access, constants as fsConstants, rm as rm2, writeFile as writeFile6 } from "fs/promises";
233980
234113
  import fs44 from "fs";
233981
234114
  import os4 from "os";
233982
- import path58 from "path";
234115
+ import path59 from "path";
233983
234116
  function readCommandVersion(command, args = ["--version"]) {
233984
234117
  try {
233985
234118
  return execFileSync3(command, args, {
@@ -234003,7 +234136,7 @@ async function checkWritableDirectory(directory) {
234003
234136
  }
234004
234137
  }
234005
234138
  async function checkTempDirectory() {
234006
- const tempFile = path58.join(os4.tmpdir(), `wp-typia-${Date.now()}.tmp`);
234139
+ const tempFile = path59.join(os4.tmpdir(), `wp-typia-${Date.now()}.tmp`);
234007
234140
  try {
234008
234141
  await writeFile6(tempFile, "ok", "utf8");
234009
234142
  await rm2(tempFile, { force: true });
@@ -234020,7 +234153,7 @@ function getTemplateDoctorChecks() {
234020
234153
  for (const template of listTemplates()) {
234021
234154
  if (!isBuiltInTemplateId(template.id)) {
234022
234155
  const templateDirExists = fs44.existsSync(template.templateDir);
234023
- const hasAssets2 = templateDirExists && fs44.existsSync(path58.join(template.templateDir, "package.json.mustache"));
234156
+ const hasAssets2 = templateDirExists && fs44.existsSync(path59.join(template.templateDir, "package.json.mustache"));
234024
234157
  checks3.push({
234025
234158
  status: !templateDirExists || hasAssets2 ? "pass" : "fail",
234026
234159
  label: `Template ${template.id}`,
@@ -234045,7 +234178,7 @@ function getTemplateDoctorChecks() {
234045
234178
  ])) : getBuiltInTemplateLayerDirs(builtInTemplateId);
234046
234179
  const missingRequiredLayer = layerDirs.some((layerDir) => !fs44.existsSync(layerDir) && !isOmittableBuiltInTemplateLayerDir(builtInTemplateId, layerDir));
234047
234180
  const existingLayerDirs = layerDirs.filter((layerDir) => fs44.existsSync(layerDir));
234048
- const hasAssets = !missingRequiredLayer && existingLayerDirs.some((layerDir) => fs44.existsSync(path58.join(layerDir, "package.json.mustache"))) && existingLayerDirs.some((layerDir) => fs44.existsSync(path58.join(layerDir, "src")));
234181
+ const hasAssets = !missingRequiredLayer && existingLayerDirs.some((layerDir) => fs44.existsSync(path59.join(layerDir, "package.json.mustache"))) && existingLayerDirs.some((layerDir) => fs44.existsSync(path59.join(layerDir, "src")));
234049
234182
  checks3.push({
234050
234183
  status: hasAssets ? "pass" : "fail",
234051
234184
  label: `Template ${template.id}`,
@@ -234076,7 +234209,7 @@ var init_cli_doctor_environment = __esm(() => {
234076
234209
 
234077
234210
  // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace.ts
234078
234211
  import fs45 from "fs";
234079
- import path59 from "path";
234212
+ import path60 from "path";
234080
234213
  import { parseScaffoldBlockMetadata as parseScaffoldBlockMetadata2 } from "@wp-typia/block-runtime/blocks";
234081
234214
  function createDoctorCheck2(label, status, detail) {
234082
234215
  return { detail, label, status };
@@ -234092,7 +234225,7 @@ function getWorkspaceBootstrapRelativePath(packageName) {
234092
234225
  return `${packageBaseName}.php`;
234093
234226
  }
234094
234227
  function checkExistingFiles(projectDir, label, filePaths) {
234095
- const missing = filePaths.filter((filePath) => typeof filePath === "string").filter((filePath) => !fs45.existsSync(path59.join(projectDir, filePath)));
234228
+ const missing = filePaths.filter((filePath) => typeof filePath === "string").filter((filePath) => !fs45.existsSync(path60.join(projectDir, filePath)));
234096
234229
  return createDoctorCheck2(label, missing.length === 0 ? "pass" : "fail", missing.length === 0 ? "All referenced files exist" : `Missing: ${missing.join(", ")}`);
234097
234230
  }
234098
234231
  function checkWorkspacePackageMetadata(workspace, packageJson) {
@@ -234118,24 +234251,24 @@ function checkWorkspacePackageMetadata(workspace, packageJson) {
234118
234251
  if (wpTypia?.phpPrefix !== workspace.workspace.phpPrefix) {
234119
234252
  issues.push(`wpTypia.phpPrefix must equal "${workspace.workspace.phpPrefix}"`);
234120
234253
  }
234121
- if (!fs45.existsSync(path59.join(workspace.projectDir, bootstrapRelativePath))) {
234254
+ if (!fs45.existsSync(path60.join(workspace.projectDir, bootstrapRelativePath))) {
234122
234255
  issues.push(`Missing bootstrap file ${bootstrapRelativePath}`);
234123
234256
  }
234124
234257
  return createDoctorCheck2("Workspace package metadata", issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `package.json metadata aligns with ${workspace.packageName} and ${bootstrapRelativePath}` : issues.join("; "));
234125
234258
  }
234126
234259
  function getWorkspaceBlockRequiredFiles(block) {
234127
- const blockDir = path59.join("src", "blocks", block.slug);
234260
+ const blockDir = path60.join("src", "blocks", block.slug);
234128
234261
  return Array.from(new Set([
234129
234262
  block.typesFile,
234130
234263
  block.apiTypesFile,
234131
234264
  block.openApiFile,
234132
- path59.join(blockDir, "index.tsx"),
234133
- ...WORKSPACE_GENERATED_BLOCK_ARTIFACTS.map((fileName) => path59.join(blockDir, fileName))
234265
+ path60.join(blockDir, "index.tsx"),
234266
+ ...WORKSPACE_GENERATED_BLOCK_ARTIFACTS.map((fileName) => path60.join(blockDir, fileName))
234134
234267
  ].filter((filePath) => typeof filePath === "string")));
234135
234268
  }
234136
234269
  function checkWorkspaceBlockMetadata(projectDir, workspace, block) {
234137
- const blockJsonRelativePath = path59.join("src", "blocks", block.slug, "block.json");
234138
- const blockJsonPath = path59.join(projectDir, blockJsonRelativePath);
234270
+ const blockJsonRelativePath = path60.join("src", "blocks", block.slug, "block.json");
234271
+ const blockJsonPath = path60.join(projectDir, blockJsonRelativePath);
234139
234272
  if (!fs45.existsSync(blockJsonPath)) {
234140
234273
  return createDoctorCheck2(`Block metadata ${block.slug}`, "fail", `Missing ${blockJsonRelativePath}`);
234141
234274
  }
@@ -234156,8 +234289,8 @@ function checkWorkspaceBlockMetadata(projectDir, workspace, block) {
234156
234289
  return createDoctorCheck2(`Block metadata ${block.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `block.json matches ${expectedName} and ${workspace.workspace.textDomain}` : issues.join("; "));
234157
234290
  }
234158
234291
  function checkWorkspaceBlockHooks(projectDir, blockSlug) {
234159
- const blockJsonRelativePath = path59.join("src", "blocks", blockSlug, "block.json");
234160
- const blockJsonPath = path59.join(projectDir, blockJsonRelativePath);
234292
+ const blockJsonRelativePath = path60.join("src", "blocks", blockSlug, "block.json");
234293
+ const blockJsonPath = path60.join(projectDir, blockJsonRelativePath);
234161
234294
  if (!fs45.existsSync(blockJsonPath)) {
234162
234295
  return createDoctorCheck2(`Block hooks ${blockSlug}`, "fail", `Missing ${blockJsonRelativePath}`);
234163
234296
  }
@@ -234179,8 +234312,8 @@ function checkWorkspaceBlockHooks(projectDir, blockSlug) {
234179
234312
  return createDoctorCheck2(`Block hooks ${blockSlug}`, invalidEntries.length === 0 ? "pass" : "fail", invalidEntries.length === 0 ? `blockHooks metadata is valid${Object.keys(blockHooks).length > 0 ? ` (${Object.keys(blockHooks).join(", ")})` : ""}` : `Invalid blockHooks entries: ${invalidEntries.map(([anchor, position]) => `${anchor || "<empty>"} => ${String(position)}`).join(", ")}`);
234180
234313
  }
234181
234314
  function checkWorkspaceBlockCollectionImport(projectDir, blockSlug) {
234182
- const entryRelativePath = path59.join("src", "blocks", blockSlug, "index.tsx");
234183
- const entryPath = path59.join(projectDir, entryRelativePath);
234315
+ const entryRelativePath = path60.join("src", "blocks", blockSlug, "index.tsx");
234316
+ const entryPath = path60.join(projectDir, entryRelativePath);
234184
234317
  if (!fs45.existsSync(entryPath)) {
234185
234318
  return createDoctorCheck2(`Block collection ${blockSlug}`, "fail", `Missing ${entryRelativePath}`);
234186
234319
  }
@@ -234190,9 +234323,9 @@ function checkWorkspaceBlockCollectionImport(projectDir, blockSlug) {
234190
234323
  }
234191
234324
  function checkWorkspacePatternBootstrap(projectDir, packageName) {
234192
234325
  const packageBaseName = packageName.split("/").pop() ?? packageName;
234193
- const bootstrapPath = path59.join(projectDir, `${packageBaseName}.php`);
234326
+ const bootstrapPath = path60.join(projectDir, `${packageBaseName}.php`);
234194
234327
  if (!fs45.existsSync(bootstrapPath)) {
234195
- return createDoctorCheck2("Pattern bootstrap", "fail", `Missing ${path59.basename(bootstrapPath)}`);
234328
+ return createDoctorCheck2("Pattern bootstrap", "fail", `Missing ${path60.basename(bootstrapPath)}`);
234196
234329
  }
234197
234330
  const source = fs45.readFileSync(bootstrapPath, "utf8");
234198
234331
  const hasCategoryAnchor = source.includes("register_block_pattern_category");
@@ -234201,9 +234334,9 @@ function checkWorkspacePatternBootstrap(projectDir, packageName) {
234201
234334
  }
234202
234335
  function checkWorkspaceBindingBootstrap(projectDir, packageName) {
234203
234336
  const packageBaseName = packageName.split("/").pop() ?? packageName;
234204
- const bootstrapPath = path59.join(projectDir, `${packageBaseName}.php`);
234337
+ const bootstrapPath = path60.join(projectDir, `${packageBaseName}.php`);
234205
234338
  if (!fs45.existsSync(bootstrapPath)) {
234206
- return createDoctorCheck2("Binding bootstrap", "fail", `Missing ${path59.basename(bootstrapPath)}`);
234339
+ return createDoctorCheck2("Binding bootstrap", "fail", `Missing ${path60.basename(bootstrapPath)}`);
234207
234340
  }
234208
234341
  const source = fs45.readFileSync(bootstrapPath, "utf8");
234209
234342
  const hasServerGlob = source.includes(WORKSPACE_BINDING_SERVER_GLOB);
@@ -234213,11 +234346,11 @@ function checkWorkspaceBindingBootstrap(projectDir, packageName) {
234213
234346
  return createDoctorCheck2("Binding bootstrap", hasServerGlob && hasEditorEnqueueHook && hasEditorScript && hasEditorAsset ? "pass" : "fail", hasServerGlob && hasEditorEnqueueHook && hasEditorScript && hasEditorAsset ? "Binding source PHP and editor bootstrap hooks are present" : "Missing binding source PHP require glob or editor enqueue hook");
234214
234347
  }
234215
234348
  function checkWorkspaceBindingSourcesIndex(projectDir, bindingSources) {
234216
- const indexRelativePath = [path59.join("src", "bindings", "index.ts"), path59.join("src", "bindings", "index.js")].find((relativePath) => fs45.existsSync(path59.join(projectDir, relativePath)));
234349
+ const indexRelativePath = [path60.join("src", "bindings", "index.ts"), path60.join("src", "bindings", "index.js")].find((relativePath) => fs45.existsSync(path60.join(projectDir, relativePath)));
234217
234350
  if (!indexRelativePath) {
234218
234351
  return createDoctorCheck2("Binding sources index", "fail", "Missing src/bindings/index.ts or src/bindings/index.js");
234219
234352
  }
234220
- const indexPath = path59.join(projectDir, indexRelativePath);
234353
+ const indexPath = path60.join(projectDir, indexRelativePath);
234221
234354
  const source = fs45.readFileSync(indexPath, "utf8");
234222
234355
  const missingImports = bindingSources.filter((bindingSource) => !source.includes(`./${bindingSource.slug}/editor`));
234223
234356
  return createDoctorCheck2("Binding sources index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Binding source editor registrations are aggregated" : `Missing editor imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
@@ -234247,7 +234380,7 @@ function getWorkspaceRestResourceRequiredFiles(restResource) {
234247
234380
  }
234248
234381
  return Array.from(new Set([
234249
234382
  restResource.apiFile,
234250
- ...Array.from(schemaNames, (schemaName) => path59.join(path59.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
234383
+ ...Array.from(schemaNames, (schemaName) => path60.join(path60.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
234251
234384
  restResource.clientFile,
234252
234385
  restResource.dataFile,
234253
234386
  restResource.openApiFile,
@@ -234263,9 +234396,9 @@ function checkWorkspaceRestResourceConfig(restResource) {
234263
234396
  }
234264
234397
  function checkWorkspaceRestResourceBootstrap(projectDir, packageName, phpPrefix) {
234265
234398
  const packageBaseName = packageName.split("/").pop() ?? packageName;
234266
- const bootstrapPath = path59.join(projectDir, `${packageBaseName}.php`);
234399
+ const bootstrapPath = path60.join(projectDir, `${packageBaseName}.php`);
234267
234400
  if (!fs45.existsSync(bootstrapPath)) {
234268
- return createDoctorCheck2("REST resource bootstrap", "fail", `Missing ${path59.basename(bootstrapPath)}`);
234401
+ return createDoctorCheck2("REST resource bootstrap", "fail", `Missing ${path60.basename(bootstrapPath)}`);
234269
234402
  }
234270
234403
  const source = fs45.readFileSync(bootstrapPath, "utf8");
234271
234404
  const registerFunctionName = `${phpPrefix}_register_rest_resources`;
@@ -234286,7 +234419,7 @@ function getWorkspaceAbilityRequiredFiles(ability) {
234286
234419
  ]));
234287
234420
  }
234288
234421
  function checkWorkspaceAbilityConfig(projectDir, ability) {
234289
- const configPath = path59.join(projectDir, ability.configFile);
234422
+ const configPath = path60.join(projectDir, ability.configFile);
234290
234423
  if (!fs45.existsSync(configPath)) {
234291
234424
  return createDoctorCheck2(`Ability config ${ability.slug}`, "fail", `Missing ${ability.configFile}`);
234292
234425
  }
@@ -234303,9 +234436,9 @@ function checkWorkspaceAbilityConfig(projectDir, ability) {
234303
234436
  }
234304
234437
  function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
234305
234438
  const packageBaseName = packageName.split("/").pop() ?? packageName;
234306
- const bootstrapPath = path59.join(projectDir, `${packageBaseName}.php`);
234439
+ const bootstrapPath = path60.join(projectDir, `${packageBaseName}.php`);
234307
234440
  if (!fs45.existsSync(bootstrapPath)) {
234308
- return createDoctorCheck2("Ability bootstrap", "fail", `Missing ${path59.basename(bootstrapPath)}`);
234441
+ return createDoctorCheck2("Ability bootstrap", "fail", `Missing ${path60.basename(bootstrapPath)}`);
234309
234442
  }
234310
234443
  const source = fs45.readFileSync(bootstrapPath, "utf8");
234311
234444
  const loadFunctionName = `${phpPrefix}_load_workflow_abilities`;
@@ -234319,17 +234452,18 @@ function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
234319
234452
  const hasServerGlob = source.includes(WORKSPACE_ABILITY_GLOB);
234320
234453
  const hasEditorScript = source.includes(WORKSPACE_ABILITY_EDITOR_SCRIPT);
234321
234454
  const hasEditorAsset = source.includes(WORKSPACE_ABILITY_EDITOR_ASSET);
234322
- return createDoctorCheck2("Ability bootstrap", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset ? "pass" : "fail", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset ? "Ability loader and admin/editor client bootstrap hooks are present" : "Missing ability loader hook or build/abilities script asset references");
234455
+ const hasScriptModuleEnqueue = source.includes("wp_enqueue_script_module");
234456
+ return createDoctorCheck2("Ability bootstrap", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset && hasScriptModuleEnqueue ? "pass" : "fail", hasLoaderHook && hasAdminEnqueueHook && hasEditorEnqueueHook && hasServerGlob && hasEditorScript && hasEditorAsset && hasScriptModuleEnqueue ? "Ability loader and admin/editor script-module bootstrap hooks are present" : "Missing ability loader hook, script-module enqueue, or build/abilities asset references");
234323
234457
  }
234324
234458
  function checkWorkspaceAbilityIndex(projectDir, abilities) {
234325
234459
  const indexRelativePath = [
234326
- path59.join("src", "abilities", "index.ts"),
234327
- path59.join("src", "abilities", "index.js")
234328
- ].find((relativePath) => fs45.existsSync(path59.join(projectDir, relativePath)));
234460
+ path60.join("src", "abilities", "index.ts"),
234461
+ path60.join("src", "abilities", "index.js")
234462
+ ].find((relativePath) => fs45.existsSync(path60.join(projectDir, relativePath)));
234329
234463
  if (!indexRelativePath) {
234330
234464
  return createDoctorCheck2("Abilities index", "fail", "Missing src/abilities/index.ts or src/abilities/index.js");
234331
234465
  }
234332
- const indexPath = path59.join(projectDir, indexRelativePath);
234466
+ const indexPath = path60.join(projectDir, indexRelativePath);
234333
234467
  const source = fs45.readFileSync(indexPath, "utf8");
234334
234468
  const missingExports = abilities.filter((ability) => {
234335
234469
  const exportPattern = new RegExp(`^\\s*export\\s+(?:\\*\\s+from|\\{[^}]+\\}\\s+from)\\s+['"\`]\\./${escapeRegex7(ability.slug)}\\/client['"\`]`, "mu");
@@ -234341,9 +234475,9 @@ function getWorkspaceAiFeatureRequiredFiles(aiFeature) {
234341
234475
  return Array.from(new Set([
234342
234476
  aiFeature.aiSchemaFile,
234343
234477
  aiFeature.apiFile,
234344
- path59.join(path59.dirname(aiFeature.typesFile), "api-schemas", "feature-request.schema.json"),
234345
- path59.join(path59.dirname(aiFeature.typesFile), "api-schemas", "feature-response.schema.json"),
234346
- path59.join(path59.dirname(aiFeature.typesFile), "api-schemas", "feature-result.schema.json"),
234478
+ path60.join(path60.dirname(aiFeature.typesFile), "api-schemas", "feature-request.schema.json"),
234479
+ path60.join(path60.dirname(aiFeature.typesFile), "api-schemas", "feature-response.schema.json"),
234480
+ path60.join(path60.dirname(aiFeature.typesFile), "api-schemas", "feature-result.schema.json"),
234347
234481
  aiFeature.clientFile,
234348
234482
  aiFeature.dataFile,
234349
234483
  aiFeature.openApiFile,
@@ -234358,9 +234492,9 @@ function checkWorkspaceAiFeatureConfig(aiFeature) {
234358
234492
  }
234359
234493
  function checkWorkspaceAiFeatureBootstrap(projectDir, packageName, phpPrefix) {
234360
234494
  const packageBaseName = packageName.split("/").pop() ?? packageName;
234361
- const bootstrapPath = path59.join(projectDir, `${packageBaseName}.php`);
234495
+ const bootstrapPath = path60.join(projectDir, `${packageBaseName}.php`);
234362
234496
  if (!fs45.existsSync(bootstrapPath)) {
234363
- return createDoctorCheck2("AI feature bootstrap", "fail", `Missing ${path59.basename(bootstrapPath)}`);
234497
+ return createDoctorCheck2("AI feature bootstrap", "fail", `Missing ${path60.basename(bootstrapPath)}`);
234364
234498
  }
234365
234499
  const source = fs45.readFileSync(bootstrapPath, "utf8");
234366
234500
  const registerFunctionName = `${phpPrefix}_register_ai_features`;
@@ -234370,13 +234504,13 @@ function checkWorkspaceAiFeatureBootstrap(projectDir, packageName, phpPrefix) {
234370
234504
  return createDoctorCheck2("AI feature bootstrap", hasServerGlob && hasRegisterHook ? "pass" : "fail", hasServerGlob && hasRegisterHook ? "AI feature PHP loader hook is present" : "Missing AI feature PHP require glob or init hook");
234371
234505
  }
234372
234506
  function getWorkspaceEditorPluginRequiredFiles(editorPlugin) {
234373
- const editorPluginDir = path59.join("src", "editor-plugins", editorPlugin.slug);
234507
+ const editorPluginDir = path60.join("src", "editor-plugins", editorPlugin.slug);
234374
234508
  return Array.from(new Set([
234375
234509
  editorPlugin.file,
234376
- path59.join(editorPluginDir, "Sidebar.tsx"),
234377
- path59.join(editorPluginDir, "data.ts"),
234378
- path59.join(editorPluginDir, "types.ts"),
234379
- path59.join(editorPluginDir, "style.scss")
234510
+ path60.join(editorPluginDir, "Sidebar.tsx"),
234511
+ path60.join(editorPluginDir, "data.ts"),
234512
+ path60.join(editorPluginDir, "types.ts"),
234513
+ path60.join(editorPluginDir, "style.scss")
234380
234514
  ]));
234381
234515
  }
234382
234516
  function checkWorkspaceEditorPluginConfig(editorPlugin) {
@@ -234386,9 +234520,9 @@ function checkWorkspaceEditorPluginConfig(editorPlugin) {
234386
234520
  }
234387
234521
  function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix) {
234388
234522
  const packageBaseName = packageName.split("/").pop() ?? packageName;
234389
- const bootstrapPath = path59.join(projectDir, `${packageBaseName}.php`);
234523
+ const bootstrapPath = path60.join(projectDir, `${packageBaseName}.php`);
234390
234524
  if (!fs45.existsSync(bootstrapPath)) {
234391
- return createDoctorCheck2("Editor plugin bootstrap", "fail", `Missing ${path59.basename(bootstrapPath)}`);
234525
+ return createDoctorCheck2("Editor plugin bootstrap", "fail", `Missing ${path60.basename(bootstrapPath)}`);
234392
234526
  }
234393
234527
  const source = fs45.readFileSync(bootstrapPath, "utf8");
234394
234528
  const enqueueFunctionName = `${phpPrefix}_enqueue_editor_plugins_editor`;
@@ -234401,13 +234535,13 @@ function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix)
234401
234535
  }
234402
234536
  function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
234403
234537
  const indexRelativePath = [
234404
- path59.join("src", "editor-plugins", "index.ts"),
234405
- path59.join("src", "editor-plugins", "index.js")
234406
- ].find((relativePath) => fs45.existsSync(path59.join(projectDir, relativePath)));
234538
+ path60.join("src", "editor-plugins", "index.ts"),
234539
+ path60.join("src", "editor-plugins", "index.js")
234540
+ ].find((relativePath) => fs45.existsSync(path60.join(projectDir, relativePath)));
234407
234541
  if (!indexRelativePath) {
234408
234542
  return createDoctorCheck2("Editor plugins index", "fail", "Missing src/editor-plugins/index.ts or src/editor-plugins/index.js");
234409
234543
  }
234410
- const indexPath = path59.join(projectDir, indexRelativePath);
234544
+ const indexPath = path60.join(projectDir, indexRelativePath);
234411
234545
  const source = fs45.readFileSync(indexPath, "utf8");
234412
234546
  const missingImports = editorPlugins.filter((editorPlugin) => {
234413
234547
  const importPattern = new RegExp(`['"\`]\\./${escapeRegex7(editorPlugin.slug)}(?:/[^'"\`]*)?['"\`]`, "u");
@@ -234416,9 +234550,9 @@ function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
234416
234550
  return createDoctorCheck2("Editor plugins index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Editor plugin registrations are aggregated" : `Missing editor plugin imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
234417
234551
  }
234418
234552
  function checkVariationEntrypoint(projectDir, blockSlug) {
234419
- const entryPath = path59.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
234553
+ const entryPath = path60.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
234420
234554
  if (!fs45.existsSync(entryPath)) {
234421
- return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, "fail", `Missing ${path59.relative(projectDir, entryPath)}`);
234555
+ return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, "fail", `Missing ${path60.relative(projectDir, entryPath)}`);
234422
234556
  }
234423
234557
  const source = fs45.readFileSync(entryPath, "utf8");
234424
234558
  const hasImport = source.includes("./variations");
@@ -234427,8 +234561,8 @@ function checkVariationEntrypoint(projectDir, blockSlug) {
234427
234561
  }
234428
234562
  function checkMigrationWorkspaceHint(workspace, packageJson) {
234429
234563
  const hasMigrationScript = typeof packageJson.scripts?.["migration:doctor"] === "string";
234430
- const migrationConfigRelativePath = path59.join("src", "migrations", "config.ts");
234431
- const hasMigrationConfig = fs45.existsSync(path59.join(workspace.projectDir, migrationConfigRelativePath));
234564
+ const migrationConfigRelativePath = path60.join("src", "migrations", "config.ts");
234565
+ const hasMigrationConfig = fs45.existsSync(path60.join(workspace.projectDir, migrationConfigRelativePath));
234432
234566
  if (!hasMigrationScript && !hasMigrationConfig) {
234433
234567
  return null;
234434
234568
  }
@@ -234486,7 +234620,7 @@ function getWorkspaceDoctorChecks(cwd) {
234486
234620
  for (const blockSlug of variationTargetBlocks) {
234487
234621
  checks3.push(checkVariationEntrypoint(workspace.projectDir, blockSlug));
234488
234622
  }
234489
- const shouldCheckPatternBootstrap = inventory.patterns.length > 0 || fs45.existsSync(path59.join(workspace.projectDir, "src", "patterns"));
234623
+ const shouldCheckPatternBootstrap = inventory.patterns.length > 0 || fs45.existsSync(path60.join(workspace.projectDir, "src", "patterns"));
234490
234624
  if (shouldCheckPatternBootstrap) {
234491
234625
  checks3.push(checkWorkspacePatternBootstrap(workspace.projectDir, workspace.packageName));
234492
234626
  }
@@ -234602,12 +234736,12 @@ __export(exports_cli_init, {
234602
234736
  getInitPlan: () => getInitPlan
234603
234737
  });
234604
234738
  import fs46 from "fs";
234605
- import path60 from "path";
234739
+ import path61 from "path";
234606
234740
  function normalizeRelativePath2(value2) {
234607
234741
  return value2.replace(/\\/gu, "/");
234608
234742
  }
234609
234743
  function readProjectPackageJson(projectDir) {
234610
- const packageJsonPath = path60.join(projectDir, "package.json");
234744
+ const packageJsonPath = path61.join(projectDir, "package.json");
234611
234745
  if (!fs46.existsSync(packageJsonPath)) {
234612
234746
  return null;
234613
234747
  }
@@ -234617,13 +234751,13 @@ function inferInitPackageManager(projectDir, packageJson) {
234617
234751
  if (packageJson?.packageManager) {
234618
234752
  return parseWorkspacePackageManagerId(packageJson.packageManager);
234619
234753
  }
234620
- if (fs46.existsSync(path60.join(projectDir, "bun.lock")) || fs46.existsSync(path60.join(projectDir, "bun.lockb"))) {
234754
+ if (fs46.existsSync(path61.join(projectDir, "bun.lock")) || fs46.existsSync(path61.join(projectDir, "bun.lockb"))) {
234621
234755
  return "bun";
234622
234756
  }
234623
- if (fs46.existsSync(path60.join(projectDir, "pnpm-lock.yaml"))) {
234757
+ if (fs46.existsSync(path61.join(projectDir, "pnpm-lock.yaml"))) {
234624
234758
  return "pnpm";
234625
234759
  }
234626
- if (fs46.existsSync(path60.join(projectDir, "yarn.lock")) || fs46.existsSync(path60.join(projectDir, ".yarnrc.yml"))) {
234760
+ if (fs46.existsSync(path61.join(projectDir, "yarn.lock")) || fs46.existsSync(path61.join(projectDir, ".yarnrc.yml"))) {
234627
234761
  return "yarn";
234628
234762
  }
234629
234763
  return "npm";
@@ -234698,13 +234832,13 @@ function buildPackageManagerFieldChange(packageJson, packageManager) {
234698
234832
  };
234699
234833
  }
234700
234834
  function buildGeneratedArtifactPaths(blockJsonFile, manifestFile) {
234701
- const manifestDir = path60.dirname(manifestFile);
234835
+ const manifestDir = path61.dirname(manifestFile);
234702
234836
  const artifactPaths = [
234703
234837
  blockJsonFile,
234704
234838
  manifestFile,
234705
- path60.join(manifestDir, "typia.schema.json"),
234706
- path60.join(manifestDir, "typia-validator.php"),
234707
- path60.join(manifestDir, "typia.openapi.json")
234839
+ path61.join(manifestDir, "typia.schema.json"),
234840
+ path61.join(manifestDir, "typia-validator.php"),
234841
+ path61.join(manifestDir, "typia.openapi.json")
234708
234842
  ];
234709
234843
  return Array.from(new Set(artifactPaths.map((filePath) => normalizeRelativePath2(filePath))));
234710
234844
  }
@@ -234816,7 +234950,7 @@ function buildRequiredDevDependencyMapEntries() {
234816
234950
  return Object.entries(buildRequiredDevDependencyMap()).map(([name2, version2]) => `${name2}@${version2.replace(/^workspace:/u, "")}`);
234817
234951
  }
234818
234952
  function getInitPlan(projectDir) {
234819
- const resolvedProjectDir = path60.resolve(projectDir);
234953
+ const resolvedProjectDir = path61.resolve(projectDir);
234820
234954
  const packageJson = readProjectPackageJson(resolvedProjectDir);
234821
234955
  const packageManager = inferInitPackageManager(resolvedProjectDir, packageJson);
234822
234956
  const workspace = tryResolveWorkspaceProject(resolvedProjectDir);
@@ -234848,7 +234982,7 @@ function getInitPlan(projectDir) {
234848
234982
  summary: "This directory is already an official wp-typia workspace. No retrofit bootstrap is needed."
234849
234983
  };
234850
234984
  }
234851
- const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path60.basename(resolvedProjectDir);
234985
+ const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path61.basename(resolvedProjectDir);
234852
234986
  const layout = buildLayoutDetails(resolvedProjectDir);
234853
234987
  const dependencyChanges = buildDependencyChanges(packageJson);
234854
234988
  const scriptChanges = buildScriptChanges(packageJson, packageManager);
@@ -234931,18 +235065,18 @@ __export(exports_cli_scaffold, {
234931
235065
  });
234932
235066
  import fs47 from "fs";
234933
235067
  import { promises as fsp23 } from "fs";
234934
- import path61 from "path";
235068
+ import path62 from "path";
234935
235069
  async function listRelativeProjectFiles(rootDir) {
234936
235070
  const relativeFiles = [];
234937
235071
  async function visit2(currentDir) {
234938
235072
  const entries = await fsp23.readdir(currentDir, { withFileTypes: true });
234939
235073
  for (const entry of entries) {
234940
- const absolutePath = path61.join(currentDir, entry.name);
235074
+ const absolutePath = path62.join(currentDir, entry.name);
234941
235075
  if (entry.isDirectory()) {
234942
235076
  await visit2(absolutePath);
234943
235077
  continue;
234944
235078
  }
234945
- relativeFiles.push(path61.relative(rootDir, absolutePath).replace(path61.sep === "\\" ? /\\/gu : /\//gu, "/"));
235079
+ relativeFiles.push(path62.relative(rootDir, absolutePath).replace(path62.sep === "\\" ? /\\/gu : /\//gu, "/"));
234946
235080
  }
234947
235081
  }
234948
235082
  await visit2(rootDir);
@@ -234980,7 +235114,7 @@ async function buildScaffoldDryRunPlan({
234980
235114
  }) {
234981
235115
  await assertDryRunTargetDirectoryReady(projectDir, allowExistingDir);
234982
235116
  const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-scaffold-plan-");
234983
- const previewProjectDir = path61.join(tempRoot, "preview-project");
235117
+ const previewProjectDir = path62.join(tempRoot, "preview-project");
234984
235118
  try {
234985
235119
  const result = await scaffoldProject({
234986
235120
  allowExistingDir: false,
@@ -235020,14 +235154,14 @@ function validateCreateProjectInput(projectInput) {
235020
235154
  if (normalizedProjectInput.length === 0) {
235021
235155
  throw new Error("Project directory is required. Usage: wp-typia create <project-dir> (or wp-typia <project-dir> when <project-dir> is the only positional argument).");
235022
235156
  }
235023
- const normalizedProjectPath = path61.normalize(normalizedProjectInput).replace(/[\\/]+$/u, "") || path61.normalize(normalizedProjectInput);
235157
+ const normalizedProjectPath = path62.normalize(normalizedProjectInput).replace(/[\\/]+$/u, "") || path62.normalize(normalizedProjectInput);
235024
235158
  if (normalizedProjectPath === "." || normalizedProjectPath === "..") {
235025
235159
  throw new Error("`wp-typia create` requires a new project directory. Use an explicit child directory instead of `.` or `..`.");
235026
235160
  }
235027
235161
  }
235028
235162
  function collectProjectDirectoryWarnings(projectDir) {
235029
235163
  const warnings = [];
235030
- const projectName = path61.basename(projectDir);
235164
+ const projectName = path62.basename(projectDir);
235031
235165
  if (/\s/u.test(projectName)) {
235032
235166
  warnings.push(`Project directory "${projectName}" contains spaces. The generated next-step commands will be quoted, but a simple kebab-case directory name is usually easier to use with shells and downstream tooling.`);
235033
235167
  }
@@ -235182,7 +235316,7 @@ function getNextSteps({
235182
235316
  noInstall,
235183
235317
  templateId
235184
235318
  }) {
235185
- const cdTarget = path61.isAbsolute(projectInput) ? projectDir : projectInput;
235319
+ const cdTarget = path62.isAbsolute(projectInput) ? projectDir : projectInput;
235186
235320
  const steps = [`cd ${quoteShellValue(cdTarget)}`];
235187
235321
  if (noInstall) {
235188
235322
  steps.push(formatInstallCommand(packageManager));
@@ -235330,8 +235464,8 @@ async function runScaffoldFlow({
235330
235464
  select: selectWithMigrationUi,
235331
235465
  yes
235332
235466
  });
235333
- const projectDir = path61.resolve(cwd, projectInput);
235334
- const projectName = path61.basename(projectDir);
235467
+ const projectDir = path62.resolve(cwd, projectInput);
235468
+ const projectName = path62.basename(projectDir);
235335
235469
  const answers = await collectScaffoldAnswers({
235336
235470
  dataStorageMode: resolvedDataStorage,
235337
235471
  namespace,
@@ -235394,7 +235528,7 @@ async function runScaffoldFlow({
235394
235528
  let availableScripts;
235395
235529
  if (!dryRun) {
235396
235530
  try {
235397
- const parsedPackageJson = JSON.parse(fs47.readFileSync(path61.join(projectDir, "package.json"), "utf8"));
235531
+ const parsedPackageJson = JSON.parse(fs47.readFileSync(path62.join(projectDir, "package.json"), "utf8"));
235398
235532
  const scripts = parsedPackageJson.scripts && typeof parsedPackageJson.scripts === "object" && !Array.isArray(parsedPackageJson.scripts) ? parsedPackageJson.scripts : {};
235399
235533
  availableScripts = Object.entries(scripts).filter(([, value2]) => typeof value2 === "string").map(([scriptName]) => scriptName);
235400
235534
  } catch {
@@ -288755,7 +288889,7 @@ import path10 from "path";
288755
288889
  // package.json
288756
288890
  var package_default2 = {
288757
288891
  name: "wp-typia",
288758
- version: "0.20.3",
288892
+ version: "0.20.5",
288759
288893
  description: "Canonical CLI package for wp-typia scaffolding and project workflows",
288760
288894
  packageManager: "bun@1.3.11",
288761
288895
  type: "module",
@@ -288823,7 +288957,7 @@ var package_default2 = {
288823
288957
  "@bunli/tui": "0.6.0",
288824
288958
  "@bunli/utils": "0.6.0",
288825
288959
  "@wp-typia/api-client": "^0.4.5",
288826
- "@wp-typia/project-tools": "0.20.0",
288960
+ "@wp-typia/project-tools": "0.20.2",
288827
288961
  "better-result": "^2.7.0",
288828
288962
  react: "^19.2.5",
288829
288963
  "react-dom": "^19.2.5",
@@ -290592,7 +290726,7 @@ init_cli_diagnostics();
290592
290726
 
290593
290727
  // src/mcp.ts
290594
290728
  import fs48 from "fs/promises";
290595
- import path62 from "path";
290729
+ import path63 from "path";
290596
290730
 
290597
290731
  // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/errors.ts
290598
290732
  class SchemaConversionError extends TaggedError("SchemaConversionError")() {
@@ -291120,7 +291254,7 @@ function isToolGroup(value2) {
291120
291254
  return isObject3(value2) && typeof value2.namespace === "string" && Array.isArray(value2.tools) && value2.tools.every(isTool);
291121
291255
  }
291122
291256
  async function readSchemaSource(cwd, source) {
291123
- const schemaPath = path62.resolve(cwd, source.path);
291257
+ const schemaPath = path63.resolve(cwd, source.path);
291124
291258
  const raw = await fs48.readFile(schemaPath, "utf8");
291125
291259
  const parsed = JSON.parse(raw);
291126
291260
  if (isToolGroup(parsed)) {
@@ -291137,7 +291271,7 @@ async function readSchemaSource(cwd, source) {
291137
291271
  async function loadMcpToolGroups(cwd, schemaSources) {
291138
291272
  return Promise.all(schemaSources.map((source) => readSchemaSource(cwd, source)));
291139
291273
  }
291140
- async function syncMcpSchemas(cwd, schemaSources, outputDir = path62.join(cwd, ".bunli", "mcp")) {
291274
+ async function syncMcpSchemas(cwd, schemaSources, outputDir = path63.join(cwd, ".bunli", "mcp")) {
291141
291275
  const groups = await loadMcpToolGroups(cwd, schemaSources);
291142
291276
  const result = await generateMCPTypes({
291143
291277
  outputDir,
@@ -291160,7 +291294,7 @@ async function syncMcpSchemas(cwd, schemaSources, outputDir = path62.join(cwd, "
291160
291294
  }
291161
291295
  }
291162
291296
  await fs48.mkdir(outputDir, { recursive: true });
291163
- await fs48.writeFile(path62.join(outputDir, "registry.json"), `${JSON.stringify(registry2, null, 2)}
291297
+ await fs48.writeFile(path63.join(outputDir, "registry.json"), `${JSON.stringify(registry2, null, 2)}
291164
291298
  `, "utf8");
291165
291299
  return {
291166
291300
  commandCount: registry2.reduce((count, group) => count + group.tools.length, 0),
@@ -291482,4 +291616,4 @@ export {
291482
291616
  cli
291483
291617
  };
291484
291618
 
291485
- //# debugId=A86DAAF9631CE27D64756E2164756E21
291619
+ //# debugId=609DB696D1E292A064756E2164756E21