@wp-typia/project-tools 0.19.2 → 0.20.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.
- package/README.md +23 -0
- package/dist/runtime/ability-spec.d.ts +90 -0
- package/dist/runtime/ability-spec.js +51 -0
- package/dist/runtime/ai-artifacts.d.ts +39 -0
- package/dist/runtime/ai-artifacts.js +68 -0
- package/dist/runtime/ai-feature-artifacts.d.ts +85 -0
- package/dist/runtime/ai-feature-artifacts.js +139 -0
- package/dist/runtime/ai-feature-capability.d.ts +114 -0
- package/dist/runtime/ai-feature-capability.js +150 -0
- package/dist/runtime/block-generator-service-spec.js +6 -0
- package/dist/runtime/cli-add-shared.d.ts +32 -1
- package/dist/runtime/cli-add-shared.js +44 -0
- package/dist/runtime/cli-add-workspace-ability.d.ts +8 -0
- package/dist/runtime/cli-add-workspace-ability.js +810 -0
- package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-ai-anchors.js +277 -0
- package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +28 -0
- package/dist/runtime/cli-add-workspace-ai-source-emitters.js +346 -0
- package/dist/runtime/cli-add-workspace-ai.d.ts +14 -0
- package/dist/runtime/cli-add-workspace-ai.js +484 -0
- package/dist/runtime/cli-add-workspace.d.ts +10 -0
- package/dist/runtime/cli-add-workspace.js +10 -0
- package/dist/runtime/cli-add.d.ts +1 -1
- package/dist/runtime/cli-add.js +1 -1
- package/dist/runtime/cli-core.d.ts +3 -1
- package/dist/runtime/cli-core.js +3 -1
- package/dist/runtime/cli-diagnostics.d.ts +2 -0
- package/dist/runtime/cli-diagnostics.js +10 -1
- package/dist/runtime/cli-doctor-workspace.js +140 -1
- package/dist/runtime/cli-help.js +7 -0
- package/dist/runtime/cli-init.d.ts +49 -0
- package/dist/runtime/cli-init.js +354 -0
- package/dist/runtime/cli-scaffold.d.ts +1 -0
- package/dist/runtime/cli-scaffold.js +5 -1
- package/dist/runtime/cli-templates.js +36 -6
- package/dist/runtime/external-template-guards.d.ts +31 -0
- package/dist/runtime/external-template-guards.js +132 -0
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.js +2 -1
- package/dist/runtime/package-managers.d.ts +8 -0
- package/dist/runtime/package-managers.js +13 -0
- package/dist/runtime/package-versions.d.ts +8 -0
- package/dist/runtime/package-versions.js +84 -19
- package/dist/runtime/scaffold-compatibility.d.ts +65 -0
- package/dist/runtime/scaffold-compatibility.js +152 -0
- package/dist/runtime/scaffold-documents.js +19 -1
- package/dist/runtime/scaffold-onboarding.d.ts +4 -0
- package/dist/runtime/scaffold-onboarding.js +25 -1
- package/dist/runtime/scaffold-template-variable-groups.d.ts +2 -0
- package/dist/runtime/scaffold-template-variables.js +6 -0
- package/dist/runtime/scaffold.d.ts +3 -0
- package/dist/runtime/scaffold.js +2 -5
- package/dist/runtime/template-registry.d.ts +23 -1
- package/dist/runtime/template-registry.js +37 -3
- package/dist/runtime/template-source-external.js +9 -3
- package/dist/runtime/template-source-remote.js +5 -0
- package/dist/runtime/template-source-seeds.js +40 -6
- package/dist/runtime/typia-llm.d.ts +213 -0
- package/dist/runtime/typia-llm.js +348 -0
- package/dist/runtime/wordpress-ai.d.ts +122 -0
- package/dist/runtime/wordpress-ai.js +177 -0
- package/dist/runtime/workspace-inventory.d.ts +51 -4
- package/dist/runtime/workspace-inventory.js +157 -4
- package/package.json +17 -2
- package/templates/_shared/base/package.json.mustache +0 -1
- package/templates/_shared/base/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/compound/core/package.json.mustache +0 -1
- package/templates/_shared/compound/core/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/compound/persistence/package.json.mustache +0 -1
- package/templates/_shared/compound/persistence-auth/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/compound/persistence-public/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/persistence/auth/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/persistence/core/package.json.mustache +0 -1
- package/templates/_shared/persistence/core/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/_shared/persistence/public/{{slugKebabCase}}.php.mustache +3 -3
- package/templates/interactivity/package.json.mustache +0 -1
- package/templates/query-loop/{{slugKebabCase}}.php.mustache +3 -3
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type RunAddAiFeatureCommandOptions } from "./cli-add-shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* Scaffold a workspace-level server-only AI feature endpoint and synchronize
|
|
4
|
+
* its typed REST plus AI-schema artifacts.
|
|
5
|
+
*
|
|
6
|
+
* @param options Command options for the AI feature scaffold workflow.
|
|
7
|
+
* @returns Resolved scaffold metadata for the created AI feature.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runAddAiFeatureCommand({ aiFeatureName, cwd, namespace, }: RunAddAiFeatureCommandOptions): Promise<{
|
|
10
|
+
aiFeatureSlug: string;
|
|
11
|
+
namespace: string;
|
|
12
|
+
projectDir: string;
|
|
13
|
+
warnings: string[];
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
import { promises as fsp } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { assertAiFeatureDoesNotExist, assertValidGeneratedSlug, getWorkspaceBootstrapPath, normalizeBlockSlug, patchFile, resolveRestResourceNamespace, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from "./cli-add-shared.js";
|
|
4
|
+
import { ensureBlockConfigCanAddRestManifests } from "./cli-add-block-legacy-validator.js";
|
|
5
|
+
import { buildAiFeatureConfigEntry, buildAiFeatureDataSource, buildAiFeatureSyncScriptSource, buildAiFeatureTypesSource, buildAiFeatureValidatorsSource, buildAiFeatureApiSource, toPascalCaseFromAiFeatureSlug, } from "./cli-add-workspace-ai-source-emitters.js";
|
|
6
|
+
import { ensureAiFeatureBootstrapAnchors, ensureAiFeaturePackageScripts, ensureAiFeatureSyncProjectAnchors, ensureAiFeatureSyncRestAnchors, } from "./cli-add-workspace-ai-anchors.js";
|
|
7
|
+
import { syncAiFeatureRestArtifacts, syncAiFeatureSchemaArtifact, } from "./ai-feature-artifacts.js";
|
|
8
|
+
import { appendWorkspaceInventoryEntries, readWorkspaceInventory } from "./workspace-inventory.js";
|
|
9
|
+
import { resolveWorkspaceProject } from "./workspace-project.js";
|
|
10
|
+
import { OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, updatePluginHeaderCompatibility, } from "./scaffold-compatibility.js";
|
|
11
|
+
import { toTitleCase } from "./string-case.js";
|
|
12
|
+
function quotePhpString(value) {
|
|
13
|
+
return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
|
|
14
|
+
}
|
|
15
|
+
function buildAiFeaturePhpSource(aiFeatureSlug, namespace, phpPrefix, textDomain) {
|
|
16
|
+
const aiFeatureTitle = toTitleCase(aiFeatureSlug);
|
|
17
|
+
const aiFeaturePhpId = aiFeatureSlug.replace(/-/g, "_");
|
|
18
|
+
const loadSchemaFunctionName = `${phpPrefix}_${aiFeaturePhpId}_load_ai_feature_schema`;
|
|
19
|
+
const loadAiSchemaFunctionName = `${phpPrefix}_${aiFeaturePhpId}_load_ai_response_schema`;
|
|
20
|
+
const normalizeSchemaFunctionName = `${phpPrefix}_${aiFeaturePhpId}_sanitize_ai_feature_schema`;
|
|
21
|
+
const validatePayloadFunctionName = `${phpPrefix}_${aiFeaturePhpId}_validate_ai_feature_payload`;
|
|
22
|
+
const canManageFunctionName = `${phpPrefix}_${aiFeaturePhpId}_can_manage_ai_feature`;
|
|
23
|
+
const buildPromptFunctionName = `${phpPrefix}_${aiFeaturePhpId}_build_ai_feature_prompt`;
|
|
24
|
+
const normalizeProviderTypeFunctionName = `${phpPrefix}_${aiFeaturePhpId}_normalize_provider_type`;
|
|
25
|
+
const buildTelemetryFunctionName = `${phpPrefix}_${aiFeaturePhpId}_build_ai_feature_telemetry`;
|
|
26
|
+
const isSupportedFunctionName = `${phpPrefix}_${aiFeaturePhpId}_is_ai_feature_supported`;
|
|
27
|
+
const adminNoticeFunctionName = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_admin_notice`;
|
|
28
|
+
const handlerFunctionName = `${phpPrefix}_${aiFeaturePhpId}_handle_run_ai_feature`;
|
|
29
|
+
const registerRoutesFunctionName = `${phpPrefix}_${aiFeaturePhpId}_register_ai_feature_routes`;
|
|
30
|
+
return `<?php
|
|
31
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
32
|
+
\treturn;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if ( ! function_exists( '${loadSchemaFunctionName}' ) ) {
|
|
36
|
+
\tfunction ${loadSchemaFunctionName}( $schema_name ) {
|
|
37
|
+
\t\t$project_root = dirname( __DIR__, 2 );
|
|
38
|
+
\t\t$schema_path = $project_root . '/src/ai-features/${aiFeatureSlug}/api-schemas/' . $schema_name . '.schema.json';
|
|
39
|
+
\t\tif ( ! file_exists( $schema_path ) ) {
|
|
40
|
+
\t\t\treturn null;
|
|
41
|
+
\t\t}
|
|
42
|
+
|
|
43
|
+
\t\t$decoded = json_decode( file_get_contents( $schema_path ), true );
|
|
44
|
+
\t\treturn is_array( $decoded ) ? $decoded : null;
|
|
45
|
+
\t}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if ( ! function_exists( '${loadAiSchemaFunctionName}' ) ) {
|
|
49
|
+
\tfunction ${loadAiSchemaFunctionName}() {
|
|
50
|
+
\t\t$project_root = dirname( __DIR__, 2 );
|
|
51
|
+
\t\t$schema_path = $project_root . '/src/ai-features/${aiFeatureSlug}/ai-schemas/feature-result.ai.schema.json';
|
|
52
|
+
\t\tif ( ! file_exists( $schema_path ) ) {
|
|
53
|
+
\t\t\treturn null;
|
|
54
|
+
\t\t}
|
|
55
|
+
|
|
56
|
+
\t\t$decoded = json_decode( file_get_contents( $schema_path ), true );
|
|
57
|
+
\t\treturn is_array( $decoded ) ? $decoded : null;
|
|
58
|
+
\t}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if ( ! function_exists( '${normalizeSchemaFunctionName}' ) ) {
|
|
62
|
+
\tfunction ${normalizeSchemaFunctionName}( $schema ) {
|
|
63
|
+
\t\tif ( ! is_array( $schema ) ) {
|
|
64
|
+
\t\t\treturn $schema;
|
|
65
|
+
\t\t}
|
|
66
|
+
|
|
67
|
+
\t\tunset( $schema['$schema'], $schema['title'] );
|
|
68
|
+
|
|
69
|
+
\t\tif ( isset( $schema['properties'] ) && is_array( $schema['properties'] ) ) {
|
|
70
|
+
\t\t\tforeach ( $schema['properties'] as $key => $property_schema ) {
|
|
71
|
+
\t\t\t\t$schema['properties'][ $key ] = ${normalizeSchemaFunctionName}( $property_schema );
|
|
72
|
+
\t\t\t}
|
|
73
|
+
\t\t}
|
|
74
|
+
|
|
75
|
+
\t\tif ( isset( $schema['items'] ) && is_array( $schema['items'] ) ) {
|
|
76
|
+
\t\t\t$schema['items'] = ${normalizeSchemaFunctionName}( $schema['items'] );
|
|
77
|
+
\t\t}
|
|
78
|
+
|
|
79
|
+
\t\treturn $schema;
|
|
80
|
+
\t}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ( ! function_exists( '${validatePayloadFunctionName}' ) ) {
|
|
84
|
+
\tfunction ${validatePayloadFunctionName}( $value, $schema_name, $param_name ) {
|
|
85
|
+
\t\t$schema = ${loadSchemaFunctionName}( $schema_name );
|
|
86
|
+
\t\tif ( ! is_array( $schema ) ) {
|
|
87
|
+
\t\t\treturn new WP_Error( 'missing_schema', 'Missing AI feature schema.', array( 'status' => 500 ) );
|
|
88
|
+
\t\t}
|
|
89
|
+
|
|
90
|
+
\t\t$rest_schema = ${normalizeSchemaFunctionName}( $schema );
|
|
91
|
+
\t\t$validation = rest_validate_value_from_schema( $value, $rest_schema, $param_name );
|
|
92
|
+
\t\tif ( is_wp_error( $validation ) ) {
|
|
93
|
+
\t\t\treturn $validation;
|
|
94
|
+
\t\t}
|
|
95
|
+
|
|
96
|
+
\t\treturn rest_sanitize_value_from_schema( $value, $rest_schema, $param_name );
|
|
97
|
+
\t}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if ( ! function_exists( '${canManageFunctionName}' ) ) {
|
|
101
|
+
\tfunction ${canManageFunctionName}() {
|
|
102
|
+
\t\treturn current_user_can( 'edit_posts' );
|
|
103
|
+
\t}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if ( ! function_exists( '${buildPromptFunctionName}' ) ) {
|
|
107
|
+
\tfunction ${buildPromptFunctionName}( array $payload ) {
|
|
108
|
+
\t\treturn sprintf(
|
|
109
|
+
\t\t\t'You are helping with the %1$s AI workflow. Read the JSON request payload and return JSON that matches the provided schema. Request payload: %2$s',
|
|
110
|
+
\t\t\t${quotePhpString(aiFeatureTitle)},
|
|
111
|
+
\t\t\twp_json_encode( $payload )
|
|
112
|
+
\t\t);
|
|
113
|
+
\t}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if ( ! function_exists( '${normalizeProviderTypeFunctionName}' ) ) {
|
|
117
|
+
\tfunction ${normalizeProviderTypeFunctionName}( $provider_type ) {
|
|
118
|
+
\t\tif ( is_object( $provider_type ) && isset( $provider_type->value ) && is_string( $provider_type->value ) ) {
|
|
119
|
+
\t\t\treturn $provider_type->value;
|
|
120
|
+
\t\t}
|
|
121
|
+
|
|
122
|
+
\t\treturn is_string( $provider_type ) && '' !== $provider_type ? $provider_type : 'cloud';
|
|
123
|
+
\t}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if ( ! function_exists( '${buildTelemetryFunctionName}' ) ) {
|
|
127
|
+
\tfunction ${buildTelemetryFunctionName}( $result ) {
|
|
128
|
+
\t\tif (
|
|
129
|
+
\t\t\t! is_object( $result ) ||
|
|
130
|
+
\t\t\t! method_exists( $result, 'getId' ) ||
|
|
131
|
+
\t\t\t! method_exists( $result, 'getModelMetadata' ) ||
|
|
132
|
+
\t\t\t! method_exists( $result, 'getProviderMetadata' ) ||
|
|
133
|
+
\t\t\t! method_exists( $result, 'getTokenUsage' )
|
|
134
|
+
\t\t) {
|
|
135
|
+
\t\t\treturn new WP_Error(
|
|
136
|
+
\t\t\t\t'ai_client_result_shape',
|
|
137
|
+
\t\t\t\t'The current WordPress AI Client result object is missing telemetry helpers.',
|
|
138
|
+
\t\t\t\tarray( 'status' => 502 )
|
|
139
|
+
\t\t\t);
|
|
140
|
+
\t\t}
|
|
141
|
+
|
|
142
|
+
\t\t$model_metadata = $result->getModelMetadata();
|
|
143
|
+
\t\t$provider_metadata = $result->getProviderMetadata();
|
|
144
|
+
\t\t$token_usage = $result->getTokenUsage();
|
|
145
|
+
|
|
146
|
+
\t\tif (
|
|
147
|
+
\t\t\t! is_object( $model_metadata ) ||
|
|
148
|
+
\t\t\t! method_exists( $model_metadata, 'getId' ) ||
|
|
149
|
+
\t\t\t! method_exists( $model_metadata, 'getName' ) ||
|
|
150
|
+
\t\t\t! is_object( $provider_metadata ) ||
|
|
151
|
+
\t\t\t! method_exists( $provider_metadata, 'getId' ) ||
|
|
152
|
+
\t\t\t! method_exists( $provider_metadata, 'getName' ) ||
|
|
153
|
+
\t\t\t! method_exists( $provider_metadata, 'getType' ) ||
|
|
154
|
+
\t\t\t! is_object( $token_usage ) ||
|
|
155
|
+
\t\t\t! method_exists( $token_usage, 'getCompletionTokens' ) ||
|
|
156
|
+
\t\t\t! method_exists( $token_usage, 'getPromptTokens' ) ||
|
|
157
|
+
\t\t\t! method_exists( $token_usage, 'getTotalTokens' )
|
|
158
|
+
\t\t) {
|
|
159
|
+
\t\t\treturn new WP_Error(
|
|
160
|
+
\t\t\t\t'ai_client_result_shape',
|
|
161
|
+
\t\t\t\t'The current WordPress AI Client telemetry objects are missing expected getters.',
|
|
162
|
+
\t\t\t\tarray( 'status' => 502 )
|
|
163
|
+
\t\t\t);
|
|
164
|
+
\t\t}
|
|
165
|
+
|
|
166
|
+
\t\t$telemetry = array(
|
|
167
|
+
\t\t\t'modelId' => (string) $model_metadata->getId(),
|
|
168
|
+
\t\t\t'modelName' => (string) $model_metadata->getName(),
|
|
169
|
+
\t\t\t'providerId' => (string) $provider_metadata->getId(),
|
|
170
|
+
\t\t\t'providerName' => (string) $provider_metadata->getName(),
|
|
171
|
+
\t\t\t'providerType' => ${normalizeProviderTypeFunctionName}( $provider_metadata->getType() ),
|
|
172
|
+
\t\t\t'resultId' => (string) $result->getId(),
|
|
173
|
+
\t\t\t'tokenUsage' => array(
|
|
174
|
+
\t\t\t\t'completionTokens' => (int) $token_usage->getCompletionTokens(),
|
|
175
|
+
\t\t\t\t'promptTokens' => (int) $token_usage->getPromptTokens(),
|
|
176
|
+
\t\t\t\t'totalTokens' => (int) $token_usage->getTotalTokens(),
|
|
177
|
+
\t\t\t),
|
|
178
|
+
\t\t);
|
|
179
|
+
|
|
180
|
+
\t\tif ( method_exists( $token_usage, 'getThoughtTokens' ) ) {
|
|
181
|
+
\t\t\t$thought_tokens = $token_usage->getThoughtTokens();
|
|
182
|
+
\t\t\tif ( null !== $thought_tokens ) {
|
|
183
|
+
\t\t\t\t$telemetry['tokenUsage']['thoughtTokens'] = (int) $thought_tokens;
|
|
184
|
+
\t\t\t}
|
|
185
|
+
\t\t}
|
|
186
|
+
|
|
187
|
+
\t\treturn $telemetry;
|
|
188
|
+
\t}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if ( ! function_exists( '${isSupportedFunctionName}' ) ) {
|
|
192
|
+
\tfunction ${isSupportedFunctionName}() {
|
|
193
|
+
\t\tstatic $is_supported = null;
|
|
194
|
+
\t\tif ( null !== $is_supported ) {
|
|
195
|
+
\t\t\treturn $is_supported;
|
|
196
|
+
\t\t}
|
|
197
|
+
|
|
198
|
+
\t\tif ( ! function_exists( 'wp_ai_client_prompt' ) ) {
|
|
199
|
+
\t\t\t$is_supported = false;
|
|
200
|
+
\t\t\treturn $is_supported;
|
|
201
|
+
\t\t}
|
|
202
|
+
|
|
203
|
+
\t\t$schema = ${loadAiSchemaFunctionName}();
|
|
204
|
+
\t\tif ( ! is_array( $schema ) ) {
|
|
205
|
+
\t\t\t$is_supported = false;
|
|
206
|
+
\t\t\treturn $is_supported;
|
|
207
|
+
\t\t}
|
|
208
|
+
|
|
209
|
+
\t\t$prompt = wp_ai_client_prompt( 'AI feature support probe.' );
|
|
210
|
+
\t\tif ( ! is_object( $prompt ) || ! method_exists( $prompt, 'as_json_response' ) ) {
|
|
211
|
+
\t\t\t$is_supported = false;
|
|
212
|
+
\t\t\treturn $is_supported;
|
|
213
|
+
\t\t}
|
|
214
|
+
|
|
215
|
+
\t\t$structured_prompt = $prompt->as_json_response( $schema );
|
|
216
|
+
\t\tif ( ! is_object( $structured_prompt ) ) {
|
|
217
|
+
\t\t\t$is_supported = false;
|
|
218
|
+
\t\t\treturn $is_supported;
|
|
219
|
+
\t\t}
|
|
220
|
+
|
|
221
|
+
\t\tif ( method_exists( $structured_prompt, 'is_supported_for_text_generation' ) ) {
|
|
222
|
+
\t\t\t$is_supported = (bool) $structured_prompt->is_supported_for_text_generation();
|
|
223
|
+
\t\t\treturn $is_supported;
|
|
224
|
+
\t\t}
|
|
225
|
+
|
|
226
|
+
\t\t$is_supported = method_exists( $structured_prompt, 'generate_text_result' );
|
|
227
|
+
\t\treturn $is_supported;
|
|
228
|
+
\t}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if ( ! function_exists( '${adminNoticeFunctionName}' ) ) {
|
|
232
|
+
\tfunction ${adminNoticeFunctionName}() {
|
|
233
|
+
\t\tif ( ! current_user_can( 'manage_options' ) || ${isSupportedFunctionName}() ) {
|
|
234
|
+
\t\t\treturn;
|
|
235
|
+
\t\t}
|
|
236
|
+
|
|
237
|
+
\t\t$message = sprintf(
|
|
238
|
+
\t\t\t/* translators: %s: AI feature name. */
|
|
239
|
+
\t\t\t__( 'The %s AI feature is optional and remains disabled until the WordPress AI Client is available with structured text generation support for the generated schema.', ${quotePhpString(textDomain)} ),
|
|
240
|
+
\t\t\t${quotePhpString(aiFeatureTitle)}
|
|
241
|
+
\t\t);
|
|
242
|
+
\t\tprintf( '<div class="notice notice-warning"><p>%s</p></div>', esc_html( $message ) );
|
|
243
|
+
\t}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if ( ! function_exists( '${handlerFunctionName}' ) ) {
|
|
247
|
+
\tfunction ${handlerFunctionName}( WP_REST_Request $request ) {
|
|
248
|
+
\t\t$payload = ${validatePayloadFunctionName}( $request->get_json_params(), 'feature-request', 'body' );
|
|
249
|
+
\t\tif ( is_wp_error( $payload ) ) {
|
|
250
|
+
\t\t\treturn $payload;
|
|
251
|
+
\t\t}
|
|
252
|
+
|
|
253
|
+
\t\tif ( ! ${isSupportedFunctionName}() ) {
|
|
254
|
+
\t\t\treturn new WP_Error(
|
|
255
|
+
\t\t\t\t'ai_client_unavailable',
|
|
256
|
+
\t\t\t\t'The WordPress AI Client is unavailable or does not support this feature endpoint.',
|
|
257
|
+
\t\t\t\tarray( 'status' => 501 )
|
|
258
|
+
\t\t\t);
|
|
259
|
+
\t\t}
|
|
260
|
+
|
|
261
|
+
\t\t$ai_schema = ${loadAiSchemaFunctionName}();
|
|
262
|
+
\t\tif ( ! is_array( $ai_schema ) ) {
|
|
263
|
+
\t\t\treturn new WP_Error(
|
|
264
|
+
\t\t\t\t'ai_client_schema_missing',
|
|
265
|
+
\t\t\t\t'The generated AI response schema is missing for this feature endpoint.',
|
|
266
|
+
\t\t\t\tarray( 'status' => 500 )
|
|
267
|
+
\t\t\t);
|
|
268
|
+
\t\t}
|
|
269
|
+
|
|
270
|
+
\t\t$prompt = wp_ai_client_prompt( ${buildPromptFunctionName}( $payload ) );
|
|
271
|
+
\t\tif ( ! is_object( $prompt ) ) {
|
|
272
|
+
\t\t\treturn new WP_Error(
|
|
273
|
+
\t\t\t\t'ai_client_unavailable',
|
|
274
|
+
\t\t\t\t'The WordPress AI Client prompt builder is unavailable on this site.',
|
|
275
|
+
\t\t\t\tarray( 'status' => 501 )
|
|
276
|
+
\t\t\t);
|
|
277
|
+
\t\t}
|
|
278
|
+
|
|
279
|
+
\t\tif ( method_exists( $prompt, 'using_temperature' ) ) {
|
|
280
|
+
\t\t\t$prompt = $prompt->using_temperature( 0.2 );
|
|
281
|
+
\t\t}
|
|
282
|
+
\t\tif ( ! method_exists( $prompt, 'as_json_response' ) ) {
|
|
283
|
+
\t\t\treturn new WP_Error(
|
|
284
|
+
\t\t\t\t'ai_client_unavailable',
|
|
285
|
+
\t\t\t\t'The current WordPress AI Client does not expose as_json_response().',
|
|
286
|
+
\t\t\t\tarray( 'status' => 501 )
|
|
287
|
+
\t\t\t);
|
|
288
|
+
\t\t}
|
|
289
|
+
|
|
290
|
+
\t\t$structured_prompt = $prompt->as_json_response( $ai_schema );
|
|
291
|
+
\t\tif ( ! is_object( $structured_prompt ) ) {
|
|
292
|
+
\t\t\treturn new WP_Error(
|
|
293
|
+
\t\t\t\t'ai_client_unavailable',
|
|
294
|
+
\t\t\t\t'The current WordPress AI Client could not prepare a structured-output prompt.',
|
|
295
|
+
\t\t\t\tarray( 'status' => 501 )
|
|
296
|
+
\t\t\t);
|
|
297
|
+
\t\t}
|
|
298
|
+
|
|
299
|
+
\t\tif (
|
|
300
|
+
\t\t\tmethod_exists( $structured_prompt, 'is_supported_for_text_generation' ) &&
|
|
301
|
+
\t\t\t! $structured_prompt->is_supported_for_text_generation()
|
|
302
|
+
\t\t) {
|
|
303
|
+
\t\t\treturn new WP_Error(
|
|
304
|
+
\t\t\t\t'ai_client_unavailable',
|
|
305
|
+
\t\t\t\t'The current WordPress AI Client provider or model does not support this structured-output feature.',
|
|
306
|
+
\t\t\t\tarray( 'status' => 501 )
|
|
307
|
+
\t\t\t);
|
|
308
|
+
\t\t}
|
|
309
|
+
\t\tif ( ! method_exists( $structured_prompt, 'generate_text_result' ) ) {
|
|
310
|
+
\t\t\treturn new WP_Error(
|
|
311
|
+
\t\t\t\t'ai_client_unavailable',
|
|
312
|
+
\t\t\t\t'The current WordPress AI Client does not expose generate_text_result() after as_json_response().',
|
|
313
|
+
\t\t\t\tarray( 'status' => 501 )
|
|
314
|
+
\t\t\t);
|
|
315
|
+
\t\t}
|
|
316
|
+
|
|
317
|
+
\t\t$result = $structured_prompt->generate_text_result();
|
|
318
|
+
\t\tif ( is_wp_error( $result ) ) {
|
|
319
|
+
\t\t\treturn $result;
|
|
320
|
+
\t\t}
|
|
321
|
+
\t\tif ( ! is_object( $result ) || ! method_exists( $result, 'toText' ) ) {
|
|
322
|
+
\t\t\treturn new WP_Error(
|
|
323
|
+
\t\t\t\t'ai_client_result_shape',
|
|
324
|
+
\t\t\t\t'The current WordPress AI Client result does not expose toText().',
|
|
325
|
+
\t\t\t\tarray( 'status' => 502 )
|
|
326
|
+
\t\t\t);
|
|
327
|
+
\t\t}
|
|
328
|
+
|
|
329
|
+
\t\t$decoded_result = json_decode( $result->toText(), true );
|
|
330
|
+
\t\tif ( ! is_array( $decoded_result ) ) {
|
|
331
|
+
\t\t\treturn new WP_Error(
|
|
332
|
+
\t\t\t\t'ai_client_invalid_json',
|
|
333
|
+
\t\t\t\t'The AI feature response did not decode to a JSON object.',
|
|
334
|
+
\t\t\t\tarray( 'status' => 502 )
|
|
335
|
+
\t\t\t);
|
|
336
|
+
\t\t}
|
|
337
|
+
|
|
338
|
+
\t\t$normalized_result = ${validatePayloadFunctionName}( $decoded_result, 'feature-result', 'result' );
|
|
339
|
+
\t\tif ( is_wp_error( $normalized_result ) ) {
|
|
340
|
+
\t\t\treturn new WP_Error(
|
|
341
|
+
\t\t\t\t'ai_client_invalid_response',
|
|
342
|
+
\t\t\t\t$normalized_result->get_error_message(),
|
|
343
|
+
\t\t\t\tarray( 'status' => 502 )
|
|
344
|
+
\t\t\t);
|
|
345
|
+
\t\t}
|
|
346
|
+
|
|
347
|
+
\t\t$telemetry = ${buildTelemetryFunctionName}( $result );
|
|
348
|
+
\t\tif ( is_wp_error( $telemetry ) ) {
|
|
349
|
+
\t\t\treturn $telemetry;
|
|
350
|
+
\t\t}
|
|
351
|
+
|
|
352
|
+
\t\t$response = ${validatePayloadFunctionName}(
|
|
353
|
+
\t\t\tarray(
|
|
354
|
+
\t\t\t\t'result' => $normalized_result,
|
|
355
|
+
\t\t\t\t'telemetry' => $telemetry,
|
|
356
|
+
\t\t\t),
|
|
357
|
+
\t\t\t'feature-response',
|
|
358
|
+
\t\t\t'response'
|
|
359
|
+
\t\t);
|
|
360
|
+
\t\tif ( is_wp_error( $response ) ) {
|
|
361
|
+
\t\t\treturn new WP_Error(
|
|
362
|
+
\t\t\t\t'ai_client_invalid_response',
|
|
363
|
+
\t\t\t\t$response->get_error_message(),
|
|
364
|
+
\t\t\t\tarray( 'status' => 502 )
|
|
365
|
+
\t\t\t);
|
|
366
|
+
\t\t}
|
|
367
|
+
|
|
368
|
+
\t\treturn rest_ensure_response( $response );
|
|
369
|
+
\t}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if ( ! function_exists( '${registerRoutesFunctionName}' ) ) {
|
|
373
|
+
\tfunction ${registerRoutesFunctionName}() {
|
|
374
|
+
\t\tregister_rest_route(
|
|
375
|
+
\t\t\t${quotePhpString(namespace)},
|
|
376
|
+
\t\t\t'/ai/${aiFeatureSlug}',
|
|
377
|
+
\t\t\tarray(
|
|
378
|
+
\t\t\t\tarray(
|
|
379
|
+
\t\t\t\t\t'methods' => WP_REST_Server::CREATABLE,
|
|
380
|
+
\t\t\t\t\t'callback' => '${handlerFunctionName}',
|
|
381
|
+
\t\t\t\t\t'permission_callback' => '${canManageFunctionName}',
|
|
382
|
+
\t\t\t\t)
|
|
383
|
+
\t\t\t)
|
|
384
|
+
\t\t);
|
|
385
|
+
\t}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
add_action( 'admin_notices', '${adminNoticeFunctionName}' );
|
|
389
|
+
add_action( 'rest_api_init', '${registerRoutesFunctionName}' );
|
|
390
|
+
`;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Scaffold a workspace-level server-only AI feature endpoint and synchronize
|
|
394
|
+
* its typed REST plus AI-schema artifacts.
|
|
395
|
+
*
|
|
396
|
+
* @param options Command options for the AI feature scaffold workflow.
|
|
397
|
+
* @returns Resolved scaffold metadata for the created AI feature.
|
|
398
|
+
*/
|
|
399
|
+
export async function runAddAiFeatureCommand({ aiFeatureName, cwd = process.cwd(), namespace, }) {
|
|
400
|
+
const workspace = resolveWorkspaceProject(cwd);
|
|
401
|
+
const aiFeatureSlug = assertValidGeneratedSlug("AI feature name", normalizeBlockSlug(aiFeatureName), "wp-typia add ai-feature <name> [--namespace <vendor/v1>]");
|
|
402
|
+
const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
|
|
403
|
+
const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY);
|
|
404
|
+
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
405
|
+
assertAiFeatureDoesNotExist(workspace.projectDir, aiFeatureSlug, inventory);
|
|
406
|
+
const blockConfigPath = path.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
407
|
+
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
408
|
+
const packageJsonPath = path.join(workspace.projectDir, "package.json");
|
|
409
|
+
const syncAiScriptPath = path.join(workspace.projectDir, "scripts", "sync-ai-features.ts");
|
|
410
|
+
const syncProjectScriptPath = path.join(workspace.projectDir, "scripts", "sync-project.ts");
|
|
411
|
+
const syncRestScriptPath = path.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
412
|
+
const aiFeatureDir = path.join(workspace.projectDir, "src", "ai-features", aiFeatureSlug);
|
|
413
|
+
const typesFilePath = path.join(aiFeatureDir, "api-types.ts");
|
|
414
|
+
const validatorsFilePath = path.join(aiFeatureDir, "api-validators.ts");
|
|
415
|
+
const apiFilePath = path.join(aiFeatureDir, "api.ts");
|
|
416
|
+
const dataFilePath = path.join(aiFeatureDir, "data.ts");
|
|
417
|
+
const phpFilePath = path.join(workspace.projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
|
|
418
|
+
const mutationSnapshot = {
|
|
419
|
+
fileSources: await snapshotWorkspaceFiles([
|
|
420
|
+
blockConfigPath,
|
|
421
|
+
bootstrapPath,
|
|
422
|
+
packageJsonPath,
|
|
423
|
+
syncAiScriptPath,
|
|
424
|
+
syncProjectScriptPath,
|
|
425
|
+
syncRestScriptPath,
|
|
426
|
+
]),
|
|
427
|
+
snapshotDirs: [],
|
|
428
|
+
targetPaths: [aiFeatureDir, phpFilePath, syncAiScriptPath],
|
|
429
|
+
};
|
|
430
|
+
try {
|
|
431
|
+
await fsp.mkdir(aiFeatureDir, { recursive: true });
|
|
432
|
+
await fsp.mkdir(path.dirname(phpFilePath), { recursive: true });
|
|
433
|
+
await ensureAiFeatureBootstrapAnchors(workspace);
|
|
434
|
+
await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
|
|
435
|
+
const packageScriptChanges = await ensureAiFeaturePackageScripts(workspace);
|
|
436
|
+
await ensureAiFeatureSyncProjectAnchors(workspace);
|
|
437
|
+
await ensureAiFeatureSyncRestAnchors(workspace);
|
|
438
|
+
await fsp.writeFile(syncAiScriptPath, buildAiFeatureSyncScriptSource(), "utf8");
|
|
439
|
+
await fsp.writeFile(typesFilePath, buildAiFeatureTypesSource(aiFeatureSlug), "utf8");
|
|
440
|
+
await fsp.writeFile(validatorsFilePath, buildAiFeatureValidatorsSource(aiFeatureSlug), "utf8");
|
|
441
|
+
await fsp.writeFile(apiFilePath, buildAiFeatureApiSource(aiFeatureSlug), "utf8");
|
|
442
|
+
await fsp.writeFile(dataFilePath, buildAiFeatureDataSource(aiFeatureSlug), "utf8");
|
|
443
|
+
await fsp.writeFile(phpFilePath, buildAiFeaturePhpSource(aiFeatureSlug, resolvedNamespace, workspace.workspace.phpPrefix, workspace.workspace.textDomain), "utf8");
|
|
444
|
+
const pascalCase = toPascalCaseFromAiFeatureSlug(aiFeatureSlug);
|
|
445
|
+
await syncAiFeatureRestArtifacts({
|
|
446
|
+
clientFile: `src/ai-features/${aiFeatureSlug}/api-client.ts`,
|
|
447
|
+
outputDir: path.join("src", "ai-features", aiFeatureSlug),
|
|
448
|
+
projectDir: workspace.projectDir,
|
|
449
|
+
typesFile: `src/ai-features/${aiFeatureSlug}/api-types.ts`,
|
|
450
|
+
validatorsFile: `src/ai-features/${aiFeatureSlug}/api-validators.ts`,
|
|
451
|
+
variables: {
|
|
452
|
+
namespace: resolvedNamespace,
|
|
453
|
+
pascalCase,
|
|
454
|
+
slugKebabCase: aiFeatureSlug,
|
|
455
|
+
title: toTitleCase(aiFeatureSlug),
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
await syncAiFeatureSchemaArtifact({
|
|
459
|
+
aiSchemaFile: `src/ai-features/${aiFeatureSlug}/ai-schemas/feature-result.ai.schema.json`,
|
|
460
|
+
outputDir: path.join("src", "ai-features", aiFeatureSlug),
|
|
461
|
+
projectDir: workspace.projectDir,
|
|
462
|
+
});
|
|
463
|
+
await appendWorkspaceInventoryEntries(workspace.projectDir, {
|
|
464
|
+
aiFeatureEntries: [
|
|
465
|
+
buildAiFeatureConfigEntry(aiFeatureSlug, resolvedNamespace),
|
|
466
|
+
],
|
|
467
|
+
transformSource: ensureBlockConfigCanAddRestManifests,
|
|
468
|
+
});
|
|
469
|
+
return {
|
|
470
|
+
aiFeatureSlug,
|
|
471
|
+
namespace: resolvedNamespace,
|
|
472
|
+
projectDir: workspace.projectDir,
|
|
473
|
+
warnings: packageScriptChanges.addedProjectToolsDependency
|
|
474
|
+
? [
|
|
475
|
+
"Added `@wp-typia/project-tools` to devDependencies for `sync-ai`. If this workspace was already installed, rerun your package manager install command before the first `wp-typia sync ai`.",
|
|
476
|
+
]
|
|
477
|
+
: [],
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
catch (error) {
|
|
481
|
+
await rollbackWorkspaceMutation(mutationSnapshot);
|
|
482
|
+
throw error;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
@@ -10,6 +10,16 @@ export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCom
|
|
|
10
10
|
* rest-resource runtime helper module.
|
|
11
11
|
*/
|
|
12
12
|
export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
|
|
13
|
+
/**
|
|
14
|
+
* Re-export the typed workflow ability scaffold workflow from the focused
|
|
15
|
+
* ability runtime helper module.
|
|
16
|
+
*/
|
|
17
|
+
export { runAddAbilityCommand } from "./cli-add-workspace-ability.js";
|
|
18
|
+
/**
|
|
19
|
+
* Re-export the server-only AI feature scaffold workflow from the focused
|
|
20
|
+
* AI-feature runtime helper module.
|
|
21
|
+
*/
|
|
22
|
+
export { runAddAiFeatureCommand } from "./cli-add-workspace-ai.js";
|
|
13
23
|
/**
|
|
14
24
|
* Add one variation entry to an existing workspace block.
|
|
15
25
|
*
|
|
@@ -129,6 +129,16 @@ export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCom
|
|
|
129
129
|
* rest-resource runtime helper module.
|
|
130
130
|
*/
|
|
131
131
|
export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
|
|
132
|
+
/**
|
|
133
|
+
* Re-export the typed workflow ability scaffold workflow from the focused
|
|
134
|
+
* ability runtime helper module.
|
|
135
|
+
*/
|
|
136
|
+
export { runAddAbilityCommand } from "./cli-add-workspace-ability.js";
|
|
137
|
+
/**
|
|
138
|
+
* Re-export the server-only AI feature scaffold workflow from the focused
|
|
139
|
+
* AI-feature runtime helper module.
|
|
140
|
+
*/
|
|
141
|
+
export { runAddAiFeatureCommand } from "./cli-add-workspace-ai.js";
|
|
132
142
|
/**
|
|
133
143
|
* Add one variation entry to an existing workspace block.
|
|
134
144
|
*
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, } from "./cli-add-shared.js";
|
|
11
11
|
export type { AddBlockTemplateId, AddKindId, EditorPluginSlotId, } from "./cli-add-shared.js";
|
|
12
12
|
export { runAddBlockCommand, seedWorkspaceMigrationProject, } from "./cli-add-block.js";
|
|
13
|
-
export { runAddBindingSourceCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
13
|
+
export { runAddBindingSourceCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
14
14
|
export { getWorkspaceBlockSelectOptions } from "./workspace-inventory.js";
|
package/dist/runtime/cli-add.js
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, } from "./cli-add-shared.js";
|
|
11
11
|
export { runAddBlockCommand, seedWorkspaceMigrationProject, } from "./cli-add-block.js";
|
|
12
|
-
export { runAddBindingSourceCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
12
|
+
export { runAddBindingSourceCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
|
|
13
13
|
export { getWorkspaceBlockSelectOptions } from "./workspace-inventory.js";
|
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
* Import `formatAddHelpText`, `runAddBlockCommand`,
|
|
9
9
|
* `runAddVariationCommand`, `runAddPatternCommand`,
|
|
10
10
|
* `runAddBindingSourceCommand`, `runAddHookedBlockCommand`,
|
|
11
|
+
* `runAddAbilityCommand` for typed workflow ability scaffolds,
|
|
11
12
|
* and `HOOKED_BLOCK_POSITION_IDS`,
|
|
12
13
|
* `getWorkspaceBlockSelectOptions`, and `seedWorkspaceMigrationProject` for
|
|
13
14
|
* explicit `wp-typia add` flows,
|
|
15
|
+
* `runAddAiFeatureCommand` for server-owned WordPress AI feature scaffolds,
|
|
14
16
|
* `runAddRestResourceCommand` for plugin-level REST resource scaffolds,
|
|
15
17
|
* `getDoctorChecks`, `runDoctor`, and `DoctorCheck` for diagnostics,
|
|
16
18
|
* `createCliCommandError` and `formatCliDiagnosticError` for shared
|
|
@@ -26,7 +28,7 @@
|
|
|
26
28
|
export { getDoctorChecks, runDoctor, type DoctorCheck } from "./cli-doctor.js";
|
|
27
29
|
export { createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
|
|
28
30
|
export type { CliDiagnosticMessage } from "./cli-diagnostics.js";
|
|
29
|
-
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
31
|
+
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddAbilityCommand, runAddBindingSourceCommand, runAddAiFeatureCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
30
32
|
export { COMPOUND_INNER_BLOCKS_PRESET_IDS, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
|
|
31
33
|
export type { CompoundInnerBlocksPresetId } from "./compound-inner-blocks.js";
|
|
32
34
|
export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
|
package/dist/runtime/cli-core.js
CHANGED
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
* Import `formatAddHelpText`, `runAddBlockCommand`,
|
|
9
9
|
* `runAddVariationCommand`, `runAddPatternCommand`,
|
|
10
10
|
* `runAddBindingSourceCommand`, `runAddHookedBlockCommand`,
|
|
11
|
+
* `runAddAbilityCommand` for typed workflow ability scaffolds,
|
|
11
12
|
* and `HOOKED_BLOCK_POSITION_IDS`,
|
|
12
13
|
* `getWorkspaceBlockSelectOptions`, and `seedWorkspaceMigrationProject` for
|
|
13
14
|
* explicit `wp-typia add` flows,
|
|
15
|
+
* `runAddAiFeatureCommand` for server-owned WordPress AI feature scaffolds,
|
|
14
16
|
* `runAddRestResourceCommand` for plugin-level REST resource scaffolds,
|
|
15
17
|
* `getDoctorChecks`, `runDoctor`, and `DoctorCheck` for diagnostics,
|
|
16
18
|
* `createCliCommandError` and `formatCliDiagnosticError` for shared
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
*/
|
|
26
28
|
export { getDoctorChecks, runDoctor } from "./cli-doctor.js";
|
|
27
29
|
export { createCliCommandError, CliDiagnosticError, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
|
|
28
|
-
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddBindingSourceCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
30
|
+
export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, runAddAbilityCommand, runAddBindingSourceCommand, runAddAiFeatureCommand, runAddBlockCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
|
|
29
31
|
export { COMPOUND_INNER_BLOCKS_PRESET_IDS, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
|
|
30
32
|
export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
|
|
31
33
|
export { formatHelpText } from "./cli-help.js";
|
|
@@ -17,6 +17,8 @@ export declare const CLI_DIAGNOSTIC_CODES: {
|
|
|
17
17
|
readonly MISSING_ARGUMENT: "missing-argument";
|
|
18
18
|
readonly MISSING_BUILD_ARTIFACT: "missing-build-artifact";
|
|
19
19
|
readonly OUTSIDE_PROJECT_ROOT: "outside-project-root";
|
|
20
|
+
readonly TEMPLATE_SOURCE_TIMEOUT: "template-source-timeout";
|
|
21
|
+
readonly TEMPLATE_SOURCE_TOO_LARGE: "template-source-too-large";
|
|
20
22
|
readonly UNSUPPORTED_COMMAND: "unsupported-command";
|
|
21
23
|
};
|
|
22
24
|
export type CliDiagnosticCode = (typeof CLI_DIAGNOSTIC_CODES)[keyof typeof CLI_DIAGNOSTIC_CODES];
|
|
@@ -8,12 +8,15 @@ export const CLI_DIAGNOSTIC_CODES = {
|
|
|
8
8
|
MISSING_ARGUMENT: "missing-argument",
|
|
9
9
|
MISSING_BUILD_ARTIFACT: "missing-build-artifact",
|
|
10
10
|
OUTSIDE_PROJECT_ROOT: "outside-project-root",
|
|
11
|
+
TEMPLATE_SOURCE_TIMEOUT: "template-source-timeout",
|
|
12
|
+
TEMPLATE_SOURCE_TOO_LARGE: "template-source-too-large",
|
|
11
13
|
UNSUPPORTED_COMMAND: "unsupported-command",
|
|
12
14
|
};
|
|
13
15
|
const DEFAULT_CLI_FAILURE_SUMMARIES = {
|
|
14
16
|
add: "Unable to complete the requested add workflow.",
|
|
15
17
|
create: "Unable to complete the requested create workflow.",
|
|
16
18
|
doctor: "One or more doctor checks failed.",
|
|
19
|
+
init: "Unable to preview the requested retrofit init plan.",
|
|
17
20
|
mcp: "Unable to inspect or sync MCP metadata.",
|
|
18
21
|
migrate: "Unable to complete the requested migration command.",
|
|
19
22
|
sync: "Unable to complete the requested sync workflow.",
|
|
@@ -168,10 +171,16 @@ function inferCliDiagnosticCode(options) {
|
|
|
168
171
|
if (/dependencies have not been installed yet/u.test(haystack)) {
|
|
169
172
|
return CLI_DIAGNOSTIC_CODES.DEPENDENCIES_NOT_INSTALLED;
|
|
170
173
|
}
|
|
174
|
+
if (/Timed out while .*external template|Timed out while .*npm template|Timed out while .*GitHub template/u.test(haystack)) {
|
|
175
|
+
return CLI_DIAGNOSTIC_CODES.TEMPLATE_SOURCE_TIMEOUT;
|
|
176
|
+
}
|
|
177
|
+
if (/external template size limit/u.test(haystack)) {
|
|
178
|
+
return CLI_DIAGNOSTIC_CODES.TEMPLATE_SOURCE_TOO_LARGE;
|
|
179
|
+
}
|
|
171
180
|
if (options.command === "doctor") {
|
|
172
181
|
return CLI_DIAGNOSTIC_CODES.DOCTOR_CHECK_FAILED;
|
|
173
182
|
}
|
|
174
|
-
if (/requires <|requires
|
|
183
|
+
if (/requires <|requires --|requires a value/u.test(haystack)) {
|
|
175
184
|
return CLI_DIAGNOSTIC_CODES.MISSING_ARGUMENT;
|
|
176
185
|
}
|
|
177
186
|
if (/Unknown .*subcommand|Unknown add kind|Unknown template|removed in favor|does not support|The Bun-free fallback runtime does not support|The positional alias only accepts/u.test(haystack)) {
|