@tangle-network/agent-app 0.44.40 → 0.44.42

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.
@@ -1,6 +1,11 @@
1
1
  import {
2
2
  stepActivityFlowTrace
3
3
  } from "./chunk-FBVLEGEG.js";
4
+ import {
5
+ UNTITLED_SESSION_LABEL,
6
+ mergeSessionPages,
7
+ sessionLabel
8
+ } from "./chunk-3E4MW5LR.js";
4
9
  import {
5
10
  WorkProductCard,
6
11
  workProductPartsFromMessageParts
@@ -31,7 +36,7 @@ import {
31
36
  } from "./chunk-CQZSAR77.js";
32
37
 
33
38
  // src/web-react/index.tsx
34
- import { useEffect as useEffect9, useMemo as useMemo7, useRef as useRef8, useState as useState13, memo } from "react";
39
+ import { useEffect as useEffect10, useMemo as useMemo8, useRef as useRef9, useState as useState14, memo } from "react";
35
40
 
36
41
  // src/web-react/smooth-text.ts
37
42
  import { useEffect, useRef, useState } from "react";
@@ -2786,9 +2791,563 @@ function SeatPaywall({
2786
2791
  ] }) });
2787
2792
  }
2788
2793
 
2794
+ // src/web-react/session-history.tsx
2795
+ import {
2796
+ useCallback as useCallback7,
2797
+ useEffect as useEffect9,
2798
+ useMemo as useMemo6,
2799
+ useRef as useRef8,
2800
+ useState as useState12
2801
+ } from "react";
2802
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
2803
+ function rethrowAsync(error) {
2804
+ queueMicrotask(() => {
2805
+ throw error;
2806
+ });
2807
+ }
2808
+ function useInfiniteScroll(onLoadMore, { enabled, root, rootMargin = "300px" }) {
2809
+ const [sentinel, setSentinel] = useState12(null);
2810
+ const sentinelRef = useCallback7((node) => setSentinel(node), []);
2811
+ const onLoadMoreRef = useRef8(onLoadMore);
2812
+ useEffect9(() => {
2813
+ onLoadMoreRef.current = onLoadMore;
2814
+ }, [onLoadMore]);
2815
+ useEffect9(() => {
2816
+ if (!sentinel || !enabled) return;
2817
+ if (typeof IntersectionObserver === "undefined") return;
2818
+ const observer = new IntersectionObserver(
2819
+ (entries) => {
2820
+ if (!entries.some((entry) => entry.isIntersecting)) return;
2821
+ try {
2822
+ onLoadMoreRef.current();
2823
+ } catch (error) {
2824
+ rethrowAsync(error);
2825
+ }
2826
+ },
2827
+ { root: root?.current ?? null, rootMargin }
2828
+ );
2829
+ observer.observe(sentinel);
2830
+ return () => observer.disconnect();
2831
+ }, [sentinel, enabled, root, rootMargin]);
2832
+ return sentinelRef;
2833
+ }
2834
+ function seedSignature(page) {
2835
+ return `${page.nextCursor ?? ""}|${page.items.map((item) => item.id).join(",")}`;
2836
+ }
2837
+ function useSessionHistory({
2838
+ fetchPage,
2839
+ q,
2840
+ sort,
2841
+ initialPage,
2842
+ defaultSort = "newest"
2843
+ }) {
2844
+ const [items, setItems] = useState12(initialPage.items);
2845
+ const [nextCursor, setNextCursor] = useState12(initialPage.nextCursor ?? null);
2846
+ const [phase, setPhase] = useState12("idle");
2847
+ const [reloadKey, setReloadKey] = useState12(0);
2848
+ const seqRef = useRef8(0);
2849
+ const resetAbortRef = useRef8(null);
2850
+ const loadMoreAbortRef = useRef8(null);
2851
+ const loadingMoreRef = useRef8(false);
2852
+ const lastOpRef = useRef8("first");
2853
+ const nextCursorRef = useRef8(nextCursor);
2854
+ nextCursorRef.current = nextCursor;
2855
+ const viewRef = useRef8({ q, sort, fetchPage });
2856
+ viewRef.current = { q, sort, fetchPage };
2857
+ const seedRef = useRef8(initialPage);
2858
+ seedRef.current = initialPage;
2859
+ const isDefaultView = q === "" && sort === defaultSort;
2860
+ const seedKey = useMemo6(() => seedSignature(initialPage), [initialPage]);
2861
+ useEffect9(() => {
2862
+ resetAbortRef.current?.abort();
2863
+ loadMoreAbortRef.current?.abort();
2864
+ loadingMoreRef.current = false;
2865
+ const seq = ++seqRef.current;
2866
+ if (isDefaultView && reloadKey === 0) {
2867
+ setItems(seedRef.current.items);
2868
+ setNextCursor(seedRef.current.nextCursor ?? null);
2869
+ setPhase("idle");
2870
+ return;
2871
+ }
2872
+ const controller = new AbortController();
2873
+ resetAbortRef.current = controller;
2874
+ lastOpRef.current = "first";
2875
+ setItems([]);
2876
+ setNextCursor(null);
2877
+ setPhase("loadingFirst");
2878
+ void (async () => {
2879
+ try {
2880
+ const page = await viewRef.current.fetchPage({ q, sort, cursor: null, signal: controller.signal });
2881
+ if (seq !== seqRef.current) return;
2882
+ setItems(page.items);
2883
+ setNextCursor(page.nextCursor ?? null);
2884
+ setPhase("idle");
2885
+ } catch {
2886
+ if (controller.signal.aborted || seq !== seqRef.current) return;
2887
+ setPhase("error");
2888
+ }
2889
+ })();
2890
+ return () => controller.abort();
2891
+ }, [q, sort, seedKey, isDefaultView, reloadKey]);
2892
+ const loadMore = useCallback7(() => {
2893
+ const cursor = nextCursorRef.current;
2894
+ if (!cursor || loadingMoreRef.current) return;
2895
+ const { q: currentQ, sort: currentSort, fetchPage: currentFetch } = viewRef.current;
2896
+ const seq = seqRef.current;
2897
+ loadingMoreRef.current = true;
2898
+ lastOpRef.current = "more";
2899
+ const controller = new AbortController();
2900
+ loadMoreAbortRef.current = controller;
2901
+ setPhase("loadingMore");
2902
+ void (async () => {
2903
+ try {
2904
+ const page = await currentFetch({ q: currentQ, sort: currentSort, cursor, signal: controller.signal });
2905
+ if (seq !== seqRef.current) return;
2906
+ setItems((prev) => mergeSessionPages(prev, page.items));
2907
+ setNextCursor(page.nextCursor ?? null);
2908
+ setPhase("idle");
2909
+ } catch {
2910
+ if (controller.signal.aborted || seq !== seqRef.current) return;
2911
+ setPhase("error");
2912
+ } finally {
2913
+ if (seq === seqRef.current) loadingMoreRef.current = false;
2914
+ }
2915
+ })();
2916
+ }, []);
2917
+ const retry = useCallback7(() => {
2918
+ if (lastOpRef.current === "more") loadMore();
2919
+ else setReloadKey((key) => key + 1);
2920
+ }, [loadMore]);
2921
+ const reload = useCallback7(() => {
2922
+ setReloadKey((key) => key + 1);
2923
+ }, []);
2924
+ useEffect9(
2925
+ () => () => {
2926
+ resetAbortRef.current?.abort();
2927
+ loadMoreAbortRef.current?.abort();
2928
+ },
2929
+ []
2930
+ );
2931
+ return {
2932
+ items,
2933
+ hasMore: nextCursor !== null,
2934
+ isLoadingFirst: phase === "loadingFirst",
2935
+ isLoadingMore: phase === "loadingMore",
2936
+ isError: phase === "error",
2937
+ loadMore,
2938
+ retry,
2939
+ reload
2940
+ };
2941
+ }
2942
+ var DEFAULT_LABELS = {
2943
+ renameTitle: "Rename session",
2944
+ renameField: "Title",
2945
+ renameSubmit: "Save",
2946
+ deleteTitle: "Delete session?",
2947
+ deleteBody: (title) => `This will permanently delete \u201C${title}\u201D and its messages. This cannot be undone.`,
2948
+ deleteSubmit: "Delete",
2949
+ cancel: "Cancel",
2950
+ renamed: "Session renamed",
2951
+ deleted: "Session deleted",
2952
+ renameFailed: "Failed to rename session",
2953
+ deleteFailed: "Failed to delete session"
2954
+ };
2955
+ function useSessionActions({
2956
+ renameSession,
2957
+ deleteSession,
2958
+ onChanged,
2959
+ onDeletedCurrent,
2960
+ currentSessionId,
2961
+ notify,
2962
+ labels
2963
+ }) {
2964
+ const text = { ...DEFAULT_LABELS, ...labels };
2965
+ const [renameTarget, setRenameTarget] = useState12(null);
2966
+ const [renameValue, setRenameValue] = useState12("");
2967
+ const [deleteTarget, setDeleteTarget] = useState12(null);
2968
+ const [busy, setBusy] = useState12(false);
2969
+ const [error, setError] = useState12(null);
2970
+ const openRename = useCallback7((session) => {
2971
+ setError(null);
2972
+ setRenameTarget(session);
2973
+ setRenameValue(session.title ?? "");
2974
+ }, []);
2975
+ const openDelete = useCallback7((session) => {
2976
+ setError(null);
2977
+ setDeleteTarget(session);
2978
+ }, []);
2979
+ const submitRename = useCallback7(async () => {
2980
+ if (!renameTarget) return;
2981
+ const title = renameValue.trim();
2982
+ if (!title || title === renameTarget.title) {
2983
+ setRenameTarget(null);
2984
+ return;
2985
+ }
2986
+ setBusy(true);
2987
+ setError(null);
2988
+ try {
2989
+ await renameSession(renameTarget.id, title);
2990
+ setRenameTarget(null);
2991
+ notify?.("success", text.renamed);
2992
+ onChanged?.();
2993
+ } catch (e) {
2994
+ const message = e instanceof Error ? e.message : text.renameFailed;
2995
+ setError(message);
2996
+ notify?.("error", message);
2997
+ } finally {
2998
+ setBusy(false);
2999
+ }
3000
+ }, [renameTarget, renameValue, renameSession, notify, onChanged, text.renamed, text.renameFailed]);
3001
+ const confirmDelete = useCallback7(async () => {
3002
+ if (!deleteTarget) return;
3003
+ const deletingCurrent = currentSessionId != null && deleteTarget.id === currentSessionId;
3004
+ setBusy(true);
3005
+ setError(null);
3006
+ try {
3007
+ await deleteSession(deleteTarget.id);
3008
+ setDeleteTarget(null);
3009
+ notify?.("success", text.deleted);
3010
+ onChanged?.();
3011
+ if (deletingCurrent) onDeletedCurrent?.();
3012
+ } catch (e) {
3013
+ const message = e instanceof Error ? e.message : text.deleteFailed;
3014
+ setError(message);
3015
+ notify?.("error", message);
3016
+ } finally {
3017
+ setBusy(false);
3018
+ }
3019
+ }, [deleteTarget, currentSessionId, deleteSession, notify, onChanged, onDeletedCurrent, text.deleted, text.deleteFailed]);
3020
+ const dialogs = /* @__PURE__ */ jsxs10(Fragment6, { children: [
3021
+ renameTarget && /* @__PURE__ */ jsxs10(
3022
+ SessionDialog,
3023
+ {
3024
+ title: text.renameTitle,
3025
+ onClose: () => setRenameTarget(null),
3026
+ busy,
3027
+ error,
3028
+ footer: /* @__PURE__ */ jsxs10(Fragment6, { children: [
3029
+ /* @__PURE__ */ jsx12(DialogButton, { onClick: () => setRenameTarget(null), disabled: busy, variant: "ghost", children: text.cancel }),
3030
+ /* @__PURE__ */ jsx12(DialogButton, { onClick: () => void submitRename(), disabled: busy || !renameValue.trim(), children: text.renameSubmit })
3031
+ ] }),
3032
+ children: [
3033
+ /* @__PURE__ */ jsx12("label", { htmlFor: "agent-app-rename-session", className: "text-xs text-muted-foreground", children: text.renameField }),
3034
+ /* @__PURE__ */ jsx12(
3035
+ "input",
3036
+ {
3037
+ id: "agent-app-rename-session",
3038
+ value: renameValue,
3039
+ autoFocus: true,
3040
+ onChange: (e) => setRenameValue(e.target.value),
3041
+ onKeyDown: (e) => {
3042
+ if (e.key === "Enter" && !busy) {
3043
+ e.preventDefault();
3044
+ void submitRename();
3045
+ }
3046
+ },
3047
+ className: "mt-1.5 h-9 w-full rounded-md border border-border bg-background px-3 text-sm text-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring"
3048
+ }
3049
+ )
3050
+ ]
3051
+ }
3052
+ ),
3053
+ deleteTarget && /* @__PURE__ */ jsx12(
3054
+ SessionDialog,
3055
+ {
3056
+ title: text.deleteTitle,
3057
+ onClose: () => setDeleteTarget(null),
3058
+ busy,
3059
+ error,
3060
+ footer: /* @__PURE__ */ jsxs10(Fragment6, { children: [
3061
+ /* @__PURE__ */ jsx12(DialogButton, { onClick: () => setDeleteTarget(null), disabled: busy, variant: "ghost", children: text.cancel }),
3062
+ /* @__PURE__ */ jsx12(DialogButton, { onClick: () => void confirmDelete(), disabled: busy, variant: "destructive", children: text.deleteSubmit })
3063
+ ] }),
3064
+ children: /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground", children: text.deleteBody(sessionLabel(deleteTarget)) })
3065
+ }
3066
+ )
3067
+ ] });
3068
+ return { openRename, openDelete, dialogs, busy };
3069
+ }
3070
+ function DialogButton({
3071
+ children,
3072
+ onClick,
3073
+ disabled,
3074
+ variant = "primary"
3075
+ }) {
3076
+ const tone = variant === "ghost" ? "text-muted-foreground hover:bg-accent/30 hover:text-foreground" : variant === "destructive" ? "bg-destructive text-destructive-foreground hover:opacity-90" : "bg-primary text-primary-foreground hover:opacity-90";
3077
+ return /* @__PURE__ */ jsx12(
3078
+ "button",
3079
+ {
3080
+ type: "button",
3081
+ onClick,
3082
+ disabled,
3083
+ className: `h-9 rounded-md px-3 text-sm font-medium transition disabled:opacity-50 ${tone}`,
3084
+ children
3085
+ }
3086
+ );
3087
+ }
3088
+ function SessionDialog({
3089
+ title,
3090
+ children,
3091
+ footer,
3092
+ onClose,
3093
+ busy,
3094
+ error
3095
+ }) {
3096
+ useEffect9(() => {
3097
+ const onKey = (e) => {
3098
+ if (e.key === "Escape" && !busy) onClose();
3099
+ };
3100
+ document.addEventListener("keydown", onKey);
3101
+ return () => document.removeEventListener("keydown", onKey);
3102
+ }, [busy, onClose]);
3103
+ return /* @__PURE__ */ jsxs10("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
3104
+ /* @__PURE__ */ jsx12(
3105
+ "div",
3106
+ {
3107
+ className: "absolute inset-0 bg-black/50",
3108
+ onClick: () => {
3109
+ if (!busy) onClose();
3110
+ },
3111
+ "aria-hidden": true
3112
+ }
3113
+ ),
3114
+ /* @__PURE__ */ jsxs10(
3115
+ "div",
3116
+ {
3117
+ role: "dialog",
3118
+ "aria-modal": "true",
3119
+ "aria-label": title,
3120
+ className: "relative w-full max-w-sm rounded-xl border border-border bg-card p-5 shadow-lg",
3121
+ children: [
3122
+ /* @__PURE__ */ jsx12("h2", { className: "text-sm font-semibold text-foreground", children: title }),
3123
+ /* @__PURE__ */ jsx12("div", { className: "mt-3", children }),
3124
+ error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "mt-3 rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive", children: error }),
3125
+ /* @__PURE__ */ jsx12("div", { className: "mt-5 flex justify-end gap-2", children: footer })
3126
+ ]
3127
+ }
3128
+ )
3129
+ ] });
3130
+ }
3131
+ function AnchorLink({ to, className, children }) {
3132
+ return /* @__PURE__ */ jsx12("a", { href: to, className, children });
3133
+ }
3134
+ var MINUTE = 6e4;
3135
+ var HOUR = 60 * MINUTE;
3136
+ var DAY = 24 * HOUR;
3137
+ function formatSessionTimestamp(isoDate) {
3138
+ if (!isoDate) return "";
3139
+ const at = Date.parse(isoDate);
3140
+ if (Number.isNaN(at)) return "";
3141
+ const delta = Date.now() - at;
3142
+ if (delta < MINUTE) return "just now";
3143
+ if (delta < HOUR) return `${Math.floor(delta / MINUTE)}m ago`;
3144
+ if (delta < DAY) return `${Math.floor(delta / HOUR)}h ago`;
3145
+ if (delta < 7 * DAY) return `${Math.floor(delta / DAY)}d ago`;
3146
+ return new Date(at).toLocaleDateString(void 0, { month: "short", day: "numeric" });
3147
+ }
3148
+ function SkeletonRows() {
3149
+ return /* @__PURE__ */ jsx12("div", { className: "flex flex-col gap-0.5", "aria-hidden": true, children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3 px-3 py-2.5", children: [
3150
+ /* @__PURE__ */ jsx12("div", { className: "h-4 w-4 animate-pulse rounded bg-muted" }),
3151
+ /* @__PURE__ */ jsx12("div", { className: "h-4 w-1/2 animate-pulse rounded bg-muted" }),
3152
+ /* @__PURE__ */ jsx12("div", { className: "ml-auto h-3 w-12 animate-pulse rounded bg-muted" })
3153
+ ] }, i)) });
3154
+ }
3155
+ function MessageIcon({ className }) {
3156
+ return /* @__PURE__ */ jsx12("svg", { viewBox: "0 0 24 24", className, fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx12("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
3157
+ }
3158
+ function SessionHistoryPanel({
3159
+ history,
3160
+ hasAnySessions,
3161
+ query,
3162
+ onQueryChange,
3163
+ sort,
3164
+ onSortChange,
3165
+ hrefForSession,
3166
+ linkComponent: Link = AnchorLink,
3167
+ respondingSessionIds,
3168
+ onRename,
3169
+ onDelete,
3170
+ newSessionHref,
3171
+ title = "History",
3172
+ untitledLabel = UNTITLED_SESSION_LABEL,
3173
+ emptyTitle = "No sessions yet",
3174
+ emptyDescription = "Your chat sessions will show up here once you start one.",
3175
+ formatTimestamp = formatSessionTimestamp,
3176
+ contentWidth = "reading",
3177
+ className
3178
+ }) {
3179
+ const scrollRef = useRef8(null);
3180
+ const sentinelRef = useInfiniteScroll(history.loadMore, {
3181
+ enabled: history.hasMore && !history.isLoadingMore && !history.isError,
3182
+ root: scrollRef,
3183
+ rootMargin: "300px"
3184
+ });
3185
+ const searchTerm = query.trim();
3186
+ const isSearching = searchTerm.length > 0;
3187
+ const column = contentWidth === "full" ? "w-full" : "mx-auto w-full max-w-3xl";
3188
+ return /* @__PURE__ */ jsxs10("div", { className: `flex min-h-0 min-w-0 flex-1 flex-col ${className ?? ""}`, children: [
3189
+ /* @__PURE__ */ jsx12("header", { className: "flex h-14 shrink-0 items-center border-b border-border px-4 sm:px-6", children: /* @__PURE__ */ jsxs10("div", { className: `flex items-center gap-3 px-3 ${column}`, children: [
3190
+ /* @__PURE__ */ jsx12("h1", { className: "flex-1 truncate text-sm font-semibold text-foreground", children: title }),
3191
+ newSessionHref && /* @__PURE__ */ jsxs10(
3192
+ Link,
3193
+ {
3194
+ to: newSessionHref,
3195
+ 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",
3196
+ children: [
3197
+ /* @__PURE__ */ jsx12("span", { "aria-hidden": true, className: "text-sm leading-none", children: "+" }),
3198
+ "New chat"
3199
+ ]
3200
+ }
3201
+ )
3202
+ ] }) }),
3203
+ /* @__PURE__ */ jsxs10("div", { ref: scrollRef, className: "min-h-0 flex-1 overflow-y-auto", children: [
3204
+ hasAnySessions && /* @__PURE__ */ jsx12("div", { className: "sticky top-0 z-10 bg-background px-4 sm:px-6", children: /* @__PURE__ */ jsxs10("div", { className: `flex flex-col gap-2 px-3 pb-3 pt-4 sm:flex-row sm:items-center sm:gap-3 ${column}`, children: [
3205
+ /* @__PURE__ */ jsx12(
3206
+ "input",
3207
+ {
3208
+ type: "search",
3209
+ value: query,
3210
+ onChange: (e) => onQueryChange(e.target.value),
3211
+ placeholder: "Search your sessions\u2026",
3212
+ "aria-label": "Search sessions",
3213
+ className: "h-9 min-w-0 appearance-none rounded-md border border-border bg-card px-3 text-sm text-foreground outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring sm:flex-1 [&::-webkit-search-cancel-button]:appearance-none"
3214
+ }
3215
+ ),
3216
+ /* @__PURE__ */ jsxs10(
3217
+ "select",
3218
+ {
3219
+ value: sort,
3220
+ onChange: (e) => onSortChange(e.target.value),
3221
+ "aria-label": "Sort sessions",
3222
+ className: "h-9 shrink-0 appearance-none rounded-md border border-border bg-card px-2 text-sm text-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring sm:w-[132px]",
3223
+ children: [
3224
+ /* @__PURE__ */ jsx12("option", { value: "newest", children: "Newest" }),
3225
+ /* @__PURE__ */ jsx12("option", { value: "oldest", children: "Oldest" })
3226
+ ]
3227
+ }
3228
+ )
3229
+ ] }) }),
3230
+ /* @__PURE__ */ jsx12("div", { className: `px-4 pb-8 pt-1 sm:px-6 ${column}`, children: !hasAnySessions ? /* @__PURE__ */ jsxs10("div", { className: "flex min-h-[50vh] flex-col items-center justify-center gap-2 text-center", children: [
3231
+ /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-foreground", children: emptyTitle }),
3232
+ /* @__PURE__ */ jsx12("p", { className: "max-w-xs text-xs text-muted-foreground", children: emptyDescription })
3233
+ ] }) : history.isLoadingFirst ? /* @__PURE__ */ jsx12(SkeletonRows, {}) : history.items.length === 0 ? history.isError ? /* @__PURE__ */ jsx12(ErrorBlock, { onRetry: history.retry, message: "Couldn\u2019t load your sessions." }) : isSearching ? /* @__PURE__ */ jsxs10("p", { className: "py-16 text-center text-sm text-muted-foreground", children: [
3234
+ "No sessions match \u201C",
3235
+ searchTerm,
3236
+ "\u201D."
3237
+ ] }) : /* @__PURE__ */ jsx12(SkeletonRows, {}) : /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-0.5", children: [
3238
+ history.items.map((session) => /* @__PURE__ */ jsx12(
3239
+ SessionRow,
3240
+ {
3241
+ session,
3242
+ href: hrefForSession(session.id),
3243
+ Link,
3244
+ responding: respondingSessionIds?.has(session.id) ?? false,
3245
+ untitledLabel,
3246
+ timestamp: formatTimestamp(session.updatedAt),
3247
+ onRename,
3248
+ onDelete
3249
+ },
3250
+ session.id
3251
+ )),
3252
+ history.isError ? /* @__PURE__ */ jsx12(ErrorBlock, { onRetry: history.retry, message: "Couldn\u2019t load more sessions.", inline: true }) : history.hasMore ? /* @__PURE__ */ jsx12("div", { ref: sentinelRef, className: "flex items-center justify-center py-6", children: history.isLoadingMore && /* @__PURE__ */ jsx12("span", { className: "text-xs text-muted-foreground", children: "Loading\u2026" }) }) : null
3253
+ ] }) })
3254
+ ] })
3255
+ ] });
3256
+ }
3257
+ function ErrorBlock({ message, onRetry, inline }) {
3258
+ return /* @__PURE__ */ jsxs10(
3259
+ "div",
3260
+ {
3261
+ 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",
3262
+ children: [
3263
+ /* @__PURE__ */ jsx12("span", { className: "text-sm text-muted-foreground", children: message }),
3264
+ /* @__PURE__ */ jsx12(
3265
+ "button",
3266
+ {
3267
+ type: "button",
3268
+ onClick: onRetry,
3269
+ className: "h-8 rounded-md border border-border px-3 text-xs font-medium text-foreground transition hover:bg-accent/30",
3270
+ children: "Retry"
3271
+ }
3272
+ )
3273
+ ]
3274
+ }
3275
+ );
3276
+ }
3277
+ function SessionRow({
3278
+ session,
3279
+ href,
3280
+ Link,
3281
+ responding,
3282
+ untitledLabel,
3283
+ timestamp,
3284
+ onRename,
3285
+ onDelete
3286
+ }) {
3287
+ const [menuOpen, setMenuOpen] = useState12(false);
3288
+ const showUnread = Boolean(session.unread) && !responding;
3289
+ return /* @__PURE__ */ jsxs10("div", { className: "group relative flex items-center gap-2 rounded-lg px-3 py-2.5 transition-colors hover:bg-accent/20", children: [
3290
+ /* @__PURE__ */ jsxs10(Link, { to: href, className: "flex min-w-0 flex-1 items-center gap-3", children: [
3291
+ showUnread && /* @__PURE__ */ jsx12("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-primary", "aria-hidden": true }),
3292
+ /* @__PURE__ */ jsx12(MessageIcon, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3293
+ /* @__PURE__ */ jsx12(
3294
+ "span",
3295
+ {
3296
+ className: `truncate text-sm ${responding ? "text-muted-foreground" : "text-foreground"} ${showUnread ? "font-semibold" : ""}`,
3297
+ ...responding ? { role: "status", "aria-label": "Agent responding" } : {},
3298
+ children: sessionLabel(session, untitledLabel)
3299
+ }
3300
+ )
3301
+ ] }),
3302
+ /* @__PURE__ */ jsx12("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: timestamp }),
3303
+ (onRename || onDelete) && /* @__PURE__ */ jsxs10("div", { className: "relative shrink-0", children: [
3304
+ /* @__PURE__ */ jsx12(
3305
+ "button",
3306
+ {
3307
+ type: "button",
3308
+ "aria-label": "Session actions",
3309
+ "aria-expanded": menuOpen,
3310
+ onClick: () => setMenuOpen((open) => !open),
3311
+ 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",
3312
+ children: /* @__PURE__ */ jsx12("span", { "aria-hidden": true, className: "text-base leading-none", children: "\u22EF" })
3313
+ }
3314
+ ),
3315
+ menuOpen && /* @__PURE__ */ jsxs10(Fragment6, { children: [
3316
+ /* @__PURE__ */ jsx12("div", { className: "fixed inset-0 z-20", onClick: () => setMenuOpen(false), "aria-hidden": true }),
3317
+ /* @__PURE__ */ jsxs10("div", { className: "absolute right-0 z-30 mt-1 w-36 overflow-hidden rounded-md border border-border bg-card py-1 shadow-lg", children: [
3318
+ onRename && /* @__PURE__ */ jsx12(
3319
+ "button",
3320
+ {
3321
+ type: "button",
3322
+ onClick: () => {
3323
+ setMenuOpen(false);
3324
+ onRename(session);
3325
+ },
3326
+ className: "block w-full px-3 py-1.5 text-left text-xs text-foreground transition hover:bg-accent/30",
3327
+ children: "Rename"
3328
+ }
3329
+ ),
3330
+ onDelete && /* @__PURE__ */ jsx12(
3331
+ "button",
3332
+ {
3333
+ type: "button",
3334
+ onClick: () => {
3335
+ setMenuOpen(false);
3336
+ onDelete(session);
3337
+ },
3338
+ className: "block w-full px-3 py-1.5 text-left text-xs text-destructive transition hover:bg-destructive/10",
3339
+ children: "Delete"
3340
+ }
3341
+ )
3342
+ ] })
3343
+ ] })
3344
+ ] })
3345
+ ] });
3346
+ }
3347
+
2789
3348
  // src/web-react/agent-session-controls.tsx
2790
- import { useMemo as useMemo6, useState as useState12 } from "react";
2791
- import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3349
+ import { useMemo as useMemo7, useState as useState13 } from "react";
3350
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2792
3351
  var HARNESS_LABELS = {
2793
3352
  opencode: "OpenCode (any model)",
2794
3353
  "claude-code": "Claude Code (Anthropic)",
@@ -2808,12 +3367,12 @@ function harnessLabel(h) {
2808
3367
  return HARNESS_LABELS[h] ?? h;
2809
3368
  }
2810
3369
  function ChevronDown2({ className }) {
2811
- return /* @__PURE__ */ jsx12("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) });
3370
+ return /* @__PURE__ */ jsx13("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx13("path", { d: "m6 9 6 6 6-6" }) });
2812
3371
  }
2813
3372
  function GearGlyph({ className }) {
2814
- return /* @__PURE__ */ jsxs10("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
2815
- /* @__PURE__ */ jsx12("circle", { cx: "12", cy: "12", r: "3" }),
2816
- /* @__PURE__ */ jsx12("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
3373
+ return /* @__PURE__ */ jsxs11("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3374
+ /* @__PURE__ */ jsx13("circle", { cx: "12", cy: "12", r: "3" }),
3375
+ /* @__PURE__ */ jsx13("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
2817
3376
  ] });
2818
3377
  }
2819
3378
  var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
@@ -2822,11 +3381,11 @@ function HarnessPicker({
2822
3381
  onChange,
2823
3382
  available
2824
3383
  }) {
2825
- const [open, setOpen] = useState12(false);
3384
+ const [open, setOpen] = useState13(false);
2826
3385
  const { containerRef, triggerProps } = usePopover(open, setOpen);
2827
3386
  const options = available ?? Object.keys(HARNESS_LABELS);
2828
- return /* @__PURE__ */ jsxs10("div", { ref: containerRef, className: "relative inline-flex", children: [
2829
- /* @__PURE__ */ jsxs10(
3387
+ return /* @__PURE__ */ jsxs11("div", { ref: containerRef, className: "relative inline-flex", children: [
3388
+ /* @__PURE__ */ jsxs11(
2830
3389
  "button",
2831
3390
  {
2832
3391
  type: "button",
@@ -2835,12 +3394,12 @@ function HarnessPicker({
2835
3394
  title: "Agent backend",
2836
3395
  className: `inline-flex w-full items-center justify-between gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 ${FOCUS_RING}`,
2837
3396
  children: [
2838
- /* @__PURE__ */ jsx12("span", { className: "truncate", children: harnessLabel(value) }),
2839
- /* @__PURE__ */ jsx12(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
3397
+ /* @__PURE__ */ jsx13("span", { className: "truncate", children: harnessLabel(value) }),
3398
+ /* @__PURE__ */ jsx13(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
2840
3399
  ]
2841
3400
  }
2842
3401
  ),
2843
- open && /* @__PURE__ */ jsx12("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx12(
3402
+ open && /* @__PURE__ */ jsx13("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx13(
2844
3403
  "button",
2845
3404
  {
2846
3405
  type: "button",
@@ -2859,7 +3418,7 @@ function HarnessPicker({
2859
3418
  }
2860
3419
  function useCoherentHandlers(props) {
2861
3420
  const { model, models, harness, onModelChange, onHarnessChange } = props;
2862
- const canonicalIds = useMemo6(() => models.map((m) => m.id), [models]);
3421
+ const canonicalIds = useMemo7(() => models.map((m) => m.id), [models]);
2863
3422
  const onModel = (next) => {
2864
3423
  onModelChange(next);
2865
3424
  const nextHarness = snapHarnessToModel(harness, next);
@@ -2887,11 +3446,11 @@ function AgentSessionControls(props) {
2887
3446
  className
2888
3447
  } = props;
2889
3448
  const { onModel, onHarness } = useCoherentHandlers(props);
2890
- const [open, setOpen] = useState12(false);
3449
+ const [open, setOpen] = useState13(false);
2891
3450
  const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
2892
3451
  const selectedModel = models.find((m) => m.id === model);
2893
3452
  const showEffort = selectedModel?.supportsReasoning ?? true;
2894
- const modelPicker = /* @__PURE__ */ jsx12(
3453
+ const modelPicker = /* @__PURE__ */ jsx13(
2895
3454
  ModelPicker,
2896
3455
  {
2897
3456
  value: model,
@@ -2902,17 +3461,17 @@ function AgentSessionControls(props) {
2902
3461
  }
2903
3462
  );
2904
3463
  if (layout === "inline") {
2905
- return /* @__PURE__ */ jsxs10("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
3464
+ return /* @__PURE__ */ jsxs11("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
2906
3465
  modelPicker,
2907
- showHarness && /* @__PURE__ */ jsx12(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
2908
- showEffort && /* @__PURE__ */ jsx12(EffortPicker, { value: effort, onChange: onEffortChange })
3466
+ showHarness && /* @__PURE__ */ jsx13(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
3467
+ showEffort && /* @__PURE__ */ jsx13(EffortPicker, { value: effort, onChange: onEffortChange })
2909
3468
  ] });
2910
3469
  }
2911
3470
  const hasAdvanced = showHarness || showEffort;
2912
- return /* @__PURE__ */ jsxs10("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
3471
+ return /* @__PURE__ */ jsxs11("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
2913
3472
  modelPicker,
2914
- hasAdvanced && /* @__PURE__ */ jsxs10("div", { ref: popoverRef, className: "relative inline-flex", children: [
2915
- /* @__PURE__ */ jsx12(
3473
+ hasAdvanced && /* @__PURE__ */ jsxs11("div", { ref: popoverRef, className: "relative inline-flex", children: [
3474
+ /* @__PURE__ */ jsx13(
2916
3475
  "button",
2917
3476
  {
2918
3477
  type: "button",
@@ -2921,19 +3480,19 @@ function AgentSessionControls(props) {
2921
3480
  title: "Model settings \u2014 pick the agent backend and how hard it thinks",
2922
3481
  className: `flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[state=open]:bg-muted ${FOCUS_RING}`,
2923
3482
  "data-state": open ? "open" : "closed",
2924
- children: /* @__PURE__ */ jsx12(GearGlyph, { className: "h-4 w-4" })
3483
+ children: /* @__PURE__ */ jsx13(GearGlyph, { className: "h-4 w-4" })
2925
3484
  }
2926
3485
  ),
2927
- open && /* @__PURE__ */ jsxs10("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
2928
- showHarness && /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2929
- /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
2930
- /* @__PURE__ */ jsx12(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
2931
- /* @__PURE__ */ jsx12("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
3486
+ open && /* @__PURE__ */ jsxs11("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
3487
+ showHarness && /* @__PURE__ */ jsxs11("div", { className: "space-y-1.5", children: [
3488
+ /* @__PURE__ */ jsx13("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
3489
+ /* @__PURE__ */ jsx13(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
3490
+ /* @__PURE__ */ jsx13("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
2932
3491
  ] }),
2933
- showEffort && /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2934
- /* @__PURE__ */ jsx12("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
2935
- /* @__PURE__ */ jsx12(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
2936
- /* @__PURE__ */ jsx12("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
3492
+ showEffort && /* @__PURE__ */ jsxs11("div", { className: "space-y-1.5", children: [
3493
+ /* @__PURE__ */ jsx13("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
3494
+ /* @__PURE__ */ jsx13(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
3495
+ /* @__PURE__ */ jsx13("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
2937
3496
  ] })
2938
3497
  ] })
2939
3498
  ] })
@@ -2941,7 +3500,7 @@ function AgentSessionControls(props) {
2941
3500
  }
2942
3501
 
2943
3502
  // src/web-react/index.tsx
2944
- import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3503
+ import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2945
3504
  function formatModelCost(msg, models) {
2946
3505
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
2947
3506
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
@@ -2955,41 +3514,41 @@ function formatTokensPerSecond(msg) {
2955
3514
  return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
2956
3515
  }
2957
3516
  function RunDrillIn({ run, onClose }) {
2958
- return /* @__PURE__ */ jsxs11("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
2959
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
2960
- /* @__PURE__ */ jsx13(
3517
+ return /* @__PURE__ */ jsxs12("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
3518
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
3519
+ /* @__PURE__ */ jsx14(
2961
3520
  "span",
2962
3521
  {
2963
3522
  className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
2964
3523
  }
2965
3524
  ),
2966
- /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
2967
- /* @__PURE__ */ jsx13("p", { className: "truncate text-sm font-semibold", children: run.title }),
2968
- /* @__PURE__ */ jsx13("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
3525
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
3526
+ /* @__PURE__ */ jsx14("p", { className: "truncate text-sm font-semibold", children: run.title }),
3527
+ /* @__PURE__ */ jsx14("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
2969
3528
  ] }),
2970
- /* @__PURE__ */ jsx13(
3529
+ /* @__PURE__ */ jsx14(
2971
3530
  "button",
2972
3531
  {
2973
3532
  type: "button",
2974
3533
  onClick: onClose,
2975
3534
  "aria-label": "Close",
2976
3535
  className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
2977
- children: /* @__PURE__ */ jsx13("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx13("path", { d: "M18 6 6 18M6 6l12 12" }) })
3536
+ children: /* @__PURE__ */ jsx14("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx14("path", { d: "M18 6 6 18M6 6l12 12" }) })
2978
3537
  }
2979
3538
  )
2980
3539
  ] }),
2981
- /* @__PURE__ */ jsxs11("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
2982
- run.steps.length === 0 && /* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
2983
- run.steps.map((step, i) => /* @__PURE__ */ jsxs11("div", { className: "rounded-lg border border-border/60 bg-background", children: [
2984
- /* @__PURE__ */ jsxs11("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
2985
- /* @__PURE__ */ jsx13("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
2986
- /* @__PURE__ */ jsx13("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
2987
- /* @__PURE__ */ jsx13("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
3540
+ /* @__PURE__ */ jsxs12("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
3541
+ run.steps.length === 0 && /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
3542
+ run.steps.map((step, i) => /* @__PURE__ */ jsxs12("div", { className: "rounded-lg border border-border/60 bg-background", children: [
3543
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
3544
+ /* @__PURE__ */ jsx14("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
3545
+ /* @__PURE__ */ jsx14("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
3546
+ /* @__PURE__ */ jsx14("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
2988
3547
  ] }),
2989
- step.detail && /* @__PURE__ */ jsx13("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: step.detail })
3548
+ step.detail && /* @__PURE__ */ jsx14("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: step.detail })
2990
3549
  ] }, i))
2991
3550
  ] }),
2992
- /* @__PURE__ */ jsx13("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Readonly drill-in. Follow up in the main chat." })
3551
+ /* @__PURE__ */ jsx14("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Readonly drill-in. Follow up in the main chat." })
2993
3552
  ] });
2994
3553
  }
2995
3554
  function pendingApprovalOf(call) {
@@ -3003,20 +3562,20 @@ function ChatEmptyState({
3003
3562
  subline = "Describe the outcome you want. The agent works through it step by step, and pauses for your approval before anything irreversible.",
3004
3563
  doors
3005
3564
  }) {
3006
- return /* @__PURE__ */ jsxs11("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
3007
- /* @__PURE__ */ jsx13("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__ */ jsx13(BrandMark, { size: 32, className: "shrink-0" }) }),
3008
- /* @__PURE__ */ jsx13("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
3009
- /* @__PURE__ */ jsx13("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
3010
- subline && /* @__PURE__ */ jsx13("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
3011
- doors && doors.length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs11(
3565
+ return /* @__PURE__ */ jsxs12("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
3566
+ /* @__PURE__ */ jsx14("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__ */ jsx14(BrandMark, { size: 32, className: "shrink-0" }) }),
3567
+ /* @__PURE__ */ jsx14("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
3568
+ /* @__PURE__ */ jsx14("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
3569
+ subline && /* @__PURE__ */ jsx14("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
3570
+ doors && doors.length > 0 && /* @__PURE__ */ jsx14("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs12(
3012
3571
  "button",
3013
3572
  {
3014
3573
  type: "button",
3015
3574
  onClick: door.onSelect,
3016
3575
  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/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
3017
3576
  children: [
3018
- /* @__PURE__ */ jsx13("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
3019
- door.description && /* @__PURE__ */ jsx13("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
3577
+ /* @__PURE__ */ jsx14("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
3578
+ door.description && /* @__PURE__ */ jsx14("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
3020
3579
  ]
3021
3580
  },
3022
3581
  i
@@ -3025,26 +3584,26 @@ function ChatEmptyState({
3025
3584
  }
3026
3585
  function ToolGlyph({ name, className }) {
3027
3586
  if (name.startsWith("sandbox_")) {
3028
- return /* @__PURE__ */ jsxs11("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3029
- /* @__PURE__ */ jsx13("polyline", { points: "4 17 10 11 4 5" }),
3030
- /* @__PURE__ */ jsx13("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
3587
+ return /* @__PURE__ */ jsxs12("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3588
+ /* @__PURE__ */ jsx14("polyline", { points: "4 17 10 11 4 5" }),
3589
+ /* @__PURE__ */ jsx14("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
3031
3590
  ] });
3032
3591
  }
3033
3592
  if (name === "submit_proposal") {
3034
- return /* @__PURE__ */ jsxs11("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3035
- /* @__PURE__ */ jsx13("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
3036
- /* @__PURE__ */ jsx13("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
3593
+ return /* @__PURE__ */ jsxs12("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3594
+ /* @__PURE__ */ jsx14("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
3595
+ /* @__PURE__ */ jsx14("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
3037
3596
  ] });
3038
3597
  }
3039
3598
  if (name === "schedule_followup") {
3040
- return /* @__PURE__ */ jsxs11("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
3041
- /* @__PURE__ */ jsx13("circle", { cx: "12", cy: "12", r: "9" }),
3042
- /* @__PURE__ */ jsx13("path", { d: "M12 7v5l3 3" })
3599
+ return /* @__PURE__ */ jsxs12("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
3600
+ /* @__PURE__ */ jsx14("circle", { cx: "12", cy: "12", r: "9" }),
3601
+ /* @__PURE__ */ jsx14("path", { d: "M12 7v5l3 3" })
3043
3602
  ] });
3044
3603
  }
3045
- return /* @__PURE__ */ jsxs11("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3046
- /* @__PURE__ */ jsx13("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
3047
- /* @__PURE__ */ jsx13("circle", { cx: "12", cy: "12", r: "4" })
3604
+ return /* @__PURE__ */ jsxs12("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
3605
+ /* @__PURE__ */ jsx14("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
3606
+ /* @__PURE__ */ jsx14("circle", { cx: "12", cy: "12", r: "4" })
3048
3607
  ] });
3049
3608
  }
3050
3609
  function toolOutcomeOf(call) {
@@ -3112,40 +3671,40 @@ function truncate(v, max = 240) {
3112
3671
  function KvRows({ data }) {
3113
3672
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
3114
3673
  if (!entries.length) return null;
3115
- return /* @__PURE__ */ jsx13("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs11("div", { className: "contents", children: [
3116
- /* @__PURE__ */ jsx13("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
3117
- /* @__PURE__ */ jsx13("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
3674
+ return /* @__PURE__ */ jsx14("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs12("div", { className: "contents", children: [
3675
+ /* @__PURE__ */ jsx14("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
3676
+ /* @__PURE__ */ jsx14("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
3118
3677
  ] }, k)) });
3119
3678
  }
3120
3679
  function ShellDetail({ call }) {
3121
3680
  const outcome = toolOutcomeOf(call);
3122
3681
  const r = outcome?.result ?? {};
3123
- return /* @__PURE__ */ jsxs11("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
3124
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
3125
- /* @__PURE__ */ jsx13("span", { className: "select-none text-zinc-500", children: "$" }),
3126
- /* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
3127
- r.exitCode != null && /* @__PURE__ */ jsxs11("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
3682
+ return /* @__PURE__ */ jsxs12("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
3683
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
3684
+ /* @__PURE__ */ jsx14("span", { className: "select-none text-zinc-500", children: "$" }),
3685
+ /* @__PURE__ */ jsx14("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
3686
+ r.exitCode != null && /* @__PURE__ */ jsxs12("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
3128
3687
  "exit ",
3129
3688
  r.exitCode
3130
3689
  ] })
3131
3690
  ] }),
3132
- /* @__PURE__ */ jsx13("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)" })
3691
+ /* @__PURE__ */ jsx14("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)" })
3133
3692
  ] });
3134
3693
  }
3135
3694
  function DefaultToolDetail({ call }) {
3136
3695
  const result = call.result;
3137
3696
  const envelope = typeof result === "object" && result !== null ? result : null;
3138
- return /* @__PURE__ */ jsxs11("div", { className: "space-y-2", children: [
3139
- call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs11("div", { children: [
3140
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
3141
- /* @__PURE__ */ jsx13(KvRows, { data: call.args })
3697
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
3698
+ call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs12("div", { children: [
3699
+ /* @__PURE__ */ jsx14("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
3700
+ /* @__PURE__ */ jsx14(KvRows, { data: call.args })
3142
3701
  ] }),
3143
- envelope ? /* @__PURE__ */ jsxs11("div", { children: [
3144
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: envelope.ok === false ? "Failed" : "Result" }),
3145
- envelope.ok === false ? /* @__PURE__ */ jsx13("p", { className: "text-xs text-destructive", children: envelope.message ?? "Tool failed" }) : envelope.result && typeof envelope.result === "object" ? /* @__PURE__ */ jsx13(KvRows, { data: envelope.result }) : envelope.result != null ? /* @__PURE__ */ jsx13("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(envelope.result) }) : null
3146
- ] }) : result != null ? /* @__PURE__ */ jsxs11("div", { children: [
3147
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Result" }),
3148
- /* @__PURE__ */ jsx13("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(result) })
3702
+ envelope ? /* @__PURE__ */ jsxs12("div", { children: [
3703
+ /* @__PURE__ */ jsx14("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: envelope.ok === false ? "Failed" : "Result" }),
3704
+ envelope.ok === false ? /* @__PURE__ */ jsx14("p", { className: "text-xs text-destructive", children: envelope.message ?? "Tool failed" }) : envelope.result && typeof envelope.result === "object" ? /* @__PURE__ */ jsx14(KvRows, { data: envelope.result }) : envelope.result != null ? /* @__PURE__ */ jsx14("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(envelope.result) }) : null
3705
+ ] }) : result != null ? /* @__PURE__ */ jsxs12("div", { children: [
3706
+ /* @__PURE__ */ jsx14("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Result" }),
3707
+ /* @__PURE__ */ jsx14("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(result) })
3149
3708
  ] }) : null
3150
3709
  ] });
3151
3710
  }
@@ -3156,23 +3715,23 @@ function ProposalCard({
3156
3715
  approval,
3157
3716
  renderers
3158
3717
  }) {
3159
- const [expanded, setExpanded] = useState13(false);
3718
+ const [expanded, setExpanded] = useState14(false);
3160
3719
  const { summary, meta } = proposalPreview(call);
3161
3720
  const custom = renderers?.[call.name]?.(call, message);
3162
3721
  const { pending: deciding, run: decide } = usePending();
3163
- return /* @__PURE__ */ jsxs11("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: [
3164
- /* @__PURE__ */ jsxs11("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
3165
- /* @__PURE__ */ jsx13("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__ */ jsx13(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
3166
- /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
3167
- /* @__PURE__ */ jsx13("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
3168
- /* @__PURE__ */ jsx13("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
3169
- summary && /* @__PURE__ */ jsx13("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
3170
- meta.length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx13("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
3722
+ return /* @__PURE__ */ jsxs12("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: [
3723
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
3724
+ /* @__PURE__ */ jsx14("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__ */ jsx14(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
3725
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
3726
+ /* @__PURE__ */ jsx14("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
3727
+ /* @__PURE__ */ jsx14("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
3728
+ summary && /* @__PURE__ */ jsx14("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
3729
+ meta.length > 0 && /* @__PURE__ */ jsx14("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx14("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
3171
3730
  ] })
3172
3731
  ] }),
3173
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
3174
- approval ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
3175
- /* @__PURE__ */ jsx13(
3732
+ /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
3733
+ approval ? /* @__PURE__ */ jsxs12(Fragment7, { children: [
3734
+ /* @__PURE__ */ jsx14(
3176
3735
  "button",
3177
3736
  {
3178
3737
  type: "button",
@@ -3182,7 +3741,7 @@ function ProposalCard({
3182
3741
  children: "Approve & run"
3183
3742
  }
3184
3743
  ),
3185
- /* @__PURE__ */ jsx13(
3744
+ /* @__PURE__ */ jsx14(
3186
3745
  "button",
3187
3746
  {
3188
3747
  type: "button",
@@ -3192,8 +3751,8 @@ function ProposalCard({
3192
3751
  children: "Reject"
3193
3752
  }
3194
3753
  )
3195
- ] }) : /* @__PURE__ */ jsx13("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
3196
- /* @__PURE__ */ jsxs11(
3754
+ ] }) : /* @__PURE__ */ jsx14("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
3755
+ /* @__PURE__ */ jsxs12(
3197
3756
  "button",
3198
3757
  {
3199
3758
  type: "button",
@@ -3202,23 +3761,23 @@ function ProposalCard({
3202
3761
  className: "ml-auto inline-flex items-center gap-1 rounded text-[12px] font-medium text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3203
3762
  children: [
3204
3763
  expanded ? "Hide details" : "View details",
3205
- /* @__PURE__ */ jsx13(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
3764
+ /* @__PURE__ */ jsx14(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
3206
3765
  ]
3207
3766
  }
3208
3767
  )
3209
3768
  ] }),
3210
- expanded && /* @__PURE__ */ jsx13("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx13(DefaultToolDetail, { call }) })
3769
+ expanded && /* @__PURE__ */ jsx14("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx14(DefaultToolDetail, { call }) })
3211
3770
  ] });
3212
3771
  }
3213
3772
  function FollowupCard({ call }) {
3214
3773
  const a = call.args ?? {};
3215
3774
  const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
3216
- return /* @__PURE__ */ jsxs11("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
3217
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3218
- /* @__PURE__ */ jsx13(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
3219
- /* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
3775
+ return /* @__PURE__ */ jsxs12("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
3776
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
3777
+ /* @__PURE__ */ jsx14(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
3778
+ /* @__PURE__ */ jsx14("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
3220
3779
  ] }),
3221
- when && /* @__PURE__ */ jsx13("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
3780
+ when && /* @__PURE__ */ jsx14("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
3222
3781
  ] });
3223
3782
  }
3224
3783
  function ToolCallCard({
@@ -3228,13 +3787,13 @@ function ToolCallCard({
3228
3787
  onOpenRun,
3229
3788
  renderers
3230
3789
  }) {
3231
- const [expanded, setExpanded] = useState13(false);
3790
+ const [expanded, setExpanded] = useState14(false);
3232
3791
  const pending = call.status === "done" ? pendingApprovalOf(call) : null;
3233
3792
  const kind = blockKindOf(call);
3234
3793
  const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
3235
3794
  const custom = renderers?.[call.name]?.(call, message);
3236
3795
  if (pending) {
3237
- return /* @__PURE__ */ jsx13(
3796
+ return /* @__PURE__ */ jsx14(
3238
3797
  ProposalCard,
3239
3798
  {
3240
3799
  call,
@@ -3246,16 +3805,16 @@ function ToolCallCard({
3246
3805
  );
3247
3806
  }
3248
3807
  if (kind === "followup" && !failed) {
3249
- return /* @__PURE__ */ jsx13(FollowupCard, { call });
3808
+ return /* @__PURE__ */ jsx14(FollowupCard, { call });
3250
3809
  }
3251
3810
  const isCommand = kind === "command";
3252
- return /* @__PURE__ */ jsxs11(
3811
+ return /* @__PURE__ */ jsxs12(
3253
3812
  "div",
3254
3813
  {
3255
3814
  className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
3256
3815
  children: [
3257
- /* @__PURE__ */ jsxs11("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
3258
- /* @__PURE__ */ jsxs11(
3816
+ /* @__PURE__ */ jsxs12("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
3817
+ /* @__PURE__ */ jsxs12(
3259
3818
  "button",
3260
3819
  {
3261
3820
  type: "button",
@@ -3263,14 +3822,14 @@ function ToolCallCard({
3263
3822
  "aria-expanded": expanded,
3264
3823
  className: "flex min-w-0 flex-1 items-center gap-2 rounded text-left focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3265
3824
  children: [
3266
- /* @__PURE__ */ jsx13(
3825
+ /* @__PURE__ */ jsx14(
3267
3826
  "span",
3268
3827
  {
3269
3828
  className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : failed ? "bg-destructive" : "bg-success"}`
3270
3829
  }
3271
3830
  ),
3272
- /* @__PURE__ */ jsx13(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
3273
- /* @__PURE__ */ jsx13(
3831
+ /* @__PURE__ */ jsx14(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
3832
+ /* @__PURE__ */ jsx14(
3274
3833
  "span",
3275
3834
  {
3276
3835
  className: `min-w-0 flex-1 truncate ${isCommand ? "font-mono text-[12px] tracking-tight text-foreground/90" : "font-medium"}`,
@@ -3280,8 +3839,8 @@ function ToolCallCard({
3280
3839
  ]
3281
3840
  }
3282
3841
  ),
3283
- /* @__PURE__ */ jsx13("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
3284
- /* @__PURE__ */ jsx13(
3842
+ /* @__PURE__ */ jsx14("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
3843
+ /* @__PURE__ */ jsx14(
3285
3844
  "button",
3286
3845
  {
3287
3846
  type: "button",
@@ -3289,13 +3848,13 @@ function ToolCallCard({
3289
3848
  "aria-label": expanded ? "Collapse details" : "Expand details",
3290
3849
  "aria-expanded": expanded,
3291
3850
  className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
3292
- children: /* @__PURE__ */ jsx13(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
3851
+ children: /* @__PURE__ */ jsx14(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
3293
3852
  }
3294
3853
  )
3295
3854
  ] }),
3296
- expanded && /* @__PURE__ */ jsxs11("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
3297
- custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx13(ShellDetail, { call }) : /* @__PURE__ */ jsx13(DefaultToolDetail, { call })),
3298
- onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx13(
3855
+ expanded && /* @__PURE__ */ jsxs12("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
3856
+ custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx14(ShellDetail, { call }) : /* @__PURE__ */ jsx14(DefaultToolDetail, { call })),
3857
+ onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx14(
3299
3858
  "button",
3300
3859
  {
3301
3860
  type: "button",
@@ -3310,7 +3869,7 @@ function ToolCallCard({
3310
3869
  );
3311
3870
  }
3312
3871
  function StreamingCaret() {
3313
- return /* @__PURE__ */ jsx13(
3872
+ return /* @__PURE__ */ jsx14(
3314
3873
  "span",
3315
3874
  {
3316
3875
  className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70",
@@ -3326,11 +3885,11 @@ function SegmentText({
3326
3885
  messageClassName
3327
3886
  }) {
3328
3887
  const text = useSmoothText(content, streaming);
3329
- const body = useMemo7(() => renderBody(text), [renderBody, text]);
3888
+ const body = useMemo8(() => renderBody(text), [renderBody, text]);
3330
3889
  if (!content.trim() && !showCaret) return null;
3331
- return /* @__PURE__ */ jsxs11("div", { className: messageClassName, children: [
3890
+ return /* @__PURE__ */ jsxs12("div", { className: messageClassName, children: [
3332
3891
  body,
3333
- showCaret && /* @__PURE__ */ jsx13(StreamingCaret, {})
3892
+ showCaret && /* @__PURE__ */ jsx14(StreamingCaret, {})
3334
3893
  ] });
3335
3894
  }
3336
3895
  var COLLAPSE_TOOL_RUN_AT = 3;
@@ -3354,7 +3913,7 @@ function SegmentedBody({
3354
3913
  const leftoverToolCalls = (msg.toolCalls ?? []).filter(
3355
3914
  (tc) => !segmentToolIds.has(tc.id)
3356
3915
  );
3357
- const renderToolCard = (call) => /* @__PURE__ */ jsx13(
3916
+ const renderToolCard = (call) => /* @__PURE__ */ jsx14(
3358
3917
  ToolCallCard,
3359
3918
  {
3360
3919
  call,
@@ -3377,9 +3936,9 @@ function SegmentedBody({
3377
3936
  else groups.push({ kind: "tools", index: i, calls: [seg.call] });
3378
3937
  }
3379
3938
  }
3380
- return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
3939
+ return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col gap-2", children: [
3381
3940
  groups.map(
3382
- (g) => g.kind === "text" ? /* @__PURE__ */ jsx13(
3941
+ (g) => g.kind === "text" ? /* @__PURE__ */ jsx14(
3383
3942
  SegmentText,
3384
3943
  {
3385
3944
  content: g.content,
@@ -3389,24 +3948,24 @@ function SegmentedBody({
3389
3948
  messageClassName
3390
3949
  },
3391
3950
  `text-${g.index}`
3392
- ) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs11(
3951
+ ) : !streaming && g.calls.length >= COLLAPSE_TOOL_RUN_AT && !g.calls.some(isImportantTool) ? /* @__PURE__ */ jsxs12(
3393
3952
  "details",
3394
3953
  {
3395
3954
  className: "rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2",
3396
3955
  children: [
3397
- /* @__PURE__ */ jsxs11("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
3956
+ /* @__PURE__ */ jsxs12("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: [
3398
3957
  "Worked through ",
3399
3958
  g.calls.length,
3400
3959
  " steps"
3401
3960
  ] }),
3402
- /* @__PURE__ */ jsx13("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
3961
+ /* @__PURE__ */ jsx14("div", { className: "mt-2 flex flex-col gap-2", children: g.calls.map(renderToolCard) })
3403
3962
  ]
3404
3963
  },
3405
3964
  `tools-${g.index}`
3406
- ) : /* @__PURE__ */ jsx13("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
3965
+ ) : /* @__PURE__ */ jsx14("div", { className: "flex flex-col gap-2", children: g.calls.map(renderToolCard) }, `tools-${g.index}`)
3407
3966
  ),
3408
3967
  leftoverToolCalls.map(renderToolCard),
3409
- streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx13(StreamingCaret, {})
3968
+ streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx14(StreamingCaret, {})
3410
3969
  ] });
3411
3970
  }
3412
3971
  function AssistantMessageImpl({
@@ -3426,40 +3985,40 @@ function AssistantMessageImpl({
3426
3985
  }) {
3427
3986
  const content = useSmoothText(msg.content, streaming);
3428
3987
  const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
3429
- const body = useMemo7(() => renderBody(content), [renderBody, content]);
3988
+ const body = useMemo8(() => renderBody(content), [renderBody, content]);
3430
3989
  const segments = msg.segments;
3431
3990
  const hasAnswerText = content !== "" || (segments?.some((s) => s.kind === "text" && s.content.trim() !== "") ?? false);
3432
- const reasoningScrollRef = useRef8(null);
3433
- const thinkStartRef = useRef8(null);
3434
- const thinkMsRef = useRef8(null);
3991
+ const reasoningScrollRef = useRef9(null);
3992
+ const thinkStartRef = useRef9(null);
3993
+ const thinkMsRef = useRef9(null);
3435
3994
  if (streaming && reasoning && !hasAnswerText && thinkStartRef.current === null) {
3436
3995
  thinkStartRef.current = performance.now();
3437
3996
  }
3438
3997
  if (hasAnswerText && thinkStartRef.current !== null && thinkMsRef.current === null) {
3439
3998
  thinkMsRef.current = performance.now() - thinkStartRef.current;
3440
3999
  }
3441
- useEffect9(() => {
4000
+ useEffect10(() => {
3442
4001
  const el = reasoningScrollRef.current;
3443
4002
  if (el && streaming && !hasAnswerText) el.scrollTop = el.scrollHeight;
3444
4003
  }, [reasoning, streaming, hasAnswerText]);
3445
4004
  const thinkingSeconds = useThinkingSeconds(
3446
4005
  streaming && !!reasoning && !hasAnswerText
3447
4006
  );
3448
- return /* @__PURE__ */ jsxs11("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
3449
- /* @__PURE__ */ jsxs11("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
3450
- /* @__PURE__ */ jsx13("span", { className: "font-semibold uppercase", children: agentLabel }),
3451
- msg.modelUsed && /* @__PURE__ */ jsx13("span", { className: "font-mono normal-case", children: msg.modelUsed }),
3452
- formatTokensPerSecond(msg) && /* @__PURE__ */ jsx13("span", { children: formatTokensPerSecond(msg) }),
3453
- formatModelCost(msg, models) && /* @__PURE__ */ jsx13("span", { children: formatModelCost(msg, models) })
4007
+ return /* @__PURE__ */ jsxs12("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
4008
+ /* @__PURE__ */ jsxs12("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
4009
+ /* @__PURE__ */ jsx14("span", { className: "font-semibold uppercase", children: agentLabel }),
4010
+ msg.modelUsed && /* @__PURE__ */ jsx14("span", { className: "font-mono normal-case", children: msg.modelUsed }),
4011
+ formatTokensPerSecond(msg) && /* @__PURE__ */ jsx14("span", { children: formatTokensPerSecond(msg) }),
4012
+ formatModelCost(msg, models) && /* @__PURE__ */ jsx14("span", { children: formatModelCost(msg, models) })
3454
4013
  ] }),
3455
- reasoning && /* @__PURE__ */ jsxs11("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
3456
- /* @__PURE__ */ jsx13("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs11("span", { className: "animate-pulse", children: [
4014
+ reasoning && /* @__PURE__ */ jsxs12("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
4015
+ /* @__PURE__ */ jsx14("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs12("span", { className: "animate-pulse", children: [
3457
4016
  "Thinking",
3458
4017
  thinkingSeconds >= 3 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
3459
4018
  ] }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
3460
- /* @__PURE__ */ jsx13("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
4019
+ /* @__PURE__ */ jsx14("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
3461
4020
  ] }),
3462
- segments && segments.length > 0 ? /* @__PURE__ */ jsx13(
4021
+ segments && segments.length > 0 ? /* @__PURE__ */ jsx14(
3463
4022
  SegmentedBody,
3464
4023
  {
3465
4024
  segments,
@@ -3471,12 +4030,12 @@ function AssistantMessageImpl({
3471
4030
  toolRenderers,
3472
4031
  messageClassName
3473
4032
  }
3474
- ) : /* @__PURE__ */ jsxs11(Fragment6, { children: [
3475
- /* @__PURE__ */ jsxs11("div", { className: messageClassName, children: [
4033
+ ) : /* @__PURE__ */ jsxs12(Fragment7, { children: [
4034
+ /* @__PURE__ */ jsxs12("div", { className: messageClassName, children: [
3476
4035
  body,
3477
- streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx13(StreamingCaret, {})
4036
+ streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx14(StreamingCaret, {})
3478
4037
  ] }),
3479
- msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx13(
4038
+ msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx14("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx14(
3480
4039
  ToolCallCard,
3481
4040
  {
3482
4041
  call: tc,
@@ -3488,7 +4047,7 @@ function AssistantMessageImpl({
3488
4047
  tc.id
3489
4048
  )) })
3490
4049
  ] }),
3491
- durableCards && msg.parts && /* @__PURE__ */ jsx13(
4050
+ durableCards && msg.parts && /* @__PURE__ */ jsx14(
3492
4051
  DurableChatCards,
3493
4052
  {
3494
4053
  ...durableCards,
@@ -3497,7 +4056,7 @@ function AssistantMessageImpl({
3497
4056
  className: "mt-3"
3498
4057
  }
3499
4058
  ),
3500
- workProductCards && workProductPartsFromMessageParts(msg.parts).map((part) => /* @__PURE__ */ jsx13(
4059
+ workProductCards && workProductPartsFromMessageParts(msg.parts).map((part) => /* @__PURE__ */ jsx14(
3501
4060
  WorkProductCard,
3502
4061
  {
3503
4062
  part,
@@ -3507,7 +4066,7 @@ function AssistantMessageImpl({
3507
4066
  `${part.ref.id}:${part.ref.version}`
3508
4067
  )),
3509
4068
  renderExtras?.(msg),
3510
- resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-2", children: /* @__PURE__ */ jsx13(
4069
+ resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */ jsx14("div", { className: "mt-2", children: /* @__PURE__ */ jsx14(
3511
4070
  MessageAttachments,
3512
4071
  {
3513
4072
  parts: attachmentPartsFromMessageParts(msg.parts),
@@ -3519,8 +4078,8 @@ function AssistantMessageImpl({
3519
4078
  }
3520
4079
  var AssistantMessage = memo(AssistantMessageImpl);
3521
4080
  function useThinkingSeconds(active) {
3522
- const [seconds, setSeconds] = useState13(0);
3523
- useEffect9(() => {
4081
+ const [seconds, setSeconds] = useState14(0);
4082
+ useEffect10(() => {
3524
4083
  if (!active) return;
3525
4084
  setSeconds(0);
3526
4085
  const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
@@ -3530,23 +4089,23 @@ function useThinkingSeconds(active) {
3530
4089
  }
3531
4090
  function ThinkingRow({ agentLabel }) {
3532
4091
  const seconds = useThinkingSeconds(true);
3533
- return /* @__PURE__ */ jsxs11("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
3534
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
3535
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
3536
- /* @__PURE__ */ jsx13("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx13("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
4092
+ return /* @__PURE__ */ jsxs12("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
4093
+ /* @__PURE__ */ jsx14("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
4094
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
4095
+ /* @__PURE__ */ jsx14("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx14("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
3537
4096
  "Thinking",
3538
4097
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
3539
4098
  ] })
3540
4099
  ] });
3541
4100
  }
3542
4101
  function StreamErrorRow({ message, onRetry }) {
3543
- return /* @__PURE__ */ jsx13("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs11("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: [
3544
- /* @__PURE__ */ jsxs11("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: [
3545
- /* @__PURE__ */ jsx13("circle", { cx: "12", cy: "12", r: "9" }),
3546
- /* @__PURE__ */ jsx13("path", { d: "M12 8v4m0 4h.01" })
4102
+ return /* @__PURE__ */ jsx14("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs12("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: [
4103
+ /* @__PURE__ */ jsxs12("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: [
4104
+ /* @__PURE__ */ jsx14("circle", { cx: "12", cy: "12", r: "9" }),
4105
+ /* @__PURE__ */ jsx14("path", { d: "M12 8v4m0 4h.01" })
3547
4106
  ] }),
3548
- /* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 break-words", children: message }),
3549
- onRetry && /* @__PURE__ */ jsx13(
4107
+ /* @__PURE__ */ jsx14("span", { className: "min-w-0 flex-1 break-words", children: message }),
4108
+ onRetry && /* @__PURE__ */ jsx14(
3550
4109
  "button",
3551
4110
  {
3552
4111
  type: "button",
@@ -3579,31 +4138,31 @@ function ChatMessages({
3579
4138
  workProductCards
3580
4139
  }) {
3581
4140
  const messageClassName = messageSize === "large" ? "agent-app-message-copy text-[17px] leading-[1.75]" : "agent-app-message-copy text-base leading-[1.75]";
3582
- const renderBody = useMemo7(
3583
- () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx13("p", { className: "whitespace-pre-wrap", children: content })),
4141
+ const renderBody = useMemo8(
4142
+ () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx14("p", { className: "whitespace-pre-wrap", children: content })),
3584
4143
  [renderMarkdown]
3585
4144
  );
3586
4145
  const lastIsUser = messages[messages.length - 1]?.role === "user";
3587
4146
  if (messages.length === 0 && !loading && !error) {
3588
- const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx13(ChatEmptyState, { ...emptyState });
3589
- return /* @__PURE__ */ jsxs11(Fragment6, { children: [
4147
+ const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx14(ChatEmptyState, { ...emptyState });
4148
+ return /* @__PURE__ */ jsxs12(Fragment7, { children: [
3590
4149
  header,
3591
4150
  empty
3592
4151
  ] });
3593
4152
  }
3594
- return /* @__PURE__ */ jsxs11(Fragment6, { children: [
4153
+ return /* @__PURE__ */ jsxs12(Fragment7, { children: [
3595
4154
  header,
3596
4155
  messages.map(
3597
- (msg) => msg.role === "user" ? /* @__PURE__ */ jsx13("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs11("div", { className: "ml-auto w-fit max-w-[85%]", children: [
3598
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
3599
- /* @__PURE__ */ jsx13(
4156
+ (msg) => msg.role === "user" ? /* @__PURE__ */ jsx14("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs12("div", { className: "ml-auto w-fit max-w-[85%]", children: [
4157
+ /* @__PURE__ */ jsx14("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
4158
+ /* @__PURE__ */ jsx14(
3600
4159
  "div",
3601
4160
  {
3602
4161
  className: `rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 ${messageClassName}`,
3603
- children: /* @__PURE__ */ jsx13("p", { className: "whitespace-pre-wrap", children: msg.content })
4162
+ children: /* @__PURE__ */ jsx14("p", { className: "whitespace-pre-wrap", children: msg.content })
3604
4163
  }
3605
4164
  ),
3606
- resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */ jsx13("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx13(
4165
+ resolveAttachmentUrl && attachmentPartsFromMessageParts(msg.parts).length > 0 && /* @__PURE__ */ jsx14("div", { className: "mt-1.5", children: /* @__PURE__ */ jsx14(
3607
4166
  MessageAttachments,
3608
4167
  {
3609
4168
  parts: attachmentPartsFromMessageParts(msg.parts),
@@ -3611,7 +4170,7 @@ function ChatMessages({
3611
4170
  justify: "end"
3612
4171
  }
3613
4172
  ) })
3614
- ] }) }, msg.id) : /* @__PURE__ */ jsx13(
4173
+ ] }) }, msg.id) : /* @__PURE__ */ jsx14(
3615
4174
  AssistantMessage,
3616
4175
  {
3617
4176
  msg,
@@ -3631,8 +4190,8 @@ function ChatMessages({
3631
4190
  msg.id
3632
4191
  )
3633
4192
  ),
3634
- loading && lastIsUser && /* @__PURE__ */ jsx13(ThinkingRow, { agentLabel }),
3635
- error && !loading && /* @__PURE__ */ jsx13(StreamErrorRow, { message: error, onRetry })
4193
+ loading && lastIsUser && /* @__PURE__ */ jsx14(ThinkingRow, { agentLabel }),
4194
+ error && !loading && /* @__PURE__ */ jsx14(StreamErrorRow, { message: error, onRetry })
3636
4195
  ] });
3637
4196
  }
3638
4197
 
@@ -3703,6 +4262,11 @@ export {
3703
4262
  MissionActivityLane,
3704
4263
  AgentActivityPanel,
3705
4264
  SeatPaywall,
4265
+ useInfiniteScroll,
4266
+ useSessionHistory,
4267
+ useSessionActions,
4268
+ formatSessionTimestamp,
4269
+ SessionHistoryPanel,
3706
4270
  AgentSessionControls,
3707
4271
  formatModelCost,
3708
4272
  formatTokensPerSecond,
@@ -3712,4 +4276,4 @@ export {
3712
4276
  useThinkingSeconds,
3713
4277
  ChatMessages
3714
4278
  };
3715
- //# sourceMappingURL=chunk-LNRDDXME.js.map
4279
+ //# sourceMappingURL=chunk-YYV3EZSF.js.map