wp-typia 0.21.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36061,6 +36061,10 @@ function toSnakeCase(input) {
36061
36061
  function toPascalCase(input) {
36062
36062
  return toKebabCase(input).split("-").filter(Boolean).map(capitalizeSegment).join("");
36063
36063
  }
36064
+ function toCamelCase(input) {
36065
+ const pascalCase = toPascalCase(input);
36066
+ return `${pascalCase.charAt(0).toLowerCase()}${pascalCase.slice(1)}`;
36067
+ }
36064
36068
  function toSegmentPascalCase(input) {
36065
36069
  return input.replace(/[^A-Za-z0-9]+/g, " ").trim().split(/\s+/).filter(Boolean).map(capitalizeSegment).join("");
36066
36070
  }
@@ -36394,7 +36398,7 @@ function assertEditorPluginDoesNotExist(projectDir, editorPluginSlug, inventory)
36394
36398
  }
36395
36399
  function formatAddHelpText() {
36396
36400
  return `Usage:
36397
- wp-typia add admin-view <name> [--source <rest-resource:slug>] [--dry-run]
36401
+ wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]
36398
36402
  wp-typia add block <name> [--template <${ADD_BLOCK_TEMPLATE_IDS.join("|")}>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>] [--dry-run]
36399
36403
  wp-typia add variation <name> --block <block-slug> [--dry-run]
36400
36404
  wp-typia add style <name> --block <block-slug> [--dry-run]
@@ -36411,7 +36415,10 @@ Notes:
36411
36415
  \`wp-typia add\` runs only inside official ${WORKSPACE_TEMPLATE_PACKAGE} workspaces scaffolded via \`wp-typia create <project-dir> --template workspace\`.
36412
36416
  Pass \`--dry-run\` to preview the workspace files that would change without writing them.
36413
36417
  Interactive add flows let you choose a template when \`--template\` is omitted; non-interactive runs default to \`basic\`.
36414
- \`add admin-view\` scaffolds an opt-in DataViews-powered WordPress admin screen under \`src/admin-views/\`; pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
36418
+ \`add admin-view\` scaffolds an opt-in DataViews-powered WordPress admin screen under \`src/admin-views/\`.
36419
+ Pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
36420
+ Pass \`--source core-data:postType/post\` or \`--source core-data:taxonomy/category\` to bind a WordPress-owned entity collection.
36421
+ Public installs currently gate this workflow until \`@wp-typia/dataviews\` is published to npm.
36415
36422
  \`query-loop\` is a create-time scaffold family. Use \`wp-typia create <project-dir> --template query-loop\` instead of \`wp-typia add block\`.
36416
36423
  \`add variation\` targets an existing block slug from \`scripts/block-config.ts\`.
36417
36424
  \`add style\` registers a Block Styles option for an existing generated block.
@@ -213268,6 +213275,16 @@ function readPackageManifest(location) {
213268
213275
  }
213269
213276
  return JSON.parse(location.source);
213270
213277
  }
213278
+ function tryReadPackageManifest(location) {
213279
+ if (!location) {
213280
+ return null;
213281
+ }
213282
+ try {
213283
+ return readPackageManifest(location);
213284
+ } catch {
213285
+ return null;
213286
+ }
213287
+ }
213271
213288
  function resolveInstalledPackageManifestLocation(packageName) {
213272
213289
  try {
213273
213290
  return resolvePackageManifestLocation(require2.resolve(`${packageName}/package.json`));
@@ -213285,6 +213302,13 @@ function resolveInstalledPackageManifestLocation(packageName) {
213285
213302
  function composePackageVersionsCacheKey(locations) {
213286
213303
  return locations.map((location) => location.cacheKey).join("|");
213287
213304
  }
213305
+ function resolveManagedPackageVersionRange(options) {
213306
+ const workspaceManifestLocation = options.workspacePackageDirName ? resolvePackageManifestLocation(path31.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", options.workspacePackageDirName, "package.json")) : null;
213307
+ const installedManifestLocation = resolveInstalledPackageManifestLocation(options.packageName);
213308
+ const workspaceManifest = tryReadPackageManifest(workspaceManifestLocation);
213309
+ const installedManifest = tryReadPackageManifest(installedManifestLocation);
213310
+ return normalizeVersionRangeWithFallback(workspaceManifest?.version ?? installedManifest?.version, options.fallback);
213311
+ }
213288
213312
  function getPackageVersions() {
213289
213313
  const createManifestLocation = resolvePackageManifestLocation(path31.join(PROJECT_TOOLS_PACKAGE_ROOT, "package.json"));
213290
213314
  const monorepoManifestLocation = resolvePackageManifestLocation(path31.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "package.json"));
@@ -213343,7 +213367,7 @@ function getPackageVersions() {
213343
213367
  };
213344
213368
  return versions2;
213345
213369
  }
213346
- var require2, DEFAULT_VERSION_RANGE = "^0.0.0", DEFAULT_EXACT_VERSION = "0.0.0", DEFAULT_TSX_PACKAGE_VERSION = "^4.20.5", DEFAULT_TYPIA_UNPLUGIN_PACKAGE_VERSION = "^12.0.1", cachedPackageVersions = null;
213370
+ var require2, DEFAULT_VERSION_RANGE = "^0.0.0", DEFAULT_EXACT_VERSION = "0.0.0", DEFAULT_TSX_PACKAGE_VERSION = "^4.20.5", DEFAULT_TYPIA_UNPLUGIN_PACKAGE_VERSION = "^12.0.1", DEFAULT_WORDPRESS_ABILITIES_VERSION = "^0.10.0", DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION = "^0.9.0", DEFAULT_WORDPRESS_CORE_DATA_VERSION = "^7.44.0", DEFAULT_WORDPRESS_DATA_VERSION = "^9.28.0", DEFAULT_WORDPRESS_DATAVIEWS_VERSION = "^14.1.0", DEFAULT_WP_TYPIA_DATAVIEWS_VERSION = "^0.1.0", cachedPackageVersions = null;
213347
213371
  var init_package_versions = __esm(() => {
213348
213372
  init_template_registry();
213349
213373
  require2 = createRequire(import.meta.url);
@@ -214611,6 +214635,17 @@ function buildInteractivityTypesSource(variables, attributes) {
214611
214635
  { name: "maxClicks", typeExpression: "number" }
214612
214636
  ],
214613
214637
  name: `${variables.pascalCase}Context`
214638
+ },
214639
+ {
214640
+ members: [
214641
+ { name: "clicks", typeExpression: "number" },
214642
+ { name: "isAnimating", typeExpression: "boolean" },
214643
+ { name: "isVisible", typeExpression: "boolean" },
214644
+ { name: "progress", typeExpression: "number" },
214645
+ { name: "clampedClicks", typeExpression: "number" },
214646
+ { name: "isComplete", typeExpression: "boolean" }
214647
+ ],
214648
+ name: `${variables.pascalCase}State`
214614
214649
  }
214615
214650
  ],
214616
214651
  typeAliases: [
@@ -224413,10 +224448,10 @@ var init_compound_inner_blocks = __esm(() => {
224413
224448
  };
224414
224449
  });
224415
224450
 
224416
- // ../wp-typia-project-tools/src/runtime/ai-feature-capability.ts
224451
+ // ../wp-typia-project-tools/src/runtime/version-floor.ts
224417
224452
  function parseVersionFloorParts(value2) {
224418
224453
  return value2.split(".").map((part, index) => {
224419
- if (!/^\d+$/.test(part)) {
224454
+ if (!/^\d+$/u.test(part)) {
224420
224455
  throw new Error(`parseVersionFloorParts received an invalid version floor "${value2}" at segment ${index + 1}.`);
224421
224456
  }
224422
224457
  return Number.parseInt(part, 10);
@@ -224447,6 +224482,8 @@ function pickHigherVersionFloor(current, candidate) {
224447
224482
  }
224448
224483
  return compareVersionFloors(current, candidate) >= 0 ? current : candidate;
224449
224484
  }
224485
+
224486
+ // ../wp-typia-project-tools/src/runtime/ai-feature-capability.ts
224450
224487
  function normalizeSelections(selections) {
224451
224488
  const normalized = new Map;
224452
224489
  for (const selection of selections) {
@@ -224556,35 +224593,8 @@ var init_ai_feature_capability = __esm(() => {
224556
224593
  });
224557
224594
 
224558
224595
  // ../wp-typia-project-tools/src/runtime/scaffold-compatibility.ts
224559
- function parseVersionFloorParts2(value2) {
224560
- return value2.split(".").map((part, index) => {
224561
- if (!/^\d+$/u.test(part)) {
224562
- throw new Error(`parseVersionFloorParts received an invalid version floor "${value2}" at segment ${index + 1}.`);
224563
- }
224564
- return Number.parseInt(part, 10);
224565
- });
224566
- }
224567
- function compareVersionFloors2(left, right) {
224568
- const leftParts = parseVersionFloorParts2(left);
224569
- const rightParts = parseVersionFloorParts2(right);
224570
- const length = Math.max(leftParts.length, rightParts.length);
224571
- for (let index = 0;index < length; index += 1) {
224572
- const leftValue = leftParts[index] ?? 0;
224573
- const rightValue = rightParts[index] ?? 0;
224574
- if (leftValue > rightValue) {
224575
- return 1;
224576
- }
224577
- if (leftValue < rightValue) {
224578
- return -1;
224579
- }
224580
- }
224581
- return 0;
224582
- }
224583
- function pickHigherVersionFloor2(current, candidate) {
224584
- if (!candidate) {
224585
- return current;
224586
- }
224587
- return compareVersionFloors2(current, candidate) >= 0 ? current : candidate;
224596
+ function pickHigherScaffoldVersionFloor(current, candidate) {
224597
+ return pickHigherVersionFloor(current, candidate) ?? current;
224588
224598
  }
224589
224599
  function pickHigherHeaderVersionFloor(policyValue, currentValue) {
224590
224600
  const normalizedCurrentValue = currentValue.trim();
@@ -224592,7 +224602,7 @@ function pickHigherHeaderVersionFloor(policyValue, currentValue) {
224592
224602
  return policyValue;
224593
224603
  }
224594
224604
  try {
224595
- return pickHigherVersionFloor2(policyValue, normalizedCurrentValue);
224605
+ return pickHigherScaffoldVersionFloor(policyValue, normalizedCurrentValue);
224596
224606
  } catch {
224597
224607
  return policyValue;
224598
224608
  }
@@ -224613,9 +224623,9 @@ function resolveScaffoldCompatibilityPolicy(selections, {
224613
224623
  baseline = DEFAULT_SCAFFOLD_COMPATIBILITY
224614
224624
  } = {}) {
224615
224625
  const capabilityPlan = resolveAiFeatureCapabilityPlan(selections);
224616
- const requiresAtLeast = pickHigherVersionFloor2(baseline.requiresAtLeast, capabilityPlan.hardMinimums.wordpress);
224617
- const requiresPhp = pickHigherVersionFloor2(baseline.requiresPhp, capabilityPlan.hardMinimums.php);
224618
- const testedUpTo = pickHigherVersionFloor2(baseline.testedUpTo, requiresAtLeast);
224626
+ const requiresAtLeast = pickHigherScaffoldVersionFloor(baseline.requiresAtLeast, capabilityPlan.hardMinimums.wordpress);
224627
+ const requiresPhp = pickHigherScaffoldVersionFloor(baseline.requiresPhp, capabilityPlan.hardMinimums.php);
224628
+ const testedUpTo = pickHigherScaffoldVersionFloor(baseline.testedUpTo, requiresAtLeast);
224619
224629
  return {
224620
224630
  capabilityPlan,
224621
224631
  pluginHeader: {
@@ -226451,6 +226461,7 @@ import { useBlockProps, InspectorControls, RichText, BlockControls, AlignmentToo
226451
226461
  import { PanelBody, RangeControl, Button, Notice } from '@wordpress/components';
226452
226462
  import { useState } from '@wordpress/element';
226453
226463
  import currentManifest from './manifest-document';
226464
+ import { {{slugCamelCase}}Store } from './interactivity-store';
226454
226465
  import {
226455
226466
  InspectorFromManifest,
226456
226467
  useEditorFields,
@@ -226531,17 +226542,22 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
226531
226542
 
226532
226543
  const blockProps = useBlockProps({
226533
226544
  className: \`{{cssClassName}} {{cssClassName}}--\${interactiveMode}\`,
226534
- 'data-wp-interactive': '{{slugKebabCase}}',
226535
- 'data-wp-context': JSON.stringify({
226536
- clicks: clickCount,
226537
- isAnimating,
226538
- isVisible,
226539
- animation,
226540
- maxClicks,
226541
- })
226545
+ 'data-wp-interactive': {{slugCamelCase}}Store.directive.interactive,
226546
+ 'data-wp-context': JSON.stringify(
226547
+ {{slugCamelCase}}Store.createContext({
226548
+ clicks: clickCount,
226549
+ isAnimating,
226550
+ isVisible,
226551
+ animation,
226552
+ maxClicks,
226553
+ })
226554
+ )
226542
226555
  });
226543
226556
  const previewContentStyle = { textAlign: alignmentValue };
226544
226557
  const progressBarStyle = { width: \`\${(clickCount / maxClicks) * 100}%\` };
226558
+ const clicksDirective = {{slugCamelCase}}Store.directive.state('clicks');
226559
+ const isAnimatingDirective = {{slugCamelCase}}Store.directive.state('isAnimating');
226560
+ const progressDirective = {{slugCamelCase}}Store.directive.state('progress') + " + '%'";
226545
226561
 
226546
226562
  const resetCounter = () => {
226547
226563
  updateField('clickCount', 0);
@@ -226638,9 +226654,9 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
226638
226654
  <div
226639
226655
  className={\`{{cssClassName}}__content \${isAnimating ? 'is-animating' : ''}\`}
226640
226656
  style={previewContentStyle}
226641
- data-wp-on--click={isPreviewing ? 'actions.handleClick' : undefined}
226642
- data-wp-on--mouseenter={isPreviewing && interactiveMode === 'hover' ? 'actions.handleMouseEnter' : undefined}
226643
- data-wp-on--mouseleave={isPreviewing && interactiveMode === 'hover' ? 'actions.handleMouseLeave' : undefined}
226657
+ data-wp-on--click={isPreviewing ? {{slugCamelCase}}Store.directive.action('handleClick') : undefined}
226658
+ data-wp-on--mouseenter={isPreviewing && interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseEnter') : undefined}
226659
+ data-wp-on--mouseleave={isPreviewing && interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseLeave') : undefined}
226644
226660
  >
226645
226661
  <RichText
226646
226662
  tagName="p"
@@ -226669,7 +226685,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
226669
226685
  </span>
226670
226686
  <span
226671
226687
  className="{{cssClassName}}__counter-value"
226672
- data-wp-text="state.clicks"
226688
+ data-wp-text={clicksDirective}
226673
226689
  >
226674
226690
  {clickCount}
226675
226691
  </span>
@@ -226681,7 +226697,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
226681
226697
  <div
226682
226698
  className="{{cssClassName}}__progress-bar"
226683
226699
  style={progressBarStyle}
226684
- data-wp-style--width="state.progress + '%'"
226700
+ data-wp-style--width={progressDirective}
226685
226701
  />
226686
226702
  </div>
226687
226703
  )}
@@ -226689,7 +226705,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
226689
226705
  {animation !== 'none' && (
226690
226706
  <div
226691
226707
  className={\`{{cssClassName}}__animation \${isAnimating ? 'is-active' : ''}\`}
226692
- data-wp-class--is-active="state.isAnimating"
226708
+ data-wp-class--is-active={isAnimatingDirective}
226693
226709
  >
226694
226710
  {animation}
226695
226711
  </div>
@@ -226701,6 +226717,7 @@ export default function Edit({ attributes, setAttributes, isSelected }: EditProp
226701
226717
  }
226702
226718
  `, INTERACTIVITY_SAVE_TEMPLATE = `import { useBlockProps, RichText } from '@wordpress/block-editor';
226703
226719
  import { __ } from '@wordpress/i18n';
226720
+ import { {{slugCamelCase}}Store } from './interactivity-store';
226704
226721
  import type { {{pascalCase}}Attributes } from './types';
226705
226722
 
226706
226723
  export default function Save({ attributes }: { attributes: {{pascalCase}}Attributes }) {
@@ -226712,27 +226729,41 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
226712
226729
  const maxClicks = attributes.maxClicks ?? 0;
226713
226730
  const showCounter = attributes.showCounter ?? true;
226714
226731
  const contentStyle = { textAlign: attributes.alignment };
226732
+ const clickActionDirective = {{slugCamelCase}}Store.directive.action('handleClick');
226733
+ const visibilityHiddenDirective = {{slugCamelCase}}Store.directive.negate(
226734
+ {{slugCamelCase}}Store.directive.state('isVisible')
226735
+ );
226736
+ const clicksDirective = {{slugCamelCase}}Store.directive.state('clicks');
226737
+ const clampedClicksDirective = {{slugCamelCase}}Store.directive.state('clampedClicks');
226738
+ const isAnimatingDirective = {{slugCamelCase}}Store.directive.state('isAnimating');
226739
+ const completionHiddenDirective = {{slugCamelCase}}Store.directive.negate(
226740
+ {{slugCamelCase}}Store.directive.state('isComplete')
226741
+ );
226742
+ const resetActionDirective = {{slugCamelCase}}Store.directive.action('reset');
226715
226743
  const blockProps = useBlockProps.save({
226716
226744
  className: \`{{cssClassName}} {{cssClassName}}--\${interactiveMode}\`,
226717
- 'data-wp-interactive': '{{slugKebabCase}}',
226718
- 'data-wp-context': JSON.stringify({
226719
- clicks: clickCount,
226720
- isAnimating,
226721
- isVisible,
226722
- animation,
226723
- maxClicks,
226724
- })
226745
+ 'data-wp-interactive': {{slugCamelCase}}Store.directive.interactive,
226746
+ 'data-wp-context': JSON.stringify(
226747
+ {{slugCamelCase}}Store.createContext({
226748
+ clicks: clickCount,
226749
+ isAnimating,
226750
+ isVisible,
226751
+ animation,
226752
+ maxClicks,
226753
+ })
226754
+ )
226725
226755
  });
226756
+ const progressDirective = {{slugCamelCase}}Store.directive.state('progress') + " + '%'";
226726
226757
 
226727
226758
  return (
226728
226759
  <div {...blockProps}>
226729
226760
  <div
226730
226761
  className={\`{{cssClassName}}__content \${isAnimating ? 'is-animating' : ''}\`}
226731
226762
  style={contentStyle}
226732
- data-wp-on--click="actions.handleClick"
226733
- data-wp-on--mouseenter={interactiveMode === 'hover' ? 'actions.handleMouseEnter' : undefined}
226734
- data-wp-on--mouseleave={interactiveMode === 'hover' ? 'actions.handleMouseLeave' : undefined}
226735
- data-wp-bind--hidden="!state.isVisible"
226763
+ data-wp-on--click={clickActionDirective}
226764
+ data-wp-on--mouseenter={interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseEnter') : undefined}
226765
+ data-wp-on--mouseleave={interactiveMode === 'hover' ? {{slugCamelCase}}Store.directive.action('handleMouseLeave') : undefined}
226766
+ data-wp-bind--hidden={visibilityHiddenDirective}
226736
226767
  >
226737
226768
  <RichText.Content
226738
226769
  tagName="p"
@@ -226752,7 +226783,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
226752
226783
  </span>
226753
226784
  <span
226754
226785
  className="{{cssClassName}}__counter-value"
226755
- data-wp-text="state.clicks"
226786
+ data-wp-text={clicksDirective}
226756
226787
  >
226757
226788
  {clickCount}
226758
226789
  </span>
@@ -226768,8 +226799,8 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
226768
226799
  aria-valuemin={0}
226769
226800
  aria-valuemax={maxClicks}
226770
226801
  aria-valuenow={Math.min(clickCount, maxClicks)}
226771
- data-wp-bind--aria-valuenow="state.clampedClicks"
226772
- data-wp-style--width="state.progress + '%'"
226802
+ data-wp-bind--aria-valuenow={clampedClicksDirective}
226803
+ data-wp-style--width={progressDirective}
226773
226804
  />
226774
226805
  </div>
226775
226806
  )}
@@ -226777,7 +226808,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
226777
226808
  <div
226778
226809
  className={\`{{cssClassName}}__animation \${animation}\`}
226779
226810
  aria-hidden="true"
226780
- data-wp-class--is-active="state.isAnimating"
226811
+ data-wp-class--is-active={isAnimatingDirective}
226781
226812
  />
226782
226813
 
226783
226814
  {maxClicks > 0 && (
@@ -226786,7 +226817,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
226786
226817
  role="status"
226787
226818
  aria-live="polite"
226788
226819
  aria-atomic="true"
226789
- data-wp-bind--hidden="!state.isComplete"
226820
+ data-wp-bind--hidden={completionHiddenDirective}
226790
226821
  >
226791
226822
  { __( '\uD83C\uDF89 Complete!', '{{textDomain}}' ) }
226792
226823
  </div>
@@ -226794,7 +226825,7 @@ export default function Save({ attributes }: { attributes: {{pascalCase}}Attribu
226794
226825
 
226795
226826
  <button
226796
226827
  className="{{cssClassName}}__reset"
226797
- data-wp-on--click="actions.reset"
226828
+ data-wp-on--click={resetActionDirective}
226798
226829
  aria-label={ __( 'Reset counter', '{{textDomain}}' ) }
226799
226830
  >
226800
226831
  <span aria-hidden="true">\u21BB</span>
@@ -226842,20 +226873,213 @@ const registration = buildScaffoldBlockRegistration(
226842
226873
  );
226843
226874
 
226844
226875
  registerScaffoldBlockType(registration.name, registration.settings);
226876
+ `, INTERACTIVITY_STORE_TEMPLATE = `import type {
226877
+ {{pascalCase}}Context,
226878
+ {{pascalCase}}State,
226879
+ } from './types';
226880
+
226881
+ type InteractivityActionShape = object;
226882
+ type InteractivityCallbackShape = object;
226883
+ type InteractivityContextShape = object;
226884
+ type InteractivityStateShape = object;
226885
+ type InteractivityCallable = CallableFunction;
226886
+ type InteractivityKey<T extends object> = Extract<keyof T, string>;
226887
+ type InteractivityMethodKey<T extends object> = {
226888
+ [Key in InteractivityKey<T>]: T[Key] extends InteractivityCallable ? Key : never;
226889
+ }[InteractivityKey<T>];
226890
+
226891
+ type InteractivityDirectivePath<
226892
+ Root extends string,
226893
+ Key extends string,
226894
+ > = \`\${Root}.\${Key}\`;
226895
+
226896
+ type NegatedInteractivityDirectivePath<Path extends string> = \`!\${Path}\`;
226897
+
226898
+ export interface TypedInteractivityDirectiveHelpers<
226899
+ State extends InteractivityStateShape,
226900
+ Context extends InteractivityContextShape,
226901
+ Actions extends InteractivityActionShape,
226902
+ Callbacks extends InteractivityCallbackShape,
226903
+ Namespace extends string,
226904
+ > {
226905
+ readonly interactive: Namespace;
226906
+ action<Key extends InteractivityMethodKey<Actions>>(
226907
+ key: Key,
226908
+ ): InteractivityDirectivePath<'actions', Key>;
226909
+ callback<Key extends InteractivityMethodKey<Callbacks>>(
226910
+ key: Key,
226911
+ ): InteractivityDirectivePath<'callbacks', Key>;
226912
+ state<Key extends InteractivityKey<State>>(
226913
+ key: Key,
226914
+ ): InteractivityDirectivePath<'state', Key>;
226915
+ context<Key extends InteractivityKey<Context>>(
226916
+ key: Key,
226917
+ ): InteractivityDirectivePath<'context', Key>;
226918
+ negate<Path extends string>(
226919
+ path: Path,
226920
+ ): NegatedInteractivityDirectivePath<Path>;
226921
+ }
226922
+
226923
+ export interface TypedInteractivityStore<
226924
+ Namespace extends string,
226925
+ State extends InteractivityStateShape,
226926
+ Context extends InteractivityContextShape,
226927
+ Actions extends InteractivityActionShape,
226928
+ Callbacks extends InteractivityCallbackShape,
226929
+ > {
226930
+ readonly namespace: Namespace;
226931
+ readonly state: State;
226932
+ readonly context: Context;
226933
+ readonly actions: Actions;
226934
+ readonly callbacks: Callbacks;
226935
+ readonly directive: TypedInteractivityDirectiveHelpers<
226936
+ State,
226937
+ Context,
226938
+ Actions,
226939
+ Callbacks,
226940
+ Namespace
226941
+ >;
226942
+ createContext(value: Context): Context;
226943
+ }
226944
+
226945
+ export function defineInteractivityStore<
226946
+ Namespace extends string,
226947
+ State extends InteractivityStateShape,
226948
+ Context extends InteractivityContextShape,
226949
+ Actions extends InteractivityActionShape,
226950
+ Callbacks extends InteractivityCallbackShape,
226951
+ >(config: {
226952
+ readonly namespace: Namespace;
226953
+ readonly state: State;
226954
+ readonly context: Context;
226955
+ readonly actions: Actions;
226956
+ readonly callbacks: Callbacks;
226957
+ }): TypedInteractivityStore<Namespace, State, Context, Actions, Callbacks> {
226958
+ return {
226959
+ namespace: config.namespace,
226960
+ state: config.state,
226961
+ context: config.context,
226962
+ actions: config.actions,
226963
+ callbacks: config.callbacks,
226964
+ directive: {
226965
+ interactive: config.namespace,
226966
+ action<Key extends InteractivityMethodKey<Actions>>(key: Key) {
226967
+ return \`actions.\${key}\` as InteractivityDirectivePath<'actions', Key>;
226968
+ },
226969
+ callback<Key extends InteractivityMethodKey<Callbacks>>(key: Key) {
226970
+ return \`callbacks.\${key}\` as InteractivityDirectivePath<'callbacks', Key>;
226971
+ },
226972
+ state<Key extends InteractivityKey<State>>(key: Key) {
226973
+ return \`state.\${key}\` as InteractivityDirectivePath<'state', Key>;
226974
+ },
226975
+ context<Key extends InteractivityKey<Context>>(key: Key) {
226976
+ return \`context.\${key}\` as InteractivityDirectivePath<'context', Key>;
226977
+ },
226978
+ negate<Path extends string>(path: Path) {
226979
+ return \`!\${path}\` as NegatedInteractivityDirectivePath<Path>;
226980
+ },
226981
+ },
226982
+ createContext(value) {
226983
+ return value;
226984
+ },
226985
+ };
226986
+ }
226987
+
226988
+ type InteractivityActionHandler = CallableFunction;
226989
+
226990
+ export interface {{pascalCase}}StoreActions {
226991
+ handleClick: InteractivityActionHandler;
226992
+ handleMouseEnter: InteractivityActionHandler;
226993
+ handleMouseLeave: InteractivityActionHandler;
226994
+ reset: InteractivityActionHandler;
226995
+ }
226996
+
226997
+ export interface {{pascalCase}}StoreCallbacks {}
226998
+
226999
+ export const {{slugCamelCase}}Store = defineInteractivityStore({
227000
+ namespace: '{{slugKebabCase}}',
227001
+ state: {} as {{pascalCase}}State,
227002
+ context: {} as {{pascalCase}}Context,
227003
+ actions: {} as {{pascalCase}}StoreActions,
227004
+ callbacks: {} as {{pascalCase}}StoreCallbacks,
227005
+ });
226845
227006
  `, INTERACTIVITY_SCRIPT_TEMPLATE = `/**
226846
227007
  * WordPress Interactivity API implementation for {{title}} block
226847
227008
  */
226848
227009
  import { store, getContext, getElement, withSyncEvent } from '@wordpress/interactivity';
226849
- import type { {{pascalCase}}Context } from './types';
227010
+ import {
227011
+ {{slugCamelCase}}Store,
227012
+ type {{pascalCase}}StoreActions,
227013
+ } from './interactivity-store';
227014
+ import type { {{pascalCase}}Context, {{pascalCase}}State } from './types';
226850
227015
 
226851
227016
  function getBlockContext() {
226852
227017
  return getContext<{{pascalCase}}Context>();
226853
227018
  }
226854
227019
 
226855
- // Store configuration
226856
- store('{{slugKebabCase}}', {
226857
- // State - reactive data that updates the UI
226858
- state: {
227020
+ const actions: {{pascalCase}}StoreActions = {
227021
+ // Handle block click
227022
+ handleClick: () => {
227023
+ const context = getBlockContext();
227024
+ const { ref } = getElement();
227025
+
227026
+ if (!ref) {
227027
+ return;
227028
+ }
227029
+
227030
+ if (context.maxClicks > 0 && context.clicks >= context.maxClicks) {
227031
+ return;
227032
+ }
227033
+
227034
+ const previousClicks = context.clicks;
227035
+
227036
+ // Increment click counter
227037
+ context.clicks += 1;
227038
+
227039
+ // Trigger animation
227040
+ if (context.animation !== 'none') {
227041
+ context.isAnimating = true;
227042
+ setTimeout(() => {
227043
+ context.isAnimating = false;
227044
+ }, 1000);
227045
+ }
227046
+
227047
+ // Emit custom event
227048
+ ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:click', {
227049
+ detail: { clicks: context.clicks }
227050
+ }));
227051
+
227052
+ // Check if max clicks reached
227053
+ if (context.maxClicks > 0 && previousClicks < context.maxClicks && context.clicks === context.maxClicks) {
227054
+ ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:complete', {
227055
+ detail: { totalClicks: context.clicks }
227056
+ }));
227057
+ }
227058
+ },
227059
+
227060
+ // Handle hover events
227061
+ handleMouseEnter: () => {
227062
+ const context = getBlockContext();
227063
+ if (context.animation === 'none') return;
227064
+ context.isAnimating = true;
227065
+ },
227066
+
227067
+ handleMouseLeave: () => {
227068
+ const context = getBlockContext();
227069
+ if (context.animation === 'none') return;
227070
+ context.isAnimating = false;
227071
+ },
227072
+
227073
+ // Reset counter
227074
+ reset: withSyncEvent((event: Event) => {
227075
+ event.stopPropagation();
227076
+ const context = getBlockContext();
227077
+ context.clicks = 0;
227078
+ context.isAnimating = false;
227079
+ })
227080
+ };
227081
+
227082
+ const state = {
226859
227083
  get clicks() {
226860
227084
  return getBlockContext().clicks;
226861
227085
  },
@@ -226883,70 +227107,14 @@ store('{{slugKebabCase}}', {
226883
227107
  const context = getBlockContext();
226884
227108
  return context.clicks >= context.maxClicks && context.maxClicks > 0;
226885
227109
  }
226886
- },
226887
-
226888
- // Actions - user interactions
226889
- actions: {
226890
- // Handle block click
226891
- handleClick: () => {
226892
- const context = getBlockContext();
226893
- const { ref } = getElement();
226894
-
226895
- if (!ref) {
226896
- return;
226897
- }
226898
-
226899
- if (context.maxClicks > 0 && context.clicks >= context.maxClicks) {
226900
- return;
226901
- }
227110
+ } satisfies {{pascalCase}}State;
226902
227111
 
226903
- const previousClicks = context.clicks;
226904
-
226905
- // Increment click counter
226906
- context.clicks += 1;
226907
-
226908
- // Trigger animation
226909
- if (context.animation !== 'none') {
226910
- context.isAnimating = true;
226911
- setTimeout(() => {
226912
- context.isAnimating = false;
226913
- }, 1000);
226914
- }
226915
-
226916
- // Emit custom event
226917
- ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:click', {
226918
- detail: { clicks: context.clicks }
226919
- }));
226920
-
226921
- // Check if max clicks reached
226922
- if (context.maxClicks > 0 && previousClicks < context.maxClicks && context.clicks === context.maxClicks) {
226923
- ref.dispatchEvent(new CustomEvent('{{slugKebabCase}}:complete', {
226924
- detail: { totalClicks: context.clicks }
226925
- }));
226926
- }
226927
- },
226928
-
226929
- // Handle hover events
226930
- handleMouseEnter: () => {
226931
- const context = getBlockContext();
226932
- if (context.animation === 'none') return;
226933
- context.isAnimating = true;
226934
- },
226935
-
226936
- handleMouseLeave: () => {
226937
- const context = getBlockContext();
226938
- if (context.animation === 'none') return;
226939
- context.isAnimating = false;
226940
- },
226941
-
226942
- // Reset counter
226943
- reset: withSyncEvent((event: Event) => {
226944
- event.stopPropagation();
226945
- const context = getBlockContext();
226946
- context.clicks = 0;
226947
- context.isAnimating = false;
226948
- })
226949
- }
227112
+ // Store configuration
227113
+ store({{slugCamelCase}}Store.namespace, {
227114
+ // State - reactive data that updates the UI
227115
+ state,
227116
+ actions,
227117
+ callbacks: {{slugCamelCase}}Store.callbacks,
226950
227118
  });
226951
227119
  `, INTERACTIVITY_VALIDATORS_TEMPLATE = `import typia from 'typia';
226952
227120
  import currentManifest from "./manifest-defaults-document";
@@ -228757,6 +228925,10 @@ function buildInteractivityCodeArtifacts(variables) {
228757
228925
  relativePath: "src/interactivity.ts",
228758
228926
  template: INTERACTIVITY_SCRIPT_TEMPLATE
228759
228927
  },
228928
+ {
228929
+ relativePath: "src/interactivity-store.ts",
228930
+ template: INTERACTIVITY_STORE_TEMPLATE
228931
+ },
228760
228932
  {
228761
228933
  relativePath: "src/validators.ts",
228762
228934
  template: INTERACTIVITY_VALIDATORS_TEMPLATE
@@ -230133,6 +230305,8 @@ async function resolveOptionalInteractiveExternalLayerId({
230133
230305
  callerCwd,
230134
230306
  externalLayerId,
230135
230307
  externalLayerSource,
230308
+ listExternalTemplateLayers = listSelectableExternalTemplateLayers,
230309
+ resolveExternalTemplateSeed = resolveTemplateSeed,
230136
230310
  selectExternalLayerId
230137
230311
  }) {
230138
230312
  if (!externalLayerSource || externalLayerId || !selectExternalLayerId) {
@@ -230141,9 +230315,9 @@ async function resolveOptionalInteractiveExternalLayerId({
230141
230315
  externalLayerSource
230142
230316
  };
230143
230317
  }
230144
- const layerSeed = await resolveTemplateSeed(parseTemplateLocator(externalLayerSource), callerCwd);
230318
+ const layerSeed = await resolveExternalTemplateSeed(parseTemplateLocator(externalLayerSource), callerCwd);
230145
230319
  try {
230146
- const selectableLayers = await listSelectableExternalTemplateLayers(layerSeed.rootDir);
230320
+ const selectableLayers = await listExternalTemplateLayers(layerSeed.rootDir);
230147
230321
  if (selectableLayers.length <= 1) {
230148
230322
  await layerSeed.cleanup?.();
230149
230323
  return {
@@ -230159,7 +230333,6 @@ async function resolveOptionalInteractiveExternalLayerId({
230159
230333
  externalLayerSource: layerSeed.rootDir
230160
230334
  };
230161
230335
  }
230162
- await layerSeed.cleanup?.();
230163
230336
  throw new Error(`Unknown external layer "${selectedLayerId}". Expected one of: ${selectableLayers.map((layer) => layer.id).join(", ")}`);
230164
230337
  } catch (error48) {
230165
230338
  await layerSeed.cleanup?.();
@@ -230545,70 +230718,98 @@ var init_cli_add_block = __esm(() => {
230545
230718
  WORKSPACE_INSTALL_MARKERS = ["node_modules", ".pnp.cjs", ".pnp.loader.mjs"];
230546
230719
  });
230547
230720
 
230548
- // ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view.ts
230549
- import fs42 from "fs";
230550
- import { promises as fsp18 } from "fs";
230551
- import { createRequire as createRequire4 } from "module";
230552
- import path51 from "path";
230553
- function toCamelCase(input) {
230554
- const pascalCase = toPascalCase(input);
230555
- return `${pascalCase.charAt(0).toLowerCase()}${pascalCase.slice(1)}`;
230721
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-types.ts
230722
+ function isAdminViewCoreDataSource(source) {
230723
+ return source?.kind === ADMIN_VIEW_CORE_DATA_SOURCE_KIND;
230556
230724
  }
230557
- function normalizeVersionRange2(value2, fallback) {
230558
- const trimmed = value2?.trim();
230559
- if (!trimmed || trimmed.startsWith("workspace:")) {
230560
- return fallback;
230725
+ function isAdminViewRestResourceSource(source) {
230726
+ return source?.kind === ADMIN_VIEW_REST_SOURCE_KIND;
230727
+ }
230728
+ function formatAdminViewSourceLocator(source) {
230729
+ if (isAdminViewCoreDataSource(source)) {
230730
+ return `${source.kind}:${source.entityKind}/${source.entityName}`;
230561
230731
  }
230562
- return /^[~^<>=]/u.test(trimmed) ? trimmed : `^${trimmed}`;
230732
+ return `${source.kind}:${source.slug}`;
230563
230733
  }
230564
- function readPackageManifestVersion(packageJsonPath) {
230565
- try {
230566
- const packageJson = JSON.parse(fs42.readFileSync(packageJsonPath, "utf8"));
230567
- return packageJson.version;
230568
- } catch {
230734
+ var ADMIN_VIEW_REST_SOURCE_KIND = "rest-resource", ADMIN_VIEW_CORE_DATA_SOURCE_KIND = "core-data", ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS, ADMIN_VIEW_CORE_DATA_ENTITY_SEGMENT_PATTERN, ADMIN_VIEW_CORE_DATA_ENTITY_NAME_PATTERN, ADMIN_VIEW_SOURCE_USAGE = "wp-typia add admin-view <name> --source <rest-resource:slug|core-data:kind/name>", ADMIN_VIEWS_SCRIPT = "build/admin-views/index.js", ADMIN_VIEWS_ASSET = "build/admin-views/index.asset.php", ADMIN_VIEWS_STYLE = "build/admin-views/style-index.css", ADMIN_VIEWS_STYLE_RTL = "build/admin-views/style-index-rtl.css", ADMIN_VIEWS_PHP_GLOB = "/inc/admin-views/*.php", ADMIN_VIEW_ALLOW_UNPUBLISHED_DATAVIEWS_ENV = "WP_TYPIA_ALLOW_UNPUBLISHED_DATAVIEWS", ADMIN_VIEW_PUBLIC_INSTALLS_ENABLED = false;
230735
+ var init_cli_add_workspace_admin_view_types = __esm(() => {
230736
+ ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS = [
230737
+ "postType",
230738
+ "taxonomy"
230739
+ ];
230740
+ ADMIN_VIEW_CORE_DATA_ENTITY_SEGMENT_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/u;
230741
+ ADMIN_VIEW_CORE_DATA_ENTITY_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/u;
230742
+ });
230743
+
230744
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-source.ts
230745
+ function isAdminViewUnpublishedDataViewsOverrideEnabled() {
230746
+ return process.env[ADMIN_VIEW_ALLOW_UNPUBLISHED_DATAVIEWS_ENV]?.trim() === "1";
230747
+ }
230748
+ function assertAdminViewPackageAvailability() {
230749
+ if (isAdminViewUnpublishedDataViewsOverrideEnabled() || ADMIN_VIEW_PUBLIC_INSTALLS_ENABLED) {
230569
230750
  return;
230570
230751
  }
230752
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, "`wp-typia add admin-view` is temporarily unavailable because `@wp-typia/dataviews` is not published to npm for public installs yet.");
230571
230753
  }
230572
- function detectJsonIndent(source) {
230573
- const indentMatch = /\n([ \t]+)"/u.exec(source);
230574
- return indentMatch?.[1] ?? 2;
230754
+ function assertValidCoreDataEntitySegment(label, value2) {
230755
+ const trimmed = value2.trim();
230756
+ if (!trimmed) {
230757
+ throw new Error(`${label} is required. Use \`${ADMIN_VIEW_SOURCE_USAGE}\`.`);
230758
+ }
230759
+ if (!ADMIN_VIEW_CORE_DATA_ENTITY_SEGMENT_PATTERN.test(trimmed)) {
230760
+ throw new Error(`${label} must start with a letter and contain only letters, numbers, underscores, or hyphens.`);
230761
+ }
230762
+ return trimmed;
230575
230763
  }
230576
- function resolvePackageVersionRange(packageName, fallback, workspacePackageDirName) {
230577
- if (workspacePackageDirName) {
230578
- const workspaceVersion = readPackageManifestVersion(path51.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", workspacePackageDirName, "package.json"));
230579
- if (workspaceVersion) {
230580
- return normalizeVersionRange2(workspaceVersion, fallback);
230581
- }
230764
+ function assertValidCoreDataEntityName(value2) {
230765
+ const normalized = value2.trim();
230766
+ if (!normalized) {
230767
+ throw new Error(`Admin view source entity name is required. Use \`${ADMIN_VIEW_SOURCE_USAGE}\`.`);
230582
230768
  }
230583
- try {
230584
- return normalizeVersionRange2(readPackageManifestVersion(require4.resolve(`${packageName}/package.json`)), fallback);
230585
- } catch {
230586
- return fallback;
230769
+ if (!ADMIN_VIEW_CORE_DATA_ENTITY_NAME_PATTERN.test(normalized)) {
230770
+ throw new Error("Admin view source entity name must start with a lowercase letter or number and contain only lowercase letters, numbers, underscores, or hyphens.");
230587
230771
  }
230772
+ return normalized;
230588
230773
  }
230589
- function getAdminViewRelativeModuleSpecifier(adminViewSlug, workspaceFile) {
230590
- const adminViewDir = `src/admin-views/${adminViewSlug}`;
230591
- const normalizedFile = workspaceFile.replace(/\\/gu, "/");
230592
- const modulePath = normalizedFile.replace(/\.[cm]?[jt]sx?$/u, "");
230593
- const relativeModulePath = path51.posix.relative(adminViewDir, modulePath);
230594
- return relativeModulePath.startsWith(".") ? relativeModulePath : `./${relativeModulePath}`;
230774
+ function assertValidCoreDataEntityKind(value2) {
230775
+ const normalized = assertValidCoreDataEntitySegment("Admin view source entity kind", value2);
230776
+ if (!ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS.includes(normalized)) {
230777
+ throw new Error(`Admin view core-data sources currently support only: ${ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS.join(", ")}.`);
230778
+ }
230779
+ return normalized;
230595
230780
  }
230596
230781
  function parseAdminViewSource(source) {
230597
230782
  const trimmed = source?.trim();
230598
230783
  if (!trimmed) {
230599
230784
  return;
230600
230785
  }
230601
- const [kind, slug, extra] = trimmed.split(":");
230602
- if (kind !== ADMIN_VIEW_SOURCE_KIND || !slug || extra !== undefined) {
230603
- throw new Error("Admin view source must use `rest-resource:<slug>` for now.");
230786
+ const separatorIndex = trimmed.indexOf(":");
230787
+ const kind = separatorIndex === -1 ? trimmed : trimmed.slice(0, separatorIndex);
230788
+ const locator = separatorIndex === -1 ? "" : trimmed.slice(separatorIndex + 1);
230789
+ if (!locator) {
230790
+ throw new Error("Admin view source must use `rest-resource:<slug>` or `core-data:<kind>/<name>`.");
230604
230791
  }
230605
- return {
230606
- kind,
230607
- slug: assertValidGeneratedSlug("Admin view source slug", normalizeBlockSlug(slug), "wp-typia add admin-view <name> --source rest-resource:<slug>")
230608
- };
230792
+ if (kind === ADMIN_VIEW_REST_SOURCE_KIND) {
230793
+ return {
230794
+ kind,
230795
+ slug: assertValidGeneratedSlug("Admin view source slug", locator, ADMIN_VIEW_SOURCE_USAGE)
230796
+ };
230797
+ }
230798
+ if (kind === ADMIN_VIEW_CORE_DATA_SOURCE_KIND) {
230799
+ const [entityKind, entityName, extra] = locator.split("/");
230800
+ if (!entityKind || !entityName || extra !== undefined) {
230801
+ throw new Error("Admin view core-data sources must use `core-data:<kind>/<name>`, for example `core-data:postType/post`.");
230802
+ }
230803
+ return {
230804
+ entityKind: assertValidCoreDataEntityKind(entityKind),
230805
+ entityName: assertValidCoreDataEntityName(entityName),
230806
+ kind
230807
+ };
230808
+ }
230809
+ throw new Error("Admin view source must use `rest-resource:<slug>` or `core-data:<kind>/<name>`.");
230609
230810
  }
230610
230811
  function resolveRestResourceSource(restResources, source) {
230611
- if (!source) {
230812
+ if (!isAdminViewRestResourceSource(source)) {
230612
230813
  return;
230613
230814
  }
230614
230815
  const restResource = restResources.find((entry) => entry.slug === source.slug);
@@ -230620,13 +230821,31 @@ function resolveRestResourceSource(restResources, source) {
230620
230821
  }
230621
230822
  return restResource;
230622
230823
  }
230824
+ function resolveAdminViewCoreDataSource(source) {
230825
+ return isAdminViewCoreDataSource(source) ? source : undefined;
230826
+ }
230827
+ var init_cli_add_workspace_admin_view_source = __esm(() => {
230828
+ init_cli_add_shared();
230829
+ init_cli_diagnostics();
230830
+ init_cli_add_workspace_admin_view_types();
230831
+ });
230832
+
230833
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-templates.ts
230834
+ import path51 from "path";
230835
+ function getAdminViewRelativeModuleSpecifier(adminViewSlug, workspaceFile) {
230836
+ const adminViewDir = `src/admin-views/${adminViewSlug}`;
230837
+ const normalizedFile = workspaceFile.replace(/\\/gu, "/");
230838
+ const modulePath = normalizedFile.replace(/\.[cm]?[jt]sx?$/u, "");
230839
+ const relativeModulePath = path51.posix.relative(adminViewDir, modulePath);
230840
+ return relativeModulePath.startsWith(".") ? relativeModulePath : `./${relativeModulePath}`;
230841
+ }
230623
230842
  function buildAdminViewConfigEntry(adminViewSlug, source) {
230624
230843
  return [
230625
230844
  "\t{",
230626
230845
  ` file: ${quoteTsString(`src/admin-views/${adminViewSlug}/index.tsx`)},`,
230627
230846
  ` phpFile: ${quoteTsString(`inc/admin-views/${adminViewSlug}.php`)},`,
230628
230847
  ` slug: ${quoteTsString(adminViewSlug)},`,
230629
- source ? ` source: ${quoteTsString(`${source.kind}:${source.slug}`)},` : null,
230848
+ source ? ` source: ${quoteTsString(formatAdminViewSourceLocator(source))},` : null,
230630
230849
  "\t},"
230631
230850
  ].filter((line) => typeof line === "string").join(`
230632
230851
  `);
@@ -230639,8 +230858,9 @@ function buildAdminViewRegistrySource(adminViewSlugs) {
230639
230858
  ` : ""}// wp-typia add admin-view entries
230640
230859
  `;
230641
230860
  }
230642
- function buildAdminViewTypesSource(adminViewSlug, restResource) {
230861
+ function buildAdminViewTypesSource(adminViewSlug, restResource, coreDataSource) {
230643
230862
  const pascalName = toPascalCase(adminViewSlug);
230863
+ const coreDataRecordTypeName = `${pascalName}CoreDataRecord`;
230644
230864
  const itemTypeName = `${pascalName}AdminViewItem`;
230645
230865
  const dataSetTypeName = `${pascalName}AdminViewDataSet`;
230646
230866
  if (restResource) {
@@ -230650,6 +230870,74 @@ function buildAdminViewTypesSource(adminViewSlug, restResource) {
230650
230870
 
230651
230871
  export type ${itemTypeName} = ${restPascalName}Record;
230652
230872
 
230873
+ export interface ${dataSetTypeName} {
230874
+ items: ${itemTypeName}[];
230875
+ paginationInfo: {
230876
+ totalItems: number;
230877
+ totalPages: number;
230878
+ };
230879
+ }
230880
+ `;
230881
+ }
230882
+ if (coreDataSource) {
230883
+ if (coreDataSource.entityKind === "taxonomy") {
230884
+ return `export interface ${coreDataRecordTypeName} {
230885
+ count?: number;
230886
+ description?: string;
230887
+ id: number;
230888
+ link?: string;
230889
+ meta?: Record<string, unknown>;
230890
+ name?: string;
230891
+ parent?: number;
230892
+ slug?: string;
230893
+ taxonomy?: string;
230894
+ [key: string]: unknown;
230895
+ }
230896
+
230897
+ export interface ${itemTypeName} {
230898
+ count: number;
230899
+ description: string;
230900
+ id: number;
230901
+ link: string;
230902
+ name: string;
230903
+ parent: number;
230904
+ raw: ${coreDataRecordTypeName};
230905
+ slug: string;
230906
+ taxonomy: string;
230907
+ }
230908
+
230909
+ export interface ${dataSetTypeName} {
230910
+ items: ${itemTypeName}[];
230911
+ paginationInfo: {
230912
+ totalItems: number;
230913
+ totalPages: number;
230914
+ };
230915
+ }
230916
+ `;
230917
+ }
230918
+ return `export interface ${coreDataRecordTypeName} {
230919
+ id: number;
230920
+ date?: string;
230921
+ modified?: string;
230922
+ name?: string;
230923
+ slug?: string;
230924
+ status?: string;
230925
+ title?: string | {
230926
+ raw?: string;
230927
+ rendered?: string;
230928
+ };
230929
+ [key: string]: unknown;
230930
+ }
230931
+
230932
+ export interface ${itemTypeName} {
230933
+ id: number;
230934
+ raw: ${coreDataRecordTypeName};
230935
+ slug: string;
230936
+ status: string;
230937
+ title: string;
230938
+ updatedAt: string;
230939
+ }
230940
+
230653
230941
  export interface ${dataSetTypeName} {
230654
230942
  items: ${itemTypeName}[];
230655
230943
  paginationInfo: {
@@ -230678,22 +230966,74 @@ export interface ${dataSetTypeName} {
230678
230966
  }
230679
230967
  `;
230680
230968
  }
230681
- function buildAdminViewConfigSource(adminViewSlug, textDomain, restResource) {
230969
+ function buildAdminViewConfigSource(adminViewSlug, textDomain, source, restResource) {
230682
230970
  const pascalName = toPascalCase(adminViewSlug);
230683
230971
  const camelName = toCamelCase(adminViewSlug);
230684
230972
  const itemTypeName = `${pascalName}AdminViewItem`;
230685
230973
  const dataViewsName = `${camelName}AdminDataViews`;
230686
- const defaultViewFields = restResource ? "['id']" : "['title', 'status', 'updatedAt']";
230974
+ const isCoreDataSource = isAdminViewCoreDataSource(source);
230975
+ const isTaxonomyCoreDataSource = isAdminViewCoreDataSource(source) && source.entityKind === "taxonomy";
230976
+ const defaultViewFields = restResource ? "['id']" : isTaxonomyCoreDataSource ? "['name', 'slug', 'count']" : isCoreDataSource ? "['title', 'slug', 'status', 'updatedAt']" : "['title', 'status', 'updatedAt']";
230687
230977
  const searchEnabled = restResource ? "false" : "true";
230688
- const titleFieldSource = restResource ? "" : ` titleField: 'title',
230978
+ const titleFieldSource = restResource ? "" : isTaxonomyCoreDataSource ? ` titleField: 'name',
230979
+ ` : ` titleField: 'title',
230689
230980
  `;
230690
- const defaultViewEnhancementsSource = restResource ? "" : ` sort: {
230981
+ const defaultViewEnhancementsSource = restResource ? "" : isTaxonomyCoreDataSource ? ` titleField: 'name',
230982
+ ` : isCoreDataSource ? ` titleField: 'title',
230983
+ ` : ` sort: {
230691
230984
  direction: 'desc',
230692
230985
  field: 'updatedAt',
230693
230986
  },
230694
230987
  titleField: 'title',
230695
230988
  `;
230696
- const additionalFieldsSource = restResource ? "\t\t// REST-backed screens start with the guaranteed ID column. Add project-owned fields here once they are declared on the REST record type." : ` owner: {
230989
+ const additionalFieldsSource = restResource ? "\t\t// REST-backed screens start with the guaranteed ID column. Add project-owned fields here once they are declared on the REST record type." : isTaxonomyCoreDataSource ? ` count: {
230990
+ label: __( 'Count', ${quoteTsString(textDomain)} ),
230991
+ schema: { type: 'integer' },
230992
+ },
230993
+ description: {
230994
+ label: __( 'Description', ${quoteTsString(textDomain)} ),
230995
+ schema: { type: 'string' },
230996
+ },
230997
+ link: {
230998
+ label: __( 'Link', ${quoteTsString(textDomain)} ),
230999
+ schema: { format: 'uri', type: 'string' },
231000
+ },
231001
+ name: {
231002
+ enableGlobalSearch: true,
231003
+ label: __( 'Name', ${quoteTsString(textDomain)} ),
231004
+ schema: { type: 'string' },
231005
+ },
231006
+ parent: {
231007
+ label: __( 'Parent', ${quoteTsString(textDomain)} ),
231008
+ schema: { type: 'integer' },
231009
+ },
231010
+ slug: {
231011
+ enableGlobalSearch: true,
231012
+ label: __( 'Slug', ${quoteTsString(textDomain)} ),
231013
+ schema: { type: 'string' },
231014
+ },
231015
+ taxonomy: {
231016
+ label: __( 'Taxonomy', ${quoteTsString(textDomain)} ),
231017
+ schema: { type: 'string' },
231018
+ },` : isCoreDataSource ? ` slug: {
231019
+ enableGlobalSearch: true,
231020
+ label: __( 'Slug', ${quoteTsString(textDomain)} ),
231021
+ schema: { type: 'string' },
231022
+ },
231023
+ status: {
231024
+ label: __( 'Status', ${quoteTsString(textDomain)} ),
231025
+ schema: { type: 'string' },
231026
+ },
231027
+ title: {
231028
+ enableGlobalSearch: true,
231029
+ label: __( 'Name', ${quoteTsString(textDomain)} ),
231030
+ schema: { type: 'string' },
231031
+ },
231032
+ updatedAt: {
231033
+ label: __( 'Updated', ${quoteTsString(textDomain)} ),
231034
+ schema: { format: 'date-time', type: 'string' },
231035
+ type: 'datetime',
231036
+ },` : ` owner: {
230697
231037
  label: __( 'Owner', ${quoteTsString(textDomain)} ),
230698
231038
  schema: { type: 'string' },
230699
231039
  },
@@ -230880,6 +231220,217 @@ export async function ${fetchName}(
230880
231220
  }
230881
231221
  `;
230882
231222
  }
231223
+ function buildCoreDataAdminViewDataSource(adminViewSlug, coreDataSource) {
231224
+ const pascalName = toPascalCase(adminViewSlug);
231225
+ const camelName = toCamelCase(adminViewSlug);
231226
+ const coreDataRecordTypeName = `${pascalName}CoreDataRecord`;
231227
+ const dataSetTypeName = `${pascalName}AdminViewDataSet`;
231228
+ const itemTypeName = `${pascalName}AdminViewItem`;
231229
+ const queryTypeName = `${pascalName}AdminViewQuery`;
231230
+ const dataViewsName = `${camelName}AdminDataViews`;
231231
+ const useEntityRecordName = `use${pascalName}EntityRecord`;
231232
+ const useEntityRecordsName = `use${pascalName}EntityRecords`;
231233
+ const useAdminViewDataName = `use${pascalName}AdminViewData`;
231234
+ if (coreDataSource.entityKind === "taxonomy") {
231235
+ return `import type { DataViewsView } from '@wp-typia/dataviews';
231236
+ import { useEntityRecord, useEntityRecords } from '@wordpress/core-data';
231237
+ import { useMemo } from '@wordpress/element';
231238
+
231239
+ import { ${dataViewsName} } from './config';
231240
+ import type {
231241
+ ${coreDataRecordTypeName},
231242
+ ${dataSetTypeName},
231243
+ ${itemTypeName},
231244
+ } from './types';
231245
+
231246
+ export interface ${queryTypeName} {
231247
+ page?: number;
231248
+ per_page?: number;
231249
+ search?: string;
231250
+ }
231251
+
231252
+ const CORE_DATA_ENTITY_KIND = ${quoteTsString(coreDataSource.entityKind)};
231253
+ const CORE_DATA_ENTITY_NAME = ${quoteTsString(coreDataSource.entityName)};
231254
+
231255
+ function normalizeCoreDataNumber(value: unknown): number {
231256
+ return typeof value === 'number' && Number.isFinite(value) ? value : 0;
231257
+ }
231258
+
231259
+ function normalizeCoreDataString(value: unknown): string {
231260
+ return typeof value === 'string' ? value : '';
231261
+ }
231262
+
231263
+ function normalizeTaxonomyRecord(record: ${coreDataRecordTypeName}): ${itemTypeName} {
231264
+ return {
231265
+ count: normalizeCoreDataNumber(record.count),
231266
+ description: normalizeCoreDataString(record.description),
231267
+ id: record.id,
231268
+ link: normalizeCoreDataString(record.link),
231269
+ name: normalizeCoreDataString(record.name) || normalizeCoreDataString(record.slug),
231270
+ parent: normalizeCoreDataNumber(record.parent),
231271
+ raw: record,
231272
+ slug: normalizeCoreDataString(record.slug),
231273
+ taxonomy: normalizeCoreDataString(record.taxonomy),
231274
+ };
231275
+ }
231276
+
231277
+ export function ${useEntityRecordName}(recordId: number | undefined) {
231278
+ return useEntityRecord<${coreDataRecordTypeName}>(
231279
+ CORE_DATA_ENTITY_KIND,
231280
+ CORE_DATA_ENTITY_NAME,
231281
+ recordId ?? 0,
231282
+ { enabled: typeof recordId === 'number' },
231283
+ );
231284
+ }
231285
+
231286
+ export function ${useEntityRecordsName}(view: DataViewsView<${itemTypeName}>) {
231287
+ const query = ${dataViewsName}.toQueryArgs<${queryTypeName}>(view, {
231288
+ perPageParam: 'per_page',
231289
+ });
231290
+
231291
+ return useEntityRecords<${coreDataRecordTypeName}>(
231292
+ CORE_DATA_ENTITY_KIND,
231293
+ CORE_DATA_ENTITY_NAME,
231294
+ query,
231295
+ );
231296
+ }
231297
+
231298
+ export function ${useAdminViewDataName}(view: DataViewsView<${itemTypeName}>) {
231299
+ const { hasResolved, isResolving, records, totalItems, totalPages } =
231300
+ ${useEntityRecordsName}(view);
231301
+ const items = useMemo(
231302
+ () => (records ?? []).map((record) => normalizeTaxonomyRecord(record)),
231303
+ [records],
231304
+ );
231305
+ const dataSet = useMemo<${dataSetTypeName}>(
231306
+ () => ({
231307
+ items,
231308
+ paginationInfo: {
231309
+ totalItems: totalItems ?? items.length,
231310
+ totalPages: Math.max(1, totalPages ?? 1),
231311
+ },
231312
+ }),
231313
+ [items, totalItems, totalPages],
231314
+ );
231315
+ const error =
231316
+ !isResolving && hasResolved && records === null
231317
+ ? 'Unable to load core-data entity records.'
231318
+ : null;
231319
+
231320
+ return {
231321
+ dataSet,
231322
+ error,
231323
+ isLoading: isResolving,
231324
+ };
231325
+ }
231326
+ `;
231327
+ }
231328
+ return `import type { DataViewsView } from '@wp-typia/dataviews';
231329
+ import { useEntityRecord, useEntityRecords } from '@wordpress/core-data';
231330
+ import { useMemo } from '@wordpress/element';
231331
+
231332
+ import { ${dataViewsName} } from './config';
231333
+ import type {
231334
+ ${coreDataRecordTypeName},
231335
+ ${dataSetTypeName},
231336
+ ${itemTypeName},
231337
+ } from './types';
231338
+
231339
+ export interface ${queryTypeName} {
231340
+ page?: number;
231341
+ per_page?: number;
231342
+ search?: string;
231343
+ }
231344
+
231345
+ const CORE_DATA_ENTITY_KIND = ${quoteTsString(coreDataSource.entityKind)};
231346
+ const CORE_DATA_ENTITY_NAME = ${quoteTsString(coreDataSource.entityName)};
231347
+
231348
+ function normalizeCoreDataString(value: unknown): string {
231349
+ return typeof value === 'string' ? value : '';
231350
+ }
231351
+
231352
+ function normalizeCoreDataTitle(record: ${coreDataRecordTypeName}): string {
231353
+ if (typeof record.title === 'string') {
231354
+ return record.title;
231355
+ }
231356
+ if (record.title && typeof record.title === 'object') {
231357
+ if (typeof record.title.rendered === 'string') {
231358
+ return record.title.rendered;
231359
+ }
231360
+ if (typeof record.title.raw === 'string') {
231361
+ return record.title.raw;
231362
+ }
231363
+ }
231364
+
231365
+ return normalizeCoreDataString(record.name) || normalizeCoreDataString(record.slug);
231366
+ }
231367
+
231368
+ function normalizeCoreDataUpdatedAt(record: ${coreDataRecordTypeName}): string {
231369
+ return normalizeCoreDataString(record.modified) || normalizeCoreDataString(record.date);
231370
+ }
231371
+
231372
+ function normalizeCoreDataRecord(record: ${coreDataRecordTypeName}): ${itemTypeName} {
231373
+ return {
231374
+ id: record.id,
231375
+ raw: record,
231376
+ slug: normalizeCoreDataString(record.slug),
231377
+ status: normalizeCoreDataString(record.status),
231378
+ title: normalizeCoreDataTitle(record),
231379
+ updatedAt: normalizeCoreDataUpdatedAt(record),
231380
+ };
231381
+ }
231382
+
231383
+ export function ${useEntityRecordName}(recordId: number | undefined) {
231384
+ return useEntityRecord<${coreDataRecordTypeName}>(
231385
+ CORE_DATA_ENTITY_KIND,
231386
+ CORE_DATA_ENTITY_NAME,
231387
+ recordId ?? 0,
231388
+ { enabled: typeof recordId === 'number' },
231389
+ );
231390
+ }
231391
+
231392
+ export function ${useEntityRecordsName}(view: DataViewsView<${itemTypeName}>) {
231393
+ const query = ${dataViewsName}.toQueryArgs<${queryTypeName}>(view, {
231394
+ perPageParam: 'per_page',
231395
+ });
231396
+
231397
+ return useEntityRecords<${coreDataRecordTypeName}>(
231398
+ CORE_DATA_ENTITY_KIND,
231399
+ CORE_DATA_ENTITY_NAME,
231400
+ query,
231401
+ );
231402
+ }
231403
+
231404
+ export function ${useAdminViewDataName}(view: DataViewsView<${itemTypeName}>) {
231405
+ const { hasResolved, isResolving, records, totalItems, totalPages } =
231406
+ ${useEntityRecordsName}(view);
231407
+ const items = useMemo(
231408
+ () => (records ?? []).map((record) => normalizeCoreDataRecord(record)),
231409
+ [records],
231410
+ );
231411
+ const dataSet = useMemo<${dataSetTypeName}>(
231412
+ () => ({
231413
+ items,
231414
+ paginationInfo: {
231415
+ totalItems: totalItems ?? items.length,
231416
+ totalPages: Math.max(1, totalPages ?? 1),
231417
+ },
231418
+ }),
231419
+ [items, totalItems, totalPages],
231420
+ );
231421
+ const error =
231422
+ !isResolving && hasResolved && records === null
231423
+ ? 'Unable to load core-data entity records.'
231424
+ : null;
231425
+
231426
+ return {
231427
+ dataSet,
231428
+ error,
231429
+ isLoading: isResolving,
231430
+ };
231431
+ }
231432
+ `;
231433
+ }
230883
231434
  function buildAdminViewScreenSource(adminViewSlug, textDomain) {
230884
231435
  const pascalName = toPascalCase(adminViewSlug);
230885
231436
  const camelName = toCamelCase(adminViewSlug);
@@ -230993,6 +231544,81 @@ export function ${componentName}() {
230993
231544
  }
230994
231545
  `;
230995
231546
  }
231547
+ function buildCoreDataAdminViewScreenSource(adminViewSlug, textDomain) {
231548
+ const pascalName = toPascalCase(adminViewSlug);
231549
+ const camelName = toCamelCase(adminViewSlug);
231550
+ const itemTypeName = `${pascalName}AdminViewItem`;
231551
+ const dataSetTypeName = `${pascalName}AdminViewDataSet`;
231552
+ const componentName = `${pascalName}AdminViewScreen`;
231553
+ const dataViewsName = `${camelName}AdminDataViews`;
231554
+ const useAdminViewDataName = `use${pascalName}AdminViewData`;
231555
+ const title = toTitleCase(adminViewSlug);
231556
+ return `import type { DataViewsConfig, DataViewsView } from '@wp-typia/dataviews';
231557
+ import { Notice, Spinner } from '@wordpress/components';
231558
+ import { useState } from '@wordpress/element';
231559
+ import { __ } from '@wordpress/i18n';
231560
+ import { DataViews } from '@wordpress/dataviews/wp';
231561
+
231562
+ import { ${dataViewsName} } from './config';
231563
+ import { ${useAdminViewDataName} } from './data';
231564
+ import type { ${dataSetTypeName}, ${itemTypeName} } from './types';
231565
+
231566
+ const TypedDataViews = DataViews as unknown as <TItem extends object>(
231567
+ props: DataViewsConfig<TItem>,
231568
+ ) => ReturnType<typeof DataViews>;
231569
+
231570
+ const EMPTY_DATA_SET: ${dataSetTypeName} = {
231571
+ items: [],
231572
+ paginationInfo: {
231573
+ totalItems: 0,
231574
+ totalPages: 1,
231575
+ },
231576
+ };
231577
+
231578
+ export function ${componentName}() {
231579
+ const [view, setView] = useState<DataViewsView<${itemTypeName}>>(
231580
+ ${dataViewsName}.defaultView,
231581
+ );
231582
+ const {
231583
+ dataSet = EMPTY_DATA_SET,
231584
+ error,
231585
+ isLoading,
231586
+ } = ${useAdminViewDataName}(view);
231587
+ const config = ${dataViewsName}.createConfig({
231588
+ data: dataSet.items,
231589
+ isLoading,
231590
+ onChangeView: setView,
231591
+ paginationInfo: dataSet.paginationInfo,
231592
+ view,
231593
+ });
231594
+
231595
+ return (
231596
+ <div className="wp-typia-admin-view-screen">
231597
+ <header className="wp-typia-admin-view-screen__header">
231598
+ <div>
231599
+ <p className="wp-typia-admin-view-screen__eyebrow">
231600
+ { __( 'DataViews admin screen', ${quoteTsString(textDomain)} ) }
231601
+ </p>
231602
+ <h1>{ __( ${quoteTsString(title)}, ${quoteTsString(textDomain)} ) }</h1>
231603
+ <p>
231604
+ { __( 'This screen reads from the WordPress core-data entity store. Extend data.ts when you need entity-specific field mapping or edit flows.', ${quoteTsString(textDomain)} ) }
231605
+ </p>
231606
+ </div>
231607
+ <div className="wp-typia-admin-view-screen__actions">
231608
+ { isLoading ? <Spinner /> : null }
231609
+ </div>
231610
+ </header>
231611
+ { error ? (
231612
+ <Notice isDismissible={ false } status="error">
231613
+ { error }
231614
+ </Notice>
231615
+ ) : null }
231616
+ <TypedDataViews<${itemTypeName}> { ...config } />
231617
+ </div>
231618
+ );
231619
+ }
231620
+ `;
231621
+ }
230996
231622
  function buildAdminViewEntrySource(adminViewSlug) {
230997
231623
  const pascalName = toPascalCase(adminViewSlug);
230998
231624
  const componentName = `${pascalName}AdminViewScreen`;
@@ -231162,15 +231788,48 @@ add_action( 'admin_menu', '${registerFunctionName}' );
231162
231788
  add_action( 'admin_enqueue_scripts', '${enqueueFunctionName}' );
231163
231789
  `;
231164
231790
  }
231165
- async function ensureAdminViewPackageDependencies(workspace) {
231166
- const packageJsonPath = path51.join(workspace.projectDir, "package.json");
231167
- const wpTypiaDataViewsVersion = resolvePackageVersionRange("@wp-typia/dataviews", DEFAULT_WP_TYPIA_DATAVIEWS_VERSION, "wp-typia-dataviews");
231168
- const wordpressDataViewsVersion = resolvePackageVersionRange("@wordpress/dataviews", DEFAULT_WORDPRESS_DATAVIEWS_VERSION);
231791
+ var init_cli_add_workspace_admin_view_templates = __esm(() => {
231792
+ init_cli_add_shared();
231793
+ init_cli_add_workspace_admin_view_types();
231794
+ });
231795
+
231796
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-scaffold.ts
231797
+ import fs42 from "fs";
231798
+ import { promises as fsp18 } from "fs";
231799
+ import path52 from "path";
231800
+ function detectJsonIndent(source) {
231801
+ const indentMatch = /\n([ \t]+)"/u.exec(source);
231802
+ return indentMatch?.[1] ?? 2;
231803
+ }
231804
+ async function ensureAdminViewPackageDependencies(workspace, adminViewSource) {
231805
+ const packageJsonPath = path52.join(workspace.projectDir, "package.json");
231806
+ const wpTypiaDataViewsVersion = resolveManagedPackageVersionRange({
231807
+ fallback: DEFAULT_WP_TYPIA_DATAVIEWS_VERSION,
231808
+ packageName: "@wp-typia/dataviews",
231809
+ workspacePackageDirName: "wp-typia-dataviews"
231810
+ });
231811
+ const wordpressDataViewsVersion = resolveManagedPackageVersionRange({
231812
+ fallback: DEFAULT_WORDPRESS_DATAVIEWS_VERSION,
231813
+ packageName: "@wordpress/dataviews"
231814
+ });
231815
+ const wordpressCoreDataVersion = resolveManagedPackageVersionRange({
231816
+ fallback: DEFAULT_WORDPRESS_CORE_DATA_VERSION,
231817
+ packageName: "@wordpress/core-data"
231818
+ });
231819
+ const wordpressDataVersion = resolveManagedPackageVersionRange({
231820
+ fallback: DEFAULT_WORDPRESS_DATA_VERSION,
231821
+ packageName: "@wordpress/data"
231822
+ });
231169
231823
  await patchFile(packageJsonPath, (source) => {
231170
231824
  const packageJson = JSON.parse(source);
231825
+ const coreDataDependencies = isAdminViewCoreDataSource(adminViewSource) ? {
231826
+ "@wordpress/core-data": packageJson.dependencies?.["@wordpress/core-data"] ?? wordpressCoreDataVersion,
231827
+ "@wordpress/data": packageJson.dependencies?.["@wordpress/data"] ?? wordpressDataVersion
231828
+ } : {};
231171
231829
  const nextDependencies = {
231172
231830
  ...packageJson.dependencies ?? {},
231173
- "@wordpress/dataviews": packageJson.dependencies?.["@wordpress/dataviews"] ?? wordpressDataViewsVersion
231831
+ "@wordpress/dataviews": packageJson.dependencies?.["@wordpress/dataviews"] ?? wordpressDataViewsVersion,
231832
+ ...coreDataDependencies
231174
231833
  };
231175
231834
  const nextDevDependencies = {
231176
231835
  ...packageJson.devDependencies ?? {},
@@ -231191,6 +231850,7 @@ async function ensureAdminViewBootstrapAnchors(workspace) {
231191
231850
  let nextSource = source;
231192
231851
  const loadFunctionName = `${workspace.workspace.phpPrefix}_load_admin_views`;
231193
231852
  const loadHook = `add_action( 'plugins_loaded', '${loadFunctionName}' );`;
231853
+ const loadHookPattern = new RegExp(`add_action\\(\\s*['"]plugins_loaded['"]\\s*,\\s*['"]${loadFunctionName}['"]\\s*\\)\\s*;`, "u");
231194
231854
  const loadFunction = `
231195
231855
 
231196
231856
  function ${loadFunctionName}() {
@@ -231235,19 +231895,19 @@ ${snippet}
231235
231895
  if (!functionSource.includes(ADMIN_VIEWS_PHP_GLOB)) {
231236
231896
  const replacedSource = replacePhpFunctionDefinition(nextSource, loadFunctionName, loadFunction);
231237
231897
  if (!replacedSource) {
231238
- throw new Error(`Unable to repair ${path51.basename(bootstrapPath)} for ${loadFunctionName}.`);
231898
+ throw new Error(`Unable to repair ${path52.basename(bootstrapPath)} for ${loadFunctionName}.`);
231239
231899
  }
231240
231900
  nextSource = replacedSource;
231241
231901
  }
231242
231902
  }
231243
- if (!nextSource.includes(loadHook)) {
231903
+ if (!loadHookPattern.test(nextSource)) {
231244
231904
  appendPhpSnippet(loadHook);
231245
231905
  }
231246
231906
  return nextSource;
231247
231907
  });
231248
231908
  }
231249
231909
  async function ensureAdminViewBuildScriptAnchors(workspace) {
231250
- const buildScriptPath = path51.join(workspace.projectDir, "scripts", "build-workspace.mjs");
231910
+ const buildScriptPath = path52.join(workspace.projectDir, "scripts", "build-workspace.mjs");
231251
231911
  await patchFile(buildScriptPath, (source) => {
231252
231912
  if (/['"]src\/admin-views\/index\.(?:ts|js)['"]/u.test(source)) {
231253
231913
  return source;
@@ -231271,11 +231931,11 @@ async function ensureAdminViewBuildScriptAnchors(workspace) {
231271
231931
  if (nextSource !== source) {
231272
231932
  return nextSource;
231273
231933
  }
231274
- throw new Error(`Unable to update ${path51.relative(workspace.projectDir, buildScriptPath)} for admin view shared entries.`);
231934
+ throw new Error(`Unable to update ${path52.relative(workspace.projectDir, buildScriptPath)} for admin view shared entries.`);
231275
231935
  });
231276
231936
  }
231277
231937
  async function ensureAdminViewWebpackAnchors(workspace) {
231278
- const webpackConfigPath = path51.join(workspace.projectDir, "webpack.config.js");
231938
+ const webpackConfigPath = path52.join(workspace.projectDir, "webpack.config.js");
231279
231939
  await patchFile(webpackConfigPath, (source) => {
231280
231940
  if (/['"]admin-views\/index['"]/u.test(source)) {
231281
231941
  return source;
@@ -231316,17 +231976,17 @@ async function ensureAdminViewWebpackAnchors(workspace) {
231316
231976
  }`;
231317
231977
  nextSource = source.replace(legacySharedEntriesBlockPattern, nextSharedEntriesBlock);
231318
231978
  if (nextSource === source) {
231319
- throw new Error(`Unable to update ${path51.relative(workspace.projectDir, webpackConfigPath)} for admin view shared entries.`);
231979
+ throw new Error(`Unable to update ${path52.relative(workspace.projectDir, webpackConfigPath)} for admin view shared entries.`);
231320
231980
  }
231321
231981
  return nextSource;
231322
231982
  });
231323
231983
  }
231324
231984
  function resolveAdminViewRegistryPath(projectDir) {
231325
- const adminViewsDir = path51.join(projectDir, "src", "admin-views");
231985
+ const adminViewsDir = path52.join(projectDir, "src", "admin-views");
231326
231986
  return [
231327
- path51.join(adminViewsDir, "index.ts"),
231328
- path51.join(adminViewsDir, "index.js")
231329
- ].find((candidatePath) => fs42.existsSync(candidatePath)) ?? path51.join(adminViewsDir, "index.ts");
231987
+ path52.join(adminViewsDir, "index.ts"),
231988
+ path52.join(adminViewsDir, "index.js")
231989
+ ].find((candidatePath) => fs42.existsSync(candidatePath)) ?? path52.join(adminViewsDir, "index.ts");
231330
231990
  }
231331
231991
  function readAdminViewRegistrySlugs(registryPath) {
231332
231992
  if (!fs42.existsSync(registryPath)) {
@@ -231336,33 +231996,34 @@ function readAdminViewRegistrySlugs(registryPath) {
231336
231996
  return Array.from(source.matchAll(/^\s*import\s+['"]\.\/([^/'"]+)(?:\/index(?:\.[cm]?[jt]sx?)?)?['"];?\s*$/gmu)).map((match3) => match3[1]);
231337
231997
  }
231338
231998
  async function writeAdminViewRegistry(projectDir, adminViewSlug) {
231339
- const adminViewsDir = path51.join(projectDir, "src", "admin-views");
231999
+ const adminViewsDir = path52.join(projectDir, "src", "admin-views");
231340
232000
  const registryPath = resolveAdminViewRegistryPath(projectDir);
231341
232001
  await fsp18.mkdir(adminViewsDir, { recursive: true });
231342
232002
  const existingAdminViewSlugs = readWorkspaceInventory(projectDir).adminViews.map((entry) => entry.slug);
231343
232003
  const existingRegistrySlugs = readAdminViewRegistrySlugs(registryPath);
231344
- const nextAdminViewSlugs = Array.from(new Set([...existingAdminViewSlugs, ...existingRegistrySlugs, adminViewSlug])).sort();
232004
+ const nextAdminViewSlugs = Array.from(new Set([
232005
+ ...existingAdminViewSlugs,
232006
+ ...existingRegistrySlugs,
232007
+ adminViewSlug
232008
+ ])).sort();
231345
232009
  await fsp18.writeFile(registryPath, buildAdminViewRegistrySource(nextAdminViewSlugs), "utf8");
231346
232010
  }
231347
- async function runAddAdminViewCommand({
231348
- adminViewName,
231349
- cwd = process.cwd(),
231350
- source
231351
- }) {
231352
- const workspace = resolveWorkspaceProject(cwd);
231353
- const adminViewSlug = assertValidGeneratedSlug("Admin view name", normalizeBlockSlug(adminViewName), "wp-typia add admin-view <name> [--source rest-resource:<slug>]");
231354
- const parsedSource = parseAdminViewSource(source);
231355
- const inventory = readWorkspaceInventory(workspace.projectDir);
231356
- const restResource = resolveRestResourceSource(inventory.restResources, parsedSource);
231357
- assertAdminViewDoesNotExist(workspace.projectDir, adminViewSlug, inventory);
231358
- const blockConfigPath = path51.join(workspace.projectDir, "scripts", "block-config.ts");
232011
+ async function scaffoldAdminViewWorkspace(options) {
232012
+ const {
232013
+ adminViewSlug,
232014
+ coreDataSource,
232015
+ parsedSource,
232016
+ restResource,
232017
+ workspace
232018
+ } = options;
232019
+ const blockConfigPath = path52.join(workspace.projectDir, "scripts", "block-config.ts");
231359
232020
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
231360
- const buildScriptPath = path51.join(workspace.projectDir, "scripts", "build-workspace.mjs");
231361
- const packageJsonPath = path51.join(workspace.projectDir, "package.json");
231362
- const webpackConfigPath = path51.join(workspace.projectDir, "webpack.config.js");
232021
+ const buildScriptPath = path52.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232022
+ const packageJsonPath = path52.join(workspace.projectDir, "package.json");
232023
+ const webpackConfigPath = path52.join(workspace.projectDir, "webpack.config.js");
231363
232024
  const adminViewsIndexPath = resolveAdminViewRegistryPath(workspace.projectDir);
231364
- const adminViewDir = path51.join(workspace.projectDir, "src", "admin-views", adminViewSlug);
231365
- const adminViewPhpPath = path51.join(workspace.projectDir, "inc", "admin-views", `${adminViewSlug}.php`);
232025
+ const adminViewDir = path52.join(workspace.projectDir, "src", "admin-views", adminViewSlug);
232026
+ const adminViewPhpPath = path52.join(workspace.projectDir, "inc", "admin-views", `${adminViewSlug}.php`);
231366
232027
  const mutationSnapshot = {
231367
232028
  fileSources: await snapshotWorkspaceFiles([
231368
232029
  adminViewsIndexPath,
@@ -231377,45 +232038,78 @@ async function runAddAdminViewCommand({
231377
232038
  };
231378
232039
  try {
231379
232040
  await fsp18.mkdir(adminViewDir, { recursive: true });
231380
- await fsp18.mkdir(path51.dirname(adminViewPhpPath), { recursive: true });
231381
- await ensureAdminViewPackageDependencies(workspace);
232041
+ await fsp18.mkdir(path52.dirname(adminViewPhpPath), { recursive: true });
232042
+ await ensureAdminViewPackageDependencies(workspace, parsedSource);
231382
232043
  await ensureAdminViewBootstrapAnchors(workspace);
231383
232044
  await ensureAdminViewBuildScriptAnchors(workspace);
231384
232045
  await ensureAdminViewWebpackAnchors(workspace);
231385
- await fsp18.writeFile(path51.join(adminViewDir, "types.ts"), buildAdminViewTypesSource(adminViewSlug, restResource), "utf8");
231386
- await fsp18.writeFile(path51.join(adminViewDir, "config.ts"), buildAdminViewConfigSource(adminViewSlug, workspace.workspace.textDomain, restResource), "utf8");
231387
- await fsp18.writeFile(path51.join(adminViewDir, "data.ts"), restResource ? buildRestAdminViewDataSource(adminViewSlug, restResource) : buildDefaultAdminViewDataSource(adminViewSlug), "utf8");
231388
- await fsp18.writeFile(path51.join(adminViewDir, "Screen.tsx"), buildAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain), "utf8");
231389
- await fsp18.writeFile(path51.join(adminViewDir, "index.tsx"), buildAdminViewEntrySource(adminViewSlug), "utf8");
231390
- await fsp18.writeFile(path51.join(adminViewDir, "style.scss"), buildAdminViewStyleSource(), "utf8");
232046
+ await fsp18.writeFile(path52.join(adminViewDir, "types.ts"), buildAdminViewTypesSource(adminViewSlug, restResource, coreDataSource), "utf8");
232047
+ await fsp18.writeFile(path52.join(adminViewDir, "config.ts"), buildAdminViewConfigSource(adminViewSlug, workspace.workspace.textDomain, parsedSource, restResource), "utf8");
232048
+ await fsp18.writeFile(path52.join(adminViewDir, "data.ts"), coreDataSource ? buildCoreDataAdminViewDataSource(adminViewSlug, coreDataSource) : restResource ? buildRestAdminViewDataSource(adminViewSlug, restResource) : buildDefaultAdminViewDataSource(adminViewSlug), "utf8");
232049
+ await fsp18.writeFile(path52.join(adminViewDir, "Screen.tsx"), coreDataSource ? buildCoreDataAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain) : buildAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain), "utf8");
232050
+ await fsp18.writeFile(path52.join(adminViewDir, "index.tsx"), buildAdminViewEntrySource(adminViewSlug), "utf8");
232051
+ await fsp18.writeFile(path52.join(adminViewDir, "style.scss"), buildAdminViewStyleSource(), "utf8");
231391
232052
  await fsp18.writeFile(adminViewPhpPath, buildAdminViewPhpSource(adminViewSlug, workspace), "utf8");
231392
232053
  await writeAdminViewRegistry(workspace.projectDir, adminViewSlug);
231393
232054
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
231394
- adminViewEntries: [buildAdminViewConfigEntry(adminViewSlug, parsedSource)]
232055
+ adminViewEntries: [
232056
+ buildAdminViewConfigEntry(adminViewSlug, parsedSource)
232057
+ ]
231395
232058
  });
231396
- return {
231397
- adminViewSlug,
231398
- projectDir: workspace.projectDir,
231399
- source: parsedSource ? `${parsedSource.kind}:${parsedSource.slug}` : undefined
231400
- };
231401
232059
  } catch (error48) {
231402
232060
  await rollbackWorkspaceMutation(mutationSnapshot);
231403
232061
  throw error48;
231404
232062
  }
231405
232063
  }
231406
- var ADMIN_VIEW_SOURCE_KIND = "rest-resource", ADMIN_VIEWS_SCRIPT = "build/admin-views/index.js", ADMIN_VIEWS_ASSET = "build/admin-views/index.asset.php", ADMIN_VIEWS_STYLE = "build/admin-views/style-index.css", ADMIN_VIEWS_STYLE_RTL = "build/admin-views/style-index-rtl.css", ADMIN_VIEWS_PHP_GLOB = "/inc/admin-views/*.php", DEFAULT_WP_TYPIA_DATAVIEWS_VERSION = "^0.1.0", DEFAULT_WORDPRESS_DATAVIEWS_VERSION = "^14.1.0", require4;
231407
- var init_cli_add_workspace_admin_view = __esm(() => {
231408
- init_workspace_project();
232064
+ var init_cli_add_workspace_admin_view_scaffold = __esm(() => {
231409
232065
  init_workspace_inventory();
231410
- init_template_registry();
232066
+ init_cli_add_workspace_admin_view_templates();
232067
+ init_cli_add_workspace_admin_view_types();
231411
232068
  init_cli_add_shared();
231412
- require4 = createRequire4(import.meta.url);
232069
+ init_package_versions();
232070
+ });
232071
+
232072
+ // ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view.ts
232073
+ async function runAddAdminViewCommand({
232074
+ adminViewName,
232075
+ cwd = process.cwd(),
232076
+ source
232077
+ }) {
232078
+ const workspace = resolveWorkspaceProject(cwd);
232079
+ assertAdminViewPackageAvailability();
232080
+ const adminViewSlug = assertValidGeneratedSlug("Admin view name", normalizeBlockSlug(adminViewName), ADD_ADMIN_VIEW_USAGE);
232081
+ const parsedSource = parseAdminViewSource(source);
232082
+ const inventory = readWorkspaceInventory(workspace.projectDir);
232083
+ const restResource = resolveRestResourceSource(inventory.restResources, parsedSource);
232084
+ const coreDataSource = resolveAdminViewCoreDataSource(parsedSource);
232085
+ assertAdminViewDoesNotExist(workspace.projectDir, adminViewSlug, inventory);
232086
+ await scaffoldAdminViewWorkspace({
232087
+ adminViewSlug,
232088
+ coreDataSource,
232089
+ parsedSource,
232090
+ restResource,
232091
+ workspace
232092
+ });
232093
+ return {
232094
+ adminViewSlug,
232095
+ projectDir: workspace.projectDir,
232096
+ source: parsedSource ? formatAdminViewSourceLocator(parsedSource) : undefined
232097
+ };
232098
+ }
232099
+ var ADD_ADMIN_VIEW_USAGE = "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>]";
232100
+ var init_cli_add_workspace_admin_view = __esm(() => {
232101
+ init_cli_add_shared();
232102
+ init_cli_add_workspace_admin_view_source();
232103
+ init_cli_add_workspace_admin_view_scaffold();
232104
+ init_cli_add_workspace_admin_view_types();
232105
+ init_workspace_inventory();
232106
+ init_workspace_project();
231413
232107
  });
231414
232108
 
231415
232109
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-assets.ts
231416
232110
  import fs43 from "fs";
231417
232111
  import { promises as fsp19 } from "fs";
231418
- import path52 from "path";
232112
+ import path53 from "path";
231419
232113
  import {
231420
232114
  syncBlockMetadata as syncBlockMetadata2
231421
232115
  } from "@wp-typia/block-runtime/metadata-core";
@@ -231690,7 +232384,7 @@ async function ensureBindingTargetBlockAttributeType(projectDir, block, target)
231690
232384
  if (!block.attributeTypeName) {
231691
232385
  throw new Error(`Workspace block "${block.slug}" must include attributeTypeName in scripts/block-config.ts before it can receive binding-source targets.`);
231692
232386
  }
231693
- const typesPath = path52.join(projectDir, block.typesFile);
232387
+ const typesPath = path53.join(projectDir, block.typesFile);
231694
232388
  const source = await fsp19.readFile(typesPath, "utf8");
231695
232389
  const targetInterface = getInterfaceDeclaration(source, block.attributeTypeName);
231696
232390
  if (!targetInterface) {
@@ -231702,10 +232396,10 @@ async function ensureBindingTargetBlockAttributeType(projectDir, block, target)
231702
232396
  await fsp19.writeFile(typesPath, nextSource, "utf8");
231703
232397
  }
231704
232398
  await syncBlockMetadata2({
231705
- blockJsonFile: path52.join("src", "blocks", block.slug, "block.json"),
231706
- jsonSchemaFile: path52.join("src", "blocks", block.slug, "typia.schema.json"),
231707
- manifestFile: path52.join("src", "blocks", block.slug, "typia.manifest.json"),
231708
- openApiFile: path52.join("src", "blocks", block.slug, "typia.openapi.json"),
232399
+ blockJsonFile: path53.join("src", "blocks", block.slug, "block.json"),
232400
+ jsonSchemaFile: path53.join("src", "blocks", block.slug, "typia.schema.json"),
232401
+ manifestFile: path53.join("src", "blocks", block.slug, "typia.manifest.json"),
232402
+ openApiFile: path53.join("src", "blocks", block.slug, "typia.openapi.json"),
231709
232403
  projectRoot: projectDir,
231710
232404
  sourceTypeName: block.attributeTypeName,
231711
232405
  typesFile: block.typesFile
@@ -231944,7 +232638,7 @@ ${patternFunctions}
231944
232638
  }
231945
232639
  }
231946
232640
  if (!nextSource.includes(patternCategoryFunctionName) || !nextSource.includes(patternRegistrationFunctionName)) {
231947
- throw new Error(`Unable to inject pattern bootstrap functions into ${path52.basename(bootstrapPath)}.`);
232641
+ throw new Error(`Unable to inject pattern bootstrap functions into ${path53.basename(bootstrapPath)}.`);
231948
232642
  }
231949
232643
  if (!nextSource.includes(patternCategoryHook)) {
231950
232644
  nextSource = `${nextSource.trimEnd()}
@@ -232132,7 +232826,7 @@ ${snippet}
232132
232826
  if (missingReferences.length > 0) {
232133
232827
  const replacedSource = replacePhpFunctionDefinition(nextSource, enqueueFunctionName, enqueueFunction);
232134
232828
  if (!replacedSource) {
232135
- throw new Error(`Unable to repair ${path52.basename(bootstrapPath)} for ${enqueueFunctionName}.`);
232829
+ throw new Error(`Unable to repair ${path53.basename(bootstrapPath)} for ${enqueueFunctionName}.`);
232136
232830
  }
232137
232831
  nextSource = replacedSource;
232138
232832
  }
@@ -232144,7 +232838,7 @@ ${snippet}
232144
232838
  });
232145
232839
  }
232146
232840
  async function ensureEditorPluginBuildScriptAnchors(workspace) {
232147
- const buildScriptPath = path52.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232841
+ const buildScriptPath = path53.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232148
232842
  await patchFile(buildScriptPath, (source) => {
232149
232843
  if (/['"]src\/editor-plugins\/index\.(?:ts|js)['"]/u.test(source)) {
232150
232844
  return source;
@@ -232157,13 +232851,13 @@ async function ensureEditorPluginBuildScriptAnchors(workspace) {
232157
232851
  'src/editor-plugins/index.js',
232158
232852
  ]`);
232159
232853
  if (nextSource === source) {
232160
- throw new Error(`Unable to update ${path52.relative(workspace.projectDir, buildScriptPath)} for editor plugin shared entries.`);
232854
+ throw new Error(`Unable to update ${path53.relative(workspace.projectDir, buildScriptPath)} for editor plugin shared entries.`);
232161
232855
  }
232162
232856
  return nextSource;
232163
232857
  });
232164
232858
  }
232165
232859
  async function ensureEditorPluginWebpackAnchors(workspace) {
232166
- const webpackConfigPath = path52.join(workspace.projectDir, "webpack.config.js");
232860
+ const webpackConfigPath = path53.join(workspace.projectDir, "webpack.config.js");
232167
232861
  await patchFile(webpackConfigPath, (source) => {
232168
232862
  if (/['"]editor-plugins\/index['"]/u.test(source)) {
232169
232863
  return source;
@@ -232191,17 +232885,17 @@ async function ensureEditorPluginWebpackAnchors(workspace) {
232191
232885
  }`;
232192
232886
  const nextSource = source.replace(legacySharedEntriesBlockPattern, nextSharedEntriesBlock);
232193
232887
  if (nextSource === source) {
232194
- throw new Error(`Unable to update ${path52.relative(workspace.projectDir, webpackConfigPath)} for editor plugin shared entries.`);
232888
+ throw new Error(`Unable to update ${path53.relative(workspace.projectDir, webpackConfigPath)} for editor plugin shared entries.`);
232195
232889
  }
232196
232890
  return nextSource;
232197
232891
  });
232198
232892
  }
232199
232893
  function resolveBindingSourceRegistryPath(projectDir) {
232200
- const bindingsDir = path52.join(projectDir, "src", "bindings");
232201
- return [path52.join(bindingsDir, "index.ts"), path52.join(bindingsDir, "index.js")].find((candidatePath) => fs43.existsSync(candidatePath)) ?? path52.join(bindingsDir, "index.ts");
232894
+ const bindingsDir = path53.join(projectDir, "src", "bindings");
232895
+ return [path53.join(bindingsDir, "index.ts"), path53.join(bindingsDir, "index.js")].find((candidatePath) => fs43.existsSync(candidatePath)) ?? path53.join(bindingsDir, "index.ts");
232202
232896
  }
232203
232897
  async function writeBindingSourceRegistry(projectDir, bindingSourceSlug) {
232204
- const bindingsDir = path52.join(projectDir, "src", "bindings");
232898
+ const bindingsDir = path53.join(projectDir, "src", "bindings");
232205
232899
  const bindingsIndexPath = resolveBindingSourceRegistryPath(projectDir);
232206
232900
  await fsp19.mkdir(bindingsDir, { recursive: true });
232207
232901
  const existingBindingSourceSlugs = fs43.readdirSync(bindingsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -232209,11 +232903,11 @@ async function writeBindingSourceRegistry(projectDir, bindingSourceSlug) {
232209
232903
  await fsp19.writeFile(bindingsIndexPath, buildBindingSourceIndexSource(nextBindingSourceSlugs), "utf8");
232210
232904
  }
232211
232905
  function resolveEditorPluginRegistryPath(projectDir) {
232212
- const editorPluginsDir = path52.join(projectDir, "src", "editor-plugins");
232906
+ const editorPluginsDir = path53.join(projectDir, "src", "editor-plugins");
232213
232907
  return [
232214
- path52.join(editorPluginsDir, "index.ts"),
232215
- path52.join(editorPluginsDir, "index.js")
232216
- ].find((candidatePath) => fs43.existsSync(candidatePath)) ?? path52.join(editorPluginsDir, "index.ts");
232908
+ path53.join(editorPluginsDir, "index.ts"),
232909
+ path53.join(editorPluginsDir, "index.js")
232910
+ ].find((candidatePath) => fs43.existsSync(candidatePath)) ?? path53.join(editorPluginsDir, "index.ts");
232217
232911
  }
232218
232912
  function readEditorPluginRegistrySlugs(registryPath) {
232219
232913
  if (!fs43.existsSync(registryPath)) {
@@ -232223,7 +232917,7 @@ function readEditorPluginRegistrySlugs(registryPath) {
232223
232917
  return Array.from(source.matchAll(/^\s*import\s+['"]\.\/([^/'"]+)(?:\/index(?:\.[cm]?[jt]sx?)?)?['"];?\s*$/gmu)).map((match3) => match3[1]);
232224
232918
  }
232225
232919
  async function writeEditorPluginRegistry(projectDir, editorPluginSlug) {
232226
- const editorPluginsDir = path52.join(projectDir, "src", "editor-plugins");
232920
+ const editorPluginsDir = path53.join(projectDir, "src", "editor-plugins");
232227
232921
  const registryPath = resolveEditorPluginRegistryPath(projectDir);
232228
232922
  await fsp19.mkdir(editorPluginsDir, { recursive: true });
232229
232923
  const existingEditorPluginSlugs = readWorkspaceInventory(projectDir).editorPlugins.map((entry) => entry.slug);
@@ -232241,17 +232935,17 @@ async function runAddEditorPluginCommand({
232241
232935
  const resolvedSlot = assertValidEditorPluginSlot(slot);
232242
232936
  const inventory = readWorkspaceInventory(workspace.projectDir);
232243
232937
  assertEditorPluginDoesNotExist(workspace.projectDir, editorPluginSlug, inventory);
232244
- const blockConfigPath = path52.join(workspace.projectDir, "scripts", "block-config.ts");
232938
+ const blockConfigPath = path53.join(workspace.projectDir, "scripts", "block-config.ts");
232245
232939
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
232246
- const buildScriptPath = path52.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232940
+ const buildScriptPath = path53.join(workspace.projectDir, "scripts", "build-workspace.mjs");
232247
232941
  const editorPluginsIndexPath = resolveEditorPluginRegistryPath(workspace.projectDir);
232248
- const webpackConfigPath = path52.join(workspace.projectDir, "webpack.config.js");
232249
- const editorPluginDir = path52.join(workspace.projectDir, "src", "editor-plugins", editorPluginSlug);
232250
- const entryFilePath = path52.join(editorPluginDir, "index.tsx");
232251
- const surfaceFilePath = path52.join(editorPluginDir, "Surface.tsx");
232252
- const dataFilePath = path52.join(editorPluginDir, "data.ts");
232253
- const typesFilePath = path52.join(editorPluginDir, "types.ts");
232254
- const styleFilePath = path52.join(editorPluginDir, "style.scss");
232942
+ const webpackConfigPath = path53.join(workspace.projectDir, "webpack.config.js");
232943
+ const editorPluginDir = path53.join(workspace.projectDir, "src", "editor-plugins", editorPluginSlug);
232944
+ const entryFilePath = path53.join(editorPluginDir, "index.tsx");
232945
+ const surfaceFilePath = path53.join(editorPluginDir, "Surface.tsx");
232946
+ const dataFilePath = path53.join(editorPluginDir, "data.ts");
232947
+ const typesFilePath = path53.join(editorPluginDir, "types.ts");
232948
+ const styleFilePath = path53.join(editorPluginDir, "style.scss");
232255
232949
  const mutationSnapshot = {
232256
232950
  fileSources: await snapshotWorkspaceFiles([
232257
232951
  blockConfigPath,
@@ -232297,16 +232991,16 @@ async function runAddPatternCommand({
232297
232991
  const patternSlug = assertValidGeneratedSlug("Pattern name", normalizeBlockSlug(patternName), "wp-typia add pattern <name>");
232298
232992
  const inventory = readWorkspaceInventory(workspace.projectDir);
232299
232993
  assertPatternDoesNotExist(workspace.projectDir, patternSlug, inventory);
232300
- const blockConfigPath = path52.join(workspace.projectDir, "scripts", "block-config.ts");
232994
+ const blockConfigPath = path53.join(workspace.projectDir, "scripts", "block-config.ts");
232301
232995
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
232302
- const patternFilePath = path52.join(workspace.projectDir, "src", "patterns", `${patternSlug}.php`);
232996
+ const patternFilePath = path53.join(workspace.projectDir, "src", "patterns", `${patternSlug}.php`);
232303
232997
  const mutationSnapshot = {
232304
232998
  fileSources: await snapshotWorkspaceFiles([blockConfigPath, bootstrapPath]),
232305
232999
  snapshotDirs: [],
232306
233000
  targetPaths: [patternFilePath]
232307
233001
  };
232308
233002
  try {
232309
- await fsp19.mkdir(path52.dirname(patternFilePath), { recursive: true });
233003
+ await fsp19.mkdir(path53.dirname(patternFilePath), { recursive: true });
232310
233004
  await ensurePatternBootstrapAnchors(workspace);
232311
233005
  await fsp19.writeFile(patternFilePath, buildPatternSource(patternSlug, workspace.workspace.namespace, workspace.workspace.textDomain), "utf8");
232312
233006
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
@@ -232336,18 +233030,18 @@ async function runAddBindingSourceCommand({
232336
233030
  blockName
232337
233031
  }, workspace.workspace.namespace);
232338
233032
  const targetBlock = target ? resolveWorkspaceBlock(inventory, target.blockSlug) : undefined;
232339
- const blockConfigPath = path52.join(workspace.projectDir, "scripts", "block-config.ts");
233033
+ const blockConfigPath = path53.join(workspace.projectDir, "scripts", "block-config.ts");
232340
233034
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
232341
233035
  const bindingsIndexPath = resolveBindingSourceRegistryPath(workspace.projectDir);
232342
- const bindingSourceDir = path52.join(workspace.projectDir, "src", "bindings", bindingSourceSlug);
232343
- const serverFilePath = path52.join(bindingSourceDir, "server.php");
232344
- const editorFilePath = path52.join(bindingSourceDir, "editor.ts");
232345
- const blockJsonPath = target ? path52.join(workspace.projectDir, "src", "blocks", target.blockSlug, "block.json") : undefined;
233036
+ const bindingSourceDir = path53.join(workspace.projectDir, "src", "bindings", bindingSourceSlug);
233037
+ const serverFilePath = path53.join(bindingSourceDir, "server.php");
233038
+ const editorFilePath = path53.join(bindingSourceDir, "editor.ts");
233039
+ const blockJsonPath = target ? path53.join(workspace.projectDir, "src", "blocks", target.blockSlug, "block.json") : undefined;
232346
233040
  const targetGeneratedMetadataPaths = target ? [
232347
- path52.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.manifest.json"),
232348
- path52.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.openapi.json"),
232349
- path52.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.schema.json"),
232350
- path52.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia-validator.php")
233041
+ path53.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.manifest.json"),
233042
+ path53.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.openapi.json"),
233043
+ path53.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.schema.json"),
233044
+ path53.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia-validator.php")
232351
233045
  ] : [];
232352
233046
  const mutationSnapshot = {
232353
233047
  fileSources: await snapshotWorkspaceFiles([
@@ -232355,7 +233049,7 @@ async function runAddBindingSourceCommand({
232355
233049
  bootstrapPath,
232356
233050
  bindingsIndexPath,
232357
233051
  ...blockJsonPath ? [blockJsonPath] : [],
232358
- ...targetBlock ? [path52.join(workspace.projectDir, targetBlock.typesFile)] : [],
233052
+ ...targetBlock ? [path53.join(workspace.projectDir, targetBlock.typesFile)] : [],
232359
233053
  ...targetGeneratedMetadataPaths
232360
233054
  ]),
232361
233055
  snapshotDirs: [],
@@ -232393,7 +233087,7 @@ var init_cli_add_workspace_assets = __esm(() => {
232393
233087
  });
232394
233088
 
232395
233089
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest-anchors.ts
232396
- import path53 from "path";
233090
+ import path54 from "path";
232397
233091
  async function ensureRestResourceBootstrapAnchors(workspace) {
232398
233092
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
232399
233093
  await patchFile(bootstrapPath, (source) => {
@@ -232440,7 +233134,7 @@ ${snippet}
232440
233134
  insertPhpSnippet(registerFunction);
232441
233135
  } else if (!nextSource.includes(REST_RESOURCE_SERVER_GLOB)) {
232442
233136
  throw new Error([
232443
- `Unable to patch ${path53.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
233137
+ `Unable to patch ${path54.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
232444
233138
  `The existing ${registerFunctionName}() definition does not include ${REST_RESOURCE_SERVER_GLOB}.`,
232445
233139
  "Restore the generated bootstrap shape or wire the REST resource loader manually before retrying."
232446
233140
  ].join(" "));
@@ -232454,7 +233148,7 @@ ${snippet}
232454
233148
  function assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
232455
233149
  if (!nextSource.includes(target) && !hasAnchor) {
232456
233150
  throw new Error([
232457
- `ensureRestResourceSyncScriptAnchors could not patch ${path53.basename(syncRestScriptPath)}.`,
233151
+ `ensureRestResourceSyncScriptAnchors could not patch ${path54.basename(syncRestScriptPath)}.`,
232458
233152
  `Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
232459
233153
  "Restore the generated template or add the REST_RESOURCES wiring manually before retrying."
232460
233154
  ].join(" "));
@@ -232469,7 +233163,7 @@ function replaceRequiredSyncRestSource(nextSource, target, anchor, replacement,
232469
233163
  return nextSource.replace(anchor, replacement);
232470
233164
  }
232471
233165
  async function ensureRestResourceSyncScriptAnchors(workspace) {
232472
- const syncRestScriptPath = path53.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
233166
+ const syncRestScriptPath = path54.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
232473
233167
  await patchFile(syncRestScriptPath, (source) => {
232474
233168
  let nextSource = source;
232475
233169
  const importAnchor = "import { BLOCKS, type WorkspaceBlockConfig } from './block-config';";
@@ -232591,7 +233285,7 @@ var init_cli_add_workspace_rest_anchors = __esm(() => {
232591
233285
  });
232592
233286
 
232593
233287
  // ../wp-typia-project-tools/src/runtime/rest-resource-artifacts.ts
232594
- import path54 from "path";
233288
+ import path55 from "path";
232595
233289
  import {
232596
233290
  defineEndpointManifest as defineEndpointManifest2,
232597
233291
  syncEndpointClient as syncEndpointClient2,
@@ -232727,8 +233421,8 @@ async function syncRestResourceArtifacts({
232727
233421
  const manifest = buildRestResourceEndpointManifest(variables, methods);
232728
233422
  for (const [baseName, contract] of Object.entries(manifest.contracts)) {
232729
233423
  await syncTypeSchemas2({
232730
- jsonSchemaFile: path54.join(outputDir, "api-schemas", `${baseName}.schema.json`),
232731
- openApiFile: path54.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
233424
+ jsonSchemaFile: path55.join(outputDir, "api-schemas", `${baseName}.schema.json`),
233425
+ openApiFile: path55.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
232732
233426
  projectRoot: projectDir,
232733
233427
  sourceTypeName: contract.sourceTypeName,
232734
233428
  typesFile
@@ -232736,7 +233430,7 @@ async function syncRestResourceArtifacts({
232736
233430
  }
232737
233431
  await syncRestOpenApi2({
232738
233432
  manifest,
232739
- openApiFile: path54.join(outputDir, "api.openapi.json"),
233433
+ openApiFile: path55.join(outputDir, "api.openapi.json"),
232740
233434
  projectRoot: projectDir,
232741
233435
  typesFile
232742
233436
  });
@@ -233138,7 +233832,7 @@ var init_cli_add_workspace_rest_source_emitters = __esm(() => {
233138
233832
 
233139
233833
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest.ts
233140
233834
  import { promises as fsp20 } from "fs";
233141
- import path55 from "path";
233835
+ import path56 from "path";
233142
233836
  function buildRestResourceRouteRegistrations(restResourceSlug, methods, functions) {
233143
233837
  const collectionRoutes = [];
233144
233838
  const itemRoutes = [];
@@ -233568,15 +234262,15 @@ async function runAddRestResourceCommand({
233568
234262
  const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
233569
234263
  const inventory = readWorkspaceInventory(workspace.projectDir);
233570
234264
  assertRestResourceDoesNotExist(workspace.projectDir, restResourceSlug, inventory);
233571
- const blockConfigPath = path55.join(workspace.projectDir, "scripts", "block-config.ts");
234265
+ const blockConfigPath = path56.join(workspace.projectDir, "scripts", "block-config.ts");
233572
234266
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
233573
- const syncRestScriptPath = path55.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
233574
- const restResourceDir = path55.join(workspace.projectDir, "src", "rest", restResourceSlug);
233575
- const typesFilePath = path55.join(restResourceDir, "api-types.ts");
233576
- const validatorsFilePath = path55.join(restResourceDir, "api-validators.ts");
233577
- const apiFilePath = path55.join(restResourceDir, "api.ts");
233578
- const dataFilePath = path55.join(restResourceDir, "data.ts");
233579
- const phpFilePath = path55.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
234267
+ const syncRestScriptPath = path56.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
234268
+ const restResourceDir = path56.join(workspace.projectDir, "src", "rest", restResourceSlug);
234269
+ const typesFilePath = path56.join(restResourceDir, "api-types.ts");
234270
+ const validatorsFilePath = path56.join(restResourceDir, "api-validators.ts");
234271
+ const apiFilePath = path56.join(restResourceDir, "api.ts");
234272
+ const dataFilePath = path56.join(restResourceDir, "data.ts");
234273
+ const phpFilePath = path56.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
233580
234274
  const mutationSnapshot = {
233581
234275
  fileSources: await snapshotWorkspaceFiles([
233582
234276
  blockConfigPath,
@@ -233588,7 +234282,7 @@ async function runAddRestResourceCommand({
233588
234282
  };
233589
234283
  try {
233590
234284
  await fsp20.mkdir(restResourceDir, { recursive: true });
233591
- await fsp20.mkdir(path55.dirname(phpFilePath), { recursive: true });
234285
+ await fsp20.mkdir(path56.dirname(phpFilePath), { recursive: true });
233592
234286
  await ensureRestResourceBootstrapAnchors(workspace);
233593
234287
  await ensureRestResourceSyncScriptAnchors(workspace);
233594
234288
  await fsp20.writeFile(typesFilePath, buildRestResourceTypesSource(restResourceSlug, resolvedMethods), "utf8");
@@ -233640,7 +234334,7 @@ var init_cli_add_workspace_rest = __esm(() => {
233640
234334
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ability.ts
233641
234335
  import fs44 from "fs";
233642
234336
  import { promises as fsp21 } from "fs";
233643
- import path56 from "path";
234337
+ import path57 from "path";
233644
234338
  import { syncTypeSchemas as syncTypeSchemas3 } from "@wp-typia/block-runtime/metadata-core";
233645
234339
  function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
233646
234340
  if (!existingVersion) {
@@ -234118,8 +234812,8 @@ function buildAbilityRegistrySource(abilitySlugs) {
234118
234812
  `);
234119
234813
  }
234120
234814
  function resolveAbilityRegistryPath(projectDir) {
234121
- const abilitiesDir = path56.join(projectDir, "src", "abilities");
234122
- return [path56.join(abilitiesDir, "index.ts"), path56.join(abilitiesDir, "index.js")].find((candidatePath) => fs44.existsSync(candidatePath)) ?? path56.join(abilitiesDir, "index.ts");
234815
+ const abilitiesDir = path57.join(projectDir, "src", "abilities");
234816
+ return [path57.join(abilitiesDir, "index.ts"), path57.join(abilitiesDir, "index.js")].find((candidatePath) => fs44.existsSync(candidatePath)) ?? path57.join(abilitiesDir, "index.ts");
234123
234817
  }
234124
234818
  function readAbilityRegistrySlugs(registryPath) {
234125
234819
  if (!fs44.existsSync(registryPath)) {
@@ -234129,7 +234823,7 @@ function readAbilityRegistrySlugs(registryPath) {
234129
234823
  return Array.from(source.matchAll(/^\s*export\s+\*\s+from\s+['"]\.\/([^/'"]+)\/client['"];?\s*$/gmu)).map((match3) => match3[1]);
234130
234824
  }
234131
234825
  async function writeAbilityRegistry(projectDir, abilitySlug) {
234132
- const abilitiesDir = path56.join(projectDir, "src", "abilities");
234826
+ const abilitiesDir = path57.join(projectDir, "src", "abilities");
234133
234827
  const registryPath = resolveAbilityRegistryPath(projectDir);
234134
234828
  await fsp21.mkdir(abilitiesDir, { recursive: true });
234135
234829
  const existingAbilitySlugs = readWorkspaceInventory(projectDir).abilities.map((entry) => entry.slug);
@@ -234261,7 +234955,7 @@ ${snippet}
234261
234955
  });
234262
234956
  }
234263
234957
  async function ensureAbilityPackageScripts(workspace) {
234264
- const packageJsonPath = path56.join(workspace.projectDir, "package.json");
234958
+ const packageJsonPath = path57.join(workspace.projectDir, "package.json");
234265
234959
  const packageJson = JSON.parse(await fsp21.readFile(packageJsonPath, "utf8"));
234266
234960
  const nextScripts = {
234267
234961
  ...packageJson.scripts ?? {},
@@ -234269,8 +234963,8 @@ async function ensureAbilityPackageScripts(workspace) {
234269
234963
  };
234270
234964
  const nextDependencies = {
234271
234965
  ...packageJson.dependencies ?? {},
234272
- [WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], WP_ABILITIES_PACKAGE_VERSION),
234273
- [WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], WP_CORE_ABILITIES_PACKAGE_VERSION)
234966
+ [WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], DEFAULT_WORDPRESS_ABILITIES_VERSION),
234967
+ [WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION)
234274
234968
  };
234275
234969
  if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {}) && JSON.stringify(nextDependencies) === JSON.stringify(packageJson.dependencies ?? {})) {
234276
234970
  return;
@@ -234281,7 +234975,7 @@ async function ensureAbilityPackageScripts(workspace) {
234281
234975
  `, "utf8");
234282
234976
  }
234283
234977
  async function ensureAbilitySyncProjectAnchors(workspace) {
234284
- const syncProjectScriptPath = path56.join(workspace.projectDir, "scripts", "sync-project.ts");
234978
+ const syncProjectScriptPath = path57.join(workspace.projectDir, "scripts", "sync-project.ts");
234285
234979
  await patchFile(syncProjectScriptPath, (source) => {
234286
234980
  let nextSource = source;
234287
234981
  const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
@@ -234296,7 +234990,7 @@ async function ensureAbilitySyncProjectAnchors(workspace) {
234296
234990
  if (!nextSource.includes(syncAbilitiesConst)) {
234297
234991
  if (!nextSource.includes(syncRestConst)) {
234298
234992
  throw new Error([
234299
- `ensureAbilitySyncProjectAnchors could not patch ${path56.basename(syncProjectScriptPath)}.`,
234993
+ `ensureAbilitySyncProjectAnchors could not patch ${path57.basename(syncProjectScriptPath)}.`,
234300
234994
  "Missing the expected sync-rest script constant in scripts/sync-project.ts.",
234301
234995
  "Restore the generated template or wire sync-abilities manually before retrying."
234302
234996
  ].join(" "));
@@ -234307,7 +235001,7 @@ ${syncAbilitiesConst}`);
234307
235001
  if (!nextSource.includes("runSyncScript( syncAbilitiesScriptPath, options );")) {
234308
235002
  if (!syncRestBlockPattern.test(nextSource)) {
234309
235003
  throw new Error([
234310
- `ensureAbilitySyncProjectAnchors could not patch ${path56.basename(syncProjectScriptPath)}.`,
235004
+ `ensureAbilitySyncProjectAnchors could not patch ${path57.basename(syncProjectScriptPath)}.`,
234311
235005
  "Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
234312
235006
  "Restore the generated template or wire sync-abilities manually before retrying."
234313
235007
  ].join(" "));
@@ -234320,7 +235014,7 @@ ${syncAbilitiesBlock}`);
234320
235014
  });
234321
235015
  }
234322
235016
  async function ensureAbilityBuildScriptAnchors(workspace) {
234323
- const buildScriptPath = path56.join(workspace.projectDir, "scripts", "build-workspace.mjs");
235017
+ const buildScriptPath = path57.join(workspace.projectDir, "scripts", "build-workspace.mjs");
234324
235018
  await patchFile(buildScriptPath, (source) => {
234325
235019
  let nextSource = source;
234326
235020
  if (/['"]src\/abilities\/index\.(?:ts|js)['"]/u.test(nextSource)) {
@@ -234330,7 +235024,7 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
234330
235024
  const match3 = nextSource.match(sharedEntriesPattern);
234331
235025
  if (!match3 || !match3[2].includes("src/bindings/index.ts") || !match3[2].includes("src/editor-plugins/index.ts")) {
234332
235026
  throw new Error([
234333
- `ensureAbilityBuildScriptAnchors could not patch ${path56.basename(buildScriptPath)}.`,
235027
+ `ensureAbilityBuildScriptAnchors could not patch ${path57.basename(buildScriptPath)}.`,
234334
235028
  "Missing the expected shared editor entries array in scripts/build-workspace.mjs.",
234335
235029
  "Restore the generated template or wire abilities/index manually before retrying."
234336
235030
  ].join(" "));
@@ -234347,7 +235041,7 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
234347
235041
  });
234348
235042
  }
234349
235043
  async function ensureAbilityWebpackAnchors(workspace) {
234350
- const webpackConfigPath = path56.join(workspace.projectDir, "webpack.config.js");
235044
+ const webpackConfigPath = path57.join(workspace.projectDir, "webpack.config.js");
234351
235045
  await patchFile(webpackConfigPath, (source) => {
234352
235046
  if (/['"]abilities\/index['"]/u.test(source)) {
234353
235047
  return source;
@@ -234378,7 +235072,7 @@ $2`);
234378
235072
  const match3 = source.match(sharedEntriesPattern);
234379
235073
  if (!match3 || !match3[1].includes("bindings/index") || !match3[1].includes("editor-plugins/index")) {
234380
235074
  throw new Error([
234381
- `ensureAbilityWebpackAnchors could not patch ${path56.basename(webpackConfigPath)}.`,
235075
+ `ensureAbilityWebpackAnchors could not patch ${path57.basename(webpackConfigPath)}.`,
234382
235076
  "Missing the expected shared editor entries block in webpack.config.js.",
234383
235077
  "Restore the generated template or wire abilities/index manually before retrying."
234384
235078
  ].join(" "));
@@ -234408,20 +235102,20 @@ async function runAddAbilityCommand({
234408
235102
  const inventory = readWorkspaceInventory(workspace.projectDir);
234409
235103
  assertAbilityDoesNotExist(workspace.projectDir, abilitySlug, inventory);
234410
235104
  const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY);
234411
- const blockConfigPath = path56.join(workspace.projectDir, "scripts", "block-config.ts");
235105
+ const blockConfigPath = path57.join(workspace.projectDir, "scripts", "block-config.ts");
234412
235106
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
234413
- const buildScriptPath = path56.join(workspace.projectDir, "scripts", "build-workspace.mjs");
234414
- const packageJsonPath = path56.join(workspace.projectDir, "package.json");
234415
- const syncAbilitiesScriptPath = path56.join(workspace.projectDir, "scripts", "sync-abilities.ts");
234416
- const syncProjectScriptPath = path56.join(workspace.projectDir, "scripts", "sync-project.ts");
234417
- const webpackConfigPath = path56.join(workspace.projectDir, "webpack.config.js");
235107
+ const buildScriptPath = path57.join(workspace.projectDir, "scripts", "build-workspace.mjs");
235108
+ const packageJsonPath = path57.join(workspace.projectDir, "package.json");
235109
+ const syncAbilitiesScriptPath = path57.join(workspace.projectDir, "scripts", "sync-abilities.ts");
235110
+ const syncProjectScriptPath = path57.join(workspace.projectDir, "scripts", "sync-project.ts");
235111
+ const webpackConfigPath = path57.join(workspace.projectDir, "webpack.config.js");
234418
235112
  const abilitiesIndexPath = resolveAbilityRegistryPath(workspace.projectDir);
234419
- const abilityDir = path56.join(workspace.projectDir, "src", "abilities", abilitySlug);
234420
- const configFilePath = path56.join(abilityDir, "ability.config.json");
234421
- const typesFilePath = path56.join(abilityDir, "types.ts");
234422
- const dataFilePath = path56.join(abilityDir, "data.ts");
234423
- const clientFilePath = path56.join(abilityDir, "client.ts");
234424
- const phpFilePath = path56.join(workspace.projectDir, "inc", "abilities", `${abilitySlug}.php`);
235113
+ const abilityDir = path57.join(workspace.projectDir, "src", "abilities", abilitySlug);
235114
+ const configFilePath = path57.join(abilityDir, "ability.config.json");
235115
+ const typesFilePath = path57.join(abilityDir, "types.ts");
235116
+ const dataFilePath = path57.join(abilityDir, "data.ts");
235117
+ const clientFilePath = path57.join(abilityDir, "client.ts");
235118
+ const phpFilePath = path57.join(workspace.projectDir, "inc", "abilities", `${abilitySlug}.php`);
234425
235119
  const mutationSnapshot = {
234426
235120
  fileSources: await snapshotWorkspaceFiles([
234427
235121
  blockConfigPath,
@@ -234438,7 +235132,7 @@ async function runAddAbilityCommand({
234438
235132
  };
234439
235133
  try {
234440
235134
  await fsp21.mkdir(abilityDir, { recursive: true });
234441
- await fsp21.mkdir(path56.dirname(phpFilePath), { recursive: true });
235135
+ await fsp21.mkdir(path57.dirname(phpFilePath), { recursive: true });
234442
235136
  await ensureAbilityBootstrapAnchors(workspace);
234443
235137
  await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
234444
235138
  await ensureAbilityPackageScripts(workspace);
@@ -234477,12 +235171,13 @@ async function runAddAbilityCommand({
234477
235171
  throw error48;
234478
235172
  }
234479
235173
  }
234480
- 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";
235174
+ 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_SCRIPT_MODULE_ID = "@wordpress/abilities", WP_CORE_ABILITIES_SCRIPT_MODULE_ID = "@wordpress/core-abilities";
234481
235175
  var init_cli_add_workspace_ability = __esm(() => {
234482
235176
  init_workspace_inventory();
234483
235177
  init_workspace_project();
234484
235178
  init_cli_add_shared();
234485
235179
  init_scaffold_compatibility();
235180
+ init_package_versions();
234486
235181
  import_semver2 = __toESM(require_semver2(), 1);
234487
235182
  });
234488
235183
 
@@ -234515,7 +235210,7 @@ var init_ai_artifacts = __esm(() => {
234515
235210
 
234516
235211
  // ../wp-typia-project-tools/src/runtime/ai-feature-artifacts.ts
234517
235212
  import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
234518
- import path57 from "path";
235213
+ import path58 from "path";
234519
235214
  import {
234520
235215
  defineEndpointManifest as defineEndpointManifest3,
234521
235216
  syncEndpointClient as syncEndpointClient3,
@@ -234528,7 +235223,7 @@ function normalizeGeneratedArtifactContent(content) {
234528
235223
  }
234529
235224
  async function reconcileGeneratedArtifact(options) {
234530
235225
  if (!options.check) {
234531
- await mkdir3(path57.dirname(options.filePath), {
235226
+ await mkdir3(path58.dirname(options.filePath), {
234532
235227
  recursive: true
234533
235228
  });
234534
235229
  await writeFile5(options.filePath, options.content, "utf8");
@@ -234600,8 +235295,8 @@ async function syncAiFeatureRestArtifacts({
234600
235295
  const manifest = buildAiFeatureEndpointManifest(variables);
234601
235296
  for (const [baseName, contract] of Object.entries(manifest.contracts)) {
234602
235297
  await syncTypeSchemas4({
234603
- jsonSchemaFile: path57.join(outputDir, "api-schemas", `${baseName}.schema.json`),
234604
- openApiFile: path57.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
235298
+ jsonSchemaFile: path58.join(outputDir, "api-schemas", `${baseName}.schema.json`),
235299
+ openApiFile: path58.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
234605
235300
  projectRoot: projectDir,
234606
235301
  sourceTypeName: contract.sourceTypeName,
234607
235302
  typesFile
@@ -234609,7 +235304,7 @@ async function syncAiFeatureRestArtifacts({
234609
235304
  }
234610
235305
  await syncRestOpenApi3({
234611
235306
  manifest,
234612
- openApiFile: path57.join(outputDir, "api.openapi.json"),
235307
+ openApiFile: path58.join(outputDir, "api.openapi.json"),
234613
235308
  projectRoot: projectDir,
234614
235309
  typesFile
234615
235310
  }, executionOptions);
@@ -234627,19 +235322,19 @@ async function syncAiFeatureSchemaArtifact({
234627
235322
  outputDir,
234628
235323
  projectDir
234629
235324
  }) {
234630
- const sourceSchemaPath = path57.join(projectDir, outputDir, "api-schemas", "feature-result.schema.json");
235325
+ const sourceSchemaPath = path58.join(projectDir, outputDir, "api-schemas", "feature-result.schema.json");
234631
235326
  const responseSchema = assertJsonObject(JSON.parse(await readFile5(sourceSchemaPath, "utf8")), sourceSchemaPath);
234632
235327
  const aiSchema = projectWordPressAiSchema(responseSchema);
234633
235328
  await reconcileGeneratedArtifact({
234634
235329
  check: check2,
234635
235330
  content: `${JSON.stringify(aiSchema, null, 2)}
234636
235331
  `,
234637
- filePath: path57.join(projectDir, aiSchemaFile),
235332
+ filePath: path58.join(projectDir, aiSchemaFile),
234638
235333
  label: "AI feature schema"
234639
235334
  });
234640
235335
  return {
234641
235336
  aiSchema,
234642
- aiSchemaPath: path57.join(projectDir, aiSchemaFile),
235337
+ aiSchemaPath: path58.join(projectDir, aiSchemaFile),
234643
235338
  check: check2,
234644
235339
  sourceSchemaPath
234645
235340
  };
@@ -234971,7 +235666,7 @@ var init_cli_add_workspace_ai_source_emitters = __esm(() => {
234971
235666
 
234972
235667
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai-anchors.ts
234973
235668
  import { promises as fsp22 } from "fs";
234974
- import path58 from "path";
235669
+ import path59 from "path";
234975
235670
  async function ensureAiFeatureBootstrapAnchors(workspace) {
234976
235671
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
234977
235672
  await patchFile(bootstrapPath, (source) => {
@@ -235018,7 +235713,7 @@ ${snippet}
235018
235713
  insertPhpSnippet(registerFunction);
235019
235714
  } else if (!nextSource.includes(AI_FEATURE_SERVER_GLOB)) {
235020
235715
  throw new Error([
235021
- `Unable to patch ${path58.basename(bootstrapPath)} in ensureAiFeatureBootstrapAnchors.`,
235716
+ `Unable to patch ${path59.basename(bootstrapPath)} in ensureAiFeatureBootstrapAnchors.`,
235022
235717
  `The existing ${registerFunctionName}() definition does not include ${AI_FEATURE_SERVER_GLOB}.`,
235023
235718
  "Restore the generated bootstrap shape or wire the AI feature loader manually before retrying."
235024
235719
  ].join(" "));
@@ -235030,7 +235725,7 @@ ${snippet}
235030
235725
  });
235031
235726
  }
235032
235727
  async function ensureAiFeaturePackageScripts(workspace) {
235033
- const packageJsonPath = path58.join(workspace.projectDir, "package.json");
235728
+ const packageJsonPath = path59.join(workspace.projectDir, "package.json");
235034
235729
  const packageJson = JSON.parse(await fsp22.readFile(packageJsonPath, "utf8"));
235035
235730
  const nextScripts = {
235036
235731
  ...packageJson.scripts ?? {},
@@ -235058,7 +235753,7 @@ async function ensureAiFeaturePackageScripts(workspace) {
235058
235753
  };
235059
235754
  }
235060
235755
  async function ensureAiFeatureSyncProjectAnchors(workspace) {
235061
- const syncProjectScriptPath = path58.join(workspace.projectDir, "scripts", "sync-project.ts");
235756
+ const syncProjectScriptPath = path59.join(workspace.projectDir, "scripts", "sync-project.ts");
235062
235757
  await patchFile(syncProjectScriptPath, (source) => {
235063
235758
  let nextSource = source;
235064
235759
  const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
@@ -235073,7 +235768,7 @@ async function ensureAiFeatureSyncProjectAnchors(workspace) {
235073
235768
  if (!nextSource.includes(syncAiConst)) {
235074
235769
  if (!nextSource.includes(syncRestConst)) {
235075
235770
  throw new Error([
235076
- `ensureAiFeatureSyncProjectAnchors could not patch ${path58.basename(syncProjectScriptPath)}.`,
235771
+ `ensureAiFeatureSyncProjectAnchors could not patch ${path59.basename(syncProjectScriptPath)}.`,
235077
235772
  "Missing the expected sync-rest script constant in scripts/sync-project.ts.",
235078
235773
  "Restore the generated template or wire sync-ai manually before retrying."
235079
235774
  ].join(" "));
@@ -235084,7 +235779,7 @@ ${syncAiConst}`);
235084
235779
  if (!nextSource.includes("runSyncScript( syncAiScriptPath, options );")) {
235085
235780
  if (!syncRestBlockPattern.test(nextSource)) {
235086
235781
  throw new Error([
235087
- `ensureAiFeatureSyncProjectAnchors could not patch ${path58.basename(syncProjectScriptPath)}.`,
235782
+ `ensureAiFeatureSyncProjectAnchors could not patch ${path59.basename(syncProjectScriptPath)}.`,
235088
235783
  "Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
235089
235784
  "Restore the generated template or wire sync-ai manually before retrying."
235090
235785
  ].join(" "));
@@ -235099,7 +235794,7 @@ ${syncAiBlock}`);
235099
235794
  function assertSyncRestAnchor2(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
235100
235795
  if (!nextSource.includes(target) && !hasAnchor) {
235101
235796
  throw new Error([
235102
- `ensureAiFeatureSyncRestAnchors could not patch ${path58.basename(syncRestScriptPath)}.`,
235797
+ `ensureAiFeatureSyncRestAnchors could not patch ${path59.basename(syncRestScriptPath)}.`,
235103
235798
  `Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
235104
235799
  "Restore the generated template or add the AI feature wiring manually before retrying."
235105
235800
  ].join(" "));
@@ -235114,7 +235809,7 @@ function replaceRequiredSyncRestSource2(nextSource, target, anchor, replacement,
235114
235809
  return nextSource.replace(anchor, replacement);
235115
235810
  }
235116
235811
  async function ensureAiFeatureSyncRestAnchors(workspace) {
235117
- const syncRestScriptPath = path58.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
235812
+ const syncRestScriptPath = path59.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
235118
235813
  await patchFile(syncRestScriptPath, (source) => {
235119
235814
  let nextSource = source;
235120
235815
  const importAnchor = [
@@ -235249,7 +235944,7 @@ var init_cli_add_workspace_ai_anchors = __esm(() => {
235249
235944
 
235250
235945
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai.ts
235251
235946
  import { promises as fsp23 } from "fs";
235252
- import path59 from "path";
235947
+ import path60 from "path";
235253
235948
  function buildAiFeaturePhpSource(aiFeatureSlug, namespace, phpPrefix, textDomain) {
235254
235949
  const aiFeatureTitle = toTitleCase(aiFeatureSlug);
235255
235950
  const aiFeaturePhpId = aiFeatureSlug.replace(/-/g, "_");
@@ -235638,18 +236333,18 @@ async function runAddAiFeatureCommand({
235638
236333
  const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY);
235639
236334
  const inventory = readWorkspaceInventory(workspace.projectDir);
235640
236335
  assertAiFeatureDoesNotExist(workspace.projectDir, aiFeatureSlug, inventory);
235641
- const blockConfigPath = path59.join(workspace.projectDir, "scripts", "block-config.ts");
236336
+ const blockConfigPath = path60.join(workspace.projectDir, "scripts", "block-config.ts");
235642
236337
  const bootstrapPath = getWorkspaceBootstrapPath(workspace);
235643
- const packageJsonPath = path59.join(workspace.projectDir, "package.json");
235644
- const syncAiScriptPath = path59.join(workspace.projectDir, "scripts", "sync-ai-features.ts");
235645
- const syncProjectScriptPath = path59.join(workspace.projectDir, "scripts", "sync-project.ts");
235646
- const syncRestScriptPath = path59.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
235647
- const aiFeatureDir = path59.join(workspace.projectDir, "src", "ai-features", aiFeatureSlug);
235648
- const typesFilePath = path59.join(aiFeatureDir, "api-types.ts");
235649
- const validatorsFilePath = path59.join(aiFeatureDir, "api-validators.ts");
235650
- const apiFilePath = path59.join(aiFeatureDir, "api.ts");
235651
- const dataFilePath = path59.join(aiFeatureDir, "data.ts");
235652
- const phpFilePath = path59.join(workspace.projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
236338
+ const packageJsonPath = path60.join(workspace.projectDir, "package.json");
236339
+ const syncAiScriptPath = path60.join(workspace.projectDir, "scripts", "sync-ai-features.ts");
236340
+ const syncProjectScriptPath = path60.join(workspace.projectDir, "scripts", "sync-project.ts");
236341
+ const syncRestScriptPath = path60.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
236342
+ const aiFeatureDir = path60.join(workspace.projectDir, "src", "ai-features", aiFeatureSlug);
236343
+ const typesFilePath = path60.join(aiFeatureDir, "api-types.ts");
236344
+ const validatorsFilePath = path60.join(aiFeatureDir, "api-validators.ts");
236345
+ const apiFilePath = path60.join(aiFeatureDir, "api.ts");
236346
+ const dataFilePath = path60.join(aiFeatureDir, "data.ts");
236347
+ const phpFilePath = path60.join(workspace.projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
235653
236348
  const mutationSnapshot = {
235654
236349
  fileSources: await snapshotWorkspaceFiles([
235655
236350
  blockConfigPath,
@@ -235664,7 +236359,7 @@ async function runAddAiFeatureCommand({
235664
236359
  };
235665
236360
  try {
235666
236361
  await fsp23.mkdir(aiFeatureDir, { recursive: true });
235667
- await fsp23.mkdir(path59.dirname(phpFilePath), { recursive: true });
236362
+ await fsp23.mkdir(path60.dirname(phpFilePath), { recursive: true });
235668
236363
  await ensureAiFeatureBootstrapAnchors(workspace);
235669
236364
  await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
235670
236365
  const packageScriptChanges = await ensureAiFeaturePackageScripts(workspace);
@@ -235679,7 +236374,7 @@ async function runAddAiFeatureCommand({
235679
236374
  const pascalCase = toPascalCase(aiFeatureSlug);
235680
236375
  await syncAiFeatureRestArtifacts({
235681
236376
  clientFile: `src/ai-features/${aiFeatureSlug}/api-client.ts`,
235682
- outputDir: path59.join("src", "ai-features", aiFeatureSlug),
236377
+ outputDir: path60.join("src", "ai-features", aiFeatureSlug),
235683
236378
  projectDir: workspace.projectDir,
235684
236379
  typesFile: `src/ai-features/${aiFeatureSlug}/api-types.ts`,
235685
236380
  validatorsFile: `src/ai-features/${aiFeatureSlug}/api-validators.ts`,
@@ -235692,7 +236387,7 @@ async function runAddAiFeatureCommand({
235692
236387
  });
235693
236388
  await syncAiFeatureSchemaArtifact({
235694
236389
  aiSchemaFile: `src/ai-features/${aiFeatureSlug}/ai-schemas/feature-result.ai.schema.json`,
235695
- outputDir: path59.join("src", "ai-features", aiFeatureSlug),
236390
+ outputDir: path60.join("src", "ai-features", aiFeatureSlug),
235696
236391
  projectDir: workspace.projectDir
235697
236392
  });
235698
236393
  await appendWorkspaceInventoryEntries(workspace.projectDir, {
@@ -235728,7 +236423,7 @@ var init_cli_add_workspace_ai = __esm(() => {
235728
236423
  // ../wp-typia-project-tools/src/runtime/cli-add-workspace.ts
235729
236424
  import fs45 from "fs";
235730
236425
  import { promises as fsp24 } from "fs";
235731
- import path60 from "path";
236426
+ import path61 from "path";
235732
236427
  function maskSourceSegment(segment) {
235733
236428
  return segment.replace(/[^\n\r]/gu, " ");
235734
236429
  }
@@ -236112,7 +236807,7 @@ ${VARIATIONS_CALL_LINE}
236112
236807
  }
236113
236808
  }
236114
236809
  if (!hasExecutablePattern(nextSource, VARIATIONS_CALL_PATTERN)) {
236115
- throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${path60.basename(blockIndexPath)}.`);
236810
+ throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${path61.basename(blockIndexPath)}.`);
236116
236811
  }
236117
236812
  return nextSource;
236118
236813
  });
@@ -236142,7 +236837,7 @@ ${BLOCK_STYLES_CALL_LINE}
236142
236837
  }
236143
236838
  }
236144
236839
  if (!hasExecutablePattern(nextSource, BLOCK_STYLES_CALL_PATTERN)) {
236145
- throw new Error(`Unable to inject ${BLOCK_STYLES_CALL_LINE} into ${path60.basename(blockIndexPath)}.`);
236840
+ throw new Error(`Unable to inject ${BLOCK_STYLES_CALL_LINE} into ${path61.basename(blockIndexPath)}.`);
236146
236841
  }
236147
236842
  return nextSource;
236148
236843
  });
@@ -236159,7 +236854,7 @@ ${nextSource}`;
236159
236854
  SCAFFOLD_REGISTRATION_SETTINGS_CALL_PATTERN
236160
236855
  ]);
236161
236856
  if (!callRange) {
236162
- throw new Error(`Unable to inject ${BLOCK_TRANSFORMS_CALL_LINE} into ${path60.basename(blockIndexPath)} because it does not expose a scaffold registration settings object.`);
236857
+ throw new Error(`Unable to inject ${BLOCK_TRANSFORMS_CALL_LINE} into ${path61.basename(blockIndexPath)} because it does not expose a scaffold registration settings object.`);
236163
236858
  }
236164
236859
  nextSource = [
236165
236860
  nextSource.slice(0, callRange.start),
@@ -236172,42 +236867,42 @@ ${nextSource}`;
236172
236867
  });
236173
236868
  }
236174
236869
  async function writeVariationRegistry(projectDir, blockSlug, variationSlug) {
236175
- const variationsDir = path60.join(projectDir, "src", "blocks", blockSlug, "variations");
236176
- const variationsIndexPath = path60.join(variationsDir, "index.ts");
236870
+ const variationsDir = path61.join(projectDir, "src", "blocks", blockSlug, "variations");
236871
+ const variationsIndexPath = path61.join(variationsDir, "index.ts");
236177
236872
  await fsp24.mkdir(variationsDir, { recursive: true });
236178
236873
  const existingVariationSlugs = fs45.readdirSync(variationsDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
236179
236874
  const nextVariationSlugs = Array.from(new Set([...existingVariationSlugs, variationSlug])).sort();
236180
236875
  await fsp24.writeFile(variationsIndexPath, buildVariationIndexSource(nextVariationSlugs), "utf8");
236181
236876
  }
236182
236877
  async function writeBlockStyleRegistry(projectDir, blockSlug, styleSlug) {
236183
- const stylesDir = path60.join(projectDir, "src", "blocks", blockSlug, "styles");
236184
- const stylesIndexPath = path60.join(stylesDir, "index.ts");
236878
+ const stylesDir = path61.join(projectDir, "src", "blocks", blockSlug, "styles");
236879
+ const stylesIndexPath = path61.join(stylesDir, "index.ts");
236185
236880
  await fsp24.mkdir(stylesDir, { recursive: true });
236186
236881
  const existingStyleSlugs = fs45.readdirSync(stylesDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
236187
236882
  const nextStyleSlugs = Array.from(new Set([...existingStyleSlugs, styleSlug])).sort();
236188
236883
  await fsp24.writeFile(stylesIndexPath, buildBlockStyleIndexSource(nextStyleSlugs), "utf8");
236189
236884
  }
236190
236885
  async function writeBlockTransformRegistry(projectDir, blockSlug, transformSlug) {
236191
- const transformsDir = path60.join(projectDir, "src", "blocks", blockSlug, "transforms");
236192
- const transformsIndexPath = path60.join(transformsDir, "index.ts");
236886
+ const transformsDir = path61.join(projectDir, "src", "blocks", blockSlug, "transforms");
236887
+ const transformsIndexPath = path61.join(transformsDir, "index.ts");
236193
236888
  await fsp24.mkdir(transformsDir, { recursive: true });
236194
236889
  const existingTransformSlugs = fs45.readdirSync(transformsDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
236195
236890
  const nextTransformSlugs = Array.from(new Set([...existingTransformSlugs, transformSlug])).sort();
236196
236891
  await fsp24.writeFile(transformsIndexPath, buildBlockTransformIndexSource(nextTransformSlugs), "utf8");
236197
236892
  }
236198
236893
  function assertBlockStyleDoesNotExist(projectDir, blockSlug, styleSlug, inventory) {
236199
- const stylePath = path60.join(projectDir, "src", "blocks", blockSlug, "styles", `${styleSlug}.ts`);
236894
+ const stylePath = path61.join(projectDir, "src", "blocks", blockSlug, "styles", `${styleSlug}.ts`);
236200
236895
  if (fs45.existsSync(stylePath)) {
236201
- throw new Error(`A block style already exists at ${path60.relative(projectDir, stylePath)}. Choose a different name.`);
236896
+ throw new Error(`A block style already exists at ${path61.relative(projectDir, stylePath)}. Choose a different name.`);
236202
236897
  }
236203
236898
  if (inventory.blockStyles.some((entry) => entry.block === blockSlug && entry.slug === styleSlug)) {
236204
236899
  throw new Error(`A block style inventory entry already exists for ${blockSlug}/${styleSlug}. Choose a different name.`);
236205
236900
  }
236206
236901
  }
236207
236902
  function assertBlockTransformDoesNotExist(projectDir, blockSlug, transformSlug, inventory) {
236208
- const transformPath = path60.join(projectDir, "src", "blocks", blockSlug, "transforms", `${transformSlug}.ts`);
236903
+ const transformPath = path61.join(projectDir, "src", "blocks", blockSlug, "transforms", `${transformSlug}.ts`);
236209
236904
  if (fs45.existsSync(transformPath)) {
236210
- throw new Error(`A block transform already exists at ${path60.relative(projectDir, transformPath)}. Choose a different name.`);
236905
+ throw new Error(`A block transform already exists at ${path61.relative(projectDir, transformPath)}. Choose a different name.`);
236211
236906
  }
236212
236907
  if (inventory.blockTransforms.some((entry) => entry.block === blockSlug && entry.slug === transformSlug)) {
236213
236908
  throw new Error(`A block transform inventory entry already exists for ${blockSlug}/${transformSlug}. Choose a different name.`);
@@ -236253,11 +236948,11 @@ async function runAddVariationCommand({
236253
236948
  const inventory = readWorkspaceInventory(workspace.projectDir);
236254
236949
  resolveWorkspaceBlock(inventory, blockSlug);
236255
236950
  assertVariationDoesNotExist(workspace.projectDir, blockSlug, variationSlug, inventory);
236256
- const blockConfigPath = path60.join(workspace.projectDir, "scripts", "block-config.ts");
236257
- const blockIndexPath = path60.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
236258
- const variationsDir = path60.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
236259
- const variationFilePath = path60.join(variationsDir, `${variationSlug}.ts`);
236260
- const variationsIndexPath = path60.join(variationsDir, "index.ts");
236951
+ const blockConfigPath = path61.join(workspace.projectDir, "scripts", "block-config.ts");
236952
+ const blockIndexPath = path61.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
236953
+ const variationsDir = path61.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
236954
+ const variationFilePath = path61.join(variationsDir, `${variationSlug}.ts`);
236955
+ const variationsIndexPath = path61.join(variationsDir, "index.ts");
236261
236956
  const shouldRemoveVariationsDirOnRollback = !fs45.existsSync(variationsDir);
236262
236957
  const mutationSnapshot = {
236263
236958
  fileSources: await snapshotWorkspaceFiles([
@@ -236300,11 +236995,11 @@ async function runAddBlockStyleCommand({
236300
236995
  const inventory = readWorkspaceInventory(workspace.projectDir);
236301
236996
  resolveWorkspaceBlock(inventory, blockSlug);
236302
236997
  assertBlockStyleDoesNotExist(workspace.projectDir, blockSlug, styleSlug, inventory);
236303
- const blockConfigPath = path60.join(workspace.projectDir, "scripts", "block-config.ts");
236304
- const blockIndexPath = path60.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
236305
- const stylesDir = path60.join(workspace.projectDir, "src", "blocks", blockSlug, "styles");
236306
- const styleFilePath = path60.join(stylesDir, `${styleSlug}.ts`);
236307
- const stylesIndexPath = path60.join(stylesDir, "index.ts");
236998
+ const blockConfigPath = path61.join(workspace.projectDir, "scripts", "block-config.ts");
236999
+ const blockIndexPath = path61.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
237000
+ const stylesDir = path61.join(workspace.projectDir, "src", "blocks", blockSlug, "styles");
237001
+ const styleFilePath = path61.join(stylesDir, `${styleSlug}.ts`);
237002
+ const stylesIndexPath = path61.join(stylesDir, "index.ts");
236308
237003
  const shouldRemoveStylesDirOnRollback = !fs45.existsSync(stylesDir);
236309
237004
  const mutationSnapshot = {
236310
237005
  fileSources: await snapshotWorkspaceFiles([
@@ -236349,11 +237044,11 @@ async function runAddBlockTransformCommand({
236349
237044
  const inventory = readWorkspaceInventory(workspace.projectDir);
236350
237045
  resolveWorkspaceBlock(inventory, target.blockSlug);
236351
237046
  assertBlockTransformDoesNotExist(workspace.projectDir, target.blockSlug, transformSlug, inventory);
236352
- const blockConfigPath = path60.join(workspace.projectDir, "scripts", "block-config.ts");
236353
- const blockIndexPath = path60.join(workspace.projectDir, "src", "blocks", target.blockSlug, "index.tsx");
236354
- const transformsDir = path60.join(workspace.projectDir, "src", "blocks", target.blockSlug, "transforms");
236355
- const transformFilePath = path60.join(transformsDir, `${transformSlug}.ts`);
236356
- const transformsIndexPath = path60.join(transformsDir, "index.ts");
237047
+ const blockConfigPath = path61.join(workspace.projectDir, "scripts", "block-config.ts");
237048
+ const blockIndexPath = path61.join(workspace.projectDir, "src", "blocks", target.blockSlug, "index.tsx");
237049
+ const transformsDir = path61.join(workspace.projectDir, "src", "blocks", target.blockSlug, "transforms");
237050
+ const transformFilePath = path61.join(transformsDir, `${transformSlug}.ts`);
237051
+ const transformsIndexPath = path61.join(transformsDir, "index.ts");
236357
237052
  const shouldRemoveTransformsDirOnRollback = !fs45.existsSync(transformsDir);
236358
237053
  const mutationSnapshot = {
236359
237054
  fileSources: await snapshotWorkspaceFiles([
@@ -236415,7 +237110,7 @@ async function runAddHookedBlockCommand({
236415
237110
  throw new Error("`wp-typia add hooked-block` cannot hook a block relative to its own block name.");
236416
237111
  }
236417
237112
  const { blockJson, blockJsonPath } = readWorkspaceBlockJson(workspace.projectDir, blockSlug);
236418
- const blockJsonRelativePath = path60.relative(workspace.projectDir, blockJsonPath);
237113
+ const blockJsonRelativePath = path61.relative(workspace.projectDir, blockJsonPath);
236419
237114
  const blockHooks = getMutableBlockHooks(blockJson, blockJsonRelativePath);
236420
237115
  if (Object.prototype.hasOwnProperty.call(blockHooks, resolvedAnchorBlockName)) {
236421
237116
  throw new Error(`${blockJsonRelativePath} already defines a blockHooks entry for "${resolvedAnchorBlockName}".`);
@@ -236493,7 +237188,7 @@ import { execFileSync as execFileSync3 } from "child_process";
236493
237188
  import { access, constants as fsConstants, rm as rm2, writeFile as writeFile6 } from "fs/promises";
236494
237189
  import fs46 from "fs";
236495
237190
  import os5 from "os";
236496
- import path61 from "path";
237191
+ import path62 from "path";
236497
237192
  function readCommandVersion(command, args = ["--version"]) {
236498
237193
  try {
236499
237194
  return execFileSync3(command, args, {
@@ -236517,7 +237212,7 @@ async function checkWritableDirectory(directory) {
236517
237212
  }
236518
237213
  }
236519
237214
  async function checkTempDirectory() {
236520
- const tempFile = path61.join(os5.tmpdir(), `wp-typia-${Date.now()}.tmp`);
237215
+ const tempFile = path62.join(os5.tmpdir(), `wp-typia-${Date.now()}.tmp`);
236521
237216
  try {
236522
237217
  await writeFile6(tempFile, "ok", "utf8");
236523
237218
  await rm2(tempFile, { force: true });
@@ -236534,7 +237229,7 @@ function getTemplateDoctorChecks() {
236534
237229
  for (const template of listTemplates()) {
236535
237230
  if (!isBuiltInTemplateId(template.id)) {
236536
237231
  const templateDirExists = fs46.existsSync(template.templateDir);
236537
- const hasAssets2 = templateDirExists && fs46.existsSync(path61.join(template.templateDir, "package.json.mustache"));
237232
+ const hasAssets2 = templateDirExists && fs46.existsSync(path62.join(template.templateDir, "package.json.mustache"));
236538
237233
  checks3.push({
236539
237234
  status: !templateDirExists || hasAssets2 ? "pass" : "fail",
236540
237235
  label: `Template ${template.id}`,
@@ -236559,7 +237254,7 @@ function getTemplateDoctorChecks() {
236559
237254
  ])) : getBuiltInTemplateLayerDirs(builtInTemplateId);
236560
237255
  const missingRequiredLayer = layerDirs.some((layerDir) => !fs46.existsSync(layerDir) && !isOmittableBuiltInTemplateLayerDir(builtInTemplateId, layerDir));
236561
237256
  const existingLayerDirs = layerDirs.filter((layerDir) => fs46.existsSync(layerDir));
236562
- const hasAssets = !missingRequiredLayer && existingLayerDirs.some((layerDir) => fs46.existsSync(path61.join(layerDir, "package.json.mustache"))) && existingLayerDirs.some((layerDir) => fs46.existsSync(path61.join(layerDir, "src")));
237257
+ const hasAssets = !missingRequiredLayer && existingLayerDirs.some((layerDir) => fs46.existsSync(path62.join(layerDir, "package.json.mustache"))) && existingLayerDirs.some((layerDir) => fs46.existsSync(path62.join(layerDir, "src")));
236563
237258
  checks3.push({
236564
237259
  status: hasAssets ? "pass" : "fail",
236565
237260
  label: `Template ${template.id}`,
@@ -236590,7 +237285,7 @@ var init_cli_doctor_environment = __esm(() => {
236590
237285
 
236591
237286
  // ../wp-typia-project-tools/src/runtime/cli-doctor-workspace.ts
236592
237287
  import fs47 from "fs";
236593
- import path62 from "path";
237288
+ import path63 from "path";
236594
237289
  import { parseScaffoldBlockMetadata as parseScaffoldBlockMetadata2 } from "@wp-typia/block-runtime/blocks";
236595
237290
  function createDoctorCheck2(label, status, detail, code) {
236596
237291
  return code ? { code, detail, label, status } : { detail, label, status };
@@ -236660,7 +237355,7 @@ function hasExecutablePattern2(source, pattern) {
236660
237355
  return pattern.test(maskTypeScriptCommentsAndLiterals2(source));
236661
237356
  }
236662
237357
  function normalizePathSeparators(relativePath) {
236663
- return relativePath.split(path62.sep).join("/");
237358
+ return relativePath.split(path63.sep).join("/");
236664
237359
  }
236665
237360
  function hasRegisteredBlockAsset(value2) {
236666
237361
  if (typeof value2 === "string") {
@@ -236672,8 +237367,8 @@ function hasRegisteredBlockAsset(value2) {
236672
237367
  return false;
236673
237368
  }
236674
237369
  function readWorkspaceBlockIframeMetadata(projectDir, blockSlug) {
236675
- const blockJsonRelativePath = path62.join("src", "blocks", blockSlug, "block.json");
236676
- const blockJsonPath = path62.join(projectDir, blockJsonRelativePath);
237370
+ const blockJsonRelativePath = path63.join("src", "blocks", blockSlug, "block.json");
237371
+ const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
236677
237372
  if (!fs47.existsSync(blockJsonPath)) {
236678
237373
  return {
236679
237374
  blockJsonRelativePath,
@@ -236718,14 +237413,14 @@ function isWorkspaceBlockSaveSource(relativePath) {
236718
237413
  return fileName.replace(/\.[^.]+$/u, "").toLowerCase() === "save";
236719
237414
  }
236720
237415
  function collectWorkspaceBlockEditorSources(projectDir, blockSlug) {
236721
- const blockDir = path62.join(projectDir, "src", "blocks", blockSlug);
237416
+ const blockDir = path63.join(projectDir, "src", "blocks", blockSlug);
236722
237417
  if (!fs47.existsSync(blockDir)) {
236723
237418
  return [];
236724
237419
  }
236725
237420
  const sources = [];
236726
237421
  const visitDirectory = (directory) => {
236727
237422
  for (const entry of fs47.readdirSync(directory, { withFileTypes: true })) {
236728
- const entryPath = path62.join(directory, entry.name);
237423
+ const entryPath = path63.join(directory, entry.name);
236729
237424
  if (entry.isDirectory()) {
236730
237425
  visitDirectory(entryPath);
236731
237426
  continue;
@@ -236733,8 +237428,8 @@ function collectWorkspaceBlockEditorSources(projectDir, blockSlug) {
236733
237428
  if (!entry.isFile()) {
236734
237429
  continue;
236735
237430
  }
236736
- const relativePath = normalizePathSeparators(path62.relative(projectDir, entryPath));
236737
- const blockRelativePath = path62.relative(blockDir, entryPath);
237431
+ const relativePath = normalizePathSeparators(path63.relative(projectDir, entryPath));
237432
+ const blockRelativePath = path63.relative(blockDir, entryPath);
236738
237433
  if (!isWorkspaceBlockEditorSource(blockRelativePath)) {
236739
237434
  continue;
236740
237435
  }
@@ -236800,7 +237495,7 @@ function getWorkspaceBootstrapRelativePath(packageName) {
236800
237495
  return `${packageBaseName}.php`;
236801
237496
  }
236802
237497
  function checkExistingFiles(projectDir, label, filePaths) {
236803
- const missing = filePaths.filter((filePath) => typeof filePath === "string").filter((filePath) => !fs47.existsSync(path62.join(projectDir, filePath)));
237498
+ const missing = filePaths.filter((filePath) => typeof filePath === "string").filter((filePath) => !fs47.existsSync(path63.join(projectDir, filePath)));
236804
237499
  return createDoctorCheck2(label, missing.length === 0 ? "pass" : "fail", missing.length === 0 ? "All referenced files exist" : `Missing: ${missing.join(", ")}`);
236805
237500
  }
236806
237501
  function checkWorkspacePackageMetadata(workspace, packageJson) {
@@ -236826,24 +237521,24 @@ function checkWorkspacePackageMetadata(workspace, packageJson) {
236826
237521
  if (wpTypia?.phpPrefix !== workspace.workspace.phpPrefix) {
236827
237522
  issues.push(`wpTypia.phpPrefix must equal "${workspace.workspace.phpPrefix}"`);
236828
237523
  }
236829
- if (!fs47.existsSync(path62.join(workspace.projectDir, bootstrapRelativePath))) {
237524
+ if (!fs47.existsSync(path63.join(workspace.projectDir, bootstrapRelativePath))) {
236830
237525
  issues.push(`Missing bootstrap file ${bootstrapRelativePath}`);
236831
237526
  }
236832
237527
  return createDoctorCheck2("Workspace package metadata", issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `package.json metadata aligns with ${workspace.packageName} and ${bootstrapRelativePath}` : issues.join("; "));
236833
237528
  }
236834
237529
  function getWorkspaceBlockRequiredFiles(block) {
236835
- const blockDir = path62.join("src", "blocks", block.slug);
237530
+ const blockDir = path63.join("src", "blocks", block.slug);
236836
237531
  return Array.from(new Set([
236837
237532
  block.typesFile,
236838
237533
  block.apiTypesFile,
236839
237534
  block.openApiFile,
236840
- path62.join(blockDir, "index.tsx"),
236841
- ...WORKSPACE_GENERATED_BLOCK_ARTIFACTS.map((fileName) => path62.join(blockDir, fileName))
237535
+ path63.join(blockDir, "index.tsx"),
237536
+ ...WORKSPACE_GENERATED_BLOCK_ARTIFACTS.map((fileName) => path63.join(blockDir, fileName))
236842
237537
  ].filter((filePath) => typeof filePath === "string")));
236843
237538
  }
236844
237539
  function checkWorkspaceBlockMetadata(projectDir, workspace, block) {
236845
- const blockJsonRelativePath = path62.join("src", "blocks", block.slug, "block.json");
236846
- const blockJsonPath = path62.join(projectDir, blockJsonRelativePath);
237540
+ const blockJsonRelativePath = path63.join("src", "blocks", block.slug, "block.json");
237541
+ const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
236847
237542
  if (!fs47.existsSync(blockJsonPath)) {
236848
237543
  return createDoctorCheck2(`Block metadata ${block.slug}`, "fail", `Missing ${blockJsonRelativePath}`);
236849
237544
  }
@@ -236864,8 +237559,8 @@ function checkWorkspaceBlockMetadata(projectDir, workspace, block) {
236864
237559
  return createDoctorCheck2(`Block metadata ${block.slug}`, issues.length === 0 ? "pass" : "fail", issues.length === 0 ? `block.json matches ${expectedName} and ${workspace.workspace.textDomain}` : issues.join("; "));
236865
237560
  }
236866
237561
  function checkWorkspaceBlockHooks(projectDir, blockSlug) {
236867
- const blockJsonRelativePath = path62.join("src", "blocks", blockSlug, "block.json");
236868
- const blockJsonPath = path62.join(projectDir, blockJsonRelativePath);
237562
+ const blockJsonRelativePath = path63.join("src", "blocks", blockSlug, "block.json");
237563
+ const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
236869
237564
  if (!fs47.existsSync(blockJsonPath)) {
236870
237565
  return createDoctorCheck2(`Block hooks ${blockSlug}`, "fail", `Missing ${blockJsonRelativePath}`);
236871
237566
  }
@@ -236887,8 +237582,8 @@ function checkWorkspaceBlockHooks(projectDir, blockSlug) {
236887
237582
  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(", ")}`);
236888
237583
  }
236889
237584
  function checkWorkspaceBlockCollectionImport(projectDir, blockSlug) {
236890
- const entryRelativePath = path62.join("src", "blocks", blockSlug, "index.tsx");
236891
- const entryPath = path62.join(projectDir, entryRelativePath);
237585
+ const entryRelativePath = path63.join("src", "blocks", blockSlug, "index.tsx");
237586
+ const entryPath = path63.join(projectDir, entryRelativePath);
236892
237587
  if (!fs47.existsSync(entryPath)) {
236893
237588
  return createDoctorCheck2(`Block collection ${blockSlug}`, "fail", `Missing ${entryRelativePath}`);
236894
237589
  }
@@ -236905,8 +237600,8 @@ function checkWorkspaceBlockIframeCompatibility(projectDir, blockSlug) {
236905
237600
  }
236906
237601
  const blockJson = metadataResult.document;
236907
237602
  const apiVersion = typeof blockJson.apiVersion === "number" && Number.isFinite(blockJson.apiVersion) ? blockJson.apiVersion : null;
236908
- const blockDir = path62.join(projectDir, "src", "blocks", blockSlug);
236909
- const localStyleFiles = WORKSPACE_BLOCK_LOCAL_STYLE_FILES.filter((fileName) => fs47.existsSync(path62.join(blockDir, fileName))).map((fileName) => normalizePathSeparators(path62.join("src", "blocks", blockSlug, fileName)));
237603
+ const blockDir = path63.join(projectDir, "src", "blocks", blockSlug);
237604
+ const localStyleFiles = WORKSPACE_BLOCK_LOCAL_STYLE_FILES.filter((fileName) => fs47.existsSync(path63.join(blockDir, fileName))).map((fileName) => normalizePathSeparators(path63.join("src", "blocks", blockSlug, fileName)));
236910
237605
  const hasRegisteredEditorStyles = hasRegisteredBlockAsset(blockJson.style) || hasRegisteredBlockAsset(blockJson.editorStyle);
236911
237606
  const editorSources = collectWorkspaceBlockEditorSources(projectDir, blockSlug);
236912
237607
  const editorWrapperSources = editorSources.filter((source) => !isWorkspaceBlockSaveSource(source.relativePath));
@@ -236924,9 +237619,9 @@ function checkWorkspaceBlockIframeCompatibility(projectDir, blockSlug) {
236924
237619
  }
236925
237620
  function checkWorkspacePatternBootstrap(projectDir, packageName) {
236926
237621
  const packageBaseName = packageName.split("/").pop() ?? packageName;
236927
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237622
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
236928
237623
  if (!fs47.existsSync(bootstrapPath)) {
236929
- return createDoctorCheck2("Pattern bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237624
+ return createDoctorCheck2("Pattern bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
236930
237625
  }
236931
237626
  const source = fs47.readFileSync(bootstrapPath, "utf8");
236932
237627
  const hasCategoryAnchor = source.includes("register_block_pattern_category");
@@ -236935,9 +237630,9 @@ function checkWorkspacePatternBootstrap(projectDir, packageName) {
236935
237630
  }
236936
237631
  function checkWorkspaceBindingBootstrap(projectDir, packageName) {
236937
237632
  const packageBaseName = packageName.split("/").pop() ?? packageName;
236938
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237633
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
236939
237634
  if (!fs47.existsSync(bootstrapPath)) {
236940
- return createDoctorCheck2("Binding bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237635
+ return createDoctorCheck2("Binding bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
236941
237636
  }
236942
237637
  const source = fs47.readFileSync(bootstrapPath, "utf8");
236943
237638
  const hasServerGlob = source.includes(WORKSPACE_BINDING_SERVER_GLOB);
@@ -236947,11 +237642,11 @@ function checkWorkspaceBindingBootstrap(projectDir, packageName) {
236947
237642
  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");
236948
237643
  }
236949
237644
  function checkWorkspaceBindingSourcesIndex(projectDir, bindingSources) {
236950
- const indexRelativePath = [path62.join("src", "bindings", "index.ts"), path62.join("src", "bindings", "index.js")].find((relativePath) => fs47.existsSync(path62.join(projectDir, relativePath)));
237645
+ const indexRelativePath = [path63.join("src", "bindings", "index.ts"), path63.join("src", "bindings", "index.js")].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
236951
237646
  if (!indexRelativePath) {
236952
237647
  return createDoctorCheck2("Binding sources index", "fail", "Missing src/bindings/index.ts or src/bindings/index.js");
236953
237648
  }
236954
- const indexPath = path62.join(projectDir, indexRelativePath);
237649
+ const indexPath = path63.join(projectDir, indexRelativePath);
236955
237650
  const source = fs47.readFileSync(indexPath, "utf8");
236956
237651
  const missingImports = bindingSources.filter((bindingSource) => !source.includes(`./${bindingSource.slug}/editor`));
236957
237652
  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(", ")}`);
@@ -236968,8 +237663,8 @@ function checkWorkspaceBindingTarget(projectDir, workspace, registeredBlockSlugs
236968
237663
  if (!registeredBlockSlugs.has(bindingSource.block)) {
236969
237664
  return createDoctorCheck2(`Binding target ${bindingSource.slug}`, "fail", `Binding target references unknown block "${bindingSource.block}".`);
236970
237665
  }
236971
- const blockJsonRelativePath = path62.join("src", "blocks", bindingSource.block, "block.json");
236972
- const blockJsonPath = path62.join(projectDir, blockJsonRelativePath);
237666
+ const blockJsonRelativePath = path63.join("src", "blocks", bindingSource.block, "block.json");
237667
+ const blockJsonPath = path63.join(projectDir, blockJsonRelativePath);
236973
237668
  const issues = [];
236974
237669
  try {
236975
237670
  const blockJson = parseScaffoldBlockMetadata2(JSON.parse(fs47.readFileSync(blockJsonPath, "utf8")));
@@ -236985,7 +237680,7 @@ function checkWorkspaceBindingTarget(projectDir, workspace, registeredBlockSlugs
236985
237680
  } catch (error48) {
236986
237681
  issues.push(error48 instanceof Error ? `Unable to read ${blockJsonRelativePath}: ${error48.message}` : `Unable to read ${blockJsonRelativePath}.`);
236987
237682
  }
236988
- const serverPath = path62.join(projectDir, bindingSource.serverFile);
237683
+ const serverPath = path63.join(projectDir, bindingSource.serverFile);
236989
237684
  if (fs47.existsSync(serverPath)) {
236990
237685
  const serverSource = fs47.readFileSync(serverPath, "utf8");
236991
237686
  const supportedAttributesFilter = `block_bindings_supported_attributes_${workspace.workspace.namespace}/${bindingSource.block}`;
@@ -236998,7 +237693,7 @@ function checkWorkspaceBindingTarget(projectDir, workspace, registeredBlockSlugs
236998
237693
  } else {
236999
237694
  issues.push(`Missing ${bindingSource.serverFile}`);
237000
237695
  }
237001
- const editorPath = path62.join(projectDir, bindingSource.editorFile);
237696
+ const editorPath = path63.join(projectDir, bindingSource.editorFile);
237002
237697
  if (fs47.existsSync(editorPath)) {
237003
237698
  const editorSource = fs47.readFileSync(editorPath, "utf8");
237004
237699
  const blockName = `${workspace.workspace.namespace}/${bindingSource.block}`;
@@ -237046,7 +237741,7 @@ function getWorkspaceRestResourceRequiredFiles(restResource) {
237046
237741
  }
237047
237742
  return Array.from(new Set([
237048
237743
  restResource.apiFile,
237049
- ...Array.from(schemaNames, (schemaName) => path62.join(path62.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
237744
+ ...Array.from(schemaNames, (schemaName) => path63.join(path63.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
237050
237745
  restResource.clientFile,
237051
237746
  restResource.dataFile,
237052
237747
  restResource.openApiFile,
@@ -237062,9 +237757,9 @@ function checkWorkspaceRestResourceConfig(restResource) {
237062
237757
  }
237063
237758
  function checkWorkspaceRestResourceBootstrap(projectDir, packageName, phpPrefix) {
237064
237759
  const packageBaseName = packageName.split("/").pop() ?? packageName;
237065
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237760
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
237066
237761
  if (!fs47.existsSync(bootstrapPath)) {
237067
- return createDoctorCheck2("REST resource bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237762
+ return createDoctorCheck2("REST resource bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
237068
237763
  }
237069
237764
  const source = fs47.readFileSync(bootstrapPath, "utf8");
237070
237765
  const registerFunctionName = `${phpPrefix}_register_rest_resources`;
@@ -237085,7 +237780,7 @@ function getWorkspaceAbilityRequiredFiles(ability) {
237085
237780
  ]));
237086
237781
  }
237087
237782
  function checkWorkspaceAbilityConfig(projectDir, ability) {
237088
- const configPath = path62.join(projectDir, ability.configFile);
237783
+ const configPath = path63.join(projectDir, ability.configFile);
237089
237784
  if (!fs47.existsSync(configPath)) {
237090
237785
  return createDoctorCheck2(`Ability config ${ability.slug}`, "fail", `Missing ${ability.configFile}`);
237091
237786
  }
@@ -237102,9 +237797,9 @@ function checkWorkspaceAbilityConfig(projectDir, ability) {
237102
237797
  }
237103
237798
  function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
237104
237799
  const packageBaseName = packageName.split("/").pop() ?? packageName;
237105
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237800
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
237106
237801
  if (!fs47.existsSync(bootstrapPath)) {
237107
- return createDoctorCheck2("Ability bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237802
+ return createDoctorCheck2("Ability bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
237108
237803
  }
237109
237804
  const source = fs47.readFileSync(bootstrapPath, "utf8");
237110
237805
  const loadFunctionName = `${phpPrefix}_load_workflow_abilities`;
@@ -237123,13 +237818,13 @@ function checkWorkspaceAbilityBootstrap(projectDir, packageName, phpPrefix) {
237123
237818
  }
237124
237819
  function checkWorkspaceAbilityIndex(projectDir, abilities) {
237125
237820
  const indexRelativePath = [
237126
- path62.join("src", "abilities", "index.ts"),
237127
- path62.join("src", "abilities", "index.js")
237128
- ].find((relativePath) => fs47.existsSync(path62.join(projectDir, relativePath)));
237821
+ path63.join("src", "abilities", "index.ts"),
237822
+ path63.join("src", "abilities", "index.js")
237823
+ ].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
237129
237824
  if (!indexRelativePath) {
237130
237825
  return createDoctorCheck2("Abilities index", "fail", "Missing src/abilities/index.ts or src/abilities/index.js");
237131
237826
  }
237132
- const indexPath = path62.join(projectDir, indexRelativePath);
237827
+ const indexPath = path63.join(projectDir, indexRelativePath);
237133
237828
  const source = fs47.readFileSync(indexPath, "utf8");
237134
237829
  const missingExports = abilities.filter((ability) => {
237135
237830
  const exportPattern = new RegExp(`^\\s*export\\s+(?:\\*\\s+from|\\{[^}]+\\}\\s+from)\\s+['"\`]\\./${escapeRegex2(ability.slug)}\\/client['"\`]`, "mu");
@@ -237141,9 +237836,9 @@ function getWorkspaceAiFeatureRequiredFiles(aiFeature) {
237141
237836
  return Array.from(new Set([
237142
237837
  aiFeature.aiSchemaFile,
237143
237838
  aiFeature.apiFile,
237144
- path62.join(path62.dirname(aiFeature.typesFile), "api-schemas", "feature-request.schema.json"),
237145
- path62.join(path62.dirname(aiFeature.typesFile), "api-schemas", "feature-response.schema.json"),
237146
- path62.join(path62.dirname(aiFeature.typesFile), "api-schemas", "feature-result.schema.json"),
237839
+ path63.join(path63.dirname(aiFeature.typesFile), "api-schemas", "feature-request.schema.json"),
237840
+ path63.join(path63.dirname(aiFeature.typesFile), "api-schemas", "feature-response.schema.json"),
237841
+ path63.join(path63.dirname(aiFeature.typesFile), "api-schemas", "feature-result.schema.json"),
237147
237842
  aiFeature.clientFile,
237148
237843
  aiFeature.dataFile,
237149
237844
  aiFeature.openApiFile,
@@ -237158,9 +237853,9 @@ function checkWorkspaceAiFeatureConfig(aiFeature) {
237158
237853
  }
237159
237854
  function checkWorkspaceAiFeatureBootstrap(projectDir, packageName, phpPrefix) {
237160
237855
  const packageBaseName = packageName.split("/").pop() ?? packageName;
237161
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237856
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
237162
237857
  if (!fs47.existsSync(bootstrapPath)) {
237163
- return createDoctorCheck2("AI feature bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237858
+ return createDoctorCheck2("AI feature bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
237164
237859
  }
237165
237860
  const source = fs47.readFileSync(bootstrapPath, "utf8");
237166
237861
  const registerFunctionName = `${phpPrefix}_register_ai_features`;
@@ -237170,14 +237865,14 @@ function checkWorkspaceAiFeatureBootstrap(projectDir, packageName, phpPrefix) {
237170
237865
  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");
237171
237866
  }
237172
237867
  function getWorkspaceEditorPluginRequiredFiles(editorPlugin) {
237173
- const editorPluginDir = path62.join("src", "editor-plugins", editorPlugin.slug);
237174
- const surfaceFile = editorPlugin.slot === "PluginSidebar" ? path62.join(editorPluginDir, "Sidebar.tsx") : path62.join(editorPluginDir, "Surface.tsx");
237868
+ const editorPluginDir = path63.join("src", "editor-plugins", editorPlugin.slug);
237869
+ const surfaceFile = editorPlugin.slot === "PluginSidebar" ? path63.join(editorPluginDir, "Sidebar.tsx") : path63.join(editorPluginDir, "Surface.tsx");
237175
237870
  return Array.from(new Set([
237176
237871
  editorPlugin.file,
237177
237872
  surfaceFile,
237178
- path62.join(editorPluginDir, "data.ts"),
237179
- path62.join(editorPluginDir, "types.ts"),
237180
- path62.join(editorPluginDir, "style.scss")
237873
+ path63.join(editorPluginDir, "data.ts"),
237874
+ path63.join(editorPluginDir, "types.ts"),
237875
+ path63.join(editorPluginDir, "style.scss")
237181
237876
  ]));
237182
237877
  }
237183
237878
  function checkWorkspaceEditorPluginConfig(editorPlugin) {
@@ -237187,9 +237882,9 @@ function checkWorkspaceEditorPluginConfig(editorPlugin) {
237187
237882
  }
237188
237883
  function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix) {
237189
237884
  const packageBaseName = packageName.split("/").pop() ?? packageName;
237190
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237885
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
237191
237886
  if (!fs47.existsSync(bootstrapPath)) {
237192
- return createDoctorCheck2("Editor plugin bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237887
+ return createDoctorCheck2("Editor plugin bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
237193
237888
  }
237194
237889
  const source = fs47.readFileSync(bootstrapPath, "utf8");
237195
237890
  const enqueueFunctionName = `${phpPrefix}_enqueue_editor_plugins_editor`;
@@ -237202,13 +237897,13 @@ function checkWorkspaceEditorPluginBootstrap(projectDir, packageName, phpPrefix)
237202
237897
  }
237203
237898
  function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
237204
237899
  const indexRelativePath = [
237205
- path62.join("src", "editor-plugins", "index.ts"),
237206
- path62.join("src", "editor-plugins", "index.js")
237207
- ].find((relativePath) => fs47.existsSync(path62.join(projectDir, relativePath)));
237900
+ path63.join("src", "editor-plugins", "index.ts"),
237901
+ path63.join("src", "editor-plugins", "index.js")
237902
+ ].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
237208
237903
  if (!indexRelativePath) {
237209
237904
  return createDoctorCheck2("Editor plugins index", "fail", "Missing src/editor-plugins/index.ts or src/editor-plugins/index.js");
237210
237905
  }
237211
- const indexPath = path62.join(projectDir, indexRelativePath);
237906
+ const indexPath = path63.join(projectDir, indexRelativePath);
237212
237907
  const source = fs47.readFileSync(indexPath, "utf8");
237213
237908
  const missingImports = editorPlugins.filter((editorPlugin) => {
237214
237909
  const importPattern = new RegExp(`['"\`]\\./${escapeRegex2(editorPlugin.slug)}(?:/[^'"\`]*)?['"\`]`, "u");
@@ -237217,15 +237912,15 @@ function checkWorkspaceEditorPluginIndex(projectDir, editorPlugins) {
237217
237912
  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(", ")}`);
237218
237913
  }
237219
237914
  function getWorkspaceAdminViewRequiredFiles(adminView) {
237220
- const adminViewDir = path62.join("src", "admin-views", adminView.slug);
237915
+ const adminViewDir = path63.join("src", "admin-views", adminView.slug);
237221
237916
  return Array.from(new Set([
237222
237917
  adminView.file,
237223
237918
  adminView.phpFile,
237224
- path62.join(adminViewDir, "Screen.tsx"),
237225
- path62.join(adminViewDir, "config.ts"),
237226
- path62.join(adminViewDir, "data.ts"),
237227
- path62.join(adminViewDir, "style.scss"),
237228
- path62.join(adminViewDir, "types.ts")
237919
+ path63.join(adminViewDir, "Screen.tsx"),
237920
+ path63.join(adminViewDir, "config.ts"),
237921
+ path63.join(adminViewDir, "data.ts"),
237922
+ path63.join(adminViewDir, "style.scss"),
237923
+ path63.join(adminViewDir, "types.ts")
237229
237924
  ]));
237230
237925
  }
237231
237926
  function checkWorkspaceAdminViewConfig(adminView, inventory) {
@@ -237233,17 +237928,18 @@ function checkWorkspaceAdminViewConfig(adminView, inventory) {
237233
237928
  return createDoctorCheck2(`Admin view config ${adminView.slug}`, "pass", "Admin view uses a replaceable local fetcher");
237234
237929
  }
237235
237930
  const source = adminView.source.trim();
237236
- const sourceMatch = /^rest-resource:([a-z][a-z0-9-]*)$/u.exec(source);
237237
- const restResourceSlug = sourceMatch?.[1];
237931
+ const restSourceMatch = /^rest-resource:([a-z][a-z0-9-]*)$/u.exec(source);
237932
+ const coreDataSourceMatch = /^core-data:(postType|taxonomy)\/([a-z0-9][a-z0-9_-]*)$/u.exec(source);
237933
+ const restResourceSlug = restSourceMatch?.[1];
237238
237934
  const restResource = restResourceSlug ? inventory.restResources.find((entry) => entry.slug === restResourceSlug) : undefined;
237239
- const isValid2 = Boolean(restResource?.methods.includes("list"));
237240
- return createDoctorCheck2(`Admin view config ${adminView.slug}`, isValid2 ? "pass" : "fail", isValid2 ? `Admin view source ${source} is list-capable` : "Admin view source must use rest-resource:<slug> and reference a list-capable REST resource");
237935
+ const isValid2 = Boolean(restResource?.methods.includes("list")) || Boolean(coreDataSourceMatch);
237936
+ return createDoctorCheck2(`Admin view config ${adminView.slug}`, isValid2 ? "pass" : "fail", isValid2 ? `Admin view source ${source} is list-capable` : "Admin view source must use rest-resource:<slug> with a list-capable REST resource or core-data:<postType|taxonomy>/<name>");
237241
237937
  }
237242
237938
  function checkWorkspaceAdminViewBootstrap(projectDir, packageName, phpPrefix) {
237243
237939
  const packageBaseName = packageName.split("/").pop() ?? packageName;
237244
- const bootstrapPath = path62.join(projectDir, `${packageBaseName}.php`);
237940
+ const bootstrapPath = path63.join(projectDir, `${packageBaseName}.php`);
237245
237941
  if (!fs47.existsSync(bootstrapPath)) {
237246
- return createDoctorCheck2("Admin view bootstrap", "fail", `Missing ${path62.basename(bootstrapPath)}`);
237942
+ return createDoctorCheck2("Admin view bootstrap", "fail", `Missing ${path63.basename(bootstrapPath)}`);
237247
237943
  }
237248
237944
  const source = fs47.readFileSync(bootstrapPath, "utf8");
237249
237945
  const loadFunctionName = `${phpPrefix}_load_admin_views`;
@@ -237254,13 +237950,13 @@ function checkWorkspaceAdminViewBootstrap(projectDir, packageName, phpPrefix) {
237254
237950
  }
237255
237951
  function checkWorkspaceAdminViewIndex(projectDir, adminViews) {
237256
237952
  const indexRelativePath = [
237257
- path62.join("src", "admin-views", "index.ts"),
237258
- path62.join("src", "admin-views", "index.js")
237259
- ].find((relativePath) => fs47.existsSync(path62.join(projectDir, relativePath)));
237953
+ path63.join("src", "admin-views", "index.ts"),
237954
+ path63.join("src", "admin-views", "index.js")
237955
+ ].find((relativePath) => fs47.existsSync(path63.join(projectDir, relativePath)));
237260
237956
  if (!indexRelativePath) {
237261
237957
  return createDoctorCheck2("Admin views index", "fail", "Missing src/admin-views/index.ts or src/admin-views/index.js");
237262
237958
  }
237263
- const indexPath = path62.join(projectDir, indexRelativePath);
237959
+ const indexPath = path63.join(projectDir, indexRelativePath);
237264
237960
  const source = fs47.readFileSync(indexPath, "utf8");
237265
237961
  const missingImports = adminViews.filter((adminView) => {
237266
237962
  const importPattern = new RegExp(`['"\`]\\./${escapeRegex2(adminView.slug)}(?:/[^'"\`]*)?['"\`]`, "u");
@@ -237269,7 +237965,7 @@ function checkWorkspaceAdminViewIndex(projectDir, adminViews) {
237269
237965
  return createDoctorCheck2("Admin views index", missingImports.length === 0 ? "pass" : "fail", missingImports.length === 0 ? "Admin view registrations are aggregated" : `Missing admin view imports for: ${missingImports.map((entry) => entry.slug).join(", ")}`);
237270
237966
  }
237271
237967
  function checkWorkspaceAdminViewPhp(projectDir, adminView) {
237272
- const phpPath = path62.join(projectDir, adminView.phpFile);
237968
+ const phpPath = path63.join(projectDir, adminView.phpFile);
237273
237969
  if (!fs47.existsSync(phpPath)) {
237274
237970
  return createDoctorCheck2(`Admin view PHP ${adminView.slug}`, "fail", `Missing ${adminView.phpFile}`);
237275
237971
  }
@@ -237283,9 +237979,9 @@ function checkWorkspaceAdminViewPhp(projectDir, adminView) {
237283
237979
  return createDoctorCheck2(`Admin view PHP ${adminView.slug}`, hasAdminMenu && hasAdminEnqueue && hasScript && hasAsset && hasStyle && hasComponentsStyleDependency ? "pass" : "fail", hasAdminMenu && hasAdminEnqueue && hasScript && hasAsset && hasStyle && hasComponentsStyleDependency ? "Admin menu, script, style, and wp-components style dependency are wired" : "Missing admin menu, enqueue hook, build/admin-views asset reference, or wp-components style dependency");
237284
237980
  }
237285
237981
  function checkVariationEntrypoint(projectDir, blockSlug) {
237286
- const entryPath = path62.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
237982
+ const entryPath = path63.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
237287
237983
  if (!fs47.existsSync(entryPath)) {
237288
- return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, "fail", `Missing ${path62.relative(projectDir, entryPath)}`);
237984
+ return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, "fail", `Missing ${path63.relative(projectDir, entryPath)}`);
237289
237985
  }
237290
237986
  const source = fs47.readFileSync(entryPath, "utf8");
237291
237987
  const hasImport = hasUncommentedPattern2(source, WORKSPACE_VARIATIONS_IMPORT_PATTERN);
@@ -237293,9 +237989,9 @@ function checkVariationEntrypoint(projectDir, blockSlug) {
237293
237989
  return createDoctorCheck2(`Variation entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Variations registration hook is present" : "Missing ./variations import or registerWorkspaceVariations() call");
237294
237990
  }
237295
237991
  function checkBlockStyleEntrypoint(projectDir, blockSlug) {
237296
- const entryPath = path62.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
237992
+ const entryPath = path63.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
237297
237993
  if (!fs47.existsSync(entryPath)) {
237298
- return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, "fail", `Missing ${path62.relative(projectDir, entryPath)}`);
237994
+ return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, "fail", `Missing ${path63.relative(projectDir, entryPath)}`);
237299
237995
  }
237300
237996
  const source = fs47.readFileSync(entryPath, "utf8");
237301
237997
  const hasImport = hasUncommentedPattern2(source, WORKSPACE_BLOCK_STYLES_IMPORT_PATTERN);
@@ -237303,9 +237999,9 @@ function checkBlockStyleEntrypoint(projectDir, blockSlug) {
237303
237999
  return createDoctorCheck2(`Block style entrypoint ${blockSlug}`, hasImport && hasCall ? "pass" : "fail", hasImport && hasCall ? "Block style registration hook is present" : "Missing ./styles import or registerWorkspaceBlockStyles() call");
237304
238000
  }
237305
238001
  function checkBlockTransformEntrypoint(projectDir, blockSlug) {
237306
- const entryPath = path62.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
238002
+ const entryPath = path63.join(projectDir, "src", "blocks", blockSlug, "index.tsx");
237307
238003
  if (!fs47.existsSync(entryPath)) {
237308
- return createDoctorCheck2(`Block transform entrypoint ${blockSlug}`, "fail", `Missing ${path62.relative(projectDir, entryPath)}`);
238004
+ return createDoctorCheck2(`Block transform entrypoint ${blockSlug}`, "fail", `Missing ${path63.relative(projectDir, entryPath)}`);
237309
238005
  }
237310
238006
  const source = fs47.readFileSync(entryPath, "utf8");
237311
238007
  const hasImport = hasUncommentedPattern2(source, WORKSPACE_BLOCK_TRANSFORMS_IMPORT_PATTERN);
@@ -237325,8 +238021,8 @@ function checkBlockTransformConfig(workspace, transform2) {
237325
238021
  }
237326
238022
  function checkMigrationWorkspaceHint(workspace, packageJson) {
237327
238023
  const hasMigrationScript = typeof packageJson.scripts?.["migration:doctor"] === "string";
237328
- const migrationConfigRelativePath = path62.join("src", "migrations", "config.ts");
237329
- const hasMigrationConfig = fs47.existsSync(path62.join(workspace.projectDir, migrationConfigRelativePath));
238024
+ const migrationConfigRelativePath = path63.join("src", "migrations", "config.ts");
238025
+ const hasMigrationConfig = fs47.existsSync(path63.join(workspace.projectDir, migrationConfigRelativePath));
237330
238026
  if (!hasMigrationScript && !hasMigrationConfig) {
237331
238027
  return null;
237332
238028
  }
@@ -237396,7 +238092,7 @@ function getWorkspaceDoctorChecks(cwd) {
237396
238092
  }
237397
238093
  for (const blockSlug of blockStyleTargetBlocks) {
237398
238094
  checks3.push(checkExistingFiles(workspace.projectDir, `Block style registry ${blockSlug}`, [
237399
- path62.join("src", "blocks", blockSlug, "styles", "index.ts")
238095
+ path63.join("src", "blocks", blockSlug, "styles", "index.ts")
237400
238096
  ]));
237401
238097
  checks3.push(checkBlockStyleEntrypoint(workspace.projectDir, blockSlug));
237402
238098
  }
@@ -237412,11 +238108,11 @@ function getWorkspaceDoctorChecks(cwd) {
237412
238108
  }
237413
238109
  for (const blockSlug of blockTransformTargetBlocks) {
237414
238110
  checks3.push(checkExistingFiles(workspace.projectDir, `Block transform registry ${blockSlug}`, [
237415
- path62.join("src", "blocks", blockSlug, "transforms", "index.ts")
238111
+ path63.join("src", "blocks", blockSlug, "transforms", "index.ts")
237416
238112
  ]));
237417
238113
  checks3.push(checkBlockTransformEntrypoint(workspace.projectDir, blockSlug));
237418
238114
  }
237419
- const shouldCheckPatternBootstrap = inventory.patterns.length > 0 || fs47.existsSync(path62.join(workspace.projectDir, "src", "patterns"));
238115
+ const shouldCheckPatternBootstrap = inventory.patterns.length > 0 || fs47.existsSync(path63.join(workspace.projectDir, "src", "patterns"));
237420
238116
  if (shouldCheckPatternBootstrap) {
237421
238117
  checks3.push(checkWorkspacePatternBootstrap(workspace.projectDir, workspace.packageName));
237422
238118
  }
@@ -237584,13 +238280,13 @@ __export(exports_cli_init, {
237584
238280
  });
237585
238281
  import fs48 from "fs";
237586
238282
  import { promises as fsp25 } from "fs";
237587
- import path63 from "path";
238283
+ import path64 from "path";
237588
238284
  import { analyzeSourceTypes } from "@wp-typia/block-runtime/metadata-parser";
237589
238285
  function normalizeRelativePath2(value2) {
237590
238286
  return value2.replace(/\\/gu, "/");
237591
238287
  }
237592
238288
  function readProjectPackageJson(projectDir) {
237593
- const packageJsonPath = path63.join(projectDir, "package.json");
238289
+ const packageJsonPath = path64.join(projectDir, "package.json");
237594
238290
  if (!fs48.existsSync(packageJsonPath)) {
237595
238291
  return null;
237596
238292
  }
@@ -237606,13 +238302,13 @@ function inferInitPackageManager(projectDir, packageJson) {
237606
238302
  if (packageJson?.packageManager) {
237607
238303
  return parseWorkspacePackageManagerId(packageJson.packageManager);
237608
238304
  }
237609
- if (fs48.existsSync(path63.join(projectDir, "bun.lock")) || fs48.existsSync(path63.join(projectDir, "bun.lockb"))) {
238305
+ if (fs48.existsSync(path64.join(projectDir, "bun.lock")) || fs48.existsSync(path64.join(projectDir, "bun.lockb"))) {
237610
238306
  return "bun";
237611
238307
  }
237612
- if (fs48.existsSync(path63.join(projectDir, "pnpm-lock.yaml"))) {
238308
+ if (fs48.existsSync(path64.join(projectDir, "pnpm-lock.yaml"))) {
237613
238309
  return "pnpm";
237614
238310
  }
237615
- if (fs48.existsSync(path63.join(projectDir, "yarn.lock")) || fs48.existsSync(path63.join(projectDir, ".yarnrc.yml"))) {
238311
+ if (fs48.existsSync(path64.join(projectDir, "yarn.lock")) || fs48.existsSync(path64.join(projectDir, ".yarnrc.yml"))) {
237616
238312
  return "yarn";
237617
238313
  }
237618
238314
  return "npm";
@@ -237696,13 +238392,13 @@ function buildPackageManagerFieldChange(packageJson, packageManager, options = {
237696
238392
  };
237697
238393
  }
237698
238394
  function buildGeneratedArtifactPaths(blockJsonFile, manifestFile) {
237699
- const manifestDir = path63.dirname(manifestFile);
238395
+ const manifestDir = path64.dirname(manifestFile);
237700
238396
  const artifactPaths = [
237701
238397
  blockJsonFile,
237702
238398
  manifestFile,
237703
- path63.join(manifestDir, "typia.schema.json"),
237704
- path63.join(manifestDir, "typia-validator.php"),
237705
- path63.join(manifestDir, "typia.openapi.json")
238399
+ path64.join(manifestDir, "typia.schema.json"),
238400
+ path64.join(manifestDir, "typia-validator.php"),
238401
+ path64.join(manifestDir, "typia.openapi.json")
237706
238402
  ];
237707
238403
  return Array.from(new Set(artifactPaths.map((filePath) => normalizeRelativePath2(filePath))));
237708
238404
  }
@@ -237723,7 +238419,7 @@ function isObjectLikeSourceType(projectDir, typesFile, sourceTypeName) {
237723
238419
  return analyzedTypes[sourceTypeName]?.kind === "object";
237724
238420
  }
237725
238421
  function inferRetrofitAttributeTypeName(projectDir, block) {
237726
- const typesPath = path63.join(projectDir, block.typesFile);
238422
+ const typesPath = path64.join(projectDir, block.typesFile);
237727
238423
  const typesSource = fs48.readFileSync(typesPath, "utf8");
237728
238424
  const blockNameSegments = block.blockName.split("/");
237729
238425
  const slug = blockNameSegments[blockNameSegments.length - 1] ?? block.key;
@@ -238029,10 +238725,10 @@ function hasExistingWpTypiaProjectSurface(projectDir, packageJson) {
238029
238725
  const scripts = packageJson?.scripts ?? {};
238030
238726
  const hasSyncSurface = typeof scripts.sync === "string" || typeof scripts["sync-types"] === "string";
238031
238727
  const hasHelperFiles = [
238032
- path63.join("scripts", "block-config.ts"),
238033
- path63.join("scripts", "sync-project.ts"),
238034
- path63.join("scripts", "sync-types-to-block-json.ts")
238035
- ].every((relativePath) => fs48.existsSync(path63.join(projectDir, relativePath)));
238728
+ path64.join("scripts", "block-config.ts"),
238729
+ path64.join("scripts", "sync-project.ts"),
238730
+ path64.join("scripts", "sync-types-to-block-json.ts")
238731
+ ].every((relativePath) => fs48.existsSync(path64.join(projectDir, relativePath)));
238036
238732
  const hasRuntimeDeps = typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-runtime") === "string" && typeof getExistingDependencyVersion(packageJson, "@wp-typia/block-types") === "string";
238037
238733
  return hasSyncSurface && hasHelperFiles && hasRuntimeDeps;
238038
238734
  }
@@ -238042,17 +238738,17 @@ function buildPlannedFiles(projectDir, layoutKind) {
238042
238738
  }
238043
238739
  return [
238044
238740
  {
238045
- action: fs48.existsSync(path63.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
238741
+ action: fs48.existsSync(path64.join(projectDir, "scripts", "block-config.ts")) ? "update" : "add",
238046
238742
  path: "scripts/block-config.ts",
238047
238743
  purpose: "Declare the current retrofit block targets so sync-types can regenerate metadata from the existing TypeScript source of truth."
238048
238744
  },
238049
238745
  {
238050
- action: fs48.existsSync(path63.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
238746
+ action: fs48.existsSync(path64.join(projectDir, "scripts", "sync-types-to-block-json.ts")) ? "update" : "add",
238051
238747
  path: "scripts/sync-types-to-block-json.ts",
238052
238748
  purpose: "Generate block.json and Typia metadata artifacts from the current TypeScript source of truth."
238053
238749
  },
238054
238750
  {
238055
- action: fs48.existsSync(path63.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
238751
+ action: fs48.existsSync(path64.join(projectDir, "scripts", "sync-project.ts")) ? "update" : "add",
238056
238752
  path: "scripts/sync-project.ts",
238057
238753
  purpose: "Provide one shared sync entrypoint that can grow into sync-rest or workspace-aware refresh steps later."
238058
238754
  }
@@ -238200,13 +238896,13 @@ function buildProjectPackageJsonSource(packageJson) {
238200
238896
  }
238201
238897
  function buildRetrofitHelperFiles(blockTargets) {
238202
238898
  return {
238203
- [path63.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
238204
- [path63.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
238205
- [path63.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
238899
+ [path64.join("scripts", "block-config.ts")]: buildRetrofitBlockConfigSource(blockTargets),
238900
+ [path64.join("scripts", "sync-project.ts")]: buildRetrofitSyncProjectScriptSource(),
238901
+ [path64.join("scripts", "sync-types-to-block-json.ts")]: buildRetrofitSyncTypesScriptSource()
238206
238902
  };
238207
238903
  }
238208
238904
  async function createRetrofitMutationSnapshot(projectDir, filePaths) {
238209
- const scriptsDir = path63.join(projectDir, "scripts");
238905
+ const scriptsDir = path64.join(projectDir, "scripts");
238210
238906
  const scriptsDirExisted = fs48.existsSync(scriptsDir);
238211
238907
  const fileSources = await snapshotWorkspaceFiles(filePaths);
238212
238908
  const targetPaths = fileSources.filter((entry) => entry.source === null).map((entry) => entry.filePath);
@@ -238221,11 +238917,11 @@ async function createRetrofitMutationSnapshot(projectDir, filePaths) {
238221
238917
  }
238222
238918
  async function writeRetrofitFiles(options) {
238223
238919
  const helperFiles = buildRetrofitHelperFiles(options.blockTargets);
238224
- const scriptsDir = path63.join(options.projectDir, "scripts");
238920
+ const scriptsDir = path64.join(options.projectDir, "scripts");
238225
238921
  await fsp25.mkdir(scriptsDir, { recursive: true });
238226
- await fsp25.writeFile(path63.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
238922
+ await fsp25.writeFile(path64.join(options.projectDir, "package.json"), buildProjectPackageJsonSource(options.packageJson), "utf8");
238227
238923
  for (const [relativePath, source] of Object.entries(helperFiles)) {
238228
- await fsp25.writeFile(path63.join(options.projectDir, relativePath), source, "utf8");
238924
+ await fsp25.writeFile(path64.join(options.projectDir, relativePath), source, "utf8");
238229
238925
  }
238230
238926
  }
238231
238927
  function buildApplyFailureError(error48) {
@@ -238233,7 +238929,7 @@ function buildApplyFailureError(error48) {
238233
238929
  return createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `Unable to apply the retrofit init plan safely. The command restored the previous package.json/helper-file snapshot. ${message}`, error48 instanceof Error ? { cause: error48 } : undefined);
238234
238930
  }
238235
238931
  function getInitPlan(projectDir, options = {}) {
238236
- const resolvedProjectDir = path63.resolve(projectDir);
238932
+ const resolvedProjectDir = path64.resolve(projectDir);
238237
238933
  const packageJson = readProjectPackageJson(resolvedProjectDir);
238238
238934
  const packageManager = resolveInitPackageManager(resolvedProjectDir, packageJson, options.packageManager);
238239
238935
  const workspace = tryResolveWorkspaceProject(resolvedProjectDir);
@@ -238269,7 +238965,7 @@ function getInitPlan(projectDir, options = {}) {
238269
238965
  status: "already-initialized"
238270
238966
  });
238271
238967
  }
238272
- const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path63.basename(resolvedProjectDir);
238968
+ const projectName = typeof packageJson?.name === "string" && packageJson.name.length > 0 ? packageJson.name : path64.basename(resolvedProjectDir);
238273
238969
  const layout = buildLayoutDetails(resolvedProjectDir);
238274
238970
  const dependencyChanges = buildDependencyChanges(packageJson);
238275
238971
  const scriptChanges = buildScriptChanges(packageJson, packageManager);
@@ -238335,8 +239031,8 @@ async function applyInitPlan(projectDir, options = {}) {
238335
239031
  });
238336
239032
  const helperFiles = buildRetrofitHelperFiles(previewPlan.blockTargets);
238337
239033
  const filePaths = [
238338
- path63.join(previewPlan.projectDir, "package.json"),
238339
- ...Object.keys(helperFiles).map((relativePath) => path63.join(previewPlan.projectDir, relativePath))
239034
+ path64.join(previewPlan.projectDir, "package.json"),
239035
+ ...Object.keys(helperFiles).map((relativePath) => path64.join(previewPlan.projectDir, relativePath))
238340
239036
  ];
238341
239037
  const mutationSnapshot = await createRetrofitMutationSnapshot(previewPlan.projectDir, filePaths);
238342
239038
  try {
@@ -238400,18 +239096,18 @@ __export(exports_cli_scaffold, {
238400
239096
  });
238401
239097
  import fs49 from "fs";
238402
239098
  import { promises as fsp26 } from "fs";
238403
- import path64 from "path";
239099
+ import path65 from "path";
238404
239100
  async function listRelativeProjectFiles(rootDir) {
238405
239101
  const relativeFiles = [];
238406
239102
  async function visit2(currentDir) {
238407
239103
  const entries = await fsp26.readdir(currentDir, { withFileTypes: true });
238408
239104
  for (const entry of entries) {
238409
- const absolutePath = path64.join(currentDir, entry.name);
239105
+ const absolutePath = path65.join(currentDir, entry.name);
238410
239106
  if (entry.isDirectory()) {
238411
239107
  await visit2(absolutePath);
238412
239108
  continue;
238413
239109
  }
238414
- relativeFiles.push(path64.relative(rootDir, absolutePath).replace(path64.sep === "\\" ? /\\/gu : /\//gu, "/"));
239110
+ relativeFiles.push(path65.relative(rootDir, absolutePath).replace(path65.sep === "\\" ? /\\/gu : /\//gu, "/"));
238415
239111
  }
238416
239112
  }
238417
239113
  await visit2(rootDir);
@@ -238449,7 +239145,7 @@ async function buildScaffoldDryRunPlan({
238449
239145
  }) {
238450
239146
  await assertDryRunTargetDirectoryReady(projectDir, allowExistingDir);
238451
239147
  const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-scaffold-plan-");
238452
- const previewProjectDir = path64.join(tempRoot, "preview-project");
239148
+ const previewProjectDir = path65.join(tempRoot, "preview-project");
238453
239149
  try {
238454
239150
  const result = await scaffoldProject({
238455
239151
  allowExistingDir: false,
@@ -238489,14 +239185,14 @@ function validateCreateProjectInput(projectInput) {
238489
239185
  if (normalizedProjectInput.length === 0) {
238490
239186
  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).");
238491
239187
  }
238492
- const normalizedProjectPath = path64.normalize(normalizedProjectInput).replace(/[\\/]+$/u, "") || path64.normalize(normalizedProjectInput);
239188
+ const normalizedProjectPath = path65.normalize(normalizedProjectInput).replace(/[\\/]+$/u, "") || path65.normalize(normalizedProjectInput);
238493
239189
  if (normalizedProjectPath === "." || normalizedProjectPath === "..") {
238494
239190
  throw new Error("`wp-typia create` requires a new project directory. Use an explicit child directory instead of `.` or `..`.");
238495
239191
  }
238496
239192
  }
238497
239193
  function collectProjectDirectoryWarnings(projectDir) {
238498
239194
  const warnings = [];
238499
- const projectName = path64.basename(projectDir);
239195
+ const projectName = path65.basename(projectDir);
238500
239196
  if (/\s/u.test(projectName)) {
238501
239197
  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.`);
238502
239198
  }
@@ -238651,7 +239347,7 @@ function getNextSteps({
238651
239347
  noInstall,
238652
239348
  templateId
238653
239349
  }) {
238654
- const cdTarget = path64.isAbsolute(projectInput) ? projectDir : projectInput;
239350
+ const cdTarget = path65.isAbsolute(projectInput) ? projectDir : projectInput;
238655
239351
  const steps = [`cd ${quoteShellValue(cdTarget)}`];
238656
239352
  if (noInstall) {
238657
239353
  steps.push(formatInstallCommand(packageManager));
@@ -238799,8 +239495,8 @@ async function runScaffoldFlow({
238799
239495
  select: selectWithMigrationUi,
238800
239496
  yes
238801
239497
  });
238802
- const projectDir = path64.resolve(cwd, projectInput);
238803
- const projectName = path64.basename(projectDir);
239498
+ const projectDir = path65.resolve(cwd, projectInput);
239499
+ const projectName = path65.basename(projectDir);
238804
239500
  const answers = await collectScaffoldAnswers({
238805
239501
  dataStorageMode: resolvedDataStorage,
238806
239502
  namespace,
@@ -238863,7 +239559,7 @@ async function runScaffoldFlow({
238863
239559
  let availableScripts;
238864
239560
  if (!dryRun) {
238865
239561
  try {
238866
- const parsedPackageJson = JSON.parse(fs49.readFileSync(path64.join(projectDir, "package.json"), "utf8"));
239562
+ const parsedPackageJson = JSON.parse(fs49.readFileSync(path65.join(projectDir, "package.json"), "utf8"));
238867
239563
  const scripts = parsedPackageJson.scripts && typeof parsedPackageJson.scripts === "object" && !Array.isArray(parsedPackageJson.scripts) ? parsedPackageJson.scripts : {};
238868
239564
  availableScripts = Object.entries(scripts).filter(([, value2]) => typeof value2 === "string").map(([scriptName]) => scriptName);
238869
239565
  } catch {
@@ -291720,7 +292416,7 @@ var ADD_OPTION_METADATA = {
291720
292416
  type: "string"
291721
292417
  },
291722
292418
  source: {
291723
- description: "Optional data source locator for admin-view workflows, such as rest-resource:products.",
292419
+ description: "Optional data source locator for admin-view workflows, such as rest-resource:products or core-data:postType/post.",
291724
292420
  type: "string"
291725
292421
  },
291726
292422
  template: {
@@ -291780,6 +292476,12 @@ var MIGRATE_OPTION_METADATA = {
291780
292476
  type: "string"
291781
292477
  }
291782
292478
  };
292479
+ var MCP_OPTION_METADATA = {
292480
+ "output-dir": {
292481
+ description: "Output directory for generated MCP metadata.",
292482
+ type: "string"
292483
+ }
292484
+ };
291783
292485
  var SYNC_OPTION_METADATA = {
291784
292486
  check: {
291785
292487
  argumentKind: "flag",
@@ -291817,10 +292519,6 @@ var GLOBAL_OPTION_METADATA = {
291817
292519
  id: {
291818
292520
  description: "Template id for top-level `templates inspect` convenience.",
291819
292521
  type: "string"
291820
- },
291821
- "output-dir": {
291822
- description: "Output directory for generated MCP metadata.",
291823
- type: "string"
291824
292522
  }
291825
292523
  };
291826
292524
  var COMMAND_OPTION_METADATA_BY_GROUP = {
@@ -291830,6 +292528,7 @@ var COMMAND_OPTION_METADATA_BY_GROUP = {
291830
292528
  global: GLOBAL_OPTION_METADATA,
291831
292529
  init: INIT_OPTION_METADATA,
291832
292530
  migrate: MIGRATE_OPTION_METADATA,
292531
+ mcp: MCP_OPTION_METADATA,
291833
292532
  sync: SYNC_OPTION_METADATA,
291834
292533
  templates: TEMPLATES_OPTION_METADATA
291835
292534
  };
@@ -291906,13 +292605,17 @@ function resolveCommandOptionValues(metadata2, options) {
291906
292605
 
291907
292606
  // src/cli-diagnostic-output.ts
291908
292607
  init_cli_diagnostics();
292608
+ function writeStructuredCliJsonToStderr(payload) {
292609
+ process.stderr.write(`${JSON.stringify(payload, null, 2)}
292610
+ `);
292611
+ }
291909
292612
  function prefersStructuredCliOutput(args) {
291910
292613
  return args.formatExplicit && args.format !== "toon" || Boolean(args.agent) || Boolean(args.context?.store?.isAIAgent);
291911
292614
  }
291912
292615
  function emitCliDiagnosticFailure(args, options) {
291913
292616
  const diagnostic = createCliCommandError(options);
291914
292617
  if (prefersStructuredCliOutput(args)) {
291915
- args.output({
292618
+ writeStructuredCliJsonToStderr({
291916
292619
  ...options.extraOutput ?? {},
291917
292620
  error: serializeCliDiagnosticError(diagnostic),
291918
292621
  ok: false
@@ -291962,6 +292665,24 @@ init_cli_diagnostics();
291962
292665
 
291963
292666
  // src/add-kind-registry.ts
291964
292667
  init_cli_diagnostics();
292668
+
292669
+ // src/add-kind-ids.ts
292670
+ var ADD_KIND_IDS = [
292671
+ "admin-view",
292672
+ "block",
292673
+ "variation",
292674
+ "style",
292675
+ "transform",
292676
+ "pattern",
292677
+ "binding-source",
292678
+ "rest-resource",
292679
+ "ability",
292680
+ "ai-feature",
292681
+ "hooked-block",
292682
+ "editor-plugin"
292683
+ ];
292684
+
292685
+ // src/add-kind-registry.ts
291965
292686
  var BLOCK_VISIBLE_FIELD_ORDER = [
291966
292687
  "kind",
291967
292688
  "name",
@@ -291971,6 +292692,54 @@ var BLOCK_VISIBLE_FIELD_ORDER = [
291971
292692
  "data-storage",
291972
292693
  "persistence-policy"
291973
292694
  ];
292695
+ var NAME_ONLY_VISIBLE_FIELDS = [
292696
+ "kind",
292697
+ "name"
292698
+ ];
292699
+ var NAME_SOURCE_VISIBLE_FIELDS = [
292700
+ "kind",
292701
+ "name",
292702
+ "source"
292703
+ ];
292704
+ var NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS = [
292705
+ "kind",
292706
+ "name",
292707
+ "block",
292708
+ "attribute"
292709
+ ];
292710
+ var NAME_BLOCK_VISIBLE_FIELDS = [
292711
+ "kind",
292712
+ "name",
292713
+ "block"
292714
+ ];
292715
+ var NAME_SLOT_VISIBLE_FIELDS = [
292716
+ "kind",
292717
+ "name",
292718
+ "slot"
292719
+ ];
292720
+ var NAME_ANCHOR_POSITION_VISIBLE_FIELDS = [
292721
+ "kind",
292722
+ "name",
292723
+ "anchor",
292724
+ "position"
292725
+ ];
292726
+ var NAME_FROM_TO_VISIBLE_FIELDS = [
292727
+ "kind",
292728
+ "name",
292729
+ "from",
292730
+ "to"
292731
+ ];
292732
+ var NAME_NAMESPACE_METHODS_VISIBLE_FIELDS = [
292733
+ "kind",
292734
+ "name",
292735
+ "namespace",
292736
+ "methods"
292737
+ ];
292738
+ var NAME_NAMESPACE_VISIBLE_FIELDS = [
292739
+ "kind",
292740
+ "name",
292741
+ "namespace"
292742
+ ];
291974
292743
  function readOptionalStringFlag(flags2, name2) {
291975
292744
  const value2 = flags2[name2];
291976
292745
  if (value2 === undefined || value2 === null) {
@@ -291981,6 +292750,21 @@ function readOptionalStringFlag(flags2, name2) {
291981
292750
  }
291982
292751
  return value2;
291983
292752
  }
292753
+ function requireStringFlag(flags2, name2, message) {
292754
+ const value2 = readOptionalStringFlag(flags2, name2);
292755
+ if (!value2) {
292756
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
292757
+ }
292758
+ return value2;
292759
+ }
292760
+ function readOptionalPairedStringFlags(flags2, leftName, rightName, message) {
292761
+ const leftValue = readOptionalStringFlag(flags2, leftName);
292762
+ const rightValue = readOptionalStringFlag(flags2, rightName);
292763
+ if (Boolean(leftValue) !== Boolean(rightValue)) {
292764
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
292765
+ }
292766
+ return [leftValue, rightValue];
292767
+ }
291984
292768
  function requireAddKindName(context, message) {
291985
292769
  if (!context.name) {
291986
292770
  throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, message);
@@ -292004,6 +292788,15 @@ function toExternalLayerPromptOptions(options) {
292004
292788
  function defineAddKindRegistryEntry(entry) {
292005
292789
  return entry;
292006
292790
  }
292791
+ function createNamedExecutionPlan(context, options) {
292792
+ const name2 = options.name ?? requireAddKindName(context, options.missingNameMessage);
292793
+ return {
292794
+ execute: (cwd) => options.execute({ cwd, name: name2 }),
292795
+ getValues: options.getValues,
292796
+ ...options.getWarnings ? { getWarnings: options.getWarnings } : {},
292797
+ ...options.warnLine ? { warnLine: options.warnLine } : {}
292798
+ };
292799
+ }
292007
292800
  function isAddPersistenceTemplate(template) {
292008
292801
  return template === "persistence" || template === "compound";
292009
292802
  }
@@ -292024,24 +292817,26 @@ var ADD_KIND_REGISTRY = {
292024
292817
  description: "Add an opt-in DataViews-powered admin screen",
292025
292818
  nameLabel: "Admin view name",
292026
292819
  async prepareExecution(context) {
292027
- const name2 = requireAddKindName(context, "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug>].");
292820
+ const name2 = requireAddKindName(context, "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].");
292028
292821
  const source = readOptionalStringFlag(context.flags, "source");
292029
- return {
292030
- execute: (cwd) => context.addRuntime.runAddAdminViewCommand({
292031
- adminViewName: name2,
292822
+ return createNamedExecutionPlan(context, {
292823
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddAdminViewCommand({
292824
+ adminViewName: name3,
292032
292825
  cwd,
292033
292826
  source
292034
292827
  }),
292035
292828
  getValues: (result) => ({
292036
292829
  adminViewSlug: result.adminViewSlug,
292037
292830
  ...result.source ? { source: result.source } : {}
292038
- })
292039
- };
292831
+ }),
292832
+ missingNameMessage: "`wp-typia add admin-view` requires <name>. Usage: wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>].",
292833
+ name: name2
292834
+ });
292040
292835
  },
292041
292836
  sortOrder: 10,
292042
292837
  supportsDryRun: true,
292043
- usage: "wp-typia add admin-view <name> [--source <rest-resource:slug>] [--dry-run]",
292044
- visibleFieldNames: () => ["kind", "name", "source"]
292838
+ usage: "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>] [--dry-run]",
292839
+ visibleFieldNames: () => NAME_SOURCE_VISIBLE_FIELDS
292045
292840
  }),
292046
292841
  "binding-source": defineAddKindRegistryEntry({
292047
292842
  completion: {
@@ -292063,15 +292858,11 @@ var ADD_KIND_REGISTRY = {
292063
292858
  nameLabel: "Binding source name",
292064
292859
  async prepareExecution(context) {
292065
292860
  const name2 = requireAddKindName(context, "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].");
292066
- const blockName = readOptionalStringFlag(context.flags, "block");
292067
- const attributeName = readOptionalStringFlag(context.flags, "attribute");
292068
- if (Boolean(blockName) !== Boolean(attributeName)) {
292069
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
292070
- }
292071
- return {
292072
- execute: (cwd) => context.addRuntime.runAddBindingSourceCommand({
292861
+ const [blockName, attributeName] = readOptionalPairedStringFlags(context.flags, "block", "attribute", "`wp-typia add binding-source` requires --block and --attribute to be provided together.");
292862
+ return createNamedExecutionPlan(context, {
292863
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBindingSourceCommand({
292073
292864
  attributeName,
292074
- bindingSourceName: name2,
292865
+ bindingSourceName: name3,
292075
292866
  blockName,
292076
292867
  cwd
292077
292868
  }),
@@ -292079,13 +292870,15 @@ var ADD_KIND_REGISTRY = {
292079
292870
  ...result.attributeName ? { attributeName: result.attributeName } : {},
292080
292871
  ...result.blockSlug ? { blockSlug: result.blockSlug } : {},
292081
292872
  bindingSourceSlug: result.bindingSourceSlug
292082
- })
292083
- };
292873
+ }),
292874
+ missingNameMessage: "`wp-typia add binding-source` requires <name>. Usage: wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>].",
292875
+ name: name2
292876
+ });
292084
292877
  },
292085
292878
  sortOrder: 70,
292086
292879
  supportsDryRun: true,
292087
292880
  usage: "wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--dry-run]",
292088
- visibleFieldNames: () => ["kind", "name", "block", "attribute"]
292881
+ visibleFieldNames: () => NAME_BLOCK_ATTRIBUTE_VISIBLE_FIELDS
292089
292882
  }),
292090
292883
  block: defineAddKindRegistryEntry({
292091
292884
  completion: {
@@ -292123,10 +292916,10 @@ var ADD_KIND_REGISTRY = {
292123
292916
  })), 1);
292124
292917
  }
292125
292918
  resolvedTemplateId ??= "basic";
292126
- return {
292127
- execute: (cwd) => context.addRuntime.runAddBlockCommand({
292919
+ return createNamedExecutionPlan(context, {
292920
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBlockCommand({
292128
292921
  alternateRenderTargets,
292129
- blockName: name2,
292922
+ blockName: name3,
292130
292923
  cwd,
292131
292924
  dataStorageMode,
292132
292925
  externalLayerId,
@@ -292141,8 +292934,10 @@ var ADD_KIND_REGISTRY = {
292141
292934
  templateId: result.templateId
292142
292935
  }),
292143
292936
  getWarnings: (result) => result.warnings,
292937
+ missingNameMessage: "`wp-typia add block` requires <name>. Usage: wp-typia add block <name> [--template <basic|interactivity|persistence|compound>]",
292938
+ name: name2,
292144
292939
  warnLine: context.warnLine
292145
- };
292940
+ });
292146
292941
  },
292147
292942
  sortOrder: 20,
292148
292943
  supportsDryRun: true,
@@ -292175,21 +292970,21 @@ var ADD_KIND_REGISTRY = {
292175
292970
  description: "Add a typed server/client workflow ability scaffold",
292176
292971
  nameLabel: "Ability name",
292177
292972
  async prepareExecution(context) {
292178
- const name2 = requireAddKindName(context, "`wp-typia add ability` requires <name>. Usage: wp-typia add ability <name>.");
292179
- return {
292180
- execute: (cwd) => context.addRuntime.runAddAbilityCommand({
292973
+ return createNamedExecutionPlan(context, {
292974
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddAbilityCommand({
292181
292975
  abilityName: name2,
292182
292976
  cwd
292183
292977
  }),
292184
292978
  getValues: (result) => ({
292185
292979
  abilitySlug: result.abilitySlug
292186
- })
292187
- };
292980
+ }),
292981
+ missingNameMessage: "`wp-typia add ability` requires <name>. Usage: wp-typia add ability <name>."
292982
+ });
292188
292983
  },
292189
292984
  sortOrder: 90,
292190
292985
  supportsDryRun: true,
292191
292986
  usage: "wp-typia add ability <name> [--dry-run]",
292192
- visibleFieldNames: () => ["kind", "name"]
292987
+ visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
292193
292988
  }),
292194
292989
  "editor-plugin": defineAddKindRegistryEntry({
292195
292990
  completion: {
@@ -292209,22 +293004,24 @@ var ADD_KIND_REGISTRY = {
292209
293004
  async prepareExecution(context) {
292210
293005
  const name2 = requireAddKindName(context, "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].");
292211
293006
  const slot = readOptionalStringFlag(context.flags, "slot");
292212
- return {
292213
- execute: (cwd) => context.addRuntime.runAddEditorPluginCommand({
293007
+ return createNamedExecutionPlan(context, {
293008
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddEditorPluginCommand({
292214
293009
  cwd,
292215
- editorPluginName: name2,
293010
+ editorPluginName: name3,
292216
293011
  slot
292217
293012
  }),
292218
293013
  getValues: (result) => ({
292219
293014
  editorPluginSlug: result.editorPluginSlug,
292220
293015
  slot: result.slot
292221
- })
292222
- };
293016
+ }),
293017
+ missingNameMessage: "`wp-typia add editor-plugin` requires <name>. Usage: wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>].",
293018
+ name: name2
293019
+ });
292223
293020
  },
292224
293021
  sortOrder: 120,
292225
293022
  supportsDryRun: true,
292226
293023
  usage: "wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>] [--dry-run]",
292227
- visibleFieldNames: () => ["kind", "name", "slot"]
293024
+ visibleFieldNames: () => NAME_SLOT_VISIBLE_FIELDS
292228
293025
  }),
292229
293026
  "hooked-block": defineAddKindRegistryEntry({
292230
293027
  completion: {
@@ -292244,18 +293041,12 @@ var ADD_KIND_REGISTRY = {
292244
293041
  nameLabel: "Target block",
292245
293042
  async prepareExecution(context) {
292246
293043
  const name2 = requireAddKindName(context, "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.");
292247
- const anchorBlockName = readOptionalStringFlag(context.flags, "anchor");
292248
- if (!anchorBlockName) {
292249
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
292250
- }
292251
- const position = readOptionalStringFlag(context.flags, "position");
292252
- if (!position) {
292253
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
292254
- }
292255
- return {
292256
- execute: (cwd) => context.addRuntime.runAddHookedBlockCommand({
293044
+ const anchorBlockName = requireStringFlag(context.flags, "anchor", "`wp-typia add hooked-block` requires --anchor <anchor-block-name>.");
293045
+ const position = requireStringFlag(context.flags, "position", "`wp-typia add hooked-block` requires --position <before|after|firstChild|lastChild>.");
293046
+ return createNamedExecutionPlan(context, {
293047
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddHookedBlockCommand({
292257
293048
  anchorBlockName,
292258
- blockName: name2,
293049
+ blockName: name3,
292259
293050
  cwd,
292260
293051
  position
292261
293052
  }),
@@ -292263,13 +293054,15 @@ var ADD_KIND_REGISTRY = {
292263
293054
  anchorBlockName: result.anchorBlockName,
292264
293055
  blockSlug: result.blockSlug,
292265
293056
  position: result.position
292266
- })
292267
- };
293057
+ }),
293058
+ missingNameMessage: "`wp-typia add hooked-block` requires <block-slug>. Usage: wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild>.",
293059
+ name: name2
293060
+ });
292268
293061
  },
292269
293062
  sortOrder: 110,
292270
293063
  supportsDryRun: true,
292271
293064
  usage: "wp-typia add hooked-block <block-slug> --anchor <anchor-block-name> --position <before|after|firstChild|lastChild> [--dry-run]",
292272
- visibleFieldNames: () => ["kind", "name", "anchor", "position"]
293065
+ visibleFieldNames: () => NAME_ANCHOR_POSITION_VISIBLE_FIELDS
292273
293066
  }),
292274
293067
  pattern: defineAddKindRegistryEntry({
292275
293068
  completion: {
@@ -292286,21 +293079,21 @@ var ADD_KIND_REGISTRY = {
292286
293079
  description: "Add a PHP block pattern shell",
292287
293080
  nameLabel: "Pattern name",
292288
293081
  async prepareExecution(context) {
292289
- const name2 = requireAddKindName(context, "`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>.");
292290
- return {
292291
- execute: (cwd) => context.addRuntime.runAddPatternCommand({
293082
+ return createNamedExecutionPlan(context, {
293083
+ execute: ({ cwd, name: name2 }) => context.addRuntime.runAddPatternCommand({
292292
293084
  cwd,
292293
293085
  patternName: name2
292294
293086
  }),
292295
293087
  getValues: (result) => ({
292296
293088
  patternSlug: result.patternSlug
292297
- })
292298
- };
293089
+ }),
293090
+ missingNameMessage: "`wp-typia add pattern` requires <name>. Usage: wp-typia add pattern <name>."
293091
+ });
292299
293092
  },
292300
293093
  sortOrder: 60,
292301
293094
  supportsDryRun: true,
292302
293095
  usage: "wp-typia add pattern <name> [--dry-run]",
292303
- visibleFieldNames: () => ["kind", "name"]
293096
+ visibleFieldNames: () => NAME_ONLY_VISIBLE_FIELDS
292304
293097
  }),
292305
293098
  style: defineAddKindRegistryEntry({
292306
293099
  completion: {
@@ -292319,26 +293112,25 @@ var ADD_KIND_REGISTRY = {
292319
293112
  nameLabel: "Style name",
292320
293113
  async prepareExecution(context) {
292321
293114
  const name2 = requireAddKindName(context, "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.");
292322
- const blockSlug = readOptionalStringFlag(context.flags, "block");
292323
- if (!blockSlug) {
292324
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add style` requires --block <block-slug>.");
292325
- }
292326
- return {
292327
- execute: (cwd) => context.addRuntime.runAddBlockStyleCommand({
293115
+ const blockSlug = requireStringFlag(context.flags, "block", "`wp-typia add style` requires --block <block-slug>.");
293116
+ return createNamedExecutionPlan(context, {
293117
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBlockStyleCommand({
292328
293118
  blockName: blockSlug,
292329
293119
  cwd,
292330
- styleName: name2
293120
+ styleName: name3
292331
293121
  }),
292332
293122
  getValues: (result) => ({
292333
293123
  blockSlug: result.blockSlug,
292334
293124
  styleSlug: result.styleSlug
292335
- })
292336
- };
293125
+ }),
293126
+ missingNameMessage: "`wp-typia add style` requires <name>. Usage: wp-typia add style <name> --block <block-slug>.",
293127
+ name: name2
293128
+ });
292337
293129
  },
292338
293130
  sortOrder: 40,
292339
293131
  supportsDryRun: true,
292340
293132
  usage: "wp-typia add style <name> --block <block-slug> [--dry-run]",
292341
- visibleFieldNames: () => ["kind", "name", "block"]
293133
+ visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
292342
293134
  }),
292343
293135
  transform: defineAddKindRegistryEntry({
292344
293136
  completion: {
@@ -292358,33 +293150,29 @@ var ADD_KIND_REGISTRY = {
292358
293150
  nameLabel: "Transform name",
292359
293151
  async prepareExecution(context) {
292360
293152
  const name2 = requireAddKindName(context, "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.");
292361
- const fromBlockName = readOptionalStringFlag(context.flags, "from");
292362
- if (!fromBlockName) {
292363
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add transform` requires --from <namespace/block>.");
292364
- }
292365
- const toBlockName = readOptionalStringFlag(context.flags, "to");
292366
- if (!toBlockName) {
292367
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
292368
- }
292369
- return {
292370
- execute: (cwd) => context.addRuntime.runAddBlockTransformCommand({
293153
+ const fromBlockName = requireStringFlag(context.flags, "from", "`wp-typia add transform` requires --from <namespace/block>.");
293154
+ const toBlockName = requireStringFlag(context.flags, "to", "`wp-typia add transform` requires --to <block-slug|namespace/block-slug>.");
293155
+ return createNamedExecutionPlan(context, {
293156
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddBlockTransformCommand({
292371
293157
  cwd,
292372
293158
  fromBlockName,
292373
293159
  toBlockName,
292374
- transformName: name2
293160
+ transformName: name3
292375
293161
  }),
292376
293162
  getValues: (result) => ({
292377
293163
  blockSlug: result.blockSlug,
292378
293164
  fromBlockName: result.fromBlockName,
292379
293165
  toBlockName: result.toBlockName,
292380
293166
  transformSlug: result.transformSlug
292381
- })
292382
- };
293167
+ }),
293168
+ missingNameMessage: "`wp-typia add transform` requires <name>. Usage: wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>.",
293169
+ name: name2
293170
+ });
292383
293171
  },
292384
293172
  sortOrder: 50,
292385
293173
  supportsDryRun: true,
292386
293174
  usage: "wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug> [--dry-run]",
292387
- visibleFieldNames: () => ["kind", "name", "from", "to"]
293175
+ visibleFieldNames: () => NAME_FROM_TO_VISIBLE_FIELDS
292388
293176
  }),
292389
293177
  "rest-resource": defineAddKindRegistryEntry({
292390
293178
  completion: {
@@ -292406,24 +293194,26 @@ var ADD_KIND_REGISTRY = {
292406
293194
  const name2 = requireAddKindName(context, "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].");
292407
293195
  const methods = readOptionalStringFlag(context.flags, "methods");
292408
293196
  const namespace = readOptionalStringFlag(context.flags, "namespace");
292409
- return {
292410
- execute: (cwd) => context.addRuntime.runAddRestResourceCommand({
293197
+ return createNamedExecutionPlan(context, {
293198
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddRestResourceCommand({
292411
293199
  cwd,
292412
293200
  methods,
292413
293201
  namespace,
292414
- restResourceName: name2
293202
+ restResourceName: name3
292415
293203
  }),
292416
293204
  getValues: (result) => ({
292417
293205
  methods: result.methods.join(", "),
292418
293206
  namespace: result.namespace,
292419
293207
  restResourceSlug: result.restResourceSlug
292420
- })
292421
- };
293208
+ }),
293209
+ missingNameMessage: "`wp-typia add rest-resource` requires <name>. Usage: wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>].",
293210
+ name: name2
293211
+ });
292422
293212
  },
292423
293213
  sortOrder: 80,
292424
293214
  supportsDryRun: true,
292425
293215
  usage: "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create,update,delete>] [--dry-run]",
292426
- visibleFieldNames: () => ["kind", "name", "namespace", "methods"]
293216
+ visibleFieldNames: () => NAME_NAMESPACE_METHODS_VISIBLE_FIELDS
292427
293217
  }),
292428
293218
  "ai-feature": defineAddKindRegistryEntry({
292429
293219
  completion: {
@@ -292443,9 +293233,9 @@ var ADD_KIND_REGISTRY = {
292443
293233
  async prepareExecution(context) {
292444
293234
  const name2 = requireAddKindName(context, "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].");
292445
293235
  const namespace = readOptionalStringFlag(context.flags, "namespace");
292446
- return {
292447
- execute: (cwd) => context.addRuntime.runAddAiFeatureCommand({
292448
- aiFeatureName: name2,
293236
+ return createNamedExecutionPlan(context, {
293237
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddAiFeatureCommand({
293238
+ aiFeatureName: name3,
292449
293239
  cwd,
292450
293240
  namespace
292451
293241
  }),
@@ -292454,13 +293244,15 @@ var ADD_KIND_REGISTRY = {
292454
293244
  namespace: result.namespace
292455
293245
  }),
292456
293246
  getWarnings: (result) => result.warnings,
293247
+ missingNameMessage: "`wp-typia add ai-feature` requires <name>. Usage: wp-typia add ai-feature <name> [--namespace <vendor/v1>].",
293248
+ name: name2,
292457
293249
  warnLine: context.warnLine
292458
- };
293250
+ });
292459
293251
  },
292460
293252
  sortOrder: 100,
292461
293253
  supportsDryRun: true,
292462
293254
  usage: "wp-typia add ai-feature <name> [--namespace <vendor/v1>] [--dry-run]",
292463
- visibleFieldNames: () => ["kind", "name", "namespace"]
293255
+ visibleFieldNames: () => NAME_NAMESPACE_VISIBLE_FIELDS
292464
293256
  }),
292465
293257
  variation: defineAddKindRegistryEntry({
292466
293258
  completion: {
@@ -292479,29 +293271,27 @@ var ADD_KIND_REGISTRY = {
292479
293271
  nameLabel: "Variation name",
292480
293272
  async prepareExecution(context) {
292481
293273
  const name2 = requireAddKindName(context, "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>");
292482
- const blockSlug = readOptionalStringFlag(context.flags, "block");
292483
- if (!blockSlug) {
292484
- throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, "`wp-typia add variation` requires --block <block-slug>.");
292485
- }
292486
- return {
292487
- execute: (cwd) => context.addRuntime.runAddVariationCommand({
293274
+ const blockSlug = requireStringFlag(context.flags, "block", "`wp-typia add variation` requires --block <block-slug>.");
293275
+ return createNamedExecutionPlan(context, {
293276
+ execute: ({ cwd, name: name3 }) => context.addRuntime.runAddVariationCommand({
292488
293277
  blockName: blockSlug,
292489
293278
  cwd,
292490
- variationName: name2
293279
+ variationName: name3
292491
293280
  }),
292492
293281
  getValues: (result) => ({
292493
293282
  blockSlug: result.blockSlug,
292494
293283
  variationSlug: result.variationSlug
292495
- })
292496
- };
293284
+ }),
293285
+ missingNameMessage: "`wp-typia add variation` requires <name>. Usage: wp-typia add variation <name> --block <block-slug>",
293286
+ name: name2
293287
+ });
292497
293288
  },
292498
293289
  sortOrder: 30,
292499
293290
  supportsDryRun: true,
292500
293291
  usage: "wp-typia add variation <name> --block <block-slug> [--dry-run]",
292501
- visibleFieldNames: () => ["kind", "name", "block"]
293292
+ visibleFieldNames: () => NAME_BLOCK_VISIBLE_FIELDS
292502
293293
  })
292503
293294
  };
292504
- var ADD_KIND_IDS = Object.keys(ADD_KIND_REGISTRY).sort((left, right) => ADD_KIND_REGISTRY[left].sortOrder - ADD_KIND_REGISTRY[right].sortOrder);
292505
293295
  function isAddKindId(value2) {
292506
293296
  return typeof value2 === "string" && ADD_KIND_IDS.includes(value2);
292507
293297
  }
@@ -292659,7 +293449,7 @@ import path10 from "path";
292659
293449
  // package.json
292660
293450
  var package_default2 = {
292661
293451
  name: "wp-typia",
292662
- version: "0.21.0",
293452
+ version: "0.22.1",
292663
293453
  description: "Canonical CLI package for wp-typia scaffolding and project workflows",
292664
293454
  packageManager: "bun@1.3.11",
292665
293455
  type: "module",
@@ -292729,7 +293519,7 @@ var package_default2 = {
292729
293519
  "@bunli/tui": "0.6.0",
292730
293520
  "@bunli/utils": "0.6.0",
292731
293521
  "@wp-typia/api-client": "^0.4.5",
292732
- "@wp-typia/project-tools": "0.21.0",
293522
+ "@wp-typia/project-tools": "0.22.1",
292733
293523
  "better-result": "^2.7.0",
292734
293524
  react: "^19.2.5",
292735
293525
  "react-dom": "^19.2.5",
@@ -292899,19 +293689,33 @@ function buildStructuredCompletionSuccessPayload(command, completion, metadata2
292899
293689
  command,
292900
293690
  ...serializedCompletion ? {
292901
293691
  completion: serializedCompletion,
292902
- files: extractPlannedFiles(serializedCompletion),
292903
- nextSteps: serializedCompletion.nextSteps,
292904
- optionalLines: serializedCompletion.optionalLines,
292905
- optionalNote: serializedCompletion.optionalNote,
292906
- optionalTitle: serializedCompletion.optionalTitle,
292907
- preambleLines: serializedCompletion.preambleLines,
292908
- summaryLines: serializedCompletion.summaryLines,
292909
- title: serializedCompletion.title,
292910
- warnings: serializedCompletion.warningLines
293692
+ files: extractPlannedFiles(serializedCompletion)
292911
293693
  } : {}
292912
293694
  }
292913
293695
  };
292914
293696
  }
293697
+ function buildStructuredInitSuccessPayload(plan) {
293698
+ const completion = serializeCompletionPayload(buildInitCompletionPayload(plan));
293699
+ const files = Array.from(new Set([
293700
+ ...plan.plannedFiles.map((filePlan) => filePlan.path),
293701
+ ...plan.commandMode === "preview-only" ? plan.generatedArtifacts : []
293702
+ ]));
293703
+ return {
293704
+ ok: true,
293705
+ data: {
293706
+ command: "init",
293707
+ completion,
293708
+ detectedLayout: plan.detectedLayout,
293709
+ files: toNonEmptyArray(files),
293710
+ mode: plan.commandMode === "apply" ? "apply" : "preview",
293711
+ packageManager: plan.packageManager,
293712
+ plan,
293713
+ projectDir: plan.projectDir,
293714
+ status: plan.status,
293715
+ summary: plan.summary
293716
+ }
293717
+ };
293718
+ }
292915
293719
  function formatCreateProgressLine(payload, markerOptions) {
292916
293720
  return formatOutputMarker("progress", `${payload.title}: ${payload.detail}`, markerOptions);
292917
293721
  }
@@ -294361,7 +295165,7 @@ var initCommand = defineCommand({
294361
295165
  projectDir: args.positional[0]
294362
295166
  }, { emitOutput: !prefersStructuredOutput });
294363
295167
  if (prefersStructuredOutput) {
294364
- args.output({ init: plan });
295168
+ args.output(buildStructuredInitSuccessPayload(plan));
294365
295169
  }
294366
295170
  } catch (error48) {
294367
295171
  emitCliDiagnosticFailure(args, {
@@ -294380,7 +295184,7 @@ init_cli_diagnostics();
294380
295184
 
294381
295185
  // src/mcp.ts
294382
295186
  import fs50 from "fs/promises";
294383
- import path65 from "path";
295187
+ import path66 from "path";
294384
295188
 
294385
295189
  // ../../node_modules/.bun/@bunli+plugin-mcp@0.2.5+ef72ce197b058209/node_modules/@bunli/plugin-mcp/src/errors.ts
294386
295190
  class SchemaConversionError extends TaggedError("SchemaConversionError")() {
@@ -294908,7 +295712,7 @@ function isToolGroup(value2) {
294908
295712
  return isObject3(value2) && typeof value2.namespace === "string" && Array.isArray(value2.tools) && value2.tools.every(isTool);
294909
295713
  }
294910
295714
  async function readSchemaSource(cwd, source) {
294911
- const schemaPath = path65.resolve(cwd, source.path);
295715
+ const schemaPath = path66.resolve(cwd, source.path);
294912
295716
  const raw = await fs50.readFile(schemaPath, "utf8");
294913
295717
  const parsed = JSON.parse(raw);
294914
295718
  if (isToolGroup(parsed)) {
@@ -294925,7 +295729,7 @@ async function readSchemaSource(cwd, source) {
294925
295729
  async function loadMcpToolGroups(cwd, schemaSources) {
294926
295730
  return Promise.all(schemaSources.map((source) => readSchemaSource(cwd, source)));
294927
295731
  }
294928
- async function syncMcpSchemas(cwd, schemaSources, outputDir = path65.join(cwd, ".bunli", "mcp")) {
295732
+ async function syncMcpSchemas(cwd, schemaSources, outputDir = path66.join(cwd, ".bunli", "mcp")) {
294929
295733
  const groups = await loadMcpToolGroups(cwd, schemaSources);
294930
295734
  const result = await generateMCPTypes({
294931
295735
  outputDir,
@@ -294948,7 +295752,7 @@ async function syncMcpSchemas(cwd, schemaSources, outputDir = path65.join(cwd, "
294948
295752
  }
294949
295753
  }
294950
295754
  await fs50.mkdir(outputDir, { recursive: true });
294951
- await fs50.writeFile(path65.join(outputDir, "registry.json"), `${JSON.stringify(registry2, null, 2)}
295755
+ await fs50.writeFile(path66.join(outputDir, "registry.json"), `${JSON.stringify(registry2, null, 2)}
294952
295756
  `, "utf8");
294953
295757
  return {
294954
295758
  commandCount: registry2.reduce((count, group) => count + group.tools.length, 0),
@@ -295009,7 +295813,9 @@ var mcpCommand = defineCommand({
295009
295813
  emitCliDiagnosticFailure(args, {
295010
295814
  code: CLI_DIAGNOSTIC_CODES.INVALID_COMMAND,
295011
295815
  command: "mcp",
295012
- detailLines: [`Unknown mcp subcommand "${subcommand}". Expected list or sync.`]
295816
+ detailLines: [
295817
+ `Unknown mcp subcommand "${subcommand}". Expected list or sync.`
295818
+ ]
295013
295819
  });
295014
295820
  } catch (error48) {
295015
295821
  emitCliDiagnosticFailure(args, {
@@ -295019,12 +295825,7 @@ var mcpCommand = defineCommand({
295019
295825
  }
295020
295826
  },
295021
295827
  name: "mcp",
295022
- options: {
295023
- "output-dir": {
295024
- description: "Output directory for generated MCP metadata during `mcp sync`.",
295025
- schema: exports_external.string().optional()
295026
- }
295027
- }
295828
+ options: buildCommandOptions(MCP_OPTION_METADATA)
295028
295829
  });
295029
295830
  var mcp_default = mcpCommand;
295030
295831
 
@@ -295270,4 +296071,4 @@ export {
295270
296071
  cli
295271
296072
  };
295272
296073
 
295273
- //# debugId=BEEA7448AE2433F864756E2164756E21
296074
+ //# debugId=7FC90D52A694344264756E2164756E21