@wp-typia/project-tools 0.22.10 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/runtime/ai-feature-artifacts.js +4 -1
  2. package/dist/runtime/block-generator-service-spec.js +2 -1
  3. package/dist/runtime/cli-add-block-json.js +5 -1
  4. package/dist/runtime/cli-add-collision.d.ts +25 -0
  5. package/dist/runtime/cli-add-collision.js +76 -0
  6. package/dist/runtime/cli-add-help.js +12 -2
  7. package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
  8. package/dist/runtime/cli-add-kind-ids.js +3 -0
  9. package/dist/runtime/cli-add-types.d.ts +129 -0
  10. package/dist/runtime/cli-add-types.js +26 -0
  11. package/dist/runtime/cli-add-validation.d.ts +97 -1
  12. package/dist/runtime/cli-add-validation.js +313 -1
  13. package/dist/runtime/cli-add-workspace-ability-scaffold.js +4 -1
  14. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +79 -20
  15. package/dist/runtime/cli-add-workspace-admin-view-source.js +11 -2
  16. package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.d.ts +34 -0
  17. package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.js +483 -0
  18. package/dist/runtime/cli-add-workspace-admin-view-templates-default.d.ts +30 -0
  19. package/dist/runtime/cli-add-workspace-admin-view-templates-default.js +310 -0
  20. package/dist/runtime/cli-add-workspace-admin-view-templates-rest.d.ts +25 -0
  21. package/dist/runtime/cli-add-workspace-admin-view-templates-rest.js +124 -0
  22. package/dist/runtime/cli-add-workspace-admin-view-templates-settings.d.ts +34 -0
  23. package/dist/runtime/cli-add-workspace-admin-view-templates-settings.js +370 -0
  24. package/dist/runtime/cli-add-workspace-admin-view-templates-shared.d.ts +49 -0
  25. package/dist/runtime/cli-add-workspace-admin-view-templates-shared.js +259 -0
  26. package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +19 -10
  27. package/dist/runtime/cli-add-workspace-admin-view-templates.js +31 -971
  28. package/dist/runtime/cli-add-workspace-admin-view-types.d.ts +21 -0
  29. package/dist/runtime/cli-add-workspace-admin-view-types.js +22 -0
  30. package/dist/runtime/cli-add-workspace-ai-anchors.js +125 -32
  31. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +17 -1
  32. package/dist/runtime/cli-add-workspace-contract-source-emitters.d.ts +15 -0
  33. package/dist/runtime/cli-add-workspace-contract-source-emitters.js +42 -0
  34. package/dist/runtime/cli-add-workspace-contract.d.ts +15 -0
  35. package/dist/runtime/cli-add-workspace-contract.js +65 -0
  36. package/dist/runtime/cli-add-workspace-integration-env.d.ts +26 -0
  37. package/dist/runtime/cli-add-workspace-integration-env.js +428 -0
  38. package/dist/runtime/cli-add-workspace-post-meta-anchors.d.ts +23 -0
  39. package/dist/runtime/cli-add-workspace-post-meta-anchors.js +244 -0
  40. package/dist/runtime/cli-add-workspace-post-meta-source-emitters.d.ts +63 -0
  41. package/dist/runtime/cli-add-workspace-post-meta-source-emitters.js +179 -0
  42. package/dist/runtime/cli-add-workspace-post-meta.d.ts +15 -0
  43. package/dist/runtime/cli-add-workspace-post-meta.js +107 -0
  44. package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +9 -0
  45. package/dist/runtime/cli-add-workspace-rest-anchors.js +326 -21
  46. package/dist/runtime/cli-add-workspace-rest-generated.d.ts +9 -0
  47. package/dist/runtime/cli-add-workspace-rest-generated.js +158 -0
  48. package/dist/runtime/cli-add-workspace-rest-manual.d.ts +8 -0
  49. package/dist/runtime/cli-add-workspace-rest-manual.js +279 -0
  50. package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +24 -0
  51. package/dist/runtime/cli-add-workspace-rest-php-templates.js +678 -0
  52. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +98 -2
  53. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +323 -29
  54. package/dist/runtime/cli-add-workspace-rest-types.d.ts +108 -0
  55. package/dist/runtime/cli-add-workspace-rest-types.js +1 -0
  56. package/dist/runtime/cli-add-workspace-rest.d.ts +3 -7
  57. package/dist/runtime/cli-add-workspace-rest.js +34 -481
  58. package/dist/runtime/cli-add-workspace.d.ts +15 -0
  59. package/dist/runtime/cli-add-workspace.js +15 -0
  60. package/dist/runtime/cli-add.d.ts +1 -1
  61. package/dist/runtime/cli-add.js +1 -1
  62. package/dist/runtime/cli-core.d.ts +3 -2
  63. package/dist/runtime/cli-core.js +3 -2
  64. package/dist/runtime/cli-diagnostics.d.ts +3 -1
  65. package/dist/runtime/cli-diagnostics.js +17 -5
  66. package/dist/runtime/cli-doctor-environment.js +1 -3
  67. package/dist/runtime/cli-doctor-workspace-bindings.js +4 -1
  68. package/dist/runtime/cli-doctor-workspace-block-addons.d.ts +12 -0
  69. package/dist/runtime/cli-doctor-workspace-block-addons.js +134 -0
  70. package/dist/runtime/cli-doctor-workspace-block-iframe.d.ts +9 -0
  71. package/dist/runtime/cli-doctor-workspace-block-iframe.js +228 -0
  72. package/dist/runtime/cli-doctor-workspace-block-metadata.d.ts +11 -0
  73. package/dist/runtime/cli-doctor-workspace-block-metadata.js +111 -0
  74. package/dist/runtime/cli-doctor-workspace-blocks.js +6 -424
  75. package/dist/runtime/cli-doctor-workspace-features-abilities.d.ts +11 -0
  76. package/dist/runtime/cli-doctor-workspace-features-abilities.js +112 -0
  77. package/dist/runtime/cli-doctor-workspace-features-admin-views.d.ts +11 -0
  78. package/dist/runtime/cli-doctor-workspace-features-admin-views.js +128 -0
  79. package/dist/runtime/cli-doctor-workspace-features-ai.d.ts +11 -0
  80. package/dist/runtime/cli-doctor-workspace-features-ai.js +57 -0
  81. package/dist/runtime/cli-doctor-workspace-features-editor-plugins.d.ts +11 -0
  82. package/dist/runtime/cli-doctor-workspace-features-editor-plugins.js +80 -0
  83. package/dist/runtime/cli-doctor-workspace-features-post-meta.d.ts +11 -0
  84. package/dist/runtime/cli-doctor-workspace-features-post-meta.js +77 -0
  85. package/dist/runtime/cli-doctor-workspace-features-rest.d.ts +11 -0
  86. package/dist/runtime/cli-doctor-workspace-features-rest.js +120 -0
  87. package/dist/runtime/cli-doctor-workspace-features.js +14 -369
  88. package/dist/runtime/cli-doctor-workspace-package.d.ts +25 -3
  89. package/dist/runtime/cli-doctor-workspace-package.js +35 -13
  90. package/dist/runtime/cli-doctor-workspace-shared.d.ts +2 -0
  91. package/dist/runtime/cli-doctor-workspace-shared.js +2 -0
  92. package/dist/runtime/cli-doctor-workspace.js +8 -3
  93. package/dist/runtime/cli-doctor.d.ts +52 -3
  94. package/dist/runtime/cli-doctor.js +79 -8
  95. package/dist/runtime/cli-help.js +10 -0
  96. package/dist/runtime/cli-init-package-json.js +4 -2
  97. package/dist/runtime/cli-init-templates.js +11 -1
  98. package/dist/runtime/cli-prompt.d.ts +16 -2
  99. package/dist/runtime/cli-prompt.js +29 -12
  100. package/dist/runtime/cli-scaffold.d.ts +2 -1
  101. package/dist/runtime/cli-scaffold.js +19 -10
  102. package/dist/runtime/contract-artifacts.d.ts +14 -0
  103. package/dist/runtime/contract-artifacts.js +15 -0
  104. package/dist/runtime/external-template-guards.js +4 -6
  105. package/dist/runtime/index.d.ts +2 -2
  106. package/dist/runtime/index.js +1 -1
  107. package/dist/runtime/json-utils.d.ts +62 -4
  108. package/dist/runtime/json-utils.js +78 -4
  109. package/dist/runtime/local-dev-presets.js +4 -1
  110. package/dist/runtime/migration-ui-capability.js +4 -1
  111. package/dist/runtime/migration-utils.js +4 -1
  112. package/dist/runtime/package-managers.js +6 -1
  113. package/dist/runtime/package-versions.js +6 -1
  114. package/dist/runtime/rest-resource-artifacts.d.ts +57 -1
  115. package/dist/runtime/rest-resource-artifacts.js +97 -1
  116. package/dist/runtime/scaffold-bootstrap.js +7 -2
  117. package/dist/runtime/scaffold-package-manager-files.js +5 -1
  118. package/dist/runtime/scaffold-repository-reference.js +4 -2
  119. package/dist/runtime/scaffold-template-variables.js +2 -1
  120. package/dist/runtime/scaffold.d.ts +18 -1
  121. package/dist/runtime/scaffold.js +55 -2
  122. package/dist/runtime/temp-roots.js +4 -1
  123. package/dist/runtime/template-layers.js +4 -1
  124. package/dist/runtime/template-registry.js +9 -3
  125. package/dist/runtime/template-render.d.ts +1 -1
  126. package/dist/runtime/template-render.js +1 -1
  127. package/dist/runtime/template-source-cache-markers.d.ts +37 -0
  128. package/dist/runtime/template-source-cache-markers.js +125 -0
  129. package/dist/runtime/template-source-cache.d.ts +1 -4
  130. package/dist/runtime/template-source-cache.js +16 -122
  131. package/dist/runtime/template-source-contracts.d.ts +2 -0
  132. package/dist/runtime/template-source-external.d.ts +4 -2
  133. package/dist/runtime/template-source-external.js +4 -2
  134. package/dist/runtime/template-source-normalization.js +2 -1
  135. package/dist/runtime/template-source-remote.d.ts +8 -4
  136. package/dist/runtime/template-source-remote.js +26 -9
  137. package/dist/runtime/template-source-seeds.js +10 -3
  138. package/dist/runtime/workspace-inventory-mutations.js +54 -4
  139. package/dist/runtime/workspace-inventory-parser-entries.d.ts +17 -0
  140. package/dist/runtime/workspace-inventory-parser-entries.js +157 -0
  141. package/dist/runtime/workspace-inventory-parser-validation.d.ts +104 -0
  142. package/dist/runtime/workspace-inventory-parser-validation.js +34 -0
  143. package/dist/runtime/workspace-inventory-parser.d.ts +3 -44
  144. package/dist/runtime/workspace-inventory-parser.js +7 -464
  145. package/dist/runtime/workspace-inventory-read.d.ts +9 -2
  146. package/dist/runtime/workspace-inventory-read.js +9 -2
  147. package/dist/runtime/workspace-inventory-section-descriptors.d.ts +19 -0
  148. package/dist/runtime/workspace-inventory-section-descriptors.js +435 -0
  149. package/dist/runtime/workspace-inventory-templates.d.ts +16 -1
  150. package/dist/runtime/workspace-inventory-templates.js +75 -4
  151. package/dist/runtime/workspace-inventory-types.d.ts +52 -2
  152. package/dist/runtime/workspace-inventory.d.ts +2 -2
  153. package/dist/runtime/workspace-inventory.js +1 -1
  154. package/dist/runtime/workspace-project.js +4 -6
  155. package/package.json +2 -2
@@ -1,427 +1,8 @@
1
- import { promises as fsp } from "node:fs";
2
- import path from "node:path";
3
- import { ensureBlockConfigCanAddRestManifests } from "./cli-add-block-legacy-validator.js";
4
- import { assertRestResourceDoesNotExist, assertValidGeneratedSlug, assertValidRestResourceMethods, getWorkspaceBootstrapPath, normalizeBlockSlug, resolveRestResourceNamespace, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from "./cli-add-shared.js";
5
- import { ensureRestResourceBootstrapAnchors, ensureRestResourceSyncScriptAnchors, } from "./cli-add-workspace-rest-anchors.js";
6
- import { buildRestResourceApiSource, buildRestResourceConfigEntry, buildRestResourceDataSource, buildRestResourceTypesSource, buildRestResourceValidatorsSource, } from "./cli-add-workspace-rest-source-emitters.js";
7
- import { quotePhpString } from "./php-utils.js";
8
- import { syncRestResourceArtifacts } from "./rest-resource-artifacts.js";
9
- import { toPascalCase, toTitleCase } from "./string-case.js";
10
- import { appendWorkspaceInventoryEntries, readWorkspaceInventoryAsync, } from "./workspace-inventory.js";
1
+ import { assertRestResourceDoesNotExist, assertValidGeneratedSlug, normalizeBlockSlug, resolveRestResourceNamespace, } from "./cli-add-shared.js";
2
+ import { scaffoldGeneratedRestResource } from "./cli-add-workspace-rest-generated.js";
3
+ import { scaffoldManualRestContract } from "./cli-add-workspace-rest-manual.js";
4
+ import { readWorkspaceInventoryAsync } from "./workspace-inventory.js";
11
5
  import { resolveWorkspaceProject } from "./workspace-project.js";
12
- function buildRestResourceRouteRegistrations(restResourceSlug, methods, functions) {
13
- const collectionRoutes = [];
14
- const itemRoutes = [];
15
- if (methods.includes("list")) {
16
- collectionRoutes.push(`\t\tarray(
17
- \t\t\t'methods' => WP_REST_Server::READABLE,
18
- \t\t\t'callback' => '${functions.listHandlerName}',
19
- \t\t\t'permission_callback' => '__return_true',
20
- \t\t)`);
21
- }
22
- if (methods.includes("create")) {
23
- collectionRoutes.push(`\t\tarray(
24
- \t\t\t'methods' => WP_REST_Server::CREATABLE,
25
- \t\t\t'callback' => '${functions.createHandlerName}',
26
- \t\t\t'permission_callback' => '${functions.canWriteFunctionName}',
27
- \t\t)`);
28
- }
29
- if (methods.includes("read")) {
30
- itemRoutes.push(`\t\tarray(
31
- \t\t\t'methods' => WP_REST_Server::READABLE,
32
- \t\t\t'callback' => '${functions.readHandlerName}',
33
- \t\t\t'permission_callback' => '__return_true',
34
- \t\t)`);
35
- }
36
- if (methods.includes("update")) {
37
- itemRoutes.push(`\t\tarray(
38
- \t\t\t'methods' => WP_REST_Server::EDITABLE,
39
- \t\t\t'callback' => '${functions.updateHandlerName}',
40
- \t\t\t'permission_callback' => '${functions.canWriteFunctionName}',
41
- \t\t)`);
42
- }
43
- if (methods.includes("delete")) {
44
- itemRoutes.push(`\t\tarray(
45
- \t\t\t'methods' => WP_REST_Server::DELETABLE,
46
- \t\t\t'callback' => '${functions.deleteHandlerName}',
47
- \t\t\t'permission_callback' => '${functions.canWriteFunctionName}',
48
- \t\t)`);
49
- }
50
- const registrations = [];
51
- if (collectionRoutes.length > 0) {
52
- registrations.push(`\tregister_rest_route(
53
- \t\t$namespace,
54
- \t\t'/${restResourceSlug}',
55
- \t\tarray(
56
- ${collectionRoutes.join(",\n")}
57
- \t\t)
58
- \t);`);
59
- }
60
- if (itemRoutes.length > 0) {
61
- registrations.push(`\tregister_rest_route(
62
- \t\t$namespace,
63
- \t\t'/${restResourceSlug}/item',
64
- \t\tarray(
65
- ${itemRoutes.join(",\n")}
66
- \t\t)
67
- \t);`);
68
- }
69
- return registrations.join("\n\n");
70
- }
71
- function buildRestResourcePhpSource(restResourceSlug, namespace, phpPrefix, textDomain, methods) {
72
- const restResourceTitle = toTitleCase(restResourceSlug);
73
- const restResourcePhpId = restResourceSlug.replace(/-/g, "_");
74
- const canWriteFunctionName = `${phpPrefix}_${restResourcePhpId}_can_manage_rest_resource`;
75
- const getItemsFunctionName = `${phpPrefix}_${restResourcePhpId}_get_rest_resource_items`;
76
- const loadSchemaFunctionName = `${phpPrefix}_${restResourcePhpId}_load_rest_resource_schema`;
77
- const normalizeSchemaFunctionName = `${phpPrefix}_${restResourcePhpId}_sanitize_rest_resource_schema`;
78
- const validatePayloadFunctionName = `${phpPrefix}_${restResourcePhpId}_validate_rest_resource_payload`;
79
- const normalizeItemFunctionName = `${phpPrefix}_${restResourcePhpId}_normalize_rest_resource_item`;
80
- const saveItemsFunctionName = `${phpPrefix}_${restResourcePhpId}_save_rest_resource_items`;
81
- const getOptionNameFunctionName = `${phpPrefix}_${restResourcePhpId}_get_rest_resource_option_name`;
82
- const listHandlerName = `${phpPrefix}_${restResourcePhpId}_handle_list_rest_resource`;
83
- const readHandlerName = `${phpPrefix}_${restResourcePhpId}_handle_read_rest_resource`;
84
- const createHandlerName = `${phpPrefix}_${restResourcePhpId}_handle_create_rest_resource`;
85
- const updateHandlerName = `${phpPrefix}_${restResourcePhpId}_handle_update_rest_resource`;
86
- const deleteHandlerName = `${phpPrefix}_${restResourcePhpId}_handle_delete_rest_resource`;
87
- const registerRoutesFunctionName = `${phpPrefix}_${restResourcePhpId}_register_rest_routes`;
88
- const routeRegistrations = buildRestResourceRouteRegistrations(restResourceSlug, methods, {
89
- canWriteFunctionName,
90
- createHandlerName,
91
- deleteHandlerName,
92
- listHandlerName,
93
- readHandlerName,
94
- updateHandlerName,
95
- });
96
- return `<?php
97
- if ( ! defined( 'ABSPATH' ) ) {
98
- \treturn;
99
- }
100
-
101
- if ( ! function_exists( '${getOptionNameFunctionName}' ) ) {
102
- \tfunction ${getOptionNameFunctionName}() {
103
- \t\treturn ${quotePhpString(`${phpPrefix}_${restResourcePhpId}_rest_resource_items`)};
104
- \t}
105
- }
106
-
107
- if ( ! function_exists( '${normalizeItemFunctionName}' ) ) {
108
- \tfunction ${normalizeItemFunctionName}( array $item ) {
109
- \t\treturn array(
110
- \t\t\t'id' => isset( $item['id'] ) ? (int) $item['id'] : 0,
111
- \t\t\t'title' => isset( $item['title'] ) ? (string) $item['title'] : '',
112
- \t\t\t'content' => isset( $item['content'] ) ? (string) $item['content'] : '',
113
- \t\t\t'status' => isset( $item['status'] ) && 'published' === $item['status'] ? 'published' : 'draft',
114
- \t\t\t'updatedAt' => isset( $item['updatedAt'] ) ? (string) $item['updatedAt'] : gmdate( 'c' ),
115
- \t\t);
116
- \t}
117
- }
118
-
119
- if ( ! function_exists( '${getItemsFunctionName}' ) ) {
120
- \tfunction ${getItemsFunctionName}() {
121
- \t\t$seed_items = array(
122
- \t\t\tarray(
123
- \t\t\t\t'id' => 1,
124
- \t\t\t\t'title' => ${quotePhpString(`${restResourceTitle} Starter`)},
125
- \t\t\t\t'content' => ${quotePhpString(`Replace this seeded ${restResourceTitle.toLowerCase()} content with your plugin data source.`)},
126
- \t\t\t\t'status' => 'draft',
127
- \t\t\t\t'updatedAt' => '2026-01-01T00:00:00Z',
128
- \t\t\t),
129
- \t\t);
130
- \t\t$items = get_option( ${getOptionNameFunctionName}(), $seed_items );
131
-
132
- \t\tif ( ! is_array( $items ) ) {
133
- \t\t\t$items = $seed_items;
134
- \t\t}
135
-
136
- \t\treturn array_values(
137
- \t\t\tarray_map(
138
- \t\t\t\t'${normalizeItemFunctionName}',
139
- \t\t\t\tarray_filter(
140
- \t\t\t\t\t$items,
141
- \t\t\t\t\t'is_array'
142
- \t\t\t\t)
143
- \t\t\t)
144
- \t\t);
145
- \t}
146
- }
147
-
148
- if ( ! function_exists( '${saveItemsFunctionName}' ) ) {
149
- \tfunction ${saveItemsFunctionName}( array $items ) {
150
- \t\tupdate_option(
151
- \t\t\t${getOptionNameFunctionName}(),
152
- \t\t\tarray_values(
153
- \t\t\t\tarray_map(
154
- \t\t\t\t\t'${normalizeItemFunctionName}',
155
- \t\t\t\t\t$items
156
- \t\t\t\t)
157
- \t\t\t),
158
- \t\t\tfalse
159
- \t\t);
160
- \t}
161
- }
162
-
163
- if ( ! function_exists( '${loadSchemaFunctionName}' ) ) {
164
- \tfunction ${loadSchemaFunctionName}( $schema_name ) {
165
- \t\t$project_root = dirname( __DIR__, 2 );
166
- \t\t$schema_path = $project_root . '/src/rest/${restResourceSlug}/api-schemas/' . $schema_name . '.schema.json';
167
- \t\tif ( ! file_exists( $schema_path ) ) {
168
- \t\t\treturn null;
169
- \t\t}
170
-
171
- \t\t$decoded = json_decode( file_get_contents( $schema_path ), true );
172
- \t\treturn is_array( $decoded ) ? $decoded : null;
173
- \t}
174
- }
175
-
176
- if ( ! function_exists( '${normalizeSchemaFunctionName}' ) ) {
177
- \tfunction ${normalizeSchemaFunctionName}( $schema ) {
178
- \t\tif ( ! is_array( $schema ) ) {
179
- \t\t\treturn $schema;
180
- \t\t}
181
-
182
- \t\tunset( $schema['$schema'], $schema['title'] );
183
-
184
- \t\tif ( isset( $schema['properties'] ) && is_array( $schema['properties'] ) ) {
185
- \t\t\tforeach ( $schema['properties'] as $key => $property_schema ) {
186
- \t\t\t\t$schema['properties'][ $key ] = ${normalizeSchemaFunctionName}( $property_schema );
187
- \t\t\t}
188
- \t\t}
189
-
190
- \t\tif ( isset( $schema['items'] ) && is_array( $schema['items'] ) ) {
191
- \t\t\t$schema['items'] = ${normalizeSchemaFunctionName}( $schema['items'] );
192
- \t\t}
193
-
194
- \t\treturn $schema;
195
- \t}
196
- }
197
-
198
- if ( ! function_exists( '${validatePayloadFunctionName}' ) ) {
199
- \tfunction ${validatePayloadFunctionName}( $value, $schema_name, $param_name ) {
200
- \t\t$schema = ${loadSchemaFunctionName}( $schema_name );
201
- \t\tif ( ! is_array( $schema ) ) {
202
- \t\t\treturn new WP_Error( 'missing_schema', 'Missing REST schema.', array( 'status' => 500 ) );
203
- \t\t}
204
-
205
- \t\t$rest_schema = ${normalizeSchemaFunctionName}( $schema );
206
- \t\t$validation = rest_validate_value_from_schema( $value, $rest_schema, $param_name );
207
- \t\tif ( is_wp_error( $validation ) ) {
208
- \t\t\treturn $validation;
209
- \t\t}
210
-
211
- \t\treturn rest_sanitize_value_from_schema( $value, $rest_schema, $param_name );
212
- \t}
213
- }
214
-
215
- if ( ! function_exists( '${canWriteFunctionName}' ) ) {
216
- \tfunction ${canWriteFunctionName}() {
217
- \t\treturn current_user_can( 'edit_posts' );
218
- \t}
219
- }
220
-
221
- if ( ! function_exists( '${listHandlerName}' ) ) {
222
- \tfunction ${listHandlerName}( WP_REST_Request $request ) {
223
- \t\t$payload_input = array();
224
- \t\t$page = $request->get_param( 'page' );
225
- \t\t$per_page = $request->get_param( 'perPage' );
226
- \t\t$search = $request->get_param( 'search' );
227
-
228
- \t\tif ( null !== $page ) {
229
- \t\t\t$payload_input['page'] = $page;
230
- \t\t}
231
- \t\tif ( null !== $per_page ) {
232
- \t\t\t$payload_input['perPage'] = $per_page;
233
- \t\t}
234
- \t\tif ( null !== $search ) {
235
- \t\t\t$payload_input['search'] = $search;
236
- \t\t}
237
-
238
- \t\t$payload = ${validatePayloadFunctionName}(
239
- \t\t\t$payload_input,
240
- \t\t\t'list-query',
241
- \t\t\t'query'
242
- \t\t);
243
-
244
- \t\tif ( is_wp_error( $payload ) ) {
245
- \t\t\treturn $payload;
246
- \t\t}
247
-
248
- \t\t$page = isset( $payload['page'] ) ? max( 1, (int) $payload['page'] ) : 1;
249
- \t\t$per_page = isset( $payload['perPage'] ) ? min( 50, max( 1, (int) $payload['perPage'] ) ) : 10;
250
- \t\t$search = isset( $payload['search'] ) ? strtolower( (string) $payload['search'] ) : '';
251
- \t\t$items = ${getItemsFunctionName}();
252
-
253
- \t\tif ( '' !== $search ) {
254
- \t\t\t$items = array_values(
255
- \t\t\t\tarray_filter(
256
- \t\t\t\t\t$items,
257
- \t\t\t\t\tstatic function ( $item ) use ( $search ) {
258
- \t\t\t\t\t\treturn false !== strpos( strtolower( (string) ( $item['title'] ?? '' ) ), $search ) ||
259
- \t\t\t\t\t\t\tfalse !== strpos( strtolower( (string) ( $item['content'] ?? '' ) ), $search );
260
- \t\t\t\t\t}
261
- \t\t\t\t)
262
- \t\t\t);
263
- \t\t}
264
-
265
- \t\t$total = count( $items );
266
- \t\t$items = array_slice( $items, ( $page - 1 ) * $per_page, $per_page );
267
-
268
- \t\treturn rest_ensure_response(
269
- \t\t\tarray(
270
- \t\t\t\t'items' => $items,
271
- \t\t\t\t'page' => $page,
272
- \t\t\t\t'perPage' => $per_page,
273
- \t\t\t\t'total' => $total,
274
- \t\t\t)
275
- \t\t);
276
- \t}
277
- }
278
-
279
- if ( ! function_exists( '${readHandlerName}' ) ) {
280
- \tfunction ${readHandlerName}( WP_REST_Request $request ) {
281
- \t\t$payload = ${validatePayloadFunctionName}(
282
- \t\t\tarray(
283
- \t\t\t\t'id' => $request->get_param( 'id' ),
284
- \t\t\t),
285
- \t\t\t'read-query',
286
- \t\t\t'query'
287
- \t\t);
288
-
289
- \t\tif ( is_wp_error( $payload ) ) {
290
- \t\t\treturn $payload;
291
- \t\t}
292
-
293
- \t\tforeach ( ${getItemsFunctionName}() as $item ) {
294
- \t\t\tif ( (int) $item['id'] === (int) $payload['id'] ) {
295
- \t\t\t\treturn rest_ensure_response( $item );
296
- \t\t\t}
297
- \t\t}
298
-
299
- \t\treturn new WP_Error( 'rest_not_found', 'Resource not found.', array( 'status' => 404 ) );
300
- \t}
301
- }
302
-
303
- if ( ! function_exists( '${createHandlerName}' ) ) {
304
- \tfunction ${createHandlerName}( WP_REST_Request $request ) {
305
- \t\t$payload = ${validatePayloadFunctionName}( $request->get_json_params(), 'create-request', 'body' );
306
- \t\tif ( is_wp_error( $payload ) ) {
307
- \t\t\treturn $payload;
308
- \t\t}
309
-
310
- \t\t$items = ${getItemsFunctionName}();
311
- \t\t$next_id = 1;
312
- \t\tforeach ( $items as $item ) {
313
- \t\t\t$next_id = max( $next_id, (int) $item['id'] + 1 );
314
- \t\t}
315
-
316
- \t\t$record = ${normalizeItemFunctionName}(
317
- \t\t\tarray(
318
- \t\t\t\t'id' => $next_id,
319
- \t\t\t\t'title' => (string) $payload['title'],
320
- \t\t\t\t'content' => isset( $payload['content'] ) ? (string) $payload['content'] : '',
321
- \t\t\t\t'status' => isset( $payload['status'] ) ? (string) $payload['status'] : 'draft',
322
- \t\t\t\t'updatedAt' => gmdate( 'c' ),
323
- \t\t\t)
324
- \t\t);
325
-
326
- \t\t$items[] = $record;
327
- \t\t${saveItemsFunctionName}( $items );
328
-
329
- \t\treturn rest_ensure_response( $record );
330
- \t}
331
- }
332
-
333
- if ( ! function_exists( '${updateHandlerName}' ) ) {
334
- \tfunction ${updateHandlerName}( WP_REST_Request $request ) {
335
- \t\t$query = ${validatePayloadFunctionName}(
336
- \t\t\tarray(
337
- \t\t\t\t'id' => $request->get_param( 'id' ),
338
- \t\t\t),
339
- \t\t\t'update-query',
340
- \t\t\t'query'
341
- \t\t);
342
- \t\tif ( is_wp_error( $query ) ) {
343
- \t\t\treturn $query;
344
- \t\t}
345
-
346
- \t\t$payload = ${validatePayloadFunctionName}( $request->get_json_params(), 'update-request', 'body' );
347
- \t\tif ( is_wp_error( $payload ) ) {
348
- \t\t\treturn $payload;
349
- \t\t}
350
-
351
- \t\t$items = ${getItemsFunctionName}();
352
- \t\tforeach ( $items as $index => $item ) {
353
- \t\t\tif ( (int) $item['id'] !== (int) $query['id'] ) {
354
- \t\t\t\tcontinue;
355
- \t\t\t}
356
-
357
- \t\t\t$items[ $index ] = ${normalizeItemFunctionName}(
358
- \t\t\t\tarray(
359
- \t\t\t\t\t'id' => $item['id'],
360
- \t\t\t\t\t'title' => isset( $payload['title'] ) ? (string) $payload['title'] : (string) $item['title'],
361
- \t\t\t\t\t'content' => array_key_exists( 'content', $payload ) ? (string) $payload['content'] : (string) $item['content'],
362
- \t\t\t\t\t'status' => isset( $payload['status'] ) ? (string) $payload['status'] : (string) $item['status'],
363
- \t\t\t\t\t'updatedAt' => gmdate( 'c' ),
364
- \t\t\t\t)
365
- \t\t\t);
366
-
367
- \t\t\t${saveItemsFunctionName}( $items );
368
- \t\t\treturn rest_ensure_response( $items[ $index ] );
369
- \t\t}
370
-
371
- \t\treturn new WP_Error( 'rest_not_found', 'Resource not found.', array( 'status' => 404 ) );
372
- \t}
373
- }
374
-
375
- if ( ! function_exists( '${deleteHandlerName}' ) ) {
376
- \tfunction ${deleteHandlerName}( WP_REST_Request $request ) {
377
- \t\t$query = ${validatePayloadFunctionName}(
378
- \t\t\tarray(
379
- \t\t\t\t'id' => $request->get_param( 'id' ),
380
- \t\t\t),
381
- \t\t\t'delete-query',
382
- \t\t\t'query'
383
- \t\t);
384
- \t\tif ( is_wp_error( $query ) ) {
385
- \t\t\treturn $query;
386
- \t\t}
387
-
388
- \t\t$items = ${getItemsFunctionName}();
389
- \t\t$filtered = array_values(
390
- \t\t\tarray_filter(
391
- \t\t\t\t$items,
392
- \t\t\t\tstatic function ( $item ) use ( $query ) {
393
- \t\t\t\t\treturn (int) $item['id'] !== (int) $query['id'];
394
- \t\t\t\t}
395
- \t\t\t)
396
- \t\t);
397
- \t\t$was_deleted = count( $filtered ) !== count( $items );
398
-
399
- \t\tif ( ! $was_deleted ) {
400
- \t\t\treturn new WP_Error( 'rest_not_found', 'Resource not found.', array( 'status' => 404 ) );
401
- \t\t}
402
-
403
- \t\t${saveItemsFunctionName}( $filtered );
404
-
405
- \t\treturn rest_ensure_response(
406
- \t\t\tarray(
407
- \t\t\t\t'deleted' => true,
408
- \t\t\t\t'id' => (int) $query['id'],
409
- \t\t\t)
410
- \t\t);
411
- \t}
412
- }
413
-
414
- if ( ! function_exists( '${registerRoutesFunctionName}' ) ) {
415
- \tfunction ${registerRoutesFunctionName}() {
416
- \t\t$namespace = ${quotePhpString(namespace)};
417
-
418
- ${routeRegistrations}
419
- \t}
420
- }
421
-
422
- add_action( 'rest_api_init', '${registerRoutesFunctionName}' );
423
- `;
424
- }
425
6
  /**
426
7
  * Scaffold a workspace-level REST resource and synchronize its generated
427
8
  * TypeScript and PHP artifacts.
@@ -429,70 +10,42 @@ add_action( 'rest_api_init', '${registerRoutesFunctionName}' );
429
10
  * @param options Command options for the REST resource scaffold workflow.
430
11
  * @returns Resolved scaffold metadata for the created REST resource.
431
12
  */
432
- export async function runAddRestResourceCommand({ cwd = process.cwd(), methods, namespace, restResourceName, }) {
13
+ export async function runAddRestResourceCommand({ auth, bodyTypeName, controllerClass, controllerExtends, cwd = process.cwd(), manual, method, methods, namespace, permissionCallback, pathPattern, queryTypeName, restResourceName, responseTypeName, routePattern, secretFieldName, secretHasValueFieldName, secretMaskedResponseFieldName, secretPreserveOnEmpty, secretStateFieldName, }) {
433
14
  const workspace = resolveWorkspaceProject(cwd);
434
15
  const restResourceSlug = assertValidGeneratedSlug("REST resource name", normalizeBlockSlug(restResourceName), "wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <list,read,create>]");
435
- const resolvedMethods = assertValidRestResourceMethods(methods);
436
16
  const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
437
17
  const inventory = await readWorkspaceInventoryAsync(workspace.projectDir);
438
18
  assertRestResourceDoesNotExist(workspace.projectDir, restResourceSlug, inventory);
439
- const blockConfigPath = path.join(workspace.projectDir, "scripts", "block-config.ts");
440
- const bootstrapPath = getWorkspaceBootstrapPath(workspace);
441
- const syncRestScriptPath = path.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
442
- const restResourceDir = path.join(workspace.projectDir, "src", "rest", restResourceSlug);
443
- const typesFilePath = path.join(restResourceDir, "api-types.ts");
444
- const validatorsFilePath = path.join(restResourceDir, "api-validators.ts");
445
- const apiFilePath = path.join(restResourceDir, "api.ts");
446
- const dataFilePath = path.join(restResourceDir, "data.ts");
447
- const phpFilePath = path.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
448
- const mutationSnapshot = {
449
- fileSources: await snapshotWorkspaceFiles([
450
- blockConfigPath,
451
- bootstrapPath,
452
- syncRestScriptPath,
453
- ]),
454
- snapshotDirs: [],
455
- targetPaths: [restResourceDir, phpFilePath],
456
- };
457
- try {
458
- await fsp.mkdir(restResourceDir, { recursive: true });
459
- await fsp.mkdir(path.dirname(phpFilePath), { recursive: true });
460
- await ensureRestResourceBootstrapAnchors(workspace);
461
- await ensureRestResourceSyncScriptAnchors(workspace);
462
- await fsp.writeFile(typesFilePath, buildRestResourceTypesSource(restResourceSlug, resolvedMethods), "utf8");
463
- await fsp.writeFile(validatorsFilePath, buildRestResourceValidatorsSource(restResourceSlug, resolvedMethods), "utf8");
464
- await fsp.writeFile(apiFilePath, buildRestResourceApiSource(restResourceSlug, resolvedMethods), "utf8");
465
- await fsp.writeFile(dataFilePath, buildRestResourceDataSource(restResourceSlug, resolvedMethods), "utf8");
466
- await fsp.writeFile(phpFilePath, buildRestResourcePhpSource(restResourceSlug, resolvedNamespace, workspace.workspace.phpPrefix, workspace.workspace.textDomain, resolvedMethods), "utf8");
467
- await syncRestResourceArtifacts({
468
- clientFile: `src/rest/${restResourceSlug}/api-client.ts`,
469
- methods: resolvedMethods,
470
- outputDir: restResourceDir,
471
- projectDir: workspace.projectDir,
472
- typesFile: `src/rest/${restResourceSlug}/api-types.ts`,
473
- validatorsFile: `src/rest/${restResourceSlug}/api-validators.ts`,
474
- variables: {
475
- namespace: resolvedNamespace,
476
- pascalCase: toPascalCase(restResourceSlug),
477
- slugKebabCase: restResourceSlug,
478
- title: toTitleCase(restResourceSlug),
479
- },
480
- });
481
- await appendWorkspaceInventoryEntries(workspace.projectDir, {
482
- restResourceEntries: [
483
- buildRestResourceConfigEntry(restResourceSlug, resolvedNamespace, resolvedMethods),
484
- ],
485
- transformSource: ensureBlockConfigCanAddRestManifests,
486
- });
487
- return {
488
- methods: resolvedMethods,
19
+ if (manual) {
20
+ return scaffoldManualRestContract({
21
+ auth,
22
+ bodyTypeName,
23
+ controllerClass,
24
+ controllerExtends,
25
+ method,
489
26
  namespace: resolvedNamespace,
490
- projectDir: workspace.projectDir,
27
+ pathPattern,
28
+ permissionCallback,
29
+ queryTypeName,
30
+ responseTypeName,
491
31
  restResourceSlug,
492
- };
493
- }
494
- catch (error) {
495
- await rollbackWorkspaceMutation(mutationSnapshot);
496
- throw error;
32
+ routePattern,
33
+ secretFieldName,
34
+ secretHasValueFieldName,
35
+ secretMaskedResponseFieldName,
36
+ secretPreserveOnEmpty,
37
+ secretStateFieldName,
38
+ workspace,
39
+ });
497
40
  }
41
+ return scaffoldGeneratedRestResource({
42
+ controllerClass,
43
+ controllerExtends,
44
+ methods,
45
+ namespace: resolvedNamespace,
46
+ permissionCallback,
47
+ restResourceSlug,
48
+ routePattern,
49
+ workspace,
50
+ });
498
51
  }
@@ -10,11 +10,26 @@ export { runAddAdminViewCommand, } from "./cli-add-workspace-admin-view.js";
10
10
  * `cli-add-workspace-assets` module.
11
11
  */
12
12
  export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCommand, } from "./cli-add-workspace-assets.js";
13
+ /**
14
+ * Re-export the local integration environment scaffold workflow from the
15
+ * focused integration-env runtime helper module.
16
+ */
17
+ export { runAddIntegrationEnvCommand } from "./cli-add-workspace-integration-env.js";
13
18
  /**
14
19
  * Re-export the plugin-level REST resource scaffold workflow from the focused
15
20
  * rest-resource runtime helper module.
16
21
  */
17
22
  export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
23
+ /**
24
+ * Re-export the standalone contract scaffold workflow from the focused
25
+ * contract runtime helper module.
26
+ */
27
+ export { runAddContractCommand } from "./cli-add-workspace-contract.js";
28
+ /**
29
+ * Re-export the typed post-meta contract scaffold workflow from the focused
30
+ * post-meta runtime helper module.
31
+ */
32
+ export { runAddPostMetaCommand } from "./cli-add-workspace-post-meta.js";
18
33
  /**
19
34
  * Re-export the typed workflow ability scaffold workflow from the focused
20
35
  * ability runtime helper module.
@@ -417,11 +417,26 @@ export { runAddAdminViewCommand, } from "./cli-add-workspace-admin-view.js";
417
417
  * `cli-add-workspace-assets` module.
418
418
  */
419
419
  export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCommand, } from "./cli-add-workspace-assets.js";
420
+ /**
421
+ * Re-export the local integration environment scaffold workflow from the
422
+ * focused integration-env runtime helper module.
423
+ */
424
+ export { runAddIntegrationEnvCommand } from "./cli-add-workspace-integration-env.js";
420
425
  /**
421
426
  * Re-export the plugin-level REST resource scaffold workflow from the focused
422
427
  * rest-resource runtime helper module.
423
428
  */
424
429
  export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
430
+ /**
431
+ * Re-export the standalone contract scaffold workflow from the focused
432
+ * contract runtime helper module.
433
+ */
434
+ export { runAddContractCommand } from "./cli-add-workspace-contract.js";
435
+ /**
436
+ * Re-export the typed post-meta contract scaffold workflow from the focused
437
+ * post-meta runtime helper module.
438
+ */
439
+ export { runAddPostMetaCommand } from "./cli-add-workspace-post-meta.js";
425
440
  /**
426
441
  * Re-export the typed workflow ability scaffold workflow from the focused
427
442
  * ability runtime helper module.
@@ -10,6 +10,6 @@
10
10
  export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, isAddBlockTemplateId, suggestAddBlockTemplateId, } 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 { runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
13
+ export { runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddContractCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddIntegrationEnvCommand, runAddPatternCommand, runAddPostMetaCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
14
14
  export { getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, } from "./workspace-inventory.js";
15
15
  export type { WorkspaceBlockSelectOption } from "./workspace-inventory.js";
@@ -9,5 +9,5 @@
9
9
  */
10
10
  export { ADD_BLOCK_TEMPLATE_IDS, ADD_KIND_IDS, EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, isAddBlockTemplateId, suggestAddBlockTemplateId, } from "./cli-add-shared.js";
11
11
  export { runAddBlockCommand, seedWorkspaceMigrationProject, } from "./cli-add-block.js";
12
- export { runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
12
+ export { runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddContractCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddIntegrationEnvCommand, runAddPatternCommand, runAddPostMetaCommand, runAddRestResourceCommand, runAddVariationCommand, } from "./cli-add-workspace.js";
13
13
  export { getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, } from "./workspace-inventory.js";
@@ -15,6 +15,7 @@
15
15
  * `seedWorkspaceMigrationProject` for
16
16
  * explicit `wp-typia add` flows,
17
17
  * `runAddAiFeatureCommand` for server-owned WordPress AI feature scaffolds,
18
+ * `runAddContractCommand` for standalone TypeScript schema artifacts,
18
19
  * `runAddRestResourceCommand` for plugin-level REST resource scaffolds,
19
20
  * `getDoctorChecks`, `runDoctor`, and `DoctorCheck` for diagnostics,
20
21
  * `createCliCommandError`, `createCliDiagnosticCodeError`,
@@ -29,10 +30,10 @@
29
30
  * `getTemplateSelectOptions`, `listTemplates`, and `isBuiltInTemplateId` for
30
31
  * template inspection flows.
31
32
  */
32
- export { getDoctorChecks, runDoctor, type DoctorCheck } from "./cli-doctor.js";
33
+ export { createDoctorRunSummary, getDoctorChecks, getDoctorExitFailureChecks, getDoctorExitFailureDetailLines, runDoctor, type DoctorCheck, type DoctorCheckScope, type DoctorExitPolicy, type DoctorFailureSummary, type DoctorRunSummary, } from "./cli-doctor.js";
33
34
  export { createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODE_METADATA, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getCliDiagnosticCodeMetadata, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
34
35
  export type { CliDiagnosticCode, CliDiagnosticCodeError, CliDiagnosticMessage, } from "./cli-diagnostics.js";
35
- export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, runAddAdminViewCommand, runAddAbilityCommand, runAddBindingSourceCommand, runAddAiFeatureCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
36
+ export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, runAddAdminViewCommand, runAddAbilityCommand, runAddBindingSourceCommand, runAddAiFeatureCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddContractCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
36
37
  export { COMPOUND_INNER_BLOCKS_PRESET_IDS, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
37
38
  export type { CompoundInnerBlocksPresetId } from "./compound-inner-blocks.js";
38
39
  export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
@@ -15,6 +15,7 @@
15
15
  * `seedWorkspaceMigrationProject` for
16
16
  * explicit `wp-typia add` flows,
17
17
  * `runAddAiFeatureCommand` for server-owned WordPress AI feature scaffolds,
18
+ * `runAddContractCommand` for standalone TypeScript schema artifacts,
18
19
  * `runAddRestResourceCommand` for plugin-level REST resource scaffolds,
19
20
  * `getDoctorChecks`, `runDoctor`, and `DoctorCheck` for diagnostics,
20
21
  * `createCliCommandError`, `createCliDiagnosticCodeError`,
@@ -29,9 +30,9 @@
29
30
  * `getTemplateSelectOptions`, `listTemplates`, and `isBuiltInTemplateId` for
30
31
  * template inspection flows.
31
32
  */
32
- export { getDoctorChecks, runDoctor } from "./cli-doctor.js";
33
+ export { createDoctorRunSummary, getDoctorChecks, getDoctorExitFailureChecks, getDoctorExitFailureDetailLines, runDoctor, } from "./cli-doctor.js";
33
34
  export { createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODE_METADATA, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatDoctorCheckLine, formatDoctorSummaryLine, getCliDiagnosticCodeMetadata, getDoctorFailureDetailLines, getFailingDoctorChecks, isCliDiagnosticError, } from "./cli-diagnostics.js";
34
- export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, runAddAdminViewCommand, runAddAbilityCommand, runAddBindingSourceCommand, runAddAiFeatureCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
35
+ export { EDITOR_PLUGIN_SLOT_IDS, formatAddHelpText, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, runAddAdminViewCommand, runAddAbilityCommand, runAddBindingSourceCommand, runAddAiFeatureCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddContractCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runAddRestResourceCommand, runAddVariationCommand, seedWorkspaceMigrationProject, } from "./cli-add.js";
35
36
  export { COMPOUND_INNER_BLOCKS_PRESET_IDS, getCompoundInnerBlocksPresetDefinition, } from "./compound-inner-blocks.js";
36
37
  export { HOOKED_BLOCK_POSITION_IDS } from "./hooked-blocks.js";
37
38
  export { formatHelpText } from "./cli-help.js";
@@ -160,7 +160,9 @@ export declare function getFailingDoctorChecks<TCheck extends DoctorCheckLike>(c
160
160
  /**
161
161
  * Format the final doctor summary row.
162
162
  */
163
- export declare function formatDoctorSummaryLine(checks: readonly DoctorCheckLike[]): string;
163
+ export declare function formatDoctorSummaryLine(checks: readonly DoctorCheckLike[], options?: {
164
+ exitFailureChecks?: readonly DoctorCheckLike[];
165
+ }): string;
164
166
  /**
165
167
  * Build detail lines for doctor failures so the non-interactive formatter can
166
168
  * restate the failed checks after the streaming rows.