@ai-matrx/design-system 0.18.22 → 0.19.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.
- package/CHANGELOG.md +8 -0
- package/dist/content-transfer/alchemy.svg +1 -1
- package/dist/content-transfer/copy-transform.svg +1 -0
- package/dist/content-transfer/icon.cjs +8 -2
- package/dist/content-transfer/icon.cjs.map +1 -1
- package/dist/content-transfer/icon.d.cts +5 -3
- package/dist/content-transfer/icon.d.ts +5 -3
- package/dist/content-transfer/icon.js +8 -2
- package/dist/content-transfer/icon.js.map +1 -1
- package/dist/content-transfer/portal.svg +1 -0
- package/dist/content-transfer.cjs +923 -304
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.css +17 -74
- package/dist/content-transfer.d.cts +14 -3
- package/dist/content-transfer.d.ts +14 -3
- package/dist/content-transfer.js +929 -305
- package/dist/content-transfer.js.map +1 -1
- package/dist/data-table/copy-helpers.d.cts +1 -1
- package/dist/data-table/copy-helpers.d.ts +1 -1
- package/dist/data-table/data-row-inspector.cjs +990 -397
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +988 -390
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +989 -396
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +987 -389
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/filter-engine.d.cts +1 -1
- package/dist/data-table/filter-engine.d.ts +1 -1
- package/dist/data-table/host.d.cts +1 -1
- package/dist/data-table/host.d.ts +1 -1
- package/dist/data-table/index.cjs +1628 -1007
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +2 -2
- package/dist/data-table/index.d.ts +2 -2
- package/dist/data-table/index.js +1480 -854
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +1 -1
- package/dist/data-table/infer-filter.d.ts +1 -1
- package/dist/data-table/layered-filters.d.cts +1 -1
- package/dist/data-table/layered-filters.d.ts +1 -1
- package/dist/data-table/pagination.cjs +1 -1
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +1 -1
- package/dist/data-table/pagination.js.map +1 -1
- package/dist/data-table/query-control.d.cts +1 -1
- package/dist/data-table/query-control.d.ts +1 -1
- package/dist/data-table/scroll-pagination.cjs +82 -54
- package/dist/data-table/scroll-pagination.cjs.map +1 -1
- package/dist/data-table/scroll-pagination.js +82 -54
- package/dist/data-table/scroll-pagination.js.map +1 -1
- package/dist/data-table/types.d.cts +1 -1
- package/dist/data-table/types.d.ts +1 -1
- package/dist/data-table/url-state.d.cts +1 -1
- package/dist/data-table/url-state.d.ts +1 -1
- package/dist/data-table/uuid-cell.cjs +1 -1
- package/dist/data-table/uuid-cell.cjs.map +1 -1
- package/dist/data-table/uuid-cell.js +1 -1
- package/dist/data-table/uuid-cell.js.map +1 -1
- package/dist/data-table/xlsx.d.cts +1 -1
- package/dist/data-table/xlsx.d.ts +1 -1
- package/dist/index.cjs +527 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +531 -0
- package/dist/index.js.map +1 -1
- package/dist/tap-target.cjs +636 -0
- package/dist/tap-target.cjs.map +1 -0
- package/dist/tap-target.css +151 -0
- package/dist/tap-target.d.cts +131 -0
- package/dist/tap-target.d.ts +131 -0
- package/dist/tap-target.js +608 -0
- package/dist/tap-target.js.map +1 -0
- package/dist/{types-Cbnj1Qlm.d.ts → types-D1m14boM.d.ts} +1 -1
- package/dist/{types-CWW4Tur-.d.cts → types-Di6QT0P1.d.cts} +1 -1
- package/package.json +14 -1
package/dist/content-transfer.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
4
|
// src/content-transfer/index.tsx
|
|
5
|
-
import * as
|
|
6
|
-
import { createPortal } from "react-dom";
|
|
5
|
+
import * as React9 from "react";
|
|
6
|
+
import { createPortal, flushSync } from "react-dom";
|
|
7
7
|
import {
|
|
8
8
|
applySectionSelection,
|
|
9
9
|
applyTransferLimits,
|
|
10
10
|
capture,
|
|
11
|
+
buildAgentPayload as buildAgentPayload2,
|
|
11
12
|
collectAllMatching,
|
|
12
13
|
createBrowserTransport as createBrowserTransport2,
|
|
13
14
|
createDraft,
|
|
@@ -460,12 +461,529 @@ var PopoverContent = React6.forwardRef(
|
|
|
460
461
|
);
|
|
461
462
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
462
463
|
|
|
464
|
+
// src/tap-target/tap-target-button.tsx
|
|
465
|
+
import {
|
|
466
|
+
cloneElement,
|
|
467
|
+
forwardRef as forwardRef5,
|
|
468
|
+
isValidElement
|
|
469
|
+
} from "react";
|
|
470
|
+
|
|
471
|
+
// src/tooltip.tsx
|
|
472
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
473
|
+
import * as React7 from "react";
|
|
474
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
475
|
+
var Tooltip = TooltipPrimitive.Root;
|
|
476
|
+
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
477
|
+
var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
|
|
478
|
+
const resolved = usePortalContainer(container);
|
|
479
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ jsx7(
|
|
480
|
+
TooltipPrimitive.Content,
|
|
481
|
+
{
|
|
482
|
+
ref,
|
|
483
|
+
"data-slot": "tooltip-content",
|
|
484
|
+
sideOffset,
|
|
485
|
+
className: cn(
|
|
486
|
+
"z-[10001] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md",
|
|
487
|
+
animated && MOTION_POPPER,
|
|
488
|
+
className
|
|
489
|
+
),
|
|
490
|
+
...props
|
|
491
|
+
}
|
|
492
|
+
) });
|
|
493
|
+
});
|
|
494
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
495
|
+
|
|
496
|
+
// src/tap-target/cn.ts
|
|
497
|
+
function cn2(...values) {
|
|
498
|
+
return values.filter(Boolean).join(" ").trim();
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// src/tap-target/link.ts
|
|
502
|
+
var LINK_SLOT = /* @__PURE__ */ Symbol.for("@ai-matrx/tap-target:link-component");
|
|
503
|
+
function getTapTargetLinkComponent() {
|
|
504
|
+
return globalThis[LINK_SLOT] ?? null;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// src/tap-target/tap-target-button.tsx
|
|
508
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
509
|
+
var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
|
|
510
|
+
var TAP_OUTER_CLASS = "matrx-tap-target group";
|
|
511
|
+
var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
|
|
512
|
+
function IconContent({
|
|
513
|
+
icon,
|
|
514
|
+
children,
|
|
515
|
+
strokeWidth = 2,
|
|
516
|
+
className
|
|
517
|
+
}) {
|
|
518
|
+
if (icon) {
|
|
519
|
+
if (isValidElement(icon)) {
|
|
520
|
+
return cloneElement(icon, {
|
|
521
|
+
className: cn2(className, icon.props.className)
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return /* @__PURE__ */ jsx8("span", { className, children: icon });
|
|
525
|
+
}
|
|
526
|
+
return /* @__PURE__ */ jsx8(
|
|
527
|
+
"svg",
|
|
528
|
+
{
|
|
529
|
+
className,
|
|
530
|
+
fill: "none",
|
|
531
|
+
viewBox: "0 0 24 24",
|
|
532
|
+
stroke: "currentColor",
|
|
533
|
+
strokeWidth,
|
|
534
|
+
children
|
|
535
|
+
}
|
|
536
|
+
);
|
|
537
|
+
}
|
|
538
|
+
function resolveTapGeometry(label, size, mobileIconOnly) {
|
|
539
|
+
const inline = Boolean(label);
|
|
540
|
+
if (size === "sm") {
|
|
541
|
+
return {
|
|
542
|
+
outerClassName: inline && mobileIconOnly ? "matrx-tap-target matrx-tap-target-sm matrx-tap-target-mobile-icon-only-sm group" : inline ? "matrx-tap-target matrx-tap-target-sm matrx-tap-target-inline-sm group" : TAP_GROUP_OUTER_CLASS,
|
|
543
|
+
inlineModifier: mobileIconOnly ? "matrx-tap-pill-mobile-icon-only-sm" : "matrx-tap-pill-inline-sm"
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
return {
|
|
547
|
+
outerClassName: inline && mobileIconOnly ? `${TAP_OUTER_CLASS} matrx-tap-target-mobile-icon-only` : inline ? `${TAP_OUTER_CLASS} matrx-tap-target-inline` : TAP_OUTER_CLASS,
|
|
548
|
+
inlineModifier: mobileIconOnly ? "matrx-tap-pill-mobile-icon-only" : "matrx-tap-pill-inline"
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function buildTapInner({
|
|
552
|
+
label,
|
|
553
|
+
pillClassName,
|
|
554
|
+
iconClassName,
|
|
555
|
+
labelClassName,
|
|
556
|
+
inlineModifier,
|
|
557
|
+
icon,
|
|
558
|
+
children,
|
|
559
|
+
strokeWidth = 2
|
|
560
|
+
}) {
|
|
561
|
+
const iconEl = /* @__PURE__ */ jsx8(
|
|
562
|
+
IconContent,
|
|
563
|
+
{
|
|
564
|
+
icon,
|
|
565
|
+
strokeWidth,
|
|
566
|
+
className: iconClassName,
|
|
567
|
+
children
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
|
|
571
|
+
if (!label) {
|
|
572
|
+
return /* @__PURE__ */ jsx8("div", { className: pillClasses, children: iconEl });
|
|
573
|
+
}
|
|
574
|
+
return /* @__PURE__ */ jsxs3("div", { className: pillClasses, children: [
|
|
575
|
+
iconEl,
|
|
576
|
+
/* @__PURE__ */ jsx8("span", { className: labelClassName ?? "matrx-tap-label", children: label })
|
|
577
|
+
] });
|
|
578
|
+
}
|
|
579
|
+
function renderTapTarget({
|
|
580
|
+
size = "default",
|
|
581
|
+
pillClassName,
|
|
582
|
+
iconClassName,
|
|
583
|
+
labelClassName,
|
|
584
|
+
icon,
|
|
585
|
+
children,
|
|
586
|
+
strokeWidth,
|
|
587
|
+
label,
|
|
588
|
+
mobileIconOnly = false,
|
|
589
|
+
onClick,
|
|
590
|
+
as,
|
|
591
|
+
htmlFor,
|
|
592
|
+
ariaLabel,
|
|
593
|
+
disabled,
|
|
594
|
+
href,
|
|
595
|
+
target,
|
|
596
|
+
rel,
|
|
597
|
+
prefetch,
|
|
598
|
+
linkComponent,
|
|
599
|
+
tooltip,
|
|
600
|
+
tooltipSide,
|
|
601
|
+
tooltipAlign,
|
|
602
|
+
rest,
|
|
603
|
+
buttonRef
|
|
604
|
+
}) {
|
|
605
|
+
const { outerClassName, inlineModifier } = resolveTapGeometry(
|
|
606
|
+
label,
|
|
607
|
+
size,
|
|
608
|
+
mobileIconOnly
|
|
609
|
+
);
|
|
610
|
+
const responsiveLabelClassName = mobileIconOnly ? `${labelClassName ?? "matrx-tap-label"} matrx-tap-label-mobile-icon-only` : labelClassName;
|
|
611
|
+
const inner = buildTapInner({
|
|
612
|
+
label,
|
|
613
|
+
pillClassName,
|
|
614
|
+
iconClassName,
|
|
615
|
+
labelClassName: responsiveLabelClassName,
|
|
616
|
+
inlineModifier: label ? inlineModifier : "",
|
|
617
|
+
icon,
|
|
618
|
+
children,
|
|
619
|
+
strokeWidth
|
|
620
|
+
});
|
|
621
|
+
const resolvedTooltip = tooltip !== void 0 ? tooltip : label ? false : void 0;
|
|
622
|
+
const triggerAriaLabel = label && !mobileIconOnly ? void 0 : ariaLabel ?? label;
|
|
623
|
+
const trigger = renderTrigger({
|
|
624
|
+
href,
|
|
625
|
+
target,
|
|
626
|
+
rel,
|
|
627
|
+
prefetch,
|
|
628
|
+
linkComponent,
|
|
629
|
+
as,
|
|
630
|
+
htmlFor,
|
|
631
|
+
onClick,
|
|
632
|
+
ariaLabel: triggerAriaLabel,
|
|
633
|
+
disabled,
|
|
634
|
+
outerClassName,
|
|
635
|
+
children: inner,
|
|
636
|
+
rest,
|
|
637
|
+
buttonRef
|
|
638
|
+
});
|
|
639
|
+
return withTooltip(trigger, {
|
|
640
|
+
tooltip: resolvedTooltip,
|
|
641
|
+
ariaLabel: triggerAriaLabel,
|
|
642
|
+
disabled,
|
|
643
|
+
tooltipSide,
|
|
644
|
+
tooltipAlign
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
function renderTrigger({
|
|
648
|
+
href,
|
|
649
|
+
target,
|
|
650
|
+
rel,
|
|
651
|
+
prefetch,
|
|
652
|
+
linkComponent,
|
|
653
|
+
as,
|
|
654
|
+
htmlFor,
|
|
655
|
+
onClick,
|
|
656
|
+
ariaLabel,
|
|
657
|
+
disabled,
|
|
658
|
+
outerClassName,
|
|
659
|
+
children,
|
|
660
|
+
rest,
|
|
661
|
+
buttonRef
|
|
662
|
+
}) {
|
|
663
|
+
if (disabled && href) {
|
|
664
|
+
return /* @__PURE__ */ jsx8(
|
|
665
|
+
"span",
|
|
666
|
+
{
|
|
667
|
+
"aria-disabled": "true",
|
|
668
|
+
"aria-label": ariaLabel,
|
|
669
|
+
className: `${outerClassName} opacity-40 pointer-events-none`,
|
|
670
|
+
children
|
|
671
|
+
}
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
if (href) {
|
|
675
|
+
const isExternal = EXTERNAL_RE.test(href);
|
|
676
|
+
if (isExternal) {
|
|
677
|
+
return /* @__PURE__ */ jsx8(
|
|
678
|
+
"a",
|
|
679
|
+
{
|
|
680
|
+
href,
|
|
681
|
+
target: target ?? "_blank",
|
|
682
|
+
rel: rel ?? "noopener noreferrer",
|
|
683
|
+
"aria-label": ariaLabel,
|
|
684
|
+
className: outerClassName,
|
|
685
|
+
children
|
|
686
|
+
}
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
const Link = linkComponent ?? getTapTargetLinkComponent();
|
|
690
|
+
if (Link) {
|
|
691
|
+
return /* @__PURE__ */ jsx8(
|
|
692
|
+
Link,
|
|
693
|
+
{
|
|
694
|
+
href,
|
|
695
|
+
target,
|
|
696
|
+
rel,
|
|
697
|
+
prefetch,
|
|
698
|
+
"aria-label": ariaLabel,
|
|
699
|
+
className: outerClassName,
|
|
700
|
+
children
|
|
701
|
+
}
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
return /* @__PURE__ */ jsx8(
|
|
705
|
+
"a",
|
|
706
|
+
{
|
|
707
|
+
href,
|
|
708
|
+
target,
|
|
709
|
+
rel,
|
|
710
|
+
"aria-label": ariaLabel,
|
|
711
|
+
className: outerClassName,
|
|
712
|
+
children
|
|
713
|
+
}
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
if (as === "label") {
|
|
717
|
+
return /* @__PURE__ */ jsx8(
|
|
718
|
+
"label",
|
|
719
|
+
{
|
|
720
|
+
htmlFor,
|
|
721
|
+
"aria-label": ariaLabel,
|
|
722
|
+
className: outerClassName,
|
|
723
|
+
children
|
|
724
|
+
}
|
|
725
|
+
);
|
|
726
|
+
}
|
|
727
|
+
return /* @__PURE__ */ jsx8(
|
|
728
|
+
"button",
|
|
729
|
+
{
|
|
730
|
+
ref: buttonRef,
|
|
731
|
+
type: "button",
|
|
732
|
+
onClick,
|
|
733
|
+
"aria-label": ariaLabel,
|
|
734
|
+
disabled,
|
|
735
|
+
...rest,
|
|
736
|
+
className: outerClassName,
|
|
737
|
+
children
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
function withTooltip(trigger, {
|
|
742
|
+
tooltip,
|
|
743
|
+
ariaLabel,
|
|
744
|
+
disabled,
|
|
745
|
+
tooltipSide = "top",
|
|
746
|
+
tooltipAlign = "center"
|
|
747
|
+
}) {
|
|
748
|
+
if (tooltip === false) return trigger;
|
|
749
|
+
const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
|
|
750
|
+
if (!label) return trigger;
|
|
751
|
+
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
752
|
+
/* @__PURE__ */ jsx8(TooltipTrigger, { asChild: true, children: disabled ? (
|
|
753
|
+
// Radix Tooltip triggers need a hoverable element; a disabled button
|
|
754
|
+
// does not dispatch pointer events, so we wrap in a span for the
|
|
755
|
+
// trigger target while keeping the disabled visual state.
|
|
756
|
+
/* @__PURE__ */ jsx8("span", { className: "inline-flex", children: trigger })
|
|
757
|
+
) : trigger }),
|
|
758
|
+
/* @__PURE__ */ jsx8(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
|
|
759
|
+
] });
|
|
760
|
+
}
|
|
761
|
+
var TapTargetButton = forwardRef5(function TapTargetButton2({
|
|
762
|
+
icon,
|
|
763
|
+
children,
|
|
764
|
+
strokeWidth = 2,
|
|
765
|
+
onClick,
|
|
766
|
+
className,
|
|
767
|
+
as,
|
|
768
|
+
htmlFor,
|
|
769
|
+
ariaLabel,
|
|
770
|
+
disabled,
|
|
771
|
+
href,
|
|
772
|
+
target,
|
|
773
|
+
rel,
|
|
774
|
+
prefetch,
|
|
775
|
+
linkComponent,
|
|
776
|
+
tooltip,
|
|
777
|
+
tooltipSide,
|
|
778
|
+
tooltipAlign,
|
|
779
|
+
label,
|
|
780
|
+
mobileIconOnly,
|
|
781
|
+
...rest
|
|
782
|
+
}, ref) {
|
|
783
|
+
const color = className ?? "text-foreground";
|
|
784
|
+
return renderTapTarget({
|
|
785
|
+
icon,
|
|
786
|
+
children,
|
|
787
|
+
strokeWidth,
|
|
788
|
+
onClick,
|
|
789
|
+
as,
|
|
790
|
+
htmlFor,
|
|
791
|
+
ariaLabel,
|
|
792
|
+
disabled,
|
|
793
|
+
href,
|
|
794
|
+
target,
|
|
795
|
+
rel,
|
|
796
|
+
prefetch,
|
|
797
|
+
linkComponent,
|
|
798
|
+
tooltip,
|
|
799
|
+
tooltipSide,
|
|
800
|
+
tooltipAlign,
|
|
801
|
+
label,
|
|
802
|
+
mobileIconOnly,
|
|
803
|
+
pillClassName: "matrx-tap-pill matrx-glass-thin-border",
|
|
804
|
+
iconClassName: `matrx-tap-icon ${color}`,
|
|
805
|
+
rest,
|
|
806
|
+
buttonRef: ref
|
|
807
|
+
});
|
|
808
|
+
});
|
|
809
|
+
var TapTargetButtonTransparent = forwardRef5(function TapTargetButtonTransparent2({
|
|
810
|
+
icon,
|
|
811
|
+
children,
|
|
812
|
+
strokeWidth = 2,
|
|
813
|
+
onClick,
|
|
814
|
+
className,
|
|
815
|
+
as,
|
|
816
|
+
htmlFor,
|
|
817
|
+
ariaLabel,
|
|
818
|
+
disabled,
|
|
819
|
+
href,
|
|
820
|
+
target,
|
|
821
|
+
rel,
|
|
822
|
+
prefetch,
|
|
823
|
+
linkComponent,
|
|
824
|
+
tooltip,
|
|
825
|
+
tooltipSide,
|
|
826
|
+
tooltipAlign,
|
|
827
|
+
label,
|
|
828
|
+
mobileIconOnly,
|
|
829
|
+
...rest
|
|
830
|
+
}, ref) {
|
|
831
|
+
const color = className ?? "text-foreground";
|
|
832
|
+
return renderTapTarget({
|
|
833
|
+
icon,
|
|
834
|
+
children,
|
|
835
|
+
strokeWidth,
|
|
836
|
+
onClick,
|
|
837
|
+
as,
|
|
838
|
+
htmlFor,
|
|
839
|
+
ariaLabel,
|
|
840
|
+
disabled,
|
|
841
|
+
href,
|
|
842
|
+
target,
|
|
843
|
+
rel,
|
|
844
|
+
prefetch,
|
|
845
|
+
linkComponent,
|
|
846
|
+
tooltip,
|
|
847
|
+
tooltipSide,
|
|
848
|
+
tooltipAlign,
|
|
849
|
+
label,
|
|
850
|
+
mobileIconOnly,
|
|
851
|
+
pillClassName: "matrx-tap-pill hover:bg-muted active:bg-muted-foreground/15",
|
|
852
|
+
iconClassName: `matrx-tap-icon ${color}`,
|
|
853
|
+
rest,
|
|
854
|
+
buttonRef: ref
|
|
855
|
+
});
|
|
856
|
+
});
|
|
857
|
+
var TapTargetButtonSolid = forwardRef5(function TapTargetButtonSolid2({
|
|
858
|
+
icon,
|
|
859
|
+
children,
|
|
860
|
+
strokeWidth = 2,
|
|
861
|
+
onClick,
|
|
862
|
+
as,
|
|
863
|
+
htmlFor,
|
|
864
|
+
ariaLabel,
|
|
865
|
+
disabled,
|
|
866
|
+
href,
|
|
867
|
+
target,
|
|
868
|
+
rel,
|
|
869
|
+
prefetch,
|
|
870
|
+
linkComponent,
|
|
871
|
+
bgColor = "bg-primary",
|
|
872
|
+
iconColor = "text-primary-foreground",
|
|
873
|
+
hoverBgColor = "hover:bg-primary/80",
|
|
874
|
+
activeBgColor = "active:brightness-90",
|
|
875
|
+
tooltip,
|
|
876
|
+
tooltipSide,
|
|
877
|
+
tooltipAlign,
|
|
878
|
+
label,
|
|
879
|
+
mobileIconOnly,
|
|
880
|
+
...rest
|
|
881
|
+
}, ref) {
|
|
882
|
+
return renderTapTarget({
|
|
883
|
+
icon,
|
|
884
|
+
children,
|
|
885
|
+
strokeWidth,
|
|
886
|
+
onClick,
|
|
887
|
+
as,
|
|
888
|
+
htmlFor,
|
|
889
|
+
ariaLabel,
|
|
890
|
+
disabled,
|
|
891
|
+
href,
|
|
892
|
+
target,
|
|
893
|
+
rel,
|
|
894
|
+
prefetch,
|
|
895
|
+
linkComponent,
|
|
896
|
+
tooltip,
|
|
897
|
+
tooltipSide,
|
|
898
|
+
tooltipAlign,
|
|
899
|
+
label,
|
|
900
|
+
mobileIconOnly,
|
|
901
|
+
pillClassName: `matrx-tap-pill ${bgColor} ${iconColor} ${hoverBgColor} ${activeBgColor}`,
|
|
902
|
+
iconClassName: `matrx-tap-icon ${iconColor}`,
|
|
903
|
+
labelClassName: `matrx-tap-label ${iconColor}`,
|
|
904
|
+
rest,
|
|
905
|
+
buttonRef: ref
|
|
906
|
+
});
|
|
907
|
+
});
|
|
908
|
+
var TapTargetButtonDestructive = forwardRef5(function TapTargetButtonDestructive2({
|
|
909
|
+
bgColor = "bg-destructive",
|
|
910
|
+
iconColor = "text-destructive-foreground",
|
|
911
|
+
hoverBgColor = "hover:bg-destructive/90",
|
|
912
|
+
...rest
|
|
913
|
+
}, ref) {
|
|
914
|
+
return /* @__PURE__ */ jsx8(
|
|
915
|
+
TapTargetButtonSolid,
|
|
916
|
+
{
|
|
917
|
+
ref,
|
|
918
|
+
bgColor,
|
|
919
|
+
iconColor,
|
|
920
|
+
hoverBgColor,
|
|
921
|
+
...rest
|
|
922
|
+
}
|
|
923
|
+
);
|
|
924
|
+
});
|
|
925
|
+
var TapTargetButtonForGroup = forwardRef5(function TapTargetButtonForGroup2({
|
|
926
|
+
icon,
|
|
927
|
+
children,
|
|
928
|
+
strokeWidth = 2,
|
|
929
|
+
onClick,
|
|
930
|
+
className,
|
|
931
|
+
as,
|
|
932
|
+
htmlFor,
|
|
933
|
+
ariaLabel,
|
|
934
|
+
disabled,
|
|
935
|
+
href,
|
|
936
|
+
target,
|
|
937
|
+
rel,
|
|
938
|
+
prefetch,
|
|
939
|
+
linkComponent,
|
|
940
|
+
tooltip,
|
|
941
|
+
tooltipSide,
|
|
942
|
+
tooltipAlign,
|
|
943
|
+
label,
|
|
944
|
+
mobileIconOnly,
|
|
945
|
+
...rest
|
|
946
|
+
}, ref) {
|
|
947
|
+
const color = className ?? "text-foreground";
|
|
948
|
+
return renderTapTarget({
|
|
949
|
+
size: "sm",
|
|
950
|
+
icon,
|
|
951
|
+
children,
|
|
952
|
+
strokeWidth,
|
|
953
|
+
onClick,
|
|
954
|
+
as,
|
|
955
|
+
htmlFor,
|
|
956
|
+
ariaLabel,
|
|
957
|
+
disabled,
|
|
958
|
+
href,
|
|
959
|
+
target,
|
|
960
|
+
rel,
|
|
961
|
+
prefetch,
|
|
962
|
+
linkComponent,
|
|
963
|
+
tooltip,
|
|
964
|
+
tooltipSide,
|
|
965
|
+
tooltipAlign,
|
|
966
|
+
label,
|
|
967
|
+
mobileIconOnly,
|
|
968
|
+
pillClassName: "matrx-tap-pill matrx-tap-pill-sm matrx-glass-interactive",
|
|
969
|
+
iconClassName: `matrx-tap-icon ${color}`,
|
|
970
|
+
labelClassName: `matrx-tap-label ${color}`,
|
|
971
|
+
rest,
|
|
972
|
+
buttonRef: ref
|
|
973
|
+
});
|
|
974
|
+
});
|
|
975
|
+
|
|
463
976
|
// src/content-transfer/icon.ts
|
|
464
|
-
var ALCHEMY_GLYPH_PATHS =
|
|
465
|
-
|
|
977
|
+
var ALCHEMY_GLYPH_PATHS = {
|
|
978
|
+
portal: ["M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4M8 12h8m-3-3 3 3-3 3"],
|
|
979
|
+
"copy-transform": ["M8 7V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v8M13 21H5a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v3m-5 4h11m-3-3 3 3-3 3"]
|
|
980
|
+
};
|
|
981
|
+
var svg = (paths) => `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">${paths.map((d) => `<path d="${d}"/>`).join("")}</svg>`;
|
|
982
|
+
var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal);
|
|
983
|
+
var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"]);
|
|
466
984
|
|
|
467
985
|
// src/content-transfer/matrx-copy.tsx
|
|
468
|
-
import * as
|
|
986
|
+
import * as React8 from "react";
|
|
469
987
|
import {
|
|
470
988
|
buildAgentPayload,
|
|
471
989
|
createBrowserTransport,
|
|
@@ -473,7 +991,7 @@ import {
|
|
|
473
991
|
normalizeTransferJson,
|
|
474
992
|
sealTransferArtifact
|
|
475
993
|
} from "@ai-matrx/kit/content-transfer";
|
|
476
|
-
import { Fragment, jsx as
|
|
994
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
477
995
|
var resolve = (value) => typeof value === "function" ? value() : value;
|
|
478
996
|
var asPayload = (value) => ({
|
|
479
997
|
kind: "markdown",
|
|
@@ -519,7 +1037,7 @@ var sourceFor = (id, label, build) => ({
|
|
|
519
1037
|
});
|
|
520
1038
|
function MatrxCopyMenu(props) {
|
|
521
1039
|
const inherited = useContentTransferCapabilities();
|
|
522
|
-
return /* @__PURE__ */
|
|
1040
|
+
return /* @__PURE__ */ jsx9(
|
|
523
1041
|
MatrxCopyMenuSession,
|
|
524
1042
|
{
|
|
525
1043
|
...props
|
|
@@ -531,12 +1049,12 @@ function MatrxCopyMenu(props) {
|
|
|
531
1049
|
);
|
|
532
1050
|
}
|
|
533
1051
|
function MatrxCopyMenuSession(props) {
|
|
534
|
-
const instance =
|
|
535
|
-
const controller =
|
|
1052
|
+
const instance = React8.useId();
|
|
1053
|
+
const controller = React8.useRef(null);
|
|
536
1054
|
const capabilities = useContentTransferCapabilities();
|
|
537
1055
|
const transport = capabilities.transport ?? createBrowserTransport();
|
|
538
|
-
const [modal, setModal] =
|
|
539
|
-
const [configuration, setConfiguration] =
|
|
1056
|
+
const [modal, setModal] = React8.useState(null);
|
|
1057
|
+
const [configuration, setConfiguration] = React8.useState(null);
|
|
540
1058
|
const copyVisible = !props.hide?.includes("copy");
|
|
541
1059
|
const aiVisible = !props.hide?.includes("ai");
|
|
542
1060
|
const exportVisible = !props.hide?.includes("export");
|
|
@@ -723,11 +1241,13 @@ function MatrxCopyMenuSession(props) {
|
|
|
723
1241
|
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
724
1242
|
if (!source && !actions.length) return null;
|
|
725
1243
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
726
|
-
return /* @__PURE__ */
|
|
727
|
-
/* @__PURE__ */
|
|
1244
|
+
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1245
|
+
/* @__PURE__ */ jsx9(
|
|
728
1246
|
ContentTransferMenu,
|
|
729
1247
|
{
|
|
730
1248
|
source: target,
|
|
1249
|
+
...props.icon !== void 0 ? { icon: props.icon } : {},
|
|
1250
|
+
...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
|
|
731
1251
|
controllerRef: controller,
|
|
732
1252
|
label: props.label,
|
|
733
1253
|
variants,
|
|
@@ -759,7 +1279,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
759
1279
|
if (!open) setModal(null);
|
|
760
1280
|
}
|
|
761
1281
|
}),
|
|
762
|
-
configuration ? /* @__PURE__ */
|
|
1282
|
+
configuration ? /* @__PURE__ */ jsx9(
|
|
763
1283
|
SourceConfiguration,
|
|
764
1284
|
{
|
|
765
1285
|
restoreFocus: () => controller.current?.focusTrigger(),
|
|
@@ -786,14 +1306,14 @@ function SourceConfiguration({
|
|
|
786
1306
|
onPrepare
|
|
787
1307
|
}) {
|
|
788
1308
|
const custom = configuration.custom;
|
|
789
|
-
const handingOff =
|
|
1309
|
+
const handingOff = React8.useRef(false);
|
|
790
1310
|
const groomer = configuration.groomer;
|
|
791
|
-
const [values, setValues] =
|
|
1311
|
+
const [values, setValues] = React8.useState(
|
|
792
1312
|
() => Object.fromEntries(
|
|
793
1313
|
custom?.options.map((option) => [option.key, option.default]) ?? []
|
|
794
1314
|
)
|
|
795
1315
|
);
|
|
796
|
-
const [sections, setSections] =
|
|
1316
|
+
const [sections, setSections] = React8.useState(
|
|
797
1317
|
() => Object.fromEntries(
|
|
798
1318
|
groomer?.sections.map((section) => [
|
|
799
1319
|
section.id,
|
|
@@ -801,8 +1321,8 @@ function SourceConfiguration({
|
|
|
801
1321
|
]) ?? []
|
|
802
1322
|
)
|
|
803
1323
|
);
|
|
804
|
-
const [error, setError] =
|
|
805
|
-
const [busy, setBusy] =
|
|
1324
|
+
const [error, setError] = React8.useState(null);
|
|
1325
|
+
const [busy, setBusy] = React8.useState(false);
|
|
806
1326
|
const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
|
|
807
1327
|
let prepared = null;
|
|
808
1328
|
let buildError = null;
|
|
@@ -839,14 +1359,14 @@ function SourceConfiguration({
|
|
|
839
1359
|
} catch (cause) {
|
|
840
1360
|
buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
|
|
841
1361
|
}
|
|
842
|
-
return /* @__PURE__ */
|
|
1362
|
+
return /* @__PURE__ */ jsx9(
|
|
843
1363
|
Dialog,
|
|
844
1364
|
{
|
|
845
1365
|
open: true,
|
|
846
1366
|
onOpenChange: (open) => {
|
|
847
1367
|
if (!open && !busy) onClose();
|
|
848
1368
|
},
|
|
849
|
-
children: /* @__PURE__ */
|
|
1369
|
+
children: /* @__PURE__ */ jsxs4(
|
|
850
1370
|
DialogContent,
|
|
851
1371
|
{
|
|
852
1372
|
onCloseAutoFocus: (event) => {
|
|
@@ -855,23 +1375,23 @@ function SourceConfiguration({
|
|
|
855
1375
|
},
|
|
856
1376
|
className: "matrx-alchemy-workspace matrx-alchemy-configuration",
|
|
857
1377
|
children: [
|
|
858
|
-
/* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
1378
|
+
/* @__PURE__ */ jsxs4(DialogHeader, { children: [
|
|
1379
|
+
/* @__PURE__ */ jsx9(DialogTitle, { children: title }),
|
|
1380
|
+
/* @__PURE__ */ jsx9(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
|
|
861
1381
|
] }),
|
|
862
|
-
/* @__PURE__ */
|
|
863
|
-
/* @__PURE__ */
|
|
864
|
-
custom?.options.map((option) => /* @__PURE__ */
|
|
1382
|
+
/* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
1383
|
+
/* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
|
|
1384
|
+
custom?.options.map((option) => /* @__PURE__ */ jsxs4("label", { children: [
|
|
865
1385
|
option.label,
|
|
866
|
-
"hint" in option && option.hint ? /* @__PURE__ */
|
|
867
|
-
option.kind === "toggle" ? /* @__PURE__ */
|
|
1386
|
+
"hint" in option && option.hint ? /* @__PURE__ */ jsx9("small", { children: option.hint }) : null,
|
|
1387
|
+
option.kind === "toggle" ? /* @__PURE__ */ jsx9(
|
|
868
1388
|
"input",
|
|
869
1389
|
{
|
|
870
1390
|
type: "checkbox",
|
|
871
1391
|
checked: Boolean(values[option.key]),
|
|
872
1392
|
onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
|
|
873
1393
|
}
|
|
874
|
-
) : option.kind === "preset" ? /* @__PURE__ */
|
|
1394
|
+
) : option.kind === "preset" ? /* @__PURE__ */ jsx9(
|
|
875
1395
|
"select",
|
|
876
1396
|
{
|
|
877
1397
|
value: Number(values[option.key]),
|
|
@@ -879,10 +1399,10 @@ function SourceConfiguration({
|
|
|
879
1399
|
...values,
|
|
880
1400
|
[option.key]: Number(event.target.value)
|
|
881
1401
|
}),
|
|
882
|
-
children: option.options.map((choice) => /* @__PURE__ */
|
|
1402
|
+
children: option.options.map((choice) => /* @__PURE__ */ jsx9("option", { value: choice.value, children: choice.label }, choice.value))
|
|
883
1403
|
}
|
|
884
|
-
) : option.kind === "slider" ? /* @__PURE__ */
|
|
885
|
-
/* @__PURE__ */
|
|
1404
|
+
) : option.kind === "slider" ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1405
|
+
/* @__PURE__ */ jsx9(
|
|
886
1406
|
"input",
|
|
887
1407
|
{
|
|
888
1408
|
type: "range",
|
|
@@ -896,9 +1416,9 @@ function SourceConfiguration({
|
|
|
896
1416
|
})
|
|
897
1417
|
}
|
|
898
1418
|
),
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
] }) : /* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
1419
|
+
/* @__PURE__ */ jsx9("span", { children: option.formatValue(Number(values[option.key])) })
|
|
1420
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1421
|
+
/* @__PURE__ */ jsx9(
|
|
902
1422
|
"input",
|
|
903
1423
|
{
|
|
904
1424
|
type: "number",
|
|
@@ -911,7 +1431,7 @@ function SourceConfiguration({
|
|
|
911
1431
|
})
|
|
912
1432
|
}
|
|
913
1433
|
),
|
|
914
|
-
option.presets?.map((preset) => /* @__PURE__ */
|
|
1434
|
+
option.presets?.map((preset) => /* @__PURE__ */ jsx9(
|
|
915
1435
|
Button,
|
|
916
1436
|
{
|
|
917
1437
|
type: "button",
|
|
@@ -924,8 +1444,8 @@ function SourceConfiguration({
|
|
|
924
1444
|
))
|
|
925
1445
|
] })
|
|
926
1446
|
] }, option.key)),
|
|
927
|
-
groomer ? /* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
1447
|
+
groomer ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1448
|
+
/* @__PURE__ */ jsx9("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx9(
|
|
929
1449
|
Button,
|
|
930
1450
|
{
|
|
931
1451
|
type: "button",
|
|
@@ -943,9 +1463,9 @@ function SourceConfiguration({
|
|
|
943
1463
|
},
|
|
944
1464
|
level
|
|
945
1465
|
)) }),
|
|
946
|
-
groomer.sections.map((section) => /* @__PURE__ */
|
|
1466
|
+
groomer.sections.map((section) => /* @__PURE__ */ jsxs4("label", { children: [
|
|
947
1467
|
section.title,
|
|
948
|
-
/* @__PURE__ */
|
|
1468
|
+
/* @__PURE__ */ jsxs4(
|
|
949
1469
|
"select",
|
|
950
1470
|
{
|
|
951
1471
|
value: sections[section.id],
|
|
@@ -954,26 +1474,26 @@ function SourceConfiguration({
|
|
|
954
1474
|
[section.id]: event.target.value
|
|
955
1475
|
}),
|
|
956
1476
|
children: [
|
|
957
|
-
["full", "compact", "brief"].map((level) => /* @__PURE__ */
|
|
958
|
-
section.cuttable ? /* @__PURE__ */
|
|
1477
|
+
["full", "compact", "brief"].map((level) => /* @__PURE__ */ jsx9("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
|
|
1478
|
+
section.cuttable ? /* @__PURE__ */ jsx9("option", { value: "off", children: "Exclude" }) : null
|
|
959
1479
|
]
|
|
960
1480
|
}
|
|
961
1481
|
),
|
|
962
|
-
section.description ? /* @__PURE__ */
|
|
1482
|
+
section.description ? /* @__PURE__ */ jsx9("span", { children: section.description }) : null
|
|
963
1483
|
] }, section.id))
|
|
964
1484
|
] }) : null
|
|
965
1485
|
] }),
|
|
966
|
-
/* @__PURE__ */
|
|
1486
|
+
/* @__PURE__ */ jsxs4("p", { children: [
|
|
967
1487
|
text.length.toLocaleString(),
|
|
968
1488
|
" characters \xB7 approximately",
|
|
969
1489
|
" ",
|
|
970
1490
|
Math.ceil(text.length / 4).toLocaleString(),
|
|
971
1491
|
" tokens"
|
|
972
1492
|
] }),
|
|
973
|
-
error || buildError ? /* @__PURE__ */
|
|
1493
|
+
error || buildError ? /* @__PURE__ */ jsx9("p", { role: "alert", children: error ?? buildError }) : null
|
|
974
1494
|
] }),
|
|
975
|
-
/* @__PURE__ */
|
|
976
|
-
/* @__PURE__ */
|
|
1495
|
+
/* @__PURE__ */ jsxs4(DialogFooter, { children: [
|
|
1496
|
+
/* @__PURE__ */ jsx9(
|
|
977
1497
|
Button,
|
|
978
1498
|
{
|
|
979
1499
|
type: "button",
|
|
@@ -984,7 +1504,7 @@ function SourceConfiguration({
|
|
|
984
1504
|
children: "Cancel"
|
|
985
1505
|
}
|
|
986
1506
|
),
|
|
987
|
-
/* @__PURE__ */
|
|
1507
|
+
/* @__PURE__ */ jsx9(
|
|
988
1508
|
Button,
|
|
989
1509
|
{
|
|
990
1510
|
type: "button",
|
|
@@ -1075,83 +1595,108 @@ function groomerPresetVariants(getConfig) {
|
|
|
1075
1595
|
}
|
|
1076
1596
|
|
|
1077
1597
|
// src/content-transfer/index.tsx
|
|
1078
|
-
import { Fragment as Fragment2, jsx as
|
|
1079
|
-
function AlchemyGlyph(props) {
|
|
1080
|
-
return /* @__PURE__ */
|
|
1598
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1599
|
+
function AlchemyGlyph({ icon = "portal", ...props }) {
|
|
1600
|
+
return /* @__PURE__ */ jsx10("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[icon].map((d) => /* @__PURE__ */ jsx10("path", { d }, d)) });
|
|
1081
1601
|
}
|
|
1082
|
-
var CapabilityContext =
|
|
1602
|
+
var CapabilityContext = React9.createContext({});
|
|
1083
1603
|
function ContentTransferCapabilitiesProvider({ value, children }) {
|
|
1084
|
-
return /* @__PURE__ */
|
|
1604
|
+
return /* @__PURE__ */ jsx10(CapabilityContext.Provider, { value, children });
|
|
1085
1605
|
}
|
|
1086
|
-
var useContentTransferCapabilities = () =>
|
|
1087
|
-
var SurfaceContext =
|
|
1606
|
+
var useContentTransferCapabilities = () => React9.useContext(CapabilityContext);
|
|
1607
|
+
var SurfaceContext = React9.createContext(null);
|
|
1088
1608
|
function ContentTransferSurfaceProvider({ handle, children }) {
|
|
1089
|
-
return /* @__PURE__ */
|
|
1609
|
+
return /* @__PURE__ */ jsx10(SurfaceContext.Provider, { value: handle, children });
|
|
1090
1610
|
}
|
|
1091
|
-
var useContentTransferSurface = () =>
|
|
1611
|
+
var useContentTransferSurface = () => React9.useContext(SurfaceContext);
|
|
1092
1612
|
function MenuPresentation({ label, hint, icon: Icon }) {
|
|
1093
|
-
return /* @__PURE__ */
|
|
1094
|
-
Icon ? /* @__PURE__ */
|
|
1095
|
-
/* @__PURE__ */
|
|
1613
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1614
|
+
Icon ? /* @__PURE__ */ jsx10(Icon, { className: "matrx-alchemy-menu-icon" }) : null,
|
|
1615
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
1096
1616
|
label,
|
|
1097
|
-
hint ? /* @__PURE__ */
|
|
1617
|
+
hint ? /* @__PURE__ */ jsx10("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1098
1618
|
] })
|
|
1099
1619
|
] });
|
|
1100
1620
|
}
|
|
1621
|
+
function DestinationPresentation({ action }) {
|
|
1622
|
+
const paths = {
|
|
1623
|
+
notes: "M5 3h14v18H5zM8 8h8M8 12h8M8 16h5",
|
|
1624
|
+
scratch: "M5 3h14v18H5zM9 12h6M12 9v6",
|
|
1625
|
+
document: "M6 3h8l4 4v14H6zM14 3v5h4M9 12h6M9 16h6",
|
|
1626
|
+
workbook: "M3 4h18v16H3zM3 9h18M9 4v16M15 9v11M3 15h18",
|
|
1627
|
+
task: "M9 6h11M9 12h11M9 18h11M3 6l1 1 2-2M3 12l1 1 2-2M3 18l1 1 2-2",
|
|
1628
|
+
attach: "m9 12 5-5a3 3 0 0 1 4 4l-7 7a5 5 0 0 1-7-7l8-8M7 14l7-7",
|
|
1629
|
+
code: "m8 6-6 6 6 6m8-12 6 6-6 6m-3-14-2 16",
|
|
1630
|
+
chat: "M4 4h16v13H9l-5 4zM8 9h8M8 13h5",
|
|
1631
|
+
assistant: "M3 4h18v16H3zM15 4v16M6 9h6M6 13h4",
|
|
1632
|
+
tools: "m14 4 3 3 4-1a6 6 0 0 1-8 7l-7 7-3-3 7-7a6 6 0 0 1 4-6z"
|
|
1633
|
+
};
|
|
1634
|
+
const path = paths[action.id.replace(/^matrx:/, "")];
|
|
1635
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1636
|
+
!action.icon ? path ? /* @__PURE__ */ jsx10("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: /* @__PURE__ */ jsx10("path", { d: path }) }) : /* @__PURE__ */ jsx10(PaletteGlyph, { file: true }) : null,
|
|
1637
|
+
/* @__PURE__ */ jsx10(MenuPresentation, { ...action })
|
|
1638
|
+
] });
|
|
1639
|
+
}
|
|
1640
|
+
function ReceiptLink({ target }) {
|
|
1641
|
+
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ jsxs5("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
|
|
1642
|
+
"Open ",
|
|
1643
|
+
target.kind
|
|
1644
|
+
] }) : null;
|
|
1645
|
+
}
|
|
1101
1646
|
function PaletteGlyph({ format, ai = false, file = false, kind }) {
|
|
1102
|
-
if (kind === "ai-copy") return /* @__PURE__ */
|
|
1103
|
-
/* @__PURE__ */
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1647
|
+
if (kind === "ai-copy") return /* @__PURE__ */ jsxs5("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: [
|
|
1648
|
+
/* @__PURE__ */ jsx10("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
|
|
1649
|
+
/* @__PURE__ */ jsx10("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
|
|
1650
|
+
/* @__PURE__ */ jsx10("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
|
|
1106
1651
|
] });
|
|
1107
|
-
if (kind === "sliders") return /* @__PURE__ */
|
|
1108
|
-
/* @__PURE__ */
|
|
1109
|
-
/* @__PURE__ */
|
|
1652
|
+
if (kind === "sliders") return /* @__PURE__ */ jsxs5("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: [
|
|
1653
|
+
/* @__PURE__ */ jsx10("path", { d: "M4 6h16M4 12h16M4 18h16" }),
|
|
1654
|
+
/* @__PURE__ */ jsx10("path", { d: "M8 3v6M16 9v6M10 15v6" })
|
|
1110
1655
|
] });
|
|
1111
|
-
if (ai) return /* @__PURE__ */
|
|
1112
|
-
/* @__PURE__ */
|
|
1113
|
-
/* @__PURE__ */
|
|
1114
|
-
/* @__PURE__ */
|
|
1656
|
+
if (ai) return /* @__PURE__ */ jsxs5("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: [
|
|
1657
|
+
/* @__PURE__ */ jsx10("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" }),
|
|
1658
|
+
/* @__PURE__ */ jsx10("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" }),
|
|
1659
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
|
|
1115
1660
|
] });
|
|
1116
|
-
if (file) return /* @__PURE__ */
|
|
1117
|
-
/* @__PURE__ */
|
|
1118
|
-
/* @__PURE__ */
|
|
1661
|
+
if (file) return /* @__PURE__ */ jsxs5("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: [
|
|
1662
|
+
/* @__PURE__ */ jsx10("path", { d: "M6 3h8l4 4v14H6z" }),
|
|
1663
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
|
|
1119
1664
|
] });
|
|
1120
|
-
const path = format === "json" ? /* @__PURE__ */
|
|
1121
|
-
/* @__PURE__ */
|
|
1122
|
-
/* @__PURE__ */
|
|
1123
|
-
] }) : format === "compact-json" ? /* @__PURE__ */
|
|
1124
|
-
/* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
1126
|
-
/* @__PURE__ */
|
|
1127
|
-
/* @__PURE__ */
|
|
1128
|
-
] }) : format === "csv" ? /* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1131
|
-
] }) : format === "tsv" ? /* @__PURE__ */
|
|
1132
|
-
/* @__PURE__ */
|
|
1133
|
-
/* @__PURE__ */
|
|
1134
|
-
] }) : format === "xlsx" ? /* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
] }) : format === "markdown" ? /* @__PURE__ */
|
|
1138
|
-
/* @__PURE__ */
|
|
1139
|
-
/* @__PURE__ */
|
|
1140
|
-
] }) : format === "html" ? /* @__PURE__ */
|
|
1141
|
-
return /* @__PURE__ */
|
|
1665
|
+
const path = format === "json" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1666
|
+
/* @__PURE__ */ jsx10("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
|
|
1667
|
+
/* @__PURE__ */ jsx10("path", { d: "M15 4c2 0 2 3 4 3v3c-2 0-2 1-2 2s0 2 2 2v3c-2 0-2 3-4 3" })
|
|
1668
|
+
] }) : format === "compact-json" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1669
|
+
/* @__PURE__ */ jsx10("path", { d: "m14 10 7-7" }),
|
|
1670
|
+
/* @__PURE__ */ jsx10("path", { d: "M20 10h-6V4" }),
|
|
1671
|
+
/* @__PURE__ */ jsx10("path", { d: "m3 21 7-7" }),
|
|
1672
|
+
/* @__PURE__ */ jsx10("path", { d: "M4 14h6v6" })
|
|
1673
|
+
] }) : format === "csv" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1674
|
+
/* @__PURE__ */ jsx10("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
|
|
1675
|
+
/* @__PURE__ */ jsx10("path", { d: "M4 10h16M10 4v16" })
|
|
1676
|
+
] }) : format === "tsv" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1677
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1678
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
|
|
1679
|
+
] }) : format === "xlsx" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1680
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1681
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
|
|
1682
|
+
] }) : format === "markdown" ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1683
|
+
/* @__PURE__ */ jsx10("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5z" }),
|
|
1684
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
|
|
1685
|
+
] }) : format === "html" ? /* @__PURE__ */ jsx10(Fragment2, { children: /* @__PURE__ */ jsx10("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ jsx10(Fragment2, { children: /* @__PURE__ */ jsx10("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
|
|
1686
|
+
return /* @__PURE__ */ jsx10("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 });
|
|
1142
1687
|
}
|
|
1143
1688
|
function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
|
|
1144
1689
|
if (!items.length && !extra) return null;
|
|
1145
|
-
return /* @__PURE__ */
|
|
1146
|
-
/* @__PURE__ */
|
|
1690
|
+
return /* @__PURE__ */ jsxs5("section", { className: "matrx-alchemy-palette-section", children: [
|
|
1691
|
+
/* @__PURE__ */ jsx10("h3", { children: title }),
|
|
1147
1692
|
items.map((item) => {
|
|
1148
1693
|
const label = item.copyLabel ?? item.label;
|
|
1149
1694
|
const hint = item.hint ?? fallbackHint;
|
|
1150
|
-
return /* @__PURE__ */
|
|
1151
|
-
item.icon ? /* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1695
|
+
return /* @__PURE__ */ jsxs5("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel ?? `${label}${hint ? ` ${hint}` : ""}`, onClick: () => onRun?.(item), children: [
|
|
1696
|
+
item.icon ? /* @__PURE__ */ jsx10(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ jsx10(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
|
|
1697
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
1153
1698
|
label,
|
|
1154
|
-
hint ? /* @__PURE__ */
|
|
1699
|
+
hint ? /* @__PURE__ */ jsx10("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1155
1700
|
] })
|
|
1156
1701
|
] }, item.id);
|
|
1157
1702
|
}),
|
|
@@ -1194,10 +1739,10 @@ function snapshotContent(snapshot) {
|
|
|
1194
1739
|
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
1195
1740
|
}
|
|
1196
1741
|
function useFence() {
|
|
1197
|
-
const mounted =
|
|
1198
|
-
const nextId =
|
|
1199
|
-
const active =
|
|
1200
|
-
|
|
1742
|
+
const mounted = React9.useRef(true);
|
|
1743
|
+
const nextId = React9.useRef(0);
|
|
1744
|
+
const active = React9.useRef(/* @__PURE__ */ new Set());
|
|
1745
|
+
React9.useEffect(() => {
|
|
1201
1746
|
mounted.current = true;
|
|
1202
1747
|
return () => {
|
|
1203
1748
|
mounted.current = false;
|
|
@@ -1206,14 +1751,14 @@ function useFence() {
|
|
|
1206
1751
|
active.current.clear();
|
|
1207
1752
|
};
|
|
1208
1753
|
}, []);
|
|
1209
|
-
const begin =
|
|
1754
|
+
const begin = React9.useCallback(() => {
|
|
1210
1755
|
const controller = new AbortController();
|
|
1211
1756
|
active.current.add(controller);
|
|
1212
1757
|
return { controller, id: ++nextId.current };
|
|
1213
1758
|
}, []);
|
|
1214
|
-
const finish =
|
|
1215
|
-
const valid =
|
|
1216
|
-
const abortAll =
|
|
1759
|
+
const finish = React9.useCallback((controller) => active.current.delete(controller), []);
|
|
1760
|
+
const valid = React9.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
|
|
1761
|
+
const abortAll = React9.useCallback(() => {
|
|
1217
1762
|
nextId.current += 1;
|
|
1218
1763
|
active.current.forEach((c) => c.abort());
|
|
1219
1764
|
active.current.clear();
|
|
@@ -1242,45 +1787,47 @@ async function buildArtifact(draft, format, label) {
|
|
|
1242
1787
|
return serialize(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
1243
1788
|
}
|
|
1244
1789
|
function ContentTransferMenu(props) {
|
|
1245
|
-
const inherited =
|
|
1790
|
+
const inherited = React9.useContext(CapabilityContext);
|
|
1246
1791
|
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
1247
|
-
return /* @__PURE__ */
|
|
1792
|
+
return /* @__PURE__ */ jsx10(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
1248
1793
|
}
|
|
1249
|
-
function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, sourceFormats = true, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
|
|
1250
|
-
const triggerRef =
|
|
1251
|
-
const inherited =
|
|
1252
|
-
const nearestSurface =
|
|
1794
|
+
function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, sourceFormats = true, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef, icon = "portal", triggerVariant = "transparent" }) {
|
|
1795
|
+
const triggerRef = React9.useRef(null);
|
|
1796
|
+
const inherited = React9.useContext(CapabilityContext);
|
|
1797
|
+
const nearestSurface = React9.useContext(SurfaceContext);
|
|
1253
1798
|
const fence = useFence();
|
|
1254
|
-
const [menuCapture, setMenuCapture] =
|
|
1255
|
-
const [menuStatus, setMenuStatus] =
|
|
1256
|
-
const [workspaces, setWorkspaces] =
|
|
1257
|
-
const [workspaceKey, setWorkspaceKey] =
|
|
1258
|
-
const [workspaceOpen, setWorkspaceOpen] =
|
|
1259
|
-
const workspaceCaptures =
|
|
1260
|
-
const externalWorkspaceKeys =
|
|
1261
|
-
const [notice, setNotice] =
|
|
1262
|
-
const [
|
|
1263
|
-
const [
|
|
1264
|
-
const
|
|
1799
|
+
const [menuCapture, setMenuCapture] = React9.useState(null);
|
|
1800
|
+
const [menuStatus, setMenuStatus] = React9.useState("idle");
|
|
1801
|
+
const [workspaces, setWorkspaces] = React9.useState({});
|
|
1802
|
+
const [workspaceKey, setWorkspaceKey] = React9.useState(null);
|
|
1803
|
+
const [workspaceOpen, setWorkspaceOpen] = React9.useState(false);
|
|
1804
|
+
const workspaceCaptures = React9.useRef(/* @__PURE__ */ new Map());
|
|
1805
|
+
const externalWorkspaceKeys = React9.useRef(/* @__PURE__ */ new Set());
|
|
1806
|
+
const [notice, setNotice] = React9.useState(null);
|
|
1807
|
+
const [receiptTarget, setReceiptTarget] = React9.useState();
|
|
1808
|
+
const [paletteOpen, setPaletteOpen] = React9.useState(false);
|
|
1809
|
+
const [mode, setMode] = React9.useState("copy");
|
|
1810
|
+
const scopes = React9.useMemo(() => table?.availableScopes ?? ["target"], [table]);
|
|
1265
1811
|
const initialScope = table?.initialScope ?? "target";
|
|
1266
1812
|
if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
|
|
1267
1813
|
const primary = surface ?? source ?? nearestSurface;
|
|
1268
1814
|
const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
|
|
1269
1815
|
const primaryWorkspaceKey = `primary:${materialIdentity(primary)}`;
|
|
1270
1816
|
const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
|
|
1271
|
-
const variantWorkspaceKeys =
|
|
1817
|
+
const variantWorkspaceKeys = React9.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
|
|
1272
1818
|
const transport = local?.transport ?? inherited.transport ?? createBrowserTransport2();
|
|
1273
1819
|
const ai = local?.ai ?? inherited.ai;
|
|
1274
|
-
const providerPreferences =
|
|
1275
|
-
const adapters =
|
|
1276
|
-
const registeredActions =
|
|
1277
|
-
|
|
1278
|
-
const report =
|
|
1820
|
+
const providerPreferences = React9.useMemo(() => resolveTransferPreferences(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
|
|
1821
|
+
const adapters = React9.useMemo(() => resolveTransferRegistry(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
|
|
1822
|
+
const registeredActions = React9.useMemo(() => resolveTransferRegistry(inherited.actions ?? [], local?.actions ?? [], actions), [actions, inherited.actions, local?.actions]);
|
|
1823
|
+
React9.useMemo(() => resolveTransferRegistry(variants), [variants]);
|
|
1824
|
+
const report = React9.useCallback((result) => {
|
|
1279
1825
|
inherited.onOutcome?.(result);
|
|
1280
1826
|
local?.onOutcome?.(result);
|
|
1281
1827
|
setNotice(outcomeMessage(result));
|
|
1828
|
+
setReceiptTarget("target" in result ? result.target : void 0);
|
|
1282
1829
|
}, [inherited, local]);
|
|
1283
|
-
|
|
1830
|
+
React9.useEffect(() => {
|
|
1284
1831
|
const valid = /* @__PURE__ */ new Set([primaryWorkspaceKey, ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
|
|
1285
1832
|
setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
|
|
1286
1833
|
for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
|
|
@@ -1289,7 +1836,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1289
1836
|
setWorkspaceOpen(false);
|
|
1290
1837
|
}
|
|
1291
1838
|
}, [nearestWorkspaceKey, primaryWorkspaceKey, variantWorkspaceKeys, workspaceKey]);
|
|
1292
|
-
const captureOne =
|
|
1839
|
+
const captureOne = React9.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
|
|
1293
1840
|
if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
|
|
1294
1841
|
let sourceMaterial;
|
|
1295
1842
|
if ("instanceId" in material) {
|
|
@@ -1323,14 +1870,14 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1323
1870
|
if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
|
|
1324
1871
|
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 } : {} };
|
|
1325
1872
|
}, [preferences, projection, providerPreferences, sections, sourceLabel]);
|
|
1326
|
-
const capturePrimary =
|
|
1873
|
+
const capturePrimary = React9.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
|
|
1327
1874
|
workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
|
|
1328
1875
|
if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
|
|
1329
1876
|
for (const variant of variants) {
|
|
1330
1877
|
const key = variantWorkspaceKeys.get(variant.id);
|
|
1331
1878
|
workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
|
|
1332
1879
|
}
|
|
1333
|
-
const preflight =
|
|
1880
|
+
const preflight = React9.useCallback(async () => {
|
|
1334
1881
|
const { controller, id } = fence.begin();
|
|
1335
1882
|
setMenuCapture(null);
|
|
1336
1883
|
setMenuStatus("loading");
|
|
@@ -1349,7 +1896,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1349
1896
|
fence.finish(controller);
|
|
1350
1897
|
}
|
|
1351
1898
|
}, [captureOne, fence, initialScope, primary]);
|
|
1352
|
-
const transfer =
|
|
1899
|
+
const transfer = React9.useCallback(async (format, download, alternate) => {
|
|
1353
1900
|
const { controller, id } = fence.begin();
|
|
1354
1901
|
try {
|
|
1355
1902
|
const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
|
|
@@ -1374,7 +1921,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1374
1921
|
fence.finish(controller);
|
|
1375
1922
|
}
|
|
1376
1923
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
1377
|
-
const openWorkspace =
|
|
1924
|
+
const openWorkspace = React9.useCallback(
|
|
1378
1925
|
async (key = primaryWorkspaceKey, variant) => {
|
|
1379
1926
|
const variantMaterial = variant && "kind" in variant.source ? {
|
|
1380
1927
|
id: `variant:${key}`,
|
|
@@ -1468,7 +2015,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1468
2015
|
setWorkspaceOpen(true);
|
|
1469
2016
|
} catch (error) {
|
|
1470
2017
|
if (fence.valid(id, controller))
|
|
1471
|
-
|
|
2018
|
+
setReceiptTarget(void 0);
|
|
2019
|
+
setNotice(errorMessage(error, "Could not capture content"));
|
|
1472
2020
|
} finally {
|
|
1473
2021
|
fence.finish(controller);
|
|
1474
2022
|
}
|
|
@@ -1485,7 +2033,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1485
2033
|
workspaces
|
|
1486
2034
|
]
|
|
1487
2035
|
);
|
|
1488
|
-
|
|
2036
|
+
React9.useImperativeHandle(controllerRef, () => ({
|
|
1489
2037
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
1490
2038
|
prepare: async (requestedSource, options) => {
|
|
1491
2039
|
const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
|
|
@@ -1494,14 +2042,15 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1494
2042
|
await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
|
|
1495
2043
|
}
|
|
1496
2044
|
}), [openWorkspace]);
|
|
1497
|
-
const runAction =
|
|
2045
|
+
const runAction = React9.useCallback(async (action) => {
|
|
1498
2046
|
const { controller, id } = fence.begin();
|
|
1499
2047
|
try {
|
|
1500
2048
|
const actionSource = action.source;
|
|
1501
2049
|
const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
|
|
1502
2050
|
const resolved = resolveTransferPreferences(providerPreferences, preferences, snapshot.limits);
|
|
1503
2051
|
const draft = applyTransferLimits(createDraft(snapshot), resolved.limits);
|
|
1504
|
-
if (
|
|
2052
|
+
if (snapshot.coverage.status !== "complete" || draft.omissions.length) throw new Error("This content is partial or requires reductions. Open Prepare for AI to review it before sending it to a destination.");
|
|
2053
|
+
if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
|
|
1505
2054
|
const result = await action.run({ snapshot, draft, signal: controller.signal });
|
|
1506
2055
|
if (fence.valid(id, controller) && draft.snapshotId === snapshot.id) report(result);
|
|
1507
2056
|
} catch (error) {
|
|
@@ -1516,99 +2065,128 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1516
2065
|
const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
|
|
1517
2066
|
const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
|
|
1518
2067
|
const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
|
|
1519
|
-
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot)) : [];
|
|
2068
|
+
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, applyTransferLimits(createDraft(menuCapture.snapshot), resolveTransferPreferences(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
|
|
1520
2069
|
const downloadActions = visibleActions.filter((action) => action.placement === "download");
|
|
1521
2070
|
const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
|
|
2071
|
+
const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
|
|
1522
2072
|
const copyAvailable = !hide.includes("copy") && visibleCopies.length + visibleAdapters.length + quickVariants("copy").length > 0;
|
|
1523
2073
|
const downloadAvailable = !hide.includes("download") && visibleDownloads.length + visibleAdapters.length + downloadActions.length > 0;
|
|
1524
2074
|
const prepareAvailable = !hide.includes("prepare") && (quickVariants("ai").length > 0 || Boolean(primary) || Boolean(nearestWorkspaceKey) || variants.length > 0);
|
|
1525
2075
|
const resolvedMode = mode === "copy" && !copyAvailable ? "download" : mode === "download" && !downloadAvailable ? "copy" : mode;
|
|
2076
|
+
const nativeAiFormat = {
|
|
2077
|
+
id: "ai-context",
|
|
2078
|
+
label: "AI context",
|
|
2079
|
+
supports: () => true,
|
|
2080
|
+
build: async (draft) => {
|
|
2081
|
+
const json = serialize(draft, "json");
|
|
2082
|
+
return sealTransferArtifact2({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: buildAgentPayload2({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
|
|
2083
|
+
}
|
|
2084
|
+
};
|
|
1526
2085
|
const closePalette = () => setPaletteOpen(false);
|
|
1527
2086
|
const tile = (id, label2, onClick, options = {}) => {
|
|
1528
2087
|
const presentation = options.action;
|
|
1529
2088
|
const Icon = presentation?.icon;
|
|
1530
2089
|
const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
|
|
1531
|
-
return /* @__PURE__ */
|
|
2090
|
+
return /* @__PURE__ */ jsxs5("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
|
|
1532
2091
|
closePalette();
|
|
1533
2092
|
onClick();
|
|
1534
2093
|
}, children: [
|
|
1535
|
-
Icon ? /* @__PURE__ */
|
|
1536
|
-
/* @__PURE__ */
|
|
2094
|
+
Icon ? /* @__PURE__ */ jsx10(Icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ jsx10(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
|
|
2095
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
1537
2096
|
label2,
|
|
1538
|
-
presentation?.hint ? /* @__PURE__ */
|
|
2097
|
+
presentation?.hint ? /* @__PURE__ */ jsx10("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
|
|
1539
2098
|
] })
|
|
1540
2099
|
] }, id);
|
|
1541
2100
|
};
|
|
1542
|
-
return /* @__PURE__ */
|
|
1543
|
-
/* @__PURE__ */
|
|
2101
|
+
return /* @__PURE__ */ jsxs5("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
|
|
2102
|
+
/* @__PURE__ */ jsxs5(Popover, { open: paletteOpen, onOpenChange: (open) => {
|
|
1544
2103
|
setPaletteOpen(open);
|
|
1545
2104
|
if (open) {
|
|
1546
2105
|
setMode("copy");
|
|
1547
2106
|
void preflight();
|
|
1548
2107
|
}
|
|
1549
2108
|
}, children: [
|
|
1550
|
-
/* @__PURE__ */
|
|
1551
|
-
/* @__PURE__ */
|
|
1552
|
-
menuStatus === "loading" ? /* @__PURE__ */
|
|
1553
|
-
copyAvailable || downloadAvailable ? /* @__PURE__ */
|
|
1554
|
-
/* @__PURE__ */
|
|
1555
|
-
copyAvailable && downloadAvailable ? /* @__PURE__ */
|
|
1556
|
-
/* @__PURE__ */
|
|
1557
|
-
/* @__PURE__ */
|
|
2109
|
+
/* @__PURE__ */ jsx10(PopoverTrigger, { asChild: true, children: triggerVariant === "glass" ? /* @__PURE__ */ jsx10(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ jsx10(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass" }) : /* @__PURE__ */ jsx10(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ jsx10(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent" }) }),
|
|
2110
|
+
/* @__PURE__ */ jsxs5(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
|
|
2111
|
+
menuStatus === "loading" ? /* @__PURE__ */ jsx10("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ jsx10("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
|
|
2112
|
+
copyAvailable || downloadAvailable ? /* @__PURE__ */ jsxs5("section", { className: "matrx-alchemy-output", children: [
|
|
2113
|
+
/* @__PURE__ */ jsx10("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
|
|
2114
|
+
copyAvailable && downloadAvailable ? /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
|
|
2115
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
|
|
2116
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
|
|
1558
2117
|
] }) : null,
|
|
1559
|
-
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */
|
|
1560
|
-
/* @__PURE__ */
|
|
2118
|
+
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2119
|
+
/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
1561
2120
|
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]}` })),
|
|
1562
2121
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
|
|
1563
2122
|
] }),
|
|
1564
|
-
quickVariants("copy").length ? /* @__PURE__ */
|
|
2123
|
+
quickVariants("copy").length ? /* @__PURE__ */ jsx10(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
|
|
1565
2124
|
closePalette();
|
|
1566
2125
|
void transfer("markdown", false, variant);
|
|
1567
2126
|
} }) : null
|
|
1568
2127
|
] }) : null,
|
|
1569
|
-
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */
|
|
2128
|
+
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ jsx10(Fragment2, { children: /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
1570
2129
|
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]}` })),
|
|
1571
2130
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
|
|
1572
2131
|
downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
|
|
1573
2132
|
] }) }) : null
|
|
1574
2133
|
] }) : null,
|
|
1575
|
-
prepareAvailable ? /* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
2134
|
+
prepareAvailable ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2135
|
+
/* @__PURE__ */ jsx10(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ jsxs5("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
2136
|
+
closePalette();
|
|
2137
|
+
void transfer(nativeAiFormat, false);
|
|
2138
|
+
}, children: [
|
|
2139
|
+
/* @__PURE__ */ jsx10(PaletteGlyph, { kind: "ai-copy" }),
|
|
2140
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
2141
|
+
"Copy with AI context",
|
|
2142
|
+
/* @__PURE__ */ jsx10("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
|
|
2143
|
+
] })
|
|
2144
|
+
] }) : null, items: quickVariants("ai"), onRun: (variant) => {
|
|
1577
2145
|
closePalette();
|
|
1578
2146
|
void transfer("markdown", false, variant);
|
|
1579
2147
|
} }),
|
|
1580
|
-
/* @__PURE__ */
|
|
2148
|
+
/* @__PURE__ */ jsx10(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ jsxs5("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
|
|
1581
2149
|
closePalette();
|
|
1582
2150
|
void openWorkspace();
|
|
1583
2151
|
}, children: [
|
|
1584
|
-
/* @__PURE__ */
|
|
1585
|
-
/* @__PURE__ */
|
|
2152
|
+
/* @__PURE__ */ jsx10(PaletteGlyph, { kind: "sliders" }),
|
|
2153
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
1586
2154
|
"Prepare for AI",
|
|
1587
|
-
/* @__PURE__ */
|
|
2155
|
+
/* @__PURE__ */ jsx10("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
|
|
1588
2156
|
] })
|
|
1589
2157
|
] }) })
|
|
1590
2158
|
] }) : null,
|
|
1591
|
-
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */
|
|
1592
|
-
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */
|
|
2159
|
+
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ jsx10(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2160
|
+
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ jsx10("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
1593
2161
|
closePalette();
|
|
1594
2162
|
void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
|
|
1595
|
-
}, children: /* @__PURE__ */
|
|
1596
|
-
variants.map((variant) => /* @__PURE__ */
|
|
2163
|
+
}, children: /* @__PURE__ */ jsx10("span", { children: "Prepare this surface" }) }) : null,
|
|
2164
|
+
variants.map((variant) => /* @__PURE__ */ jsx10("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
|
|
1597
2165
|
closePalette();
|
|
1598
2166
|
void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
|
|
1599
|
-
}, children: /* @__PURE__ */
|
|
2167
|
+
}, children: /* @__PURE__ */ jsx10(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
|
|
1600
2168
|
] }) }) : null,
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
2169
|
+
["save", "chat", "other"].map((group) => {
|
|
2170
|
+
const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
|
|
2171
|
+
return entries.length ? /* @__PURE__ */ jsxs5("details", { className: "matrx-alchemy-palette-destinations", children: [
|
|
2172
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
2173
|
+
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
|
|
2174
|
+
/* @__PURE__ */ jsx10("span", { children: entries.length })
|
|
2175
|
+
] }),
|
|
2176
|
+
/* @__PURE__ */ jsx10("div", { children: entries.map((action) => /* @__PURE__ */ jsx10("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
|
|
2177
|
+
closePalette();
|
|
2178
|
+
void runAction(action);
|
|
2179
|
+
}, children: /* @__PURE__ */ jsx10(DestinationPresentation, { action }) }, action.id)) })
|
|
2180
|
+
] }, group) : null;
|
|
2181
|
+
})
|
|
1605
2182
|
] })
|
|
1606
2183
|
] }),
|
|
1607
|
-
notice && triggerRef.current ? createPortal(/* @__PURE__ */
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
2184
|
+
notice && triggerRef.current ? createPortal(/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-feedback", children: [
|
|
2185
|
+
/* @__PURE__ */ jsx10("span", { role: "status", children: notice }),
|
|
2186
|
+
/* @__PURE__ */ jsx10(ReceiptLink, { target: receiptTarget }),
|
|
2187
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
|
|
1610
2188
|
] }), triggerRef.current.ownerDocument.body) : null,
|
|
1611
|
-
Object.values(workspaces).map((saved) => /* @__PURE__ */
|
|
2189
|
+
Object.values(workspaces).map((saved) => /* @__PURE__ */ jsx10(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, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key))
|
|
1612
2190
|
] });
|
|
1613
2191
|
}
|
|
1614
2192
|
function initialControls(state) {
|
|
@@ -1660,30 +2238,34 @@ function preview(draft, format) {
|
|
|
1660
2238
|
const resolved = isBuiltInFormat(format) ? format : "plain";
|
|
1661
2239
|
return serialize(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
|
|
1662
2240
|
}
|
|
1663
|
-
function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, onOutcome, captureScope }) {
|
|
2241
|
+
function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
1664
2242
|
const fence = useFence();
|
|
1665
|
-
const latest =
|
|
2243
|
+
const latest = React9.useRef(state);
|
|
1666
2244
|
latest.current = state;
|
|
1667
|
-
const aiSession =
|
|
2245
|
+
const aiSession = React9.useRef(void 0);
|
|
1668
2246
|
if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
|
|
1669
|
-
const [controls, setControls] =
|
|
1670
|
-
const [controlsHistory, setControlsHistory] =
|
|
1671
|
-
const [pendingControls, setPendingControls] =
|
|
2247
|
+
const [controls, setControls] = React9.useState(() => initialControls(state));
|
|
2248
|
+
const [controlsHistory, setControlsHistory] = React9.useState([]);
|
|
2249
|
+
const [pendingControls, setPendingControls] = React9.useState(null);
|
|
1672
2250
|
const requestedFormat = state.preferences.initialFormat;
|
|
1673
|
-
const [format, setFormat] =
|
|
1674
|
-
const [buffer, setBuffer] =
|
|
1675
|
-
const [bufferError, setBufferError] =
|
|
1676
|
-
const [formatError, setFormatError] =
|
|
1677
|
-
const [preparedArtifact, setPreparedArtifact] =
|
|
1678
|
-
const [instruction, setInstruction] =
|
|
1679
|
-
const [busy, setBusy] =
|
|
1680
|
-
const [aiFailed, setAiFailed] =
|
|
1681
|
-
|
|
2251
|
+
const [format, setFormat] = React9.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
|
|
2252
|
+
const [buffer, setBuffer] = React9.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
|
|
2253
|
+
const [bufferError, setBufferError] = React9.useState(null);
|
|
2254
|
+
const [formatError, setFormatError] = React9.useState(null);
|
|
2255
|
+
const [preparedArtifact, setPreparedArtifact] = React9.useState(null);
|
|
2256
|
+
const [instruction, setInstruction] = React9.useState("");
|
|
2257
|
+
const [busy, setBusy] = React9.useState(null);
|
|
2258
|
+
const [aiFailed, setAiFailed] = React9.useState(false);
|
|
2259
|
+
React9.useEffect(() => {
|
|
1682
2260
|
setAiFailed(false);
|
|
1683
2261
|
}, [state.snapshot.id, state.draft.revision]);
|
|
1684
|
-
const
|
|
1685
|
-
|
|
1686
|
-
|
|
2262
|
+
const handingOff = React9.useRef(false);
|
|
2263
|
+
React9.useEffect(() => {
|
|
2264
|
+
if (open) handingOff.current = false;
|
|
2265
|
+
}, [open]);
|
|
2266
|
+
const activeAi = React9.useRef(null);
|
|
2267
|
+
const activeCapture = React9.useRef(null);
|
|
2268
|
+
React9.useEffect(() => {
|
|
1687
2269
|
if (bufferError) return;
|
|
1688
2270
|
const adapter = adapters.find((candidate) => candidate.id === format);
|
|
1689
2271
|
const controller = new AbortController();
|
|
@@ -1703,7 +2285,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1703
2285
|
});
|
|
1704
2286
|
return () => controller.abort();
|
|
1705
2287
|
}, [adapters, bufferError, format, state.draft, state.snapshot.id]);
|
|
1706
|
-
const close =
|
|
2288
|
+
const close = React9.useCallback(() => {
|
|
1707
2289
|
activeAi.current?.abort();
|
|
1708
2290
|
activeCapture.current?.abort();
|
|
1709
2291
|
activeAi.current = null;
|
|
@@ -1832,8 +2414,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1832
2414
|
if (fence.valid(id, controller)) setBusy(null);
|
|
1833
2415
|
}
|
|
1834
2416
|
};
|
|
1835
|
-
const [deliveryNotice, setDeliveryNotice] =
|
|
1836
|
-
|
|
2417
|
+
const [deliveryNotice, setDeliveryNotice] = React9.useState(null);
|
|
2418
|
+
React9.useEffect(() => {
|
|
1837
2419
|
setDeliveryNotice(null);
|
|
1838
2420
|
}, [state.draft.revision]);
|
|
1839
2421
|
const reportDelivery = (outcome) => {
|
|
@@ -1860,45 +2442,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1860
2442
|
if (fence.valid(id, controller)) setBusy(null);
|
|
1861
2443
|
}
|
|
1862
2444
|
};
|
|
2445
|
+
const deliverAction = async (action) => {
|
|
2446
|
+
if (busy || bufferError || formatError || !preparedArtifact) return;
|
|
2447
|
+
const { controller, id } = fence.begin();
|
|
2448
|
+
const current = latest.current;
|
|
2449
|
+
setBusy("action");
|
|
2450
|
+
try {
|
|
2451
|
+
if (!action.supports(current.snapshot, current.draft)) throw new Error(`${action.label} is unavailable for this prepared content.`);
|
|
2452
|
+
handingOff.current = true;
|
|
2453
|
+
flushSync(() => onClose());
|
|
2454
|
+
const result = await action.run({ snapshot: current.snapshot, draft: current.draft, signal: controller.signal });
|
|
2455
|
+
if (fence.valid(id, controller)) reportDelivery(result);
|
|
2456
|
+
} catch (error) {
|
|
2457
|
+
if (fence.valid(id, controller)) reportDelivery({ status: "error", code: "destination-failed", message: errorMessage(error, "Could not deliver prepared content"), retryable: false });
|
|
2458
|
+
} finally {
|
|
2459
|
+
fence.finish(controller);
|
|
2460
|
+
if (fence.valid(id, controller)) setBusy(null);
|
|
2461
|
+
}
|
|
2462
|
+
};
|
|
2463
|
+
const eligibleActions = actions.filter((action) => action.supports(state.snapshot, state.draft));
|
|
1863
2464
|
const rows = state.original.payload.kind === "rows" ? state.original.payload : null;
|
|
1864
2465
|
const formats = COPIES.filter((f) => supportsBuiltIn(f, state.draft.payload));
|
|
1865
2466
|
const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
|
|
1866
2467
|
const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
|
|
1867
2468
|
const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${Number(value).toLocaleString()}`).join(" \xB7 ");
|
|
1868
|
-
return /* @__PURE__ */
|
|
2469
|
+
return /* @__PURE__ */ jsx10(Dialog, { open, onOpenChange: (next) => {
|
|
1869
2470
|
if (!next) close();
|
|
1870
|
-
}, children: /* @__PURE__ */
|
|
2471
|
+
}, children: /* @__PURE__ */ jsxs5(DialogContent, { onCloseAutoFocus: (event) => {
|
|
1871
2472
|
event.preventDefault();
|
|
1872
|
-
restoreFocus();
|
|
2473
|
+
if (!handingOff.current) restoreFocus();
|
|
1873
2474
|
}, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
|
|
1874
|
-
/* @__PURE__ */
|
|
1875
|
-
/* @__PURE__ */
|
|
2475
|
+
/* @__PURE__ */ jsxs5(DialogHeader, { children: [
|
|
2476
|
+
/* @__PURE__ */ jsxs5(DialogTitle, { children: [
|
|
1876
2477
|
"Prepare ",
|
|
1877
2478
|
state.snapshot.label
|
|
1878
2479
|
] }),
|
|
1879
|
-
/* @__PURE__ */
|
|
2480
|
+
/* @__PURE__ */ jsxs5(DialogDescription, { children: [
|
|
1880
2481
|
state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
|
|
1881
2482
|
"Review and edit this copy. Your original stays unchanged."
|
|
1882
2483
|
] })
|
|
1883
2484
|
] }),
|
|
1884
|
-
/* @__PURE__ */
|
|
1885
|
-
/* @__PURE__ */
|
|
1886
|
-
/* @__PURE__ */
|
|
1887
|
-
/* @__PURE__ */
|
|
1888
|
-
scopes.length > 1 ? /* @__PURE__ */
|
|
2485
|
+
/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
2486
|
+
/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-workspace-grid", children: [
|
|
2487
|
+
/* @__PURE__ */ jsxs5("section", { className: "matrx-alchemy-main", children: [
|
|
2488
|
+
/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2489
|
+
scopes.length > 1 ? /* @__PURE__ */ jsxs5("label", { children: [
|
|
1889
2490
|
"Scope",
|
|
1890
|
-
/* @__PURE__ */
|
|
2491
|
+
/* @__PURE__ */ jsx10("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ jsx10("option", { value: scope, children: SCOPE_LABEL[scope] }, scope)) })
|
|
1891
2492
|
] }) : null,
|
|
1892
|
-
/* @__PURE__ */
|
|
2493
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
1893
2494
|
"Detail",
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
/* @__PURE__ */
|
|
1897
|
-
/* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
2495
|
+
/* @__PURE__ */ jsxs5("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
|
|
2496
|
+
/* @__PURE__ */ jsx10("option", { value: "full", children: "Full" }),
|
|
2497
|
+
/* @__PURE__ */ jsx10("option", { value: "compact", children: "Compact" }),
|
|
2498
|
+
/* @__PURE__ */ jsx10("option", { value: "brief", children: "Brief" }),
|
|
2499
|
+
/* @__PURE__ */ jsx10("option", { value: "custom", children: "Custom" })
|
|
1899
2500
|
] })
|
|
1900
2501
|
] }),
|
|
1901
|
-
/* @__PURE__ */
|
|
2502
|
+
/* @__PURE__ */ jsx10(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
|
|
1902
2503
|
setBufferError(null);
|
|
1903
2504
|
if (controlsHistory.length) {
|
|
1904
2505
|
const next = controlsHistory[controlsHistory.length - 1];
|
|
@@ -1907,7 +2508,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1907
2508
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
1908
2509
|
} else onChange({ ...state, draft: undoDraft(state.draft), error: void 0 });
|
|
1909
2510
|
}, children: "Undo" }),
|
|
1910
|
-
/* @__PURE__ */
|
|
2511
|
+
/* @__PURE__ */ jsx10(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
|
|
1911
2512
|
const next = initialControls(state);
|
|
1912
2513
|
setControls(next);
|
|
1913
2514
|
setControlsHistory([]);
|
|
@@ -1915,64 +2516,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1915
2516
|
setBufferError(null);
|
|
1916
2517
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
1917
2518
|
}, children: "Reset" }),
|
|
1918
|
-
/* @__PURE__ */
|
|
2519
|
+
/* @__PURE__ */ jsx10(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
|
|
1919
2520
|
] }),
|
|
1920
|
-
controls.preset === "custom"
|
|
1921
|
-
/* @__PURE__ */
|
|
1922
|
-
[["maxDepth", "Maximum depth"], ["maxStringChars", "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].map(([key, text]) => /* @__PURE__ */
|
|
2521
|
+
controls.preset === "custom" ? /* @__PURE__ */ jsxs5("fieldset", { className: "matrx-alchemy-options", children: [
|
|
2522
|
+
/* @__PURE__ */ jsx10("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
|
|
2523
|
+
[["maxDepth", "Maximum depth"], ["maxStringChars", state.draft.payload.kind === "rows" ? "Maximum characters per cell" : "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].filter(([key]) => key === "maxStringChars" || state.draft.payload.kind === "json" || state.draft.payload.kind === "registered").map(([key, text]) => /* @__PURE__ */ jsxs5("label", { children: [
|
|
1923
2524
|
text,
|
|
1924
|
-
/* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsx10("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
1925
2526
|
] }, key))
|
|
1926
2527
|
] }) : null,
|
|
1927
|
-
rows ? /* @__PURE__ */
|
|
1928
|
-
/* @__PURE__ */
|
|
2528
|
+
rows ? /* @__PURE__ */ jsxs5("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
|
|
2529
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
1929
2530
|
"Data selection \xB7 ",
|
|
1930
2531
|
controls.visibleColumns.length,
|
|
1931
2532
|
" columns",
|
|
1932
2533
|
controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
|
|
1933
2534
|
] }),
|
|
1934
|
-
/* @__PURE__ */
|
|
2535
|
+
/* @__PURE__ */ jsx10("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ jsx10(RowControls, { rows, controls, change: changeControls }) })
|
|
1935
2536
|
] }) : null,
|
|
1936
|
-
state.snapshot.sections.length ? /* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
2537
|
+
state.snapshot.sections.length ? /* @__PURE__ */ jsxs5("details", { className: "matrx-alchemy-options", children: [
|
|
2538
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
1938
2539
|
"Sections \xB7 ",
|
|
1939
2540
|
controls.sections.length,
|
|
1940
2541
|
" included"
|
|
1941
2542
|
] }),
|
|
1942
|
-
/* @__PURE__ */
|
|
1943
|
-
/* @__PURE__ */
|
|
2543
|
+
/* @__PURE__ */ jsx10("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ jsxs5("label", { children: [
|
|
2544
|
+
/* @__PURE__ */ jsx10("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) }) }),
|
|
1944
2545
|
" ",
|
|
1945
2546
|
section.label
|
|
1946
2547
|
] }, section.id)) })
|
|
1947
2548
|
] }) : null,
|
|
1948
|
-
/* @__PURE__ */
|
|
2549
|
+
/* @__PURE__ */ jsxs5("label", { className: "matrx-alchemy-preview-label", children: [
|
|
1949
2550
|
"Output format",
|
|
1950
|
-
/* @__PURE__ */
|
|
1951
|
-
formats.map((f) => /* @__PURE__ */
|
|
1952
|
-
state.draft.payload.kind === "rows" ? /* @__PURE__ */
|
|
1953
|
-
workspaceAdapters.map((adapter) => /* @__PURE__ */
|
|
2551
|
+
/* @__PURE__ */ jsxs5("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
|
|
2552
|
+
formats.map((f) => /* @__PURE__ */ jsx10("option", { value: f, children: LABEL[f] }, f)),
|
|
2553
|
+
state.draft.payload.kind === "rows" ? /* @__PURE__ */ jsx10("option", { value: "xlsx", children: "Excel workbook" }) : null,
|
|
2554
|
+
workspaceAdapters.map((adapter) => /* @__PURE__ */ jsx10("option", { value: adapter.id, children: adapter.label }, adapter.id))
|
|
1954
2555
|
] })
|
|
1955
2556
|
] }),
|
|
1956
|
-
/* @__PURE__ */
|
|
1957
|
-
/* @__PURE__ */
|
|
1958
|
-
/* @__PURE__ */
|
|
2557
|
+
/* @__PURE__ */ jsx10("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) }),
|
|
2558
|
+
/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-coverage", children: [
|
|
2559
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
1959
2560
|
state.snapshot.coverage.included.toLocaleString(),
|
|
1960
2561
|
" included",
|
|
1961
2562
|
state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
|
|
1962
2563
|
" \xB7 ",
|
|
1963
2564
|
state.snapshot.coverage.status
|
|
1964
2565
|
] }),
|
|
1965
|
-
state.snapshot.coverage.reason ? /* @__PURE__ */
|
|
1966
|
-
limitText ? /* @__PURE__ */
|
|
2566
|
+
state.snapshot.coverage.reason ? /* @__PURE__ */ jsx10("span", { children: state.snapshot.coverage.reason }) : null,
|
|
2567
|
+
limitText ? /* @__PURE__ */ jsxs5("span", { children: [
|
|
1967
2568
|
"Limits: ",
|
|
1968
2569
|
limitText
|
|
1969
2570
|
] }) : null,
|
|
1970
|
-
displayedOmissions.length ? /* @__PURE__ */
|
|
1971
|
-
/* @__PURE__ */
|
|
2571
|
+
displayedOmissions.length ? /* @__PURE__ */ jsxs5("details", { children: [
|
|
2572
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
1972
2573
|
displayedOmissions.length,
|
|
1973
2574
|
" omissions or adjustments"
|
|
1974
2575
|
] }),
|
|
1975
|
-
/* @__PURE__ */
|
|
2576
|
+
/* @__PURE__ */ jsx10("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ jsxs5("li", { children: [
|
|
1976
2577
|
o.path || "/",
|
|
1977
2578
|
": ",
|
|
1978
2579
|
o.reason,
|
|
@@ -1980,57 +2581,79 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1980
2581
|
] }, `${o.path}-${o.reason}-${i}`)) })
|
|
1981
2582
|
] }) : null
|
|
1982
2583
|
] }),
|
|
1983
|
-
bufferError ? /* @__PURE__ */
|
|
1984
|
-
formatError ? /* @__PURE__ */
|
|
1985
|
-
bufferError ? /* @__PURE__ */
|
|
2584
|
+
bufferError ? /* @__PURE__ */ jsx10("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
|
|
2585
|
+
formatError ? /* @__PURE__ */ jsx10("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
|
|
2586
|
+
bufferError ? /* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
|
|
1986
2587
|
const fallback = editDraft(state.draft, { kind: "text", text: buffer });
|
|
1987
2588
|
setBufferError(null);
|
|
1988
2589
|
onChange({ ...state, draft: fallback, error: void 0 });
|
|
1989
2590
|
setFormat("plain");
|
|
1990
2591
|
}, children: "Use invalid JSON as plain text" }) : null
|
|
1991
2592
|
] }),
|
|
1992
|
-
ai || busy === "capture" || state.error ? /* @__PURE__ */
|
|
1993
|
-
ai ? /* @__PURE__ */
|
|
1994
|
-
/* @__PURE__ */
|
|
2593
|
+
ai || busy === "capture" || state.error ? /* @__PURE__ */ jsxs5("aside", { children: [
|
|
2594
|
+
ai ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2595
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2596
|
+
"Start with",
|
|
2597
|
+
/* @__PURE__ */ jsxs5("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
|
|
2598
|
+
if (event.target.value) setInstruction(event.target.value);
|
|
2599
|
+
}, children: [
|
|
2600
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "Choose an instruction" }),
|
|
2601
|
+
/* @__PURE__ */ jsx10("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
|
|
2602
|
+
/* @__PURE__ */ jsx10("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
|
|
2603
|
+
/* @__PURE__ */ jsx10("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
|
|
2604
|
+
/* @__PURE__ */ jsx10("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
|
|
2605
|
+
/* @__PURE__ */ jsx10("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
|
|
2606
|
+
/* @__PURE__ */ jsx10("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
|
|
2607
|
+
] })
|
|
2608
|
+
] }),
|
|
2609
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
1995
2610
|
"AI instruction",
|
|
1996
|
-
/* @__PURE__ */
|
|
2611
|
+
/* @__PURE__ */ jsx10("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
|
|
1997
2612
|
] }),
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
busy === "ai" ? /* @__PURE__ */
|
|
2613
|
+
/* @__PURE__ */ jsx10(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" }),
|
|
2614
|
+
busy === "ai" ? /* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
|
|
2000
2615
|
] }) : null,
|
|
2001
|
-
busy === "capture" ? /* @__PURE__ */
|
|
2616
|
+
busy === "capture" ? /* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
|
|
2002
2617
|
activeCapture.current?.abort();
|
|
2003
2618
|
activeCapture.current = null;
|
|
2004
2619
|
setBusy(null);
|
|
2005
2620
|
}, children: "Stop loading rows" }) : null,
|
|
2006
|
-
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */
|
|
2007
|
-
ai ? /* @__PURE__ */
|
|
2008
|
-
state.error ? /* @__PURE__ */
|
|
2621
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx10(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,
|
|
2622
|
+
ai ? /* @__PURE__ */ jsx10("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,
|
|
2623
|
+
state.error ? /* @__PURE__ */ jsx10("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
2009
2624
|
] }) : null
|
|
2010
2625
|
] }),
|
|
2011
|
-
pendingControls ? /* @__PURE__ */
|
|
2012
|
-
/* @__PURE__ */
|
|
2013
|
-
/* @__PURE__ */
|
|
2014
|
-
/* @__PURE__ */
|
|
2626
|
+
pendingControls ? /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2627
|
+
/* @__PURE__ */ jsx10("p", { children: "This control would replace your manual edit." }),
|
|
2628
|
+
/* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
2629
|
+
/* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
2015
2630
|
] }) : null,
|
|
2016
|
-
state.sourceStale ? /* @__PURE__ */
|
|
2017
|
-
state.pending ? /* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2631
|
+
state.sourceStale ? /* @__PURE__ */ jsx10("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
2632
|
+
state.pending ? /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2633
|
+
/* @__PURE__ */ jsx10("p", { children: "A fresh source snapshot is ready." }),
|
|
2634
|
+
/* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
2635
|
+
/* @__PURE__ */ jsx10(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
|
|
2636
|
+
] }) : null,
|
|
2637
|
+
eligibleActions.length ? /* @__PURE__ */ jsxs5("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
|
|
2638
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
2639
|
+
"Use prepared content \xB7 ",
|
|
2640
|
+
eligibleActions.length,
|
|
2641
|
+
" destinations"
|
|
2642
|
+
] }),
|
|
2643
|
+
/* @__PURE__ */ jsx10("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ jsx10("button", { type: "button", className: "matrx-alchemy-palette-row", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliverAction(action), children: /* @__PURE__ */ jsx10(DestinationPresentation, { action }) }, action.id)) })
|
|
2021
2644
|
] }) : null,
|
|
2022
|
-
deliveryNotice ? /* @__PURE__ */
|
|
2645
|
+
deliveryNotice ? /* @__PURE__ */ jsx10("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
|
|
2023
2646
|
] }),
|
|
2024
|
-
/* @__PURE__ */
|
|
2025
|
-
/* @__PURE__ */
|
|
2647
|
+
/* @__PURE__ */ jsxs5(DialogFooter, { children: [
|
|
2648
|
+
/* @__PURE__ */ jsxs5("span", { className: "matrx-alchemy-meta", children: [
|
|
2026
2649
|
buffer.length.toLocaleString(),
|
|
2027
2650
|
" characters \xB7 ~",
|
|
2028
2651
|
estimateTokens(buffer).toLocaleString(),
|
|
2029
2652
|
" tokens"
|
|
2030
2653
|
] }),
|
|
2031
|
-
/* @__PURE__ */
|
|
2032
|
-
/* @__PURE__ */
|
|
2033
|
-
/* @__PURE__ */
|
|
2654
|
+
/* @__PURE__ */ jsx10(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
|
|
2655
|
+
/* @__PURE__ */ jsx10(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" }),
|
|
2656
|
+
/* @__PURE__ */ jsx10(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" })
|
|
2034
2657
|
] })
|
|
2035
2658
|
] }) });
|
|
2036
2659
|
}
|
|
@@ -2038,59 +2661,59 @@ function RowControls({ rows, controls, change }) {
|
|
|
2038
2661
|
const filterCount = Object.values(controls.filters).filter(Boolean).length;
|
|
2039
2662
|
const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
|
|
2040
2663
|
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 ");
|
|
2041
|
-
return /* @__PURE__ */
|
|
2042
|
-
/* @__PURE__ */
|
|
2043
|
-
/* @__PURE__ */
|
|
2664
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2665
|
+
/* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2666
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2044
2667
|
"Search",
|
|
2045
|
-
/* @__PURE__ */
|
|
2668
|
+
/* @__PURE__ */ jsx10("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
|
|
2046
2669
|
] }),
|
|
2047
|
-
/* @__PURE__ */
|
|
2670
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2048
2671
|
"Sort",
|
|
2049
|
-
/* @__PURE__ */
|
|
2050
|
-
/* @__PURE__ */
|
|
2051
|
-
rows.columns.map((column) => /* @__PURE__ */
|
|
2672
|
+
/* @__PURE__ */ jsxs5("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
|
|
2673
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "None" }),
|
|
2674
|
+
rows.columns.map((column) => /* @__PURE__ */ jsx10("option", { value: column.id, children: column.label }, column.id))
|
|
2052
2675
|
] })
|
|
2053
2676
|
] }),
|
|
2054
|
-
/* @__PURE__ */
|
|
2677
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2055
2678
|
"Direction",
|
|
2056
|
-
/* @__PURE__ */
|
|
2057
|
-
/* @__PURE__ */
|
|
2058
|
-
/* @__PURE__ */
|
|
2679
|
+
/* @__PURE__ */ jsxs5("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
|
|
2680
|
+
/* @__PURE__ */ jsx10("option", { value: "asc", children: "Ascending" }),
|
|
2681
|
+
/* @__PURE__ */ jsx10("option", { value: "desc", children: "Descending" })
|
|
2059
2682
|
] })
|
|
2060
2683
|
] }),
|
|
2061
|
-
/* @__PURE__ */
|
|
2684
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2062
2685
|
"Top rows",
|
|
2063
|
-
/* @__PURE__ */
|
|
2686
|
+
/* @__PURE__ */ jsx10("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
2064
2687
|
] })
|
|
2065
2688
|
] }),
|
|
2066
|
-
/* @__PURE__ */
|
|
2067
|
-
/* @__PURE__ */
|
|
2689
|
+
/* @__PURE__ */ jsxs5("details", { className: "matrx-alchemy-options", children: [
|
|
2690
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
2068
2691
|
"Columns and filters",
|
|
2069
2692
|
dataSummary ? ` \u2014 ${dataSummary}` : ""
|
|
2070
2693
|
] }),
|
|
2071
|
-
/* @__PURE__ */
|
|
2072
|
-
/* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2694
|
+
/* @__PURE__ */ jsx10("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-column", children: [
|
|
2695
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2696
|
+
/* @__PURE__ */ jsx10("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) }) }),
|
|
2074
2697
|
" ",
|
|
2075
2698
|
column.label
|
|
2076
2699
|
] }),
|
|
2077
|
-
/* @__PURE__ */
|
|
2700
|
+
/* @__PURE__ */ jsx10("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 } }) })
|
|
2078
2701
|
] }, column.id)) })
|
|
2079
2702
|
] }),
|
|
2080
|
-
/* @__PURE__ */
|
|
2081
|
-
/* @__PURE__ */
|
|
2703
|
+
/* @__PURE__ */ jsxs5("details", { className: "matrx-alchemy-options", children: [
|
|
2704
|
+
/* @__PURE__ */ jsxs5("summary", { children: [
|
|
2082
2705
|
"Rows \u2014 ",
|
|
2083
2706
|
selectionSummary
|
|
2084
2707
|
] }),
|
|
2085
|
-
/* @__PURE__ */
|
|
2086
|
-
/* @__PURE__ */
|
|
2087
|
-
/* @__PURE__ */
|
|
2708
|
+
/* @__PURE__ */ jsxs5("fieldset", { "aria-label": "Row selection", children: [
|
|
2709
|
+
/* @__PURE__ */ jsxs5("label", { children: [
|
|
2710
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
|
|
2088
2711
|
" Only selected rows"
|
|
2089
2712
|
] }),
|
|
2090
|
-
/* @__PURE__ */
|
|
2713
|
+
/* @__PURE__ */ jsx10("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
|
|
2091
2714
|
const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String(readTransferCell(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
|
|
2092
|
-
return /* @__PURE__ */
|
|
2093
|
-
/* @__PURE__ */
|
|
2715
|
+
return /* @__PURE__ */ jsxs5("label", { children: [
|
|
2716
|
+
/* @__PURE__ */ jsx10("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) }) }),
|
|
2094
2717
|
" Row ",
|
|
2095
2718
|
index + 1,
|
|
2096
2719
|
summary ? ` \u2014 ${summary}` : ""
|
|
@@ -2101,6 +2724,7 @@ function RowControls({ rows, controls, change }) {
|
|
|
2101
2724
|
] });
|
|
2102
2725
|
}
|
|
2103
2726
|
export {
|
|
2727
|
+
ALCHEMY_COPY_TRANSFORM_SVG,
|
|
2104
2728
|
ALCHEMY_GLYPH_SVG,
|
|
2105
2729
|
AlchemyGlyph,
|
|
2106
2730
|
ContentTransferCapabilitiesProvider,
|