cxtms 1.9.13

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 (215) hide show
  1. package/README.md +384 -0
  2. package/dist/cli.d.ts +6 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +4784 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/extractUtils.d.ts +11 -0
  7. package/dist/extractUtils.d.ts.map +1 -0
  8. package/dist/extractUtils.js +19 -0
  9. package/dist/extractUtils.js.map +1 -0
  10. package/dist/index.d.ts +7 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +11 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/types.d.ts +129 -0
  15. package/dist/types.d.ts.map +1 -0
  16. package/dist/types.js +6 -0
  17. package/dist/types.js.map +1 -0
  18. package/dist/utils/schemaLoader.d.ts +17 -0
  19. package/dist/utils/schemaLoader.d.ts.map +1 -0
  20. package/dist/utils/schemaLoader.js +134 -0
  21. package/dist/utils/schemaLoader.js.map +1 -0
  22. package/dist/validator.d.ts +72 -0
  23. package/dist/validator.d.ts.map +1 -0
  24. package/dist/validator.js +432 -0
  25. package/dist/validator.js.map +1 -0
  26. package/dist/workflowValidator.d.ts +103 -0
  27. package/dist/workflowValidator.d.ts.map +1 -0
  28. package/dist/workflowValidator.js +753 -0
  29. package/dist/workflowValidator.js.map +1 -0
  30. package/package.json +51 -0
  31. package/schemas/actions/all.json +27 -0
  32. package/schemas/actions/clipboard.json +46 -0
  33. package/schemas/actions/confirm.json +21 -0
  34. package/schemas/actions/consoleLog.json +16 -0
  35. package/schemas/actions/dialog.json +25 -0
  36. package/schemas/actions/fileDownload.json +16 -0
  37. package/schemas/actions/forEach.json +31 -0
  38. package/schemas/actions/if.json +12 -0
  39. package/schemas/actions/mutation.json +25 -0
  40. package/schemas/actions/navigate.json +18 -0
  41. package/schemas/actions/navigateBack.json +22 -0
  42. package/schemas/actions/navigateBackOrClose.json +21 -0
  43. package/schemas/actions/notification.json +19 -0
  44. package/schemas/actions/openBarcodeScanner.json +104 -0
  45. package/schemas/actions/query.json +32 -0
  46. package/schemas/actions/refresh.json +13 -0
  47. package/schemas/actions/resetDirtyState.json +22 -0
  48. package/schemas/actions/setFields.json +21 -0
  49. package/schemas/actions/setStore.json +13 -0
  50. package/schemas/actions/validateForm.json +15 -0
  51. package/schemas/actions/workflow.json +24 -0
  52. package/schemas/components/README.md +147 -0
  53. package/schemas/components/appComponent.json +58 -0
  54. package/schemas/components/barcodeScanner.json +69 -0
  55. package/schemas/components/button.json +123 -0
  56. package/schemas/components/calendar.json +489 -0
  57. package/schemas/components/card.json +176 -0
  58. package/schemas/components/collection.json +54 -0
  59. package/schemas/components/dataGrid.json +119 -0
  60. package/schemas/components/datasource.json +151 -0
  61. package/schemas/components/dropdown.json +57 -0
  62. package/schemas/components/field-collection.json +618 -0
  63. package/schemas/components/field.json +265 -0
  64. package/schemas/components/form.json +234 -0
  65. package/schemas/components/index.json +71 -0
  66. package/schemas/components/layout.json +69 -0
  67. package/schemas/components/module.json +167 -0
  68. package/schemas/components/navDropdown.json +36 -0
  69. package/schemas/components/navbar.json +78 -0
  70. package/schemas/components/navbarItem.json +28 -0
  71. package/schemas/components/navbarLink.json +36 -0
  72. package/schemas/components/row.json +31 -0
  73. package/schemas/components/slot.json +30 -0
  74. package/schemas/components/tab.json +34 -0
  75. package/schemas/components/tabs.json +35 -0
  76. package/schemas/components/timeline.json +172 -0
  77. package/schemas/components/timelineGrid.json +328 -0
  78. package/schemas/fields/README.md +66 -0
  79. package/schemas/fields/attachment.json +156 -0
  80. package/schemas/fields/autocomplete-googleplaces.json +130 -0
  81. package/schemas/fields/checkbox.json +82 -0
  82. package/schemas/fields/date.json +88 -0
  83. package/schemas/fields/datetime.json +75 -0
  84. package/schemas/fields/email.json +75 -0
  85. package/schemas/fields/index.json +53 -0
  86. package/schemas/fields/number.json +91 -0
  87. package/schemas/fields/password.json +70 -0
  88. package/schemas/fields/radio.json +94 -0
  89. package/schemas/fields/rangedatetime.json +56 -0
  90. package/schemas/fields/select-async.json +334 -0
  91. package/schemas/fields/select.json +115 -0
  92. package/schemas/fields/tel.json +79 -0
  93. package/schemas/fields/text.json +86 -0
  94. package/schemas/fields/textarea.json +95 -0
  95. package/schemas/fields/time.json +91 -0
  96. package/schemas/fields/url.json +74 -0
  97. package/schemas/schema.graphql +12248 -0
  98. package/schemas/schemas.json +610 -0
  99. package/schemas/workflows/activity.json +96 -0
  100. package/schemas/workflows/common/condition.json +48 -0
  101. package/schemas/workflows/common/expression.json +76 -0
  102. package/schemas/workflows/common/mapping.json +173 -0
  103. package/schemas/workflows/common/step.json +38 -0
  104. package/schemas/workflows/flow/aggregation.json +44 -0
  105. package/schemas/workflows/flow/entity.json +129 -0
  106. package/schemas/workflows/flow/state.json +105 -0
  107. package/schemas/workflows/flow/transition.json +143 -0
  108. package/schemas/workflows/input.json +122 -0
  109. package/schemas/workflows/output.json +61 -0
  110. package/schemas/workflows/schedule.json +26 -0
  111. package/schemas/workflows/tasks/accounting-transaction.json +95 -0
  112. package/schemas/workflows/tasks/action-event.json +65 -0
  113. package/schemas/workflows/tasks/all.json +152 -0
  114. package/schemas/workflows/tasks/appmodule.json +56 -0
  115. package/schemas/workflows/tasks/attachment.json +97 -0
  116. package/schemas/workflows/tasks/authentication.json +86 -0
  117. package/schemas/workflows/tasks/caching.json +68 -0
  118. package/schemas/workflows/tasks/charge.json +92 -0
  119. package/schemas/workflows/tasks/commodity.json +92 -0
  120. package/schemas/workflows/tasks/contact-address.json +72 -0
  121. package/schemas/workflows/tasks/contact-payment-method.json +72 -0
  122. package/schemas/workflows/tasks/contact.json +82 -0
  123. package/schemas/workflows/tasks/csv.json +81 -0
  124. package/schemas/workflows/tasks/document-render.json +105 -0
  125. package/schemas/workflows/tasks/document-send.json +84 -0
  126. package/schemas/workflows/tasks/edi.json +157 -0
  127. package/schemas/workflows/tasks/email-send.json +110 -0
  128. package/schemas/workflows/tasks/error.json +72 -0
  129. package/schemas/workflows/tasks/export.json +90 -0
  130. package/schemas/workflows/tasks/filetransfer.json +102 -0
  131. package/schemas/workflows/tasks/flow-transition.json +68 -0
  132. package/schemas/workflows/tasks/foreach.json +69 -0
  133. package/schemas/workflows/tasks/generic.json +47 -0
  134. package/schemas/workflows/tasks/graphql.json +78 -0
  135. package/schemas/workflows/tasks/httpRequest.json +161 -0
  136. package/schemas/workflows/tasks/import.json +64 -0
  137. package/schemas/workflows/tasks/inventory.json +67 -0
  138. package/schemas/workflows/tasks/job.json +88 -0
  139. package/schemas/workflows/tasks/log.json +73 -0
  140. package/schemas/workflows/tasks/map.json +58 -0
  141. package/schemas/workflows/tasks/movement.json +54 -0
  142. package/schemas/workflows/tasks/note.json +59 -0
  143. package/schemas/workflows/tasks/number.json +65 -0
  144. package/schemas/workflows/tasks/order-tracking-event.json +109 -0
  145. package/schemas/workflows/tasks/order.json +139 -0
  146. package/schemas/workflows/tasks/payment.json +85 -0
  147. package/schemas/workflows/tasks/pdf-document.json +60 -0
  148. package/schemas/workflows/tasks/postal-codes.json +92 -0
  149. package/schemas/workflows/tasks/resolve-timezone.json +65 -0
  150. package/schemas/workflows/tasks/setVariable.json +76 -0
  151. package/schemas/workflows/tasks/switch.json +75 -0
  152. package/schemas/workflows/tasks/template.json +73 -0
  153. package/schemas/workflows/tasks/tracking-event.json +137 -0
  154. package/schemas/workflows/tasks/transmission.json +185 -0
  155. package/schemas/workflows/tasks/unzip-file.json +68 -0
  156. package/schemas/workflows/tasks/user.json +70 -0
  157. package/schemas/workflows/tasks/validation.json +99 -0
  158. package/schemas/workflows/tasks/while.json +53 -0
  159. package/schemas/workflows/tasks/workflow-execute.json +82 -0
  160. package/schemas/workflows/trigger.json +90 -0
  161. package/schemas/workflows/variable.json +46 -0
  162. package/schemas/workflows/workflow.json +335 -0
  163. package/scripts/postinstall.js +291 -0
  164. package/scripts/setup-vscode.js +80 -0
  165. package/skills/cxtms-developer/SKILL.md +118 -0
  166. package/skills/cxtms-developer/ref-cli-auth.md +120 -0
  167. package/skills/cxtms-developer/ref-entity-accounting.md +180 -0
  168. package/skills/cxtms-developer/ref-entity-commodity.md +239 -0
  169. package/skills/cxtms-developer/ref-entity-contact.md +163 -0
  170. package/skills/cxtms-developer/ref-entity-geography.md +154 -0
  171. package/skills/cxtms-developer/ref-entity-job.md +77 -0
  172. package/skills/cxtms-developer/ref-entity-notification.md +85 -0
  173. package/skills/cxtms-developer/ref-entity-order-sub.md +160 -0
  174. package/skills/cxtms-developer/ref-entity-order.md +183 -0
  175. package/skills/cxtms-developer/ref-entity-organization.md +41 -0
  176. package/skills/cxtms-developer/ref-entity-rate.md +182 -0
  177. package/skills/cxtms-developer/ref-entity-shared.md +176 -0
  178. package/skills/cxtms-developer/ref-entity-warehouse.md +115 -0
  179. package/skills/cxtms-developer/ref-graphql-query.md +309 -0
  180. package/skills/cxtms-module-builder/SKILL.md +477 -0
  181. package/skills/cxtms-module-builder/ref-components-data.md +293 -0
  182. package/skills/cxtms-module-builder/ref-components-display.md +411 -0
  183. package/skills/cxtms-module-builder/ref-components-forms.md +369 -0
  184. package/skills/cxtms-module-builder/ref-components-interactive.md +317 -0
  185. package/skills/cxtms-module-builder/ref-components-layout.md +390 -0
  186. package/skills/cxtms-module-builder/ref-components-specialized.md +477 -0
  187. package/skills/cxtms-workflow-builder/SKILL.md +438 -0
  188. package/skills/cxtms-workflow-builder/ref-accounting.md +66 -0
  189. package/skills/cxtms-workflow-builder/ref-communication.md +169 -0
  190. package/skills/cxtms-workflow-builder/ref-entity.md +342 -0
  191. package/skills/cxtms-workflow-builder/ref-expressions-ncalc.md +128 -0
  192. package/skills/cxtms-workflow-builder/ref-expressions-template.md +161 -0
  193. package/skills/cxtms-workflow-builder/ref-filetransfer.md +80 -0
  194. package/skills/cxtms-workflow-builder/ref-flow.md +210 -0
  195. package/skills/cxtms-workflow-builder/ref-other.md +157 -0
  196. package/skills/cxtms-workflow-builder/ref-query.md +105 -0
  197. package/skills/cxtms-workflow-builder/ref-utilities.md +417 -0
  198. package/templates/module-configuration.yaml +44 -0
  199. package/templates/module-form.yaml +152 -0
  200. package/templates/module-grid.yaml +229 -0
  201. package/templates/module-select.yaml +139 -0
  202. package/templates/module.yaml +84 -0
  203. package/templates/workflow-api-tracking.yaml +189 -0
  204. package/templates/workflow-basic.yaml +76 -0
  205. package/templates/workflow-document.yaml +155 -0
  206. package/templates/workflow-entity-trigger.yaml +90 -0
  207. package/templates/workflow-ftp-edi.yaml +158 -0
  208. package/templates/workflow-ftp-tracking.yaml +161 -0
  209. package/templates/workflow-mcp-tool.yaml +112 -0
  210. package/templates/workflow-public-api.yaml +135 -0
  211. package/templates/workflow-scheduled-execute.yaml +75 -0
  212. package/templates/workflow-scheduled.yaml +125 -0
  213. package/templates/workflow-utility.yaml +96 -0
  214. package/templates/workflow-webhook.yaml +128 -0
  215. package/templates/workflow.yaml +140 -0
@@ -0,0 +1,477 @@
1
+ ---
2
+ name: cxtms-module-builder
3
+ description: >
4
+ Works with CXTMS app module YAML files — creates, modifies, fixes, validates, and deploys UI screens, forms, grids, and routes.
5
+ Use when the user asks to create, modify, or fix a module YAML file, references *-module.yaml files, or asks about UI components/forms/grids/routes in a CX project.
6
+ Not for workflow YAML files, TypeScript code, or non-YAML tasks.
7
+ argument-hint: <description of what to build>
8
+ ---
9
+
10
+ You are a CargoXplorer module YAML builder. You generate schema-valid YAML for CX app modules — UI screens, forms, data grids, routes, and components. All output must conform to the JSON schemas in `.cx-schema/`.
11
+
12
+ **IMPORTANT — use `cxtms` for all module operations:**
13
+ - **Scaffold**: `npx cxtms create module <name> --template <template>` — generates a schema-valid YAML file. ALWAYS run this first, then read the generated file, then customize. Do NOT write YAML from scratch or copy templates manually.
14
+ - **Scaffold with fields**: `npx cxtms create module <name> --template <template> --options '<json>'`
15
+ - **Validate**: `npx cxtms <file.yaml>` — run after every change
16
+ - **Schema lookup**: `npx cxtms schema <component>` — e.g., `cxtms schema form`, `cxtms schema dataGrid`
17
+ - **Examples**: `npx cxtms example <component>` — show example YAML
18
+ - **List schemas**: `npx cxtms list`
19
+ - **Extract**: `npx cxtms extract <source> <component> --to <target>` — move components between modules
20
+ - **Feature folder**: `npx cxtms create module <name> --template <template> --feature <feature-name>`
21
+ - **Deploy to server**: `npx cxtms appmodule deploy <file.yaml> --org <id>` — creates or updates module on the CX server
22
+ - **Undeploy from server**: `npx cxtms appmodule undeploy <appModuleId> --org <id>` — removes a module by UUID
23
+ - **Publish all**: `npx cxtms publish [--feature <name>] --org <id>` — deploy all modules and workflows to the server
24
+
25
+ ## Generation Workflow
26
+
27
+ ### Step 1: Scaffold via CLI — MANDATORY
28
+
29
+ **You MUST run `cxtms create module` to generate the initial file.** Do not skip this step. Do not write YAML from scratch. Do not read template files and copy them manually. The CLI generates correct UUIDs, file paths, and structure.
30
+
31
+ ```bash
32
+ npx cxtms create module <name> --template <template>
33
+ npx cxtms create module <name> --template <template> --options '<json>'
34
+ ```
35
+
36
+ | Template | Use Case |
37
+ |----------|----------|
38
+ | `default` | Generic module with form |
39
+ | `form` | Entity create/edit form |
40
+ | `configuration` | Settings/config screen |
41
+ | `grid` | List/table view |
42
+ | `select` | Reusable async select |
43
+
44
+ ### Step 2: Read the generated file
45
+
46
+ ### Step 3: Customize for the use case
47
+
48
+ **All templates** — update module name, component names, entity fields, permissions, GraphQL queries/mutations.
49
+
50
+ **`form`** — update form fields, validationSchema, query/mutation field lists. Add tabs for grouped fields. Customize toolbar buttons. Update dirtyGuard messages.
51
+
52
+ **`configuration`** — update form fields, initialValues.append defaults, validationSchema rules, query/mutation field lists. Add tabs for grouped settings.
53
+
54
+ **`grid`** — update view columns, filters, entity fields. Add/remove views. Customize dotsMenu actions. Configure toolbar with export/import actions.
55
+
56
+ **`select`** — update `valueFieldName`, `itemLabelTemplate`, `itemValueTemplate`. Customize GraphQL query fields and variables. Set `navigateActionPermission`. Configure `dropDownToolbar` create button dialog.
57
+
58
+ ### Step 4: Validate
59
+
60
+ ```bash
61
+ npx cxtms <generated-file.yaml>
62
+ ```
63
+
64
+ ---
65
+
66
+ ## --options Flag
67
+
68
+ Customize generated modules at scaffold time with `--options`. Accepts inline JSON or a file path.
69
+
70
+ ### Field Array Format (all templates)
71
+
72
+ ```bash
73
+ npx cxtms create module "Tariff" --template grid --options '[
74
+ {"name": "code", "type": "text", "label": "Tariff Code", "required": true},
75
+ {"name": "rate", "type": "number", "label": "Rate %"},
76
+ {"name": "effectiveDate", "type": "date"},
77
+ {"name": "isActive", "type": "checkbox", "label": "Active"}
78
+ ]'
79
+ ```
80
+
81
+ ### Object Format (with entityName)
82
+
83
+ ```bash
84
+ npx cxtms create module "Country" --template select --options '{
85
+ "entityName": "Country",
86
+ "fields": [
87
+ {"name": "countryCode", "type": "text", "label": "Country Code"},
88
+ {"name": "countryName", "type": "text", "label": "Country Name"}
89
+ ]
90
+ }'
91
+ ```
92
+
93
+ ### Field Properties
94
+
95
+ | Property | Type | Description |
96
+ |----------|------|-------------|
97
+ | `name` | string | **Required.** Field name (camelCase) |
98
+ | `type` | string | **Required.** text, number, checkbox, date, select, select-async, textarea, email |
99
+ | `label` | string | Display label (auto-generated from name if omitted) |
100
+ | `required` | boolean | Add to validationSchema as required |
101
+ | `default` | any | Default value (form/configuration template: added to initialValues.append) |
102
+
103
+ ### What --options Customizes Per Template
104
+
105
+ | Template | Fields | Entity | Queries |
106
+ |----------|--------|--------|---------|
107
+ | `form` | Form children, validationSchema, initialValues.append | Entity field definitions | GraphQL query field lists (preserves `id`) |
108
+ | `configuration` | Form children, validationSchema, initialValues.append | Entity field definitions | GraphQL query field lists |
109
+ | `grid` | View columns (with showAs by type), entity fields | Entity name + rootEntityName | — |
110
+ | `select` | Entity fields, itemLabelTemplate | Entity name | GraphQL query field lists |
111
+
112
+ ---
113
+
114
+ ## Extract Command
115
+
116
+ Move or copy a component (and its routes) from one module into another. Useful for splitting large modules or sharing components.
117
+
118
+ ```bash
119
+ cxtms extract <source-file> <component-name> --to <target-file>
120
+ cxtms extract <source-file> <component-name> --to <target-file> --copy
121
+ ```
122
+
123
+ ### Flags
124
+ - `--to <file>` — target module file (required)
125
+ - `--copy` — copy instead of move (source keeps the component, target gets a higher-priority copy)
126
+
127
+ ### What Gets Moved/Copied
128
+ - The component matching the exact `name` field
129
+ - Any routes whose `component` field matches the component name
130
+ - Permissions and entities are **NOT** moved
131
+
132
+ ### Examples
133
+
134
+ ```bash
135
+ # Move a component to a new file (creates module scaffold automatically)
136
+ npx cxtms extract modules/orders.yaml Orders/CreateItem --to modules/order-create.yaml
137
+
138
+ # Copy a component (source unchanged, target gets higher priority)
139
+ npx cxtms extract modules/orders.yaml Orders/CreateItem --to modules/order-create.yaml --copy
140
+
141
+ # Extract to an existing module
142
+ npx cxtms extract modules/main.yaml Dashboard --to modules/dashboard.yaml
143
+ ```
144
+
145
+ ### New Target Scaffold
146
+ When the target file doesn't exist, a new module is created with:
147
+ - `module` name derived from filename (PascalCase)
148
+ - Fresh `appModuleId` (UUID)
149
+ - `application` copied from source
150
+ - Empty `entities` and `permissions` arrays
151
+
152
+ ### Workflow
153
+ 1. Run `extract` to move the component
154
+ 2. Manually move any related permissions/entities if needed
155
+ 3. Validate both files: `npx cxtms <source>` and `npx cxtms <target>`
156
+
157
+ ---
158
+
159
+ ## On-Demand References
160
+
161
+ **Read these files only when needed for the current task.** Do not load all references upfront.
162
+
163
+ ### Entity Field Reference (cxtms-developer)
164
+
165
+ !cat skills/cxtms-developer/SKILL.md
166
+
167
+ ### Component Directory
168
+
169
+ Read the relevant category ref file when building specific component types:
170
+
171
+ | Category | Components | File |
172
+ |----------|-----------|------|
173
+ | **Layout & Structure** | `layout`, `row`, `col`, `header`, `tabs`, `toolbar`, `card`, `line`, `slot` | `skills/cxtms-module-builder/ref-components-layout.md` |
174
+ | **Forms & Input** | `form`, `field`, `field-collection`, `barcodeScanner` | `skills/cxtms-module-builder/ref-components-forms.md` |
175
+ | **Data Display** | `dataGrid`, `text`, `markup`, `badge`, `icon`, `image`, `photo`, `summary`, `diff`, `viewer`, `embed` | `skills/cxtms-module-builder/ref-components-display.md` |
176
+ | **Interactive & Nav** | `button`, `dropdown`, `menuButton`, `link`, `redirect`, `navbar`, `navbarItem`, `navbarLink`, `navDropdown` | `skills/cxtms-module-builder/ref-components-interactive.md` |
177
+ | **Data & Collections** | `collection`, `list`, `listItem`, `datasource`, `script` | `skills/cxtms-module-builder/ref-components-data.md` |
178
+ | **Specialized** | `calendar`, `notes`, `dashboard`, `dashboard-widget`, `widget`, `timeline`, `timeline-grid`, `oauth2` | `skills/cxtms-module-builder/ref-components-specialized.md` |
179
+
180
+ ### Templates
181
+
182
+ Read the relevant template after scaffolding to understand the generated structure:
183
+
184
+ | Template | File |
185
+ |----------|------|
186
+ | default | `templates/module.yaml` |
187
+ | form | `templates/module-form.yaml` |
188
+ | configuration | `templates/module-configuration.yaml` |
189
+ | grid | `templates/module-grid.yaml` |
190
+ | select | `templates/module-select.yaml` |
191
+
192
+ ### JSON Schemas
193
+
194
+ Read schema files from `.cx-schema/` only when debugging validation errors:
195
+ - `schemas.json` — main schema definitions
196
+ - `components/<type>.json` — component schemas (layout, form, dataGrid, field, button, tabs, card, calendar, collection, appComponent, slot, module)
197
+ - `fields/<type>.json` — field schemas (text, select, select-async)
198
+ - `actions/<type>.json` — action schemas (navigate, mutation, dialog, all)
199
+
200
+ ---
201
+
202
+ # Module YAML Reference
203
+
204
+ ## Top-Level Structure
205
+
206
+ ```yaml
207
+ module:
208
+ name: "<ModuleName>" # PascalCase identifier
209
+ appModuleId: "<uuid>" # Generate a new UUID v4
210
+ displayName:
211
+ en-US: "Human Readable Name"
212
+ description:
213
+ en-US: "Module description"
214
+ application: "CargoXplorer" # Required
215
+ filePath: "modules/<name>-module.yaml" # File path in repo
216
+
217
+ entities:
218
+ - name: <EntityName>
219
+ entityKind: Order | Contact | OrderEntity | AccountingTransaction | Calendar | CalendarEvent | Other
220
+ extension: false # true if extending existing entity
221
+ displayName: { en-US: "..." }
222
+ fields:
223
+ - name: fieldName
224
+ fieldType: text | number | date | boolean | ...
225
+ displayName: { en-US: "..." }
226
+ isCustomField: false
227
+ props:
228
+ allowOrderBy: true
229
+ allowFilter: true
230
+ filter: # Optional filter selector
231
+ component: "Contacts/Select"
232
+ props:
233
+ filter: "contactType: Customer"
234
+ options: { baseName: "contactId" }
235
+
236
+ permissions:
237
+ - name: "ModuleName/Read" # PascalCase with slashes
238
+ displayName: { en-US: "..." }
239
+ roles: ["Admin", "Manager"]
240
+
241
+ configurations: # Optional: org-level config definitions
242
+ - configName: "apps.myFeature" # Unique config key
243
+ displayName: { en-US: "My Feature Settings" }
244
+ description: { en-US: "Configure my feature" }
245
+ component: "ModuleName/ConfigComponent" # Component that renders the config UI
246
+ defaultValue: # Optional default values
247
+ enabled: true
248
+ limit: 100
249
+
250
+ routes:
251
+ - name: "routeName"
252
+ path: "/module-path" # Supports :params
253
+ component: ComponentName # References component name
254
+ platforms: [web, mobile] # Optional, defaults to both
255
+ props:
256
+ title: { en-US: "..." }
257
+ icon: "icon-name"
258
+ permission: "permission-name"
259
+
260
+ components:
261
+ - name: "ModuleName/ComponentName" # Pattern: Module/Component
262
+ displayName: { en-US: "..." }
263
+ permissions: "permission-name" # String or array
264
+ layout:
265
+ component: layout # Root must be a component
266
+ # ... component tree
267
+ ```
268
+
269
+ ## Action Types
270
+
271
+ Actions are used in event handlers (onClick, onSubmit, etc.) as arrays:
272
+
273
+ ```yaml
274
+ onClick:
275
+ - navigate: "~/path/{{ id }}" # Navigate to route
276
+ - navigateBack: { fallback: "/home" } # Go back in history
277
+ - navigateBackOrClose: { fallback: "/home" } # Go back or close dialog
278
+ - refresh: "componentName" # Refresh a component
279
+ - notification: { message: { en-US: "Saved!" }, type: success } # success|error|warning|info
280
+ - confirm: { title: { en-US: "Delete?" }, message: { en-US: "Are you sure?" } }
281
+ - mutation:
282
+ command: "mutation M($input: MInput!) { m(input: $input) { result } }"
283
+ variables: { input: "{{ form }}" }
284
+ onSuccess: [...]
285
+ onError: [...]
286
+ - query:
287
+ command: "query Q($id: ID!) { entity(id: $id) { id name } }"
288
+ variables: { id: "{{ entityId }}" }
289
+ onSuccess: [...]
290
+ onError: [...]
291
+ - setFields: { "fieldName": "{{ value }}" } # Set form field values
292
+ - setStore: { "key": "{{ value }}" } # Set store values
293
+ - validateForm: {} # Trigger form validation
294
+ - dialog:
295
+ name: "dialogName"
296
+ props: { title: { en-US: "Title" } }
297
+ component: { component: "Module/Component" }
298
+ onClose: [...]
299
+ - workflow:
300
+ workflowId: "<uuid>"
301
+ inputs: { key: "value" }
302
+ onSuccess: [...]
303
+ onError: [...]
304
+ - fileDownload: { url: "...", fileName: "..." }
305
+ - forEach:
306
+ items: "{{ selectedItems }}"
307
+ item: "currentItem"
308
+ actions: [...]
309
+ - if: "{{ condition }}"
310
+ then: [...]
311
+ else: [...]
312
+ - consoleLog: { message: "debug info" }
313
+ - openBarcodeScanner: { onScan: [...] }
314
+ - resetDirtyState: {}
315
+ ```
316
+
317
+ ## Common Patterns
318
+
319
+ ### Localized strings
320
+ ```yaml
321
+ displayName:
322
+ en-US: "English text"
323
+ es-ES: "Spanish text"
324
+ ```
325
+
326
+ ### Template expressions
327
+ ```yaml
328
+ value: "{{ fieldName }}" # Simple variable
329
+ value: "{{ format date L }}" # Format helper
330
+ value: "{{ number quantity }}" # Type cast
331
+ value: "{{ eval items.length > 0 }}" # JavaScript expression
332
+ isHidden: "{{ eval !canEdit }}" # Conditional visibility
333
+ ```
334
+
335
+ ### Permissions
336
+ ```yaml
337
+ permission: "ModuleName/Read" # Single string (PascalCase/Action)
338
+ permissions: # Array
339
+ - "ModuleName/Read"
340
+ - "ModuleName/Update"
341
+ ```
342
+
343
+ ### Async Select Component Pattern
344
+
345
+ Reusable select components (e.g., `Countries/Select`, `Ports/Select`) follow this structure:
346
+
347
+ ```yaml
348
+ - name: Entity/Select
349
+ displayName: { en-US: "Select Entity" }
350
+ platforms: [web, mobile]
351
+ layout:
352
+ component: field
353
+ name: entityId # Value binding field name
354
+ props:
355
+ type: select-async
356
+ label: { en-US: "Entity" }
357
+ options:
358
+ valueFieldName: "entityId" # Which result field holds the value
359
+ itemLabelTemplate: "{{name}}" # Handlebars template for labels
360
+ itemValueTemplate: "{{entityId}}" # Handlebars template for values
361
+ navigateActionPermission: "Entity/Update"
362
+ searchQuery: # References list query below
363
+ name: getEntities
364
+ path: entities.items
365
+ params:
366
+ search: "{{ string search }}"
367
+ take: "{{ number pageSize }}"
368
+ skip: "{{ number skip }}"
369
+ filter: "{{ string filter }}"
370
+ valueQuery: # References single-item query below
371
+ name: getEntity
372
+ path: entity
373
+ params:
374
+ entityId: "{{entityId}}"
375
+ allowSearch: true
376
+ allowClear: true
377
+ dropDownToolbar: # Create button in dropdown
378
+ - component: button
379
+ name: createBtn
380
+ props:
381
+ label: { en-US: "Create Entity" }
382
+ icon: plus
383
+ onClick:
384
+ - dialog:
385
+ component: Entity/CreateEntity
386
+ onClose:
387
+ - selectValue: "{{ result.entityId }}"
388
+ queries:
389
+ - name: getEntities # Paginated search query
390
+ query:
391
+ command: >-
392
+ query($organizationId: Int!, $filter: String!, $search: String!, $take: Int!, $skip: Int!) {
393
+ entities(...) { items { entityId name } totalCount }
394
+ }
395
+ variables: { organizationId: "{{number organizationId}}", ... }
396
+ - name: getEntity # Single-value lookup query
397
+ query:
398
+ command: >-
399
+ query($organizationId: Int!, $entityId: Int!) {
400
+ entity(...) { entityId name }
401
+ }
402
+ variables: { entityId: "{{number entityId}}" }
403
+ onEditClick: # Edit action on selected item
404
+ - dialog:
405
+ component: { layout: { component: layout, children: [{ component: Entity/UpdateEntity }] } }
406
+ ```
407
+
408
+ ---
409
+
410
+ ## Server Module Commands
411
+
412
+ Deploy, undeploy, and release commands are listed in the CLI section at the top of this file. For authentication setup (login, PAT tokens, org management): see [cxtms-developer/ref-cli-auth.md](skills/cxtms-developer/ref-cli-auth.md)
413
+
414
+ ### Releasing App to GitHub
415
+
416
+ Use `app release` to release modified modules and workflows from the CX server to a GitHub repository. This creates a branch and pull request — it does NOT push directly to the target branch.
417
+
418
+ ```bash
419
+ # Release all unpublished changes to GitHub (creates a PR) — message is required
420
+ npx cxtms app release -m "Add warehouse locations module"
421
+
422
+ # Release specific modules and/or workflows by YAML file
423
+ npx cxtms app release -m "Fix country module" modules/my-module.yaml
424
+ npx cxtms app release -m "Update billing" modules/a.yaml workflows/b.yaml
425
+
426
+ # Force release all modules and workflows (not just unpublished ones)
427
+ npx cxtms app release -m "Full republish" --force
428
+
429
+ # Release with explicit org
430
+ npx cxtms app release -m "Add warehouse locations module" --org 42
431
+ ```
432
+
433
+ **What `app release` does:**
434
+ 1. Reads `app.yaml` for the `id` (appManifestId), repository, and branch
435
+ 2. Increments the app version (patch bump)
436
+ 3. Creates a `publish/{app-name}-v{version}-{timestamp}` branch on GitHub
437
+ 4. Commits `app.yaml` + selected module/workflow YAML files to the branch
438
+ 5. Creates a pull request from the publish branch to the target branch
439
+ 6. Marks published modules and workflows as `hasUnpublishedChanges: false`
440
+
441
+ **This is a release-to-git operation** — it commits the current server-side YAML directly to GitHub via the API. No local git repo is involved. The modules and workflows being released are taken from the CX server database, not from local files. The YAML file arguments only identify *which* items to include by their IDs.
442
+
443
+ **Important:** Modules and workflows must be deployed to the TMS server before they can be released. Use `cxtms appmodule deploy` or `cxtms workflow deploy` first, then `cxtms app release` to commit them to GitHub.
444
+
445
+ **Do NOT run `app release` automatically.** Only release when the user explicitly requests it. Releasing creates a branch and PR on GitHub, so it should be done once when all changes are ready — not after every deploy.
446
+
447
+ **Prerequisites:**
448
+ - `app.yaml` must exist with a valid `id` field
449
+ - The app manifest must be installed on the server (`app install` first)
450
+ - The server must have a GitHub token configured for the organization
451
+ - The repository and branch must be set on the app manifest
452
+
453
+ **Related commands:**
454
+ - `npx cxtms app install` — install/refresh app from GitHub into the server
455
+ - `npx cxtms app install --force` — force reinstall even if same version
456
+ - `npx cxtms app install --branch develop` — install from a specific branch
457
+ - `npx cxtms app install --skip-changed` — skip modules with local changes
458
+ - `npx cxtms app list` — list installed app manifests on the server
459
+
460
+ ---
461
+
462
+ # Generation Rules
463
+
464
+ 1. **Always scaffold via `cxtms create module` first** — never write YAML from scratch, never copy templates manually
465
+ 2. **Use localized strings** `{ en-US: "..." }` for all user-visible text
466
+ 3. **Follow naming conventions**:
467
+ - Module names: PascalCase (e.g., `WarehouseLocations`)
468
+ - Component names: Module/Component pattern (e.g., `WarehouseLocations/List`)
469
+ - Route paths: kebab-case (e.g., `/warehouse-locations`)
470
+ - Permission names: PascalCase with slashes (e.g., `WarehouseLocations/Read`, `System/Contacts/Update`)
471
+ 4. **Template expressions** use `{{ expression }}` syntax (double curly braces)
472
+ 5. **Include filePath** property pointing to the YAML file location
473
+ 6. **Set proper entityKind** when defining entities (Order, Contact, OrderEntity, AccountingTransaction, Calendar, CalendarEvent, Other)
474
+ 7. **DataGrid options** requires ALL properties: query, rootEntityName, entityKeys, navigationType, enableDynamicGrid, enableViews, enableSearch, enablePagination, enableColumns, enableFilter, defaultView, onRowClick
475
+ 8. **Form component** requires `validationSchema` in props
476
+ 9. **Do not change `appModuleId` or `filePath`** — set correctly by CLI scaffold
477
+ 10. **Always validate** the final YAML: `npx cxtms <file.yaml>`