@fluentcommerce/ai-skills 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @fluentcommerce/ai-skills might be problematic. Click here for more details.

Files changed (169) hide show
  1. package/README.md +866 -616
  2. package/bin/cli.mjs +2112 -1973
  3. package/content/cli/agents/fluent-cli/agent.json +149 -149
  4. package/content/cli/agents/fluent-cli.md +132 -132
  5. package/content/cli/skills/fluent-bootstrap/SKILL.md +214 -190
  6. package/content/cli/skills/fluent-cli-index/SKILL.md +1 -1
  7. package/content/cli/skills/fluent-cli-mcp-cicd/SKILL.md +117 -1
  8. package/content/cli/skills/fluent-cli-reference/SKILL.md +1040 -623
  9. package/content/cli/skills/fluent-cli-retailer/SKILL.md +27 -2
  10. package/content/cli/skills/fluent-cli-settings/SKILL.md +21 -1
  11. package/content/cli/skills/fluent-connect/SKILL.md +937 -886
  12. package/content/cli/skills/fluent-module-deploy/SKILL.md +181 -17
  13. package/content/cli/skills/fluent-profile/SKILL.md +73 -0
  14. package/content/cli/skills/fluent-workflow/SKILL.md +360 -310
  15. package/content/dev/agents/fluent-backend-dev/AGENT.md +58 -0
  16. package/content/dev/agents/fluent-backend-dev/agent.json +69 -0
  17. package/content/dev/agents/fluent-backend-dev.md +287 -0
  18. package/content/dev/agents/fluent-dev/AGENT.md +98 -76
  19. package/content/dev/agents/fluent-dev/agent.json +24 -2
  20. package/content/dev/agents/fluent-dev.md +194 -524
  21. package/content/dev/agents/fluent-frontend-dev/AGENT.md +63 -0
  22. package/content/dev/agents/fluent-frontend-dev/agent.json +52 -0
  23. package/content/dev/agents/fluent-frontend-dev.md +323 -0
  24. package/content/dev/skills/fluent-archive/SKILL.md +234 -0
  25. package/content/dev/skills/fluent-build/SKILL.md +312 -170
  26. package/content/dev/skills/fluent-connection-analysis/SKILL.md +422 -386
  27. package/content/dev/skills/fluent-custom-code/SKILL.md +15 -9
  28. package/content/dev/skills/fluent-data-module-scaffold/SKILL.md +731 -0
  29. package/content/dev/skills/fluent-e2e-test/SKILL.md +501 -394
  30. package/content/dev/skills/fluent-event-api/SKILL.md +962 -945
  31. package/content/dev/skills/fluent-feature-explain/SKILL.md +680 -603
  32. package/content/dev/skills/fluent-feature-plan/PLAN_TEMPLATE.md +40 -11
  33. package/content/dev/skills/fluent-feature-plan/SKILL.md +478 -221
  34. package/content/dev/skills/fluent-feature-status/SKILL.md +335 -0
  35. package/content/dev/skills/fluent-feedback/SKILL.md +221 -0
  36. package/content/dev/skills/fluent-implementation-map/SKILL.md +644 -0
  37. package/content/dev/skills/fluent-job-batch/SKILL.md +10 -0
  38. package/content/dev/skills/fluent-module-scaffold/SKILL.md +134 -3
  39. package/content/dev/skills/fluent-module-validate/SKILL.md +778 -775
  40. package/content/dev/skills/fluent-mystique-analyze/SKILL.md +817 -0
  41. package/content/dev/skills/fluent-mystique-builder/COMPONENT_TEMPLATE.md +81 -0
  42. package/content/dev/skills/fluent-mystique-builder/README.md +63 -0
  43. package/content/dev/skills/fluent-mystique-builder/SKILL.md +1294 -0
  44. package/content/dev/skills/fluent-mystique-builder/components/INDEX.md +92 -0
  45. package/content/dev/skills/fluent-mystique-builder/components/fc.accordion.md +48 -0
  46. package/content/dev/skills/fluent-mystique-builder/components/fc.action.field.fulfilmentpack.md +20 -0
  47. package/content/dev/skills/fluent-mystique-builder/components/fc.action.field.multiparcel.md +21 -0
  48. package/content/dev/skills/fluent-mystique-builder/components/fc.action.field.returnitems.md +21 -0
  49. package/content/dev/skills/fluent-mystique-builder/components/fc.action.field.wavepick.md +21 -0
  50. package/content/dev/skills/fluent-mystique-builder/components/fc.action.inline.md +24 -0
  51. package/content/dev/skills/fluent-mystique-builder/components/fc.activity.entity.md +25 -0
  52. package/content/dev/skills/fluent-mystique-builder/components/fc.analytics.viz.md +20 -0
  53. package/content/dev/skills/fluent-mystique-builder/components/fc.attribute.column.md +111 -0
  54. package/content/dev/skills/fluent-mystique-builder/components/fc.attribute.json.md +20 -0
  55. package/content/dev/skills/fluent-mystique-builder/components/fc.attribute.jsoneditor.md +54 -0
  56. package/content/dev/skills/fluent-mystique-builder/components/fc.attribute.locationId.md +51 -0
  57. package/content/dev/skills/fluent-mystique-builder/components/fc.attribute.retailerId.md +52 -0
  58. package/content/dev/skills/fluent-mystique-builder/components/fc.button.bar.md +57 -0
  59. package/content/dev/skills/fluent-mystique-builder/components/fc.button.print.download.md +53 -0
  60. package/content/dev/skills/fluent-mystique-builder/components/fc.button.print.inline.compatibility.md +60 -0
  61. package/content/dev/skills/fluent-mystique-builder/components/fc.button.print.inline.md +53 -0
  62. package/content/dev/skills/fluent-mystique-builder/components/fc.button.print.md +24 -0
  63. package/content/dev/skills/fluent-mystique-builder/components/fc.button.print.pick.md +61 -0
  64. package/content/dev/skills/fluent-mystique-builder/components/fc.buttons.add.reject.md +20 -0
  65. package/content/dev/skills/fluent-mystique-builder/components/fc.card.attribute.md +73 -0
  66. package/content/dev/skills/fluent-mystique-builder/components/fc.card.attributes.grid.md +40 -0
  67. package/content/dev/skills/fluent-mystique-builder/components/fc.card.image.md +37 -0
  68. package/content/dev/skills/fluent-mystique-builder/components/fc.card.map.point.md +24 -0
  69. package/content/dev/skills/fluent-mystique-builder/components/fc.card.multi.md +79 -0
  70. package/content/dev/skills/fluent-mystique-builder/components/fc.card.product.md +27 -0
  71. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.area.md +34 -0
  72. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.area.wrapper.feed.md +98 -0
  73. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.bar.md +52 -0
  74. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.bar.wrapper.source.md +104 -0
  75. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.gauge.md +28 -0
  76. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.gauge.wrapper.threshold.md +118 -0
  77. package/content/dev/skills/fluent-mystique-builder/components/fc.chart.line.md +32 -0
  78. package/content/dev/skills/fluent-mystique-builder/components/fc.conditional.md +62 -0
  79. package/content/dev/skills/fluent-mystique-builder/components/fc.dashboard.threshold.md +65 -0
  80. package/content/dev/skills/fluent-mystique-builder/components/fc.daterange.wrapper.forwarder.md +56 -0
  81. package/content/dev/skills/fluent-mystique-builder/components/fc.drawer.button.md +21 -0
  82. package/content/dev/skills/fluent-mystique-builder/components/fc.event.detail.md +20 -0
  83. package/content/dev/skills/fluent-mystique-builder/components/fc.events.search.md +21 -0
  84. package/content/dev/skills/fluent-mystique-builder/components/fc.field.daterange.md +83 -0
  85. package/content/dev/skills/fluent-mystique-builder/components/fc.field.filterComplex.md +106 -0
  86. package/content/dev/skills/fluent-mystique-builder/components/fc.field.intrange.md +82 -0
  87. package/content/dev/skills/fluent-mystique-builder/components/fc.field.multistring.md +50 -0
  88. package/content/dev/skills/fluent-mystique-builder/components/fc.filterPanel.md +53 -0
  89. package/content/dev/skills/fluent-mystique-builder/components/fc.json.editor.md +22 -0
  90. package/content/dev/skills/fluent-mystique-builder/components/fc.json.viewer.md +21 -0
  91. package/content/dev/skills/fluent-mystique-builder/components/fc.list.customAction.md +79 -0
  92. package/content/dev/skills/fluent-mystique-builder/components/fc.list.md +116 -0
  93. package/content/dev/skills/fluent-mystique-builder/components/fc.list.wrapper.bppmetrics.md +69 -0
  94. package/content/dev/skills/fluent-mystique-builder/components/fc.list.wrapper.feed.md +65 -0
  95. package/content/dev/skills/fluent-mystique-builder/components/fc.list.wrapper.source.md +64 -0
  96. package/content/dev/skills/fluent-mystique-builder/components/fc.modal.button.addItem.md +60 -0
  97. package/content/dev/skills/fluent-mystique-builder/components/fc.modal.button.md +21 -0
  98. package/content/dev/skills/fluent-mystique-builder/components/fc.mutation.inline.md +88 -0
  99. package/content/dev/skills/fluent-mystique-builder/components/fc.mystique.collapsible.attributes.md +83 -0
  100. package/content/dev/skills/fluent-mystique-builder/components/fc.mystique.collapsible.text.md +33 -0
  101. package/content/dev/skills/fluent-mystique-builder/components/fc.mystique.link.md +30 -0
  102. package/content/dev/skills/fluent-mystique-builder/components/fc.order.itemDetails.md +20 -0
  103. package/content/dev/skills/fluent-mystique-builder/components/fc.order.shipmentDetails.md +20 -0
  104. package/content/dev/skills/fluent-mystique-builder/components/fc.page.filter.select.md +87 -0
  105. package/content/dev/skills/fluent-mystique-builder/components/fc.page.md +64 -0
  106. package/content/dev/skills/fluent-mystique-builder/components/fc.page.refresh.md +48 -0
  107. package/content/dev/skills/fluent-mystique-builder/components/fc.page.section.column.md +71 -0
  108. package/content/dev/skills/fluent-mystique-builder/components/fc.page.section.header.md +61 -0
  109. package/content/dev/skills/fluent-mystique-builder/components/fc.page.section.md +59 -0
  110. package/content/dev/skills/fluent-mystique-builder/components/fc.page.wizard.md +45 -0
  111. package/content/dev/skills/fluent-mystique-builder/components/fc.page.wizard.summary.md +56 -0
  112. package/content/dev/skills/fluent-mystique-builder/components/fc.progress.circular.md +20 -0
  113. package/content/dev/skills/fluent-mystique-builder/components/fc.provider.graphql.md +71 -0
  114. package/content/dev/skills/fluent-mystique-builder/components/fc.quantity.list.md +87 -0
  115. package/content/dev/skills/fluent-mystique-builder/components/fc.repeater.md +56 -0
  116. package/content/dev/skills/fluent-mystique-builder/components/fc.reports.ipuipc.md +54 -0
  117. package/content/dev/skills/fluent-mystique-builder/components/fc.return.rowExpansion.md +19 -0
  118. package/content/dev/skills/fluent-mystique-builder/components/fc.scanner.barcode.md +21 -0
  119. package/content/dev/skills/fluent-mystique-builder/components/fc.scanner.barcodeFilter.md +72 -0
  120. package/content/dev/skills/fluent-mystique-builder/components/fc.scanner.camera.md +20 -0
  121. package/content/dev/skills/fluent-mystique-builder/components/fc.settingForm.md +64 -0
  122. package/content/dev/skills/fluent-mystique-builder/components/fc.sourcing.profile.drawer.button.md +19 -0
  123. package/content/dev/skills/fluent-mystique-builder/components/fc.sourcing.profile.modal.button.md +64 -0
  124. package/content/dev/skills/fluent-mystique-builder/components/fc.sourcing.strategy.modal.button.md +20 -0
  125. package/content/dev/skills/fluent-mystique-builder/components/fc.stepper.md +20 -0
  126. package/content/dev/skills/fluent-mystique-builder/components/fc.tab.content.md +56 -0
  127. package/content/dev/skills/fluent-mystique-builder/components/fc.tabs.card.md +64 -0
  128. package/content/dev/skills/fluent-mystique-builder/components/fc.tabs.md +69 -0
  129. package/content/dev/skills/fluent-mystique-builder/components/fc.tile.metric.md +73 -0
  130. package/content/dev/skills/fluent-mystique-builder/components/fc.workflow.provider.md +77 -0
  131. package/content/dev/skills/fluent-mystique-builder/validate-docs.ps1 +260 -0
  132. package/content/dev/skills/fluent-mystique-scaffold/SKILL.md +1830 -0
  133. package/content/dev/skills/fluent-mystique-validate/SKILL.md +646 -0
  134. package/content/dev/skills/fluent-pre-deploy-check/SKILL.md +1144 -1090
  135. package/content/dev/skills/fluent-retailer-config/SKILL.md +1162 -1120
  136. package/content/dev/skills/fluent-rollback/SKILL.md +387 -0
  137. package/content/dev/skills/fluent-rule-scaffold/SKILL.md +515 -394
  138. package/content/dev/skills/fluent-scope-decompose/SKILL.md +1123 -1021
  139. package/content/dev/skills/fluent-session-audit-export/SKILL.md +880 -632
  140. package/content/dev/skills/fluent-session-summary/SKILL.md +320 -195
  141. package/content/dev/skills/fluent-settings/SKILL.md +151 -2
  142. package/content/dev/skills/fluent-source-onboard/SKILL.md +23 -4
  143. package/content/dev/skills/fluent-sourcing/SKILL.md +14 -0
  144. package/content/dev/skills/fluent-system-monitoring/SKILL.md +771 -767
  145. package/content/dev/skills/fluent-test-data/SKILL.md +514 -513
  146. package/content/dev/skills/fluent-trace/SKILL.md +1169 -1143
  147. package/content/dev/skills/fluent-transition-api/SKILL.md +364 -346
  148. package/content/dev/skills/fluent-use-case-discover/SKILL.md +593 -471
  149. package/content/dev/skills/fluent-use-case-discover/SPEC_TEMPLATE.md +22 -1
  150. package/content/dev/skills/fluent-version-manage/SKILL.md +44 -3
  151. package/content/dev/skills/fluent-workflow-analyzer/SKILL.md +995 -959
  152. package/content/dev/skills/fluent-workflow-builder/SKILL.md +668 -326
  153. package/content/dev/skills/fluent-workflow-deploy/SKILL.md +480 -0
  154. package/content/dev/skills/fluent-workspace-tree/SKILL.md +281 -0
  155. package/content/mcp-extn/agents/fluent-mcp.md +133 -132
  156. package/content/mcp-extn/skills/fluent-mcp-tools/SKILL.md +812 -800
  157. package/content/mcp-official/agents/fluent-mcp-core.md +91 -91
  158. package/content/mcp-official/skills/fluent-mcp-core/SKILL.md +94 -94
  159. package/content/rfl/skills/fluent-rfl-assess/SKILL.md +172 -172
  160. package/docs/CAPABILITY_MAP.md +106 -73
  161. package/docs/DEPLOYMENT_PROMOTION_RUNBOOK.md +218 -0
  162. package/docs/DESIGN-implementation-map.md +698 -0
  163. package/docs/DEV_WORKFLOW.md +814 -802
  164. package/docs/FLOW_RUN.md +142 -142
  165. package/docs/GETTING_STARTED.md +427 -0
  166. package/docs/USE_CASES.md +906 -50
  167. package/metadata.json +184 -155
  168. package/package.json +7 -2
  169. package/docs/USE_CASES.pdf +0 -0
@@ -0,0 +1,731 @@
1
+ ---
2
+ name: fluent-data-module-scaffold
3
+ description: Scaffold a new Fluent Commerce data module (no Java plugins). Generates module structure with assets directories, module.json, config template, and build script. Triggers on "create data module", "scaffold data module", "new data module", "data module".
4
+ user-invocable: true
5
+ allowed-tools: Bash, Read, Write, Edit, Glob, Grep
6
+ argument-hint: <module-name> [--profile <profile>]
7
+ ---
8
+
9
+ # Data Module Scaffolder
10
+
11
+ Generate a complete Fluent Commerce data module skeleton with no Java plugins, no Maven, and no compilation step. Data modules package infrastructure data (locations, networks, carriers), product catalogues, settings, workflows, and other JSON/CSV assets into a deployable module ZIP.
12
+
13
+ ## Planning Gate
14
+
15
+ **Before scaffolding, write a plan and get approval.** This is mandatory for all non-trivial module creation.
16
+
17
+ **Plan file path:** `accounts/<PROFILE>/tasks/<YYYY-MM-DD>-data-module-scaffold-<slug>.md`
18
+
19
+ The plan should cover:
20
+ 1. **Purpose** -- what data this module will contain and why it is a separate module
21
+ 2. **Asset inventory** -- which asset directories will be populated and with what content
22
+ 3. **Config variables** -- what `[[variable]]` tokens will be used and their expected values
23
+ 4. **Dependencies** -- other modules that must be installed first or after
24
+ 5. **Target retailer(s)** -- which retailer(s) this data is scoped to
25
+
26
+ Write the plan file, present it to the user, and wait for explicit approval ("yes", "go ahead", "approved", "do it") before generating any files. On approval, update the plan status to `APPROVED`.
27
+
28
+ **Skip the gate** when: the user says "just do it" or "skip planning", or a pre-approved plan already exists in `accounts/<PROFILE>/features/*/status.json` or `accounts/<PROFILE>/tasks/`.
29
+
30
+ ## Handoff Protocol
31
+
32
+ ### Signals emitted by this skill
33
+
34
+ | Signal | Condition | Example |
35
+ |--------|-----------|---------|
36
+ | `-> READY: <path>` | Data module scaffolded | `-> READY: accounts/HMDEV/SOURCE/fc-data-locations/` |
37
+ | `-> NEXT: /fluent-<skill>` | Ready for build or deploy | `-> NEXT: /fluent-module-deploy` |
38
+ | `-> BLOCKED: <reason>` | Cannot proceed | `-> BLOCKED: PLAN_REQUIRED — Write a plan via /fluent-feature-plan` |
39
+
40
+ ### Error codes
41
+
42
+ | Code | Condition | Recovery |
43
+ |------|-----------|----------|
44
+ | `PLAN_REQUIRED` | Scaffolding attempted without approved plan | Run `/fluent-feature-plan` first |
45
+ | `VALIDATION_FAILED` | Module name conflicts or missing required assets | Fix input and retry |
46
+
47
+ ## When to Use
48
+
49
+ - Infrastructure data: locations, networks, carriers, storage areas
50
+ - Product catalogues, categories, and product data
51
+ - Inventory catalogue and virtual catalogue definitions
52
+ - Settings bundles (retailer-scoped or account-scoped)
53
+ - Workflow-only modules (deploying workflow JSON without custom rules)
54
+ - Sample or test data for development and QA environments
55
+ - Any module that contains only JSON/CSV assets and no Java plugins
56
+
57
+ ## When NOT to Use
58
+
59
+ - If you need custom Java orchestration rules, use `/fluent-module-scaffold` instead
60
+ - If you need to add rules to an existing module, use `/fluent-rule-scaffold`
61
+ - If you are building an extension module with Maven/OSGi plugins, use `/fluent-module-scaffold`
62
+
63
+ ## Ownership Boundary
64
+
65
+ This skill owns:
66
+ - Creating the data module directory structure
67
+ - Generating `module.json` (no rules section)
68
+ - Generating `module.config.json` template
69
+ - Creating empty asset directories
70
+ - Generating build scripts (bash `.sh` and PowerShell `.ps1`) for ZIP packaging
71
+ - Providing asset JSON schema examples
72
+
73
+ This skill does **not** own:
74
+ - Java compilation or Maven builds --> `/fluent-module-scaffold`
75
+ - Adding rules to any module --> `/fluent-rule-scaffold`
76
+ - Building extension modules with plugins --> `/fluent-build`
77
+ - Deploying modules --> `/fluent-module-deploy`
78
+ - Validating module structure --> `/fluent-module-validate`
79
+
80
+ ## Inputs
81
+
82
+ | Parameter | Required | Default | Description |
83
+ |-----------|----------|---------|-------------|
84
+ | `module-name` | Yes | -- | Module identifier (e.g., `hm-infra-data`). Lowercase alphanumeric with hyphens only. Used for directory name and `module.json` name field. |
85
+ | `--description` | No | Auto-generated | Module description for `module.json` |
86
+ | `--account-prefix` | No | Auto-detect from profile | Account/company prefix for the module name in `module.json` (e.g., `hm`, `acme`) |
87
+ | `--profile` | No | Active profile | Fluent CLI profile for path resolution and prefix detection |
88
+ | `--initial-version` | No | `1.0.0` | Initial version in `module.json` |
89
+
90
+ ## Pre-Check: Module Already Exists?
91
+
92
+ Before creating anything, check if the target directory already exists:
93
+
94
+ ```
95
+ accounts/<PROFILE>/SOURCE/<module-name>/
96
+ ```
97
+
98
+ If it exists, **abort** with message:
99
+ ```
100
+ Module directory already exists: accounts/<PROFILE>/SOURCE/<module-name>/
101
+ Choose a different module name or delete the existing directory first.
102
+ ```
103
+
104
+ Also check for a Maven-based module with the same name:
105
+ ```
106
+ accounts/<PROFILE>/SOURCE/fluentcommerce-fc-module-<module-name>/
107
+ ```
108
+
109
+ If found, warn that an extension module with this name already exists.
110
+
111
+ ## Account Prefix Detection
112
+
113
+ The account prefix appears in the `module.json` `name` field as `<prefix>/<module-name>`. Detection order:
114
+
115
+ ```
116
+ 1. If --account-prefix provided, use it directly
117
+
118
+ 2. Else check existing modules under accounts/<PROFILE>/SOURCE/
119
+ Read any module.json and extract the prefix from the "name" field
120
+ e.g., "name": "hm/infra-data" --> prefix is "hm"
121
+
122
+ 3. Else derive from PROFILE name (lowercase)
123
+ HMDEV --> hmdev
124
+ SAGIRISH --> sagirish
125
+
126
+ 4. Fallback: "my-company"
127
+ Warn user: "Could not detect account prefix. Update module.json name field manually."
128
+ ```
129
+
130
+ ## Generated Directory Structure
131
+
132
+ ```
133
+ accounts/<PROFILE>/SOURCE/<module-name>/
134
+ +-- resources/
135
+ | +-- module.json # Module manifest (no rules)
136
+ | +-- module.config.json # Variable template
137
+ | +-- assets/
138
+ | +-- locations/ # Location JSON files
139
+ | +-- networks/ # Network JSON files
140
+ | +-- carriers/ # Carrier JSON files
141
+ | +-- categories/ # Category JSON files
142
+ | +-- products/ # Product JSON files
143
+ | +-- inventory-catalogues/ # Inventory catalogue definitions
144
+ | +-- product-catalogues/ # Product catalogue definitions
145
+ | +-- virtual-catalogues/ # Virtual catalogue definitions
146
+ | +-- settings/ # Settings JSON files
147
+ | +-- workflows/ # Workflow JSON files
148
+ | +-- workflow-fragments/ # Workflow fragment groups
149
+ | | +-- <workflow-name>/ # One subdirectory per workflow
150
+ | +-- controls/ # Control group JSON files
151
+ | +-- storage-areas/ # Storage area definitions
152
+ | +-- users/ # User JSON files
153
+ +-- scripts/
154
+ | +-- build-module.sh # Bash build script (ZIP packaging)
155
+ | +-- build-module.ps1 # PowerShell build script (ZIP packaging)
156
+ +-- dist/ # Output directory for built ZIPs
157
+ ```
158
+
159
+ **Key difference from extension modules:** No `plugins/` directory, no `pom.xml`, no `global/` directory, no `.gitignore` for Maven artifacts. The entire module is just `resources/` + `scripts/`.
160
+
161
+ ## File Templates
162
+
163
+ ### Module Manifest (`resources/module.json`)
164
+
165
+ ```json
166
+ {
167
+ "_schema": "1.0.0",
168
+ "name": "${ACCOUNT_PREFIX}/${MODULE_NAME}",
169
+ "version": "${INITIAL_VERSION}",
170
+ "title": "${MODULE_TITLE}",
171
+ "description": "${MODULE_DESCRIPTION}",
172
+ "authors": [
173
+ {
174
+ "name": "Implementation Team"
175
+ }
176
+ ],
177
+ "dependencies": [
178
+ {
179
+ "name": "fluent-commerce/core",
180
+ "type": "module",
181
+ "version": "2.x.x"
182
+ }
183
+ ],
184
+ "contracts": []
185
+ }
186
+ ```
187
+
188
+ **Important:** Data modules have NO `modules[].provides` section and NO `rules` array. There are no Java plugins to register.
189
+
190
+ ### Config Template (`resources/module.config.json`)
191
+
192
+ ```json
193
+ {
194
+ "default:carrier.ref": "",
195
+ "default:network.ref": "",
196
+ "default:catalogue.ref": "",
197
+ "workflow:order:hd:network.ref": "",
198
+ "workflow:order:cc:network.ref": "",
199
+ "setting:api.timeout": "30000"
200
+ }
201
+ ```
202
+
203
+ Populate this template with keys relevant to the module's asset files. Keys that are not needed can be removed. An empty `{}` is valid if no variables are used.
204
+
205
+ ### Config Prefix System
206
+
207
+ Config keys in `module.config.json` use a prefix system to control variable scope:
208
+
209
+ | Prefix | Scope | Example |
210
+ |--------|-------|---------|
211
+ | `default:` | Applied to all assets | `default:carrier.ref` |
212
+ | `workflow:<type>:<subtype>:` | Applied only to matching workflow assets | `workflow:order:hd:network.ref` |
213
+ | `setting:` | Applied only to settings assets | `setting:api.timeout` |
214
+ | *(none)* | Global scope | `carrier.ref` |
215
+
216
+ **Specificity rule:** More specific prefixes (more colons) take priority over less specific ones. For example, `workflow:order:hd:network.ref` overrides `default:network.ref` for the ORDER::HD workflow.
217
+
218
+ **Auto-injected variables** (available without config): `account.id`, `retailer.id`, `retailer.ref`, `retailer.name`.
219
+
220
+ ### Variable Syntax
221
+
222
+ Use `[[variable]]` tokens inside asset JSON files. The Fluent CLI resolves these at install time using the config file values.
223
+
224
+ ```json
225
+ {
226
+ "ref": "NET_HD_1",
227
+ "name": "HD Network",
228
+ "type": "FulfilmentNetwork",
229
+ "defaultCarrier": "[[carrier.ref]]"
230
+ }
231
+ ```
232
+
233
+ Unresolved tokens are left as-is in the installed data. Always verify that all tokens have corresponding config entries before deploying to production.
234
+
235
+ ## Asset JSON Schema Examples
236
+
237
+ ### Location (`resources/assets/locations/locations.json`)
238
+
239
+ ```json
240
+ [
241
+ {
242
+ "ref": "LOC_WH_1",
243
+ "name": "Warehouse 1",
244
+ "type": "WAREHOUSE",
245
+ "defaultCarrier": "[[carrier.ref]]",
246
+ "supportPhoneNumber": "+1-555-0100",
247
+ "attributes": [
248
+ {
249
+ "name": "storageCapacity",
250
+ "type": "STRING",
251
+ "value": "5000"
252
+ }
253
+ ]
254
+ },
255
+ {
256
+ "ref": "LOC_STORE_1",
257
+ "name": "Store 1",
258
+ "type": "STORE",
259
+ "defaultCarrier": "[[carrier.ref]]"
260
+ }
261
+ ]
262
+ ```
263
+
264
+ ### Network (`resources/assets/networks/networks.json`)
265
+
266
+ ```json
267
+ [
268
+ {
269
+ "ref": "NET_HD_1",
270
+ "name": "HD Network",
271
+ "type": "FulfilmentNetwork",
272
+ "locationRefs": [
273
+ "LOC_WH_1"
274
+ ]
275
+ },
276
+ {
277
+ "ref": "NET_CC_1",
278
+ "name": "CC Network",
279
+ "type": "FulfilmentNetwork",
280
+ "locationRefs": [
281
+ "LOC_STORE_1"
282
+ ]
283
+ }
284
+ ]
285
+ ```
286
+
287
+ ### Carrier (`resources/assets/carriers/carriers.json`)
288
+
289
+ ```json
290
+ [
291
+ {
292
+ "ref": "CARRIER_STD",
293
+ "name": "Standard Carrier"
294
+ },
295
+ {
296
+ "ref": "CARRIER_EXPRESS",
297
+ "name": "Express Carrier"
298
+ }
299
+ ]
300
+ ```
301
+
302
+ ### Setting (`resources/assets/settings/settings.json`)
303
+
304
+ ```json
305
+ [
306
+ {
307
+ "name": "WEBHOOK_ORDER_URL",
308
+ "value": "https://example.com/webhook/order",
309
+ "context": "RETAILER"
310
+ },
311
+ {
312
+ "name": "ORDER_NOTES_ENABLED",
313
+ "value": "true",
314
+ "context": "RETAILER"
315
+ },
316
+ {
317
+ "name": "FULFILMENT_BATCH_SIZE",
318
+ "value": "50",
319
+ "context": "ACCOUNT"
320
+ }
321
+ ]
322
+ ```
323
+
324
+ ### Product Catalogue (`resources/assets/product-catalogues/product-catalogues.json`)
325
+
326
+ ```json
327
+ [
328
+ {
329
+ "ref": "PC:MASTER:[[retailer.id]]",
330
+ "name": "Master Product Catalogue",
331
+ "type": "DEFAULT",
332
+ "description": "Primary product catalogue"
333
+ }
334
+ ]
335
+ ```
336
+
337
+ ### Inventory Catalogue (`resources/assets/inventory-catalogues/inventory-catalogues.json`)
338
+
339
+ ```json
340
+ [
341
+ {
342
+ "ref": "DEFAULT:[[retailer.id]]",
343
+ "name": "Default Inventory Catalogue",
344
+ "type": "DEFAULT",
345
+ "description": "Primary inventory catalogue",
346
+ "retailerRefs": [
347
+ "[[retailer.ref]]"
348
+ ]
349
+ }
350
+ ]
351
+ ```
352
+
353
+ ### Virtual Catalogue (`resources/assets/virtual-catalogues/virtual-catalogues.json`)
354
+
355
+ ```json
356
+ [
357
+ {
358
+ "ref": "VC:DEFAULT:[[retailer.id]]",
359
+ "name": "Default Virtual Catalogue",
360
+ "type": "DEFAULT",
361
+ "inventoryCatalogueRef": "DEFAULT:[[retailer.id]]",
362
+ "productCatalogueRef": "PC:MASTER:[[retailer.id]]",
363
+ "networkRef": "[[network.ref]]"
364
+ }
365
+ ]
366
+ ```
367
+
368
+ ## Build Script Templates
369
+
370
+ Data module build scripts are simpler than extension module scripts -- no Maven, no Java compilation. They read the version from `module.json` and ZIP the `resources/` directory.
371
+
372
+ ### Bash Build Script (`scripts/build-module.sh`)
373
+
374
+ ```bash
375
+ #!/bin/bash
376
+ set -euo pipefail
377
+
378
+ VERBOSE=false
379
+
380
+ parse_options() {
381
+ while getopts "x" opt; do
382
+ case $opt in
383
+ x) VERBOSE=true ;;
384
+ *)
385
+ echo "Usage: $0 [-x]"
386
+ echo " -x Enable verbose mode"
387
+ exit 1
388
+ ;;
389
+ esac
390
+ done
391
+ }
392
+
393
+ log() {
394
+ if [ "$VERBOSE" = true ]; then
395
+ echo "$@"
396
+ fi
397
+ }
398
+
399
+ require_command() {
400
+ local command_name=$1
401
+ if ! command -v "$command_name" >/dev/null 2>&1; then
402
+ echo "Error: required command '$command_name' was not found in PATH"
403
+ exit 1
404
+ fi
405
+ }
406
+
407
+ clean_folder() {
408
+ local dist_dir=$1
409
+ if [ -d "$dist_dir" ]; then
410
+ log "Directory $dist_dir exists, clearing..."
411
+ rm -rf "${dist_dir:?}/"
412
+ fi
413
+ }
414
+
415
+ main() {
416
+ parse_options "$@"
417
+ require_command zip
418
+ require_command sed
419
+
420
+ SCRIPT_DIR=$(dirname "$(realpath "$0")")
421
+ MODULE_BASE_DIR="$SCRIPT_DIR/.."
422
+ DIST_DIR="$MODULE_BASE_DIR/dist"
423
+ RESOURCES_DIR="$MODULE_BASE_DIR/resources"
424
+
425
+ log "Script Directory: $SCRIPT_DIR"
426
+ log "Module Directory: $MODULE_BASE_DIR"
427
+
428
+ if [ ! -f "$RESOURCES_DIR/module.json" ]; then
429
+ echo "Error: resources/module.json not found"
430
+ exit 1
431
+ fi
432
+
433
+ module_name=$(sed -n 's/.*"name": *"\([^"]*\)".*/\1/p' "$RESOURCES_DIR/module.json" | head -n 1)
434
+ sanitized_name=$(echo "$module_name" | sed 's|/|-|g')
435
+ module_version=$(sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' "$RESOURCES_DIR/module.json" | head -n 1)
436
+ combined_name="$sanitized_name-$module_version"
437
+
438
+ echo "Building data module: $module_name v$module_version"
439
+
440
+ clean_folder "$DIST_DIR"
441
+
442
+ local module_dist_dir="$DIST_DIR/$combined_name"
443
+ local module_dist_assets_dir="$module_dist_dir/assets"
444
+ mkdir -p "$module_dist_dir"
445
+
446
+ # Copy module.json
447
+ cp "$RESOURCES_DIR/module.json" "$module_dist_dir/"
448
+
449
+ # Copy module.config.json if present
450
+ if [ -f "$RESOURCES_DIR/module.config.json" ]; then
451
+ cp "$RESOURCES_DIR/module.config.json" "$module_dist_dir/"
452
+ fi
453
+
454
+ # Copy all asset directories
455
+ if [ -d "$RESOURCES_DIR/assets" ]; then
456
+ mkdir -p "$module_dist_assets_dir"
457
+ for entry in "$RESOURCES_DIR/assets"/*; do
458
+ [ -e "$entry" ] || continue
459
+ cp -r "$entry" "$module_dist_assets_dir/"
460
+ done
461
+ fi
462
+
463
+ # Create ZIP
464
+ local zip_file="$combined_name.zip"
465
+ (cd "$module_dist_dir" && zip -r "$zip_file" . -q)
466
+ mv "$module_dist_dir/$zip_file" "$DIST_DIR/"
467
+
468
+ echo "Built: dist/$zip_file"
469
+ echo "Install with: fluent module install ./ -p <PROFILE> -r <RETAILER>"
470
+ }
471
+
472
+ main "$@"
473
+ ```
474
+
475
+ ### PowerShell Build Script (`scripts/build-module.ps1`)
476
+
477
+ ```powershell
478
+ #!/usr/bin/env pwsh
479
+
480
+ <#
481
+ .SYNOPSIS
482
+ Build a Fluent Commerce data module (no Java, ZIP packaging only)
483
+
484
+ .DESCRIPTION
485
+ Reads version from module.json, copies resources into a staging directory,
486
+ and creates a distributable ZIP file in dist/.
487
+
488
+ .PARAMETER VerboseLogging
489
+ Enable verbose logging
490
+
491
+ .EXAMPLE
492
+ .\build-module.ps1
493
+
494
+ .EXAMPLE
495
+ .\build-module.ps1 -VerboseLogging
496
+ #>
497
+
498
+ [CmdletBinding()]
499
+ param(
500
+ [Alias('x')]
501
+ [switch]$VerboseLogging
502
+ )
503
+
504
+ $Script:VerboseMode = $VerboseLogging
505
+
506
+ function Write-Log {
507
+ param([string]$Message)
508
+ if ($Script:VerboseMode) {
509
+ Write-Host $Message
510
+ }
511
+ }
512
+
513
+ function Remove-FolderIfExists {
514
+ param([string]$Path)
515
+ if (Test-Path $Path) {
516
+ Write-Log "Directory $Path exists, clearing..."
517
+ Remove-Item -Path $Path -Recurse -Force
518
+ }
519
+ }
520
+
521
+ function Get-JsonValue {
522
+ param(
523
+ [string]$FilePath,
524
+ [string]$PropertyName
525
+ )
526
+ if (-not (Test-Path $FilePath)) { return $null }
527
+ try {
528
+ $json = Get-Content $FilePath -Raw | ConvertFrom-Json
529
+ return $json.$PropertyName
530
+ } catch {
531
+ Write-Log "Failed to parse JSON from $FilePath"
532
+ return $null
533
+ }
534
+ }
535
+
536
+ function Main {
537
+ if ($PSScriptRoot) {
538
+ $scriptDir = $PSScriptRoot
539
+ } elseif ($MyInvocation.MyCommand.Path) {
540
+ $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
541
+ } else {
542
+ $scriptDir = (Get-Location).Path
543
+ }
544
+
545
+ $moduleBaseDir = Split-Path -Parent $scriptDir
546
+ $distDir = Join-Path $moduleBaseDir "dist"
547
+ $resourcesDir = Join-Path $moduleBaseDir "resources"
548
+
549
+ $moduleJsonPath = Join-Path $resourcesDir "module.json"
550
+ if (-not (Test-Path $moduleJsonPath)) {
551
+ Write-Error "resources/module.json not found"
552
+ exit 1
553
+ }
554
+
555
+ $moduleName = Get-JsonValue $moduleJsonPath "name"
556
+ $moduleVersion = Get-JsonValue $moduleJsonPath "version"
557
+ if (-not $moduleName -or -not $moduleVersion) {
558
+ Write-Error "Could not extract module name or version from module.json"
559
+ exit 1
560
+ }
561
+
562
+ $sanitizedName = $moduleName -replace "/", "-"
563
+ $combinedName = "$sanitizedName-$moduleVersion"
564
+
565
+ Write-Host "Building data module: $moduleName v$moduleVersion"
566
+
567
+ Remove-FolderIfExists $distDir
568
+
569
+ $moduleDistDir = Join-Path $distDir $combinedName
570
+ $moduleDistAssetsDir = Join-Path $moduleDistDir "assets"
571
+ New-Item -ItemType Directory -Path $moduleDistDir -Force | Out-Null
572
+
573
+ # Copy module.json
574
+ Copy-Item $moduleJsonPath $moduleDistDir
575
+
576
+ # Copy module.config.json if present
577
+ $configPath = Join-Path $resourcesDir "module.config.json"
578
+ if (Test-Path $configPath) {
579
+ Copy-Item $configPath $moduleDistDir
580
+ }
581
+
582
+ # Copy all asset directories
583
+ $assetsDir = Join-Path $resourcesDir "assets"
584
+ if (Test-Path $assetsDir) {
585
+ New-Item -ItemType Directory -Path $moduleDistAssetsDir -Force | Out-Null
586
+ Get-ChildItem -Path $assetsDir | ForEach-Object {
587
+ Copy-Item -Path $_.FullName -Destination $moduleDistAssetsDir -Recurse -Force
588
+ }
589
+ }
590
+
591
+ # Create ZIP
592
+ $zipPath = Join-Path $distDir "$combinedName.zip"
593
+ Compress-Archive -Path "$moduleDistDir\*" -DestinationPath $zipPath -Force
594
+
595
+ Write-Host "Built: dist/$combinedName.zip"
596
+ Write-Host "Install with: fluent module install ./ -p <PROFILE> -r <RETAILER>"
597
+ }
598
+
599
+ Main
600
+ ```
601
+
602
+ ## Deployment
603
+
604
+ After building, install the module using the Fluent CLI:
605
+
606
+ ```bash
607
+ # Basic install (no config variables)
608
+ fluent module install ./<module-name>/ -p <PROFILE> -r <RETAILER>
609
+
610
+ # Install with config file (resolves [[variable]] tokens)
611
+ fluent module install ./<module-name>/ -p <PROFILE> -r <RETAILER> --config module.config.<RETAILER>.<module>.json
612
+
613
+ # Generate a retailer-specific config from the template
614
+ fluent module config <module-name> -p <PROFILE> -r <RETAILER>
615
+ ```
616
+
617
+ **Install order matters.** Infrastructure data (locations, networks, carriers) must be installed before modules that reference them (orders, fulfilments). A typical sequence:
618
+
619
+ ```
620
+ 1. Core module (fluent-commerce/core) -- usually pre-installed
621
+ 2. Infrastructure data module -- locations, networks, carriers
622
+ 3. Order/fulfilment workflow modules -- reference network and location refs
623
+ 4. Product and inventory data modules -- catalogues and stock
624
+ ```
625
+
626
+ ## Scaffold Execution Protocol
627
+
628
+ Follow these steps in order when scaffolding a new data module:
629
+
630
+ ```
631
+ 1. VALIDATE inputs
632
+ a. module-name: must match /^[a-z][a-z0-9-]*$/ (lowercase, hyphens, no leading hyphen)
633
+ b. module-name length: 1-50 characters
634
+ c. Reject names starting with digits or containing spaces/special characters
635
+
636
+ 2. PRE-CHECK: Module already exists?
637
+ a. Check accounts/<PROFILE>/SOURCE/<module-name>/ exists
638
+ b. Check accounts/<PROFILE>/SOURCE/fluentcommerce-fc-module-<module-name>/ exists
639
+ c. If either exists --> ABORT with guidance
640
+
641
+ 3. DETECT account prefix
642
+ a. If --account-prefix provided --> use it
643
+ b. Else scan existing modules under accounts/<PROFILE>/SOURCE/*/resources/module.json
644
+ Extract prefix from "name" field (part before the slash)
645
+ c. Else derive from PROFILE name (lowercase)
646
+ d. Fallback: "my-company" with warning
647
+
648
+ 4. COMPUTE derived values
649
+ a. MODULE_TITLE = title-case of module-name with hyphens as spaces
650
+ (e.g., "hm-infra-data" --> "Hm Infra Data")
651
+ b. MODULE_DESCRIPTION = description from --description or auto-generated
652
+ (e.g., "Data module for Hm Infra Data")
653
+
654
+ 5. CREATE directory structure
655
+ a. Create the root: accounts/<PROFILE>/SOURCE/<module-name>/
656
+ b. Create resources/ and resources/assets/ with all subdirectories
657
+ c. Create scripts/ and dist/
658
+
659
+ 6. GENERATE files (use Write tool, not bash echo)
660
+ a. resources/module.json -- with substituted values
661
+ b. resources/module.config.json -- empty template {}
662
+ c. scripts/build-module.sh -- bash ZIP script
663
+ d. scripts/build-module.ps1 -- PowerShell ZIP script
664
+
665
+ 7. MAKE build script executable
666
+ bash: chmod +x scripts/build-module.sh
667
+
668
+ 8. REPORT generated files
669
+ List all files and directories created.
670
+ Print next steps:
671
+ - "Data module scaffolded at: accounts/<PROFILE>/SOURCE/<module-name>/"
672
+ - "Next: Add asset JSON files under resources/assets/<type>/"
673
+ - "Build: cd accounts/<PROFILE>/SOURCE/<module-name> && bash scripts/build-module.sh"
674
+ - "Deploy: fluent module install ./<module-name>/ -p <PROFILE> -r <RETAILER>"
675
+ ```
676
+
677
+ ## Integration with Other Skills
678
+
679
+ | Skill | Relationship |
680
+ |-------|-------------|
681
+ | `/fluent-module-scaffold` | For extension modules with Java plugins. If you realize you need custom rules, scaffold an extension module instead. |
682
+ | `/fluent-module-validate` | Validates the data module structure. Should pass with 0 FAILs on a freshly scaffolded module. |
683
+ | `/fluent-module-deploy` | Deploys the built ZIP to a target retailer. |
684
+ | `/fluent-settings` | For managing settings via MCP tools. Data module settings are an alternative approach using the module install pipeline. |
685
+ | `/fluent-retailer-config` | For creating locations, networks, and carriers via GraphQL mutations. Data modules are the alternative file-based approach. |
686
+ | `/fluent-workflow-builder` | Workflows can be packaged in a data module under `assets/workflows/` for deployment via `fluent module install`. |
687
+ | `/fluent-build` | Extension module build skill. Not needed for data modules -- use the included `scripts/build-module.sh` instead. |
688
+
689
+ ## Edge Cases
690
+
691
+ ### Empty module (no assets yet)
692
+
693
+ A scaffolded module with empty asset directories is valid. The build script will produce a ZIP containing only `module.json` and empty `assets/` directories. This is useful as a starting point -- add JSON files incrementally.
694
+
695
+ ### Module name conflicts
696
+
697
+ Check both data module and extension module naming patterns:
698
+ ```bash
699
+ ls accounts/<PROFILE>/SOURCE/ | grep -i "<module-name>"
700
+ ```
701
+ If found, abort. Do NOT overwrite an existing module.
702
+
703
+ ### Windows path handling
704
+
705
+ - Build scripts have both `.sh` (Git Bash, WSL, macOS, Linux) and `.ps1` (PowerShell) variants
706
+ - Asset directory names use hyphens, not colons (e.g., `inventory-catalogues`, not `inventory::catalogues`)
707
+ - Workflow fragment subdirectories should use Windows-safe names (e.g., `ORDER-HD` instead of `ORDER::HD`)
708
+
709
+ ### Large asset files
710
+
711
+ For large datasets (thousands of products, inventory positions):
712
+ - Split into multiple JSON files within the same asset directory
713
+ - The Fluent CLI processes all files in each asset directory
714
+ - Consider using CSV format for inventory data (`inventory.csv` instead of `inventory.json`)
715
+
716
+ ### Config variable not resolved
717
+
718
+ If a `[[variable]]` token has no matching key in the config file:
719
+ - The token is left as-is in the installed data (e.g., the literal string `[[carrier.ref]]`)
720
+ - This will likely cause errors in the Fluent environment
721
+ - Always run `fluent module config <module> -p <PROFILE> -r <RETAILER>` to generate and fill the config before production installs
722
+
723
+ ## Gotchas
724
+
725
+ - **`module.config.json` is required** even if empty. The Fluent CLI expects this file to exist. Use `{}` for modules with no variables.
726
+ - **No `rules` array in `module.json`** for data modules. Including an empty `"rules": []` is harmless but unnecessary. Including rule names that do not exist will cause install warnings.
727
+ - **Asset directory names are convention-driven.** The Fluent CLI maps directory names to entity types. Using a non-standard directory name (e.g., `locs/` instead of `locations/`) will cause the assets to be skipped silently.
728
+ - **Install order matters.** Locations must exist before networks can reference them. Networks must exist before workflows can reference them. Install infrastructure data before order/fulfilment modules.
729
+ - **Workflow fragments** go in `workflow-fragments/<group>/`, not `workflows/`. Fragments are partial workflow definitions that merge into existing workflows. Full workflow JSONs go in `workflows/`.
730
+ - **The `_schema` field** in `module.json` must be `"1.0.0"`. This is a Fluent CLI requirement and not a user-defined version.
731
+ - **Config key auto-injection:** `account.id`, `retailer.id`, `retailer.ref`, and `retailer.name` are always available as `[[account.id]]`, `[[retailer.id]]`, etc. without needing config entries. Do not duplicate these in `module.config.json`.