@wp-typia/project-tools 0.23.0 → 0.24.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 (228) 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/built-in-block-non-ts-basic-artifacts.d.ts +9 -0
  4. package/dist/runtime/built-in-block-non-ts-basic-artifacts.js +84 -0
  5. package/dist/runtime/built-in-block-non-ts-compound-artifacts.d.ts +9 -0
  6. package/dist/runtime/built-in-block-non-ts-compound-artifacts.js +36 -0
  7. package/dist/runtime/built-in-block-non-ts-compound-templates.d.ts +23 -0
  8. package/dist/runtime/built-in-block-non-ts-compound-templates.js +453 -0
  9. package/dist/runtime/built-in-block-non-ts-family-artifacts.d.ts +8 -26
  10. package/dist/runtime/built-in-block-non-ts-family-artifacts.js +8 -1034
  11. package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.d.ts +9 -0
  12. package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.js +83 -0
  13. package/dist/runtime/built-in-block-non-ts-persistence-artifacts.d.ts +9 -0
  14. package/dist/runtime/built-in-block-non-ts-persistence-artifacts.js +33 -0
  15. package/dist/runtime/built-in-block-non-ts-persistence-templates.d.ts +23 -0
  16. package/dist/runtime/built-in-block-non-ts-persistence-templates.js +395 -0
  17. package/dist/runtime/cli-add-block-json.js +5 -1
  18. package/dist/runtime/cli-add-collision.js +8 -0
  19. package/dist/runtime/cli-add-help.js +14 -10
  20. package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
  21. package/dist/runtime/cli-add-kind-ids.js +1 -0
  22. package/dist/runtime/cli-add-types.d.ts +45 -6
  23. package/dist/runtime/cli-add-types.js +2 -0
  24. package/dist/runtime/cli-add-validation.d.ts +7 -0
  25. package/dist/runtime/cli-add-validation.js +9 -0
  26. package/dist/runtime/cli-add-workspace-ability-anchors.d.ts +24 -0
  27. package/dist/runtime/cli-add-workspace-ability-anchors.js +294 -0
  28. package/dist/runtime/cli-add-workspace-ability-registry.d.ts +10 -0
  29. package/dist/runtime/cli-add-workspace-ability-registry.js +51 -0
  30. package/dist/runtime/cli-add-workspace-ability-scaffold.d.ts +1 -1
  31. package/dist/runtime/cli-add-workspace-ability-scaffold.js +5 -308
  32. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +6 -2
  33. package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.d.ts +34 -0
  34. package/dist/runtime/cli-add-workspace-admin-view-templates-core-data.js +483 -0
  35. package/dist/runtime/cli-add-workspace-admin-view-templates-default.d.ts +30 -0
  36. package/dist/runtime/cli-add-workspace-admin-view-templates-default.js +310 -0
  37. package/dist/runtime/cli-add-workspace-admin-view-templates-rest.d.ts +25 -0
  38. package/dist/runtime/cli-add-workspace-admin-view-templates-rest.js +124 -0
  39. package/dist/runtime/cli-add-workspace-admin-view-templates-settings.d.ts +34 -0
  40. package/dist/runtime/cli-add-workspace-admin-view-templates-settings.js +370 -0
  41. package/dist/runtime/cli-add-workspace-admin-view-templates-shared.d.ts +49 -0
  42. package/dist/runtime/cli-add-workspace-admin-view-templates-shared.js +259 -0
  43. package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +18 -27
  44. package/dist/runtime/cli-add-workspace-admin-view-templates.js +30 -1326
  45. package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +4 -4
  46. package/dist/runtime/cli-add-workspace-ai-anchors.js +8 -233
  47. package/dist/runtime/cli-add-workspace-ai-scaffold.js +4 -2
  48. package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +1 -4
  49. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +1 -129
  50. package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.d.ts +5 -0
  51. package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.js +236 -0
  52. package/dist/runtime/cli-add-workspace-ai-sync-script-source.d.ts +4 -0
  53. package/dist/runtime/cli-add-workspace-ai-sync-script-source.js +145 -0
  54. package/dist/runtime/cli-add-workspace-assets.d.ts +6 -63
  55. package/dist/runtime/cli-add-workspace-assets.js +6 -950
  56. package/dist/runtime/cli-add-workspace-binding-source-anchors.d.ts +23 -0
  57. package/dist/runtime/cli-add-workspace-binding-source-anchors.js +112 -0
  58. package/dist/runtime/cli-add-workspace-binding-source-source-emitters.d.ts +33 -0
  59. package/dist/runtime/cli-add-workspace-binding-source-source-emitters.js +436 -0
  60. package/dist/runtime/cli-add-workspace-binding-source-types.d.ts +20 -0
  61. package/dist/runtime/cli-add-workspace-binding-source-types.js +1 -0
  62. package/dist/runtime/cli-add-workspace-binding-source.d.ts +40 -0
  63. package/dist/runtime/cli-add-workspace-binding-source.js +275 -0
  64. package/dist/runtime/cli-add-workspace-block-style.d.ts +22 -0
  65. package/dist/runtime/cli-add-workspace-block-style.js +148 -0
  66. package/dist/runtime/cli-add-workspace-block-transform.d.ts +32 -0
  67. package/dist/runtime/cli-add-workspace-block-transform.js +197 -0
  68. package/dist/runtime/cli-add-workspace-contract.js +1 -1
  69. package/dist/runtime/cli-add-workspace-core-variation.d.ts +20 -0
  70. package/dist/runtime/cli-add-workspace-core-variation.js +322 -0
  71. package/dist/runtime/cli-add-workspace-editor-plugin-anchors.d.ts +37 -0
  72. package/dist/runtime/cli-add-workspace-editor-plugin-anchors.js +206 -0
  73. package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.d.ts +47 -0
  74. package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.js +219 -0
  75. package/dist/runtime/cli-add-workspace-editor-plugin.d.ts +22 -0
  76. package/dist/runtime/cli-add-workspace-editor-plugin.js +78 -0
  77. package/dist/runtime/cli-add-workspace-hooked-block.d.ts +23 -0
  78. package/dist/runtime/cli-add-workspace-hooked-block.js +57 -0
  79. package/dist/runtime/cli-add-workspace-integration-env-files.d.ts +33 -0
  80. package/dist/runtime/cli-add-workspace-integration-env-files.js +65 -0
  81. package/dist/runtime/cli-add-workspace-integration-env-package-json.d.ts +38 -0
  82. package/dist/runtime/cli-add-workspace-integration-env-package-json.js +122 -0
  83. package/dist/runtime/cli-add-workspace-integration-env-source-emitters.d.ts +44 -0
  84. package/dist/runtime/cli-add-workspace-integration-env-source-emitters.js +262 -0
  85. package/dist/runtime/cli-add-workspace-integration-env.d.ts +3 -1
  86. package/dist/runtime/cli-add-workspace-integration-env.js +10 -313
  87. package/dist/runtime/cli-add-workspace-pattern-anchors.d.ts +10 -0
  88. package/dist/runtime/cli-add-workspace-pattern-anchors.js +95 -0
  89. package/dist/runtime/cli-add-workspace-pattern-options.d.ts +20 -0
  90. package/dist/runtime/cli-add-workspace-pattern-options.js +113 -0
  91. package/dist/runtime/cli-add-workspace-pattern-source-emitters.d.ts +20 -0
  92. package/dist/runtime/cli-add-workspace-pattern-source-emitters.js +57 -0
  93. package/dist/runtime/cli-add-workspace-pattern.d.ts +42 -0
  94. package/dist/runtime/cli-add-workspace-pattern.js +99 -0
  95. package/dist/runtime/cli-add-workspace-post-meta.js +1 -1
  96. package/dist/runtime/cli-add-workspace-registration-hooks.d.ts +50 -0
  97. package/dist/runtime/cli-add-workspace-registration-hooks.js +162 -0
  98. package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +9 -4
  99. package/dist/runtime/cli-add-workspace-rest-anchors.js +9 -428
  100. package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.d.ts +17 -0
  101. package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.js +108 -0
  102. package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.d.ts +9 -0
  103. package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.js +142 -0
  104. package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.d.ts +51 -0
  105. package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.js +415 -0
  106. package/dist/runtime/cli-add-workspace-rest-generated.d.ts +9 -0
  107. package/dist/runtime/cli-add-workspace-rest-generated.js +160 -0
  108. package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.d.ts +80 -0
  109. package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.js +238 -0
  110. package/dist/runtime/cli-add-workspace-rest-manual.d.ts +8 -0
  111. package/dist/runtime/cli-add-workspace-rest-manual.js +266 -0
  112. package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +18 -0
  113. package/dist/runtime/cli-add-workspace-rest-php-templates.js +359 -0
  114. package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.d.ts +33 -0
  115. package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.js +145 -0
  116. package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.d.ts +9 -0
  117. package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.js +162 -0
  118. package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.d.ts +7 -0
  119. package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.js +193 -0
  120. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +5 -91
  121. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +5 -642
  122. package/dist/runtime/cli-add-workspace-rest-source-utils.d.ts +17 -0
  123. package/dist/runtime/cli-add-workspace-rest-source-utils.js +50 -0
  124. package/dist/runtime/cli-add-workspace-rest-sync-script-shared.d.ts +56 -0
  125. package/dist/runtime/cli-add-workspace-rest-sync-script-shared.js +122 -0
  126. package/dist/runtime/cli-add-workspace-rest-types.d.ts +108 -0
  127. package/dist/runtime/cli-add-workspace-rest-types.js +1 -0
  128. package/dist/runtime/cli-add-workspace-rest.d.ts +3 -20
  129. package/dist/runtime/cli-add-workspace-rest.js +33 -788
  130. package/dist/runtime/cli-add-workspace-variation.d.ts +22 -0
  131. package/dist/runtime/cli-add-workspace-variation.js +162 -0
  132. package/dist/runtime/cli-add-workspace.d.ts +42 -107
  133. package/dist/runtime/cli-add-workspace.js +42 -674
  134. package/dist/runtime/cli-add.d.ts +3 -3
  135. package/dist/runtime/cli-add.js +2 -2
  136. package/dist/runtime/cli-core.d.ts +3 -2
  137. package/dist/runtime/cli-core.js +2 -2
  138. package/dist/runtime/cli-diagnostics.d.ts +3 -1
  139. package/dist/runtime/cli-diagnostics.js +17 -5
  140. package/dist/runtime/cli-doctor-workspace-bindings.js +63 -1
  141. package/dist/runtime/cli-doctor-workspace-block-addons.d.ts +12 -0
  142. package/dist/runtime/cli-doctor-workspace-block-addons.js +162 -0
  143. package/dist/runtime/cli-doctor-workspace-block-iframe.d.ts +9 -0
  144. package/dist/runtime/cli-doctor-workspace-block-iframe.js +228 -0
  145. package/dist/runtime/cli-doctor-workspace-block-metadata.d.ts +11 -0
  146. package/dist/runtime/cli-doctor-workspace-block-metadata.js +111 -0
  147. package/dist/runtime/cli-doctor-workspace-blocks.js +6 -424
  148. package/dist/runtime/cli-doctor-workspace-features-abilities.d.ts +11 -0
  149. package/dist/runtime/cli-doctor-workspace-features-abilities.js +112 -0
  150. package/dist/runtime/cli-doctor-workspace-features-admin-views.d.ts +11 -0
  151. package/dist/runtime/cli-doctor-workspace-features-admin-views.js +128 -0
  152. package/dist/runtime/cli-doctor-workspace-features-ai.d.ts +11 -0
  153. package/dist/runtime/cli-doctor-workspace-features-ai.js +57 -0
  154. package/dist/runtime/cli-doctor-workspace-features-editor-plugins.d.ts +11 -0
  155. package/dist/runtime/cli-doctor-workspace-features-editor-plugins.js +80 -0
  156. package/dist/runtime/cli-doctor-workspace-features-post-meta.d.ts +11 -0
  157. package/dist/runtime/cli-doctor-workspace-features-post-meta.js +77 -0
  158. package/dist/runtime/cli-doctor-workspace-features-rest.d.ts +11 -0
  159. package/dist/runtime/cli-doctor-workspace-features-rest.js +120 -0
  160. package/dist/runtime/cli-doctor-workspace-features.js +14 -487
  161. package/dist/runtime/cli-doctor.d.ts +54 -3
  162. package/dist/runtime/cli-doctor.js +92 -10
  163. package/dist/runtime/cli-help.js +12 -7
  164. package/dist/runtime/cli-init-package-json.js +4 -2
  165. package/dist/runtime/cli-prompt.d.ts +16 -2
  166. package/dist/runtime/cli-prompt.js +29 -12
  167. package/dist/runtime/cli-scaffold.d.ts +2 -1
  168. package/dist/runtime/cli-scaffold.js +19 -10
  169. package/dist/runtime/external-template-guards.js +4 -6
  170. package/dist/runtime/index.d.ts +6 -3
  171. package/dist/runtime/index.js +4 -2
  172. package/dist/runtime/json-utils.d.ts +62 -4
  173. package/dist/runtime/json-utils.js +78 -4
  174. package/dist/runtime/local-dev-presets.js +6 -2
  175. package/dist/runtime/migration-ui-capability.js +4 -1
  176. package/dist/runtime/migration-utils.js +4 -1
  177. package/dist/runtime/package-managers.js +6 -1
  178. package/dist/runtime/package-versions.d.ts +1 -0
  179. package/dist/runtime/package-versions.js +16 -3
  180. package/dist/runtime/pattern-catalog.d.ts +122 -0
  181. package/dist/runtime/pattern-catalog.js +471 -0
  182. package/dist/runtime/post-meta-binding-fields.d.ts +46 -0
  183. package/dist/runtime/post-meta-binding-fields.js +135 -0
  184. package/dist/runtime/scaffold-bootstrap.js +7 -2
  185. package/dist/runtime/scaffold-package-manager-files.js +5 -1
  186. package/dist/runtime/scaffold-repository-reference.js +4 -2
  187. package/dist/runtime/scaffold-template-variables.js +2 -1
  188. package/dist/runtime/scaffold.d.ts +18 -1
  189. package/dist/runtime/scaffold.js +55 -2
  190. package/dist/runtime/temp-roots.js +4 -1
  191. package/dist/runtime/template-layers.js +4 -1
  192. package/dist/runtime/template-registry.js +9 -3
  193. package/dist/runtime/template-source-contracts.d.ts +2 -0
  194. package/dist/runtime/template-source-normalization.js +2 -1
  195. package/dist/runtime/template-source-remote.js +18 -5
  196. package/dist/runtime/template-source-seeds.js +10 -3
  197. package/dist/runtime/typia-llm-json-schema.d.ts +24 -0
  198. package/dist/runtime/typia-llm-json-schema.js +33 -0
  199. package/dist/runtime/typia-llm-openapi-constraints.d.ts +20 -0
  200. package/dist/runtime/typia-llm-openapi-constraints.js +254 -0
  201. package/dist/runtime/typia-llm-projection.d.ts +25 -0
  202. package/dist/runtime/typia-llm-projection.js +58 -0
  203. package/dist/runtime/typia-llm-render.d.ts +21 -0
  204. package/dist/runtime/typia-llm-render.js +252 -0
  205. package/dist/runtime/typia-llm-sync.d.ts +10 -0
  206. package/dist/runtime/typia-llm-sync.js +63 -0
  207. package/dist/runtime/typia-llm-types.d.ts +197 -0
  208. package/dist/runtime/typia-llm-types.js +1 -0
  209. package/dist/runtime/typia-llm.d.ts +9 -255
  210. package/dist/runtime/typia-llm.js +5 -634
  211. package/dist/runtime/workspace-inventory-mutations.js +15 -1
  212. package/dist/runtime/workspace-inventory-parser-entries.d.ts +17 -0
  213. package/dist/runtime/workspace-inventory-parser-entries.js +157 -0
  214. package/dist/runtime/workspace-inventory-parser-validation.d.ts +104 -0
  215. package/dist/runtime/workspace-inventory-parser-validation.js +34 -0
  216. package/dist/runtime/workspace-inventory-parser.d.ts +3 -45
  217. package/dist/runtime/workspace-inventory-parser.js +3 -581
  218. package/dist/runtime/workspace-inventory-section-descriptors.d.ts +19 -0
  219. package/dist/runtime/workspace-inventory-section-descriptors.js +443 -0
  220. package/dist/runtime/workspace-inventory-templates.d.ts +3 -3
  221. package/dist/runtime/workspace-inventory-templates.js +10 -1
  222. package/dist/runtime/workspace-inventory-types.d.ts +10 -1
  223. package/dist/runtime/workspace-project.js +4 -6
  224. package/package.json +8 -3
  225. package/templates/_shared/compound/core/scripts/block-config.ts.mustache +22 -0
  226. package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +103 -2
  227. package/templates/_shared/compound/core/src/inner-blocks-templates.ts.mustache +13 -0
  228. package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +22 -1
@@ -1,6 +1,42 @@
1
- import { CLI_DIAGNOSTIC_CODES, createCliCommandError, formatDoctorCheckLine, formatDoctorSummaryLine, getDoctorFailureDetailLines, } from "./cli-diagnostics.js";
1
+ import { CLI_DIAGNOSTIC_CODES, createCliCommandError, formatDoctorCheckLine, formatDoctorSummaryLine, } from "./cli-diagnostics.js";
2
2
  import { getEnvironmentDoctorChecks } from "./cli-doctor-environment.js";
3
3
  import { getWorkspaceDoctorChecks } from "./cli-doctor-workspace.js";
4
+ const DEFAULT_DOCTOR_EXIT_POLICY = "strict";
5
+ const defaultDoctorLinePrinter = (line) => {
6
+ process.stdout.write(`${line}\n`);
7
+ };
8
+ function renderDefaultDoctorCheckLine(check) {
9
+ defaultDoctorLinePrinter(formatDoctorCheckLine(check));
10
+ }
11
+ function renderDefaultDoctorSummaryLine(summaryLine) {
12
+ defaultDoctorLinePrinter(summaryLine);
13
+ }
14
+ function annotateDoctorChecks(checks, scope) {
15
+ return checks.map((check) => ({
16
+ ...check,
17
+ scope: check.scope ?? scope,
18
+ }));
19
+ }
20
+ function resolveDoctorExitPolicy(options) {
21
+ return options.exitPolicy ?? DEFAULT_DOCTOR_EXIT_POLICY;
22
+ }
23
+ function doesCheckContributeToExit(check, exitPolicy) {
24
+ if (check.status !== "fail") {
25
+ return false;
26
+ }
27
+ if (exitPolicy === "strict") {
28
+ return true;
29
+ }
30
+ return check.scope === "workspace";
31
+ }
32
+ function toFailureSummary(check, severity) {
33
+ return {
34
+ ...(check.code ? { code: check.code } : {}),
35
+ label: check.label,
36
+ scope: check.scope ?? "unknown",
37
+ severity,
38
+ };
39
+ }
4
40
  /**
5
41
  * Collect all runtime doctor checks for the current environment.
6
42
  *
@@ -14,28 +50,74 @@ import { getWorkspaceDoctorChecks } from "./cli-doctor-workspace.js";
14
50
  */
15
51
  export async function getDoctorChecks(cwd) {
16
52
  return [
17
- ...(await getEnvironmentDoctorChecks(cwd)),
18
- ...(await getWorkspaceDoctorChecks(cwd)),
53
+ ...annotateDoctorChecks(await getEnvironmentDoctorChecks(cwd), "environment"),
54
+ ...annotateDoctorChecks(await getWorkspaceDoctorChecks(cwd), "workspace"),
19
55
  ];
20
56
  }
21
57
  /**
22
- * Run doctor checks, render each line, and fail when any check does not pass.
58
+ * Return failed rows that contribute to the process exit code for one policy.
59
+ */
60
+ export function getDoctorExitFailureChecks(checks, options = {}) {
61
+ const exitPolicy = resolveDoctorExitPolicy(options);
62
+ return checks.filter((check) => doesCheckContributeToExit(check, exitPolicy));
63
+ }
64
+ /**
65
+ * Format only exit-contributing doctor failures for structured diagnostics.
66
+ */
67
+ export function getDoctorExitFailureDetailLines(checks, options = {}) {
68
+ return getDoctorExitFailureChecks(checks, options).map((check) => `${check.label}: ${check.detail}`);
69
+ }
70
+ /**
71
+ * Build the stable JSON summary for one doctor run.
72
+ */
73
+ export function createDoctorRunSummary(checks, options = {}) {
74
+ const exitPolicy = resolveDoctorExitPolicy(options);
75
+ const failedChecks = checks.filter((check) => check.status === "fail");
76
+ const exitFailureChecks = failedChecks.filter((check) => doesCheckContributeToExit(check, exitPolicy));
77
+ const advisoryFailureChecks = failedChecks.filter((check) => !doesCheckContributeToExit(check, exitPolicy));
78
+ const warnings = checks.filter((check) => check.status === "warn").length;
79
+ return {
80
+ advisoryFailureCount: advisoryFailureChecks.length,
81
+ advisoryFailures: advisoryFailureChecks.map((check) => toFailureSummary(check, "advisory")),
82
+ exitCode: exitFailureChecks.length > 0 ? 1 : 0,
83
+ exitFailureCount: exitFailureChecks.length,
84
+ exitFailures: exitFailureChecks.map((check) => toFailureSummary(check, "error")),
85
+ exitPolicy,
86
+ failed: failedChecks.length,
87
+ passed: checks.length - failedChecks.length - warnings,
88
+ total: checks.length,
89
+ warnings,
90
+ };
91
+ }
92
+ /**
93
+ * Run doctor checks, render each line, and fail when one or more failed checks
94
+ * contribute to the exit code under the active exit policy.
95
+ *
96
+ * The default `strict` policy treats every failed row as exit-contributing.
97
+ * The `workspace-only` policy only fails on workspace-scoped rows so
98
+ * environment/runtime failures remain advisory for CI gates that only care
99
+ * about generated workspace artifacts.
23
100
  *
24
101
  * @param cwd Working directory to validate.
25
- * @param options Optional renderer override for each emitted check row.
102
+ * @param options Optional renderer overrides and exit-policy selection.
103
+ * @param options.exitPolicy Policy deciding which failed checks contribute to the process exit code.
104
+ * @param options.renderLine Optional renderer for each check row. Defaults to the stdout line printer.
105
+ * @param options.renderSummaryLine Optional renderer for the summary row. Defaults to the stdout line printer unless a custom `renderLine` suppresses implicit summary output.
26
106
  * @returns The completed list of doctor checks.
27
- * @throws {Error} When one or more checks fail.
107
+ * @throws {Error} When one or more failed checks contribute to the exit code under the active policy.
28
108
  */
29
109
  export async function runDoctor(cwd, options = {}) {
30
- const renderLine = options.renderLine ?? ((check) => console.log(formatDoctorCheckLine(check)));
110
+ const exitPolicy = resolveDoctorExitPolicy(options);
111
+ const renderLine = options.renderLine ?? renderDefaultDoctorCheckLine;
31
112
  const renderSummaryLine = options.renderSummaryLine ??
32
- (options.renderLine ? () => undefined : (summaryLine) => console.log(summaryLine));
113
+ (options.renderLine ? () => undefined : renderDefaultDoctorSummaryLine);
33
114
  const checks = await getDoctorChecks(cwd);
34
115
  for (const check of checks) {
35
116
  renderLine(check);
36
117
  }
37
- renderSummaryLine(formatDoctorSummaryLine(checks));
38
- const failureDetailLines = getDoctorFailureDetailLines(checks);
118
+ const exitFailureChecks = getDoctorExitFailureChecks(checks, { exitPolicy });
119
+ renderSummaryLine(formatDoctorSummaryLine(checks, { exitFailureChecks }));
120
+ const failureDetailLines = getDoctorExitFailureDetailLines(checks, { exitPolicy });
39
121
  if (failureDetailLines.length > 0) {
40
122
  throw createCliCommandError({
41
123
  code: CLI_DIAGNOSTIC_CODES.DOCTOR_CHECK_FAILED,
@@ -11,6 +11,7 @@ import { TEMPLATE_IDS } from "./template-registry.js";
11
11
  export function formatHelpText() {
12
12
  return `Usage:
13
13
  wp-typia create <project-dir> [--template <basic|interactivity>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
14
+ wp-typia create <project-dir> [--template workspace] [--profile <plugin-qa>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
14
15
  wp-typia create <project-dir> [--template query-loop] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--query-post-type <post-type>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-migration-ui] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
15
16
  wp-typia create <project-dir> [--template <./path|github:owner/repo/path[#ref]>] [--variant <name>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
16
17
  wp-typia create <project-dir> [--template <npm-package>] [--variant <name>] [--namespace <value>] [--text-domain <value>] [--php-prefix <value>] [--with-wp-env] [--with-test-preset] [--yes] [--dry-run] [--no-install] [--package-manager <id>]
@@ -20,14 +21,16 @@ export function formatHelpText() {
20
21
  wp-typia init [project-dir] [--apply] [--package-manager <id>]
21
22
  wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>]
22
23
  wp-typia add block <name> [--template <basic|interactivity|persistence|compound>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>]
23
- wp-typia add integration-env <name> [--wp-env] [--service <none|docker-compose>]
24
+ wp-typia add integration-env <name> [--wp-env] [--release-zip] [--service <none|docker-compose>]
25
+ wp-typia add core-variation <block-name> <name>
26
+ wp-typia add core-variation <name> --block <namespace/block>
24
27
  wp-typia add variation <name> --block <block-slug>
25
28
  wp-typia add style <name> --block <block-slug>
26
29
  wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>
27
- wp-typia add pattern <name>
28
- wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>]
30
+ wp-typia add pattern <name> [--scope <full|section>] [--section-role <role>] [--tags <tag,...>] [--thumbnail-url <url>]
31
+ wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>] [--from-post-meta|--post-meta <post-meta> [--meta-path <field>]]
29
32
  wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <method[,method...]>]
30
- wp-typia add rest-resource <name> --manual [--namespace <vendor/v1>] [--method <GET|POST|PUT|PATCH|DELETE>] [--auth <public|authenticated|public-write-protected>] [--path <route-pattern>] [--query-type <Type>] [--body-type <Type>] [--response-type <Type>]
33
+ wp-typia add rest-resource <name> --manual [--namespace <vendor/v1>] [--method <GET|POST|PUT|PATCH|DELETE>] [--auth <public|authenticated|public-write-protected>] [--path <route-pattern>|--route-pattern <route-pattern>] [--permission-callback <callback>] [--controller-class <ClassName>] [--controller-extends <BaseClass>] [--query-type <Type>] [--body-type <Type>] [--response-type <Type>] [--secret-field <field>] [--secret-state-field|--secret-has-value-field <field>] [--secret-preserve-on-empty <true|false>]
31
34
  wp-typia add post-meta <name> --post-type <post-type> [--type <ExportedTypeName>] [--meta-key <meta-key>] [--hide-from-rest]
32
35
  wp-typia add ability <name>
33
36
  wp-typia add ai-feature <name> [--namespace <vendor/v1>]
@@ -51,21 +54,23 @@ Notes:
51
54
  \`wp-typia <project-dir>\` remains a backward-compatible alias to \`create\` when \`<project-dir>\` is the only positional argument.
52
55
  \`wp-typia init\` previews the minimum retrofit sync surface by default; rerun with \`--apply\` to write package.json updates and generated helper scripts.
53
56
  Use \`--template workspace\` as shorthand for \`@wp-typia/create-workspace-template\`, the official empty workspace scaffold behind \`wp-typia add ...\`.
57
+ Use \`--profile plugin-qa\` with \`--template workspace\` when a plugin needs local wp-env smoke checks, \`.env.example\`, and release zip scripts from day one; omit it for the minimal workspace shell.
54
58
  Interactive add flows let you choose a template when \`--template\` is omitted; non-interactive runs default to \`basic\`.
55
59
  \`add admin-view\` scaffolds an opt-in DataViews-powered WordPress admin screen under \`src/admin-views/\`.
56
60
  Pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
57
61
  Pass \`--source core-data:postType/post\` or \`--source core-data:taxonomy/category\` to bind a WordPress-owned entity collection.
58
62
  Generated admin-view workspaces add \`@wp-typia/dataviews\` and the needed WordPress DataViews packages as opt-in dependencies.
59
63
  \`add integration-env\` generates an opt-in local smoke starter under \`scripts/integration-smoke/\`, updates \`.env.example\`, and can add \`@wordpress/env\` plus \`.wp-env.json\` when \`--wp-env\` is passed.
64
+ Pass \`--release-zip\` to add \`release:zip\`, \`release:zip:check\`, and \`qa:check\` scripts for plugin QA packaging.
60
65
  Pass \`--service docker-compose\` to include a placeholder local service stack that can be adapted to project-specific dependencies.
61
66
  \`query-loop\` is create-only. Use \`wp-typia create <project-dir> --template query-loop\`; \`wp-typia add block\` accepts only basic, interactivity, persistence, and compound families.
62
67
  \`add variation\` uses an existing workspace block from \`scripts/block-config.ts\`.
63
68
  \`add style\` registers a Block Styles option for an existing generated block.
64
69
  \`add transform\` adds a block-to-block transform into an existing generated block.
65
- \`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/\`.
66
- \`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`; pass \`--block\` and \`--attribute\` together to declare a bindable generated-block attribute.
70
+ \`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/full/\` or \`src/patterns/sections/\`.
71
+ \`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`; pass \`--block\` and \`--attribute\` together to declare a bindable generated-block attribute. Pass \`--from-post-meta\` or \`--post-meta\` to back the source from a typed post-meta contract and \`--meta-path\` to choose its default top-level field.
67
72
  \`add rest-resource\` scaffolds plugin-level TypeScript REST contracts under \`src/rest/\` and PHP route glue under \`inc/rest/\`.
68
- \`add rest-resource --manual\` tracks an external REST route with typed schemas, OpenAPI, clients, and drift checks without generating PHP route/controller files.
73
+ \`add rest-resource --manual\` tracks an external/provider REST route with typed schemas, OpenAPI, clients, and drift checks without generating PHP route/controller files while still allowing route-owner metadata such as permission callbacks and controller classes. Settings contracts can add \`--secret-field\` plus \`--secret-preserve-on-empty\` to model write-only credentials and preserve blank submissions.
69
74
  \`add post-meta\` scaffolds typed post meta contracts under \`src/post-meta/\`, emits schema artifacts, and wires generated \`register_post_meta()\` helpers under \`inc/post-meta/\`.
70
75
  \`add ability\` scaffolds typed workflow abilities under \`src/abilities/\` and server registration under \`inc/abilities/\`.
71
76
  \`add ai-feature\` scaffolds server-owned AI feature endpoints under \`src/ai-features/\` and PHP route glue under \`inc/ai-features/\`.
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { CLI_DIAGNOSTIC_CODES, createCliDiagnosticCodeError, } from "./cli-diagnostics.js";
4
4
  import { getPackageManager, transformPackageManagerText, } from "./package-managers.js";
5
5
  import { getPackageVersions } from "./package-versions.js";
6
+ import { readJsonFileSync } from "./json-utils.js";
6
7
  import { parseWorkspacePackageManagerId } from "./workspace-project.js";
7
8
  const BASE_RETROFIT_SCRIPTS = {
8
9
  sync: "tsx scripts/sync-project.ts",
@@ -22,9 +23,10 @@ export function readProjectPackageJson(projectDir) {
22
23
  if (!fs.existsSync(packageJsonPath)) {
23
24
  return null;
24
25
  }
25
- const source = fs.readFileSync(packageJsonPath, "utf8");
26
26
  try {
27
- return JSON.parse(source);
27
+ return readJsonFileSync(packageJsonPath, {
28
+ context: "project package manifest",
29
+ });
28
30
  }
29
31
  catch (error) {
30
32
  const message = error instanceof Error ? error.message : String(error);
@@ -1,4 +1,5 @@
1
1
  type ValidateInput = (value: string) => boolean | string;
2
+ export type PromptLinePrinter = (line: string) => void;
2
3
  interface PromptOption<T extends string> {
3
4
  hint?: string;
4
5
  label: string;
@@ -12,6 +13,15 @@ export interface ReadlinePrompt {
12
13
  select<T extends string>(message: string, options: PromptOption<T>[], defaultValue?: number): Promise<T>;
13
14
  text(message: string, defaultValue: string, validate?: ValidateInput): Promise<string>;
14
15
  }
16
+ /**
17
+ * Output adapters used by prompt rendering and validation feedback.
18
+ */
19
+ export interface ReadlinePromptOutput {
20
+ /** Render one informational prompt line. */
21
+ printLine?: PromptLinePrinter;
22
+ /** Render one validation or selection error line. */
23
+ errorLine?: PromptLinePrinter;
24
+ }
15
25
  /**
16
26
  * Adapter interface for readline-style prompt interactions.
17
27
  *
@@ -33,14 +43,18 @@ export interface ReadlineQuestionAdapter {
33
43
  /**
34
44
  * Create the default readline-backed prompt implementation for the CLI.
35
45
  *
46
+ * @param output Optional line printers for prompt and validation output.
36
47
  * @returns A prompt adapter that reads from stdin and writes to stdout.
37
48
  */
38
- export declare function createReadlinePrompt(): ReadlinePrompt;
49
+ export declare function createReadlinePrompt(output?: ReadlinePromptOutput): ReadlinePrompt;
39
50
  /**
40
51
  * Build a prompt adapter around a supplied readline-style question interface.
41
52
  *
42
53
  * This keeps the production CLI path unchanged while letting tests validate
43
54
  * retry behavior without stubbing global stdin/stdout.
55
+ *
56
+ * @param rl Readline-compatible question adapter.
57
+ * @param output Optional line printers for prompt and validation output.
44
58
  */
45
- export declare function createReadlinePromptWithInterface(rl: ReadlineQuestionAdapter): ReadlinePrompt;
59
+ export declare function createReadlinePromptWithInterface(rl: ReadlineQuestionAdapter, output?: ReadlinePromptOutput): ReadlinePrompt;
46
60
  export {};
@@ -2,22 +2,27 @@ import readline from "node:readline";
2
2
  /**
3
3
  * Create the default readline-backed prompt implementation for the CLI.
4
4
  *
5
+ * @param output Optional line printers for prompt and validation output.
5
6
  * @returns A prompt adapter that reads from stdin and writes to stdout.
6
7
  */
7
- export function createReadlinePrompt() {
8
+ export function createReadlinePrompt(output = {}) {
8
9
  const rl = readline.createInterface({
9
10
  input: process.stdin,
10
11
  output: process.stdout,
11
12
  });
12
- return createReadlinePromptWithInterface(rl);
13
+ return createReadlinePromptWithInterface(rl, output);
13
14
  }
14
15
  /**
15
16
  * Build a prompt adapter around a supplied readline-style question interface.
16
17
  *
17
18
  * This keeps the production CLI path unchanged while letting tests validate
18
19
  * retry behavior without stubbing global stdin/stdout.
20
+ *
21
+ * @param rl Readline-compatible question adapter.
22
+ * @param output Optional line printers for prompt and validation output.
19
23
  */
20
- export function createReadlinePromptWithInterface(rl) {
24
+ export function createReadlinePromptWithInterface(rl, output = {}) {
25
+ const { errorLine, printLine } = resolveReadlinePromptOutput(output);
21
26
  const askQuestion = (query) => new Promise((resolve) => {
22
27
  rl.question(query, resolve);
23
28
  });
@@ -28,7 +33,7 @@ export function createReadlinePromptWithInterface(rl) {
28
33
  if (validate) {
29
34
  const result = validate(value);
30
35
  if (result !== true) {
31
- console.error(formatValidationError(message, result, defaultValue));
36
+ errorLine(formatValidationError(message, result, defaultValue));
32
37
  continue;
33
38
  }
34
39
  }
@@ -40,7 +45,7 @@ export function createReadlinePromptWithInterface(rl) {
40
45
  throw new Error(`select() requires at least one option for prompt: ${message}`);
41
46
  }
42
47
  const resolvedDefaultIndex = getResolvedDefaultIndex(options, defaultValue);
43
- renderSelectPrompt(message, options, resolvedDefaultIndex);
48
+ renderSelectPrompt(message, options, resolvedDefaultIndex, printLine);
44
49
  while (true) {
45
50
  const answer = normalizePromptAnswer(await askQuestion(formatChoicePrompt(resolvedDefaultIndex)));
46
51
  if (answer.length === 0) {
@@ -51,10 +56,10 @@ export function createReadlinePromptWithInterface(rl) {
51
56
  return selection.value;
52
57
  }
53
58
  if (isPromptHelpToken(answer)) {
54
- renderSelectPrompt(message, options, resolvedDefaultIndex);
59
+ renderSelectPrompt(message, options, resolvedDefaultIndex, printLine);
55
60
  continue;
56
61
  }
57
- console.error(formatInvalidSelectionError(answer, options, resolvedDefaultIndex));
62
+ errorLine(formatInvalidSelectionError(answer, options, resolvedDefaultIndex));
58
63
  }
59
64
  },
60
65
  close() {
@@ -62,6 +67,18 @@ export function createReadlinePromptWithInterface(rl) {
62
67
  },
63
68
  };
64
69
  }
70
+ function resolveReadlinePromptOutput({ errorLine, printLine, }) {
71
+ return {
72
+ errorLine: errorLine ?? writePromptErrorLine,
73
+ printLine: printLine ?? writePromptLine,
74
+ };
75
+ }
76
+ function writePromptLine(line) {
77
+ process.stdout.write(`${line}\n`);
78
+ }
79
+ function writePromptErrorLine(line) {
80
+ process.stderr.write(`${line}\n`);
81
+ }
65
82
  function normalizePromptAnswer(value) {
66
83
  return String(value).trim();
67
84
  }
@@ -84,17 +101,17 @@ function formatValidationError(message, result, defaultValue) {
84
101
  function formatChoicePrompt(defaultIndex) {
85
102
  return `Choice [default: ${defaultIndex + 1}, ? for options]: `;
86
103
  }
87
- function renderSelectPrompt(message, options, defaultIndex) {
88
- console.log(message);
89
- console.log(" Enter a number, option label, or option value. Press Enter to keep the default, or type ? to list choices again.");
104
+ function renderSelectPrompt(message, options, defaultIndex, printLine) {
105
+ printLine(message);
106
+ printLine(" Enter a number, option label, or option value. Press Enter to keep the default, or type ? to list choices again.");
90
107
  options.forEach((option, index) => {
91
108
  const defaultMarker = index === defaultIndex ? " (default)" : "";
92
109
  const valueHint = normalizePromptToken(option.label) === normalizePromptToken(option.value)
93
110
  ? ""
94
111
  : ` [${option.value}]`;
95
- console.log(` ${index + 1}. ${option.label}${valueHint}${defaultMarker}`);
112
+ printLine(` ${index + 1}. ${option.label}${valueHint}${defaultMarker}`);
96
113
  if (option.hint) {
97
- console.log(` ${option.hint}`);
114
+ printLine(` ${option.hint}`);
98
115
  }
99
116
  });
100
117
  }
@@ -41,6 +41,7 @@ interface RunScaffoldFlowOptions {
41
41
  onProgress?: ((event: ScaffoldProgressEvent) => void | Promise<void>) | undefined;
42
42
  packageManager?: string;
43
43
  phpPrefix?: string;
44
+ profile?: string;
44
45
  projectInput: string;
45
46
  promptText?: Parameters<typeof collectScaffoldAnswers>[0]["promptText"];
46
47
  queryPostType?: string;
@@ -83,7 +84,7 @@ export declare function getOptionalOnboarding({ availableScripts, packageManager
83
84
  * project.
84
85
  * @returns The scaffold result together with next-step guidance.
85
86
  */
86
- export declare function runScaffoldFlow({ projectInput, cwd, templateId, alternateRenderTargets, dataStorageMode, dryRun, externalLayerId, externalLayerSource, innerBlocksPreset, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, queryPostType, yes, noInstall, onProgress, isInteractive, allowExistingDir, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }: RunScaffoldFlowOptions): Promise<{
87
+ export declare function runScaffoldFlow({ projectInput, cwd, templateId, alternateRenderTargets, dataStorageMode, dryRun, externalLayerId, externalLayerSource, innerBlocksPreset, persistencePolicy, packageManager, namespace, profile, textDomain, phpPrefix, queryPostType, yes, noInstall, onProgress, isInteractive, allowExistingDir, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }: RunScaffoldFlowOptions): Promise<{
87
88
  dryRun: boolean;
88
89
  optionalOnboarding: OptionalOnboardingGuidance;
89
90
  plan: ScaffoldDryRunPlan | undefined;
@@ -1,6 +1,6 @@
1
1
  import { promises as fsp } from "node:fs";
2
2
  import path from "node:path";
3
- import { collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, resolvePackageManagerId, resolveTemplateId, scaffoldProject, } from "./scaffold.js";
3
+ import { collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, resolveCreateProfileId, isPersistencePolicy, resolvePackageManagerId, resolveTemplateId, scaffoldProject, } from "./scaffold.js";
4
4
  import { parseAlternateRenderTargets } from "./alternate-render-targets.js";
5
5
  import { parseCompoundInnerBlocksPreset } from "./compound-inner-blocks.js";
6
6
  import { isCompoundPersistenceEnabled } from "./scaffold-template-variable-groups.js";
@@ -10,6 +10,7 @@ import { createManagedTempRoot } from "./temp-roots.js";
10
10
  import { getOptionalOnboardingNote, getOptionalOnboardingShortNote, getOptionalOnboardingSteps, } from "./scaffold-onboarding.js";
11
11
  import { formatNonEmptyTargetDirectoryError } from "./scaffold-bootstrap.js";
12
12
  import { pathExists } from "./fs-async.js";
13
+ import { readJsonFile } from "./json-utils.js";
13
14
  import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, isBuiltInTemplateId, } from "./template-registry.js";
14
15
  import { resolveOptionalInteractiveExternalLayerId, } from "./external-layer-selection.js";
15
16
  import { assertBuiltInTemplateVariantAllowed, resolveLocalCliPathOption, normalizeOptionalCliString, } from "./cli-validation.js";
@@ -40,7 +41,7 @@ async function assertDryRunTargetDirectoryReady(projectDir, allowExistingDir) {
40
41
  throw new Error(formatNonEmptyTargetDirectoryError(projectDir));
41
42
  }
42
43
  }
43
- async function buildScaffoldDryRunPlan({ allowExistingDir, alternateRenderTargets, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, installDependencies, noInstall, onProgress, packageManager, persistencePolicy, projectDir, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }) {
44
+ async function buildScaffoldDryRunPlan({ allowExistingDir, alternateRenderTargets, answers, cwd, dataStorageMode, externalLayerId, externalLayerSource, externalLayerSourceLabel, installDependencies, noInstall, onProgress, packageManager, persistencePolicy, profile, projectDir, templateId, variant, withMigrationUi, withTestPreset, withWpEnv, }) {
44
45
  await assertDryRunTargetDirectoryReady(projectDir, allowExistingDir);
45
46
  const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-scaffold-plan-");
46
47
  const previewProjectDir = path.join(tempRoot, "preview-project");
@@ -59,6 +60,7 @@ async function buildScaffoldDryRunPlan({ allowExistingDir, alternateRenderTarget
59
60
  onProgress,
60
61
  packageManager,
61
62
  persistencePolicy,
63
+ profile,
62
64
  projectDir: previewProjectDir,
63
65
  templateId,
64
66
  variant,
@@ -272,7 +274,7 @@ export function getOptionalOnboarding({ availableScripts, packageManager, templa
272
274
  * project.
273
275
  * @returns The scaffold result together with next-step guidance.
274
276
  */
275
- export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, alternateRenderTargets, dataStorageMode, dryRun = false, externalLayerId, externalLayerSource, innerBlocksPreset, persistencePolicy, packageManager, namespace, textDomain, phpPrefix, queryPostType, yes = false, noInstall = false, onProgress, isInteractive = false, allowExistingDir = false, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies = undefined, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }) {
277
+ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, alternateRenderTargets, dataStorageMode, dryRun = false, externalLayerId, externalLayerSource, innerBlocksPreset, persistencePolicy, packageManager, namespace, profile, textDomain, phpPrefix, queryPostType, yes = false, noInstall = false, onProgress, isInteractive = false, allowExistingDir = false, selectTemplate, selectDataStorage, selectExternalLayerId, selectPersistencePolicy, selectPackageManager, promptText, installDependencies = undefined, variant, selectWithTestPreset, selectWithWpEnv, selectWithMigrationUi, withMigrationUi, withTestPreset, withWpEnv, }) {
276
278
  const normalizedExternalLayerId = normalizeOptionalCliString(externalLayerId);
277
279
  const normalizedExternalLayerSource = resolveLocalCliPathOption({
278
280
  cwd,
@@ -286,6 +288,7 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
286
288
  isInteractive,
287
289
  selectTemplate,
288
290
  });
291
+ const resolvedProfile = resolveCreateProfileId(profile);
289
292
  validateCreateFlagContract({
290
293
  alternateRenderTargets,
291
294
  dataStorageMode,
@@ -339,12 +342,14 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
339
342
  isInteractive,
340
343
  selectPackageManager,
341
344
  });
342
- const resolvedWithWpEnv = await resolveOptionalBooleanFlag({
343
- explicitValue: withWpEnv,
344
- isInteractive,
345
- select: selectWithWpEnv,
346
- yes,
347
- });
345
+ const resolvedWithWpEnv = resolvedProfile === "plugin-qa"
346
+ ? true
347
+ : await resolveOptionalBooleanFlag({
348
+ explicitValue: withWpEnv,
349
+ isInteractive,
350
+ select: selectWithWpEnv,
351
+ yes,
352
+ });
348
353
  const resolvedWithTestPreset = await resolveOptionalBooleanFlag({
349
354
  explicitValue: withTestPreset,
350
355
  isInteractive,
@@ -391,6 +396,7 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
391
396
  onProgress,
392
397
  packageManager: resolvedPackageManager,
393
398
  persistencePolicy: resolvedPersistencePolicy,
399
+ profile: resolvedProfile,
394
400
  projectDir,
395
401
  templateId: resolvedTemplateId,
396
402
  variant,
@@ -414,6 +420,7 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
414
420
  onProgress,
415
421
  packageManager: resolvedPackageManager,
416
422
  persistencePolicy: resolvedPersistencePolicy,
423
+ profile: resolvedProfile,
417
424
  projectDir,
418
425
  templateId: resolvedTemplateId,
419
426
  variant,
@@ -425,7 +432,9 @@ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templ
425
432
  let availableScripts;
426
433
  if (!dryRun) {
427
434
  try {
428
- const parsedPackageJson = JSON.parse(await fsp.readFile(path.join(projectDir, "package.json"), "utf8"));
435
+ const parsedPackageJson = await readJsonFile(path.join(projectDir, "package.json"), {
436
+ context: "generated package manifest",
437
+ });
429
438
  const scripts = parsedPackageJson.scripts &&
430
439
  typeof parsedPackageJson.scripts === "object" &&
431
440
  !Array.isArray(parsedPackageJson.scripts)
@@ -1,4 +1,5 @@
1
1
  import fs from "node:fs";
2
+ import { safeJsonParse } from "./json-utils.js";
2
3
  export const TEMPLATE_SOURCE_TIMEOUT_CODE = "template-source-timeout";
3
4
  export const TEMPLATE_SOURCE_TOO_LARGE_CODE = "template-source-too-large";
4
5
  const DEFAULT_EXTERNAL_TEMPLATE_TIMEOUT_MS = 20000;
@@ -120,12 +121,9 @@ async function readResponseBodyWithLimit(response, options) {
120
121
  }
121
122
  export async function readJsonResponseWithLimit(response, options) {
122
123
  const buffer = await readResponseBodyWithLimit(response, options);
123
- try {
124
- return JSON.parse(buffer.toString("utf8"));
125
- }
126
- catch (error) {
127
- throw new Error(`Failed to parse ${options.label}: ${error instanceof Error ? error.message : String(error)}`);
128
- }
124
+ return safeJsonParse(buffer.toString("utf8"), {
125
+ context: options.label,
126
+ });
129
127
  }
130
128
  export async function readBufferResponseWithLimit(response, options) {
131
129
  return readResponseBodyWithLimit(response, options);
@@ -7,7 +7,8 @@
7
7
  * and workspace-aware helpers such as `getWorkspaceBlockSelectOptions`,
8
8
  * `getWorkspaceBlockSelectOptionsAsync`,
9
9
  * `runAddBlockCommand`, `runAddBlockStyleCommand`,
10
- * `runAddBlockTransformCommand`, `runAddVariationCommand`,
10
+ * `runAddBlockTransformCommand`, `runAddCoreVariationCommand`,
11
+ * `runAddVariationCommand`,
11
12
  * `runAddPatternCommand`, `runAddBindingSourceCommand`,
12
13
  * `runAddEditorPluginCommand`,
13
14
  * `runAddAdminViewCommand`,
@@ -38,5 +39,7 @@ export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOpti
38
39
  export { EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV, pruneExternalTemplateCache, } from "./template-source-cache.js";
39
40
  export type { ExternalTemplateCachePruneOptions, ExternalTemplateCachePruneResult, } from "./template-source-cache.js";
40
41
  export { STALE_TEMP_ROOT_MAX_AGE_MS, WP_TYPIA_TEMP_ROOT_PREFIX, cleanupManagedTempRoot, cleanupStaleTempRoots, createManagedTempRoot, getTrackedTempRoots, } from "./temp-roots.js";
41
- export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
42
- export type { CliDiagnosticCode, CliDiagnosticCodeError, CliDiagnosticMessage, DoctorCheck, EditorPluginSlotId, HookedBlockPositionId, ReadlinePrompt, WorkspaceBlockSelectOption, } from "./cli-core.js";
42
+ export { createReadlinePrompt, createDoctorRunSummary, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorExitFailureChecks, getDoctorExitFailureDetailLines, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddCoreVariationCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
43
+ export { extractPatternSectionRoleMatches, extractPatternSectionRolesFromAttributes, formatPatternCatalogDiagnostics, PATTERN_CATALOG_SCOPE_IDS, resolvePatternCatalogContentFile, validatePatternCatalog, } from "./pattern-catalog.js";
44
+ export type { CliDiagnosticCode, CliDiagnosticCodeError, CliDiagnosticMessage, DoctorCheck, DoctorCheckScope, DoctorExitPolicy, DoctorFailureSummary, DoctorRunSummary, EditorPluginSlotId, HookedBlockPositionId, ReadlinePrompt, WorkspaceBlockSelectOption, } from "./cli-core.js";
45
+ export type { PatternCatalogDiagnostic, PatternCatalogDiagnosticCode, PatternCatalogDiagnosticSeverity, PatternCatalogEntry, PatternCatalogScope, PatternCatalogSectionRoleConvention, PatternCatalogSectionRoleMatch, PatternCatalogValidationOptions, PatternCatalogValidationResult, } from "./pattern-catalog.js";
@@ -7,7 +7,8 @@
7
7
  * and workspace-aware helpers such as `getWorkspaceBlockSelectOptions`,
8
8
  * `getWorkspaceBlockSelectOptionsAsync`,
9
9
  * `runAddBlockCommand`, `runAddBlockStyleCommand`,
10
- * `runAddBlockTransformCommand`, `runAddVariationCommand`,
10
+ * `runAddBlockTransformCommand`, `runAddCoreVariationCommand`,
11
+ * `runAddVariationCommand`,
11
12
  * `runAddPatternCommand`, `runAddBindingSourceCommand`,
12
13
  * `runAddEditorPluginCommand`,
13
14
  * `runAddAdminViewCommand`,
@@ -29,4 +30,5 @@ export { clearPackageVersionsCache, getPackageVersions, invalidatePackageVersion
29
30
  export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOptions, listTemplates, } from "./template-registry.js";
30
31
  export { EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV, pruneExternalTemplateCache, } from "./template-source-cache.js";
31
32
  export { STALE_TEMP_ROOT_MAX_AGE_MS, WP_TYPIA_TEMP_ROOT_PREFIX, cleanupManagedTempRoot, cleanupStaleTempRoots, createManagedTempRoot, getTrackedTempRoots, } from "./temp-roots.js";
32
- export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
33
+ export { createReadlinePrompt, createDoctorRunSummary, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorExitFailureChecks, getDoctorExitFailureDetailLines, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddCoreVariationCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
34
+ export { extractPatternSectionRoleMatches, extractPatternSectionRolesFromAttributes, formatPatternCatalogDiagnostics, PATTERN_CATALOG_SCOPE_IDS, resolvePatternCatalogContentFile, validatePatternCatalog, } from "./pattern-catalog.js";
@@ -1,7 +1,65 @@
1
1
  /**
2
- * Re-exports JSON cloning helpers from `@wp-typia/block-runtime`.
3
- * This adapter keeps the existing project-tools module path stable while the
4
- * runtime implementation now lives in block-runtime.
2
+ * JSON helpers shared by project-tools runtime modules.
3
+ *
4
+ * File-backed runtime JSON readers should use `safeJsonParse`,
5
+ * `readJsonFileSync`, or `readJsonFile` so malformed JSON reports the file path
6
+ * and operation context. Raw `JSON.parse` remains intentional for trusted
7
+ * in-memory clones, subprocess output, test fixtures, generated workspace
8
+ * script templates that embed their own path-aware parse handling,
9
+ * package-version manifest cache probes with colocated path-aware wrappers,
10
+ * and cache/discovery probes that immediately catch malformed documents to
11
+ * continue with fallback behavior.
12
+ *
13
+ * This module keeps `cloneJsonValue` local instead of re-exporting the
14
+ * block-runtime helper so Bunli CLI bundles that only need project-tools JSON
15
+ * readers do not need to resolve the block-runtime subpath at runtime.
16
+ *
5
17
  * @module
6
18
  */
7
- export * from "@wp-typia/block-runtime/json-utils";
19
+ /**
20
+ * Create a deep clone of a JSON-serializable value.
21
+ *
22
+ * @remarks
23
+ * Values that are not JSON-serializable, such as functions, `undefined`,
24
+ * `BigInt`, class instances, and `Date` objects, are not preserved faithfully.
25
+ *
26
+ * @param value JSON-compatible data to clone.
27
+ * @returns A deep-cloned copy created with `JSON.parse(JSON.stringify(...))`.
28
+ */
29
+ export declare function cloneJsonValue<T>(value: T): T;
30
+ /**
31
+ * Optional metadata used to enrich JSON parse errors.
32
+ */
33
+ export interface SafeJsonParseOptions {
34
+ /** Human-readable operation label included in parse failures. */
35
+ context?: string;
36
+ /** Source file path included in parse failures when available. */
37
+ filePath?: string;
38
+ }
39
+ /**
40
+ * Parse JSON and include operation/file context when decoding fails.
41
+ *
42
+ * @param source Raw JSON source text.
43
+ * @param options Optional file path and human-readable operation context.
44
+ * @returns Parsed JSON value cast to the caller-specified type.
45
+ * @throws {Error} When the source is malformed JSON.
46
+ */
47
+ export declare function safeJsonParse<T = unknown>(source: string, options?: SafeJsonParseOptions): T;
48
+ /**
49
+ * Read and parse a JSON file synchronously with path-aware parse errors.
50
+ *
51
+ * @param filePath JSON file path to read.
52
+ * @param options Optional parse context. `filePath` is always set from the
53
+ * reader argument.
54
+ * @returns Parsed JSON value cast to the caller-specified type.
55
+ */
56
+ export declare function readJsonFileSync<T = unknown>(filePath: string, options?: Omit<SafeJsonParseOptions, "filePath">): T;
57
+ /**
58
+ * Read and parse a JSON file asynchronously with path-aware parse errors.
59
+ *
60
+ * @param filePath JSON file path to read.
61
+ * @param options Optional parse context. `filePath` is always set from the
62
+ * reader argument.
63
+ * @returns Parsed JSON value cast to the caller-specified type.
64
+ */
65
+ export declare function readJsonFile<T = unknown>(filePath: string, options?: Omit<SafeJsonParseOptions, "filePath">): Promise<T>;