@ai-matrx/design-system 0.18.10 → 0.18.12

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 (62) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/content-transfer/alchemy.svg +1 -1
  3. package/dist/content-transfer/icon.cjs +3 -1
  4. package/dist/content-transfer/icon.cjs.map +1 -1
  5. package/dist/content-transfer/icon.d.cts +3 -2
  6. package/dist/content-transfer/icon.d.ts +3 -2
  7. package/dist/content-transfer/icon.js +3 -1
  8. package/dist/content-transfer/icon.js.map +1 -1
  9. package/dist/content-transfer.cjs +312 -278
  10. package/dist/content-transfer.cjs.map +1 -1
  11. package/dist/content-transfer.css +87 -24
  12. package/dist/content-transfer.d.cts +1 -1
  13. package/dist/content-transfer.d.ts +1 -1
  14. package/dist/content-transfer.js +312 -278
  15. package/dist/content-transfer.js.map +1 -1
  16. package/dist/data-table/copy-helpers.d.cts +1 -1
  17. package/dist/data-table/copy-helpers.d.ts +1 -1
  18. package/dist/data-table/copy-types.cjs.map +1 -1
  19. package/dist/data-table/copy-types.d.cts +1 -1
  20. package/dist/data-table/copy-types.d.ts +1 -1
  21. package/dist/data-table/data-row-inspector.cjs +314 -277
  22. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  23. package/dist/data-table/data-row-inspector.js +314 -277
  24. package/dist/data-table/data-row-inspector.js.map +1 -1
  25. package/dist/data-table/data-row-window.cjs +314 -277
  26. package/dist/data-table/data-row-window.cjs.map +1 -1
  27. package/dist/data-table/data-row-window.js +314 -277
  28. package/dist/data-table/data-row-window.js.map +1 -1
  29. package/dist/data-table/filter-engine.d.cts +1 -1
  30. package/dist/data-table/filter-engine.d.ts +1 -1
  31. package/dist/data-table/host.cjs.map +1 -1
  32. package/dist/data-table/host.d.cts +16 -2
  33. package/dist/data-table/host.d.ts +16 -2
  34. package/dist/data-table/host.js.map +1 -1
  35. package/dist/data-table/index.cjs +452 -399
  36. package/dist/data-table/index.cjs.map +1 -1
  37. package/dist/data-table/index.d.cts +3 -3
  38. package/dist/data-table/index.d.ts +3 -3
  39. package/dist/data-table/index.js +453 -400
  40. package/dist/data-table/index.js.map +1 -1
  41. package/dist/data-table/infer-filter.d.cts +1 -1
  42. package/dist/data-table/infer-filter.d.ts +1 -1
  43. package/dist/data-table/layered-filters.d.cts +1 -1
  44. package/dist/data-table/layered-filters.d.ts +1 -1
  45. package/dist/data-table/pagination.cjs.map +1 -1
  46. package/dist/data-table/pagination.js.map +1 -1
  47. package/dist/data-table/query-control.d.cts +1 -1
  48. package/dist/data-table/query-control.d.ts +1 -1
  49. package/dist/data-table/types.cjs.map +1 -1
  50. package/dist/data-table/types.d.cts +1 -1
  51. package/dist/data-table/types.d.ts +1 -1
  52. package/dist/data-table/url-state.d.cts +1 -1
  53. package/dist/data-table/url-state.d.ts +1 -1
  54. package/dist/data-table/uuid-cell.cjs.map +1 -1
  55. package/dist/data-table/uuid-cell.js.map +1 -1
  56. package/dist/data-table/xlsx.d.cts +1 -1
  57. package/dist/data-table/xlsx.d.ts +1 -1
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/{types-C2xN6W_q.d.ts → types-BuDKVpeF.d.ts} +2 -1
  61. package/dist/{types-D_tpuk6m.d.cts → types-Dqcb7jXO.d.cts} +2 -1
  62. package/package.json +2 -2
@@ -460,7 +460,8 @@ var PopoverContent = React6.forwardRef(
460
460
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
461
461
 
462
462
  // src/content-transfer/icon.ts
463
- var ALCHEMY_GLYPH_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 5.5h8v11h-8z"/><path d="M8.5 9.5h8v9h-8z"/><path d="m18.5 3 .65 1.85L21 5.5l-1.85.65L18.5 8l-.65-1.85L16 5.5l1.85-.65z"/></svg>';
463
+ var ALCHEMY_GLYPH_PATHS = ["M9 3h6", "M10 3v6l-5.2 8.7A2 2 0 0 0 6.5 21h11a2 2 0 0 0 1.7-3.3L14 9V3", "M8 15h8"];
464
+ var ALCHEMY_GLYPH_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">${ALCHEMY_GLYPH_PATHS.map((d) => `<path d="${d}"/>`).join("")}</svg>`;
464
465
 
465
466
  // src/content-transfer/matrx-copy.tsx
466
467
  import * as React7 from "react";
@@ -617,7 +618,7 @@ function MatrxCopyMenuSession(props) {
617
618
  if (aiVisible && props.aiCustom)
618
619
  actions.push({
619
620
  id: "configure-source",
620
- label: props.aiCustom.label ?? "Customize source\u2026",
621
+ label: props.aiCustom.label ?? "Customize source",
621
622
  ...props.aiCustom.hint ? { hint: props.aiCustom.hint } : {},
622
623
  supports: () => true,
623
624
  run: async () => {
@@ -628,7 +629,7 @@ function MatrxCopyMenuSession(props) {
628
629
  if (aiVisible && props.groomer)
629
630
  actions.push({
630
631
  id: "groom-source",
631
- label: "Customize sections\u2026",
632
+ label: "Customize sections",
632
633
  supports: () => true,
633
634
  run: async () => {
634
635
  setConfiguration({ groomer: props.groomer() });
@@ -738,7 +739,8 @@ function MatrxCopyMenuSession(props) {
738
739
  className: cn(
739
740
  props.className,
740
741
  props.size === "xs" && "matrx-alchemy-xs",
741
- props.size === "sm" && "matrx-alchemy-sm"
742
+ props.size === "sm" && "matrx-alchemy-sm",
743
+ props.size === "toolbar" && "matrx-alchemy-toolbar-target"
742
744
  ),
743
745
  ...props.stopPropagation !== void 0 ? { stopPropagation: props.stopPropagation } : {}
744
746
  }
@@ -843,127 +845,132 @@ function SourceConfiguration({
843
845
  event.preventDefault();
844
846
  if (!handingOff.current) restoreFocus();
845
847
  },
846
- className: "matrx-alchemy-workspace",
848
+ className: "matrx-alchemy-workspace matrx-alchemy-configuration",
847
849
  children: [
848
850
  /* @__PURE__ */ jsxs3(DialogHeader, { children: [
849
851
  /* @__PURE__ */ jsx7(DialogTitle, { children: title }),
850
852
  /* @__PURE__ */ jsx7(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
851
853
  ] }),
852
- /* @__PURE__ */ jsxs3("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
853
- custom?.options.map((option) => /* @__PURE__ */ jsxs3("label", { children: [
854
- option.label,
855
- "hint" in option && option.hint ? /* @__PURE__ */ jsx7("small", { children: option.hint }) : null,
856
- option.kind === "toggle" ? /* @__PURE__ */ jsx7(
857
- "input",
858
- {
859
- type: "checkbox",
860
- checked: Boolean(values[option.key]),
861
- onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
862
- }
863
- ) : option.kind === "preset" ? /* @__PURE__ */ jsx7(
864
- "select",
865
- {
866
- value: Number(values[option.key]),
867
- onChange: (event) => setValues({
868
- ...values,
869
- [option.key]: Number(event.target.value)
870
- }),
871
- children: option.options.map((choice) => /* @__PURE__ */ jsx7("option", { value: choice.value, children: choice.label }, choice.value))
872
- }
873
- ) : option.kind === "slider" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
874
- /* @__PURE__ */ jsx7(
854
+ /* @__PURE__ */ jsxs3("div", { className: "matrx-alchemy-workspace-body", children: [
855
+ /* @__PURE__ */ jsxs3("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
856
+ custom?.options.map((option) => /* @__PURE__ */ jsxs3("label", { children: [
857
+ option.label,
858
+ "hint" in option && option.hint ? /* @__PURE__ */ jsx7("small", { children: option.hint }) : null,
859
+ option.kind === "toggle" ? /* @__PURE__ */ jsx7(
875
860
  "input",
876
861
  {
877
- type: "range",
878
- min: 0,
879
- max: Math.max(0, option.stops.length - 1),
880
- step: 1,
881
- value: option.stops.indexOf(Number(values[option.key])),
882
- onChange: (event) => setValues({
883
- ...values,
884
- [option.key]: option.stops[Number(event.target.value)]
885
- })
862
+ type: "checkbox",
863
+ checked: Boolean(values[option.key]),
864
+ onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
886
865
  }
887
- ),
888
- /* @__PURE__ */ jsx7("span", { children: option.formatValue(Number(values[option.key])) })
889
- ] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
890
- /* @__PURE__ */ jsx7(
891
- "input",
866
+ ) : option.kind === "preset" ? /* @__PURE__ */ jsx7(
867
+ "select",
892
868
  {
893
- type: "number",
894
- min: option.min,
895
- step: option.step,
896
869
  value: Number(values[option.key]),
897
870
  onChange: (event) => setValues({
898
871
  ...values,
899
872
  [option.key]: Number(event.target.value)
900
- })
873
+ }),
874
+ children: option.options.map((choice) => /* @__PURE__ */ jsx7("option", { value: choice.value, children: choice.label }, choice.value))
901
875
  }
902
- ),
903
- option.presets?.map((preset) => /* @__PURE__ */ jsx7(
876
+ ) : option.kind === "slider" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
877
+ /* @__PURE__ */ jsx7(
878
+ "input",
879
+ {
880
+ type: "range",
881
+ min: 0,
882
+ max: Math.max(0, option.stops.length - 1),
883
+ step: 1,
884
+ value: option.stops.indexOf(Number(values[option.key])),
885
+ onChange: (event) => setValues({
886
+ ...values,
887
+ [option.key]: option.stops[Number(event.target.value)]
888
+ })
889
+ }
890
+ ),
891
+ /* @__PURE__ */ jsx7("span", { children: option.formatValue(Number(values[option.key])) })
892
+ ] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
893
+ /* @__PURE__ */ jsx7(
894
+ "input",
895
+ {
896
+ type: "number",
897
+ min: option.min,
898
+ step: option.step,
899
+ value: Number(values[option.key]),
900
+ onChange: (event) => setValues({
901
+ ...values,
902
+ [option.key]: Number(event.target.value)
903
+ })
904
+ }
905
+ ),
906
+ option.presets?.map((preset) => /* @__PURE__ */ jsx7(
907
+ Button,
908
+ {
909
+ type: "button",
910
+ variant: "ghost",
911
+ className: "matrx-alchemy-workspace-secondary",
912
+ onClick: () => setValues({ ...values, [option.key]: preset.value }),
913
+ children: preset.label
914
+ },
915
+ preset.value
916
+ ))
917
+ ] })
918
+ ] }, option.key)),
919
+ groomer ? /* @__PURE__ */ jsxs3(Fragment, { children: [
920
+ /* @__PURE__ */ jsx7("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx7(
904
921
  Button,
905
922
  {
906
923
  type: "button",
907
924
  variant: "ghost",
908
- onClick: () => setValues({ ...values, [option.key]: preset.value }),
909
- children: preset.label
925
+ className: "matrx-alchemy-workspace-secondary",
926
+ onClick: () => setSections(
927
+ Object.fromEntries(
928
+ groomer.sections.map((section) => [
929
+ section.id,
930
+ level === "brief" && section.cuttable ? "off" : level
931
+ ])
932
+ )
933
+ ),
934
+ children: level
910
935
  },
911
- preset.value
912
- ))
913
- ] })
914
- ] }, option.key)),
915
- groomer ? /* @__PURE__ */ jsxs3(Fragment, { children: [
916
- /* @__PURE__ */ jsx7("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx7(
917
- Button,
918
- {
919
- type: "button",
920
- variant: "ghost",
921
- onClick: () => setSections(
922
- Object.fromEntries(
923
- groomer.sections.map((section) => [
924
- section.id,
925
- level === "brief" && section.cuttable ? "off" : level
926
- ])
927
- )
936
+ level
937
+ )) }),
938
+ groomer.sections.map((section) => /* @__PURE__ */ jsxs3("label", { children: [
939
+ section.title,
940
+ /* @__PURE__ */ jsxs3(
941
+ "select",
942
+ {
943
+ value: sections[section.id],
944
+ onChange: (event) => setSections({
945
+ ...sections,
946
+ [section.id]: event.target.value
947
+ }),
948
+ children: [
949
+ ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx7("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
950
+ section.cuttable ? /* @__PURE__ */ jsx7("option", { value: "off", children: "Exclude" }) : null
951
+ ]
952
+ }
928
953
  ),
929
- children: level
930
- },
931
- level
932
- )) }),
933
- groomer.sections.map((section) => /* @__PURE__ */ jsxs3("label", { children: [
934
- section.title,
935
- /* @__PURE__ */ jsxs3(
936
- "select",
937
- {
938
- value: sections[section.id],
939
- onChange: (event) => setSections({
940
- ...sections,
941
- [section.id]: event.target.value
942
- }),
943
- children: [
944
- ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx7("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
945
- section.cuttable ? /* @__PURE__ */ jsx7("option", { value: "off", children: "Exclude" }) : null
946
- ]
947
- }
948
- ),
949
- section.description ? /* @__PURE__ */ jsx7("span", { children: section.description }) : null
950
- ] }, section.id))
951
- ] }) : null
952
- ] }),
953
- /* @__PURE__ */ jsxs3("p", { children: [
954
- text.length.toLocaleString(),
955
- " characters \xB7 approximately",
956
- " ",
957
- Math.ceil(text.length / 4).toLocaleString(),
958
- " tokens"
954
+ section.description ? /* @__PURE__ */ jsx7("span", { children: section.description }) : null
955
+ ] }, section.id))
956
+ ] }) : null
957
+ ] }),
958
+ /* @__PURE__ */ jsxs3("p", { children: [
959
+ text.length.toLocaleString(),
960
+ " characters \xB7 approximately",
961
+ " ",
962
+ Math.ceil(text.length / 4).toLocaleString(),
963
+ " tokens"
964
+ ] }),
965
+ error || buildError ? /* @__PURE__ */ jsx7("p", { role: "alert", children: error ?? buildError }) : null
959
966
  ] }),
960
- error || buildError ? /* @__PURE__ */ jsx7("p", { role: "alert", children: error ?? buildError }) : null,
961
967
  /* @__PURE__ */ jsxs3(DialogFooter, { children: [
962
968
  /* @__PURE__ */ jsx7(
963
969
  Button,
964
970
  {
965
971
  type: "button",
966
972
  variant: "ghost",
973
+ className: "matrx-alchemy-workspace-secondary",
967
974
  disabled: busy,
968
975
  onClick: onClose,
969
976
  children: "Cancel"
@@ -973,6 +980,7 @@ function SourceConfiguration({
973
980
  Button,
974
981
  {
975
982
  type: "button",
983
+ className: "matrx-alchemy-workspace-primary",
976
984
  disabled: busy || !prepared || Boolean(buildError),
977
985
  onClick: async () => {
978
986
  if (!prepared) return;
@@ -1061,11 +1069,7 @@ function groomerPresetVariants(getConfig) {
1061
1069
  // src/content-transfer/index.tsx
1062
1070
  import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1063
1071
  function AlchemyGlyph(props) {
1064
- 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: [
1065
- /* @__PURE__ */ jsx8("path", { d: "M4.5 5.5h8v11h-8z" }),
1066
- /* @__PURE__ */ jsx8("path", { d: "M8.5 9.5h8v9h-8z" }),
1067
- /* @__PURE__ */ jsx8("path", { d: "m18.5 3 .65 1.85L21 5.5l-1.85.65L18.5 8l-.65-1.85L16 5.5l1.85-.65z" })
1068
- ] });
1072
+ return /* @__PURE__ */ jsx8("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: ALCHEMY_GLYPH_PATHS.map((d) => /* @__PURE__ */ jsx8("path", { d }, d)) });
1069
1073
  }
1070
1074
  var CapabilityContext = React8.createContext({});
1071
1075
  function ContentTransferCapabilitiesProvider({ value, children }) {
@@ -1086,7 +1090,16 @@ function MenuPresentation({ label, hint, icon: Icon }) {
1086
1090
  ] })
1087
1091
  ] });
1088
1092
  }
1089
- function PaletteGlyph({ format, ai = false, file = false }) {
1093
+ function PaletteGlyph({ format, ai = false, file = false, kind }) {
1094
+ if (kind === "ai-copy") return /* @__PURE__ */ jsxs4("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1095
+ /* @__PURE__ */ jsx8("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
1096
+ /* @__PURE__ */ jsx8("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
1097
+ /* @__PURE__ */ jsx8("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
1098
+ ] });
1099
+ if (kind === "sliders") return /* @__PURE__ */ jsxs4("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1100
+ /* @__PURE__ */ jsx8("path", { d: "M4 6h16M4 12h16M4 18h16" }),
1101
+ /* @__PURE__ */ jsx8("path", { d: "M8 3v6M16 9v6M10 15v6" })
1102
+ ] });
1090
1103
  if (ai) return /* @__PURE__ */ jsxs4("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1091
1104
  /* @__PURE__ */ jsx8("path", { d: "M12 5a3 3 0 1 0-5.997.125A4 4 0 0 0 3.5 10.9a4 4 0 0 0 .556 6.588A4 4 0 0 0 12 19" }),
1092
1105
  /* @__PURE__ */ jsx8("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.503 5.775 4 4 0 0 1-.556 6.588A4 4 0 0 1 12 19" }),
@@ -1119,15 +1132,15 @@ function PaletteGlyph({ format, ai = false, file = false }) {
1119
1132
  ] }) : format === "html" ? /* @__PURE__ */ jsx8(Fragment2, { children: /* @__PURE__ */ jsx8("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ jsx8(Fragment2, { children: /* @__PURE__ */ jsx8("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
1120
1133
  return /* @__PURE__ */ jsx8("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: path });
1121
1134
  }
1122
- function PaletteRows({ title, items, onRun, extra, ai = false }) {
1135
+ function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
1123
1136
  if (!items.length && !extra) return null;
1124
1137
  return /* @__PURE__ */ jsxs4("section", { className: "matrx-alchemy-palette-section", children: [
1125
1138
  /* @__PURE__ */ jsx8("h3", { children: title }),
1126
1139
  items.map((item) => /* @__PURE__ */ jsxs4("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel, onClick: () => onRun?.(item), children: [
1127
- item.icon ? /* @__PURE__ */ jsx8(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ jsx8(PaletteGlyph, { ai }),
1140
+ item.icon ? /* @__PURE__ */ jsx8(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ jsx8(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
1128
1141
  /* @__PURE__ */ jsxs4("span", { children: [
1129
1142
  item.copyLabel ?? item.label,
1130
- item.hint ? /* @__PURE__ */ jsx8("small", { className: "matrx-alchemy-menu-hint", children: item.hint }) : null
1143
+ item.hint ?? fallbackHint ? /* @__PURE__ */ jsx8("small", { className: "matrx-alchemy-menu-hint", children: item.hint ?? fallbackHint }) : null
1131
1144
  ] })
1132
1145
  ] }, item.id)),
1133
1146
  extra
@@ -1524,45 +1537,54 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
1524
1537
  }, children: [
1525
1538
  /* @__PURE__ */ jsx8(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx8("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__ */ jsx8(AlchemyGlyph, {}) }) }),
1526
1539
  /* @__PURE__ */ jsxs4(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
1527
- copyAvailable && downloadAvailable ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
1528
- /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
1529
- /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
1530
- ] }) : null,
1531
1540
  menuStatus === "loading" ? /* @__PURE__ */ jsx8("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ jsx8("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
1532
- resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1533
- /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-palette-grid", children: [
1534
- visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
1535
- visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
1536
- ] }),
1537
- quickVariants("copy").length ? /* @__PURE__ */ jsx8(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
1541
+ copyAvailable || downloadAvailable ? /* @__PURE__ */ jsxs4("section", { className: "matrx-alchemy-output", children: [
1542
+ /* @__PURE__ */ jsx8("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
1543
+ copyAvailable && downloadAvailable ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
1544
+ /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
1545
+ /* @__PURE__ */ jsx8("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
1546
+ ] }) : null,
1547
+ resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1548
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-palette-grid", children: [
1549
+ visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
1550
+ visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
1551
+ ] }),
1552
+ quickVariants("copy").length ? /* @__PURE__ */ jsx8(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
1553
+ closePalette();
1554
+ void transfer("markdown", false, variant);
1555
+ } }) : null
1556
+ ] }) : null,
1557
+ resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ jsx8(Fragment2, { children: /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-palette-grid", children: [
1558
+ visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
1559
+ visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
1560
+ downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
1561
+ ] }) }) : null
1562
+ ] }) : null,
1563
+ prepareAvailable ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1564
+ /* @__PURE__ */ jsx8(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", items: quickVariants("ai"), onRun: (variant) => {
1538
1565
  closePalette();
1539
1566
  void transfer("markdown", false, variant);
1540
- } }) : null
1567
+ } }),
1568
+ /* @__PURE__ */ jsx8(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ jsxs4("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
1569
+ closePalette();
1570
+ void openWorkspace();
1571
+ }, children: [
1572
+ /* @__PURE__ */ jsx8(PaletteGlyph, { kind: "sliders" }),
1573
+ /* @__PURE__ */ jsxs4("span", { children: [
1574
+ "Prepare for AI",
1575
+ /* @__PURE__ */ jsx8("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
1576
+ ] })
1577
+ ] }) })
1541
1578
  ] }) : null,
1542
- resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ jsx8(Fragment2, { children: /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-palette-grid", children: [
1543
- visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
1544
- visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
1545
- downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
1546
- ] }) }) : null,
1547
- prepareAvailable ? /* @__PURE__ */ jsx8(PaletteRows, { title: "Prepare", ai: true, items: quickVariants("ai"), onRun: (variant) => {
1548
- closePalette();
1549
- void transfer("markdown", false, variant);
1550
- }, extra: /* @__PURE__ */ jsxs4("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
1551
- closePalette();
1552
- void openWorkspace();
1553
- }, children: [
1554
- /* @__PURE__ */ jsx8(PaletteGlyph, { ai: true }),
1555
- /* @__PURE__ */ jsx8("span", { children: "Prepare for AI\u2026" })
1556
- ] }) }) : null,
1557
- prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ jsx8(PaletteRows, { title: "Context", items: [], extra: /* @__PURE__ */ jsxs4(Fragment2, { children: [
1579
+ prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ jsx8(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ jsxs4(Fragment2, { children: [
1558
1580
  nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ jsx8("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
1559
1581
  closePalette();
1560
1582
  void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
1561
- }, children: /* @__PURE__ */ jsx8("span", { children: "Prepare this surface\u2026" }) }) : null,
1583
+ }, children: /* @__PURE__ */ jsx8("span", { children: "Prepare this surface" }) }) : null,
1562
1584
  variants.map((variant) => /* @__PURE__ */ jsx8("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
1563
1585
  closePalette();
1564
1586
  void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
1565
- }, children: /* @__PURE__ */ jsx8(MenuPresentation, { ...variant, label: `Prepare ${variant.label}\u2026` }) }, variant.id))
1587
+ }, children: /* @__PURE__ */ jsx8(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
1566
1588
  ] }) }) : null,
1567
1589
  ordinaryActions.length ? /* @__PURE__ */ jsx8(PaletteRows, { title: "Actions", items: [], extra: ordinaryActions.map((action) => /* @__PURE__ */ jsx8("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
1568
1590
  closePalette();
@@ -1840,137 +1862,138 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1840
1862
  state.snapshot.label
1841
1863
  ] }),
1842
1864
  /* @__PURE__ */ jsxs4(DialogDescription, { children: [
1843
- "Captured ",
1844
- state.snapshot.unsavedChanges ? "from your unsaved draft" : "as an immutable snapshot",
1845
- ". Your source is never edited."
1865
+ state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
1866
+ "Review and edit this copy. Your original stays unchanged."
1846
1867
  ] })
1847
1868
  ] }),
1848
- /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-workspace-grid", children: [
1849
- /* @__PURE__ */ jsxs4("section", { className: "matrx-alchemy-main", children: [
1850
- /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-toolbar", children: [
1851
- scopes.length > 1 ? /* @__PURE__ */ jsxs4("label", { children: [
1852
- "Scope",
1853
- /* @__PURE__ */ jsx8("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ jsx8("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
1854
- ] }) : null,
1855
- /* @__PURE__ */ jsxs4("label", { children: [
1856
- "Detail",
1857
- /* @__PURE__ */ jsxs4("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
1858
- /* @__PURE__ */ jsx8("option", { value: "full", children: "Full" }),
1859
- /* @__PURE__ */ jsx8("option", { value: "compact", children: "Compact" }),
1860
- /* @__PURE__ */ jsx8("option", { value: "brief", children: "Brief" }),
1861
- /* @__PURE__ */ jsx8("option", { value: "custom", children: "Custom" })
1862
- ] })
1863
- ] }),
1864
- /* @__PURE__ */ jsx8(Button, { type: "button", size: "sm", variant: "outline", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
1865
- setBufferError(null);
1866
- if (controlsHistory.length) {
1867
- const next = controlsHistory[controlsHistory.length - 1];
1869
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-workspace-body", children: [
1870
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-workspace-grid", children: [
1871
+ /* @__PURE__ */ jsxs4("section", { className: "matrx-alchemy-main", children: [
1872
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-toolbar", children: [
1873
+ scopes.length > 1 ? /* @__PURE__ */ jsxs4("label", { children: [
1874
+ "Scope",
1875
+ /* @__PURE__ */ jsx8("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ jsx8("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
1876
+ ] }) : null,
1877
+ /* @__PURE__ */ jsxs4("label", { children: [
1878
+ "Detail",
1879
+ /* @__PURE__ */ jsxs4("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
1880
+ /* @__PURE__ */ jsx8("option", { value: "full", children: "Full" }),
1881
+ /* @__PURE__ */ jsx8("option", { value: "compact", children: "Compact" }),
1882
+ /* @__PURE__ */ jsx8("option", { value: "brief", children: "Brief" }),
1883
+ /* @__PURE__ */ jsx8("option", { value: "custom", children: "Custom" })
1884
+ ] })
1885
+ ] }),
1886
+ /* @__PURE__ */ jsx8(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
1887
+ setBufferError(null);
1888
+ if (controlsHistory.length) {
1889
+ const next = controlsHistory[controlsHistory.length - 1];
1890
+ setControls(next);
1891
+ setControlsHistory((history) => history.slice(0, -1));
1892
+ onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1893
+ } else onChange({ ...state, draft: undoDraft(state.draft), error: void 0 });
1894
+ }, children: "Undo" }),
1895
+ /* @__PURE__ */ jsx8(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
1896
+ const next = initialControls(state);
1868
1897
  setControls(next);
1869
- setControlsHistory((history) => history.slice(0, -1));
1898
+ setControlsHistory([]);
1899
+ setPendingControls(null);
1900
+ setBufferError(null);
1870
1901
  onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1871
- } else onChange({ ...state, draft: undoDraft(state.draft), error: void 0 });
1872
- }, children: "Undo" }),
1873
- /* @__PURE__ */ jsx8(Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => {
1874
- const next = initialControls(state);
1875
- setControls(next);
1876
- setControlsHistory([]);
1877
- setPendingControls(null);
1878
- setBufferError(null);
1879
- onChange({ ...state, draft: rebuild(state, next), error: void 0 });
1880
- }, children: "Reset" }),
1881
- /* @__PURE__ */ jsx8(Button, { type: "button", size: "sm", variant: "outline", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
1882
- ] }),
1883
- controls.preset === "custom" && (state.draft.payload.kind === "json" || state.draft.payload.kind === "registered") ? /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1884
- /* @__PURE__ */ jsx8("legend", { children: "JSON limits" }),
1885
- [["maxDepth", "Maximum depth"], ["maxStringChars", "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].map(([key, text]) => /* @__PURE__ */ jsxs4("label", { children: [
1886
- text,
1887
- /* @__PURE__ */ jsx8("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1888
- ] }, key))
1889
- ] }) : null,
1890
- rows ? /* @__PURE__ */ jsx8(RowControls, { rows, controls, change: changeControls }) : null,
1891
- state.snapshot.sections.length ? /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1892
- /* @__PURE__ */ jsx8("legend", { children: "Sections" }),
1893
- state.snapshot.sections.map((section) => /* @__PURE__ */ jsxs4("label", { children: [
1894
- /* @__PURE__ */ jsx8("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) }) }),
1895
- " ",
1896
- section.label
1897
- ] }, section.id))
1898
- ] }) : null,
1899
- /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-coverage", children: [
1900
- /* @__PURE__ */ jsxs4("span", { children: [
1901
- state.snapshot.coverage.included.toLocaleString(),
1902
- " included",
1903
- state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
1904
- " \xB7 ",
1905
- state.snapshot.coverage.status
1902
+ }, children: "Reset" }),
1903
+ /* @__PURE__ */ jsx8(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
1906
1904
  ] }),
1907
- state.snapshot.coverage.reason ? /* @__PURE__ */ jsx8("span", { children: state.snapshot.coverage.reason }) : null,
1908
- limitText ? /* @__PURE__ */ jsxs4("span", { children: [
1909
- "Limits: ",
1910
- limitText
1905
+ controls.preset === "custom" && (state.draft.payload.kind === "json" || state.draft.payload.kind === "registered") ? /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1906
+ /* @__PURE__ */ jsx8("legend", { children: "JSON limits" }),
1907
+ [["maxDepth", "Maximum depth"], ["maxStringChars", "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].map(([key, text]) => /* @__PURE__ */ jsxs4("label", { children: [
1908
+ text,
1909
+ /* @__PURE__ */ jsx8("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
1910
+ ] }, key))
1911
1911
  ] }) : null,
1912
- displayedOmissions.length ? /* @__PURE__ */ jsxs4("details", { children: [
1913
- /* @__PURE__ */ jsxs4("summary", { children: [
1914
- displayedOmissions.length,
1915
- " omissions or adjustments"
1912
+ rows ? /* @__PURE__ */ jsx8(RowControls, { rows, controls, change: changeControls }) : null,
1913
+ state.snapshot.sections.length ? /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
1914
+ /* @__PURE__ */ jsx8("legend", { children: "Sections" }),
1915
+ state.snapshot.sections.map((section) => /* @__PURE__ */ jsxs4("label", { children: [
1916
+ /* @__PURE__ */ jsx8("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) }) }),
1917
+ " ",
1918
+ section.label
1919
+ ] }, section.id))
1920
+ ] }) : null,
1921
+ /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-coverage", children: [
1922
+ /* @__PURE__ */ jsxs4("span", { children: [
1923
+ state.snapshot.coverage.included.toLocaleString(),
1924
+ " included",
1925
+ state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
1926
+ " \xB7 ",
1927
+ state.snapshot.coverage.status
1916
1928
  ] }),
1917
- /* @__PURE__ */ jsx8("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ jsxs4("li", { children: [
1918
- o.path || "/",
1919
- ": ",
1920
- o.reason,
1921
- o.count == null ? "" : ` (${o.count})`
1922
- ] }, `${o.path}-${o.reason}-${i}`)) })
1923
- ] }) : null
1924
- ] }),
1925
- /* @__PURE__ */ jsxs4("label", { className: "matrx-alchemy-preview-label", children: [
1926
- "Output format",
1927
- /* @__PURE__ */ jsxs4("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
1928
- formats.map((f) => /* @__PURE__ */ jsx8("option", { value: f, children: LABEL[f] }, f)),
1929
- state.draft.payload.kind === "rows" ? /* @__PURE__ */ jsx8("option", { value: "xlsx", children: "Excel workbook" }) : null,
1930
- workspaceAdapters.map((adapter) => /* @__PURE__ */ jsx8("option", { value: adapter.id, children: adapter.label }, adapter.id))
1931
- ] })
1929
+ state.snapshot.coverage.reason ? /* @__PURE__ */ jsx8("span", { children: state.snapshot.coverage.reason }) : null,
1930
+ limitText ? /* @__PURE__ */ jsxs4("span", { children: [
1931
+ "Limits: ",
1932
+ limitText
1933
+ ] }) : null,
1934
+ displayedOmissions.length ? /* @__PURE__ */ jsxs4("details", { children: [
1935
+ /* @__PURE__ */ jsxs4("summary", { children: [
1936
+ displayedOmissions.length,
1937
+ " omissions or adjustments"
1938
+ ] }),
1939
+ /* @__PURE__ */ jsx8("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ jsxs4("li", { children: [
1940
+ o.path || "/",
1941
+ ": ",
1942
+ o.reason,
1943
+ o.count == null ? "" : ` (${o.count})`
1944
+ ] }, `${o.path}-${o.reason}-${i}`)) })
1945
+ ] }) : null
1946
+ ] }),
1947
+ /* @__PURE__ */ jsxs4("label", { className: "matrx-alchemy-preview-label", children: [
1948
+ "Output format",
1949
+ /* @__PURE__ */ jsxs4("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
1950
+ formats.map((f) => /* @__PURE__ */ jsx8("option", { value: f, children: LABEL[f] }, f)),
1951
+ state.draft.payload.kind === "rows" ? /* @__PURE__ */ jsx8("option", { value: "xlsx", children: "Excel workbook" }) : null,
1952
+ workspaceAdapters.map((adapter) => /* @__PURE__ */ jsx8("option", { value: adapter.id, children: adapter.label }, adapter.id))
1953
+ ] })
1954
+ ] }),
1955
+ /* @__PURE__ */ jsx8("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) }),
1956
+ bufferError ? /* @__PURE__ */ jsx8("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
1957
+ formatError ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
1958
+ bufferError ? /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
1959
+ const fallback = editDraft(state.draft, { kind: "text", text: buffer });
1960
+ setBufferError(null);
1961
+ onChange({ ...state, draft: fallback, error: void 0 });
1962
+ setFormat("plain");
1963
+ }, children: "Use invalid JSON as plain text" }) : null
1932
1964
  ] }),
1933
- /* @__PURE__ */ jsx8("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) }),
1934
- bufferError ? /* @__PURE__ */ jsx8("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
1935
- formatError ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
1936
- bufferError ? /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
1937
- const fallback = editDraft(state.draft, { kind: "text", text: buffer });
1938
- setBufferError(null);
1939
- onChange({ ...state, draft: fallback, error: void 0 });
1940
- setFormat("plain");
1941
- }, children: "Use invalid JSON as plain text" }) : null
1965
+ ai || busy === "capture" || state.error ? /* @__PURE__ */ jsxs4("aside", { children: [
1966
+ ai ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1967
+ /* @__PURE__ */ jsxs4("label", { children: [
1968
+ "AI instruction",
1969
+ /* @__PURE__ */ jsx8("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
1970
+ ] }),
1971
+ /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
1972
+ busy === "ai" ? /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
1973
+ ] }) : null,
1974
+ busy === "capture" ? /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
1975
+ activeCapture.current?.abort();
1976
+ activeCapture.current = null;
1977
+ setBusy(null);
1978
+ }, children: "Stop loading rows" }) : null,
1979
+ ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
1980
+ ai ? /* @__PURE__ */ jsx8("p", { className: "matrx-alchemy-meta", children: "AI updates the preview; copy it when you are ready. Closing this window lets the AI run continue." }) : null,
1981
+ state.error ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
1982
+ ] }) : null
1942
1983
  ] }),
1943
- ai || busy === "capture" || state.error ? /* @__PURE__ */ jsxs4("aside", { children: [
1944
- ai ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1945
- /* @__PURE__ */ jsxs4("label", { children: [
1946
- "AI instruction",
1947
- /* @__PURE__ */ jsx8("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
1948
- ] }),
1949
- /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
1950
- busy === "ai" ? /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
1951
- ] }) : null,
1952
- busy === "capture" ? /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => {
1953
- activeCapture.current?.abort();
1954
- activeCapture.current = null;
1955
- setBusy(null);
1956
- }, children: "Stop loading rows" }) : null,
1957
- ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
1958
- ai ? /* @__PURE__ */ jsx8("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
1959
- state.error ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
1960
- ] }) : null
1984
+ pendingControls ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1985
+ /* @__PURE__ */ jsx8("p", { children: "This control would replace your manual edit." }),
1986
+ /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
1987
+ /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
1988
+ ] }) : null,
1989
+ state.sourceStale ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
1990
+ state.pending ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1991
+ /* @__PURE__ */ jsx8("p", { children: "A fresh source snapshot is ready." }),
1992
+ /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
1993
+ /* @__PURE__ */ jsx8(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
1994
+ ] }) : null,
1995
+ deliveryNotice ? /* @__PURE__ */ jsx8("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
1961
1996
  ] }),
1962
- pendingControls ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1963
- /* @__PURE__ */ jsx8("p", { children: "This control would replace your manual edit." }),
1964
- /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
1965
- /* @__PURE__ */ jsx8(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
1966
- ] }) : null,
1967
- state.sourceStale ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
1968
- state.pending ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
1969
- /* @__PURE__ */ jsx8("p", { children: "A fresh source snapshot is ready." }),
1970
- /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
1971
- /* @__PURE__ */ jsx8(Button, { type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
1972
- ] }) : null,
1973
- deliveryNotice ? /* @__PURE__ */ jsx8("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null,
1974
1997
  /* @__PURE__ */ jsxs4(DialogFooter, { children: [
1975
1998
  /* @__PURE__ */ jsxs4("span", { className: "matrx-alchemy-meta", children: [
1976
1999
  buffer.length.toLocaleString(),
@@ -1978,13 +2001,16 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1978
2001
  estimateTokens(buffer).toLocaleString(),
1979
2002
  " tokens"
1980
2003
  ] }),
1981
- /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: close, children: "Close" }),
1982
- /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download prepared output" }),
1983
- /* @__PURE__ */ jsx8(Button, { type: "button", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy prepared output" })
2004
+ /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
2005
+ /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", "aria-label": "Download prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download" }),
2006
+ /* @__PURE__ */ jsx8(Button, { type: "button", className: "matrx-alchemy-workspace-primary", "aria-label": "Copy prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy" })
1984
2007
  ] })
1985
2008
  ] }) });
1986
2009
  }
1987
2010
  function RowControls({ rows, controls, change }) {
2011
+ const filterCount = Object.values(controls.filters).filter(Boolean).length;
2012
+ const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
2013
+ const dataSummary = [controls.search ? "search active" : "", controls.sort ? `sorted by ${rows.columns.find((column) => column.id === controls.sort)?.label ?? controls.sort}` : "", filterCount ? `${filterCount} filter${filterCount === 1 ? "" : "s"}` : ""].filter(Boolean).join(" \xB7 ");
1988
2014
  return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1989
2015
  /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-toolbar", children: [
1990
2016
  /* @__PURE__ */ jsxs4("label", { children: [
@@ -2010,32 +2036,40 @@ function RowControls({ rows, controls, change }) {
2010
2036
  /* @__PURE__ */ jsx8("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
2011
2037
  ] })
2012
2038
  ] }),
2013
- /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
2014
- /* @__PURE__ */ jsx8("legend", { children: "Columns and filters" }),
2015
- rows.columns.map((column) => /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-column", children: [
2039
+ /* @__PURE__ */ jsxs4("details", { className: "matrx-alchemy-options", children: [
2040
+ /* @__PURE__ */ jsxs4("summary", { children: [
2041
+ "Columns and filters",
2042
+ dataSummary ? ` \u2014 ${dataSummary}` : ""
2043
+ ] }),
2044
+ /* @__PURE__ */ jsx8("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-column", children: [
2016
2045
  /* @__PURE__ */ jsxs4("label", { children: [
2017
2046
  /* @__PURE__ */ jsx8("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) }) }),
2018
2047
  " ",
2019
2048
  column.label
2020
2049
  ] }),
2021
2050
  /* @__PURE__ */ jsx8("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 } }) })
2022
- ] }, column.id))
2051
+ ] }, column.id)) })
2023
2052
  ] }),
2024
- /* @__PURE__ */ jsxs4("fieldset", { className: "matrx-alchemy-options", children: [
2025
- /* @__PURE__ */ jsx8("legend", { children: "Rows" }),
2026
- /* @__PURE__ */ jsxs4("label", { children: [
2027
- /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
2028
- " Only selected rows"
2053
+ /* @__PURE__ */ jsxs4("details", { className: "matrx-alchemy-options", children: [
2054
+ /* @__PURE__ */ jsxs4("summary", { children: [
2055
+ "Rows \u2014 ",
2056
+ selectionSummary
2029
2057
  ] }),
2030
- /* @__PURE__ */ jsx8("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
2031
- const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String(readTransferCell(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
2032
- return /* @__PURE__ */ jsxs4("label", { children: [
2033
- /* @__PURE__ */ jsx8("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) }) }),
2034
- " Row ",
2035
- index + 1,
2036
- summary ? ` \u2014 ${summary}` : ""
2037
- ] }, index);
2038
- }) })
2058
+ /* @__PURE__ */ jsxs4("fieldset", { "aria-label": "Row selection", children: [
2059
+ /* @__PURE__ */ jsxs4("label", { children: [
2060
+ /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
2061
+ " Only selected rows"
2062
+ ] }),
2063
+ /* @__PURE__ */ jsx8("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
2064
+ const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String(readTransferCell(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
2065
+ return /* @__PURE__ */ jsxs4("label", { children: [
2066
+ /* @__PURE__ */ jsx8("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) }) }),
2067
+ " Row ",
2068
+ index + 1,
2069
+ summary ? ` \u2014 ${summary}` : ""
2070
+ ] }, index);
2071
+ }) })
2072
+ ] })
2039
2073
  ] })
2040
2074
  ] });
2041
2075
  }