@wp-typia/project-tools 0.20.2 → 0.22.0

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.
Files changed (60) hide show
  1. package/dist/runtime/ai-feature-capability.js +2 -33
  2. package/dist/runtime/built-in-block-artifact-types.js +11 -0
  3. package/dist/runtime/built-in-block-code-artifacts.js +5 -1
  4. package/dist/runtime/built-in-block-code-templates/interactivity.d.ts +4 -3
  5. package/dist/runtime/built-in-block-code-templates/interactivity.js +259 -100
  6. package/dist/runtime/built-in-block-code-templates.d.ts +1 -1
  7. package/dist/runtime/built-in-block-code-templates.js +1 -1
  8. package/dist/runtime/cli-add-shared.d.ts +74 -5
  9. package/dist/runtime/cli-add-shared.js +61 -11
  10. package/dist/runtime/cli-add-workspace-ability.js +14 -61
  11. package/dist/runtime/cli-add-workspace-admin-view.d.ts +25 -0
  12. package/dist/runtime/cli-add-workspace-admin-view.js +1401 -0
  13. package/dist/runtime/cli-add-workspace-ai-anchors.js +2 -5
  14. package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +0 -4
  15. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +7 -17
  16. package/dist/runtime/cli-add-workspace-ai.js +4 -6
  17. package/dist/runtime/cli-add-workspace-assets.d.ts +13 -5
  18. package/dist/runtime/cli-add-workspace-assets.js +290 -106
  19. package/dist/runtime/cli-add-workspace-rest-anchors.js +2 -5
  20. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +0 -1
  21. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +7 -14
  22. package/dist/runtime/cli-add-workspace-rest.js +4 -6
  23. package/dist/runtime/cli-add-workspace.d.ts +58 -1
  24. package/dist/runtime/cli-add-workspace.js +588 -18
  25. package/dist/runtime/cli-add.d.ts +1 -1
  26. package/dist/runtime/cli-add.js +1 -1
  27. package/dist/runtime/cli-core.d.ts +8 -5
  28. package/dist/runtime/cli-core.js +7 -4
  29. package/dist/runtime/cli-diagnostics.d.ts +83 -1
  30. package/dist/runtime/cli-diagnostics.js +85 -2
  31. package/dist/runtime/cli-doctor-workspace.js +553 -13
  32. package/dist/runtime/cli-doctor.d.ts +4 -2
  33. package/dist/runtime/cli-doctor.js +2 -1
  34. package/dist/runtime/cli-help.js +22 -9
  35. package/dist/runtime/cli-init.d.ts +67 -3
  36. package/dist/runtime/cli-init.js +603 -64
  37. package/dist/runtime/cli-validation.js +4 -3
  38. package/dist/runtime/external-layer-selection.d.ts +8 -2
  39. package/dist/runtime/external-layer-selection.js +3 -4
  40. package/dist/runtime/index.d.ts +9 -4
  41. package/dist/runtime/index.js +7 -3
  42. package/dist/runtime/package-json-types.d.ts +12 -0
  43. package/dist/runtime/package-json-types.js +1 -0
  44. package/dist/runtime/package-versions.d.ts +30 -2
  45. package/dist/runtime/package-versions.js +59 -1
  46. package/dist/runtime/php-utils.d.ts +16 -0
  47. package/dist/runtime/php-utils.js +59 -0
  48. package/dist/runtime/scaffold-answer-resolution.js +7 -6
  49. package/dist/runtime/scaffold-apply-utils.d.ts +2 -3
  50. package/dist/runtime/scaffold-apply-utils.js +3 -43
  51. package/dist/runtime/scaffold-compatibility.d.ts +2 -2
  52. package/dist/runtime/scaffold-compatibility.js +22 -48
  53. package/dist/runtime/template-source-cache.d.ts +112 -0
  54. package/dist/runtime/template-source-cache.js +434 -0
  55. package/dist/runtime/template-source-seeds.js +319 -53
  56. package/dist/runtime/version-floor.d.ts +26 -0
  57. package/dist/runtime/version-floor.js +56 -0
  58. package/dist/runtime/workspace-inventory.d.ts +44 -2
  59. package/dist/runtime/workspace-inventory.js +138 -5
  60. package/package.json +4 -3
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { CLI_DIAGNOSTIC_CODES, createCliDiagnosticCodeError, } from "./cli-diagnostics.js";
3
4
  /**
4
5
  * Normalize one optional CLI string flag by trimming whitespace and collapsing
5
6
  * empty strings to `undefined`.
@@ -44,7 +45,7 @@ export function resolveLocalCliPathOption(options) {
44
45
  }
45
46
  const resolvedPath = path.resolve(options.cwd, normalizedValue);
46
47
  if (!fs.existsSync(resolvedPath)) {
47
- throw new Error(`\`${options.label}\` path does not exist: ${resolvedPath}. Check the path relative to ${options.cwd}.`);
48
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `\`${options.label}\` path does not exist: ${resolvedPath}. Check the path relative to ${options.cwd}.`);
48
49
  }
49
50
  return resolvedPath;
50
51
  }
@@ -58,7 +59,7 @@ export function resolveLocalCliPathOption(options) {
58
59
  */
59
60
  export function assertExternalLayerCompositionOptions(options) {
60
61
  if (options.externalLayerId && !options.externalLayerSource) {
61
- throw new Error("externalLayerId requires externalLayerSource when composing built-in template layers.");
62
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, "externalLayerId requires externalLayerSource when composing built-in template layers.");
62
63
  }
63
64
  }
64
65
  /**
@@ -85,7 +86,7 @@ export function assertBuiltInTemplateVariantAllowed(options) {
85
86
  if (!options.variant) {
86
87
  return;
87
88
  }
88
- throw new Error(createBuiltInVariantErrorMessage({
89
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, createBuiltInVariantErrorMessage({
89
90
  templateId: options.templateId,
90
91
  variant: options.variant,
91
92
  }));
@@ -1,4 +1,5 @@
1
- import { type SelectableExternalTemplateLayer } from "./template-layers.js";
1
+ import { resolveTemplateSeed } from "./template-source.js";
2
+ import { listSelectableExternalTemplateLayers, type SelectableExternalTemplateLayer } from "./template-layers.js";
2
3
  export interface ExternalLayerSelectionOption extends SelectableExternalTemplateLayer {
3
4
  }
4
5
  export interface ResolvedExternalLayerSelection {
@@ -6,9 +7,14 @@ export interface ResolvedExternalLayerSelection {
6
7
  externalLayerId?: string;
7
8
  externalLayerSource?: string;
8
9
  }
9
- export declare function resolveOptionalInteractiveExternalLayerId({ callerCwd, externalLayerId, externalLayerSource, selectExternalLayerId, }: {
10
+ type ResolveExternalTemplateSeed = typeof resolveTemplateSeed;
11
+ type ListExternalTemplateLayers = typeof listSelectableExternalTemplateLayers;
12
+ export declare function resolveOptionalInteractiveExternalLayerId({ callerCwd, externalLayerId, externalLayerSource, listExternalTemplateLayers, resolveExternalTemplateSeed, selectExternalLayerId, }: {
10
13
  callerCwd: string;
11
14
  externalLayerId?: string;
12
15
  externalLayerSource?: string;
16
+ listExternalTemplateLayers?: ListExternalTemplateLayers;
17
+ resolveExternalTemplateSeed?: ResolveExternalTemplateSeed;
13
18
  selectExternalLayerId?: (options: ExternalLayerSelectionOption[]) => Promise<string>;
14
19
  }): Promise<ResolvedExternalLayerSelection>;
20
+ export {};
@@ -1,15 +1,15 @@
1
1
  import { parseTemplateLocator, resolveTemplateSeed, } from "./template-source.js";
2
2
  import { listSelectableExternalTemplateLayers, } from "./template-layers.js";
3
- export async function resolveOptionalInteractiveExternalLayerId({ callerCwd, externalLayerId, externalLayerSource, selectExternalLayerId, }) {
3
+ export async function resolveOptionalInteractiveExternalLayerId({ callerCwd, externalLayerId, externalLayerSource, listExternalTemplateLayers = listSelectableExternalTemplateLayers, resolveExternalTemplateSeed = resolveTemplateSeed, selectExternalLayerId, }) {
4
4
  if (!externalLayerSource || externalLayerId || !selectExternalLayerId) {
5
5
  return {
6
6
  externalLayerId,
7
7
  externalLayerSource,
8
8
  };
9
9
  }
10
- const layerSeed = await resolveTemplateSeed(parseTemplateLocator(externalLayerSource), callerCwd);
10
+ const layerSeed = await resolveExternalTemplateSeed(parseTemplateLocator(externalLayerSource), callerCwd);
11
11
  try {
12
- const selectableLayers = await listSelectableExternalTemplateLayers(layerSeed.rootDir);
12
+ const selectableLayers = await listExternalTemplateLayers(layerSeed.rootDir);
13
13
  if (selectableLayers.length <= 1) {
14
14
  await layerSeed.cleanup?.();
15
15
  return {
@@ -25,7 +25,6 @@ export async function resolveOptionalInteractiveExternalLayerId({ callerCwd, ext
25
25
  externalLayerSource: layerSeed.rootDir,
26
26
  };
27
27
  }
28
- await layerSeed.cleanup?.();
29
28
  throw new Error(`Unknown external layer "${selectedLayerId}". Expected one of: ${selectableLayers.map((layer) => layer.id).join(", ")}`);
30
29
  }
31
30
  catch (error) {
@@ -5,8 +5,11 @@
5
5
  * CLI while keeping reusable project logic out of the CLI package itself.
6
6
  * Consumers should prefer these exports for scaffold, add, migrate, doctor,
7
7
  * and workspace-aware helpers such as `getWorkspaceBlockSelectOptions`,
8
- * `runAddBlockCommand`, `runAddVariationCommand`, `runAddPatternCommand`,
9
- * `runAddBindingSourceCommand`, `runAddEditorPluginCommand`,
8
+ * `runAddBlockCommand`, `runAddBlockStyleCommand`,
9
+ * `runAddBlockTransformCommand`, `runAddVariationCommand`,
10
+ * `runAddPatternCommand`, `runAddBindingSourceCommand`,
11
+ * `runAddEditorPluginCommand`,
12
+ * `runAddAdminViewCommand`,
10
13
  * `runAddHookedBlockCommand`,
11
14
  * `HOOKED_BLOCK_POSITION_IDS`, and `runDoctor`.
12
15
  */
@@ -26,7 +29,9 @@ export { manifestAttributeToJsonSchema, projectJsonSchemaDocument, manifestToJso
26
29
  export { buildCompoundChildStarterManifestDocument, getStarterManifestFiles, stringifyStarterManifest, } from "./starter-manifests.js";
27
30
  export type { EndpointAuthIntent, EndpointOpenApiAuthMode, EndpointOpenApiContractDocument, EndpointOpenApiDocumentOptions, EndpointOpenApiEndpointDefinition, EndpointOpenApiMethod, EndpointWordPressAuthDefinition, EndpointWordPressAuthMechanism, JsonSchemaDocument, JsonSchemaProjectionProfile, JsonSchemaObject, NormalizedEndpointAuthDefinition, OpenApiDocument, OpenApiInfo, OpenApiOperation, OpenApiParameter, OpenApiPathItem, OpenApiSecurityScheme, } from "./schema-core.js";
28
31
  export { PACKAGE_MANAGER_IDS, PACKAGE_MANAGERS, formatPackageExecCommand, formatInstallCommand, formatRunScript, getPackageManager, getPackageManagerSelectOptions, transformPackageManagerText, } from "./package-managers.js";
32
+ export { clearPackageVersionsCache, getPackageVersions, invalidatePackageVersionsCache, } from "./package-versions.js";
33
+ export type { PackageVersions } from "./package-versions.js";
29
34
  export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOptions, listTemplates, } from "./template-registry.js";
30
35
  export { STALE_TEMP_ROOT_MAX_AGE_MS, WP_TYPIA_TEMP_ROOT_PREFIX, cleanupManagedTempRoot, cleanupStaleTempRoots, createManagedTempRoot, getTrackedTempRoots, } from "./temp-roots.js";
31
- export { createReadlinePrompt, createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
32
- export type { CliDiagnosticMessage, DoctorCheck, EditorPluginSlotId, HookedBlockPositionId, ReadlinePrompt, } from "./cli-core.js";
36
+ export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
37
+ export type { CliDiagnosticCode, CliDiagnosticCodeError, CliDiagnosticMessage, DoctorCheck, EditorPluginSlotId, HookedBlockPositionId, ReadlinePrompt, } from "./cli-core.js";
@@ -5,8 +5,11 @@
5
5
  * CLI while keeping reusable project logic out of the CLI package itself.
6
6
  * Consumers should prefer these exports for scaffold, add, migrate, doctor,
7
7
  * and workspace-aware helpers such as `getWorkspaceBlockSelectOptions`,
8
- * `runAddBlockCommand`, `runAddVariationCommand`, `runAddPatternCommand`,
9
- * `runAddBindingSourceCommand`, `runAddEditorPluginCommand`,
8
+ * `runAddBlockCommand`, `runAddBlockStyleCommand`,
9
+ * `runAddBlockTransformCommand`, `runAddVariationCommand`,
10
+ * `runAddPatternCommand`, `runAddBindingSourceCommand`,
11
+ * `runAddEditorPluginCommand`,
12
+ * `runAddAdminViewCommand`,
10
13
  * `runAddHookedBlockCommand`,
11
14
  * `HOOKED_BLOCK_POSITION_IDS`, and `runDoctor`.
12
15
  */
@@ -20,6 +23,7 @@ export { parseWorkspacePackageManagerId, resolveWorkspaceProject, tryResolveWork
20
23
  export { manifestAttributeToJsonSchema, projectJsonSchemaDocument, manifestToJsonSchema, manifestToOpenApi, normalizeEndpointAuthDefinition, } from "./schema-core.js";
21
24
  export { buildCompoundChildStarterManifestDocument, getStarterManifestFiles, stringifyStarterManifest, } from "./starter-manifests.js";
22
25
  export { PACKAGE_MANAGER_IDS, PACKAGE_MANAGERS, formatPackageExecCommand, formatInstallCommand, formatRunScript, getPackageManager, getPackageManagerSelectOptions, transformPackageManagerText, } from "./package-managers.js";
26
+ export { clearPackageVersionsCache, getPackageVersions, invalidatePackageVersionsCache, } from "./package-versions.js";
23
27
  export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOptions, listTemplates, } from "./template-registry.js";
24
28
  export { STALE_TEMP_ROOT_MAX_AGE_MS, WP_TYPIA_TEMP_ROOT_PREFIX, cleanupManagedTempRoot, cleanupStaleTempRoots, createManagedTempRoot, getTrackedTempRoots, } from "./temp-roots.js";
25
- export { createReadlinePrompt, createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
29
+ export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
@@ -0,0 +1,12 @@
1
+ export interface GeneratedPackageJson {
2
+ dependencies?: Record<string, string>;
3
+ devDependencies?: Record<string, string>;
4
+ packageManager?: string;
5
+ scripts?: Record<string, string>;
6
+ wpTypia?: {
7
+ projectType?: string;
8
+ templatePackage?: string;
9
+ [key: string]: unknown;
10
+ };
11
+ [key: string]: unknown;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,12 +1,29 @@
1
- interface PackageVersions {
1
+ export interface PackageVersions {
2
2
  apiClientPackageVersion: string;
3
3
  blockRuntimePackageVersion: string;
4
4
  blockTypesPackageVersion: string;
5
5
  projectToolsPackageVersion: string;
6
6
  restPackageVersion: string;
7
+ tsxPackageVersion: string;
8
+ typiaPackageVersion: string;
9
+ typiaUnpluginPackageVersion: string;
10
+ typescriptPackageVersion: string;
7
11
  wpTypiaPackageExactVersion: string;
8
12
  wpTypiaPackageVersion: string;
9
13
  }
14
+ /**
15
+ * Explicit fallback ranges for managed WordPress-facing workspace dependencies.
16
+ *
17
+ * These remain centralized here even when individual scaffold flows resolve a
18
+ * fresher local or installed manifest version first, so add-command defaults do
19
+ * not drift across runtime modules.
20
+ */
21
+ export declare const DEFAULT_WORDPRESS_ABILITIES_VERSION = "^0.10.0";
22
+ export declare const DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION = "^0.9.0";
23
+ export declare const DEFAULT_WORDPRESS_CORE_DATA_VERSION = "^7.44.0";
24
+ export declare const DEFAULT_WORDPRESS_DATA_VERSION = "^9.28.0";
25
+ export declare const DEFAULT_WORDPRESS_DATAVIEWS_VERSION = "^14.1.0";
26
+ export declare const DEFAULT_WP_TYPIA_DATAVIEWS_VERSION = "^0.1.0";
10
27
  /**
11
28
  * Clears the in-memory cache used by `getPackageVersions()`.
12
29
  *
@@ -14,6 +31,17 @@ interface PackageVersions {
14
31
  * manifests when they want the next lookup to recompute version metadata
15
32
  * synchronously from disk.
16
33
  */
34
+ export declare function clearPackageVersionsCache(): void;
35
+ /**
36
+ * Backwards-compatible alias for integrations that adopted the original
37
+ * internal invalidation name before the public cache policy was documented.
38
+ */
17
39
  export declare function invalidatePackageVersionsCache(): void;
40
+ /**
41
+ * Resolve package versions used in generated manifests and onboarding text.
42
+ *
43
+ * The lookup keeps a process-local cached result while recomputing manifest
44
+ * fingerprints on each call. When the relevant package metadata changes on
45
+ * disk, the cache key changes and the returned version object is refreshed.
46
+ */
18
47
  export declare function getPackageVersions(): PackageVersions;
19
- export {};
@@ -5,6 +5,21 @@ import { PROJECT_TOOLS_PACKAGE_ROOT } from "./template-registry.js";
5
5
  const require = createRequire(import.meta.url);
6
6
  const DEFAULT_VERSION_RANGE = "^0.0.0";
7
7
  const DEFAULT_EXACT_VERSION = "0.0.0";
8
+ const DEFAULT_TSX_PACKAGE_VERSION = "^4.20.5";
9
+ const DEFAULT_TYPIA_UNPLUGIN_PACKAGE_VERSION = "^12.0.1";
10
+ /**
11
+ * Explicit fallback ranges for managed WordPress-facing workspace dependencies.
12
+ *
13
+ * These remain centralized here even when individual scaffold flows resolve a
14
+ * fresher local or installed manifest version first, so add-command defaults do
15
+ * not drift across runtime modules.
16
+ */
17
+ export const DEFAULT_WORDPRESS_ABILITIES_VERSION = "^0.10.0";
18
+ export const DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION = "^0.9.0";
19
+ export const DEFAULT_WORDPRESS_CORE_DATA_VERSION = "^7.44.0";
20
+ export const DEFAULT_WORDPRESS_DATA_VERSION = "^9.28.0";
21
+ export const DEFAULT_WORDPRESS_DATAVIEWS_VERSION = "^14.1.0";
22
+ export const DEFAULT_WP_TYPIA_DATAVIEWS_VERSION = "^0.1.0";
8
23
  let cachedPackageVersions = null;
9
24
  function getErrorCode(error) {
10
25
  return typeof error === "object" && error !== null && "code" in error
@@ -31,6 +46,10 @@ function normalizeExactVersion(value) {
31
46
  }
32
47
  return trimmed.replace(/^[~^<>=]+/, "");
33
48
  }
49
+ function normalizeVersionRangeWithFallback(value, fallback) {
50
+ const normalized = normalizeVersionRange(value);
51
+ return normalized === DEFAULT_VERSION_RANGE ? fallback : normalized;
52
+ }
34
53
  function createContentFingerprint(source) {
35
54
  let hash = 2166136261;
36
55
  for (let index = 0; index < source.length; index += 1) {
@@ -91,11 +110,26 @@ function composePackageVersionsCacheKey(locations) {
91
110
  * manifests when they want the next lookup to recompute version metadata
92
111
  * synchronously from disk.
93
112
  */
94
- export function invalidatePackageVersionsCache() {
113
+ export function clearPackageVersionsCache() {
95
114
  cachedPackageVersions = null;
96
115
  }
116
+ /**
117
+ * Backwards-compatible alias for integrations that adopted the original
118
+ * internal invalidation name before the public cache policy was documented.
119
+ */
120
+ export function invalidatePackageVersionsCache() {
121
+ clearPackageVersionsCache();
122
+ }
123
+ /**
124
+ * Resolve package versions used in generated manifests and onboarding text.
125
+ *
126
+ * The lookup keeps a process-local cached result while recomputing manifest
127
+ * fingerprints on each call. When the relevant package metadata changes on
128
+ * disk, the cache key changes and the returned version object is refreshed.
129
+ */
97
130
  export function getPackageVersions() {
98
131
  const createManifestLocation = resolvePackageManifestLocation(path.join(PROJECT_TOOLS_PACKAGE_ROOT, "package.json"));
132
+ const monorepoManifestLocation = resolvePackageManifestLocation(path.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "package.json"));
99
133
  const blockRuntimeManifestLocation = resolvePackageManifestLocation(path.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", "wp-typia-block-runtime", "package.json"));
100
134
  const wpTypiaManifestLocation = resolvePackageManifestLocation(path.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", "wp-typia", "package.json"));
101
135
  const installedProjectToolsManifestLocation = resolveInstalledPackageManifestLocation("@wp-typia/project-tools");
@@ -103,9 +137,14 @@ export function getPackageVersions() {
103
137
  const installedBlockRuntimeManifestLocation = resolveInstalledPackageManifestLocation("@wp-typia/block-runtime");
104
138
  const installedBlockTypesManifestLocation = resolveInstalledPackageManifestLocation("@wp-typia/block-types");
105
139
  const installedRestManifestLocation = resolveInstalledPackageManifestLocation("@wp-typia/rest");
140
+ const installedTsxManifestLocation = resolveInstalledPackageManifestLocation("tsx");
141
+ const installedTypiaManifestLocation = resolveInstalledPackageManifestLocation("typia");
142
+ const installedTypiaUnpluginManifestLocation = resolveInstalledPackageManifestLocation("@typia/unplugin");
143
+ const installedTypescriptManifestLocation = resolveInstalledPackageManifestLocation("typescript");
106
144
  const installedWpTypiaManifestLocation = resolveInstalledPackageManifestLocation("wp-typia");
107
145
  const cacheKey = composePackageVersionsCacheKey([
108
146
  createManifestLocation,
147
+ monorepoManifestLocation,
109
148
  blockRuntimeManifestLocation,
110
149
  wpTypiaManifestLocation,
111
150
  installedProjectToolsManifestLocation,
@@ -113,6 +152,10 @@ export function getPackageVersions() {
113
152
  installedBlockRuntimeManifestLocation,
114
153
  installedBlockTypesManifestLocation,
115
154
  installedRestManifestLocation,
155
+ installedTsxManifestLocation,
156
+ installedTypiaManifestLocation,
157
+ installedTypiaUnpluginManifestLocation,
158
+ installedTypescriptManifestLocation,
116
159
  installedWpTypiaManifestLocation,
117
160
  ]);
118
161
  if (cachedPackageVersions?.cacheKey === cacheKey) {
@@ -121,6 +164,7 @@ export function getPackageVersions() {
121
164
  const createManifest = readPackageManifest(createManifestLocation) ??
122
165
  readPackageManifest(installedProjectToolsManifestLocation) ??
123
166
  {};
167
+ const monorepoManifest = readPackageManifest(monorepoManifestLocation) ?? {};
124
168
  const blockRuntimeManifest = readPackageManifest(blockRuntimeManifestLocation) ??
125
169
  readPackageManifest(installedBlockRuntimeManifestLocation) ??
126
170
  {};
@@ -139,6 +183,20 @@ export function getPackageVersions() {
139
183
  projectToolsPackageVersion: normalizeVersionRange(createManifest.version),
140
184
  restPackageVersion: normalizeVersionRange(createManifest.dependencies?.["@wp-typia/rest"] ??
141
185
  readPackageManifest(installedRestManifestLocation)?.version),
186
+ tsxPackageVersion: normalizeVersionRangeWithFallback(monorepoManifest.dependencies?.tsx ??
187
+ monorepoManifest.devDependencies?.tsx ??
188
+ readPackageManifest(installedTsxManifestLocation)?.version, DEFAULT_TSX_PACKAGE_VERSION),
189
+ typiaPackageVersion: normalizeVersionRangeWithFallback(monorepoManifest.dependencies?.typia ??
190
+ monorepoManifest.devDependencies?.typia ??
191
+ createManifest.dependencies?.typia ??
192
+ readPackageManifest(installedTypiaManifestLocation)?.version, DEFAULT_VERSION_RANGE),
193
+ typiaUnpluginPackageVersion: normalizeVersionRangeWithFallback(monorepoManifest.dependencies?.["@typia/unplugin"] ??
194
+ monorepoManifest.devDependencies?.["@typia/unplugin"] ??
195
+ readPackageManifest(installedTypiaUnpluginManifestLocation)?.version, DEFAULT_TYPIA_UNPLUGIN_PACKAGE_VERSION),
196
+ typescriptPackageVersion: normalizeVersionRangeWithFallback(monorepoManifest.dependencies?.typescript ??
197
+ monorepoManifest.devDependencies?.typescript ??
198
+ createManifest.dependencies?.typescript ??
199
+ readPackageManifest(installedTypescriptManifestLocation)?.version, DEFAULT_VERSION_RANGE),
142
200
  wpTypiaPackageExactVersion: normalizeExactVersion(wpTypiaManifest.version),
143
201
  wpTypiaPackageVersion: normalizeVersionRange(wpTypiaManifest.version),
144
202
  };
@@ -0,0 +1,16 @@
1
+ export type PhpFunctionRange = {
2
+ end: number;
3
+ source: string;
4
+ start: number;
5
+ };
6
+ export type PhpFunctionRangeOptions = {
7
+ includeTrailingNewlines?: boolean;
8
+ };
9
+ export type ReplacePhpFunctionDefinitionOptions = PhpFunctionRangeOptions & {
10
+ trimReplacementStart?: boolean;
11
+ };
12
+ export declare function escapeRegex(value: string): string;
13
+ export declare function quotePhpString(value: string): string;
14
+ export declare function hasPhpFunctionDefinition(source: string, functionName: string): boolean;
15
+ export declare function findPhpFunctionRange(source: string, functionName: string, options?: PhpFunctionRangeOptions): PhpFunctionRange | null;
16
+ export declare function replacePhpFunctionDefinition(source: string, functionName: string, replacement: string, options?: ReplacePhpFunctionDefinitionOptions): string | null;
@@ -0,0 +1,59 @@
1
+ export function escapeRegex(value) {
2
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
3
+ }
4
+ export function quotePhpString(value) {
5
+ return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
6
+ }
7
+ export function hasPhpFunctionDefinition(source, functionName) {
8
+ return new RegExp(`function\\s+${escapeRegex(functionName)}\\s*\\(`, "u").test(source);
9
+ }
10
+ export function findPhpFunctionRange(source, functionName, options = {}) {
11
+ const signaturePattern = new RegExp(`function\\s+${escapeRegex(functionName)}\\s*\\([^)]*\\)\\s*(?::\\s*[^{};]+)?\\s*\\{`, "u");
12
+ const signatureMatch = signaturePattern.exec(source);
13
+ if (!signatureMatch) {
14
+ return null;
15
+ }
16
+ const functionStart = signatureMatch.index;
17
+ const openBraceOffset = signatureMatch[0].lastIndexOf("{");
18
+ if (openBraceOffset === -1) {
19
+ return null;
20
+ }
21
+ const openBraceIndex = functionStart + openBraceOffset;
22
+ let depth = 0;
23
+ for (let index = openBraceIndex; index < source.length; index += 1) {
24
+ const character = source[index];
25
+ if (character === "{") {
26
+ depth += 1;
27
+ continue;
28
+ }
29
+ if (character !== "}") {
30
+ continue;
31
+ }
32
+ depth -= 1;
33
+ if (depth === 0) {
34
+ let end = index + 1;
35
+ if (options.includeTrailingNewlines ?? true) {
36
+ while (end < source.length && /[\r\n]/u.test(source[end] ?? "")) {
37
+ end += 1;
38
+ }
39
+ }
40
+ return {
41
+ end,
42
+ source: source.slice(functionStart, end),
43
+ start: functionStart,
44
+ };
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+ export function replacePhpFunctionDefinition(source, functionName, replacement, options = {}) {
50
+ const functionRange = findPhpFunctionRange(source, functionName, options);
51
+ if (!functionRange) {
52
+ return null;
53
+ }
54
+ return [
55
+ source.slice(0, functionRange.start),
56
+ options.trimReplacementStart ? replacement.trimStart() : replacement,
57
+ source.slice(functionRange.end),
58
+ ].join("");
59
+ }
@@ -2,6 +2,7 @@ import { execSync } from 'node:child_process';
2
2
  import path from 'node:path';
3
3
  import { PACKAGE_MANAGER_IDS, getPackageManager, } from './package-managers.js';
4
4
  import { normalizeBlockSlug, resolveScaffoldIdentifiers, validateBlockSlug, validateNamespace, } from './scaffold-identifiers.js';
5
+ import { CLI_DIAGNOSTIC_CODES, createCliDiagnosticCodeError, } from './cli-diagnostics.js';
5
6
  import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, TEMPLATE_IDS, getTemplateById, isBuiltInTemplateId, } from './template-registry.js';
6
7
  import { getRemovedBuiltInTemplateMessage, isRemovedBuiltInTemplateId, } from './template-defaults.js';
7
8
  import { parseNpmTemplateLocator } from './template-source-locators.js';
@@ -75,7 +76,7 @@ function normalizeQueryPostType(value) {
75
76
  }
76
77
  const validationResult = validateQueryPostType(value);
77
78
  if (validationResult !== true) {
78
- throw new Error(validationResult);
79
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, validationResult);
79
80
  }
80
81
  return value.trim().toLowerCase();
81
82
  }
@@ -163,7 +164,7 @@ export async function resolveTemplateId({ templateId, yes = false, isInteractive
163
164
  if (templateId) {
164
165
  const normalizedTemplateId = normalizeTemplateSelection(templateId);
165
166
  if (isRemovedBuiltInTemplateId(templateId)) {
166
- throw new Error(getRemovedBuiltInTemplateMessage(templateId));
167
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.UNKNOWN_TEMPLATE, getRemovedBuiltInTemplateMessage(templateId));
167
168
  }
168
169
  if (normalizedTemplateId === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE) {
169
170
  return normalizedTemplateId;
@@ -173,10 +174,10 @@ export async function resolveTemplateId({ templateId, yes = false, isInteractive
173
174
  }
174
175
  const mistypedBuiltInTemplateMessage = getMistypedBuiltInTemplateMessage(templateId);
175
176
  if (mistypedBuiltInTemplateMessage) {
176
- throw new Error(mistypedBuiltInTemplateMessage);
177
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.UNKNOWN_TEMPLATE, mistypedBuiltInTemplateMessage);
177
178
  }
178
179
  if (!looksLikeExplicitExternalTemplateLocator(normalizedTemplateId)) {
179
- throw new Error(getUnknownTemplateMessage(templateId));
180
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.UNKNOWN_TEMPLATE, getUnknownTemplateMessage(templateId));
180
181
  }
181
182
  return normalizedTemplateId;
182
183
  }
@@ -184,7 +185,7 @@ export async function resolveTemplateId({ templateId, yes = false, isInteractive
184
185
  return 'basic';
185
186
  }
186
187
  if (!isInteractive || !selectTemplate) {
187
- throw new Error(`Template is required in non-interactive mode. Use ${TEMPLATE_SELECTION_HINT}.`);
188
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `Template is required in non-interactive mode. Use ${TEMPLATE_SELECTION_HINT}.`);
188
189
  }
189
190
  return normalizeTemplateSelection(await selectTemplate());
190
191
  }
@@ -202,7 +203,7 @@ export async function resolvePackageManagerId({ packageManager, yes = false, isI
202
203
  return 'npm';
203
204
  }
204
205
  if (!isInteractive || !selectPackageManager) {
205
- throw new Error(`Package manager is required in non-interactive mode. Use --package-manager <${PACKAGE_MANAGER_IDS.join('|')}>.`);
206
+ throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT, `Package manager is required in non-interactive mode. Use --package-manager <${PACKAGE_MANAGER_IDS.join('|')}>.`);
206
207
  }
207
208
  return selectPackageManager();
208
209
  }
@@ -2,8 +2,9 @@ import { type BuiltInBlockArtifact } from "./built-in-block-artifacts.js";
2
2
  import type { BuiltInCodeArtifact } from "./built-in-block-code-artifacts.js";
3
3
  import { type BuiltInTemplateId } from "./template-registry.js";
4
4
  import type { PackageManagerId } from "./package-managers.js";
5
+ export { applyWorkspaceMigrationCapability, isOfficialWorkspaceProject, } from "./scaffold-bootstrap.js";
5
6
  import type { ScaffoldProgressEvent, ScaffoldTemplateVariables } from "./scaffold.js";
6
- export { buildGitignore, buildReadme, mergeTextLines, } from "./scaffold-documents.js";
7
+ export { buildGitignore, buildReadme, mergeTextLines } from "./scaffold-documents.js";
7
8
  export interface InstallDependenciesOptions {
8
9
  packageManager: PackageManagerId;
9
10
  projectDir: string;
@@ -27,8 +28,6 @@ export declare function replaceTextRecursively(targetDir: string, packageManager
27
28
  repositoryReference?: string;
28
29
  }): Promise<void>;
29
30
  export declare function defaultInstallDependencies({ projectDir, packageManager, }: InstallDependenciesOptions): Promise<void>;
30
- export declare function isOfficialWorkspaceProject(projectDir: string): boolean;
31
- export declare function applyWorkspaceMigrationCapability(projectDir: string, packageManager: PackageManagerId): Promise<void>;
32
31
  /**
33
32
  * Applies a built-in scaffold into the target directory, including generated
34
33
  * code artifacts, starter manifests, preset files, and placeholder rewrites.
@@ -5,19 +5,17 @@ import { execSync } from "node:child_process";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { applyGeneratedProjectDxPackageJson, applyLocalDevPresetFiles, } from "./local-dev-presets.js";
7
7
  import { applyMigrationUiCapability } from "./migration-ui-capability.js";
8
- import { getPackageVersions } from "./package-versions.js";
9
- import { ensureMigrationDirectories, writeInitialMigrationScaffold, writeMigrationConfig, } from "./migration-project.js";
10
8
  import { syncPersistenceRestArtifacts, } from "./persistence-rest-artifacts.js";
11
9
  import { buildGitignore, buildReadme, mergeTextLines, } from "./scaffold-documents.js";
12
10
  import { getStarterManifestFiles, stringifyStarterManifest, } from "./starter-manifests.js";
13
11
  import { formatNonEmptyTargetDirectoryError, } from "./scaffold-bootstrap.js";
14
12
  import { stringifyBuiltInBlockJsonDocument, } from "./built-in-block-artifacts.js";
15
- import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, } from "./template-registry.js";
16
13
  import { copyInterpolatedDirectory } from "./template-render.js";
17
- import { formatInstallCommand, formatPackageExecCommand, transformPackageManagerText, } from "./package-managers.js";
14
+ import { formatInstallCommand, transformPackageManagerText, } from "./package-managers.js";
18
15
  import { normalizePackageJson } from "./scaffold-package-manager-files.js";
16
+ export { applyWorkspaceMigrationCapability, isOfficialWorkspaceProject, } from "./scaffold-bootstrap.js";
19
17
  import { replaceRepositoryReferencePlaceholders, resolveScaffoldRepositoryReference, } from "./scaffold-repository-reference.js";
20
- export { buildGitignore, buildReadme, mergeTextLines, } from "./scaffold-documents.js";
18
+ export { buildGitignore, buildReadme, mergeTextLines } from "./scaffold-documents.js";
21
19
  async function reportScaffoldProgress(onProgress, event) {
22
20
  await onProgress?.(event);
23
21
  }
@@ -208,44 +206,6 @@ export async function defaultInstallDependencies({ projectDir, packageManager, }
208
206
  stdio: "inherit",
209
207
  });
210
208
  }
211
- export function isOfficialWorkspaceProject(projectDir) {
212
- const packageJsonPath = path.join(projectDir, "package.json");
213
- if (!fs.existsSync(packageJsonPath)) {
214
- return false;
215
- }
216
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
217
- return (packageJson.wpTypia?.projectType === "workspace" &&
218
- packageJson.wpTypia?.templatePackage === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE);
219
- }
220
- export async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
221
- const packageJsonPath = path.join(projectDir, "package.json");
222
- const packageJson = JSON.parse(await fsp.readFile(packageJsonPath, "utf8"));
223
- const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
224
- const canonicalCliSpecifier = wpTypiaPackageVersion === "^0.0.0"
225
- ? "wp-typia"
226
- : `wp-typia@${wpTypiaPackageVersion.replace(/^[~^]/u, "")}`;
227
- const migrationCli = (args) => formatPackageExecCommand(packageManager, canonicalCliSpecifier, `migrate ${args}`);
228
- packageJson.scripts = {
229
- ...(packageJson.scripts ?? {}),
230
- "migration:init": migrationCli("init --current-migration-version v1"),
231
- "migration:snapshot": migrationCli("snapshot"),
232
- "migration:diff": migrationCli("diff"),
233
- "migration:scaffold": migrationCli("scaffold"),
234
- "migration:doctor": migrationCli("doctor --all"),
235
- "migration:fixtures": migrationCli("fixtures --all"),
236
- "migration:verify": migrationCli("verify --all"),
237
- "migration:fuzz": migrationCli("fuzz --all"),
238
- };
239
- await fsp.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}\n`, "utf8");
240
- writeMigrationConfig(projectDir, {
241
- blocks: [],
242
- currentMigrationVersion: "v1",
243
- snapshotDir: "src/migrations/versions",
244
- supportedMigrationVersions: ["v1"],
245
- });
246
- ensureMigrationDirectories(projectDir, []);
247
- writeInitialMigrationScaffold(projectDir, "v1", []);
248
- }
249
209
  /**
250
210
  * Applies a built-in scaffold into the target directory, including generated
251
211
  * code artifacts, starter manifests, preset files, and placeholder rewrites.
@@ -4,7 +4,7 @@
4
4
  * The policy keeps plugin headers, runtime gates, and workspace inventory
5
5
  * metadata aligned when optional or required AI-capable features are added.
6
6
  */
7
- import { type AiFeatureCapabilitySelection, type AiFeatureCompatibilityFloor, type ResolvedAiFeatureCapabilityPlan } from "./ai-feature-capability.js";
7
+ import { type AiFeatureCapabilitySelection, type AiFeatureCompatibilityFloor, type ResolvedAiFeatureCapabilityPlan } from './ai-feature-capability.js';
8
8
  /**
9
9
  * WordPress plugin header version floors emitted by scaffold templates.
10
10
  */
@@ -25,7 +25,7 @@ export interface ScaffoldCompatibilityPolicy {
25
25
  */
26
26
  export interface ScaffoldCompatibilityConfig {
27
27
  hardMinimums: AiFeatureCompatibilityFloor;
28
- mode: "baseline" | "optional" | "required";
28
+ mode: 'baseline' | 'optional' | 'required';
29
29
  optionalFeatures: string[];
30
30
  requiredFeatures: string[];
31
31
  runtimeGates: string[];