@salsita-ai/sdk 0.50.0-develop.016963b09e → 0.50.0-develop.08837efd9c

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 (260) hide show
  1. package/dist/application-spec/core/components/component-filter.d.ts +53 -0
  2. package/dist/application-spec/core/components/component-filter.js +1 -0
  3. package/dist/application-spec/core/components/index.d.ts +2 -0
  4. package/dist/application-spec/core/components/index.js +1 -0
  5. package/dist/application-spec/core/components/sdk-code-ref.d.ts +9 -0
  6. package/dist/application-spec/core/components/sdk-code-ref.js +1 -0
  7. package/dist/application-spec/core/enhanced-json-value.d.ts +0 -68
  8. package/dist/application-spec/core/enhanced-json-value.js +1 -1
  9. package/dist/application-spec/core/index.d.ts +1 -0
  10. package/dist/application-spec/core/index.js +1 -1
  11. package/dist/application-spec/core/json-value.d.ts +1 -1
  12. package/dist/application-spec/{core → enhanced-json}/eval-to-constant.d.ts +1 -1
  13. package/dist/application-spec/enhanced-json/index.d.ts +4 -0
  14. package/dist/application-spec/enhanced-json/index.js +1 -0
  15. package/dist/application-spec/enhanced-json/is-enhanced-json-array.d.ts +2 -0
  16. package/dist/application-spec/enhanced-json/is-enhanced-json-array.js +1 -0
  17. package/dist/application-spec/enhanced-json/resolve-enhanced-json-value.d.ts +18 -0
  18. package/dist/application-spec/enhanced-json/resolve-enhanced-json-value.js +1 -0
  19. package/dist/application-spec/enhanced-json/schema-from-value.d.ts +24 -0
  20. package/dist/application-spec/enhanced-json/schema-from-value.js +1 -0
  21. package/dist/application-spec/enhanced-json/stringify-enhanced-json-value.d.ts +14 -0
  22. package/dist/application-spec/enhanced-json/stringify-enhanced-json-value.js +1 -0
  23. package/dist/application-spec/enhanced-json/validate-enhanced-json-value-caps.d.ts +12 -0
  24. package/dist/application-spec/enhanced-json/validate-enhanced-json-value-caps.js +1 -0
  25. package/dist/application-spec/enhanced-json/validate-no-legacy-code-ref.d.ts +13 -0
  26. package/dist/application-spec/enhanced-json/validate-no-legacy-code-ref.js +1 -0
  27. package/dist/application-spec/errors/diagnostic-codes.d.ts +5 -0
  28. package/dist/application-spec/errors/diagnostic-codes.js +1 -1
  29. package/dist/application-spec/errors/diagnostic-messages.d.ts +8 -0
  30. package/dist/application-spec/errors/diagnostic-messages.js +1 -1
  31. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-component-optics.js +4 -4
  32. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-defaults.js +1 -1
  33. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.js +41 -40
  34. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-phx-globals.js +3 -0
  35. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-resources.d.ts +6 -8
  36. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-resources.js +11 -11
  37. package/dist/application-spec/generate-application/code/templates/domain-spec/index.d.ts +1 -1
  38. package/dist/application-spec/generate-application/code/templates/domain-spec/index.js +1 -1
  39. package/dist/application-spec/generate-application/code/templates/domain-spec.js +12 -12
  40. package/dist/application-spec/generate-application/code/templates/globals.js +5 -4
  41. package/dist/application-spec/generate-application/code/templates/skills/phoenix-review-skill.js +8 -2
  42. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +3 -2
  43. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +2 -2
  44. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.d.ts +1 -1
  45. package/dist/application-spec/generate-application/runtime/sections/build-sdk-optic.js +1 -1
  46. package/dist/application-spec/index.d.ts +1 -0
  47. package/dist/application-spec/index.js +1 -1
  48. package/dist/application-spec/parse-application-files/categorize/module-analysis.d.ts +1 -1
  49. package/dist/application-spec/parse-application-files/categorize/module-analysis.js +1 -1
  50. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +16 -3
  51. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
  52. package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.js +1 -1
  53. package/dist/application-spec/parse-application-files/spec/components/component-entry.d.ts +1 -9
  54. package/dist/application-spec/parse-application-files/spec/components/component-entry.js +1 -1
  55. package/dist/application-spec/parse-application-files/spec/components/component-filter.d.ts +1 -54
  56. package/dist/application-spec/parse-application-files/spec/components/component-filter.js +1 -1
  57. package/dist/application-spec/parse-application-files/spec/components/index.d.ts +1 -1
  58. package/dist/application-spec/parse-application-files/spec/components/index.js +1 -1
  59. package/dist/application-spec/parse-application-files/spec/expressions/memo-eval-plan.js +1 -1
  60. package/dist/application-spec/parse-application-files/spec/expressions/user-expressions.js +1 -1
  61. package/dist/application-spec/parse-application-files/spec/model/defaults.js +1 -1
  62. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
  63. package/dist/application-spec/parse-application-files/spec/sections/infra.d.ts +2 -0
  64. package/dist/application-spec/parse-application-files/spec/sections/infra.js +1 -1
  65. package/dist/client/phoenix-api.d.ts +96 -0
  66. package/dist/configurator/application-runtime/extensions/create-configurator-extensions.js +1 -1
  67. package/dist/configurator/application-runtime/extensions/selectors.d.ts +3 -1
  68. package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
  69. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +3 -1
  70. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -1
  71. package/dist/configurator/application-runtime/extensions/systems/drag-and-drop-system/drag-and-drop-system.d.ts +3 -3
  72. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.d.ts +14 -4
  73. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  74. package/dist/configurator/application-runtime/extensions/systems/graphql-system/inject-assistant-lenses.d.ts +11 -0
  75. package/dist/configurator/application-runtime/extensions/systems/graphql-system/inject-assistant-lenses.js +1 -0
  76. package/dist/configurator/application-runtime/extensions/systems/layout-system/layout-system.d.ts +2 -2
  77. package/dist/configurator/application-runtime/extensions/systems/layout-system/layout-system.js +1 -1
  78. package/dist/configurator/common/configurator-interface.d.ts +5 -1
  79. package/dist/configurator/common/configurator-interface.js +1 -1
  80. package/dist/configurator/common/frontend-analytics.d.ts +2 -0
  81. package/dist/configurator/common/frontend-analytics.js +1 -1
  82. package/dist/configurator/configurator-context/configurator-hooks/layout-hooks.d.ts +1 -1
  83. package/dist/configurator/scene/scene-controls/hotspot-drag-handle/HotspotDragHandle.d.ts +1 -1
  84. package/dist/configurator/scene/scene-controls/hotspot-drag-handle/HotspotDragSceneHandle.d.ts +1 -1
  85. package/dist/configurator/scene/scene-entity/dimension-indicators/DimensionIndicator.d.ts +1 -1
  86. package/dist/configurator/scene/scene-entity/dimension-indicators/DimensionIndicatorInternal.d.ts +1 -1
  87. package/dist/configurator/scene/scene-entity/drag-and-drop/shared.d.ts +2 -2
  88. package/dist/configurator/scene/scene-entity/drag-and-drop/use-drag-object.d.ts +1 -1
  89. package/dist/configurator/scene/scene-entity/materials/RemoteReplacedMaterial.js +1 -1
  90. package/dist/configurator/scene/scene-entity/objects/SceneEntityObjectTextDecal.d.ts +1 -1
  91. package/dist/configurator/ui/assistant/AssistantMarkdown.d.ts +1 -1
  92. package/dist/configurator/ui/assistant/AssistantMarkdown.js +1 -1
  93. package/dist/configurator/ui/assistant/AssistantThread.js +1 -1
  94. package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.d.ts +13 -0
  95. package/dist/configurator/ui/assistant/entity-link/AssistantEntityLink.js +1 -0
  96. package/dist/configurator/ui/assistant/entity-link/entity-link-selection.d.ts +22 -0
  97. package/dist/configurator/ui/assistant/entity-link/entity-link-selection.js +1 -0
  98. package/dist/configurator/ui/assistant/entity-link/entity-link-state.d.ts +27 -0
  99. package/dist/configurator/ui/assistant/entity-link/entity-link-state.js +1 -0
  100. package/dist/configurator/ui/assistant/entity-link/entity-link-target.d.ts +5 -0
  101. package/dist/configurator/ui/assistant/entity-link/entity-link-target.js +1 -0
  102. package/dist/configurator/ui/assistant/entity-link/index.d.ts +3 -0
  103. package/dist/configurator/ui/assistant/entity-link/index.js +1 -0
  104. package/dist/configurator/ui/configurator-layout/sidebar-keys/index.d.ts +1 -0
  105. package/dist/configurator/ui/configurator-layout/sidebar-keys/index.js +1 -0
  106. package/dist/configurator/ui/configurator-layout/sidebar-keys/sidebar-keys.d.ts +11 -0
  107. package/dist/configurator/ui/configurator-layout/sidebar-keys/sidebar-keys.js +1 -0
  108. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/DesktopSidebar.d.ts +101 -0
  109. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/DesktopSidebar.js +16 -0
  110. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/index.d.ts +1 -0
  111. package/dist/configurator/ui/configurator-layout/slots/desktop-sidebar/index.js +1 -0
  112. package/dist/configurator/ui/configurator-layout/slots/slots.d.ts +1 -0
  113. package/dist/configurator/ui/configurator-layout/slots/slots.js +1 -1
  114. package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.d.ts +0 -74
  115. package/dist/configurator/ui/configurator-layout/universal/DesktopLayout.js +5 -20
  116. package/dist/configurator/ui/legacy/layout/steps/StepsNavigation.d.ts +2 -2
  117. package/dist/configurator/ui/phoenix-layout-elements/header/common/step-navigation/StepsNavigation.d.ts +2 -2
  118. package/dist/docs/dimensions/3d-scene-integration/dimension-indicators.mdx +2 -2
  119. package/dist/docs/dimensions/3d-scene-integration/editable-angle-indicator.mdx +1 -1
  120. package/dist/docs/dimensions/3d-scene-integration/editable-distance-dimension-indicator.mdx +1 -1
  121. package/dist/docs/dimensions/3d-scene-integration/list-selector-dimension-indicator.mdx +1 -1
  122. package/dist/docs/drag-and-drop/drag-handle.mdx +1 -1
  123. package/dist/docs/drag-and-drop/hotspot-handle.mdx +1 -1
  124. package/dist/docs/drag-and-drop/planes.mdx +1 -1
  125. package/dist/docs/drag-and-drop/rotatable.mdx +2 -2
  126. package/dist/docs/index.json +32 -1
  127. package/dist/docs/layouts/custom-layout.mdx +981 -0
  128. package/dist/docs/layouts/header/fixed.mdx +2 -2
  129. package/dist/docs/layouts/header/floating.mdx +2 -2
  130. package/dist/docs/layouts/sidebar/in-a-custom-layout.mdx +380 -0
  131. package/dist/docs/other-features/client-side-rendering/declarative.mdx +1 -1
  132. package/dist/docs/other-features/transformers.mdx +4 -0
  133. package/dist/docs/phoenix/configurator-interface.mdx +8 -2
  134. package/dist/docs/phoenix/project-structure.mdx +2 -1
  135. package/dist/docs/phoenix/testing.mdx +140 -0
  136. package/dist/docs/phoenix/webhook-membership.mdx +10 -9
  137. package/dist/docs/phoenix/webhooks.mdx +1 -1
  138. package/dist/domain/application/assistant/assistant-fields.d.ts +12 -0
  139. package/dist/domain/application/assistant/assistant-fields.js +1 -0
  140. package/dist/domain/application/assistant/assistant-manifest.d.ts +9 -1
  141. package/dist/domain/application/assistant/assistant-resolved-manifest.d.ts +38 -2
  142. package/dist/domain/application/assistant/assistant-resolved-manifest.js +1 -1
  143. package/dist/domain/application/assistant/build-assistant-lenses.d.ts +14 -0
  144. package/dist/domain/application/assistant/build-assistant-lenses.js +5 -0
  145. package/dist/domain/application/assistant/build-assistant-manifest.js +1 -1
  146. package/dist/domain/application/assistant/create-assistant-execution-schema.d.ts +32 -0
  147. package/dist/domain/application/assistant/create-assistant-execution-schema.js +1 -0
  148. package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
  149. package/dist/domain/application/assistant/index.d.ts +6 -1
  150. package/dist/domain/application/assistant/index.js +1 -1
  151. package/dist/domain/application/assistant/session-setup/AssistantSetupHandler.d.ts +20 -0
  152. package/dist/domain/application/assistant/session-setup/AssistantSetupHandler.js +1 -0
  153. package/dist/domain/application/assistant/session-setup/apply-assistant-setup.d.ts +10 -0
  154. package/dist/domain/application/assistant/session-setup/apply-assistant-setup.js +1 -0
  155. package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.d.ts +48 -0
  156. package/dist/domain/application/assistant/session-setup/assistant-setup-manifest.js +1 -0
  157. package/dist/domain/application/assistant/session-setup/create-session-assistant.d.ts +15 -0
  158. package/dist/domain/application/assistant/session-setup/create-session-assistant.js +1 -0
  159. package/dist/domain/application/assistant/session-setup/index.d.ts +4 -0
  160. package/dist/domain/application/assistant/session-setup/index.js +1 -0
  161. package/dist/domain/application/configurator-builder.d.ts +1 -1
  162. package/dist/domain/application/configurator-builder.js +1 -1
  163. package/dist/domain/application/index.d.ts +0 -1
  164. package/dist/domain/application/index.js +1 -1
  165. package/dist/domain/core/expression/constant-expressions.d.ts +16 -8
  166. package/dist/domain/core/invariant/violation.d.ts +50 -2
  167. package/dist/domain/core/invariant/violation.js +1 -1
  168. package/dist/domain/domain-runtime/access/selectors.d.ts +9 -0
  169. package/dist/domain/domain-runtime/access/selectors.js +1 -1
  170. package/dist/domain/domain-runtime/access/types.d.ts +2 -0
  171. package/dist/domain/domain-runtime/access/types.js +1 -1
  172. package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
  173. package/dist/domain/domain-runtime/domain-context/types.d.ts +4 -1
  174. package/dist/domain/domain-runtime/domain-runtime.d.ts +16 -0
  175. package/dist/domain/domain-runtime/errors/implementation-error-collector.d.ts +19 -0
  176. package/dist/domain/domain-runtime/errors/implementation-error-collector.js +1 -0
  177. package/dist/domain/domain-runtime/errors/implementation-error.d.ts +46 -0
  178. package/dist/domain/domain-runtime/errors/implementation-error.js +1 -0
  179. package/dist/domain/domain-runtime/errors/implementation-errors.d.ts +13 -0
  180. package/dist/domain/domain-runtime/errors/implementation-errors.js +1 -0
  181. package/dist/domain/domain-runtime/errors/index.d.ts +4 -0
  182. package/dist/domain/domain-runtime/errors/index.js +1 -0
  183. package/dist/domain/domain-runtime/errors/to-implementation-errors.d.ts +10 -0
  184. package/dist/domain/domain-runtime/errors/to-implementation-errors.js +1 -0
  185. package/dist/domain/domain-runtime/index.d.ts +1 -0
  186. package/dist/domain/domain-runtime/index.js +1 -1
  187. package/dist/domain/domain-runtime/spec/initialize.d.ts +11 -0
  188. package/dist/domain/domain-runtime/spec/initialize.js +1 -1
  189. package/dist/domain/domain-runtime/spec/module-checks/project-modules.d.ts +8 -1
  190. package/dist/domain/domain-runtime/spec/module-checks/project-modules.js +1 -1
  191. package/dist/domain/domain-runtime/spec/module-checks/resolve-action-modules.js +1 -1
  192. package/dist/domain/domain-runtime/spec/module-checks/resolve-expression-modules.js +1 -1
  193. package/dist/domain/domain-runtime/spec/module-checks/resolve-imported-transformers.js +1 -1
  194. package/dist/domain/domain-runtime/spec/module-checks/resolve-invariant-modules.js +1 -1
  195. package/dist/domain/extensions/canvas-config.d.ts +1 -1
  196. package/dist/domain/extensions/client-side-image.d.ts +2 -2
  197. package/dist/domain/extensions/client-side-image.js +1 -1
  198. package/dist/domain/extensions/common/angle-indicator-schema.d.ts +2 -2
  199. package/dist/domain/extensions/common/dimension-indicator-schema.d.ts +2 -2
  200. package/dist/domain/extensions/editable-angle-indicator.d.ts +1 -1
  201. package/dist/domain/extensions/editable-distance-dimension-indicator.d.ts +1 -1
  202. package/dist/domain/extensions/editable-offset-indicator.d.ts +1 -1
  203. package/dist/domain/extensions/editable-offset-indicator.js +1 -1
  204. package/dist/domain/extensions/horizontal-tabs.d.ts +2 -2
  205. package/dist/domain/extensions/list-selector-dimension-indicator.d.ts +1 -1
  206. package/dist/domain/extensions/navigation-steps.d.ts +2 -2
  207. package/dist/domain/extensions/offset-indicator.js +1 -1
  208. package/dist/domain/extensions/rotation-handle.d.ts +2 -2
  209. package/dist/domain/extensions/save-template-thumbnail.d.ts +2 -2
  210. package/dist/domain/extensions/save-template-thumbnail.js +1 -1
  211. package/dist/domain/mocks/create-mock-domain-runtime.d.ts +9 -0
  212. package/dist/domain/mocks/create-mock-domain-runtime.js +1 -1
  213. package/dist/domain/mocks/create-mock-domain.js +1 -1
  214. package/dist/domain/mocks/create-test-application-config.d.ts +59 -0
  215. package/dist/domain/mocks/create-test-application-config.js +1 -0
  216. package/dist/domain/mocks/index.d.ts +1 -0
  217. package/dist/domain/mocks/index.js +1 -1
  218. package/dist/domain/system-components/application-config.d.ts +2 -2
  219. package/dist/domain/system-components/collision-box-geometry.d.ts +4 -2
  220. package/dist/domain/system-components/collision-geometry.d.ts +4 -2
  221. package/dist/domain/system-components/collision-point-geometry.d.ts +4 -2
  222. package/dist/domain/system-components/common/material-override-schema.d.ts +2 -2
  223. package/dist/domain/system-components/constraint.d.ts +10 -23
  224. package/dist/domain/system-components/drag-handle.d.ts +1 -1
  225. package/dist/domain/system-components/hotspot-drag-handle.d.ts +1 -1
  226. package/dist/domain/system-components/material-swatch.js +1 -1
  227. package/dist/domain/system-components/scene-entity-material-override.d.ts +1 -1
  228. package/dist/domain/system-components/scene-entity-object-material-override.d.ts +1 -1
  229. package/dist/domain/system-components/scene-entity-object-text-decal.d.ts +1 -1
  230. package/dist/domain/system-components/scene-entity-object-transimissive-material-override.d.ts +1 -1
  231. package/dist/domain/system-components/scene-entity-transimissive-material-override.d.ts +1 -1
  232. package/dist/editor/mocks/EditorMockContext.js +1 -1
  233. package/dist/legacy/domain-cli/gen/configurator-builder.js +13 -12
  234. package/dist/legacy/domain-cli/gen/constant-expressions.js +1 -1
  235. package/dist/legacy/domain-cli/utils/cache.d.ts +1 -1
  236. package/dist/legacy/domain-cli/utils/cache.js +1 -1
  237. package/dist/legacy/domain-spec/__generated/domain-schema.d.ts +16 -5
  238. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/claude-md.d.ts +1 -1
  239. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/cursor-rules.d.ts +1 -1
  240. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.d.ts +1 -1
  241. package/dist/legacy/phoenix-cli/project-gen/generators/file-templates/agents/shared-sdk-content.js +1 -1
  242. package/dist/react-sdk/application-runtime/hooks/use-access-service.d.ts +2 -0
  243. package/dist/react-sdk/application-runtime/mocks/create-mock-application-runtime.js +1 -1
  244. package/dist/react-sdk/application-runtime/routing/access-service.d.ts +1 -0
  245. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +17 -0
  246. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.js +1 -1
  247. package/dist/react-sdk/domain-context/index.d.ts +1 -1
  248. package/dist/react-sdk/domain-context/index.js +1 -1
  249. package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.d.ts +6 -0
  250. package/dist/react-sdk/domain-context/system-hooks/navigation-hooks.js +1 -1
  251. package/dist/react-sdk/domain-controls/hooks/use-angle-dimension.d.ts +1 -1
  252. package/dist/ui-sdk/theme/types.d.ts +1 -1
  253. package/dist/webhook/builders/webhook-builder.js +1 -1
  254. package/package.json +3 -3
  255. package/schema/domain-spec.json +209 -16
  256. package/dist/domain/application/resource-builder.d.ts +0 -13
  257. package/dist/domain/application/resource-builder.js +0 -1
  258. /package/dist/application-spec/{core → enhanced-json}/eval-code-uses-self.d.ts +0 -0
  259. /package/dist/application-spec/{core → enhanced-json}/eval-code-uses-self.js +0 -0
  260. /package/dist/application-spec/{core → enhanced-json}/eval-to-constant.js +0 -0
@@ -1,30 +1,31 @@
1
- import{P as e,match as t}from"ts-pattern";import{Imports as a}from"./imports.js";export const generateConfigBuilder=(i,n,o,s,r,d,l,m,p,h,c,u,g)=>{let y=[],C=new a("./configurator-builder.js",g);C.importMembers("./application-types.js","PrefetchedFinalizeData","FinalizeData","FinalizeResult","NavigationState","ViewState","ToolState","ExportState","CallbackData","AdminNavigationState","AdminViewState","ApplicationVersion","PublishedDataHash","$dataSpec");let w=(a=>{if(!a||0===a.length)return"";let i=[];for(let n of a){let a=t(n).with({type:"ConfigurationLink"},e=>` .addLink({
1
+ import{P as e,match as t}from"ts-pattern";import{Imports as a}from"./imports.js";export const generateConfigBuilder=(i,n,o,s,r,d,m,l,p,h,c,u,g)=>{let y=[],w=new a("./configurator-builder.js",g);w.importMembers("./application-types.js","PrefetchedFinalizeData","FinalizeData","FinalizeResult","NavigationState","ViewState","ToolState","ExportState","CallbackData","AdminNavigationState","AdminViewState","ApplicationVersion","PublishedDataHash","$dataSpec");let C=(a=>{if(!a||0===a.length)return"";let i=[],n=new Set;for(let o of a){if(n.has(o.name))throw Error(`Resource with name ${o.name} already exists!`);n.add(o.name);let a=t(o).with({type:"ConfigurationLink"},e=>` {
2
2
  type: 'ConfigurationLink',
3
3
  name: '${e.name}',
4
- })`).with({type:"Csv"},e=>{let t=e.s3Key?`,
5
- s3Key: '${e.s3Key}'`:"";return` .addCsv({
4
+ },`).with({type:"Csv"},e=>{let t=e.s3Key?`,
5
+ s3Key: '${e.s3Key}'`:"";return` {
6
6
  type: 'Csv',
7
7
  name: '${e.name}'${t},
8
- })`}).with({type:"Pdf"},e=>{let t=e.s3Key?`,
9
- s3Key: '${e.s3Key}'`:"";return` .addPdf({
8
+ },`}).with({type:"Pdf"},e=>{let t=e.s3Key?`,
9
+ s3Key: '${e.s3Key}'`:"";return` {
10
10
  type: 'Pdf',
11
11
  name: '${e.name}'${t},
12
- })`}).with({type:"Image",clientGenerated:!0,s3Key:e.string},e=>` .addClientGeneratedImage({
12
+ },`}).with({type:"Image",clientGenerated:!0,s3Key:e.string},e=>` {
13
13
  type: 'Image',
14
14
  name: '${e.name}',
15
15
  clientGenerated: true,
16
16
  s3Key: '${e.s3Key}',
17
- })`).with({type:"Image",exists:!0,url:e.string},e=>` .addExistingImage({
17
+ },`).with({type:"Image",exists:!0,url:e.string},e=>` {
18
18
  type: 'Image',
19
19
  name: '${e.name}',
20
20
  exists: true,
21
21
  url: '${e.url}',
22
- })`).with({type:"Image"},e=>` .addGeneratedImage({
22
+ },`).with({type:"Image"},e=>` {
23
23
  type: 'Image',
24
24
  name: '${e.name}',
25
25
  s3Key: '${e.s3Key}',
26
- })`).exhaustive();i.push(a)}return`const generatedResources = new ResourceBuilder()${i.join("\n")}
27
- .build()`})(s);if(w&&y.push(w),y.push(`
26
+ },`).exhaustive();i.push(a)}return`const generatedResources = [
27
+ ${i.join("\n")}
28
+ ] as const`})(s);if(C&&y.push(C),y.push(`
28
29
  // The generated optics reach the builder as untyped project modules, so the entity and data types
29
30
  // they used to carry by inference are stated here.
30
31
  export const generatedConfiguratorBuilder = new ConfiguratorBuilder<
@@ -55,7 +56,7 @@ import{P as e,match as t}from"ts-pattern";import{Imports as a}from"./imports.js"
55
56
  .withDataSpec($dataSpec)
56
57
  .withPublishedDataHash(PublishedDataHash)
57
58
  .withVersion(ApplicationVersion)${c?`
58
- .withTextLanguages(${JSON.stringify(c)})`:""}`),o&&y.push(`.withWebComponentTag('${o}')`),i&&(y.push(".withPresets(generatedPresets)"),C.importMembers("./presets.js","generatedPresets")),n&&(y.push(".withAdminPresets(generatedAdminPresets)"),C.importMembers("./admin-presets.js","generatedAdminPresets")),w&&y.push(".withResources(generatedResources)"),r?.canCreate&&y.push(`.withAcl({ canCreate: [${r.canCreate.map(e=>`'${e}'`).join(", ")}] })`),d&&y.push(".withAdminRelease(true)"),void 0!==l||void 0!==m||void 0!==p){let e=[];void 0!==l&&e.push(`appLoader: '${l}'`),void 0!==m&&e.push(`preview: '${m}'`),void 0!==p&&e.push(`alwaysExpand: ${p}`),e.length>0&&y.push(`.withUi({ ${e.join(", ")} })`)}if(h){let e=[];if(void 0!==h.baseResourcesUrl&&e.push(`baseResourcesUrl: ${JSON.stringify(h.baseResourcesUrl)}`),void 0!==h.prefetchTextureUrls){let t=h.prefetchTextureUrls.map(e=>JSON.stringify(e)).join(", ");e.push(`prefetchTextureUrls: [${t}]`)}void 0!==h.deploymentQueryDisabled&&e.push(`deploymentQueryDisabled: ${h.deploymentQueryDisabled}`),e.length>0&&y.push(`.withResourcesConfig({ ${e.join(", ")} })`)}if(u&&Object.keys(u).length>0){let e=JSON.stringify(u);y.push(`.withChunks(${e})`)}let b=["ConfiguratorBuilder"];return w&&b.push("ResourceBuilder"),C.importMembers("@salsita-ai/sdk/domain",...b),C.importMembers("./components/index.js","generatedComponents"),C.importMembers("./admin-components/index.js","adminGeneratedComponents"),C.importMembers("./implementation.js","createRecipe","implementCustomInvariants","attachComponent","implementCustomExpressions"),C.importMembers("./admin-implementation.js","createAdminRecipe","implementCustomAdminInvariants","attachAdminComponent","implementAdminCustomExpressions","createMapPublishedRevisionDataHandler","createMapPublishedChunkedDataHandler","createDataRowValidatorHandler","createSheetValidatorHandler"),y.push(`
59
+ .withTextLanguages(${JSON.stringify(c)})`:""}`),o&&y.push(`.withWebComponentTag('${o}')`),i&&(y.push(".withPresets(generatedPresets)"),w.importMembers("./presets.js","generatedPresets")),n&&(y.push(".withAdminPresets(generatedAdminPresets)"),w.importMembers("./admin-presets.js","generatedAdminPresets")),C&&y.push(".withResources(generatedResources)"),r?.canCreate&&y.push(`.withAcl({ canCreate: [${r.canCreate.map(e=>`'${e}'`).join(", ")}] })`),d&&y.push(".withAdminRelease(true)"),void 0!==m||void 0!==l||void 0!==p){let e=[];void 0!==m&&e.push(`appLoader: '${m}'`),void 0!==l&&e.push(`preview: '${l}'`),void 0!==p&&e.push(`alwaysExpand: ${p}`),e.length>0&&y.push(`.withUi({ ${e.join(", ")} })`)}if(h){let e=[];if(void 0!==h.baseResourcesUrl&&e.push(`baseResourcesUrl: ${JSON.stringify(h.baseResourcesUrl)}`),void 0!==h.prefetchTextureUrls){let t=h.prefetchTextureUrls.map(e=>JSON.stringify(e)).join(", ");e.push(`prefetchTextureUrls: [${t}]`)}void 0!==h.deploymentQueryDisabled&&e.push(`deploymentQueryDisabled: ${h.deploymentQueryDisabled}`),e.length>0&&y.push(`.withResourcesConfig({ ${e.join(", ")} })`)}if(u&&Object.keys(u).length>0){let e=JSON.stringify(u);y.push(`.withChunks(${e})`)}return w.importMembers("@salsita-ai/sdk/domain","ConfiguratorBuilder"),w.importMembers("./components/index.js","generatedComponents"),w.importMembers("./admin-components/index.js","adminGeneratedComponents"),w.importMembers("./implementation.js","createRecipe","implementCustomInvariants","attachComponent","implementCustomExpressions"),w.importMembers("./admin-implementation.js","createAdminRecipe","implementCustomAdminInvariants","attachAdminComponent","implementAdminCustomExpressions","createMapPublishedRevisionDataHandler","createMapPublishedChunkedDataHandler","createDataRowValidatorHandler","createSheetValidatorHandler"),y.push(`
59
60
  import * as AdminEnhancenModel from './admin-enhanced-model.js'
60
61
  import * as AdminModel from './admin-model/index.js'
61
62
  import * as EnhancedModel from './enhanced-model.js'
@@ -101,4 +102,4 @@ import{P as e,match as t}from"ts-pattern";import{Imports as a}from"./imports.js"
101
102
  createSheetValidatorHandler: createSheetValidatorHandler,
102
103
  },
103
104
  }
104
- `),{modulePath:C.targetModule,content:["/* eslint-disable */",C.toString(),...y].join("\n")}};
105
+ `),{modulePath:w.targetModule,content:["/* eslint-disable */",w.toString(),...y].join("\n")}};
@@ -1,2 +1,2 @@
1
- import{DOMAIN_SDK_MODULE as t}from"./imports.js";export const generateConstantExpressions=(n,s)=>(n.importMembers(t,"createConstantExpressionFactory"),n.importMembers(s?"./admin-model/index.js":"./model/index.js","AnyDomainEntity","Aliases","RootEntity"),n.importMembers(s?"./admin-enhanced-model.js":"./enhanced-model.js","constants"),`export const constantExpressions = createConstantExpressionFactory<AnyDomainEntity, RootEntity, PublishedData, SessionData, FrontendData, Aliases>()(constants)
1
+ import{DOMAIN_SDK_MODULE as s}from"./imports.js";export const generateConstantExpressions=(t,n)=>(t.importMembers(s,"createConstantExpressionFactory"),t.importMembers(n?"./admin-enhanced-model.js":"./enhanced-model.js","constants"),`export const constantExpressions = createConstantExpressionFactory()(constants)
2
2
  `);
@@ -1,3 +1,3 @@
1
- export declare const cacheVersion = 764;
1
+ export declare const cacheVersion = 767;
2
2
  export declare const needsRebuild: (fileContents: string[], outputDirectory: string) => Promise<boolean>;
3
3
  export declare const writeCacheInfo: (fileContents: string[], outputDirectory: string) => Promise<void>;
@@ -1 +1 @@
1
- import{createHash as e}from"crypto";import{existsSync as r}from"fs";import{readFile as t}from"fs/promises";import{isEqualArray as o}from"@salsita-ai/common/utils";import{writeFormatted as i}from"../gen/write-formatted.js";export const cacheVersion=764;let s=r=>({version:764,files:r.map(r=>e("md5").update(r).digest("base64")).sort()});export const needsRebuild=async(e,i)=>{let a=`${i}/cache.json`;if(!r(a))return!0;try{let r=JSON.parse(await t(a,"utf-8")),i=s(e);return 764!==r.version||!o(r.files,i.files)}catch(e){return console.error("Failed to read cache file, forcing rebuild",e),!0}};export const writeCacheInfo=async(e,r)=>{let t=`${r}/cache.json`,o=s(e);await i(t,JSON.stringify(o,null,2))};
1
+ import{createHash as e}from"crypto";import{existsSync as r}from"fs";import{readFile as t}from"fs/promises";import{isEqualArray as o}from"@salsita-ai/common/utils";import{writeFormatted as i}from"../gen/write-formatted.js";export const cacheVersion=767;let s=r=>({version:767,files:r.map(r=>e("md5").update(r).digest("base64")).sort()});export const needsRebuild=async(e,i)=>{let a=`${i}/cache.json`;if(!r(a))return!0;try{let r=JSON.parse(await t(a,"utf-8")),i=s(e);return 767!==r.version||!o(r.files,i.files)}catch(e){return console.error("Failed to read cache file, forcing rebuild",e),!0}};export const writeCacheInfo=async(e,r)=>{let t=`${r}/cache.json`,o=s(e);await i(t,JSON.stringify(o,null,2))};
@@ -4232,13 +4232,13 @@ export interface DomainSpecification {
4232
4232
  labelPrefixFontColor?: (string | number) | ReadEnhancement;
4233
4233
  targetEntityOffsetAnchors: string[] | ReadEnhancement;
4234
4234
  targetReferenceOffsetAnchors: string[] | ReadEnhancement;
4235
- referenceEntityIds?: string[] | ReadEnhancement;
4235
+ referenceEntityIds?: (string[] | null) | ReadEnhancement;
4236
4236
  directionVector: {
4237
4237
  x?: EnhancedNumberRead;
4238
4238
  y?: EnhancedNumberRead;
4239
4239
  z?: EnhancedNumberRead;
4240
4240
  } | ReadEnhancement;
4241
- directionVectorRelativeToEntityId?: EnhancedStringRead;
4241
+ directionVectorRelativeToEntityId?: (string | null) | ReadEnhancement;
4242
4242
  maxDistance?: (number | null) | ReadEnhancement;
4243
4243
  minDistance?: (number | null) | ReadEnhancement;
4244
4244
  maxPerpendicularDistance?: (number | null) | ReadEnhancement;
@@ -4900,13 +4900,13 @@ export interface DomainSpecification {
4900
4900
  labelPrefixFontColor?: (string | number) | ReadEnhancement;
4901
4901
  targetEntityOffsetAnchors: string[] | ReadEnhancement;
4902
4902
  targetReferenceOffsetAnchors: string[] | ReadEnhancement;
4903
- referenceEntityIds?: string[] | ReadEnhancement;
4903
+ referenceEntityIds?: (string[] | null) | ReadEnhancement;
4904
4904
  directionVector: {
4905
4905
  x?: EnhancedNumberRead;
4906
4906
  y?: EnhancedNumberRead;
4907
4907
  z?: EnhancedNumberRead;
4908
4908
  } | ReadEnhancement;
4909
- directionVectorRelativeToEntityId?: EnhancedStringRead;
4909
+ directionVectorRelativeToEntityId?: (string | null) | ReadEnhancement;
4910
4910
  maxDistance?: (number | null) | ReadEnhancement;
4911
4911
  minDistance?: (number | null) | ReadEnhancement;
4912
4912
  maxPerpendicularDistance?: (number | null) | ReadEnhancement;
@@ -5307,7 +5307,18 @@ export interface DomainSpecification {
5307
5307
  violations: {
5308
5308
  type: EnhancedStringRead;
5309
5309
  severity: ('fatal' | 'fixable' | 'warning' | 'notice') | ReadEnhancement;
5310
- message?: EnhancedStringRead;
5310
+ message?: (string | {
5311
+ id: EnhancedStringRead;
5312
+ comment?: EnhancedStringRead;
5313
+ message?: EnhancedStringRead;
5314
+ values?: {
5315
+ [k: string]: unknown;
5316
+ } | ReadEnhancement;
5317
+ } | {
5318
+ $lang: {
5319
+ [k: string]: EnhancedStringRead;
5320
+ } | ReadEnhancement;
5321
+ }) | ReadEnhancement;
5311
5322
  controlViolationPriority?: EnhancedNumberRead;
5312
5323
  }[] | ReadEnhancement;
5313
5324
  $filter?: ComponentSystemFilter;
@@ -1,2 +1,2 @@
1
1
  export declare const mergeClaudeMdContent: (existingContent: string | undefined) => string;
2
- export declare const claudeMdFile = "[PHOENIX-SDK-START]\n## Phoenix Configurator Project\n\nDeclarative 3D product configurator built with Phoenix SDK. Domain model defined in YAML, custom logic in TypeScript.\n\n## Build Commands\n- `pnpm phoenix build` \u2014 Full production build\n- `pnpm phoenix dev` \u2014 Development mode with hot reload\n- `pnpm phoenix sync` \u2014 Sync generated files without full build\n\n## Dev Logs\n- `pnpm phoenix dev` writes all logs to `.phoenix/phoenix-dev.log`\n- Contains: spec parse errors, build errors, browser runtime errors, file watcher events\n- After making changes, always check the log for errors: `tail -50 .phoenix/phoenix-dev.log` or `grep ERROR .phoenix/phoenix-dev.log`\n- Rotated automatically at 10MB (`.log.1`, `.log.2` are older rotations)\n\n## Project Structure\n- `spec/` \u2014 Domain YAML specs (entities, relations, expressions, invariants, components, application config)\n- `src/expressions/` \u2014 Computed/derived entity properties (`phx.domain.implementCustomExpressions()`)\n- `src/invariants/` \u2014 Business rule constraints (`phx.domain.implementCustomInvariants()`)\n- `src/transformers/` \u2014 Automatic state fixers (`phx.frontend.transformerBuilder`)\n- `src/components/` \u2014 ECS system components (`phx.domain.attachComponent.withEntity()`)\n- `src/elements/` \u2014 Page-level React components (`phx.frontend.createCustomPhoenixLayoutElement()`)\n - A layout element named `ConfiguratorLayout` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount `LayoutSlots.SharedCanvas` (from `@salsita-ai/sdk/configurator`) in it, or the app loader stays on screen, and call `useSceneSafeArea()` (same import) with its `containerRef` on the element covering the whole canvas and its `safeAreaRef` on the region the layout's UI leaves free, so the camera frames the scene there\n- `src/handlers/` \u2014 Event & lifecycle handlers\n- `src/webhooks/` \u2014 Server-side webhook handlers (`phx.webhooks.*Builder`)\n- `src/migrations/` \u2014 Schema version migrations (v*.ts)\n- `src/locales/` \u2014 Locale catalogs (authored .po sources; compiled .ts, do not edit)\n- `src/admin/` \u2014 Admin interface (mirrors main src/ structure)\n- `src/_shared/` \u2014 Shared utilities (NOT auto-imported, requires explicit imports)\n- `.phoenix/` \u2014 Auto-generated files (DO NOT EDIT)\n- `public/` \u2014 Static assets (3D models, textures, images, HDRI maps, fonts)\n- `assets/` \u2014 Uploadable resources (PDF templates, email assets)\n\n## Architecture Principles\n- YAML-first: 99% of configuration in spec/*.yaml, custom code is last resort\n- ECS pattern: entities (domain objects) + components (behavior/UI) + systems (SDK runtime)\n- Reactive state: immutable domain state flows through RxJS pipelines\n- Data binding: `$read` (read-only), `$write` (write-only), `$bind` (bidirectional) connect components to domain\n- memoEval: all component implementations must use memoEval for stable object references\n\n## Key Patterns\n- Expressions = computed properties on entities (prefix: `$`), implemented per-entity in src/expressions/\n- Invariants = validation rules returning violations, static or dynamic\n- Transformers = auto-fixers maintaining consistency after state changes\n- Components defined in YAML with `$read`/`$bind` bindings, or custom in src/components/ using attachComponent builder\n- Webhooks = server-side finalization tasks (PDF, email, CSV, image rendering)\n- Filters = contextual component activation via navigationStates, viewStates, modes, selectedEntityIds\n\n## File Conventions\n- Components: PascalCase (.tsx)\n- Utilities: kebab-case (.ts)\n- Expressions: entity-name.ts\n- Migrations: v*.ts (sequential)\n- Specs: kebab-case.yaml\n- Underscore folders (_shared/, _utils/) are NOT auto-imported\n\n## Export Rules\nAll files in src/expressions/, src/invariants/, src/transformers/, src/components/, src/handlers/, src/webhooks/ MUST use default exports. Can be a single item or an array. Named exports are ignored by the SDK auto-import system.\n\n## Webhook Membership\n- User-authored components, admin components, and handlers are frontend-only by default.\n- A handler that registers `createMapPublishedRevisionDataHandler`, `createMapPublishedChunkedDataHandler`, `createDataRowValidatorHandler`, or `createSheetValidatorHandler` is included in the webhook automatically.\n- To include another component or handler in the webhook, put `'use webhook'` as its first statement (leading comments are allowed).\n- A webhook-included file and its runtime local-import closure must not import browser SDK entrypoints (`application`, `admin`, `configurator`, `editor`, `react`, `ui`) or style/font/image assets. Spec parsing reports the unsafe import and inclusion reason as a diagnostic.\n- Keep browser rendering in an unpinned file. Move shared server-safe logic into a separate module when both frontend and webhook code need it.\n\n## Do Not Edit\n- `.phoenix/` directory \u2014 completely regenerated on each build\n- `tsconfig.json`, `eslint.config.js`, `prettier.config.js`, `.prettierignore`, `.linguirc`, `.nvmrc`\n- `src/locales/` .ts files \u2014 compiled from .po files\n\n## Code Review\nUse `/review` command to review code changes before committing.\n\n## SDK Documentation\n\nAlways search SDK docs for relevant examples before implementing Phoenix features.\n\n### Commands\n- `pnpm phoenix docs` \u2014 Full documentation index with descriptions\n- `pnpm phoenix docs -s <term>` \u2014 Search all doc content and metadata (case-insensitive)\n- `pnpm phoenix docs --dir` \u2014 Print the absolute docs directory for grep or ripgrep\n- `pnpm phoenix docs -r <path>` \u2014 Read specific doc (raw text to stdout)\n- `pnpm phoenix docs -c <category>` \u2014 List docs in a category\n- `pnpm phoenix docs -l` \u2014 List all doc paths with titles\n\n### 3D Asset Inspection\n\nRun `pnpm phoenix inspect:assets` to discover all glTF/GLB files in `public/` and get a summary table. Use `--file <path>` for detailed single-file inspection.\n\n**When to use:** before writing YAML/code that references objectName, materialsToOverride, morphTargetInfluences, or object positioning.\n\n**What it shows per node:**\n- Name, type (Mesh/Light/Camera/Empty), children\n- Transform: `pos=`, `rot=`, `scale=` (only non-default values shown)\n- Per-node morph targets: `morphs=Width,Height`\n- Bounding box: `bounds=WxHxD` (width x height x depth in meters)\n- Origin placement: `origin=center`, `bottom-center`, `top-center`, `bottom-corner`, etc. with numerical offset\n\n**Use cases:**\n- Find exact node names for `objectName` in scene entity components\n- Find material names for `materialsToOverride`\n- Find morph target names for `morphTargetInfluences`\n- Check model dimensions (bounds) for positioning, dimension indicators, or invariants\n- Check origin placement to understand how models anchor (center vs bottom-center)\n- Use `--json` for programmatic access to all data\n\n**Flags:** `--objects`, `--materials`, `--morphs`, `--animations`, `--json`\n\n### Screenshot CLI\n\nCapture 3D canvas screenshots from a running dev server via `pnpm phoenix screenshot`.\n\n**Prerequisites:**\n1. `phoenix dev` must be running (starts the WebSocket server on port 3020)\n2. Configurator must be open in a browser (the browser does the actual rendering)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (default: `./screenshot.png`)\n- `--width, -w` \u2014 Width in pixels (default: 1920)\n- `--height` \u2014 Height in pixels (default: 1080)\n- `--format, -f` \u2014 Image format: PNG or JPEG (default: PNG)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example workflow:**\n1. Start dev server: `pnpm phoenix dev`\n2. Open configurator in browser (or via Playwright MCP)\n3. Take screenshot: `pnpm phoenix screenshot -o ./render.png -w 2560 --height 1440`\n\n**Use cases:** visual regression testing, generating product images, debugging 3D renders\n\n### Inspect: State\n\nGet the current editor runtime state as JSON via `pnpm phoenix inspect:state`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--sections, -s` \u2014 Comma-separated: entities, navigation, validation (default: all)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example:** `pnpm phoenix inspect:state -o ./state.json -s entities,navigation`\n\n**Lifecycle status:** Always included in response. Shows which systems are ready:\n- `domainLoaded` \u2014 domain data loaded\n- `domainContextReady` \u2014 domain context initialized (entities available)\n- `configuratorReady` \u2014 3D configurator initialized\n- `sessionAuthenticated` \u2014 session service active\n- `editorMode` \u2014 editor mode enabled\n\n**Tips:** Use `--sections` to limit payload size. Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:state | head -50`).\n\n**Use cases:** AI agent context, debugging entity state, inspecting navigation/validation\n\n### Inspect: Data\n\nGet the current editor context data as JSON via `pnpm phoenix inspect:data`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** publishedData, frontendData, backendData, sessionData, accessData, webComponentProperties\n\n**Example:** `pnpm phoenix inspect:data -o ./data.json`\n\n**Tips:** Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:data | head -30`).\n\n**Use cases:** AI agent context, debugging published/session/access data\n\n### Inspect: Scene\n\nGet the current Three.js scene graph as JSON via `pnpm phoenix inspect:scene`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** Recursive scene tree with per-node: name, type, visible, position, rotation, scale, userData (entityId), and for meshes: geometry name, bounding box, material properties (color, metalness, roughness, opacity, textures), morph target influences. Lights include color, intensity, and type-specific properties.\n\n**Example:** `pnpm phoenix inspect:scene -o ./scene.json`\n\n**Tips:** Scene graphs can be large. Pipe through `head`/`tail` for partial output.\n\n**Use cases:** AI agent context, debugging 3D scene layout, inspecting materials and lighting\n\n### Key Docs\n- `docs/phoenix/getting-started.mdx` \u2014 Setup, prerequisites, first project\n- `docs/phoenix/quickstart.mdx` \u2014 End-to-end tutorial building a configurator\n- `docs/phoenix/domain-model.mdx` \u2014 Entities, attributes, relations, specs\n- `docs/phoenix/components.mdx` \u2014 ECS pattern, YAML components, custom components\n- `docs/phoenix/project-structure.mdx` \u2014 Files, folders, conventions\n- `docs/phoenix/best-practices.mdx` \u2014 YAML-first, code patterns, common pitfalls\n- `docs/phoenix/state-management.mdx` \u2014 Reactive state, RxJS pipelines, data flow\n- `docs/phoenix/expression-context.mdx` \u2014 Expression API, context object, helpers\n- `docs/phoenix/webhooks.mdx` \u2014 Server-side finalization workflows\n- `docs/phoenix/finalization.mdx` \u2014 Finalization system, PDF/email/CSV generation\n- `docs/phoenix/migrations.mdx` \u2014 Schema versioning, migration files\n\n### Agent Workflow\n1. Find relevant docs by content: `pnpm phoenix docs -s \"camera\"`\n2. Read matching doc: `pnpm phoenix docs -r docs/3d-scene/cameras/transitions.mdx`\n3. Search within a doc: `pnpm phoenix docs -r <path> | grep \"example\"`\n4. Search titles only as a fallback: `pnpm phoenix docs -l | grep \"camera\"`\n5. Search generated files directly when needed: `grep -rn \"camera\" \"$(pnpm phoenix docs --dir)\"`\n6. Browse a topic area: `pnpm phoenix docs -c \"Layouts\"`\n\n### Playwright MCP Setup (for AI agents)\n\nTo interact with the 3D configurator in a browser, Playwright MCP needs GPU-enabled flags for WebGL rendering. Add to `~/.claude/.mcp.json`:\n\n```json\n{\n \"mcpServers\": {\n \"playwright\": {\n \"command\": \"npx\",\n \"args\": [\n \"@playwright/mcp@latest\",\n \"--headed\",\n \"--launch-options\",\n \"{\\\"args\\\":[\\\"--use-gl=swiftshader\\\",\\\"--enable-webgl\\\",\\\"--ignore-gpu-blocklist\\\"]}\"\n ]\n }\n }\n}\n```\n\nKey flags:\n- `--headed` \u2014 visible browser (required for GPU rendering)\n- `--use-gl=swiftshader` \u2014 software GPU fallback for environments without a physical GPU\n- `--enable-webgl` + `--ignore-gpu-blocklist` \u2014 ensure WebGL is available\n[PHOENIX-SDK-END]\n";
2
+ export declare const claudeMdFile = "[PHOENIX-SDK-START]\n## Phoenix Configurator Project\n\nDeclarative 3D product configurator built with Phoenix SDK. Domain model defined in YAML, custom logic in TypeScript.\n\n## Build Commands\n- `pnpm phoenix build` \u2014 Full production build\n- `pnpm phoenix dev` \u2014 Development mode with hot reload\n- `pnpm phoenix sync` \u2014 Sync generated files without full build\n\n## Dev Logs\n- `pnpm phoenix dev` writes all logs to `.phoenix/phoenix-dev.log`\n- Contains: spec parse errors, build errors, browser runtime errors, file watcher events\n- After making changes, always check the log for errors: `tail -50 .phoenix/phoenix-dev.log` or `grep ERROR .phoenix/phoenix-dev.log`\n- Rotated automatically at 10MB (`.log.1`, `.log.2` are older rotations)\n\n## Project Structure\n- `spec/` \u2014 Domain YAML specs (entities, relations, expressions, invariants, components, application config)\n- `src/expressions/` \u2014 Computed/derived entity properties (`phx.domain.implementCustomExpressions()`)\n- `src/invariants/` \u2014 Business rule constraints (`phx.domain.implementCustomInvariants()`)\n- `src/transformers/` \u2014 Automatic state fixers (`phx.frontend.transformerBuilder`)\n- `src/components/` \u2014 ECS system components (`phx.domain.attachComponent.withEntity()`)\n- `src/elements/` \u2014 Page-level React components (`phx.frontend.createCustomPhoenixLayoutElement()`)\n - A layout element named `ConfiguratorLayout` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount `LayoutSlots.SharedCanvas` (from `@salsita-ai/sdk/configurator`) in it, or the app loader stays on screen, and call `useSceneSafeArea()` (same import) with its `containerRef` on the element covering the whole canvas and its `safeAreaRef` on the region the layout's UI leaves free, so the camera frames the scene there, and to keep the spec's tabs, property pages, sidebar footer and assistant panel while moving them, mount `LayoutSlots.DesktopSidebar` (same import) in a positioned container that sets its size, with `side=\"start\"` when it is on the left\n- `src/handlers/` \u2014 Event & lifecycle handlers\n- `src/webhooks/` \u2014 Server-side webhook handlers (`phx.webhooks.*Builder`)\n- `src/migrations/` \u2014 Schema version migrations (v*.ts)\n- `src/locales/` \u2014 Locale catalogs (authored .po sources; compiled .ts, do not edit)\n- `src/admin/` \u2014 Admin interface (mirrors main src/ structure)\n- `src/_shared/` \u2014 Shared utilities (NOT auto-imported, requires explicit imports)\n- `.phoenix/` \u2014 Auto-generated files (DO NOT EDIT)\n- `public/` \u2014 Static assets (3D models, textures, images, HDRI maps, fonts)\n- `assets/` \u2014 Uploadable resources (PDF templates, email assets)\n\n## Architecture Principles\n- YAML-first: 99% of configuration in spec/*.yaml, custom code is last resort\n- ECS pattern: entities (domain objects) + components (behavior/UI) + systems (SDK runtime)\n- Reactive state: immutable domain state flows through RxJS pipelines\n- Data binding: `$read` (read-only), `$write` (write-only), `$bind` (bidirectional) connect components to domain\n- memoEval: all component implementations must use memoEval for stable object references\n\n## Key Patterns\n- Expressions = computed properties on entities (prefix: `$`), implemented per-entity in src/expressions/\n- Invariants = validation rules returning violations, static or dynamic\n- Transformers = auto-fixers maintaining consistency after state changes\n- Components defined in YAML with `$read`/`$bind` bindings, or custom in src/components/ using attachComponent builder\n- Webhooks = server-side finalization tasks (PDF, email, CSV, image rendering)\n- Filters = contextual component activation via navigationStates, viewStates, modes, selectedEntityIds\n\n## File Conventions\n- Components: PascalCase (.tsx)\n- Utilities: kebab-case (.ts)\n- Expressions: entity-name.ts\n- Migrations: v*.ts (sequential)\n- Specs: kebab-case.yaml\n- Underscore folders (_shared/, _utils/) are NOT auto-imported\n\n## Export Rules\nAll files in src/expressions/, src/invariants/, src/transformers/, src/components/, src/handlers/, src/webhooks/ MUST use default exports. Can be a single item or an array. Named exports are ignored by the SDK auto-import system.\n\n## Webhook Membership\n- User-authored components, admin components, and handlers are frontend-only by default.\n- A handler that registers `createMapPublishedRevisionDataHandler`, `createMapPublishedChunkedDataHandler`, `createDataRowValidatorHandler`, or `createSheetValidatorHandler` is included in the webhook automatically.\n- To include another component or handler in the webhook, put `'use webhook'` as its first statement (leading comments are allowed).\n- A webhook-included file and its runtime local-import closure must not import browser SDK entrypoints (`application`, `admin`, `configurator`, `editor`, `react`, `ui`) or style/font/image assets. Spec parsing reports the unsafe import and inclusion reason as a diagnostic.\n- Keep browser rendering in an unpinned file. Move shared server-safe logic into a separate module when both frontend and webhook code need it.\n\n## Do Not Edit\n- `.phoenix/` directory \u2014 completely regenerated on each build\n- `tsconfig.json`, `eslint.config.js`, `prettier.config.js`, `.prettierignore`, `.linguirc`, `.nvmrc`\n- `src/locales/` .ts files \u2014 compiled from .po files\n\n## Code Review\nUse `/review` command to review code changes before committing.\n\n## SDK Documentation\n\nAlways search SDK docs for relevant examples before implementing Phoenix features.\n\n### Commands\n- `pnpm phoenix docs` \u2014 Full documentation index with descriptions\n- `pnpm phoenix docs -s <term>` \u2014 Search all doc content and metadata (case-insensitive)\n- `pnpm phoenix docs --dir` \u2014 Print the absolute docs directory for grep or ripgrep\n- `pnpm phoenix docs -r <path>` \u2014 Read specific doc (raw text to stdout)\n- `pnpm phoenix docs -c <category>` \u2014 List docs in a category\n- `pnpm phoenix docs -l` \u2014 List all doc paths with titles\n\n### 3D Asset Inspection\n\nRun `pnpm phoenix inspect:assets` to discover all glTF/GLB files in `public/` and get a summary table. Use `--file <path>` for detailed single-file inspection.\n\n**When to use:** before writing YAML/code that references objectName, materialsToOverride, morphTargetInfluences, or object positioning.\n\n**What it shows per node:**\n- Name, type (Mesh/Light/Camera/Empty), children\n- Transform: `pos=`, `rot=`, `scale=` (only non-default values shown)\n- Per-node morph targets: `morphs=Width,Height`\n- Bounding box: `bounds=WxHxD` (width x height x depth in meters)\n- Origin placement: `origin=center`, `bottom-center`, `top-center`, `bottom-corner`, etc. with numerical offset\n\n**Use cases:**\n- Find exact node names for `objectName` in scene entity components\n- Find material names for `materialsToOverride`\n- Find morph target names for `morphTargetInfluences`\n- Check model dimensions (bounds) for positioning, dimension indicators, or invariants\n- Check origin placement to understand how models anchor (center vs bottom-center)\n- Use `--json` for programmatic access to all data\n\n**Flags:** `--objects`, `--materials`, `--morphs`, `--animations`, `--json`\n\n### Screenshot CLI\n\nCapture 3D canvas screenshots from a running dev server via `pnpm phoenix screenshot`.\n\n**Prerequisites:**\n1. `phoenix dev` must be running (starts the WebSocket server on port 3020)\n2. Configurator must be open in a browser (the browser does the actual rendering)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (default: `./screenshot.png`)\n- `--width, -w` \u2014 Width in pixels (default: 1920)\n- `--height` \u2014 Height in pixels (default: 1080)\n- `--format, -f` \u2014 Image format: PNG or JPEG (default: PNG)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example workflow:**\n1. Start dev server: `pnpm phoenix dev`\n2. Open configurator in browser (or via Playwright MCP)\n3. Take screenshot: `pnpm phoenix screenshot -o ./render.png -w 2560 --height 1440`\n\n**Use cases:** visual regression testing, generating product images, debugging 3D renders\n\n### Inspect: State\n\nGet the current editor runtime state as JSON via `pnpm phoenix inspect:state`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--sections, -s` \u2014 Comma-separated: entities, navigation, validation (default: all)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example:** `pnpm phoenix inspect:state -o ./state.json -s entities,navigation`\n\n**Lifecycle status:** Always included in response. Shows which systems are ready:\n- `domainLoaded` \u2014 domain data loaded\n- `domainContextReady` \u2014 domain context initialized (entities available)\n- `configuratorReady` \u2014 3D configurator initialized\n- `sessionAuthenticated` \u2014 session service active\n- `editorMode` \u2014 editor mode enabled\n\n**Tips:** Use `--sections` to limit payload size. Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:state | head -50`).\n\n**Use cases:** AI agent context, debugging entity state, inspecting navigation/validation\n\n### Inspect: Data\n\nGet the current editor context data as JSON via `pnpm phoenix inspect:data`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** publishedData, frontendData, backendData, sessionData, accessData, webComponentProperties\n\n**Example:** `pnpm phoenix inspect:data -o ./data.json`\n\n**Tips:** Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:data | head -30`).\n\n**Use cases:** AI agent context, debugging published/session/access data\n\n### Inspect: Scene\n\nGet the current Three.js scene graph as JSON via `pnpm phoenix inspect:scene`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** Recursive scene tree with per-node: name, type, visible, position, rotation, scale, userData (entityId), and for meshes: geometry name, bounding box, material properties (color, metalness, roughness, opacity, textures), morph target influences. Lights include color, intensity, and type-specific properties.\n\n**Example:** `pnpm phoenix inspect:scene -o ./scene.json`\n\n**Tips:** Scene graphs can be large. Pipe through `head`/`tail` for partial output.\n\n**Use cases:** AI agent context, debugging 3D scene layout, inspecting materials and lighting\n\n### Key Docs\n- `docs/phoenix/getting-started.mdx` \u2014 Setup, prerequisites, first project\n- `docs/phoenix/quickstart.mdx` \u2014 End-to-end tutorial building a configurator\n- `docs/phoenix/domain-model.mdx` \u2014 Entities, attributes, relations, specs\n- `docs/phoenix/components.mdx` \u2014 ECS pattern, YAML components, custom components\n- `docs/phoenix/project-structure.mdx` \u2014 Files, folders, conventions\n- `docs/phoenix/best-practices.mdx` \u2014 YAML-first, code patterns, common pitfalls\n- `docs/phoenix/state-management.mdx` \u2014 Reactive state, RxJS pipelines, data flow\n- `docs/phoenix/expression-context.mdx` \u2014 Expression API, context object, helpers\n- `docs/phoenix/webhooks.mdx` \u2014 Server-side finalization workflows\n- `docs/phoenix/finalization.mdx` \u2014 Finalization system, PDF/email/CSV generation\n- `docs/phoenix/migrations.mdx` \u2014 Schema versioning, migration files\n\n### Agent Workflow\n1. Find relevant docs by content: `pnpm phoenix docs -s \"camera\"`\n2. Read matching doc: `pnpm phoenix docs -r docs/3d-scene/cameras/transitions.mdx`\n3. Search within a doc: `pnpm phoenix docs -r <path> | grep \"example\"`\n4. Search titles only as a fallback: `pnpm phoenix docs -l | grep \"camera\"`\n5. Search generated files directly when needed: `grep -rn \"camera\" \"$(pnpm phoenix docs --dir)\"`\n6. Browse a topic area: `pnpm phoenix docs -c \"Layouts\"`\n\n### Playwright MCP Setup (for AI agents)\n\nTo interact with the 3D configurator in a browser, Playwright MCP needs GPU-enabled flags for WebGL rendering. Add to `~/.claude/.mcp.json`:\n\n```json\n{\n \"mcpServers\": {\n \"playwright\": {\n \"command\": \"npx\",\n \"args\": [\n \"@playwright/mcp@latest\",\n \"--headed\",\n \"--launch-options\",\n \"{\\\"args\\\":[\\\"--use-gl=swiftshader\\\",\\\"--enable-webgl\\\",\\\"--ignore-gpu-blocklist\\\"]}\"\n ]\n }\n }\n}\n```\n\nKey flags:\n- `--headed` \u2014 visible browser (required for GPU rendering)\n- `--use-gl=swiftshader` \u2014 software GPU fallback for environments without a physical GPU\n- `--enable-webgl` + `--ignore-gpu-blocklist` \u2014 ensure WebGL is available\n[PHOENIX-SDK-END]\n";
@@ -1,2 +1,2 @@
1
1
  export declare const mergeCursorRulesContent: (existingContent: string | undefined) => string;
2
- export declare const cursorRulesFile = "---\ndescription: Phoenix SDK project rules\nglobs:\nalwaysApply: true\n---\n\n[PHOENIX-SDK-START]\n## Phoenix Configurator Project\n\nDeclarative 3D product configurator built with Phoenix SDK. Domain model defined in YAML, custom logic in TypeScript.\n\n## Build Commands\n- `pnpm phoenix build` \u2014 Full production build\n- `pnpm phoenix dev` \u2014 Development mode with hot reload\n- `pnpm phoenix sync` \u2014 Sync generated files without full build\n\n## Dev Logs\n- `pnpm phoenix dev` writes all logs to `.phoenix/phoenix-dev.log`\n- Contains: spec parse errors, build errors, browser runtime errors, file watcher events\n- After making changes, always check the log for errors: `tail -50 .phoenix/phoenix-dev.log` or `grep ERROR .phoenix/phoenix-dev.log`\n- Rotated automatically at 10MB (`.log.1`, `.log.2` are older rotations)\n\n## Project Structure\n- `spec/` \u2014 Domain YAML specs (entities, relations, expressions, invariants, components, application config)\n- `src/expressions/` \u2014 Computed/derived entity properties (`phx.domain.implementCustomExpressions()`)\n- `src/invariants/` \u2014 Business rule constraints (`phx.domain.implementCustomInvariants()`)\n- `src/transformers/` \u2014 Automatic state fixers (`phx.frontend.transformerBuilder`)\n- `src/components/` \u2014 ECS system components (`phx.domain.attachComponent.withEntity()`)\n- `src/elements/` \u2014 Page-level React components (`phx.frontend.createCustomPhoenixLayoutElement()`)\n - A layout element named `ConfiguratorLayout` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount `LayoutSlots.SharedCanvas` (from `@salsita-ai/sdk/configurator`) in it, or the app loader stays on screen, and call `useSceneSafeArea()` (same import) with its `containerRef` on the element covering the whole canvas and its `safeAreaRef` on the region the layout's UI leaves free, so the camera frames the scene there\n- `src/handlers/` \u2014 Event & lifecycle handlers\n- `src/webhooks/` \u2014 Server-side webhook handlers (`phx.webhooks.*Builder`)\n- `src/migrations/` \u2014 Schema version migrations (v*.ts)\n- `src/locales/` \u2014 Locale catalogs (authored .po sources; compiled .ts, do not edit)\n- `src/admin/` \u2014 Admin interface (mirrors main src/ structure)\n- `src/_shared/` \u2014 Shared utilities (NOT auto-imported, requires explicit imports)\n- `.phoenix/` \u2014 Auto-generated files (DO NOT EDIT)\n- `public/` \u2014 Static assets (3D models, textures, images, HDRI maps, fonts)\n- `assets/` \u2014 Uploadable resources (PDF templates, email assets)\n\n## Architecture Principles\n- YAML-first: 99% of configuration in spec/*.yaml, custom code is last resort\n- ECS pattern: entities (domain objects) + components (behavior/UI) + systems (SDK runtime)\n- Reactive state: immutable domain state flows through RxJS pipelines\n- Data binding: `$read` (read-only), `$write` (write-only), `$bind` (bidirectional) connect components to domain\n- memoEval: all component implementations must use memoEval for stable object references\n\n## Key Patterns\n- Expressions = computed properties on entities (prefix: `$`), implemented per-entity in src/expressions/\n- Invariants = validation rules returning violations, static or dynamic\n- Transformers = auto-fixers maintaining consistency after state changes\n- Components defined in YAML with `$read`/`$bind` bindings, or custom in src/components/ using attachComponent builder\n- Webhooks = server-side finalization tasks (PDF, email, CSV, image rendering)\n- Filters = contextual component activation via navigationStates, viewStates, modes, selectedEntityIds\n\n## File Conventions\n- Components: PascalCase (.tsx)\n- Utilities: kebab-case (.ts)\n- Expressions: entity-name.ts\n- Migrations: v*.ts (sequential)\n- Specs: kebab-case.yaml\n- Underscore folders (_shared/, _utils/) are NOT auto-imported\n\n## Export Rules\nAll files in src/expressions/, src/invariants/, src/transformers/, src/components/, src/handlers/, src/webhooks/ MUST use default exports. Can be a single item or an array. Named exports are ignored by the SDK auto-import system.\n\n## Webhook Membership\n- User-authored components, admin components, and handlers are frontend-only by default.\n- A handler that registers `createMapPublishedRevisionDataHandler`, `createMapPublishedChunkedDataHandler`, `createDataRowValidatorHandler`, or `createSheetValidatorHandler` is included in the webhook automatically.\n- To include another component or handler in the webhook, put `'use webhook'` as its first statement (leading comments are allowed).\n- A webhook-included file and its runtime local-import closure must not import browser SDK entrypoints (`application`, `admin`, `configurator`, `editor`, `react`, `ui`) or style/font/image assets. Spec parsing reports the unsafe import and inclusion reason as a diagnostic.\n- Keep browser rendering in an unpinned file. Move shared server-safe logic into a separate module when both frontend and webhook code need it.\n\n## Do Not Edit\n- `.phoenix/` directory \u2014 completely regenerated on each build\n- `tsconfig.json`, `eslint.config.js`, `prettier.config.js`, `.prettierignore`, `.linguirc`, `.nvmrc`\n- `src/locales/` .ts files \u2014 compiled from .po files\n\n## Code Review\nUse `/review` command to review code changes before committing.\n\n## SDK Documentation\n\nAlways search SDK docs for relevant examples before implementing Phoenix features.\n\n### Commands\n- `pnpm phoenix docs` \u2014 Full documentation index with descriptions\n- `pnpm phoenix docs -s <term>` \u2014 Search all doc content and metadata (case-insensitive)\n- `pnpm phoenix docs --dir` \u2014 Print the absolute docs directory for grep or ripgrep\n- `pnpm phoenix docs -r <path>` \u2014 Read specific doc (raw text to stdout)\n- `pnpm phoenix docs -c <category>` \u2014 List docs in a category\n- `pnpm phoenix docs -l` \u2014 List all doc paths with titles\n\n### 3D Asset Inspection\n\nRun `pnpm phoenix inspect:assets` to discover all glTF/GLB files in `public/` and get a summary table. Use `--file <path>` for detailed single-file inspection.\n\n**When to use:** before writing YAML/code that references objectName, materialsToOverride, morphTargetInfluences, or object positioning.\n\n**What it shows per node:**\n- Name, type (Mesh/Light/Camera/Empty), children\n- Transform: `pos=`, `rot=`, `scale=` (only non-default values shown)\n- Per-node morph targets: `morphs=Width,Height`\n- Bounding box: `bounds=WxHxD` (width x height x depth in meters)\n- Origin placement: `origin=center`, `bottom-center`, `top-center`, `bottom-corner`, etc. with numerical offset\n\n**Use cases:**\n- Find exact node names for `objectName` in scene entity components\n- Find material names for `materialsToOverride`\n- Find morph target names for `morphTargetInfluences`\n- Check model dimensions (bounds) for positioning, dimension indicators, or invariants\n- Check origin placement to understand how models anchor (center vs bottom-center)\n- Use `--json` for programmatic access to all data\n\n**Flags:** `--objects`, `--materials`, `--morphs`, `--animations`, `--json`\n\n### Screenshot CLI\n\nCapture 3D canvas screenshots from a running dev server via `pnpm phoenix screenshot`.\n\n**Prerequisites:**\n1. `phoenix dev` must be running (starts the WebSocket server on port 3020)\n2. Configurator must be open in a browser (the browser does the actual rendering)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (default: `./screenshot.png`)\n- `--width, -w` \u2014 Width in pixels (default: 1920)\n- `--height` \u2014 Height in pixels (default: 1080)\n- `--format, -f` \u2014 Image format: PNG or JPEG (default: PNG)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example workflow:**\n1. Start dev server: `pnpm phoenix dev`\n2. Open configurator in browser (or via Playwright MCP)\n3. Take screenshot: `pnpm phoenix screenshot -o ./render.png -w 2560 --height 1440`\n\n**Use cases:** visual regression testing, generating product images, debugging 3D renders\n\n### Inspect: State\n\nGet the current editor runtime state as JSON via `pnpm phoenix inspect:state`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--sections, -s` \u2014 Comma-separated: entities, navigation, validation (default: all)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example:** `pnpm phoenix inspect:state -o ./state.json -s entities,navigation`\n\n**Lifecycle status:** Always included in response. Shows which systems are ready:\n- `domainLoaded` \u2014 domain data loaded\n- `domainContextReady` \u2014 domain context initialized (entities available)\n- `configuratorReady` \u2014 3D configurator initialized\n- `sessionAuthenticated` \u2014 session service active\n- `editorMode` \u2014 editor mode enabled\n\n**Tips:** Use `--sections` to limit payload size. Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:state | head -50`).\n\n**Use cases:** AI agent context, debugging entity state, inspecting navigation/validation\n\n### Inspect: Data\n\nGet the current editor context data as JSON via `pnpm phoenix inspect:data`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** publishedData, frontendData, backendData, sessionData, accessData, webComponentProperties\n\n**Example:** `pnpm phoenix inspect:data -o ./data.json`\n\n**Tips:** Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:data | head -30`).\n\n**Use cases:** AI agent context, debugging published/session/access data\n\n### Inspect: Scene\n\nGet the current Three.js scene graph as JSON via `pnpm phoenix inspect:scene`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** Recursive scene tree with per-node: name, type, visible, position, rotation, scale, userData (entityId), and for meshes: geometry name, bounding box, material properties (color, metalness, roughness, opacity, textures), morph target influences. Lights include color, intensity, and type-specific properties.\n\n**Example:** `pnpm phoenix inspect:scene -o ./scene.json`\n\n**Tips:** Scene graphs can be large. Pipe through `head`/`tail` for partial output.\n\n**Use cases:** AI agent context, debugging 3D scene layout, inspecting materials and lighting\n\n### Key Docs\n- `docs/phoenix/getting-started.mdx` \u2014 Setup, prerequisites, first project\n- `docs/phoenix/quickstart.mdx` \u2014 End-to-end tutorial building a configurator\n- `docs/phoenix/domain-model.mdx` \u2014 Entities, attributes, relations, specs\n- `docs/phoenix/components.mdx` \u2014 ECS pattern, YAML components, custom components\n- `docs/phoenix/project-structure.mdx` \u2014 Files, folders, conventions\n- `docs/phoenix/best-practices.mdx` \u2014 YAML-first, code patterns, common pitfalls\n- `docs/phoenix/state-management.mdx` \u2014 Reactive state, RxJS pipelines, data flow\n- `docs/phoenix/expression-context.mdx` \u2014 Expression API, context object, helpers\n- `docs/phoenix/webhooks.mdx` \u2014 Server-side finalization workflows\n- `docs/phoenix/finalization.mdx` \u2014 Finalization system, PDF/email/CSV generation\n- `docs/phoenix/migrations.mdx` \u2014 Schema versioning, migration files\n\n### Agent Workflow\n1. Find relevant docs by content: `pnpm phoenix docs -s \"camera\"`\n2. Read matching doc: `pnpm phoenix docs -r docs/3d-scene/cameras/transitions.mdx`\n3. Search within a doc: `pnpm phoenix docs -r <path> | grep \"example\"`\n4. Search titles only as a fallback: `pnpm phoenix docs -l | grep \"camera\"`\n5. Search generated files directly when needed: `grep -rn \"camera\" \"$(pnpm phoenix docs --dir)\"`\n6. Browse a topic area: `pnpm phoenix docs -c \"Layouts\"`\n\n### Playwright MCP Setup (for AI agents)\n\nTo interact with the 3D configurator in a browser, Playwright MCP needs GPU-enabled flags for WebGL rendering. Add to `~/.claude/.mcp.json`:\n\n```json\n{\n \"mcpServers\": {\n \"playwright\": {\n \"command\": \"npx\",\n \"args\": [\n \"@playwright/mcp@latest\",\n \"--headed\",\n \"--launch-options\",\n \"{\\\"args\\\":[\\\"--use-gl=swiftshader\\\",\\\"--enable-webgl\\\",\\\"--ignore-gpu-blocklist\\\"]}\"\n ]\n }\n }\n}\n```\n\nKey flags:\n- `--headed` \u2014 visible browser (required for GPU rendering)\n- `--use-gl=swiftshader` \u2014 software GPU fallback for environments without a physical GPU\n- `--enable-webgl` + `--ignore-gpu-blocklist` \u2014 ensure WebGL is available\n[PHOENIX-SDK-END]\n";
2
+ export declare const cursorRulesFile = "---\ndescription: Phoenix SDK project rules\nglobs:\nalwaysApply: true\n---\n\n[PHOENIX-SDK-START]\n## Phoenix Configurator Project\n\nDeclarative 3D product configurator built with Phoenix SDK. Domain model defined in YAML, custom logic in TypeScript.\n\n## Build Commands\n- `pnpm phoenix build` \u2014 Full production build\n- `pnpm phoenix dev` \u2014 Development mode with hot reload\n- `pnpm phoenix sync` \u2014 Sync generated files without full build\n\n## Dev Logs\n- `pnpm phoenix dev` writes all logs to `.phoenix/phoenix-dev.log`\n- Contains: spec parse errors, build errors, browser runtime errors, file watcher events\n- After making changes, always check the log for errors: `tail -50 .phoenix/phoenix-dev.log` or `grep ERROR .phoenix/phoenix-dev.log`\n- Rotated automatically at 10MB (`.log.1`, `.log.2` are older rotations)\n\n## Project Structure\n- `spec/` \u2014 Domain YAML specs (entities, relations, expressions, invariants, components, application config)\n- `src/expressions/` \u2014 Computed/derived entity properties (`phx.domain.implementCustomExpressions()`)\n- `src/invariants/` \u2014 Business rule constraints (`phx.domain.implementCustomInvariants()`)\n- `src/transformers/` \u2014 Automatic state fixers (`phx.frontend.transformerBuilder`)\n- `src/components/` \u2014 ECS system components (`phx.domain.attachComponent.withEntity()`)\n- `src/elements/` \u2014 Page-level React components (`phx.frontend.createCustomPhoenixLayoutElement()`)\n - A layout element named `ConfiguratorLayout` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount `LayoutSlots.SharedCanvas` (from `@salsita-ai/sdk/configurator`) in it, or the app loader stays on screen, and call `useSceneSafeArea()` (same import) with its `containerRef` on the element covering the whole canvas and its `safeAreaRef` on the region the layout's UI leaves free, so the camera frames the scene there, and to keep the spec's tabs, property pages, sidebar footer and assistant panel while moving them, mount `LayoutSlots.DesktopSidebar` (same import) in a positioned container that sets its size, with `side=\"start\"` when it is on the left\n- `src/handlers/` \u2014 Event & lifecycle handlers\n- `src/webhooks/` \u2014 Server-side webhook handlers (`phx.webhooks.*Builder`)\n- `src/migrations/` \u2014 Schema version migrations (v*.ts)\n- `src/locales/` \u2014 Locale catalogs (authored .po sources; compiled .ts, do not edit)\n- `src/admin/` \u2014 Admin interface (mirrors main src/ structure)\n- `src/_shared/` \u2014 Shared utilities (NOT auto-imported, requires explicit imports)\n- `.phoenix/` \u2014 Auto-generated files (DO NOT EDIT)\n- `public/` \u2014 Static assets (3D models, textures, images, HDRI maps, fonts)\n- `assets/` \u2014 Uploadable resources (PDF templates, email assets)\n\n## Architecture Principles\n- YAML-first: 99% of configuration in spec/*.yaml, custom code is last resort\n- ECS pattern: entities (domain objects) + components (behavior/UI) + systems (SDK runtime)\n- Reactive state: immutable domain state flows through RxJS pipelines\n- Data binding: `$read` (read-only), `$write` (write-only), `$bind` (bidirectional) connect components to domain\n- memoEval: all component implementations must use memoEval for stable object references\n\n## Key Patterns\n- Expressions = computed properties on entities (prefix: `$`), implemented per-entity in src/expressions/\n- Invariants = validation rules returning violations, static or dynamic\n- Transformers = auto-fixers maintaining consistency after state changes\n- Components defined in YAML with `$read`/`$bind` bindings, or custom in src/components/ using attachComponent builder\n- Webhooks = server-side finalization tasks (PDF, email, CSV, image rendering)\n- Filters = contextual component activation via navigationStates, viewStates, modes, selectedEntityIds\n\n## File Conventions\n- Components: PascalCase (.tsx)\n- Utilities: kebab-case (.ts)\n- Expressions: entity-name.ts\n- Migrations: v*.ts (sequential)\n- Specs: kebab-case.yaml\n- Underscore folders (_shared/, _utils/) are NOT auto-imported\n\n## Export Rules\nAll files in src/expressions/, src/invariants/, src/transformers/, src/components/, src/handlers/, src/webhooks/ MUST use default exports. Can be a single item or an array. Named exports are ignored by the SDK auto-import system.\n\n## Webhook Membership\n- User-authored components, admin components, and handlers are frontend-only by default.\n- A handler that registers `createMapPublishedRevisionDataHandler`, `createMapPublishedChunkedDataHandler`, `createDataRowValidatorHandler`, or `createSheetValidatorHandler` is included in the webhook automatically.\n- To include another component or handler in the webhook, put `'use webhook'` as its first statement (leading comments are allowed).\n- A webhook-included file and its runtime local-import closure must not import browser SDK entrypoints (`application`, `admin`, `configurator`, `editor`, `react`, `ui`) or style/font/image assets. Spec parsing reports the unsafe import and inclusion reason as a diagnostic.\n- Keep browser rendering in an unpinned file. Move shared server-safe logic into a separate module when both frontend and webhook code need it.\n\n## Do Not Edit\n- `.phoenix/` directory \u2014 completely regenerated on each build\n- `tsconfig.json`, `eslint.config.js`, `prettier.config.js`, `.prettierignore`, `.linguirc`, `.nvmrc`\n- `src/locales/` .ts files \u2014 compiled from .po files\n\n## Code Review\nUse `/review` command to review code changes before committing.\n\n## SDK Documentation\n\nAlways search SDK docs for relevant examples before implementing Phoenix features.\n\n### Commands\n- `pnpm phoenix docs` \u2014 Full documentation index with descriptions\n- `pnpm phoenix docs -s <term>` \u2014 Search all doc content and metadata (case-insensitive)\n- `pnpm phoenix docs --dir` \u2014 Print the absolute docs directory for grep or ripgrep\n- `pnpm phoenix docs -r <path>` \u2014 Read specific doc (raw text to stdout)\n- `pnpm phoenix docs -c <category>` \u2014 List docs in a category\n- `pnpm phoenix docs -l` \u2014 List all doc paths with titles\n\n### 3D Asset Inspection\n\nRun `pnpm phoenix inspect:assets` to discover all glTF/GLB files in `public/` and get a summary table. Use `--file <path>` for detailed single-file inspection.\n\n**When to use:** before writing YAML/code that references objectName, materialsToOverride, morphTargetInfluences, or object positioning.\n\n**What it shows per node:**\n- Name, type (Mesh/Light/Camera/Empty), children\n- Transform: `pos=`, `rot=`, `scale=` (only non-default values shown)\n- Per-node morph targets: `morphs=Width,Height`\n- Bounding box: `bounds=WxHxD` (width x height x depth in meters)\n- Origin placement: `origin=center`, `bottom-center`, `top-center`, `bottom-corner`, etc. with numerical offset\n\n**Use cases:**\n- Find exact node names for `objectName` in scene entity components\n- Find material names for `materialsToOverride`\n- Find morph target names for `morphTargetInfluences`\n- Check model dimensions (bounds) for positioning, dimension indicators, or invariants\n- Check origin placement to understand how models anchor (center vs bottom-center)\n- Use `--json` for programmatic access to all data\n\n**Flags:** `--objects`, `--materials`, `--morphs`, `--animations`, `--json`\n\n### Screenshot CLI\n\nCapture 3D canvas screenshots from a running dev server via `pnpm phoenix screenshot`.\n\n**Prerequisites:**\n1. `phoenix dev` must be running (starts the WebSocket server on port 3020)\n2. Configurator must be open in a browser (the browser does the actual rendering)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (default: `./screenshot.png`)\n- `--width, -w` \u2014 Width in pixels (default: 1920)\n- `--height` \u2014 Height in pixels (default: 1080)\n- `--format, -f` \u2014 Image format: PNG or JPEG (default: PNG)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example workflow:**\n1. Start dev server: `pnpm phoenix dev`\n2. Open configurator in browser (or via Playwright MCP)\n3. Take screenshot: `pnpm phoenix screenshot -o ./render.png -w 2560 --height 1440`\n\n**Use cases:** visual regression testing, generating product images, debugging 3D renders\n\n### Inspect: State\n\nGet the current editor runtime state as JSON via `pnpm phoenix inspect:state`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--sections, -s` \u2014 Comma-separated: entities, navigation, validation (default: all)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example:** `pnpm phoenix inspect:state -o ./state.json -s entities,navigation`\n\n**Lifecycle status:** Always included in response. Shows which systems are ready:\n- `domainLoaded` \u2014 domain data loaded\n- `domainContextReady` \u2014 domain context initialized (entities available)\n- `configuratorReady` \u2014 3D configurator initialized\n- `sessionAuthenticated` \u2014 session service active\n- `editorMode` \u2014 editor mode enabled\n\n**Tips:** Use `--sections` to limit payload size. Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:state | head -50`).\n\n**Use cases:** AI agent context, debugging entity state, inspecting navigation/validation\n\n### Inspect: Data\n\nGet the current editor context data as JSON via `pnpm phoenix inspect:data`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** publishedData, frontendData, backendData, sessionData, accessData, webComponentProperties\n\n**Example:** `pnpm phoenix inspect:data -o ./data.json`\n\n**Tips:** Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:data | head -30`).\n\n**Use cases:** AI agent context, debugging published/session/access data\n\n### Inspect: Scene\n\nGet the current Three.js scene graph as JSON via `pnpm phoenix inspect:scene`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** Recursive scene tree with per-node: name, type, visible, position, rotation, scale, userData (entityId), and for meshes: geometry name, bounding box, material properties (color, metalness, roughness, opacity, textures), morph target influences. Lights include color, intensity, and type-specific properties.\n\n**Example:** `pnpm phoenix inspect:scene -o ./scene.json`\n\n**Tips:** Scene graphs can be large. Pipe through `head`/`tail` for partial output.\n\n**Use cases:** AI agent context, debugging 3D scene layout, inspecting materials and lighting\n\n### Key Docs\n- `docs/phoenix/getting-started.mdx` \u2014 Setup, prerequisites, first project\n- `docs/phoenix/quickstart.mdx` \u2014 End-to-end tutorial building a configurator\n- `docs/phoenix/domain-model.mdx` \u2014 Entities, attributes, relations, specs\n- `docs/phoenix/components.mdx` \u2014 ECS pattern, YAML components, custom components\n- `docs/phoenix/project-structure.mdx` \u2014 Files, folders, conventions\n- `docs/phoenix/best-practices.mdx` \u2014 YAML-first, code patterns, common pitfalls\n- `docs/phoenix/state-management.mdx` \u2014 Reactive state, RxJS pipelines, data flow\n- `docs/phoenix/expression-context.mdx` \u2014 Expression API, context object, helpers\n- `docs/phoenix/webhooks.mdx` \u2014 Server-side finalization workflows\n- `docs/phoenix/finalization.mdx` \u2014 Finalization system, PDF/email/CSV generation\n- `docs/phoenix/migrations.mdx` \u2014 Schema versioning, migration files\n\n### Agent Workflow\n1. Find relevant docs by content: `pnpm phoenix docs -s \"camera\"`\n2. Read matching doc: `pnpm phoenix docs -r docs/3d-scene/cameras/transitions.mdx`\n3. Search within a doc: `pnpm phoenix docs -r <path> | grep \"example\"`\n4. Search titles only as a fallback: `pnpm phoenix docs -l | grep \"camera\"`\n5. Search generated files directly when needed: `grep -rn \"camera\" \"$(pnpm phoenix docs --dir)\"`\n6. Browse a topic area: `pnpm phoenix docs -c \"Layouts\"`\n\n### Playwright MCP Setup (for AI agents)\n\nTo interact with the 3D configurator in a browser, Playwright MCP needs GPU-enabled flags for WebGL rendering. Add to `~/.claude/.mcp.json`:\n\n```json\n{\n \"mcpServers\": {\n \"playwright\": {\n \"command\": \"npx\",\n \"args\": [\n \"@playwright/mcp@latest\",\n \"--headed\",\n \"--launch-options\",\n \"{\\\"args\\\":[\\\"--use-gl=swiftshader\\\",\\\"--enable-webgl\\\",\\\"--ignore-gpu-blocklist\\\"]}\"\n ]\n }\n }\n}\n```\n\nKey flags:\n- `--headed` \u2014 visible browser (required for GPU rendering)\n- `--use-gl=swiftshader` \u2014 software GPU fallback for environments without a physical GPU\n- `--enable-webgl` + `--ignore-gpu-blocklist` \u2014 ensure WebGL is available\n[PHOENIX-SDK-END]\n";
@@ -1 +1 @@
1
- export declare const sdkContent = "[PHOENIX-SDK-START]\n## Phoenix Configurator Project\n\nDeclarative 3D product configurator built with Phoenix SDK. Domain model defined in YAML, custom logic in TypeScript.\n\n## Build Commands\n- `pnpm phoenix build` \u2014 Full production build\n- `pnpm phoenix dev` \u2014 Development mode with hot reload\n- `pnpm phoenix sync` \u2014 Sync generated files without full build\n\n## Dev Logs\n- `pnpm phoenix dev` writes all logs to `.phoenix/phoenix-dev.log`\n- Contains: spec parse errors, build errors, browser runtime errors, file watcher events\n- After making changes, always check the log for errors: `tail -50 .phoenix/phoenix-dev.log` or `grep ERROR .phoenix/phoenix-dev.log`\n- Rotated automatically at 10MB (`.log.1`, `.log.2` are older rotations)\n\n## Project Structure\n- `spec/` \u2014 Domain YAML specs (entities, relations, expressions, invariants, components, application config)\n- `src/expressions/` \u2014 Computed/derived entity properties (`phx.domain.implementCustomExpressions()`)\n- `src/invariants/` \u2014 Business rule constraints (`phx.domain.implementCustomInvariants()`)\n- `src/transformers/` \u2014 Automatic state fixers (`phx.frontend.transformerBuilder`)\n- `src/components/` \u2014 ECS system components (`phx.domain.attachComponent.withEntity()`)\n- `src/elements/` \u2014 Page-level React components (`phx.frontend.createCustomPhoenixLayoutElement()`)\n - A layout element named `ConfiguratorLayout` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount `LayoutSlots.SharedCanvas` (from `@salsita-ai/sdk/configurator`) in it, or the app loader stays on screen, and call `useSceneSafeArea()` (same import) with its `containerRef` on the element covering the whole canvas and its `safeAreaRef` on the region the layout's UI leaves free, so the camera frames the scene there\n- `src/handlers/` \u2014 Event & lifecycle handlers\n- `src/webhooks/` \u2014 Server-side webhook handlers (`phx.webhooks.*Builder`)\n- `src/migrations/` \u2014 Schema version migrations (v*.ts)\n- `src/locales/` \u2014 Locale catalogs (authored .po sources; compiled .ts, do not edit)\n- `src/admin/` \u2014 Admin interface (mirrors main src/ structure)\n- `src/_shared/` \u2014 Shared utilities (NOT auto-imported, requires explicit imports)\n- `.phoenix/` \u2014 Auto-generated files (DO NOT EDIT)\n- `public/` \u2014 Static assets (3D models, textures, images, HDRI maps, fonts)\n- `assets/` \u2014 Uploadable resources (PDF templates, email assets)\n\n## Architecture Principles\n- YAML-first: 99% of configuration in spec/*.yaml, custom code is last resort\n- ECS pattern: entities (domain objects) + components (behavior/UI) + systems (SDK runtime)\n- Reactive state: immutable domain state flows through RxJS pipelines\n- Data binding: `$read` (read-only), `$write` (write-only), `$bind` (bidirectional) connect components to domain\n- memoEval: all component implementations must use memoEval for stable object references\n\n## Key Patterns\n- Expressions = computed properties on entities (prefix: `$`), implemented per-entity in src/expressions/\n- Invariants = validation rules returning violations, static or dynamic\n- Transformers = auto-fixers maintaining consistency after state changes\n- Components defined in YAML with `$read`/`$bind` bindings, or custom in src/components/ using attachComponent builder\n- Webhooks = server-side finalization tasks (PDF, email, CSV, image rendering)\n- Filters = contextual component activation via navigationStates, viewStates, modes, selectedEntityIds\n\n## File Conventions\n- Components: PascalCase (.tsx)\n- Utilities: kebab-case (.ts)\n- Expressions: entity-name.ts\n- Migrations: v*.ts (sequential)\n- Specs: kebab-case.yaml\n- Underscore folders (_shared/, _utils/) are NOT auto-imported\n\n## Export Rules\nAll files in src/expressions/, src/invariants/, src/transformers/, src/components/, src/handlers/, src/webhooks/ MUST use default exports. Can be a single item or an array. Named exports are ignored by the SDK auto-import system.\n\n## Webhook Membership\n- User-authored components, admin components, and handlers are frontend-only by default.\n- A handler that registers `createMapPublishedRevisionDataHandler`, `createMapPublishedChunkedDataHandler`, `createDataRowValidatorHandler`, or `createSheetValidatorHandler` is included in the webhook automatically.\n- To include another component or handler in the webhook, put `'use webhook'` as its first statement (leading comments are allowed).\n- A webhook-included file and its runtime local-import closure must not import browser SDK entrypoints (`application`, `admin`, `configurator`, `editor`, `react`, `ui`) or style/font/image assets. Spec parsing reports the unsafe import and inclusion reason as a diagnostic.\n- Keep browser rendering in an unpinned file. Move shared server-safe logic into a separate module when both frontend and webhook code need it.\n\n## Do Not Edit\n- `.phoenix/` directory \u2014 completely regenerated on each build\n- `tsconfig.json`, `eslint.config.js`, `prettier.config.js`, `.prettierignore`, `.linguirc`, `.nvmrc`\n- `src/locales/` .ts files \u2014 compiled from .po files\n\n## Code Review\nUse `/review` command to review code changes before committing.\n\n## SDK Documentation\n\nAlways search SDK docs for relevant examples before implementing Phoenix features.\n\n### Commands\n- `pnpm phoenix docs` \u2014 Full documentation index with descriptions\n- `pnpm phoenix docs -s <term>` \u2014 Search all doc content and metadata (case-insensitive)\n- `pnpm phoenix docs --dir` \u2014 Print the absolute docs directory for grep or ripgrep\n- `pnpm phoenix docs -r <path>` \u2014 Read specific doc (raw text to stdout)\n- `pnpm phoenix docs -c <category>` \u2014 List docs in a category\n- `pnpm phoenix docs -l` \u2014 List all doc paths with titles\n\n### 3D Asset Inspection\n\nRun `pnpm phoenix inspect:assets` to discover all glTF/GLB files in `public/` and get a summary table. Use `--file <path>` for detailed single-file inspection.\n\n**When to use:** before writing YAML/code that references objectName, materialsToOverride, morphTargetInfluences, or object positioning.\n\n**What it shows per node:**\n- Name, type (Mesh/Light/Camera/Empty), children\n- Transform: `pos=`, `rot=`, `scale=` (only non-default values shown)\n- Per-node morph targets: `morphs=Width,Height`\n- Bounding box: `bounds=WxHxD` (width x height x depth in meters)\n- Origin placement: `origin=center`, `bottom-center`, `top-center`, `bottom-corner`, etc. with numerical offset\n\n**Use cases:**\n- Find exact node names for `objectName` in scene entity components\n- Find material names for `materialsToOverride`\n- Find morph target names for `morphTargetInfluences`\n- Check model dimensions (bounds) for positioning, dimension indicators, or invariants\n- Check origin placement to understand how models anchor (center vs bottom-center)\n- Use `--json` for programmatic access to all data\n\n**Flags:** `--objects`, `--materials`, `--morphs`, `--animations`, `--json`\n\n### Screenshot CLI\n\nCapture 3D canvas screenshots from a running dev server via `pnpm phoenix screenshot`.\n\n**Prerequisites:**\n1. `phoenix dev` must be running (starts the WebSocket server on port 3020)\n2. Configurator must be open in a browser (the browser does the actual rendering)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (default: `./screenshot.png`)\n- `--width, -w` \u2014 Width in pixels (default: 1920)\n- `--height` \u2014 Height in pixels (default: 1080)\n- `--format, -f` \u2014 Image format: PNG or JPEG (default: PNG)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example workflow:**\n1. Start dev server: `pnpm phoenix dev`\n2. Open configurator in browser (or via Playwright MCP)\n3. Take screenshot: `pnpm phoenix screenshot -o ./render.png -w 2560 --height 1440`\n\n**Use cases:** visual regression testing, generating product images, debugging 3D renders\n\n### Inspect: State\n\nGet the current editor runtime state as JSON via `pnpm phoenix inspect:state`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--sections, -s` \u2014 Comma-separated: entities, navigation, validation (default: all)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example:** `pnpm phoenix inspect:state -o ./state.json -s entities,navigation`\n\n**Lifecycle status:** Always included in response. Shows which systems are ready:\n- `domainLoaded` \u2014 domain data loaded\n- `domainContextReady` \u2014 domain context initialized (entities available)\n- `configuratorReady` \u2014 3D configurator initialized\n- `sessionAuthenticated` \u2014 session service active\n- `editorMode` \u2014 editor mode enabled\n\n**Tips:** Use `--sections` to limit payload size. Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:state | head -50`).\n\n**Use cases:** AI agent context, debugging entity state, inspecting navigation/validation\n\n### Inspect: Data\n\nGet the current editor context data as JSON via `pnpm phoenix inspect:data`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** publishedData, frontendData, backendData, sessionData, accessData, webComponentProperties\n\n**Example:** `pnpm phoenix inspect:data -o ./data.json`\n\n**Tips:** Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:data | head -30`).\n\n**Use cases:** AI agent context, debugging published/session/access data\n\n### Inspect: Scene\n\nGet the current Three.js scene graph as JSON via `pnpm phoenix inspect:scene`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** Recursive scene tree with per-node: name, type, visible, position, rotation, scale, userData (entityId), and for meshes: geometry name, bounding box, material properties (color, metalness, roughness, opacity, textures), morph target influences. Lights include color, intensity, and type-specific properties.\n\n**Example:** `pnpm phoenix inspect:scene -o ./scene.json`\n\n**Tips:** Scene graphs can be large. Pipe through `head`/`tail` for partial output.\n\n**Use cases:** AI agent context, debugging 3D scene layout, inspecting materials and lighting\n\n### Key Docs\n- `docs/phoenix/getting-started.mdx` \u2014 Setup, prerequisites, first project\n- `docs/phoenix/quickstart.mdx` \u2014 End-to-end tutorial building a configurator\n- `docs/phoenix/domain-model.mdx` \u2014 Entities, attributes, relations, specs\n- `docs/phoenix/components.mdx` \u2014 ECS pattern, YAML components, custom components\n- `docs/phoenix/project-structure.mdx` \u2014 Files, folders, conventions\n- `docs/phoenix/best-practices.mdx` \u2014 YAML-first, code patterns, common pitfalls\n- `docs/phoenix/state-management.mdx` \u2014 Reactive state, RxJS pipelines, data flow\n- `docs/phoenix/expression-context.mdx` \u2014 Expression API, context object, helpers\n- `docs/phoenix/webhooks.mdx` \u2014 Server-side finalization workflows\n- `docs/phoenix/finalization.mdx` \u2014 Finalization system, PDF/email/CSV generation\n- `docs/phoenix/migrations.mdx` \u2014 Schema versioning, migration files\n\n### Agent Workflow\n1. Find relevant docs by content: `pnpm phoenix docs -s \"camera\"`\n2. Read matching doc: `pnpm phoenix docs -r docs/3d-scene/cameras/transitions.mdx`\n3. Search within a doc: `pnpm phoenix docs -r <path> | grep \"example\"`\n4. Search titles only as a fallback: `pnpm phoenix docs -l | grep \"camera\"`\n5. Search generated files directly when needed: `grep -rn \"camera\" \"$(pnpm phoenix docs --dir)\"`\n6. Browse a topic area: `pnpm phoenix docs -c \"Layouts\"`\n\n### Playwright MCP Setup (for AI agents)\n\nTo interact with the 3D configurator in a browser, Playwright MCP needs GPU-enabled flags for WebGL rendering. Add to `~/.claude/.mcp.json`:\n\n```json\n{\n \"mcpServers\": {\n \"playwright\": {\n \"command\": \"npx\",\n \"args\": [\n \"@playwright/mcp@latest\",\n \"--headed\",\n \"--launch-options\",\n \"{\\\"args\\\":[\\\"--use-gl=swiftshader\\\",\\\"--enable-webgl\\\",\\\"--ignore-gpu-blocklist\\\"]}\"\n ]\n }\n }\n}\n```\n\nKey flags:\n- `--headed` \u2014 visible browser (required for GPU rendering)\n- `--use-gl=swiftshader` \u2014 software GPU fallback for environments without a physical GPU\n- `--enable-webgl` + `--ignore-gpu-blocklist` \u2014 ensure WebGL is available\n[PHOENIX-SDK-END]";
1
+ export declare const sdkContent = "[PHOENIX-SDK-START]\n## Phoenix Configurator Project\n\nDeclarative 3D product configurator built with Phoenix SDK. Domain model defined in YAML, custom logic in TypeScript.\n\n## Build Commands\n- `pnpm phoenix build` \u2014 Full production build\n- `pnpm phoenix dev` \u2014 Development mode with hot reload\n- `pnpm phoenix sync` \u2014 Sync generated files without full build\n\n## Dev Logs\n- `pnpm phoenix dev` writes all logs to `.phoenix/phoenix-dev.log`\n- Contains: spec parse errors, build errors, browser runtime errors, file watcher events\n- After making changes, always check the log for errors: `tail -50 .phoenix/phoenix-dev.log` or `grep ERROR .phoenix/phoenix-dev.log`\n- Rotated automatically at 10MB (`.log.1`, `.log.2` are older rotations)\n\n## Project Structure\n- `spec/` \u2014 Domain YAML specs (entities, relations, expressions, invariants, components, application config)\n- `src/expressions/` \u2014 Computed/derived entity properties (`phx.domain.implementCustomExpressions()`)\n- `src/invariants/` \u2014 Business rule constraints (`phx.domain.implementCustomInvariants()`)\n- `src/transformers/` \u2014 Automatic state fixers (`phx.frontend.transformerBuilder`)\n- `src/components/` \u2014 ECS system components (`phx.domain.attachComponent.withEntity()`)\n- `src/elements/` \u2014 Page-level React components (`phx.frontend.createCustomPhoenixLayoutElement()`)\n - A layout element named `ConfiguratorLayout` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount `LayoutSlots.SharedCanvas` (from `@salsita-ai/sdk/configurator`) in it, or the app loader stays on screen, and call `useSceneSafeArea()` (same import) with its `containerRef` on the element covering the whole canvas and its `safeAreaRef` on the region the layout's UI leaves free, so the camera frames the scene there, and to keep the spec's tabs, property pages, sidebar footer and assistant panel while moving them, mount `LayoutSlots.DesktopSidebar` (same import) in a positioned container that sets its size, with `side=\"start\"` when it is on the left\n- `src/handlers/` \u2014 Event & lifecycle handlers\n- `src/webhooks/` \u2014 Server-side webhook handlers (`phx.webhooks.*Builder`)\n- `src/migrations/` \u2014 Schema version migrations (v*.ts)\n- `src/locales/` \u2014 Locale catalogs (authored .po sources; compiled .ts, do not edit)\n- `src/admin/` \u2014 Admin interface (mirrors main src/ structure)\n- `src/_shared/` \u2014 Shared utilities (NOT auto-imported, requires explicit imports)\n- `.phoenix/` \u2014 Auto-generated files (DO NOT EDIT)\n- `public/` \u2014 Static assets (3D models, textures, images, HDRI maps, fonts)\n- `assets/` \u2014 Uploadable resources (PDF templates, email assets)\n\n## Architecture Principles\n- YAML-first: 99% of configuration in spec/*.yaml, custom code is last resort\n- ECS pattern: entities (domain objects) + components (behavior/UI) + systems (SDK runtime)\n- Reactive state: immutable domain state flows through RxJS pipelines\n- Data binding: `$read` (read-only), `$write` (write-only), `$bind` (bidirectional) connect components to domain\n- memoEval: all component implementations must use memoEval for stable object references\n\n## Key Patterns\n- Expressions = computed properties on entities (prefix: `$`), implemented per-entity in src/expressions/\n- Invariants = validation rules returning violations, static or dynamic\n- Transformers = auto-fixers maintaining consistency after state changes\n- Components defined in YAML with `$read`/`$bind` bindings, or custom in src/components/ using attachComponent builder\n- Webhooks = server-side finalization tasks (PDF, email, CSV, image rendering)\n- Filters = contextual component activation via navigationStates, viewStates, modes, selectedEntityIds\n\n## File Conventions\n- Components: PascalCase (.tsx)\n- Utilities: kebab-case (.ts)\n- Expressions: entity-name.ts\n- Migrations: v*.ts (sequential)\n- Specs: kebab-case.yaml\n- Underscore folders (_shared/, _utils/) are NOT auto-imported\n\n## Export Rules\nAll files in src/expressions/, src/invariants/, src/transformers/, src/components/, src/handlers/, src/webhooks/ MUST use default exports. Can be a single item or an array. Named exports are ignored by the SDK auto-import system.\n\n## Webhook Membership\n- User-authored components, admin components, and handlers are frontend-only by default.\n- A handler that registers `createMapPublishedRevisionDataHandler`, `createMapPublishedChunkedDataHandler`, `createDataRowValidatorHandler`, or `createSheetValidatorHandler` is included in the webhook automatically.\n- To include another component or handler in the webhook, put `'use webhook'` as its first statement (leading comments are allowed).\n- A webhook-included file and its runtime local-import closure must not import browser SDK entrypoints (`application`, `admin`, `configurator`, `editor`, `react`, `ui`) or style/font/image assets. Spec parsing reports the unsafe import and inclusion reason as a diagnostic.\n- Keep browser rendering in an unpinned file. Move shared server-safe logic into a separate module when both frontend and webhook code need it.\n\n## Do Not Edit\n- `.phoenix/` directory \u2014 completely regenerated on each build\n- `tsconfig.json`, `eslint.config.js`, `prettier.config.js`, `.prettierignore`, `.linguirc`, `.nvmrc`\n- `src/locales/` .ts files \u2014 compiled from .po files\n\n## Code Review\nUse `/review` command to review code changes before committing.\n\n## SDK Documentation\n\nAlways search SDK docs for relevant examples before implementing Phoenix features.\n\n### Commands\n- `pnpm phoenix docs` \u2014 Full documentation index with descriptions\n- `pnpm phoenix docs -s <term>` \u2014 Search all doc content and metadata (case-insensitive)\n- `pnpm phoenix docs --dir` \u2014 Print the absolute docs directory for grep or ripgrep\n- `pnpm phoenix docs -r <path>` \u2014 Read specific doc (raw text to stdout)\n- `pnpm phoenix docs -c <category>` \u2014 List docs in a category\n- `pnpm phoenix docs -l` \u2014 List all doc paths with titles\n\n### 3D Asset Inspection\n\nRun `pnpm phoenix inspect:assets` to discover all glTF/GLB files in `public/` and get a summary table. Use `--file <path>` for detailed single-file inspection.\n\n**When to use:** before writing YAML/code that references objectName, materialsToOverride, morphTargetInfluences, or object positioning.\n\n**What it shows per node:**\n- Name, type (Mesh/Light/Camera/Empty), children\n- Transform: `pos=`, `rot=`, `scale=` (only non-default values shown)\n- Per-node morph targets: `morphs=Width,Height`\n- Bounding box: `bounds=WxHxD` (width x height x depth in meters)\n- Origin placement: `origin=center`, `bottom-center`, `top-center`, `bottom-corner`, etc. with numerical offset\n\n**Use cases:**\n- Find exact node names for `objectName` in scene entity components\n- Find material names for `materialsToOverride`\n- Find morph target names for `morphTargetInfluences`\n- Check model dimensions (bounds) for positioning, dimension indicators, or invariants\n- Check origin placement to understand how models anchor (center vs bottom-center)\n- Use `--json` for programmatic access to all data\n\n**Flags:** `--objects`, `--materials`, `--morphs`, `--animations`, `--json`\n\n### Screenshot CLI\n\nCapture 3D canvas screenshots from a running dev server via `pnpm phoenix screenshot`.\n\n**Prerequisites:**\n1. `phoenix dev` must be running (starts the WebSocket server on port 3020)\n2. Configurator must be open in a browser (the browser does the actual rendering)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (default: `./screenshot.png`)\n- `--width, -w` \u2014 Width in pixels (default: 1920)\n- `--height` \u2014 Height in pixels (default: 1080)\n- `--format, -f` \u2014 Image format: PNG or JPEG (default: PNG)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example workflow:**\n1. Start dev server: `pnpm phoenix dev`\n2. Open configurator in browser (or via Playwright MCP)\n3. Take screenshot: `pnpm phoenix screenshot -o ./render.png -w 2560 --height 1440`\n\n**Use cases:** visual regression testing, generating product images, debugging 3D renders\n\n### Inspect: State\n\nGet the current editor runtime state as JSON via `pnpm phoenix inspect:state`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--sections, -s` \u2014 Comma-separated: entities, navigation, validation (default: all)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Example:** `pnpm phoenix inspect:state -o ./state.json -s entities,navigation`\n\n**Lifecycle status:** Always included in response. Shows which systems are ready:\n- `domainLoaded` \u2014 domain data loaded\n- `domainContextReady` \u2014 domain context initialized (entities available)\n- `configuratorReady` \u2014 3D configurator initialized\n- `sessionAuthenticated` \u2014 session service active\n- `editorMode` \u2014 editor mode enabled\n\n**Tips:** Use `--sections` to limit payload size. Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:state | head -50`).\n\n**Use cases:** AI agent context, debugging entity state, inspecting navigation/validation\n\n### Inspect: Data\n\nGet the current editor context data as JSON via `pnpm phoenix inspect:data`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** publishedData, frontendData, backendData, sessionData, accessData, webComponentProperties\n\n**Example:** `pnpm phoenix inspect:data -o ./data.json`\n\n**Tips:** Pipe through `head`/`tail` for partial output (e.g., `pnpm phoenix inspect:data | head -30`).\n\n**Use cases:** AI agent context, debugging published/session/access data\n\n### Inspect: Scene\n\nGet the current Three.js scene graph as JSON via `pnpm phoenix inspect:scene`.\n\n**Prerequisites:** same as screenshot (dev server running + browser open)\n\n**Options:**\n- `--output, -o` \u2014 Output file path (prints to stdout if omitted)\n- `--pretty` \u2014 Pretty-print JSON (default: true)\n- `--port` \u2014 WebSocket server port (default: 3020)\n\n**Returns:** Recursive scene tree with per-node: name, type, visible, position, rotation, scale, userData (entityId), and for meshes: geometry name, bounding box, material properties (color, metalness, roughness, opacity, textures), morph target influences. Lights include color, intensity, and type-specific properties.\n\n**Example:** `pnpm phoenix inspect:scene -o ./scene.json`\n\n**Tips:** Scene graphs can be large. Pipe through `head`/`tail` for partial output.\n\n**Use cases:** AI agent context, debugging 3D scene layout, inspecting materials and lighting\n\n### Key Docs\n- `docs/phoenix/getting-started.mdx` \u2014 Setup, prerequisites, first project\n- `docs/phoenix/quickstart.mdx` \u2014 End-to-end tutorial building a configurator\n- `docs/phoenix/domain-model.mdx` \u2014 Entities, attributes, relations, specs\n- `docs/phoenix/components.mdx` \u2014 ECS pattern, YAML components, custom components\n- `docs/phoenix/project-structure.mdx` \u2014 Files, folders, conventions\n- `docs/phoenix/best-practices.mdx` \u2014 YAML-first, code patterns, common pitfalls\n- `docs/phoenix/state-management.mdx` \u2014 Reactive state, RxJS pipelines, data flow\n- `docs/phoenix/expression-context.mdx` \u2014 Expression API, context object, helpers\n- `docs/phoenix/webhooks.mdx` \u2014 Server-side finalization workflows\n- `docs/phoenix/finalization.mdx` \u2014 Finalization system, PDF/email/CSV generation\n- `docs/phoenix/migrations.mdx` \u2014 Schema versioning, migration files\n\n### Agent Workflow\n1. Find relevant docs by content: `pnpm phoenix docs -s \"camera\"`\n2. Read matching doc: `pnpm phoenix docs -r docs/3d-scene/cameras/transitions.mdx`\n3. Search within a doc: `pnpm phoenix docs -r <path> | grep \"example\"`\n4. Search titles only as a fallback: `pnpm phoenix docs -l | grep \"camera\"`\n5. Search generated files directly when needed: `grep -rn \"camera\" \"$(pnpm phoenix docs --dir)\"`\n6. Browse a topic area: `pnpm phoenix docs -c \"Layouts\"`\n\n### Playwright MCP Setup (for AI agents)\n\nTo interact with the 3D configurator in a browser, Playwright MCP needs GPU-enabled flags for WebGL rendering. Add to `~/.claude/.mcp.json`:\n\n```json\n{\n \"mcpServers\": {\n \"playwright\": {\n \"command\": \"npx\",\n \"args\": [\n \"@playwright/mcp@latest\",\n \"--headed\",\n \"--launch-options\",\n \"{\\\"args\\\":[\\\"--use-gl=swiftshader\\\",\\\"--enable-webgl\\\",\\\"--ignore-gpu-blocklist\\\"]}\"\n ]\n }\n }\n}\n```\n\nKey flags:\n- `--headed` \u2014 visible browser (required for GPU rendering)\n- `--use-gl=swiftshader` \u2014 software GPU fallback for environments without a physical GPU\n- `--enable-webgl` + `--ignore-gpu-blocklist` \u2014 ensure WebGL is available\n[PHOENIX-SDK-END]";
@@ -21,7 +21,7 @@ Declarative 3D product configurator built with Phoenix SDK. Domain model defined
21
21
  - \`src/transformers/\` — Automatic state fixers (\`phx.frontend.transformerBuilder\`)
22
22
  - \`src/components/\` — ECS system components (\`phx.domain.attachComponent.withEntity()\`)
23
23
  - \`src/elements/\` — Page-level React components (\`phx.frontend.createCustomPhoenixLayoutElement()\`)
24
- - A layout element named \`ConfiguratorLayout\` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount \`LayoutSlots.SharedCanvas\` (from \`@salsita-ai/sdk/configurator\`) in it, or the app loader stays on screen, and call \`useSceneSafeArea()\` (same import) with its \`containerRef\` on the element covering the whole canvas and its \`safeAreaRef\` on the region the layout's UI leaves free, so the camera frames the scene there
24
+ - A layout element named \`ConfiguratorLayout\` replaces everything the built-in layout renders for a loaded configuration, the finalize page included, so prefer arranging the layout in the spec; when you register it, mount \`LayoutSlots.SharedCanvas\` (from \`@salsita-ai/sdk/configurator\`) in it, or the app loader stays on screen, and call \`useSceneSafeArea()\` (same import) with its \`containerRef\` on the element covering the whole canvas and its \`safeAreaRef\` on the region the layout's UI leaves free, so the camera frames the scene there, and to keep the spec's tabs, property pages, sidebar footer and assistant panel while moving them, mount \`LayoutSlots.DesktopSidebar\` (same import) in a positioned container that sets its size, with \`side="start"\` when it is on the left
25
25
  - \`src/handlers/\` — Event & lifecycle handlers
26
26
  - \`src/webhooks/\` — Server-side webhook handlers (\`phx.webhooks.*Builder\`)
27
27
  - \`src/migrations/\` — Schema version migrations (v*.ts)
@@ -12,12 +12,14 @@ export declare const useConfiguratorRawAccessService: () => AccessService | null
12
12
  export declare const useAdminRawAccessService: () => AccessService | null;
13
13
  export declare const useConfiguratorRawAccessInfo: () => {
14
14
  raw: string;
15
+ access: import("@salsita-ai/contracts/api").AccessLevel;
15
16
  viewMode: boolean;
16
17
  revisionId: string | undefined;
17
18
  configurationId: string;
18
19
  } | null;
19
20
  export declare const useAdminRawAccessInfo: () => {
20
21
  raw: string;
22
+ access: import("@salsita-ai/contracts/api").AccessLevel;
21
23
  viewMode: boolean;
22
24
  revisionId: string | undefined;
23
25
  configurationId: string;
@@ -1 +1 @@
1
- import{memoOnce as e}from"@salsita-ai/common/utils";import{createDomainRuntime as t,createMockDomainRuntimeServices as o,createMockSessionContext as n}from"#package/domain";import{createCommonServicesSelectors as s}from"../common-services/index.js";import{createDomainApplicationContextSelectors as i}from"../domain-application-context/index.js";import{createIntegrationActions as a,createIntegrationSelectors as r,initializeIntegration as c}from"../integration/index.js";import{createRoutingActions as m,createRoutingSelectors as d,initializeRouting as p}from"../routing/index.js";import{SessionService as l,createSessionRuntimeActions as S,createSessionRuntimeSelectors as g,initializeSessionRuntime as v}from"../session/index.js";import{createMockWebComponentApi as u}from"../web-component/index.js";export const createMockApplicationRuntime=(f,C)=>{var x;let b,y,w,A,D,k,E,I,h,j,R,T,O,L,F,{sessionData:M,mode:U,role:V}=C,z=o(),q=(x={webComponentOptions:C.webComponentOptions??f.mount.options,webComponentApi:C.webComponentApi??u()},w=v(),A=t({config:f,services:z,getExtensionSystems:e=>F[e].getInitializableSystems()}),D=new Set,k=()=>{D.forEach(e=>{e()})},b=c({actions:E=a({setIntegration:e=>{b=e(b),k()}})}),I=r({getState:()=>({integration:b})}),h=m({setRouting:e=>{y=e(y),k()}}),y=p(),j=d({getState:()=>({...A.getState(),routing:y}),actions:h,accessActions:A.actions.access,loadedDataActions:A.actions.loadedData,domainServicesSelectors:A.selectors.domainServices,overridesSelectors:A.selectors.overrides}),R=s({getState:()=>({...A.getState(),session:w}),environmentSelectors:A.selectors.environment,specSelectors:A.selectors.spec,accessSelectors:A.selectors.access,domainServicesSelectors:A.selectors.domainServices,webComponentOptions:x.webComponentOptions,webComponentApi:x.webComponentApi,getSessionService:()=>L(),routingSelectors:j}),T=S({setSessionRuntime:e=>{w=e(w),k()}}),O=g({getState:()=>({...A.getState(),session:w}),sessionContextSelectors:A.selectors.sessionContext}),L=e(()=>new l({getLogger:()=>A.selectors.domainServices.getLogger(),getAnalyticsService:()=>A.selectors.domainServices.getAnalyticsService(),getUnauthenticatedClient:R.getUnauthenticatedClient,environmentSelectors:A.selectors.environment,sessionActions:T,setSessionContext:A.actions.sessionContext.setSessionContext,sessionSelectors:O,specSelectors:A.selectors.spec})),F={configurator:i({applicationType:"configurator",commonServicesSelectors:R,domainServicesSelectors:A.selectors.domainServices,domainContextSelectors:A.selectors.domainContext.configurator,getApplicationRuntimeExtensions:()=>[]}),admin:i({applicationType:"admin",commonServicesSelectors:R,domainServicesSelectors:A.selectors.domainServices,domainContextSelectors:A.selectors.domainContext.admin,getApplicationRuntimeExtensions:()=>[]})},{subscribe:e=>{D.add(e);let t=A.subscribe(e);return()=>{D.delete(e),t()}},getState:()=>({...A.getState(),integration:b,routing:y,session:w}),selectors:{...A.selectors,commonServices:R,integration:I,routing:j,session:O,domainApplicationContext:F},actions:{...A.actions,integration:E,routing:h,session:T}}),B=q.getState().spec;return q.actions.spec.updateSpec({...B,configurator:{...B.configurator,createTransformers:e=>C.transformers.map(t=>t.transformer.register(e,t.priority??1/0))}}),q.actions.sessionContext.setSessionContext(n(V,M)),q.actions.access.setConfiguratorAccessInfo({raw:"mock-access-token",viewMode:"read"===U,revisionId:void 0,configurationId:"mock"}),q.actions.domainData.setDomainData({publishedData:C.publishedData,frontendData:C.frontendData,backendData:C.backendData}),q.actions.loadedData.completeConfiguratorLoad({initialRevisionId:"mock-revision",initialEntities:C.entities,modelVersion:f.domain.domainFactory.modelVersion,rootEntityType:C.rootEntityType,schemaIdentity:f.domain.domainFactory}),q};
1
+ import{memoOnce as e}from"@salsita-ai/common/utils";import{AccessLevel as t}from"@salsita-ai/contracts/api";import{createDomainRuntime as o,createMockDomainRuntimeServices as n,createMockSessionContext as s}from"#package/domain";import{createCommonServicesSelectors as i}from"../common-services/index.js";import{createDomainApplicationContextSelectors as a}from"../domain-application-context/index.js";import{createIntegrationActions as r,createIntegrationSelectors as c,initializeIntegration as m}from"../integration/index.js";import{createRoutingActions as d,createRoutingSelectors as p,initializeRouting as l}from"../routing/index.js";import{SessionService as S,createSessionRuntimeActions as g,createSessionRuntimeSelectors as v,initializeSessionRuntime as u}from"../session/index.js";import{createMockWebComponentApi as f}from"../web-component/index.js";export const createMockApplicationRuntime=(C,x)=>{var b;let w,y,A,D,k,E,I,R,h,j,O,T,L,F,M,{sessionData:U,mode:V,role:z}=x,q=n(),B=(b={webComponentOptions:x.webComponentOptions??C.mount.options,webComponentApi:x.webComponentApi??f()},A=u(),D=o({config:C,services:q,getExtensionSystems:e=>M[e].getInitializableSystems()}),k=new Set,E=()=>{k.forEach(e=>{e()})},w=m({actions:I=r({setIntegration:e=>{w=e(w),E()}})}),R=c({getState:()=>({integration:w})}),h=d({setRouting:e=>{y=e(y),E()}}),y=l(),j=p({getState:()=>({...D.getState(),routing:y}),actions:h,accessActions:D.actions.access,loadedDataActions:D.actions.loadedData,domainServicesSelectors:D.selectors.domainServices,overridesSelectors:D.selectors.overrides}),O=i({getState:()=>({...D.getState(),session:A}),environmentSelectors:D.selectors.environment,specSelectors:D.selectors.spec,accessSelectors:D.selectors.access,domainServicesSelectors:D.selectors.domainServices,webComponentOptions:b.webComponentOptions,webComponentApi:b.webComponentApi,getSessionService:()=>F(),routingSelectors:j}),T=g({setSessionRuntime:e=>{A=e(A),E()}}),L=v({getState:()=>({...D.getState(),session:A}),sessionContextSelectors:D.selectors.sessionContext}),F=e(()=>new S({getLogger:()=>D.selectors.domainServices.getLogger(),getAnalyticsService:()=>D.selectors.domainServices.getAnalyticsService(),getUnauthenticatedClient:O.getUnauthenticatedClient,environmentSelectors:D.selectors.environment,sessionActions:T,setSessionContext:D.actions.sessionContext.setSessionContext,sessionSelectors:L,specSelectors:D.selectors.spec})),M={configurator:a({applicationType:"configurator",commonServicesSelectors:O,domainServicesSelectors:D.selectors.domainServices,domainContextSelectors:D.selectors.domainContext.configurator,getApplicationRuntimeExtensions:()=>[]}),admin:a({applicationType:"admin",commonServicesSelectors:O,domainServicesSelectors:D.selectors.domainServices,domainContextSelectors:D.selectors.domainContext.admin,getApplicationRuntimeExtensions:()=>[]})},{subscribe:e=>{k.add(e);let t=D.subscribe(e);return()=>{k.delete(e),t()}},getState:()=>({...D.getState(),integration:w,routing:y,session:A}),selectors:{...D.selectors,commonServices:O,integration:R,routing:j,session:L,domainApplicationContext:M},actions:{...D.actions,integration:I,routing:h,session:T}}),G=B.getState().spec;return B.actions.spec.updateSpec({...G,configurator:{...G.configurator,createTransformers:e=>x.transformers.map(t=>t.transformer.register(e,t.priority??1/0))}}),B.actions.sessionContext.setSessionContext(s(z,U)),B.actions.access.setConfiguratorAccessInfo({raw:"mock-access-token",access:"read"===V?t.Read:t.Owner,viewMode:"read"===V,revisionId:void 0,configurationId:"mock"}),B.actions.domainData.setDomainData({publishedData:x.publishedData,frontendData:x.frontendData,backendData:x.backendData}),B.actions.loadedData.completeConfiguratorLoad({initialRevisionId:"mock-revision",initialEntities:x.entities,modelVersion:C.domain.domainFactory.modelVersion,rootEntityType:x.rootEntityType,schemaIdentity:C.domain.domainFactory}),B};
@@ -3,6 +3,7 @@ export declare const getAccessTokenFromLocalStorage: (configurationId: string) =
3
3
  export declare const removeAccessTokenFromLocalStorage: (configurationId: string) => void;
4
4
  export declare const getAccessInfo: (configurationId: string, accessToken?: string) => {
5
5
  raw: string;
6
+ access: import("@salsita-ai/contracts/api").AccessLevel;
6
7
  viewMode: boolean;
7
8
  revisionId: string | undefined;
8
9
  configurationId: string;
@@ -36,6 +36,7 @@ interface Props<State extends ApplicationRuntimeState, CONFIGURATOR_EXTENSIONS e
36
36
  * `createDomainRuntimeSlices`, which this composes.
37
37
  */
38
38
  export declare function createApplicationRuntimeSlices<State extends ApplicationRuntimeState, CONFIGURATOR_EXTENSIONS extends readonly AnyApplicationRuntimeExtension[]>(props: Props<State, CONFIGURATOR_EXTENSIONS>): {
39
+ getState: () => State;
39
40
  initialize: () => {
40
41
  spec: import("#package/domain").ApplicationSpec;
41
42
  overrides: import("#package/domain").ApplicationOverrides;
@@ -278,24 +279,28 @@ export declare function createApplicationRuntimeSlices<State extends Application
278
279
  access: {
279
280
  selectConfiguratorRawAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
280
281
  raw: string;
282
+ access: import("@salsita-ai/contracts/api").AccessLevel;
281
283
  viewMode: boolean;
282
284
  revisionId: string | undefined;
283
285
  configurationId: string;
284
286
  } | null>;
285
287
  selectAdminRawAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
286
288
  raw: string;
289
+ access: import("@salsita-ai/contracts/api").AccessLevel;
287
290
  viewMode: boolean;
288
291
  revisionId: string | undefined;
289
292
  configurationId: string;
290
293
  } | null>;
291
294
  selectConfiguratorAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
292
295
  raw: string;
296
+ access: import("@salsita-ai/contracts/api").AccessLevel;
293
297
  viewMode: boolean;
294
298
  revisionId: string | undefined;
295
299
  configurationId: string;
296
300
  }>;
297
301
  selectAdminAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
298
302
  raw: string;
303
+ access: import("@salsita-ai/contracts/api").AccessLevel;
299
304
  viewMode: boolean;
300
305
  revisionId: string | undefined;
301
306
  configurationId: string;
@@ -308,24 +313,28 @@ export declare function createApplicationRuntimeSlices<State extends Application
308
313
  selectAdminConfigurationId: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, string>;
309
314
  getConfiguratorRawAccessInfo: () => {
310
315
  raw: string;
316
+ access: import("@salsita-ai/contracts/api").AccessLevel;
311
317
  viewMode: boolean;
312
318
  revisionId: string | undefined;
313
319
  configurationId: string;
314
320
  } | null;
315
321
  getAdminRawAccessInfo: () => {
316
322
  raw: string;
323
+ access: import("@salsita-ai/contracts/api").AccessLevel;
317
324
  viewMode: boolean;
318
325
  revisionId: string | undefined;
319
326
  configurationId: string;
320
327
  } | null;
321
328
  getConfiguratorAccessInfo: () => {
322
329
  raw: string;
330
+ access: import("@salsita-ai/contracts/api").AccessLevel;
323
331
  viewMode: boolean;
324
332
  revisionId: string | undefined;
325
333
  configurationId: string;
326
334
  };
327
335
  getAdminAccessInfo: () => {
328
336
  raw: string;
337
+ access: import("@salsita-ai/contracts/api").AccessLevel;
329
338
  viewMode: boolean;
330
339
  revisionId: string | undefined;
331
340
  configurationId: string;
@@ -938,24 +947,28 @@ declare const createApplicationRuntimeImpl: <EXTENSIONS extends readonly AnyAppl
938
947
  access: {
939
948
  selectConfiguratorRawAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
940
949
  raw: string;
950
+ access: import("@salsita-ai/contracts/api").AccessLevel;
941
951
  viewMode: boolean;
942
952
  revisionId: string | undefined;
943
953
  configurationId: string;
944
954
  } | null>;
945
955
  selectAdminRawAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
946
956
  raw: string;
957
+ access: import("@salsita-ai/contracts/api").AccessLevel;
947
958
  viewMode: boolean;
948
959
  revisionId: string | undefined;
949
960
  configurationId: string;
950
961
  } | null>;
951
962
  selectConfiguratorAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
952
963
  raw: string;
964
+ access: import("@salsita-ai/contracts/api").AccessLevel;
953
965
  viewMode: boolean;
954
966
  revisionId: string | undefined;
955
967
  configurationId: string;
956
968
  }>;
957
969
  selectAdminAccessInfo: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, {
958
970
  raw: string;
971
+ access: import("@salsita-ai/contracts/api").AccessLevel;
959
972
  viewMode: boolean;
960
973
  revisionId: string | undefined;
961
974
  configurationId: string;
@@ -968,24 +981,28 @@ declare const createApplicationRuntimeImpl: <EXTENSIONS extends readonly AnyAppl
968
981
  selectAdminConfigurationId: import("@salsita-ai/common/utils").Selector<import("#package/domain").AccessSelectorState, string>;
969
982
  getConfiguratorRawAccessInfo: () => {
970
983
  raw: string;
984
+ access: import("@salsita-ai/contracts/api").AccessLevel;
971
985
  viewMode: boolean;
972
986
  revisionId: string | undefined;
973
987
  configurationId: string;
974
988
  } | null;
975
989
  getAdminRawAccessInfo: () => {
976
990
  raw: string;
991
+ access: import("@salsita-ai/contracts/api").AccessLevel;
977
992
  viewMode: boolean;
978
993
  revisionId: string | undefined;
979
994
  configurationId: string;
980
995
  } | null;
981
996
  getConfiguratorAccessInfo: () => {
982
997
  raw: string;
998
+ access: import("@salsita-ai/contracts/api").AccessLevel;
983
999
  viewMode: boolean;
984
1000
  revisionId: string | undefined;
985
1001
  configurationId: string;
986
1002
  };
987
1003
  getAdminAccessInfo: () => {
988
1004
  raw: string;
1005
+ access: import("@salsita-ai/contracts/api").AccessLevel;
989
1006
  viewMode: boolean;
990
1007
  revisionId: string | undefined;
991
1008
  configurationId: string;
@@ -1 +1 @@
1
- import{BehaviorSubject as e}from"rxjs";import{memoOnce as t}from"@salsita-ai/common/utils";import{createDomainRuntimeSlices as i,resolveIsDev as n}from"#package/domain";import{initializeAnalyticsService as o}from"../common-services/analytics/analytics-service.js";import{initializeI18n as s,initializeLogger as r}from"../common-services/initialize.js";import{createCommonServicesSelectors as a}from"../common-services/selectors.js";import{createDomainApplicationContextSelectors as c}from"../domain-application-context/index.js";import{createIntegrationActions as m,createIntegrationSelectors as l,initializeIntegration as p}from"../integration/index.js";import{createRoutingActions as u,createRoutingSelectors as d,initializeRouting as g}from"../routing/index.js";import{SessionService as S,createSessionRuntimeActions as v,createSessionRuntimeSelectors as x,initializeSessionRuntime as f}from"../session/index.js";import{registerGodModeGlobal as C}from"./god-mode.js";export function createApplicationRuntimeSlices(e){let{config:y,bootConfig:A,getSubject:b,getConfiguratorExtensions:j}=e,w=n(y),R=r(y,w),I={analyticsService:o(y,R,w),i18n:s(y),logger:R},{initialize:E,selectors:h,actions:z}=i({config:y,services:I,getSubject:b,getExtensionSystems:e=>J[e].getInitializableSystems()}),D=E(),T=m({setIntegration:e=>{let t=b(),i=e(t.value.integration);t.next({...t.value,integration:i})}}),L=l({getState:()=>b().value}),O=p({actions:T}),U=u({setRouting:e=>{let t=b(),i=e(t.value.routing);t.next({...t.value,routing:i})}}),k=d({getState:()=>b().value,actions:U,accessActions:z.access,loadedDataActions:z.loadedData,domainServicesSelectors:h.domainServices,overridesSelectors:h.overrides}),G=g(),$=a({getState:()=>b().value,environmentSelectors:h.environment,specSelectors:h.spec,accessSelectors:h.access,domainServicesSelectors:h.domainServices,webComponentOptions:A.webComponentOptions,webComponentApi:A.webComponentApi,getSessionService:()=>H(),routingSelectors:k}),q=v({setSessionRuntime:e=>{let t=b(),i=e(t.value.session);t.next({...t.value,session:i})}}),B=x({getState:()=>b().value,sessionContextSelectors:h.sessionContext}),F=f(),H=t(()=>new S({getLogger:()=>h.domainServices.getLogger(),getAnalyticsService:()=>h.domainServices.getAnalyticsService(),getUnauthenticatedClient:$.getUnauthenticatedClient,environmentSelectors:h.environment,sessionActions:q,setSessionContext:z.sessionContext.setSessionContext,sessionSelectors:B,specSelectors:h.spec})),J={configurator:c({applicationType:"configurator",commonServicesSelectors:$,domainServicesSelectors:h.domainServices,domainContextSelectors:h.domainContext.configurator,getApplicationRuntimeExtensions:j}),admin:c({applicationType:"admin",commonServicesSelectors:$,domainServicesSelectors:h.domainServices,domainContextSelectors:h.domainContext.admin,getApplicationRuntimeExtensions:()=>[]})};return C({environmentActions:z.environment}),R.info(`Configurator Application loaded with deployment ID: ${y.deploymentId}!`),R.appendToGlobalContext({deploymentId:y.deploymentId}),{initialize:()=>({...D,integration:O,routing:G,session:F}),selectors:{...h,commonServices:$,integration:L,routing:k,session:B,domainApplicationContext:J},actions:{...z,integration:T,routing:U,session:q}}}export function createApplicationRuntime(t,i,n){return((t,i,n)=>{let o=null,s=null,r=()=>{if(!o)throw Error("Subject not yet initialized!");return o},{initialize:a,...c}=createApplicationRuntimeSlices({config:t,bootConfig:i,getSubject:r,getConfiguratorExtensions:()=>s});return s=n?n(c):[],c.selectors.domainApplicationContext.configurator.getSystems(),o=new e(a()),{...c,getState:()=>r().value,subscribe:e=>{let t=r().subscribe(()=>e());return()=>t.unsubscribe()}}})(t,i,n)}
1
+ import{BehaviorSubject as e}from"rxjs";import{memoOnce as t}from"@salsita-ai/common/utils";import{createDomainRuntimeSlices as i,resolveIsDev as n}from"#package/domain";import{initializeAnalyticsService as o}from"../common-services/analytics/analytics-service.js";import{initializeI18n as s,initializeLogger as r}from"../common-services/initialize.js";import{createCommonServicesSelectors as a}from"../common-services/selectors.js";import{createDomainApplicationContextSelectors as c}from"../domain-application-context/index.js";import{createIntegrationActions as m,createIntegrationSelectors as l,initializeIntegration as p}from"../integration/index.js";import{createRoutingActions as u,createRoutingSelectors as d,initializeRouting as g}from"../routing/index.js";import{SessionService as S,createSessionRuntimeActions as v,createSessionRuntimeSelectors as x,initializeSessionRuntime as f}from"../session/index.js";import{registerGodModeGlobal as C}from"./god-mode.js";export function createApplicationRuntimeSlices(e){let{config:y,bootConfig:A,getSubject:b,getConfiguratorExtensions:j}=e,w=n(y),R=r(y,w),I={analyticsService:o(y,R,w),i18n:s(y),logger:R},{initialize:E,selectors:h,actions:z}=i({config:y,services:I,getSubject:b,getExtensionSystems:e=>J[e].getInitializableSystems()}),D=E(),T=m({setIntegration:e=>{let t=b(),i=e(t.value.integration);t.next({...t.value,integration:i})}}),L=l({getState:()=>b().value}),O=p({actions:T}),U=u({setRouting:e=>{let t=b(),i=e(t.value.routing);t.next({...t.value,routing:i})}}),k=d({getState:()=>b().value,actions:U,accessActions:z.access,loadedDataActions:z.loadedData,domainServicesSelectors:h.domainServices,overridesSelectors:h.overrides}),G=g(),$=a({getState:()=>b().value,environmentSelectors:h.environment,specSelectors:h.spec,accessSelectors:h.access,domainServicesSelectors:h.domainServices,webComponentOptions:A.webComponentOptions,webComponentApi:A.webComponentApi,getSessionService:()=>H(),routingSelectors:k}),q=v({setSessionRuntime:e=>{let t=b(),i=e(t.value.session);t.next({...t.value,session:i})}}),B=x({getState:()=>b().value,sessionContextSelectors:h.sessionContext}),F=f(),H=t(()=>new S({getLogger:()=>h.domainServices.getLogger(),getAnalyticsService:()=>h.domainServices.getAnalyticsService(),getUnauthenticatedClient:$.getUnauthenticatedClient,environmentSelectors:h.environment,sessionActions:q,setSessionContext:z.sessionContext.setSessionContext,sessionSelectors:B,specSelectors:h.spec})),J={configurator:c({applicationType:"configurator",commonServicesSelectors:$,domainServicesSelectors:h.domainServices,domainContextSelectors:h.domainContext.configurator,getApplicationRuntimeExtensions:j}),admin:c({applicationType:"admin",commonServicesSelectors:$,domainServicesSelectors:h.domainServices,domainContextSelectors:h.domainContext.admin,getApplicationRuntimeExtensions:()=>[]})};return C({environmentActions:z.environment}),R.info(`Configurator Application loaded with deployment ID: ${y.deploymentId}!`),R.appendToGlobalContext({deploymentId:y.deploymentId}),{getState:()=>b().value,initialize:()=>({...D,integration:O,routing:G,session:F}),selectors:{...h,commonServices:$,integration:L,routing:k,session:B,domainApplicationContext:J},actions:{...z,integration:T,routing:U,session:q}}}export function createApplicationRuntime(t,i,n){return((t,i,n)=>{let o=null,s=null,r=()=>{if(!o)throw Error("Subject not yet initialized!");return o},{initialize:a,...c}=createApplicationRuntimeSlices({config:t,bootConfig:i,getSubject:r,getConfiguratorExtensions:()=>s});return s=n?n(c):[],c.selectors.domainApplicationContext.configurator.getSystems(),o=new e(a()),{...c,getState:()=>r().value,subscribe:e=>{let t=r().subscribe(()=>e());return()=>t.unsubscribe()}}})(t,i,n)}
@@ -7,7 +7,7 @@ export { useCommittedState, useCommittedSlice, useRenderedSlice, useRenderedStat
7
7
  export { useDomainEntityState, useDomainEntityRenderedState, type UseDomainEntityState, } from './entity-hooks/use-domain-entity-state.js';
8
8
  export { useEntityPrice, useRootEntityPrice, type UseEntityPrice, type UseRootEntityPrice, } from './entity-hooks/use-entity-price.js';
9
9
  export { useSelectEntity, type UseSelectEntity, useSelectedEntity, type UseSelectedEntity, useSelectedEntityId, type UseSelectedEntityId, useSelectedDomainEntityId, type UseSelectedDomainEntityId, useDeselect, type UseDeselect, useSelectParent, type UseSelectParent, } from './system-hooks/selection-hooks.js';
10
- export { useActiveNavigationState, type UseActiveNavigationState, useActiveViewState, type UseActiveViewState, useActiveToolState, type UseActiveToolState, useIsFullscreenActive, type UseIsFullscreenActive, useActiveViewports, type UseActiveViewports, useDraggedDomainEntityId, type UseDraggedDomainEntityId, useNavigate, type UseNavigate, usePushNavigate, type UsePushNavigate, usePopNavigate, type UsePopNavigate, } from './system-hooks/navigation-hooks.js';
10
+ export { useActiveNavigationState, type UseActiveNavigationState, useActiveViewState, type UseActiveViewState, useActiveToolState, type UseActiveToolState, useIsFullscreenActive, type UseIsFullscreenActive, useSetFullscreen, type UseSetFullscreen, useActiveViewports, type UseActiveViewports, useDraggedDomainEntityId, type UseDraggedDomainEntityId, useNavigate, type UseNavigate, usePushNavigate, type UsePushNavigate, usePopNavigate, type UsePopNavigate, } from './system-hooks/navigation-hooks.js';
11
11
  export { useComposition, type UseComposition } from './system-hooks/composition-hooks.js';
12
12
  export { useHoveredDomainEntityId, useHoveredEntity, useHoveredEntityId, type UseHoveredDomainEntityId, type UseHoveredEntity, type UseHoveredEntityId, } from './system-hooks/hover-hooks.js';
13
13
  export { type UseRootEntityState, useRootEntityState, useRootEntityRenderedState, } from './entity-hooks/use-root-entity-state.js';
@@ -1 +1 @@
1
- export{useDomain}from"./common-hooks/use-domain-context.js";export{useStoreSelector,useRenderedSelector,useRenderedSelector$,useStoreSelector$}from"./common-hooks/use-store-selector.js";export{useEagerObservableSelector,usePatientObservableSelector,usePatientObservableValue,useEagerObservableValue}from"./common-hooks/use-observable-selector.js";export{useStateValidity,useMapViolationHints,useControlViolations,useFinalizeViolations}from"./common-hooks/use-state-validity.js";export{useComponent,useRenderedComponent,useComponents,useDynamicComponents,useRenderedComponents,useRootComponents,useRootRenderedComponents,useFirstComponent,useFirstRenderedComponent,useFirstRootComponent,useFirstRootRenderedComponent}from"./component-hooks/use-component.js";export{useCommittedState,useCommittedSlice,useRenderedSlice,useRenderedState}from"./common-hooks/use-slices.js";export{useDomainEntityState,useDomainEntityRenderedState}from"./entity-hooks/use-domain-entity-state.js";export{useEntityPrice,useRootEntityPrice}from"./entity-hooks/use-entity-price.js";export{useSelectEntity,useSelectedEntity,useSelectedEntityId,useSelectedDomainEntityId,useDeselect,useSelectParent}from"./system-hooks/selection-hooks.js";export{useActiveNavigationState,useActiveViewState,useActiveToolState,useIsFullscreenActive,useActiveViewports,useDraggedDomainEntityId,useNavigate,usePushNavigate,usePopNavigate}from"./system-hooks/navigation-hooks.js";export{useComposition}from"./system-hooks/composition-hooks.js";export{useHoveredDomainEntityId,useHoveredEntity,useHoveredEntityId}from"./system-hooks/hover-hooks.js";export{useRootEntityState,useRootEntityRenderedState}from"./entity-hooks/use-root-entity-state.js";export{useRootEntityId,useRootEntityRenderedId}from"./entity-hooks/use-root-entity-id.js";export{useEntitySelector,useRootEntitySelector,useRenderedEntitySelector,useRenderedRootEntitySelector}from"./common-hooks/use-entity-selector.js";export{useDimensionState,useDimensions,useDimensionConfig}from"./system-hooks/dimension-hooks.js";
1
+ export{useDomain}from"./common-hooks/use-domain-context.js";export{useStoreSelector,useRenderedSelector,useRenderedSelector$,useStoreSelector$}from"./common-hooks/use-store-selector.js";export{useEagerObservableSelector,usePatientObservableSelector,usePatientObservableValue,useEagerObservableValue}from"./common-hooks/use-observable-selector.js";export{useStateValidity,useMapViolationHints,useControlViolations,useFinalizeViolations}from"./common-hooks/use-state-validity.js";export{useComponent,useRenderedComponent,useComponents,useDynamicComponents,useRenderedComponents,useRootComponents,useRootRenderedComponents,useFirstComponent,useFirstRenderedComponent,useFirstRootComponent,useFirstRootRenderedComponent}from"./component-hooks/use-component.js";export{useCommittedState,useCommittedSlice,useRenderedSlice,useRenderedState}from"./common-hooks/use-slices.js";export{useDomainEntityState,useDomainEntityRenderedState}from"./entity-hooks/use-domain-entity-state.js";export{useEntityPrice,useRootEntityPrice}from"./entity-hooks/use-entity-price.js";export{useSelectEntity,useSelectedEntity,useSelectedEntityId,useSelectedDomainEntityId,useDeselect,useSelectParent}from"./system-hooks/selection-hooks.js";export{useActiveNavigationState,useActiveViewState,useActiveToolState,useIsFullscreenActive,useSetFullscreen,useActiveViewports,useDraggedDomainEntityId,useNavigate,usePushNavigate,usePopNavigate}from"./system-hooks/navigation-hooks.js";export{useComposition}from"./system-hooks/composition-hooks.js";export{useHoveredDomainEntityId,useHoveredEntity,useHoveredEntityId}from"./system-hooks/hover-hooks.js";export{useRootEntityState,useRootEntityRenderedState}from"./entity-hooks/use-root-entity-state.js";export{useRootEntityId,useRootEntityRenderedId}from"./entity-hooks/use-root-entity-id.js";export{useEntitySelector,useRootEntitySelector,useRenderedEntitySelector,useRenderedRootEntitySelector}from"./common-hooks/use-entity-selector.js";export{useDimensionState,useDimensions,useDimensionConfig}from"./system-hooks/dimension-hooks.js";
@@ -19,6 +19,12 @@ export type UseIsFullscreenActive = () => boolean;
19
19
  * Get the currently active fullscreen state
20
20
  */
21
21
  export declare const useIsFullscreenActive: () => boolean;
22
+ export type UseSetFullscreen = () => (enabled: boolean) => void;
23
+ /**
24
+ * Hook to turn the fullscreen state on or off. The state is a flag the layout reads with `useIsFullscreenActive`;
25
+ * it does not put the browser into fullscreen
26
+ */
27
+ export declare const useSetFullscreen: () => (enabled: boolean) => void;
22
28
  export type UseDraggedDomainEntityId = () => DomainEntityId<string> | null;
23
29
  /**
24
30
  * Get the id of the entity currently being dragged in the scene, or `null` while nothing is dragged