@superxd-studio/adptr 0.5.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.
Files changed (221) hide show
  1. package/GENERATIVE.md +101 -0
  2. package/INTERACTIONS.md +51 -0
  3. package/LICENSE +21 -0
  4. package/README.md +57 -0
  5. package/REUSE.md +170 -0
  6. package/REVIEW.md +68 -0
  7. package/THIRD-PARTY-NOTICES.md +28 -0
  8. package/ai-sdk/index.js +96 -0
  9. package/assets/ibm-plex-mono-cyrillic-400-normal.woff2 +0 -0
  10. package/assets/ibm-plex-mono-cyrillic-500-normal.woff2 +0 -0
  11. package/assets/ibm-plex-mono-cyrillic-ext-400-normal.woff2 +0 -0
  12. package/assets/ibm-plex-mono-cyrillic-ext-500-normal.woff2 +0 -0
  13. package/assets/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  14. package/assets/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  15. package/assets/ibm-plex-mono-latin-ext-400-normal.woff2 +0 -0
  16. package/assets/ibm-plex-mono-latin-ext-500-normal.woff2 +0 -0
  17. package/assets/ibm-plex-mono-vietnamese-400-normal.woff2 +0 -0
  18. package/assets/ibm-plex-mono-vietnamese-500-normal.woff2 +0 -0
  19. package/assets/instrument-sans-latin-ext-wght-normal.woff2 +0 -0
  20. package/assets/instrument-sans-latin-wght-normal.woff2 +0 -0
  21. package/assistant-ui/index.js +139 -0
  22. package/chunks/callout-DKMHSnjc.js +342 -0
  23. package/chunks/canvas-BJ15-XxE.js +598 -0
  24. package/chunks/controller-Cfpg0C7v.js +180 -0
  25. package/chunks/core-BCqVRLUy.js +312 -0
  26. package/chunks/text-field-BLtoaZFn.js +41 -0
  27. package/chunks/types-BGF7r1my.js +115 -0
  28. package/chunks/ui-9DyNsYXY.js +967 -0
  29. package/core/index.js +4 -0
  30. package/custom/index.js +64 -0
  31. package/examples/ai-sdk-backend/package.json +11 -0
  32. package/examples/ai-sdk-backend/server.mjs +316 -0
  33. package/examples/custom-backend/copy.mjs +7 -0
  34. package/examples/custom-backend/server.mjs +118 -0
  35. package/examples/generative/specs.json +2094 -0
  36. package/examples/review-backend/copy.mjs +27 -0
  37. package/examples/review-backend/package.json +11 -0
  38. package/examples/review-backend/server.mjs +276 -0
  39. package/examples/web-ai-sdk/index.html +12 -0
  40. package/examples/web-ai-sdk/package.json +21 -0
  41. package/examples/web-ai-sdk/src/copy.ts +1 -0
  42. package/examples/web-ai-sdk/src/main.tsx +64 -0
  43. package/examples/web-ai-sdk/tsconfig.json +13 -0
  44. package/examples/web-generative/index.html +12 -0
  45. package/examples/web-generative/package.json +23 -0
  46. package/examples/web-generative/src/copy.ts +42 -0
  47. package/examples/web-generative/src/main.tsx +74 -0
  48. package/examples/web-generative/tsconfig.json +14 -0
  49. package/examples/web-independent/index.html +12 -0
  50. package/examples/web-independent/package.json +20 -0
  51. package/examples/web-independent/src/main.tsx +32 -0
  52. package/examples/web-independent/tsconfig.json +14 -0
  53. package/examples/web-interactions/index.html +12 -0
  54. package/examples/web-interactions/package.json +21 -0
  55. package/examples/web-interactions/src/copy.ts +215 -0
  56. package/examples/web-interactions/src/examples.tsx +628 -0
  57. package/examples/web-interactions/src/main.tsx +116 -0
  58. package/examples/web-interactions/tsconfig.json +14 -0
  59. package/examples/web-review/index.html +12 -0
  60. package/examples/web-review/package.json +20 -0
  61. package/examples/web-review/src/main.tsx +59 -0
  62. package/examples/web-review/tsconfig.json +14 -0
  63. package/fonts.css +117 -0
  64. package/generative/index.js +1560 -0
  65. package/interactions/index.js +1591 -0
  66. package/langgraph-review/index.js +36 -0
  67. package/licenses/ai-sdk.txt +13 -0
  68. package/licenses/assistant-ui-generative.txt +21 -0
  69. package/licenses/assistant-ui.txt +23 -0
  70. package/licenses/ibm-plex-mono.txt +93 -0
  71. package/licenses/instrument-sans.txt +93 -0
  72. package/licenses/internationalized-date.txt +201 -0
  73. package/licenses/langgraph.txt +21 -0
  74. package/licenses/lucide.txt +43 -0
  75. package/licenses/react-markdown.txt +21 -0
  76. package/licenses/remark-gfm.txt +22 -0
  77. package/licenses/zod.txt +21 -0
  78. package/package.json +138 -0
  79. package/review/index.js +31 -0
  80. package/source/components/avatar.tsx +50 -0
  81. package/source/components/button.tsx +155 -0
  82. package/source/components/callout.tsx +65 -0
  83. package/source/components/canvas/connector.tsx +14 -0
  84. package/source/components/canvas/copy.ts +34 -0
  85. package/source/components/canvas/index.tsx +257 -0
  86. package/source/components/canvas/recorder.ts +36 -0
  87. package/source/components/date-time-field.tsx +77 -0
  88. package/source/components/flow-motion.tsx +109 -0
  89. package/source/components/icons.tsx +275 -0
  90. package/source/components/responsive-overlay.tsx +91 -0
  91. package/source/components/scenario-picker/copy.ts +5 -0
  92. package/source/components/scenario-picker/index.tsx +142 -0
  93. package/source/components/scroll-area.tsx +59 -0
  94. package/source/components/search-picker.tsx +127 -0
  95. package/source/components/segmented-control.tsx +123 -0
  96. package/source/components/skeleton.tsx +11 -0
  97. package/source/components/spinner.tsx +19 -0
  98. package/source/components/superxd-arrow.tsx +22 -0
  99. package/source/components/switch.tsx +45 -0
  100. package/source/components/text-field.tsx +81 -0
  101. package/source/components/thinking.tsx +16 -0
  102. package/source/components/ui/copy.ts +12 -0
  103. package/source/components/ui/display.tsx +276 -0
  104. package/source/components/ui/navigation.tsx +346 -0
  105. package/source/components/ui/portal-theme.tsx +28 -0
  106. package/source/components/ui/selection.tsx +336 -0
  107. package/source/lib/cn.ts +23 -0
  108. package/source/reusable/ai-sdk/index.ts +114 -0
  109. package/source/reusable/assistant-ui/index.tsx +266 -0
  110. package/source/reusable/core/attachments.ts +163 -0
  111. package/source/reusable/core/index.ts +417 -0
  112. package/source/reusable/custom/index.ts +90 -0
  113. package/source/reusable/generative/actions.ts +188 -0
  114. package/source/reusable/generative/copy.ts +47 -0
  115. package/source/reusable/generative/data.tsx +126 -0
  116. package/source/reusable/generative/index.tsx +517 -0
  117. package/source/reusable/generative/schema.ts +327 -0
  118. package/source/reusable/generative/timeline.tsx +214 -0
  119. package/source/reusable/generative/vocabulary.tsx +847 -0
  120. package/source/reusable/interactions/agent.ts +259 -0
  121. package/source/reusable/interactions/artifact.ts +236 -0
  122. package/source/reusable/interactions/context.tsx +38 -0
  123. package/source/reusable/interactions/copy.ts +117 -0
  124. package/source/reusable/interactions/feedback.ts +73 -0
  125. package/source/reusable/interactions/index.ts +11 -0
  126. package/source/reusable/interactions/presentation.tsx +483 -0
  127. package/source/reusable/interactions/store.ts +74 -0
  128. package/source/reusable/interactions/threads.ts +126 -0
  129. package/source/reusable/interactions/web.tsx +574 -0
  130. package/source/reusable/langgraph-review/index.ts +73 -0
  131. package/source/reusable/review/controller.ts +263 -0
  132. package/source/reusable/review/index.ts +47 -0
  133. package/source/reusable/review/types.ts +189 -0
  134. package/source/reusable/ui/index.ts +25 -0
  135. package/source/reusable/uploads/index.ts +48 -0
  136. package/source/reusable/web/attachments/copy.ts +23 -0
  137. package/source/reusable/web/attachments/index.tsx +233 -0
  138. package/source/reusable/web/copy.ts +22 -0
  139. package/source/reusable/web/index.tsx +470 -0
  140. package/source/reusable/web/message/copy.ts +26 -0
  141. package/source/reusable/web/message/index.tsx +388 -0
  142. package/source/reusable/web/message/streaming.ts +64 -0
  143. package/source/reusable/web/message/styles.css +21 -0
  144. package/source/reusable/web/review/copy.ts +78 -0
  145. package/source/reusable/web/review/flow.ts +24 -0
  146. package/source/reusable/web/review/index.tsx +506 -0
  147. package/source/reusable/web/styles.ts +2 -0
  148. package/source/styles/library.css +612 -0
  149. package/source/styles/theme.css +228 -0
  150. package/styles.css +3 -0
  151. package/styles.d.ts +1 -0
  152. package/types/components/avatar.d.ts +14 -0
  153. package/types/components/button.d.ts +36 -0
  154. package/types/components/callout.d.ts +19 -0
  155. package/types/components/canvas/connector.d.ts +2 -0
  156. package/types/components/canvas/copy.d.ts +34 -0
  157. package/types/components/canvas/index.d.ts +33 -0
  158. package/types/components/canvas/recorder.d.ts +10 -0
  159. package/types/components/date-time-field.d.ts +11 -0
  160. package/types/components/flow-motion.d.ts +38 -0
  161. package/types/components/icons.d.ts +138 -0
  162. package/types/components/responsive-overlay.d.ts +15 -0
  163. package/types/components/scenario-picker/copy.d.ts +5 -0
  164. package/types/components/scenario-picker/index.d.ts +14 -0
  165. package/types/components/scroll-area.d.ts +14 -0
  166. package/types/components/search-picker.d.ts +27 -0
  167. package/types/components/segmented-control.d.ts +23 -0
  168. package/types/components/skeleton.d.ts +4 -0
  169. package/types/components/spinner.d.ts +4 -0
  170. package/types/components/superxd-arrow.d.ts +5 -0
  171. package/types/components/switch.d.ts +8 -0
  172. package/types/components/text-field.d.ts +19 -0
  173. package/types/components/thinking.d.ts +8 -0
  174. package/types/components/ui/copy.d.ts +12 -0
  175. package/types/components/ui/display.d.ts +50 -0
  176. package/types/components/ui/navigation.d.ts +63 -0
  177. package/types/components/ui/portal-theme.d.ts +8 -0
  178. package/types/components/ui/selection.d.ts +37 -0
  179. package/types/lib/cn.d.ts +3 -0
  180. package/types/reusable/ai-sdk/index.d.ts +15 -0
  181. package/types/reusable/assistant-ui/index.d.ts +12 -0
  182. package/types/reusable/core/attachments.d.ts +54 -0
  183. package/types/reusable/core/index.d.ts +107 -0
  184. package/types/reusable/custom/index.d.ts +14 -0
  185. package/types/reusable/generative/actions.d.ts +45 -0
  186. package/types/reusable/generative/copy.d.ts +48 -0
  187. package/types/reusable/generative/data.d.ts +4 -0
  188. package/types/reusable/generative/index.d.ts +30 -0
  189. package/types/reusable/generative/schema.d.ts +303 -0
  190. package/types/reusable/generative/timeline.d.ts +21 -0
  191. package/types/reusable/generative/vocabulary.d.ts +34 -0
  192. package/types/reusable/interactions/agent.d.ts +98 -0
  193. package/types/reusable/interactions/artifact.d.ts +118 -0
  194. package/types/reusable/interactions/context.d.ts +130 -0
  195. package/types/reusable/interactions/copy.d.ts +115 -0
  196. package/types/reusable/interactions/feedback.d.ts +34 -0
  197. package/types/reusable/interactions/index.d.ts +10 -0
  198. package/types/reusable/interactions/presentation.d.ts +97 -0
  199. package/types/reusable/interactions/store.d.ts +29 -0
  200. package/types/reusable/interactions/threads.d.ts +38 -0
  201. package/types/reusable/interactions/web.d.ts +22 -0
  202. package/types/reusable/langgraph-review/index.d.ts +5 -0
  203. package/types/reusable/review/controller.d.ts +52 -0
  204. package/types/reusable/review/index.d.ts +12 -0
  205. package/types/reusable/review/types.d.ts +61 -0
  206. package/types/reusable/ui/index.d.ts +19 -0
  207. package/types/reusable/uploads/index.d.ts +11 -0
  208. package/types/reusable/web/attachments/copy.d.ts +25 -0
  209. package/types/reusable/web/attachments/index.d.ts +24 -0
  210. package/types/reusable/web/copy.d.ts +24 -0
  211. package/types/reusable/web/index.d.ts +41 -0
  212. package/types/reusable/web/message/copy.d.ts +27 -0
  213. package/types/reusable/web/message/index.d.ts +56 -0
  214. package/types/reusable/web/message/streaming.d.ts +27 -0
  215. package/types/reusable/web/review/copy.d.ts +72 -0
  216. package/types/reusable/web/review/flow.d.ts +3 -0
  217. package/types/reusable/web/review/index.d.ts +38 -0
  218. package/types/reusable/web/styles.d.ts +2 -0
  219. package/ui/index.js +4 -0
  220. package/uploads/index.js +34 -0
  221. package/web/index.js +931 -0
package/GENERATIVE.md ADDED
@@ -0,0 +1,101 @@
1
+ # Generative interfaces
2
+
3
+ This is a supplied-data web family, built from the [assistant-ui Generative renderer](https://www.assistant-ui.com/elements/generative-ui) and all 22 [gallery examples](https://www.assistant-ui.com/elements#generative). SuperXD owns the approved controls, tokens, validation and action lifecycle. The upstream MIT renderer and chart geometry are reused through `@assistant-ui/react-generative-ui`; Zod validates incoming data. Tested package version bounds are in [REUSE.md](./REUSE.md#tested-dependency-boundaries). These packages are justified by the existing public vocabulary/renderer contract and strict runtime validation; no model SDK or chart engine was reinvented.
4
+
5
+ ## Where to see it
6
+
7
+ - Visitor family: `/site/#/family/generative` — 22 composed component examples plus one Structured response flow.
8
+ - Visitor flow: `/site/#/generative` — choose any example; ready, fail-once or lost-response actions.
9
+ - Visitor blocks: `/site/#/b/generative-<slug>` (earlier component links remain supported).
10
+ - Named flow states: `/site/#/f/generative/<state>`.
11
+ - Workbench: `/#/generative`, with 11 action-state frames, five destination frames and a Conference session action-sequence frame.
12
+
13
+ Names and counts come from the registered examples, not hard-coded badges. Domain compositions share 29 vocabulary nodes; they are not 22 competing form/state systems. Existing booking/month/calendar components remain unchanged.
14
+
15
+ ## Public API
16
+
17
+ Install the local `@superxd-studio/adptr` 0.5.0 artifact and the optional Generative peer. This entry is independent of a conversation runtime, although the upstream package requires its compatible React peer packages. Other library entries do not import this renderer.
18
+
19
+ ```tsx
20
+ import { StructuredResponse, type GenerativeActions } from "@superxd-studio/adptr/generative";
21
+ import "@superxd-studio/adptr/styles.css";
22
+
23
+ const actions: GenerativeActions = {
24
+ create_task: {
25
+ kind: "mutate",
26
+ label: "Create this task",
27
+ description: "Create the task with exactly the reviewed title and due date.",
28
+ execute: (request, signal) => destination.create(request, signal),
29
+ lookup: (request, signal) => destination.lookup(request.key, signal),
30
+ },
31
+ };
32
+
33
+ <StructuredResponse
34
+ responseId="tool-result-17"
35
+ spec={completedToolResult}
36
+ status="done"
37
+ actions={actions}
38
+ />;
39
+ ```
40
+
41
+ `destination` is the consuming application's authorized adapter, not an included production service. Keep the action registry/controller stable for a response; change `responseId` when opening a different result. The component owns a controller unless one is explicitly supplied; supplied controllers are disposed by their owner. No action is called on render or on streamed partial content. Unsupported actions are disabled.
42
+
43
+ Exports: `StructuredResponse`, `createSuperxdGenerativeLibrary`, `GenerativeForm`, `GenerativeTable`, `GenerativeChart`, `parseStructuredSpec`, node/chart/table schemas, copy and typed action/controller contracts. `createSuperxdGenerativeLibrary` can be used with an upstream toolkit, but all externally supplied specs still need `parseStructuredSpec` and the controlled response's approval/runtime boundary. Calling the raw upstream renderer does not confer these guarantees. A compatible toolkit bridge inside the existing Chat owners is still future work.
44
+
45
+ ## Wire format and trust
46
+
47
+ Supported vocabulary: Card, Form, Row, Col, Text, Header, Caption, Markdown, Badge, Fact, Divider, Spacer, Accent, Icon, Image, Avatar, Alert, ListView, ListViewItem, Input, Select, DatePicker, RadioGroup, Checkbox, Button, Progress, Chart, Table.
48
+
49
+ The tree is JSON with `$type`, optional `$key`, allowlisted properties and `children`. `$action` is valid only on explicit action controls/Form; card footers carry their own action. A submit button needs a form; fields need unique names in one form. Options and date defaults, aligned chart series and table rows are validated. Unknown types/properties, non-JSON/cyclic/prototype payloads, duplicate identities, deep/large trees and oversized actions are rejected before the upstream renderer runs. React renders plain text; Markdown uses the established safe parser, with raw HTML and unsafe links excluded. There is no arbitrary HTML, CSS, JavaScript, embedded frame or executable code vocabulary.
50
+
51
+ Images require an explicit host `resolveImage(src)` allowlist. Omitted/failed resolution uses a labelled fallback; a model URL alone never triggers a request. Avatar examples use initials. URLs returned by an approved resolver are HTTPS or root-relative; the host must also enforce its own fetch/access policy. No remote media is copied into the package.
52
+
53
+ Facts may have a host binding. `resolveFact(binding, values)` computes the displayed quote and includes the exact resulting `$bindings` alongside `$input` in confirmation. The destination must recompute/check a price, not trust either a model-supplied amount or a browser-provided quote. The fictional plan example updates seats/billing and carries the amount into the frozen decision.
54
+
55
+ ## Forms and action state
56
+
57
+ Controls use the existing React Aria fields/buttons plus segmented dates, select, radio and checkbox primitives. Required/email/date/range validation preserves values, links errors to the controls and focuses the first invalid field on submit. A complete form collects named values; failed actions do not discard the draft. Charts have a data-table alternative and differentiated lines; tables expose labelled sortable headers and keyboard scrolling. Motion uses the existing reduced-motion foundations.
58
+
59
+ The host classifies an action as `inspect`, `mutate` or `dismiss`; model arguments cannot grant permission or bypass mutation confirmation. Mutations first show host-authored intent plus the exact submitted details. Back returns to the originating control. Confirm freezes a deep immutable payload and idempotency key; it disables duplicates and keeps the review's layout while applying, so a double-click cannot hit a card revealed underneath.
60
+
61
+ Receipt: `{ key, type, state: "complete" | "not-applied", message }`. The key/type must match. A confirmed not-applied result permits editing or retrying; an exception, missing or malformed/mismatched receipt is uncertain. Checking may return null, which retains the original key and payload and does not enable a new decision. Retry uses the same request. Unmount aborts work and ignores late replies. Replacing content while an action is pending keeps the reviewed content frozen until that action settles.
62
+
63
+ **Destination responsibilities:** authorize the caller, validate action arguments and revision/target, require the approved operation at the effect boundary, enforce durable idempotency, return matching durable receipts and support lookup. A frontend confirmation is not server authorization. For real services, apply the existing review flow's enforcement rules and AGENTS.md's high-risk Codex/outside-review requirements. The local demonstrations change no actual bookings, calendars, email, orders, payments or tasks; selection of a playlist track does not pretend to play audio without a media source.
64
+
65
+ ## Delivery scope
66
+
67
+ The 22 fictional examples are web compositions. There are 11 named response states: ready, loading, streaming, empty, invalid, confirm, submitting, failed, uncertain, complete and dismissed. Loading and streaming show a calm placeholder with actions held until a fully validated tree arrives. Action receipts and quote computation are local fixtures; no live model calls or provider/domain integrations were made. Native/Ink equivalents, incremental per-node streaming, actual media playback, richer table/chart variants and runtime tool-result bridges remain separate work.
68
+
69
+ The 22 fictional example specifications are included under `examples/generative/specs.json` and downloadable from the visitor flow. Supply a specification to `StructuredResponse` and register its host actions; these specifications do not provide domain services. An executable consumer under `examples/web-generative` uses the actual exported entry with no model/backend. `npm run test:generative-consumer` builds, installs and exercises the packed artifact. Automated verification evidence and captured visuals are recorded in HANDOFF after completion. No publication, commit or deployment is part of this request.
70
+
71
+ ### Action destinations
72
+
73
+ `StructuredResponse` accepts an optional host-authored `renderResult(request)` callback. It is called only after a matching successful receipt. Return a React view for the destination, or `null` to keep the standard completion receipt. Each non-ready action screen (review, progress, failure, receipt or dismissal) replaces the visible source content in place. The built-in Back button restores the original content and focus to the action that opened it. The original content stays mounted so input drafts are retained. No result is shown before confirmation or while an outcome is unknown.
74
+
75
+ The local catalogue supplies speaker profiles, order details, delivery progress, a local support-request form and playlist selection. Support messages stay in memory; sample tracks have no audio source. The reusable package does not hardcode these demo destinations or imply live external services. Five destination frames are also available in the generative workbench.
76
+
77
+ ### Canvas action sequence
78
+
79
+ `retainSteps` opts reusable `StructuredResponse` consumers into a vertical action sequence. It remains off by default. One seeded Conference session frame demonstrates this layout in the workbench. The visitor library now uses the separate observation mode described below, leaving its live demo unchanged.
80
+
81
+ Each controller transition adds a numbered step below the last: ready, loading/applying, review, failure, status check or result. The recorder subscribes to controller notifications so a quickly resolved check still leaves its loading step. Earlier React views stay mounted to preserve their form values and local result state, but are inert and excluded from keyboard navigation and live announcements. Their animations keep running, including loading dots; reduced-motion preferences still apply. Visible captions identify them as previous states. Only the newest step accepts input. This records action lifecycle transitions, not keystrokes or every internal change inside a host-supplied destination.
82
+
83
+ Before completion, Back adds a fresh editable card below the sequence, populated from the last submitted form values. It returns keyboard focus to the matching action in that new card. Completion or dismissal ends the run: there is no terminal Back button, and subsequent controller notifications cannot append more steps. The workspace Reset starts a fresh run. Standard single-view consumers retain their existing terminal Back action.
84
+
85
+ New steps scroll into view only after a visitor action; seeded workbench frames do not take focus. Reset, changing example/scenario, navigating away or changing `responseId` clears the sequence. History is local to the mounted preview and is not saved or sent anywhere.
86
+
87
+ ### Visitor state observation
88
+
89
+ The floating dock has a `Component states` Switch, off by default on every route. The demo always runs in its normal presentation. Switching only reveals or hides read-only state snapshots underneath it and the flow’s named state gallery. There is one live session: drafts, selections, pending requests, popovers and approval rules are unchanged by the switch. Reset remounts that session and clears its history.
90
+
91
+ `CanvasObservationContext` opts the visitor preview into recording while keeping `CanvasModeContext` off. `CanvasSequence` wraps the live owner once and records presentation-only frames from `CanvasStage`. History cannot accept input, take focus or publish another frame. Loading animations remain running; reduced motion still applies. Repeated renders of the same phase update its snapshot rather than appending another step. Terminal outcomes stop the recording; the live demo can continue its normal actions.
92
+
93
+ Structured responses subscribe to their existing controller so even quickly resolved loading and status checks are captured. Input values are captured before submission. The recorder stops observing the controller after completion/dismissal; a host-owned continuation, such as the local support form, can publish its own final steps. The actual result view keeps its Back/edit actions. No extra controller, provider call, mutation or model request is created for a history frame.
94
+
95
+ Calendar keeps its event popover or phone drawer regardless of the switch. Only subsequent event transitions are recorded; the starting calendar is not duplicated and snapshots do not open overlays. Booking, rescheduling, cancellation, Draft review, Review decision and generative action blocks follow the same rule. Conversation keeps its transcript intact and uses the switch to reveal its named state catalogue.
96
+
97
+ The switch is available for full flows, direct non-email state pages, Calendar grid/Event details/Review decision blocks and generative blocks with registered actions. Simple controls, display-only cards and collection pages show the same disabled switch. Captions use SuperXD’s system blue in both themes. History stays in memory and is never sent anywhere.
98
+
99
+ Snapshot captions and content share a component-width frame. State frames are separated by 80px, with SuperXD’s downward arrow centred between them; the first and last frames have no dangling connector. Event details snapshots include the same surface used by the live overlay; forms nested in a result include their enclosing card surface. An enclosing result yields to its own first child stage, so a support form is not recorded twice.
100
+
101
+ The shared recorder observes entry phases without displaying them. Recording starts with pointer, keyboard or assistive activation inside the live demo, then captures subsequent phase changes. Loading a direct state URL, automatic fixture preparation and typing in the starting screen never add another default card. The switch itself is outside this interaction boundary and cannot start or replay a run. Same-phase updates retain the latest entered values; changing phases appends a frame; terminal frames close the recording.
@@ -0,0 +1,51 @@
1
+ # Foundational controls and AI interactions
2
+
3
+ These are additive local package entries. They do not change the existing Calendar, Booking, Chat, Review or StructuredResponse APIs.
4
+
5
+ ## Install and style
6
+
7
+ Build the local package with `npm run build:library`, then install `dist/library` or its generated tarball in another React 19 project. Import `@superxd-studio/adptr/styles.css` once. Import foundational components from `@superxd-studio/adptr/ui` and the state owners and AI presentations from `@superxd-studio/adptr/interactions`.
8
+
9
+ The controls use the installed React Aria primitives for keyboard use, focus, selection, validation and overlays. No additional runtime dependency was introduced. Surface, type, colour, spacing, borders, radius and motion use the shared theme tokens. Override those variables within your `.sxd` root to customise appearance. Controlled values, labels, descriptions, tab/disclosure content, menu actions and host adapters customise behaviour without replacing the design system. These presentations do not execute code or infer permissions.
10
+
11
+ `InteractionProvider` scopes AI words independently of state identities and adapter contracts. Its `copy` prop accepts partial overrides, including default headings and accessible labels; nested providers inherit the enclosing copy. Each owner presentation also accepts an explicit `label`. Controlled UI values and host callbacks remain the behaviour boundary.
12
+
13
+ ## Foundations
14
+
15
+ The UI entry exports Checkbox, CheckboxGroup, RadioGroup, Select, Slider, Toggle, Form, Menu, Accordion, Tabs, Tooltip, ModalDialog, Pagination, Breadcrumbs, Card, Badge, Progress, Separator, AspectRatio, KeyboardHint, DataTable and ToastRegion, alongside the existing Button, TextField, Switch, SearchPicker, SegmentedControl, Avatar, Callout, Skeleton, Spinner, ScrollArea, ResponsiveOverlay and DateTimeField.
16
+
17
+ Select and choice controls accept stable IDs, labels, descriptions and disabled options. Forms use React Aria/native validation and named fields, with server validation errors passed explicitly. Menus represent commands; tabs represent alternate content panels. ModalDialog traps focus, returns focus to its trigger and can prevent dismissal while a write settles. Pagination clamps boundaries. DataTable sorts a copy of the supplied rows, supports selection, stable IDs and empty content; server pagination, filtering and virtualisation belong to the host. ToastRegion uses a host-owned notification queue, with an explicit dismiss action. Its dependency currently exposes the toast primitives as unstable; that dependency is isolated behind this wrapper.
18
+
19
+ ## Supervised plan
20
+
21
+ Create `AgentController(adapter, steps)` and pass it to `AgentSupervision`. A step has `id`, `title`, `tool`, JSON `input` and a human-readable `scope`. Each step is reviewed independently. Approval freezes the exact step and inputs for a bounded time; it does not grant server permission. There is no automatic execution, hidden scheduling, provider integration or background-job claim.
22
+
23
+ `adapter.execute(request, signal, reportProgress)` must authorise server-side and deduplicate by `requestId`. Return completed with output, rejected with a reason, or unknown, always matching the request ID. `adapter.lookup(requestId, signal)` recovers that exact receipt. A not-found response must mean definitely unaccepted, not merely absent from an eventually consistent read. Earlier completed results survive failure. Declining is terminal. Stop waiting aborts the browser request and marks the outcome unknown; it cannot promise that remote work stopped. Failed or expired approval requires review again. An uncertain request cannot be repeated until its receipt is checked.
24
+
25
+ ## Artifact workspace
26
+
27
+ Create `ArtifactController(adapter)` and render `ArtifactWorkspace`; call `open(id)` to load a record. Records have stable identity, title, revision, content, editable permission and bounded revision history. Loading another artifact cannot discard a dirty draft. Read-only records cannot be edited.
28
+
29
+ `adapter.save` must authorise, deduplicate by request ID and atomically compare `baseRevision`. A conflict returns the latest record, preserving the local draft until the person chooses the latest version or explicitly rebases their draft. A saved result must return the same artifact and a new revision. Unknown outcomes lock edits and discard until `lookup` establishes the original save result. The host must persist content and receipts; the browser controller alone is not durable storage.
30
+
31
+ ## Feedback and conversation history
32
+
33
+ ResponseFeedback uses FeedbackController with a specific response ID. The host upserts feedback for that response and acknowledges storage before the UI says saved. A failed or lost acknowledgement retains the exact feedback and request ID for idempotent retry.
34
+
35
+ ConversationHistory uses ThreadController with list/load/rename/archive callbacks. The host owns storage and conversation hydration. Thread payloads are bounded JSON and remain opaque: messages, branches and attachments are preserved rather than converted into a smaller transcript. While the list refreshes, opening another thread is temporarily disabled in both the controller and its presentation. When refresh settles, the updated list can be opened normally; switching never silently cancels a refresh. Supply `canLeave` to block switching/archive while unsaved or running work needs attention. Supply `renderThread` to render/hydrate the returned document in your own runtime. This is not a provider runtime or a durable ChatController persistence implementation.
36
+
37
+ Dispose controllers when their host lifetime ends. The snapshots are immutable external stores and can also be consumed by another renderer via `subscribe` and `getSnapshot`. Late or mismatched replies cannot overwrite a newer request.
38
+
39
+ ## AI presentations
40
+
41
+ Sources and Citation validate external HTTP(S) destinations and reject executable schemes and embedded credentials. Unavailable evidence stays visible as unavailable. RetrievalInspection shows supplied included/excluded context. Reasoning shows a supplied progress explanation; it does not expose or invent model chain-of-thought. ToolCall separates declared inputs, lifecycle and result from the executor. Guardrail and Confidence display supplied policy/uncertainty with explicit alternatives. ComposerTools changes model/context/command selections through host callbacks; it does not silently send a message. QuotedExcerpt retains source attribution. ExecutionInspector displays code/files/results/checks without executing them. Observability reports supplied measurements and displays missing values as not reported.
42
+
43
+ ## Remaining boundaries
44
+
45
+ This pass does not implement a hosted MCP, authentication, paid provider calls, arbitrary code execution, durable job queues, stream resumption, scheduling, voice/video generation, shared remote storage or provider memory. Existing reference-only concepts remain labelled accordingly. Domains with irreversible actions need their own policy and server enforcement. Package code and demo adapters must not be mistaken for production backends.
46
+
47
+ ## Proven sources
48
+
49
+ The implementation wraps the existing [React Aria](https://react-aria.adobe.com/) dependency (Apache-2.0). Its controls and overlays supply accessibility behaviour. The presentation/adapter separation follows the documented boundaries in [AI Elements Tool](https://elements.ai-sdk.dev/components/tool), [Sources](https://elements.ai-sdk.dev/components/sources) and [assistant-ui external stores](https://www.assistant-ui.com/docs/runtimes/custom/external-store). These were design/API references; their implementation source was not copied into these new owners.
50
+
51
+ Source-recipe delivery checks the physical path of guides, licences and other build inputs before reading them, in addition to the registry's existing path-segment validation. Symlinks resolving outside the project are rejected.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SuperXD
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # ADPTR
2
+
3
+ React components and finished product flows by [SuperXD](https://superxd.app): conversation, review and AI-assisted work, with every state designed. They're accessible by default (built on React Aria) and restyled from one set of theme tokens.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @superxd-studio/adptr
9
+ ```
10
+
11
+ ADPTR needs React and React DOM 19.3 or later within React 19.
12
+
13
+ ## Use
14
+
15
+ Import the styles once, then use components anywhere:
16
+
17
+ ```tsx
18
+ import "@superxd-studio/adptr/styles.css";
19
+ import "@superxd-studio/adptr/fonts.css"; // Optional: SuperXD's type. Leave it out to use your own fonts.
20
+ import { Button } from "@superxd-studio/adptr/ui";
21
+
22
+ export function Continue() {
23
+ return <Button variant="primary">Continue</Button>;
24
+ }
25
+ ```
26
+
27
+ The interactive entry points are marked for React Server Components, so they work straight in Next.js App Router pages.
28
+
29
+ ## What's inside
30
+
31
+ | Entry | What it's for |
32
+ | ------------------------------------ | ------------------------------------------------------------------------------ |
33
+ | `@superxd-studio/adptr/ui` | Buttons, fields, choices, menus, dialogs and the other shared components |
34
+ | `@superxd-studio/adptr/web` | Conversation (`Chat`) and draft review (`DraftReview`) |
35
+ | `@superxd-studio/adptr/core` | Framework-free controllers for conversations and reviews, safe on a server |
36
+ | `@superxd-studio/adptr/custom` | Connect a conversation to your own HTTP endpoint |
37
+ | `@superxd-studio/adptr/generative` | Structured responses: cards, forms, charts and tables an assistant can propose |
38
+ | `@superxd-studio/adptr/interactions` | Supervised plans, artifact editing, saved conversations and feedback |
39
+ | `@superxd-studio/adptr/styles.css` | Component styles and theme tokens (no fonts) |
40
+ | `@superxd-studio/adptr/fonts.css` | Optional fonts: Instrument Sans and IBM Plex Mono |
41
+
42
+ Optional integrations for assistant-ui, the AI SDK and LangGraph live in `assistant-ui`, `ai-sdk` and `langgraph-review`; install those libraries only if you use them.
43
+
44
+ ## Make it yours
45
+
46
+ Every component reads semantic theme tokens: colours, type, spacing, corners, elevation and motion. Override them after the stylesheet to change the look everywhere. Components take `className` and copy overrides for their words.
47
+
48
+ ## Learn more
49
+
50
+ - `REUSE.md`: conversations, attachments, connecting your backend and supported versions.
51
+ - `REVIEW.md`: draft review and its server contract.
52
+ - `GENERATIVE.md`: structured responses and their wire format.
53
+ - `INTERACTIONS.md`: plans, artifacts and saved conversations.
54
+
55
+ ## Licence
56
+
57
+ MIT. Fonts and third-party notices are in `licenses/` and `THIRD-PARTY-NOTICES.md`.
package/REUSE.md ADDED
@@ -0,0 +1,170 @@
1
+ # Reuse the conversation and attachments
2
+
3
+ This local artifact exports a controlled React conversation, a platform-neutral controller and a customer-owned HTTP adapter. The optional assistant-ui integration uses the **same Chat component**, with that runtime owning state. This is the M1–M2b plus draft-review and supplied-data Generative local artifact (0.5.0), not the complete library release.
4
+
5
+ The visitor library collects these examples in **Blocks → Conversation**, at `/site/#/b/conversation`. Its simulated demo runs without a server; the connected examples below use the local HTTP and AI SDK example servers. Old `/site/#/reusable` links redirect to this block. The integration workbench at `/#/reusable` still includes the optional runtime comparisons.
6
+
7
+ ## Run the independent consumer
8
+
9
+ From the library repository:
10
+
11
+ ```sh
12
+ npm run pack:library
13
+ npm run dev:backend
14
+ ```
15
+
16
+ In another terminal:
17
+
18
+ ```sh
19
+ cd examples/web-independent
20
+ npm install
21
+ npm run dev
22
+ ```
23
+
24
+ Open `http://127.0.0.1:5300`. The example package points at the built package directory for convenient iteration. The clean-install check uses the **actual tarball**, not that directory or a private alias. There are no assistant-ui imports/dependencies in this consumer. No hosted account, API key or model call is needed. The HTTP server streams deterministic responses; it is an integration example, not an AI provider.
25
+
26
+ ## Public API and ownership
27
+
28
+ ```tsx
29
+ import { ChatController } from "@superxd-studio/adptr/core";
30
+ import { createHttpChatAdapter } from "@superxd-studio/adptr/custom";
31
+ import { Chat, useChatController } from "@superxd-studio/adptr/web";
32
+ import "@superxd-studio/adptr/styles.css";
33
+ import "@superxd-studio/adptr/fonts.css"; // Optional: omit when supplying your own font.
34
+
35
+ // Create once per mounted conversation, dispose when it unmounts.
36
+ const controller = new ChatController(createHttpChatAdapter({ endpoint: customerEndpoint }), () =>
37
+ crypto.randomUUID(),
38
+ );
39
+ const snapshot = useChatController(controller);
40
+ return <Chat snapshot={snapshot} actions={controller} />;
41
+ ```
42
+
43
+ Your existing application can instead own `ChatSnapshot` and implement `ChatActions`. `Chat` is presentation only; it has local unsent draft state but never a transcript store. `renderMessage`, `footer`, `copy` and `className` are deliberate customization points. Assistant responses use the exported safe Markdown renderer by default; user text is escaped plain text. Supply `renderMessage` to override presentation with your own safe renderer. The artifact includes editable TypeScript source under `source/`, with supporting primitives/styles and no private aliases, plus the runnable independent consumer and backend under `examples/`. From an extracted package, run `node examples/custom-backend/server.mjs` and start `examples/web-independent` in another terminal. Styles are explicitly imported, use existing SuperXD tokens; the optional `fonts.css` supplies licensed Instrument Sans and IBM Plex Mono, SuperXD's two type voices. Override semantic tokens in your application after the stylesheet. Native and terminal renderers are not part of this first artifact yet.
44
+
45
+ Optional integration:
46
+
47
+ ```tsx
48
+ import { AssistantChat } from "@superxd-studio/adptr/assistant-ui";
49
+ return <AssistantChat adapter={adapter}>{(chat) => <Chat {...chat} />}</AssistantChat>;
50
+ ```
51
+
52
+ Install a tested `@assistant-ui/react` version (see the compatibility table below) only for that entry. It owns all transcript/run state; the integration projects it read-only. The independent controller is not present. The bridge supports the shared text/file contract when its adapter advertises attachments. Public editing, regeneration and branch navigation are enabled only when the adapter explicitly advertises them. Thread management and tool/media parts remain outside this slice. No unstable API is used in this bridge.
53
+
54
+ ## Editable source and styling
55
+
56
+ For source reuse, copy `source/reusable/core`, `custom` and `web`, plus `source/components` and `source/lib`, retaining their relative structure. Install the React/React DOM peers and the dependencies listed in the artifact's `package.json`. Omit `source/reusable/assistant-ui` unless using that optional integration. Import the **compiled** `styles.css` supplied in the artifact and retain its `assets/` directory; this removes the need for a Tailwind compiler in the consumer. Add `fonts.css` to use the supplied Instrument Sans and IBM Plex Mono files, or override the font tokens with your own fonts. The `source/reusable/web/styles.ts` entry is the repository's build input, not the stylesheet to import in a consumer.
57
+
58
+ The original theme/library CSS is included for inspection and editing. Rebuilding that raw CSS requires the repository's Tailwind/Vite setup and the `@fontsource-variable/instrument-sans` and `@fontsource/ibm-plex-mono` packages; the current compiled package is the tested installation path. Next.js/server-component bundling has not been verified in this milestone. All web examples were built with Vite.
59
+
60
+ ## Custom backend wire contract
61
+
62
+ `POST endpoint` with JSON `{ requestId, messages: [{ id, role: "user" | "assistant", text }] }`. Return `Content-Type: application/x-ndjson` and newline-terminated JSON events:
63
+
64
+ ```json
65
+ {"type":"text","text":"First part "}
66
+ {"type":"text","text":"of the response."}
67
+ {"type":"finish"}
68
+ ```
69
+
70
+ An explicit `{ "type": "error" }` is a failure. End-of-stream without `finish` is an interruption. Stop aborts the fetch and retains partial output; Restart starts a **new run**, shows a new response on the selected path and reuses the question once. Earlier responses remain in the session tree; version controls require the branches capability. It never claims to resume. There is no automatic retry of potentially consequential work. Customer adapters must enforce their own idempotency and tool permissions on the server. The example deduplicates request IDs in bounded process memory and executes no side effects; this is not durable replay protection or production authorization.
71
+
72
+ `headers: () => Promise<HeadersInit>` supports consumer-owned refreshed credentials; `credentials` controls cookie use. Production endpoints must validate data, authenticate/authorize the user, enforce request limits and handle cancellation. Never put provider secrets in that callback or any client bundle. Configure CORS for your application. The example accepts only listed loopback origins and binds to `127.0.0.1`.
73
+
74
+ Snapshot statuses: idle, waiting, streaming, complete, cancelled, error, interrupted. Capabilities expose send/cancel/retry, optional attachments and opt-in edit/regenerate/branches. Editing/regeneration/version controls are absent unless explicitly enabled. Approval, persistence and resume controls remain unsupported. The custom NDJSON adapter remains text-only; the SDK adapter enables uploads through a separate consumer-owned upload adapter. Metadata can be supplied in the owned public message model; the NDJSON example server deliberately ignores it. Messages can carry verified `ChatFile` references when the adapter advertises attachments. Provider-specific rich metadata conversion belongs in subsequent adapter batches.
75
+
76
+ ## Validation and gaps
77
+
78
+ Run `npm run check`, `npm run test:consumer` and `npm run pack:library`. The plan records actual results and distinguishes them from live-provider execution. Native, Ink and LangGraph remain required upcoming implementation batches. AI SDK transport and upload execution are covered by the local server; live model-provider execution is not verified. The shared core is checked without DOM libraries now. There are no editable Figma assets available yet.
79
+
80
+ ## AI SDK conversation with attachments
81
+
82
+ The optional `@superxd-studio/adptr/ai-sdk` entry requires a tested **ai 7** version (see below) (Apache-2.0). It uses the official `DefaultChatTransport` and `readUIMessageStream` APIs; there is no second transcript store or mandatory SDK React hook. The `core`, `web`, `custom` and `uploads` entries do not import `ai`. A web-only independent consumer installs neither `ai` nor assistant-ui. Both peers are optional.
83
+
84
+ From this repository, start `npm run dev:ai-sdk-backend`. Then install and run `examples/web-ai-sdk` in another terminal. From the extracted package, run `npm install` then `npm start` inside `examples/ai-sdk-backend`; install and run `examples/web-ai-sdk` separately. Both use Node 22 or newer. Stop the other consumer using port 5300 first.
85
+
86
+ ```tsx
87
+ import { ChatController, AttachmentController } from "@superxd-studio/adptr/core";
88
+ import { createAiSdkChatAdapter } from "@superxd-studio/adptr/ai-sdk";
89
+ import { createHttpUploadAdapter } from "@superxd-studio/adptr/uploads";
90
+ import {
91
+ Chat,
92
+ AttachmentPicker,
93
+ useAttachments,
94
+ useChatController,
95
+ } from "@superxd-studio/adptr/web";
96
+ ```
97
+
98
+ The runnable example contains the complete lifecycle/composition. Instantiate controllers once, subscribe with the supplied hooks, dispose on unmount, pass ready references as `draftFiles` and block sending while any selected item is unresolved. `onSent={uploads.transfer}` transfers ownership only after send succeeds. Streaming failure leaves sent file references in the transcript; restart reuses that question and those references. Upload retry retains its source and stable upload ID; removal aborts and ignores late completion. Never clear a queue merely because Send was pressed.
99
+
100
+ `createAiSdkChatAdapter({ endpoint, chatId, headers, credentials, fetch })` separates a stable conversation `chatId` from each run's request ID. Its request contains standard SDK messages plus `requestId` and `metadata.superxdFiles`. Text/files convert at the integration boundary. Incoming provider metadata and non-text parts remain available under `message.metadata.aiSdk`; this slice displays text and user-supplied file references only. SDK step resets replace discarded text. Tool chunks fail explicitly until M3 implements tool capabilities. EOF without finish is interrupted; retry starts a new run. No automatic reconnect/resume is claimed.
101
+
102
+ `AttachmentList` is independently usable from supplied items, with list/grid/inline layouts, names/types/sizes/status and optional remove/retry/cancel callbacks. Callback-free displays show no action buttons. `AttachmentPicker` uses React Aria's file selection and the generic upload controller. Uploads may use `Blob` on web; the core source-data type is generic for upcoming native/Ink implementations. PNG/JPEG thumbnails require explicit `previewImages` opt-in and a trusted HTTP(S) origin; PDFs, HTML and generated code are never embedded/executed. Hover previews, audio/video and source-document citations remain separate catalogue work.
103
+
104
+ ### Local upload example contract and limits
105
+
106
+ `POST /uploads` sends raw bytes with `Content-Type`, a percent-encoded `X-File-Name` and stable `X-Upload-Id`. A successful JSON response is `{ id, name, mediaType, size, url }`. The local example allows PNG, JPEG, PDF and UTF-8 plain text, up to 5 MB each; the preview allows four files. It checks signatures/UTF-8, declared length and actual bytes. These are basic format checks, not a full parser or malware scan. Metadata and content must both match a reused upload ID. Concurrent reuse is rejected; completed reuse returns the same reference. This is process-local replay protection.
107
+
108
+ Removed draft references may be deleted through a consumer-provided `releaseEndpoint`. Once sent, they cannot be deleted through that draft endpoint. Uploaded bytes expire after 15 minutes and are reclaimed on a subsequent request; they disappear when the server stops. Storage is bounded to 20 MB, with bounded concurrent/file counts. The sample server verifies every SDK file part against its own stored references and never fetches an arbitrary submitted URL.
109
+
110
+ The example binds to loopback and checks browser origins. It has **no production authentication, durable storage or live model**. Its SDK stream is deterministic and acknowledges verified references; it does not claim to have analysed file content with a model. Consumers must supply real storage, access checks, retention, signed URLs/provider uploads, durable idempotency and provider configuration on the server. Refreshed auth headers/cookies belong to the consumer; provider keys never belong in client configuration. Deployment needs the backend safety review recorded in the plan.
111
+
112
+ The installed-artifact check exercises independent NDJSON, SDK with actual uploads through the packaged server, and optional assistant-ui rendering. Deterministic execution does not verify external model credentials or provider file support. Next.js/server-component bundling, editable Figma assets, native and Ink remain unverified.
113
+
114
+ ## Rich messages and version history
115
+
116
+ `MessageMarkdown`, `CodeBlock`, `CopyButton`, `MessageEditor` and `BranchPicker` are independent exported web components. They take supplied text/data and callbacks; no chat provider, SDK or assistant-ui dependency is needed. `Chat` renders assistant text with the same Markdown component and user text as escaped plain text. Existing `renderMessage` still overrides presentation. CommonMark and GFM formatting use tested, bounded `react-markdown` and `remark-gfm` versions (see below) rather than a custom parser. Both are MIT dependencies with retained notices.
117
+
118
+ Markdown skips raw HTML, rejects unsafe/credential-bearing URLs, renders image alt text without fetching images, and never executes code. Code blocks are plain monochrome text in the approved tokens, with keyboard scrolling and exact-code copy; no syntax highlighting or generated execution is claimed. Code copy is disabled while the response is arriving. Message copy preserves the supplied Markdown source. Clipboard permission failures show recovery text, and only resolved writes report success. `writeText` allows the consuming application to own clipboard I/O.
119
+
120
+ `createHttpChatAdapter({ endpoint, conversationActions: true })` or the SDK equivalent opts into replay-safe editing, regeneration and versions. This must be an explicit host decision: resending a question starts a new server run and does not undo or roll back previous side effects. Server authentication, authorization and durable idempotency remain the host's responsibility. The local examples have no tools/side effects, so their rich previews enable this option. Defaults leave these controls absent.
121
+
122
+ The owned `ChatActions` contract adds optional `edit(messageId, text)`, `regenerate(messageId)` and `selectBranch(messageId, "previous" | "next")`. Actions return whether accepted. The selected path is projected as `messages`; sibling positions are supplied under `snapshot.branches[messageId]` with zero-based `index` and `count`. Editing creates a sibling question and keeps verified file references. Regeneration creates an alternative answer beneath the same question. Selecting an earlier version restores its selected descendants, and only that path is sent on a later request. Drafts remain local and survive version changes. The independent owner bounds its in-memory tree to 500 nodes and 20 alternatives at one position; it refuses additions at those limits. Histories are session-only, with no persistence/export/import contract yet.
123
+
124
+ The optional integration uses assistant-ui's public append/reload/branch methods, preserving one runtime owner. It projects branch positions and file metadata read-only. It does not instantiate `ChatController`, use internal APIs or synchronize a competing history. Both owners are exercised against the real local HTTP examples for editing, regeneration, descendant preservation and files.
125
+
126
+ `Chat` accepts `messageCopy` for action words and `writeText` for clipboard. `scrollable` opts into the existing bounded conversation height; `autoScroll` follows new content only while the person remains at the bottom. Reading earlier content stops following. Jump to latest restores it. Neither streaming nor specimen initialization moves keyboard focus. Editors opened by the person restore focus to the main composer after saving/cancelling. Standalone `MessageEditor` defaults `autoFocus` to false, so supplied-data specimens do not steal focus.
127
+
128
+ The same semantic CSS tokens are used throughout, allowing consumer overrides after the stylesheet. A visitor theme editor/import/export workflow has not been implemented. The original rich conversation prototype is preserved separately; the public owned family now covers this documented subset. Tool approvals, threads/persistence, native/Ink and broader catalogue work remain visible in the plan.
129
+
130
+ ## Review and approval
131
+
132
+ The package also exports `ReviewController`, `createHttpReviewAdapter`, `ReviewChangeCard`, `ReviewDecisionPanel` and `DraftReview`. See [REVIEW.md](./REVIEW.md) for the decision/recovery contract and executable examples. The optional `langgraph-review` entry is server-side only. Native/Ink, generic tool flows and chat approval integrations remain planned.
133
+
134
+ ## Generative interfaces
135
+
136
+ The optional `@superxd-studio/adptr/generative` entry exports `StructuredResponse`, a validated 29-node vocabulary, reusable form/table/chart components and a host-owned action controller. The 22 gallery compositions share this entry; the package includes their JSON specifications under `examples/generative/specs.json`, with no workbench controllers. Mutating actions require a separate confirmation and preserve a frozen request/key through failure or lost-response recovery. A supplied response update preserves edited field values; opening a different task requires a new `responseId`.
137
+
138
+ Install tested `@assistant-ui/react-generative-ui` and `@assistant-ui/react` versions (see below) only when using this entry. Existing independent conversation and review entries do not import/install those optional runtimes. See [GENERATIVE.md](./GENERATIVE.md) for validation, media allowlisting, host quotes, destination enforcement responsibilities and the complete API. The package includes the runnable `examples/web-generative` consumer; `npm run test:generative-consumer` in the repository exercises the actual packed artifact. Its actions are local fixtures, with no provider, email, calendar or payment service.
139
+
140
+ ## Additive foundation and AI interaction entries
141
+
142
+ `@superxd-studio/adptr/ui` exports standalone form, selection, navigation, overlay and display controls. `@superxd-studio/adptr/interactions` exports supervised plans, artifact revisions, response feedback, saved-thread adapters and supplied AI presentations. Both use the same styles and tokens as the existing entries. Their host contracts and limits are documented in [INTERACTIONS.md](./INTERACTIONS.md); the packed `examples/web-interactions` project consumes only public imports.
143
+
144
+ `InteractionProvider` scopes copy overrides without changing lifecycle names or request contracts. A host can supply its own labels, content and callbacks, override theme variables, and consume controller snapshots in another renderer. These APIs do not include a hosted execution or persistence service. `npm run test:layer-consumer` installs the generated tarball in a clean temporary project, builds it and checks its browser behaviour.
145
+
146
+ ## Task observation and restarting
147
+
148
+ `useReview` loads and subscribes to a host-owned ReviewController. Closing a view only unsubscribes it: other views and later remounts receive the same result. Call `controller.disconnect()` when the host ends the task's observation lifetime; this aborts local observation, publishes uncertainty to remaining observers and cannot undo remote work. Chat, AttachmentController and interaction owners likewise belong to the host, which calls their disposal method when their lifetime ends.
149
+
150
+ Both `createHttpChatAdapter` and `createAiSdkChatAdapter` accept additive `retry?: boolean`, defaulting to `true` for compatibility. Set `retry: false` to remove Restart. `conversationActions` independently opts into editing, regeneration and versions. A restart uses a new `requestId` and preserves the user message `id`. Endpoints with side effects must authorise and deduplicate the underlying action durably per question (stable user message ID, scoped to the authenticated conversation/person), not merely per run/request ID. Editing creates a new question ID and needs the host's own policy too. Nothing here resumes a stream or rolls back an action.
151
+
152
+ The loopback review example prunes expired sessions before checking capacity, never active receipts. It accepts an optional `now` clock for deterministic tests. Expired credentials cannot recover receipts: a real service needs a durable retention/recovery policy. The SDK example checks the exact loopback Host on every route and retains the most recent 500 run IDs and failure-fixture keys by evicting one oldest key at a time. Older IDs can still replay, a restart forgets memory, and Host/Origin checks are not authentication. These examples remain high-risk starting points for real backends: add durable deduplication, access control and an outside security review before going live.
153
+
154
+ ## Tested dependency boundaries
155
+
156
+ These inclusive ranges are deliberately limited to released versions tested by the clean tarball consumers; widening them requires rerunning those checks. This changes no React support policy. Optional runtimes remain optional.
157
+
158
+ | Package | Oldest | Newest |
159
+ | --------------------------------- | ------- | ------- |
160
+ | ai | 7.0.126 | 7.0.127 |
161
+ | @assistant-ui/react | 0.15.22 | 0.15.23 |
162
+ | @assistant-ui/react-generative-ui | 0.0.21 | 0.0.22 |
163
+ | @langchain/langgraph | 1.4.18 | 1.4.19 |
164
+ | zod | 4.6.4 | 4.6.5 |
165
+ | react-markdown | 10.0.0 | 10.1.0 |
166
+ | remark-gfm | 4.0.0 | 4.0.1 |
167
+
168
+ Run the existing conversation, review, generative and interaction-layer consumer scripts with `ADPTR_CONSUMER_EDGE=oldest` and `ADPTR_CONSUMER_EDGE=newest`. They install actual tarballs and exercise their existing build/browser checks with these selected dependencies. Component CSS excludes all fonts; `fonts.css` is an optional public entry with relative WOFF2 assets. Site/workbench font imports and theme tokens remain unchanged. The library build excludes the website public directory.
169
+
170
+ The earlier conversation prototype uses the same URL filter and renders image alt text instead of fetching images. This keeps its existing reusable inventory entry while closing the remote-image leak with two renderer overrides.
package/REVIEW.md ADDED
@@ -0,0 +1,68 @@
1
+ # Reusable review and approval
2
+
3
+ Local package version **0.5.0**. This batch implements draft review on web: proposed-change cards, a decision panel and a complete flow. It preserves the approved warm foundations. It does not connect to a model, send emails or apply changes to a real document.
4
+
5
+ ## Install and compose
6
+
7
+ Install the downloaded `superxd-studio-adptr-0.5.0.tgz` with npm. React 19 is a peer. React Aria supplies keyboard and focus behaviour. The web entry does not require LangGraph or assistant-ui.
8
+
9
+ ```tsx
10
+ import { useState } from "react";
11
+ import { ReviewController, createHttpReviewAdapter } from "@superxd-studio/adptr/review";
12
+ import { DraftReview } from "@superxd-studio/adptr/web";
13
+ import "@superxd-studio/adptr/styles.css";
14
+
15
+ export function Review() {
16
+ const [controller] = useState(
17
+ () =>
18
+ new ReviewController(
19
+ createHttpReviewAdapter({
20
+ endpoint: "/api/reviews/welcome-draft",
21
+ // Authentication is supplied by your application and evaluated every request.
22
+ credentials: "same-origin",
23
+ }),
24
+ ),
25
+ );
26
+ return <DraftReview controller={controller} />;
27
+ }
28
+ ```
29
+
30
+ `DraftReview` loads the supplied review and cleans up observation on unmount. Use one controller per task; keep its identity when changing canvas or theme. A lost response remains uncertain until the server confirms what happened. Disconnecting cannot undo an already received decision.
31
+
32
+ The `core` entry also exports the portable types, reducer and controller without browser or runtime-vendor imports. The `review` entry adds the HTTP adapter. `ReviewChangeCard` and `ReviewDecisionPanel` in `web` work independently with supplied data/callbacks. UI words accept a `copy` override; semantic theme tokens style all parts. Container width changes the comparison and composition; it does not create another task or clear selection.
33
+
34
+ ## HTTP contract
35
+
36
+ The endpoint represents a review that your server already associates with the authenticated person. Browser selection and enabled controls never establish authorization.
37
+
38
+ | Operation | Response |
39
+ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
40
+ | GET the review endpoint | `ReviewRecord`: authoritative proposal, revision, applied IDs, remaining IDs and outcome |
41
+ | POST `/decisions` | `ReviewReceipt`, containing the request ID, choice, newly applied IDs and authoritative record |
42
+ | GET `/receipts/:requestId` | `ReviewRecovery`: authoritative record and the original receipt, or `null` when no receipt is recorded at the time of the check |
43
+
44
+ A decision contains only `requestId`, `proposalId`, `revision`, `choice` (`approve` or `deny`) and `changeIds`. Text and tool arguments are resolved from the server's immutable stored proposal. Approved IDs must be nonempty, unique and within the remaining scope. Deny carries no IDs. The example validates exact fields, bounded inputs and result structure. Authentication refresh is consumer-owned. 401/403 blocks decisions; 409 requires a fresh review. Other failures remain uncertain until a receipt check, including failed parsing and transport timeouts.
45
+
46
+ The server must atomically enforce identity, ownership, current permission, proposal revision, resource preconditions and selected scope. Record the receipt in the same transaction as the side effect. Serialize decisions for the same resource. Reusing the same request ID and decision must return its original receipt; changing its payload must fail. Preserve receipts through the retry horizon. Do not evict replay protection to accept more requests.
47
+
48
+ Receipt absence cannot prove an earlier request will never arrive. After an uncertain result, the controller retains the frozen decision and request ID even if a lookup finds no receipt. It permits another status check or retrying exactly that decision; Back and a different selection stay unavailable. A delayed receipt settles the original decision without another mutation.
49
+
50
+ After a partial result, only the approved remainder stays eligible. Applying it requires another explicit review and confirmation with the new revision and a new request ID. Declining the remainder keeps the already applied changes. Previously unselected changes stay untouched. The example's synchronous in-memory commit demonstrates these invariants; it is not a distributed transaction recipe or production authorization/persistence.
51
+
52
+ ## Run the local examples
53
+
54
+ From the repository, run `npm run dev:review-backend`, then `npm run dev`. The visitor flow is `/site/#/review`; workbench examples are `/#/review`. The visitor flow uses actual HTTP. State thumbnails are supplied-data fixtures and never create backend approvals. The packed artifact includes `examples/web-review` and `examples/review-backend`.
55
+
56
+ The backend is loopback-only, with random short-lived per-review capability tokens kept in browser memory, fixed fictional text, origin/host validation and bounded requests. There are at most 200 process-local sessions, valid for 30 minutes. Capacity refuses new sessions rather than clearing receipts. Restarting loses sessions and receipts. The public demo does not imply durable auth, storage, a production service or a live AI provider. No tracing or paid model calls were used in verification.
57
+
58
+ The optional **server-side** `langgraph-review` entry imports `@langchain/langgraph` within the tested bounds in [REUSE.md](./REUSE.md#tested-dependency-boundaries) (MIT). Install it only in a backend that uses it. `createLangGraphReviewDriver(commit)` pauses with a real `interrupt`, then uses `Command({resume: decision})` on the same checkpoint. The host's `commit` remains responsible for authorization and atomic receipts. Failed commit retries must retain the original decision; another decision cannot take over its checkpoint. `MemorySaver` is process-local; use durable checkpointing and durable effect/receipt storage before live use. This driver covers draft approval, not arbitrary tools or complete AI SDK/assistant-ui approval parity.
59
+
60
+ Official implementation references: [interrupt and resume](https://docs.langchain.com/oss/javascript/langgraph/interrupts), [durable execution and side effects](https://docs.langchain.com/oss/javascript/langgraph/durable-execution). The example keeps effects after approval and rechecks their preconditions at commit.
61
+
62
+ ## State coverage and boundaries
63
+
64
+ Eighteen named states cover ready, no selection, approve/deny confirmation, loading/retry, applying, uncertain/recovery, changed draft, view only, partial result, declining the remainder, completed/declined and empty. The same exported flow renders them. Browser checks exercise actual transitions, keyboard focus and both themes at 1440/1024/768/390/360.
65
+
66
+ This is a review slice of M3. General tool progress, structured questions, chat-runtime approval bridges, native and Ink rendering remain required later work. No calendar extraction, new palette, full theme editor, publication or deployment is included.
67
+
68
+ The backend is high-risk code. Codex reviews its boundaries and automated tests directly attack them. AGENTS.md requires Codex review for high-risk changes and recommends a one-off outside security review before live use. That review should cover durable transactions, access control, expiration and ambiguous-result recovery.
@@ -0,0 +1,28 @@
1
+ # Distribution provenance
2
+
3
+ SuperXD-owned library source is MIT. This does not relicense third-party dependencies, fonts or copied artwork. The M1–M2b and review package allowlist excludes the marketing chrome, mascot family, studio-waves art, app documentation, fixtures and private files. No upstream AI Elements implementation has been copied in M1–M2b; its attachment patterns are reference material.
4
+
5
+ | Material | Exact scope/version | Handling |
6
+ | --------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | SuperXD | `src/reusable/**`, existing Button/Callout/Spinner/cn helpers and approved theme used in M1–M2b | Original project code; MIT |
8
+ | Lucide / Feather | SVG paths in `src/components/icons.tsx` | Complete ISC and Feather MIT notices in `licenses/lucide.txt`; retain with source/artifacts |
9
+ | Instrument Sans | `@fontsource-variable/instrument-sans@5.3.0`, the library's text font and the optional `fonts.css` | SIL OFL-1.1 in `licenses/instrument-sans.txt`; not MIT; no modified font/name claim |
10
+ | IBM Plex Mono | `@fontsource/ibm-plex-mono@5.3.0` (400, 500), the library's system voice and the optional `fonts.css` | SIL OFL-1.1 in `licenses/ibm-plex-mono.txt`; not MIT; no modified font/name claim |
11
+ | assistant-ui | React 0.15.22 optional peer (the optional bridge); the earlier prototype's core and Markdown packages were removed | MIT package notices; `licenses/assistant-ui.txt`; optional bridge imports stable APIs; replacement is another snapshot/actions integration |
12
+ | AI SDK | ai 7.0.126 optional peer; its pinned provider-utils/provider/gateway dependencies stay within that package | Apache-2.0; upstream copyright in `licenses/ai-sdk.txt`; imports isolated in the optional SDK entry and executable server. Default transport/message-stream APIs are stable. Replacement is another `ChatAdapter`, without changing `Chat`. |
13
+ | React / React DOM | 19.3.x peers | MIT; packages retain their notices |
14
+ | React Aria components | 1.21.1 web dependency | Apache-2.0; package retains full notice; maintained web accessibility primitive |
15
+ | react-markdown / remark-gfm | 10.1.0 / 4.0.1 web dependencies | MIT; notices in `licenses/react-markdown.txt` and `licenses/remark-gfm.txt`. Established CommonMark/GFM parsing, external package dependencies rather than copied implementations. No raw-HTML plugins or upstream global styles. |
16
+ | clsx / tailwind-merge | 2.1.1 / 3.7.x | MIT; original package notices retained by npm |
17
+ | AI Elements | audited source `6a9d5b1822ffb10bba4bd97175f01edd7d8651cd` | Apache-2.0; reference only in M1–M2b. Any adapted file in later batches must retain its original licence/notice and changed-file attribution |
18
+ | cal.diy | audited source `54343aa685ae8f33159d2f485ec4a57bad5c574a` | MIT reference, existing booking spec says reference-only implementation; no cal.diy source copied in M1; inspect exact directories/assets before extraction |
19
+
20
+ The historical booking appendix referenced `calcom/cal.com` while describing cal.diy. These are distinct repositories; the evaluated cal.diy snapshot is recorded here. Do not assume the licence of one applies to the other or every directory/asset.
21
+
22
+ The local example servers have no model-provider credentials, real booking data or real external side effects. The review example issues random, short-lived, per-review capability tokens held in browser memory and changes fictional process-local text. Future backend adapters and real calendar integrations require separate safety review. Publishing this prepared package or exposing this repository is not authorized by the build task.
23
+
24
+ LangGraph 1.4.18 is a justified optional server peer: it supplies actual checkpointed interrupts and resume instead of a simulated authorization switch. MIT notice is in `licenses/langgraph.txt`; its dependency packages retain their npm notices. Installed source approval/checkpoint paths and transitive manifest/licence boundaries were inspected; npm installation reported zero known vulnerabilities. No LangGraph code or global styles were copied into the renderer. The review example alone changes fictional process-local document fields; it adds no real service or model provider.
25
+
26
+ Generative milestone: `@assistant-ui/react-generative-ui@0.0.22` (MIT) is an optional peer isolated to `/generative`. Its tree renderer and default chart geometry are imported, with SuperXD's closed validated vocabulary and controls. The 22 demonstration trees in `src/workbench/generative/copy.ts` are adapted from `assistant-ui/assistant-ui` `apps/docs/lib/gallery-templates.ts` at `8e411ab2d050280e7a76a5acf3f1961c49169852` (MIT, AgentbaseAI Inc.); source attribution is retained and the complete 2026 licence is retained in `licenses/assistant-ui-generative.txt` (earlier runtime notices remain in `licenses/assistant-ui.txt`). The fixture metadata is not included in the public package source; the separate runnable consumer has its own fictional example. No upstream global styles or component application code were copied.
27
+
28
+ Zod 4.6.5 (MIT) validates bounded JSON before the renderer; `@internationalized/date` 3.12.4 (Apache-2.0) supplies date parsing used by the React Aria controls. Full notices are retained in `licenses/zod.txt` and `licenses/internationalized-date.txt`. This does not claim that browser validation is server authorization.