@flowget/ai-chat 0.1.0 → 0.1.1

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ All notable changes to `@flowget/ai-chat` are documented here. This
4
4
  project adheres to [Semantic Versioning](https://semver.org/) (pre-1.0:
5
5
  minor = breaking).
6
6
 
7
+ ## [0.1.1]
8
+
9
+ ### Added
10
+
11
+ - **`theme?: string` on `<WorkflowChat>`.** Stamps `data-theme={theme}` on the
12
+ chat **panel** portal root (`.fg-aichat-panel`), omitted entirely when unset.
13
+ The panel portals into `document.body` (via assistant-ui's
14
+ `AssistantModalPrimitive` → Radix Popover portal), outside any host wrapper,
15
+ so a scoped token override like `[data-theme="X"] { --flowget-*: … }` (the same
16
+ block a host writes for `<FlowgetBuilder theme="X">`) previously fell back to
17
+ `:root` inside the panel. Passing `theme` re-scopes the block so those tokens
18
+ cascade into the portaled panel. Only the panel portals — the launcher is
19
+ inline and already inherits the host theme, so it is untouched. Plain `string`
20
+ — builder-agnostic, not tied to any named-theme enum. **Additive and
21
+ non-breaking**: omitting `theme` keeps today's `:root`-token behavior
22
+ unchanged. Documented in the README "Theming" section.
23
+
7
24
  ## [0.1.0]
8
25
 
9
26
  Initial release — a builder-agnostic AI workflow-authoring chat.
package/README.md CHANGED
@@ -60,6 +60,7 @@ function BuilderChat() {
60
60
  | `endpoint?` | `string` | endpoint for the default SSE transport (`/api/chat`) |
61
61
  | `heading?` | `string` | panel heading (default `"Workflow AI"`) |
62
62
  | `subtitle?` | `string` | panel subtitle (default `"Draft & edit with a prompt"`) |
63
+ | `theme?` | `string` | stamp `data-theme` on the body-portaled panel so a scoped `[data-theme]` token override reaches it (see [Theming](#theming)) |
63
64
  | `examples?` | `readonly string[]` | empty-state suggestion chips; `[]` hides them |
64
65
  | `layout?` | `WorkflowLayout` | lay a proposal out before apply (default `layoutProposal`) — see below |
65
66
  | `actor?` | `ChatActor` | caller-identity hint — **untrusted on the wire** (see [Security](#security)) |
@@ -212,6 +213,31 @@ Two package-owned knobs control placement (class prefix: `fg-aichat-`):
212
213
  | `--fg-aichat-z` | `200` | stacking order of the launcher + panel |
213
214
  | `--fg-aichat-launcher-offset` | `24px` | gap from the bottom-right corner |
214
215
 
216
+ ### ⚠️ Scoped theme overrides and the body portal
217
+
218
+ The chat **panel portals into `document.body`** — outside your builder wrapper.
219
+ (The launcher is inline and already inherits your theme; only the panel
220
+ portals.) So a token override you *scope* to a selector on that wrapper doesn't
221
+ cascade into the panel. If you theme the builder with a scoped block like
222
+
223
+ ```css
224
+ [data-theme="midnight"] { --flowget-color-accent: #22d3ee; /* … */ }
225
+ ```
226
+
227
+ (the same block `<FlowgetBuilder theme="midnight">` stamps `data-theme` for),
228
+ those tokens fall back to `:root` inside the portaled panel unless you pass the
229
+ matching `theme`:
230
+
231
+ ```tsx
232
+ <WorkflowChat currentGraph={graph} applyGraph={setGraph} theme="midnight" />
233
+ ```
234
+
235
+ `theme` stamps `data-theme="midnight"` on the panel root (`.fg-aichat-panel`), so
236
+ the scoped block now matches and the tokens cascade into the panel. It's a
237
+ **plain string** (builder-agnostic — not tied to any named-theme enum) and is
238
+ **omitted entirely when unset**, so unscoped (`:root`-defined) tokens keep
239
+ working with no change.
240
+
215
241
  ## How it fits together
216
242
 
217
243
  ```
package/dist/react.cjs CHANGED
@@ -479,6 +479,7 @@ function WorkflowChat({
479
479
  endpoint,
480
480
  heading = DEFAULT_HEADING,
481
481
  subtitle = DEFAULT_SUBTITLE,
482
+ theme,
482
483
  examples,
483
484
  layout,
484
485
  actor,
@@ -547,6 +548,7 @@ function WorkflowChat({
547
548
  side: "top",
548
549
  align: "end",
549
550
  sideOffset: 12,
551
+ ...theme !== void 0 ? { "data-theme": theme } : {},
550
552
  children: [
551
553
  /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { heading, subtitle }),
552
554
  /* @__PURE__ */ jsxRuntime.jsx(Thread, { ...examples !== void 0 ? { examples } : {} })
package/dist/react.d.cts CHANGED
@@ -164,6 +164,17 @@ type WorkflowChatProps = {
164
164
  heading?: string;
165
165
  /** Panel subtitle. Default `"Draft & edit with a prompt"`. */
166
166
  subtitle?: string;
167
+ /**
168
+ * Stamps `data-theme={theme}` on the chat **panel** portal root (the
169
+ * `.fg-aichat-panel` node; omitted when unset). The panel portals into
170
+ * `document.body`, outside any host wrapper — so a scoped override like
171
+ * `[data-theme="X"] { --flowget-*: … }` (the same block you wrote for
172
+ * `<FlowgetBuilder theme="X">`) otherwise can't reach it. Set this to the
173
+ * host's active theme so those tokens cascade into the panel. Plain `string`
174
+ * — builder-agnostic; not tied to any named-theme enum. (The launcher renders
175
+ * inline and already inherits the host theme, so it is left untouched.)
176
+ */
177
+ theme?: string;
167
178
  /** Empty-state suggestion chips. Pass `[]` to hide them. */
168
179
  examples?: readonly string[];
169
180
  /**
@@ -182,7 +193,7 @@ type WorkflowChatProps = {
182
193
  /** Opaque continuity payload forwarded to the model with each request. */
183
194
  context?: unknown;
184
195
  };
185
- declare function WorkflowChat({ currentGraph, applyGraph, transport, endpoint, heading, subtitle, examples, layout, actor, context, }: WorkflowChatProps): react.JSX.Element;
196
+ declare function WorkflowChat({ currentGraph, applyGraph, transport, endpoint, heading, subtitle, theme, examples, layout, actor, context, }: WorkflowChatProps): react.JSX.Element;
186
197
 
187
198
  /**
188
199
  * The assistant-ui `ChatModelAdapter` for workflow authoring.
package/dist/react.d.ts CHANGED
@@ -164,6 +164,17 @@ type WorkflowChatProps = {
164
164
  heading?: string;
165
165
  /** Panel subtitle. Default `"Draft & edit with a prompt"`. */
166
166
  subtitle?: string;
167
+ /**
168
+ * Stamps `data-theme={theme}` on the chat **panel** portal root (the
169
+ * `.fg-aichat-panel` node; omitted when unset). The panel portals into
170
+ * `document.body`, outside any host wrapper — so a scoped override like
171
+ * `[data-theme="X"] { --flowget-*: … }` (the same block you wrote for
172
+ * `<FlowgetBuilder theme="X">`) otherwise can't reach it. Set this to the
173
+ * host's active theme so those tokens cascade into the panel. Plain `string`
174
+ * — builder-agnostic; not tied to any named-theme enum. (The launcher renders
175
+ * inline and already inherits the host theme, so it is left untouched.)
176
+ */
177
+ theme?: string;
167
178
  /** Empty-state suggestion chips. Pass `[]` to hide them. */
168
179
  examples?: readonly string[];
169
180
  /**
@@ -182,7 +193,7 @@ type WorkflowChatProps = {
182
193
  /** Opaque continuity payload forwarded to the model with each request. */
183
194
  context?: unknown;
184
195
  };
185
- declare function WorkflowChat({ currentGraph, applyGraph, transport, endpoint, heading, subtitle, examples, layout, actor, context, }: WorkflowChatProps): react.JSX.Element;
196
+ declare function WorkflowChat({ currentGraph, applyGraph, transport, endpoint, heading, subtitle, theme, examples, layout, actor, context, }: WorkflowChatProps): react.JSX.Element;
186
197
 
187
198
  /**
188
199
  * The assistant-ui `ChatModelAdapter` for workflow authoring.
package/dist/react.js CHANGED
@@ -477,6 +477,7 @@ function WorkflowChat({
477
477
  endpoint,
478
478
  heading = DEFAULT_HEADING,
479
479
  subtitle = DEFAULT_SUBTITLE,
480
+ theme,
480
481
  examples,
481
482
  layout,
482
483
  actor,
@@ -545,6 +546,7 @@ function WorkflowChat({
545
546
  side: "top",
546
547
  align: "end",
547
548
  sideOffset: 12,
549
+ ...theme !== void 0 ? { "data-theme": theme } : {},
548
550
  children: [
549
551
  /* @__PURE__ */ jsx(ChatHeader, { heading, subtitle }),
550
552
  /* @__PURE__ */ jsx(Thread, { ...examples !== void 0 ? { examples } : {} })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowget/ai-chat",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Builder-agnostic AI workflow-authoring chat for Flowget — an assistant-ui chat panel (./react) + an SSE BFF helper (./server) over @flowget/ai's streaming author(). Bring your own builder via the currentGraph/applyGraph seam.",
5
5
  "keywords": [
6
6
  "flowget",
@@ -73,10 +73,12 @@
73
73
  "@assistant-ui/react": "^0.14.26",
74
74
  "@eslint/js": "^9.39.4",
75
75
  "@flowget/ai": "^0.1.0",
76
+ "@testing-library/react": "^16.3.0",
76
77
  "@types/node": "^22.19.21",
77
78
  "@types/react": "^19.2.17",
78
79
  "@types/react-dom": "^19.2.3",
79
80
  "eslint": "^9.39.4",
81
+ "happy-dom": "^15.11.7",
80
82
  "react": "^19.2.7",
81
83
  "react-dom": "^19.2.7",
82
84
  "tsup": "^8.5.1",