wp-typia 0.22.4 → 0.22.6

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.
@@ -4,14 +4,14 @@ import {
4
4
  } from "./cli-1sm60g1z.js";
5
5
  import {
6
6
  seedProjectMigrations
7
- } from "./cli-2mt6bvcj.js";
7
+ } from "./cli-0q0tz4dq.js";
8
8
  import {
9
9
  ensureMigrationDirectories,
10
10
  isPlainObject,
11
11
  stableJsonStringify,
12
12
  writeInitialMigrationScaffold,
13
13
  writeMigrationConfig
14
- } from "./cli-hb9vpsev.js";
14
+ } from "./cli-2rqf6t0b.js";
15
15
  import {
16
16
  getBuiltInSharedTemplateLayerDir,
17
17
  getBuiltInTemplateLayerDirs,
@@ -51,7 +51,7 @@ import {
51
51
  toTitleCase,
52
52
  validateBlockSlug,
53
53
  validateNamespace
54
- } from "./cli-qr2ek735.js";
54
+ } from "./cli-5kn2p7ee.js";
55
55
  import {
56
56
  createManagedTempRoot
57
57
  } from "./cli-t73q5aqz.js";
@@ -66,7 +66,7 @@ import {
66
66
  formatRunScript,
67
67
  getPackageManager,
68
68
  transformPackageManagerText
69
- } from "./cli-6bhfzq5e.js";
69
+ } from "./cli-52ke0ptp.js";
70
70
  import {
71
71
  __commonJS,
72
72
  __require,
@@ -4548,7 +4548,7 @@ function getPhpRestExtensionPointsSection(templateId, { compoundPersistenceEnabl
4548
4548
 
4549
4549
  // ../wp-typia-project-tools/src/runtime/scaffold-bootstrap.ts
4550
4550
  import fs2 from "fs";
4551
- import { promises as fsp3 } from "fs";
4551
+ import { promises as fsp4 } from "fs";
4552
4552
  import path4 from "path";
4553
4553
 
4554
4554
  // ../wp-typia-project-tools/src/runtime/persistence-rest-artifacts.ts
@@ -5679,17 +5679,41 @@ function stringifyStarterManifest(document) {
5679
5679
  `;
5680
5680
  }
5681
5681
 
5682
+ // ../wp-typia-project-tools/src/runtime/fs-async.ts
5683
+ import { promises as fsp3 } from "fs";
5684
+ async function pathExists(filePath) {
5685
+ try {
5686
+ await fsp3.access(filePath);
5687
+ return true;
5688
+ } catch {
5689
+ return false;
5690
+ }
5691
+ }
5692
+ async function readOptionalUtf8File(filePath) {
5693
+ try {
5694
+ return await fsp3.readFile(filePath, "utf8");
5695
+ } catch (error) {
5696
+ if (isFileNotFoundError(error)) {
5697
+ return null;
5698
+ }
5699
+ throw error;
5700
+ }
5701
+ }
5702
+ function getNodeErrorCode(error) {
5703
+ return typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
5704
+ }
5705
+ function isFileNotFoundError(error) {
5706
+ return getNodeErrorCode(error) === "ENOENT";
5707
+ }
5708
+
5682
5709
  // ../wp-typia-project-tools/src/runtime/scaffold-bootstrap.ts
5683
5710
  var EPHEMERAL_NODE_MODULES_LINK_TYPE = process.platform === "win32" ? "junction" : "dir";
5684
5711
  async function ensureScaffoldDirectory(targetDir, allowExisting = false) {
5685
- if (!fs2.existsSync(targetDir)) {
5686
- await fsp3.mkdir(targetDir, { recursive: true });
5687
- return;
5688
- }
5712
+ await fsp4.mkdir(targetDir, { recursive: true });
5689
5713
  if (allowExisting) {
5690
5714
  return;
5691
5715
  }
5692
- const entries = await fsp3.readdir(targetDir);
5716
+ const entries = await fsp4.readdir(targetDir);
5693
5717
  if (entries.length > 0) {
5694
5718
  throw new Error(formatNonEmptyTargetDirectoryError(targetDir));
5695
5719
  }
@@ -5708,8 +5732,8 @@ async function writeStarterManifestFiles(targetDir, templateId, variables) {
5708
5732
  const manifests = getStarterManifestFiles(templateId, variables);
5709
5733
  for (const { document, relativePath } of manifests) {
5710
5734
  const destinationPath = path4.join(targetDir, relativePath);
5711
- await fsp3.mkdir(path4.dirname(destinationPath), { recursive: true });
5712
- await fsp3.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
5735
+ await fsp4.mkdir(path4.dirname(destinationPath), { recursive: true });
5736
+ await fsp4.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
5713
5737
  }
5714
5738
  }
5715
5739
  async function seedBuiltInPersistenceArtifacts(targetDir, templateId, variables) {
@@ -5741,7 +5765,7 @@ function isWorkspaceProject(projectDir) {
5741
5765
  }
5742
5766
  async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
5743
5767
  const packageJsonPath = path4.join(projectDir, "package.json");
5744
- const packageJson = JSON.parse(await fsp3.readFile(packageJsonPath, "utf8"));
5768
+ const packageJson = JSON.parse(await fsp4.readFile(packageJsonPath, "utf8"));
5745
5769
  const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
5746
5770
  const canonicalCliSpecifier = wpTypiaPackageVersion === "^0.0.0" ? "wp-typia" : `wp-typia@${wpTypiaPackageVersion.replace(/^[~^]/u, "")}`;
5747
5771
  const migrationCli = (args) => formatPackageExecCommand(packageManager, canonicalCliSpecifier, `migrate ${args}`);
@@ -5756,7 +5780,7 @@ async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
5756
5780
  "migration:verify": migrationCli("verify --all"),
5757
5781
  "migration:fuzz": migrationCli("fuzz --all")
5758
5782
  };
5759
- await fsp3.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
5783
+ await fsp4.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
5760
5784
  `, "utf8");
5761
5785
  writeMigrationConfig(projectDir, {
5762
5786
  blocks: [],
@@ -5767,14 +5791,14 @@ async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
5767
5791
  ensureMigrationDirectories(projectDir, []);
5768
5792
  writeInitialMigrationScaffold(projectDir, "v1", []);
5769
5793
  }
5770
- function resolveScaffoldGeneratorNodeModulesPath() {
5794
+ async function resolveScaffoldGeneratorNodeModulesPath() {
5771
5795
  const candidates = [
5772
5796
  path4.join(PROJECT_TOOLS_PACKAGE_ROOT, "node_modules"),
5773
5797
  path4.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", ".."),
5774
5798
  path4.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "node_modules")
5775
5799
  ];
5776
5800
  for (const candidate of candidates) {
5777
- if (fs2.existsSync(path4.join(candidate, "typia", "package.json"))) {
5801
+ if (await pathExists(path4.join(candidate, "typia", "package.json"))) {
5778
5802
  return candidate;
5779
5803
  }
5780
5804
  }
@@ -5782,19 +5806,19 @@ function resolveScaffoldGeneratorNodeModulesPath() {
5782
5806
  }
5783
5807
  async function withEphemeralScaffoldNodeModules(targetDir, callback) {
5784
5808
  const targetNodeModulesPath = path4.join(targetDir, "node_modules");
5785
- if (fs2.existsSync(targetNodeModulesPath)) {
5809
+ if (await pathExists(targetNodeModulesPath)) {
5786
5810
  await callback();
5787
5811
  return;
5788
5812
  }
5789
- const sourceNodeModulesPath = resolveScaffoldGeneratorNodeModulesPath();
5813
+ const sourceNodeModulesPath = await resolveScaffoldGeneratorNodeModulesPath();
5790
5814
  if (!sourceNodeModulesPath) {
5791
5815
  throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
5792
5816
  }
5793
- await fsp3.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE);
5817
+ await fsp4.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE);
5794
5818
  try {
5795
5819
  await callback();
5796
5820
  } finally {
5797
- await fsp3.rm(targetNodeModulesPath, { force: true, recursive: true });
5821
+ await fsp4.rm(targetNodeModulesPath, { force: true, recursive: true });
5798
5822
  }
5799
5823
  }
5800
5824
 
@@ -6219,37 +6243,36 @@ async function collectScaffoldAnswers({
6219
6243
  }
6220
6244
 
6221
6245
  // ../wp-typia-project-tools/src/runtime/scaffold.ts
6222
- import fs15 from "fs";
6223
- import { promises as fsp11 } from "fs";
6246
+ import fs12 from "fs";
6247
+ import { promises as fsp13 } from "fs";
6224
6248
  import path18 from "path";
6225
6249
 
6226
6250
  // ../wp-typia-project-tools/src/runtime/scaffold-apply-utils.ts
6227
- import fs6 from "fs";
6228
- import { promises as fsp6 } from "fs";
6251
+ import { promises as fsp7 } from "fs";
6229
6252
  import path11 from "path";
6230
6253
  import { execSync as execSync3 } from "child_process";
6231
6254
  import { fileURLToPath } from "url";
6232
6255
 
6233
6256
  // ../wp-typia-project-tools/src/runtime/migration-ui-capability.ts
6234
- import { promises as fsp4 } from "fs";
6257
+ import { promises as fsp5 } from "fs";
6235
6258
  import path8 from "path";
6236
6259
  var INITIAL_MIGRATION_VERSION = "v1";
6237
6260
  var BLOCK_METADATA_IMPORT_LINE = "import metadata from './block-metadata';";
6238
6261
  var LEGACY_BLOCK_JSON_IMPORT_LINE = "import metadata from './block.json';";
6239
6262
  async function mutatePackageJson2(projectDir, mutate) {
6240
6263
  const packageJsonPath = path8.join(projectDir, "package.json");
6241
- const packageJson = JSON.parse(await fsp4.readFile(packageJsonPath, "utf8"));
6264
+ const packageJson = JSON.parse(await fsp5.readFile(packageJsonPath, "utf8"));
6242
6265
  mutate(packageJson);
6243
- await fsp4.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
6266
+ await fsp5.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
6244
6267
  `, "utf8");
6245
6268
  }
6246
6269
  async function patchFile(filePath, transform) {
6247
- const source = await fsp4.readFile(filePath, "utf8");
6270
+ const source = await fsp5.readFile(filePath, "utf8");
6248
6271
  const nextSource = transform(source);
6249
6272
  if (nextSource === source) {
6250
6273
  throw new Error(`Unable to apply migration UI patch for ${filePath}`);
6251
6274
  }
6252
- await fsp4.writeFile(filePath, nextSource, "utf8");
6275
+ await fsp5.writeFile(filePath, nextSource, "utf8");
6253
6276
  }
6254
6277
  function injectAfter(source, needle, insertion) {
6255
6278
  if (source.includes(insertion)) {
@@ -6458,6 +6481,18 @@ function formatReadmeTemplateIdentity(templateId) {
6458
6481
  return [`- Template id: ${templateId}`, "- Type: custom or external scaffold"].join(`
6459
6482
  `);
6460
6483
  }
6484
+ function getPackageManagerInstallGuidance(packageManager) {
6485
+ if (packageManager !== "npm") {
6486
+ return "";
6487
+ }
6488
+ const installCommand = formatInstallCommand(packageManager);
6489
+ return [
6490
+ "",
6491
+ `> npm note: the scaffold uses \`${installCommand}\` for the first install so npm does not spend the initial create flow in the audit resolver. Run \`npm audit\` separately when you want npm vulnerability output.`,
6492
+ "> If npm prints React peer dependency noise from WordPress block-editor packages, validate with `npm run typecheck` and `npm run build` before changing WordPress package ranges."
6493
+ ].join(`
6494
+ `);
6495
+ }
6461
6496
  function buildReadme(templateId, variables, packageManager, {
6462
6497
  withMigrationUi = false,
6463
6498
  withTestPreset = false,
@@ -6552,6 +6587,7 @@ ${formatReadmeTemplateIdentity(templateId)}
6552
6587
  ${formatInstallCommand(packageManager)}
6553
6588
  ${formatRunScript(packageManager, developmentScript)}
6554
6589
  \`\`\`
6590
+ ${getPackageManagerInstallGuidance(packageManager)}
6555
6591
 
6556
6592
  ${getQuickStartWorkflowNote(packageManager, templateId, {
6557
6593
  compoundPersistenceEnabled
@@ -6647,8 +6683,7 @@ function mergeTextLines(primaryContent, existingContent) {
6647
6683
  }
6648
6684
 
6649
6685
  // ../wp-typia-project-tools/src/runtime/scaffold-package-manager-files.ts
6650
- import fs4 from "fs";
6651
- import { promises as fsp5 } from "fs";
6686
+ import { promises as fsp6 } from "fs";
6652
6687
  import { execSync as execSync2 } from "child_process";
6653
6688
  import path9 from "path";
6654
6689
  var LOCKFILES = {
@@ -6660,19 +6695,20 @@ var LOCKFILES = {
6660
6695
  async function normalizePackageManagerFiles(targetDir, packageManagerId) {
6661
6696
  const yarnRcPath = path9.join(targetDir, ".yarnrc.yml");
6662
6697
  if (packageManagerId === "yarn") {
6663
- await fsp5.writeFile(yarnRcPath, `nodeLinker: node-modules
6698
+ await fsp6.writeFile(yarnRcPath, `nodeLinker: node-modules
6664
6699
  `, "utf8");
6665
6700
  return;
6666
6701
  }
6667
- await fsp5.rm(yarnRcPath, { force: true });
6702
+ await fsp6.rm(yarnRcPath, { force: true });
6668
6703
  }
6669
6704
  async function normalizePackageJson(targetDir, packageManagerId) {
6670
6705
  const packageJsonPath = path9.join(targetDir, "package.json");
6671
- if (!fs4.existsSync(packageJsonPath)) {
6706
+ const packageJsonSource = await readOptionalUtf8File(packageJsonPath);
6707
+ if (packageJsonSource === null) {
6672
6708
  return;
6673
6709
  }
6674
6710
  const packageManager = getPackageManager(packageManagerId);
6675
- const packageJson = JSON.parse(await fsp5.readFile(packageJsonPath, "utf8"));
6711
+ const packageJson = JSON.parse(packageJsonSource);
6676
6712
  if (packageManagerId === "npm") {
6677
6713
  delete packageJson.packageManager;
6678
6714
  } else {
@@ -6685,7 +6721,7 @@ async function normalizePackageJson(targetDir, packageManagerId) {
6685
6721
  }
6686
6722
  }
6687
6723
  }
6688
- await fsp5.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
6724
+ await fsp6.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
6689
6725
  `, "utf8");
6690
6726
  }
6691
6727
  async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
@@ -6695,7 +6731,7 @@ async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
6695
6731
  if (keep.has(filename)) {
6696
6732
  return;
6697
6733
  }
6698
- await fsp5.rm(path9.join(targetDir, filename), { force: true });
6734
+ await fsp6.rm(path9.join(targetDir, filename), { force: true });
6699
6735
  }));
6700
6736
  }
6701
6737
  async function defaultInstallDependencies({
@@ -6708,7 +6744,7 @@ async function defaultInstallDependencies({
6708
6744
  });
6709
6745
  }
6710
6746
  // ../wp-typia-project-tools/src/runtime/scaffold-repository-reference.ts
6711
- import fs5 from "fs";
6747
+ import fs4 from "fs";
6712
6748
  import { createRequire } from "module";
6713
6749
  import path10 from "path";
6714
6750
  var require2 = createRequire(import.meta.url);
@@ -6718,7 +6754,7 @@ function getErrorCode(error) {
6718
6754
  }
6719
6755
  function readRepositoryPackageManifest(packageJsonPath) {
6720
6756
  try {
6721
- return JSON.parse(fs5.readFileSync(packageJsonPath, "utf8"));
6757
+ return JSON.parse(fs4.readFileSync(packageJsonPath, "utf8"));
6722
6758
  } catch (error) {
6723
6759
  if (getErrorCode(error) === "ENOENT") {
6724
6760
  return null;
@@ -6813,14 +6849,11 @@ var LOCKFILES2 = {
6813
6849
  yarn: ["yarn.lock"]
6814
6850
  };
6815
6851
  async function ensureDirectory(targetDir, allowExisting = false) {
6816
- if (!fs6.existsSync(targetDir)) {
6817
- await fsp6.mkdir(targetDir, { recursive: true });
6818
- return;
6819
- }
6852
+ await fsp7.mkdir(targetDir, { recursive: true });
6820
6853
  if (allowExisting) {
6821
6854
  return;
6822
6855
  }
6823
- const entries = await fsp6.readdir(targetDir);
6856
+ const entries = await fsp7.readdir(targetDir);
6824
6857
  if (entries.length > 0) {
6825
6858
  throw new Error(formatNonEmptyTargetDirectoryError(targetDir));
6826
6859
  }
@@ -6832,26 +6865,26 @@ async function writeStarterManifestFiles2(targetDir, templateId, variables, arti
6832
6865
  })) : getStarterManifestFiles(templateId, variables);
6833
6866
  for (const { document, relativePath } of manifests) {
6834
6867
  const destinationPath = path11.join(targetDir, relativePath);
6835
- await fsp6.mkdir(path11.dirname(destinationPath), { recursive: true });
6836
- await fsp6.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
6868
+ await fsp7.mkdir(path11.dirname(destinationPath), { recursive: true });
6869
+ await fsp7.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
6837
6870
  }
6838
6871
  }
6839
6872
  async function writeBuiltInStructuralArtifacts(targetDir, artifacts) {
6840
6873
  for (const artifact of artifacts) {
6841
6874
  const destinationDir = path11.join(targetDir, artifact.relativeDir);
6842
- await fsp6.mkdir(destinationDir, { recursive: true });
6843
- await fsp6.writeFile(path11.join(destinationDir, "types.ts"), artifact.typesSource, "utf8");
6844
- await fsp6.writeFile(path11.join(destinationDir, "block.json"), stringifyBuiltInBlockJsonDocument(artifact.blockJsonDocument), "utf8");
6875
+ await fsp7.mkdir(destinationDir, { recursive: true });
6876
+ await fsp7.writeFile(path11.join(destinationDir, "types.ts"), artifact.typesSource, "utf8");
6877
+ await fsp7.writeFile(path11.join(destinationDir, "block.json"), stringifyBuiltInBlockJsonDocument(artifact.blockJsonDocument), "utf8");
6845
6878
  }
6846
6879
  }
6847
6880
  async function writeBuiltInCodeArtifacts(targetDir, codeArtifacts) {
6848
6881
  for (const artifact of codeArtifacts) {
6849
6882
  const destinationPath = path11.join(targetDir, artifact.relativePath);
6850
- await fsp6.mkdir(path11.dirname(destinationPath), { recursive: true });
6851
- await fsp6.writeFile(destinationPath, artifact.source, "utf8");
6883
+ await fsp7.mkdir(path11.dirname(destinationPath), { recursive: true });
6884
+ await fsp7.writeFile(destinationPath, artifact.source, "utf8");
6852
6885
  }
6853
6886
  }
6854
- function resolveScaffoldGeneratorNodeModulesPath2() {
6887
+ async function resolveScaffoldGeneratorNodeModulesPath2() {
6855
6888
  const projectToolsPackageRoot = path11.resolve(__dirname2, "..", "..");
6856
6889
  const candidates = [
6857
6890
  path11.join(projectToolsPackageRoot, "node_modules"),
@@ -6859,7 +6892,7 @@ function resolveScaffoldGeneratorNodeModulesPath2() {
6859
6892
  path11.resolve(projectToolsPackageRoot, "..", "..", "node_modules")
6860
6893
  ];
6861
6894
  for (const candidate of candidates) {
6862
- if (fs6.existsSync(path11.join(candidate, "typia", "package.json"))) {
6895
+ if (await pathExists(path11.join(candidate, "typia", "package.json"))) {
6863
6896
  return candidate;
6864
6897
  }
6865
6898
  }
@@ -6867,19 +6900,19 @@ function resolveScaffoldGeneratorNodeModulesPath2() {
6867
6900
  }
6868
6901
  async function withEphemeralScaffoldNodeModules2(targetDir, callback) {
6869
6902
  const targetNodeModulesPath = path11.join(targetDir, "node_modules");
6870
- if (fs6.existsSync(targetNodeModulesPath)) {
6903
+ if (await pathExists(targetNodeModulesPath)) {
6871
6904
  await callback();
6872
6905
  return;
6873
6906
  }
6874
- const sourceNodeModulesPath = resolveScaffoldGeneratorNodeModulesPath2();
6907
+ const sourceNodeModulesPath = await resolveScaffoldGeneratorNodeModulesPath2();
6875
6908
  if (!sourceNodeModulesPath) {
6876
6909
  throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
6877
6910
  }
6878
- await fsp6.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE2);
6911
+ await fsp7.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE2);
6879
6912
  try {
6880
6913
  await callback();
6881
6914
  } finally {
6882
- await fsp6.rm(targetNodeModulesPath, { force: true, recursive: true });
6915
+ await fsp7.rm(targetNodeModulesPath, { force: true, recursive: true });
6883
6916
  }
6884
6917
  }
6885
6918
  async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables) {
@@ -6908,19 +6941,17 @@ async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables
6908
6941
  async function normalizePackageManagerFiles2(targetDir, packageManagerId) {
6909
6942
  const yarnRcPath = path11.join(targetDir, ".yarnrc.yml");
6910
6943
  if (packageManagerId === "yarn") {
6911
- await fsp6.writeFile(yarnRcPath, `nodeLinker: node-modules
6944
+ await fsp7.writeFile(yarnRcPath, `nodeLinker: node-modules
6912
6945
  `, "utf8");
6913
6946
  return;
6914
6947
  }
6915
- if (fs6.existsSync(yarnRcPath)) {
6916
- await fsp6.rm(yarnRcPath, { force: true });
6917
- }
6948
+ await fsp7.rm(yarnRcPath, { force: true });
6918
6949
  }
6919
6950
  async function removeQueryLoopPlaceholderFiles(projectDir, templateId) {
6920
6951
  if (templateId !== "query-loop") {
6921
6952
  return;
6922
6953
  }
6923
- await fsp6.rm(path11.join(projectDir, "src", "validator-toolkit.ts"), {
6954
+ await fsp7.rm(path11.join(projectDir, "src", "validator-toolkit.ts"), {
6924
6955
  force: true
6925
6956
  });
6926
6957
  }
@@ -6931,10 +6962,7 @@ async function removeUnexpectedLockfiles2(targetDir, packageManagerId) {
6931
6962
  if (keep.has(filename)) {
6932
6963
  return;
6933
6964
  }
6934
- const filePath = path11.join(targetDir, filename);
6935
- if (fs6.existsSync(filePath)) {
6936
- await fsp6.rm(filePath, { force: true });
6937
- }
6965
+ await fsp7.rm(path11.join(targetDir, filename), { force: true });
6938
6966
  }));
6939
6967
  }
6940
6968
  async function replaceTextRecursively(targetDir, packageManagerId, {
@@ -6957,9 +6985,9 @@ async function replaceTextRecursively(targetDir, packageManagerId, {
6957
6985
  manifestPaths: repositoryManifestPaths
6958
6986
  });
6959
6987
  async function visit(currentPath) {
6960
- const stats = await fsp6.stat(currentPath);
6988
+ const stats = await fsp7.stat(currentPath);
6961
6989
  if (stats.isDirectory()) {
6962
- const entries = await fsp6.readdir(currentPath);
6990
+ const entries = await fsp7.readdir(currentPath);
6963
6991
  for (const entry of entries) {
6964
6992
  await visit(path11.join(currentPath, entry));
6965
6993
  }
@@ -6968,10 +6996,10 @@ async function replaceTextRecursively(targetDir, packageManagerId, {
6968
6996
  if (path11.basename(currentPath) === "package.json" || !textExtensions.has(path11.extname(currentPath))) {
6969
6997
  return;
6970
6998
  }
6971
- const content = await fsp6.readFile(currentPath, "utf8");
6999
+ const content = await fsp7.readFile(currentPath, "utf8");
6972
7000
  const nextContent = replaceRepositoryReferencePlaceholders(transformPackageManagerText(content, packageManagerId), resolvedRepositoryReference);
6973
7001
  if (nextContent !== content) {
6974
- await fsp6.writeFile(currentPath, nextContent, "utf8");
7002
+ await fsp7.writeFile(currentPath, nextContent, "utf8");
6975
7003
  }
6976
7004
  }
6977
7005
  await visit(targetDir);
@@ -7044,16 +7072,16 @@ async function applyBuiltInScaffoldProjectFiles({
7044
7072
  title: "Finalizing scaffold output"
7045
7073
  });
7046
7074
  const readmePath = path11.join(projectDir, "README.md");
7047
- if (!fs6.existsSync(readmePath)) {
7048
- await fsp6.writeFile(readmePath, readmeContent ?? buildReadme(templateId, variables, packageManager, {
7075
+ if (!await pathExists(readmePath)) {
7076
+ await fsp7.writeFile(readmePath, readmeContent ?? buildReadme(templateId, variables, packageManager, {
7049
7077
  withMigrationUi,
7050
7078
  withTestPreset,
7051
7079
  withWpEnv
7052
7080
  }), "utf8");
7053
7081
  }
7054
7082
  const gitignorePath = path11.join(projectDir, ".gitignore");
7055
- const existingGitignore = fs6.existsSync(gitignorePath) ? await fsp6.readFile(gitignorePath, "utf8") : "";
7056
- await fsp6.writeFile(gitignorePath, mergeTextLines(gitignoreContent ?? buildGitignore(), existingGitignore), "utf8");
7083
+ const existingGitignore = await readOptionalUtf8File(gitignorePath) ?? "";
7084
+ await fsp7.writeFile(gitignorePath, mergeTextLines(gitignoreContent ?? buildGitignore(), existingGitignore), "utf8");
7057
7085
  await normalizePackageJson(projectDir, packageManager);
7058
7086
  await applyGeneratedProjectDxPackageJson({
7059
7087
  compoundPersistenceEnabled: variables.compoundPersistenceEnabled === "true",
@@ -7084,13 +7112,12 @@ async function applyBuiltInScaffoldProjectFiles({
7084
7112
  }
7085
7113
 
7086
7114
  // ../wp-typia-project-tools/src/runtime/template-source-normalization.ts
7087
- import fs11 from "fs";
7088
7115
  import path15 from "path";
7089
7116
 
7090
7117
  // ../wp-typia-project-tools/src/runtime/template-layers.ts
7091
- import fs7 from "fs";
7118
+ import fs5 from "fs";
7092
7119
  import path12 from "path";
7093
- import { promises as fsp7 } from "fs";
7120
+ import { promises as fsp8 } from "fs";
7094
7121
  var TEMPLATE_LAYER_MANIFEST_FILENAME = "wp-typia.layers.json";
7095
7122
  var TEMPLATE_LAYER_MANIFEST_VERSION = 1;
7096
7123
  function resolveLayerPath(sourceRoot, relativePath) {
@@ -7102,14 +7129,14 @@ function resolveLayerPath(sourceRoot, relativePath) {
7102
7129
  return targetPath;
7103
7130
  }
7104
7131
  async function assertNoSymlinks(sourceDir) {
7105
- const stats = await fsp7.lstat(sourceDir);
7132
+ const stats = await fsp8.lstat(sourceDir);
7106
7133
  if (stats.isSymbolicLink()) {
7107
7134
  throw new Error(`Template layer packages may not include symbolic links: ${sourceDir}`);
7108
7135
  }
7109
7136
  if (!stats.isDirectory()) {
7110
7137
  return;
7111
7138
  }
7112
- for (const entry of await fsp7.readdir(sourceDir)) {
7139
+ for (const entry of await fsp8.readdir(sourceDir)) {
7113
7140
  await assertNoSymlinks(path12.join(sourceDir, entry));
7114
7141
  }
7115
7142
  }
@@ -7140,10 +7167,10 @@ function parseLayerDefinition(layerId, value) {
7140
7167
  }
7141
7168
  async function loadExternalTemplateLayerManifest(sourceRoot) {
7142
7169
  const manifestPath = path12.join(sourceRoot, TEMPLATE_LAYER_MANIFEST_FILENAME);
7143
- if (!fs7.existsSync(manifestPath)) {
7170
+ if (!fs5.existsSync(manifestPath)) {
7144
7171
  return null;
7145
7172
  }
7146
- const raw = JSON.parse(await fsp7.readFile(manifestPath, "utf8"));
7173
+ const raw = JSON.parse(await fsp8.readFile(manifestPath, "utf8"));
7147
7174
  if (!isPlainObject(raw)) {
7148
7175
  throw new Error(`${TEMPLATE_LAYER_MANIFEST_FILENAME} must export a JSON object.`);
7149
7176
  }
@@ -7237,7 +7264,7 @@ async function resolveExternalTemplateLayers({
7237
7264
  return;
7238
7265
  }
7239
7266
  const layerDir = resolveLayerPath(sourceRoot, definition.path);
7240
- const stats = await fsp7.stat(layerDir).catch(() => null);
7267
+ const stats = await fsp8.stat(layerDir).catch(() => null);
7241
7268
  if (!stats || !stats.isDirectory()) {
7242
7269
  throw new Error(`Layer "${layerId}" points to a missing directory: ${definition.path}`);
7243
7270
  }
@@ -7275,12 +7302,13 @@ async function assertExternalTemplateLayersDoNotWriteProtectedOutputs({
7275
7302
  }
7276
7303
 
7277
7304
  // ../wp-typia-project-tools/src/runtime/template-source-external.ts
7278
- import fs9 from "fs";
7305
+ import fs7 from "fs";
7306
+ import { promises as fsp9 } from "fs";
7279
7307
  import path13 from "path";
7280
7308
  import { pathToFileURL } from "url";
7281
7309
 
7282
7310
  // ../wp-typia-project-tools/src/runtime/external-template-guards.ts
7283
- import fs8 from "fs";
7311
+ import fs6 from "fs";
7284
7312
  var TEMPLATE_SOURCE_TIMEOUT_CODE = "template-source-timeout";
7285
7313
  var TEMPLATE_SOURCE_TOO_LARGE_CODE = "template-source-too-large";
7286
7314
  var DEFAULT_EXTERNAL_TEMPLATE_TIMEOUT_MS = 20000;
@@ -7322,7 +7350,7 @@ function createExternalTemplateTooLargeError(label, maxBytes) {
7322
7350
  return createTemplateGuardError(TEMPLATE_SOURCE_TOO_LARGE_CODE, `${label} exceeded the external template size limit (${maxBytes} bytes).`);
7323
7351
  }
7324
7352
  function assertExternalTemplateFileSize(filePath, options) {
7325
- const stats = fs8.statSync(filePath);
7353
+ const stats = fs6.statSync(filePath);
7326
7354
  if (stats.size > options.maxBytes) {
7327
7355
  throw createExternalTemplateTooLargeError(options.label, options.maxBytes);
7328
7356
  }
@@ -7427,17 +7455,17 @@ function resolveSourceSubpath(sourceDir, relativePath) {
7427
7455
  }
7428
7456
  return targetPath;
7429
7457
  }
7430
- function getExternalTemplateEntry(sourceDir) {
7458
+ async function findExternalTemplateEntry(sourceDir) {
7431
7459
  for (const filename of EXTERNAL_TEMPLATE_ENTRY_CANDIDATES) {
7432
7460
  const candidate = path13.join(sourceDir, filename);
7433
- if (fs9.existsSync(candidate)) {
7461
+ if (await pathExists(candidate)) {
7434
7462
  return candidate;
7435
7463
  }
7436
7464
  }
7437
7465
  return null;
7438
7466
  }
7439
7467
  async function loadExternalTemplateConfig(sourceDir) {
7440
- const entryPath = getExternalTemplateEntry(sourceDir);
7468
+ const entryPath = await findExternalTemplateEntry(sourceDir);
7441
7469
  if (!entryPath) {
7442
7470
  throw new Error(`No external template config entry found in ${sourceDir}.`);
7443
7471
  }
@@ -7445,7 +7473,8 @@ async function loadExternalTemplateConfig(sourceDir) {
7445
7473
  label: `External template config "${entryPath}"`,
7446
7474
  maxBytes: getExternalTemplateConfigMaxBytes()
7447
7475
  });
7448
- const moduleUrl = `${pathToFileURL(entryPath).href}?mtime=${fs9.statSync(entryPath).mtimeMs}`;
7476
+ const entryStats = await fsp9.stat(entryPath);
7477
+ const moduleUrl = `${pathToFileURL(entryPath).href}?mtime=${entryStats.mtimeMs}`;
7449
7478
  const loadedModule = await withExternalTemplateTimeout(`loading external template config "${entryPath}"`, () => import(moduleUrl));
7450
7479
  const loadedConfig = loadedModule.default ?? loadedModule;
7451
7480
  if (!isPlainObject(loadedConfig)) {
@@ -7558,15 +7587,16 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
7558
7587
  await copyRenderedDirectory(blockTemplateDir, blockDir, view, {
7559
7588
  filter: (sourcePath, _destinationPath, entry) => {
7560
7589
  const mustacheVariantPath = path13.join(path13.dirname(sourcePath), `${entry.name}.mustache`);
7561
- return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && fs9.existsSync(mustacheVariantPath));
7590
+ return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && fs7.existsSync(mustacheVariantPath));
7562
7591
  }
7563
7592
  });
7564
7593
  const assetsPath = typeof variantConfig.assetsPath === "string" ? variantConfig.assetsPath : config.assetsPath;
7565
7594
  if (typeof assetsPath === "string" && assetsPath.trim().length > 0) {
7566
7595
  await copyRawDirectory(resolveSourceSubpath(sourceDir, assetsPath), path13.join(tempRoot, "assets"));
7567
7596
  }
7597
+ const assetsDir = path13.join(tempRoot, "assets");
7568
7598
  return {
7569
- assetsDir: fs9.existsSync(path13.join(tempRoot, "assets")) ? path13.join(tempRoot, "assets") : undefined,
7599
+ assetsDir: await pathExists(assetsDir) ? assetsDir : undefined,
7570
7600
  blockDir,
7571
7601
  cleanup,
7572
7602
  formatHint,
@@ -7581,8 +7611,8 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
7581
7611
  }
7582
7612
 
7583
7613
  // ../wp-typia-project-tools/src/runtime/template-source-remote.ts
7584
- import fs10 from "fs";
7585
- import { promises as fsp8 } from "fs";
7614
+ import fs8 from "fs";
7615
+ import { promises as fsp10 } from "fs";
7586
7616
  import path14 from "path";
7587
7617
  async function cleanupSeedRootPair(cleanup, seedCleanup) {
7588
7618
  let cleanupError;
@@ -7603,32 +7633,32 @@ async function cleanupSeedRootPair(cleanup, seedCleanup) {
7603
7633
  function getDefaultCategoryFromBlockJson(blockJson) {
7604
7634
  return typeof blockJson.category === "string" && blockJson.category.trim().length > 0 ? blockJson.category.trim() : "widgets";
7605
7635
  }
7606
- function readRemoteBlockJson(blockDir) {
7607
- const sourceRoot = fs10.existsSync(path14.join(blockDir, "src")) ? path14.join(blockDir, "src") : blockDir;
7636
+ async function readRemoteBlockJsonAsync(blockDir) {
7637
+ const sourceRoot = await getSeedSourceRoot(blockDir);
7608
7638
  for (const candidate of [
7609
7639
  path14.join(blockDir, "block.json"),
7610
7640
  path14.join(sourceRoot, "block.json")
7611
7641
  ]) {
7612
- if (fs10.existsSync(candidate)) {
7613
- return JSON.parse(fs10.readFileSync(candidate, "utf8"));
7642
+ if (await pathExists(candidate)) {
7643
+ return JSON.parse(await fsp10.readFile(candidate, "utf8"));
7614
7644
  }
7615
7645
  }
7616
7646
  throw new Error(`Unable to locate block.json in ${blockDir}`);
7617
7647
  }
7618
- function getDefaultCategory(sourceDir) {
7648
+ async function getDefaultCategoryAsync(sourceDir) {
7619
7649
  try {
7620
- const blockJson = readRemoteBlockJson(sourceDir);
7650
+ const blockJson = await readRemoteBlockJsonAsync(sourceDir);
7621
7651
  return getDefaultCategoryFromBlockJson(blockJson);
7622
7652
  } catch {
7623
7653
  return "widgets";
7624
7654
  }
7625
7655
  }
7626
- function readTemplatePackageJson(sourceDir) {
7656
+ async function readTemplatePackageJsonAsync(sourceDir) {
7627
7657
  for (const candidate of [
7628
7658
  path14.join(sourceDir, "package.json.mustache"),
7629
7659
  path14.join(sourceDir, "package.json")
7630
7660
  ]) {
7631
- if (!fs10.existsSync(candidate)) {
7661
+ if (!await pathExists(candidate)) {
7632
7662
  continue;
7633
7663
  }
7634
7664
  try {
@@ -7637,7 +7667,7 @@ function readTemplatePackageJson(sourceDir) {
7637
7667
  maxBytes: getExternalTemplatePackageJsonMaxBytes()
7638
7668
  });
7639
7669
  return {
7640
- packageJson: JSON.parse(fs10.readFileSync(candidate, "utf8")),
7670
+ packageJson: JSON.parse(await fsp10.readFile(candidate, "utf8")),
7641
7671
  sourcePath: candidate
7642
7672
  };
7643
7673
  } catch (error) {
@@ -7647,8 +7677,8 @@ function readTemplatePackageJson(sourceDir) {
7647
7677
  }
7648
7678
  return null;
7649
7679
  }
7650
- function getTemplateProjectType(sourceDir) {
7651
- const packageJsonEntry = readTemplatePackageJson(sourceDir);
7680
+ async function getTemplateProjectTypeAsync(sourceDir) {
7681
+ const packageJsonEntry = await readTemplatePackageJsonAsync(sourceDir);
7652
7682
  if (!packageJsonEntry) {
7653
7683
  return null;
7654
7684
  }
@@ -7668,11 +7698,11 @@ async function normalizeWpTypiaTemplateSeed(seed) {
7668
7698
  await copyRawDirectory(seed.blockDir, normalizedDir, {
7669
7699
  filter: (sourcePath, _targetPath, entry) => {
7670
7700
  const mustacheVariantPath = path14.join(path14.dirname(sourcePath), `${entry.name}.mustache`);
7671
- return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && fs10.existsSync(mustacheVariantPath));
7701
+ return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && fs8.existsSync(mustacheVariantPath));
7672
7702
  }
7673
7703
  });
7674
- if (seed.assetsDir && fs10.existsSync(seed.assetsDir)) {
7675
- await fsp8.cp(seed.assetsDir, path14.join(normalizedDir, "assets"), {
7704
+ if (seed.assetsDir && await pathExists(seed.assetsDir)) {
7705
+ await fsp10.cp(seed.assetsDir, path14.join(normalizedDir, "assets"), {
7676
7706
  recursive: true,
7677
7707
  force: true
7678
7708
  });
@@ -7763,9 +7793,9 @@ async function rewriteBlockJsonImports(directory) {
7763
7793
  const textExtensions = new Set([".js", ".jsx", ".ts", ".tsx"]);
7764
7794
  const targetBlockJsonPath = path14.join(directory, "block.json");
7765
7795
  async function visit(currentPath) {
7766
- const stats = await fsp8.stat(currentPath);
7796
+ const stats = await fsp10.stat(currentPath);
7767
7797
  if (stats.isDirectory()) {
7768
- const entries = await fsp8.readdir(currentPath);
7798
+ const entries = await fsp10.readdir(currentPath);
7769
7799
  for (const entry of entries) {
7770
7800
  await visit(path14.join(currentPath, entry));
7771
7801
  }
@@ -7774,19 +7804,19 @@ async function rewriteBlockJsonImports(directory) {
7774
7804
  if (!textExtensions.has(path14.extname(currentPath))) {
7775
7805
  return;
7776
7806
  }
7777
- const content = await fsp8.readFile(currentPath, "utf8");
7807
+ const content = await fsp10.readFile(currentPath, "utf8");
7778
7808
  const relativeSpecifier = path14.relative(path14.dirname(currentPath), targetBlockJsonPath).replace(/\\/g, "/");
7779
7809
  const normalizedSpecifier = relativeSpecifier.startsWith(".") ? relativeSpecifier : `./${relativeSpecifier}`;
7780
7810
  const next = content.replace(/(['"])\.{1,2}\/[^'"]*block\.json\1/g, `$1${normalizedSpecifier}$1`);
7781
7811
  if (next !== content) {
7782
- await fsp8.writeFile(currentPath, next, "utf8");
7812
+ await fsp10.writeFile(currentPath, next, "utf8");
7783
7813
  }
7784
7814
  }
7785
7815
  await visit(directory);
7786
7816
  }
7787
7817
  async function patchRemotePackageJson(templateDir, needsInteractivity) {
7788
7818
  const packageJsonPath = path14.join(templateDir, "package.json.mustache");
7789
- const packageJson = JSON.parse(await fsp8.readFile(packageJsonPath, "utf8"));
7819
+ const packageJson = JSON.parse(await fsp10.readFile(packageJsonPath, "utf8"));
7790
7820
  const existingDependencies = { ...packageJson.dependencies ?? {} };
7791
7821
  const existingDevDependencies = { ...packageJson.devDependencies ?? {} };
7792
7822
  delete existingDependencies["@wp-typia/project-tools"];
@@ -7806,18 +7836,18 @@ async function patchRemotePackageJson(templateDir, needsInteractivity) {
7806
7836
  } else {
7807
7837
  delete packageJson.dependencies;
7808
7838
  }
7809
- await fsp8.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
7839
+ await fsp10.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
7810
7840
  `, "utf8");
7811
7841
  }
7812
- function getSeedSourceRoot(blockDir) {
7813
- return fs10.existsSync(path14.join(blockDir, "src")) ? path14.join(blockDir, "src") : blockDir;
7842
+ async function getSeedSourceRoot(blockDir) {
7843
+ return await pathExists(path14.join(blockDir, "src")) ? path14.join(blockDir, "src") : blockDir;
7814
7844
  }
7815
- function findSeedRenderPhp(seed) {
7845
+ async function findSeedRenderPhp(seed) {
7816
7846
  for (const candidate of [
7817
7847
  path14.join(seed.blockDir, "render.php"),
7818
7848
  path14.join(seed.rootDir, "render.php")
7819
7849
  ]) {
7820
- if (fs10.existsSync(candidate)) {
7850
+ if (await pathExists(candidate)) {
7821
7851
  return candidate;
7822
7852
  }
7823
7853
  }
@@ -7856,47 +7886,54 @@ async function removeSeedEntryConflicts(templateDir) {
7856
7886
  "view.ts",
7857
7887
  "view.tsx"
7858
7888
  ]) {
7859
- await fsp8.rm(path14.join(templateDir, "src", filename), { force: true });
7889
+ await fsp10.rm(path14.join(templateDir, "src", filename), { force: true });
7860
7890
  }
7861
7891
  }
7862
7892
  async function normalizeCreateBlockSubset(seed, context) {
7863
7893
  const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-remote-template-");
7864
7894
  try {
7865
7895
  const templateDir = path14.join(tempRoot, "template");
7866
- const blockJson = readRemoteBlockJson(seed.blockDir);
7867
- const sourceRoot = getSeedSourceRoot(seed.blockDir);
7868
- await fsp8.mkdir(templateDir, { recursive: true });
7896
+ const blockJson = await readRemoteBlockJsonAsync(seed.blockDir);
7897
+ const sourceRoot = await getSeedSourceRoot(seed.blockDir);
7898
+ await fsp10.mkdir(templateDir, { recursive: true });
7869
7899
  for (const layerDir of getBuiltInTemplateLayerDirs("basic")) {
7870
- if (!fs10.existsSync(layerDir)) {
7900
+ if (!await pathExists(layerDir)) {
7871
7901
  if (isOmittableBuiltInTemplateLayerDir("basic", layerDir)) {
7872
7902
  continue;
7873
7903
  }
7874
7904
  throw new Error(`Built-in template layer is missing: ${layerDir}`);
7875
7905
  }
7876
- await fsp8.cp(layerDir, templateDir, {
7906
+ await fsp10.cp(layerDir, templateDir, {
7877
7907
  recursive: true,
7878
7908
  force: true
7879
7909
  });
7880
7910
  }
7881
7911
  await removeSeedEntryConflicts(templateDir);
7882
- await fsp8.cp(sourceRoot, path14.join(templateDir, "src"), {
7912
+ await fsp10.cp(sourceRoot, path14.join(templateDir, "src"), {
7883
7913
  recursive: true,
7884
7914
  force: true
7885
7915
  });
7886
- const remoteRenderPath = findSeedRenderPhp(seed);
7916
+ const remoteRenderPath = await findSeedRenderPhp(seed);
7887
7917
  if (remoteRenderPath) {
7888
- await fsp8.copyFile(remoteRenderPath, path14.join(templateDir, "render.php"));
7918
+ await fsp10.copyFile(remoteRenderPath, path14.join(templateDir, "render.php"));
7889
7919
  }
7890
- if (seed.assetsDir && fs10.existsSync(seed.assetsDir)) {
7891
- await fsp8.cp(seed.assetsDir, path14.join(templateDir, "assets"), {
7920
+ if (seed.assetsDir && await pathExists(seed.assetsDir)) {
7921
+ await fsp10.cp(seed.assetsDir, path14.join(templateDir, "assets"), {
7892
7922
  recursive: true,
7893
7923
  force: true
7894
7924
  });
7895
7925
  }
7896
- await fsp8.writeFile(path14.join(templateDir, "src", "types.ts"), buildRemoteTypesSource(blockJson, context), "utf8");
7897
- await fsp8.writeFile(path14.join(templateDir, "src", "block.json"), buildRemoteBlockJsonTemplate(blockJson), "utf8");
7926
+ await fsp10.writeFile(path14.join(templateDir, "src", "types.ts"), buildRemoteTypesSource(blockJson, context), "utf8");
7927
+ await fsp10.writeFile(path14.join(templateDir, "src", "block.json"), buildRemoteBlockJsonTemplate(blockJson), "utf8");
7898
7928
  await rewriteBlockJsonImports(path14.join(templateDir, "src"));
7899
- const needsInteractivity = typeof blockJson.viewScriptModule === "string" || typeof blockJson.viewScript === "string" || fs10.existsSync(path14.join(templateDir, "src", "view.js")) || fs10.existsSync(path14.join(templateDir, "src", "view.ts")) || fs10.existsSync(path14.join(templateDir, "src", "view.tsx")) || fs10.existsSync(path14.join(templateDir, "src", "interactivity.js")) || fs10.existsSync(path14.join(templateDir, "src", "interactivity.ts"));
7929
+ const needsInteractivity = typeof blockJson.viewScriptModule === "string" || typeof blockJson.viewScript === "string" || (await Promise.all([
7930
+ "view.js",
7931
+ "view.jsx",
7932
+ "view.ts",
7933
+ "view.tsx",
7934
+ "interactivity.js",
7935
+ "interactivity.ts"
7936
+ ].map((filename) => pathExists(path14.join(templateDir, "src", filename))))).some(Boolean);
7900
7937
  await patchRemotePackageJson(templateDir, needsInteractivity);
7901
7938
  return {
7902
7939
  id: "remote:create-block-subset",
@@ -7946,27 +7983,27 @@ function getTemplateVariableContext(variables) {
7946
7983
  };
7947
7984
  }
7948
7985
  async function detectTemplateSourceFormat(sourceDir) {
7949
- if (fs11.existsSync(path15.join(sourceDir, "package.json.mustache"))) {
7986
+ if (await pathExists(path15.join(sourceDir, "package.json.mustache"))) {
7950
7987
  return "wp-typia";
7951
7988
  }
7952
7989
  if (await loadExternalTemplateLayerManifest(sourceDir)) {
7953
7990
  throw new Error(`Template source at ${sourceDir} is an external layer package. External layers currently compose only through built-in scaffolds via the runtime API, not as standalone template ids.`);
7954
7991
  }
7955
- if (getExternalTemplateEntry(sourceDir)) {
7992
+ if (await findExternalTemplateEntry(sourceDir)) {
7956
7993
  return "create-block-external";
7957
7994
  }
7958
- if (getTemplateProjectType(sourceDir) !== null) {
7995
+ if (await getTemplateProjectTypeAsync(sourceDir) !== null) {
7959
7996
  return "wp-typia";
7960
7997
  }
7961
- const sourceRoot = fs11.existsSync(path15.join(sourceDir, "src")) ? path15.join(sourceDir, "src") : sourceDir;
7998
+ const sourceRoot = await pathExists(path15.join(sourceDir, "src")) ? path15.join(sourceDir, "src") : sourceDir;
7962
7999
  const blockJsonCandidates = [
7963
8000
  path15.join(sourceDir, "block.json"),
7964
8001
  path15.join(sourceRoot, "block.json")
7965
8002
  ];
7966
- const hasBlockJson = blockJsonCandidates.some((candidate) => fs11.existsSync(candidate));
7967
- const hasIndexFile = ["index.js", "index.jsx", "index.ts", "index.tsx"].some((filename) => fs11.existsSync(path15.join(sourceRoot, filename)));
7968
- const hasEditFile = ["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].some((filename) => fs11.existsSync(path15.join(sourceRoot, filename)));
7969
- const hasSaveFile = ["save.js", "save.jsx", "save.ts", "save.tsx"].some((filename) => fs11.existsSync(path15.join(sourceRoot, filename)));
8003
+ const hasBlockJson = (await Promise.all(blockJsonCandidates.map((candidate) => pathExists(candidate)))).some(Boolean);
8004
+ const hasIndexFile = (await Promise.all(["index.js", "index.jsx", "index.ts", "index.tsx"].map((filename) => pathExists(path15.join(sourceRoot, filename))))).some(Boolean);
8005
+ const hasEditFile = (await Promise.all(["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].map((filename) => pathExists(path15.join(sourceRoot, filename))))).some(Boolean);
8006
+ const hasSaveFile = (await Promise.all(["save.js", "save.jsx", "save.ts", "save.tsx"].map((filename) => pathExists(path15.join(sourceRoot, filename))))).some(Boolean);
7970
8007
  if (hasBlockJson && hasIndexFile && hasEditFile && hasSaveFile) {
7971
8008
  return "create-block-subset";
7972
8009
  }
@@ -7975,8 +8012,8 @@ async function detectTemplateSourceFormat(sourceDir) {
7975
8012
 
7976
8013
  // ../wp-typia-project-tools/src/runtime/template-source-seeds.ts
7977
8014
  var import_semver = __toESM(require_semver2(), 1);
7978
- import fs14 from "fs";
7979
- import { promises as fsp10 } from "fs";
8015
+ import fs11 from "fs";
8016
+ import { promises as fsp12 } from "fs";
7980
8017
  import { createRequire as createRequire2 } from "module";
7981
8018
  import path17 from "path";
7982
8019
  import { spawnSync } from "child_process";
@@ -10251,7 +10288,7 @@ var Vn = 512 * 1024;
10251
10288
  var $n = pr | ur | dr | mr;
10252
10289
  var lr = !fr && typeof ar == "number" ? ar | ur | dr | mr : null;
10253
10290
  var cs = lr !== null ? () => lr : Kn ? (s3) => s3 < Vn ? $n : "w" : () => "w";
10254
- var fs12 = (s3, t, e) => {
10291
+ var fs9 = (s3, t, e) => {
10255
10292
  try {
10256
10293
  return mi.lchownSync(s3, t, e);
10257
10294
  } catch (i) {
@@ -10300,7 +10337,7 @@ var ds = (s3, t, e, i) => {
10300
10337
  });
10301
10338
  };
10302
10339
  var qn = (s3, t, e, i) => {
10303
- t.isDirectory() && us(Ee.resolve(s3, t.name), e, i), fs12(Ee.resolve(s3, t.name), e, i);
10340
+ t.isDirectory() && us(Ee.resolve(s3, t.name), e, i), fs9(Ee.resolve(s3, t.name), e, i);
10304
10341
  };
10305
10342
  var us = (s3, t, e) => {
10306
10343
  let i;
@@ -10311,12 +10348,12 @@ var us = (s3, t, e) => {
10311
10348
  if (n?.code === "ENOENT")
10312
10349
  return;
10313
10350
  if (n?.code === "ENOTDIR" || n?.code === "ENOTSUP")
10314
- return fs12(s3, t, e);
10351
+ return fs9(s3, t, e);
10315
10352
  throw n;
10316
10353
  }
10317
10354
  for (let r of i)
10318
10355
  qn(s3, r, t, e);
10319
- return fs12(s3, t, e);
10356
+ return fs9(s3, t, e);
10320
10357
  };
10321
10358
  var we = class extends Error {
10322
10359
  path;
@@ -11130,15 +11167,18 @@ var So = (s3) => {
11130
11167
 
11131
11168
  // ../wp-typia-project-tools/src/runtime/template-source-cache.ts
11132
11169
  import { createHash } from "crypto";
11133
- import fs13 from "fs";
11134
- import { promises as fsp9 } from "fs";
11170
+ import fs10 from "fs";
11171
+ import { promises as fsp11 } from "fs";
11135
11172
  import os2 from "os";
11136
11173
  import path16 from "path";
11137
11174
  var EXTERNAL_TEMPLATE_CACHE_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE";
11138
11175
  var EXTERNAL_TEMPLATE_CACHE_DIR_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_DIR";
11139
11176
  var EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_TTL_DAYS";
11177
+ var EXTERNAL_TEMPLATE_CACHE_PRUNE_INTERVAL_MS_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_PRUNE_INTERVAL_MS";
11140
11178
  var CACHE_MARKER_FILE = "wp-typia-template-cache.json";
11179
+ var CACHE_PRUNE_MARKER_FILE = "wp-typia-template-cache-prune.json";
11141
11180
  var MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
11181
+ var DEFAULT_CACHE_PRUNE_INTERVAL_MS = 60 * 60 * 1000;
11142
11182
  var PRIVATE_CACHE_DIRECTORY_MODE = 448;
11143
11183
  var REDACTED_CACHE_METADATA_VALUE = "[redacted]";
11144
11184
  var DISABLED_CACHE_VALUES = new Set(["0", "false", "no", "off"]);
@@ -11186,12 +11226,33 @@ function resolveExternalTemplateCacheTtlMs(options = {}) {
11186
11226
  const ttlMs = ttlDays * MILLISECONDS_PER_DAY;
11187
11227
  return Number.isFinite(ttlMs) ? ttlMs : null;
11188
11228
  }
11229
+ function parseExternalTemplateCachePruneIntervalMs(value) {
11230
+ if (typeof value !== "string" && typeof value !== "number") {
11231
+ return null;
11232
+ }
11233
+ const intervalMs = typeof value === "number" ? value : Number(value.trim());
11234
+ if (!Number.isFinite(intervalMs) || intervalMs <= 0) {
11235
+ return null;
11236
+ }
11237
+ return intervalMs;
11238
+ }
11239
+ function resolveExternalTemplateCachePruneIntervalMs(options = {}) {
11240
+ if (options.pruneIntervalMs !== undefined) {
11241
+ return parseExternalTemplateCachePruneIntervalMs(options.pruneIntervalMs);
11242
+ }
11243
+ const env = options.env ?? process.env;
11244
+ const envValue = env[EXTERNAL_TEMPLATE_CACHE_PRUNE_INTERVAL_MS_ENV];
11245
+ if (envValue === undefined) {
11246
+ return DEFAULT_CACHE_PRUNE_INTERVAL_MS;
11247
+ }
11248
+ return parseExternalTemplateCachePruneIntervalMs(envValue);
11249
+ }
11189
11250
  function createExternalTemplateCacheKey(keyParts) {
11190
11251
  return createHash("sha256").update(JSON.stringify(keyParts)).digest("hex");
11191
11252
  }
11192
- async function pathExists(filePath) {
11253
+ async function pathExists2(filePath) {
11193
11254
  try {
11194
- await fsp9.access(filePath, fs13.constants.F_OK);
11255
+ await fsp11.access(filePath, fs10.constants.F_OK);
11195
11256
  return true;
11196
11257
  } catch {
11197
11258
  return false;
@@ -11199,18 +11260,18 @@ async function pathExists(filePath) {
11199
11260
  }
11200
11261
  async function isDirectoryPath(directory) {
11201
11262
  try {
11202
- const stats = await fsp9.lstat(directory);
11263
+ const stats = await fsp11.lstat(directory);
11203
11264
  return stats.isDirectory() && !stats.isSymbolicLink();
11204
11265
  } catch {
11205
11266
  return false;
11206
11267
  }
11207
11268
  }
11208
- function getNodeErrorCode(error) {
11269
+ function getNodeErrorCode2(error) {
11209
11270
  return typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
11210
11271
  }
11211
11272
  async function removeTemporaryCacheEntry(entryDir) {
11212
11273
  try {
11213
- await fsp9.rm(entryDir, { force: true, recursive: true });
11274
+ await fsp11.rm(entryDir, { force: true, recursive: true });
11214
11275
  } catch {}
11215
11276
  }
11216
11277
  function getCurrentUserCacheSegment() {
@@ -11229,7 +11290,7 @@ function getCurrentUid() {
11229
11290
  }
11230
11291
  async function isPrivateCacheDirectory(directory) {
11231
11292
  try {
11232
- const stats = await fsp9.lstat(directory);
11293
+ const stats = await fsp11.lstat(directory);
11233
11294
  if (!stats.isDirectory() || stats.isSymbolicLink()) {
11234
11295
  return false;
11235
11296
  }
@@ -11247,11 +11308,11 @@ async function isPrivateCacheDirectory(directory) {
11247
11308
  }
11248
11309
  async function ensurePrivateCacheDirectory(directory) {
11249
11310
  try {
11250
- await fsp9.mkdir(directory, {
11311
+ await fsp11.mkdir(directory, {
11251
11312
  mode: PRIVATE_CACHE_DIRECTORY_MODE,
11252
11313
  recursive: true
11253
11314
  });
11254
- const stats = await fsp9.lstat(directory);
11315
+ const stats = await fsp11.lstat(directory);
11255
11316
  if (!stats.isDirectory() || stats.isSymbolicLink()) {
11256
11317
  return false;
11257
11318
  }
@@ -11261,7 +11322,7 @@ async function ensurePrivateCacheDirectory(directory) {
11261
11322
  }
11262
11323
  if (process.platform !== "win32") {
11263
11324
  if ((stats.mode & 63) !== 0) {
11264
- await fsp9.chmod(directory, PRIVATE_CACHE_DIRECTORY_MODE);
11325
+ await fsp11.chmod(directory, PRIVATE_CACHE_DIRECTORY_MODE);
11265
11326
  }
11266
11327
  }
11267
11328
  return isPrivateCacheDirectory(directory);
@@ -11319,7 +11380,7 @@ function getCacheEntryPaths(descriptor) {
11319
11380
  };
11320
11381
  }
11321
11382
  async function isReusableCacheEntry(entryDir, markerPath, sourceDir) {
11322
- return await isPrivateCacheDirectory(entryDir) && await pathExists(markerPath) && await isDirectoryPath(sourceDir);
11383
+ return await isPrivateCacheDirectory(entryDir) && await pathExists2(markerPath) && await isDirectoryPath(sourceDir);
11323
11384
  }
11324
11385
  function parseCacheMarkerMetadata(markerText) {
11325
11386
  let marker;
@@ -11349,6 +11410,13 @@ function parseCacheMarkerMetadata(markerText) {
11349
11410
  metadata
11350
11411
  };
11351
11412
  }
11413
+ async function readCacheEntryMarker(markerPath) {
11414
+ try {
11415
+ return parseCacheMarkerMetadata(await fsp11.readFile(markerPath, "utf8"));
11416
+ } catch {
11417
+ return null;
11418
+ }
11419
+ }
11352
11420
  function cacheMetadataMatches(actual, expected) {
11353
11421
  return Object.entries(expected).every(([key, value]) => actual[key] === value);
11354
11422
  }
@@ -11356,6 +11424,19 @@ function getExternalTemplateCacheNowMs(now) {
11356
11424
  const nowMs = now instanceof Date ? now.getTime() : typeof now === "number" ? now : Date.now();
11357
11425
  return Number.isFinite(nowMs) ? nowMs : Date.now();
11358
11426
  }
11427
+ function isCacheEntryFreshForTtl(createdAtMs, nowMs, ttlMs) {
11428
+ return ttlMs === null || createdAtMs >= nowMs - ttlMs;
11429
+ }
11430
+ async function getReusableCacheEntryMarker(entryDir, markerPath, sourceDir) {
11431
+ if (!await isReusableCacheEntry(entryDir, markerPath, sourceDir)) {
11432
+ return null;
11433
+ }
11434
+ return readCacheEntryMarker(markerPath);
11435
+ }
11436
+ async function isReusableFreshCacheEntry(entryDir, markerPath, sourceDir, nowMs, ttlMs) {
11437
+ const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
11438
+ return marker !== null && isCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs);
11439
+ }
11359
11440
  function isPathInsideDirectory(directory, candidatePath) {
11360
11441
  const relativePath = path16.relative(directory, candidatePath);
11361
11442
  return relativePath.length > 0 && !relativePath.startsWith("..") && !path16.isAbsolute(relativePath);
@@ -11365,12 +11446,82 @@ async function removeCacheEntryWithinRoot(cacheRoot, entryDir) {
11365
11446
  return false;
11366
11447
  }
11367
11448
  try {
11368
- await fsp9.rm(entryDir, { force: true, recursive: true });
11449
+ await fsp11.rm(entryDir, { force: true, recursive: true });
11369
11450
  return true;
11370
11451
  } catch {
11371
11452
  return false;
11372
11453
  }
11373
11454
  }
11455
+ function getCachePruneMarkerPath(cacheRoot) {
11456
+ return path16.join(cacheRoot, CACHE_PRUNE_MARKER_FILE);
11457
+ }
11458
+ function parseCachePruneMarker(markerText) {
11459
+ let marker;
11460
+ try {
11461
+ marker = JSON.parse(markerText);
11462
+ } catch {
11463
+ return null;
11464
+ }
11465
+ if (typeof marker !== "object" || marker === null || Array.isArray(marker)) {
11466
+ return null;
11467
+ }
11468
+ const rawPrunedAt = marker.prunedAt;
11469
+ const prunedAtMs = typeof rawPrunedAt === "string" ? Date.parse(rawPrunedAt) : Number.NaN;
11470
+ const rawPruneIntervalMs = marker.pruneIntervalMs;
11471
+ const rawTtlMs = marker.ttlMs;
11472
+ if (typeof rawTtlMs !== "number" || !Number.isFinite(rawTtlMs)) {
11473
+ return null;
11474
+ }
11475
+ if (!Number.isFinite(prunedAtMs)) {
11476
+ return null;
11477
+ }
11478
+ if (rawPruneIntervalMs !== null && (typeof rawPruneIntervalMs !== "number" || !Number.isFinite(rawPruneIntervalMs))) {
11479
+ return null;
11480
+ }
11481
+ return {
11482
+ prunedAtMs,
11483
+ pruneIntervalMs: rawPruneIntervalMs ?? null,
11484
+ ttlMs: rawTtlMs
11485
+ };
11486
+ }
11487
+ async function shouldSkipExternalTemplateCachePrune({
11488
+ cacheRoot,
11489
+ force,
11490
+ nowMs,
11491
+ pruneIntervalMs,
11492
+ ttlMs
11493
+ }) {
11494
+ if (force || pruneIntervalMs === null) {
11495
+ return false;
11496
+ }
11497
+ let markerText;
11498
+ try {
11499
+ markerText = await fsp11.readFile(getCachePruneMarkerPath(cacheRoot), "utf8");
11500
+ } catch {
11501
+ return false;
11502
+ }
11503
+ const marker = parseCachePruneMarker(markerText);
11504
+ if (!marker || marker.ttlMs !== ttlMs || marker.pruneIntervalMs !== pruneIntervalMs) {
11505
+ return false;
11506
+ }
11507
+ const elapsedMs = nowMs - marker.prunedAtMs;
11508
+ return elapsedMs >= 0 && elapsedMs < pruneIntervalMs;
11509
+ }
11510
+ async function writeExternalTemplateCachePruneMarker({
11511
+ cacheRoot,
11512
+ nowMs,
11513
+ pruneIntervalMs,
11514
+ ttlMs
11515
+ }) {
11516
+ try {
11517
+ await fsp11.writeFile(getCachePruneMarkerPath(cacheRoot), `${JSON.stringify({
11518
+ prunedAt: new Date(nowMs).toISOString(),
11519
+ pruneIntervalMs,
11520
+ ttlMs
11521
+ }, null, 2)}
11522
+ `, "utf8");
11523
+ } catch {}
11524
+ }
11374
11525
  async function pruneExternalTemplateCache(options = {}) {
11375
11526
  const env = options.env ?? process.env;
11376
11527
  const cacheRoot = getExternalTemplateCacheRoot(env);
@@ -11378,23 +11529,39 @@ async function pruneExternalTemplateCache(options = {}) {
11378
11529
  env,
11379
11530
  ttlDays: options.ttlDays
11380
11531
  });
11532
+ const pruneIntervalMs = resolveExternalTemplateCachePruneIntervalMs({
11533
+ env,
11534
+ pruneIntervalMs: options.pruneIntervalMs
11535
+ });
11381
11536
  const result = {
11382
11537
  cacheRoot,
11383
11538
  prunedEntries: 0,
11384
11539
  scannedEntries: 0,
11385
11540
  skippedEntries: 0,
11541
+ skippedByThrottle: false,
11386
11542
  ttlMs
11387
11543
  };
11388
11544
  if (ttlMs === null || !await isPrivateCacheDirectory(cacheRoot)) {
11389
11545
  return result;
11390
11546
  }
11547
+ const nowMs = getExternalTemplateCacheNowMs(options.now);
11548
+ if (await shouldSkipExternalTemplateCachePrune({
11549
+ cacheRoot,
11550
+ force: options.force,
11551
+ nowMs,
11552
+ pruneIntervalMs,
11553
+ ttlMs
11554
+ })) {
11555
+ result.skippedByThrottle = true;
11556
+ return result;
11557
+ }
11391
11558
  let namespaceEntries;
11392
11559
  try {
11393
- namespaceEntries = await fsp9.readdir(cacheRoot, { withFileTypes: true });
11560
+ namespaceEntries = await fsp11.readdir(cacheRoot, { withFileTypes: true });
11394
11561
  } catch {
11395
11562
  return result;
11396
11563
  }
11397
- const expiresBeforeMs = getExternalTemplateCacheNowMs(options.now) - ttlMs;
11564
+ const expiresBeforeMs = nowMs - ttlMs;
11398
11565
  for (const namespaceEntry of namespaceEntries) {
11399
11566
  if (!namespaceEntry.isDirectory()) {
11400
11567
  continue;
@@ -11406,7 +11573,7 @@ async function pruneExternalTemplateCache(options = {}) {
11406
11573
  }
11407
11574
  let cacheEntries;
11408
11575
  try {
11409
- cacheEntries = await fsp9.readdir(namespaceDir, { withFileTypes: true });
11576
+ cacheEntries = await fsp11.readdir(namespaceDir, { withFileTypes: true });
11410
11577
  } catch {
11411
11578
  result.skippedEntries += 1;
11412
11579
  continue;
@@ -11427,18 +11594,7 @@ async function pruneExternalTemplateCache(options = {}) {
11427
11594
  }
11428
11595
  const markerPath = path16.join(entryDir, CACHE_MARKER_FILE);
11429
11596
  const sourceDir = path16.join(entryDir, "source");
11430
- if (!await isReusableCacheEntry(entryDir, markerPath, sourceDir)) {
11431
- result.skippedEntries += 1;
11432
- continue;
11433
- }
11434
- let markerText;
11435
- try {
11436
- markerText = await fsp9.readFile(markerPath, "utf8");
11437
- } catch {
11438
- result.skippedEntries += 1;
11439
- continue;
11440
- }
11441
- const marker = parseCacheMarkerMetadata(markerText);
11597
+ const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
11442
11598
  if (!marker) {
11443
11599
  result.skippedEntries += 1;
11444
11600
  continue;
@@ -11452,6 +11608,12 @@ async function pruneExternalTemplateCache(options = {}) {
11452
11608
  }
11453
11609
  }
11454
11610
  }
11611
+ await writeExternalTemplateCachePruneMarker({
11612
+ cacheRoot,
11613
+ nowMs,
11614
+ pruneIntervalMs,
11615
+ ttlMs
11616
+ });
11455
11617
  return result;
11456
11618
  }
11457
11619
  async function findReusableExternalTemplateSourceCache(descriptor) {
@@ -11466,10 +11628,12 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
11466
11628
  if (!await isPrivateCacheDirectory(cacheRoot) || !await isPrivateCacheDirectory(namespaceDir)) {
11467
11629
  return null;
11468
11630
  }
11631
+ const ttlMs = resolveExternalTemplateCacheTtlMs();
11632
+ const nowMs = getExternalTemplateCacheNowMs(undefined);
11469
11633
  await pruneExternalTemplateCache();
11470
11634
  let entries;
11471
11635
  try {
11472
- entries = await fsp9.readdir(namespaceDir, { withFileTypes: true });
11636
+ entries = await fsp11.readdir(namespaceDir, { withFileTypes: true });
11473
11637
  } catch {
11474
11638
  return null;
11475
11639
  }
@@ -11481,17 +11645,8 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
11481
11645
  const entryDir = path16.join(namespaceDir, entry.name);
11482
11646
  const markerPath = path16.join(entryDir, CACHE_MARKER_FILE);
11483
11647
  const sourceDir = path16.join(entryDir, "source");
11484
- if (!await isReusableCacheEntry(entryDir, markerPath, sourceDir)) {
11485
- continue;
11486
- }
11487
- let markerText;
11488
- try {
11489
- markerText = await fsp9.readFile(markerPath, "utf8");
11490
- } catch {
11491
- continue;
11492
- }
11493
- const marker = parseCacheMarkerMetadata(markerText);
11494
- if (!marker || !cacheMetadataMatches(marker.metadata, descriptor.metadata)) {
11648
+ const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
11649
+ if (!marker || !isCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs) || !cacheMetadataMatches(marker.metadata, descriptor.metadata)) {
11495
11650
  continue;
11496
11651
  }
11497
11652
  if (!bestEntry || marker.createdAtMs > bestEntry.createdAtMs) {
@@ -11518,23 +11673,29 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
11518
11673
  if (!await ensurePrivateCacheDirectory(cacheRoot) || !await ensurePrivateCacheDirectory(namespaceDir)) {
11519
11674
  return null;
11520
11675
  }
11676
+ const ttlMs = resolveExternalTemplateCacheTtlMs();
11677
+ const nowMs = getExternalTemplateCacheNowMs(undefined);
11521
11678
  await pruneExternalTemplateCache();
11522
- if (await isReusableCacheEntry(entryDir, markerPath, sourceDir)) {
11679
+ const existingMarker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
11680
+ if (existingMarker && isCacheEntryFreshForTtl(existingMarker.createdAtMs, nowMs, ttlMs)) {
11523
11681
  return {
11524
11682
  cacheHit: true,
11525
11683
  sourceDir
11526
11684
  };
11527
11685
  }
11686
+ if (existingMarker) {
11687
+ await removeCacheEntryWithinRoot(cacheRoot, entryDir);
11688
+ }
11528
11689
  const temporaryEntryDir = path16.join(namespaceDir, `.tmp-${cacheKey}-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
11529
11690
  const temporarySourceDir = path16.join(temporaryEntryDir, "source");
11530
11691
  let populateFailed = false;
11531
11692
  try {
11532
- await fsp9.mkdir(temporarySourceDir, {
11693
+ await fsp11.mkdir(temporarySourceDir, {
11533
11694
  mode: PRIVATE_CACHE_DIRECTORY_MODE,
11534
11695
  recursive: true
11535
11696
  });
11536
11697
  if (process.platform !== "win32") {
11537
- await fsp9.chmod(temporaryEntryDir, PRIVATE_CACHE_DIRECTORY_MODE);
11698
+ await fsp11.chmod(temporaryEntryDir, PRIVATE_CACHE_DIRECTORY_MODE);
11538
11699
  }
11539
11700
  try {
11540
11701
  await populateSourceDir(temporarySourceDir);
@@ -11542,14 +11703,14 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
11542
11703
  populateFailed = true;
11543
11704
  throw error;
11544
11705
  }
11545
- await fsp9.writeFile(path16.join(temporaryEntryDir, CACHE_MARKER_FILE), `${JSON.stringify({
11706
+ await fsp11.writeFile(path16.join(temporaryEntryDir, CACHE_MARKER_FILE), `${JSON.stringify({
11546
11707
  createdAt: new Date().toISOString(),
11547
11708
  key: cacheKey,
11548
11709
  metadata: sanitizeCacheMetadata(descriptor.metadata),
11549
11710
  namespace: descriptor.namespace
11550
11711
  }, null, 2)}
11551
11712
  `, "utf8");
11552
- await fsp9.rename(temporaryEntryDir, entryDir);
11713
+ await fsp11.rename(temporaryEntryDir, entryDir);
11553
11714
  return {
11554
11715
  cacheHit: false,
11555
11716
  sourceDir
@@ -11557,13 +11718,13 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
11557
11718
  } catch (error) {
11558
11719
  await removeTemporaryCacheEntry(temporaryEntryDir);
11559
11720
  if (populateFailed) {
11560
- if (CACHE_UNAVAILABLE_ERROR_CODES.has(getNodeErrorCode(error))) {
11721
+ if (CACHE_UNAVAILABLE_ERROR_CODES.has(getNodeErrorCode2(error))) {
11561
11722
  return null;
11562
11723
  }
11563
11724
  throw error;
11564
11725
  }
11565
- const errorCode = getNodeErrorCode(error);
11566
- if (CACHE_PUBLISH_RACE_ERROR_CODES.has(errorCode) && await isReusableCacheEntry(entryDir, markerPath, sourceDir)) {
11726
+ const errorCode = getNodeErrorCode2(error);
11727
+ if (CACHE_PUBLISH_RACE_ERROR_CODES.has(errorCode) && await isReusableFreshCacheEntry(entryDir, markerPath, sourceDir, nowMs, ttlMs)) {
11567
11728
  return {
11568
11729
  cacheHit: true,
11569
11730
  sourceDir
@@ -11621,8 +11782,8 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
11621
11782
  throw new Error(`Failed to download npm template tarball for ${locator.raw}: ${tarballResponse.status}`);
11622
11783
  }
11623
11784
  const tarballPath = path17.join(path17.dirname(unpackDir), "template.tgz");
11624
- await fsp10.mkdir(unpackDir, { recursive: true });
11625
- await fsp10.writeFile(tarballPath, await readBufferResponseWithLimit(tarballResponse, {
11785
+ await fsp12.mkdir(unpackDir, { recursive: true });
11786
+ await fsp12.writeFile(tarballPath, await readBufferResponseWithLimit(tarballResponse, {
11626
11787
  label: `npm template tarball for ${locator.raw}@${resolvedVersion}`,
11627
11788
  maxBytes: getExternalTemplateTarballMaxBytes()
11628
11789
  }));
@@ -11631,7 +11792,7 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
11631
11792
  file: tarballPath,
11632
11793
  strip: 1
11633
11794
  });
11634
- await fsp10.rm(tarballPath, { force: true });
11795
+ await fsp12.rm(tarballPath, { force: true });
11635
11796
  await assertNoSymlinks2(unpackDir);
11636
11797
  }
11637
11798
  function selectRegistryVersion(metadata, locator) {
@@ -11743,8 +11904,8 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
11743
11904
  return null;
11744
11905
  }
11745
11906
  const workspacePackagesRoot = path17.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..");
11746
- if (fs14.existsSync(workspacePackagesRoot)) {
11747
- for (const entry of fs14.readdirSync(workspacePackagesRoot, {
11907
+ if (fs11.existsSync(workspacePackagesRoot)) {
11908
+ for (const entry of fs11.readdirSync(workspacePackagesRoot, {
11748
11909
  withFileTypes: true
11749
11910
  })) {
11750
11911
  if (!entry.isDirectory()) {
@@ -11752,10 +11913,10 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
11752
11913
  }
11753
11914
  const packageDir = path17.join(workspacePackagesRoot, entry.name);
11754
11915
  const packageJsonPath = path17.join(packageDir, "package.json");
11755
- if (!fs14.existsSync(packageJsonPath)) {
11916
+ if (!fs11.existsSync(packageJsonPath)) {
11756
11917
  continue;
11757
11918
  }
11758
- const manifest = JSON.parse(fs14.readFileSync(packageJsonPath, "utf8"));
11919
+ const manifest = JSON.parse(fs11.readFileSync(packageJsonPath, "utf8"));
11759
11920
  if (manifest.name === locator.name) {
11760
11921
  return {
11761
11922
  blockDir: packageDir,
@@ -11766,7 +11927,7 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
11766
11927
  }
11767
11928
  const workspaceRequire = createRequire2(path17.join(path17.resolve(cwd), "__wp_typia_template_resolver__.cjs"));
11768
11929
  try {
11769
- const packageJsonPath = fs14.realpathSync(workspaceRequire.resolve(`${locator.name}/package.json`));
11930
+ const packageJsonPath = fs11.realpathSync(workspaceRequire.resolve(`${locator.name}/package.json`));
11770
11931
  const sourceDir = path17.dirname(packageJsonPath);
11771
11932
  return {
11772
11933
  blockDir: sourceDir,
@@ -11777,10 +11938,10 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
11777
11938
  if (errorCode === "MODULE_NOT_FOUND" || errorCode === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
11778
11939
  for (const basePath of workspaceRequire.resolve.paths(locator.name) ?? []) {
11779
11940
  const packageJsonPath = path17.join(basePath, locator.name, "package.json");
11780
- if (!fs14.existsSync(packageJsonPath)) {
11941
+ if (!fs11.existsSync(packageJsonPath)) {
11781
11942
  continue;
11782
11943
  }
11783
- const sourceDir = path17.dirname(fs14.realpathSync(packageJsonPath));
11944
+ const sourceDir = path17.dirname(fs11.realpathSync(packageJsonPath));
11784
11945
  return {
11785
11946
  blockDir: sourceDir,
11786
11947
  rootDir: sourceDir
@@ -11793,25 +11954,25 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
11793
11954
  }
11794
11955
  function isOfficialWorkspaceTemplateSeed(seed) {
11795
11956
  const packageJsonPath = path17.join(seed.rootDir, "package.json");
11796
- if (!fs14.existsSync(packageJsonPath)) {
11957
+ if (!fs11.existsSync(packageJsonPath)) {
11797
11958
  return false;
11798
11959
  }
11799
11960
  try {
11800
- const packageJson = JSON.parse(fs14.readFileSync(packageJsonPath, "utf8"));
11961
+ const packageJson = JSON.parse(fs11.readFileSync(packageJsonPath, "utf8"));
11801
11962
  return packageJson.name === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE;
11802
11963
  } catch {
11803
11964
  return false;
11804
11965
  }
11805
11966
  }
11806
11967
  async function assertNoSymlinks2(sourceDir) {
11807
- const stats = await fsp10.lstat(sourceDir);
11968
+ const stats = await fsp12.lstat(sourceDir);
11808
11969
  if (stats.isSymbolicLink()) {
11809
11970
  throw new Error(`Template sources may not include symbolic links: ${sourceDir}`);
11810
11971
  }
11811
11972
  if (!stats.isDirectory()) {
11812
11973
  return;
11813
11974
  }
11814
- for (const entry of await fsp10.readdir(sourceDir)) {
11975
+ for (const entry of await fsp12.readdir(sourceDir)) {
11815
11976
  await assertNoSymlinks2(path17.join(sourceDir, entry));
11816
11977
  }
11817
11978
  }
@@ -11846,7 +12007,7 @@ function resolveGitHubTemplateDirectory(checkoutDir, locator) {
11846
12007
  if (relativeSourceDir.startsWith("..") || path17.isAbsolute(relativeSourceDir)) {
11847
12008
  throw new Error("GitHub template path must stay within the cloned repository.");
11848
12009
  }
11849
- if (!fs14.existsSync(sourceDir)) {
12010
+ if (!fs11.existsSync(sourceDir)) {
11850
12011
  throw new Error(`GitHub template path does not exist: ${locator.sourcePath}`);
11851
12012
  }
11852
12013
  return sourceDir;
@@ -12050,7 +12211,7 @@ async function resolveGitHubTemplateSource(locator) {
12050
12211
  async function resolveTemplateSeed(locator, cwd) {
12051
12212
  if (locator.kind === "path") {
12052
12213
  const sourceDir = path17.resolve(cwd, locator.templatePath);
12053
- if (!fs14.existsSync(sourceDir)) {
12214
+ if (!fs11.existsSync(sourceDir)) {
12054
12215
  throw new Error(`Template path does not exist: ${sourceDir}`);
12055
12216
  }
12056
12217
  await assertNoSymlinks2(sourceDir);
@@ -12095,10 +12256,10 @@ async function resolveTemplateSource(templateId, cwd, variables, variant) {
12095
12256
  throw new Error(`--variant is only supported for official external template configs. Received variant "${variant}" for "${templateId}".`);
12096
12257
  }
12097
12258
  normalizedSeed = await normalizeWpTypiaTemplateSeed(seed);
12098
- const supportsMigrationUi = getTemplateProjectType(seed.blockDir) === "workspace";
12259
+ const supportsMigrationUi = await getTemplateProjectTypeAsync(seed.blockDir) === "workspace";
12099
12260
  return {
12100
12261
  id: templateId,
12101
- defaultCategory: getDefaultCategory(seed.blockDir),
12262
+ defaultCategory: await getDefaultCategoryAsync(seed.blockDir),
12102
12263
  description: "A remote wp-typia template source",
12103
12264
  features: ["Remote source", "wp-typia format"],
12104
12265
  format,
@@ -12115,28 +12276,37 @@ async function resolveTemplateSource(templateId, cwd, variables, variant) {
12115
12276
  const renderedFormat = normalizedSeed.formatHint ?? await detectTemplateSourceFormat(normalizedSeed.blockDir);
12116
12277
  if (renderedFormat === "wp-typia") {
12117
12278
  const normalized3 = await normalizeWpTypiaTemplateSeed(normalizedSeed);
12118
- const supportsMigrationUi = getTemplateProjectType(normalizedSeed.blockDir) === "workspace";
12119
- return {
12120
- cleanup: async () => {
12121
- await normalized3.cleanup?.();
12122
- await seed.cleanup?.();
12123
- },
12124
- defaultCategory: getDefaultCategory(normalizedSeed.blockDir),
12125
- description: "A wp-typia scaffold normalized from an official external template config",
12126
- features: [
12127
- "Remote source",
12128
- "official external template",
12129
- "wp-typia format",
12130
- ...supportsMigrationUi ? ["workspace-capable scaffold"] : []
12131
- ],
12132
- format,
12133
- id: "remote:create-block-external",
12134
- isOfficialWorkspaceTemplate,
12135
- selectedVariant: normalizedSeed.selectedVariant ?? null,
12136
- supportsMigrationUi,
12137
- templateDir: normalized3.blockDir,
12138
- warnings: normalizedSeed.warnings ?? []
12139
- };
12279
+ try {
12280
+ const [projectType, defaultCategory] = await Promise.all([
12281
+ getTemplateProjectTypeAsync(normalizedSeed.blockDir),
12282
+ getDefaultCategoryAsync(normalizedSeed.blockDir)
12283
+ ]);
12284
+ const supportsMigrationUi = projectType === "workspace";
12285
+ return {
12286
+ cleanup: async () => {
12287
+ await normalized3.cleanup?.();
12288
+ await seed.cleanup?.();
12289
+ },
12290
+ defaultCategory,
12291
+ description: "A wp-typia scaffold normalized from an official external template config",
12292
+ features: [
12293
+ "Remote source",
12294
+ "official external template",
12295
+ "wp-typia format",
12296
+ ...supportsMigrationUi ? ["workspace-capable scaffold"] : []
12297
+ ],
12298
+ format,
12299
+ id: "remote:create-block-external",
12300
+ isOfficialWorkspaceTemplate,
12301
+ selectedVariant: normalizedSeed.selectedVariant ?? null,
12302
+ supportsMigrationUi,
12303
+ templateDir: normalized3.blockDir,
12304
+ warnings: normalizedSeed.warnings ?? []
12305
+ };
12306
+ } catch (error) {
12307
+ await normalized3.cleanup?.();
12308
+ throw error;
12309
+ }
12140
12310
  }
12141
12311
  const normalized2 = await normalizeCreateBlockSubset(normalizedSeed, context);
12142
12312
  return {
@@ -12200,10 +12370,16 @@ function compareVersionFloors(left, right) {
12200
12370
  return 0;
12201
12371
  }
12202
12372
  function pickHigherVersionFloor(current, candidate) {
12203
- if (!candidate) {
12373
+ if (current !== undefined) {
12374
+ parseVersionFloorParts(current);
12375
+ }
12376
+ if (candidate !== undefined) {
12377
+ parseVersionFloorParts(candidate);
12378
+ }
12379
+ if (candidate === undefined) {
12204
12380
  return current;
12205
12381
  }
12206
- if (!current) {
12382
+ if (current === undefined) {
12207
12383
  return candidate;
12208
12384
  }
12209
12385
  return compareVersionFloors(current, candidate) >= 0 ? current : candidate;
@@ -12283,6 +12459,24 @@ function normalizeSelections(selections) {
12283
12459
  }
12284
12460
  return [...normalized.values()];
12285
12461
  }
12462
+ function validateFeatureMinimumVersions(definition) {
12463
+ for (const [platform, value] of [
12464
+ ["wordpress", definition.minimumVersions?.wordpress],
12465
+ ["php", definition.minimumVersions?.php]
12466
+ ]) {
12467
+ if (value === undefined) {
12468
+ continue;
12469
+ }
12470
+ try {
12471
+ pickHigherVersionFloor(value, undefined);
12472
+ } catch (error) {
12473
+ throw new Error([
12474
+ `Invalid ${platform} minimum version floor for AI feature "${definition.id}": "${value}".`,
12475
+ 'Expected dotted numeric segments such as "6.7" or "8.1.2".'
12476
+ ].join(" "), { cause: error });
12477
+ }
12478
+ }
12479
+ }
12286
12480
  function resolveAiFeatureCapabilityPlan(selections, registry = DEFAULT_AI_FEATURE_REGISTRY) {
12287
12481
  const requiredFeatures = [];
12288
12482
  const optionalFeatures = [];
@@ -12293,6 +12487,7 @@ function resolveAiFeatureCapabilityPlan(selections, registry = DEFAULT_AI_FEATUR
12293
12487
  if (!definition) {
12294
12488
  throw new Error(`Unknown AI feature capability "${selection.featureId}".`);
12295
12489
  }
12490
+ validateFeatureMinimumVersions(definition);
12296
12491
  const resolvedDefinition = {
12297
12492
  ...definition,
12298
12493
  mode: selection.mode
@@ -12340,17 +12535,44 @@ var REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY = [
12340
12535
  function pickHigherScaffoldVersionFloor(current, candidate) {
12341
12536
  return pickHigherVersionFloor(current, candidate) ?? current;
12342
12537
  }
12343
- function pickHigherHeaderVersionFloor(policyValue, currentValue) {
12538
+ function pickHigherHeaderVersionFloor(policyValue, currentValue, {
12539
+ headerName,
12540
+ onWarning
12541
+ }) {
12344
12542
  const normalizedCurrentValue = currentValue.trim();
12345
12543
  if (!normalizedCurrentValue) {
12346
12544
  return policyValue;
12347
12545
  }
12348
12546
  try {
12349
12547
  return pickHigherScaffoldVersionFloor(policyValue, normalizedCurrentValue);
12350
- } catch {
12548
+ } catch (error) {
12549
+ const warning = [
12550
+ `Invalid plugin header version floor for ${headerName}: "${normalizedCurrentValue}".`,
12551
+ 'Expected dotted numeric segments such as "6.7" or "8.1.2".',
12552
+ `Replacing it with compatibility policy value "${policyValue}".`
12553
+ ].join(" ");
12554
+ if (!onWarning) {
12555
+ throw new Error(warning, { cause: error });
12556
+ }
12557
+ onWarning(warning);
12351
12558
  return policyValue;
12352
12559
  }
12353
12560
  }
12561
+ function assertPolicyVersionFloor(headerName, value) {
12562
+ try {
12563
+ parseVersionFloorParts(value);
12564
+ } catch (error) {
12565
+ throw new Error([
12566
+ `Invalid scaffold compatibility policy floor for ${headerName}: "${value}".`,
12567
+ 'Expected dotted numeric segments such as "6.7" or "8.1.2".'
12568
+ ].join(" "), { cause: error });
12569
+ }
12570
+ }
12571
+ function assertPluginHeaderPolicyVersionFloors(pluginHeader) {
12572
+ assertPolicyVersionFloor("Requires at least", pluginHeader.requiresAtLeast);
12573
+ assertPolicyVersionFloor("Tested up to", pluginHeader.testedUpTo);
12574
+ assertPolicyVersionFloor("Requires PHP", pluginHeader.requiresPhp);
12575
+ }
12354
12576
  function formatRuntimeGate(feature) {
12355
12577
  return (feature.runtimeGates ?? []).map((gate) => `${feature.label}: ${gate.kind} ${gate.value}`);
12356
12578
  }
@@ -12400,17 +12622,21 @@ function renderScaffoldCompatibilityConfig(policy, indent = "\t\t") {
12400
12622
  `).map((line, index) => index === 0 ? line : `${indent}${line}`).join(`
12401
12623
  `);
12402
12624
  }
12403
- function replacePluginHeaderVersionFloor(source, pattern, policyValue) {
12625
+ function replacePluginHeaderVersionFloor(source, pattern, policyValue, headerName, options) {
12404
12626
  return source.replace(pattern, (_match, prefix, currentValue, lineEnding) => {
12405
12627
  const versionPrefix = prefix.endsWith(":") ? `${prefix} ` : prefix;
12406
- return `${versionPrefix}${pickHigherHeaderVersionFloor(policyValue, currentValue)}${lineEnding}`;
12628
+ return `${versionPrefix}${pickHigherHeaderVersionFloor(policyValue, currentValue, {
12629
+ headerName,
12630
+ onWarning: options.onWarning
12631
+ })}${lineEnding}`;
12407
12632
  });
12408
12633
  }
12409
- function updatePluginHeaderCompatibility(source, policy) {
12634
+ function updatePluginHeaderCompatibility(source, policy, options = {}) {
12410
12635
  const { pluginHeader } = policy;
12411
- const nextSource = replacePluginHeaderVersionFloor(source, /(\* Requires at least:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.requiresAtLeast);
12412
- const nextSourceWithTestedUpTo = replacePluginHeaderVersionFloor(nextSource, /(\* Tested up to:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.testedUpTo);
12413
- return replacePluginHeaderVersionFloor(nextSourceWithTestedUpTo, /(\* Requires PHP:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.requiresPhp);
12636
+ assertPluginHeaderPolicyVersionFloors(pluginHeader);
12637
+ const nextSource = replacePluginHeaderVersionFloor(source, /(\* Requires at least:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.requiresAtLeast, "Requires at least", options);
12638
+ const nextSourceWithTestedUpTo = replacePluginHeaderVersionFloor(nextSource, /(\* Tested up to:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.testedUpTo, "Tested up to", options);
12639
+ return replacePluginHeaderVersionFloor(nextSourceWithTestedUpTo, /(\* Requires PHP:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.requiresPhp, "Requires PHP", options);
12414
12640
  }
12415
12641
 
12416
12642
  // ../wp-typia-project-tools/src/runtime/block-generator-service-spec.ts
@@ -17358,16 +17584,16 @@ async function scaffoldProject({
17358
17584
  title: "Finalizing scaffold output"
17359
17585
  });
17360
17586
  const readmePath = path18.join(projectDir, "README.md");
17361
- if (!fs15.existsSync(readmePath)) {
17362
- await fsp11.writeFile(readmePath, buildReadme(resolvedTemplateId, variables, resolvedPackageManager, {
17587
+ if (!fs12.existsSync(readmePath)) {
17588
+ await fsp13.writeFile(readmePath, buildReadme(resolvedTemplateId, variables, resolvedPackageManager, {
17363
17589
  withMigrationUi: isBuiltInTemplate || isWorkspace ? withMigrationUi : false,
17364
17590
  withTestPreset: isBuiltInTemplate ? withTestPreset : false,
17365
17591
  withWpEnv: isBuiltInTemplate ? withWpEnv : false
17366
17592
  }), "utf8");
17367
17593
  }
17368
17594
  const gitignorePath = path18.join(projectDir, ".gitignore");
17369
- const existingGitignore = fs15.existsSync(gitignorePath) ? await fsp11.readFile(gitignorePath, "utf8") : "";
17370
- await fsp11.writeFile(gitignorePath, mergeTextLines(buildGitignore(), existingGitignore), "utf8");
17595
+ const existingGitignore = fs12.existsSync(gitignorePath) ? await fsp13.readFile(gitignorePath, "utf8") : "";
17596
+ await fsp13.writeFile(gitignorePath, mergeTextLines(buildGitignore(), existingGitignore), "utf8");
17371
17597
  await normalizePackageJson(projectDir, resolvedPackageManager);
17372
17598
  if (isBuiltInTemplate) {
17373
17599
  const variableGroups = getScaffoldTemplateVariableGroups(variables);
@@ -17447,6 +17673,6 @@ async function resolveOptionalInteractiveExternalLayerId({
17447
17673
  }
17448
17674
  }
17449
17675
 
17450
- export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, formatNonEmptyTargetDirectoryError, require_semver2 as require_semver, parseTemplateLocator, resolveExternalTemplateLayers, resolveTemplateSeed, normalizeOptionalCliString, resolveLocalCliPathOption, assertExternalLayerCompositionOptions, assertBuiltInTemplateVariantAllowed, parseAlternateRenderTargets, parseCompoundInnerBlocksPreset, OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, createScaffoldCompatibilityConfig, renderScaffoldCompatibilityConfig, updatePluginHeaderCompatibility, getDefaultAnswers, resolveTemplateId, resolvePackageManagerId, collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, scaffoldProject, resolveOptionalInteractiveExternalLayerId };
17676
+ export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, pathExists, formatNonEmptyTargetDirectoryError, require_semver2 as require_semver, parseTemplateLocator, resolveExternalTemplateLayers, resolveTemplateSeed, normalizeOptionalCliString, resolveLocalCliPathOption, assertExternalLayerCompositionOptions, assertBuiltInTemplateVariantAllowed, parseAlternateRenderTargets, parseCompoundInnerBlocksPreset, OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, createScaffoldCompatibilityConfig, renderScaffoldCompatibilityConfig, updatePluginHeaderCompatibility, getDefaultAnswers, resolveTemplateId, resolvePackageManagerId, collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, scaffoldProject, resolveOptionalInteractiveExternalLayerId };
17451
17677
 
17452
- //# debugId=7E585E3F386D6E1964756E2164756E21
17678
+ //# debugId=7CCCC2F398FB931D64756E2164756E21