@salsita-ai/sdk 0.50.0-develop.bc08a38ffe → 0.50.0-develop.bd84173265

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 (348) hide show
  1. package/README.md +14 -13
  2. package/dist/application-spec/caching/content-diff.js +1 -1
  3. package/dist/application-spec/core/application-file.d.ts +0 -2
  4. package/dist/application-spec/core/application-file.js +1 -1
  5. package/dist/application-spec/errors/diagnostic-codes.d.ts +4 -0
  6. package/dist/application-spec/errors/diagnostic-codes.js +1 -1
  7. package/dist/application-spec/errors/diagnostic-messages.d.ts +4 -0
  8. package/dist/application-spec/errors/diagnostic-messages.js +1 -1
  9. package/dist/application-spec/generate-application/code/domain-runtime-files.js +1 -1
  10. package/dist/application-spec/generate-application/code/generate-application-code.d.ts +3 -2
  11. package/dist/application-spec/generate-application/code/generate-application-code.js +1 -1
  12. package/dist/application-spec/generate-application/code/project-scaffolding.d.ts +11 -8
  13. package/dist/application-spec/generate-application/code/project-scaffolding.js +2 -2
  14. package/dist/application-spec/generate-application/code/standalone-app-files.d.ts +2 -2
  15. package/dist/application-spec/generate-application/code/standalone-app-files.js +1 -1
  16. package/dist/application-spec/generate-application/code/templates/configurator-config.js +6 -4
  17. package/dist/application-spec/generate-application/code/templates/eslint-config.d.ts +5 -0
  18. package/dist/application-spec/generate-application/code/templates/eslint-config.js +4 -5
  19. package/dist/application-spec/generate-application/code/templates/frontend-config.js +3 -5
  20. package/dist/application-spec/generate-application/code/templates/gitignore.js +0 -3
  21. package/dist/application-spec/generate-application/code/templates/globals.js +3 -4
  22. package/dist/application-spec/generate-application/code/templates/index.d.ts +1 -1
  23. package/dist/application-spec/generate-application/code/templates/index.js +1 -1
  24. package/dist/application-spec/generate-application/code/templates/lingui-rc.d.ts +5 -0
  25. package/dist/application-spec/generate-application/code/templates/lingui-rc.js +4 -4
  26. package/dist/application-spec/generate-application/code/templates/package-json.js +1 -1
  27. package/dist/application-spec/generate-application/code/templates/prettier-config.d.ts +5 -0
  28. package/dist/application-spec/generate-application/code/templates/prettier-config.js +4 -5
  29. package/dist/application-spec/generate-application/code/templates/root-tsconfig.d.ts +6 -0
  30. package/dist/application-spec/generate-application/code/templates/root-tsconfig.js +2 -0
  31. package/dist/application-spec/generate-application/code/templates/skills/phoenix-cli-skill.js +1 -1
  32. package/dist/application-spec/generate-application/code/templates/skills/phoenix-review-skill.js +1 -1
  33. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +13 -7
  34. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +2 -2
  35. package/dist/application-spec/generate-application/code/templates/tsconfig.d.ts +5 -0
  36. package/dist/application-spec/generate-application/code/templates/tsconfig.js +1 -1
  37. package/dist/application-spec/generate-application/code/templates/webhook-index.d.ts +6 -1
  38. package/dist/application-spec/generate-application/code/templates/webhook-index.js +10 -1
  39. package/dist/application-spec/generate-application/code/templates/webhooks-config.js +2 -3
  40. package/dist/application-spec/generate-application/index.d.ts +2 -0
  41. package/dist/application-spec/generate-application/index.js +1 -1
  42. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-model-runtime.d.ts +4 -3
  43. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.d.ts +7 -3
  44. package/dist/application-spec/generate-application/runtime/admin-runtime/admin-runtime.js +1 -1
  45. package/dist/application-spec/generate-application/runtime/admin-runtime/states-runtime.d.ts +2 -2
  46. package/dist/application-spec/generate-application/runtime/application-runtime.d.ts +13 -5
  47. package/dist/application-spec/generate-application/runtime/application-runtime.js +1 -1
  48. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-model-runtime.d.ts +4 -3
  49. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +6 -2
  50. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
  51. package/dist/application-spec/generate-application/runtime/configurator-runtime/states-runtime.d.ts +2 -2
  52. package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.d.ts +43 -0
  53. package/dist/application-spec/generate-application/runtime/factory-data/factory-data-runtime.js +1 -0
  54. package/dist/application-spec/generate-application/runtime/factory-data/index.d.ts +3 -0
  55. package/dist/application-spec/generate-application/runtime/factory-data/index.js +1 -0
  56. package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.d.ts +13 -0
  57. package/dist/application-spec/generate-application/runtime/factory-data/recipe-defaults.js +1 -0
  58. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.d.ts +16 -0
  59. package/dist/application-spec/generate-application/runtime/factory-data/static-violations.js +1 -0
  60. package/dist/application-spec/generate-application/runtime/migrations/index.d.ts +1 -0
  61. package/dist/application-spec/generate-application/runtime/migrations/index.js +1 -0
  62. package/dist/application-spec/generate-application/runtime/migrations/migration-runtime.d.ts +53 -0
  63. package/dist/application-spec/generate-application/runtime/migrations/migration-runtime.js +1 -0
  64. package/dist/application-spec/generate-application/runtime/sections/assistant-runtime.d.ts +2 -2
  65. package/dist/application-spec/generate-application/runtime/sections/data-runtime.d.ts +4 -4
  66. package/dist/application-spec/generate-application/runtime/sections/expression-runtime.d.ts +3 -2
  67. package/dist/application-spec/generate-application/runtime/sections/theme-runtime.d.ts +2 -2
  68. package/dist/application-spec/generate-application/runtime/sections/transformers-runtime.d.ts +3 -3
  69. package/dist/application-spec/generate-application/runtime-spec/decode-runtime-spec.d.ts +9 -0
  70. package/dist/application-spec/generate-application/runtime-spec/decode-runtime-spec.js +1 -0
  71. package/dist/application-spec/generate-application/runtime-spec/encode-runtime-spec.d.ts +8 -0
  72. package/dist/application-spec/generate-application/runtime-spec/encode-runtime-spec.js +1 -0
  73. package/dist/application-spec/generate-application/runtime-spec/encoded-runtime-spec.d.ts +27 -0
  74. package/dist/application-spec/generate-application/runtime-spec/encoded-runtime-spec.js +1 -0
  75. package/dist/application-spec/generate-application/runtime-spec/index.d.ts +4 -0
  76. package/dist/application-spec/generate-application/runtime-spec/index.js +1 -0
  77. package/dist/application-spec/generate-application/runtime-spec/runtime-spec.d.ts +68 -0
  78. package/dist/application-spec/generate-application/runtime-spec/runtime-spec.js +1 -0
  79. package/dist/application-spec/parse-application-files/categorize/categorize-files.d.ts +34 -0
  80. package/dist/application-spec/parse-application-files/categorize/categorize-files.js +1 -1
  81. package/dist/application-spec/parse-application-files/categorize/earlier-generated-editor-configs.d.ts +16 -0
  82. package/dist/application-spec/parse-application-files/categorize/earlier-generated-editor-configs.js +9 -0
  83. package/dist/application-spec/parse-application-files/categorize/earlier-generated-tsconfig.d.ts +9 -0
  84. package/dist/application-spec/parse-application-files/categorize/earlier-generated-tsconfig.js +1 -0
  85. package/dist/application-spec/parse-application-files/raw-spec/parse-yaml-spec-file.js +1 -1
  86. package/dist/application-spec/parse-application-files/spec/application/admin-spec/admin-spec.js +1 -1
  87. package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.js +1 -1
  88. package/dist/application-spec/parse-application-files/spec/common/index.d.ts +1 -0
  89. package/dist/application-spec/parse-application-files/spec/common/index.js +1 -1
  90. package/dist/application-spec/parse-application-files/spec/common/value-type/format-value-type.d.ts +3 -0
  91. package/dist/application-spec/parse-application-files/spec/common/value-type/format-value-type.js +1 -0
  92. package/dist/application-spec/parse-application-files/spec/common/value-type/index.d.ts +5 -0
  93. package/dist/application-spec/parse-application-files/spec/common/value-type/index.js +1 -0
  94. package/dist/application-spec/parse-application-files/spec/common/value-type/intersect-value-types.d.ts +6 -0
  95. package/dist/application-spec/parse-application-files/spec/common/value-type/intersect-value-types.js +1 -0
  96. package/dist/application-spec/parse-application-files/spec/common/value-type/is-assignable-value-type.d.ts +8 -0
  97. package/dist/application-spec/parse-application-files/spec/common/value-type/is-assignable-value-type.js +1 -0
  98. package/dist/application-spec/parse-application-files/spec/common/value-type/value-type-at.d.ts +10 -0
  99. package/dist/application-spec/parse-application-files/spec/common/value-type/value-type-at.js +1 -0
  100. package/dist/application-spec/parse-application-files/spec/common/value-type/value-type.d.ts +98 -0
  101. package/dist/application-spec/parse-application-files/spec/common/value-type/value-type.js +1 -0
  102. package/dist/application-spec/parse-application-files/spec/components/bindings/component-path.d.ts +13 -0
  103. package/dist/application-spec/parse-application-files/spec/components/bindings/component-path.js +1 -0
  104. package/dist/application-spec/parse-application-files/spec/components/bindings/index.d.ts +2 -0
  105. package/dist/application-spec/parse-application-files/spec/components/bindings/index.js +1 -1
  106. package/dist/application-spec/parse-application-files/spec/components/bindings/read-binding-type.d.ts +24 -0
  107. package/dist/application-spec/parse-application-files/spec/components/bindings/read-binding-type.js +1 -0
  108. package/dist/application-spec/parse-application-files/spec/components/component-state-type.d.ts +8 -0
  109. package/dist/application-spec/parse-application-files/spec/components/component-state-type.js +1 -0
  110. package/dist/application-spec/parse-application-files/spec/components/filter-criterion-types.d.ts +13 -0
  111. package/dist/application-spec/parse-application-files/spec/components/filter-criterion-types.js +1 -0
  112. package/dist/application-spec/parse-application-files/spec/components/static-entity-id.d.ts +14 -0
  113. package/dist/application-spec/parse-application-files/spec/components/static-entity-id.js +1 -0
  114. package/dist/application-spec/parse-application-files/spec/components/user-component-entry.d.ts +6 -0
  115. package/dist/application-spec/parse-application-files/spec/components/user-component-entry.js +1 -1
  116. package/dist/application-spec/parse-application-files/spec/components/user-components.d.ts +7 -4
  117. package/dist/application-spec/parse-application-files/spec/components/user-components.js +1 -1
  118. package/dist/application-spec/parse-application-files/spec/expressions/expression-read-types.d.ts +19 -0
  119. package/dist/application-spec/parse-application-files/spec/expressions/expression-read-types.js +1 -0
  120. package/dist/application-spec/parse-application-files/spec/expressions/expression-read.d.ts +13 -0
  121. package/dist/application-spec/parse-application-files/spec/expressions/expression-read.js +1 -0
  122. package/dist/application-spec/parse-application-files/spec/expressions/expressions.d.ts +6 -2
  123. package/dist/application-spec/parse-application-files/spec/expressions/expressions.js +1 -1
  124. package/dist/application-spec/parse-application-files/spec/invariants/invariants.d.ts +2 -2
  125. package/dist/application-spec/parse-application-files/spec/invariants/invariants.js +1 -1
  126. package/dist/application-spec/parse-application-files/spec/model/index.d.ts +1 -0
  127. package/dist/application-spec/parse-application-files/spec/model/index.js +1 -1
  128. package/dist/application-spec/parse-application-files/spec/model/model-type-resolution.d.ts +10 -0
  129. package/dist/application-spec/parse-application-files/spec/model/model-type-resolution.js +1 -0
  130. package/dist/client/phoenix-api.d.ts +367 -0
  131. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +36 -1
  132. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  133. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.d.ts +7 -1
  134. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -1
  135. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +6 -0
  136. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  137. package/dist/configurator/common/configurator-interface.d.ts +16 -1
  138. package/dist/configurator/common/configurator-interface.js +1 -1
  139. package/dist/configurator/common/index.d.ts +2 -0
  140. package/dist/configurator/common/index.js +1 -1
  141. package/dist/configurator/common/use-finalize-action.d.ts +31 -0
  142. package/dist/configurator/common/use-finalize-action.js +1 -0
  143. package/dist/configurator/common/use-reset-camera.d.ts +6 -0
  144. package/dist/configurator/common/use-reset-camera.js +1 -0
  145. package/dist/configurator/pages/DefaultConfiguratorLayout.d.ts +3 -2
  146. package/dist/configurator/pages/LoadedConfiguratorDetailPage.js +1 -1
  147. package/dist/configurator/pages/configurator-layout-name.d.ts +2 -0
  148. package/dist/configurator/pages/configurator-layout-name.js +1 -0
  149. package/dist/configurator/pages/default-configurator-elements.d.ts +8 -0
  150. package/dist/configurator/pages/default-configurator-elements.js +1 -0
  151. package/dist/configurator/pages/default-elements/built-in-entity-element.d.ts +10 -0
  152. package/dist/configurator/pages/default-elements/built-in-entity-element.js +1 -0
  153. package/dist/configurator/pages/default-elements/built-in-layout-element.d.ts +10 -0
  154. package/dist/configurator/pages/default-elements/built-in-layout-element.js +1 -0
  155. package/dist/configurator/pages/default-elements/domain-control-elements.d.ts +6 -0
  156. package/dist/configurator/pages/default-elements/domain-control-elements.js +1 -0
  157. package/dist/configurator/pages/default-elements/index.d.ts +4 -0
  158. package/dist/configurator/pages/default-elements/index.js +1 -0
  159. package/dist/configurator/pages/default-elements/recipe-panel-elements.d.ts +3 -0
  160. package/dist/configurator/pages/default-elements/recipe-panel-elements.js +1 -0
  161. package/dist/configurator/pages/default-elements/sidebar-footer-elements.d.ts +7 -0
  162. package/dist/configurator/pages/default-elements/sidebar-footer-elements.js +1 -0
  163. package/dist/configurator/pages/default-elements/toolbar-elements.d.ts +7 -0
  164. package/dist/configurator/pages/default-elements/toolbar-elements.js +1 -0
  165. package/dist/configurator/pages/index.d.ts +1 -0
  166. package/dist/configurator/pages/index.js +1 -1
  167. package/dist/configurator/ui/assistant/AssistantChips.d.ts +8 -2
  168. package/dist/configurator/ui/assistant/AssistantChips.js +1 -1
  169. package/dist/configurator/ui/assistant/AssistantMarkdown.d.ts +7 -2
  170. package/dist/configurator/ui/assistant/AssistantMarkdown.js +1 -1
  171. package/dist/configurator/ui/assistant/AssistantPanel.js +1 -1
  172. package/dist/configurator/ui/assistant/AssistantThread.js +1 -1
  173. package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.d.ts +1 -1
  174. package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.js +1 -1
  175. package/dist/configurator/ui/assistant/entity-link/entity-link-state.d.ts +1 -1
  176. package/dist/configurator/ui/assistant/entity-link/index.d.ts +0 -1
  177. package/dist/configurator/ui/assistant/entity-link/index.js +1 -1
  178. package/dist/configurator/ui/assistant/form/AssistantForm.d.ts +19 -0
  179. package/dist/configurator/ui/assistant/form/AssistantForm.js +1 -0
  180. package/dist/configurator/ui/assistant/form/built-in-form-registry.d.ts +10 -0
  181. package/dist/configurator/ui/assistant/form/built-in-form-registry.js +1 -0
  182. package/dist/configurator/ui/assistant/form/compose-answer.d.ts +11 -0
  183. package/dist/configurator/ui/assistant/form/compose-answer.js +1 -0
  184. package/dist/configurator/ui/assistant/form/describe-build-errors.d.ts +6 -0
  185. package/dist/configurator/ui/assistant/form/describe-build-errors.js +1 -0
  186. package/dist/configurator/ui/assistant/form/form-element-definition.d.ts +14 -0
  187. package/dist/configurator/ui/assistant/form/form-element-definition.js +1 -0
  188. package/dist/configurator/ui/assistant/form/form-model.d.ts +38 -0
  189. package/dist/configurator/ui/assistant/form/form-model.js +1 -0
  190. package/dist/configurator/ui/assistant/form/form-registry.d.ts +31 -0
  191. package/dist/configurator/ui/assistant/form/form-registry.js +8 -0
  192. package/dist/configurator/ui/assistant/form/form-state.d.ts +4 -0
  193. package/dist/configurator/ui/assistant/form/form-state.js +1 -0
  194. package/dist/configurator/ui/assistant/form/index.d.ts +2 -0
  195. package/dist/configurator/ui/assistant/form/index.js +1 -0
  196. package/dist/configurator/ui/assistant/form/parse-form-block.d.ts +9 -0
  197. package/dist/configurator/ui/assistant/form/parse-form-block.js +1 -0
  198. package/dist/configurator/ui/assistant/form/read-form-attributes.d.ts +13 -0
  199. package/dist/configurator/ui/assistant/form/read-form-attributes.js +1 -0
  200. package/dist/configurator/ui/assistant/form-elements/FormGroup.d.ts +3 -0
  201. package/dist/configurator/ui/assistant/form-elements/FormGroup.js +1 -0
  202. package/dist/configurator/ui/assistant/form-elements/FormOptions.d.ts +3 -0
  203. package/dist/configurator/ui/assistant/form-elements/FormOptions.js +1 -0
  204. package/dist/configurator/ui/assistant/form-elements/FormReply.d.ts +3 -0
  205. package/dist/configurator/ui/assistant/form-elements/FormReply.js +1 -0
  206. package/dist/configurator/ui/assistant/form-elements/FormText.d.ts +3 -0
  207. package/dist/configurator/ui/assistant/form-elements/FormText.js +1 -0
  208. package/dist/configurator/ui/assistant/form-elements/form-element-props.d.ts +34 -0
  209. package/dist/configurator/ui/assistant/form-elements/form-element-props.js +1 -0
  210. package/dist/configurator/ui/assistant/form-elements/index.d.ts +5 -0
  211. package/dist/configurator/ui/assistant/form-elements/index.js +1 -0
  212. package/dist/configurator/ui/assistant/reference-link/AssistantReferenceLink.d.ts +16 -0
  213. package/dist/configurator/ui/assistant/reference-link/AssistantReferenceLink.js +1 -0
  214. package/dist/configurator/ui/assistant/reference-link/assistant-link-target.d.ts +34 -0
  215. package/dist/configurator/ui/assistant/reference-link/assistant-link-target.js +1 -0
  216. package/dist/configurator/ui/assistant/reference-link/assistant-reference-details.d.ts +25 -0
  217. package/dist/configurator/ui/assistant/reference-link/assistant-reference-details.js +1 -0
  218. package/dist/configurator/ui/assistant/reference-link/index.d.ts +3 -0
  219. package/dist/configurator/ui/assistant/reference-link/index.js +1 -0
  220. package/dist/configurator/ui/assistant/reference-link/reference-styles.d.ts +12 -0
  221. package/dist/configurator/ui/assistant/reference-link/reference-styles.js +1 -0
  222. package/dist/configurator/ui/assistant/reference-link/use-assistant-reference-details.d.ts +8 -0
  223. package/dist/configurator/ui/assistant/reference-link/use-assistant-reference-details.js +1 -0
  224. package/dist/configurator/ui/assistant/streamed-markdown.d.ts +2 -0
  225. package/dist/configurator/ui/assistant/streamed-markdown.js +2 -2
  226. package/dist/configurator/ui/assistant/thread-items.d.ts +8 -1
  227. package/dist/configurator/ui/assistant/thread-items.js +1 -1
  228. package/dist/docs/controls/select-child-entity/cardselect.mdx +1 -0
  229. package/dist/docs/fabs/basic.mdx +2 -2
  230. package/dist/docs/index.json +1 -1
  231. package/dist/docs/layouts/custom-layout.mdx +1466 -196
  232. package/dist/docs/phoenix/components.mdx +6 -0
  233. package/dist/docs/phoenix/configurator-interface.mdx +66 -13
  234. package/dist/docs/phoenix/deployments.mdx +2 -6
  235. package/dist/docs/phoenix/domain-model.mdx +2 -0
  236. package/dist/docs/phoenix/finalization.mdx +1 -1
  237. package/dist/docs/phoenix/getting-started.mdx +2 -1
  238. package/dist/docs/phoenix/layout-slots.mdx +4 -2
  239. package/dist/docs/phoenix/localization.mdx +8 -6
  240. package/dist/docs/phoenix/migration-guide.mdx +21 -8
  241. package/dist/docs/phoenix/phoenix-cli.mdx +46 -10
  242. package/dist/docs/phoenix/project-structure.mdx +31 -12
  243. package/dist/docs/phoenix/sdk-builder-workflow.mdx +2 -2
  244. package/dist/docs/phoenix/webhooks.mdx +21 -4
  245. package/dist/domain/application/application-config.d.ts +3 -1
  246. package/dist/domain/application/assistant/assistant-form-elements.d.ts +28 -0
  247. package/dist/domain/application/assistant/assistant-form-elements.js +1 -0
  248. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  249. package/dist/domain/application/assistant/index.d.ts +2 -0
  250. package/dist/domain/application/assistant/index.js +1 -1
  251. package/dist/domain/application/assistant-recipe-groups.d.ts +3 -1
  252. package/dist/domain/application/configurator-builder.d.ts +4 -1
  253. package/dist/domain/application/configurator-builder.js +1 -1
  254. package/dist/domain/core/schema/extended-schema-validator.js +1 -1
  255. package/dist/domain/domain-context/index.d.ts +1 -1
  256. package/dist/domain/domain-context/undo-system.d.ts +28 -1
  257. package/dist/domain/domain-context/undo-system.js +1 -1
  258. package/dist/domain/domain-runtime/spec/initialize.js +1 -1
  259. package/dist/domain/domain-runtime/spec/selectors.js +1 -1
  260. package/dist/domain/domain-runtime/spec/types.d.ts +2 -0
  261. package/dist/domain/system-components/child-entity-selection.js +1 -1
  262. package/dist/domain/system-components/common/scene-entity-control-schema.d.ts +3 -0
  263. package/dist/domain/system-components/common/scene-entity-control-schema.js +1 -1
  264. package/dist/globals/index.d.ts +2 -0
  265. package/dist/i18n/locales/cs/messages.js +1 -1
  266. package/dist/i18n/locales/da/messages.js +1 -1
  267. package/dist/i18n/locales/de/messages.js +1 -1
  268. package/dist/i18n/locales/de-AT/messages.js +1 -1
  269. package/dist/i18n/locales/en/messages.js +1 -1
  270. package/dist/i18n/locales/en-AU/messages.js +1 -1
  271. package/dist/i18n/locales/en-GB/messages.js +1 -1
  272. package/dist/i18n/locales/es/messages.js +1 -1
  273. package/dist/i18n/locales/fr/messages.js +1 -1
  274. package/dist/i18n/locales/hu/messages.js +1 -1
  275. package/dist/i18n/locales/it/messages.js +1 -1
  276. package/dist/i18n/locales/nl/messages.js +1 -1
  277. package/dist/i18n/locales/pl/messages.js +1 -1
  278. package/dist/i18n/locales/pt/messages.js +1 -1
  279. package/dist/i18n/locales/ro/messages.js +1 -1
  280. package/dist/i18n/locales/sk/messages.js +1 -1
  281. package/dist/i18n/locales/tr/messages.js +1 -1
  282. package/dist/legacy/domain-cli/utils/cache.d.ts +1 -1
  283. package/dist/legacy/domain-cli/utils/cache.js +1 -1
  284. package/dist/legacy/domain-spec/__generated/domain-schema.d.ts +79 -80
  285. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/claude-md.d.ts +1 -1
  286. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/cursor-rules.d.ts +1 -1
  287. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.d.ts +1 -1
  288. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.js +7 -2
  289. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-admin.js +18 -16
  290. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-configurator.js +14 -12
  291. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-embedded-admin.js +13 -11
  292. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/frontend-embedded-configurator.js +13 -11
  293. package/dist/phoenix/application-spec/application-spec-builder.js +1 -1
  294. package/dist/phoenix/application-spec/generate-application-spec-story.js +2 -2
  295. package/dist/phoenix/application-spec/project-files.js +1 -1
  296. package/dist/phoenix/bin.d.ts +2 -0
  297. package/dist/phoenix/bin.js +2 -0
  298. package/dist/phoenix/check-configs/built-in-eslint-config.d.ts +9 -0
  299. package/dist/phoenix/check-configs/built-in-eslint-config.js +1 -0
  300. package/dist/phoenix/check-configs/eslint-config.d.ts +10 -0
  301. package/dist/phoenix/check-configs/eslint-config.js +1 -0
  302. package/dist/phoenix/check-configs/index.d.ts +8 -0
  303. package/dist/phoenix/check-configs/index.js +1 -0
  304. package/dist/phoenix/check-configs/typescript-project.d.ts +5 -0
  305. package/dist/phoenix/check-configs/typescript-project.js +1 -0
  306. package/dist/phoenix/cli.d.ts +0 -1
  307. package/dist/phoenix/cli.js +1 -2
  308. package/dist/phoenix/commands/check.js +1 -1
  309. package/dist/phoenix/commands/deps/deps.d.ts +52 -0
  310. package/dist/phoenix/commands/deps/deps.js +3 -0
  311. package/dist/phoenix/commands/deps/index.d.ts +1 -0
  312. package/dist/phoenix/commands/deps/index.js +1 -0
  313. package/dist/phoenix/commands/deps/sdk-manifest.d.ts +12 -0
  314. package/dist/phoenix/commands/deps/sdk-manifest.js +1 -0
  315. package/dist/phoenix/commands/dev.js +5 -5
  316. package/dist/phoenix/commands/fix.js +1 -1
  317. package/dist/phoenix/commands/index.d.ts +1 -0
  318. package/dist/phoenix/commands/index.js +1 -1
  319. package/dist/phoenix/commands/prettier.js +1 -1
  320. package/dist/phoenix/services/application-spec-project-watcher.d.ts +2 -0
  321. package/dist/phoenix/services/application-spec-project-watcher.js +3 -3
  322. package/dist/phoenix/services/lingui.d.ts +8 -0
  323. package/dist/phoenix/services/lingui.js +1 -1
  324. package/dist/phoenix/services/swc.js +1 -1
  325. package/dist/phoenix/services/vite-config.js +1 -1
  326. package/dist/phoenix/utils/index.d.ts +2 -1
  327. package/dist/phoenix/utils/index.js +1 -1
  328. package/dist/phoenix/utils/node-version/index.d.ts +1 -0
  329. package/dist/phoenix/utils/node-version/index.js +1 -0
  330. package/dist/phoenix/utils/node-version/supported-node-version.d.ts +12 -0
  331. package/dist/phoenix/utils/node-version/supported-node-version.js +4 -0
  332. package/dist/phoenix/utils/run-command.d.ts +11 -0
  333. package/dist/phoenix/utils/run-command.js +1 -1
  334. package/dist/phoenix/utils/sdk-tool/index.d.ts +1 -0
  335. package/dist/phoenix/utils/sdk-tool/index.js +1 -0
  336. package/dist/phoenix/utils/sdk-tool/resolve-sdk-tool-bin.d.ts +15 -0
  337. package/dist/phoenix/utils/sdk-tool/resolve-sdk-tool-bin.js +1 -0
  338. package/dist/react-sdk/domain-context/index.d.ts +1 -1
  339. package/dist/react-sdk/domain-context/index.js +1 -1
  340. package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.d.ts +5 -0
  341. package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.js +1 -1
  342. package/dist/ui-sdk/theme/types.d.ts +1 -1
  343. package/package.json +46 -35
  344. package/schema/domain-spec.json +86 -8
  345. package/dist/application-spec/generate-application/code/templates/webhook-implementation.d.ts +0 -1
  346. package/dist/application-spec/generate-application/code/templates/webhook-implementation.js +0 -7
  347. package/dist/configurator/ui/assistant/entity-link/entity-link-target.d.ts +0 -5
  348. package/dist/configurator/ui/assistant/entity-link/entity-link-target.js +0 -1
@@ -273,6 +273,12 @@ components:
273
273
 
274
274
  `$bind` is essential for form controls that need to show current state and accept changes, any UI element that both displays and modifies data, and interactive controls like attribute selectors, toggles, sliders, and input fields.
275
275
 
276
+ ### Types of bound values
277
+
278
+ The build checks that the field a `$read` or `$bind` reads fits the prop it is read into, the filter criterion, or, for `$filter: { $read: field }`, the whole filter. A `string` field read into a number prop, a nullable field read into a text, or an array read into a boolean is reported as `COMPONENT_BINDING_TYPE_MISMATCH` at the prop. A field whose schema gives its type only as `tsType` is not checked here. Expressions are checked where their type is settled.
279
+
280
+ A prop or filter criterion that takes an entity id, such as the `value` of `childEntitySelection` or `selectedEntityIds`, cannot hold an id written in YAML: an entity id is a branded type that only comes from the domain state. Bind it to a field or expression that holds the id; a written id is reported as `COMPONENT_STATIC_ENTITY_ID`.
281
+
276
282
  ### `$eval` - Inline Expressions
277
283
 
278
284
  `$eval` allows simple dynamic calculations directly in YAML without defining separate `$expression` implementations in TypeScript. It can appear wherever `$read` is allowed — including in component filter `active` properties — and is mutually exclusive with `$read` on the same property, but both can coexist on the same component instance across different properties.
@@ -165,6 +165,10 @@ const popNavigate = phx.frontend.usePopNavigate() // popNavigate() returns to th
165
165
  // Fullscreen: a flag in the configurator's state that the layout honours; it does not put the browser into fullscreen
166
166
  const isFullscreen = phx.frontend.useIsFullscreenActive()
167
167
  const setFullscreen = phx.frontend.useSetFullscreen() // setFullscreen(true) or setFullscreen(false)
168
+
169
+ // View state and camera
170
+ const setViewState = phx.frontend.useSetViewState() // setViewState(state) makes one of the spec's viewStates active
171
+ const resetCamera = phx.frontend.useResetCamera() // resetCamera() undoes the user's orbit, pan and zoom
168
172
  ```
169
173
 
170
174
  ### Controls
@@ -429,9 +433,11 @@ export default phx.frontend.createCustomPhoenixLayoutElement('ConfiguratorLayout
429
433
  - `LayoutSlots.DesktopSidebar` is the built-in desktop sidebar as one piece: the spec's tabs, back button, property pages and sidebar footer with their spacing, scrolling and empty states, and the assistant panel. Use it when the spec's property pages are what the customer should see and only their place changes, for example a sidebar on the left; build the controls yourself when they have to look like the brand's own. Without `width` it fills its container, so the layout positions and sizes that container; `miniSidebar` does not shrink it, so a layout that honours it reads `LayoutSlots.useSidebarContent().hasMiniSidebar` and lets the container take the sidebar's height. Its tabs sit outside it on the left; `side="start"` puts them on its right, for a sidebar on the left. In fullscreen it stays in place, transparent and inert, so a layout that wants the space back removes it while `phx.frontend.useIsFullscreenActive()` is set. See [Sidebar in a Custom Layout](?path=/docs/layouts-sidebar-in-a-custom-layout--docs).
430
434
  - Nothing of the built-in layouts is rendered for it. A project layout finalizes over the spec's `finalizeAction` components, see the finalize paragraph of [Hooks for a Project Layout](#hooks-for-a-project-layout). The `finalizePage` and `finalizeButton` components are legacy: they cannot be declared in YAML, only in TypeScript, and `Legacy.CommonFinalizePage`, which is deprecated, shows a `finalizePage` for projects that still have one. `LayoutDialog` renders only what the project registers with `createLayoutDialog` and is not part of the finalize flow. The preview start screen is `DesktopPreview` or `MobilePreview`, which the layout shows while `usePreview().isPreview` is set. Both previews frame the scene themselves, so the layout renders the component that calls `useSceneSafeArea()` only while `isPreview` is not set; it then measures when it mounts after the preview. The assistant panel is available to a project layout only inside `LayoutSlots.DesktopSidebar`.
431
435
  - The layout reads the state it has to react to from hooks, listed with what each returns in [Hooks for a Project Layout](#hooks-for-a-project-layout).
432
- - Messages for the user come one of two ways. `LayoutSlots.Services` shows violations of a rejected change, side-effect hints and errors as the built-in snackbars, which render into `LayoutSlots.DesktopSnackbarsRoot` or `LayoutSlots.MobileSnackbarsRoot` wherever the layout mounts it. `phx.frontend.useConfiguratorMessages(onMessage)` hands the same messages to the layout's own UI instead, with their text resolved, as the toast in [Custom Layout](?path=/docs/layouts-custom-layout--docs#show-messages) does; mount one of the two, not both, or every message is shown twice. Some messages stay snackbars either way: a failure to save the configuration and an error of the built-in finalize and other actions. They render into the snackbar root, so a layout that mounts none shows them outside the configurator, in the page's `body`. An error while a preset is applied appears on the preset screen, outside the layout.
436
+ - Messages for the user come one of two ways. `LayoutSlots.Services` shows violations of a rejected change, side-effect hints and errors as the built-in snackbars, which render into `LayoutSlots.DesktopSnackbarsRoot` or `LayoutSlots.MobileSnackbarsRoot` wherever the layout mounts it. `phx.frontend.useConfiguratorMessages(onMessage)` hands the same messages to the layout's own UI instead, with their text resolved, as the toast in [Custom Layout](?path=/docs/layouts-custom-layout--docs#show-messages) does; mount one of the two, not both, or every message is shown twice. Some messages stay snackbars either way: a failure to save the configuration and an error of the built-in finalize and other actions. They render into the snackbar root, so a layout that mounts none shows them outside the configurator, in the page's `body`. An error while a preset is applied appears on the preset screen, outside the layout. A finalize action the layout runs with `phx.frontend.useFinalizeAction` reports its error as that hook's `error` instead, neither as a message nor as a snackbar.
433
437
  - Any project layout element named `ConfiguratorLayout` takes over the page.
434
438
 
439
+ `defaultConfiguratorElements`, exported from `@salsita-ai/sdk/configurator`, holds the built-in UI as a `ConfiguratorLayout` registration that renders the layout the spec selects. Generated code registers these defaults with `withDefaultElements`, apart from the project's elements, so the built-in UI is a registration like any other; a project element registered under the same name wins over a default. The list also holds the configurator's built-in controls and layout elements under the kinds the spec names them by, such as `attributeSelect` or `undoToolbarButton`, so a project element registered under one of those names replaces the built-in one wherever the spec names that kind. A config assembled by hand, without generated code, calls `withDefaultElements(defaultConfiguratorElements)` too; without it no `ConfiguratorLayout` is registered and the page shows a "not found" box instead of the configurator.
440
+
435
441
  #### Hooks for a Project Layout
436
442
 
437
443
  A project layout reads the product and the configurator's state through hooks, and changes them through the functions the hooks return. Each row names where its hook comes from; the `phx.frontend` hooks in these tables are also exported from `@salsita-ai/sdk/react` under the same name. No hook looks at read mode: the control hooks and the navigation and fullscreen setters keep working while `accessInfo.viewMode` is `true`, so the layout decides what a viewer can change.
@@ -461,15 +467,17 @@ Texts from the spec, such as option titles and the `detail` fields, are `Localiz
461
467
 
462
468
  **Mode, fullscreen, preview and navigation**
463
469
 
464
- | Hook | Returns |
465
- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
466
- | `phx.frontend.useAccessService()` | `{ configurationId, accessInfo }`. `accessInfo.viewMode` is `true` while a configuration shared for viewing is open, and also while the host sets the `readonly` property. |
467
- | `phx.frontend.useIsFullscreenActive()` and `phx.frontend.useSetFullscreen()` | The fullscreen flag, a `boolean`, and a function `(enabled: boolean) => void` that sets it. |
468
- | `usePreview()` from `@salsita-ai/sdk/configurator` | `{ isPreview, isExpanded, isPreviewEnabled, isHidden, enter, leave }`. The layout shows a preview start screen while `isPreview` is `true`. |
469
- | `phx.frontend.useActiveNavigationState()` | The active navigation state, one of the spec's `navigationStates`. |
470
- | `phx.frontend.usePushNavigate()` and `phx.frontend.usePopNavigate()` | `(state) => void`, which enters a state and remembers the active one, and `() => void`, which returns to the remembered state and does nothing when there is none. `phx.frontend.useNavigate()` returns `(state) => void`, which enters a state and forgets the history. |
471
- | `phx.frontend.useActiveViewState()` and `phx.frontend.useActiveToolState()` | The active view state and tool state. |
472
- | `useActiveViewports()` from `@salsita-ai/sdk/react` | The responsive breakpoints the configurator's container satisfies, as `Viewport[]`, or `null` before it is measured. It follows the container, not the window, so it is the switch between a desktop and a phone layout. |
470
+ | Hook | Returns |
471
+ | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
472
+ | `phx.frontend.useAccessService()` | `{ configurationId, accessInfo }`. `accessInfo.viewMode` is `true` while a configuration shared for viewing is open, and also while the host sets the `readonly` property. |
473
+ | `phx.frontend.useIsFullscreenActive()` and `phx.frontend.useSetFullscreen()` | The fullscreen flag, a `boolean`, and a function `(enabled: boolean) => void` that sets it. |
474
+ | `usePreview()` from `@salsita-ai/sdk/configurator` | `{ isPreview, isExpanded, isPreviewEnabled, isHidden, enter, leave }`. The layout shows a preview start screen while `isPreview` is `true`. |
475
+ | `phx.frontend.useActiveNavigationState()` | The active navigation state, one of the spec's `navigationStates`. |
476
+ | `phx.frontend.usePushNavigate()` and `phx.frontend.usePopNavigate()` | `(state) => void`, which enters a state and remembers the active one, and `() => void`, which returns to the remembered state and does nothing when there is none. `phx.frontend.useNavigate()` returns `(state) => void`, which enters a state and forgets the history. |
477
+ | `phx.frontend.useActiveViewState()` and `phx.frontend.useActiveToolState()` | The active view state and tool state. |
478
+ | `phx.frontend.useSetViewState()` | `(state) => void`, which makes the given view state, one of the spec's `viewStates`, the active one; setting the active state again keeps it. Cameras and components filtered by `viewStates` follow the change. |
479
+ | `phx.frontend.useResetCamera()` | `() => void`, which moves the camera back to the framing of the active camera configuration, undoing the user's orbit, pan and zoom, as the toolbar's reset button does. Besides `phx.frontend`, `@salsita-ai/sdk/configurator` exports it, not `@salsita-ai/sdk/react`. |
480
+ | `useActiveViewports()` from `@salsita-ai/sdk/react` | The responsive breakpoints the configurator's container satisfies, as `Viewport[]`, or `null` before it is measured. It follows the container, not the window, so it is the switch between a desktop and a phone layout. `desktop` is a container wider than 768 pixels and `mobile` one at most 768 pixels wide; `phone` is narrower than 480 and `tablet` between 480 and 1024 pixels; `landscape` and `portrait` follow the browser window's orientation. The built-in layout uses its phone arrangement unless `desktop` is active. |
473
481
 
474
482
  **Violations**
475
483
 
@@ -478,16 +486,61 @@ Texts from the spec, such as option titles and the `detail` fields, are `Localiz
478
486
  | `phx.frontend.useStateValidity()` | The validity of the last committed state: `{ valid: true, severity: null }`, or `{ valid: true, severity: 'notice' \| 'warning', entityViolations }`. A change that leaves a `fixable` or `fatal` violation is rejected and never committed, and neither is a change during which an error was thrown, so neither is seen here. |
479
487
  | `phx.frontend.useFinalizeViolations()` | `{ disabled, hints, violations }`. `disabled` is `true` while a `warning`, `fixable` or `fatal` violation holds or the configuration failed to save; `hints` is the violations' text, or `undefined`. |
480
488
  | `phx.frontend.useConfiguratorMessages(onMessage)` | Nothing. It calls `onMessage(message)` once per message: `{ kind: 'violation', entityId, violation, text }` for each violation of the rejected state, including notices and warnings already present, so `violation.severity` tells the reason for the rejection (`fixable` or `fatal`) from them, `{ kind: 'sideEffect', text }` for each hint of a committed update, and `{ kind: 'error', error, text }` when an error is thrown while a change is validated, with `text` the generic "Oops, something went wrong". `text` is resolved to the current language; a violation's is its `message`, or its `type` without one, and the built-in snackbar prefixes it with `entityId`. Hints committed before the layout mounted are not delivered; when the most recent change was rejected or threw, its messages are delivered again when the hook mounts. `onMessage` may be a new function on every render. On `phx.frontend` the message is typed by the project, so `violation.type` narrows to its violation types; from `@salsita-ai/sdk/react` the type is `ConfiguratorMessage`. |
489
+ | `phx.frontend.useFinalizeAction(handler)` | `{ run, isPending, error, disabled, hints }` for the `finalizeAction` whose `handler` it is given; see the Finalize paragraph below for how to call it. `run()` records the finalize-button click for analytics and runs the project's handler, and does nothing while `disabled` or `isPending`; `error` is what the handler's last run rejected with, or `null`; `disabled` and `hints` are those of `useFinalizeViolations()`. The type of the result is `UseFinalizeActionResult` from `@salsita-ai/sdk/configurator`, which also exports the hook. |
481
490
 
482
491
  `LayoutSlots.Services` shows the messages of `useConfiguratorMessages` as snackbars; see the messages paragraph of [Loaded Configuration UI](#loaded-configuration-ui) for choosing between the two and for the messages that stay snackbars.
483
492
 
484
493
  **Finalize**
485
494
 
486
- A project layout finalizes over the spec's `finalizeAction` components. `phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] })`, with `finalizeActionComponent` from `@salsita-ai/sdk/domain`, lists them; each `state` is `{ variant, label, title, icon, handler }`, where `variant` is `'primary'` or `'secondary'` and `handler` names the project's handler registered with `phx.frontend.createPhoenixHandler`. The built-in footer offers the first `'primary'` action, or else the first action, as its button and the others in a menu, and disables them with `phx.frontend.useFinalizeViolations()`.
495
+ A project layout finalizes over the spec's `finalizeAction` components. `phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] })`, with `finalizeActionComponent` from `@salsita-ai/sdk/domain`, lists them; each `state` is `{ variant, label, title, icon, handler }`, where `variant` is `'primary'` or `'secondary'` and `handler` names the project's handler registered with `phx.frontend.createPhoenixHandler`. The built-in footer offers the first `'primary'` action, or else the first action, as its button and the others in a menu; a project layout follows the same rule when it offers one action.
496
+
497
+ Each action gets a component of its own that calls `phx.frontend.useFinalizeAction(action.state.handler)` once, never in a loop or conditionally, because the hook runs the project's handler factory, which calls hooks. The layout wraps that component in `<PhoenixHandlerBoundary name={action.state.handler}>` from `@salsita-ai/sdk/react`, so an edited handler takes effect without a reload. The hook returns:
498
+
499
+ - `run()`, which records the finalize-button click for analytics and then runs the handler. It does nothing while `disabled` or `isPending`.
500
+ - `isPending`, `true` while the handler runs.
501
+ - `error`, what the handler's last run rejected with, or `null`; a rejection that is not an `Error` is wrapped in one, with the value as its `cause`. It is cleared when the action runs again. No snackbar is raised; the layout shows the error its own way.
502
+ - `disabled` and `hints`, those of `useFinalizeViolations()`: finalizing is not possible while a `warning`, `fixable` or `fatal` violation holds or the configuration failed to save, and `hints` says why.
503
+
504
+ `isPending` and `error` belong to the mounted component: when it unmounts during a run, the handler keeps running, and a component mounted afterwards starts with `isPending` false and no `error`.
505
+
506
+ ```tsx
507
+ import { finalizeActionComponent } from '@salsita-ai/sdk/domain'
508
+ import { PhoenixHandlerBoundary, useResolveLocalizable } from '@salsita-ai/sdk/react'
509
+
510
+ const FinalizeButton = ({ handler, label }: { handler: string; label: string }) => {
511
+ const { run, isPending, error, disabled, hints } = phx.frontend.useFinalizeAction(handler)
512
+
513
+ return (
514
+ <div>
515
+ <button type="button" disabled={disabled || isPending} onClick={run} title={hints}>
516
+ {isPending ? 'Sending…' : label}
517
+ </button>
518
+ {error && <p role="alert">{error.message}</p>}
519
+ </div>
520
+ )
521
+ }
522
+
523
+ export const Finalize = () => {
524
+ const { accessInfo } = phx.frontend.useAccessService()
525
+ const resolve = useResolveLocalizable()
526
+ const actions = phx.frontend.useComponents({ componentTypes: [finalizeActionComponent] }) ?? []
527
+ const primary = actions.find(action => action.state.variant === 'primary') ?? actions[0]
528
+
529
+ if (accessInfo.viewMode || !primary) {
530
+ return null
531
+ }
532
+
533
+ return (
534
+ <PhoenixHandlerBoundary name={primary.state.handler}>
535
+ <FinalizeButton handler={primary.state.handler} label={resolve(primary.state.label)} />
536
+ </PhoenixHandlerBoundary>
537
+ )
538
+ }
539
+ ```
487
540
 
488
- To offer the same buttons, a project layout mounts `<FinalizeActions />` from `@salsita-ai/sdk/configurator`: the built-in footer's finalize buttons, the primary action plus a menu of the others, disabled with the hints of `useFinalizeViolations()`, with a spinner while the handler runs and a snackbar when it fails. It renders nothing without a `finalizeAction`, and it does not check read mode, so a layout hides it while `accessInfo.viewMode` is `true`.
541
+ The hook does not check read mode, so the layout hides finalizing while `accessInfo.viewMode` is `true`, as above. [Custom Layout](?path=/docs/layouts-custom-layout--docs#request-a-quote) runs a finalize action this way from its review step.
489
542
 
490
- To build its own buttons, a layout runs an action with `usePhoenixHandler(action.state.handler).handler()` from `@salsita-ai/sdk/react`, which returns a promise. `usePhoenixHandler` runs the project's handler factory, which calls hooks, so each action gets its own component that calls it once, never in a loop, and that component is wrapped in `<PhoenixHandlerBoundary name={action.state.handler}>` from the same import, so an edited handler takes effect without a reload. The layout then shows the pending state, the error and the disabled state from `useFinalizeViolations()` itself.
543
+ Instead of its own buttons, a project layout can mount `<FinalizeActions />` from `@salsita-ai/sdk/configurator`: the built-in footer's finalize buttons, the primary action plus a menu of the others, disabled with the hints of `useFinalizeViolations()`, with a spinner while the handler runs and a snackbar when it fails. It renders nothing without a `finalizeAction`, and it does not check read mode either.
491
544
 
492
545
  ## TransformerBuilder
493
546
 
@@ -281,9 +281,7 @@ Phoenix provides two helper functions for reading environment variables with val
281
281
  **`createEnvReader`** - General purpose environment reader used in frontend and deployment contexts:
282
282
 
283
283
  ```typescript
284
- import { bool, str } from 'envalid'
285
-
286
- import { createEnvReader } from '@salsita-ai/sdk/common/env'
284
+ import { bool, createEnvReader, str } from '@salsita-ai/sdk/common/env'
287
285
 
288
286
  // Create a reader function
289
287
  const readEnv = createEnvReader({
@@ -301,9 +299,7 @@ console.log(env.SERVER_URL) // Typed and validated
301
299
 
302
300
  ```typescript
303
301
  // webhooks/webhooks.config.ts
304
- import { str } from 'envalid'
305
-
306
- import { createEnvReader } from '@salsita-ai/sdk/common/env'
302
+ import { createEnvReader, str } from '@salsita-ai/sdk/common/env'
307
303
 
308
304
  export const readRuntimeConfig = createEnvReader({
309
305
  AWS_S3_PUBLIC_RESOURCES_BUCKET: str(),
@@ -329,6 +329,8 @@ components:
329
329
 
330
330
  The code generator will automatically create an expression with the same name and infer the return type based on usage context.
331
331
 
332
+ The type of an expression must share values with the type every component expects where it is read, and with its declared type. An expression declared as a number and read into a `title`, or one read both into a `title` and into `offsetX`, has no value its implementation could return, so the build reports `EXPRESSION_READ_TYPE_CONFLICT` at the expression and names each place it is read. A type given only as `tsType` is not checked here.
333
+
332
334
  ## Constants
333
335
 
334
336
  Constants are pre-generated expressions that return fixed values. Under the hood, they are implemented as expressions but are automatically generated by the Phoenix system, so you don't need to write TypeScript implementation code for them.
@@ -15,7 +15,7 @@ Finalization is Phoenix's system for completing configurator sessions and proces
15
15
 
16
16
  > For integration-specific finalization flows — how host-specific data is passed in and how the host is notified on completion (event dispatch in `headless`, redirect in `handoff`) — see [Finalization (Internal)](?path=/docs/phoenix-integration-finalization-internal--docs) and [Finalization (External)](?path=/docs/phoenix-integration-finalization-external--docs).
17
17
 
18
- The universal sidebar footer offers the spec's `finalizeAction` components: Phoenix selects one primary footer action and places additional finalization actions in its menu. It never opens a `finalizePage`; the `finalizePage` and `finalizeButton` components are legacy, declared only in TypeScript, and used by the basic sidebar footer and the legacy layouts. Built-in finalization actions use configuration validity to disable the footer action and provide pending and generic error states, including for add-to-cart handlers. See [Universal Sidebar Footer](?path=/docs/layouts-sidebar-footer-universal--docs) for the layout behavior.
18
+ The universal sidebar footer offers the spec's `finalizeAction` components: Phoenix selects one primary footer action and places additional finalization actions in its menu. It never opens a `finalizePage`; the `finalizePage` and `finalizeButton` components are legacy, declared only in TypeScript, and used by the basic sidebar footer and the legacy layouts. Built-in finalization actions use configuration validity to disable the footer action and provide pending and generic error states, including for add-to-cart handlers. See [Universal Sidebar Footer](?path=/docs/layouts-sidebar-footer-universal--docs) for the layout behavior. A project layout (`ConfiguratorLayout`) offers the same actions with its own buttons through `phx.frontend.useFinalizeAction`, which runs an action's handler and returns its pending state, its error and the disabled state with hints; see the Finalize paragraph of [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout).
19
19
 
20
20
  ## How Finalization Works
21
21
 
@@ -26,6 +26,7 @@ The Phoenix CLI (`phoenix` command) is the unified tool for all configurator dev
26
26
  - `phoenix dev` - Start the development server with hot reload
27
27
  - `phoenix build` - Build the configurator for production
28
28
  - `phoenix sync` - Synchronize dependencies and generated code
29
+ - `phoenix deps` - Add the SDK's missing peer dependencies to `package.json` and move out-of-range ones into range
29
30
  - `phoenix check` - Validate domain configuration and code
30
31
  - `phoenix fix` - Auto-fix common issues in domain files
31
32
 
@@ -57,7 +58,7 @@ This section provides practical guidance for developers who are new to Phoenix P
57
58
 
58
59
  Before diving into Phoenix Platform development, ensure you have:
59
60
 
60
- - **Node.js** and **pnpm** - Required versions are set automatically in the project
61
+ - **Node.js 22.13 or newer** and **pnpm** - The SDK and the Phoenix CLI run on Node.js 22.13 or newer (see [Starting a New Project](?path=/docs/phoenix-phoenix-cli--docs#starting-a-new-project)); a project generated by Phoenix pins the exact Node.js and pnpm versions it is developed with
61
62
  - **JavaScript/TypeScript** - Phoenix generates TypeScript code and uses modern JavaScript patterns
62
63
  - **React** - The platform builds on React components, hooks, and modern React patterns
63
64
  - **Three.js** - Basic knowledge of 3D graphics, scenes, cameras, and rendering concepts
@@ -27,7 +27,7 @@ export const Toolbar = () => (
27
27
  - A slot takes no props unless its row names them, and reads what it shows from the spec and the configurator's state. It renders inside the configurator only, under a `ConfiguratorLayout`.
28
28
  - A slot brings its own look but not its place: it adds no padding or scrolling around itself, so the layout puts it in a container. Two members differ: `SharedCanvas` fills its nearest positioned ancestor, and `DesktopSidebar` brings the sidebar's spacing and scrolling with it.
29
29
  - Read mode means `useAccessService().accessInfo.viewMode` is `true`: a configuration shared for viewing is open, or the host sets the `readonly` property. "No change" in the read-mode column means the slot renders the same for a viewer, so the layout decides whether a viewer sees it.
30
- - `Desktop*` and `Mobile*` members are twins that differ in size and arrangement; [Phone layout](#phone-layout) lists the phone ones. The container's width, not the window's, decides which one fits: `useActiveViewports()` from `@salsita-ai/sdk/react` returns the breakpoints the container satisfies.
30
+ - `Desktop*` and `Mobile*` members are twins that differ in size and arrangement; [Phone layout](#phone-layout) lists the phone ones. The container's width, not the window's, decides which one fits: `useActiveViewports()` from `@salsita-ai/sdk/react` returns the breakpoints the container satisfies. The built-in layout uses the `Desktop*` members while `desktop` is active, for a container wider than 768 pixels, and the `Mobile*` members otherwise, while `mobile` is active; `phone` means narrower than 480 pixels and `tablet` between 480 and 1024.
31
31
 
32
32
  ## Canvas and services
33
33
 
@@ -42,7 +42,7 @@ export const Toolbar = () => (
42
42
 
43
43
  - Mount `SharedCanvas`, not `Canvas`: `Canvas` suspends while it probes the GPU on its first mount, and `SharedCanvas` holds the boundary that catches it. Without either, the app loader stays on screen unless the project sets `appLoader: legacy`.
44
44
  - `SharedCanvas` fills its nearest positioned ancestor and paints an opaque background, so the layout positions its own UI after it in the markup.
45
- - Snackbars are raised by `Services`, and also by the built-in finalize and footer actions when their handler fails and when saving the configuration fails. A layout that shows violations, side-effect hints and validation errors its own way calls `phx.frontend.useConfiguratorMessages(onMessage)` instead of mounting `Services`, see [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout); the other snackbars still need a root. They render into the snackbar root the layout mounts; with no root mounted they render into the page's `document.body`, outside the configurator. The desktop root is a zero-height element the snackbars stack upwards from, so the layout places it where their bottom edge belongs. The phone root leaves them fixed to the viewport, see `MobileSnackbarsRoot`.
45
+ - Snackbars are raised by `Services`, and also by the built-in finalize and footer actions when their handler fails and when saving the configuration fails. A layout that shows violations, side-effect hints and validation errors its own way calls `phx.frontend.useConfiguratorMessages(onMessage)` instead of mounting `Services`, see [Configurator Interface → Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout); the other snackbars still need a root. They render into the snackbar root the layout mounts; with no root mounted they render into the page's `document.body`, outside the configurator. The desktop root is a zero-height element the snackbars stack upwards from, so the layout places it where their bottom edge belongs. The phone root leaves them fixed to the viewport, see `MobileSnackbarsRoot`. A finalize action the layout runs with `phx.frontend.useFinalizeAction` raises no snackbar; its error is the hook's `error`.
46
46
 
47
47
  ## Desktop sidebar
48
48
 
@@ -70,6 +70,8 @@ A sidebar footer with `universalSidebarFooter` does not check read mode, althoug
70
70
  | `ToolControls` | The same component as `DesktopToolControls` and `MobileToolControls` | As `DesktopToolControls` | Nothing without the component | No change |
71
71
  | `DesktopCallToAction` | **The button that leaves a tool mode, not the finalize button.** Clicking it switches to the component's `exitTo` tool state | An `exitToolModeFab` component, usually filtered to the tool states it belongs to | Nothing. It throws when more than one is active | Nothing |
72
72
 
73
+ Instead of `DesktopViewControls` or `MobileViewControls`, a layout can build its own view buttons with `phx.frontend.useActiveViewState()` and `phx.frontend.useSetViewState()`, which need no `viewControls` component, see [Hooks for a Project Layout](?path=/docs/phoenix-configurator-interface--docs#hooks-for-a-project-layout).
74
+
73
75
  ## Banners and branding
74
76
 
75
77
  | Member | Shows | Fed by | With nothing configured | Read mode |
@@ -408,7 +408,7 @@ function EntityList({ entities }) {
408
408
  When you need to do more complex text formatting with placeholders or embedded elements, you can reach for Lingui's `Trans` macro directly:
409
409
 
410
410
  ```tsx
411
- import { Trans, msg } from '@lingui/macro'
411
+ import { Trans } from '@lingui/react/macro'
412
412
 
413
413
  function WelcomeMessage({ userName, itemCount }) {
414
414
  return (
@@ -423,14 +423,14 @@ function WelcomeMessage({ userName, itemCount }) {
423
423
 
424
424
  ## Server-Side Translations for Webhooks
425
425
 
426
- The localization system isn't just for the frontend — it works in server-side webhook handlers too. PDF and email tasks render React templates with the same `@lingui/macro` toolchain (`<Trans>`, `msg`) you already use in UI components. The task context exposes `ctx.resolveLocalizable` already bound to the request locale and domain fallback chain, and the React builders use it for localizable subjects, attachment filenames, bodies, headers, footers, and watermark text.
426
+ The localization system isn't just for the frontend — it works in server-side webhook handlers too. PDF and email tasks render React templates with the same Lingui macros (`<Trans>` from `@lingui/react/macro`, `msg` from `@lingui/core/macro`) you already use in UI components. The task context exposes `ctx.resolveLocalizable` already bound to the request locale and domain fallback chain, and the React builders use it for localizable subjects, attachment filenames, bodies, headers, footers, and watermark text.
427
427
 
428
428
  ### In the handler
429
429
 
430
430
  Use the `msg` template tag for one-off strings you pass into builder methods:
431
431
 
432
432
  ```tsx
433
- import { msg } from '@lingui/macro'
433
+ import { msg } from '@lingui/core/macro'
434
434
 
435
435
  export const emailTask = phx.webhooks.taskFactory.createSendEmailTask((resources, data, ctx) => {
436
436
  return ctx.emailTaskBuilder
@@ -450,7 +450,7 @@ export const emailTask = phx.webhooks.taskFactory.createSendEmailTask((resources
450
450
  Use `<Trans>` for inline strings — exactly as in the frontend — and `<HtmlHelpers.Localized>` to render localizable values pulled from the domain (e.g. `$root.$summary[].title`, which are typed as `MessageDescriptor` or `MultilingualString`):
451
451
 
452
452
  ```tsx
453
- import { Trans } from '@lingui/macro'
453
+ import { Trans } from '@lingui/react/macro'
454
454
 
455
455
  import { HtmlHelpers } from '@salsita-ai/sdk/webhook'
456
456
 
@@ -547,6 +547,8 @@ When you're ready to ship:
547
547
  phx build
548
548
  ```
549
549
 
550
+ With the application-spec pipeline, `phx dev` and `phx build` compile the Lingui macros in your frontend code with the SDK's own Lingui macro plugin and the configuration in `.phoenix/.linguirc`, so the project installs no Babel macro packages for them (see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)).
551
+
550
552
  ### Translation Files
551
553
 
552
554
  The `.po` files in `src/locales/` are standard GNU gettext format that most translation tools support:
@@ -565,7 +567,7 @@ During development, missing translations fall back to the message ID. In product
565
567
 
566
568
  ### Locale Fallback Configuration
567
569
 
568
- Phoenix automatically configures comprehensive locale fallbacks in the generated `.linguirc` file. When a translation is missing for a specific regional locale, it gracefully falls back to the base language before falling back to the default language (English).
570
+ Phoenix automatically configures comprehensive locale fallbacks in the Lingui configuration it generates. When a translation is missing for a specific regional locale, it gracefully falls back to the base language before falling back to the default language (English).
569
571
 
570
572
  **Fallback Rules:**
571
573
 
@@ -595,7 +597,7 @@ User locale: de-AT (Austrian German)
595
597
  └─ Translation in en? → Use it (default fallback)
596
598
  ```
597
599
 
598
- The fallback configuration is generated by `phx sync` and stored in `.linguirc`. You don't need to configure this manually - it's handled automatically based on your `availableLocales` in `spec/application.yaml`.
600
+ The fallback configuration is generated by `phx sync` and stored in `.phoenix/.linguirc` (in the project root on the legacy pipeline; see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)). You don't need to configure this manually - it's handled automatically based on your `availableLocales` in `spec/application.yaml`.
599
601
 
600
602
  ## What We Learned
601
603
 
@@ -251,8 +251,21 @@ rm src/frontend/frontend.tsx
251
251
  # Remove empty domain/frontend folders after moving all files
252
252
  rmdir src/domain/implementation src/domain/data src/domain
253
253
  rmdir src/frontend/systems/transformers src/frontend/systems src/frontend/ui src/frontend/admin-pages src/frontend
254
+
255
+ # Remove the root TypeScript settings (sync writes the file again)
256
+ rm tsconfig.json
257
+ ```
258
+
259
+ With the application-spec pipeline (`phoenix.applicationFlow` in `package.json`; see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)), the project's TypeScript settings are generated into `.phoenix/tsconfig.json`. Sync writes the root `tsconfig.json` only into a project that has none, as a single line that extends them:
260
+
261
+ ```json
262
+ { "extends": "./.phoenix/tsconfig.json" }
254
263
  ```
255
264
 
265
+ A root `tsconfig.json` from the old multi-folder template, or one written by hand, stays as it is and does not pick up the generated settings or the global `phx` types in `.phoenix/globals.d.ts`, so `pnpm ts:check` fails. Delete it, or replace its content with the line above, before the first sync.
266
+
267
+ With the application-spec pipeline (see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)), `eslint.config.js` and `prettier.config.js` are the project's. Sync replaces a file earlier SDK versions generated, the one under the "Auto-generated file. Do not modify this file manually." header that re-exports `eslintrc` or `prettierrc`, with a file that re-exports the same configuration from `@salsita-ai/sdk/common/eslint` or `@salsita-ai/sdk/common/prettier`, and writes that file into a project that has none. A file of your own stays as it is, and editors, `phoenix check` and `phoenix fix` use it; make sure it imports only packages the project still depends on, or delete it before the first sync. Without the file, `phoenix check` and `phoenix fix` use the SDK's configuration. The legacy pipeline rewrites both files on every sync.
268
+
256
269
  ### 10. Create Mocks (Optional)
257
270
 
258
271
  If you have mock files, move them to `mocks/`:
@@ -390,7 +403,7 @@ pnpm install
390
403
 
391
404
  1. Run type check: `pnpm ts:check`
392
405
  2. Update any broken type imports
393
- 3. Ensure `tsconfig.json` paths are correct (auto-generated by Phoenix)
406
+ 3. With the application-spec pipeline (`phoenix.applicationFlow`; see [Current and legacy project tooling](?path=/docs/phoenix-phoenix-cli--docs#current-and-legacy-project-tooling)), check that the root `tsconfig.json` is the one-line file that extends `.phoenix/tsconfig.json` (see [step 9](#9-remove-auto-generated-files))
394
407
 
395
408
  ## Checklist
396
409
 
@@ -433,13 +446,13 @@ Use this checklist to verify migration completeness:
433
446
 
434
447
  The following files are no longer needed - they are auto-generated by the CLI:
435
448
 
436
- | File | Replacement |
437
- | --------------------------- | -------------------------------------------- |
438
- | `src/domain/domain.ts` | Auto-generated in `.phoenix/domain.ts` |
439
- | `src/frontend/frontend.tsx` | Auto-generated in `.phoenix/configurator.ts` |
440
- | `tsconfig.json` | Auto-generated by CLI |
441
- | `eslint.config.js` | Auto-generated by CLI |
442
- | `prettier.config.js` | Auto-generated by CLI |
449
+ | File | Replacement |
450
+ | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
451
+ | `src/domain/domain.ts` | Auto-generated in `.phoenix/domain.ts` |
452
+ | `src/frontend/frontend.tsx` | Auto-generated in `.phoenix/configurator.ts` |
453
+ | `tsconfig.json` | Delete before the first sync; with the application-spec pipeline, sync writes a one-line file that extends `.phoenix/tsconfig.json` |
454
+ | `eslint.config.js` | With the application-spec pipeline, sync replaces the file earlier SDK versions generated with one that re-exports the SDK's ESLint configuration, or writes one when there is none; a file of your own stays (see [step 9](#9-remove-auto-generated-files)) |
455
+ | `prettier.config.js` | With the application-spec pipeline, sync replaces the file earlier SDK versions generated with one that re-exports the SDK's Prettier configuration, or writes one when there is none; a file of your own stays (see [step 9](#9-remove-auto-generated-files)) |
443
456
 
444
457
  ## Builder Options Moved to YAML
445
458
 
@@ -14,6 +14,8 @@ The Phoenix CLI (`phoenix` command) is the unified tool for all configurator dev
14
14
 
15
15
  ## Starting a New Project
16
16
 
17
+ The SDK and its CLI run on Node.js 22.13 or newer, the range declared in `engines.node` of `@salsita-ai/sdk`. On an older Node.js, `phoenix` stops before it runs a command, names the running version and the required range, and exits with a non-zero code. The legacy binaries run no such check; package managers warn about the range when the SDK is installed.
18
+
17
19
  `phoenix init [folder]` starts a configurator project in `[folder]` (default: the working directory):
18
20
 
19
21
  ```bash
@@ -135,24 +137,35 @@ The same streams are available in the editor's **Logs** sidebar panel with per-s
135
137
 
136
138
  ### `phoenix check`
137
139
 
138
- Runs all code quality checks in sequence:
140
+ Runs all code quality checks in sequence, with the TypeScript compiler, ESLint and Prettier the SDK installs as its own dependencies, so the versions in the project's `package.json` do not decide them:
139
141
 
140
- 1. **TypeScript** — Type checking with `tsc`
141
- 2. **ESLint** — Linting rules
142
- 3. **Prettier** — Code formatting
142
+ 1. **TypeScript** — Type checking with the SDK's `tsc` (TypeScript 7), with the project's root `tsconfig.json`, or with `.phoenix/tsconfig.json` when the project has none (see [Project Structure](?path=/docs/phoenix-project-structure--docs#root-level-files))
143
+ 2. **ESLint** — Linting rules, over `src/`; a project with no files there passes. ESLint uses the project's `eslint.config.js`, or the SDK's configuration when the project has none; its type-aware rules then read the same TypeScript configuration as the type check
144
+ 3. **Prettier** — Code formatting, with the project's Prettier configuration, or the SDK's when the project has none
143
145
 
144
146
  ### `phoenix fix`
145
147
 
146
- Auto-fixes ESLint and Prettier issues. Equivalent to running `eslint --fix` and `prettier --write` together.
148
+ Auto-fixes ESLint and Prettier issues, with the same tools and configurations as `phoenix check`. Equivalent to running the SDK's `eslint --fix` and `prettier --write` together.
147
149
 
148
150
  ## Environment Variables
149
151
 
150
- When you run `deployment:prepare-local` or `deployment:prepare`, the CLI communicates with the Phoenix server, which generates environment variables and writes them to `.env.generated`.
152
+ When you run `deployment:prepare-local` or `deployment:prepare`, the CLI communicates with the Phoenix server, which generates environment variables and writes them to `.env.generated`. `phoenix dev` does the same for its development deployment when it starts.
153
+
154
+ ### The generated env file
155
+
156
+ A project has one generated env file. Phoenix keeps it in `.phoenix/`, as `.phoenix/.env.generated`, unless the project has a `.env.generated` in its root, which then is the one that counts.
157
+
158
+ - `phoenix dev` reads and writes `.phoenix/.env.generated` in a project without a root `.env.generated`, and creates no file in the project root. In a project that has a root `.env.generated`, it reads and writes that file and `.phoenix/.env.generated` is not used.
159
+ - The deployment and environment commands (`deployment:prepare`, `deployment:prepare-dev`, `deployment:prepare-local`, `deployment:build-envs` and the others with an `--outFile` option) write `.env.generated` in the project root unless `--outFile` or `OUT_FILE` names another file. Deploy pipelines read it there. Once one of them has written it, `phoenix dev` and `phoenix build` use it.
160
+ - Everything that reads environment variables follows the same rule: the root `.env.generated` when it exists, otherwise `.phoenix/.env.generated`. The two files are never merged.
161
+ - `phoenix clean` removes `.phoenix/` and with it `.phoenix/.env.generated`; the next `phoenix dev` prepares the development deployment again. A root `.env.generated` stays.
162
+
163
+ This holds for a project on the application-spec pipeline. In a project on the legacy pipeline (see [Current and legacy project tooling](#current-and-legacy-project-tooling)), `phoenix dev` always reads and writes `.env.generated` in the project root.
151
164
 
152
165
  ### Data Flow
153
166
 
154
167
  ```
155
- spec/application.yaml → Server prepares environment → CLI writes .env.generated → Frontend/Webhooks read it
168
+ spec/application.yaml → Server prepares environment → CLI writes the generated env file → Frontend/Webhooks read it
156
169
  ```
157
170
 
158
171
  ### Project Scripts
@@ -173,7 +186,7 @@ A project may have other scripts than these five, such as `sync`, `test` or `ver
173
186
 
174
187
  ### Server-Generated Variables
175
188
 
176
- These are automatically computed by the server and written to `.env.generated`:
189
+ These are automatically computed by the server and written to the generated env file:
177
190
 
178
191
  | Variable | Purpose |
179
192
  | -------------------------------- | ------------------------------------------------------- |
@@ -261,7 +274,7 @@ A development environment keeps the AI assistant's conversation when the assista
261
274
  Environment variables are resolved in this order (highest to lowest priority):
262
275
 
263
276
  1. Process environment variables (shell)
264
- 2. `.env.generated` (created by deployment commands)
277
+ 2. [The generated env file](#the-generated-env-file): `.env.generated` in the project root when the project has one, otherwise `.phoenix/.env.generated`
265
278
  3. `.env` (manual overrides)
266
279
 
267
280
  ### Generated Config Files
@@ -292,13 +305,18 @@ Starts the full development environment: Vite dev server, development webhook tu
292
305
  | `--region` | `PHOENIX_REGION` | `eu` | Region of the signed-in workspace, used when no server URL is set |
293
306
  | `--skipUpload` / `--su` | `SKIP_UPLOAD` | `false` | Skip the S3 asset upload when the development deployment is prepared at startup |
294
307
 
308
+ With the application-spec pipeline, `phoenix dev` creates an empty `src/` folder when the project has none, so that it rebuilds when the first source file, such as `src/webhooks/index.ts`, is added.
309
+
310
+ With the application-spec pipeline, the SDK's own Lingui CLI runs with the configuration in `.phoenix/.linguirc`, both for `--withLingui` and when `phoenix sync` and `phoenix build` extract and compile the catalogs; see [Root Level Files](?path=/docs/phoenix-project-structure--docs#root-level-files). The dev server and `phoenix build` compile the Lingui macros (`msg`, `t`, `Trans` and the others, imported from `@lingui/core/macro`, `@lingui/react/macro` or `@lingui/macro`) with the SDK's own Lingui macro plugin and the same configuration, so the project needs neither `babel-plugin-macros` nor `@lingui/macro` for them. Babel macros of other packages are not compiled.
311
+
295
312
  In `server` persistence mode the project comes from `--projectSlug`, `PROJECT_SLUG` or `project` in the spec, and the credential from `DEVELOPMENT_KEY` or the `phoenix login` sign-in; see [Starting a New Project](#starting-a-new-project). When signed in, the environment is always your own development environment and `--environmentSlug` is ignored.
296
313
 
297
314
  The dev server watches for changes in:
298
315
 
299
316
  - `spec/**/*.yaml` — Domain specification files
300
317
  - `src/**/*.{ts,tsx,yaml,yml,json,html,css}` — Source files
301
- - `.env`, `.env.generated` — Environment files (triggers full Vite restart)
318
+ - `.env` — Environment file; a change restarts the Vite dev server
319
+ - `.env.generated`, `.phoenix/.env.generated` — Generated env files; a change rebuilds the project files. Only a file that exists when `phoenix dev` starts is watched: a root `.env.generated` that a deployment command creates while dev runs is not watched; restart `phoenix dev` to use it.
302
320
 
303
321
  When linked SDK packages are detected (`phoenix link`), changes to SDK dist files are also watched.
304
322
 
@@ -396,6 +414,24 @@ With the application-spec pipeline (see [Current and legacy project tooling](#cu
396
414
  | ---------------- | --------------- | ------- | ------------------------------ |
397
415
  | `--force` / `-f` | `FORCE_REBUILD` | `false` | Force full rebuild, skip cache |
398
416
 
417
+ ### `phoenix deps`
418
+
419
+ Brings `package.json` in line with the SDK's peer dependencies: the packages the SDK's code imports and the project installs next to it, so the project and the SDK share one copy. The `peerDependencies` of the installed `@salsita-ai/sdk` decide which packages and which versions. `@clerk/clerk-react` is needed only when the spec sets `useClerk`.
420
+
421
+ ```bash
422
+ pnpm phoenix deps
423
+ pnpm install
424
+ ```
425
+
426
+ - A missing peer is added at the lowest version of the SDK's range, as an exact version, in alphabetical order: type packages (`@types/*`) to `devDependencies`, the others to `dependencies`.
427
+ - A peer declared with a version range whose lowest version falls outside the SDK's range is set to the lowest version of the SDK's range, in the field that declares it. The output says when that is a downgrade.
428
+ - A peer declared with a specifier that is not a version range, such as `workspace:`, `npm:`, `catalog:`, `file:`, `link:` or a git URL, stays as it is.
429
+ - `@salsita-ai/common`, `@salsita-ai/contracts`, `@salsita-ai/platform-project-sdk`, `@salsita-ai/platform-common` and `@salsita-ai/platform-contracts` are removed, because `@salsita-ai/sdk` replaces them. No other entry is removed.
430
+
431
+ Every other part of `package.json` keeps its order and formatting. `phoenix deps` installs nothing: it lists each change and names `pnpm install` as the next step, or says that nothing needed to change. Running it again changes nothing. It reads the spec to learn whether the project uses Clerk, so it stops with the spec's errors when the spec does not parse.
432
+
433
+ This holds for a project on the application-spec pipeline. In a project on the legacy pipeline (see [Current and legacy project tooling](#current-and-legacy-project-tooling)), `phoenix deps` changes nothing and says that `phoenix sync` manages the dependencies.
434
+
399
435
  ### Current and legacy project tooling
400
436
 
401
437
  Use the `phoenix` binary for projects that still use domain-spec generation. The CLI selects a