@wp-typia/project-tools 0.19.3 → 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.
Files changed (50) hide show
  1. package/README.md +23 -0
  2. package/dist/runtime/ability-spec.d.ts +90 -0
  3. package/dist/runtime/ability-spec.js +51 -0
  4. package/dist/runtime/ai-artifacts.d.ts +39 -0
  5. package/dist/runtime/ai-artifacts.js +68 -0
  6. package/dist/runtime/ai-feature-artifacts.d.ts +85 -0
  7. package/dist/runtime/ai-feature-artifacts.js +139 -0
  8. package/dist/runtime/ai-feature-capability.d.ts +114 -0
  9. package/dist/runtime/ai-feature-capability.js +150 -0
  10. package/dist/runtime/block-generator-service-spec.js +6 -0
  11. package/dist/runtime/cli-add-shared.d.ts +32 -1
  12. package/dist/runtime/cli-add-shared.js +44 -0
  13. package/dist/runtime/cli-add-workspace-ability.d.ts +8 -0
  14. package/dist/runtime/cli-add-workspace-ability.js +810 -0
  15. package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +22 -0
  16. package/dist/runtime/cli-add-workspace-ai-anchors.js +277 -0
  17. package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +28 -0
  18. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +346 -0
  19. package/dist/runtime/cli-add-workspace-ai.d.ts +14 -0
  20. package/dist/runtime/cli-add-workspace-ai.js +484 -0
  21. package/dist/runtime/cli-add-workspace.d.ts +10 -0
  22. package/dist/runtime/cli-add-workspace.js +10 -0
  23. package/dist/runtime/cli-add.d.ts +1 -1
  24. package/dist/runtime/cli-add.js +1 -1
  25. package/dist/runtime/cli-core.d.ts +3 -1
  26. package/dist/runtime/cli-core.js +3 -1
  27. package/dist/runtime/cli-doctor-workspace.js +140 -1
  28. package/dist/runtime/cli-help.js +4 -0
  29. package/dist/runtime/index.d.ts +3 -1
  30. package/dist/runtime/index.js +2 -1
  31. package/dist/runtime/scaffold-compatibility.d.ts +65 -0
  32. package/dist/runtime/scaffold-compatibility.js +152 -0
  33. package/dist/runtime/scaffold-template-variable-groups.d.ts +2 -0
  34. package/dist/runtime/scaffold-template-variables.js +6 -0
  35. package/dist/runtime/scaffold.d.ts +3 -0
  36. package/dist/runtime/typia-llm.d.ts +213 -0
  37. package/dist/runtime/typia-llm.js +348 -0
  38. package/dist/runtime/wordpress-ai.d.ts +122 -0
  39. package/dist/runtime/wordpress-ai.js +177 -0
  40. package/dist/runtime/workspace-inventory.d.ts +51 -4
  41. package/dist/runtime/workspace-inventory.js +157 -4
  42. package/package.json +12 -2
  43. package/templates/_shared/base/{{slugKebabCase}}.php.mustache +3 -3
  44. package/templates/_shared/compound/core/{{slugKebabCase}}.php.mustache +3 -3
  45. package/templates/_shared/compound/persistence-auth/{{slugKebabCase}}.php.mustache +3 -3
  46. package/templates/_shared/compound/persistence-public/{{slugKebabCase}}.php.mustache +3 -3
  47. package/templates/_shared/persistence/auth/{{slugKebabCase}}.php.mustache +3 -3
  48. package/templates/_shared/persistence/core/{{slugKebabCase}}.php.mustache +3 -3
  49. package/templates/_shared/persistence/public/{{slugKebabCase}}.php.mustache +3 -3
  50. package/templates/query-loop/{{slugKebabCase}}.php.mustache +3 -3
package/README.md CHANGED
@@ -17,6 +17,8 @@ Supported public imports:
17
17
 
18
18
  - `@wp-typia/project-tools`
19
19
  - `@wp-typia/project-tools/schema-core`
20
+ - `@wp-typia/project-tools/ai-artifacts`
21
+ - `@wp-typia/project-tools/typia-llm`
20
22
 
21
23
  Implementation note:
22
24
 
@@ -48,6 +50,20 @@ import {
48
50
  import { normalizeEndpointAuthDefinition } from '@wp-typia/project-tools/schema-core';
49
51
  ```
50
52
 
53
+ ```ts
54
+ import {
55
+ syncWordPressAiArtifacts,
56
+ type AbilitySpecCatalog,
57
+ } from '@wp-typia/project-tools/ai-artifacts';
58
+ ```
59
+
60
+ ```ts
61
+ import {
62
+ syncTypiaLlmAdapterModule,
63
+ projectTypiaLlmApplicationArtifact,
64
+ } from '@wp-typia/project-tools/typia-llm';
65
+ ```
66
+
51
67
  `BlockGeneratorService` is the additive typed orchestration boundary for built-in
52
68
  block scaffolds. Built-in templates no longer ship structural, TS/TSX, style,
53
69
  or block-local `render.php` Mustache files for built-in `types.ts`,
@@ -81,3 +97,10 @@ and `inspectBlockGeneration(...)`. The layer contract record lives in
81
97
  [`docs/external-template-layer-composition.md`](https://imjlk.github.io/wp-typia/architecture/external-template-layer-composition/).
82
98
 
83
99
  If you need metadata sync, editor helpers, validation helpers, or other generated-project runtime utilities, import them directly from `@wp-typia/block-runtime/*`.
100
+
101
+ `@wp-typia/project-tools/typia-llm` is an opt-in build-time adapter target for
102
+ downstream TypeScript-first tool/function consumers. It renders the generated
103
+ `typia.llm` TypeScript module from endpoint manifests and canonical contract
104
+ types, and exposes JSON-friendly projection helpers for compiled
105
+ `typia.llm.application(...)` and `typia.llm.structuredOutput(...)` results. It
106
+ does not add a generated-project runtime dependency on `typia.llm`.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Marks behavioral flags that shape how an ability should be exposed to
3
+ * WordPress-native AI and workflow consumers.
4
+ */
5
+ export interface AbilityAnnotationSpec {
6
+ /** Indicates that invoking the ability mutates persisted state. */
7
+ destructive?: boolean;
8
+ /** Indicates that repeated invocations with the same input are safe. */
9
+ idempotent?: boolean;
10
+ /** Indicates that the ability only reads data and does not mutate state. */
11
+ readonly?: boolean;
12
+ }
13
+ /**
14
+ * Describes a shared category bucket that multiple projected abilities can
15
+ * reference.
16
+ */
17
+ export interface AbilityCategorySpec {
18
+ /** Stable category identifier written into the generated abilities document. */
19
+ id: string;
20
+ /** Human-readable label presented by downstream discovery surfaces. */
21
+ label: string;
22
+ }
23
+ /**
24
+ * Defines optional metadata that an adapter can use when exposing abilities to
25
+ * MCP-aware consumers.
26
+ */
27
+ export interface AbilityMcpProjectionSpec {
28
+ /** Marks an ability as safe to expose through an opt-in public MCP adapter. */
29
+ public?: boolean;
30
+ }
31
+ /**
32
+ * Carries WordPress-specific metadata that should survive ability projection
33
+ * without taking ownership away from the endpoint manifest.
34
+ */
35
+ export interface AbilityMetaSpec {
36
+ /** Allows forward-compatible metadata keys owned by the ability layer. */
37
+ [key: string]: unknown;
38
+ /** Namespaces optional MCP adapter hints away from core WordPress metadata. */
39
+ mcp?: AbilityMcpProjectionSpec;
40
+ }
41
+ /**
42
+ * Describes WordPress-owned metadata that merges with an endpoint manifest when
43
+ * building projected ability artifacts.
44
+ */
45
+ export interface AbilitySpec {
46
+ /** Behavioral annotations that describe how the ability should be treated. */
47
+ annotations?: AbilityAnnotationSpec;
48
+ /** Category identifier that must resolve inside the shared catalog map. */
49
+ categoryId: string;
50
+ /** PHP callback that executes the ability on the server. */
51
+ executeCallback: string;
52
+ /** Human-readable label shown to downstream discovery clients. */
53
+ label: string;
54
+ /** Optional WordPress-owned metadata preserved in the projected document. */
55
+ meta?: AbilityMetaSpec;
56
+ /** PHP callback that gates access before execution. */
57
+ permissionCallback: string;
58
+ /** Controls whether the projected ability stays visible to REST discovery. */
59
+ showInRest?: boolean;
60
+ }
61
+ /**
62
+ * Groups all WordPress-owned ability specs and category definitions for a
63
+ * projection unit.
64
+ */
65
+ export interface AbilitySpecCatalog {
66
+ /** Ability definitions keyed by the endpoint operationId they augment. */
67
+ abilities: Record<string, AbilitySpec>;
68
+ /** Shared category definitions keyed by category id. */
69
+ categories: Record<string, AbilityCategorySpec>;
70
+ }
71
+ /**
72
+ * Documents which fields remain owned by AbilitySpec metadata versus the
73
+ * endpoint manifest when the two surfaces are merged.
74
+ */
75
+ export declare const ABILITY_SPEC_MERGE_BOUNDARY: {
76
+ /** Property paths that must come from the AbilitySpec layer. */
77
+ readonly abilitySpecOwns: readonly ["categoryId", "category.label", "label", "executeCallback", "permissionCallback", "annotations.readonly", "annotations.destructive", "annotations.idempotent", "meta.mcp.public", "showInRest"];
78
+ readonly endpointManifestOwns: readonly ["operationId", "method", "path", "summary", "queryContract", "bodyContract", "responseContract", "auth", "authMode", "wordpressAuth"];
79
+ };
80
+ /**
81
+ * Resolves and validates the category referenced by an AbilitySpec.
82
+ *
83
+ * @param abilitySpec Ability definition that references a shared category id.
84
+ * @param categories Available category map for the current projection scope.
85
+ * @param operationId Endpoint identifier used in validation errors.
86
+ * @returns The resolved category definition.
87
+ * @throws When the category id is missing from the catalog.
88
+ * @throws When the resolved category definition reports a different id.
89
+ */
90
+ export declare function resolveAbilityCategorySpec(abilitySpec: AbilitySpec, categories: Record<string, AbilityCategorySpec>, operationId: string): AbilityCategorySpec;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Documents which fields remain owned by AbilitySpec metadata versus the
3
+ * endpoint manifest when the two surfaces are merged.
4
+ */
5
+ export const ABILITY_SPEC_MERGE_BOUNDARY = {
6
+ /** Property paths that must come from the AbilitySpec layer. */
7
+ abilitySpecOwns: [
8
+ 'categoryId',
9
+ 'category.label',
10
+ 'label',
11
+ 'executeCallback',
12
+ 'permissionCallback',
13
+ 'annotations.readonly',
14
+ 'annotations.destructive',
15
+ 'annotations.idempotent',
16
+ 'meta.mcp.public',
17
+ 'showInRest',
18
+ ],
19
+ endpointManifestOwns: [
20
+ 'operationId',
21
+ 'method',
22
+ 'path',
23
+ 'summary',
24
+ 'queryContract',
25
+ 'bodyContract',
26
+ 'responseContract',
27
+ 'auth',
28
+ 'authMode',
29
+ 'wordpressAuth',
30
+ ],
31
+ };
32
+ /**
33
+ * Resolves and validates the category referenced by an AbilitySpec.
34
+ *
35
+ * @param abilitySpec Ability definition that references a shared category id.
36
+ * @param categories Available category map for the current projection scope.
37
+ * @param operationId Endpoint identifier used in validation errors.
38
+ * @returns The resolved category definition.
39
+ * @throws When the category id is missing from the catalog.
40
+ * @throws When the resolved category definition reports a different id.
41
+ */
42
+ export function resolveAbilityCategorySpec(abilitySpec, categories, operationId) {
43
+ const category = categories[abilitySpec.categoryId];
44
+ if (!category) {
45
+ throw new Error(`Operation "${operationId}" references unknown AbilitySpec category "${abilitySpec.categoryId}".`);
46
+ }
47
+ if (category.id !== abilitySpec.categoryId) {
48
+ throw new Error(`AbilitySpec category "${abilitySpec.categoryId}" resolves to category id "${category.id}".`);
49
+ }
50
+ return category;
51
+ }
@@ -0,0 +1,39 @@
1
+ import type { ArtifactSyncExecutionOptions } from '@wp-typia/block-runtime/metadata-core';
2
+ import { buildWordPressAiArtifacts, type ProjectedWordPressAbilitiesDocument } from './wordpress-ai.js';
3
+ export { buildWordPressAiArtifacts, buildWordPressAbilitiesDocument, projectWordPressAiSchema, } from './wordpress-ai.js';
4
+ export type { AbilityAnnotationSpec, AbilityCategorySpec, AbilityMcpProjectionSpec, AbilityMetaSpec, AbilitySpec, AbilitySpecCatalog, ProjectedWordPressAbilityDefinition, ProjectedWordPressAbilitiesDocument, WordPressAiInputSchemaTransformContext, } from './wordpress-ai.js';
5
+ type BuildWordPressAiArtifactsParameters = Parameters<typeof buildWordPressAiArtifacts>[0];
6
+ /**
7
+ * Configures where the generated WordPress AI artifacts should be written or
8
+ * verified on disk.
9
+ */
10
+ export interface SyncWordPressAiArtifactsOptions extends ArtifactSyncExecutionOptions, BuildWordPressAiArtifactsParameters {
11
+ /** Destination path for the generated `*.abilities.json` document. */
12
+ abilitiesDocumentFile: string;
13
+ /** Destination path for the generated `*.ai.schema.json` document. */
14
+ aiSchemaFile: string;
15
+ }
16
+ /**
17
+ * Describes the generated artifact payloads and the file paths they were
18
+ * written to or verified against.
19
+ */
20
+ export interface SyncWordPressAiArtifactsResult {
21
+ /** Generated abilities document content. */
22
+ abilitiesDocument: ProjectedWordPressAbilitiesDocument;
23
+ /** Destination path for the generated abilities document. */
24
+ abilitiesDocumentPath: string;
25
+ /** Generated AI response schema content. */
26
+ aiResponseSchema: Record<string, unknown>;
27
+ /** Destination path for the generated AI response schema. */
28
+ aiSchemaPath: string;
29
+ /** True when files were only verified, false when they were written. */
30
+ check: boolean;
31
+ }
32
+ /**
33
+ * Builds WordPress AI artifact documents from a manifest-first contract surface
34
+ * and then writes or verifies the generated JSON files on disk.
35
+ *
36
+ * @param options Artifact destinations plus the same manifest/category/schema inputs used by `buildWordPressAiArtifacts()`.
37
+ * @returns Generated documents and the output file paths that were checked or written.
38
+ */
39
+ export declare function syncWordPressAiArtifacts({ abilitiesDocumentFile, aiSchemaFile, check, ...buildOptions }: SyncWordPressAiArtifactsOptions): Promise<SyncWordPressAiArtifactsResult>;
@@ -0,0 +1,68 @@
1
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { buildWordPressAiArtifacts, } from './wordpress-ai.js';
4
+ export { buildWordPressAiArtifacts, buildWordPressAbilitiesDocument, projectWordPressAiSchema, } from './wordpress-ai.js';
5
+ function normalizeGeneratedArtifactContent(content) {
6
+ return content.replace(/\r\n?/g, '\n');
7
+ }
8
+ async function reconcileGeneratedAiArtifacts(artifacts, check) {
9
+ if (!check) {
10
+ for (const artifact of artifacts) {
11
+ await mkdir(path.dirname(artifact.filePath), {
12
+ recursive: true,
13
+ });
14
+ await writeFile(artifact.filePath, artifact.content, 'utf8');
15
+ }
16
+ return;
17
+ }
18
+ const issues = [];
19
+ for (const artifact of artifacts) {
20
+ try {
21
+ const current = normalizeGeneratedArtifactContent(await readFile(artifact.filePath, 'utf8'));
22
+ const expected = normalizeGeneratedArtifactContent(artifact.content);
23
+ if (current !== expected) {
24
+ issues.push(`- ${artifact.filePath} (stale)`);
25
+ }
26
+ }
27
+ catch (error) {
28
+ const code = error && typeof error === 'object' && 'code' in error
29
+ ? error.code
30
+ : undefined;
31
+ if (code === 'ENOENT') {
32
+ issues.push(`- ${artifact.filePath} (missing)`);
33
+ continue;
34
+ }
35
+ issues.push(`- ${artifact.filePath} (unreadable: ${error instanceof Error ? error.message : code ?? 'unknown'})`);
36
+ }
37
+ }
38
+ if (issues.length > 0) {
39
+ throw new Error(`Generated WordPress AI artifacts are missing or stale:\n${issues.join('\n')}`);
40
+ }
41
+ }
42
+ /**
43
+ * Builds WordPress AI artifact documents from a manifest-first contract surface
44
+ * and then writes or verifies the generated JSON files on disk.
45
+ *
46
+ * @param options Artifact destinations plus the same manifest/category/schema inputs used by `buildWordPressAiArtifacts()`.
47
+ * @returns Generated documents and the output file paths that were checked or written.
48
+ */
49
+ export async function syncWordPressAiArtifacts({ abilitiesDocumentFile, aiSchemaFile, check = false, ...buildOptions }) {
50
+ const { abilitiesDocument, aiResponseSchema } = await buildWordPressAiArtifacts(buildOptions);
51
+ await reconcileGeneratedAiArtifacts([
52
+ {
53
+ content: `${JSON.stringify(aiResponseSchema, null, 2)}\n`,
54
+ filePath: aiSchemaFile,
55
+ },
56
+ {
57
+ content: `${JSON.stringify(abilitiesDocument, null, 2)}\n`,
58
+ filePath: abilitiesDocumentFile,
59
+ },
60
+ ], check);
61
+ return {
62
+ abilitiesDocument,
63
+ abilitiesDocumentPath: abilitiesDocumentFile,
64
+ aiResponseSchema,
65
+ aiSchemaPath: aiSchemaFile,
66
+ check,
67
+ };
68
+ }
@@ -0,0 +1,85 @@
1
+ import { type ArtifactSyncExecutionOptions } from "@wp-typia/block-runtime/metadata-core";
2
+ import type { JsonSchemaDocument } from "./schema-core.js";
3
+ interface AiFeatureTemplateVariablesLike {
4
+ namespace: string;
5
+ pascalCase: string;
6
+ slugKebabCase: string;
7
+ title: string;
8
+ }
9
+ interface SyncAiFeatureRestArtifactsOptions {
10
+ clientFile: string;
11
+ executionOptions?: ArtifactSyncExecutionOptions;
12
+ outputDir: string;
13
+ projectDir: string;
14
+ typesFile: string;
15
+ validatorsFile: string;
16
+ variables: AiFeatureTemplateVariablesLike;
17
+ }
18
+ /**
19
+ * Configures the AI-safe schema projection for one scaffolded AI feature.
20
+ */
21
+ export interface SyncAiFeatureSchemaArtifactOptions extends ArtifactSyncExecutionOptions {
22
+ aiSchemaFile: string;
23
+ outputDir: string;
24
+ projectDir: string;
25
+ }
26
+ /**
27
+ * Carries the generated AI schema document and the file paths touched on disk.
28
+ */
29
+ export interface SyncAiFeatureSchemaArtifactResult {
30
+ aiSchema: JsonSchemaDocument & Record<string, unknown>;
31
+ aiSchemaPath: string;
32
+ check: boolean;
33
+ sourceSchemaPath: string;
34
+ }
35
+ /**
36
+ * Build the endpoint manifest for a workspace-level AI feature scaffold.
37
+ *
38
+ * The endpoint response wraps a typed AI result payload together with provider,
39
+ * model, and token-usage telemetry. The nested `feature-result` contract is
40
+ * also kept in the manifest so `sync-rest` can emit the canonical JSON Schema
41
+ * that `sync-ai` later projects into the AI structured-output profile.
42
+ *
43
+ * @param variables Template naming data used for type names, routes, and docs.
44
+ * @returns Endpoint manifest consumed by schema, OpenAPI, and client generators.
45
+ */
46
+ export declare function buildAiFeatureEndpointManifest(variables: AiFeatureTemplateVariablesLike): import("@wp-typia/block-runtime/metadata-core").EndpointManifestDefinition<{
47
+ readonly "feature-request": {
48
+ readonly sourceTypeName: `${string}AiFeatureRequest`;
49
+ };
50
+ readonly "feature-response": {
51
+ readonly sourceTypeName: `${string}AiFeatureResponse`;
52
+ };
53
+ readonly "feature-result": {
54
+ readonly sourceTypeName: `${string}AiFeatureResult`;
55
+ };
56
+ }, readonly [{
57
+ readonly auth: "authenticated";
58
+ readonly bodyContract: "feature-request";
59
+ readonly method: "POST";
60
+ readonly operationId: `run${string}AiFeature`;
61
+ readonly path: `/${string}/ai/${string}`;
62
+ readonly responseContract: "feature-response";
63
+ readonly summary: `Run the ${string} AI feature endpoint.`;
64
+ readonly tags: readonly [`${string} AI`];
65
+ readonly wordpressAuth: {
66
+ readonly mechanism: "rest-nonce";
67
+ };
68
+ }]>;
69
+ /**
70
+ * Synchronize generated schemas, OpenAPI output, and endpoint client code for
71
+ * a workspace-level AI feature scaffold.
72
+ *
73
+ * @param options Feature file paths and naming variables.
74
+ * @returns A promise that resolves after every generated REST artifact has been refreshed.
75
+ */
76
+ export declare function syncAiFeatureRestArtifacts({ clientFile, executionOptions, outputDir, projectDir, typesFile, validatorsFile, variables, }: SyncAiFeatureRestArtifactsOptions): Promise<void>;
77
+ /**
78
+ * Project the canonical AI result contract for one scaffolded feature into the
79
+ * AI structured-output schema profile consumed by `wp_ai_client_prompt()`.
80
+ *
81
+ * @param options Artifact destination plus the feature output directory.
82
+ * @returns The projected AI schema and the source schema path it derived from.
83
+ */
84
+ export declare function syncAiFeatureSchemaArtifact({ aiSchemaFile, check, outputDir, projectDir, }: SyncAiFeatureSchemaArtifactOptions): Promise<SyncAiFeatureSchemaArtifactResult>;
85
+ export {};
@@ -0,0 +1,139 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { defineEndpointManifest, syncEndpointClient, syncRestOpenApi, syncTypeSchemas, } from "@wp-typia/block-runtime/metadata-core";
4
+ import { projectWordPressAiSchema } from "./ai-artifacts.js";
5
+ function normalizeGeneratedArtifactContent(content) {
6
+ return content.replace(/\r\n?/g, "\n");
7
+ }
8
+ async function reconcileGeneratedArtifact(options) {
9
+ if (!options.check) {
10
+ await mkdir(path.dirname(options.filePath), {
11
+ recursive: true,
12
+ });
13
+ await writeFile(options.filePath, options.content, "utf8");
14
+ return;
15
+ }
16
+ try {
17
+ const current = normalizeGeneratedArtifactContent(await readFile(options.filePath, "utf8"));
18
+ const expected = normalizeGeneratedArtifactContent(options.content);
19
+ if (current !== expected) {
20
+ throw new Error(`Generated AI feature artifact is stale: ${options.label} (${options.filePath}).`);
21
+ }
22
+ }
23
+ catch (error) {
24
+ const code = error && typeof error === "object" && "code" in error
25
+ ? error.code
26
+ : undefined;
27
+ if (code === "ENOENT") {
28
+ throw new Error(`Generated AI feature artifact is missing: ${options.label} (${options.filePath}).`);
29
+ }
30
+ throw error;
31
+ }
32
+ }
33
+ function assertJsonObject(value, label) {
34
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
35
+ throw new Error(`Expected ${label} to decode to a JSON object.`);
36
+ }
37
+ return value;
38
+ }
39
+ /**
40
+ * Build the endpoint manifest for a workspace-level AI feature scaffold.
41
+ *
42
+ * The endpoint response wraps a typed AI result payload together with provider,
43
+ * model, and token-usage telemetry. The nested `feature-result` contract is
44
+ * also kept in the manifest so `sync-rest` can emit the canonical JSON Schema
45
+ * that `sync-ai` later projects into the AI structured-output profile.
46
+ *
47
+ * @param variables Template naming data used for type names, routes, and docs.
48
+ * @returns Endpoint manifest consumed by schema, OpenAPI, and client generators.
49
+ */
50
+ export function buildAiFeatureEndpointManifest(variables) {
51
+ return defineEndpointManifest({
52
+ contracts: {
53
+ "feature-request": {
54
+ sourceTypeName: `${variables.pascalCase}AiFeatureRequest`,
55
+ },
56
+ "feature-response": {
57
+ sourceTypeName: `${variables.pascalCase}AiFeatureResponse`,
58
+ },
59
+ "feature-result": {
60
+ sourceTypeName: `${variables.pascalCase}AiFeatureResult`,
61
+ },
62
+ },
63
+ endpoints: [
64
+ {
65
+ auth: "authenticated",
66
+ bodyContract: "feature-request",
67
+ method: "POST",
68
+ operationId: `run${variables.pascalCase}AiFeature`,
69
+ path: `/${variables.namespace}/ai/${variables.slugKebabCase}`,
70
+ responseContract: "feature-response",
71
+ summary: `Run the ${variables.title} AI feature endpoint.`,
72
+ tags: [`${variables.title} AI`],
73
+ wordpressAuth: {
74
+ mechanism: "rest-nonce",
75
+ },
76
+ },
77
+ ],
78
+ info: {
79
+ title: `${variables.title} AI Feature API`,
80
+ version: "1.0.0",
81
+ },
82
+ });
83
+ }
84
+ /**
85
+ * Synchronize generated schemas, OpenAPI output, and endpoint client code for
86
+ * a workspace-level AI feature scaffold.
87
+ *
88
+ * @param options Feature file paths and naming variables.
89
+ * @returns A promise that resolves after every generated REST artifact has been refreshed.
90
+ */
91
+ export async function syncAiFeatureRestArtifacts({ clientFile, executionOptions, outputDir, projectDir, typesFile, validatorsFile, variables, }) {
92
+ const manifest = buildAiFeatureEndpointManifest(variables);
93
+ for (const [baseName, contract] of Object.entries(manifest.contracts)) {
94
+ await syncTypeSchemas({
95
+ jsonSchemaFile: path.join(outputDir, "api-schemas", `${baseName}.schema.json`),
96
+ openApiFile: path.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
97
+ projectRoot: projectDir,
98
+ sourceTypeName: contract.sourceTypeName,
99
+ typesFile,
100
+ }, executionOptions);
101
+ }
102
+ await syncRestOpenApi({
103
+ manifest,
104
+ openApiFile: path.join(outputDir, "api.openapi.json"),
105
+ projectRoot: projectDir,
106
+ typesFile,
107
+ }, executionOptions);
108
+ await syncEndpointClient({
109
+ clientFile,
110
+ manifest,
111
+ projectRoot: projectDir,
112
+ typesFile,
113
+ validatorsFile,
114
+ }, executionOptions);
115
+ }
116
+ /**
117
+ * Project the canonical AI result contract for one scaffolded feature into the
118
+ * AI structured-output schema profile consumed by `wp_ai_client_prompt()`.
119
+ *
120
+ * @param options Artifact destination plus the feature output directory.
121
+ * @returns The projected AI schema and the source schema path it derived from.
122
+ */
123
+ export async function syncAiFeatureSchemaArtifact({ aiSchemaFile, check = false, outputDir, projectDir, }) {
124
+ const sourceSchemaPath = path.join(projectDir, outputDir, "api-schemas", "feature-result.schema.json");
125
+ const responseSchema = assertJsonObject(JSON.parse(await readFile(sourceSchemaPath, "utf8")), sourceSchemaPath);
126
+ const aiSchema = projectWordPressAiSchema(responseSchema);
127
+ await reconcileGeneratedArtifact({
128
+ check,
129
+ content: `${JSON.stringify(aiSchema, null, 2)}\n`,
130
+ filePath: path.join(projectDir, aiSchemaFile),
131
+ label: "AI feature schema",
132
+ });
133
+ return {
134
+ aiSchema,
135
+ aiSchemaPath: path.join(projectDir, aiSchemaFile),
136
+ check,
137
+ sourceSchemaPath,
138
+ };
139
+ }
@@ -0,0 +1,114 @@
1
+ /** Declares whether a generated feature is optional or required at runtime. */
2
+ export type AiFeatureCapabilityMode = 'optional' | 'required';
3
+ /** Describes the minimum compatible platform versions for a feature. */
4
+ export interface AiFeatureCompatibilityFloor {
5
+ /** Minimum supported PHP version, when a feature depends on PHP behavior. */
6
+ php?: string;
7
+ /** Minimum supported WordPress version, when a feature depends on core APIs. */
8
+ wordpress?: string;
9
+ }
10
+ /** Identifies a concrete runtime signal that a feature depends on. */
11
+ export interface AiFeatureRuntimeGate {
12
+ /** The kind of runtime dependency or capability being checked. */
13
+ kind: 'adapter' | 'php-function' | 'script-package' | 'wordpress-core-feature';
14
+ /** The concrete symbol, package, or adapter name required at runtime. */
15
+ value: string;
16
+ }
17
+ /** Defines a single AI-related feature that scaffold compatibility can target. */
18
+ export interface AiFeatureDefinition {
19
+ /** Human-readable summary for docs, onboarding, and generated notices. */
20
+ description: string;
21
+ /** Stable machine-readable identifier used in capability selections. */
22
+ id: string;
23
+ /** Display label presented to maintainers and downstream tooling. */
24
+ label: string;
25
+ /** Optional minimum platform versions required by the feature. */
26
+ minimumVersions?: AiFeatureCompatibilityFloor;
27
+ /** Optional runtime gates that explain what the feature depends on. */
28
+ runtimeGates?: readonly AiFeatureRuntimeGate[];
29
+ }
30
+ /** Selects a feature and whether it is required or merely optional. */
31
+ export interface AiFeatureCapabilitySelection {
32
+ /** Feature identifier that must exist in the active registry. */
33
+ featureId: string;
34
+ /** Required selections take precedence over optional duplicates. */
35
+ mode: AiFeatureCapabilityMode;
36
+ }
37
+ /** Feature definition resolved together with its selected mode. */
38
+ export interface ResolvedAiFeatureCapability extends AiFeatureDefinition {
39
+ /** Final selected mode after duplicate feature ids are normalized. */
40
+ mode: AiFeatureCapabilityMode;
41
+ }
42
+ /** Groups the normalized feature plan used by scaffold compatibility logic. */
43
+ export interface ResolvedAiFeatureCapabilityPlan {
44
+ /** Highest required PHP and WordPress version floors across required features. */
45
+ hardMinimums: AiFeatureCompatibilityFloor;
46
+ /** Optional features that do not raise the minimum platform floor. */
47
+ optionalFeatures: ResolvedAiFeatureCapability[];
48
+ /** Required features that downstream projects must treat as mandatory. */
49
+ requiredFeatures: ResolvedAiFeatureCapability[];
50
+ }
51
+ /** Canonical registry of AI-related features supported by wp-typia today. */
52
+ export declare const AI_FEATURE_DEFINITIONS: {
53
+ readonly wordpressAiClient: {
54
+ readonly description: "WordPress 7.0 AI Client surface used by AI-capable feature endpoints.";
55
+ readonly id: "wordpress-ai-client";
56
+ readonly label: "WordPress AI Client";
57
+ readonly minimumVersions: {
58
+ readonly wordpress: "7.0";
59
+ };
60
+ readonly runtimeGates: readonly [{
61
+ readonly kind: "wordpress-core-feature";
62
+ readonly value: "WordPress AI Client";
63
+ }];
64
+ };
65
+ readonly wordpressCoreAbilities: {
66
+ readonly description: "Client-side ability discovery surface for editor and admin flows.";
67
+ readonly id: "wordpress-core-abilities";
68
+ readonly label: "@wordpress/core-abilities";
69
+ readonly minimumVersions: {
70
+ readonly wordpress: "7.0";
71
+ };
72
+ readonly runtimeGates: readonly [{
73
+ readonly kind: "script-package";
74
+ readonly value: "@wordpress/core-abilities";
75
+ }];
76
+ };
77
+ readonly wordpressMcpPublicMetadata: {
78
+ readonly description: "Optional MCP exposure metadata consumed by a separate adapter path rather than core alone.";
79
+ readonly id: "wordpress-mcp-public-metadata";
80
+ readonly label: "MCP public metadata";
81
+ readonly runtimeGates: readonly [{
82
+ readonly kind: "adapter";
83
+ readonly value: "MCP adapter";
84
+ }];
85
+ };
86
+ readonly wordpressServerAbilities: {
87
+ readonly description: "Server-side ability registration and execution surface for WordPress-native abilities.";
88
+ readonly id: "wordpress-server-abilities";
89
+ readonly label: "WordPress Abilities API";
90
+ readonly minimumVersions: {
91
+ readonly wordpress: "6.9";
92
+ };
93
+ readonly runtimeGates: readonly [{
94
+ readonly kind: "php-function";
95
+ readonly value: "wp_register_ability";
96
+ }, {
97
+ readonly kind: "php-function";
98
+ readonly value: "wp_register_ability_category";
99
+ }];
100
+ };
101
+ };
102
+ /**
103
+ * Resolves a normalized AI feature capability plan from a list of selections.
104
+ *
105
+ * Required selections win when the same feature id appears multiple times, and
106
+ * the resulting hard minimum platform floor is computed from required features
107
+ * only.
108
+ *
109
+ * @param selections Desired feature selections for a scaffold or projection.
110
+ * @param registry Feature registry to resolve against. Defaults to the built-in registry.
111
+ * @returns The normalized capability plan plus required version floors.
112
+ * @throws When a selection references an unknown feature id.
113
+ */
114
+ export declare function resolveAiFeatureCapabilityPlan(selections: readonly AiFeatureCapabilitySelection[], registry?: Readonly<Record<string, AiFeatureDefinition>>): ResolvedAiFeatureCapabilityPlan;