@ai-matrx/design-system 0.17.3 → 0.18.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 (54) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +1 -0
  3. package/dist/content-transfer/alchemy.svg +1 -0
  4. package/dist/content-transfer/icon.cjs +28 -0
  5. package/dist/content-transfer/icon.cjs.map +1 -0
  6. package/dist/content-transfer/icon.d.cts +4 -0
  7. package/dist/content-transfer/icon.d.ts +4 -0
  8. package/dist/content-transfer/icon.js +8 -0
  9. package/dist/content-transfer/icon.js.map +1 -0
  10. package/dist/content-transfer.cjs +1978 -0
  11. package/dist/content-transfer.cjs.map +1 -0
  12. package/dist/content-transfer.css +382 -0
  13. package/dist/content-transfer.d.cts +208 -0
  14. package/dist/content-transfer.d.ts +208 -0
  15. package/dist/content-transfer.js +1974 -0
  16. package/dist/content-transfer.js.map +1 -0
  17. package/dist/data-table/copy-helpers.d.cts +1 -1
  18. package/dist/data-table/copy-helpers.d.ts +1 -1
  19. package/dist/data-table/copy-types.cjs.map +1 -1
  20. package/dist/data-table/copy-types.d.cts +2 -0
  21. package/dist/data-table/copy-types.d.ts +2 -0
  22. package/dist/data-table/data-row-inspector.cjs +1603 -319
  23. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  24. package/dist/data-table/data-row-inspector.js +1634 -324
  25. package/dist/data-table/data-row-inspector.js.map +1 -1
  26. package/dist/data-table/data-row-window.cjs +1531 -245
  27. package/dist/data-table/data-row-window.cjs.map +1 -1
  28. package/dist/data-table/data-row-window.js +1561 -249
  29. package/dist/data-table/data-row-window.js.map +1 -1
  30. package/dist/data-table/filter-engine.d.cts +1 -1
  31. package/dist/data-table/filter-engine.d.ts +1 -1
  32. package/dist/data-table/index.cjs +2558 -1146
  33. package/dist/data-table/index.cjs.map +1 -1
  34. package/dist/data-table/index.d.cts +2 -2
  35. package/dist/data-table/index.d.ts +2 -2
  36. package/dist/data-table/index.js +2589 -1151
  37. package/dist/data-table/index.js.map +1 -1
  38. package/dist/data-table/infer-filter.d.cts +1 -1
  39. package/dist/data-table/infer-filter.d.ts +1 -1
  40. package/dist/data-table/layered-filters.d.cts +1 -1
  41. package/dist/data-table/layered-filters.d.ts +1 -1
  42. package/dist/data-table/query-control.d.cts +1 -1
  43. package/dist/data-table/query-control.d.ts +1 -1
  44. package/dist/data-table/types.cjs.map +1 -1
  45. package/dist/data-table/types.d.cts +1 -1
  46. package/dist/data-table/types.d.ts +1 -1
  47. package/dist/data-table/url-state.d.cts +1 -1
  48. package/dist/data-table/url-state.d.ts +1 -1
  49. package/dist/data-table/xlsx.d.cts +1 -1
  50. package/dist/data-table/xlsx.d.ts +1 -1
  51. package/dist/styles.css +2 -0
  52. package/dist/{types-pZ95iFk5.d.ts → types-BhSkeZQ_.d.ts} +14 -0
  53. package/dist/{types-4fmLG5AN.d.cts → types-CD4xGL5Z.d.cts} +14 -0
  54. package/package.json +25 -2
@@ -8,9 +8,39 @@ function cn(...inputs) {
8
8
  return twMerge(clsx(inputs));
9
9
  }
10
10
 
11
- // src/data-table/copy.tsx
12
- import { useState as useState4 } from "react";
13
- import { useClipboard } from "@ai-matrx/kit/clipboard";
11
+ // src/content-transfer/matrx-copy.tsx
12
+ import * as React8 from "react";
13
+ import {
14
+ buildAgentPayload,
15
+ createBrowserTransport as createBrowserTransport2,
16
+ directSource as directSource2,
17
+ normalizeTransferJson,
18
+ sealTransferArtifact as sealTransferArtifact2
19
+ } from "@ai-matrx/kit/content-transfer";
20
+
21
+ // src/content-transfer/index.tsx
22
+ import * as React7 from "react";
23
+ import {
24
+ applySectionSelection,
25
+ applyTransferLimits,
26
+ capture,
27
+ collectAllMatching,
28
+ createBrowserTransport,
29
+ createDraft,
30
+ directSource,
31
+ editDraft,
32
+ projectSnapshot,
33
+ readTransferCell,
34
+ reduceJson,
35
+ resetDraft,
36
+ resolveTransferPreferences,
37
+ resolveTransferRegistry,
38
+ sealTransferArtifact,
39
+ serialize,
40
+ serializeMarkdownRich,
41
+ transformRows,
42
+ undoDraft
43
+ } from "@ai-matrx/kit/content-transfer";
14
44
 
15
45
  // src/button.tsx
16
46
  import { Slot } from "@radix-ui/react-slot";
@@ -83,9 +113,11 @@ var Button = React.forwardRef(
83
113
  );
84
114
  Button.displayName = "Button";
85
115
 
86
- // src/popover.tsx
87
- import * as PopoverPrimitive from "@radix-ui/react-popover";
88
- import * as React3 from "react";
116
+ // src/dialog.tsx
117
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
118
+ import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
119
+ import { treeContainsComponent } from "@ai-matrx/kit/react-tree";
120
+ import * as React5 from "react";
89
121
 
90
122
  // src/motion.ts
91
123
  var MOTION_OVERLAY = "matrx-motion-overlay";
@@ -111,72 +143,8 @@ var ALL_MOTION_CLASSES = [
111
143
  MOTION_SPIN
112
144
  ];
113
145
 
114
- // src/portal-container.tsx
115
- import * as React2 from "react";
116
- import { jsx as jsx2 } from "react/jsx-runtime";
117
- var CONTEXT_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.portal-container-context");
118
- var contextRegistry = globalThis;
119
- var PortalContainerContext = contextRegistry[CONTEXT_SLOT] ??= React2.createContext(void 0);
120
- function PortalContainerProvider({
121
- container,
122
- children
123
- }) {
124
- return /* @__PURE__ */ jsx2(PortalContainerContext.Provider, { value: container ?? void 0, children });
125
- }
126
- function usePortalContainer(explicit) {
127
- const injected = React2.useContext(PortalContainerContext);
128
- if (explicit !== void 0) {
129
- return explicit ?? void 0;
130
- }
131
- return injected ?? void 0;
132
- }
133
-
134
- // src/popover.tsx
135
- import { jsx as jsx3 } from "react/jsx-runtime";
136
- var Popover = PopoverPrimitive.Root;
137
- var PopoverTrigger = PopoverPrimitive.Trigger;
138
- var PopoverContent = React3.forwardRef(
139
- ({
140
- className,
141
- align = "center",
142
- sideOffset = 4,
143
- container,
144
- animated = true,
145
- ...props
146
- }, ref) => {
147
- const portalContainer = usePortalContainer(container);
148
- return /* @__PURE__ */ jsx3(PopoverPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx3(
149
- PopoverPrimitive.Content,
150
- {
151
- ref,
152
- align,
153
- sideOffset,
154
- className: cn(
155
- // Cap to the viewport space Radix measured and scroll — a popover taller
156
- // than the screen must never trap the user with unreachable content.
157
- // z must EQUAL the dialog layer (z-[10000]), never exceed it: with equal
158
- // z, DOM portal order decides, so a dialog opened FROM a popover stacks
159
- // above it, and a popover opened from a dialog still stacks above the
160
- // dialog. z-[10001] buried dialogs behind fullscreen popovers.
161
- "z-[10000] w-72 max-h-[var(--radix-popover-content-available-height)] overflow-y-auto overscroll-contain rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
162
- animated && MOTION_POPPER,
163
- className
164
- ),
165
- ...props
166
- }
167
- ) });
168
- }
169
- );
170
- PopoverContent.displayName = PopoverPrimitive.Content.displayName;
171
-
172
- // src/dialog.tsx
173
- import * as DialogPrimitive from "@radix-ui/react-dialog";
174
- import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
175
- import { treeContainsComponent } from "@ai-matrx/kit/react-tree";
176
- import * as React6 from "react";
177
-
178
146
  // src/icons.tsx
179
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
147
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
180
148
  function lucideProps(props) {
181
149
  return {
182
150
  xmlns: "http://www.w3.org/2000/svg",
@@ -192,34 +160,96 @@ function lucideProps(props) {
192
160
  }
193
161
  function XIcon(props) {
194
162
  return /* @__PURE__ */ jsxs("svg", { ...lucideProps(props), children: [
195
- /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18" }),
196
- /* @__PURE__ */ jsx4("path", { d: "m6 6 12 12" })
163
+ /* @__PURE__ */ jsx2("path", { d: "M18 6 6 18" }),
164
+ /* @__PURE__ */ jsx2("path", { d: "m6 6 12 12" })
197
165
  ] });
198
166
  }
167
+ function radixProps(props) {
168
+ return {
169
+ xmlns: "http://www.w3.org/2000/svg",
170
+ viewBox: "0 0 15 15",
171
+ width: 15,
172
+ height: 15,
173
+ fill: "none",
174
+ "aria-hidden": true,
175
+ ...props
176
+ };
177
+ }
178
+ function CheckIcon(props) {
179
+ return /* @__PURE__ */ jsx2("svg", { ...radixProps(props), children: /* @__PURE__ */ jsx2(
180
+ "path",
181
+ {
182
+ d: "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
183
+ fill: "currentColor",
184
+ fillRule: "evenodd",
185
+ clipRule: "evenodd"
186
+ }
187
+ ) });
188
+ }
189
+ function DotFilledIcon(props) {
190
+ return /* @__PURE__ */ jsx2("svg", { ...radixProps(props), children: /* @__PURE__ */ jsx2(
191
+ "path",
192
+ {
193
+ d: "M9.875 7.5C9.875 8.81168 8.81168 9.875 7.5 9.875C6.18832 9.875 5.125 8.81168 5.125 7.5C5.125 6.18832 6.18832 5.125 7.5 5.125C8.81168 5.125 9.875 6.18832 9.875 7.5Z",
194
+ fill: "currentColor"
195
+ }
196
+ ) });
197
+ }
198
+ function RadixChevronRightIcon(props) {
199
+ return /* @__PURE__ */ jsx2("svg", { ...radixProps(props), children: /* @__PURE__ */ jsx2(
200
+ "path",
201
+ {
202
+ d: "M6.1584 3.13508C6.35985 2.94621 6.67627 2.95642 6.86514 3.15788L10.6151 7.15788C10.7954 7.3502 10.7954 7.64949 10.6151 7.84182L6.86514 11.8418C6.67627 12.0433 6.35985 12.0535 6.1584 11.8646C5.95694 11.6757 5.94673 11.3593 6.1356 11.1579L9.565 7.49985L6.1356 3.84182C5.94673 3.64036 5.95694 3.32394 6.1584 3.13508Z",
203
+ fill: "currentColor",
204
+ fillRule: "evenodd",
205
+ clipRule: "evenodd"
206
+ }
207
+ ) });
208
+ }
209
+
210
+ // src/portal-container.tsx
211
+ import * as React2 from "react";
212
+ import { jsx as jsx3 } from "react/jsx-runtime";
213
+ var CONTEXT_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.portal-container-context");
214
+ var contextRegistry = globalThis;
215
+ var PortalContainerContext = contextRegistry[CONTEXT_SLOT] ??= React2.createContext(void 0);
216
+ function PortalContainerProvider({
217
+ container,
218
+ children
219
+ }) {
220
+ return /* @__PURE__ */ jsx3(PortalContainerContext.Provider, { value: container ?? void 0, children });
221
+ }
222
+ function usePortalContainer(explicit) {
223
+ const injected = React2.useContext(PortalContainerContext);
224
+ if (explicit !== void 0) {
225
+ return explicit ?? void 0;
226
+ }
227
+ return injected ?? void 0;
228
+ }
199
229
 
200
230
  // src/radix-dialog-modal-context.tsx
201
- import * as React4 from "react";
202
- import { jsx as jsx5 } from "react/jsx-runtime";
231
+ import * as React3 from "react";
232
+ import { jsx as jsx4 } from "react/jsx-runtime";
203
233
  var CONTEXT_SLOT2 = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.dialog-modal-context");
204
234
  var contextRegistry2 = globalThis;
205
- var RadixDialogModalContext = contextRegistry2[CONTEXT_SLOT2] ??= React4.createContext(true);
235
+ var RadixDialogModalContext = contextRegistry2[CONTEXT_SLOT2] ??= React3.createContext(true);
206
236
  function RadixDialogModalProvider({
207
237
  children,
208
238
  modal
209
239
  }) {
210
- return /* @__PURE__ */ jsx5(RadixDialogModalContext.Provider, { value: modal, children });
240
+ return /* @__PURE__ */ jsx4(RadixDialogModalContext.Provider, { value: modal, children });
211
241
  }
212
242
  function useRadixDialogModal() {
213
- return React4.useContext(RadixDialogModalContext);
243
+ return React3.useContext(RadixDialogModalContext);
214
244
  }
215
245
 
216
246
  // src/use-is-mobile.ts
217
- import * as React5 from "react";
247
+ import * as React4 from "react";
218
248
  var MOBILE_BREAKPOINT = 768;
219
249
  function useIsMobile() {
220
- const [isMobile, setIsMobile] = React5.useState(false);
221
- const [hasMounted, setHasMounted] = React5.useState(false);
222
- React5.useEffect(() => {
250
+ const [isMobile, setIsMobile] = React4.useState(false);
251
+ const [hasMounted, setHasMounted] = React4.useState(false);
252
+ React4.useEffect(() => {
223
253
  setHasMounted(true);
224
254
  const onChange = () => {
225
255
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
@@ -239,13 +269,13 @@ function useIsMobile() {
239
269
  }
240
270
 
241
271
  // src/dialog.tsx
242
- import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
272
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
243
273
  var Dialog = ({
244
274
  children,
245
275
  ...props
246
276
  }) => {
247
277
  const modal = props.modal ?? true;
248
- return /* @__PURE__ */ jsx6(RadixDialogModalProvider, { modal, children: /* @__PURE__ */ jsx6(DialogPrimitive.Root, { ...props, modal, children }) });
278
+ return /* @__PURE__ */ jsx5(RadixDialogModalProvider, { modal, children: /* @__PURE__ */ jsx5(DialogPrimitive.Root, { ...props, modal, children }) });
249
279
  };
250
280
  Dialog.displayName = "Dialog";
251
281
  var DialogPortal = ({
@@ -253,13 +283,13 @@ var DialogPortal = ({
253
283
  ...props
254
284
  }) => {
255
285
  const resolved = usePortalContainer(container);
256
- return /* @__PURE__ */ jsx6(DialogPrimitive.Portal, { container: resolved ?? null, ...props });
286
+ return /* @__PURE__ */ jsx5(DialogPrimitive.Portal, { container: resolved ?? null, ...props });
257
287
  };
258
288
  DialogPortal.displayName = "DialogPortal";
259
289
  var CONTEXT_SLOT3 = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.dialog-container-context");
260
290
  var contextRegistry3 = globalThis;
261
- var DialogContainerContext = contextRegistry3[CONTEXT_SLOT3] ??= React6.createContext(null);
262
- var DialogOverlay = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
291
+ var DialogContainerContext = contextRegistry3[CONTEXT_SLOT3] ??= React5.createContext(null);
292
+ var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
263
293
  DialogPrimitive.Overlay,
264
294
  {
265
295
  ref,
@@ -275,9 +305,9 @@ var DialogOverlay = React6.forwardRef(({ className, ...props }, ref) => /* @__PU
275
305
  }
276
306
  ));
277
307
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
278
- var DialogContentPrimitive = React6.forwardRef((props, ref) => {
308
+ var DialogContentPrimitive = React5.forwardRef((props, ref) => {
279
309
  const isModal = useRadixDialogModal();
280
- return /* @__PURE__ */ jsx6(
310
+ return /* @__PURE__ */ jsx5(
281
311
  DialogPrimitive.Content,
282
312
  {
283
313
  ...props,
@@ -290,7 +320,7 @@ DialogContentPrimitive.displayName = "DialogContentPrimitive";
290
320
  var DIALOG_DESKTOP_CLASSES = "matrx-dialog-card fixed inset-0 z-[10000] m-auto grid h-fit min-w-0 w-full max-w-lg gap-4 max-h-[85dvh] overflow-y-auto overscroll-contain [--dialog-pad:1.5rem] overflow-x-clip border bg-background p-6 shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full sm:rounded-lg";
291
321
  var DIALOG_MOBILE_SHEET_CLASSES = "matrx-mobile-sheet matrx-dialog-card fixed inset-x-0 bottom-0 left-0 right-0 top-auto z-[10000] flex min-w-0 flex-col w-full max-w-full max-h-[90dvh] gap-4 [--dialog-pad:1rem] overflow-x-clip border-t bg-background p-4 pb-safe shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full rounded-t-2xl rounded-b-none overflow-y-auto overscroll-contain";
292
322
  var DIALOG_MOBILE_SHEET_OVERRIDE = "inset-x-0 bottom-0 left-0 right-0 top-auto translate-none w-full max-w-full max-h-[90dvh] rounded-b-none rounded-t-2xl overflow-y-auto";
293
- var DialogContent = React6.forwardRef(
323
+ var DialogContent = React5.forwardRef(
294
324
  ({
295
325
  className,
296
326
  children,
@@ -304,10 +334,10 @@ var DialogContent = React6.forwardRef(
304
334
  const isModal = useRadixDialogModal();
305
335
  const injectedContainer = usePortalContainer(container);
306
336
  const asSheet = mobileSheet && isMobile;
307
- const [containerEl, setContainerEl] = React6.useState(
337
+ const [containerEl, setContainerEl] = React5.useState(
308
338
  null
309
339
  );
310
- const mergedRef = React6.useCallback(
340
+ const mergedRef = React5.useCallback(
311
341
  (node) => {
312
342
  setContainerEl(node);
313
343
  if (typeof ref === "function") ref(node);
@@ -319,7 +349,7 @@ var DialogContent = React6.forwardRef(
319
349
  const hasTitle = treeContainsComponent(children, DialogTitle) || treeContainsComponent(children, DialogPrimitive.Title);
320
350
  const hasDescription = treeContainsComponent(children, DialogDescription) || treeContainsComponent(children, DialogPrimitive.Description);
321
351
  return /* @__PURE__ */ jsxs2(DialogPortal, { container, children: [
322
- isModal ? /* @__PURE__ */ jsx6(DialogOverlay, {}) : null,
352
+ isModal ? /* @__PURE__ */ jsx5(DialogOverlay, {}) : null,
323
353
  /* @__PURE__ */ jsxs2(
324
354
  DialogContentPrimitive,
325
355
  {
@@ -339,8 +369,8 @@ var DialogContent = React6.forwardRef(
339
369
  ...hasDescription ? {} : { "aria-describedby": void 0 },
340
370
  ...props,
341
371
  children: [
342
- hasTitle ? null : /* @__PURE__ */ jsx6(VisuallyHidden.Root, { children: /* @__PURE__ */ jsx6(DialogPrimitive.Title, { children: "Dialog" }) }),
343
- /* @__PURE__ */ jsx6(DialogContainerContext.Provider, { value: containerEl, children: /* @__PURE__ */ jsx6(
372
+ hasTitle ? null : /* @__PURE__ */ jsx5(VisuallyHidden.Root, { children: /* @__PURE__ */ jsx5(DialogPrimitive.Title, { children: "Dialog" }) }),
373
+ /* @__PURE__ */ jsx5(DialogContainerContext.Provider, { value: containerEl, children: /* @__PURE__ */ jsx5(
344
374
  PortalContainerProvider,
345
375
  {
346
376
  container: containerEl ?? injectedContainer ?? null,
@@ -354,8 +384,8 @@ var DialogContent = React6.forwardRef(
354
384
  "aria-label": "Close",
355
385
  className: "absolute right-2 top-4 flex h-11 w-11 items-center justify-center rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground sm:right-4 lg:h-10 lg:w-10",
356
386
  children: [
357
- /* @__PURE__ */ jsx6(XIcon, { className: "h-4 w-4" }),
358
- /* @__PURE__ */ jsx6("span", { className: "sr-only", children: "Close" })
387
+ /* @__PURE__ */ jsx5(XIcon, { className: "h-4 w-4" }),
388
+ /* @__PURE__ */ jsx5("span", { className: "sr-only", children: "Close" })
359
389
  ]
360
390
  }
361
391
  ) : null
@@ -369,7 +399,7 @@ DialogContent.displayName = DialogPrimitive.Content.displayName;
369
399
  var DialogHeader = ({
370
400
  className,
371
401
  ...props
372
- }) => /* @__PURE__ */ jsx6(
402
+ }) => /* @__PURE__ */ jsx5(
373
403
  "div",
374
404
  {
375
405
  "data-slot": "dialog-header",
@@ -386,7 +416,7 @@ DialogHeader.displayName = "DialogHeader";
386
416
  var DialogFooter = ({
387
417
  className,
388
418
  ...props
389
- }) => /* @__PURE__ */ jsx6(
419
+ }) => /* @__PURE__ */ jsx5(
390
420
  "div",
391
421
  {
392
422
  "data-slot": "dialog-footer",
@@ -418,7 +448,7 @@ var DialogFooter = ({
418
448
  }
419
449
  );
420
450
  DialogFooter.displayName = "DialogFooter";
421
- var DialogTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
451
+ var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
422
452
  DialogPrimitive.Title,
423
453
  {
424
454
  ref,
@@ -428,7 +458,7 @@ var DialogTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE
428
458
  }
429
459
  ));
430
460
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
431
- var DialogDescription = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
461
+ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
432
462
  DialogPrimitive.Description,
433
463
  {
434
464
  ref,
@@ -439,223 +469,1503 @@ var DialogDescription = React6.forwardRef(({ className, ...props }, ref) => /* @
439
469
  ));
440
470
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
441
471
 
442
- // src/data-table/icons.tsx
443
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
444
- function Icon({ children, ...props }) {
445
- return /* @__PURE__ */ jsx7("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", ...props, children });
446
- }
447
- var Check = (p) => /* @__PURE__ */ jsx7(Icon, { ...p, children: /* @__PURE__ */ jsx7("path", { d: "m5 12 4 4L19 6" }) });
448
- var SlidersHorizontal = (p) => /* @__PURE__ */ jsx7(Icon, { ...p, children: /* @__PURE__ */ jsx7("path", { d: "M4 7h16M4 17h16M9 7v0M15 17v0" }) });
449
- var PanelRight = (p) => /* @__PURE__ */ jsxs3(Icon, { ...p, children: [
450
- /* @__PURE__ */ jsx7("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }),
451
- /* @__PURE__ */ jsx7("path", { d: "M15 4v16" })
452
- ] });
453
- var ExternalLink = (p) => /* @__PURE__ */ jsx7(Icon, { ...p, children: /* @__PURE__ */ jsx7("path", { d: "M14 4h6v6M20 4l-9 9M19 13v6H5V5h6" }) });
454
- var Copy = (p) => /* @__PURE__ */ jsxs3(Icon, { ...p, children: [
455
- /* @__PURE__ */ jsx7("rect", { x: "9", y: "9", width: "11", height: "11", rx: "2" }),
456
- /* @__PURE__ */ jsx7("path", { d: "M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3" })
457
- ] });
458
- var Lightbulb = (p) => /* @__PURE__ */ jsx7(Icon, { ...p, children: /* @__PURE__ */ jsx7("path", { d: "M9 18h6M10 22h4M8 14a6 6 0 1 1 8 0c-1 1-1 2-1 3H9c0-1 0-2-1-3z" }) });
459
- var ShieldOff = (p) => /* @__PURE__ */ jsx7(Icon, { ...p, children: /* @__PURE__ */ jsx7("path", { d: "m3 3 18 18M12 3l7 3v5c0 4-3 7-7 9-4-2-7-5-7-9V6l4-2" }) });
472
+ // src/dropdown-menu.tsx
473
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
474
+ import * as React6 from "react";
475
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
476
+ var DropdownMenu = DropdownMenuPrimitive.Root;
477
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
478
+ var MENU_SURFACE_CLASS = "z-[10001] min-w-[8rem] max-h-[var(--radix-dropdown-menu-content-available-height)] overflow-y-auto overflow-x-hidden overscroll-contain rounded-md border bg-popover p-1 text-popover-foreground";
479
+ var MENU_ITEM_CLASS = "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
480
+ var MENU_INDICATOR_ITEM_CLASS = "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
481
+ var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs3(
482
+ DropdownMenuPrimitive.SubTrigger,
483
+ {
484
+ ref,
485
+ "data-slot": "dropdown-menu-sub-trigger",
486
+ className: cn(
487
+ "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
488
+ inset && "pl-8",
489
+ className
490
+ ),
491
+ ...props,
492
+ children: [
493
+ children,
494
+ /* @__PURE__ */ jsx6(RadixChevronRightIcon, { className: "ml-auto h-4 w-4" })
495
+ ]
496
+ }
497
+ ));
498
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
499
+ var DropdownMenuSubContent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
500
+ DropdownMenuPrimitive.SubContent,
501
+ {
502
+ ref,
503
+ "data-slot": "dropdown-menu-sub-content",
504
+ className: cn(MENU_SURFACE_CLASS, "shadow-lg", MOTION_POPPER, className),
505
+ ...props
506
+ }
507
+ ));
508
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
509
+ var DropdownMenuContent = React6.forwardRef(({ className, sideOffset = 4, container, ...props }, ref) => {
510
+ const portalContainer = usePortalContainer(container);
511
+ return /* @__PURE__ */ jsx6(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx6(
512
+ DropdownMenuPrimitive.Content,
513
+ {
514
+ ref,
515
+ "data-slot": "dropdown-menu-content",
516
+ sideOffset,
517
+ className: cn(
518
+ MENU_SURFACE_CLASS,
519
+ "shadow-md",
520
+ MOTION_POPPER,
521
+ className
522
+ ),
523
+ ...props
524
+ }
525
+ ) });
526
+ });
527
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
528
+ var DropdownMenuItem = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx6(
529
+ DropdownMenuPrimitive.Item,
530
+ {
531
+ ref,
532
+ "data-slot": "dropdown-menu-item",
533
+ className: cn(MENU_ITEM_CLASS, inset && "pl-8", className),
534
+ ...props
535
+ }
536
+ ));
537
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
538
+ var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(
539
+ DropdownMenuPrimitive.CheckboxItem,
540
+ {
541
+ ref,
542
+ "data-slot": "dropdown-menu-checkbox-item",
543
+ className: cn(MENU_INDICATOR_ITEM_CLASS, className),
544
+ ...props,
545
+ children: [
546
+ /* @__PURE__ */ jsx6("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx6(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx6(CheckIcon, { className: "h-4 w-4" }) }) }),
547
+ children
548
+ ]
549
+ }
550
+ ));
551
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
552
+ var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(
553
+ DropdownMenuPrimitive.RadioItem,
554
+ {
555
+ ref,
556
+ "data-slot": "dropdown-menu-radio-item",
557
+ className: cn(MENU_INDICATOR_ITEM_CLASS, className),
558
+ ...props,
559
+ children: [
560
+ /* @__PURE__ */ jsx6("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx6(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx6(DotFilledIcon, { className: "h-4 w-4 fill-current" }) }) }),
561
+ children
562
+ ]
563
+ }
564
+ ));
565
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
566
+ var DropdownMenuLabel = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx6(
567
+ DropdownMenuPrimitive.Label,
568
+ {
569
+ ref,
570
+ "data-slot": "dropdown-menu-label",
571
+ className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
572
+ ...props
573
+ }
574
+ ));
575
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
576
+ var DropdownMenuSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
577
+ DropdownMenuPrimitive.Separator,
578
+ {
579
+ ref,
580
+ "data-slot": "dropdown-menu-separator",
581
+ className: cn("-mx-1 my-1 h-px bg-muted", className),
582
+ ...props
583
+ }
584
+ ));
585
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
586
+ var DropdownMenuShortcut = ({
587
+ className,
588
+ ...props
589
+ }) => /* @__PURE__ */ jsx6(
590
+ "span",
591
+ {
592
+ "data-slot": "dropdown-menu-shortcut",
593
+ className: cn("ml-auto text-xs tracking-widest opacity-60", className),
594
+ ...props
595
+ }
596
+ );
597
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
460
598
 
461
- // src/data-table/host.tsx
462
- import { createContext as createContext4, useContext as useContext4 } from "react";
463
- import { jsx as jsx8 } from "react/jsx-runtime";
464
- var HOST_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.table-host-context");
465
- var hostRegistry = globalThis;
466
- var HostContext = hostRegistry[HOST_SLOT] ??= createContext4({});
467
- function useMatrxDataTableHost() {
468
- return useContext4(HostContext);
599
+ // src/content-transfer/index.tsx
600
+ import { Fragment, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
601
+ function AlchemyGlyph(props) {
602
+ return /* @__PURE__ */ jsxs4("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: [
603
+ /* @__PURE__ */ jsx7("path", { d: "M4.5 5.5h8v11h-8z" }),
604
+ /* @__PURE__ */ jsx7("path", { d: "M8.5 9.5h8v9h-8z" }),
605
+ /* @__PURE__ */ jsx7("path", { d: "m18.5 3 .65 1.85L21 5.5l-1.85.65L18.5 8l-.65-1.85L16 5.5l1.85-.65z" })
606
+ ] });
469
607
  }
470
-
471
- // src/data-table/useTableNotice.tsx
472
- import { useState as useState3 } from "react";
473
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
474
- function useTableNotice() {
475
- const host = useMatrxDataTableHost();
476
- const [message, setMessage] = useState3(null);
477
- const notify = {
478
- success(text) {
479
- if (host.notify) host.notify.success(text);
480
- else setMessage({ text, error: false });
481
- },
482
- error(text) {
483
- if (host.notify) host.notify.error(text);
484
- else setMessage({ text, error: true });
608
+ var CapabilityContext = React7.createContext({});
609
+ var useContentTransferCapabilities = () => React7.useContext(CapabilityContext);
610
+ var SurfaceContext = React7.createContext(null);
611
+ function MenuPresentation({ label, hint, icon: Icon2 }) {
612
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
613
+ Icon2 ? /* @__PURE__ */ jsx7(Icon2, { className: "matrx-alchemy-menu-icon" }) : null,
614
+ /* @__PURE__ */ jsxs4("span", { children: [
615
+ label,
616
+ hint ? /* @__PURE__ */ jsx7("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
617
+ ] })
618
+ ] });
619
+ }
620
+ var LABEL = { plain: "Plain text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact JSON", csv: "CSV", tsv: "Google Sheets", xlsx: "Excel workbook" };
621
+ var BUILT_INS = Object.freeze(Object.keys(LABEL).map((id) => ({ id })));
622
+ var COPIES = ["plain", "markdown", "html", "json", "compact-json", "csv", "tsv"];
623
+ var DOWNLOADS = [...COPIES, "xlsx"];
624
+ var EMPTY_VARIANTS = [];
625
+ var SCOPE_LABEL = { target: "This content", row: "This row", selected: "Selected rows", view: "Current view", loaded: "Loaded rows", "all-matching": "All matching rows" };
626
+ var filenameFor = (label) => label.toLocaleLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "") || "export";
627
+ var estimateTokens = (text) => Math.ceil(text.length / 4);
628
+ var errorMessage = (error, fallback) => error instanceof Error ? error.message : fallback;
629
+ var isAbort = (error) => error instanceof DOMException && error.name === "AbortError";
630
+ var supportsBuiltIn = (format, payload) => !["csv", "tsv", "xlsx"].includes(format) || payload.kind === "rows";
631
+ var outcomeMessage = (result) => {
632
+ if (result.status === "success") {
633
+ const success = result;
634
+ return success.delivered === "action" ? success.message ?? "Action completed" : success.delivered === "download-started" ? "Download started" : success.message ?? "Copied";
635
+ }
636
+ return result.status === "degraded" ? `Copied as plain text: ${result.reason}` : result.status === "cancelled" ? "Cancelled" : result.message;
637
+ };
638
+ var materialIds = /* @__PURE__ */ new WeakMap();
639
+ var nextMaterialId = 0;
640
+ function materialIdentity(material) {
641
+ if (!material) return "missing";
642
+ if ("instanceId" in material) return `surface:${material.instanceId}`;
643
+ if ("id" in material) return `source:${material.id}`;
644
+ let id = materialIds.get(material);
645
+ if (id === void 0) {
646
+ id = ++nextMaterialId;
647
+ materialIds.set(material, id);
648
+ }
649
+ return `payload:${id}`;
650
+ }
651
+ function useFence() {
652
+ const mounted = React7.useRef(true);
653
+ const nextId = React7.useRef(0);
654
+ const active = React7.useRef(/* @__PURE__ */ new Set());
655
+ React7.useEffect(() => {
656
+ mounted.current = true;
657
+ return () => {
658
+ mounted.current = false;
659
+ nextId.current += 1;
660
+ active.current.forEach((c) => c.abort());
661
+ active.current.clear();
662
+ };
663
+ }, []);
664
+ const begin = React7.useCallback(() => {
665
+ const controller = new AbortController();
666
+ active.current.add(controller);
667
+ return { controller, id: ++nextId.current };
668
+ }, []);
669
+ const finish = React7.useCallback((controller) => active.current.delete(controller), []);
670
+ const valid = React7.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
671
+ const abortAll = React7.useCallback(() => {
672
+ nextId.current += 1;
673
+ active.current.forEach((c) => c.abort());
674
+ active.current.clear();
675
+ }, []);
676
+ return { begin, finish, valid, abortAll };
677
+ }
678
+ async function xlsxArtifact(draft, label) {
679
+ if (draft.payload.kind !== "rows") throw new Error("Excel workbook export requires tabular content.");
680
+ const XLSX = await import("xlsx");
681
+ const columns = draft.payload.columns.filter((c) => c.visible && c.exportable !== false && c.classification !== "secret" && c.classification !== "credential");
682
+ const cells = draft.payload.rows.map((row) => columns.map((column) => {
683
+ const value = readTransferCell(row, column);
684
+ return value === null || ["string", "number", "boolean"].includes(typeof value) ? value : value === void 0 ? "" : JSON.stringify(value);
685
+ }));
686
+ const sheet = XLSX.utils.aoa_to_sheet([columns.map((c) => c.label), ...cells]);
687
+ const book = XLSX.utils.book_new();
688
+ XLSX.utils.book_append_sheet(book, sheet, label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data");
689
+ const written = XLSX.write(book, { type: "array", bookType: "xlsx", compression: true });
690
+ return sealTransferArtifact({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "xlsx", plainText: serialize(draft, "tsv", { spreadsheetSafe: true }).plainText, file: { filename: `${filenameFor(label)}.xlsx`, mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", bytes: written instanceof Uint8Array ? written : new Uint8Array(written) }, omissions: [...draft.omissions] });
691
+ }
692
+ async function buildArtifact(draft, format, label) {
693
+ if (!supportsBuiltIn(format, draft.payload)) throw new Error(`${LABEL[format]} is available for tabular content only.`);
694
+ if (format === "xlsx") return xlsxArtifact(draft, label);
695
+ if (format === "html" && draft.payload.kind === "markdown") return serializeMarkdownRich(draft, `${filenameFor(label)}.html`);
696
+ const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
697
+ return serialize(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
698
+ }
699
+ function ContentTransferMenu({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
700
+ const triggerRef = React7.useRef(null);
701
+ const inherited = React7.useContext(CapabilityContext);
702
+ const nearestSurface = React7.useContext(SurfaceContext);
703
+ const fence = useFence();
704
+ const [menuCapture, setMenuCapture] = React7.useState(null);
705
+ const [menuStatus, setMenuStatus] = React7.useState("idle");
706
+ const [workspaces, setWorkspaces] = React7.useState({});
707
+ const [workspaceKey, setWorkspaceKey] = React7.useState(null);
708
+ const [workspaceOpen, setWorkspaceOpen] = React7.useState(false);
709
+ const workspaceCaptures = React7.useRef(/* @__PURE__ */ new Map());
710
+ const externalWorkspaceKeys = React7.useRef(/* @__PURE__ */ new Set());
711
+ const [notice, setNotice] = React7.useState(null);
712
+ const scopes = React7.useMemo(() => table?.availableScopes ?? ["target"], [table]);
713
+ const initialScope = table?.initialScope ?? "target";
714
+ if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
715
+ const primary = surface ?? source ?? nearestSurface;
716
+ const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
717
+ const primaryWorkspaceKey = `primary:${materialIdentity(primary)}`;
718
+ const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
719
+ const variantWorkspaceKeys = React7.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
720
+ const transport = local?.transport ?? inherited.transport ?? createBrowserTransport();
721
+ const ai = local?.ai ?? inherited.ai;
722
+ const providerPreferences = React7.useMemo(() => resolveTransferPreferences(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
723
+ const adapters = React7.useMemo(() => resolveTransferRegistry(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
724
+ const registeredActions = React7.useMemo(() => resolveTransferRegistry(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
725
+ React7.useMemo(() => resolveTransferRegistry(variants), [variants]);
726
+ const report = React7.useCallback((result) => {
727
+ inherited.onOutcome?.(result);
728
+ local?.onOutcome?.(result);
729
+ setNotice(outcomeMessage(result));
730
+ }, [inherited, local]);
731
+ React7.useEffect(() => {
732
+ const valid = /* @__PURE__ */ new Set([primaryWorkspaceKey, ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
733
+ setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
734
+ for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
735
+ if (workspaceKey && !valid.has(workspaceKey)) {
736
+ setWorkspaceKey(null);
737
+ setWorkspaceOpen(false);
485
738
  }
739
+ }, [nearestWorkspaceKey, primaryWorkspaceKey, variantWorkspaceKeys, workspaceKey]);
740
+ const captureOne = React7.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
741
+ if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
742
+ let sourceMaterial;
743
+ if ("instanceId" in material) {
744
+ if (!material.isMounted()) throw new Error("The requested transfer surface is no longer mounted.");
745
+ const captured = await material.capture(signal);
746
+ sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
747
+ } else if ("kind" in material) {
748
+ sourceMaterial = applyMenuProjection ? { id: "direct", label: sourceLabel, capture: async () => directSource(material, { label: sourceLabel, ...projection ? { projection } : {}, ...sections ? { sections } : {} }) } : material;
749
+ } else if (applyMenuProjection && (projection || sections)) {
750
+ sourceMaterial = {
751
+ id: material.id,
752
+ label: material.label,
753
+ capture: async (request) => {
754
+ const captured = await material.capture(request);
755
+ return {
756
+ ...captured,
757
+ projection: { rules: [...captured.projection.rules, ...projection?.rules ?? []] },
758
+ snapshot: { ...captured.snapshot, ...sections ? { sections } : {} }
759
+ };
760
+ }
761
+ };
762
+ } else {
763
+ sourceMaterial = material;
764
+ }
765
+ const raw = "kind" in sourceMaterial ? directSource(sourceMaterial) : await sourceMaterial.capture({ scope, signal });
766
+ const constrained = resolveTransferPreferences(providerPreferences, preferences, raw.snapshot.limits);
767
+ const result = await capture({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
768
+ if (scope !== "all-matching" || !collectPages) return result;
769
+ if (!result.allMatching) throw new Error("This source cannot provide a stable all-matching export.");
770
+ const collected = await collectAllMatching(result.allMatching, signal);
771
+ if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
772
+ return { snapshot: projectSnapshot({ ...result.snapshot, payload: { kind: "rows", rows: collected.rows, columns: result.snapshot.payload.columns }, coverage: collected.coverage, omissions: [...collected.omissions] }, { rules: [] }), allMatching: result.allMatching, ...collected.error ? { collectionError: collected.error.message } : {} };
773
+ }, [preferences, projection, providerPreferences, sections, sourceLabel]);
774
+ const capturePrimary = React7.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
775
+ workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
776
+ if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
777
+ for (const variant of variants) {
778
+ const key = variantWorkspaceKeys.get(variant.id);
779
+ workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
780
+ }
781
+ const preflight = React7.useCallback(async () => {
782
+ const { controller, id } = fence.begin();
783
+ setMenuCapture(null);
784
+ setMenuStatus("loading");
785
+ try {
786
+ const result = await captureOne(primary, initialScope, controller.signal, true, false);
787
+ if (fence.valid(id, controller)) {
788
+ setMenuCapture(result);
789
+ setMenuStatus("idle");
790
+ }
791
+ } catch (error) {
792
+ if (fence.valid(id, controller)) {
793
+ setMenuCapture(null);
794
+ setMenuStatus(errorMessage(error, "Could not inspect content"));
795
+ }
796
+ } finally {
797
+ fence.finish(controller);
798
+ }
799
+ }, [captureOne, fence, initialScope, primary]);
800
+ const transfer = React7.useCallback(async (format, download, alternate) => {
801
+ const { controller, id } = fence.begin();
802
+ try {
803
+ const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
804
+ const result = await (explicit ? captureOne(explicit, initialScope, controller.signal, true) : capturePrimary(initialScope, controller.signal));
805
+ if (result.collectionError) throw new Error(`The complete source could not be collected: ${result.collectionError}`);
806
+ if (result.snapshot.coverage.status !== "complete" || result.snapshot.omissions.length > 0) {
807
+ const reason = result.snapshot.coverage.reason ?? `${result.snapshot.omissions.length} omission${result.snapshot.omissions.length === 1 ? "" : "s"}`;
808
+ throw new Error(`Quick transfer is partial (${reason}). Open Prepare for AI to review it before delivery.`);
809
+ }
810
+ const resolved = resolveTransferPreferences(providerPreferences, preferences, result.snapshot.limits);
811
+ const draft = applyTransferLimits(createDraft(result.snapshot), resolved.limits);
812
+ const revision = draft.revision;
813
+ if (draft.omissions.length > result.snapshot.omissions.length) throw new Error("Quick transfer requires content reductions. Open Prepare for AI to review them before delivery.");
814
+ const artifact = typeof format === "string" ? await buildArtifact(draft, format, result.snapshot.label) : await format.build(draft, controller.signal);
815
+ if (artifact.omissions.length > draft.omissions.length) throw new Error(`Quick format requires ${artifact.omissions.length - draft.omissions.length} adjustment${artifact.omissions.length - draft.omissions.length === 1 ? "" : "s"}. Open Prepare for AI to review before delivery.`);
816
+ if (!fence.valid(id, controller) || artifact.snapshotId !== result.snapshot.id || artifact.draftRevision !== revision) return;
817
+ const outcome = await transport[download ? "download" : "copy"](artifact, controller.signal);
818
+ if (fence.valid(id, controller)) report(outcome.status === "success" && alternate?.successMessage ? { ...outcome, message: alternate.successMessage } : outcome);
819
+ } catch (error) {
820
+ if (fence.valid(id, controller)) report({ status: "error", code: "prepare-failed", message: errorMessage(error, "Preparation failed"), retryable: true });
821
+ } finally {
822
+ fence.finish(controller);
823
+ }
824
+ }, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
825
+ const openWorkspace = React7.useCallback(async (key = primaryWorkspaceKey, variant) => {
826
+ const variantMaterial = variant && "kind" in variant.source ? { id: `variant:${key}`, label: variant.label, capture: async () => directSource(variant.source, { label: variant.label }) } : variant?.source;
827
+ const captureWorkspace = variantMaterial ? (scope, signal) => captureOne(variantMaterial, scope, signal, true) : capturePrimary;
828
+ workspaceCaptures.current.set(key, captureWorkspace);
829
+ if (workspaces[key]) {
830
+ setWorkspaceKey(key);
831
+ setWorkspaceOpen(true);
832
+ return;
833
+ }
834
+ const { controller, id } = fence.begin();
835
+ try {
836
+ const result = await captureWorkspace(initialScope, controller.signal);
837
+ if (!fence.valid(id, controller)) return;
838
+ const resolved = resolveTransferPreferences(providerPreferences, preferences, result.snapshot.limits);
839
+ const original = createDraft(result.snapshot);
840
+ const base = { ...result, key, original, draft: original, scope: initialScope, preferences: resolved, ...result.collectionError ? { error: result.collectionError } : {} };
841
+ setWorkspaces((current) => ({ ...current, [key]: { ...base, draft: rebuild(base, initialControls(base)) } }));
842
+ setWorkspaceKey(key);
843
+ setWorkspaceOpen(true);
844
+ } catch (error) {
845
+ if (fence.valid(id, controller)) setNotice(errorMessage(error, "Could not capture content"));
846
+ } finally {
847
+ fence.finish(controller);
848
+ }
849
+ }, [captureOne, capturePrimary, fence, initialScope, preferences, primaryWorkspaceKey, providerPreferences, workspaces]);
850
+ React7.useImperativeHandle(controllerRef, () => ({
851
+ focusTrigger: () => triggerRef.current?.focus(),
852
+ prepare: async (requestedSource, options) => {
853
+ const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
854
+ const requestedKey = `controller:${options?.id ?? "source"}:${materialIdentity(requestedSource)}`;
855
+ externalWorkspaceKeys.current.add(requestedKey);
856
+ await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
857
+ }
858
+ }), [openWorkspace]);
859
+ const runAction = React7.useCallback(async (action) => {
860
+ const { controller, id } = fence.begin();
861
+ try {
862
+ const actionSource = action.source;
863
+ const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
864
+ const resolved = resolveTransferPreferences(providerPreferences, preferences, snapshot.limits);
865
+ const draft = applyTransferLimits(createDraft(snapshot), resolved.limits);
866
+ if (!action.supports(snapshot)) throw new Error(`${action.label} is unavailable for this content.`);
867
+ const result = await action.run({ snapshot, draft, signal: controller.signal });
868
+ if (fence.valid(id, controller) && draft.snapshotId === snapshot.id) report(result);
869
+ } catch (error) {
870
+ if (fence.valid(id, controller)) report({ status: "error", code: "action-failed", message: errorMessage(error, "Action failed"), retryable: true });
871
+ } finally {
872
+ fence.finish(controller);
873
+ }
874
+ }, [captureOne, capturePrimary, fence, initialScope, preferences, providerPreferences, report]);
875
+ if (!enabled) return null;
876
+ const payload = menuCapture?.snapshot.payload ?? (source && "kind" in source ? source : void 0);
877
+ const quickVariants = (section) => variants.filter((v) => v.copyLabel && (v.section ?? "ai") === section).map((v) => /* @__PURE__ */ jsx7(DropdownMenuItem, { "aria-label": v.ariaLabel, onSelect: () => void transfer("markdown", false, v), children: /* @__PURE__ */ jsx7(MenuPresentation, { ...v, label: v.copyLabel }) }, `copy:${v.id}`));
878
+ const visibleCopies = COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows");
879
+ const visibleDownloads = DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows");
880
+ const visibleAdapters = menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
881
+ const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot)) : [];
882
+ return /* @__PURE__ */ jsxs4("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
883
+ /* @__PURE__ */ jsxs4(DropdownMenu, { onOpenChange: (open) => {
884
+ if (open) void preflight();
885
+ }, children: [
886
+ /* @__PURE__ */ jsx7(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx7("button", { ref: triggerRef, type: "button", className: "matrx-alchemy-trigger", disabled, "aria-label": `Copy, transform or export ${sourceLabel}`, title: "Alchemy \u2014 copy, transform, export", children: /* @__PURE__ */ jsx7(AlchemyGlyph, {}) }) }),
887
+ /* @__PURE__ */ jsxs4(DropdownMenuContent, { align: "end", className: "matrx-alchemy-menu", children: [
888
+ menuStatus === "loading" ? /* @__PURE__ */ jsx7(DropdownMenuItem, { disabled: true, children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ jsx7(DropdownMenuItem, { disabled: true, children: menuStatus }) : null,
889
+ !hide.includes("copy") ? /* @__PURE__ */ jsxs4(Fragment, { children: [
890
+ /* @__PURE__ */ jsx7(DropdownMenuLabel, { children: "Copy" }),
891
+ quickVariants("copy"),
892
+ visibleCopies.map((format) => /* @__PURE__ */ jsx7(DropdownMenuItem, { onSelect: () => void transfer(format, false), children: format === "plain" ? "Copy" : `Copy ${LABEL[format]}` }, format)),
893
+ visibleAdapters.map((adapter) => /* @__PURE__ */ jsxs4(DropdownMenuItem, { onSelect: () => void transfer(adapter, false), children: [
894
+ "Copy ",
895
+ adapter.label
896
+ ] }, adapter.id))
897
+ ] }) : null,
898
+ !hide.includes("prepare") ? /* @__PURE__ */ jsxs4(Fragment, { children: [
899
+ /* @__PURE__ */ jsx7(DropdownMenuSeparator, {}),
900
+ quickVariants("ai"),
901
+ /* @__PURE__ */ jsx7(DropdownMenuItem, { onSelect: () => void openWorkspace(), children: "Prepare for AI\u2026" }),
902
+ nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ jsx7(DropdownMenuItem, { onSelect: () => void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName }), children: "Prepare this surface\u2026" }) : null,
903
+ variants.map((variant) => /* @__PURE__ */ jsx7(DropdownMenuItem, { onSelect: () => void openWorkspace(variantWorkspaceKeys.get(variant.id), variant), children: /* @__PURE__ */ jsx7(MenuPresentation, { ...variant, label: `Prepare ${variant.label}\u2026` }) }, variant.id))
904
+ ] }) : null,
905
+ !hide.includes("download") ? /* @__PURE__ */ jsxs4(Fragment, { children: [
906
+ /* @__PURE__ */ jsx7(DropdownMenuSeparator, {}),
907
+ /* @__PURE__ */ jsx7(DropdownMenuLabel, { children: "Download" }),
908
+ visibleDownloads.map((format) => /* @__PURE__ */ jsxs4(DropdownMenuItem, { onSelect: () => void transfer(format, true), children: [
909
+ "Download ",
910
+ LABEL[format]
911
+ ] }, format)),
912
+ visibleAdapters.map((adapter) => /* @__PURE__ */ jsxs4(DropdownMenuItem, { onSelect: () => void transfer(adapter, true), children: [
913
+ "Download ",
914
+ adapter.label
915
+ ] }, `download:${adapter.id}`))
916
+ ] }) : null,
917
+ visibleActions.length ? /* @__PURE__ */ jsx7(DropdownMenuSeparator, {}) : null,
918
+ visibleActions.map((action) => /* @__PURE__ */ jsx7(DropdownMenuItem, { "aria-label": action.ariaLabel, onSelect: () => void runAction(action), children: /* @__PURE__ */ jsx7(MenuPresentation, { ...action, label: action.label }) }, action.id))
919
+ ] })
920
+ ] }),
921
+ notice ? /* @__PURE__ */ jsx7("span", { className: "matrx-alchemy-notice", role: "status", children: notice }) : null,
922
+ Object.values(workspaces).map((saved) => /* @__PURE__ */ jsx7(PreparationWorkspace, { restoreFocus: () => triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key))
923
+ ] });
924
+ }
925
+ function initialControls(state) {
926
+ const rows = state.original.payload.kind === "rows" ? state.original.payload : null;
927
+ return {
928
+ preset: state.preferences.initialPreset,
929
+ sections: state.snapshot.sections.filter((s) => s.includedByDefault).map((s) => s.id),
930
+ search: "",
931
+ filters: {},
932
+ sort: "",
933
+ direction: "asc",
934
+ top: state.preferences.limits.maxRows,
935
+ visibleColumns: rows?.columns.filter((c) => c.visible).map((c) => c.id) ?? [],
936
+ selectedOnly: false,
937
+ selectedIndices: [],
938
+ maxDepth: state.preferences.limits.maxDepth,
939
+ maxStringChars: state.preferences.limits.maxStringChars,
940
+ maxArrayItems: state.preferences.limits.maxArrayItems ?? null
486
941
  };
487
- const notice = message ? /* @__PURE__ */ jsxs4("span", { role: message.error ? "alert" : "status", className: message.error ? "text-xs text-destructive" : "text-xs text-muted-foreground", children: [
488
- message.text,
489
- /* @__PURE__ */ jsx9("button", { type: "button", "aria-label": "Dismiss notification", className: "ml-2 underline", onClick: () => setMessage(null), children: "Dismiss" })
490
- ] }) : null;
491
- return { notify, notice };
492
942
  }
493
-
494
- // src/data-table/copy-payload.ts
495
- function tableAgentText(value) {
496
- if (typeof value === "string") return value;
497
- const attributes = Object.entries(value.attributes ?? {}).filter(([, entry]) => entry !== null && entry !== void 0 && entry !== "").map(([key, entry]) => ` ${key}="${String(entry)}"`).join("");
498
- const context = Object.entries(value.context ?? {}).filter(([, entry]) => entry !== null && entry !== void 0 && entry !== "").map(([key, entry]) => `<${key}>${String(entry)}</${key}>`).join("\n");
499
- const url = typeof window === "undefined" ? "" : window.location.href;
500
- const route = typeof window === "undefined" ? "" : window.location.pathname;
501
- return `<${value.kind}${attributes}>
502
- <context>
503
- <location>${value.location}</location>
504
- ${url ? `<url>${url}</url>` : ""}
505
- ${route ? `<route>${route}</route>` : ""}
506
- <copied>${value.description}</copied>
507
- <copied-at>${(/* @__PURE__ */ new Date()).toISOString()}</copied-at>
508
- ${context}
509
- </context>
510
- ${value.summary ? `<summary>
511
- ${value.summary}
512
- </summary>
513
- ` : ""}<data format="json">
514
- \`\`\`json
515
- ${JSON.stringify(value.data, null, 2)}
516
- \`\`\`
517
- </data>
518
- </${value.kind}>`;
943
+ function presetLimits(preset, controls, preferences) {
944
+ const min = (choice, cap) => choice == null ? cap : cap == null ? choice : Math.min(choice, cap);
945
+ if (preset === "full") return preferences.limits;
946
+ const request = preset === "brief" ? { maxDepth: 4, maxStringChars: 800, maxArrayItems: 25 } : preset === "compact" ? { maxDepth: 8, maxStringChars: 4e3, maxArrayItems: 100 } : { maxDepth: controls.maxDepth, maxStringChars: controls.maxStringChars, maxArrayItems: controls.maxArrayItems };
947
+ return { ...preferences.limits, maxDepth: min(request.maxDepth, preferences.limits.maxDepth), maxStringChars: min(request.maxStringChars, preferences.limits.maxStringChars), maxArrayItems: min(request.maxArrayItems, preferences.limits.maxArrayItems ?? null) };
519
948
  }
520
-
521
- // src/data-table/copy.tsx
522
- import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
523
- function resolve(value) {
524
- return typeof value === "function" ? value() : value;
525
- }
526
- function download(item) {
527
- if (!item.build) throw new Error(`No export action is available for ${item.label}.`);
528
- const file = item.build();
529
- const url = URL.createObjectURL(new Blob([file.content], { type: file.mime }));
530
- try {
531
- const link = document.createElement("a");
532
- link.href = url;
533
- link.download = `${item.label.replace(/[^a-z0-9]+/gi, "-")}.${file.extension}`;
534
- document.body.append(link);
535
- link.click();
536
- link.remove();
537
- } finally {
538
- URL.revokeObjectURL(url);
949
+ function rebuild(state, controls) {
950
+ let draft = resetDraft(state.snapshot);
951
+ if (state.snapshot.sections.length) draft = applySectionSelection(draft, state.snapshot, controls.sections);
952
+ if (draft.payload.kind === "rows") draft = transformRows(draft, {
953
+ search: controls.search,
954
+ filters: controls.filters,
955
+ ...controls.sort ? { sort: { column: controls.sort, direction: controls.direction } } : {},
956
+ ...controls.selectedOnly ? { selectedIndices: controls.selectedIndices } : {},
957
+ visibleColumns: controls.visibleColumns,
958
+ structuredProjection: "visible",
959
+ top: controls.top
960
+ });
961
+ const limits = presetLimits(controls.preset, controls, state.preferences);
962
+ if (draft.payload.kind === "json" || draft.payload.kind === "registered") {
963
+ draft = reduceJson(draft, { maxDepth: limits.maxDepth, maxStringChars: limits.maxStringChars, maxArrayItems: limits.maxArrayItems ?? null });
539
964
  }
965
+ return applyTransferLimits(draft, limits);
540
966
  }
541
- function CopyButtons(props) {
542
- const { CopyControls } = useMatrxDataTableHost();
543
- if (CopyControls) return /* @__PURE__ */ jsx10(CopyControls, { ...props });
544
- return /* @__PURE__ */ jsx10(DefaultCopyButtons, { ...props });
967
+ function isBuiltInFormat(format) {
968
+ return format in LABEL;
545
969
  }
546
- function DefaultCopyButtons({ human, agent, json, label, size = "icon", appearance = "segmented", disabled = false, stopPropagation = true, className, aiVariants = [], agentVariant, aiCustom, export: exportConfig, hide }) {
547
- const { notify, notice } = useTableNotice();
548
- const clipboard = useClipboard({ notify: (message, kind) => notify[kind](message) });
549
- const [busy, setBusy] = useState4(false);
550
- const [modal, setModal] = useState4(null);
551
- const run = async (operation) => {
552
- if (busy) return;
553
- setBusy(true);
970
+ function preview(draft, format) {
971
+ const resolved = isBuiltInFormat(format) ? format : "plain";
972
+ return serialize(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
973
+ }
974
+ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, onOutcome, captureScope }) {
975
+ const fence = useFence();
976
+ const latest = React7.useRef(state);
977
+ latest.current = state;
978
+ const aiSession = React7.useRef(void 0);
979
+ if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
980
+ const [controls, setControls] = React7.useState(() => initialControls(state));
981
+ const [controlsHistory, setControlsHistory] = React7.useState([]);
982
+ const [pendingControls, setPendingControls] = React7.useState(null);
983
+ const requestedFormat = state.preferences.initialFormat;
984
+ const [format, setFormat] = React7.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
985
+ const [buffer, setBuffer] = React7.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
986
+ const [bufferError, setBufferError] = React7.useState(null);
987
+ const [formatError, setFormatError] = React7.useState(null);
988
+ const [preparedArtifact, setPreparedArtifact] = React7.useState(null);
989
+ const [instruction, setInstruction] = React7.useState("");
990
+ const [busy, setBusy] = React7.useState(null);
991
+ const [aiFailed, setAiFailed] = React7.useState(false);
992
+ const activeAi = React7.useRef(null);
993
+ const activeCapture = React7.useRef(null);
994
+ React7.useEffect(() => {
995
+ if (bufferError) return;
996
+ const adapter = adapters.find((candidate) => candidate.id === format);
997
+ const controller = new AbortController();
998
+ const snapshotId = state.snapshot.id;
999
+ const revision = state.draft.revision;
1000
+ setPreparedArtifact(null);
1001
+ setFormatError(null);
1002
+ if (adapter) setBuffer("Preparing format preview\u2026");
1003
+ const artifactPromise = adapter ? adapter.build(state.draft, controller.signal) : buildArtifact(state.draft, isBuiltInFormat(format) ? format : "plain", state.snapshot.label);
1004
+ void artifactPromise.then((artifact) => {
1005
+ if (!controller.signal.aborted && artifact.snapshotId === snapshotId && artifact.draftRevision === revision) {
1006
+ setPreparedArtifact(artifact);
1007
+ setBuffer(artifact.plainText);
1008
+ }
1009
+ }).catch((error) => {
1010
+ if (!controller.signal.aborted) setFormatError(errorMessage(error, "Format preview failed"));
1011
+ });
1012
+ return () => controller.abort();
1013
+ }, [adapters, bufferError, format, state.draft, state.snapshot.id]);
1014
+ const close = React7.useCallback(() => {
1015
+ activeAi.current?.abort();
1016
+ activeCapture.current?.abort();
1017
+ activeAi.current = null;
1018
+ activeCapture.current = null;
1019
+ fence.abortAll();
1020
+ setBusy(null);
1021
+ onClose();
1022
+ }, [fence, onClose]);
1023
+ const changeControls = (next) => {
1024
+ if (state.draft.manuallyEdited) {
1025
+ setPendingControls(next);
1026
+ return;
1027
+ }
1028
+ setControlsHistory((history) => [...history, controls]);
1029
+ setControls(next);
1030
+ onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1031
+ };
1032
+ const applyPendingControls = () => {
1033
+ if (!pendingControls) return;
1034
+ setControlsHistory((history) => [...history, controls]);
1035
+ setControls(pendingControls);
1036
+ setBufferError(null);
1037
+ onChange({ ...state, draft: rebuild(state, pendingControls), error: void 0 });
1038
+ setPendingControls(null);
1039
+ };
1040
+ const editBuffer = (text) => {
1041
+ setBuffer(text);
1042
+ setPreparedArtifact(null);
1043
+ setFormatError(null);
1044
+ const payload = state.draft.payload;
1045
+ if (payload.kind === "json" || payload.kind === "registered") {
1046
+ try {
1047
+ const value = JSON.parse(text);
1048
+ const next = payload.kind === "json" ? { kind: "json", value } : { kind: "registered", format: payload.format, value };
1049
+ setBufferError(null);
1050
+ onChange({ ...state, draft: editDraft(state.draft, next), error: void 0 });
1051
+ } catch {
1052
+ setBufferError("JSON is incomplete or invalid. Fix it before copying or downloading.");
1053
+ }
1054
+ return;
1055
+ }
1056
+ setBufferError(null);
1057
+ const kind = payload.kind === "markdown" || format === "markdown" ? "markdown" : "text";
1058
+ if (payload.kind === "rows" || !isBuiltInFormat(format)) setFormat("plain");
1059
+ onChange({ ...state, draft: editDraft(state.draft, { kind, text }), error: void 0 });
1060
+ };
1061
+ const requestCapture = async (scope) => {
1062
+ activeCapture.current?.abort();
1063
+ const { controller, id } = fence.begin();
1064
+ activeCapture.current = controller;
1065
+ const revision = state.draft.revision;
1066
+ setBusy("capture");
1067
+ try {
1068
+ const result = await captureScope(scope, controller.signal);
1069
+ if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, error: result.collectionError });
1070
+ } catch (error) {
1071
+ if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "Refresh failed") });
1072
+ } finally {
1073
+ fence.finish(controller);
1074
+ if (activeCapture.current === controller) activeCapture.current = null;
1075
+ if (fence.valid(id, controller)) setBusy(null);
1076
+ }
1077
+ };
1078
+ const resolveCapture = (choice) => {
1079
+ if (!state.pending) return;
1080
+ if (choice === "keep") {
1081
+ const { pending: _pending, ...kept } = state;
1082
+ onChange({ ...kept, error: void 0 });
1083
+ return;
1084
+ }
1085
+ const pending = state.pending;
1086
+ const preferences = resolveTransferPreferences({}, state.preferences, pending.snapshot.limits);
1087
+ const base = { ...pending, key: state.key, original: createDraft(pending.snapshot), draft: createDraft(pending.snapshot), scope: pending.scope, preferences, ...pending.collectionError ? { error: pending.collectionError } : {} };
1088
+ const nextControls = initialControls(base);
1089
+ setControls(nextControls);
1090
+ setControlsHistory([]);
1091
+ setPendingControls(null);
1092
+ setBufferError(null);
1093
+ onChange({ ...base, draft: rebuild(base, nextControls) });
1094
+ };
1095
+ const runAi = async (recover = false) => {
1096
+ const adapter = aiSession.current;
1097
+ if (!adapter || !adapter.supports(state.snapshot) || !recover && !instruction.trim() || recover && !adapter.recover) return;
1098
+ activeAi.current?.abort();
1099
+ const { controller, id } = fence.begin();
1100
+ activeAi.current = controller;
1101
+ const snapshotId = state.snapshot.id;
1102
+ const revision = state.draft.revision;
1103
+ setBusy("ai");
1104
+ setAiFailed(false);
1105
+ try {
1106
+ const next = recover ? await adapter.recover({ snapshot: state.snapshot, draft: state.draft, signal: controller.signal }) : await adapter.run({ snapshot: state.snapshot, draft: state.draft, instruction, signal: controller.signal });
1107
+ const current = latest.current;
1108
+ if (!fence.valid(id, controller) || current.snapshot.id !== snapshotId || current.draft.revision !== revision || next.snapshotId !== snapshotId || next.sourceId !== state.draft.sourceId || next.sourceRevision !== state.draft.sourceRevision || next.revision <= revision) return;
1109
+ try {
1110
+ serialize(next, "plain");
1111
+ } catch {
1112
+ onChange({ ...current, error: "AI returned an invalid transfer draft." });
1113
+ setAiFailed(true);
1114
+ return;
1115
+ }
1116
+ onChange({ ...current, draft: next, error: void 0 });
1117
+ setBufferError(null);
1118
+ } catch (error) {
1119
+ if (!isAbort(error) && fence.valid(id, controller)) {
1120
+ setAiFailed(true);
1121
+ onChange({ ...latest.current, error: errorMessage(error, "AI preparation failed") });
1122
+ }
1123
+ } finally {
1124
+ fence.finish(controller);
1125
+ if (activeAi.current === controller) activeAi.current = null;
1126
+ if (fence.valid(id, controller)) setBusy(null);
1127
+ }
1128
+ };
1129
+ const cancelAi = async () => {
1130
+ const aiController = activeAi.current;
1131
+ const { controller, id } = fence.begin();
1132
+ try {
1133
+ await aiSession.current?.cancel?.();
1134
+ } catch (error) {
1135
+ if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "AI cancellation failed") });
1136
+ } finally {
1137
+ aiController?.abort();
1138
+ fence.finish(controller);
1139
+ if (activeAi.current === aiController) activeAi.current = null;
1140
+ if (fence.valid(id, controller)) setBusy(null);
1141
+ }
1142
+ };
1143
+ const [deliveryNotice, setDeliveryNotice] = React7.useState(null);
1144
+ React7.useEffect(() => {
1145
+ setDeliveryNotice(null);
1146
+ }, [state.draft.revision]);
1147
+ const reportDelivery = (outcome) => {
1148
+ setDeliveryNotice(outcomeMessage(outcome));
1149
+ onOutcome(outcome);
1150
+ };
1151
+ const deliver = async (download) => {
1152
+ if (bufferError) return;
1153
+ const { controller, id } = fence.begin();
1154
+ const snapshotId = state.snapshot.id;
1155
+ const revision = state.draft.revision;
1156
+ setBusy(download ? "download" : "copy");
554
1157
  try {
555
- await operation();
1158
+ if (!preparedArtifact) throw new Error("Wait for the selected format preview before delivery.");
1159
+ const artifact = preparedArtifact;
1160
+ const current = latest.current;
1161
+ if (!fence.valid(id, controller) || current.snapshot.id !== snapshotId || current.draft.revision !== revision || artifact.snapshotId !== snapshotId || artifact.draftRevision !== revision) return;
1162
+ const result = await transport[download ? "download" : "copy"](artifact, controller.signal);
1163
+ if (fence.valid(id, controller)) reportDelivery(result);
556
1164
  } catch (error) {
557
- notify.error(error instanceof Error ? error.message : String(error));
1165
+ if (fence.valid(id, controller)) reportDelivery({ status: "error", code: "prepare-failed", message: errorMessage(error, "Preparation failed"), retryable: true });
558
1166
  } finally {
559
- setBusy(false);
1167
+ fence.finish(controller);
1168
+ if (fence.valid(id, controller)) setBusy(null);
560
1169
  }
561
1170
  };
562
- const faithfulAgent = agent === void 0 ? [] : [{
563
- id: agentVariant?.id ?? "copy-for-ai",
564
- label: agentVariant?.label ?? "Copy for AI",
565
- ...agentVariant?.hint === void 0 ? {} : { hint: agentVariant.hint },
566
- section: "ai",
567
- build: () => resolve(agent)
568
- }];
569
- const orderedAgent = agentVariant?.position === "last" ? [...aiVariants, ...faithfulAgent] : [...faithfulAgent, ...aiVariants];
570
- const variants = [
571
- ...json === void 0 ? [] : [{ id: "json", label: "Copy JSON", section: "copy", build: () => JSON.stringify(resolve(json), null, 2) }],
572
- ...orderedAgent
573
- ].filter((variant) => !hide?.includes(variant.section ?? "ai"));
574
- const exports = hide?.includes("export") ? void 0 : exportConfig;
575
- const showCustom = aiCustom && !hide?.includes("ai");
576
- const buttonClass = `${size === "xs" ? "h-8 w-8 lg:h-5 lg:w-8" : ""} ${appearance === "bare" ? "border-0 bg-transparent shadow-none" : ""}`;
577
- return /* @__PURE__ */ jsxs5("span", { className: `inline-flex flex-wrap items-center gap-0.5 ${className ?? ""}`, onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
578
- human !== void 0 && !hide?.includes("copy") ? /* @__PURE__ */ jsx10(Button, { type: "button", variant: "ghost", size: "icon", className: buttonClass, disabled: disabled || busy, "aria-label": `Copy ${label}`, onClick: () => void run(() => clipboard.copyText(resolve(human), `${label} copied`)), children: /* @__PURE__ */ jsx10(Copy, { className: "h-3.5 w-3.5" }) }) : null,
579
- variants.length > 0 || showCustom || exports ? /* @__PURE__ */ jsxs5(Popover, { children: [
580
- /* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(Button, { type: "button", variant: "ghost", size: "icon", className: buttonClass, disabled: disabled || busy, "aria-label": `Copy ${label} for AI or export`, children: /* @__PURE__ */ jsx10(SlidersHorizontal, { className: "h-3.5 w-3.5" }) }) }),
581
- /* @__PURE__ */ jsxs5(PopoverContent, { align: "end", className: "w-64 p-1", children: [
582
- variants.map((variant) => /* @__PURE__ */ jsx10(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full justify-start", disabled: busy, onClick: () => void run(async () => {
583
- if (variant.onSelect) variant.onSelect();
584
- else if (variant.modal) setModal(variant.id);
585
- else if (variant.build) await clipboard.copyText(tableAgentText(await variant.build()), variant.successMessage ?? `${label} copied`);
586
- else throw new Error(`No copy action is available for ${variant.label}.`);
587
- }), children: variant.label }, variant.id)),
588
- showCustom ? /* @__PURE__ */ jsx10(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full justify-start", onClick: () => setModal("custom"), children: aiCustom.label ?? "Custom copy\u2026" }) : null,
589
- exports?.items.map((item) => /* @__PURE__ */ jsx10(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full justify-start", disabled: busy, onClick: () => void run(async () => {
590
- if (item.onSelect) await item.onSelect();
591
- else download(item);
592
- }), children: item.label }, item.id)),
593
- exports?.sheetRows ? /* @__PURE__ */ jsx10(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full justify-start", onClick: () => void run(async () => {
594
- const rows = exports.sheetRows?.();
595
- if (!rows) return;
596
- const keys = [...new Set(rows.flatMap((row) => Object.keys(row)))];
597
- const value = (input) => String(input ?? "").replace(/[\t\r\n]+/g, " ");
598
- await clipboard.copyText([keys.map(value).join(" "), ...rows.map((row) => keys.map((key) => value(row[key])).join(" "))].join("\n"), "Copied for pasting into Google Sheets");
599
- }), children: "Copy for Google Sheets" }) : null
1171
+ const rows = state.original.payload.kind === "rows" ? state.original.payload : null;
1172
+ const formats = COPIES.filter((f) => supportsBuiltIn(f, state.draft.payload));
1173
+ const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
1174
+ const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
1175
+ const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${Number(value).toLocaleString()}`).join(" \xB7 ");
1176
+ return /* @__PURE__ */ jsx7(Dialog, { open, onOpenChange: (next) => {
1177
+ if (!next) close();
1178
+ }, children: /* @__PURE__ */ jsxs4(DialogContent, { onCloseAutoFocus: (event) => {
1179
+ event.preventDefault();
1180
+ restoreFocus();
1181
+ }, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
1182
+ /* @__PURE__ */ jsxs4(DialogHeader, { children: [
1183
+ /* @__PURE__ */ jsxs4(DialogTitle, { children: [
1184
+ "Prepare ",
1185
+ state.snapshot.label
1186
+ ] }),
1187
+ /* @__PURE__ */ jsxs4(DialogDescription, { children: [
1188
+ "Captured ",
1189
+ state.snapshot.unsavedChanges ? "from your unsaved draft" : "as an immutable snapshot",
1190
+ ". Your source is never edited."
600
1191
  ] })
1192
+ ] }),
1193
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-workspace-grid", children: [
1194
+ /* @__PURE__ */ jsxs4("section", { className: "matrx-alchemy-main", children: [
1195
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-toolbar", children: [
1196
+ scopes.length > 1 ? /* @__PURE__ */ jsxs4("label", { children: [
1197
+ "Scope",
1198
+ /* @__PURE__ */ jsx7("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ jsx7("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
1199
+ ] }) : null,
1200
+ /* @__PURE__ */ jsxs4("label", { children: [
1201
+ "Detail",
1202
+ /* @__PURE__ */ jsxs4("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
1203
+ /* @__PURE__ */ jsx7("option", { value: "full", children: "Full" }),
1204
+ /* @__PURE__ */ jsx7("option", { value: "compact", children: "Compact" }),
1205
+ /* @__PURE__ */ jsx7("option", { value: "brief", children: "Brief" }),
1206
+ /* @__PURE__ */ jsx7("option", { value: "custom", children: "Custom" })
1207
+ ] })
1208
+ ] }),
1209
+ /* @__PURE__ */ jsx7(Button, { type: "button", size: "sm", variant: "outline", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
1210
+ setBufferError(null);
1211
+ if (controlsHistory.length) {
1212
+ const next = controlsHistory[controlsHistory.length - 1];
1213
+ setControls(next);
1214
+ setControlsHistory((history) => history.slice(0, -1));
1215
+ onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1216
+ } else onChange({ ...state, draft: undoDraft(state.draft), error: void 0 });
1217
+ }, children: "Undo" }),
1218
+ /* @__PURE__ */ jsx7(Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => {
1219
+ const next = initialControls(state);
1220
+ setControls(next);
1221
+ setControlsHistory([]);
1222
+ setPendingControls(null);
1223
+ setBufferError(null);
1224
+ onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1225
+ }, children: "Reset" }),
1226
+ /* @__PURE__ */ jsx7(Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
1227
+ ] }),
1228
+ controls.preset === "custom" && (state.draft.payload.kind === "json" || state.draft.payload.kind === "registered") ? /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1229
+ /* @__PURE__ */ jsx7("legend", { children: "JSON limits" }),
1230
+ [["maxDepth", "Maximum depth"], ["maxStringChars", "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].map(([key, text]) => /* @__PURE__ */ jsxs4("label", { children: [
1231
+ text,
1232
+ /* @__PURE__ */ jsx7("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1233
+ ] }, key))
1234
+ ] }) : null,
1235
+ rows ? /* @__PURE__ */ jsx7(RowControls, { rows, controls, change: changeControls }) : null,
1236
+ state.snapshot.sections.length ? /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1237
+ /* @__PURE__ */ jsx7("legend", { children: "Sections" }),
1238
+ state.snapshot.sections.map((section) => /* @__PURE__ */ jsxs4("label", { children: [
1239
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: controls.sections.includes(section.id), onChange: (e) => changeControls({ ...controls, sections: e.target.checked ? [...controls.sections, section.id] : controls.sections.filter((id) => id !== section.id) }) }),
1240
+ " ",
1241
+ section.label
1242
+ ] }, section.id))
1243
+ ] }) : null,
1244
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-coverage", children: [
1245
+ /* @__PURE__ */ jsxs4("span", { children: [
1246
+ state.snapshot.coverage.included.toLocaleString(),
1247
+ " included",
1248
+ state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
1249
+ " \xB7 ",
1250
+ state.snapshot.coverage.status
1251
+ ] }),
1252
+ state.snapshot.coverage.reason ? /* @__PURE__ */ jsx7("span", { children: state.snapshot.coverage.reason }) : null,
1253
+ limitText ? /* @__PURE__ */ jsxs4("span", { children: [
1254
+ "Limits: ",
1255
+ limitText
1256
+ ] }) : null,
1257
+ displayedOmissions.length ? /* @__PURE__ */ jsxs4("details", { children: [
1258
+ /* @__PURE__ */ jsxs4("summary", { children: [
1259
+ displayedOmissions.length,
1260
+ " omissions or adjustments"
1261
+ ] }),
1262
+ /* @__PURE__ */ jsx7("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ jsxs4("li", { children: [
1263
+ o.path || "/",
1264
+ ": ",
1265
+ o.reason,
1266
+ o.count == null ? "" : ` (${o.count})`
1267
+ ] }, `${o.path}-${o.reason}-${i}`)) })
1268
+ ] }) : null
1269
+ ] }),
1270
+ /* @__PURE__ */ jsxs4("label", { className: "matrx-alchemy-preview-label", children: [
1271
+ "Output format",
1272
+ /* @__PURE__ */ jsxs4("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
1273
+ formats.map((f) => /* @__PURE__ */ jsx7("option", { value: f, children: LABEL[f] }, f)),
1274
+ state.draft.payload.kind === "rows" ? /* @__PURE__ */ jsx7("option", { value: "xlsx", children: "Excel workbook" }) : null,
1275
+ workspaceAdapters.map((adapter) => /* @__PURE__ */ jsx7("option", { value: adapter.id, children: adapter.label }, adapter.id))
1276
+ ] })
1277
+ ] }),
1278
+ /* @__PURE__ */ jsx7("textarea", { className: "matrx-alchemy-preview", "aria-label": "Prepared output", "aria-invalid": bufferError ? true : void 0, "aria-describedby": bufferError ? "alchemy-buffer-error" : void 0, value: buffer, onChange: (e) => editBuffer(e.target.value) }),
1279
+ bufferError ? /* @__PURE__ */ jsx7("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
1280
+ formatError ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
1281
+ bufferError ? /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
1282
+ const fallback = editDraft(state.draft, { kind: "text", text: buffer });
1283
+ setBufferError(null);
1284
+ onChange({ ...state, draft: fallback, error: void 0 });
1285
+ setFormat("plain");
1286
+ }, children: "Use invalid JSON as plain text" }) : null
1287
+ ] }),
1288
+ ai || busy === "capture" || state.error ? /* @__PURE__ */ jsxs4("aside", { children: [
1289
+ ai ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1290
+ /* @__PURE__ */ jsxs4("label", { children: [
1291
+ "AI instruction",
1292
+ /* @__PURE__ */ jsx7("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
1293
+ ] }),
1294
+ /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
1295
+ busy === "ai" ? /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
1296
+ ] }) : null,
1297
+ busy === "capture" ? /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => {
1298
+ activeCapture.current?.abort();
1299
+ activeCapture.current = null;
1300
+ setBusy(null);
1301
+ }, children: "Stop loading rows" }) : null,
1302
+ ai && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
1303
+ ai ? /* @__PURE__ */ jsx7("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
1304
+ state.error ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
1305
+ ] }) : null
1306
+ ] }),
1307
+ pendingControls ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1308
+ /* @__PURE__ */ jsx7("p", { children: "This control would replace your manual edit." }),
1309
+ /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
1310
+ /* @__PURE__ */ jsx7(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
601
1311
  ] }) : null,
602
- variants.map((variant) => variant.modal && modal === variant.id ? /* @__PURE__ */ jsx10("span", { children: variant.modal({ open: true, onOpenChange: (open) => setModal(open ? variant.id : null) }) }, variant.id) : null),
603
- modal === "custom" && aiCustom ? /* @__PURE__ */ jsx10(CustomCopy, { source: aiCustom, onClose: () => setModal(null) }) : null,
604
- notice
1312
+ state.pending ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1313
+ /* @__PURE__ */ jsx7("p", { children: "A fresh source snapshot is ready." }),
1314
+ /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
1315
+ /* @__PURE__ */ jsx7(Button, { type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
1316
+ ] }) : null,
1317
+ deliveryNotice ? /* @__PURE__ */ jsx7("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null,
1318
+ /* @__PURE__ */ jsxs4(DialogFooter, { children: [
1319
+ /* @__PURE__ */ jsxs4("span", { className: "matrx-alchemy-meta", children: [
1320
+ buffer.length.toLocaleString(),
1321
+ " characters \xB7 ~",
1322
+ estimateTokens(buffer).toLocaleString(),
1323
+ " tokens"
1324
+ ] }),
1325
+ /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: close, children: "Close" }),
1326
+ /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download prepared output" }),
1327
+ /* @__PURE__ */ jsx7(Button, { type: "button", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy prepared output" })
1328
+ ] })
1329
+ ] }) });
1330
+ }
1331
+ function RowControls({ rows, controls, change }) {
1332
+ return /* @__PURE__ */ jsxs4(Fragment, { children: [
1333
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-toolbar", children: [
1334
+ /* @__PURE__ */ jsxs4("label", { children: [
1335
+ "Search",
1336
+ /* @__PURE__ */ jsx7("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
1337
+ ] }),
1338
+ /* @__PURE__ */ jsxs4("label", { children: [
1339
+ "Sort",
1340
+ /* @__PURE__ */ jsxs4("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
1341
+ /* @__PURE__ */ jsx7("option", { value: "", children: "None" }),
1342
+ rows.columns.map((column) => /* @__PURE__ */ jsx7("option", { value: column.id, children: column.label }, column.id))
1343
+ ] })
1344
+ ] }),
1345
+ /* @__PURE__ */ jsxs4("label", { children: [
1346
+ "Direction",
1347
+ /* @__PURE__ */ jsxs4("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
1348
+ /* @__PURE__ */ jsx7("option", { value: "asc", children: "Ascending" }),
1349
+ /* @__PURE__ */ jsx7("option", { value: "desc", children: "Descending" })
1350
+ ] })
1351
+ ] }),
1352
+ /* @__PURE__ */ jsxs4("label", { children: [
1353
+ "Top rows",
1354
+ /* @__PURE__ */ jsx7("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1355
+ ] })
1356
+ ] }),
1357
+ /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1358
+ /* @__PURE__ */ jsx7("legend", { children: "Columns and filters" }),
1359
+ rows.columns.map((column) => /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-column", children: [
1360
+ /* @__PURE__ */ jsxs4("label", { children: [
1361
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: controls.visibleColumns.includes(column.id), onChange: (e) => change({ ...controls, visibleColumns: e.target.checked ? [...controls.visibleColumns, column.id] : controls.visibleColumns.filter((id) => id !== column.id) }) }),
1362
+ " ",
1363
+ column.label
1364
+ ] }),
1365
+ /* @__PURE__ */ jsx7("input", { "aria-label": `Filter ${column.label}`, placeholder: "Filter", value: controls.filters[column.id] ?? "", onChange: (e) => change({ ...controls, filters: { ...controls.filters, [column.id]: e.target.value } }) })
1366
+ ] }, column.id))
1367
+ ] }),
1368
+ /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1369
+ /* @__PURE__ */ jsx7("legend", { children: "Rows" }),
1370
+ /* @__PURE__ */ jsxs4("label", { children: [
1371
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
1372
+ " Only selected rows"
1373
+ ] }),
1374
+ /* @__PURE__ */ jsx7("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
1375
+ const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String(readTransferCell(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
1376
+ return /* @__PURE__ */ jsxs4("label", { children: [
1377
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: controls.selectedIndices.includes(index), onChange: (e) => change({ ...controls, selectedIndices: e.target.checked ? [...controls.selectedIndices, index] : controls.selectedIndices.filter((value) => value !== index) }) }),
1378
+ " Row ",
1379
+ index + 1,
1380
+ summary ? ` \u2014 ${summary}` : ""
1381
+ ] }, index);
1382
+ }) })
1383
+ ] })
605
1384
  ] });
606
1385
  }
607
- function CustomCopy({ source, onClose }) {
608
- const [values, setValues] = useState4(() => Object.fromEntries(source.options.map((option) => [option.key, option.default])));
609
- const { notify, notice } = useTableNotice();
610
- const clipboard = useClipboard({ notify: (message, kind) => notify[kind](message) });
1386
+
1387
+ // src/content-transfer/matrx-copy.tsx
1388
+ import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1389
+ var resolve = (value) => typeof value === "function" ? value() : value;
1390
+ var asPayload = (value) => ({
1391
+ kind: "markdown",
1392
+ text: typeof value === "string" ? value : buildAgentPayload(value)
1393
+ });
1394
+ var structuredPayload = (value) => {
1395
+ if (typeof value === "string") return { kind: "markdown", text: value };
1396
+ const clean = (record) => Object.fromEntries(
1397
+ Object.entries(record ?? {}).filter(([, entry]) => entry !== void 0)
1398
+ );
1399
+ return {
1400
+ kind: "json",
1401
+ value: normalizeTransferJson({
1402
+ kind: value.kind,
1403
+ location: value.location,
1404
+ description: value.description,
1405
+ data: value.data,
1406
+ ...value.summary !== void 0 ? { summary: value.summary } : {},
1407
+ attributes: clean(value.attributes),
1408
+ context: clean(value.context)
1409
+ })
1410
+ };
1411
+ };
1412
+ var actionDone = (message) => ({
1413
+ status: "success",
1414
+ delivered: "action",
1415
+ mimeTypes: [],
1416
+ message
1417
+ });
1418
+ var sourceFor = (id, label, build) => ({
1419
+ id,
1420
+ label,
1421
+ capture: async ({ signal }) => {
1422
+ signal.throwIfAborted();
1423
+ const payload = await build();
1424
+ signal.throwIfAborted();
1425
+ return directSource2(payload, { sourceId: id, label });
1426
+ }
1427
+ });
1428
+ function MatrxCopyMenu(props) {
1429
+ return /* @__PURE__ */ jsx8(MatrxCopyMenuSession, { ...props }, props.sourceId ?? props.label);
1430
+ }
1431
+ function MatrxCopyMenuSession(props) {
1432
+ const instance = React8.useId();
1433
+ const controller = React8.useRef(null);
1434
+ const capabilities = useContentTransferCapabilities();
1435
+ const transport = capabilities.transport ?? createBrowserTransport2();
1436
+ const [modal, setModal] = React8.useState(null);
1437
+ const [configuration, setConfiguration] = React8.useState(null);
1438
+ const copyVisible = !props.hide?.includes("copy");
1439
+ const aiVisible = !props.hide?.includes("ai");
1440
+ const exportVisible = !props.hide?.includes("export");
1441
+ const make = (suffix, build, label = props.label) => sourceFor(
1442
+ `${props.sourceId ?? `${instance}:${props.label}`}:${suffix}`,
1443
+ label,
1444
+ build
1445
+ );
1446
+ const human = copyVisible && props.human !== void 0 ? make("human", () => ({ kind: "text", text: resolve(props.human) })) : void 0;
1447
+ const humanMarkdown = copyVisible && props.human !== void 0 ? make("human-markdown", () => ({
1448
+ kind: "markdown",
1449
+ text: resolve(props.human)
1450
+ })) : void 0;
1451
+ const json = aiVisible && props.json !== void 0 ? make("json", () => ({
1452
+ kind: "json",
1453
+ value: normalizeTransferJson(resolve(props.json))
1454
+ })) : void 0;
1455
+ const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
1456
+ const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
1457
+ const table = exportVisible && props.export?.sheetRows ? make("rows", () => {
1458
+ const value = normalizeTransferJson(props.export.sheetRows());
1459
+ if (!Array.isArray(value) || value.some(
1460
+ (row) => row === null || typeof row !== "object" || Array.isArray(row)
1461
+ ))
1462
+ throw new Error("Sheet rows must be JSON objects.");
1463
+ const rows = value;
1464
+ const keys = [...new Set(rows.flatMap((row) => Object.keys(row)))];
1465
+ return {
1466
+ kind: "rows",
1467
+ rows,
1468
+ columns: keys.map((key) => ({
1469
+ id: key,
1470
+ label: key,
1471
+ path: `/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`,
1472
+ visible: true
1473
+ }))
1474
+ };
1475
+ }) : void 0;
1476
+ const builderVariants = aiVisible ? (props.aiVariants ?? []).filter(
1477
+ (variant) => variant.build && !variant.onSelect && !variant.modal
1478
+ ).map((variant) => ({
1479
+ ...variant,
1480
+ copyLabel: variant.label,
1481
+ source: make(
1482
+ `variant:${variant.id}`,
1483
+ async () => asPayload(await variant.build()),
1484
+ variant.label
1485
+ )
1486
+ })) : [];
1487
+ const faithful = agent ? [
1488
+ {
1489
+ id: props.agentVariant?.id ?? "faithful",
1490
+ label: props.agentVariant?.label ?? "Full AI context",
1491
+ source: agent,
1492
+ copyLabel: props.agentVariant?.label ?? "Copy for AI",
1493
+ ...props.agentVariant?.hint ? { hint: props.agentVariant.hint } : {}
1494
+ }
1495
+ ] : [];
1496
+ const variants = props.agentVariant?.position === "last" ? [...builderVariants, ...faithful] : [...faithful, ...builderVariants];
1497
+ const actions = [];
1498
+ if (aiVisible)
1499
+ for (const variant of props.aiVariants ?? []) {
1500
+ if (!variant.onSelect && !variant.modal) continue;
1501
+ actions.push({
1502
+ ...variant,
1503
+ id: `variant-action:${variant.id}`,
1504
+ label: variant.label,
1505
+ supports: () => true,
1506
+ run: async () => {
1507
+ if (variant.onSelect) await variant.onSelect();
1508
+ else setModal(variant);
1509
+ return actionDone(`Opened ${variant.label}`);
1510
+ }
1511
+ });
1512
+ }
1513
+ if (aiVisible && props.aiCustom)
1514
+ actions.push({
1515
+ id: "configure-source",
1516
+ label: props.aiCustom.label ?? "Customize source\u2026",
1517
+ ...props.aiCustom.hint ? { hint: props.aiCustom.hint } : {},
1518
+ supports: () => true,
1519
+ run: async () => {
1520
+ setConfiguration({ custom: props.aiCustom });
1521
+ return actionDone("Source options opened");
1522
+ }
1523
+ });
1524
+ if (aiVisible && props.groomer)
1525
+ actions.push({
1526
+ id: "groom-source",
1527
+ label: "Customize sections\u2026",
1528
+ supports: () => true,
1529
+ run: async () => {
1530
+ setConfiguration({ groomer: props.groomer() });
1531
+ return actionDone("Section options opened");
1532
+ }
1533
+ });
1534
+ if (exportVisible)
1535
+ for (const item of props.export?.items ?? [])
1536
+ actions.push({
1537
+ id: `export:${item.id}`,
1538
+ label: item.label,
1539
+ supports: () => true,
1540
+ ...item.build && !item.onSelect ? {
1541
+ source: make(
1542
+ `export:${item.id}`,
1543
+ async () => {
1544
+ const file = item.build();
1545
+ const bytes = new Uint8Array(
1546
+ await new Blob([file.content], {
1547
+ type: file.mime
1548
+ }).arrayBuffer()
1549
+ );
1550
+ return {
1551
+ kind: "registered",
1552
+ format: "matrx-file",
1553
+ value: {
1554
+ bytes: Array.from(bytes),
1555
+ mime: file.mime,
1556
+ extension: file.extension
1557
+ }
1558
+ };
1559
+ },
1560
+ item.label
1561
+ )
1562
+ } : {},
1563
+ run: async ({ snapshot, draft, signal }) => {
1564
+ if (item.onSelect) {
1565
+ await item.onSelect();
1566
+ return actionDone(`Opened ${item.label}`);
1567
+ }
1568
+ const value = draft.payload.kind === "registered" ? draft.payload.value : null;
1569
+ if (!value || Array.isArray(value) || typeof value !== "object" || !Array.isArray(value.bytes) || typeof value.mime !== "string" || typeof value.extension !== "string" || value.bytes.some(
1570
+ (byte) => typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255
1571
+ ))
1572
+ throw new Error(`${item.label} did not capture a valid file.`);
1573
+ if (draft.omissions.some((omission) => omission.reason !== "duplicate"))
1574
+ throw new Error(
1575
+ "This custom file exceeds the configured export limits or contains excluded content. Use a standard format or revise the source options."
1576
+ );
1577
+ const bytes = new Uint8Array(value.bytes);
1578
+ const filename = `${props.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "export"}.${value.extension.replace(/[^a-zA-Z0-9.-]/g, "") || "bin"}`;
1579
+ return transport.download(
1580
+ sealTransferArtifact2({
1581
+ snapshotId: snapshot.id,
1582
+ draftRevision: draft.revision,
1583
+ format: `export:${item.id}`,
1584
+ plainText: "",
1585
+ file: { filename, mime: value.mime, bytes },
1586
+ omissions: [...draft.omissions]
1587
+ }),
1588
+ signal
1589
+ );
1590
+ }
1591
+ });
1592
+ if (exportVisible && table && props.sendToSheet)
1593
+ actions.push({
1594
+ id: "send-google-sheet",
1595
+ label: "Send to Google Sheet",
1596
+ source: table,
1597
+ supports: () => true,
1598
+ run: async ({ draft }) => {
1599
+ if (draft.payload.kind !== "rows")
1600
+ throw new Error("Google Sheets requires captured rows.");
1601
+ return props.sendToSheet(draft.payload.rows, props.label);
1602
+ }
1603
+ });
1604
+ const source = json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
1605
+ if (!source && !actions.length) return null;
1606
+ const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
1607
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
1608
+ /* @__PURE__ */ jsx8(
1609
+ ContentTransferMenu,
1610
+ {
1611
+ source: target,
1612
+ controllerRef: controller,
1613
+ label: props.label,
1614
+ variants,
1615
+ actions,
1616
+ hide: [
1617
+ ...!copyVisible || !source ? ["copy"] : [],
1618
+ ...!aiVisible || !source ? ["prepare"] : [],
1619
+ ...!exportVisible || !source ? ["download"] : []
1620
+ ],
1621
+ formatSources: {
1622
+ ...human ? { plain: human, markdown: humanMarkdown, html: humanMarkdown } : {},
1623
+ ...json ? { json, "compact-json": json } : {},
1624
+ ...table ? { csv: table, tsv: table } : {}
1625
+ },
1626
+ ...props.disabled !== void 0 ? { disabled: props.disabled } : {},
1627
+ className: cn(
1628
+ props.className,
1629
+ props.size === "xs" && "matrx-alchemy-xs",
1630
+ props.size === "sm" && "matrx-alchemy-sm"
1631
+ ),
1632
+ ...props.stopPropagation !== void 0 ? { stopPropagation: props.stopPropagation } : {}
1633
+ }
1634
+ ),
1635
+ modal?.modal?.({
1636
+ open: true,
1637
+ onOpenChange: (open) => {
1638
+ if (!open) setModal(null);
1639
+ }
1640
+ }),
1641
+ configuration ? /* @__PURE__ */ jsx8(
1642
+ SourceConfiguration,
1643
+ {
1644
+ restoreFocus: () => controller.current?.focusTrigger(),
1645
+ configuration,
1646
+ onClose: () => setConfiguration(null),
1647
+ onPrepare: async (payload, label) => {
1648
+ if (!controller.current)
1649
+ throw new Error("Alchemy is no longer mounted.");
1650
+ await controller.current.prepare(payload, {
1651
+ label,
1652
+ id: `${instance}:configured:${crypto.randomUUID()}`
1653
+ });
1654
+ setConfiguration(null);
1655
+ }
1656
+ },
1657
+ `${instance}:configuration`
1658
+ ) : null
1659
+ ] });
1660
+ }
1661
+ function SourceConfiguration({
1662
+ restoreFocus,
1663
+ configuration,
1664
+ onClose,
1665
+ onPrepare
1666
+ }) {
1667
+ const custom = configuration.custom;
1668
+ const handingOff = React8.useRef(false);
1669
+ const groomer = configuration.groomer;
1670
+ const [values, setValues] = React8.useState(
1671
+ () => Object.fromEntries(
1672
+ custom?.options.map((option) => [option.key, option.default]) ?? []
1673
+ )
1674
+ );
1675
+ const [sections, setSections] = React8.useState(
1676
+ () => Object.fromEntries(
1677
+ groomer?.sections.map((section) => [
1678
+ section.id,
1679
+ section.defaultSelection ?? "full"
1680
+ ]) ?? []
1681
+ )
1682
+ );
1683
+ const [error, setError] = React8.useState(null);
1684
+ const [busy, setBusy] = React8.useState(false);
1685
+ const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
1686
+ let prepared = null;
1687
+ let buildError = null;
611
1688
  let text = "";
612
- let error = null;
613
1689
  try {
614
- const built = source.build(values);
615
- text = tableAgentText(source.wrap(built.text, values, built.meta));
616
- } catch (raw) {
617
- error = raw instanceof Error ? raw.message : String(raw);
1690
+ if (custom) {
1691
+ const result = custom.build(values);
1692
+ prepared = custom.wrap(result.text, values, result.meta);
1693
+ } else if (groomer) {
1694
+ const data = {};
1695
+ const omitted = [];
1696
+ for (const section of groomer.sections) {
1697
+ const level = sections[section.id] ?? "full";
1698
+ if (level === "off") omitted.push(section.id);
1699
+ else {
1700
+ const value = section.build(level);
1701
+ if (value !== void 0 && value !== null) data[section.id] = value;
1702
+ }
1703
+ }
1704
+ prepared = {
1705
+ kind: groomer.kind,
1706
+ location: groomer.location,
1707
+ description: groomer.description,
1708
+ data,
1709
+ ...groomer.summary ? { summary: groomer.summary } : {},
1710
+ attributes: {
1711
+ ...groomer.attributes,
1712
+ dropped_sections: omitted.join(",")
1713
+ },
1714
+ ...groomer.context ? { context: groomer.context } : {}
1715
+ };
1716
+ }
1717
+ text = prepared ? buildAgentPayload(prepared) : "";
1718
+ } catch (cause) {
1719
+ buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
618
1720
  }
619
- return /* @__PURE__ */ jsx10(Dialog, { open: true, onOpenChange: (open) => {
620
- if (!open) onClose();
621
- }, children: /* @__PURE__ */ jsxs5(DialogContent, { children: [
622
- /* @__PURE__ */ jsx10(DialogHeader, { children: /* @__PURE__ */ jsx10(DialogTitle, { children: source.dialogTitle ?? "Custom copy" }) }),
623
- source.dialogDescription ? /* @__PURE__ */ jsx10("p", { className: "text-sm", children: source.dialogDescription }) : null,
624
- source.options.map((option) => /* @__PURE__ */ jsxs5("label", { className: "flex items-center justify-between gap-3 text-sm", children: [
625
- option.label,
626
- option.kind === "toggle" ? /* @__PURE__ */ jsx10("input", { type: "checkbox", checked: values[option.key] === true, onChange: (e) => setValues({ ...values, [option.key]: e.target.checked }) }) : option.kind === "preset" ? /* @__PURE__ */ jsx10("select", { "aria-label": option.label, value: Number(values[option.key]), onChange: (e) => setValues({ ...values, [option.key]: Number(e.target.value) }), children: option.options.map((choice) => /* @__PURE__ */ jsx10("option", { value: choice.value, children: choice.label }, choice.value)) }) : option.kind === "slider" ? /* @__PURE__ */ jsx10("input", { "aria-label": option.label, type: "range", min: 0, max: option.stops.length - 1, step: 1, value: Math.max(0, option.stops.indexOf(Number(values[option.key]))), onChange: (e) => setValues({ ...values, [option.key]: option.stops[Number(e.target.value)] ?? option.default }) }) : /* @__PURE__ */ jsxs5("span", { className: "flex gap-1", children: [
627
- option.presets?.map((choice) => /* @__PURE__ */ jsx10(Button, { type: "button", size: "sm", variant: "outline", onClick: () => setValues({ ...values, [option.key]: choice.value }), children: choice.label }, choice.value)),
628
- /* @__PURE__ */ jsx10("input", { "aria-label": option.label, type: "number", value: Number(values[option.key]), min: option.min, step: option.step, onChange: (e) => {
629
- if (Number.isFinite(e.target.valueAsNumber)) setValues({ ...values, [option.key]: e.target.valueAsNumber });
630
- } })
631
- ] })
632
- ] }, option.key)),
633
- error ? /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-destructive", children: error }) : /* @__PURE__ */ jsx10("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap text-xs", children: text }),
634
- notice,
635
- /* @__PURE__ */ jsxs5(DialogFooter, { children: [
636
- /* @__PURE__ */ jsx10(Button, { type: "button", variant: "outline", onClick: onClose, children: "Close" }),
637
- /* @__PURE__ */ jsx10(Button, { type: "button", disabled: error !== null, onClick: () => void clipboard.copyText(text, "Custom copy copied"), children: "Copy" })
638
- ] })
639
- ] }) });
1721
+ return /* @__PURE__ */ jsx8(
1722
+ Dialog,
1723
+ {
1724
+ open: true,
1725
+ onOpenChange: (open) => {
1726
+ if (!open && !busy) onClose();
1727
+ },
1728
+ children: /* @__PURE__ */ jsxs5(
1729
+ DialogContent,
1730
+ {
1731
+ onCloseAutoFocus: (event) => {
1732
+ event.preventDefault();
1733
+ if (!handingOff.current) restoreFocus();
1734
+ },
1735
+ className: "matrx-alchemy-workspace",
1736
+ children: [
1737
+ /* @__PURE__ */ jsxs5(DialogHeader, { children: [
1738
+ /* @__PURE__ */ jsx8(DialogTitle, { children: title }),
1739
+ /* @__PURE__ */ jsx8(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
1740
+ ] }),
1741
+ /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
1742
+ custom?.options.map((option) => /* @__PURE__ */ jsxs5("label", { children: [
1743
+ option.label,
1744
+ "hint" in option && option.hint ? /* @__PURE__ */ jsx8("small", { children: option.hint }) : null,
1745
+ option.kind === "toggle" ? /* @__PURE__ */ jsx8(
1746
+ "input",
1747
+ {
1748
+ type: "checkbox",
1749
+ checked: Boolean(values[option.key]),
1750
+ onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
1751
+ }
1752
+ ) : option.kind === "preset" ? /* @__PURE__ */ jsx8(
1753
+ "select",
1754
+ {
1755
+ value: Number(values[option.key]),
1756
+ onChange: (event) => setValues({
1757
+ ...values,
1758
+ [option.key]: Number(event.target.value)
1759
+ }),
1760
+ children: option.options.map((choice) => /* @__PURE__ */ jsx8("option", { value: choice.value, children: choice.label }, choice.value))
1761
+ }
1762
+ ) : option.kind === "slider" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
1763
+ /* @__PURE__ */ jsx8(
1764
+ "input",
1765
+ {
1766
+ type: "range",
1767
+ min: 0,
1768
+ max: Math.max(0, option.stops.length - 1),
1769
+ step: 1,
1770
+ value: option.stops.indexOf(Number(values[option.key])),
1771
+ onChange: (event) => setValues({
1772
+ ...values,
1773
+ [option.key]: option.stops[Number(event.target.value)]
1774
+ })
1775
+ }
1776
+ ),
1777
+ /* @__PURE__ */ jsx8("span", { children: option.formatValue(Number(values[option.key])) })
1778
+ ] }) : /* @__PURE__ */ jsxs5(Fragment2, { children: [
1779
+ /* @__PURE__ */ jsx8(
1780
+ "input",
1781
+ {
1782
+ type: "number",
1783
+ min: option.min,
1784
+ step: option.step,
1785
+ value: Number(values[option.key]),
1786
+ onChange: (event) => setValues({
1787
+ ...values,
1788
+ [option.key]: Number(event.target.value)
1789
+ })
1790
+ }
1791
+ ),
1792
+ option.presets?.map((preset) => /* @__PURE__ */ jsx8(
1793
+ Button,
1794
+ {
1795
+ type: "button",
1796
+ variant: "ghost",
1797
+ onClick: () => setValues({ ...values, [option.key]: preset.value }),
1798
+ children: preset.label
1799
+ },
1800
+ preset.value
1801
+ ))
1802
+ ] })
1803
+ ] }, option.key)),
1804
+ groomer ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
1805
+ /* @__PURE__ */ jsx8("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx8(
1806
+ Button,
1807
+ {
1808
+ type: "button",
1809
+ variant: "ghost",
1810
+ onClick: () => setSections(
1811
+ Object.fromEntries(
1812
+ groomer.sections.map((section) => [
1813
+ section.id,
1814
+ level === "brief" && section.cuttable ? "off" : level
1815
+ ])
1816
+ )
1817
+ ),
1818
+ children: level
1819
+ },
1820
+ level
1821
+ )) }),
1822
+ groomer.sections.map((section) => /* @__PURE__ */ jsxs5("label", { children: [
1823
+ section.title,
1824
+ /* @__PURE__ */ jsxs5(
1825
+ "select",
1826
+ {
1827
+ value: sections[section.id],
1828
+ onChange: (event) => setSections({
1829
+ ...sections,
1830
+ [section.id]: event.target.value
1831
+ }),
1832
+ children: [
1833
+ ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx8("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
1834
+ section.cuttable ? /* @__PURE__ */ jsx8("option", { value: "off", children: "Exclude" }) : null
1835
+ ]
1836
+ }
1837
+ ),
1838
+ section.description ? /* @__PURE__ */ jsx8("span", { children: section.description }) : null
1839
+ ] }, section.id))
1840
+ ] }) : null
1841
+ ] }),
1842
+ /* @__PURE__ */ jsxs5("p", { children: [
1843
+ text.length.toLocaleString(),
1844
+ " characters \xB7 approximately",
1845
+ " ",
1846
+ Math.ceil(text.length / 4).toLocaleString(),
1847
+ " tokens"
1848
+ ] }),
1849
+ error || buildError ? /* @__PURE__ */ jsx8("p", { role: "alert", children: error ?? buildError }) : null,
1850
+ /* @__PURE__ */ jsxs5(DialogFooter, { children: [
1851
+ /* @__PURE__ */ jsx8(
1852
+ Button,
1853
+ {
1854
+ type: "button",
1855
+ variant: "ghost",
1856
+ disabled: busy,
1857
+ onClick: onClose,
1858
+ children: "Cancel"
1859
+ }
1860
+ ),
1861
+ /* @__PURE__ */ jsx8(
1862
+ Button,
1863
+ {
1864
+ type: "button",
1865
+ disabled: busy || !prepared || Boolean(buildError),
1866
+ onClick: async () => {
1867
+ if (!prepared) return;
1868
+ setBusy(true);
1869
+ setError(null);
1870
+ try {
1871
+ handingOff.current = true;
1872
+ await onPrepare(structuredPayload(prepared), title);
1873
+ } catch (cause) {
1874
+ handingOff.current = false;
1875
+ setError(
1876
+ cause instanceof Error ? cause.message : "Could not open Alchemy."
1877
+ );
1878
+ } finally {
1879
+ setBusy(false);
1880
+ }
1881
+ },
1882
+ children: busy ? "Preparing\u2026" : "Prepare in Alchemy"
1883
+ }
1884
+ )
1885
+ ] })
1886
+ ]
1887
+ }
1888
+ )
1889
+ }
1890
+ );
1891
+ }
1892
+
1893
+ // src/data-table/host.tsx
1894
+ import { createContext as createContext5, useContext as useContext5 } from "react";
1895
+ import { jsx as jsx9 } from "react/jsx-runtime";
1896
+ var HOST_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.table-host-context");
1897
+ var hostRegistry = globalThis;
1898
+ var HostContext = hostRegistry[HOST_SLOT] ??= createContext5({});
1899
+ function useMatrxDataTableHost() {
1900
+ return useContext5(HostContext);
1901
+ }
1902
+
1903
+ // src/data-table/copy.tsx
1904
+ import { jsx as jsx10 } from "react/jsx-runtime";
1905
+ function CopyButtons(props) {
1906
+ const { CopyControls } = useMatrxDataTableHost();
1907
+ if (CopyControls) return /* @__PURE__ */ jsx10(CopyControls, { ...props });
1908
+ return /* @__PURE__ */ jsx10(MatrxCopyMenu, { ...props });
640
1909
  }
641
1910
 
642
1911
  // src/data-table/MatrxUuidCell.tsx
643
1912
  import {
644
- useEffect as useEffect2,
645
- useRef,
646
- useState as useState5
1913
+ useEffect as useEffect3,
1914
+ useRef as useRef3,
1915
+ useState as useState6
647
1916
  } from "react";
648
1917
 
1918
+ // src/data-table/icons.tsx
1919
+ import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
1920
+ function Icon({ children, ...props }) {
1921
+ return /* @__PURE__ */ jsx11("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", ...props, children });
1922
+ }
1923
+ var Check = (p) => /* @__PURE__ */ jsx11(Icon, { ...p, children: /* @__PURE__ */ jsx11("path", { d: "m5 12 4 4L19 6" }) });
1924
+ var PanelRight = (p) => /* @__PURE__ */ jsxs6(Icon, { ...p, children: [
1925
+ /* @__PURE__ */ jsx11("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }),
1926
+ /* @__PURE__ */ jsx11("path", { d: "M15 4v16" })
1927
+ ] });
1928
+ var ExternalLink = (p) => /* @__PURE__ */ jsx11(Icon, { ...p, children: /* @__PURE__ */ jsx11("path", { d: "M14 4h6v6M20 4l-9 9M19 13v6H5V5h6" }) });
1929
+ var Copy = (p) => /* @__PURE__ */ jsxs6(Icon, { ...p, children: [
1930
+ /* @__PURE__ */ jsx11("rect", { x: "9", y: "9", width: "11", height: "11", rx: "2" }),
1931
+ /* @__PURE__ */ jsx11("path", { d: "M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3" })
1932
+ ] });
1933
+ var Lightbulb = (p) => /* @__PURE__ */ jsx11(Icon, { ...p, children: /* @__PURE__ */ jsx11("path", { d: "M9 18h6M10 22h4M8 14a6 6 0 1 1 8 0c-1 1-1 2-1 3H9c0-1 0-2-1-3z" }) });
1934
+ var ShieldOff = (p) => /* @__PURE__ */ jsx11(Icon, { ...p, children: /* @__PURE__ */ jsx11("path", { d: "m3 3 18 18M12 3l7 3v5c0 4-3 7-7 9-4-2-7-5-7-9V6l4-2" }) });
1935
+
1936
+ // src/data-table/useTableNotice.tsx
1937
+ import { useState as useState5 } from "react";
1938
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
1939
+ function useTableNotice() {
1940
+ const host = useMatrxDataTableHost();
1941
+ const [message, setMessage] = useState5(null);
1942
+ const notify = {
1943
+ success(text) {
1944
+ if (host.notify) host.notify.success(text);
1945
+ else setMessage({ text, error: false });
1946
+ },
1947
+ error(text) {
1948
+ if (host.notify) host.notify.error(text);
1949
+ else setMessage({ text, error: true });
1950
+ }
1951
+ };
1952
+ const notice = message ? /* @__PURE__ */ jsxs7("span", { role: message.error ? "alert" : "status", className: message.error ? "text-xs text-destructive" : "text-xs text-muted-foreground", children: [
1953
+ message.text,
1954
+ /* @__PURE__ */ jsx12("button", { type: "button", "aria-label": "Dismiss notification", className: "ml-2 underline", onClick: () => setMessage(null), children: "Dismiss" })
1955
+ ] }) : null;
1956
+ return { notify, notice };
1957
+ }
1958
+
649
1959
  // src/tooltip.tsx
650
1960
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
651
- import * as React7 from "react";
652
- import { jsx as jsx11 } from "react/jsx-runtime";
1961
+ import * as React9 from "react";
1962
+ import { jsx as jsx13 } from "react/jsx-runtime";
653
1963
  var TooltipProvider = TooltipPrimitive.Provider;
654
1964
  var Tooltip = TooltipPrimitive.Root;
655
1965
  var TooltipTrigger = TooltipPrimitive.Trigger;
656
- var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
1966
+ var TooltipContent = React9.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
657
1967
  const resolved = usePortalContainer(container);
658
- return /* @__PURE__ */ jsx11(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ jsx11(
1968
+ return /* @__PURE__ */ jsx13(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ jsx13(
659
1969
  TooltipPrimitive.Content,
660
1970
  {
661
1971
  ref,
@@ -673,7 +1983,7 @@ var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, container,
673
1983
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
674
1984
 
675
1985
  // src/data-table/MatrxUuidCell.tsx
676
- import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1986
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
677
1987
  var SHORT_LEN = 8;
678
1988
  function shortUuid(id, len = SHORT_LEN) {
679
1989
  return id.slice(0, len);
@@ -712,18 +2022,18 @@ function MatrxUuidCell({
712
2022
  }) {
713
2023
  const { resolveEntityDoors, ResourcePeek } = useMatrxDataTableHost();
714
2024
  const { notify, notice } = useTableNotice();
715
- const [copied, setCopied] = useState5(false);
716
- const [opening, setOpening] = useState5(false);
717
- const [peekOpen, setPeekOpen] = useState5(false);
718
- const timer = useRef(null);
719
- useEffect2(
2025
+ const [copied, setCopied] = useState6(false);
2026
+ const [opening, setOpening] = useState6(false);
2027
+ const [peekOpen, setPeekOpen] = useState6(false);
2028
+ const timer = useRef3(null);
2029
+ useEffect3(
720
2030
  () => () => {
721
2031
  if (timer.current) clearTimeout(timer.current);
722
2032
  },
723
2033
  []
724
2034
  );
725
2035
  if (!value) {
726
- return /* @__PURE__ */ jsx12("span", { className: "text-muted-foreground/40", children: "\u2014" });
2036
+ return /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground/40", children: "\u2014" });
727
2037
  }
728
2038
  const doors = token ? resolveEntityDoors?.(token, value, href) ?? null : null;
729
2039
  const resolvedHref = doors?.href ?? href ?? null;
@@ -766,13 +2076,13 @@ function MatrxUuidCell({
766
2076
  };
767
2077
  const idNode = (() => {
768
2078
  if (forbidden) {
769
- return /* @__PURE__ */ jsxs6("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-muted-foreground/70 tabular-nums", children: [
770
- /* @__PURE__ */ jsx12("span", { className: "min-w-0 truncate", children: display }),
771
- /* @__PURE__ */ jsx12(ShieldOff, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true })
2079
+ return /* @__PURE__ */ jsxs8("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-muted-foreground/70 tabular-nums", children: [
2080
+ /* @__PURE__ */ jsx14("span", { className: "min-w-0 truncate", children: display }),
2081
+ /* @__PURE__ */ jsx14(ShieldOff, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true })
772
2082
  ] });
773
2083
  }
774
2084
  if (onOpen) {
775
- return /* @__PURE__ */ jsxs6(
2085
+ return /* @__PURE__ */ jsxs8(
776
2086
  "button",
777
2087
  {
778
2088
  type: "button",
@@ -781,14 +2091,14 @@ function MatrxUuidCell({
781
2091
  disabled: opening,
782
2092
  className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400 disabled:opacity-60",
783
2093
  children: [
784
- /* @__PURE__ */ jsx12("span", { className: "min-w-0 truncate tabular-nums", children: display }),
785
- /* @__PURE__ */ jsx12(PanelRight, { className: "h-3 w-3 shrink-0 opacity-50" })
2094
+ /* @__PURE__ */ jsx14("span", { className: "min-w-0 truncate tabular-nums", children: display }),
2095
+ /* @__PURE__ */ jsx14(PanelRight, { className: "h-3 w-3 shrink-0 opacity-50" })
786
2096
  ]
787
2097
  }
788
2098
  );
789
2099
  }
790
2100
  if (resolvedHref) {
791
- return /* @__PURE__ */ jsxs6(
2101
+ return /* @__PURE__ */ jsxs8(
792
2102
  "a",
793
2103
  {
794
2104
  href: resolvedHref,
@@ -798,15 +2108,15 @@ function MatrxUuidCell({
798
2108
  onClick: stop,
799
2109
  className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400",
800
2110
  children: [
801
- /* @__PURE__ */ jsx12("span", { className: "min-w-0 truncate tabular-nums", children: display }),
802
- /* @__PURE__ */ jsx12(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-50" })
2111
+ /* @__PURE__ */ jsx14("span", { className: "min-w-0 truncate tabular-nums", children: display }),
2112
+ /* @__PURE__ */ jsx14(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-50" })
803
2113
  ]
804
2114
  }
805
2115
  );
806
2116
  }
807
- return /* @__PURE__ */ jsx12("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
2117
+ return /* @__PURE__ */ jsx14("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
808
2118
  })();
809
- return /* @__PURE__ */ jsxs6(
2119
+ return /* @__PURE__ */ jsxs8(
810
2120
  "span",
811
2121
  {
812
2122
  "data-matrx-cell-control": true,
@@ -816,11 +2126,11 @@ function MatrxUuidCell({
816
2126
  ),
817
2127
  onClick: stop,
818
2128
  children: [
819
- /* @__PURE__ */ jsx12(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs6(Tooltip, { children: [
820
- /* @__PURE__ */ jsx12(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx12("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
821
- /* @__PURE__ */ jsx12(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
2129
+ /* @__PURE__ */ jsx14(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs8(Tooltip, { children: [
2130
+ /* @__PURE__ */ jsx14(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx14("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
2131
+ /* @__PURE__ */ jsx14(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
822
2132
  ] }) }),
823
- /* @__PURE__ */ jsx12(
2133
+ /* @__PURE__ */ jsx14(
824
2134
  "button",
825
2135
  {
826
2136
  type: "button",
@@ -831,10 +2141,10 @@ function MatrxUuidCell({
831
2141
  "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
832
2142
  copied && "text-primary"
833
2143
  ),
834
- children: copied ? /* @__PURE__ */ jsx12(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx12(Copy, { className: "h-3 w-3" })
2144
+ children: copied ? /* @__PURE__ */ jsx14(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx14(Copy, { className: "h-3 w-3" })
835
2145
  }
836
2146
  ),
837
- canPeek ? /* @__PURE__ */ jsx12(
2147
+ canPeek ? /* @__PURE__ */ jsx14(
838
2148
  "button",
839
2149
  {
840
2150
  type: "button",
@@ -845,10 +2155,10 @@ function MatrxUuidCell({
845
2155
  "aria-label": `Quick look at ${label ?? "record"}`,
846
2156
  title: `Quick look at ${label ?? "record"}`,
847
2157
  className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
848
- children: /* @__PURE__ */ jsx12(Lightbulb, { className: "h-3 w-3" })
2158
+ children: /* @__PURE__ */ jsx14(Lightbulb, { className: "h-3 w-3" })
849
2159
  }
850
2160
  ) : null,
851
- onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ jsx12(
2161
+ onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ jsx14(
852
2162
  "a",
853
2163
  {
854
2164
  href: resolvedHref,
@@ -858,12 +2168,12 @@ function MatrxUuidCell({
858
2168
  "aria-label": `Open ${label ?? "record"} in a new tab`,
859
2169
  title: `Open ${label ?? "record"} in a new tab`,
860
2170
  className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
861
- children: /* @__PURE__ */ jsx12(ExternalLink, { className: "h-3 w-3" })
2171
+ children: /* @__PURE__ */ jsx14(ExternalLink, { className: "h-3 w-3" })
862
2172
  }
863
2173
  ) : null,
864
2174
  trailing,
865
2175
  notice,
866
- canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ jsx12(
2176
+ canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ jsx14(
867
2177
  ResourcePeek,
868
2178
  {
869
2179
  kind: doors?.peekKind ?? token ?? "record",
@@ -883,7 +2193,7 @@ function isUuidValue(value) {
883
2193
  }
884
2194
 
885
2195
  // src/data-table/DataRowInspector.tsx
886
- import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
2196
+ import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
887
2197
  var noFieldToken = () => null;
888
2198
  function formatValue(value) {
889
2199
  if (value == null) return "\u2014";
@@ -912,7 +2222,7 @@ function DataRowInspector({
912
2222
  tokenForField = noFieldToken
913
2223
  }) {
914
2224
  const entries = isPlainObject(row) ? Object.entries(row) : [["value", row]];
915
- const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ jsx13("div", { className: "absolute right-1 top-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/field:opacity-100", children: /* @__PURE__ */ jsx13(
2225
+ const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ jsx15("div", { className: "absolute right-1 top-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/field:opacity-100", children: /* @__PURE__ */ jsx15(
916
2226
  CopyButtons,
917
2227
  {
918
2228
  size: "xs",
@@ -927,21 +2237,21 @@ function DataRowInspector({
927
2237
  })
928
2238
  }
929
2239
  ) }) : null;
930
- return /* @__PURE__ */ jsxs7(
2240
+ return /* @__PURE__ */ jsxs9(
931
2241
  "div",
932
2242
  {
933
2243
  className: cn("flex h-full min-h-0 flex-col overflow-hidden", className),
934
2244
  children: [
935
- title ? /* @__PURE__ */ jsx13("div", { className: "shrink-0 border-b border-border px-3 py-2 text-sm font-medium", children: title }) : null,
936
- /* @__PURE__ */ jsx13("div", { className: "min-h-0 flex-1 overflow-auto p-3", children: /* @__PURE__ */ jsx13("dl", { className: "space-y-2", children: entries.map(([key, value]) => {
2245
+ title ? /* @__PURE__ */ jsx15("div", { className: "shrink-0 border-b border-border px-3 py-2 text-sm font-medium", children: title }) : null,
2246
+ /* @__PURE__ */ jsx15("div", { className: "min-h-0 flex-1 overflow-auto p-3", children: /* @__PURE__ */ jsx15("dl", { className: "space-y-2", children: entries.map(([key, value]) => {
937
2247
  if (isUuidValue(value)) {
938
- return /* @__PURE__ */ jsxs7(
2248
+ return /* @__PURE__ */ jsxs9(
939
2249
  "div",
940
2250
  {
941
2251
  className: "group/field relative grid grid-cols-[minmax(7rem,9rem)_1fr] gap-2 rounded-md border border-border/60 bg-muted/20 px-2.5 py-2",
942
2252
  children: [
943
- /* @__PURE__ */ jsx13("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
944
- /* @__PURE__ */ jsx13("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx13(
2253
+ /* @__PURE__ */ jsx15("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
2254
+ /* @__PURE__ */ jsx15("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx15(
945
2255
  MatrxUuidCell,
946
2256
  {
947
2257
  value,
@@ -956,13 +2266,13 @@ function DataRowInspector({
956
2266
  }
957
2267
  const formatted = formatValue(value);
958
2268
  const multiline = formatted.includes("\n") || formatted.length > 80;
959
- return /* @__PURE__ */ jsxs7(
2269
+ return /* @__PURE__ */ jsxs9(
960
2270
  "div",
961
2271
  {
962
2272
  className: "group/field relative grid grid-cols-[minmax(7rem,9rem)_1fr] gap-2 rounded-md border border-border/60 bg-muted/20 py-2 pl-2.5 pr-12",
963
2273
  children: [
964
- /* @__PURE__ */ jsx13("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
965
- /* @__PURE__ */ jsx13(
2274
+ /* @__PURE__ */ jsx15("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
2275
+ /* @__PURE__ */ jsx15(
966
2276
  "dd",
967
2277
  {
968
2278
  className: cn(