@proveanything/smartlinks 2.0.5 → 2.0.9

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 (185) hide show
  1. package/dist/api/ai.d.ts +1 -1
  2. package/dist/api/ai.js +1 -1
  3. package/dist/api/analytics.d.ts +1 -1
  4. package/dist/api/analytics.js +1 -1
  5. package/dist/api/appConfiguration.d.ts +3 -3
  6. package/dist/api/appConfiguration.js +3 -3
  7. package/dist/api/appObjects.d.ts +1 -1
  8. package/dist/api/appObjects.js +1 -1
  9. package/dist/api/asset.d.ts +1 -1
  10. package/dist/api/asset.js +2 -2
  11. package/dist/api/async.d.ts +1 -1
  12. package/dist/api/async.js +1 -1
  13. package/dist/api/attestation.d.ts +1 -1
  14. package/dist/api/attestation.js +1 -1
  15. package/dist/api/attestations.d.ts +1 -1
  16. package/dist/api/attestations.js +1 -1
  17. package/dist/api/auth.d.ts +2 -2
  18. package/dist/api/auth.js +2 -2
  19. package/dist/api/authKit.d.ts +1 -1
  20. package/dist/api/authKit.js +1 -1
  21. package/dist/api/batch.d.ts +1 -1
  22. package/dist/api/batch.js +1 -1
  23. package/dist/api/broadcasts.d.ts +2 -2
  24. package/dist/api/broadcasts.js +1 -1
  25. package/dist/api/claimSet.d.ts +1 -1
  26. package/dist/api/claimSet.js +1 -1
  27. package/dist/api/collection.d.ts +1 -1
  28. package/dist/api/collection.js +1 -1
  29. package/dist/api/comms.d.ts +15 -15
  30. package/dist/api/comms.js +1 -1
  31. package/dist/api/config.d.ts +1 -1
  32. package/dist/api/config.js +1 -1
  33. package/dist/api/contact.d.ts +1 -1
  34. package/dist/api/contact.js +1 -1
  35. package/dist/api/containers.d.ts +1 -1
  36. package/dist/api/containers.js +1 -1
  37. package/dist/api/crate.d.ts +1 -1
  38. package/dist/api/crate.js +1 -1
  39. package/dist/api/facets.d.ts +1 -1
  40. package/dist/api/facets.js +1 -1
  41. package/dist/api/form.js +1 -1
  42. package/dist/api/http.js +1 -1
  43. package/dist/api/index.d.ts +46 -46
  44. package/dist/api/index.js +46 -46
  45. package/dist/api/integrations.d.ts +1 -1
  46. package/dist/api/integrations.js +1 -1
  47. package/dist/api/interactions.d.ts +1 -1
  48. package/dist/api/interactions.js +1 -1
  49. package/dist/api/jobs.d.ts +1 -1
  50. package/dist/api/jobs.js +1 -1
  51. package/dist/api/journeys.d.ts +1 -1
  52. package/dist/api/journeys.js +1 -1
  53. package/dist/api/journeysAnalytics.d.ts +1 -1
  54. package/dist/api/journeysAnalytics.js +1 -1
  55. package/dist/api/location.d.ts +1 -1
  56. package/dist/api/location.js +1 -1
  57. package/dist/api/lots.d.ts +1 -1
  58. package/dist/api/lots.js +1 -1
  59. package/dist/api/loyalty.d.ts +1 -1
  60. package/dist/api/loyalty.js +1 -1
  61. package/dist/api/navigation.d.ts +1 -1
  62. package/dist/api/navigation.js +1 -1
  63. package/dist/api/nfc.d.ts +1 -1
  64. package/dist/api/nfc.js +1 -1
  65. package/dist/api/order.d.ts +1 -1
  66. package/dist/api/order.js +1 -1
  67. package/dist/api/product.d.ts +1 -1
  68. package/dist/api/product.js +1 -1
  69. package/dist/api/products.d.ts +1 -1
  70. package/dist/api/products.js +1 -1
  71. package/dist/api/proof.d.ts +1 -1
  72. package/dist/api/proof.js +1 -1
  73. package/dist/api/qr.d.ts +1 -1
  74. package/dist/api/qr.js +1 -1
  75. package/dist/api/realtime.d.ts +1 -1
  76. package/dist/api/realtime.js +1 -1
  77. package/dist/api/research.d.ts +1 -1
  78. package/dist/api/research.js +1 -1
  79. package/dist/api/secrets.d.ts +1 -1
  80. package/dist/api/secrets.js +1 -1
  81. package/dist/api/segments.d.ts +1 -1
  82. package/dist/api/segments.js +1 -1
  83. package/dist/api/sequence.js +1 -1
  84. package/dist/api/tags.d.ts +1 -1
  85. package/dist/api/tags.js +1 -1
  86. package/dist/api/template.d.ts +1 -1
  87. package/dist/api/template.js +1 -1
  88. package/dist/api/translations.d.ts +1 -1
  89. package/dist/api/translations.js +2 -2
  90. package/dist/api/variant.d.ts +1 -1
  91. package/dist/api/variant.js +1 -1
  92. package/dist/containers/types.d.ts +1 -1
  93. package/dist/docs/API_SUMMARY.md +7 -7
  94. package/dist/docs/agent-tools.md +111 -0
  95. package/dist/docs/ai.md +14 -520
  96. package/dist/docs/analytics.md +41 -2
  97. package/dist/docs/app-data-storage.md +0 -38
  98. package/dist/docs/app-manifest.md +104 -7
  99. package/dist/docs/app-objects.md +0 -148
  100. package/dist/docs/app-records-pattern.md +2 -2
  101. package/dist/docs/building-react-components.md +6 -14
  102. package/dist/docs/caching.md +20 -21
  103. package/dist/docs/container-tracking.md +2 -0
  104. package/dist/docs/containers.md +14 -66
  105. package/dist/docs/deploying-apps.md +8 -3
  106. package/dist/docs/executor.md +4 -4
  107. package/dist/docs/host-dependency-contract.md +159 -0
  108. package/dist/docs/iframe-responder.md +308 -0
  109. package/dist/docs/item-context.md +0 -2
  110. package/dist/docs/manifests.md +3 -3
  111. package/dist/docs/mobile-admin-container.md +4 -4
  112. package/dist/docs/mpa.md +5 -5
  113. package/dist/docs/native-facade.md +1 -1
  114. package/dist/docs/overview.md +36 -15
  115. package/dist/docs/portal-back-button.md +2 -3
  116. package/dist/docs/sequences.md +1 -1
  117. package/dist/docs/server-functions.md +2 -3
  118. package/dist/docs/widgets.md +11 -69
  119. package/dist/http.d.ts +24 -8
  120. package/dist/http.js +32 -14
  121. package/dist/iframe.d.ts +2 -2
  122. package/dist/iframe.js +1 -1
  123. package/dist/iframeResponder.d.ts +7 -1
  124. package/dist/iframeResponder.js +45 -4
  125. package/dist/index.d.ts +30 -27
  126. package/dist/index.js +10 -8
  127. package/dist/mobile-admin/errors.d.ts +1 -1
  128. package/dist/mobile-admin/types.d.ts +2 -2
  129. package/dist/openapi.yaml +12 -0
  130. package/dist/shared-dependencies.d.ts +37 -0
  131. package/dist/shared-dependencies.js +79 -0
  132. package/dist/testing/index.d.ts +1 -1
  133. package/dist/translationCache.d.ts +1 -1
  134. package/dist/types/appManifest.d.ts +23 -0
  135. package/dist/types/broadcasts.d.ts +1 -1
  136. package/dist/types/collection.d.ts +2 -2
  137. package/dist/types/comms.d.ts +5 -5
  138. package/dist/types/contact.d.ts +1 -1
  139. package/dist/types/facets.d.ts +1 -1
  140. package/dist/types/iframeResponder.d.ts +3 -3
  141. package/dist/types/index.d.ts +44 -44
  142. package/dist/types/index.js +44 -44
  143. package/dist/types/interaction.d.ts +1 -1
  144. package/dist/types/itemContext.d.ts +1 -1
  145. package/dist/types/journeysAnalytics.d.ts +1 -1
  146. package/dist/types/navigation.d.ts +1 -1
  147. package/dist/types/product.d.ts +1 -1
  148. package/dist/types/proof.d.ts +1 -1
  149. package/dist/types/segments.d.ts +1 -1
  150. package/dist/types/widgets.d.ts +2 -2
  151. package/dist/utils/conditions.d.ts +1 -1
  152. package/dist/utils/index.d.ts +3 -3
  153. package/dist/utils/index.js +3 -3
  154. package/dist/utils/paths.d.ts +4 -4
  155. package/docs/API_SUMMARY.md +7 -7
  156. package/docs/agent-tools.md +111 -0
  157. package/docs/ai.md +14 -520
  158. package/docs/analytics.md +41 -2
  159. package/docs/app-data-storage.md +0 -38
  160. package/docs/app-manifest.md +104 -7
  161. package/docs/app-objects.md +0 -148
  162. package/docs/app-records-pattern.md +2 -2
  163. package/docs/building-react-components.md +6 -14
  164. package/docs/caching.md +20 -21
  165. package/docs/container-tracking.md +2 -0
  166. package/docs/containers.md +14 -66
  167. package/docs/deploying-apps.md +8 -3
  168. package/docs/executor.md +4 -4
  169. package/docs/host-dependency-contract.md +159 -0
  170. package/docs/iframe-responder.md +308 -0
  171. package/docs/item-context.md +0 -2
  172. package/docs/mobile-admin-container.md +4 -4
  173. package/docs/mpa.md +5 -5
  174. package/docs/native-facade.md +1 -1
  175. package/docs/overview.md +36 -15
  176. package/docs/portal-back-button.md +2 -3
  177. package/docs/sequences.md +1 -1
  178. package/docs/server-functions.md +2 -3
  179. package/docs/widgets.md +11 -69
  180. package/openapi.yaml +12 -0
  181. package/package.json +17 -6
  182. package/scripts/doctor.mjs +171 -0
  183. package/docs/analytics-metadata-conventions.md +0 -88
  184. package/docs/iframe-streaming-parent-changes.md +0 -308
  185. package/docs/manifests.md +0 -204
@@ -1,308 +0,0 @@
1
- # Iframe Streaming Parent Changes
2
-
3
- This note describes the parent-side changes needed to support AI streaming when an embedded SmartLinks app is running in iframe proxy mode.
4
-
5
- If you are using the SDK `IframeResponder` directly, this is already implemented in the SDK changes. You only need this document if your parent application has its own iframe proxy handler and does not rely on `IframeResponder`.
6
-
7
- ## Goal
8
-
9
- Keep the existing architecture:
10
-
11
- - local mode: child calls API directly
12
- - iframe proxy mode: child never owns auth state and streams through the parent
13
-
14
- This keeps user/session authority in the parent while making AI streaming behave like the rest of the SDK transport.
15
-
16
- ## What changed
17
-
18
- Previously, proxy mode only supported one-shot request/response messages:
19
-
20
- - `_smartlinksProxyRequest`
21
- - `_smartlinksProxyResponse`
22
-
23
- Streaming now adds a second protocol for long-lived responses:
24
-
25
- - `_smartlinksProxyStreamRequest`
26
- - `_smartlinksProxyStream`
27
- - `_smartlinksProxyStreamAbort`
28
-
29
- ## New parent message handling
30
-
31
- ### 1. Listen for stream requests
32
-
33
- The iframe child may now send this message:
34
-
35
- ```ts
36
- {
37
- _smartlinksProxyStreamRequest: true,
38
- id: string,
39
- method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
40
- path: string,
41
- body?: any,
42
- headers?: Record<string, string>
43
- }
44
- ```
45
-
46
- Parent behavior:
47
-
48
- - treat this like a proxied API request
49
- - build the real API URL from your configured base URL plus `path`
50
- - send the request using the parent's current auth/session context
51
- - expect an SSE / streaming response body
52
- - keep the request open until the stream ends or is aborted
53
-
54
- ### 2. Forward stream lifecycle messages back to the child
55
-
56
- The parent should send messages back to the iframe using this envelope:
57
-
58
- ```ts
59
- {
60
- _smartlinksProxyStream: true,
61
- id: string,
62
- phase: 'open' | 'event' | 'end' | 'error',
63
- data?: any,
64
- error?: string,
65
- status?: number
66
- }
67
- ```
68
-
69
- Phases:
70
-
71
- - `open`
72
- - optional but recommended
73
- - indicates the upstream streaming request was accepted and a body exists
74
- - `event`
75
- - contains one parsed JSON event from an SSE `data:` frame
76
- - send one message per logical event payload
77
- - `end`
78
- - sent once when the stream finishes normally
79
- - `error`
80
- - sent if the upstream request fails before or during streaming
81
-
82
- ### 3. Support abort from the child
83
-
84
- The child may stop reading early and send:
85
-
86
- ```ts
87
- {
88
- _smartlinksProxyStreamAbort: true,
89
- id: string
90
- }
91
- ```
92
-
93
- Parent behavior:
94
-
95
- - look up the active stream by `id`
96
- - abort the underlying fetch / reader
97
- - clean up any local state for that stream
98
- - do not keep streaming after abort
99
-
100
- ## SSE forwarding rules
101
-
102
- The upstream AI endpoints return SSE-like frames. The parent should:
103
-
104
- - read the response body as a stream
105
- - buffer text until line boundaries
106
- - collect `data:` lines for a single event
107
- - join multi-line `data:` payloads with `\n`
108
- - ignore blank events
109
- - stop on `data: [DONE]`
110
- - JSON-parse each event payload
111
- - forward parsed payloads to the iframe as `_smartlinksProxyStream` with `phase: 'event'`
112
-
113
- Minimal parsing behavior:
114
-
115
- 1. accumulate bytes into text
116
- 2. split on `\r?\n`
117
- 3. collect each `data:` line
118
- 4. on blank line, finalize the event
119
- 5. if payload is `[DONE]`, finish
120
- 6. otherwise `JSON.parse(payload)` and forward
121
-
122
- ## Auth and session expectations
123
-
124
- The parent remains the source of truth for auth.
125
-
126
- That means the parent stream handler should:
127
-
128
- - use the same auth headers/token source as normal proxied requests
129
- - not require the iframe to know the bearer token or API key
130
- - naturally pick up the current logged-in user when the stream starts
131
- - cancel active streams if your app invalidates session state on logout or account switch
132
-
133
- In practice, the stream request should use the same header-building logic as your normal parent proxy transport.
134
-
135
- ## Error handling expectations
136
-
137
- If the upstream fetch returns a non-2xx status:
138
-
139
- - try to read the JSON error body
140
- - derive a useful message
141
- - send one `_smartlinksProxyStream` message with `phase: 'error'`
142
- - include `status` when available
143
- - do not send `end` afterward
144
-
145
- If the stream body is missing unexpectedly:
146
-
147
- - send `phase: 'error'`
148
-
149
- If JSON parsing fails for a single event chunk:
150
-
151
- - safest behavior is to ignore that malformed chunk and continue
152
-
153
- ## State the parent should keep
154
-
155
- Track active streams in a map keyed by `id`:
156
-
157
- ```ts
158
- Map<string, AbortController>
159
- ```
160
-
161
- Recommended cleanup points:
162
-
163
- - on normal stream end
164
- - on error
165
- - on child abort
166
- - on iframe detach/unmount
167
- - on parent auth reset/logout if you want all in-flight streams cancelled immediately
168
-
169
- ## Parent implementation outline
170
-
171
- ```ts
172
- const activeStreams = new Map<string, AbortController>()
173
-
174
- window.addEventListener('message', async (event) => {
175
- const msg = event.data
176
-
177
- if (msg?._smartlinksProxyStreamAbort && msg.id) {
178
- activeStreams.get(msg.id)?.abort()
179
- activeStreams.delete(msg.id)
180
- return
181
- }
182
-
183
- if (msg?._smartlinksProxyStreamRequest && msg.id) {
184
- const controller = new AbortController()
185
- activeStreams.set(msg.id, controller)
186
-
187
- try {
188
- const response = await fetch(buildUrl(msg.path), {
189
- method: msg.method,
190
- headers: msg.headers,
191
- body: msg.body ? JSON.stringify(msg.body) : undefined,
192
- signal: controller.signal,
193
- })
194
-
195
- if (!response.ok || !response.body) {
196
- postError(...)
197
- return
198
- }
199
-
200
- postOpen(...)
201
- await forwardSse(response.body, parsed => postEvent(...parsed))
202
- postEnd(...)
203
- } catch (err) {
204
- if (err?.name !== 'AbortError') postError(...)
205
- } finally {
206
- activeStreams.delete(msg.id)
207
- }
208
- }
209
- })
210
- ```
211
-
212
- ## Exact protocol summary
213
-
214
- ### Child → parent
215
-
216
- Standard stream request:
217
-
218
- ```ts
219
- {
220
- _smartlinksProxyStreamRequest: true,
221
- id,
222
- method,
223
- path,
224
- body,
225
- headers
226
- }
227
- ```
228
-
229
- Abort request:
230
-
231
- ```ts
232
- {
233
- _smartlinksProxyStreamAbort: true,
234
- id
235
- }
236
- ```
237
-
238
- ### Parent → child
239
-
240
- Open:
241
-
242
- ```ts
243
- {
244
- _smartlinksProxyStream: true,
245
- id,
246
- phase: 'open'
247
- }
248
- ```
249
-
250
- Event:
251
-
252
- ```ts
253
- {
254
- _smartlinksProxyStream: true,
255
- id,
256
- phase: 'event',
257
- data: parsedJsonEvent
258
- }
259
- ```
260
-
261
- End:
262
-
263
- ```ts
264
- {
265
- _smartlinksProxyStream: true,
266
- id,
267
- phase: 'end'
268
- }
269
- ```
270
-
271
- Error:
272
-
273
- ```ts
274
- {
275
- _smartlinksProxyStream: true,
276
- id,
277
- phase: 'error',
278
- error: 'message',
279
- status?: number
280
- }
281
- ```
282
-
283
- ## What does not change
284
-
285
- These parts of the parent iframe integration stay the same:
286
-
287
- - normal `_smartlinksProxyRequest` request/response flow
288
- - upload proxy flow
289
- - auth login/logout postMessage handling
290
- - route/deep-link handling
291
- - resize handling
292
-
293
- This is an additive protocol, not a replacement.
294
-
295
- ## Current SDK reference
296
-
297
- The SDK implementation lives in:
298
-
299
- - [src/http.ts](src/http.ts)
300
- - [src/iframeResponder.ts](src/iframeResponder.ts)
301
- - [src/types/iframeResponder.ts](src/types/iframeResponder.ts)
302
- - [src/api/ai.ts](src/api/ai.ts)
303
-
304
- ## Practical recommendation
305
-
306
- If your parent already uses `IframeResponder`, prefer upgrading to the SDK version with these changes instead of re-implementing the protocol manually.
307
-
308
- If your parent has a custom iframe bridge, implement exactly the three new message types above and reuse your existing auth/header logic from normal proxied requests.
package/docs/manifests.md DELETED
@@ -1,204 +0,0 @@
1
- # AI-Native App Manifests
2
-
3
- SmartLinks apps are designed to be **AI-discoverable, AI-configurable, and AI-importable**. Every app ships with a structured manifest and a prose guide that allow AI systems to set up, configure, and populate apps without custom integration code.
4
-
5
- ---
6
-
7
- ## The Split Manifest
8
-
9
- The manifest is split into two files so the public portal never loads admin-only configuration data.
10
-
11
- ```text
12
- app.manifest.json ← lean, always loaded (widget render, SEO, executor discovery)
13
- app.admin.json ← loaded on-demand (setup wizards, import, AI config flows)
14
- ```
15
-
16
- ### `app.manifest.json` — always loaded
17
-
18
- | Section | Purpose | AI Consumer |
19
- |---------|---------|-------------|
20
- | `meta` | App identity, version, appId, SEO priority | All workflows |
21
- | `admin` | Pointer to `app.admin.json` | Admin orchestrators |
22
- | `widgets` | Bundle files + component definitions + settings schemas; can also declare widget-instance resolution via `widgetId` | Widget Builder |
23
- | `containers` | Bundle files + component definitions | Container Loader |
24
- | `executor` | Bundle files, factory name, exports list | Server / AI |
25
- | `linkable` | Static deep-link routes | Portal menus / AI nav |
26
-
27
- ```json
28
- {
29
- "meta": { "name": "My App", "appId": "my-app", "version": "1.0.0" },
30
- "admin": "app.admin.json",
31
- "widgets": {
32
- "instanceResolution": true,
33
- "instanceParam": "widgetId",
34
- "files": {
35
- "js": { "umd": "dist/widgets.umd.js", "esm": "dist/widgets.es.js" },
36
- "css": null
37
- },
38
- "components": [
39
- {
40
- "name": "MyWidget",
41
- "description": "Compact summary card.",
42
- "sizes": ["compact", "standard", "large"],
43
- "settings": { ... }
44
- }
45
- ]
46
- },
47
- "containers": {
48
- "files": {
49
- "js": { "umd": "dist/containers.umd.js", "esm": "dist/containers.es.js" },
50
- "css": null
51
- },
52
- "components": [{ "name": "PublicContainer", "description": "Full app view." }]
53
- },
54
- "executor": {
55
- "files": { "js": { "umd": "dist/executor.umd.js", "esm": "dist/executor.es.js" } },
56
- "factory": "createMyAppExecutor",
57
- "exports": ["createMyAppExecutor", "getSEO", "getLLMContent"],
58
- "description": "Programmatic configuration and SEO API for My App."
59
- },
60
- "linkable": [
61
- { "title": "Home", "path": "/" },
62
- { "title": "Gallery", "path": "/gallery" }
63
- ]
64
- }
65
- ```
66
-
67
- When `instanceResolution` is enabled, the app is declaring that consumers can pass a widget instance identifier such as `?appId=widget-toolkit&widgetId=launch-countdown`, and the widget bundle will resolve its stored configuration from app config.
68
-
69
- > ⚠️ **`css` is `null` by default.** Most widgets and containers use Tailwind/shadcn classes inherited from the parent and produce **no CSS output file**. Set `"css": null` in the manifest. Only set it to a filename if your widget/container ships a custom CSS file that actually exists in `dist/`. The parent portal checks this value before injecting a `<link>` tag — a non-null value pointing to a missing file will cause a 404.
70
-
71
- ---
72
-
73
- ### `app.admin.json` — loaded on-demand
74
-
75
- | Section | Purpose | AI Consumer |
76
- |---------|---------|-------------|
77
- | `aiGuide` | Pointer to `ai-guide.md` prose instructions | All AI workflows |
78
- | `setup` | Setup wizard: questions, config schema, save instructions | Setup Wizard |
79
- | `import` | Bulk data import: field definitions, CSV shape, API calls | Data Importer |
80
- | `tunable` | Runtime-adjustable settings | AI Optimizer |
81
- | `metrics` | Tracked interactions and KPIs | Analytics Advisor |
82
-
83
- The admin orchestrator fetches the manifest, reads the `admin` pointer, and fetches `app.admin.json` only when needed — never on public page loads.
84
-
85
- See the [App Configuration Files reference](app-manifest.md) for the full field-by-field schema for both files.
86
-
87
- ---
88
-
89
- ## Widget Settings Schema
90
-
91
- Each widget component in `app.manifest.json` should include a `settings` object using **JSON Schema** to describe its configurable props. This enables schema-form libraries and AI orchestrators to auto-generate configuration UIs without per-widget code.
92
-
93
- ```json
94
- "components": [
95
- {
96
- "name": "MyWidget",
97
- "description": "What this widget does",
98
- "sizes": ["compact", "standard", "large"],
99
- "settings": {
100
- "type": "object",
101
- "properties": {
102
- "displayMode": {
103
- "type": "string",
104
- "title": "Display Mode",
105
- "description": "How the widget renders",
106
- "enum": ["compact", "standard", "large"],
107
- "enumLabels": {
108
- "compact": "Icons only",
109
- "standard": "With names",
110
- "large": "Full cards"
111
- },
112
- "default": "standard",
113
- "order": 1
114
- },
115
- "showImage": {
116
- "type": "boolean",
117
- "title": "Show Product Image",
118
- "default": true,
119
- "order": 2
120
- }
121
- }
122
- }
123
- }
124
- ]
125
- ```
126
-
127
- | Field | Purpose |
128
- |-------|---------|
129
- | `type`, `enum` | Standard JSON Schema for validation |
130
- | `title` | Human-readable label for form rendering |
131
- | `description` | Help text shown alongside the field |
132
- | `enumLabels` | Friendly display names for enum values (`{ value → label }`) |
133
- | `default` | Pre-selected value when no configuration exists |
134
- | `order` | Field display order in rendered forms (lower number = higher position) |
135
-
136
- The `settings` schema serves dual purposes: AI orchestrators use it to understand what a widget accepts and generate configuration conversationally; schema-form renderers (e.g., in admin consoles) use it to auto-generate settings UIs.
137
-
138
- ---
139
-
140
- ## The AI Guide (`ai-guide.md`)
141
-
142
- A companion Markdown file deployed alongside the manifest provides **natural-language instructions** for AI orchestrators. The admin config references it via `"aiGuide": "ai-guide.md"` — orchestrators resolve and fetch it relative to the manifest URL.
143
-
144
- While the manifest is structured data, the AI guide provides prose context, nuance, and step-by-step instructions that help an LLM drive setup wizards, imports, and troubleshooting flows conversationally.
145
-
146
- Use the [AI Guide Template](ai-guide-template.md) as your starting point.
147
-
148
- ---
149
-
150
- ## Three AI Workflows
151
-
152
- ### 1. Widget Builder
153
-
154
- An AI fetches `app.manifest.json`, reads `widgets.components[]` including the `settings` JSON Schema for each widget, and can:
155
- - Generate React code to embed the widget with correct props
156
- - Auto-render a configuration UI from the settings schema
157
- - Understand valid size hints and required vs optional props
158
-
159
- ### 2. Setup Wizard
160
-
161
- An AI reads `setup` from `app.admin.json` to drive a conversational configuration flow:
162
-
163
- 1. Walk the user through each `setup.questions[]` entry
164
- 2. Validate answers against `setup.configSchema` (JSON Schema)
165
- 3. Optionally use `setup.contentHints` to auto-generate content via `SL.ai.chat.completions`
166
- 4. Save using the `setup.saveWith` instructions (method, scope, admin flag)
167
-
168
- The AI guide (`ai-guide.md`) provides prose instructions on how to handle each question, what sensible defaults look like, and what to do if the user is unsure.
169
-
170
- ### 3. Data Importer
171
-
172
- An AI reads `import` from `app.admin.json` to:
173
-
174
- 1. Generate a CSV template from `import.fields[]` (with types, required flags, and examples)
175
- 2. Normalise user-provided data against field types
176
- 3. Call `import.saveWith.method` for each row
177
-
178
- For multi-app imports, fields from multiple manifests can be merged into a single CSV template.
179
-
180
- ---
181
-
182
- ## Maintaining the Manifest
183
-
184
- When you change your app's configuration shape, update all three files together:
185
-
186
- | File | What to update |
187
- |------|---------------|
188
- | `app.manifest.json` | `widgets.components[].settings`, `containers`, `executor.exports`, `linkable` |
189
- | `app.admin.json` | `setup.questions`, `setup.configSchema`, `import.fields`, `tunable.fields` |
190
- | `ai-guide.md` | Prose instructions, validation rules, examples, and any new question guidance |
191
-
192
- Keeping all three in sync ensures AI orchestrators, setup wizards, and data importers all work from consistent, accurate information.
193
-
194
- ---
195
-
196
- ## Related Guides
197
-
198
- | Guide | What it covers |
199
- |-------|---------------|
200
- | [App Configuration Files](app-manifest.md) | Full field-by-field reference for both JSON files |
201
- | [Executor Model](executor.md) | Building `executor.umd.js` — SEO, LLM content, config mutations |
202
- | [Deep Link Discovery](deep-link-discovery.md) | `linkable` — static and dynamic navigable states |
203
- | [AI Guide Template](ai-guide-template.md) | Starter template for `ai-guide.md` |
204
- | [AI & Chat Completions](ai.md) | `SL.ai` — used in `contentHints` auto-generation |