@opengeni/react 5.0.5-canary.3 → 5.2.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.js +1391 -2
- package/dist/artifacts.js.map +1 -1
- package/dist/chunk-2TKI3WEG.js +73 -0
- package/dist/chunk-2TKI3WEG.js.map +1 -0
- package/dist/{chunk-V3WX3TQG.js → chunk-45XEUVTK.js} +2 -2
- package/dist/{chunk-M2HNWZYR.js → chunk-IHQII5WO.js} +69 -18
- package/dist/chunk-IHQII5WO.js.map +1 -0
- package/dist/{chunk-HUMIRRYI.js → chunk-IYCR4343.js} +19 -19
- package/dist/{chunk-HUMIRRYI.js.map → chunk-IYCR4343.js.map} +1 -1
- package/dist/{chunk-6J56T3MG.js → chunk-NYESIADM.js} +14 -5
- package/dist/chunk-NYESIADM.js.map +1 -0
- package/dist/{chunk-7S2KWUJD.js → chunk-QXJCNVSD.js} +2283 -2215
- package/dist/chunk-QXJCNVSD.js.map +1 -0
- package/dist/{chunk-BV5A4OTE.js → chunk-T5FRXMC3.js} +21 -2
- package/dist/{chunk-BV5A4OTE.js.map → chunk-T5FRXMC3.js.map} +1 -1
- package/dist/{chunk-BRFMGY4L.js → chunk-UGMKPUEM.js} +28 -3
- package/dist/chunk-UGMKPUEM.js.map +1 -0
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +2 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/markdown.d.ts +13 -1
- package/dist/components/message-timeline.d.ts +4 -1
- package/dist/components/session-conversation.d.ts +3 -0
- package/dist/components/user-message-body.d.ts +10 -1
- package/dist/composer.js +2 -2
- package/dist/{computer-viewer-7TEZC6Y2.js → computer-viewer-AA4JH2AP.js} +2 -2
- package/dist/connect.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +1 -1
- package/dist/{platform-activity-row-27LKAWZD.js → platform-activity-row-UW4UVVM4.js} +6 -3
- package/dist/platform-activity-row-UW4UVVM4.js.map +1 -0
- package/dist/session-ui.d.ts +1 -1
- package/dist/session-ui.js +6 -5
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +2 -2
- package/dist/sites-ui.d.ts +2 -1
- package/dist/sites.js +12 -4
- package/dist/sites.js.map +1 -1
- package/dist/timeline/activity-rail.d.ts +1 -0
- package/dist/timeline/platform-activity-row.d.ts +1 -1
- package/dist/timeline/retained-image.d.ts +16 -0
- package/dist/timeline/rolling-activity.d.ts +9 -0
- package/dist/timeline/shared.d.ts +4 -1
- package/dist/timeline/turn-summary.d.ts +4 -1
- package/package.json +4 -4
- package/src/artifacts.ts +2 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/published-html-artifact-frame.tsx +32 -2
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/copy-button.tsx +7 -2
- package/src/components/markdown.tsx +111 -34
- package/src/components/message-timeline.tsx +61 -4
- package/src/components/session-conversation.tsx +5 -0
- package/src/components/user-message-body.tsx +20 -2
- package/src/hooks/use-composer.ts +15 -2
- package/src/hooks/use-computer-session.ts +36 -1
- package/src/index.ts +10 -2
- package/src/session-ui.ts +4 -1
- package/src/sites-ui.tsx +23 -6
- package/src/timeline/activity-rail.tsx +20 -3
- package/src/timeline/platform-activity-row.tsx +5 -2
- package/src/timeline/retained-image.ts +91 -0
- package/src/timeline/rolling-activity.tsx +83 -0
- package/src/timeline/shared.tsx +33 -12
- package/src/timeline/tool-renderers.tsx +7 -91
- package/src/timeline/turn-summary.tsx +21 -15
- package/styles/compiled.css +122 -0
- package/styles/index.css +49 -0
- package/dist/chunk-6J56T3MG.js.map +0 -1
- package/dist/chunk-7S2KWUJD.js.map +0 -1
- package/dist/chunk-BRFMGY4L.js.map +0 -1
- package/dist/chunk-M2HNWZYR.js.map +0 -1
- package/dist/platform-activity-row-27LKAWZD.js.map +0 -1
- /package/dist/{chunk-V3WX3TQG.js.map → chunk-45XEUVTK.js.map} +0 -0
- /package/dist/{computer-viewer-7TEZC6Y2.js.map → computer-viewer-AA4JH2AP.js.map} +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { renderActivity } from "./activity-rail";
|
|
2
|
+
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
|
|
3
|
+
import { WrenchIcon } from "lucide-react";
|
|
4
|
+
import { Suspense, useEffect, useState } from "react";
|
|
5
|
+
import { CompactActivityContext } from "./shared";
|
|
6
|
+
import { defaultToolRegistry } from "./tool-renderers";
|
|
7
|
+
import type { ToolRegistry } from "./registry";
|
|
8
|
+
import { toolDisplayName } from "./tool-display-name";
|
|
9
|
+
import type { ActivityItem } from "./types";
|
|
10
|
+
|
|
11
|
+
/** One stable viewport; updates replace its content without moving the conversation. */
|
|
12
|
+
export function RollingActivity({
|
|
13
|
+
items,
|
|
14
|
+
toolRegistry = defaultToolRegistry,
|
|
15
|
+
previousItem,
|
|
16
|
+
}: {
|
|
17
|
+
items: ActivityItem[];
|
|
18
|
+
/** The standalone item visible immediately before this reel mounted. */
|
|
19
|
+
previousItem?: ActivityItem | undefined;
|
|
20
|
+
toolRegistry?: ToolRegistry;
|
|
21
|
+
}) {
|
|
22
|
+
const reduced = useReducedMotion();
|
|
23
|
+
const [mounted, setMounted] = useState(false);
|
|
24
|
+
useEffect(() => setMounted(true), []);
|
|
25
|
+
const work = items.filter((item) => item.kind !== "startup-phase");
|
|
26
|
+
const active = work.filter((item) =>
|
|
27
|
+
item.kind === "reasoning" ? item.streaming : "status" in item && item.status === "running",
|
|
28
|
+
);
|
|
29
|
+
// Advance with the event order; finishing a parallel tool must not replay an older one.
|
|
30
|
+
const item = !mounted && previousItem ? previousItem : work.at(-1);
|
|
31
|
+
if (!item) return null;
|
|
32
|
+
const earlierCount = Math.max(
|
|
33
|
+
0,
|
|
34
|
+
work.findIndex((entry) => entry.id === item.id),
|
|
35
|
+
);
|
|
36
|
+
const fallback = (
|
|
37
|
+
<span className="og-rolling-label">
|
|
38
|
+
<WrenchIcon className="size-3.5" />
|
|
39
|
+
<span>{item.kind === "tool-call" ? toolDisplayName(item.name) : "Working"}</span>
|
|
40
|
+
</span>
|
|
41
|
+
);
|
|
42
|
+
return (
|
|
43
|
+
<span
|
|
44
|
+
className="og-rolling-status"
|
|
45
|
+
data-running={active.some((entry) => entry.id === item.id) ? "true" : undefined}
|
|
46
|
+
>
|
|
47
|
+
<span className="sr-only">
|
|
48
|
+
{item.kind === "tool-call"
|
|
49
|
+
? toolDisplayName(item.name)
|
|
50
|
+
: item.kind === "reasoning"
|
|
51
|
+
? "Thinking"
|
|
52
|
+
: "Working"}
|
|
53
|
+
</span>
|
|
54
|
+
<span className="og-rolling-window" aria-hidden="true">
|
|
55
|
+
<AnimatePresence initial={false} mode="sync">
|
|
56
|
+
<motion.span
|
|
57
|
+
key={item.id}
|
|
58
|
+
className="og-rolling-face"
|
|
59
|
+
initial={{
|
|
60
|
+
opacity: 0,
|
|
61
|
+
y: reduced ? 0 : 24,
|
|
62
|
+
}}
|
|
63
|
+
animate={{ opacity: 1, y: 0 }}
|
|
64
|
+
exit={{
|
|
65
|
+
opacity: 0,
|
|
66
|
+
y: reduced ? 0 : -24,
|
|
67
|
+
}}
|
|
68
|
+
transition={{ duration: reduced ? 0 : 0.4, ease: [0.22, 1, 0.36, 1] }}
|
|
69
|
+
>
|
|
70
|
+
<CompactActivityContext.Provider value={true}>
|
|
71
|
+
<Suspense fallback={fallback}>
|
|
72
|
+
{renderActivity(item, toolRegistry, undefined, undefined, undefined, undefined)}
|
|
73
|
+
</Suspense>
|
|
74
|
+
</CompactActivityContext.Provider>
|
|
75
|
+
</motion.span>
|
|
76
|
+
</AnimatePresence>
|
|
77
|
+
</span>
|
|
78
|
+
{earlierCount > 0 ? (
|
|
79
|
+
<span className="og-rolling-count">{`+${earlierCount} earlier`}</span>
|
|
80
|
+
) : null}
|
|
81
|
+
</span>
|
|
82
|
+
);
|
|
83
|
+
}
|
package/src/timeline/shared.tsx
CHANGED
|
@@ -55,6 +55,8 @@ export function ToolCallTruncationProvider({
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export type ActivityDisclosureProps = {
|
|
58
|
+
/** Override the rolling preview; null keeps rapidly streaming details out of the header. */
|
|
59
|
+
compactPreview?: ReactNode;
|
|
58
60
|
icon: ReactNode;
|
|
59
61
|
/** Icon tint. Defaults to the muted foreground; renderers pass accent/failed. */
|
|
60
62
|
iconTone?: "accent" | "failed" | "running" | "muted" | undefined;
|
|
@@ -116,6 +118,8 @@ const ICON_TONE: Record<NonNullable<ActivityDisclosureProps["iconTone"]>, string
|
|
|
116
118
|
* inline media, and at most one right-gutter settle chip. Compact by default;
|
|
117
119
|
* the body mounts only when expanded.
|
|
118
120
|
*/
|
|
121
|
+
export const CompactActivityContext = createContext(false);
|
|
122
|
+
|
|
119
123
|
export function ActivityDisclosure({
|
|
120
124
|
icon,
|
|
121
125
|
iconTone: iconToneProp = "muted",
|
|
@@ -123,6 +127,7 @@ export function ActivityDisclosure({
|
|
|
123
127
|
titleMono,
|
|
124
128
|
running,
|
|
125
129
|
preview,
|
|
130
|
+
compactPreview,
|
|
126
131
|
media,
|
|
127
132
|
chip: chipProp,
|
|
128
133
|
failed,
|
|
@@ -150,6 +155,21 @@ export function ActivityDisclosure({
|
|
|
150
155
|
const forcedDefaultOpen = useForcedDefaultOpen();
|
|
151
156
|
const [open, setOpen] = useState(defaultOpen ?? forcedDefaultOpen ?? false);
|
|
152
157
|
const truncation = useContext(ToolCallTruncationContext);
|
|
158
|
+
const compact = useContext(CompactActivityContext);
|
|
159
|
+
if (compact)
|
|
160
|
+
return (
|
|
161
|
+
<span className="og-rolling-label">
|
|
162
|
+
<span className={cn("shrink-0", ICON_TONE[iconTone])}>{icon}</span>
|
|
163
|
+
<span className="og-command-reel">
|
|
164
|
+
<span className="og-reel-title">{title}</span>
|
|
165
|
+
{(compactPreview === undefined ? preview : compactPreview) ? (
|
|
166
|
+
<span className="og-reel-preview text-og-fg-subtle">
|
|
167
|
+
{compactPreview === undefined ? preview : compactPreview}
|
|
168
|
+
</span>
|
|
169
|
+
) : null}
|
|
170
|
+
</span>
|
|
171
|
+
</span>
|
|
172
|
+
);
|
|
153
173
|
const hasBody = expandable && (children != null || truncation != null);
|
|
154
174
|
|
|
155
175
|
// The preview is detail-on-demand: it is suppressed once the row is open so a
|
|
@@ -189,20 +209,21 @@ export function ActivityDisclosure({
|
|
|
189
209
|
<span className="size-3.5 shrink-0" />
|
|
190
210
|
)}
|
|
191
211
|
<span className={cn("shrink-0", ICON_TONE[iconTone])}>{icon}</span>
|
|
192
|
-
<span
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
212
|
+
<span className={cn("og-command-reel", running && "og-command-reel-running")}>
|
|
213
|
+
<span
|
|
214
|
+
className={cn(
|
|
215
|
+
"min-w-0 shrink truncate text-og-base font-medium",
|
|
216
|
+
titleMono && "font-og-mono text-og-sm font-normal",
|
|
217
|
+
)}
|
|
218
|
+
>
|
|
219
|
+
{title}
|
|
220
|
+
</span>
|
|
221
|
+
{previewVisible && !media ? (
|
|
222
|
+
<span className="min-w-0 flex-1 truncate text-og-sm text-og-fg-subtle">{preview}</span>
|
|
223
|
+
) : (
|
|
224
|
+
<span className="flex-1" />
|
|
197
225
|
)}
|
|
198
|
-
>
|
|
199
|
-
{title}
|
|
200
226
|
</span>
|
|
201
|
-
{previewVisible && !media ? (
|
|
202
|
-
<span className="min-w-0 flex-1 truncate text-og-sm text-og-fg-subtle">{preview}</span>
|
|
203
|
-
) : (
|
|
204
|
-
<span className="flex-1" />
|
|
205
|
-
)}
|
|
206
227
|
{/* The right gutter carries at most ONE signal: the media thumbnail, else a
|
|
207
228
|
terse settle chip (hidden once expanded — the body owns the detail). */}
|
|
208
229
|
{media && !open ? (
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useRetainedImageObjectUrl } from "./retained-image";
|
|
1
2
|
import {
|
|
2
3
|
parseSandboxFileArtifactReceipt,
|
|
3
4
|
type GitFileDiff,
|
|
@@ -34,7 +35,7 @@ import {
|
|
|
34
35
|
VideoIcon,
|
|
35
36
|
WrenchIcon,
|
|
36
37
|
} from "lucide-react";
|
|
37
|
-
import {
|
|
38
|
+
import { useContext, useState, type ReactNode } from "react";
|
|
38
39
|
import { formatBytes, stringifyPayload, tryParseJson } from "../lib/format";
|
|
39
40
|
import { useTimelineComputeLabel } from "./compute-label";
|
|
40
41
|
import {
|
|
@@ -71,6 +72,7 @@ import {
|
|
|
71
72
|
TermBlock,
|
|
72
73
|
Thumbnail,
|
|
73
74
|
ActivityDisclosure,
|
|
75
|
+
CompactActivityContext,
|
|
74
76
|
type DisclosureChip,
|
|
75
77
|
} from "./shared";
|
|
76
78
|
import { RawPatch, ToolDiff } from "./tool-diff";
|
|
@@ -96,9 +98,12 @@ const ICON_SIZE = "size-3.5";
|
|
|
96
98
|
* left-to-right.
|
|
97
99
|
*/
|
|
98
100
|
function RunningPreview({ children }: { children: ReactNode }) {
|
|
101
|
+
const compact = useContext(CompactActivityContext);
|
|
99
102
|
return (
|
|
100
103
|
<span className="inline-flex items-center gap-1.5">
|
|
101
|
-
|
|
104
|
+
{!compact && (
|
|
105
|
+
<span className="size-1.5 shrink-0 animate-og-pulse rounded-full bg-og-status-running" />
|
|
106
|
+
)}
|
|
102
107
|
<span className="min-w-0 truncate">{children}</span>
|
|
103
108
|
</span>
|
|
104
109
|
);
|
|
@@ -766,95 +771,6 @@ function ComputerCallRenderer({ item, loadRetainedScreenshot }: ToolRendererProp
|
|
|
766
771
|
);
|
|
767
772
|
}
|
|
768
773
|
|
|
769
|
-
type RetainedImageState =
|
|
770
|
-
| { kind: "loading" }
|
|
771
|
-
| { kind: "ready"; url: string }
|
|
772
|
-
| { kind: "unavailable"; label: string }
|
|
773
|
-
| { kind: "error"; message: string };
|
|
774
|
-
|
|
775
|
-
function useRetainedImageObjectUrl(
|
|
776
|
-
artifact: RetainedArtifactReference,
|
|
777
|
-
load: ToolRendererProps["loadRetainedArtifact"],
|
|
778
|
-
): RetainedImageState {
|
|
779
|
-
const [state, setState] = useState<RetainedImageState>({ kind: "loading" });
|
|
780
|
-
// Function outputs are commonly serialized JSON. Parsing them creates a new
|
|
781
|
-
// object on every render, so depend on the immutable wire value rather than
|
|
782
|
-
// object identity; otherwise the loader can refetch after its own setState.
|
|
783
|
-
const artifactValue = retainedArtifactValue(artifact);
|
|
784
|
-
const stableArtifactRef = useRef({ value: artifactValue, artifact });
|
|
785
|
-
if (stableArtifactRef.current.value !== artifactValue) {
|
|
786
|
-
stableArtifactRef.current = { value: artifactValue, artifact };
|
|
787
|
-
}
|
|
788
|
-
const stableArtifact = stableArtifactRef.current.artifact;
|
|
789
|
-
useEffect(() => {
|
|
790
|
-
if (!load) {
|
|
791
|
-
setState({ kind: "unavailable", label: "retrieval is not configured" });
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
const controller = new AbortController();
|
|
795
|
-
let objectUrl: string | null = null;
|
|
796
|
-
setState({ kind: "loading" });
|
|
797
|
-
void load(stableArtifact, controller.signal)
|
|
798
|
-
.then((source) => {
|
|
799
|
-
if (controller.signal.aborted) return;
|
|
800
|
-
if (!source) {
|
|
801
|
-
setState({ kind: "unavailable", label: "bytes are unavailable" });
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
if (!(source instanceof Uint8Array)) {
|
|
805
|
-
if (!source.url.trim()) {
|
|
806
|
-
setState({ kind: "unavailable", label: "URL is unavailable" });
|
|
807
|
-
return;
|
|
808
|
-
}
|
|
809
|
-
setState({ kind: "ready", url: source.url });
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
objectUrl = URL.createObjectURL(
|
|
813
|
-
new Blob([source as unknown as BlobPart], { type: stableArtifact.contentType }),
|
|
814
|
-
);
|
|
815
|
-
setState({ kind: "ready", url: objectUrl });
|
|
816
|
-
})
|
|
817
|
-
.catch((error: unknown) => {
|
|
818
|
-
if (controller.signal.aborted) return;
|
|
819
|
-
const status =
|
|
820
|
-
error && typeof error === "object" && "status" in error
|
|
821
|
-
? Number((error as { status?: unknown }).status)
|
|
822
|
-
: null;
|
|
823
|
-
setState(
|
|
824
|
-
status === 404
|
|
825
|
-
? { kind: "unavailable", label: "deleted" }
|
|
826
|
-
: status === 410
|
|
827
|
-
? { kind: "unavailable", label: "expired or unavailable" }
|
|
828
|
-
: { kind: "error", message: "retrieval failed" },
|
|
829
|
-
);
|
|
830
|
-
});
|
|
831
|
-
return () => {
|
|
832
|
-
controller.abort();
|
|
833
|
-
if (objectUrl) URL.revokeObjectURL(objectUrl);
|
|
834
|
-
};
|
|
835
|
-
}, [stableArtifact, load]);
|
|
836
|
-
return state;
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
function retainedArtifactValue(artifact: RetainedArtifactReference): string {
|
|
840
|
-
return [
|
|
841
|
-
artifact.artifactId,
|
|
842
|
-
artifact.kind,
|
|
843
|
-
artifact.contentType,
|
|
844
|
-
artifact.originalBytes,
|
|
845
|
-
artifact.sha256,
|
|
846
|
-
artifact.retainedAt,
|
|
847
|
-
artifact.dimensions?.width ?? "",
|
|
848
|
-
artifact.dimensions?.height ?? "",
|
|
849
|
-
artifact.retention.policy,
|
|
850
|
-
artifact.retention.expiresAt ?? "",
|
|
851
|
-
artifact.retrieval.method,
|
|
852
|
-
artifact.retrieval.path,
|
|
853
|
-
artifact.retrieval.acceptRanges,
|
|
854
|
-
artifact.retrieval.maxRangeBytes,
|
|
855
|
-
].join("\0");
|
|
856
|
-
}
|
|
857
|
-
|
|
858
774
|
function RetainedSessionImageDisclosure({
|
|
859
775
|
artifact,
|
|
860
776
|
load,
|
|
@@ -115,6 +115,8 @@ type ReplaceTurnSummaryFacets = Readonly<{
|
|
|
115
115
|
export type TurnSummaryFacetConfiguration = ModifyTurnSummaryFacets | ReplaceTurnSummaryFacets;
|
|
116
116
|
|
|
117
117
|
export type TurnSummaryOptions = Readonly<{
|
|
118
|
+
/** Experimental compact live activity reel. */
|
|
119
|
+
rolling?: boolean;
|
|
118
120
|
facets?: TurnSummaryFacetConfiguration;
|
|
119
121
|
}>;
|
|
120
122
|
|
|
@@ -133,6 +135,7 @@ export type TurnSummaryProps = {
|
|
|
133
135
|
durationMs?: number | undefined;
|
|
134
136
|
/** Start expanded. */
|
|
135
137
|
defaultOpen?: boolean | undefined;
|
|
138
|
+
liveHeader?: ReactNode;
|
|
136
139
|
/**
|
|
137
140
|
* A nested fold — a cluster or sub-turn INSIDE an already-expanded turn. It
|
|
138
141
|
* drops the bordered/filled chip and renders as a plain disclosure node on the
|
|
@@ -187,6 +190,7 @@ export function TurnSummary({
|
|
|
187
190
|
failureText,
|
|
188
191
|
durationMs,
|
|
189
192
|
defaultOpen,
|
|
193
|
+
liveHeader,
|
|
190
194
|
bare,
|
|
191
195
|
facets: facetConfiguration,
|
|
192
196
|
settleFold,
|
|
@@ -443,7 +447,7 @@ export function TurnSummary({
|
|
|
443
447
|
/>
|
|
444
448
|
{/* Completion is the quiet default and needs no repeated glyph. Failed,
|
|
445
449
|
cancelled, and still-running folds retain a visible state marker. */}
|
|
446
|
-
{outcome === "complete" ? null : (
|
|
450
|
+
{outcome === "complete" || (liveHeader && !outcome) ? null : (
|
|
447
451
|
<span
|
|
448
452
|
className={cn(
|
|
449
453
|
"inline-flex shrink-0 items-center justify-center",
|
|
@@ -463,21 +467,23 @@ export function TurnSummary({
|
|
|
463
467
|
<span
|
|
464
468
|
className={cn("min-w-0 flex-1 truncate", bare ? "text-og-sm" : "text-og-fg-muted")}
|
|
465
469
|
>
|
|
466
|
-
{
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
{
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
<span aria-
|
|
473
|
-
{result.icon
|
|
470
|
+
{liveHeader && !open
|
|
471
|
+
? liveHeader
|
|
472
|
+
: facets.map(({ facet, result }, index) => (
|
|
473
|
+
<FacetRenderBoundary key={facet.id}>
|
|
474
|
+
<>
|
|
475
|
+
{index > 0 ? " · " : null}
|
|
476
|
+
<span aria-label={result.ariaLabel} title={result.title}>
|
|
477
|
+
{result.icon ? (
|
|
478
|
+
<span aria-hidden className="mr-1 inline-flex align-[-0.125em]">
|
|
479
|
+
{result.icon}
|
|
480
|
+
</span>
|
|
481
|
+
) : null}
|
|
482
|
+
{result.content}
|
|
474
483
|
</span>
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
</>
|
|
479
|
-
</FacetRenderBoundary>
|
|
480
|
-
))}
|
|
484
|
+
</>
|
|
485
|
+
</FacetRenderBoundary>
|
|
486
|
+
))}
|
|
481
487
|
{outcome === "failed" && failureText ? (
|
|
482
488
|
<span className="text-og-status-failed"> · {failureText}</span>
|
|
483
489
|
) : null}
|
package/styles/compiled.css
CHANGED
|
@@ -443,6 +443,8 @@
|
|
|
443
443
|
}
|
|
444
444
|
/*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */
|
|
445
445
|
:where(.og-root) {
|
|
446
|
+
--font-sans: var(--og-font-sans);
|
|
447
|
+
--font-mono: var(--og-font-mono);
|
|
446
448
|
--color-black: #000;
|
|
447
449
|
--color-white: #fff;
|
|
448
450
|
--spacing: 0.25rem;
|
|
@@ -469,7 +471,11 @@
|
|
|
469
471
|
--leading-tight: 1.25;
|
|
470
472
|
--leading-snug: 1.375;
|
|
471
473
|
--leading-relaxed: 1.625;
|
|
474
|
+
--radius-sm: var(--og-radius-sm);
|
|
475
|
+
--radius-md: var(--og-radius-md);
|
|
476
|
+
--radius-lg: var(--og-radius-lg);
|
|
472
477
|
--radius-2xl: 1rem;
|
|
478
|
+
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
473
479
|
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
474
480
|
--blur-sm: 8px;
|
|
475
481
|
--blur-md: 12px;
|
|
@@ -911,6 +917,110 @@
|
|
|
911
917
|
animation: none;
|
|
912
918
|
}
|
|
913
919
|
}
|
|
920
|
+
:where(.og-root).og-rolling-status,:where(.og-root) .og-rolling-status {
|
|
921
|
+
display: flex;
|
|
922
|
+
align-items: center;
|
|
923
|
+
gap: 12px;
|
|
924
|
+
min-width: 0;
|
|
925
|
+
width: 100%;
|
|
926
|
+
}
|
|
927
|
+
:where(.og-root).og-rolling-window,:where(.og-root) .og-rolling-window {
|
|
928
|
+
position: relative;
|
|
929
|
+
display: block;
|
|
930
|
+
flex: 1;
|
|
931
|
+
min-width: 0;
|
|
932
|
+
height: 24px;
|
|
933
|
+
overflow: hidden;
|
|
934
|
+
}
|
|
935
|
+
:where(.og-root).og-rolling-face,:where(.og-root) .og-rolling-face {
|
|
936
|
+
position: absolute;
|
|
937
|
+
inset: 0;
|
|
938
|
+
display: flex;
|
|
939
|
+
align-items: center;
|
|
940
|
+
}
|
|
941
|
+
:where(.og-root).og-rolling-label,:where(.og-root) .og-rolling-label {
|
|
942
|
+
display: flex;
|
|
943
|
+
align-items: center;
|
|
944
|
+
gap: 8px;
|
|
945
|
+
min-width: 0;
|
|
946
|
+
width: 100%;
|
|
947
|
+
font-size: 13px;
|
|
948
|
+
font-weight: 450;
|
|
949
|
+
line-height: 20px;
|
|
950
|
+
color: var(--og-color-fg-muted);
|
|
951
|
+
}
|
|
952
|
+
:where(.og-root).og-rolling-label > svg,:where(.og-root) .og-rolling-label > svg {
|
|
953
|
+
flex-shrink: 0;
|
|
954
|
+
}
|
|
955
|
+
:where(.og-root).og-rolling-count,:where(.og-root) .og-rolling-count {
|
|
956
|
+
flex-shrink: 0;
|
|
957
|
+
font-size: 11px;
|
|
958
|
+
color: var(--og-color-fg-subtle);
|
|
959
|
+
font-variant-numeric: tabular-nums;
|
|
960
|
+
}
|
|
961
|
+
:where(.og-root).og-command-reel,:where(.og-root) .og-command-reel {
|
|
962
|
+
display: flex;
|
|
963
|
+
flex: 1;
|
|
964
|
+
align-items: center;
|
|
965
|
+
gap: 8px;
|
|
966
|
+
min-width: 0;
|
|
967
|
+
transform-origin: 50% 50%;
|
|
968
|
+
}
|
|
969
|
+
:where(.og-root).og-reasoning-preview,:where(.og-root) .og-reasoning-preview,:where(.og-root) .og-reasoning-preview :is(div,p,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,pre),:where(.og-root) .og-reasoning-preview :is(div,p,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,pre) {
|
|
970
|
+
display: inline;
|
|
971
|
+
margin: 0;
|
|
972
|
+
padding: 0;
|
|
973
|
+
font-size: inherit;
|
|
974
|
+
line-height: inherit;
|
|
975
|
+
}
|
|
976
|
+
:where(.og-root).og-reasoning-preview br,:where(.og-root) .og-reasoning-preview br {
|
|
977
|
+
display: none;
|
|
978
|
+
}
|
|
979
|
+
:where(.og-root).og-reasoning-preview :is(p,li,h1,h2,h3,h4)::after,:where(.og-root) .og-reasoning-preview :is(p,li,h1,h2,h3,h4)::after {
|
|
980
|
+
content: " ";
|
|
981
|
+
}
|
|
982
|
+
:where(.og-root).og-reel-title,:where(.og-root) .og-reel-title {
|
|
983
|
+
flex: 0 0 auto;
|
|
984
|
+
min-width: 0;
|
|
985
|
+
max-width: 75%;
|
|
986
|
+
overflow: hidden;
|
|
987
|
+
text-overflow: ellipsis;
|
|
988
|
+
white-space: nowrap;
|
|
989
|
+
}
|
|
990
|
+
:where(.og-root).og-reel-title:only-child,:where(.og-root) .og-reel-title:only-child {
|
|
991
|
+
max-width: 100%;
|
|
992
|
+
}
|
|
993
|
+
:where(.og-root).og-reel-preview,:where(.og-root) .og-reel-preview {
|
|
994
|
+
flex: 1 1 0%;
|
|
995
|
+
min-width: 0;
|
|
996
|
+
overflow: hidden;
|
|
997
|
+
text-overflow: ellipsis;
|
|
998
|
+
white-space: nowrap;
|
|
999
|
+
}
|
|
1000
|
+
:where(.og-root).og-command-reel-running,:where(.og-root) .og-command-reel-running,:where(.og-root) .og-rolling-status[data-running="true"] .og-command-reel,:where(.og-root) .og-rolling-status[data-running="true"] .og-command-reel {
|
|
1001
|
+
background-image: linear-gradient(90deg, light-dark(#898c94,#686b76) 42%, light-dark(#f0f1f4,#fff) 50%, light-dark(#898c94,#686b76) 58%);
|
|
1002
|
+
background-size: 300% 100%;
|
|
1003
|
+
background-position: 100% 0;
|
|
1004
|
+
background-clip: text;
|
|
1005
|
+
-webkit-background-clip: text;
|
|
1006
|
+
-webkit-text-fill-color: transparent;
|
|
1007
|
+
animation: og-activity-sweep 3.6s linear infinite;
|
|
1008
|
+
}
|
|
1009
|
+
@keyframes og-activity-sweep {
|
|
1010
|
+
from {
|
|
1011
|
+
background-position: 100% 0;
|
|
1012
|
+
}
|
|
1013
|
+
to {
|
|
1014
|
+
background-position: 0% 0;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
@media (prefers-reduced-motion:reduce), (forced-colors:active) {
|
|
1018
|
+
:where(.og-root).og-command-reel-running,:where(.og-root) .og-command-reel-running,:where(.og-root) .og-rolling-status[data-running="true"] .og-command-reel,:where(.og-root) .og-rolling-status[data-running="true"] .og-command-reel {
|
|
1019
|
+
animation: none;
|
|
1020
|
+
background: none;
|
|
1021
|
+
-webkit-text-fill-color: currentColor;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
914
1024
|
:where(.og-root).pointer-events-auto,:where(.og-root) .pointer-events-auto {
|
|
915
1025
|
pointer-events: auto;
|
|
916
1026
|
}
|
|
@@ -1717,6 +1827,9 @@
|
|
|
1717
1827
|
:where(.og-root).flex-\[1_1_5rem\],:where(.og-root) .flex-\[1_1_5rem\] {
|
|
1718
1828
|
flex: 1 1 5rem;
|
|
1719
1829
|
}
|
|
1830
|
+
:where(.og-root).flex-shrink,:where(.og-root) .flex-shrink {
|
|
1831
|
+
flex-shrink: 1;
|
|
1832
|
+
}
|
|
1720
1833
|
:where(.og-root).shrink,:where(.og-root) .shrink {
|
|
1721
1834
|
flex-shrink: 1;
|
|
1722
1835
|
}
|
|
@@ -3207,6 +3320,9 @@
|
|
|
3207
3320
|
:where(.og-root).text-balance,:where(.og-root) .text-balance {
|
|
3208
3321
|
text-wrap: balance;
|
|
3209
3322
|
}
|
|
3323
|
+
:where(.og-root).text-nowrap,:where(.og-root) .text-nowrap {
|
|
3324
|
+
text-wrap: nowrap;
|
|
3325
|
+
}
|
|
3210
3326
|
:where(.og-root).\[overflow-wrap\:anywhere\],:where(.og-root) .\[overflow-wrap\:anywhere\] {
|
|
3211
3327
|
overflow-wrap: anywhere;
|
|
3212
3328
|
}
|
|
@@ -3231,6 +3347,9 @@
|
|
|
3231
3347
|
:where(.og-root).whitespace-pre-wrap,:where(.og-root) .whitespace-pre-wrap {
|
|
3232
3348
|
white-space: pre-wrap;
|
|
3233
3349
|
}
|
|
3350
|
+
:where(.og-root).text-destructive,:where(.og-root) .text-destructive {
|
|
3351
|
+
color: var(--og-color-danger);
|
|
3352
|
+
}
|
|
3234
3353
|
:where(.og-root).text-fg,:where(.og-root) .text-fg {
|
|
3235
3354
|
color: var(--og-color-fg);
|
|
3236
3355
|
}
|
|
@@ -3240,6 +3359,9 @@
|
|
|
3240
3359
|
:where(.og-root).text-fg-subtle,:where(.og-root) .text-fg-subtle {
|
|
3241
3360
|
color: var(--og-color-fg-subtle);
|
|
3242
3361
|
}
|
|
3362
|
+
:where(.og-root).text-muted,:where(.og-root) .text-muted {
|
|
3363
|
+
color: var(--color-surface-2);
|
|
3364
|
+
}
|
|
3243
3365
|
:where(.og-root).text-og-accent,:where(.og-root) .text-og-accent {
|
|
3244
3366
|
color: var(--og-color-accent);
|
|
3245
3367
|
}
|
package/styles/index.css
CHANGED
|
@@ -594,3 +594,52 @@
|
|
|
594
594
|
@media (prefers-reduced-motion: reduce) {
|
|
595
595
|
.og-genie-phrase { animation: none; }
|
|
596
596
|
}
|
|
597
|
+
|
|
598
|
+
/* A single softly lit reel: motion stays inside the header's fixed footprint. */
|
|
599
|
+
.og-rolling-status { display:flex; align-items:center; gap:12px; min-width:0; width:100%; }
|
|
600
|
+
.og-rolling-window { position:relative; display:block; flex:1; min-width:0; height:24px; overflow:hidden; }
|
|
601
|
+
.og-rolling-face { position:absolute; inset:0; display:flex; align-items:center; }
|
|
602
|
+
.og-rolling-label { display:flex; align-items:center; gap:8px; min-width:0; width:100%; font-size:13px; font-weight:450; line-height:20px; color:var(--og-color-fg-muted); }
|
|
603
|
+
.og-rolling-label > svg { flex-shrink:0; }
|
|
604
|
+
.og-rolling-count { flex-shrink:0; font-size:11px; color:var(--og-color-fg-subtle); font-variant-numeric:tabular-nums; }
|
|
605
|
+
|
|
606
|
+
/* The complete text line rolls as one surface, without moving its layout box. */
|
|
607
|
+
.og-command-reel { display:flex; flex:1; align-items:center; gap:8px; min-width:0; transform-origin:50% 50%; }
|
|
608
|
+
/* Render reasoning Markdown as one clipped preview; full formatting lives inside. */
|
|
609
|
+
.og-reasoning-preview,
|
|
610
|
+
.og-reasoning-preview :is(div,p,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,pre) {
|
|
611
|
+
display: inline;
|
|
612
|
+
margin: 0;
|
|
613
|
+
padding: 0;
|
|
614
|
+
font-size: inherit;
|
|
615
|
+
line-height: inherit;
|
|
616
|
+
}
|
|
617
|
+
.og-reasoning-preview br { display: none; }
|
|
618
|
+
.og-reasoning-preview :is(p,li,h1,h2,h3,h4)::after { content: " "; }
|
|
619
|
+
|
|
620
|
+
/* Details consume leftover width; they never push the activity name away. */
|
|
621
|
+
.og-reel-title { flex:0 0 auto; min-width:0; max-width:75%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
622
|
+
.og-reel-title:only-child { max-width:100%; }
|
|
623
|
+
.og-reel-preview { flex:1 1 0%; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
|
624
|
+
|
|
625
|
+
/* Focused beam: one shared light source clipped to the entire text row. */
|
|
626
|
+
.og-command-reel-running,
|
|
627
|
+
.og-rolling-status[data-running="true"] .og-command-reel {
|
|
628
|
+
background-image:linear-gradient(90deg, light-dark(#898c94,#686b76) 42%, light-dark(#f0f1f4,#fff) 50%, light-dark(#898c94,#686b76) 58%);
|
|
629
|
+
background-size:300% 100%;
|
|
630
|
+
background-position:100% 0;
|
|
631
|
+
background-clip:text;
|
|
632
|
+
-webkit-background-clip:text;
|
|
633
|
+
-webkit-text-fill-color:transparent;
|
|
634
|
+
animation:og-activity-sweep 3.6s linear infinite;
|
|
635
|
+
}
|
|
636
|
+
@keyframes og-activity-sweep {
|
|
637
|
+
from { background-position:100% 0; }
|
|
638
|
+
to { background-position:0% 0; }
|
|
639
|
+
}
|
|
640
|
+
@media (prefers-reduced-motion:reduce), (forced-colors:active) {
|
|
641
|
+
.og-command-reel-running,
|
|
642
|
+
.og-rolling-status[data-running="true"] .og-command-reel {
|
|
643
|
+
animation:none; background:none; -webkit-text-fill-color:currentColor;
|
|
644
|
+
}
|
|
645
|
+
}
|