@tangle-network/agent-app 0.46.2 → 0.46.3
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/README.md +1 -1
- package/dist/assistant/index.js +2 -1
- package/dist/assistant/index.js.map +1 -1
- package/dist/chunk-KKBTPZIE.js +805 -0
- package/dist/chunk-KKBTPZIE.js.map +1 -0
- package/dist/{chunk-2RTYQU4W.js → chunk-LEGZX5MQ.js} +150 -4
- package/dist/chunk-LEGZX5MQ.js.map +1 -0
- package/dist/{chunk-MBKNKAN2.js → chunk-RZ6MYWMJ.js} +416 -1210
- package/dist/chunk-RZ6MYWMJ.js.map +1 -0
- package/dist/stories/studio/StudioProviders.d.ts +10 -0
- package/dist/stories/studio/fixtures.d.ts +10 -2
- package/dist/studio/audio-preview.d.ts +12 -0
- package/dist/studio/generation.d.ts +22 -1
- package/dist/studio/index.d.ts +2 -0
- package/dist/studio/index.js +29 -1
- package/dist/studio/ports.d.ts +54 -0
- package/dist/studio-react/composer-option-controls.d.ts +19 -8
- package/dist/studio-react/download-generations.d.ts +4 -0
- package/dist/studio-react/index.d.ts +38 -22
- package/dist/studio-react/index.js +2198 -545
- package/dist/studio-react/index.js.map +1 -1
- package/dist/studio-react/media-tile.d.ts +21 -0
- package/dist/studio-react/media-viewer.d.ts +12 -0
- package/dist/studio-react/studio-confirm.d.ts +8 -0
- package/dist/studio-react/studio-generation-screen.d.ts +42 -0
- package/dist/studio-react/studio-history-screen.d.ts +28 -0
- package/dist/studio-react/studio-home-screen.d.ts +20 -0
- package/dist/studio-react/studio-playback.d.ts +31 -0
- package/dist/studio-react/studio-toasts.d.ts +21 -0
- package/dist/studio-react/studio.css +142 -72
- package/dist/studio-react/use-batch-navigation.d.ts +20 -0
- package/dist/studio-react/use-deferred-delete.d.ts +19 -0
- package/dist/studio-react/use-generation-history.d.ts +22 -0
- package/dist/studio-react/vault-path-popover.d.ts +12 -0
- package/dist/web-react/index.js +8 -6
- package/package.json +2 -7
- package/dist/chunk-2RTYQU4W.js.map +0 -1
- package/dist/chunk-MBKNKAN2.js.map +0 -1
- package/dist/studio-react/generation-card.d.ts +0 -9
- package/dist/studio-react/generation-detail-modal.d.ts +0 -11
- package/dist/studio-react/generation-detail.d.ts +0 -6
- package/dist/studio-react/generation-grid.d.ts +0 -15
- package/dist/studio-react/library-drawer.d.ts +0 -12
- package/dist/studio-react/library-panel.d.ts +0 -15
- package/dist/studio-react/result-canvas.d.ts +0 -6
- package/dist/studio-react/studio-header.d.ts +0 -5
- package/dist/studio-react/studio-sheet.d.ts +0 -12
- package/dist/studio-react/studio-workspace.d.ts +0 -21
- package/dist/studio-react/type-config.d.ts +0 -11
|
@@ -23,11 +23,8 @@ import {
|
|
|
23
23
|
AsyncView
|
|
24
24
|
} from "./chunk-3UBAO3N5.js";
|
|
25
25
|
import {
|
|
26
|
-
UNTITLED_SESSION_LABEL,
|
|
27
26
|
filterCommandPaletteItems,
|
|
28
|
-
groupCommandPaletteItems
|
|
29
|
-
mergeSessionPages,
|
|
30
|
-
sessionLabel
|
|
27
|
+
groupCommandPaletteItems
|
|
31
28
|
} from "./chunk-EDTWGSQT.js";
|
|
32
29
|
import {
|
|
33
30
|
attachmentPartsFromMessageParts
|
|
@@ -48,7 +45,7 @@ import {
|
|
|
48
45
|
} from "./chunk-YJMCRXQQ.js";
|
|
49
46
|
|
|
50
47
|
// src/web-react/index.tsx
|
|
51
|
-
import { useEffect as
|
|
48
|
+
import { useEffect as useEffect13, useMemo as useMemo8, useRef as useRef13, useState as useState17, memo } from "react";
|
|
52
49
|
import { InlineToolItem, RunRowShell } from "@tangle-network/ui/run";
|
|
53
50
|
|
|
54
51
|
// src/web-react/smooth-text.ts
|
|
@@ -3722,8 +3719,10 @@ function SeatPaywall({
|
|
|
3722
3719
|
] }) });
|
|
3723
3720
|
}
|
|
3724
3721
|
|
|
3725
|
-
// src/web-react/
|
|
3722
|
+
// src/web-react/record-grid.tsx
|
|
3726
3723
|
import {
|
|
3724
|
+
Fragment as Fragment5,
|
|
3725
|
+
isValidElement,
|
|
3727
3726
|
useCallback as useCallback9,
|
|
3728
3727
|
useEffect as useEffect10,
|
|
3729
3728
|
useId as useId3,
|
|
@@ -3731,794 +3730,6 @@ import {
|
|
|
3731
3730
|
useRef as useRef10,
|
|
3732
3731
|
useState as useState14
|
|
3733
3732
|
} from "react";
|
|
3734
|
-
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3735
|
-
function rethrowAsync(error) {
|
|
3736
|
-
queueMicrotask(() => {
|
|
3737
|
-
throw error;
|
|
3738
|
-
});
|
|
3739
|
-
}
|
|
3740
|
-
function useInfiniteScroll(onLoadMore, { enabled, root, rootMargin = "300px" }) {
|
|
3741
|
-
const [sentinel, setSentinel] = useState14(null);
|
|
3742
|
-
const sentinelRef = useCallback9((node) => setSentinel(node), []);
|
|
3743
|
-
const onLoadMoreRef = useRef10(onLoadMore);
|
|
3744
|
-
useEffect10(() => {
|
|
3745
|
-
onLoadMoreRef.current = onLoadMore;
|
|
3746
|
-
}, [onLoadMore]);
|
|
3747
|
-
useEffect10(() => {
|
|
3748
|
-
if (!sentinel || !enabled) return;
|
|
3749
|
-
if (typeof IntersectionObserver === "undefined") return;
|
|
3750
|
-
const observer = new IntersectionObserver(
|
|
3751
|
-
(entries) => {
|
|
3752
|
-
if (!entries.some((entry) => entry.isIntersecting)) return;
|
|
3753
|
-
try {
|
|
3754
|
-
onLoadMoreRef.current();
|
|
3755
|
-
} catch (error) {
|
|
3756
|
-
rethrowAsync(error);
|
|
3757
|
-
}
|
|
3758
|
-
},
|
|
3759
|
-
{ root: root?.current ?? null, rootMargin }
|
|
3760
|
-
);
|
|
3761
|
-
observer.observe(sentinel);
|
|
3762
|
-
return () => observer.disconnect();
|
|
3763
|
-
}, [sentinel, enabled, root, rootMargin]);
|
|
3764
|
-
return sentinelRef;
|
|
3765
|
-
}
|
|
3766
|
-
function seedSignature(page) {
|
|
3767
|
-
return `${page.nextCursor ?? ""}|${page.items.map((item) => item.id).join(",")}`;
|
|
3768
|
-
}
|
|
3769
|
-
function useSessionHistory({
|
|
3770
|
-
fetchPage,
|
|
3771
|
-
q,
|
|
3772
|
-
sort,
|
|
3773
|
-
initialPage,
|
|
3774
|
-
defaultSort = "newest"
|
|
3775
|
-
}) {
|
|
3776
|
-
const [items, setItems] = useState14(initialPage.items);
|
|
3777
|
-
const [nextCursor, setNextCursor] = useState14(initialPage.nextCursor ?? null);
|
|
3778
|
-
const [phase, setPhase] = useState14("idle");
|
|
3779
|
-
const [reloadKey, setReloadKey] = useState14(0);
|
|
3780
|
-
const seqRef = useRef10(0);
|
|
3781
|
-
const resetAbortRef = useRef10(null);
|
|
3782
|
-
const loadMoreAbortRef = useRef10(null);
|
|
3783
|
-
const loadingMoreRef = useRef10(false);
|
|
3784
|
-
const lastOpRef = useRef10("first");
|
|
3785
|
-
const nextCursorRef = useRef10(nextCursor);
|
|
3786
|
-
nextCursorRef.current = nextCursor;
|
|
3787
|
-
const viewRef = useRef10({ q, sort, fetchPage });
|
|
3788
|
-
viewRef.current = { q, sort, fetchPage };
|
|
3789
|
-
const seedRef = useRef10(initialPage);
|
|
3790
|
-
seedRef.current = initialPage;
|
|
3791
|
-
const isDefaultView = q === "" && sort === defaultSort;
|
|
3792
|
-
const seedKey = useMemo6(() => seedSignature(initialPage), [initialPage]);
|
|
3793
|
-
useEffect10(() => {
|
|
3794
|
-
resetAbortRef.current?.abort();
|
|
3795
|
-
loadMoreAbortRef.current?.abort();
|
|
3796
|
-
loadingMoreRef.current = false;
|
|
3797
|
-
const seq = ++seqRef.current;
|
|
3798
|
-
if (isDefaultView && reloadKey === 0) {
|
|
3799
|
-
setItems(seedRef.current.items);
|
|
3800
|
-
setNextCursor(seedRef.current.nextCursor ?? null);
|
|
3801
|
-
setPhase("idle");
|
|
3802
|
-
return;
|
|
3803
|
-
}
|
|
3804
|
-
const controller = new AbortController();
|
|
3805
|
-
resetAbortRef.current = controller;
|
|
3806
|
-
lastOpRef.current = "first";
|
|
3807
|
-
setItems([]);
|
|
3808
|
-
setNextCursor(null);
|
|
3809
|
-
setPhase("loadingFirst");
|
|
3810
|
-
void (async () => {
|
|
3811
|
-
try {
|
|
3812
|
-
const page = await viewRef.current.fetchPage({ q, sort, cursor: null, signal: controller.signal });
|
|
3813
|
-
if (seq !== seqRef.current) return;
|
|
3814
|
-
setItems(page.items);
|
|
3815
|
-
setNextCursor(page.nextCursor ?? null);
|
|
3816
|
-
setPhase("idle");
|
|
3817
|
-
} catch {
|
|
3818
|
-
if (controller.signal.aborted || seq !== seqRef.current) return;
|
|
3819
|
-
setPhase("error");
|
|
3820
|
-
}
|
|
3821
|
-
})();
|
|
3822
|
-
return () => controller.abort();
|
|
3823
|
-
}, [q, sort, seedKey, isDefaultView, reloadKey]);
|
|
3824
|
-
const loadMore = useCallback9(() => {
|
|
3825
|
-
const cursor = nextCursorRef.current;
|
|
3826
|
-
if (!cursor || loadingMoreRef.current) return;
|
|
3827
|
-
const { q: currentQ, sort: currentSort, fetchPage: currentFetch } = viewRef.current;
|
|
3828
|
-
const seq = seqRef.current;
|
|
3829
|
-
loadingMoreRef.current = true;
|
|
3830
|
-
lastOpRef.current = "more";
|
|
3831
|
-
const controller = new AbortController();
|
|
3832
|
-
loadMoreAbortRef.current = controller;
|
|
3833
|
-
setPhase("loadingMore");
|
|
3834
|
-
void (async () => {
|
|
3835
|
-
try {
|
|
3836
|
-
const page = await currentFetch({ q: currentQ, sort: currentSort, cursor, signal: controller.signal });
|
|
3837
|
-
if (seq !== seqRef.current) return;
|
|
3838
|
-
setItems((prev) => mergeSessionPages(prev, page.items));
|
|
3839
|
-
setNextCursor(page.nextCursor ?? null);
|
|
3840
|
-
setPhase("idle");
|
|
3841
|
-
} catch {
|
|
3842
|
-
if (controller.signal.aborted || seq !== seqRef.current) return;
|
|
3843
|
-
setPhase("error");
|
|
3844
|
-
} finally {
|
|
3845
|
-
if (seq === seqRef.current) loadingMoreRef.current = false;
|
|
3846
|
-
}
|
|
3847
|
-
})();
|
|
3848
|
-
}, []);
|
|
3849
|
-
const retry = useCallback9(() => {
|
|
3850
|
-
if (lastOpRef.current === "more") loadMore();
|
|
3851
|
-
else setReloadKey((key) => key + 1);
|
|
3852
|
-
}, [loadMore]);
|
|
3853
|
-
const reload = useCallback9(() => {
|
|
3854
|
-
setReloadKey((key) => key + 1);
|
|
3855
|
-
}, []);
|
|
3856
|
-
useEffect10(
|
|
3857
|
-
() => () => {
|
|
3858
|
-
resetAbortRef.current?.abort();
|
|
3859
|
-
loadMoreAbortRef.current?.abort();
|
|
3860
|
-
},
|
|
3861
|
-
[]
|
|
3862
|
-
);
|
|
3863
|
-
return {
|
|
3864
|
-
items,
|
|
3865
|
-
hasMore: nextCursor !== null,
|
|
3866
|
-
isLoadingFirst: phase === "loadingFirst",
|
|
3867
|
-
isLoadingMore: phase === "loadingMore",
|
|
3868
|
-
isError: phase === "error",
|
|
3869
|
-
loadMore,
|
|
3870
|
-
retry,
|
|
3871
|
-
reload
|
|
3872
|
-
};
|
|
3873
|
-
}
|
|
3874
|
-
var DEFAULT_LABELS = {
|
|
3875
|
-
renameTitle: "Rename session",
|
|
3876
|
-
renameField: "Title",
|
|
3877
|
-
renameSubmit: "Save",
|
|
3878
|
-
deleteTitle: "Delete session?",
|
|
3879
|
-
deleteBody: (title) => `This will permanently delete \u201C${title}\u201D and its messages. This cannot be undone.`,
|
|
3880
|
-
deleteSubmit: "Delete",
|
|
3881
|
-
cancel: "Cancel",
|
|
3882
|
-
renamed: "Session renamed",
|
|
3883
|
-
deleted: "Session deleted",
|
|
3884
|
-
renameFailed: "Failed to rename session",
|
|
3885
|
-
deleteFailed: "Failed to delete session"
|
|
3886
|
-
};
|
|
3887
|
-
function useSessionActions({
|
|
3888
|
-
renameSession,
|
|
3889
|
-
deleteSession,
|
|
3890
|
-
onChanged,
|
|
3891
|
-
onDeletedCurrent,
|
|
3892
|
-
currentSessionId,
|
|
3893
|
-
notify,
|
|
3894
|
-
labels
|
|
3895
|
-
}) {
|
|
3896
|
-
const text = { ...DEFAULT_LABELS, ...labels };
|
|
3897
|
-
const [renameTarget, setRenameTarget] = useState14(null);
|
|
3898
|
-
const [renameValue, setRenameValue] = useState14("");
|
|
3899
|
-
const [deleteTarget, setDeleteTarget] = useState14(null);
|
|
3900
|
-
const [busy, setBusy] = useState14(false);
|
|
3901
|
-
const [error, setError] = useState14(null);
|
|
3902
|
-
const openRename = useCallback9((session) => {
|
|
3903
|
-
setError(null);
|
|
3904
|
-
setRenameTarget(session);
|
|
3905
|
-
setRenameValue(session.title ?? "");
|
|
3906
|
-
}, []);
|
|
3907
|
-
const openDelete = useCallback9((session) => {
|
|
3908
|
-
setError(null);
|
|
3909
|
-
setDeleteTarget(session);
|
|
3910
|
-
}, []);
|
|
3911
|
-
const submitRename = useCallback9(async () => {
|
|
3912
|
-
if (!renameTarget) return;
|
|
3913
|
-
const title = renameValue.trim();
|
|
3914
|
-
if (!title || title === renameTarget.title) {
|
|
3915
|
-
setRenameTarget(null);
|
|
3916
|
-
return;
|
|
3917
|
-
}
|
|
3918
|
-
setBusy(true);
|
|
3919
|
-
setError(null);
|
|
3920
|
-
try {
|
|
3921
|
-
await renameSession(renameTarget.id, title);
|
|
3922
|
-
setRenameTarget(null);
|
|
3923
|
-
notify?.("success", text.renamed);
|
|
3924
|
-
onChanged?.();
|
|
3925
|
-
} catch (e) {
|
|
3926
|
-
const message = e instanceof Error ? e.message : text.renameFailed;
|
|
3927
|
-
setError(message);
|
|
3928
|
-
notify?.("error", message);
|
|
3929
|
-
} finally {
|
|
3930
|
-
setBusy(false);
|
|
3931
|
-
}
|
|
3932
|
-
}, [renameTarget, renameValue, renameSession, notify, onChanged, text.renamed, text.renameFailed]);
|
|
3933
|
-
const confirmDelete = useCallback9(async () => {
|
|
3934
|
-
if (!deleteTarget) return;
|
|
3935
|
-
const deletingCurrent = currentSessionId != null && deleteTarget.id === currentSessionId;
|
|
3936
|
-
setBusy(true);
|
|
3937
|
-
setError(null);
|
|
3938
|
-
try {
|
|
3939
|
-
await deleteSession(deleteTarget.id);
|
|
3940
|
-
setDeleteTarget(null);
|
|
3941
|
-
notify?.("success", text.deleted);
|
|
3942
|
-
onChanged?.();
|
|
3943
|
-
if (deletingCurrent) onDeletedCurrent?.();
|
|
3944
|
-
} catch (e) {
|
|
3945
|
-
const message = e instanceof Error ? e.message : text.deleteFailed;
|
|
3946
|
-
setError(message);
|
|
3947
|
-
notify?.("error", message);
|
|
3948
|
-
} finally {
|
|
3949
|
-
setBusy(false);
|
|
3950
|
-
}
|
|
3951
|
-
}, [deleteTarget, currentSessionId, deleteSession, notify, onChanged, onDeletedCurrent, text.deleted, text.deleteFailed]);
|
|
3952
|
-
const dialogs = /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3953
|
-
renameTarget && /* @__PURE__ */ jsxs9(
|
|
3954
|
-
SessionDialog,
|
|
3955
|
-
{
|
|
3956
|
-
title: text.renameTitle,
|
|
3957
|
-
onClose: () => setRenameTarget(null),
|
|
3958
|
-
busy,
|
|
3959
|
-
error,
|
|
3960
|
-
footer: /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3961
|
-
/* @__PURE__ */ jsx11(DialogButton, { onClick: () => setRenameTarget(null), disabled: busy, variant: "ghost", children: text.cancel }),
|
|
3962
|
-
/* @__PURE__ */ jsx11(DialogButton, { onClick: () => void submitRename(), disabled: busy || !renameValue.trim(), children: text.renameSubmit })
|
|
3963
|
-
] }),
|
|
3964
|
-
children: [
|
|
3965
|
-
/* @__PURE__ */ jsx11("label", { htmlFor: "agent-app-rename-session", className: "text-xs text-muted-foreground", children: text.renameField }),
|
|
3966
|
-
/* @__PURE__ */ jsx11(
|
|
3967
|
-
"input",
|
|
3968
|
-
{
|
|
3969
|
-
id: "agent-app-rename-session",
|
|
3970
|
-
value: renameValue,
|
|
3971
|
-
autoFocus: true,
|
|
3972
|
-
onChange: (e) => setRenameValue(e.target.value),
|
|
3973
|
-
onKeyDown: (e) => {
|
|
3974
|
-
if (e.key === "Enter" && !busy) {
|
|
3975
|
-
e.preventDefault();
|
|
3976
|
-
void submitRename();
|
|
3977
|
-
}
|
|
3978
|
-
},
|
|
3979
|
-
className: "mt-1.5 h-9 w-full rounded-md border border-strong bg-background px-3 text-sm text-foreground"
|
|
3980
|
-
}
|
|
3981
|
-
)
|
|
3982
|
-
]
|
|
3983
|
-
}
|
|
3984
|
-
),
|
|
3985
|
-
deleteTarget && /* @__PURE__ */ jsx11(
|
|
3986
|
-
SessionDialog,
|
|
3987
|
-
{
|
|
3988
|
-
title: text.deleteTitle,
|
|
3989
|
-
onClose: () => setDeleteTarget(null),
|
|
3990
|
-
busy,
|
|
3991
|
-
error,
|
|
3992
|
-
footer: /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
3993
|
-
/* @__PURE__ */ jsx11(DialogButton, { onClick: () => setDeleteTarget(null), disabled: busy, variant: "ghost", children: text.cancel }),
|
|
3994
|
-
/* @__PURE__ */ jsx11(DialogButton, { onClick: () => void confirmDelete(), disabled: busy, variant: "destructive", children: text.deleteSubmit })
|
|
3995
|
-
] }),
|
|
3996
|
-
children: /* @__PURE__ */ jsx11("p", { className: "text-sm text-muted-foreground", children: text.deleteBody(sessionLabel(deleteTarget)) })
|
|
3997
|
-
}
|
|
3998
|
-
)
|
|
3999
|
-
] });
|
|
4000
|
-
return { openRename, openDelete, dialogs, busy };
|
|
4001
|
-
}
|
|
4002
|
-
function DialogButton({
|
|
4003
|
-
children,
|
|
4004
|
-
onClick,
|
|
4005
|
-
disabled,
|
|
4006
|
-
variant = "primary"
|
|
4007
|
-
}) {
|
|
4008
|
-
const tone = variant === "ghost" ? "text-muted-foreground hover:bg-accent hover:text-foreground" : variant === "destructive" ? "bg-destructive text-destructive-foreground hover:opacity-90" : "bg-primary text-primary-foreground hover:opacity-90";
|
|
4009
|
-
return /* @__PURE__ */ jsx11(
|
|
4010
|
-
"button",
|
|
4011
|
-
{
|
|
4012
|
-
type: "button",
|
|
4013
|
-
onClick,
|
|
4014
|
-
disabled,
|
|
4015
|
-
className: `h-9 rounded-md px-3 text-sm font-medium transition disabled:opacity-50 ${tone}`,
|
|
4016
|
-
children
|
|
4017
|
-
}
|
|
4018
|
-
);
|
|
4019
|
-
}
|
|
4020
|
-
function SessionDialog({
|
|
4021
|
-
title,
|
|
4022
|
-
children,
|
|
4023
|
-
footer,
|
|
4024
|
-
onClose,
|
|
4025
|
-
busy,
|
|
4026
|
-
error
|
|
4027
|
-
}) {
|
|
4028
|
-
useEffect10(() => {
|
|
4029
|
-
const onKey = (e) => {
|
|
4030
|
-
if (e.key === "Escape" && !busy) onClose();
|
|
4031
|
-
};
|
|
4032
|
-
document.addEventListener("keydown", onKey);
|
|
4033
|
-
return () => document.removeEventListener("keydown", onKey);
|
|
4034
|
-
}, [busy, onClose]);
|
|
4035
|
-
return /* @__PURE__ */ jsxs9("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
|
|
4036
|
-
/* @__PURE__ */ jsx11(
|
|
4037
|
-
"div",
|
|
4038
|
-
{
|
|
4039
|
-
className: "absolute inset-0 bg-black/50",
|
|
4040
|
-
onClick: () => {
|
|
4041
|
-
if (!busy) onClose();
|
|
4042
|
-
},
|
|
4043
|
-
"aria-hidden": true
|
|
4044
|
-
}
|
|
4045
|
-
),
|
|
4046
|
-
/* @__PURE__ */ jsxs9(
|
|
4047
|
-
"div",
|
|
4048
|
-
{
|
|
4049
|
-
role: "dialog",
|
|
4050
|
-
"aria-modal": "true",
|
|
4051
|
-
"aria-label": title,
|
|
4052
|
-
className: `relative w-full max-w-sm rounded-xl border border-card-edge bg-popover p-5 ${OVERLAY_SHADOW}`,
|
|
4053
|
-
children: [
|
|
4054
|
-
/* @__PURE__ */ jsx11("h2", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
4055
|
-
/* @__PURE__ */ jsx11("div", { className: "mt-3", children }),
|
|
4056
|
-
error && /* @__PURE__ */ jsx11("p", { role: "alert", className: "mt-3 rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
|
|
4057
|
-
/* @__PURE__ */ jsx11("div", { className: "mt-5 flex justify-end gap-2", children: footer })
|
|
4058
|
-
]
|
|
4059
|
-
}
|
|
4060
|
-
)
|
|
4061
|
-
] });
|
|
4062
|
-
}
|
|
4063
|
-
function AnchorLink({ to, className, children }) {
|
|
4064
|
-
return /* @__PURE__ */ jsx11("a", { href: to, className, children });
|
|
4065
|
-
}
|
|
4066
|
-
var MINUTE = 6e4;
|
|
4067
|
-
var HOUR = 60 * MINUTE;
|
|
4068
|
-
var DAY = 24 * HOUR;
|
|
4069
|
-
function formatSessionTimestamp(isoDate) {
|
|
4070
|
-
if (!isoDate) return "";
|
|
4071
|
-
const at = Date.parse(isoDate);
|
|
4072
|
-
if (Number.isNaN(at)) return "";
|
|
4073
|
-
const delta = Date.now() - at;
|
|
4074
|
-
if (delta < MINUTE) return "just now";
|
|
4075
|
-
if (delta < HOUR) return `${Math.floor(delta / MINUTE)}m ago`;
|
|
4076
|
-
if (delta < DAY) return `${Math.floor(delta / HOUR)}h ago`;
|
|
4077
|
-
if (delta < 7 * DAY) return `${Math.floor(delta / DAY)}d ago`;
|
|
4078
|
-
return new Date(at).toLocaleDateString(void 0, { month: "short", day: "numeric" });
|
|
4079
|
-
}
|
|
4080
|
-
function SkeletonRows() {
|
|
4081
|
-
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
4082
|
-
/* @__PURE__ */ jsx11("span", { role: "status", "aria-live": "polite", "aria-busy": true, className: "sr-only", children: "Loading sessions\u2026" }),
|
|
4083
|
-
/* @__PURE__ */ jsx11("div", { className: "flex flex-col gap-0.5", "aria-hidden": true, children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 px-3 py-2.5", children: [
|
|
4084
|
-
/* @__PURE__ */ jsx11("div", { className: "h-4 w-4 animate-pulse rounded bg-muted" }),
|
|
4085
|
-
/* @__PURE__ */ jsx11("div", { className: "h-4 w-1/2 animate-pulse rounded bg-muted" }),
|
|
4086
|
-
/* @__PURE__ */ jsx11("div", { className: "ml-auto h-3 w-12 animate-pulse rounded bg-muted" })
|
|
4087
|
-
] }, i)) })
|
|
4088
|
-
] });
|
|
4089
|
-
}
|
|
4090
|
-
function MessageIcon({ className }) {
|
|
4091
|
-
return /* @__PURE__ */ jsx11("svg", { viewBox: "0 0 24 24", className, fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx11("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
|
|
4092
|
-
}
|
|
4093
|
-
function SessionHistoryPanel({
|
|
4094
|
-
history,
|
|
4095
|
-
hasAnySessions,
|
|
4096
|
-
query,
|
|
4097
|
-
onQueryChange,
|
|
4098
|
-
sort,
|
|
4099
|
-
onSortChange,
|
|
4100
|
-
hrefForSession,
|
|
4101
|
-
linkComponent: Link = AnchorLink,
|
|
4102
|
-
respondingSessionIds,
|
|
4103
|
-
onRename,
|
|
4104
|
-
onDelete,
|
|
4105
|
-
onBulkAction,
|
|
4106
|
-
renameLabel = "Rename",
|
|
4107
|
-
deleteLabel = "Delete",
|
|
4108
|
-
extraActions,
|
|
4109
|
-
newSessionHref,
|
|
4110
|
-
title = "History",
|
|
4111
|
-
untitledLabel = UNTITLED_SESSION_LABEL,
|
|
4112
|
-
emptyTitle = "No sessions yet",
|
|
4113
|
-
emptyDescription = "Your chat sessions will show up here once you start one.",
|
|
4114
|
-
formatTimestamp = formatSessionTimestamp,
|
|
4115
|
-
contentWidth = "reading",
|
|
4116
|
-
className
|
|
4117
|
-
}) {
|
|
4118
|
-
const scrollRef = useRef10(null);
|
|
4119
|
-
const sentinelRef = useInfiniteScroll(history.loadMore, {
|
|
4120
|
-
enabled: history.hasMore && !history.isLoadingMore && !history.isError,
|
|
4121
|
-
root: scrollRef,
|
|
4122
|
-
rootMargin: "300px"
|
|
4123
|
-
});
|
|
4124
|
-
const searchTerm = query.trim();
|
|
4125
|
-
const isSearching = searchTerm.length > 0;
|
|
4126
|
-
const column = contentWidth === "full" ? "w-full" : "mx-auto w-full max-w-4xl";
|
|
4127
|
-
const [selectedIds, setSelectedIds] = useState14(/* @__PURE__ */ new Set());
|
|
4128
|
-
const [ageDays, setAgeDays] = useState14("30");
|
|
4129
|
-
const [bulkTarget, setBulkTarget] = useState14(null);
|
|
4130
|
-
const [bulkBusy, setBulkBusy] = useState14(false);
|
|
4131
|
-
const [bulkError, setBulkError] = useState14(null);
|
|
4132
|
-
useEffect10(() => {
|
|
4133
|
-
setSelectedIds(/* @__PURE__ */ new Set());
|
|
4134
|
-
}, [searchTerm, sort]);
|
|
4135
|
-
useEffect10(() => {
|
|
4136
|
-
const visible = new Set(history.items.map((item) => item.id));
|
|
4137
|
-
setSelectedIds((current) => {
|
|
4138
|
-
const next = new Set([...current].filter((id) => visible.has(id)));
|
|
4139
|
-
return next.size === current.size ? current : next;
|
|
4140
|
-
});
|
|
4141
|
-
}, [history.items]);
|
|
4142
|
-
const selectedCount = selectedIds.size;
|
|
4143
|
-
const allVisibleSelected = history.items.length > 0 && history.items.every((item) => selectedIds.has(item.id));
|
|
4144
|
-
const parsedAgeDays = Number(ageDays);
|
|
4145
|
-
const validAgeDays = Number.isInteger(parsedAgeDays) && parsedAgeDays >= 1 && parsedAgeDays <= 36500;
|
|
4146
|
-
const openBulkAction = useCallback9((action) => {
|
|
4147
|
-
const verb = deleteLabel.toLowerCase();
|
|
4148
|
-
if (action.kind === "selected") {
|
|
4149
|
-
setBulkTarget({
|
|
4150
|
-
action,
|
|
4151
|
-
title: `${deleteLabel} selected sessions?`,
|
|
4152
|
-
body: `${verb === "delete" ? "This permanently removes" : `This ${verb}s`} ${action.ids.length} selected session${action.ids.length === 1 ? "" : "s"} and its messages.`
|
|
4153
|
-
});
|
|
4154
|
-
return;
|
|
4155
|
-
}
|
|
4156
|
-
const range = action.kind === "older-than" ? `older than ${action.days} days` : `from the last ${action.days} days`;
|
|
4157
|
-
setBulkTarget({
|
|
4158
|
-
action,
|
|
4159
|
-
title: `${deleteLabel} sessions ${range}?`,
|
|
4160
|
-
body: "This applies to every matching session in this workspace, including sessions not currently loaded in this list."
|
|
4161
|
-
});
|
|
4162
|
-
}, [deleteLabel]);
|
|
4163
|
-
const confirmBulkAction = useCallback9(async () => {
|
|
4164
|
-
if (!bulkTarget || !onBulkAction) return;
|
|
4165
|
-
setBulkBusy(true);
|
|
4166
|
-
setBulkError(null);
|
|
4167
|
-
try {
|
|
4168
|
-
await onBulkAction(bulkTarget.action);
|
|
4169
|
-
setBulkTarget(null);
|
|
4170
|
-
setSelectedIds(/* @__PURE__ */ new Set());
|
|
4171
|
-
history.reload();
|
|
4172
|
-
} catch (error) {
|
|
4173
|
-
setBulkError(error instanceof Error ? error.message : `Could not ${deleteLabel.toLowerCase()} sessions`);
|
|
4174
|
-
} finally {
|
|
4175
|
-
setBulkBusy(false);
|
|
4176
|
-
}
|
|
4177
|
-
}, [bulkTarget, deleteLabel, history, onBulkAction]);
|
|
4178
|
-
return /* @__PURE__ */ jsxs9("div", { className: `flex min-h-0 min-w-0 flex-1 flex-col ${className ?? ""}`, children: [
|
|
4179
|
-
/* @__PURE__ */ jsx11("header", { className: "flex h-14 shrink-0 items-center border-b border-border px-4 sm:px-6", children: /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-3 px-3 ${column}`, children: [
|
|
4180
|
-
/* @__PURE__ */ jsx11("h1", { className: "flex-1 truncate text-sm font-semibold text-foreground", children: title }),
|
|
4181
|
-
newSessionHref && /* @__PURE__ */ jsxs9(
|
|
4182
|
-
Link,
|
|
4183
|
-
{
|
|
4184
|
-
to: newSessionHref,
|
|
4185
|
-
className: "inline-flex h-8 shrink-0 items-center gap-1.5 rounded-md bg-primary px-3 text-xs font-medium text-primary-foreground transition hover:opacity-90",
|
|
4186
|
-
children: [
|
|
4187
|
-
/* @__PURE__ */ jsx11("span", { "aria-hidden": true, className: "text-sm leading-none", children: "+" }),
|
|
4188
|
-
"New chat"
|
|
4189
|
-
]
|
|
4190
|
-
}
|
|
4191
|
-
)
|
|
4192
|
-
] }) }),
|
|
4193
|
-
/* @__PURE__ */ jsxs9("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
4194
|
-
hasAnySessions && /* @__PURE__ */ jsxs9("div", { className: "sticky top-0 z-10 bg-background px-4 sm:px-6", children: [
|
|
4195
|
-
/* @__PURE__ */ jsxs9("div", { className: `flex flex-col gap-2 px-3 pb-3 pt-4 sm:flex-row sm:items-center sm:gap-3 ${column}`, children: [
|
|
4196
|
-
/* @__PURE__ */ jsx11(
|
|
4197
|
-
"input",
|
|
4198
|
-
{
|
|
4199
|
-
type: "search",
|
|
4200
|
-
value: query,
|
|
4201
|
-
onChange: (e) => onQueryChange(e.target.value),
|
|
4202
|
-
placeholder: "Search your sessions\u2026",
|
|
4203
|
-
"aria-label": "Search sessions",
|
|
4204
|
-
className: "h-9 min-w-0 appearance-none rounded-md border border-strong bg-card px-3 text-sm text-foreground placeholder:text-muted-foreground sm:flex-1 [&::-webkit-search-cancel-button]:appearance-none"
|
|
4205
|
-
}
|
|
4206
|
-
),
|
|
4207
|
-
/* @__PURE__ */ jsxs9(
|
|
4208
|
-
"select",
|
|
4209
|
-
{
|
|
4210
|
-
value: sort,
|
|
4211
|
-
onChange: (e) => onSortChange(e.target.value),
|
|
4212
|
-
"aria-label": "Sort sessions",
|
|
4213
|
-
className: "h-9 shrink-0 appearance-none rounded-md border border-strong bg-card px-2 text-sm text-foreground sm:w-[132px]",
|
|
4214
|
-
children: [
|
|
4215
|
-
/* @__PURE__ */ jsx11("option", { value: "newest", children: "Newest" }),
|
|
4216
|
-
/* @__PURE__ */ jsx11("option", { value: "oldest", children: "Oldest" })
|
|
4217
|
-
]
|
|
4218
|
-
}
|
|
4219
|
-
)
|
|
4220
|
-
] }),
|
|
4221
|
-
onBulkAction && /* @__PURE__ */ jsxs9("div", { className: `flex flex-col gap-2 border-t border-border px-3 py-3 ${column}`, children: [
|
|
4222
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4223
|
-
/* @__PURE__ */ jsx11(
|
|
4224
|
-
"button",
|
|
4225
|
-
{
|
|
4226
|
-
type: "button",
|
|
4227
|
-
onClick: () => setSelectedIds(new Set(history.items.map((item) => item.id))),
|
|
4228
|
-
disabled: allVisibleSelected || history.items.length === 0,
|
|
4229
|
-
className: "h-8 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition hover:bg-accent disabled:opacity-50",
|
|
4230
|
-
children: "Select all"
|
|
4231
|
-
}
|
|
4232
|
-
),
|
|
4233
|
-
/* @__PURE__ */ jsx11(
|
|
4234
|
-
"button",
|
|
4235
|
-
{
|
|
4236
|
-
type: "button",
|
|
4237
|
-
onClick: () => setSelectedIds(/* @__PURE__ */ new Set()),
|
|
4238
|
-
disabled: selectedCount === 0,
|
|
4239
|
-
className: "h-8 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition hover:bg-accent disabled:opacity-50",
|
|
4240
|
-
children: "Deselect all"
|
|
4241
|
-
}
|
|
4242
|
-
),
|
|
4243
|
-
/* @__PURE__ */ jsxs9("span", { className: "text-xs text-muted-foreground", "aria-live": "polite", children: [
|
|
4244
|
-
selectedCount,
|
|
4245
|
-
" selected"
|
|
4246
|
-
] }),
|
|
4247
|
-
selectedCount > 0 && /* @__PURE__ */ jsxs9(
|
|
4248
|
-
"button",
|
|
4249
|
-
{
|
|
4250
|
-
type: "button",
|
|
4251
|
-
onClick: () => openBulkAction({ kind: "selected", ids: [...selectedIds] }),
|
|
4252
|
-
className: "h-8 rounded-md bg-destructive px-2.5 text-xs font-medium text-destructive-foreground transition hover:opacity-90",
|
|
4253
|
-
children: [
|
|
4254
|
-
deleteLabel,
|
|
4255
|
-
" selected"
|
|
4256
|
-
]
|
|
4257
|
-
}
|
|
4258
|
-
)
|
|
4259
|
-
] }),
|
|
4260
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
4261
|
-
/* @__PURE__ */ jsx11("label", { htmlFor: "agent-app-session-age", className: "text-xs text-muted-foreground", children: "Session age" }),
|
|
4262
|
-
/* @__PURE__ */ jsx11(
|
|
4263
|
-
"input",
|
|
4264
|
-
{
|
|
4265
|
-
id: "agent-app-session-age",
|
|
4266
|
-
type: "number",
|
|
4267
|
-
min: 1,
|
|
4268
|
-
max: 36500,
|
|
4269
|
-
value: ageDays,
|
|
4270
|
-
onChange: (event) => setAgeDays(event.target.value),
|
|
4271
|
-
"aria-invalid": ageDays.length > 0 && !validAgeDays,
|
|
4272
|
-
className: "h-8 w-20 rounded-md border border-strong bg-card px-2 text-xs tabular-nums text-foreground"
|
|
4273
|
-
}
|
|
4274
|
-
),
|
|
4275
|
-
/* @__PURE__ */ jsx11("span", { className: "text-xs text-muted-foreground", children: "days" }),
|
|
4276
|
-
/* @__PURE__ */ jsxs9(
|
|
4277
|
-
"button",
|
|
4278
|
-
{
|
|
4279
|
-
type: "button",
|
|
4280
|
-
onClick: () => openBulkAction({ kind: "older-than", days: parsedAgeDays }),
|
|
4281
|
-
disabled: !validAgeDays,
|
|
4282
|
-
className: "h-8 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition hover:bg-accent disabled:opacity-50",
|
|
4283
|
-
children: [
|
|
4284
|
-
deleteLabel,
|
|
4285
|
-
" older"
|
|
4286
|
-
]
|
|
4287
|
-
}
|
|
4288
|
-
),
|
|
4289
|
-
/* @__PURE__ */ jsxs9(
|
|
4290
|
-
"button",
|
|
4291
|
-
{
|
|
4292
|
-
type: "button",
|
|
4293
|
-
onClick: () => openBulkAction({ kind: "newer-than", days: parsedAgeDays }),
|
|
4294
|
-
disabled: !validAgeDays,
|
|
4295
|
-
className: "h-8 rounded-md border border-border px-2.5 text-xs font-medium text-foreground transition hover:bg-accent disabled:opacity-50",
|
|
4296
|
-
children: [
|
|
4297
|
-
deleteLabel,
|
|
4298
|
-
" recent"
|
|
4299
|
-
]
|
|
4300
|
-
}
|
|
4301
|
-
)
|
|
4302
|
-
] })
|
|
4303
|
-
] })
|
|
4304
|
-
] }),
|
|
4305
|
-
/* @__PURE__ */ jsx11("div", { className: `px-4 pb-8 pt-1 sm:px-6 ${column}`, children: !hasAnySessions ? /* @__PURE__ */ jsxs9("div", { className: "flex min-h-[50vh] flex-col items-center justify-center gap-2 text-center", children: [
|
|
4306
|
-
/* @__PURE__ */ jsx11("p", { className: "text-sm font-medium text-foreground", children: emptyTitle }),
|
|
4307
|
-
/* @__PURE__ */ jsx11("p", { className: "max-w-xs text-xs text-muted-foreground", children: emptyDescription })
|
|
4308
|
-
] }) : history.isLoadingFirst ? /* @__PURE__ */ jsx11(SkeletonRows, {}) : history.items.length === 0 ? history.isError ? /* @__PURE__ */ jsx11(ErrorBlock, { onRetry: history.retry, message: "Couldn\u2019t load your sessions." }) : isSearching ? /* @__PURE__ */ jsxs9("p", { className: "py-16 text-center text-sm text-muted-foreground", children: [
|
|
4309
|
-
"No sessions match \u201C",
|
|
4310
|
-
searchTerm,
|
|
4311
|
-
"\u201D."
|
|
4312
|
-
] }) : /* @__PURE__ */ jsx11("p", { className: "py-16 text-center text-sm text-muted-foreground", children: "No sessions remain." }) : /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-0.5", children: [
|
|
4313
|
-
history.items.map((session) => /* @__PURE__ */ jsx11(
|
|
4314
|
-
SessionRow,
|
|
4315
|
-
{
|
|
4316
|
-
session,
|
|
4317
|
-
href: hrefForSession(session.id),
|
|
4318
|
-
Link,
|
|
4319
|
-
responding: respondingSessionIds?.has(session.id) ?? false,
|
|
4320
|
-
untitledLabel,
|
|
4321
|
-
timestamp: formatTimestamp(session.updatedAt),
|
|
4322
|
-
onRename,
|
|
4323
|
-
onDelete,
|
|
4324
|
-
selectable: Boolean(onBulkAction),
|
|
4325
|
-
selected: selectedIds.has(session.id),
|
|
4326
|
-
onSelectedChange: (selected) => {
|
|
4327
|
-
setSelectedIds((current) => {
|
|
4328
|
-
const next = new Set(current);
|
|
4329
|
-
if (selected) next.add(session.id);
|
|
4330
|
-
else next.delete(session.id);
|
|
4331
|
-
return next;
|
|
4332
|
-
});
|
|
4333
|
-
},
|
|
4334
|
-
renameLabel,
|
|
4335
|
-
deleteLabel,
|
|
4336
|
-
extraActions
|
|
4337
|
-
},
|
|
4338
|
-
session.id
|
|
4339
|
-
)),
|
|
4340
|
-
history.isError ? /* @__PURE__ */ jsx11(ErrorBlock, { onRetry: history.retry, message: "Couldn\u2019t load more sessions.", inline: true }) : history.hasMore ? /* @__PURE__ */ jsx11("div", { ref: sentinelRef, className: "flex items-center justify-center py-6", children: history.isLoadingMore && /* @__PURE__ */ jsx11("span", { role: "status", "aria-live": "polite", "aria-busy": true, className: "text-xs text-muted-foreground", children: "Loading\u2026" }) }) : null
|
|
4341
|
-
] }) })
|
|
4342
|
-
] }),
|
|
4343
|
-
bulkTarget && /* @__PURE__ */ jsx11(
|
|
4344
|
-
SessionDialog,
|
|
4345
|
-
{
|
|
4346
|
-
title: bulkTarget.title,
|
|
4347
|
-
onClose: () => {
|
|
4348
|
-
if (!bulkBusy) {
|
|
4349
|
-
setBulkTarget(null);
|
|
4350
|
-
setBulkError(null);
|
|
4351
|
-
}
|
|
4352
|
-
},
|
|
4353
|
-
busy: bulkBusy,
|
|
4354
|
-
error: bulkError,
|
|
4355
|
-
footer: /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
4356
|
-
/* @__PURE__ */ jsx11(
|
|
4357
|
-
DialogButton,
|
|
4358
|
-
{
|
|
4359
|
-
onClick: () => {
|
|
4360
|
-
setBulkTarget(null);
|
|
4361
|
-
setBulkError(null);
|
|
4362
|
-
},
|
|
4363
|
-
disabled: bulkBusy,
|
|
4364
|
-
variant: "ghost",
|
|
4365
|
-
children: "Cancel"
|
|
4366
|
-
}
|
|
4367
|
-
),
|
|
4368
|
-
/* @__PURE__ */ jsx11(DialogButton, { onClick: () => void confirmBulkAction(), disabled: bulkBusy, variant: "destructive", children: bulkBusy ? "Working\u2026" : deleteLabel })
|
|
4369
|
-
] }),
|
|
4370
|
-
children: /* @__PURE__ */ jsx11("p", { className: "text-sm text-muted-foreground", children: bulkTarget.body })
|
|
4371
|
-
}
|
|
4372
|
-
)
|
|
4373
|
-
] });
|
|
4374
|
-
}
|
|
4375
|
-
function ErrorBlock({ message, onRetry, inline }) {
|
|
4376
|
-
return /* @__PURE__ */ jsxs9(
|
|
4377
|
-
"div",
|
|
4378
|
-
{
|
|
4379
|
-
className: inline ? "flex items-center justify-center gap-3 py-6 text-sm text-muted-foreground" : "flex min-h-[40vh] flex-col items-center justify-center gap-3 text-center",
|
|
4380
|
-
children: [
|
|
4381
|
-
/* @__PURE__ */ jsx11("span", { className: "text-sm text-muted-foreground", children: message }),
|
|
4382
|
-
/* @__PURE__ */ jsx11(
|
|
4383
|
-
"button",
|
|
4384
|
-
{
|
|
4385
|
-
type: "button",
|
|
4386
|
-
onClick: onRetry,
|
|
4387
|
-
className: "h-8 rounded-md border border-border px-3 text-xs font-medium text-foreground transition hover:bg-accent",
|
|
4388
|
-
children: "Retry"
|
|
4389
|
-
}
|
|
4390
|
-
)
|
|
4391
|
-
]
|
|
4392
|
-
}
|
|
4393
|
-
);
|
|
4394
|
-
}
|
|
4395
|
-
function SessionRow({
|
|
4396
|
-
session,
|
|
4397
|
-
href,
|
|
4398
|
-
Link,
|
|
4399
|
-
responding,
|
|
4400
|
-
untitledLabel,
|
|
4401
|
-
timestamp,
|
|
4402
|
-
onRename,
|
|
4403
|
-
onDelete,
|
|
4404
|
-
renameLabel,
|
|
4405
|
-
deleteLabel,
|
|
4406
|
-
extraActions,
|
|
4407
|
-
selectable,
|
|
4408
|
-
selected,
|
|
4409
|
-
onSelectedChange
|
|
4410
|
-
}) {
|
|
4411
|
-
const [menuOpen, setMenuOpen] = useState14(false);
|
|
4412
|
-
const panelId = useId3();
|
|
4413
|
-
const { containerRef, triggerRef, panelRef, triggerProps } = usePopover(menuOpen, setMenuOpen);
|
|
4414
|
-
const extras = extraActions?.(session) ?? [];
|
|
4415
|
-
const hasMenu = Boolean(onRename) || Boolean(onDelete) || extras.length > 0;
|
|
4416
|
-
const showUnread = Boolean(session.unread) && !responding;
|
|
4417
|
-
return /* @__PURE__ */ jsxs9("div", { className: `group relative flex items-center gap-2 rounded-lg px-3 py-2.5 transition-colors hover:bg-accent ${selected ? "bg-primary/10" : ""}`, children: [
|
|
4418
|
-
selectable && /* @__PURE__ */ jsx11(
|
|
4419
|
-
"input",
|
|
4420
|
-
{
|
|
4421
|
-
type: "checkbox",
|
|
4422
|
-
checked: selected,
|
|
4423
|
-
onChange: (event) => onSelectedChange(event.target.checked),
|
|
4424
|
-
"aria-label": `Select ${sessionLabel(session, untitledLabel)}`,
|
|
4425
|
-
className: "h-4 w-4 shrink-0 rounded border-border accent-primary"
|
|
4426
|
-
}
|
|
4427
|
-
),
|
|
4428
|
-
/* @__PURE__ */ jsxs9(Link, { to: href, className: "flex min-w-0 flex-1 items-center gap-3", children: [
|
|
4429
|
-
showUnread && /* @__PURE__ */ jsx11("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-primary", "aria-hidden": true }),
|
|
4430
|
-
/* @__PURE__ */ jsx11(MessageIcon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
|
|
4431
|
-
/* @__PURE__ */ jsx11(
|
|
4432
|
-
"span",
|
|
4433
|
-
{
|
|
4434
|
-
className: `truncate text-sm ${responding ? "text-muted-foreground" : "text-foreground"} ${showUnread ? "font-semibold" : ""}`,
|
|
4435
|
-
...responding ? { role: "status", "aria-label": "Agent responding" } : {},
|
|
4436
|
-
children: sessionLabel(session, untitledLabel)
|
|
4437
|
-
}
|
|
4438
|
-
)
|
|
4439
|
-
] }),
|
|
4440
|
-
/* @__PURE__ */ jsx11("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: timestamp }),
|
|
4441
|
-
hasMenu && /* @__PURE__ */ jsxs9("div", { ref: containerRef, className: "relative shrink-0", children: [
|
|
4442
|
-
/* @__PURE__ */ jsx11(
|
|
4443
|
-
"button",
|
|
4444
|
-
{
|
|
4445
|
-
type: "button",
|
|
4446
|
-
...triggerProps,
|
|
4447
|
-
"aria-label": "Session actions",
|
|
4448
|
-
"aria-controls": menuOpen ? panelId : void 0,
|
|
4449
|
-
onClick: () => setMenuOpen((open) => !open),
|
|
4450
|
-
className: "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition hover:bg-muted hover:text-foreground focus-visible:opacity-100 sm:opacity-0 sm:group-hover:opacity-100 aria-expanded:opacity-100",
|
|
4451
|
-
children: /* @__PURE__ */ jsx11("span", { "aria-hidden": true, className: "text-base leading-none", children: "\u22EF" })
|
|
4452
|
-
}
|
|
4453
|
-
),
|
|
4454
|
-
/* @__PURE__ */ jsxs9(
|
|
4455
|
-
PopoverSurface,
|
|
4456
|
-
{
|
|
4457
|
-
open: menuOpen,
|
|
4458
|
-
id: panelId,
|
|
4459
|
-
role: "menu",
|
|
4460
|
-
triggerRef,
|
|
4461
|
-
panelRef,
|
|
4462
|
-
className: `w-36 overflow-hidden rounded-md border border-card-edge bg-popover py-1 ${OVERLAY_SHADOW}`,
|
|
4463
|
-
children: [
|
|
4464
|
-
onRename && /* @__PURE__ */ jsx11(
|
|
4465
|
-
"button",
|
|
4466
|
-
{
|
|
4467
|
-
type: "button",
|
|
4468
|
-
role: "menuitem",
|
|
4469
|
-
onClick: () => {
|
|
4470
|
-
setMenuOpen(false);
|
|
4471
|
-
onRename(session);
|
|
4472
|
-
},
|
|
4473
|
-
className: "block w-full px-3 py-1.5 text-left text-xs text-foreground transition hover:bg-accent",
|
|
4474
|
-
children: renameLabel
|
|
4475
|
-
}
|
|
4476
|
-
),
|
|
4477
|
-
extras.map((action) => /* @__PURE__ */ jsx11(
|
|
4478
|
-
"button",
|
|
4479
|
-
{
|
|
4480
|
-
type: "button",
|
|
4481
|
-
role: "menuitem",
|
|
4482
|
-
onClick: () => {
|
|
4483
|
-
setMenuOpen(false);
|
|
4484
|
-
action.onSelect();
|
|
4485
|
-
},
|
|
4486
|
-
className: `block w-full px-3 py-1.5 text-left text-xs transition ${action.destructive ? "text-destructive hover:bg-destructive/10" : "text-foreground hover:bg-accent"}`,
|
|
4487
|
-
children: action.label
|
|
4488
|
-
},
|
|
4489
|
-
action.id
|
|
4490
|
-
)),
|
|
4491
|
-
onDelete && /* @__PURE__ */ jsx11(
|
|
4492
|
-
"button",
|
|
4493
|
-
{
|
|
4494
|
-
type: "button",
|
|
4495
|
-
role: "menuitem",
|
|
4496
|
-
onClick: () => {
|
|
4497
|
-
setMenuOpen(false);
|
|
4498
|
-
onDelete(session);
|
|
4499
|
-
},
|
|
4500
|
-
className: "block w-full px-3 py-1.5 text-left text-xs text-destructive transition hover:bg-destructive/10",
|
|
4501
|
-
children: deleteLabel
|
|
4502
|
-
}
|
|
4503
|
-
)
|
|
4504
|
-
]
|
|
4505
|
-
}
|
|
4506
|
-
)
|
|
4507
|
-
] })
|
|
4508
|
-
] });
|
|
4509
|
-
}
|
|
4510
|
-
|
|
4511
|
-
// src/web-react/record-grid.tsx
|
|
4512
|
-
import {
|
|
4513
|
-
Fragment as Fragment6,
|
|
4514
|
-
isValidElement,
|
|
4515
|
-
useCallback as useCallback10,
|
|
4516
|
-
useEffect as useEffect11,
|
|
4517
|
-
useId as useId4,
|
|
4518
|
-
useMemo as useMemo7,
|
|
4519
|
-
useRef as useRef11,
|
|
4520
|
-
useState as useState15
|
|
4521
|
-
} from "react";
|
|
4522
3733
|
|
|
4523
3734
|
// src/web-react/record-grid-model.ts
|
|
4524
3735
|
function recordGridOk(value) {
|
|
@@ -4873,7 +4084,7 @@ function pruneRecordGridOverlay(rows, overlay) {
|
|
|
4873
4084
|
}
|
|
4874
4085
|
|
|
4875
4086
|
// src/web-react/record-grid.tsx
|
|
4876
|
-
import { jsx as
|
|
4087
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4877
4088
|
var EMPTY_RECORD_GRID_ROWS = [];
|
|
4878
4089
|
var CELL_KEY_SEPARATOR = "\0";
|
|
4879
4090
|
function cellKey(rowId, columnId) {
|
|
@@ -4932,57 +4143,57 @@ function RecordGrid({
|
|
|
4932
4143
|
loadingRowCount = 3,
|
|
4933
4144
|
className
|
|
4934
4145
|
}) {
|
|
4935
|
-
const fieldPrefix =
|
|
4936
|
-
const [overlay, setOverlay] =
|
|
4937
|
-
const [editing, setEditingState] =
|
|
4938
|
-
const [cellErrors, setCellErrors] =
|
|
4939
|
-
const [rowErrors, setRowErrors] =
|
|
4940
|
-
const [pendingRows, setPendingRows] =
|
|
4941
|
-
const [focus, setFocus] =
|
|
4942
|
-
const [openSource, setOpenSource] =
|
|
4943
|
-
const [confirmDelete, setConfirmDelete] =
|
|
4944
|
-
const [adding, setAdding] =
|
|
4945
|
-
const [draft, setDraft] =
|
|
4946
|
-
const [draftErrors, setDraftErrors] =
|
|
4947
|
-
const [draftError, setDraftError] =
|
|
4948
|
-
const [creating, setCreating] =
|
|
4949
|
-
const cellRefs =
|
|
4950
|
-
const settling =
|
|
4951
|
-
const draftCounter =
|
|
4952
|
-
const editingRef =
|
|
4953
|
-
const setEditing =
|
|
4146
|
+
const fieldPrefix = useId3();
|
|
4147
|
+
const [overlay, setOverlay] = useState14(EMPTY_RECORD_GRID_OVERLAY);
|
|
4148
|
+
const [editing, setEditingState] = useState14(null);
|
|
4149
|
+
const [cellErrors, setCellErrors] = useState14({});
|
|
4150
|
+
const [rowErrors, setRowErrors] = useState14({});
|
|
4151
|
+
const [pendingRows, setPendingRows] = useState14({});
|
|
4152
|
+
const [focus, setFocus] = useState14(null);
|
|
4153
|
+
const [openSource, setOpenSource] = useState14(null);
|
|
4154
|
+
const [confirmDelete, setConfirmDelete] = useState14(null);
|
|
4155
|
+
const [adding, setAdding] = useState14(false);
|
|
4156
|
+
const [draft, setDraft] = useState14({ ...newRowDefaults ?? {} });
|
|
4157
|
+
const [draftErrors, setDraftErrors] = useState14({});
|
|
4158
|
+
const [draftError, setDraftError] = useState14(null);
|
|
4159
|
+
const [creating, setCreating] = useState14(false);
|
|
4160
|
+
const cellRefs = useRef10(/* @__PURE__ */ new Map());
|
|
4161
|
+
const settling = useRef10(false);
|
|
4162
|
+
const draftCounter = useRef10(0);
|
|
4163
|
+
const editingRef = useRef10(null);
|
|
4164
|
+
const setEditing = useCallback9((next) => {
|
|
4954
4165
|
editingRef.current = next;
|
|
4955
4166
|
setEditingState(next);
|
|
4956
4167
|
}, []);
|
|
4957
4168
|
const callerRows = state.status === "ready" || state.status === "empty" ? state.value : EMPTY_RECORD_GRID_ROWS;
|
|
4958
|
-
|
|
4169
|
+
useEffect10(() => {
|
|
4959
4170
|
setOverlay((current) => pruneRecordGridOverlay(callerRows, current));
|
|
4960
4171
|
}, [callerRows]);
|
|
4961
|
-
const visibleRows =
|
|
4962
|
-
const diffs =
|
|
4172
|
+
const visibleRows = useMemo6(() => projectRecordGridRows(callerRows, overlay), [callerRows, overlay]);
|
|
4173
|
+
const diffs = useMemo6(
|
|
4963
4174
|
() => proposed === void 0 ? null : diffRecordGridProposal(visibleRows, proposed),
|
|
4964
4175
|
[proposed, visibleRows]
|
|
4965
4176
|
);
|
|
4966
4177
|
const reviewing = diffs !== null && diffs.length > 0;
|
|
4967
|
-
const diffByRow =
|
|
4968
|
-
const diffCellByKey =
|
|
4178
|
+
const diffByRow = useMemo6(() => new Map((diffs ?? []).map((diff) => [diff.rowId, diff])), [diffs]);
|
|
4179
|
+
const diffCellByKey = useMemo6(() => {
|
|
4969
4180
|
const map = /* @__PURE__ */ new Map();
|
|
4970
4181
|
for (const diff of diffs ?? []) {
|
|
4971
4182
|
for (const cell of diff.cells) map.set(cellKey(diff.rowId, cell.columnId), cell);
|
|
4972
4183
|
}
|
|
4973
4184
|
return map;
|
|
4974
4185
|
}, [diffs]);
|
|
4975
|
-
const addedRows =
|
|
4186
|
+
const addedRows = useMemo6(
|
|
4976
4187
|
() => (diffs ?? []).filter((diff) => diff.kind === "added").map((diff) => diff.row),
|
|
4977
4188
|
[diffs]
|
|
4978
4189
|
);
|
|
4979
|
-
const activeFocus =
|
|
4190
|
+
const activeFocus = useMemo6(() => {
|
|
4980
4191
|
if (focus === null) return null;
|
|
4981
4192
|
if (!visibleRows.some((row) => row.id === focus.rowId)) return null;
|
|
4982
4193
|
if (!columns.some((column) => column.id === focus.columnId)) return null;
|
|
4983
4194
|
return focus;
|
|
4984
4195
|
}, [columns, focus, visibleRows]);
|
|
4985
|
-
const setCellError =
|
|
4196
|
+
const setCellError = useCallback9((key, message) => {
|
|
4986
4197
|
setCellErrors((current) => {
|
|
4987
4198
|
if (message === null) {
|
|
4988
4199
|
if (!(key in current)) return current;
|
|
@@ -4994,7 +4205,7 @@ function RecordGrid({
|
|
|
4994
4205
|
return { ...current, [key]: message };
|
|
4995
4206
|
});
|
|
4996
4207
|
}, []);
|
|
4997
|
-
const setRowError =
|
|
4208
|
+
const setRowError = useCallback9((rowId, message) => {
|
|
4998
4209
|
setRowErrors((current) => {
|
|
4999
4210
|
if (message === null) {
|
|
5000
4211
|
if (!(rowId in current)) return current;
|
|
@@ -5005,7 +4216,7 @@ function RecordGrid({
|
|
|
5005
4216
|
return { ...current, [rowId]: message };
|
|
5006
4217
|
});
|
|
5007
4218
|
}, []);
|
|
5008
|
-
const setRowPending =
|
|
4219
|
+
const setRowPending = useCallback9((rowId, pending) => {
|
|
5009
4220
|
setPendingRows((current) => {
|
|
5010
4221
|
if (pending) return rowId in current ? current : { ...current, [rowId]: true };
|
|
5011
4222
|
if (!(rowId in current)) return current;
|
|
@@ -5014,11 +4225,11 @@ function RecordGrid({
|
|
|
5014
4225
|
return next;
|
|
5015
4226
|
});
|
|
5016
4227
|
}, []);
|
|
5017
|
-
const focusCell =
|
|
4228
|
+
const focusCell = useCallback9((rowId, columnId) => {
|
|
5018
4229
|
setFocus({ rowId, columnId });
|
|
5019
4230
|
cellRefs.current.get(cellKey(rowId, columnId))?.focus();
|
|
5020
4231
|
}, []);
|
|
5021
|
-
const beginEdit =
|
|
4232
|
+
const beginEdit = useCallback9(
|
|
5022
4233
|
(row, column) => {
|
|
5023
4234
|
setCellError(cellKey(row.id, column.id), null);
|
|
5024
4235
|
setEditing({
|
|
@@ -5029,7 +4240,7 @@ function RecordGrid({
|
|
|
5029
4240
|
},
|
|
5030
4241
|
[setCellError, setEditing]
|
|
5031
4242
|
);
|
|
5032
|
-
const applyCellWrite =
|
|
4243
|
+
const applyCellWrite = useCallback9(
|
|
5033
4244
|
async (row, column, value) => {
|
|
5034
4245
|
if (!onUpdate) return;
|
|
5035
4246
|
const values = { ...row.values, [column.id]: value };
|
|
@@ -5057,7 +4268,7 @@ function RecordGrid({
|
|
|
5057
4268
|
},
|
|
5058
4269
|
[locale, onUpdate, setRowError, setRowPending]
|
|
5059
4270
|
);
|
|
5060
|
-
const commitEdit =
|
|
4271
|
+
const commitEdit = useCallback9(
|
|
5061
4272
|
async (row, column, text) => {
|
|
5062
4273
|
const open = editingRef.current;
|
|
5063
4274
|
if (open === null || open.rowId !== row.id || open.columnId !== column.id) return;
|
|
@@ -5081,7 +4292,7 @@ function RecordGrid({
|
|
|
5081
4292
|
},
|
|
5082
4293
|
[applyCellWrite, setCellError, setEditing]
|
|
5083
4294
|
);
|
|
5084
|
-
const cancelEdit =
|
|
4295
|
+
const cancelEdit = useCallback9(
|
|
5085
4296
|
(row, column) => {
|
|
5086
4297
|
setCellError(cellKey(row.id, column.id), null);
|
|
5087
4298
|
setEditing(null);
|
|
@@ -5089,7 +4300,7 @@ function RecordGrid({
|
|
|
5089
4300
|
},
|
|
5090
4301
|
[focusCell, setCellError, setEditing]
|
|
5091
4302
|
);
|
|
5092
|
-
const performDelete =
|
|
4303
|
+
const performDelete = useCallback9(
|
|
5093
4304
|
async (row) => {
|
|
5094
4305
|
if (!onDelete) return;
|
|
5095
4306
|
setConfirmDelete(null);
|
|
@@ -5107,16 +4318,16 @@ function RecordGrid({
|
|
|
5107
4318
|
},
|
|
5108
4319
|
[columns, onDelete, setRowError]
|
|
5109
4320
|
);
|
|
5110
|
-
const resetDraft =
|
|
4321
|
+
const resetDraft = useCallback9(() => {
|
|
5111
4322
|
setDraft({ ...newRowDefaults ?? {} });
|
|
5112
4323
|
setDraftErrors({});
|
|
5113
4324
|
setDraftError(null);
|
|
5114
4325
|
}, [newRowDefaults]);
|
|
5115
|
-
const openAdd =
|
|
4326
|
+
const openAdd = useCallback9(() => {
|
|
5116
4327
|
resetDraft();
|
|
5117
4328
|
setAdding(true);
|
|
5118
4329
|
}, [resetDraft]);
|
|
5119
|
-
const submitDraft =
|
|
4330
|
+
const submitDraft = useCallback9(async () => {
|
|
5120
4331
|
if (!onCreate) return;
|
|
5121
4332
|
const validated = validateRecordGridRow(columns, draft);
|
|
5122
4333
|
if (!validated.succeeded) {
|
|
@@ -5146,7 +4357,7 @@ function RecordGrid({
|
|
|
5146
4357
|
setOverlay((current) => withoutRecordGridCreated(current, draftId));
|
|
5147
4358
|
setDraftError(outcome.error);
|
|
5148
4359
|
}, [columns, draft, fieldPrefix, onCreate, resetDraft]);
|
|
5149
|
-
const handleGridKeyDown =
|
|
4360
|
+
const handleGridKeyDown = useCallback9(
|
|
5150
4361
|
(event) => {
|
|
5151
4362
|
if (editing !== null) return;
|
|
5152
4363
|
const target = event.target;
|
|
@@ -5185,9 +4396,9 @@ function RecordGrid({
|
|
|
5185
4396
|
[beginEdit, columns, editing, focusCell, onUpdate, reviewing, visibleRows]
|
|
5186
4397
|
);
|
|
5187
4398
|
if (state.status === "idle" || state.status === "loading") {
|
|
5188
|
-
return /* @__PURE__ */
|
|
4399
|
+
return /* @__PURE__ */ jsxs9("div", { className: `space-y-3 ${className ?? ""}`, children: [
|
|
5189
4400
|
toolbar,
|
|
5190
|
-
/* @__PURE__ */
|
|
4401
|
+
/* @__PURE__ */ jsxs9(
|
|
5191
4402
|
"div",
|
|
5192
4403
|
{
|
|
5193
4404
|
role: "status",
|
|
@@ -5195,22 +4406,22 @@ function RecordGrid({
|
|
|
5195
4406
|
"aria-live": "polite",
|
|
5196
4407
|
className: "space-y-2 rounded-xl border border-card-edge bg-card p-4",
|
|
5197
4408
|
children: [
|
|
5198
|
-
/* @__PURE__ */
|
|
4409
|
+
/* @__PURE__ */ jsxs9("span", { className: "sr-only", children: [
|
|
5199
4410
|
"Loading ",
|
|
5200
4411
|
caption
|
|
5201
4412
|
] }),
|
|
5202
|
-
Array.from({ length: Math.max(1, loadingRowCount) }, (_, index) => /* @__PURE__ */
|
|
4413
|
+
Array.from({ length: Math.max(1, loadingRowCount) }, (_, index) => /* @__PURE__ */ jsx11("div", { className: "h-8 animate-pulse rounded-md bg-secondary", "aria-hidden": true }, index))
|
|
5203
4414
|
]
|
|
5204
4415
|
}
|
|
5205
4416
|
)
|
|
5206
4417
|
] });
|
|
5207
4418
|
}
|
|
5208
4419
|
if (state.status === "error") {
|
|
5209
|
-
return /* @__PURE__ */
|
|
4420
|
+
return /* @__PURE__ */ jsxs9("div", { className: `space-y-3 ${className ?? ""}`, children: [
|
|
5210
4421
|
toolbar,
|
|
5211
|
-
/* @__PURE__ */
|
|
5212
|
-
/* @__PURE__ */
|
|
5213
|
-
/* @__PURE__ */
|
|
4422
|
+
/* @__PURE__ */ jsxs9("div", { role: "alert", className: "rounded-xl border border-destructive/40 bg-destructive/10 px-4 py-4", children: [
|
|
4423
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm font-medium text-destructive", children: state.message }),
|
|
4424
|
+
/* @__PURE__ */ jsx11(
|
|
5214
4425
|
"button",
|
|
5215
4426
|
{
|
|
5216
4427
|
type: "button",
|
|
@@ -5222,7 +4433,7 @@ function RecordGrid({
|
|
|
5222
4433
|
] })
|
|
5223
4434
|
] });
|
|
5224
4435
|
}
|
|
5225
|
-
const addForm = adding && onCreate && !reviewing ? /* @__PURE__ */
|
|
4436
|
+
const addForm = adding && onCreate && !reviewing ? /* @__PURE__ */ jsx11(
|
|
5226
4437
|
AddRecordForm,
|
|
5227
4438
|
{
|
|
5228
4439
|
columns,
|
|
@@ -5241,13 +4452,13 @@ function RecordGrid({
|
|
|
5241
4452
|
}
|
|
5242
4453
|
) : null;
|
|
5243
4454
|
if (visibleRows.length === 0 && !reviewing) {
|
|
5244
|
-
return /* @__PURE__ */
|
|
4455
|
+
return /* @__PURE__ */ jsxs9("div", { className: `space-y-3 ${className ?? ""}`, children: [
|
|
5245
4456
|
toolbar,
|
|
5246
|
-
addForm ?? /* @__PURE__ */
|
|
5247
|
-
/* @__PURE__ */
|
|
5248
|
-
empty.description && /* @__PURE__ */
|
|
5249
|
-
/* @__PURE__ */
|
|
5250
|
-
empty.action && (isValidElement(empty.action) ? empty.action : /* @__PURE__ */
|
|
4457
|
+
addForm ?? /* @__PURE__ */ jsxs9("div", { className: "rounded-xl border border-dashed border-border px-6 py-10 text-center", children: [
|
|
4458
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm font-medium text-foreground", children: empty.title }),
|
|
4459
|
+
empty.description && /* @__PURE__ */ jsx11("p", { className: "mx-auto mt-1 max-w-md text-sm text-muted-foreground", children: empty.description }),
|
|
4460
|
+
/* @__PURE__ */ jsxs9("div", { className: "mt-4 flex flex-wrap items-center justify-center gap-2", children: [
|
|
4461
|
+
empty.action && (isValidElement(empty.action) ? empty.action : /* @__PURE__ */ jsx11(
|
|
5251
4462
|
"button",
|
|
5252
4463
|
{
|
|
5253
4464
|
type: "button",
|
|
@@ -5256,7 +4467,7 @@ function RecordGrid({
|
|
|
5256
4467
|
children: empty.action.label
|
|
5257
4468
|
}
|
|
5258
4469
|
)),
|
|
5259
|
-
onCreate && /* @__PURE__ */
|
|
4470
|
+
onCreate && /* @__PURE__ */ jsx11(
|
|
5260
4471
|
"button",
|
|
5261
4472
|
{
|
|
5262
4473
|
type: "button",
|
|
@@ -5281,18 +4492,18 @@ function RecordGrid({
|
|
|
5281
4492
|
addedCount > 0 ? `${addedCount} added` : null,
|
|
5282
4493
|
removedCount > 0 ? `${removedCount} removed` : null
|
|
5283
4494
|
].filter((part) => part !== null).join(" \xB7 ");
|
|
5284
|
-
const reviewBar = reviewing ? /* @__PURE__ */
|
|
4495
|
+
const reviewBar = reviewing ? /* @__PURE__ */ jsxs9(
|
|
5285
4496
|
"div",
|
|
5286
4497
|
{
|
|
5287
4498
|
"data-record-grid-review": "",
|
|
5288
4499
|
className: "flex flex-wrap items-center justify-between gap-3 rounded-xl border border-card-edge bg-card px-4 py-2.5",
|
|
5289
4500
|
children: [
|
|
5290
|
-
/* @__PURE__ */
|
|
5291
|
-
/* @__PURE__ */
|
|
5292
|
-
/* @__PURE__ */
|
|
4501
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
|
|
4502
|
+
/* @__PURE__ */ jsx11("p", { className: "text-[11px] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: "Proposed changes" }),
|
|
4503
|
+
/* @__PURE__ */ jsx11("p", { className: "mt-0.5 text-xs tabular-nums text-muted-foreground", children: reviewSummary })
|
|
5293
4504
|
] }),
|
|
5294
|
-
(onAcceptAll || onRejectAll) && /* @__PURE__ */
|
|
5295
|
-
onRejectAll && /* @__PURE__ */
|
|
4505
|
+
(onAcceptAll || onRejectAll) && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
4506
|
+
onRejectAll && /* @__PURE__ */ jsx11(
|
|
5296
4507
|
"button",
|
|
5297
4508
|
{
|
|
5298
4509
|
type: "button",
|
|
@@ -5302,7 +4513,7 @@ function RecordGrid({
|
|
|
5302
4513
|
children: "Reject all"
|
|
5303
4514
|
}
|
|
5304
4515
|
),
|
|
5305
|
-
onAcceptAll && /* @__PURE__ */
|
|
4516
|
+
onAcceptAll && /* @__PURE__ */ jsx11(
|
|
5306
4517
|
"button",
|
|
5307
4518
|
{
|
|
5308
4519
|
type: "button",
|
|
@@ -5316,10 +4527,10 @@ function RecordGrid({
|
|
|
5316
4527
|
]
|
|
5317
4528
|
}
|
|
5318
4529
|
) : null;
|
|
5319
|
-
return /* @__PURE__ */
|
|
4530
|
+
return /* @__PURE__ */ jsxs9("div", { className: `space-y-3 ${className ?? ""}`, children: [
|
|
5320
4531
|
toolbar,
|
|
5321
4532
|
reviewBar,
|
|
5322
|
-
/* @__PURE__ */
|
|
4533
|
+
/* @__PURE__ */ jsx11("div", { className: "overflow-x-auto rounded-xl border border-card-edge bg-card", children: /* @__PURE__ */ jsxs9(
|
|
5323
4534
|
"table",
|
|
5324
4535
|
{
|
|
5325
4536
|
role: "grid",
|
|
@@ -5327,8 +4538,8 @@ function RecordGrid({
|
|
|
5327
4538
|
className: "w-full border-collapse text-left text-sm",
|
|
5328
4539
|
onKeyDown: handleGridKeyDown,
|
|
5329
4540
|
children: [
|
|
5330
|
-
/* @__PURE__ */
|
|
5331
|
-
columns.map((column) => /* @__PURE__ */
|
|
4541
|
+
/* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs9("tr", { role: "row", className: "border-b border-border text-xs uppercase tracking-[0.05em] text-muted-foreground", children: [
|
|
4542
|
+
columns.map((column) => /* @__PURE__ */ jsx11(
|
|
5332
4543
|
"th",
|
|
5333
4544
|
{
|
|
5334
4545
|
role: "columnheader",
|
|
@@ -5338,17 +4549,17 @@ function RecordGrid({
|
|
|
5338
4549
|
},
|
|
5339
4550
|
column.id
|
|
5340
4551
|
)),
|
|
5341
|
-
showActionsColumn && /* @__PURE__ */
|
|
4552
|
+
showActionsColumn && /* @__PURE__ */ jsx11("th", { role: "columnheader", scope: "col", className: "w-px px-3 py-2 font-medium", children: /* @__PURE__ */ jsx11("span", { className: "sr-only", children: reviewing ? "Review" : "Row actions" }) })
|
|
5342
4553
|
] }) }),
|
|
5343
|
-
/* @__PURE__ */
|
|
4554
|
+
/* @__PURE__ */ jsxs9("tbody", { children: [
|
|
5344
4555
|
visibleRows.map((row) => {
|
|
5345
4556
|
const rowLabel = recordGridRowLabel(columns, row);
|
|
5346
4557
|
const pending = row.id in pendingRows;
|
|
5347
4558
|
const rowError = rowErrors[row.id];
|
|
5348
4559
|
const rowDiff = reviewing ? diffByRow.get(row.id) : void 0;
|
|
5349
4560
|
const removedRow = rowDiff?.kind === "removed";
|
|
5350
|
-
return /* @__PURE__ */
|
|
5351
|
-
/* @__PURE__ */
|
|
4561
|
+
return /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
4562
|
+
/* @__PURE__ */ jsxs9(
|
|
5352
4563
|
"tr",
|
|
5353
4564
|
{
|
|
5354
4565
|
role: "row",
|
|
@@ -5368,8 +4579,8 @@ function RecordGrid({
|
|
|
5368
4579
|
const errorId = `${fieldPrefix}-cell-error-${row.id}-${column.id}`;
|
|
5369
4580
|
const cellDiff = rowDiff?.kind === "changed" ? diffCellByKey.get(key) : void 0;
|
|
5370
4581
|
if (isEditing && editable) {
|
|
5371
|
-
return /* @__PURE__ */
|
|
5372
|
-
/* @__PURE__ */
|
|
4582
|
+
return /* @__PURE__ */ jsxs9("td", { role: "gridcell", className: `px-3 py-1.5 ${alignmentClass(column)}`, children: [
|
|
4583
|
+
/* @__PURE__ */ jsx11(
|
|
5373
4584
|
CellEditor,
|
|
5374
4585
|
{
|
|
5375
4586
|
column,
|
|
@@ -5382,11 +4593,11 @@ function RecordGrid({
|
|
|
5382
4593
|
onCancel: () => cancelEdit(row, column)
|
|
5383
4594
|
}
|
|
5384
4595
|
),
|
|
5385
|
-
cellError !== void 0 && /* @__PURE__ */
|
|
4596
|
+
cellError !== void 0 && /* @__PURE__ */ jsx11("p", { id: errorId, role: "alert", className: "mt-1 text-xs leading-snug text-destructive", children: cellError })
|
|
5386
4597
|
] }, column.id);
|
|
5387
4598
|
}
|
|
5388
4599
|
if (column.kind === "boolean" && editable) {
|
|
5389
|
-
return /* @__PURE__ */
|
|
4600
|
+
return /* @__PURE__ */ jsx11("td", { role: "gridcell", className: `px-3 py-2 ${alignmentClass(column)}`, children: /* @__PURE__ */ jsx11(
|
|
5390
4601
|
"input",
|
|
5391
4602
|
{
|
|
5392
4603
|
type: "checkbox",
|
|
@@ -5405,7 +4616,7 @@ function RecordGrid({
|
|
|
5405
4616
|
) }, column.id);
|
|
5406
4617
|
}
|
|
5407
4618
|
const display = applicable ? formatRecordGridValue(column, value, locale) : "";
|
|
5408
|
-
return /* @__PURE__ */
|
|
4619
|
+
return /* @__PURE__ */ jsx11(
|
|
5409
4620
|
"td",
|
|
5410
4621
|
{
|
|
5411
4622
|
role: "gridcell",
|
|
@@ -5423,20 +4634,20 @@ function RecordGrid({
|
|
|
5423
4634
|
className: `px-3 py-2 outline-none focus:ring-2 focus:ring-inset focus:ring-primary/50 ${alignmentClass(
|
|
5424
4635
|
column
|
|
5425
4636
|
)} ${editable ? "cursor-text" : ""}`,
|
|
5426
|
-
children: /* @__PURE__ */
|
|
5427
|
-
column.id === columns[0]?.id && removedRow && /* @__PURE__ */
|
|
5428
|
-
cellDiff ? /* @__PURE__ */
|
|
5429
|
-
/* @__PURE__ */
|
|
5430
|
-
/* @__PURE__ */
|
|
5431
|
-
/* @__PURE__ */
|
|
5432
|
-
] }) : /* @__PURE__ */
|
|
4637
|
+
children: /* @__PURE__ */ jsxs9("span", { className: "inline-flex max-w-full items-center gap-1.5", children: [
|
|
4638
|
+
column.id === columns[0]?.id && removedRow && /* @__PURE__ */ jsx11("span", { className: "inline-flex shrink-0 rounded border border-destructive/60 px-1 py-px text-[11px] font-semibold uppercase tracking-[0.05em] text-destructive", children: "Remove" }),
|
|
4639
|
+
cellDiff ? /* @__PURE__ */ jsxs9("span", { className: "inline-flex max-w-full flex-wrap items-baseline gap-x-1.5", children: [
|
|
4640
|
+
/* @__PURE__ */ jsx11("span", { className: "tabular-nums text-destructive line-through decoration-destructive/60", children: formatRecordGridValue(column, cellDiff.before, locale) || "\u2014" }),
|
|
4641
|
+
/* @__PURE__ */ jsx11("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2192" }),
|
|
4642
|
+
/* @__PURE__ */ jsx11("span", { className: "tabular-nums font-medium text-success", children: formatRecordGridValue(column, cellDiff.after, locale) || "\u2014" })
|
|
4643
|
+
] }) : /* @__PURE__ */ jsx11(
|
|
5433
4644
|
"span",
|
|
5434
4645
|
{
|
|
5435
4646
|
className: removedRow ? "truncate text-destructive line-through decoration-destructive/60" : display === "" ? "text-muted-foreground" : "truncate text-foreground",
|
|
5436
4647
|
children: display === "" ? applicable ? "\u2014" : "n/a" : display
|
|
5437
4648
|
}
|
|
5438
4649
|
),
|
|
5439
|
-
source && /* @__PURE__ */
|
|
4650
|
+
source && /* @__PURE__ */ jsx11(
|
|
5440
4651
|
SourceMarker,
|
|
5441
4652
|
{
|
|
5442
4653
|
panelId: `${fieldPrefix}-source-${row.id}-${column.id}`,
|
|
@@ -5452,7 +4663,7 @@ function RecordGrid({
|
|
|
5452
4663
|
column.id
|
|
5453
4664
|
);
|
|
5454
4665
|
}),
|
|
5455
|
-
showActionsColumn && /* @__PURE__ */
|
|
4666
|
+
showActionsColumn && /* @__PURE__ */ jsx11("td", { role: "gridcell", className: "px-3 py-2 text-right", children: reviewing ? rowDiff && /* @__PURE__ */ jsx11(
|
|
5456
4667
|
ReviewActions,
|
|
5457
4668
|
{
|
|
5458
4669
|
rowId: row.id,
|
|
@@ -5461,8 +4672,8 @@ function RecordGrid({
|
|
|
5461
4672
|
onAccept: onAcceptRow,
|
|
5462
4673
|
onReject: onRejectRow
|
|
5463
4674
|
}
|
|
5464
|
-
) : row.readOnly === true ? null : confirmDelete === row.id ? /* @__PURE__ */
|
|
5465
|
-
/* @__PURE__ */
|
|
4675
|
+
) : row.readOnly === true ? null : confirmDelete === row.id ? /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
4676
|
+
/* @__PURE__ */ jsx11(
|
|
5466
4677
|
"button",
|
|
5467
4678
|
{
|
|
5468
4679
|
type: "button",
|
|
@@ -5472,7 +4683,7 @@ function RecordGrid({
|
|
|
5472
4683
|
children: "Delete"
|
|
5473
4684
|
}
|
|
5474
4685
|
),
|
|
5475
|
-
/* @__PURE__ */
|
|
4686
|
+
/* @__PURE__ */ jsx11(
|
|
5476
4687
|
"button",
|
|
5477
4688
|
{
|
|
5478
4689
|
type: "button",
|
|
@@ -5482,14 +4693,14 @@ function RecordGrid({
|
|
|
5482
4693
|
children: "Cancel"
|
|
5483
4694
|
}
|
|
5484
4695
|
)
|
|
5485
|
-
] }) : /* @__PURE__ */
|
|
4696
|
+
] }) : /* @__PURE__ */ jsx11(
|
|
5486
4697
|
"button",
|
|
5487
4698
|
{
|
|
5488
4699
|
type: "button",
|
|
5489
4700
|
"aria-label": `Delete ${rowLabel}`,
|
|
5490
4701
|
onClick: () => setConfirmDelete(row.id),
|
|
5491
4702
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-destructive/10 hover:text-destructive",
|
|
5492
|
-
children: /* @__PURE__ */
|
|
4703
|
+
children: /* @__PURE__ */ jsxs9(
|
|
5493
4704
|
"svg",
|
|
5494
4705
|
{
|
|
5495
4706
|
viewBox: "0 0 24 24",
|
|
@@ -5501,8 +4712,8 @@ function RecordGrid({
|
|
|
5501
4712
|
strokeLinejoin: "round",
|
|
5502
4713
|
"aria-hidden": true,
|
|
5503
4714
|
children: [
|
|
5504
|
-
/* @__PURE__ */
|
|
5505
|
-
/* @__PURE__ */
|
|
4715
|
+
/* @__PURE__ */ jsx11("polyline", { points: "3 6 5 6 21 6" }),
|
|
4716
|
+
/* @__PURE__ */ jsx11("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
|
|
5506
4717
|
]
|
|
5507
4718
|
}
|
|
5508
4719
|
)
|
|
@@ -5511,12 +4722,12 @@ function RecordGrid({
|
|
|
5511
4722
|
]
|
|
5512
4723
|
}
|
|
5513
4724
|
),
|
|
5514
|
-
rowError !== void 0 && /* @__PURE__ */
|
|
4725
|
+
rowError !== void 0 && /* @__PURE__ */ jsx11("tr", { role: "row", className: "border-b border-border", children: /* @__PURE__ */ jsx11("td", { role: "gridcell", colSpan: columnSpan, className: "px-3 pb-2", children: /* @__PURE__ */ jsx11("p", { role: "alert", className: "rounded-md bg-destructive/10 px-2.5 py-1.5 text-xs text-destructive", children: rowError }) }) })
|
|
5515
4726
|
] }, row.id);
|
|
5516
4727
|
}),
|
|
5517
4728
|
reviewing && addedRows.map((row) => {
|
|
5518
4729
|
const rowLabel = recordGridRowLabel(columns, row);
|
|
5519
|
-
return /* @__PURE__ */
|
|
4730
|
+
return /* @__PURE__ */ jsxs9(
|
|
5520
4731
|
"tr",
|
|
5521
4732
|
{
|
|
5522
4733
|
role: "row",
|
|
@@ -5527,9 +4738,9 @@ function RecordGrid({
|
|
|
5527
4738
|
const applicable = isRecordGridCellApplicable(column, row.values);
|
|
5528
4739
|
const value = row.values[column.id] ?? null;
|
|
5529
4740
|
const display = applicable ? formatRecordGridValue(column, value, locale) : "";
|
|
5530
|
-
return /* @__PURE__ */
|
|
5531
|
-
columnIndex === 0 && /* @__PURE__ */
|
|
5532
|
-
/* @__PURE__ */
|
|
4741
|
+
return /* @__PURE__ */ jsx11("td", { role: "gridcell", className: `px-3 py-2 ${alignmentClass(column)}`, children: /* @__PURE__ */ jsxs9("span", { className: "inline-flex max-w-full items-center gap-1.5", children: [
|
|
4742
|
+
columnIndex === 0 && /* @__PURE__ */ jsx11("span", { className: "inline-flex shrink-0 rounded border border-success/60 px-1 py-px text-[11px] font-semibold uppercase tracking-[0.05em] text-success", children: "New" }),
|
|
4743
|
+
/* @__PURE__ */ jsx11(
|
|
5533
4744
|
"span",
|
|
5534
4745
|
{
|
|
5535
4746
|
className: `tabular-nums ${display === "" ? "text-muted-foreground" : "truncate text-foreground"}`,
|
|
@@ -5538,7 +4749,7 @@ function RecordGrid({
|
|
|
5538
4749
|
)
|
|
5539
4750
|
] }) }, column.id);
|
|
5540
4751
|
}),
|
|
5541
|
-
/* @__PURE__ */
|
|
4752
|
+
/* @__PURE__ */ jsx11("td", { role: "gridcell", className: "px-3 py-2 text-right", children: /* @__PURE__ */ jsx11(
|
|
5542
4753
|
ReviewActions,
|
|
5543
4754
|
{
|
|
5544
4755
|
rowId: row.id,
|
|
@@ -5554,8 +4765,8 @@ function RecordGrid({
|
|
|
5554
4765
|
);
|
|
5555
4766
|
})
|
|
5556
4767
|
] }),
|
|
5557
|
-
hasFooter && /* @__PURE__ */
|
|
5558
|
-
columns.map((column) => /* @__PURE__ */
|
|
4768
|
+
hasFooter && /* @__PURE__ */ jsx11("tfoot", { children: /* @__PURE__ */ jsxs9("tr", { role: "row", className: "border-t-2 border-border", children: [
|
|
4769
|
+
columns.map((column) => /* @__PURE__ */ jsx11(
|
|
5559
4770
|
"td",
|
|
5560
4771
|
{
|
|
5561
4772
|
role: "gridcell",
|
|
@@ -5564,19 +4775,19 @@ function RecordGrid({
|
|
|
5564
4775
|
},
|
|
5565
4776
|
column.id
|
|
5566
4777
|
)),
|
|
5567
|
-
showActionsColumn && /* @__PURE__ */
|
|
4778
|
+
showActionsColumn && /* @__PURE__ */ jsx11("td", { role: "gridcell" })
|
|
5568
4779
|
] }) })
|
|
5569
4780
|
]
|
|
5570
4781
|
}
|
|
5571
4782
|
) }),
|
|
5572
|
-
onCreate && !reviewing && (addForm ?? /* @__PURE__ */
|
|
4783
|
+
onCreate && !reviewing && (addForm ?? /* @__PURE__ */ jsxs9(
|
|
5573
4784
|
"button",
|
|
5574
4785
|
{
|
|
5575
4786
|
type: "button",
|
|
5576
4787
|
onClick: openAdd,
|
|
5577
4788
|
className: "inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent",
|
|
5578
4789
|
children: [
|
|
5579
|
-
/* @__PURE__ */
|
|
4790
|
+
/* @__PURE__ */ jsxs9(
|
|
5580
4791
|
"svg",
|
|
5581
4792
|
{
|
|
5582
4793
|
viewBox: "0 0 24 24",
|
|
@@ -5588,8 +4799,8 @@ function RecordGrid({
|
|
|
5588
4799
|
strokeLinejoin: "round",
|
|
5589
4800
|
"aria-hidden": true,
|
|
5590
4801
|
children: [
|
|
5591
|
-
/* @__PURE__ */
|
|
5592
|
-
/* @__PURE__ */
|
|
4802
|
+
/* @__PURE__ */ jsx11("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
4803
|
+
/* @__PURE__ */ jsx11("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
5593
4804
|
]
|
|
5594
4805
|
}
|
|
5595
4806
|
),
|
|
@@ -5601,8 +4812,8 @@ function RecordGrid({
|
|
|
5601
4812
|
}
|
|
5602
4813
|
function ReviewActions({ rowId, kind, rowLabel, onAccept, onReject }) {
|
|
5603
4814
|
const noun = kind === "changed" ? `proposed change to ${rowLabel}` : kind === "added" ? `new row ${rowLabel}` : `removal of ${rowLabel}`;
|
|
5604
|
-
return /* @__PURE__ */
|
|
5605
|
-
onReject && /* @__PURE__ */
|
|
4815
|
+
return /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
4816
|
+
onReject && /* @__PURE__ */ jsx11(
|
|
5606
4817
|
"button",
|
|
5607
4818
|
{
|
|
5608
4819
|
type: "button",
|
|
@@ -5612,7 +4823,7 @@ function ReviewActions({ rowId, kind, rowLabel, onAccept, onReject }) {
|
|
|
5612
4823
|
children: "Reject"
|
|
5613
4824
|
}
|
|
5614
4825
|
),
|
|
5615
|
-
onAccept && /* @__PURE__ */
|
|
4826
|
+
onAccept && /* @__PURE__ */ jsx11(
|
|
5616
4827
|
"button",
|
|
5617
4828
|
{
|
|
5618
4829
|
type: "button",
|
|
@@ -5633,7 +4844,7 @@ function CellEditor({ column, rowLabel, text, invalid, describedBy, onText, onCo
|
|
|
5633
4844
|
className: INPUT_CLASS
|
|
5634
4845
|
};
|
|
5635
4846
|
if (column.kind === "select") {
|
|
5636
|
-
return /* @__PURE__ */
|
|
4847
|
+
return /* @__PURE__ */ jsxs9(
|
|
5637
4848
|
"select",
|
|
5638
4849
|
{
|
|
5639
4850
|
...shared,
|
|
@@ -5650,8 +4861,8 @@ function CellEditor({ column, rowLabel, text, invalid, describedBy, onText, onCo
|
|
|
5650
4861
|
},
|
|
5651
4862
|
onBlur: () => onCommit(text),
|
|
5652
4863
|
children: [
|
|
5653
|
-
/* @__PURE__ */
|
|
5654
|
-
column.options.map((option) => /* @__PURE__ */
|
|
4864
|
+
/* @__PURE__ */ jsx11("option", { value: "", children: "\u2014" }),
|
|
4865
|
+
column.options.map((option) => /* @__PURE__ */ jsx11("option", { value: option.value, children: option.label }, option.value))
|
|
5655
4866
|
]
|
|
5656
4867
|
}
|
|
5657
4868
|
);
|
|
@@ -5669,7 +4880,7 @@ function CellEditor({ column, rowLabel, text, invalid, describedBy, onText, onCo
|
|
|
5669
4880
|
}
|
|
5670
4881
|
};
|
|
5671
4882
|
if (column.kind === "text" && column.multiline === true) {
|
|
5672
|
-
return /* @__PURE__ */
|
|
4883
|
+
return /* @__PURE__ */ jsx11(
|
|
5673
4884
|
"textarea",
|
|
5674
4885
|
{
|
|
5675
4886
|
...shared,
|
|
@@ -5681,7 +4892,7 @@ function CellEditor({ column, rowLabel, text, invalid, describedBy, onText, onCo
|
|
|
5681
4892
|
}
|
|
5682
4893
|
);
|
|
5683
4894
|
}
|
|
5684
|
-
return /* @__PURE__ */
|
|
4895
|
+
return /* @__PURE__ */ jsx11(
|
|
5685
4896
|
"input",
|
|
5686
4897
|
{
|
|
5687
4898
|
...shared,
|
|
@@ -5696,15 +4907,15 @@ function CellEditor({ column, rowLabel, text, invalid, describedBy, onText, onCo
|
|
|
5696
4907
|
}
|
|
5697
4908
|
function SourceMarker({ panelId, columnHeader, rowLabel, source, open, onToggle }) {
|
|
5698
4909
|
const basis = source.basis ?? "asserted";
|
|
5699
|
-
const setOpen =
|
|
4910
|
+
const setOpen = useCallback9(
|
|
5700
4911
|
(next) => {
|
|
5701
4912
|
if (!next) onToggle();
|
|
5702
4913
|
},
|
|
5703
4914
|
[onToggle]
|
|
5704
4915
|
);
|
|
5705
4916
|
const { containerRef, triggerRef, panelRef, triggerProps } = usePopover(open, setOpen);
|
|
5706
|
-
return /* @__PURE__ */
|
|
5707
|
-
/* @__PURE__ */
|
|
4917
|
+
return /* @__PURE__ */ jsxs9("span", { ref: containerRef, className: "relative inline-flex", children: [
|
|
4918
|
+
/* @__PURE__ */ jsx11(
|
|
5708
4919
|
"button",
|
|
5709
4920
|
{
|
|
5710
4921
|
type: "button",
|
|
@@ -5717,7 +4928,7 @@ function SourceMarker({ panelId, columnHeader, rowLabel, source, open, onToggle
|
|
|
5717
4928
|
onToggle();
|
|
5718
4929
|
},
|
|
5719
4930
|
className: `inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full border ${BASIS_TONES2[basis]}`,
|
|
5720
|
-
children: /* @__PURE__ */
|
|
4931
|
+
children: /* @__PURE__ */ jsx11(
|
|
5721
4932
|
"svg",
|
|
5722
4933
|
{
|
|
5723
4934
|
viewBox: "0 0 24 24",
|
|
@@ -5727,12 +4938,12 @@ function SourceMarker({ panelId, columnHeader, rowLabel, source, open, onToggle
|
|
|
5727
4938
|
strokeWidth: "2.5",
|
|
5728
4939
|
strokeLinecap: "round",
|
|
5729
4940
|
"aria-hidden": true,
|
|
5730
|
-
children: /* @__PURE__ */
|
|
4941
|
+
children: /* @__PURE__ */ jsx11("path", { d: "M9 8h6M9 12h6M9 16h3" })
|
|
5731
4942
|
}
|
|
5732
4943
|
)
|
|
5733
4944
|
}
|
|
5734
4945
|
),
|
|
5735
|
-
/* @__PURE__ */
|
|
4946
|
+
/* @__PURE__ */ jsxs9(
|
|
5736
4947
|
PopoverSurface,
|
|
5737
4948
|
{
|
|
5738
4949
|
open,
|
|
@@ -5742,17 +4953,17 @@ function SourceMarker({ panelId, columnHeader, rowLabel, source, open, onToggle
|
|
|
5742
4953
|
panelRef,
|
|
5743
4954
|
className: `w-64 rounded-lg border border-card-edge bg-popover p-3 text-left ${OVERLAY_SHADOW}`,
|
|
5744
4955
|
children: [
|
|
5745
|
-
source.quote && /* @__PURE__ */
|
|
4956
|
+
source.quote && /* @__PURE__ */ jsxs9("span", { className: "block border-l-2 border-primary/50 pl-2 text-xs italic leading-snug text-foreground", children: [
|
|
5746
4957
|
"\u201C",
|
|
5747
4958
|
source.quote,
|
|
5748
4959
|
"\u201D"
|
|
5749
4960
|
] }),
|
|
5750
|
-
/* @__PURE__ */
|
|
4961
|
+
/* @__PURE__ */ jsxs9("span", { className: "mt-2 block text-xs text-muted-foreground", children: [
|
|
5751
4962
|
source.label ?? "Source",
|
|
5752
4963
|
source.locator ? ` \xB7 ${source.locator}` : "",
|
|
5753
4964
|
` \xB7 ${BASIS_TITLES[basis]}`
|
|
5754
4965
|
] }),
|
|
5755
|
-
source.href && /* @__PURE__ */
|
|
4966
|
+
source.href && /* @__PURE__ */ jsx11(
|
|
5756
4967
|
"a",
|
|
5757
4968
|
{
|
|
5758
4969
|
href: source.href,
|
|
@@ -5780,8 +4991,8 @@ function AddRecordForm({
|
|
|
5780
4991
|
onSubmit,
|
|
5781
4992
|
onCancel
|
|
5782
4993
|
}) {
|
|
5783
|
-
const groups =
|
|
5784
|
-
return /* @__PURE__ */
|
|
4994
|
+
const groups = useMemo6(() => groupColumns(columns), [columns]);
|
|
4995
|
+
return /* @__PURE__ */ jsxs9(
|
|
5785
4996
|
"form",
|
|
5786
4997
|
{
|
|
5787
4998
|
noValidate: true,
|
|
@@ -5792,31 +5003,31 @@ function AddRecordForm({
|
|
|
5792
5003
|
},
|
|
5793
5004
|
className: "space-y-4 rounded-xl border border-card-edge bg-card p-4",
|
|
5794
5005
|
children: [
|
|
5795
|
-
/* @__PURE__ */
|
|
5796
|
-
formError !== null && /* @__PURE__ */
|
|
5006
|
+
/* @__PURE__ */ jsx11("h3", { className: "text-sm font-semibold text-foreground", children: label }),
|
|
5007
|
+
formError !== null && /* @__PURE__ */ jsx11("p", { role: "alert", className: "rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive", children: formError }),
|
|
5797
5008
|
groups.map((group) => {
|
|
5798
5009
|
const fields = group.columns.filter((column) => isRecordGridCellApplicable(column, draft));
|
|
5799
5010
|
if (fields.length === 0) return null;
|
|
5800
|
-
return /* @__PURE__ */
|
|
5011
|
+
return /* @__PURE__ */ jsxs9(
|
|
5801
5012
|
"fieldset",
|
|
5802
5013
|
{
|
|
5803
5014
|
className: group.label === null ? "min-w-0" : "min-w-0 rounded-lg border border-card-edge p-3",
|
|
5804
5015
|
children: [
|
|
5805
|
-
group.label !== null && /* @__PURE__ */
|
|
5806
|
-
/* @__PURE__ */
|
|
5016
|
+
group.label !== null && /* @__PURE__ */ jsx11("legend", { className: "px-1 text-xs font-medium text-muted-foreground", children: group.label }),
|
|
5017
|
+
/* @__PURE__ */ jsx11("div", { className: "grid gap-3 sm:grid-cols-2", children: fields.map((column) => {
|
|
5807
5018
|
const fieldId = `${fieldPrefix}-${column.id}`;
|
|
5808
5019
|
const errorId = `${fieldId}-error`;
|
|
5809
5020
|
const message = errors[column.id];
|
|
5810
|
-
return /* @__PURE__ */
|
|
5021
|
+
return /* @__PURE__ */ jsxs9(
|
|
5811
5022
|
"div",
|
|
5812
5023
|
{
|
|
5813
5024
|
className: column.kind === "text" && column.multiline === true ? "sm:col-span-2" : "",
|
|
5814
5025
|
children: [
|
|
5815
|
-
/* @__PURE__ */
|
|
5026
|
+
/* @__PURE__ */ jsxs9("label", { htmlFor: fieldId, className: "mb-1 block text-xs font-medium text-muted-foreground", children: [
|
|
5816
5027
|
column.header,
|
|
5817
|
-
column.required === true && /* @__PURE__ */
|
|
5028
|
+
column.required === true && /* @__PURE__ */ jsx11("span", { className: "ml-0.5 text-destructive", children: "*" })
|
|
5818
5029
|
] }),
|
|
5819
|
-
/* @__PURE__ */
|
|
5030
|
+
/* @__PURE__ */ jsx11(
|
|
5820
5031
|
DraftField,
|
|
5821
5032
|
{
|
|
5822
5033
|
column,
|
|
@@ -5827,8 +5038,8 @@ function AddRecordForm({
|
|
|
5827
5038
|
onValue: (next) => setDraft({ ...draft, [column.id]: next })
|
|
5828
5039
|
}
|
|
5829
5040
|
),
|
|
5830
|
-
column.hint && /* @__PURE__ */
|
|
5831
|
-
message !== void 0 && /* @__PURE__ */
|
|
5041
|
+
column.hint && /* @__PURE__ */ jsx11("p", { className: "mt-1 text-xs text-muted-foreground", children: column.hint }),
|
|
5042
|
+
message !== void 0 && /* @__PURE__ */ jsx11("p", { id: errorId, role: "alert", className: "mt-1 text-xs text-destructive", children: message })
|
|
5832
5043
|
]
|
|
5833
5044
|
},
|
|
5834
5045
|
column.id
|
|
@@ -5839,8 +5050,8 @@ function AddRecordForm({
|
|
|
5839
5050
|
group.label ?? "_"
|
|
5840
5051
|
);
|
|
5841
5052
|
}),
|
|
5842
|
-
/* @__PURE__ */
|
|
5843
|
-
/* @__PURE__ */
|
|
5053
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
5054
|
+
/* @__PURE__ */ jsx11(
|
|
5844
5055
|
"button",
|
|
5845
5056
|
{
|
|
5846
5057
|
type: "submit",
|
|
@@ -5849,7 +5060,7 @@ function AddRecordForm({
|
|
|
5849
5060
|
children: busy ? "Saving\u2026" : "Save"
|
|
5850
5061
|
}
|
|
5851
5062
|
),
|
|
5852
|
-
/* @__PURE__ */
|
|
5063
|
+
/* @__PURE__ */ jsx11(
|
|
5853
5064
|
"button",
|
|
5854
5065
|
{
|
|
5855
5066
|
type: "button",
|
|
@@ -5870,7 +5081,7 @@ function DraftField({ column, id, value, invalid, describedBy, onValue }) {
|
|
|
5870
5081
|
"aria-describedby": describedBy
|
|
5871
5082
|
};
|
|
5872
5083
|
if (column.kind === "boolean") {
|
|
5873
|
-
return /* @__PURE__ */
|
|
5084
|
+
return /* @__PURE__ */ jsx11(
|
|
5874
5085
|
"input",
|
|
5875
5086
|
{
|
|
5876
5087
|
...shared,
|
|
@@ -5882,7 +5093,7 @@ function DraftField({ column, id, value, invalid, describedBy, onValue }) {
|
|
|
5882
5093
|
);
|
|
5883
5094
|
}
|
|
5884
5095
|
if (column.kind === "select") {
|
|
5885
|
-
return /* @__PURE__ */
|
|
5096
|
+
return /* @__PURE__ */ jsxs9(
|
|
5886
5097
|
"select",
|
|
5887
5098
|
{
|
|
5888
5099
|
...shared,
|
|
@@ -5890,14 +5101,14 @@ function DraftField({ column, id, value, invalid, describedBy, onValue }) {
|
|
|
5890
5101
|
value: typeof value === "string" ? value : "",
|
|
5891
5102
|
onChange: (event) => onValue(event.target.value === "" ? null : event.target.value),
|
|
5892
5103
|
children: [
|
|
5893
|
-
/* @__PURE__ */
|
|
5894
|
-
column.options.map((option) => /* @__PURE__ */
|
|
5104
|
+
/* @__PURE__ */ jsx11("option", { value: "", children: "\u2014" }),
|
|
5105
|
+
column.options.map((option) => /* @__PURE__ */ jsx11("option", { value: option.value, children: option.label }, option.value))
|
|
5895
5106
|
]
|
|
5896
5107
|
}
|
|
5897
5108
|
);
|
|
5898
5109
|
}
|
|
5899
5110
|
if (column.kind === "text" && column.multiline === true) {
|
|
5900
|
-
return /* @__PURE__ */
|
|
5111
|
+
return /* @__PURE__ */ jsx11(
|
|
5901
5112
|
"textarea",
|
|
5902
5113
|
{
|
|
5903
5114
|
...shared,
|
|
@@ -5909,7 +5120,7 @@ function DraftField({ column, id, value, invalid, describedBy, onValue }) {
|
|
|
5909
5120
|
);
|
|
5910
5121
|
}
|
|
5911
5122
|
if (column.kind === "number" || column.kind === "currency") {
|
|
5912
|
-
return /* @__PURE__ */
|
|
5123
|
+
return /* @__PURE__ */ jsx11(
|
|
5913
5124
|
"input",
|
|
5914
5125
|
{
|
|
5915
5126
|
...shared,
|
|
@@ -5929,7 +5140,7 @@ function DraftField({ column, id, value, invalid, describedBy, onValue }) {
|
|
|
5929
5140
|
}
|
|
5930
5141
|
);
|
|
5931
5142
|
}
|
|
5932
|
-
return /* @__PURE__ */
|
|
5143
|
+
return /* @__PURE__ */ jsx11(
|
|
5933
5144
|
"input",
|
|
5934
5145
|
{
|
|
5935
5146
|
...shared,
|
|
@@ -5943,19 +5154,19 @@ function DraftField({ column, id, value, invalid, describedBy, onValue }) {
|
|
|
5943
5154
|
|
|
5944
5155
|
// src/web-react/command-palette.tsx
|
|
5945
5156
|
import {
|
|
5946
|
-
useCallback as
|
|
5947
|
-
useEffect as
|
|
5948
|
-
useId as
|
|
5949
|
-
useMemo as
|
|
5950
|
-
useRef as
|
|
5951
|
-
useState as
|
|
5157
|
+
useCallback as useCallback10,
|
|
5158
|
+
useEffect as useEffect11,
|
|
5159
|
+
useId as useId4,
|
|
5160
|
+
useMemo as useMemo7,
|
|
5161
|
+
useRef as useRef11,
|
|
5162
|
+
useState as useState15
|
|
5952
5163
|
} from "react";
|
|
5953
5164
|
import { createPortal } from "react-dom";
|
|
5954
|
-
import { Fragment as
|
|
5165
|
+
import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5955
5166
|
function SearchGlyph({ className }) {
|
|
5956
|
-
return /* @__PURE__ */
|
|
5957
|
-
/* @__PURE__ */
|
|
5958
|
-
/* @__PURE__ */
|
|
5167
|
+
return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
5168
|
+
/* @__PURE__ */ jsx12("circle", { cx: "11", cy: "11", r: "8" }),
|
|
5169
|
+
/* @__PURE__ */ jsx12("path", { d: "m21 21-4.3-4.3" })
|
|
5959
5170
|
] });
|
|
5960
5171
|
}
|
|
5961
5172
|
function CommandPalette({
|
|
@@ -5970,25 +5181,25 @@ function CommandPalette({
|
|
|
5970
5181
|
emptyMessage,
|
|
5971
5182
|
label = "Command palette"
|
|
5972
5183
|
}) {
|
|
5973
|
-
const [internalOpen, setInternalOpen] =
|
|
5184
|
+
const [internalOpen, setInternalOpen] = useState15(false);
|
|
5974
5185
|
const open = controlledOpen ?? internalOpen;
|
|
5975
|
-
const setOpen =
|
|
5186
|
+
const setOpen = useCallback10(
|
|
5976
5187
|
(next) => {
|
|
5977
5188
|
if (controlledOpen === void 0) setInternalOpen(next);
|
|
5978
5189
|
onOpenChange?.(next);
|
|
5979
5190
|
},
|
|
5980
5191
|
[controlledOpen, onOpenChange]
|
|
5981
5192
|
);
|
|
5982
|
-
const [query, setQuery] =
|
|
5983
|
-
const [active, setActive] =
|
|
5984
|
-
const inputRef =
|
|
5985
|
-
const surfaceId =
|
|
5193
|
+
const [query, setQuery] = useState15(initialQuery ?? "");
|
|
5194
|
+
const [active, setActive] = useState15(0);
|
|
5195
|
+
const inputRef = useRef11(null);
|
|
5196
|
+
const surfaceId = useId4();
|
|
5986
5197
|
const listId = `${surfaceId}-list`;
|
|
5987
|
-
const flat =
|
|
5988
|
-
const sections =
|
|
5198
|
+
const flat = useMemo7(() => filterCommandPaletteItems(items, query), [items, query]);
|
|
5199
|
+
const sections = useMemo7(() => groupCommandPaletteItems(flat), [flat]);
|
|
5989
5200
|
const activeIndex = flat.length === 0 ? 0 : Math.min(active, flat.length - 1);
|
|
5990
5201
|
const activeId = flat.length > 0 ? `${listId}-${activeIndex}` : void 0;
|
|
5991
|
-
|
|
5202
|
+
useEffect11(() => {
|
|
5992
5203
|
if (!hotkey) return;
|
|
5993
5204
|
function onKeyDown(e) {
|
|
5994
5205
|
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
|
|
@@ -5999,8 +5210,8 @@ function CommandPalette({
|
|
|
5999
5210
|
document.addEventListener("keydown", onKeyDown);
|
|
6000
5211
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
6001
5212
|
}, [hotkey, open, setOpen]);
|
|
6002
|
-
const restoreFocusRef =
|
|
6003
|
-
|
|
5213
|
+
const restoreFocusRef = useRef11(null);
|
|
5214
|
+
useEffect11(() => {
|
|
6004
5215
|
if (open) {
|
|
6005
5216
|
restoreFocusRef.current = document.activeElement;
|
|
6006
5217
|
inputRef.current?.focus();
|
|
@@ -6012,11 +5223,11 @@ function CommandPalette({
|
|
|
6012
5223
|
restoreFocusRef.current = null;
|
|
6013
5224
|
if (restore instanceof HTMLElement) restore.focus();
|
|
6014
5225
|
}, [open]);
|
|
6015
|
-
|
|
5226
|
+
useEffect11(() => {
|
|
6016
5227
|
if (!open || !activeId) return;
|
|
6017
5228
|
document.getElementById(activeId)?.scrollIntoView?.({ block: "nearest" });
|
|
6018
5229
|
}, [open, activeId]);
|
|
6019
|
-
const choose =
|
|
5230
|
+
const choose = useCallback10(
|
|
6020
5231
|
(item) => {
|
|
6021
5232
|
onSelect(item);
|
|
6022
5233
|
setOpen(false);
|
|
@@ -6042,8 +5253,8 @@ function CommandPalette({
|
|
|
6042
5253
|
if (!open || typeof document === "undefined") return null;
|
|
6043
5254
|
let rowIndex = -1;
|
|
6044
5255
|
return createPortal(
|
|
6045
|
-
/* @__PURE__ */
|
|
6046
|
-
/* @__PURE__ */
|
|
5256
|
+
/* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
5257
|
+
/* @__PURE__ */ jsx12(
|
|
6047
5258
|
"div",
|
|
6048
5259
|
{
|
|
6049
5260
|
"aria-hidden": true,
|
|
@@ -6052,7 +5263,7 @@ function CommandPalette({
|
|
|
6052
5263
|
className: "fixed inset-0 z-[999] bg-background/80"
|
|
6053
5264
|
}
|
|
6054
5265
|
),
|
|
6055
|
-
/* @__PURE__ */
|
|
5266
|
+
/* @__PURE__ */ jsx12("div", { className: "pointer-events-none fixed inset-x-0 top-[15%] z-[1000] flex justify-center px-4", children: /* @__PURE__ */ jsxs10(
|
|
6056
5267
|
"div",
|
|
6057
5268
|
{
|
|
6058
5269
|
role: "dialog",
|
|
@@ -6061,9 +5272,9 @@ function CommandPalette({
|
|
|
6061
5272
|
...{ [POPOVER_SURFACE_ATTR]: surfaceId },
|
|
6062
5273
|
className: `agent-pop-in pointer-events-auto flex max-h-[70vh] w-[560px] max-w-full flex-col overflow-hidden rounded-xl border border-card-edge bg-popover ${OVERLAY_SHADOW}`,
|
|
6063
5274
|
children: [
|
|
6064
|
-
/* @__PURE__ */
|
|
6065
|
-
/* @__PURE__ */
|
|
6066
|
-
/* @__PURE__ */
|
|
5275
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex shrink-0 items-center gap-2 border-b border-border px-3 py-2.5", children: [
|
|
5276
|
+
/* @__PURE__ */ jsx12(SearchGlyph, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
|
|
5277
|
+
/* @__PURE__ */ jsx12(
|
|
6067
5278
|
"input",
|
|
6068
5279
|
{
|
|
6069
5280
|
ref: inputRef,
|
|
@@ -6084,15 +5295,15 @@ function CommandPalette({
|
|
|
6084
5295
|
}
|
|
6085
5296
|
)
|
|
6086
5297
|
] }),
|
|
6087
|
-
/* @__PURE__ */
|
|
6088
|
-
loading && /* @__PURE__ */
|
|
6089
|
-
!loading && flat.length === 0 && /* @__PURE__ */
|
|
6090
|
-
!loading && sections.map((section) => /* @__PURE__ */
|
|
6091
|
-
/* @__PURE__ */
|
|
5298
|
+
/* @__PURE__ */ jsxs10("div", { role: "listbox", id: listId, className: "min-h-0 flex-1 overflow-y-auto p-1 pb-2", children: [
|
|
5299
|
+
loading && /* @__PURE__ */ jsx12("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "Loading\u2026" }),
|
|
5300
|
+
!loading && flat.length === 0 && /* @__PURE__ */ jsx12("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: emptyMessage ?? (query.trim() ? `No results for \u201C${query.trim()}\u201D` : "Nothing here yet") }),
|
|
5301
|
+
!loading && sections.map((section) => /* @__PURE__ */ jsxs10("div", { children: [
|
|
5302
|
+
/* @__PURE__ */ jsx12("div", { className: "px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: section.group }),
|
|
6092
5303
|
section.items.map((item) => {
|
|
6093
5304
|
rowIndex += 1;
|
|
6094
5305
|
const index = rowIndex;
|
|
6095
|
-
return /* @__PURE__ */
|
|
5306
|
+
return /* @__PURE__ */ jsxs10(
|
|
6096
5307
|
"div",
|
|
6097
5308
|
{
|
|
6098
5309
|
id: `${listId}-${index}`,
|
|
@@ -6102,9 +5313,9 @@ function CommandPalette({
|
|
|
6102
5313
|
onClick: () => choose(item),
|
|
6103
5314
|
className: `flex w-full cursor-pointer items-center gap-2.5 rounded-md px-3 py-2.5 text-left text-sm ${index === activeIndex ? "bg-accent" : ""}`,
|
|
6104
5315
|
children: [
|
|
6105
|
-
/* @__PURE__ */
|
|
6106
|
-
item.description && /* @__PURE__ */
|
|
6107
|
-
item.hint && /* @__PURE__ */
|
|
5316
|
+
/* @__PURE__ */ jsx12("span", { className: "truncate text-foreground", children: item.label }),
|
|
5317
|
+
item.description && /* @__PURE__ */ jsx12("span", { className: "truncate text-xs text-muted-foreground", children: item.description }),
|
|
5318
|
+
item.hint && /* @__PURE__ */ jsx12("span", { className: "ml-auto shrink-0 text-xs tabular-nums text-muted-foreground", children: item.hint })
|
|
6108
5319
|
]
|
|
6109
5320
|
},
|
|
6110
5321
|
item.id
|
|
@@ -6112,15 +5323,15 @@ function CommandPalette({
|
|
|
6112
5323
|
})
|
|
6113
5324
|
] }, section.group))
|
|
6114
5325
|
] }),
|
|
6115
|
-
/* @__PURE__ */
|
|
6116
|
-
/* @__PURE__ */
|
|
6117
|
-
/* @__PURE__ */
|
|
6118
|
-
/* @__PURE__ */
|
|
6119
|
-
/* @__PURE__ */
|
|
6120
|
-
/* @__PURE__ */
|
|
6121
|
-
/* @__PURE__ */
|
|
6122
|
-
/* @__PURE__ */
|
|
6123
|
-
/* @__PURE__ */
|
|
5326
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex shrink-0 items-center justify-between border-t border-border px-3 py-2 text-xs text-muted-foreground", children: [
|
|
5327
|
+
/* @__PURE__ */ jsx12("span", { className: "tabular-nums", children: query.trim() ? `${flat.length} of ${items.length}` : `${items.length} items` }),
|
|
5328
|
+
/* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-1.5", children: [
|
|
5329
|
+
/* @__PURE__ */ jsx12("kbd", { className: "rounded border border-border bg-background px-1 py-0.5", children: "\u2191\u2193" }),
|
|
5330
|
+
/* @__PURE__ */ jsx12("span", { children: "navigate" }),
|
|
5331
|
+
/* @__PURE__ */ jsx12("kbd", { className: "ml-1.5 rounded border border-border bg-background px-1 py-0.5", children: "\u21B5" }),
|
|
5332
|
+
/* @__PURE__ */ jsx12("span", { children: "select" }),
|
|
5333
|
+
/* @__PURE__ */ jsx12("kbd", { className: "ml-1.5 rounded border border-border bg-background px-1 py-0.5", children: "esc" }),
|
|
5334
|
+
/* @__PURE__ */ jsx12("span", { children: "close" })
|
|
6124
5335
|
] })
|
|
6125
5336
|
] })
|
|
6126
5337
|
]
|
|
@@ -6143,7 +5354,7 @@ function joinClasses(...parts) {
|
|
|
6143
5354
|
}
|
|
6144
5355
|
|
|
6145
5356
|
// src/web-react/sparkline.tsx
|
|
6146
|
-
import { jsx as
|
|
5357
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
6147
5358
|
var DEFAULT_SPARKLINE_WIDTH = 96;
|
|
6148
5359
|
var DEFAULT_SPARKLINE_HEIGHT = 24;
|
|
6149
5360
|
var DEFAULT_INSET = 2.5;
|
|
@@ -6249,21 +5460,21 @@ function Sparkline({
|
|
|
6249
5460
|
const geometry = sparklineGeometry(values, { width, height });
|
|
6250
5461
|
const accessibleName = sparklineLabel(values, { label, format });
|
|
6251
5462
|
if (geometry.points.length === 0) {
|
|
6252
|
-
return /* @__PURE__ */
|
|
5463
|
+
return /* @__PURE__ */ jsxs11(
|
|
6253
5464
|
"span",
|
|
6254
5465
|
{
|
|
6255
5466
|
"data-sparkline": geometry.gaps > 0 ? "unavailable" : "empty",
|
|
6256
5467
|
className: joinClasses("text-[11px] text-muted-foreground", className),
|
|
6257
5468
|
children: [
|
|
6258
|
-
/* @__PURE__ */
|
|
6259
|
-
/* @__PURE__ */
|
|
5469
|
+
/* @__PURE__ */ jsx13("span", { className: "sr-only", children: accessibleName }),
|
|
5470
|
+
/* @__PURE__ */ jsx13("span", { "aria-hidden": "true", children: geometry.gaps > 0 ? unavailableLabel : emptyLabel })
|
|
6260
5471
|
]
|
|
6261
5472
|
}
|
|
6262
5473
|
);
|
|
6263
5474
|
}
|
|
6264
5475
|
const drawsLine = geometry.segments.some((segment) => segment.length > 1);
|
|
6265
5476
|
const end = geometry.points[geometry.points.length - 1];
|
|
6266
|
-
return /* @__PURE__ */
|
|
5477
|
+
return /* @__PURE__ */ jsxs11(
|
|
6267
5478
|
"svg",
|
|
6268
5479
|
{
|
|
6269
5480
|
role: "img",
|
|
@@ -6280,7 +5491,7 @@ function Sparkline({
|
|
|
6280
5491
|
geometry.segments.map((segment, index) => {
|
|
6281
5492
|
const key = `segment-${index}`;
|
|
6282
5493
|
if (segment.length > 1) {
|
|
6283
|
-
return /* @__PURE__ */
|
|
5494
|
+
return /* @__PURE__ */ jsx13(
|
|
6284
5495
|
"polyline",
|
|
6285
5496
|
{
|
|
6286
5497
|
points: sparklinePointsAttribute(segment),
|
|
@@ -6296,9 +5507,9 @@ function Sparkline({
|
|
|
6296
5507
|
}
|
|
6297
5508
|
const only = segment[0];
|
|
6298
5509
|
if (only.x === end.x && only.y === end.y) return null;
|
|
6299
|
-
return /* @__PURE__ */
|
|
5510
|
+
return /* @__PURE__ */ jsx13("circle", { cx: only.x, cy: only.y, r: DOT_RADIUS, fill: "currentColor" }, key);
|
|
6300
5511
|
}),
|
|
6301
|
-
/* @__PURE__ */
|
|
5512
|
+
/* @__PURE__ */ jsx13("circle", { cx: end.x, cy: end.y, r: DOT_RADIUS, fill: "currentColor" })
|
|
6302
5513
|
]
|
|
6303
5514
|
}
|
|
6304
5515
|
);
|
|
@@ -6307,12 +5518,12 @@ function Sparkline({
|
|
|
6307
5518
|
// src/web-react/insight-card.tsx
|
|
6308
5519
|
import {
|
|
6309
5520
|
isValidElement as isValidElement2,
|
|
6310
|
-
useCallback as
|
|
6311
|
-
useEffect as
|
|
6312
|
-
useRef as
|
|
6313
|
-
useState as
|
|
5521
|
+
useCallback as useCallback11,
|
|
5522
|
+
useEffect as useEffect12,
|
|
5523
|
+
useRef as useRef12,
|
|
5524
|
+
useState as useState16
|
|
6314
5525
|
} from "react";
|
|
6315
|
-
import { Fragment as
|
|
5526
|
+
import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
6316
5527
|
function insightDelta(value, previous) {
|
|
6317
5528
|
if (typeof value !== "number" || !Number.isFinite(value)) return null;
|
|
6318
5529
|
if (typeof previous !== "number" || !Number.isFinite(previous)) return null;
|
|
@@ -6365,7 +5576,7 @@ function InsightCard({
|
|
|
6365
5576
|
const tone = delta ? insightDeltaTone(delta.direction, polarity) : "neutral";
|
|
6366
5577
|
const unavailable = typeof value === "number" && !Number.isFinite(value);
|
|
6367
5578
|
const shown = typeof value === "number" ? format(value) : value;
|
|
6368
|
-
return /* @__PURE__ */
|
|
5579
|
+
return /* @__PURE__ */ jsxs12(
|
|
6369
5580
|
"article",
|
|
6370
5581
|
{
|
|
6371
5582
|
"data-insight-card": "",
|
|
@@ -6373,40 +5584,40 @@ function InsightCard({
|
|
|
6373
5584
|
className: joinClasses("agent-arrive flex h-full flex-col rounded-xl border border-card-edge bg-card p-4", className),
|
|
6374
5585
|
style,
|
|
6375
5586
|
children: [
|
|
6376
|
-
eyebrow ? /* @__PURE__ */
|
|
6377
|
-
/* @__PURE__ */
|
|
6378
|
-
/* @__PURE__ */
|
|
5587
|
+
eyebrow ? /* @__PURE__ */ jsx14("p", { "data-insight-eyebrow": "", className: "mb-0.5 text-[11px] font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: eyebrow }) : null,
|
|
5588
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
5589
|
+
/* @__PURE__ */ jsx14("h3", { className: "text-[13px] font-medium text-muted-foreground", children: title }),
|
|
6379
5590
|
live ? (
|
|
6380
5591
|
// No `data-motion` opt-out: the word is the signal and the sweep is
|
|
6381
5592
|
// emphasis, so the reduced-motion floor reaches this like everything
|
|
6382
5593
|
// else and leaves a static, legible label.
|
|
6383
|
-
/* @__PURE__ */
|
|
5594
|
+
/* @__PURE__ */ jsx14("span", { className: "agent-shimmer shrink-0 text-[11px] font-medium", "data-insight-live": "", children: liveLabel })
|
|
6384
5595
|
) : null
|
|
6385
5596
|
] }),
|
|
6386
|
-
/* @__PURE__ */
|
|
6387
|
-
/* @__PURE__ */
|
|
6388
|
-
/* @__PURE__ */
|
|
6389
|
-
] }) : /* @__PURE__ */
|
|
6390
|
-
/* @__PURE__ */
|
|
6391
|
-
unit ? /* @__PURE__ */
|
|
5597
|
+
/* @__PURE__ */ jsx14("p", { className: "mt-1 flex items-baseline gap-1", children: unavailable ? /* @__PURE__ */ jsxs12("span", { "data-insight-value": "unavailable", className: "text-xl font-semibold text-muted-foreground", children: [
|
|
5598
|
+
/* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: INSIGHT_UNAVAILABLE_GLYPH }),
|
|
5599
|
+
/* @__PURE__ */ jsx14("span", { className: "sr-only", children: INSIGHT_UNAVAILABLE_LABEL })
|
|
5600
|
+
] }) : /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
5601
|
+
/* @__PURE__ */ jsx14("span", { className: "text-xl font-semibold tabular-nums text-foreground", children: shown }),
|
|
5602
|
+
unit ? /* @__PURE__ */ jsx14("span", { className: "text-[11px] text-muted-foreground", children: unit }) : null
|
|
6392
5603
|
] }) }),
|
|
6393
|
-
delta ? /* @__PURE__ */
|
|
6394
|
-
/* @__PURE__ */
|
|
5604
|
+
delta ? /* @__PURE__ */ jsxs12("p", { "data-insight-delta": delta.direction, className: `mt-0.5 text-[11px] font-medium ${TONE_CLASS[tone]}`, children: [
|
|
5605
|
+
/* @__PURE__ */ jsxs12("span", { "aria-hidden": "true", children: [
|
|
6395
5606
|
DIRECTION_GLYPH[delta.direction],
|
|
6396
5607
|
" "
|
|
6397
5608
|
] }),
|
|
6398
5609
|
formatInsightDelta(delta, format)
|
|
6399
5610
|
] }) : null,
|
|
6400
|
-
description ? /* @__PURE__ */
|
|
6401
|
-
series ? /* @__PURE__ */
|
|
6402
|
-
action ? /* @__PURE__ */
|
|
5611
|
+
description ? /* @__PURE__ */ jsx14("p", { className: "mt-1 text-[11px] text-muted-foreground", children: description }) : null,
|
|
5612
|
+
series ? /* @__PURE__ */ jsx14("div", { className: "mt-2 text-muted-foreground", children: /* @__PURE__ */ jsx14(Sparkline, { values: series, label: seriesLabel ?? title, format }) }) : null,
|
|
5613
|
+
action ? /* @__PURE__ */ jsx14("div", { className: "mt-3", children: renderInsightAction(action) }) : null
|
|
6403
5614
|
]
|
|
6404
5615
|
}
|
|
6405
5616
|
);
|
|
6406
5617
|
}
|
|
6407
5618
|
function renderInsightAction(action) {
|
|
6408
5619
|
if (isValidElement2(action)) return action;
|
|
6409
|
-
return /* @__PURE__ */
|
|
5620
|
+
return /* @__PURE__ */ jsx14(
|
|
6410
5621
|
"button",
|
|
6411
5622
|
{
|
|
6412
5623
|
type: "button",
|
|
@@ -6475,15 +5686,15 @@ function InsightDeck({
|
|
|
6475
5686
|
className,
|
|
6476
5687
|
onPageChange
|
|
6477
5688
|
}) {
|
|
6478
|
-
const [page, setPage] =
|
|
6479
|
-
const [held, setHeld] =
|
|
5689
|
+
const [page, setPage] = useState16(0);
|
|
5690
|
+
const [held, setHeld] = useState16(null);
|
|
6480
5691
|
const answered = state.status === "error" || state.status === "empty";
|
|
6481
5692
|
const carried = state.status === "ready" ? state.value : answered ? null : held;
|
|
6482
5693
|
if (carried !== held) setHeld(carried);
|
|
6483
5694
|
const shown = carried !== null && state.status !== "ready" ? { status: "ready", value: carried, retry: state.retry } : state;
|
|
6484
5695
|
const refreshing = shown !== state;
|
|
6485
|
-
const reported =
|
|
6486
|
-
const settlePage =
|
|
5696
|
+
const reported = useRef12(0);
|
|
5697
|
+
const settlePage = useCallback11(
|
|
6487
5698
|
(next) => {
|
|
6488
5699
|
if (reported.current === next) return;
|
|
6489
5700
|
reported.current = next;
|
|
@@ -6491,7 +5702,7 @@ function InsightDeck({
|
|
|
6491
5702
|
},
|
|
6492
5703
|
[onPageChange]
|
|
6493
5704
|
);
|
|
6494
|
-
return /* @__PURE__ */
|
|
5705
|
+
return /* @__PURE__ */ jsx14(
|
|
6495
5706
|
AsyncView,
|
|
6496
5707
|
{
|
|
6497
5708
|
state: shown,
|
|
@@ -6499,7 +5710,7 @@ function InsightDeck({
|
|
|
6499
5710
|
loadingLabel,
|
|
6500
5711
|
retryLabel,
|
|
6501
5712
|
className,
|
|
6502
|
-
children: (insights) => /* @__PURE__ */
|
|
5713
|
+
children: (insights) => /* @__PURE__ */ jsx14(
|
|
6503
5714
|
InsightPages,
|
|
6504
5715
|
{
|
|
6505
5716
|
insights,
|
|
@@ -6566,18 +5777,18 @@ function InsightPages({
|
|
|
6566
5777
|
const pageCount = insightPageCount(insights.length, size);
|
|
6567
5778
|
const current = Math.min(Math.max(page, 0), pageCount - 1);
|
|
6568
5779
|
const visible = insightPageSlice(insights, current, size);
|
|
6569
|
-
const sectionRef =
|
|
6570
|
-
const listRef =
|
|
6571
|
-
const recoverFocus =
|
|
6572
|
-
|
|
5780
|
+
const sectionRef = useRef12(null);
|
|
5781
|
+
const listRef = useRef12(null);
|
|
5782
|
+
const recoverFocus = useRef12(false);
|
|
5783
|
+
useEffect12(() => {
|
|
6573
5784
|
onPageSettled(current);
|
|
6574
5785
|
}, [current, onPageSettled]);
|
|
6575
|
-
|
|
5786
|
+
useEffect12(() => {
|
|
6576
5787
|
if (!recoverFocus.current) return;
|
|
6577
5788
|
recoverFocus.current = false;
|
|
6578
5789
|
sectionRef.current?.focus();
|
|
6579
5790
|
}, [current]);
|
|
6580
|
-
const goTo =
|
|
5791
|
+
const goTo = useCallback11(
|
|
6581
5792
|
(next) => {
|
|
6582
5793
|
const clamped = Math.min(Math.max(next, 0), pageCount - 1);
|
|
6583
5794
|
if (clamped === current) return false;
|
|
@@ -6612,7 +5823,7 @@ function InsightPages({
|
|
|
6612
5823
|
}
|
|
6613
5824
|
if (moved) event.preventDefault();
|
|
6614
5825
|
};
|
|
6615
|
-
return /* @__PURE__ */
|
|
5826
|
+
return /* @__PURE__ */ jsxs12(
|
|
6616
5827
|
"section",
|
|
6617
5828
|
{
|
|
6618
5829
|
ref: sectionRef,
|
|
@@ -6624,7 +5835,7 @@ function InsightPages({
|
|
|
6624
5835
|
tabIndex: pageCount > 1 ? 0 : void 0,
|
|
6625
5836
|
"aria-keyshortcuts": pageCount > 1 ? "ArrowLeft ArrowRight PageUp PageDown Home End" : void 0,
|
|
6626
5837
|
children: [
|
|
6627
|
-
/* @__PURE__ */
|
|
5838
|
+
/* @__PURE__ */ jsx14("ul", { ref: listRef, className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-3", children: visible.map(({ id, style, ...card }, index) => (
|
|
6628
5839
|
// The page index is in the key on purpose: a page turn is an arrival,
|
|
6629
5840
|
// and reusing the node would swap the text under a card that never
|
|
6630
5841
|
// moved. Remounting replays `.agent-arrive` with the new stagger.
|
|
@@ -6635,10 +5846,10 @@ function InsightPages({
|
|
|
6635
5846
|
// does not arrive a second time. The key does BOTH jobs — but only
|
|
6636
5847
|
// because the deck now keeps this subtree mounted across a reload
|
|
6637
5848
|
// (see `InsightDeck`); a key is never compared across a teardown.
|
|
6638
|
-
/* @__PURE__ */
|
|
5849
|
+
/* @__PURE__ */ jsx14("li", { children: /* @__PURE__ */ jsx14(InsightCard, { ...card, style: staggerStyle(index, style) }) }, `${current}:${id}`)
|
|
6639
5850
|
)) }),
|
|
6640
|
-
/* @__PURE__ */
|
|
6641
|
-
/* @__PURE__ */
|
|
5851
|
+
/* @__PURE__ */ jsxs12("div", { className: pageCount > 1 ? "flex items-center justify-between gap-2" : void 0, children: [
|
|
5852
|
+
/* @__PURE__ */ jsxs12(
|
|
6642
5853
|
"p",
|
|
6643
5854
|
{
|
|
6644
5855
|
role: "status",
|
|
@@ -6652,8 +5863,8 @@ function InsightPages({
|
|
|
6652
5863
|
]
|
|
6653
5864
|
}
|
|
6654
5865
|
),
|
|
6655
|
-
pageCount > 1 ? /* @__PURE__ */
|
|
6656
|
-
/* @__PURE__ */
|
|
5866
|
+
pageCount > 1 ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1", children: [
|
|
5867
|
+
/* @__PURE__ */ jsx14(PagerButton, { label: "Previous insights", glyph: "\u2039", atEnd: current === 0, onClick: () => goTo(current - 1) }),
|
|
6657
5868
|
pageCount <= MAX_PAGE_DOTS ? Array.from({ length: pageCount }, (_, index) => (
|
|
6658
5869
|
// WCAG 2.2 SC 2.5.8 wants a 24x24 CSS px target. The dot stays
|
|
6659
5870
|
// 8px because a 24px dot is a different control; the BUTTON
|
|
@@ -6661,7 +5872,7 @@ function InsightPages({
|
|
|
6661
5872
|
// and the span is the graphic. The Spacing exception cannot
|
|
6662
5873
|
// rescue the bare dot — at a 12px pitch the 24px circle around
|
|
6663
5874
|
// each centre overlaps its neighbour's.
|
|
6664
|
-
/* @__PURE__ */
|
|
5875
|
+
/* @__PURE__ */ jsx14(
|
|
6665
5876
|
"button",
|
|
6666
5877
|
{
|
|
6667
5878
|
type: "button",
|
|
@@ -6669,7 +5880,7 @@ function InsightPages({
|
|
|
6669
5880
|
"aria-current": index === current ? "page" : void 0,
|
|
6670
5881
|
onClick: () => goTo(index),
|
|
6671
5882
|
className: "group flex h-6 w-6 shrink-0 items-center justify-center rounded-full",
|
|
6672
|
-
children: /* @__PURE__ */
|
|
5883
|
+
children: /* @__PURE__ */ jsx14(
|
|
6673
5884
|
"span",
|
|
6674
5885
|
{
|
|
6675
5886
|
"aria-hidden": "true",
|
|
@@ -6683,7 +5894,7 @@ function InsightPages({
|
|
|
6683
5894
|
index
|
|
6684
5895
|
)
|
|
6685
5896
|
)) : null,
|
|
6686
|
-
/* @__PURE__ */
|
|
5897
|
+
/* @__PURE__ */ jsx14(
|
|
6687
5898
|
PagerButton,
|
|
6688
5899
|
{
|
|
6689
5900
|
label: "Next insights",
|
|
@@ -6704,7 +5915,7 @@ function PagerButton({
|
|
|
6704
5915
|
atEnd,
|
|
6705
5916
|
onClick
|
|
6706
5917
|
}) {
|
|
6707
|
-
return /* @__PURE__ */
|
|
5918
|
+
return /* @__PURE__ */ jsx14(
|
|
6708
5919
|
"button",
|
|
6709
5920
|
{
|
|
6710
5921
|
type: "button",
|
|
@@ -6714,13 +5925,13 @@ function PagerButton({
|
|
|
6714
5925
|
if (!atEnd) onClick();
|
|
6715
5926
|
},
|
|
6716
5927
|
className: `flex h-6 w-6 items-center justify-center rounded-md border border-border text-xs text-muted-foreground transition ${atEnd ? "opacity-40" : "hover:bg-accent hover:text-foreground"}`,
|
|
6717
|
-
children: /* @__PURE__ */
|
|
5928
|
+
children: /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: glyph })
|
|
6718
5929
|
}
|
|
6719
5930
|
);
|
|
6720
5931
|
}
|
|
6721
5932
|
|
|
6722
5933
|
// src/web-react/index.tsx
|
|
6723
|
-
import { Fragment as
|
|
5934
|
+
import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
6724
5935
|
function formatModelCost(msg, models) {
|
|
6725
5936
|
if (msg.promptTokens == null && msg.completionTokens == null) return null;
|
|
6726
5937
|
const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
|
|
@@ -6739,41 +5950,41 @@ function formatTokensPerSecond(msg) {
|
|
|
6739
5950
|
return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
|
|
6740
5951
|
}
|
|
6741
5952
|
function RunDrillIn({ run, onClose }) {
|
|
6742
|
-
return /* @__PURE__ */
|
|
6743
|
-
/* @__PURE__ */
|
|
6744
|
-
/* @__PURE__ */
|
|
5953
|
+
return /* @__PURE__ */ jsxs13("div", { className: `fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-card-edge bg-popover ${OVERLAY_SHADOW}`, children: [
|
|
5954
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
|
|
5955
|
+
/* @__PURE__ */ jsx15(
|
|
6745
5956
|
"span",
|
|
6746
5957
|
{
|
|
6747
5958
|
className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
|
|
6748
5959
|
}
|
|
6749
5960
|
),
|
|
6750
|
-
/* @__PURE__ */
|
|
6751
|
-
/* @__PURE__ */
|
|
6752
|
-
/* @__PURE__ */
|
|
5961
|
+
/* @__PURE__ */ jsxs13("div", { className: "min-w-0 flex-1", children: [
|
|
5962
|
+
/* @__PURE__ */ jsx15("p", { className: "truncate text-[15px] font-semibold", children: run.title }),
|
|
5963
|
+
/* @__PURE__ */ jsx15("p", { className: "truncate font-mono text-xs text-muted-foreground", children: run.toolName })
|
|
6753
5964
|
] }),
|
|
6754
|
-
/* @__PURE__ */
|
|
5965
|
+
/* @__PURE__ */ jsx15(
|
|
6755
5966
|
"button",
|
|
6756
5967
|
{
|
|
6757
5968
|
type: "button",
|
|
6758
5969
|
onClick: onClose,
|
|
6759
5970
|
"aria-label": "Close",
|
|
6760
5971
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent hover:text-foreground",
|
|
6761
|
-
children: /* @__PURE__ */
|
|
5972
|
+
children: /* @__PURE__ */ jsx15("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx15("path", { d: "M18 6 6 18M6 6l12 12" }) })
|
|
6762
5973
|
}
|
|
6763
5974
|
)
|
|
6764
5975
|
] }),
|
|
6765
|
-
/* @__PURE__ */
|
|
6766
|
-
run.steps.length === 0 && /* @__PURE__ */
|
|
6767
|
-
run.steps.map((step, i) => /* @__PURE__ */
|
|
6768
|
-
/* @__PURE__ */
|
|
6769
|
-
/* @__PURE__ */
|
|
6770
|
-
/* @__PURE__ */
|
|
6771
|
-
/* @__PURE__ */
|
|
5976
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
|
|
5977
|
+
run.steps.length === 0 && /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
|
|
5978
|
+
run.steps.map((step, i) => /* @__PURE__ */ jsxs13("div", { className: "rounded-lg border border-card-edge bg-card", children: [
|
|
5979
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-baseline gap-2 border-b border-border px-3 py-1.5", children: [
|
|
5980
|
+
/* @__PURE__ */ jsx15("span", { className: `font-mono text-xs ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
|
|
5981
|
+
/* @__PURE__ */ jsx15("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
|
|
5982
|
+
/* @__PURE__ */ jsx15("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: new Date(step.at).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) })
|
|
6772
5983
|
] }),
|
|
6773
|
-
step.detail && /* @__PURE__ */
|
|
5984
|
+
step.detail && /* @__PURE__ */ jsx15("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-xs leading-relaxed text-muted-foreground", children: step.detail })
|
|
6774
5985
|
] }, i))
|
|
6775
5986
|
] }),
|
|
6776
|
-
/* @__PURE__ */
|
|
5987
|
+
/* @__PURE__ */ jsx15("p", { className: "border-t border-border px-4 py-2 text-xs text-muted-foreground", children: "Read-only transcript \u2014 reply in the main chat." })
|
|
6777
5988
|
] });
|
|
6778
5989
|
}
|
|
6779
5990
|
function pendingApprovalOf(call) {
|
|
@@ -6789,23 +6000,23 @@ function ChatEmptyState({
|
|
|
6789
6000
|
}) {
|
|
6790
6001
|
const doorCount = Math.min(doors?.length ?? 0, 3);
|
|
6791
6002
|
const doorsGridClass = doorCount === 1 ? "mx-auto max-w-sm sm:grid-cols-1" : doorCount === 2 ? "sm:grid-cols-2" : "sm:grid-cols-3";
|
|
6792
|
-
return /* @__PURE__ */
|
|
6793
|
-
/* @__PURE__ */
|
|
6794
|
-
/* @__PURE__ */
|
|
6795
|
-
/* @__PURE__ */
|
|
6796
|
-
subline && /* @__PURE__ */
|
|
6797
|
-
doors && doors.length > 0 && /* @__PURE__ */
|
|
6003
|
+
return /* @__PURE__ */ jsxs13("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
|
|
6004
|
+
/* @__PURE__ */ jsx15("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx15(BrandMark, { size: 32, className: "shrink-0" }) }),
|
|
6005
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: productName }),
|
|
6006
|
+
/* @__PURE__ */ jsx15("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground", children: headline }),
|
|
6007
|
+
subline && /* @__PURE__ */ jsx15("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
|
|
6008
|
+
doors && doors.length > 0 && /* @__PURE__ */ jsx15("div", { className: `mt-7 grid w-full gap-2.5 ${doorsGridClass}`, children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs13(
|
|
6798
6009
|
"button",
|
|
6799
6010
|
{
|
|
6800
6011
|
type: "button",
|
|
6801
6012
|
onClick: door.onSelect,
|
|
6802
6013
|
className: "group flex min-h-[44px] flex-col items-start rounded-xl border border-border bg-card px-4 py-3 text-left transition hover:border-primary/40 hover:bg-accent",
|
|
6803
6014
|
children: [
|
|
6804
|
-
/* @__PURE__ */
|
|
6015
|
+
/* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2 text-sm font-semibold text-foreground", children: [
|
|
6805
6016
|
door.icon,
|
|
6806
6017
|
door.label
|
|
6807
6018
|
] }),
|
|
6808
|
-
door.description && /* @__PURE__ */
|
|
6019
|
+
door.description && /* @__PURE__ */ jsx15("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
|
|
6809
6020
|
]
|
|
6810
6021
|
},
|
|
6811
6022
|
i
|
|
@@ -6814,26 +6025,26 @@ function ChatEmptyState({
|
|
|
6814
6025
|
}
|
|
6815
6026
|
function ToolGlyph({ name, className }) {
|
|
6816
6027
|
if (name.startsWith("sandbox_")) {
|
|
6817
|
-
return /* @__PURE__ */
|
|
6818
|
-
/* @__PURE__ */
|
|
6819
|
-
/* @__PURE__ */
|
|
6028
|
+
return /* @__PURE__ */ jsxs13("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
6029
|
+
/* @__PURE__ */ jsx15("polyline", { points: "4 17 10 11 4 5" }),
|
|
6030
|
+
/* @__PURE__ */ jsx15("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
|
|
6820
6031
|
] });
|
|
6821
6032
|
}
|
|
6822
6033
|
if (name === "submit_proposal") {
|
|
6823
|
-
return /* @__PURE__ */
|
|
6824
|
-
/* @__PURE__ */
|
|
6825
|
-
/* @__PURE__ */
|
|
6034
|
+
return /* @__PURE__ */ jsxs13("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
6035
|
+
/* @__PURE__ */ jsx15("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
6036
|
+
/* @__PURE__ */ jsx15("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
|
|
6826
6037
|
] });
|
|
6827
6038
|
}
|
|
6828
6039
|
if (name === "schedule_followup") {
|
|
6829
|
-
return /* @__PURE__ */
|
|
6830
|
-
/* @__PURE__ */
|
|
6831
|
-
/* @__PURE__ */
|
|
6040
|
+
return /* @__PURE__ */ jsxs13("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
|
|
6041
|
+
/* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "9" }),
|
|
6042
|
+
/* @__PURE__ */ jsx15("path", { d: "M12 7v5l3 3" })
|
|
6832
6043
|
] });
|
|
6833
6044
|
}
|
|
6834
|
-
return /* @__PURE__ */
|
|
6835
|
-
/* @__PURE__ */
|
|
6836
|
-
/* @__PURE__ */
|
|
6045
|
+
return /* @__PURE__ */ jsxs13("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
6046
|
+
/* @__PURE__ */ jsx15("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
|
|
6047
|
+
/* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "4" })
|
|
6837
6048
|
] });
|
|
6838
6049
|
}
|
|
6839
6050
|
function toolOutcomeOf(call) {
|
|
@@ -6919,40 +6130,40 @@ function truncate(v, max = 240) {
|
|
|
6919
6130
|
function KvRows({ data }) {
|
|
6920
6131
|
const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
|
|
6921
6132
|
if (!entries.length) return null;
|
|
6922
|
-
return /* @__PURE__ */
|
|
6923
|
-
/* @__PURE__ */
|
|
6924
|
-
/* @__PURE__ */
|
|
6133
|
+
return /* @__PURE__ */ jsx15("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs13("div", { className: "contents", children: [
|
|
6134
|
+
/* @__PURE__ */ jsx15("dt", { className: "font-mono text-xs text-muted-foreground", children: k }),
|
|
6135
|
+
/* @__PURE__ */ jsx15("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-xs text-muted-foreground", children: truncate(v) })
|
|
6925
6136
|
] }, k)) });
|
|
6926
6137
|
}
|
|
6927
6138
|
function ShellDetail({ call }) {
|
|
6928
6139
|
const outcome = toolOutcomeOf(call);
|
|
6929
6140
|
const r = outcome?.result ?? {};
|
|
6930
|
-
return /* @__PURE__ */
|
|
6931
|
-
/* @__PURE__ */
|
|
6932
|
-
/* @__PURE__ */
|
|
6933
|
-
/* @__PURE__ */
|
|
6934
|
-
r.exitCode != null && /* @__PURE__ */
|
|
6141
|
+
return /* @__PURE__ */ jsxs13("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-xs leading-relaxed", children: [
|
|
6142
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
|
|
6143
|
+
/* @__PURE__ */ jsx15("span", { className: "select-none text-zinc-500", children: "$" }),
|
|
6144
|
+
/* @__PURE__ */ jsx15("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
|
|
6145
|
+
r.exitCode != null && /* @__PURE__ */ jsxs13("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
|
|
6935
6146
|
"exit ",
|
|
6936
6147
|
r.exitCode
|
|
6937
6148
|
] })
|
|
6938
6149
|
] }),
|
|
6939
|
-
/* @__PURE__ */
|
|
6150
|
+
/* @__PURE__ */ jsx15("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap px-3 pb-2.5 pt-1.5 text-zinc-300", children: outcome?.ok === false ? outcome.message ?? "failed" : [r.stdout, r.stderr].filter(Boolean).join("\n") || "(no output)" })
|
|
6940
6151
|
] });
|
|
6941
6152
|
}
|
|
6942
6153
|
function DefaultToolDetail({ call }) {
|
|
6943
6154
|
const result = call.result;
|
|
6944
6155
|
const envelope = typeof result === "object" && result !== null ? result : null;
|
|
6945
|
-
return /* @__PURE__ */
|
|
6946
|
-
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */
|
|
6947
|
-
/* @__PURE__ */
|
|
6948
|
-
/* @__PURE__ */
|
|
6156
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-2", children: [
|
|
6157
|
+
call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs13("div", { children: [
|
|
6158
|
+
/* @__PURE__ */ jsx15("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
|
|
6159
|
+
/* @__PURE__ */ jsx15(KvRows, { data: call.args })
|
|
6949
6160
|
] }),
|
|
6950
|
-
envelope ? /* @__PURE__ */
|
|
6951
|
-
/* @__PURE__ */
|
|
6952
|
-
envelope.ok === false ? /* @__PURE__ */
|
|
6953
|
-
] }) : result != null ? /* @__PURE__ */
|
|
6954
|
-
/* @__PURE__ */
|
|
6955
|
-
/* @__PURE__ */
|
|
6161
|
+
envelope ? /* @__PURE__ */ jsxs13("div", { children: [
|
|
6162
|
+
/* @__PURE__ */ jsx15("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: envelope.ok === false ? "Failed" : "Result" }),
|
|
6163
|
+
envelope.ok === false ? /* @__PURE__ */ jsx15("p", { className: "text-xs text-destructive", children: envelope.message ?? "Tool failed" }) : envelope.result && typeof envelope.result === "object" ? /* @__PURE__ */ jsx15(KvRows, { data: envelope.result }) : envelope.result != null ? /* @__PURE__ */ jsx15("p", { className: "font-mono text-xs text-muted-foreground", children: truncate(envelope.result) }) : null
|
|
6164
|
+
] }) : result != null ? /* @__PURE__ */ jsxs13("div", { children: [
|
|
6165
|
+
/* @__PURE__ */ jsx15("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Result" }),
|
|
6166
|
+
/* @__PURE__ */ jsx15("p", { className: "font-mono text-xs text-muted-foreground", children: truncate(result) })
|
|
6956
6167
|
] }) : null
|
|
6957
6168
|
] });
|
|
6958
6169
|
}
|
|
@@ -6963,24 +6174,24 @@ function ProposalCard({
|
|
|
6963
6174
|
approval,
|
|
6964
6175
|
renderers
|
|
6965
6176
|
}) {
|
|
6966
|
-
const [expanded, setExpanded] =
|
|
6177
|
+
const [expanded, setExpanded] = useState17(false);
|
|
6967
6178
|
const { summary, meta, typeSlug } = proposalPreview(call);
|
|
6968
6179
|
const custom = renderers?.[call.name]?.(call, message);
|
|
6969
6180
|
const { pending: deciding, run: decide } = usePending();
|
|
6970
|
-
return /* @__PURE__ */
|
|
6971
|
-
/* @__PURE__ */
|
|
6972
|
-
/* @__PURE__ */
|
|
6973
|
-
/* @__PURE__ */
|
|
6974
|
-
/* @__PURE__ */
|
|
6975
|
-
/* @__PURE__ */
|
|
6976
|
-
summary && /* @__PURE__ */
|
|
6977
|
-
typeSlug && /* @__PURE__ */
|
|
6978
|
-
meta.length > 0 && /* @__PURE__ */
|
|
6181
|
+
return /* @__PURE__ */ jsxs13("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
|
|
6182
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
|
|
6183
|
+
/* @__PURE__ */ jsx15("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx15(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
|
|
6184
|
+
/* @__PURE__ */ jsxs13("div", { className: "min-w-0 flex-1", children: [
|
|
6185
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs font-semibold uppercase tracking-[0.05em] text-warning-strong", children: approval ? "Needs your approval" : "Awaiting approval" }),
|
|
6186
|
+
/* @__PURE__ */ jsx15("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
|
|
6187
|
+
summary && /* @__PURE__ */ jsx15("p", { className: "mt-1 text-xs leading-relaxed text-muted-foreground", children: summary }),
|
|
6188
|
+
typeSlug && /* @__PURE__ */ jsx15("p", { className: "mt-1 font-mono text-xs text-muted-foreground", children: typeSlug }),
|
|
6189
|
+
meta.length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx15("span", { className: "rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-muted-foreground", children: m }, i)) })
|
|
6979
6190
|
] })
|
|
6980
6191
|
] }),
|
|
6981
|
-
/* @__PURE__ */
|
|
6982
|
-
approval && /* @__PURE__ */
|
|
6983
|
-
/* @__PURE__ */
|
|
6192
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
|
|
6193
|
+
approval && /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
6194
|
+
/* @__PURE__ */ jsx15(
|
|
6984
6195
|
"button",
|
|
6985
6196
|
{
|
|
6986
6197
|
type: "button",
|
|
@@ -6990,7 +6201,7 @@ function ProposalCard({
|
|
|
6990
6201
|
children: "Approve & run"
|
|
6991
6202
|
}
|
|
6992
6203
|
),
|
|
6993
|
-
/* @__PURE__ */
|
|
6204
|
+
/* @__PURE__ */ jsx15(
|
|
6994
6205
|
"button",
|
|
6995
6206
|
{
|
|
6996
6207
|
type: "button",
|
|
@@ -7001,7 +6212,7 @@ function ProposalCard({
|
|
|
7001
6212
|
}
|
|
7002
6213
|
)
|
|
7003
6214
|
] }),
|
|
7004
|
-
/* @__PURE__ */
|
|
6215
|
+
/* @__PURE__ */ jsxs13(
|
|
7005
6216
|
"button",
|
|
7006
6217
|
{
|
|
7007
6218
|
type: "button",
|
|
@@ -7010,12 +6221,12 @@ function ProposalCard({
|
|
|
7010
6221
|
className: "ml-auto inline-flex items-center gap-1 rounded text-[12px] font-medium text-muted-foreground transition hover:text-foreground",
|
|
7011
6222
|
children: [
|
|
7012
6223
|
expanded ? "Hide details" : "View details",
|
|
7013
|
-
/* @__PURE__ */
|
|
6224
|
+
/* @__PURE__ */ jsx15(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
|
|
7014
6225
|
]
|
|
7015
6226
|
}
|
|
7016
6227
|
)
|
|
7017
6228
|
] }),
|
|
7018
|
-
expanded && /* @__PURE__ */
|
|
6229
|
+
expanded && /* @__PURE__ */ jsx15("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx15(DefaultToolDetail, { call }) })
|
|
7019
6230
|
] });
|
|
7020
6231
|
}
|
|
7021
6232
|
function formatFollowupWhen(when) {
|
|
@@ -7030,14 +6241,14 @@ function FollowupCard({ call }) {
|
|
|
7030
6241
|
const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
|
|
7031
6242
|
const failed = toolCallFailed(call);
|
|
7032
6243
|
const errorText = failed ? toolOutcomeOf(call)?.message ?? "Scheduling failed" : null;
|
|
7033
|
-
return /* @__PURE__ */
|
|
7034
|
-
/* @__PURE__ */
|
|
7035
|
-
/* @__PURE__ */
|
|
7036
|
-
/* @__PURE__ */
|
|
7037
|
-
when && /* @__PURE__ */
|
|
7038
|
-
/* @__PURE__ */
|
|
6244
|
+
return /* @__PURE__ */ jsx15("div", { className: "flex items-start gap-2", children: /* @__PURE__ */ jsxs13("div", { className: "min-w-0 flex-1 overflow-hidden rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--md3-surface-container)]", children: [
|
|
6245
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex w-full items-center gap-2.5 px-3 py-2", children: [
|
|
6246
|
+
/* @__PURE__ */ jsx15("span", { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-[var(--radius-sm)] border border-border bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx15(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
|
|
6247
|
+
/* @__PURE__ */ jsx15("span", { className: "shrink-0 whitespace-nowrap text-xs font-medium text-foreground", children: friendlyToolTitle(call) }),
|
|
6248
|
+
when && /* @__PURE__ */ jsx15("span", { title: when, className: "hidden min-w-0 flex-1 truncate font-mono text-xs tabular-nums text-muted-foreground sm:inline", children: formatFollowupWhen(when) }),
|
|
6249
|
+
/* @__PURE__ */ jsx15("span", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: call.status === "running" ? /* @__PURE__ */ jsx15("svg", { className: "h-3 w-3 shrink-0 animate-spin text-[var(--accent-text)]", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx15("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }) : /* @__PURE__ */ jsx15("span", { className: `h-1.5 w-1.5 shrink-0 rounded-full ${failed ? "bg-[var(--surface-danger-text)]" : "bg-[var(--surface-success-text)]"}` }) })
|
|
7039
6250
|
] }),
|
|
7040
|
-
errorText && /* @__PURE__ */
|
|
6251
|
+
errorText && /* @__PURE__ */ jsx15("div", { className: "border-t border-border px-3 py-2 text-xs text-[var(--surface-danger-text)]", children: errorText })
|
|
7041
6252
|
] }) });
|
|
7042
6253
|
}
|
|
7043
6254
|
function toolRowTitle(call) {
|
|
@@ -7060,10 +6271,10 @@ function ToolCallCard({
|
|
|
7060
6271
|
const arrival = useArrivalStyle(staggerIndex ?? 0);
|
|
7061
6272
|
const pending = call.status === "done" ? pendingApprovalOf(call) : null;
|
|
7062
6273
|
const kind = blockKindOf(call);
|
|
7063
|
-
const arrive = (row) => /* @__PURE__ */
|
|
6274
|
+
const arrive = (row) => /* @__PURE__ */ jsx15("div", { className: "agent-arrive", style: arrival, children: row });
|
|
7064
6275
|
if (pending) {
|
|
7065
6276
|
return arrive(
|
|
7066
|
-
/* @__PURE__ */
|
|
6277
|
+
/* @__PURE__ */ jsx15(
|
|
7067
6278
|
ProposalCard,
|
|
7068
6279
|
{
|
|
7069
6280
|
call,
|
|
@@ -7076,18 +6287,18 @@ function ToolCallCard({
|
|
|
7076
6287
|
);
|
|
7077
6288
|
}
|
|
7078
6289
|
if (kind === "followup") {
|
|
7079
|
-
return arrive(/* @__PURE__ */
|
|
6290
|
+
return arrive(/* @__PURE__ */ jsx15(FollowupCard, { call }));
|
|
7080
6291
|
}
|
|
7081
6292
|
const custom = renderers?.[call.name]?.(call, message);
|
|
7082
6293
|
return arrive(
|
|
7083
|
-
/* @__PURE__ */
|
|
6294
|
+
/* @__PURE__ */ jsx15(
|
|
7084
6295
|
InlineToolItem,
|
|
7085
6296
|
{
|
|
7086
6297
|
part: chatToolCallPart(call),
|
|
7087
6298
|
title: toolRowTitle(call),
|
|
7088
6299
|
description: toolRowDescription(call),
|
|
7089
|
-
renderToolDetail: () => custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */
|
|
7090
|
-
actions: onOpenRun && call.name.startsWith("sandbox_") ? /* @__PURE__ */
|
|
6300
|
+
renderToolDetail: () => custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx15(ShellDetail, { call }) : /* @__PURE__ */ jsx15(DefaultToolDetail, { call })),
|
|
6301
|
+
actions: onOpenRun && call.name.startsWith("sandbox_") ? /* @__PURE__ */ jsx15(
|
|
7091
6302
|
"button",
|
|
7092
6303
|
{
|
|
7093
6304
|
type: "button",
|
|
@@ -7095,9 +6306,9 @@ function ToolCallCard({
|
|
|
7095
6306
|
"aria-label": "Open full transcript",
|
|
7096
6307
|
title: "Open full transcript",
|
|
7097
6308
|
className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent hover:text-foreground",
|
|
7098
|
-
children: /* @__PURE__ */
|
|
7099
|
-
/* @__PURE__ */
|
|
7100
|
-
/* @__PURE__ */
|
|
6309
|
+
children: /* @__PURE__ */ jsxs13("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
6310
|
+
/* @__PURE__ */ jsx15("path", { d: "M7 17 17 7" }),
|
|
6311
|
+
/* @__PURE__ */ jsx15("path", { d: "M7 7h10v10" })
|
|
7101
6312
|
] })
|
|
7102
6313
|
}
|
|
7103
6314
|
) : void 0
|
|
@@ -7106,7 +6317,7 @@ function ToolCallCard({
|
|
|
7106
6317
|
);
|
|
7107
6318
|
}
|
|
7108
6319
|
function StreamingCaret() {
|
|
7109
|
-
return /* @__PURE__ */
|
|
6320
|
+
return /* @__PURE__ */ jsx15(
|
|
7110
6321
|
"span",
|
|
7111
6322
|
{
|
|
7112
6323
|
className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-[agent-caret_1s_step-end_infinite] rounded-sm bg-foreground/70",
|
|
@@ -7123,7 +6334,7 @@ function SegmentText({
|
|
|
7123
6334
|
messageClassName
|
|
7124
6335
|
}) {
|
|
7125
6336
|
const text = useSmoothText(content, streaming);
|
|
7126
|
-
const body =
|
|
6337
|
+
const body = useMemo8(() => renderBody(text), [renderBody, text]);
|
|
7127
6338
|
if (!content.trim() && !showCaret) return null;
|
|
7128
6339
|
return (
|
|
7129
6340
|
// A settled run arrives from a short blur; the LIVE run does not, because
|
|
@@ -7131,9 +6342,9 @@ function SegmentText({
|
|
|
7131
6342
|
// the container on top of that makes the paragraph shimmer while it types.
|
|
7132
6343
|
// The distinction is what separates "the answer materialised" from "the
|
|
7133
6344
|
// log was appended to".
|
|
7134
|
-
/* @__PURE__ */
|
|
6345
|
+
/* @__PURE__ */ jsxs13("div", { className: `${messageClassName}${streaming ? "" : " agent-stream-in"}`, children: [
|
|
7135
6346
|
body,
|
|
7136
|
-
showCaret && /* @__PURE__ */
|
|
6347
|
+
showCaret && /* @__PURE__ */ jsx15(StreamingCaret, {})
|
|
7137
6348
|
] })
|
|
7138
6349
|
);
|
|
7139
6350
|
}
|
|
@@ -7158,7 +6369,7 @@ function SegmentedBody({
|
|
|
7158
6369
|
const leftoverToolCalls = (msg.toolCalls ?? []).filter(
|
|
7159
6370
|
(tc) => !segmentToolIds.has(tc.id)
|
|
7160
6371
|
);
|
|
7161
|
-
const renderToolCard = (call, index) => /* @__PURE__ */
|
|
6372
|
+
const renderToolCard = (call, index) => /* @__PURE__ */ jsx15(
|
|
7162
6373
|
ToolCallCard,
|
|
7163
6374
|
{
|
|
7164
6375
|
call,
|
|
@@ -7186,7 +6397,7 @@ function SegmentedBody({
|
|
|
7186
6397
|
for (const g of groups) {
|
|
7187
6398
|
if (g.kind === "text") {
|
|
7188
6399
|
children.push(
|
|
7189
|
-
/* @__PURE__ */
|
|
6400
|
+
/* @__PURE__ */ jsx15(
|
|
7190
6401
|
SegmentText,
|
|
7191
6402
|
{
|
|
7192
6403
|
content: g.content,
|
|
@@ -7202,13 +6413,13 @@ function SegmentedBody({
|
|
|
7202
6413
|
}
|
|
7203
6414
|
if (!streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool)) {
|
|
7204
6415
|
children.push(
|
|
7205
|
-
/* @__PURE__ */
|
|
7206
|
-
/* @__PURE__ */
|
|
6416
|
+
/* @__PURE__ */ jsxs13("details", { children: [
|
|
6417
|
+
/* @__PURE__ */ jsxs13("summary", { className: "cursor-pointer select-none rounded-md py-0.5 text-xs font-medium text-muted-foreground [transition:color_var(--motion-control)] hover:text-foreground", children: [
|
|
7207
6418
|
"Worked through ",
|
|
7208
6419
|
g.calls.length,
|
|
7209
6420
|
" steps"
|
|
7210
6421
|
] }),
|
|
7211
|
-
/* @__PURE__ */
|
|
6422
|
+
/* @__PURE__ */ jsx15("div", { className: "mt-1.5 flex flex-col gap-1.5", children: g.calls.map(renderToolCard) })
|
|
7212
6423
|
] }, `tools-fold-${g.index}`)
|
|
7213
6424
|
);
|
|
7214
6425
|
continue;
|
|
@@ -7217,9 +6428,9 @@ function SegmentedBody({
|
|
|
7217
6428
|
}
|
|
7218
6429
|
leftoverToolCalls.forEach((call, index) => children.push(renderToolCard(call, index)));
|
|
7219
6430
|
if (streaming && segments[lastIndex]?.kind === "tool") {
|
|
7220
|
-
children.push(/* @__PURE__ */
|
|
6431
|
+
children.push(/* @__PURE__ */ jsx15(StreamingCaret, {}, "streaming-caret"));
|
|
7221
6432
|
}
|
|
7222
|
-
return /* @__PURE__ */
|
|
6433
|
+
return /* @__PURE__ */ jsx15("div", { className: "flex flex-col gap-2", children });
|
|
7223
6434
|
}
|
|
7224
6435
|
var QUIET_META_LANE_CLASS = "mt-1 flex h-[18px] items-center gap-2 text-xs tabular-nums text-muted-foreground opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 motion-reduce:transition-none [@media(hover:none)]:opacity-100";
|
|
7225
6436
|
function copyTextOf(msg) {
|
|
@@ -7228,9 +6439,9 @@ function copyTextOf(msg) {
|
|
|
7228
6439
|
return msg.content;
|
|
7229
6440
|
}
|
|
7230
6441
|
function CopyMessageButton({ text }) {
|
|
7231
|
-
const [copied, setCopied] =
|
|
7232
|
-
const timerRef =
|
|
7233
|
-
|
|
6442
|
+
const [copied, setCopied] = useState17(false);
|
|
6443
|
+
const timerRef = useRef13(null);
|
|
6444
|
+
useEffect13(
|
|
7234
6445
|
() => () => {
|
|
7235
6446
|
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
7236
6447
|
},
|
|
@@ -7249,7 +6460,7 @@ function CopyMessageButton({ text }) {
|
|
|
7249
6460
|
}
|
|
7250
6461
|
);
|
|
7251
6462
|
};
|
|
7252
|
-
return /* @__PURE__ */
|
|
6463
|
+
return /* @__PURE__ */ jsx15(
|
|
7253
6464
|
"button",
|
|
7254
6465
|
{
|
|
7255
6466
|
type: "button",
|
|
@@ -7257,9 +6468,9 @@ function CopyMessageButton({ text }) {
|
|
|
7257
6468
|
"aria-label": "Copy message",
|
|
7258
6469
|
title: "Copy message",
|
|
7259
6470
|
className: "rounded p-0.5 text-muted-foreground transition hover:bg-accent hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
7260
|
-
children: copied ? /* @__PURE__ */
|
|
7261
|
-
/* @__PURE__ */
|
|
7262
|
-
/* @__PURE__ */
|
|
6471
|
+
children: copied ? /* @__PURE__ */ jsx15("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx15("polyline", { points: "20 6 9 17 4 12" }) }) : /* @__PURE__ */ jsxs13("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
6472
|
+
/* @__PURE__ */ jsx15("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
|
|
6473
|
+
/* @__PURE__ */ jsx15("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
7263
6474
|
] })
|
|
7264
6475
|
}
|
|
7265
6476
|
);
|
|
@@ -7282,34 +6493,34 @@ function AssistantMessageImpl({
|
|
|
7282
6493
|
}) {
|
|
7283
6494
|
const content = useSmoothText(msg.content, streaming);
|
|
7284
6495
|
const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
|
|
7285
|
-
const body =
|
|
6496
|
+
const body = useMemo8(() => renderBody(content), [renderBody, content]);
|
|
7286
6497
|
const segments = msg.segments;
|
|
7287
6498
|
const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
|
|
7288
|
-
const reasoningScrollRef =
|
|
7289
|
-
const thinkStartRef =
|
|
7290
|
-
const thinkMsRef =
|
|
6499
|
+
const reasoningScrollRef = useRef13(null);
|
|
6500
|
+
const thinkStartRef = useRef13(null);
|
|
6501
|
+
const thinkMsRef = useRef13(null);
|
|
7291
6502
|
if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
|
|
7292
6503
|
thinkStartRef.current = performance.now();
|
|
7293
6504
|
}
|
|
7294
6505
|
if (hasAnswerText && thinkStartRef.current !== null && thinkMsRef.current === null) {
|
|
7295
6506
|
thinkMsRef.current = performance.now() - thinkStartRef.current;
|
|
7296
6507
|
}
|
|
7297
|
-
|
|
6508
|
+
useEffect13(() => {
|
|
7298
6509
|
const el = reasoningScrollRef.current;
|
|
7299
6510
|
if (el && streaming && !hasAnswerText) el.scrollTop = el.scrollHeight;
|
|
7300
6511
|
}, [reasoning, streaming, hasAnswerText]);
|
|
7301
6512
|
const thinkingSeconds = useThinkingSeconds(
|
|
7302
6513
|
streaming && !!reasoning && !hasAnswerText
|
|
7303
6514
|
);
|
|
7304
|
-
const [reasoningToggled, setReasoningToggled] =
|
|
6515
|
+
const [reasoningToggled, setReasoningToggled] = useState17(null);
|
|
7305
6516
|
const reasoningOpen = reasoningToggled ?? !hasAnswerText;
|
|
7306
6517
|
const quiet = chrome === "quiet";
|
|
7307
|
-
return /* @__PURE__ */
|
|
7308
|
-
!quiet && /* @__PURE__ */
|
|
7309
|
-
/* @__PURE__ */
|
|
7310
|
-
msg.modelUsed && /* @__PURE__ */
|
|
7311
|
-
formatTokensPerSecond(msg) && /* @__PURE__ */
|
|
7312
|
-
formatModelCost(msg, models) && /* @__PURE__ */
|
|
6518
|
+
return /* @__PURE__ */ jsxs13("div", { className: `mx-auto w-full max-w-3xl px-6 ${quiet ? "group pb-1 pt-3" : "py-3"}`, children: [
|
|
6519
|
+
!quiet && /* @__PURE__ */ jsxs13("div", { className: "mb-1 flex items-baseline gap-2 text-xs tabular-nums text-muted-foreground", children: [
|
|
6520
|
+
/* @__PURE__ */ jsx15("span", { className: "font-semibold uppercase tracking-[0.05em]", children: agentLabel }),
|
|
6521
|
+
msg.modelUsed && /* @__PURE__ */ jsx15("span", { className: "font-mono normal-case", children: msg.modelUsed }),
|
|
6522
|
+
formatTokensPerSecond(msg) && /* @__PURE__ */ jsx15("span", { children: formatTokensPerSecond(msg) }),
|
|
6523
|
+
formatModelCost(msg, models) && /* @__PURE__ */ jsx15("span", { children: formatModelCost(msg, models) })
|
|
7313
6524
|
] }),
|
|
7314
6525
|
reasoning && // The canonical run-row grammar (RunRowShell — the same shell the tool
|
|
7315
6526
|
// rows compose): one family of rows instead of a bespoke disclosure per
|
|
@@ -7319,12 +6530,12 @@ function AssistantMessageImpl({
|
|
|
7319
6530
|
// and a click outranks the default from then on — the contract the old
|
|
7320
6531
|
// hand-rolled disclosure had, now enforced through the shell's
|
|
7321
6532
|
// controlled `open`.
|
|
7322
|
-
/* @__PURE__ */
|
|
6533
|
+
/* @__PURE__ */ jsx15(
|
|
7323
6534
|
RunRowShell,
|
|
7324
6535
|
{
|
|
7325
6536
|
className: "mb-2",
|
|
7326
|
-
icon: /* @__PURE__ */
|
|
7327
|
-
title: !hasAnswerText ? /* @__PURE__ */
|
|
6537
|
+
icon: /* @__PURE__ */ jsx15(BrainGlyph, { className: "h-3.5 w-3.5" }),
|
|
6538
|
+
title: !hasAnswerText ? /* @__PURE__ */ jsxs13("span", { className: "agent-shimmer", "data-motion": "essential", children: [
|
|
7328
6539
|
"Thinking",
|
|
7329
6540
|
thinkingSeconds >= 1 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
|
|
7330
6541
|
] }) : thinkMsRef.current != null ? (
|
|
@@ -7339,7 +6550,7 @@ function AssistantMessageImpl({
|
|
|
7339
6550
|
status: hasAnswerText ? "idle" : "running",
|
|
7340
6551
|
open: reasoningOpen,
|
|
7341
6552
|
onOpenChange: (next) => setReasoningToggled(next),
|
|
7342
|
-
children: /* @__PURE__ */
|
|
6553
|
+
children: /* @__PURE__ */ jsx15(
|
|
7343
6554
|
"div",
|
|
7344
6555
|
{
|
|
7345
6556
|
ref: reasoningScrollRef,
|
|
@@ -7349,7 +6560,7 @@ function AssistantMessageImpl({
|
|
|
7349
6560
|
)
|
|
7350
6561
|
}
|
|
7351
6562
|
),
|
|
7352
|
-
segments && segments.length > 0 ? /* @__PURE__ */
|
|
6563
|
+
segments && segments.length > 0 ? /* @__PURE__ */ jsx15(
|
|
7353
6564
|
SegmentedBody,
|
|
7354
6565
|
{
|
|
7355
6566
|
segments,
|
|
@@ -7361,12 +6572,12 @@ function AssistantMessageImpl({
|
|
|
7361
6572
|
toolRenderers,
|
|
7362
6573
|
messageClassName
|
|
7363
6574
|
}
|
|
7364
|
-
) : /* @__PURE__ */
|
|
7365
|
-
/* @__PURE__ */
|
|
6575
|
+
) : /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
6576
|
+
/* @__PURE__ */ jsxs13("div", { className: messageClassName, children: [
|
|
7366
6577
|
body,
|
|
7367
|
-
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */
|
|
6578
|
+
streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx15(StreamingCaret, {})
|
|
7368
6579
|
] }),
|
|
7369
|
-
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */
|
|
6580
|
+
msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc, index) => /* @__PURE__ */ jsx15(
|
|
7370
6581
|
ToolCallCard,
|
|
7371
6582
|
{
|
|
7372
6583
|
call: tc,
|
|
@@ -7379,7 +6590,7 @@ function AssistantMessageImpl({
|
|
|
7379
6590
|
tc.id
|
|
7380
6591
|
)) })
|
|
7381
6592
|
] }),
|
|
7382
|
-
durableCards && msg.parts && /* @__PURE__ */
|
|
6593
|
+
durableCards && msg.parts && /* @__PURE__ */ jsx15(
|
|
7383
6594
|
DurableChatCards,
|
|
7384
6595
|
{
|
|
7385
6596
|
...durableCards,
|
|
@@ -7388,7 +6599,7 @@ function AssistantMessageImpl({
|
|
|
7388
6599
|
className: "mt-3"
|
|
7389
6600
|
}
|
|
7390
6601
|
),
|
|
7391
|
-
workProductCards && workProductPartsFromMessageParts(msg.parts).map((part) => /* @__PURE__ */
|
|
6602
|
+
workProductCards && workProductPartsFromMessageParts(msg.parts).map((part) => /* @__PURE__ */ jsx15(
|
|
7392
6603
|
WorkProductCard,
|
|
7393
6604
|
{
|
|
7394
6605
|
part,
|
|
@@ -7398,7 +6609,7 @@ function AssistantMessageImpl({
|
|
|
7398
6609
|
`${part.ref.id}:${part.ref.version}`
|
|
7399
6610
|
)),
|
|
7400
6611
|
renderExtras?.(msg),
|
|
7401
|
-
resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */
|
|
6612
|
+
resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-2", children: /* @__PURE__ */ jsx15(
|
|
7402
6613
|
MessageAttachments,
|
|
7403
6614
|
{
|
|
7404
6615
|
parts: attachmentPartsFromMessageParts(msg.parts),
|
|
@@ -7406,18 +6617,18 @@ function AssistantMessageImpl({
|
|
|
7406
6617
|
justify: "start"
|
|
7407
6618
|
}
|
|
7408
6619
|
) }),
|
|
7409
|
-
quiet && /* @__PURE__ */
|
|
7410
|
-
/* @__PURE__ */
|
|
7411
|
-
msg.modelUsed && /* @__PURE__ */
|
|
7412
|
-
formatTokensPerSecond(msg) && /* @__PURE__ */
|
|
7413
|
-
formatModelCost(msg, models) && /* @__PURE__ */
|
|
6620
|
+
quiet && /* @__PURE__ */ jsxs13("div", { "data-testid": "message-meta-lane", className: QUIET_META_LANE_CLASS, children: [
|
|
6621
|
+
/* @__PURE__ */ jsx15(CopyMessageButton, { text: copyTextOf(msg) }),
|
|
6622
|
+
msg.modelUsed && /* @__PURE__ */ jsx15("span", { className: "font-mono", children: msg.modelUsed }),
|
|
6623
|
+
formatTokensPerSecond(msg) && /* @__PURE__ */ jsx15("span", { children: formatTokensPerSecond(msg) }),
|
|
6624
|
+
formatModelCost(msg, models) && /* @__PURE__ */ jsx15("span", { children: formatModelCost(msg, models) })
|
|
7414
6625
|
] })
|
|
7415
6626
|
] });
|
|
7416
6627
|
}
|
|
7417
6628
|
var AssistantMessage = memo(AssistantMessageImpl);
|
|
7418
6629
|
function useThinkingSeconds(active) {
|
|
7419
|
-
const [seconds, setSeconds] =
|
|
7420
|
-
|
|
6630
|
+
const [seconds, setSeconds] = useState17(0);
|
|
6631
|
+
useEffect13(() => {
|
|
7421
6632
|
if (!active) return;
|
|
7422
6633
|
setSeconds(0);
|
|
7423
6634
|
const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
|
|
@@ -7427,23 +6638,23 @@ function useThinkingSeconds(active) {
|
|
|
7427
6638
|
}
|
|
7428
6639
|
function ThinkingRow({ agentLabel, chrome = "labeled" }) {
|
|
7429
6640
|
const seconds = useThinkingSeconds(true);
|
|
7430
|
-
return /* @__PURE__ */
|
|
7431
|
-
chrome !== "quiet" && /* @__PURE__ */
|
|
7432
|
-
/* @__PURE__ */
|
|
7433
|
-
/* @__PURE__ */
|
|
6641
|
+
return /* @__PURE__ */ jsxs13("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
|
|
6642
|
+
chrome !== "quiet" && /* @__PURE__ */ jsx15("p", { className: "mb-1 text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: agentLabel }),
|
|
6643
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 text-[15px] text-muted-foreground", children: [
|
|
6644
|
+
/* @__PURE__ */ jsx15("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx15("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
|
|
7434
6645
|
"Thinking",
|
|
7435
6646
|
seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
|
|
7436
6647
|
] })
|
|
7437
6648
|
] });
|
|
7438
6649
|
}
|
|
7439
6650
|
function StreamErrorRow({ message, onRetry }) {
|
|
7440
|
-
return /* @__PURE__ */
|
|
7441
|
-
/* @__PURE__ */
|
|
7442
|
-
/* @__PURE__ */
|
|
7443
|
-
/* @__PURE__ */
|
|
6651
|
+
return /* @__PURE__ */ jsx15("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs13("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
|
|
6652
|
+
/* @__PURE__ */ jsxs13("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
|
|
6653
|
+
/* @__PURE__ */ jsx15("circle", { cx: "12", cy: "12", r: "9" }),
|
|
6654
|
+
/* @__PURE__ */ jsx15("path", { d: "M12 8v4m0 4h.01" })
|
|
7444
6655
|
] }),
|
|
7445
|
-
/* @__PURE__ */
|
|
7446
|
-
onRetry && /* @__PURE__ */
|
|
6656
|
+
/* @__PURE__ */ jsx15("span", { className: "min-w-0 flex-1 break-words", children: message }),
|
|
6657
|
+
onRetry && /* @__PURE__ */ jsx15(
|
|
7447
6658
|
"button",
|
|
7448
6659
|
{
|
|
7449
6660
|
type: "button",
|
|
@@ -7477,33 +6688,33 @@ function ChatMessages({
|
|
|
7477
6688
|
workProductCards
|
|
7478
6689
|
}) {
|
|
7479
6690
|
const messageClassName = messageSize === "large" ? "agent-app-message-copy text-[17px] leading-[1.6]" : "agent-app-message-copy text-base leading-[1.6]";
|
|
7480
|
-
const renderBody =
|
|
7481
|
-
() => renderMarkdown ?? ((content) => /* @__PURE__ */
|
|
6691
|
+
const renderBody = useMemo8(
|
|
6692
|
+
() => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx15("p", { className: "whitespace-pre-wrap", children: content })),
|
|
7482
6693
|
[renderMarkdown]
|
|
7483
6694
|
);
|
|
7484
6695
|
const lastIsUser = messages[messages.length - 1]?.role === "user";
|
|
7485
6696
|
const quiet = chrome === "quiet";
|
|
7486
6697
|
if (messages.length === 0 && !loading && !error) {
|
|
7487
|
-
const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */
|
|
7488
|
-
return /* @__PURE__ */
|
|
6698
|
+
const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx15(ChatEmptyState, { ...emptyState });
|
|
6699
|
+
return /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
7489
6700
|
header,
|
|
7490
6701
|
empty
|
|
7491
6702
|
] });
|
|
7492
6703
|
}
|
|
7493
|
-
return /* @__PURE__ */
|
|
6704
|
+
return /* @__PURE__ */ jsxs13(Fragment8, { children: [
|
|
7494
6705
|
header,
|
|
7495
6706
|
messages.map(
|
|
7496
|
-
(msg) => msg.role === "user" ? /* @__PURE__ */
|
|
7497
|
-
/* @__PURE__ */
|
|
7498
|
-
!quiet && /* @__PURE__ */
|
|
7499
|
-
/* @__PURE__ */
|
|
6707
|
+
(msg) => msg.role === "user" ? /* @__PURE__ */ jsxs13("div", { className: `mx-auto w-full max-w-3xl px-6 ${quiet ? "group pb-1 pt-3" : "py-3"}`, children: [
|
|
6708
|
+
/* @__PURE__ */ jsxs13("div", { className: `ml-auto w-fit ${quiet ? "max-w-[72%]" : "max-w-[85%]"}`, children: [
|
|
6709
|
+
!quiet && /* @__PURE__ */ jsx15("p", { className: "mb-1 text-right text-xs font-semibold uppercase tracking-[0.05em] text-muted-foreground", children: userLabel }),
|
|
6710
|
+
/* @__PURE__ */ jsx15(
|
|
7500
6711
|
"div",
|
|
7501
6712
|
{
|
|
7502
6713
|
className: quiet ? `rounded-2xl bg-[color-mix(in_srgb,hsl(var(--secondary))_65%,hsl(var(--background)))] px-4 py-2.5 ${messageClassName}` : `rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 ${messageClassName}`,
|
|
7503
|
-
children: /* @__PURE__ */
|
|
6714
|
+
children: /* @__PURE__ */ jsx15("p", { className: "whitespace-pre-wrap", children: msg.content })
|
|
7504
6715
|
}
|
|
7505
6716
|
),
|
|
7506
|
-
resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */
|
|
6717
|
+
resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx15(
|
|
7507
6718
|
MessageAttachments,
|
|
7508
6719
|
{
|
|
7509
6720
|
parts: attachmentPartsFromMessageParts(msg.parts),
|
|
@@ -7512,8 +6723,8 @@ function ChatMessages({
|
|
|
7512
6723
|
}
|
|
7513
6724
|
) })
|
|
7514
6725
|
] }),
|
|
7515
|
-
quiet && /* @__PURE__ */
|
|
7516
|
-
] }, msg.id) : /* @__PURE__ */
|
|
6726
|
+
quiet && /* @__PURE__ */ jsx15("div", { "data-testid": "message-meta-lane", className: `${QUIET_META_LANE_CLASS} justify-end`, children: /* @__PURE__ */ jsx15(CopyMessageButton, { text: msg.content }) })
|
|
6727
|
+
] }, msg.id) : /* @__PURE__ */ jsx15(
|
|
7517
6728
|
AssistantMessage,
|
|
7518
6729
|
{
|
|
7519
6730
|
msg,
|
|
@@ -7534,8 +6745,8 @@ function ChatMessages({
|
|
|
7534
6745
|
msg.id
|
|
7535
6746
|
)
|
|
7536
6747
|
),
|
|
7537
|
-
loading && lastIsUser && /* @__PURE__ */
|
|
7538
|
-
error && !loading && /* @__PURE__ */
|
|
6748
|
+
loading && lastIsUser && /* @__PURE__ */ jsx15(ThinkingRow, { agentLabel, chrome }),
|
|
6749
|
+
error && !loading && /* @__PURE__ */ jsx15(StreamErrorRow, { message: error, onRetry })
|
|
7539
6750
|
] });
|
|
7540
6751
|
}
|
|
7541
6752
|
|
|
@@ -7620,11 +6831,6 @@ export {
|
|
|
7620
6831
|
ProvenanceValue,
|
|
7621
6832
|
ProvenanceLegend,
|
|
7622
6833
|
SeatPaywall,
|
|
7623
|
-
useInfiniteScroll,
|
|
7624
|
-
useSessionHistory,
|
|
7625
|
-
useSessionActions,
|
|
7626
|
-
formatSessionTimestamp,
|
|
7627
|
-
SessionHistoryPanel,
|
|
7628
6834
|
recordGridOk,
|
|
7629
6835
|
recordGridFail,
|
|
7630
6836
|
isRecordGridCellApplicable,
|
|
@@ -7679,4 +6885,4 @@ export {
|
|
|
7679
6885
|
useThinkingSeconds,
|
|
7680
6886
|
ChatMessages
|
|
7681
6887
|
};
|
|
7682
|
-
//# sourceMappingURL=chunk-
|
|
6888
|
+
//# sourceMappingURL=chunk-RZ6MYWMJ.js.map
|