@salsita-ai/sdk 0.50.0-develop.da8d27f5d7 → 0.50.0-develop.ea458ea381

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 (146) hide show
  1. package/dist/application-spec/errors/diagnostic-codes.d.ts +6 -0
  2. package/dist/application-spec/errors/diagnostic-codes.js +1 -1
  3. package/dist/application-spec/errors/diagnostic-messages.d.ts +6 -0
  4. package/dist/application-spec/errors/diagnostic-messages.js +1 -1
  5. package/dist/application-spec/generate-application/code/domain-runtime-files.js +1 -1
  6. package/dist/application-spec/generate-application/code/templates/application-types.js +6 -6
  7. package/dist/application-spec/generate-application/code/templates/configurator-domain-code.d.ts +1 -0
  8. package/dist/application-spec/generate-application/code/templates/configurator-domain-code.js +11 -8
  9. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.d.ts +3 -1
  10. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.js +70 -66
  11. package/dist/application-spec/generate-application/code/templates/domain-spec/generate-phx-globals.js +3 -0
  12. package/dist/application-spec/generate-application/code/templates/domain-spec.js +5 -5
  13. package/dist/application-spec/generate-application/code/templates/domain.js +2 -2
  14. package/dist/application-spec/generate-application/code/templates/global-definition/generate-action-types.d.ts +11 -0
  15. package/dist/application-spec/generate-application/code/templates/global-definition/generate-action-types.js +8 -0
  16. package/dist/application-spec/generate-application/code/templates/global-definition/index.d.ts +1 -0
  17. package/dist/application-spec/generate-application/code/templates/global-definition/index.js +1 -1
  18. package/dist/application-spec/generate-application/code/templates/globals.js +1 -0
  19. package/dist/application-spec/generate-application/code/templates/index.d.ts +6 -6
  20. package/dist/application-spec/generate-application/code/templates/index.js +1 -1
  21. package/dist/application-spec/generate-application/code/templates/skills/agents-md.js +2 -0
  22. package/dist/application-spec/generate-application/code/templates/skills/phoenix-cli-skill.js +1 -0
  23. package/dist/application-spec/generate-application/code/templates/{phoenix-create-configurator-skill.d.ts → skills/phoenix-create-configurator-skill.d.ts} +1 -1
  24. package/dist/application-spec/generate-application/code/templates/{phoenix-create-configurator-skill.js → skills/phoenix-create-configurator-skill.js} +1 -1
  25. package/dist/application-spec/generate-application/code/templates/{phoenix-feedback-skill.js → skills/phoenix-feedback-skill.js} +1 -1
  26. package/dist/application-spec/generate-application/code/templates/{phoenix-review-skill.js → skills/phoenix-review-skill.js} +6 -4
  27. package/dist/application-spec/generate-application/code/templates/skills/phoenix-skill.js +1 -0
  28. package/dist/application-spec/generate-application/code/templates/{common → skills}/sdk-content.d.ts +24 -1
  29. package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +67 -0
  30. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +2 -0
  31. package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
  32. package/dist/application-spec/generate-application/runtime/sections/actions-runtime.d.ts +14 -0
  33. package/dist/application-spec/generate-application/runtime/sections/actions-runtime.js +1 -0
  34. package/dist/application-spec/generate-application/runtime/sections/index.d.ts +1 -0
  35. package/dist/application-spec/generate-application/runtime/sections/index.js +1 -1
  36. package/dist/application-spec/parse-application-files/categorize/categorize-files.d.ts +3 -1
  37. package/dist/application-spec/parse-application-files/categorize/categorize-files.js +1 -1
  38. package/dist/application-spec/parse-application-files/merge/index.d.ts +1 -0
  39. package/dist/application-spec/parse-application-files/merge/index.js +1 -1
  40. package/dist/application-spec/parse-application-files/merge/merged-actions.d.ts +11 -0
  41. package/dist/application-spec/parse-application-files/merge/merged-actions.js +1 -0
  42. package/dist/application-spec/parse-application-files/merge/merged-spec.d.ts +2 -0
  43. package/dist/application-spec/parse-application-files/merge/merged-spec.js +1 -1
  44. package/dist/application-spec/parse-application-files/raw-spec/index.d.ts +1 -0
  45. package/dist/application-spec/parse-application-files/raw-spec/index.js +1 -1
  46. package/dist/application-spec/parse-application-files/raw-spec/raw-actions.d.ts +18 -0
  47. package/dist/application-spec/parse-application-files/raw-spec/raw-actions.js +1 -0
  48. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +14 -2
  49. package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
  50. package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.d.ts +2 -0
  51. package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.js +1 -1
  52. package/dist/application-spec/parse-application-files/resolve/resolve-import-modules.js +1 -1
  53. package/dist/application-spec/parse-application-files/spec/application/application-spec.js +1 -1
  54. package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.d.ts +4 -2
  55. package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.js +1 -1
  56. package/dist/application-spec/parse-application-files/spec/common/index.d.ts +1 -0
  57. package/dist/application-spec/parse-application-files/spec/common/index.js +1 -1
  58. package/dist/application-spec/parse-application-files/spec/common/schema-ref-resolver.d.ts +23 -0
  59. package/dist/application-spec/parse-application-files/spec/common/schema-ref-resolver.js +1 -0
  60. package/dist/application-spec/parse-application-files/spec/model/names/action-name.d.ts +10 -0
  61. package/dist/application-spec/parse-application-files/spec/model/names/action-name.js +1 -0
  62. package/dist/application-spec/parse-application-files/spec/model/names/index.d.ts +1 -0
  63. package/dist/application-spec/parse-application-files/spec/model/names/index.js +1 -1
  64. package/dist/application-spec/parse-application-files/spec/sections/actions.d.ts +35 -0
  65. package/dist/application-spec/parse-application-files/spec/sections/actions.js +1 -0
  66. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-field-type.d.ts +3 -14
  67. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-field-type.js +1 -1
  68. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.d.ts +12 -3
  69. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
  70. package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant.d.ts +5 -3
  71. package/dist/application-spec/parse-application-files/spec/sections/index.d.ts +1 -0
  72. package/dist/application-spec/parse-application-files/spec/sections/index.js +1 -1
  73. package/dist/client/phoenix-api.d.ts +5 -1
  74. package/dist/configurator/application-runtime/extensions/configurator-extension-systems.d.ts +2 -1
  75. package/dist/configurator/application-runtime/extensions/configurator-extension-systems.js +1 -1
  76. package/dist/configurator/application-runtime/extensions/selectors.d.ts +2 -1
  77. package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
  78. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +35 -0
  79. package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -0
  80. package/dist/configurator/{assistant → application-runtime/extensions/systems/assistant-system}/browser-details.d.ts +1 -1
  81. package/dist/configurator/application-runtime/extensions/systems/assistant-system/browser-details.js +1 -0
  82. package/dist/configurator/{assistant → application-runtime/extensions/systems/assistant-system}/graphql-tools.d.ts +13 -14
  83. package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -0
  84. package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
  85. package/dist/configurator/application-runtime/extensions/systems/index.d.ts +1 -0
  86. package/dist/configurator/application-runtime/extensions/systems/index.js +1 -1
  87. package/dist/configurator/assistant/use-assistant-chat.js +1 -1
  88. package/dist/docs/index.json +12 -2
  89. package/dist/docs/other-features/domain-actions.mdx +418 -0
  90. package/dist/docs/phoenix/best-practices.mdx +1 -0
  91. package/dist/docs/phoenix/migrations.mdx +45 -5
  92. package/dist/docs/phoenix/phoenix-cli.mdx +5 -3
  93. package/dist/docs/phoenix/project-structure.mdx +3 -0
  94. package/dist/docs/phoenix/sdk-builder-workflow.mdx +6 -4
  95. package/dist/domain/actions/action-factory.d.ts +10 -0
  96. package/dist/domain/actions/action-factory.js +1 -0
  97. package/dist/domain/actions/prepare-action-implementations.d.ts +15 -0
  98. package/dist/domain/actions/prepare-action-implementations.js +5 -0
  99. package/dist/domain/application/application-config.d.ts +3 -1
  100. package/dist/domain/application/assistant-mutations.d.ts +15 -14
  101. package/dist/domain/application/assistant-mutations.js +1 -1
  102. package/dist/domain/core/action.d.ts +67 -0
  103. package/dist/domain/core/action.js +1 -0
  104. package/dist/domain/core/domain-factory.d.ts +4 -0
  105. package/dist/domain/core/index.d.ts +1 -0
  106. package/dist/domain/domain-builder.d.ts +7 -0
  107. package/dist/domain/domain-builder.js +1 -1
  108. package/dist/domain/domain-context/action-system/action-system.d.ts +40 -0
  109. package/dist/domain/domain-context/action-system/action-system.js +1 -0
  110. package/dist/domain/domain-context/domain-context-systems.d.ts +5 -2
  111. package/dist/domain/domain-context/index.d.ts +1 -0
  112. package/dist/domain/domain-context/index.js +1 -1
  113. package/dist/domain/domain-runtime/domain-context/domain-context.js +1 -1
  114. package/dist/domain/domain-runtime/domain-context/selectors.d.ts +4 -0
  115. package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
  116. package/dist/domain/domain-runtime/domain-runtime.d.ts +12 -0
  117. package/dist/domain/domain-runtime/spec/initialize.js +1 -1
  118. package/dist/domain/domain-runtime/spec/types.d.ts +15 -1
  119. package/dist/domain/index.d.ts +2 -0
  120. package/dist/domain/index.js +1 -1
  121. package/dist/domain/mocks/create-mock-domain-runtime.d.ts +6 -0
  122. package/dist/editor/domain-editors/DomainSpecContext.js +1 -1
  123. package/dist/editor/domain-editors/apply-spec-update.js +1 -1
  124. package/dist/editor/domain-editors/use-implementation-files.d.ts +7 -3
  125. package/dist/editor/domain-editors/use-implementation-files.js +1 -1
  126. package/dist/phoenix/application-spec/generate-assistant-prompt.d.ts +2 -2
  127. package/dist/phoenix/application-spec/generate-assistant-prompt.js +1 -1
  128. package/dist/phoenix/commands/deploy.js +2 -2
  129. package/dist/phoenix/commands/login.d.ts +24 -6
  130. package/dist/phoenix/commands/login.js +2 -2
  131. package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +12 -0
  132. package/dist/react-sdk/domain-context/common-hooks/use-domain-context.d.ts +3 -0
  133. package/package.json +3 -3
  134. package/dist/application-spec/generate-application/code/templates/agents-md.js +0 -2
  135. package/dist/application-spec/generate-application/code/templates/common/sdk-content.js +0 -67
  136. package/dist/application-spec/generate-application/code/templates/phoenix-cli-skill.js +0 -1
  137. package/dist/application-spec/generate-application/code/templates/phoenix-skill.js +0 -1
  138. package/dist/configurator/assistant/browser-details.js +0 -1
  139. package/dist/configurator/assistant/graphql-tools.js +0 -1
  140. /package/dist/application-spec/generate-application/code/templates/{common → skills}/agent-skill.d.ts +0 -0
  141. /package/dist/application-spec/generate-application/code/templates/{common → skills}/agent-skill.js +0 -0
  142. /package/dist/application-spec/generate-application/code/templates/{agents-md.d.ts → skills/agents-md.d.ts} +0 -0
  143. /package/dist/application-spec/generate-application/code/templates/{phoenix-cli-skill.d.ts → skills/phoenix-cli-skill.d.ts} +0 -0
  144. /package/dist/application-spec/generate-application/code/templates/{phoenix-feedback-skill.d.ts → skills/phoenix-feedback-skill.d.ts} +0 -0
  145. /package/dist/application-spec/generate-application/code/templates/{phoenix-review-skill.d.ts → skills/phoenix-review-skill.d.ts} +0 -0
  146. /package/dist/application-spec/generate-application/code/templates/{phoenix-skill.d.ts → skills/phoenix-skill.d.ts} +0 -0
@@ -1,87 +1,90 @@
1
- import{skipApplicationTypeImports as e}from"../../common/index.js";import{generateComponentOpticsCode as n}from"./generate-component-optics.js";import{generateDefaultsBlock as t}from"./generate-defaults.js";import{generateInvariantsBlock as a}from"./generate-invariants.js";import{generateRelationExpressionsCode as i}from"./generate-relation-expressions.js";import{generateStaticValueCode as o}from"./generate-static-value-code.js";import{generateValueExpressionsCode as s}from"./generate-value-expressions.js";let r="@salsita-ai/sdk/domain",l=(e,n,t)=>{let a=[],i=[];for(let o of e.modelVersion.entitySchemas){let e=JSON.stringify(o.shapeSchema,null,2);a.push(`${t}const ${o.entityType} = new DomainEntityReflection<${n}${o.entityType}>('${o.entityType}', [${e}])`),i.push(String(o.entityType))}return{entityDecls:a.join("\n"),entityNames:i}};export const generateDomainBlock=m=>{let{domainSpec:$,invariants:p,typePrefix:d,versionNsPrefix:c,isAdmin:u,modelVersionsExportName:y,relationExpressionsExportName:h,componentOpticsExportName:f,valueExpressionsExportName:E,createRecipeExportName:D,imports:R,registerApplicationTypeImports:g=e}=m;R.addImport(r,"$DomainEntityReflection"),R.addImport(r,"DomainBuilder"),R.addImport(r,"DomainComponentOpticBuilder"),R.addImport(r,"DomainEntityReflection"),R.addImport(r,"EnhancedAliasReflection"),R.addImport(r,"InvariantBuilder"),R.addImport(r,"RawAliasReflection"),R.addImport(r,"SchemaReflection"),R.addImport(r,"createCustomExpressionFactory"),R.addImport(r,"createCustomInvariantFactory"),u&&(R.addImport(r,"commonAdminCustomExpressions"),R.addImport(r,"commonAdminViolationExpressions"),R.addImport(r,"createMapPublishedRevisionDataHandlerFactory"),R.addImport(r,"createMapPublishedChunkedDataHandlerFactory"),R.addImport(r,"createDataRowValidatorHandler"),R.addImport(r,"createSheetValidatorHandler")),R.addTypeImport(r,"SchemaOfObject");let{entityTypes:S,entitySchemas:v}=$.latestModel,x=[...$.latestModel.aliases],j=x.map(([e])=>String(e)),C=j.includes("RootEntity")?"RootEntity":"AnyDomainEntity",{resolvedVersions:I}=$,M=I.latestVersion,A=d?`${d}.`:"",B=new Map([...$.expressions.constants].map(([e,n])=>[String(e),n])),w=(e,n)=>{let t=[...B.get(n)?.keys()??[]],a=t.length>0?`, ${t.map(e=>`'${e}'`).join(" | ")}`:"";return`${e}<${A}$${n}${a}>`},b=e=>{let n=B.get(e);if(!n)return"{}";let t=[...n].map(([e,n])=>{let t=o(n,R).replaceAll("\n","\n ");return` ${e}: ${t},`});return`{
1
+ import{skipApplicationTypeImports as e}from"../../common/index.js";import{generateComponentOpticsCode as n}from"./generate-component-optics.js";import{generateDefaultsBlock as t}from"./generate-defaults.js";import{generateInvariantsBlock as i}from"./generate-invariants.js";import{generateRelationExpressionsCode as a}from"./generate-relation-expressions.js";import{generateStaticValueCode as o}from"./generate-static-value-code.js";import{generateValueExpressionsCode as s}from"./generate-value-expressions.js";let r="@salsita-ai/sdk/domain",m=(e,n,t)=>{let i=[],a=[];for(let o of e.modelVersion.entitySchemas){let e=JSON.stringify(o.shapeSchema,null,2);i.push(`${t}const ${o.entityType} = new DomainEntityReflection<${n}${o.entityType}>('${o.entityType}', [${e}])`),a.push(String(o.entityType))}return{entityDecls:i.join("\n"),entityNames:a}};export const generateDomainBlock=l=>{let{domainSpec:$,invariants:p,actions:c,typePrefix:d,versionNsPrefix:u,isAdmin:y,modelVersionsExportName:h,relationExpressionsExportName:f,componentOpticsExportName:D,valueExpressionsExportName:E,createRecipeExportName:S,imports:R,registerApplicationTypeImports:g=e}=l;R.addImport(r,"$DomainEntityReflection"),R.addImport(r,"DomainBuilder"),R.addImport(r,"DomainComponentOpticBuilder"),R.addImport(r,"DomainEntityReflection"),R.addImport(r,"EnhancedAliasReflection"),R.addImport(r,"InvariantBuilder"),R.addImport(r,"RawAliasReflection"),R.addImport(r,"SchemaReflection"),R.addImport(r,"createCustomExpressionFactory"),R.addImport(r,"createCustomInvariantFactory"),y&&(R.addImport(r,"commonAdminCustomExpressions"),R.addImport(r,"commonAdminViolationExpressions"),R.addImport(r,"createMapPublishedRevisionDataHandlerFactory"),R.addImport(r,"createMapPublishedChunkedDataHandlerFactory"),R.addImport(r,"createDataRowValidatorHandler"),R.addImport(r,"createSheetValidatorHandler")),R.addTypeImport(r,"SchemaOfObject"),c&&(R.addImport(r,"createActionFactory"),R.addTypeImport(r,"ActionDefinition"));let{entityTypes:v,entitySchemas:x}=$.latestModel,A=[...$.latestModel.aliases],j=A.map(([e])=>String(e)),C=j.includes("RootEntity")?"RootEntity":"AnyDomainEntity",{resolvedVersions:I}=$,M=I.latestVersion,w=d?`${d}.`:"",B=new Map([...$.expressions.constants].map(([e,n])=>[String(e),n])),b=(e,n)=>{let t=[...B.get(n)?.keys()??[]],i=t.length>0?`, ${t.map(e=>`'${e}'`).join(" | ")}`:"";return`${e}<${w}$${n}${i}>`},P=e=>{let n=B.get(e);if(!n)return"{}";let t=[...n].map(([e,n])=>{let t=o(n,R).replaceAll("\n","\n ");return` ${e}: ${t},`});return`{
2
2
  ${t.join("\n")}
3
- }`},P=v.map(e=>{let n=JSON.stringify(e.shapeSchema,null,2);return` const ${e.entityType} = new DomainEntityReflection<${A}${e.entityType}>('${e.entityType}', [${n}])`}),k=x.map(([e,n])=>{let t=n.map(String).join(", ");return` const ${e} = new RawAliasReflection<${A}${e}>('${e}', [${t}])`}),H=[...$.latestModel.commonTypes],F=H.map(([e])=>String(e)),O=I.versionedModels.filter(e=>!e.isLatest).map(e=>`${c}${e.version}`);g(R,[...u?["Admin",...O]:[...S.map(String),...j,...F,...S.map(e=>`$${String(e)}`),...j.map(e=>`$${e}`),"Aliases","$Map",...O],"PublishedData","SessionData","FrontendData",...u?[]:["BackendData"]]);let V=H.map(([e,n])=>{let t=JSON.stringify(n.runtimeSchema,null,2);return n.schema.enum?.length&&n.schema.enum.every(e=>"string"==typeof e)?` const ${e}: EnumLike<${A}${e}> = new EnumReflection('${e}', ${t}) as EnumLike<${A}${e}>`:` const ${e}: SchemaReflection<${A}${e}> = new SchemaReflection('${e}', ${t})`}),T=[...$.latestModel.shapes],J=T.map(([e,n])=>{let t=JSON.stringify(n.runtimeSchema,null,2);return` const ${e}Shape = new SchemaReflection('${e}Shape', ${t})`}),N=T.map(([e])=>`${e}Shape`),L=j.map(e=>` ${e}: ${e}.types,`).join("\n"),_=j.map(e=>` ${e},`).join("\n"),z=F.map(e=>` ${e},`).join("\n"),G=N.map(e=>` ${e},`).join("\n"),q=S.map(e=>` ${e},`).join("\n"),K=[];for(let[e,n]of $.expressions.expressions)n.size>0&&K.push(` const ${e}Expressions = ${JSON.stringify([...n.keys()])}`);let Q=S.map(e=>{let n=$.expressions.entityExpressions.get(e),t=(n?.shapeGroups??[]).map(e=>`${e}Expressions`),a=t.length>0?t.map(e=>`...${e}`).join(", "):"",i=w("$DomainEntityReflection",String(e));return` const $${e}: ${i} = new ${i}('${e}', [${a}], ${b(String(e))})`}).join("\n"),U=S.map(e=>` ${e}: $${e},`).join("\n"),W=x.map(([e,n])=>{let t=n.map(e=>JSON.stringify(String(e))).join(", "),a=w("EnhancedAliasReflection",String(e));return` const $${e}: ${a} = new ${a}('$${e}', [${t}], ${b(String(e))})`}).join("\n"),X=[...S.map(String),...j].map(e=>` $${e},`).join("\n"),Y=[],Z=[];for(let e of I.versionedModels)if(e.isLatest)Y.push(` ${e.version}: entities,`),Z.push(` readonly ${e.version}: {
4
- ${S.map(e=>` readonly ${String(e)}: DomainEntityReflection<${A}${String(e)}>`).join("\n")}
5
- }`);else{let n=`${c}${e.version}.`,{entityDecls:t,entityNames:a}=l(e,n," "),i=a.map(e=>` ${e},`).join("\n");Y.push(` ${e.version}: (() => {
3
+ }`},k=x.map(e=>{let n=JSON.stringify(e.shapeSchema,null,2);return` const ${e.entityType} = new DomainEntityReflection<${w}${e.entityType}>('${e.entityType}', [${n}])`}),F=A.map(([e,n])=>{let t=n.map(String).join(", ");return` const ${e} = new RawAliasReflection<${w}${e}>('${e}', [${t}])`}),H=[...$.latestModel.commonTypes],V=H.map(([e])=>String(e)),O=I.versionedModels.filter(e=>!e.isLatest).map(e=>`${u}${e.version}`);g(R,[...y?["Admin",...O]:[...v.map(String),...j,...V,...v.map(e=>`$${String(e)}`),...j.map(e=>`$${e}`),"Aliases","$Map",...O,...c?["ActionTypes","NavigationState","ViewState","ToolState","ExportState"]:[]],"PublishedData","SessionData","FrontendData",...y?[]:["BackendData"]]);let T=H.map(([e,n])=>{let t=JSON.stringify(n.runtimeSchema,null,2);return n.schema.enum?.length&&n.schema.enum.every(e=>"string"==typeof e)?` const ${e}: EnumLike<${w}${e}> = new EnumReflection('${e}', ${t}) as EnumLike<${w}${e}>`:` const ${e}: SchemaReflection<${w}${e}> = new SchemaReflection('${e}', ${t})`}),N=[...$.latestModel.shapes],J=N.map(([e,n])=>{let t=JSON.stringify(n.runtimeSchema,null,2);return` const ${e}Shape = new SchemaReflection('${e}Shape', ${t})`}),L=N.map(([e])=>`${e}Shape`),_=j.map(e=>` ${e}: ${e}.types,`).join("\n"),z=j.map(e=>` ${e},`).join("\n"),G=V.map(e=>` ${e},`).join("\n"),q=L.map(e=>` ${e},`).join("\n"),K=v.map(e=>` ${e},`).join("\n"),Q=[];for(let[e,n]of $.expressions.expressions)n.size>0&&Q.push(` const ${e}Expressions = ${JSON.stringify([...n.keys()])}`);let U=v.map(e=>{let n=$.expressions.entityExpressions.get(e),t=(n?.shapeGroups??[]).map(e=>`${e}Expressions`),i=t.length>0?t.map(e=>`...${e}`).join(", "):"",a=b("$DomainEntityReflection",String(e));return` const $${e}: ${a} = new ${a}('${e}', [${i}], ${P(String(e))})`}).join("\n"),W=v.map(e=>` ${e}: $${e},`).join("\n"),X=A.map(([e,n])=>{let t=n.map(e=>JSON.stringify(String(e))).join(", "),i=b("EnhancedAliasReflection",String(e));return` const $${e}: ${i} = new ${i}('$${e}', [${t}], ${P(String(e))})`}).join("\n"),Y=[...v.map(String),...j].map(e=>` $${e},`).join("\n"),Z=[],ee=[];for(let e of I.versionedModels)if(e.isLatest)Z.push(` ${e.version}: entities,`),ee.push(` readonly ${e.version}: {
4
+ ${v.map(e=>` readonly ${String(e)}: DomainEntityReflection<${w}${String(e)}>`).join("\n")}
5
+ }`);else{let n=`${u}${e.version}.`,{entityDecls:t,entityNames:i}=m(e,n," "),a=i.map(e=>` ${e},`).join("\n");Z.push(` ${e.version}: (() => {
6
6
  ${t}
7
7
  return {
8
- ${i}
8
+ ${a}
9
9
  } as const
10
- })(),`),Z.push(` readonly ${e.version}: {
11
- ${a.map(e=>` readonly ${e}: DomainEntityReflection<${n}${e}>`).join("\n")}
12
- }`)}let ee=u?"adminDomainBuilder":"domainBuilder",en=u?"attachAdminComponent":"attachComponent",et=u?"implementAdminCustomExpressions":"implementCustomExpressions",ea=u?"implementCustomAdminInvariants":"implementCustomInvariants",ei=u?"adminInvariantBuilder":"invariantBuilder",eo=u?"adminModel":"model",es=u?"adminEnhancedModel":"enhancedModel",er=u?"implementAdminRelation":"implementRelation",el=u?"__adminDomain":"__configuratorDomain",em=`${A}AnyDomainEntity, ${A}RootEntity, ${A}$Map, PublishedData, SessionData, FrontendData, ${A}Aliases`,e$=`<${em}>`,ep=a(p,em,R),ed=(e,n)=>e===n?e:`${e}: ${n}`,ec=[...$.expressions.expressions.values()].some(e=>[...e.values()].some(e=>"relation"===e.implementation.kind));ec&&R.addImport(r,"createRelationFactory");let eu=ec?`
13
- const ${er} = createRelationFactory${e$}(aliases)
14
-
15
- const relationExpressions = ${i($.expressions,er)}`:"\n const relationExpressions = {} as const",ey=`
16
- const componentOptics = ${n($.components,R)}`,eh=`
17
- const valueExpressions = ${s($.expressions,R,"implementCustomExpressions",u?{PresetCategory:"commonAdminCustomExpressions.PresetCategory"}:{})}`;R.addImport(r,"RecipeFactoryBuilder");let ef=t($.defaults,R),eE=`
18
- const createRecipe = RecipeFactoryBuilder.forAliases<${A}AnyDomainEntity, ${A}Aliases>(aliases)
10
+ })(),`),ee.push(` readonly ${e.version}: {
11
+ ${i.map(e=>` readonly ${e}: DomainEntityReflection<${n}${e}>`).join("\n")}
12
+ }`)}let en=y?"adminDomainBuilder":"domainBuilder",et=y?"attachAdminComponent":"attachComponent",ei=y?"implementAdminCustomExpressions":"implementCustomExpressions",ea=y?"implementCustomAdminInvariants":"implementCustomInvariants",eo=y?"adminInvariantBuilder":"invariantBuilder",es=y?"adminModel":"model",er=y?"adminEnhancedModel":"enhancedModel",em=y?"implementAdminRelation":"implementRelation",el=y?"__adminDomain":"__configuratorDomain",e$="PublishedData, SessionData, FrontendData",ep=`${w}AnyDomainEntity, ${w}RootEntity, ${w}$Map, ${e$}, ${w}Aliases`,ec=`<${ep}>`,ed=i(p,ep,R),eu=(e,n)=>e===n?e:`${e}: ${n}`,ey=[...$.expressions.expressions.values()].some(e=>[...e.values()].some(e=>"relation"===e.implementation.kind));ey&&R.addImport(r,"createRelationFactory");let eh=ey?`
13
+ const ${em} = createRelationFactory${ec}(aliases)
14
+
15
+ const relationExpressions = ${a($.expressions,em)}`:"\n const relationExpressions = {} as const",ef=`
16
+ const componentOptics = ${n($.components,R)}`,eD=`
17
+ const valueExpressions = ${s($.expressions,R,"implementCustomExpressions",y?{PresetCategory:"commonAdminCustomExpressions.PresetCategory"}:{})}`;R.addImport(r,"RecipeFactoryBuilder");let eE=t($.defaults,R),eS=[...c?.values()??[]].map(e=>({name:String(e.name),...void 0===e.description?{}:{description:e.description},params:e.paramsSchema})),eR=c?`
18
+ const actionDefinitions: readonly ActionDefinition[] = ${JSON.stringify(eS,null,2).replaceAll("\n","\n ")}
19
+
20
+ const implementActions = createActionFactory<${w}AnyDomainEntity, ${w}RootEntity, ${w}$Map, ${e$}, NavigationState, ViewState, ToolState, ExportState, ActionTypes>()`:"",eg=`
21
+ const createRecipe = RecipeFactoryBuilder.forAliases<${w}AnyDomainEntity, ${w}Aliases>(aliases)
19
22
  .forEntities(AnyDomainEntity.reflections)
20
23
  .withDefaults(defaults)
21
- .build()`,eD=[...S.map(e=>` readonly ${String(e)}: DomainEntityReflection<${A}${String(e)}>`),...j.map(e=>` readonly ${e}: RawAliasReflection<${A}${e}>`),...H.map(([e,n])=>{let t=n.schema.enum?.length&&n.schema.enum.every(e=>"string"==typeof e)?"EnumLike":"SchemaReflection";return` readonly ${e}: ${t}<${A}${e}>`}),...N.map(e=>` readonly ${e}: SchemaReflection<unknown>`)].join("\n"),eR=`{
22
- ${eD}
23
- }`,eg=[...S.map(e=>` readonly $${String(e)}: ${w("$DomainEntityReflection",String(e))}`),...j.map(e=>` readonly $${e}: ${w("EnhancedAliasReflection",e)}`)].join("\n"),eS=`{
24
- ${eg}
25
- }`,ev=`{
26
- ${Z.join("\n")}
24
+ .build()`,ev=[...v.map(e=>` readonly ${String(e)}: DomainEntityReflection<${w}${String(e)}>`),...j.map(e=>` readonly ${e}: RawAliasReflection<${w}${e}>`),...H.map(([e,n])=>{let t=n.schema.enum?.length&&n.schema.enum.every(e=>"string"==typeof e)?"EnumLike":"SchemaReflection";return` readonly ${e}: ${t}<${w}${e}>`}),...L.map(e=>` readonly ${e}: SchemaReflection<unknown>`)].join("\n"),ex=`{
25
+ ${ev}
26
+ }`,eA=[...v.map(e=>` readonly $${String(e)}: ${b("$DomainEntityReflection",String(e))}`),...j.map(e=>` readonly $${e}: ${b("EnhancedAliasReflection",e)}`)].join("\n"),ej=`{
27
+ ${eA}
28
+ }`,eC=`{
29
+ ${ee.join("\n")}
27
30
  }`;return`const ${el} = (() => {
28
31
  const modelVersion = ${M}
29
32
 
30
- ${ef}
31
-
32
- ${P.join("\n")}
33
+ ${eE}
33
34
 
34
35
  ${k.join("\n")}
35
36
 
36
- ${V.join("\n")}
37
+ ${F.join("\n")}
38
+
39
+ ${T.join("\n")}
37
40
 
38
41
  ${J.join("\n")}
39
42
 
40
43
  const aliases = {
41
- ${L}
44
+ ${_}
42
45
  } as const
43
46
 
44
47
  const entities = {
45
- ${q}
48
+ ${K}
46
49
  } as const
47
50
 
48
51
  const model = {
49
- ${q}
50
- ${_}
52
+ ${K}
51
53
  ${z}
52
54
  ${G}
55
+ ${q}
53
56
  } as const
54
57
 
55
- ${K.length>0?K.join("\n")+"\n":""}
56
- ${Q}
57
- ${W}
58
- const $entityReflections = {
58
+ ${Q.length>0?Q.join("\n")+"\n":""}
59
59
  ${U}
60
+ ${X}
61
+ const $entityReflections = {
62
+ ${W}
60
63
  }
61
64
 
62
65
  const enhancedModel = {
63
- ${X}
66
+ ${Y}
64
67
  } as const
65
68
 
66
- const implementCustomExpressions = createCustomExpressionFactory${e$}({})
67
- ${eu}
68
- ${eh}
69
+ const implementCustomExpressions = createCustomExpressionFactory${ec}({})
70
+ ${eR}${eh}
71
+ ${eD}
69
72
 
70
73
  const modelVersions = {
71
- ${Y.join("\n")}
74
+ ${Z.join("\n")}
72
75
  } as const
73
- const attachComponent = DomainComponentOpticBuilder.from${e$}(aliases)
74
-
75
- ${ep}
76
- const invariantBuilder = new InvariantBuilder${e$}(aliases)${u?"\n .withInvariants(implementCustomInvariants(commonAdminViolationExpressions))":""}
77
- ${u?`
78
- const createMapPublishedRevisionDataHandler = createMapPublishedRevisionDataHandlerFactory<${A}AnyDomainEntity, ${A}RootEntity, ${A}$Map, PublishedData>()
79
- const createMapPublishedChunkedDataHandler = createMapPublishedChunkedDataHandlerFactory<${A}AnyDomainEntity, ${A}RootEntity, ${A}$Map>()
80
- `:""}${ey}
81
- ${eE}
76
+ const attachComponent = DomainComponentOpticBuilder.from${ec}(aliases)
77
+
78
+ ${ed}
79
+ const invariantBuilder = new InvariantBuilder${ec}(aliases)${y?"\n .withInvariants(implementCustomInvariants(commonAdminViolationExpressions))":""}
80
+ ${y?`
81
+ const createMapPublishedRevisionDataHandler = createMapPublishedRevisionDataHandlerFactory<${w}AnyDomainEntity, ${w}RootEntity, ${w}$Map, PublishedData>()
82
+ const createMapPublishedChunkedDataHandler = createMapPublishedChunkedDataHandlerFactory<${w}AnyDomainEntity, ${w}RootEntity, ${w}$Map>()
83
+ `:""}${ef}
84
+ ${eg}
82
85
 
83
86
  return {
84
- domainBuilder: DomainBuilder.from${e$}(
87
+ domainBuilder: DomainBuilder.from${ec}(
85
88
  entities,
86
89
  aliases,
87
90
  $entityReflections,
@@ -90,13 +93,13 @@ ${eE}
90
93
  PublishedData,
91
94
  SessionData,
92
95
  FrontendData,
93
- ${u?"undefined":"BackendData"},
94
- ${u}
95
- ).withExpressions(valueExpressions),
96
- attachComponent,
96
+ ${y?"undefined":"BackendData"},
97
+ ${y}
98
+ ).withExpressions(valueExpressions)${c?".withActions(actionDefinitions)":""},
99
+ attachComponent,${c?"\n implementActions,":""}
97
100
  implementCustomExpressions,
98
101
  implementCustomInvariants,
99
- invariantBuilder,${u?`
102
+ invariantBuilder,${y?`
100
103
  createMapPublishedRevisionDataHandler,
101
104
  createMapPublishedChunkedDataHandler,`:""}
102
105
  model,
@@ -110,20 +113,21 @@ ${eE}
110
113
  })()
111
114
 
112
115
  const {
113
- ${ed("domainBuilder",ee)},
114
- ${ed("attachComponent",en)},
115
- ${ed("implementCustomExpressions",et)},
116
- ${ed("implementCustomInvariants",ea)},
117
- ${ed("invariantBuilder",ei)},${u?`
116
+ ${eu("domainBuilder",en)},
117
+ ${eu("attachComponent",et)},
118
+ ${eu("implementCustomExpressions",ei)},
119
+ ${eu("implementCustomInvariants",ea)},
120
+ ${eu("invariantBuilder",eo)},${y?`
118
121
  createMapPublishedRevisionDataHandler,
119
- createMapPublishedChunkedDataHandler,`:""}
120
- ${ed("relationExpressions",h)},
121
- ${ed("valueExpressions",E)},
122
- ${ed("componentOptics",f)},
123
- ${ed("createRecipe",D)},
122
+ createMapPublishedChunkedDataHandler,`:`
123
+ implementActions,`}
124
+ ${eu("relationExpressions",f)},
125
+ ${eu("valueExpressions",E)},
126
+ ${eu("componentOptics",D)},
127
+ ${eu("createRecipe",S)},
124
128
  } = ${el}
125
129
 
126
- const ${eo}: ${eR} = ${el}.model
127
- const ${es}: ${eS} = ${el}.enhancedModel
128
- const ${y}: ${ev} = ${el}.modelVersions
129
- export { ${ee}, ${en}, ${et}, ${ea}, ${ei}, ${eo}, ${es}, ${h}, ${E}, ${f}, ${y}, ${D}${u?", createMapPublishedRevisionDataHandler, createMapPublishedChunkedDataHandler, createDataRowValidatorHandler, createSheetValidatorHandler":""} }`};
130
+ const ${es}: ${ex} = ${el}.model
131
+ const ${er}: ${ej} = ${el}.enhancedModel
132
+ const ${h}: ${eC} = ${el}.modelVersions
133
+ export { ${en}, ${et}, ${ei}, ${ea}, ${eo}, ${es}, ${er}, ${f}, ${E}, ${D}, ${h}, ${S}${y?", createMapPublishedRevisionDataHandler, createMapPublishedChunkedDataHandler, createDataRowValidatorHandler, createSheetValidatorHandler":", implementActions"} }`};
@@ -10,6 +10,7 @@ globalThis.phx.domain = {
10
10
  enhancedModel,
11
11
  implementCustomExpressions,
12
12
  implementCustomInvariants,
13
+ implementActions,
13
14
  attachComponent,
14
15
  createRecipe,
15
16
 
@@ -50,6 +51,7 @@ globalThis.phx.applicationTypes = {
50
51
  readonly enhancedModel: typeof enhancedModel
51
52
  readonly implementCustomExpressions: typeof implementCustomExpressions
52
53
  readonly implementCustomInvariants: typeof implementCustomInvariants
54
+ readonly implementActions: typeof implementActions
53
55
  readonly attachComponent: typeof attachComponent
54
56
  readonly createRecipe: typeof createRecipe
55
57
  readonly admin: {
@@ -69,6 +71,7 @@ globalThis.phx.applicationTypes = {
69
71
  enhancedModel,
70
72
  implementCustomExpressions,
71
73
  implementCustomInvariants,
74
+ implementActions,
72
75
  attachComponent,
73
76
  createRecipe,
74
77
 
@@ -1,5 +1,5 @@
1
- import{CodeImports as e,autoHeader as a,skipApplicationTypeImports as i}from"../common/index.js";import{generateApplicationMetadataBlock as o,generateAssistantBlock as n,generateBaseConfiguratorBuilder as t,generateChunksSpec as s,generateDataSchemaConstants as r,generateDataSpec as p,generateDomainBlock as m,generateLocaleCodegen as d,generatePhxGlobalsBlock as c,generateResourcesCodegen as l,generateStateConstants as x}from"./domain-spec/index.js";let u="@salsita-ai/sdk/domain",g="@salsita-ai/sdk/i18n";export const globalDomainSpecPhxBinding={generateBindingBlock:c,generateStateConstants:x,registerApplicationTypeImports:i};export const generateApplicationSpecDomainSpecFile=(i,c=globalDomainSpecPhxBinding)=>{let x=new e,{registerApplicationTypeImports:E}=c,f=m({domainSpec:i.configurator,invariants:i.configurator.invariants,typePrefix:"",versionNsPrefix:"ModelV",isAdmin:!1,modelVersionsExportName:"modelVersions",relationExpressionsExportName:"relationExpressions",componentOpticsExportName:"componentOptics",valueExpressionsExportName:"valueExpressions",createRecipeExportName:"createRecipe",imports:x,registerApplicationTypeImports:E}),S=m({domainSpec:i.admin,invariants:i.admin.invariants,typePrefix:"Admin",versionNsPrefix:"AdminV",isAdmin:!0,modelVersionsExportName:"adminModelVersions",relationExpressionsExportName:"adminRelationExpressions",componentOpticsExportName:"adminComponentOptics",valueExpressionsExportName:"adminValueExpressions",createRecipeExportName:"createAdminRecipe",imports:x,registerApplicationTypeImports:E}),{hasResources:$}=l(i);x.addImport(u,"ConfiguratorBuilder"),x.addImport(u,"EnumReflection"),x.addTypeImport(u,"AssistantManifest"),x.addTypeImport(u,"ChunksSpec"),x.addTypeImport(u,"DataSpec"),x.addTypeImport(u,"EnumLike"),$&&x.addImport(u,"ResourceBuilder"),x.addImport(g,"mergeCatalogs"),x.addImport(g,"sdkCatalog"),x.addImport("@lingui/core","setupI18n");let k=r(i.configurator.dataSchemas,x,E),I=c.generateStateConstants({configuratorStates:i.configurator.states,adminStates:i.admin.states},x,E),N=o(i),{importBlock:v,catalogBlock:h,createI18nExport:A}=d(i.configurator.ui.availableLocales),{preBlock:B,builderBlock:C}=t(i,x,E),y=c.generateBindingBlock();return`${a("domain-spec.ts","Domain builders, model schemas, component optics and expression definitions derived from the spec.")}
2
- ${x.toString()}${v}
1
+ import{CodeImports as e,autoHeader as a,skipApplicationTypeImports as i}from"../common/index.js";import{generateApplicationMetadataBlock as o,generateAssistantBlock as n,generateBaseConfiguratorBuilder as t,generateChunksSpec as s,generateDataSchemaConstants as r,generateDataSpec as p,generateDomainBlock as m,generateLocaleCodegen as d,generatePhxGlobalsBlock as c,generateResourcesCodegen as l,generateStateConstants as u}from"./domain-spec/index.js";let x="@salsita-ai/sdk/domain",g="@salsita-ai/sdk/i18n";export const globalDomainSpecPhxBinding={generateBindingBlock:c,generateStateConstants:u,registerApplicationTypeImports:i};export const generateApplicationSpecDomainSpecFile=(i,c=globalDomainSpecPhxBinding)=>{let u=new e,{registerApplicationTypeImports:f}=c,E=m({domainSpec:i.configurator,invariants:i.configurator.invariants,actions:i.configurator.actions,typePrefix:"",versionNsPrefix:"ModelV",isAdmin:!1,modelVersionsExportName:"modelVersions",relationExpressionsExportName:"relationExpressions",componentOpticsExportName:"componentOptics",valueExpressionsExportName:"valueExpressions",createRecipeExportName:"createRecipe",imports:u,registerApplicationTypeImports:f}),S=m({domainSpec:i.admin,invariants:i.admin.invariants,actions:void 0,typePrefix:"Admin",versionNsPrefix:"AdminV",isAdmin:!0,modelVersionsExportName:"adminModelVersions",relationExpressionsExportName:"adminRelationExpressions",componentOpticsExportName:"adminComponentOptics",valueExpressionsExportName:"adminValueExpressions",createRecipeExportName:"createAdminRecipe",imports:u,registerApplicationTypeImports:f}),{hasResources:$}=l(i);u.addImport(x,"ConfiguratorBuilder"),u.addImport(x,"EnumReflection"),u.addTypeImport(x,"AssistantManifest"),u.addTypeImport(x,"ChunksSpec"),u.addTypeImport(x,"DataSpec"),u.addTypeImport(x,"EnumLike"),$&&u.addImport(x,"ResourceBuilder"),u.addImport(g,"mergeCatalogs"),u.addImport(g,"sdkCatalog"),u.addImport("@lingui/core","setupI18n");let k=r(i.configurator.dataSchemas,u,f),v=c.generateStateConstants({configuratorStates:i.configurator.states,adminStates:i.admin.states},u,f),I=o(i),{importBlock:N,catalogBlock:h,createI18nExport:A}=d(i.configurator.ui.availableLocales),{preBlock:B,builderBlock:C}=t(i,u,f),y=c.generateBindingBlock();return`${a("domain-spec.ts","Domain builders, model schemas, component optics and expression definitions derived from the spec.")}
2
+ ${u.toString()}${N}
3
3
 
4
4
  // ---- Data schemas ----
5
5
 
@@ -11,7 +11,7 @@ ${S}
11
11
 
12
12
  // ---- Configurator domain ----
13
13
 
14
- ${f}
14
+ ${E}
15
15
 
16
16
  // ---- i18n ----
17
17
 
@@ -21,11 +21,11 @@ ${A}
21
21
 
22
22
  // ---- Application metadata ----
23
23
 
24
- ${N}
24
+ ${I}
25
25
 
26
26
  // ---- State enums ----
27
27
 
28
- ${I}
28
+ ${v}
29
29
 
30
30
  const $dataSpec: DataSpec = ${p(i.dataSpec.entries)}
31
31
 
@@ -1,9 +1,9 @@
1
- import{CodeImports as i}from"../common/code-imports.js";import{autoHeader as n}from"../common/file-headers.js";let o=/v(\d+)\.ts$/,t=(i,n)=>i.versionedModels.filter(i=>void 0!==i.migrationFile).map(i=>({version:i.version,file:i.migrationFile,importName:n?`${n}MigrateToV${i.version}`:`migrateToV${i.version}`})),s=i=>i.map(i=>{let n=i.file.replace(o,`v${i.version}.js`),t=`migrateToV${i.version}`,s=i.importName!==t?` as ${i.importName}`:"";return`import { ${t}${s} } from '../${n}'`}).join("\n"),e=(i,n,o,t)=>[`const ${t}Migrations = {`,...i.map(i=>` ${i.version}: ${i.importName},`),"}","",`const ${t} = MigrateFunctionBuilder`,` .fromVersions(${n})`,` .to(${o})`,` .using(${t}Migrations)`," .build()"].join("\n");export const generateApplicationSpecDomainFile=o=>{let r=new i,a="./domain-spec.js",m="./configurator-domain-code.js",d="./admin-domain-code.js",p=i=>[...i.expressions.values()].some(i=>[...i.values()].some(i=>"relation"===i.implementation.kind)),l=p(o.configurator.expressions),c=p(o.admin.expressions),u=t(o.configurator.resolvedVersions,""),I=t(o.admin.resolvedVersions,"admin"),g=u.length>0,h=I.length>0;r.addImport(a,"baseConfiguratorBuilder"),r.addImport(a,"domainBuilder"),r.addImport(a,"adminDomainBuilder"),r.addImport(a,"attachComponent"),r.addImport(a,"attachAdminComponent"),r.addImport(a,"implementCustomExpressions"),r.addImport(a,"implementAdminCustomExpressions"),r.addImport(a,"createI18n"),r.addImport(a,"componentOptics"),r.addImport(a,"adminComponentOptics"),r.addImport(a,"invariantBuilder"),r.addImport(a,"adminInvariantBuilder"),r.addImport(m,"customExpressions"),r.addImport(m,"customInvariants"),r.addImport(d,"customAdminExpressions"),r.addImport(d,"customAdminInvariants"),l&&r.addImport(a,"relationExpressions"),c&&r.addImport(a,"adminRelationExpressions"),(g||h)&&r.addImport("@salsita-ai/sdk/domain","MigrateFunctionBuilder"),g&&r.addImport(a,"modelVersions"),h&&r.addImport(a,"adminModelVersions");let x=[];g&&x.push(s(u)),h&&x.push(s(I));let v=x.length>0?"\n"+x.join("\n")+"\n":"",$=[];g&&$.push(e(u,"modelVersions",o.configurator.schemaVersion,"migrate")),h&&$.push(e(I,"adminModelVersions",o.admin.schemaVersion,"migrateAdmin"));let E=$.length>0?"\n"+$.join("\n\n")+"\n":"",f=["const domainFactory = domainBuilder",l?" .withExpressions(relationExpressions)":null," .withExpressions(invariantBuilder.withInvariants(customInvariants).buildViolationExpressions())"," .withExpressions(customExpressions)",g?" .withMigrate(migrate)":null," .build()"].filter(Boolean).join("\n"),w=["const adminDomainFactory = adminDomainBuilder",c?" .withExpressions(adminRelationExpressions)":null," .withExpressions(adminInvariantBuilder.withInvariants(customAdminInvariants).buildViolationExpressions())"," .withExpressions(customAdminExpressions)",h?" .withMigrate(migrateAdmin)":null," .build()"].filter(Boolean).join("\n");return`${n("domain.ts","Assembles domain and admin domain factories from builders, migrations, expressions and invariants.")}
1
+ import{CodeImports as i}from"../common/code-imports.js";import{autoHeader as n}from"../common/file-headers.js";let o=/v(\d+)\.ts$/,t=(i,n)=>i.versionedModels.filter(i=>void 0!==i.migrationFile).map(i=>({version:i.version,file:i.migrationFile,importName:n?`${n}MigrateToV${i.version}`:`migrateToV${i.version}`})),s=i=>i.map(i=>{let n=i.file.replace(o,`v${i.version}.js`),t=`migrateToV${i.version}`,s=i.importName!==t?` as ${i.importName}`:"";return`import { ${t}${s} } from '../${n}'`}).join("\n"),e=(i,n,o,t)=>[`const ${t}Migrations = {`,...i.map(i=>` ${i.version}: ${i.importName},`),"}","",`const ${t} = MigrateFunctionBuilder`,` .fromVersions(${n})`,` .to(${o})`,` .using(${t}Migrations)`," .build()"].join("\n");export const generateApplicationSpecDomainFile=o=>{let r=new i,a="./domain-spec.js",m="./configurator-domain-code.js",d="./admin-domain-code.js",p=i=>[...i.expressions.values()].some(i=>[...i.values()].some(i=>"relation"===i.implementation.kind)),l=p(o.configurator.expressions),c=p(o.admin.expressions),u=t(o.configurator.resolvedVersions,""),I=t(o.admin.resolvedVersions,"admin"),g=u.length>0,h=I.length>0;r.addImport(a,"baseConfiguratorBuilder"),r.addImport(a,"domainBuilder"),r.addImport(a,"adminDomainBuilder"),r.addImport(a,"attachComponent"),r.addImport(a,"attachAdminComponent"),r.addImport(a,"implementCustomExpressions"),r.addImport(a,"implementAdminCustomExpressions"),r.addImport(a,"createI18n"),r.addImport(a,"componentOptics"),r.addImport(a,"adminComponentOptics"),r.addImport(a,"invariantBuilder"),r.addImport(a,"adminInvariantBuilder"),r.addImport(m,"customExpressions"),r.addImport(m,"customInvariants"),r.addImport(m,"customActions"),r.addImport(d,"customAdminExpressions"),r.addImport(d,"customAdminInvariants"),l&&r.addImport(a,"relationExpressions"),c&&r.addImport(a,"adminRelationExpressions"),(g||h)&&r.addImport("@salsita-ai/sdk/domain","MigrateFunctionBuilder"),g&&r.addImport(a,"modelVersions"),h&&r.addImport(a,"adminModelVersions");let x=[];g&&x.push(s(u)),h&&x.push(s(I));let v=x.length>0?"\n"+x.join("\n")+"\n":"",$=[];g&&$.push(e(u,"modelVersions",o.configurator.schemaVersion,"migrate")),h&&$.push(e(I,"adminModelVersions",o.admin.schemaVersion,"migrateAdmin"));let E=$.length>0?"\n"+$.join("\n\n")+"\n":"",f=["const domainFactory = domainBuilder",l?" .withExpressions(relationExpressions)":null," .withExpressions(invariantBuilder.withInvariants(customInvariants).buildViolationExpressions())"," .withExpressions(customExpressions)"," .withActionImplementations(customActions)",g?" .withMigrate(migrate)":null," .build()"].filter(Boolean).join("\n"),A=["const adminDomainFactory = adminDomainBuilder",c?" .withExpressions(adminRelationExpressions)":null," .withExpressions(adminInvariantBuilder.withInvariants(customAdminInvariants).buildViolationExpressions())"," .withExpressions(customAdminExpressions)",h?" .withMigrate(migrateAdmin)":null," .build()"].filter(Boolean).join("\n");return`${n("domain.ts","Assembles domain and admin domain factories from builders, migrations, expressions and invariants.")}
2
2
  ${r.toString()}
3
3
  ${v}export { attachComponent, attachAdminComponent, implementCustomExpressions, implementAdminCustomExpressions, createI18n }
4
4
  ${E}
5
5
  ${f}
6
- ${w}
6
+ ${A}
7
7
 
8
8
  export const configuratorBuilder = baseConfiguratorBuilder
9
9
  .withDomainFactory(domainFactory)
@@ -0,0 +1,11 @@
1
+ import type { PhoenixDefinitions } from '../../../../core/phoenix-definitions.js';
2
+ import type { Actions, ModelVersion } from '../../../../parse-application-files/index.js';
3
+ import type { CodeImports } from '../../common/code-imports.js';
4
+ /**
5
+ * Generates the `ActionTypes` map of the declared actions (name → `{ params, result }`) and the
6
+ * `ActionName`, `ActionParams<NAME>` and `ActionResult<NAME>` types derived from it. A nullable
7
+ * param is optional. The `description` of an action, a param and a result member becomes the doc
8
+ * comment of its property, so it shows wherever the types are used. Without actions the map is
9
+ * empty, so `ActionName` is `never`.
10
+ */
11
+ export declare const generateActionTypeDecls: (actions: Actions, model: ModelVersion, phxDefinitions: PhoenixDefinitions, imports: CodeImports, indent: number, typeOnlyImports?: boolean) => string;
@@ -0,0 +1,8 @@
1
+ import{schemaToTypeString as e}from"../common/schema-to-type-string.js";let t=(e,t)=>{let n=(e??"").trim().replaceAll("*/","*\\/").split("\n").map(e=>e.trim());return""===n[0]||void 0===n[0]?[]:1===n.length?[`${t}/** ${n[0]} */`]:[`${t}/**`,...n.map(e=>`${t} * ${e}`.trimEnd()),`${t} */`]};export const generateActionTypeDecls=(n,r,o,a,p,s=!1)=>{let i=" ".repeat(p),$=" ".repeat(p+2),c=" ".repeat(p+4),l=" ".repeat(p+6),m={phxDefinitions:o,commonTypeNames:new Set(r.commonTypes.keys()),imports:a,typeOnlyImports:s},y=[...n.values()].map(n=>{let r=Object.entries(n.params).flatMap(([n,{schema:r,required:o}])=>[...t(r.description,l),`${l}readonly ${n}${o?"":"?"}: ${e(r,m)}`]),o=Object.entries(n.result).flatMap(([n,r])=>[...t(r.description,l),`${l}readonly ${n}: ${e(r,m)}`]),a=e=>e.length>0?`{
2
+ ${e.join("\n")}
3
+ ${c}}`:"Record<string, never>";return[...t(n.description,$),`${$}readonly ${n.name}: {`,`${c}readonly params: ${a(r)}`,`${c}readonly result: ${a(o)}`,`${$}}`].join("\n")}),A=y.length>0?`{
4
+ ${y.join("\n")}
5
+ ${i}}`:"Record<never, never>";return`${i}type ActionTypes = ${A}
6
+ ${i}type ActionName = keyof ActionTypes
7
+ ${i}type ActionParams<NAME extends ActionName> = ActionTypes[NAME]['params']
8
+ ${i}type ActionResult<NAME extends ActionName> = ActionTypes[NAME]['result']`};
@@ -1,3 +1,4 @@
1
+ export { generateActionTypeDecls } from './generate-action-types.js';
1
2
  export { generateModelTypeDecls } from './generate-model-types.js';
2
3
  export { generateExpressionTypeDecls, generateEntityExpressionComposites } from './generate-expression-types.js';
3
4
  export { generateDataSchemaTypeDecls } from './generate-data-schema-types.js';
@@ -1 +1 @@
1
- export{generateModelTypeDecls}from"./generate-model-types.js";export{generateExpressionTypeDecls,generateEntityExpressionComposites}from"./generate-expression-types.js";export{generateDataSchemaTypeDecls}from"./generate-data-schema-types.js";
1
+ export{generateActionTypeDecls}from"./generate-action-types.js";export{generateModelTypeDecls}from"./generate-model-types.js";export{generateExpressionTypeDecls,generateEntityExpressionComposites}from"./generate-expression-types.js";export{generateDataSchemaTypeDecls}from"./generate-data-schema-types.js";
@@ -73,6 +73,7 @@ ${h}
73
73
  readonly enhancedModel: typeof import('./domain-spec.js').enhancedModel
74
74
  readonly implementCustomExpressions: typeof import('./domain-spec.js').implementCustomExpressions
75
75
  readonly implementCustomInvariants: typeof import('./domain-spec.js').implementCustomInvariants
76
+ readonly implementActions: typeof import('./domain-spec.js').implementActions
76
77
  readonly attachComponent: typeof import('./domain-spec.js').attachComponent
77
78
  readonly createRecipe: typeof import('./domain-spec.js').createRecipe
78
79
 
@@ -12,7 +12,7 @@
12
12
  * @module
13
13
  */
14
14
  export { stripSdkMarkerContent } from './common/strip-sdk-marker-content.js';
15
- export { generateAgentsMd } from './agents-md.js';
15
+ export { generateAgentsMd } from './skills/agents-md.js';
16
16
  export { generateApplicationSpecAdminConfig } from './admin-config.js';
17
17
  export { generateApplicationSpecAdminCode } from './admin-domain-code.js';
18
18
  export { generateApplicationSpecAdminFrontendCode } from './admin-frontend-code.js';
@@ -42,11 +42,11 @@ export { generateApplicationSpecHtmlIndex } from './html-index.js';
42
42
  export { generateLinguiRcFile } from './lingui-rc.js';
43
43
  export { generateApplicationSpecNvmrc } from './nvmrc.js';
44
44
  export { generateApplicationSpecPackageJson } from './package-json.js';
45
- export { generatePhoenixCliSkill } from './phoenix-cli-skill.js';
46
- export { generatePhoenixCreateConfiguratorSkill, generatePhoenixCreateConfiguratorSkillReferences, } from './phoenix-create-configurator-skill.js';
47
- export { generatePhoenixFeedbackSkill } from './phoenix-feedback-skill.js';
48
- export { generatePhoenixReviewSkill } from './phoenix-review-skill.js';
49
- export { type PhoenixSkillOptions, followsCanaryBuilds, generatePhoenixSkill } from './phoenix-skill.js';
45
+ export { generatePhoenixCliSkill } from './skills/phoenix-cli-skill.js';
46
+ export { generatePhoenixCreateConfiguratorSkill, generatePhoenixCreateConfiguratorSkillReferences, } from './skills/phoenix-create-configurator-skill.js';
47
+ export { generatePhoenixFeedbackSkill } from './skills/phoenix-feedback-skill.js';
48
+ export { generatePhoenixReviewSkill } from './skills/phoenix-review-skill.js';
49
+ export { type PhoenixSkillOptions, followsCanaryBuilds, generatePhoenixSkill } from './skills/phoenix-skill.js';
50
50
  export { generateApplicationSpecPrettierConfig } from './prettier-config.js';
51
51
  export { generateApplicationSpecPrettierIgnore } from './prettier-ignore.js';
52
52
  export { generateApplicationSpecPrivateAssetsReadme } from './private-assets-readme.js';
@@ -1 +1 @@
1
- export{stripSdkMarkerContent}from"./common/strip-sdk-marker-content.js";export{generateAgentsMd}from"./agents-md.js";export{generateApplicationSpecAdminConfig}from"./admin-config.js";export{generateApplicationSpecAdminCode}from"./admin-domain-code.js";export{generateApplicationSpecAdminFrontendCode}from"./admin-frontend-code.js";export{generateAdminGlobalBindingBlock,generateApplicationSpecAdminGlobals}from"./admin-globals.js";export{generateApplicationSpecTypesModule}from"./application-types.js";export{generateApplicationSpecAdminFile}from"./admin.js";export{generateApplicationSpecConfiguratorConfig}from"./configurator-config.js";export{generateApplicationSpecConfiguratorCode}from"./configurator-domain-code.js";export{generateApplicationSpecConfiguratorFrontendCode}from"./configurator-frontend-code.js";export{generateApplicationSpecConfiguratorGlobals,generateConfiguratorGlobalBindingBlock}from"./configurator-globals.js";export{generateApplicationSpecConfiguratorFile}from"./configurator.js";export{generateApplicationSpecDomainSpecFile}from"./domain-spec.js";export{generateImportedStateConstants,generatePhxExportsBlock,generatePhxGlobalsBlock,generateStateConstants}from"./domain-spec/index.js";export{generateApplicationSpecDomainFile}from"./domain.js";export{generateApplicationSpecEditorFile}from"./editor.js";export{generateApplicationSpecEmbeddedAdmin}from"./embedded-admin.js";export{generateApplicationSpecEmbeddedConfigurator}from"./embedded-configurator.js";export{generateApplicationSpecEnvCi}from"./env-ci.js";export{generateApplicationSpecEnvExample}from"./env-example.js";export{generateApplicationSpecEslintConfig}from"./eslint-config.js";export{generateApplicationSpecFavicon}from"./favicon.js";export{generateApplicationSpecFrontendConfig}from"./frontend-config.js";export{generateApplicationSpecGitignore}from"./gitignore.js";export{generateApplicationSpecGlobals}from"./globals.js";export{generateApplicationSpecHtmlAdminIndex}from"./html-admin-index.js";export{generateApplicationSpecHtmlIndex}from"./html-index.js";export{generateLinguiRcFile}from"./lingui-rc.js";export{generateApplicationSpecNvmrc}from"./nvmrc.js";export{generateApplicationSpecPackageJson}from"./package-json.js";export{generatePhoenixCliSkill}from"./phoenix-cli-skill.js";export{generatePhoenixCreateConfiguratorSkill,generatePhoenixCreateConfiguratorSkillReferences}from"./phoenix-create-configurator-skill.js";export{generatePhoenixFeedbackSkill}from"./phoenix-feedback-skill.js";export{generatePhoenixReviewSkill}from"./phoenix-review-skill.js";export{followsCanaryBuilds,generatePhoenixSkill}from"./phoenix-skill.js";export{generateApplicationSpecPrettierConfig}from"./prettier-config.js";export{generateApplicationSpecPrettierIgnore}from"./prettier-ignore.js";export{generateApplicationSpecPrivateAssetsReadme}from"./private-assets-readme.js";export{generateApplicationSpecPublicAssetsReadme}from"./public-assets-readme.js";export{generateApplicationSpecReadme}from"./readme.js";export{generateApplicationSpecRobotsTxt}from"./robots-txt.js";export{generateApplicationSpecStoryDevDeclaration,generateApplicationSpecStoryPhxModule,generateApplicationSpecStoryRawProjectFiles,generateApplicationSpecStoryWrapper}from"./story/index.js";export{generateApplicationSpecTsconfig}from"./tsconfig.js";export{generateApplicationSpecWebhookBuilders}from"./webhook-builders.js";export{generateApplicationSpecWebhookImplementation}from"./webhook-implementation.js";export{generateApplicationSpecWebhookIndex}from"./webhook-index.js";export{generateApplicationSpecWebhooksConfig}from"./webhooks-config.js";
1
+ export{stripSdkMarkerContent}from"./common/strip-sdk-marker-content.js";export{generateAgentsMd}from"./skills/agents-md.js";export{generateApplicationSpecAdminConfig}from"./admin-config.js";export{generateApplicationSpecAdminCode}from"./admin-domain-code.js";export{generateApplicationSpecAdminFrontendCode}from"./admin-frontend-code.js";export{generateAdminGlobalBindingBlock,generateApplicationSpecAdminGlobals}from"./admin-globals.js";export{generateApplicationSpecTypesModule}from"./application-types.js";export{generateApplicationSpecAdminFile}from"./admin.js";export{generateApplicationSpecConfiguratorConfig}from"./configurator-config.js";export{generateApplicationSpecConfiguratorCode}from"./configurator-domain-code.js";export{generateApplicationSpecConfiguratorFrontendCode}from"./configurator-frontend-code.js";export{generateApplicationSpecConfiguratorGlobals,generateConfiguratorGlobalBindingBlock}from"./configurator-globals.js";export{generateApplicationSpecConfiguratorFile}from"./configurator.js";export{generateApplicationSpecDomainSpecFile}from"./domain-spec.js";export{generateImportedStateConstants,generatePhxExportsBlock,generatePhxGlobalsBlock,generateStateConstants}from"./domain-spec/index.js";export{generateApplicationSpecDomainFile}from"./domain.js";export{generateApplicationSpecEditorFile}from"./editor.js";export{generateApplicationSpecEmbeddedAdmin}from"./embedded-admin.js";export{generateApplicationSpecEmbeddedConfigurator}from"./embedded-configurator.js";export{generateApplicationSpecEnvCi}from"./env-ci.js";export{generateApplicationSpecEnvExample}from"./env-example.js";export{generateApplicationSpecEslintConfig}from"./eslint-config.js";export{generateApplicationSpecFavicon}from"./favicon.js";export{generateApplicationSpecFrontendConfig}from"./frontend-config.js";export{generateApplicationSpecGitignore}from"./gitignore.js";export{generateApplicationSpecGlobals}from"./globals.js";export{generateApplicationSpecHtmlAdminIndex}from"./html-admin-index.js";export{generateApplicationSpecHtmlIndex}from"./html-index.js";export{generateLinguiRcFile}from"./lingui-rc.js";export{generateApplicationSpecNvmrc}from"./nvmrc.js";export{generateApplicationSpecPackageJson}from"./package-json.js";export{generatePhoenixCliSkill}from"./skills/phoenix-cli-skill.js";export{generatePhoenixCreateConfiguratorSkill,generatePhoenixCreateConfiguratorSkillReferences}from"./skills/phoenix-create-configurator-skill.js";export{generatePhoenixFeedbackSkill}from"./skills/phoenix-feedback-skill.js";export{generatePhoenixReviewSkill}from"./skills/phoenix-review-skill.js";export{followsCanaryBuilds,generatePhoenixSkill}from"./skills/phoenix-skill.js";export{generateApplicationSpecPrettierConfig}from"./prettier-config.js";export{generateApplicationSpecPrettierIgnore}from"./prettier-ignore.js";export{generateApplicationSpecPrivateAssetsReadme}from"./private-assets-readme.js";export{generateApplicationSpecPublicAssetsReadme}from"./public-assets-readme.js";export{generateApplicationSpecReadme}from"./readme.js";export{generateApplicationSpecRobotsTxt}from"./robots-txt.js";export{generateApplicationSpecStoryDevDeclaration,generateApplicationSpecStoryPhxModule,generateApplicationSpecStoryRawProjectFiles,generateApplicationSpecStoryWrapper}from"./story/index.js";export{generateApplicationSpecTsconfig}from"./tsconfig.js";export{generateApplicationSpecWebhookBuilders}from"./webhook-builders.js";export{generateApplicationSpecWebhookImplementation}from"./webhook-implementation.js";export{generateApplicationSpecWebhookIndex}from"./webhook-index.js";export{generateApplicationSpecWebhooksConfig}from"./webhooks-config.js";
@@ -0,0 +1,2 @@
1
+ import{sdkGuidanceSections as e}from"./sdk-content.js";export const generateAgentsMd=()=>`${[e.projectIntro,e.buildCommands,e.doNotEdit,"Phoenix SDK guidance lives in the `phoenix`, `phoenix-cli`, `phoenix-create-configurator`, `phoenix-feedback` and `phoenix-review` skills under `.claude/skills/` and `.agents/skills/`. Phoenix rewrites them on every sync, removes anything else inside their folders and removes other `phoenix`-prefixed skill folders, so to customise a skill, copy it to a folder whose name does not start with `phoenix`."].join("\n\n")}
2
+ `;
@@ -0,0 +1 @@
1
+ import{renderAgentSkill as n}from"./agent-skill.js";import{sdkGuidanceSections as e}from"./sdk-content.js";export const generatePhoenixCliSkill=()=>n({name:"phoenix-cli",description:"Phoenix CLI tooling for building and inspecting this configurator, covering build, dev and sync commands, dev logs, glTF asset inspection, screenshots, runtime state, data and scene inspection, and Playwright MCP setup. Use when building, debugging build or runtime errors, checking 3D assets, or inspecting the running configurator.",sections:[e.buildCommands,e.devLogs,e.assetInspection,e.screenshotCli,e.inspectState,e.inspectData,e.inspectScene,e.playwrightMcpSetup]});
@@ -1,3 +1,3 @@
1
- import { type AgentSkillReference } from './common/agent-skill.js';
1
+ import { type AgentSkillReference } from './agent-skill.js';
2
2
  export declare const generatePhoenixCreateConfiguratorSkill: () => string;
3
3
  export declare const generatePhoenixCreateConfiguratorSkillReferences: () => readonly AgentSkillReference[];
@@ -1,4 +1,4 @@
1
- import{renderAgentSkill as e}from"./common/agent-skill.js";let t=`Guide the client through five stages: a representative first slice, the overall configuration flow, iterative options and features, finalization, and a complete review. Make the client comfortable, informed, and in control while taking responsibility for platform research, implementation, and verification.
1
+ import{renderAgentSkill as e}from"./agent-skill.js";let t=`Guide the client through five stages: a representative first slice, the overall configuration flow, iterative options and features, finalization, and a complete review. Make the client comfortable, informed, and in control while taking responsibility for platform research, implementation, and verification.
2
2
 
3
3
  “Client” means the person creating the configurator. “Configurator user” means its intended user, such as a buyer, salesperson, or designer. Tailor the experience to that audience; do not assume a purchasing journey.`,n=`## Foundations
4
4
 
@@ -1,4 +1,4 @@
1
- import{renderAgentSkill as e}from"./common/agent-skill.js";let t=`## When to Raise Feedback
1
+ import{renderAgentSkill as e}from"./agent-skill.js";let t=`## When to Raise Feedback
2
2
  Draft feedback for the Phoenix team when one of these happens while you work in this project:
3
3
  - **Bug** — the SDK, the \`phoenix\` CLI or generated code crashes, produces wrong output or behaves differently from its documentation, and the cause is not in this project's own code.
4
4
  - **Misleading guidance** — a doc page, a Phoenix skill or an error message sent you the wrong way, or did not say what you needed.
@@ -1,4 +1,4 @@
1
- import{renderAgentSkill as e}from"./common/agent-skill.js";let i=`Review all current git changes for correctness, Phoenix pattern violations, and security issues.
1
+ import{renderAgentSkill as e}from"./agent-skill.js";let i=`Review all current git changes for correctness, Phoenix pattern violations, and security issues.
2
2
 
3
3
  ## Phoenix-Specific Review
4
4
 
@@ -7,13 +7,15 @@ import{renderAgentSkill as e}from"./common/agent-skill.js";let i=`Review all cur
7
7
  - [ ] Relations properly define parent-child ownership (1-N, 0-1)
8
8
  - [ ] Expressions have matching implementations in src/expressions/
9
9
  - [ ] Invariants have matching implementations in src/invariants/
10
+ - [ ] Actions declared under actions: have matching implementations in src/actions/ (a missing one fails the type check of the generated barrel)
10
11
  - [ ] Component bindings use correct entity types or aliases
11
12
  - [ ] $read/$write/$bind reference valid properties or expressions
12
- - [ ] Model version incremented when schema changes (requires new v\\*.ts migration)
13
+ - [ ] A model that has been deployed is unchanged under its version: the change is in \`model.latest\`, the deployed model is kept as \`model.v<N>\`, and \`src/migrations/v<N+1>.ts\` migrates saved configurations
13
14
 
14
- ### Expressions & Invariants (src/expressions/, src/invariants/)
15
+ ### Expressions, Actions & Invariants (src/expressions/, src/actions/, src/invariants/)
15
16
 
16
- - [ ] Use phx.domain.implementCustomExpressions() / implementCustomInvariants()
17
+ - [ ] Use phx.domain.implementCustomExpressions() / implementActions() / implementCustomInvariants()
18
+ - [ ] Actions only prepare: they return updates and a readResult reader, never stage or commit, and throw messages that say what to send instead
17
19
  - [ ] Expression names prefixed with $ in YAML match implementation
18
20
  - [ ] No side effects in expressions (pure computed values only)
19
21
  - [ ] Invariant violations return proper severity and messages
@@ -0,0 +1 @@
1
+ import{renderAgentSkill as e}from"./agent-skill.js";import{sdkGuidanceSections as t}from"./sdk-content.js";export const followsCanaryBuilds=e=>!e.useWorkspace&&e.sdkVersion.includes("-develop.");export const generatePhoenixSkill=({checkLatestCanary:n})=>e({name:"phoenix",description:`Phoenix SDK project conventions, covering project structure, architecture principles, key patterns, file and export rules, webhook membership, versioning the domain model once it is deployed, showing the user the dev preview and the build of a deploy, and how to search the SDK documentation${n?", and the internal-beta check for the latest canary SDK build":""}. Use before writing or changing specs or source code in this Phoenix configurator project.`,sections:[...n?["## Stay on the Latest Canary\nDuring the internal beta this project uses the `canary` build of the SDK, which is published from every change to the platform. Once per conversation, before you change anything, compare the installed version with the newest canary:\n```bash\npnpm list @salsita-ai/sdk --depth 0\nnpm view @salsita-ai/sdk@canary version\n```\nWhen they differ, tell the user which version you are moving to, then update the project and regenerate its files:\n```bash\npnpm add @salsita-ai/sdk@canary\npnpm phoenix sync\n```\n`sync` rewrites the Phoenix skills, so read the ones you use again after it. When the user runs a globally installed `phoenix`, update that too with `npm install -g @salsita-ai/sdk@canary`. If the project no longer builds after the update, stop and tell the user; the `phoenix-feedback` skill covers reporting it."]:[],t.projectStructure,t.architecturePrinciples,t.keyPatterns,t.fileConventions,t.exportRules,t.webhookMembership,t.doNotEdit,t.modelVersioning,"## Show the Preview While You Work\nThe user should see the configurator change as you build it. Before your first change in a conversation, make sure `pnpm phoenix dev` is running (start it in the background when it is not) and open the address it prints as `Preview: <url>` (also written to `.phoenix/phoenix-dev.log`) in the user's browser: `open '<url>'` on macOS, `xdg-open '<url>'` on Linux, `Start-Process '<url>'` in PowerShell, `start \"\" \"<url>\"` in cmd. Keep the quotes, the shell would otherwise read a `?` in the address as a pattern. The log keeps the lines of earlier runs, so when you have just started dev, wait for the `Preview:` line written after your start and use the last one. Open it once; the preview reloads on every change, so tell the user to keep that tab open instead of opening it again.","## Show the Build After a Deploy\n`pnpm phoenix deploy` starts a build on the server and waits for it to go live. Right after `Build <id> started` it prints `Follow the build in Studio: <url>`. Run the deploy so that you can read its output while it runs, and open that link in the user's browser, quoted as above, as soon as it appears, so they can follow the build they just triggered. When the line is missing, the sign-in is older than the link: tell the user the build is listed under Deployments in Studio, and that `pnpm phoenix login <workspace>` brings the link back.","## Code Review\nUse the `phoenix-review` skill to review code changes before committing.",t.sdkDocumentation]});
@@ -25,6 +25,7 @@ Declarative 3D product configurator built with Phoenix SDK. Domain model defined
25
25
  readonly projectStructure: `## Project Structure
26
26
  - \`spec/\` — Domain YAML specs (entities, relations, expressions, invariants, components, application config)
27
27
  - \`src/expressions/\` — Computed/derived entity properties (\`phx.domain.implementCustomExpressions()\`)
28
+ - \`src/actions/\` — Domain operations declared under \`actions:\` in the spec (\`phx.domain.implementActions()\`), run by controls and exposed to the assistant
28
29
  - \`src/invariants/\` — Business rule constraints (\`phx.domain.implementCustomInvariants()\`)
29
30
  - \`src/transformers/\` — Automatic state fixers (\`phx.frontend.transformerBuilder\`)
30
31
  - \`src/components/\` — ECS system components (\`phx.domain.attachComponent.withEntity()\`)
@@ -48,6 +49,7 @@ Declarative 3D product configurator built with Phoenix SDK. Domain model defined
48
49
  /** Expressions, invariants, transformers, components, webhooks, and filters at a glance. */
49
50
  readonly keyPatterns: `## Key Patterns
50
51
  - Expressions = computed properties on entities (prefix: \`$\`), implemented per-entity in src/expressions/
52
+ - Actions = named domain operations (\`actions:\` in YAML with \`params\` and \`result\` schemas), implemented in src/actions/, prepared through \`actionSystem.prepareAction()\` and exposed as assistant mutations through \`assistant.actions\`
51
53
  - Invariants = validation rules returning violations, static or dynamic
52
54
  - Transformers = auto-fixers maintaining consistency after state changes
53
55
  - Components defined in YAML with \`$read\`/\`$bind\` bindings, or custom in src/components/ using attachComponent builder
@@ -63,7 +65,7 @@ Declarative 3D product configurator built with Phoenix SDK. Domain model defined
63
65
  - Underscore folders (_shared/, _utils/) are NOT auto-imported`;
64
66
  /** The default-export rule of the SDK auto-import system. */
65
67
  readonly exportRules: `## Export Rules
66
- All 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.`;
68
+ All files in src/expressions/, src/actions/, 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.`;
67
69
  /** Which components and handlers are bundled into the webhook. */
68
70
  readonly webhookMembership: `## Webhook Membership
69
71
  - User-authored components, admin components, and handlers are frontend-only by default.
@@ -76,6 +78,27 @@ All files in src/expressions/, src/invariants/, src/transformers/, src/component
76
78
  - \`.phoenix/\` directory — completely regenerated on each build
77
79
  - \`tsconfig.json\`, \`eslint.config.js\`, \`prettier.config.js\`, \`.prettierignore\`, \`.linguirc\`, \`.nvmrc\`
78
80
  - \`src/locales/\` .ts files — compiled from .po files`;
81
+ /** When and how a deployed domain model gets a new version and a migration, with the recipe for replacing the starter. */
82
+ readonly modelVersioning: `## Version the Domain Model Once It Is Deployed
83
+ A deployed model version cannot change, because saved configurations depend on it. \`pnpm phoenix deploy\` is refused, before anything is uploaded, when the model differs from the one already deployed under the same version. The version is not written anywhere: \`model.latest\` is always the highest numbered version plus one, so a spec with only \`latest\` is v1, and \`applicationVersion\` plays no part. \`pnpm phoenix dev\` accepts every model change, so a working preview does not show that the deploy will pass.
84
+
85
+ To change a model that has been deployed as v<N>:
86
+ 1. Keep the deployed model, unchanged, as \`model.v<N>\` in the spec. A file of its own, such as \`spec/model-v<N>.yaml\`, keeps \`latest\` readable.
87
+ 2. Make the change in \`model.latest\`, which is now v<N+1>.
88
+ 3. Add \`src/migrations/v<N+1>.ts\` exporting \`migrateToV<N+1>\`. It receives the saved entities of v<N> and returns entities that are valid in v<N+1>; \`ModelV<N>\` and \`ModelV<N+1>\` are generated global namespaces.
89
+
90
+ The admin model is versioned on its own, under \`src/admin/migrations/\`, with its types in \`AdminV<N>\`.
91
+
92
+ **Replacing the starter.** When the first deployment of the workspace was the starter, its \`Box\` model is v1 in production. When the real model replaces it, keep the starter's model as \`model.v1\` and define the real model in \`latest\`. Configurations saved from the starter are not worth converting, so the migration returns the starting state of the new model, the \`initialDomainEntities\` of its preset, and drops the boxes:
93
+ \`\`\`typescript
94
+ // src/migrations/v2.ts
95
+ import type { Migration } from '@salsita-ai/sdk/domain'
96
+
97
+ export const migrateToV2: Migration<ModelV1.AnyDomainEntity, ModelV2.AnyDomainEntity> = () => [
98
+ // the entities of the new model's preset
99
+ ]
100
+ \`\`\`
101
+ An entity of a type the new version no longer has must not stay in the returned state. An entity id starts with its type (\`Box-1\`), so an entity that keeps its data under a new type name needs a new id and every relation pointing at it rewritten. Read \`docs/phoenix/migrations.mdx\` before writing any other migration.`;
79
102
  /** How to find and read SDK documentation from the CLI. */
80
103
  readonly sdkDocumentation: `## SDK Documentation
81
104