@workflow/web 5.0.0-beta.15 → 5.0.0-beta.16
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/build/client/assets/{highlighted-body-B3W2YXNL-BQ1pmB9V.js → highlighted-body-B3W2YXNL-QKf7Yrcl.js} +1 -1
- package/build/client/assets/{home-DmsdVk2U.js → home-C2tAadK2.js} +2 -2
- package/build/client/assets/{manifest-67209c1f.js → manifest-96e6bcc7.js} +1 -1
- package/build/client/assets/{mermaid-3ZIDBTTL-BMWEihLr.js → mermaid-3ZIDBTTL-DQJ4rkIZ.js} +933 -276
- package/build/client/assets/root-D1iC2mNY.css +1 -0
- package/build/client/assets/{root-BABNjrUh.js → root-QCHdCGTF.js} +1 -1
- package/build/client/assets/{run-detail-9xQOGhVk.js → run-detail-D4mcR51B.js} +201 -222
- package/build/client/assets/server-build-6KQbeuD8.css +1 -0
- package/build/client/assets/{workflow-graph-viewer-fgQ2XQ5R.js → workflow-graph-viewer-BEhdopGj.js} +4918 -4917
- package/build/server/assets/{app-DM9e_6xn.js → app-BxW1wRWj.js} +1 -1
- package/build/server/assets/{highlighted-body-B3W2YXNL-tYGHwGrY.js → highlighted-body-B3W2YXNL-CP6Zp179.js} +2 -2
- package/build/server/assets/{index-8Fb8OEQ2.js → index-Cxv7xPiz.js} +3 -3
- package/build/server/assets/{mermaid-3ZIDBTTL-EN1JYLRP.js → mermaid-3ZIDBTTL-BMFjZDcW.js} +2 -2
- package/build/server/assets/{server-build-CZXlov2m.js → server-build-B4JanZE6.js} +10829 -10028
- package/build/server/assets/{token-util-C02bLOPS.js → token-util-Cw2FB_2n.js} +2 -2
- package/build/server/assets/{token-CDoC3gHn.js → token-w6r7bnnd.js} +2 -2
- package/build/server/index.js +1 -1
- package/package.json +5 -5
- package/build/client/assets/root-Bqr5evzw.css +0 -1
- package/build/client/assets/server-build-Ik-p0gUh.css +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { q as Check, O as Copy,
|
|
3
|
-
import { c as createLucideIcon, N as
|
|
1
|
+
import { r as reactExports, j as jsxRuntimeExports, f as reactDomExports, G as ReactDOM, B as useNavigate, C as useSearchParams, A as Link, w as withComponentProps, H as useParams } from "./index-BXZSIDEp.js";
|
|
2
|
+
import { q as Check, O as Copy, j as ChevronRight, o as ChevronDown, C as CircleAlert, Q as parseStepName, B as parseWorkflowName, U as ErrorCard, V as format, Z as Zap, S as Send, R as ResolveHookModal, Y as Circle, p as ChevronUp, X, N as ErrorBoundary, I as unwrapServerActionResult, u as unwrapOrThrow, W as WorkflowWebAPIError, _ as useEscapeKeydown, t as composeEventHandlers, $ as useCallbackRef, a0 as useLayoutEffect2, s as useControllableState, a1 as useId, a2 as createContext2, v as Presence, x as createContextScope, l as hideOthers, m as ReactRemoveScroll, a3 as useFocusGuards, a4 as LAYOUT, a5 as wakeUpRun, r as resumeHook, A as Alert, c as AlertTitle, d as AlertDescription, a as Skeleton$1, a6 as RunActionsButtons, F as StatusBadge, e as CopyableText, b as RelativeTime, T as Tabs, K as TabsList, L as TabsTrigger, M as TabsContent, y as cancelRun, a7 as recreateRun } from "./workflow-graph-viewer-BEhdopGj.js";
|
|
3
|
+
import { c as createLucideIcon, N as cn, O as DataInspector, U as DecryptClickContext, W as Button, X as Spinner, Y as Lock, Z as RESERVED_ATTRIBUTE_KEY_PREFIX, _ as useHasContextCardProvider, $ as ContextCardProvider, a0 as ContextCardTrigger, g as useToast, a1 as Skeleton, a2 as Yr, a3 as isEncryptedMarker, a4 as formatDuration, a5 as _r, a6 as RunClickContext, a7 as StreamClickContext, a8 as isExpiredMarker, a9 as isDoStreamStep, aa as extractConversation, ab as hasEncryptedFields, ac as EVENT_DATA_REF_FIELDS, ad as useSidebarDataOptional, ae as clsx, af as useRowWindow, ag as isSpanDimmedBySearch, ah as ROW_HEIGHT_PX, ai as getSpanDurationMs, aj as formatDurationPrecise, ak as TooltipProvider, al as ActiveSpanProvider, am as useActiveSpan, an as useSidebarData, ao as searchSpans, ap as computeRootBounds, aq as computeTimeMarkers, ar as getHighResInMs, as as TIMELINE_PADDING_PX, at as Timeline, au as TimelineHeader, av as IconButton, aw as Tooltip, ax as TooltipTrigger, ay as TooltipContent, az as useReducedMotion, aA as SidebarDataProvider, aB as hydrateResourceIOWithKey, aC as hydrateResourceIO, aD as fetchHook, k as fetchEvents, G as fetchRun, aE as fetchStep, aF as fetchStreams, aG as Slot, F as useComposedRefs, aH as Slottable, d as cn$1, aI as buttonVariants, aJ as fetchEvent, aK as fetchEventsByCorrelationId, aL as isEncryptedData, aM as hydrateData, aN as getWebRevivers, T as Tooltip$1, a as TooltipTrigger$1, b as TooltipContent$1, aO as LIVE_UPDATE_INTERVAL_MS$1, u as useServerConfig, aP as getEncryptionKeyForRun, t as toast, L as LoaderCircle, aQ as StreamViewer } from "./mermaid-3ZIDBTTL-DQJ4rkIZ.js";
|
|
4
4
|
import { decrypt, importKey } from "./encryption-g14N5vQl.js";
|
|
5
5
|
import "./index-B6-SzLmT.js";
|
|
6
6
|
/**
|
|
@@ -104,10 +104,6 @@ function looksLikeWorkflowIdSearchInput(query) {
|
|
|
104
104
|
}
|
|
105
105
|
return /\d/.test(trimmed);
|
|
106
106
|
}
|
|
107
|
-
const STYLES$2 = `.wf-decrypt-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-decrypt-idle{color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400)}.wf-decrypt-idle:hover{background:var(--ds-gray-alpha-200)}.wf-decrypt-done{color:var(--ds-green-900);background:var(--ds-green-100);box-shadow:0 0 0 1px var(--ds-green-400);cursor:default}`;
|
|
108
|
-
function DecryptButton({ decrypted = false, loading = false, onClick }) {
|
|
109
|
-
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$2 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick: decrypted ? void 0 : onClick, disabled: decrypted || loading, className: `wf-decrypt-btn ${decrypted ? "wf-decrypt-done" : "wf-decrypt-idle"}`, children: [loading ? jsxRuntimeExports.jsx(Spinner, { size: 14 }) : decrypted ? jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })] }) : jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), loading ? "Decrypting…" : decrypted ? "Decrypted" : "Decrypt"] })] });
|
|
110
|
-
}
|
|
111
107
|
function CopyButton({ copyText, ariaLabel, className }) {
|
|
112
108
|
const [copied, setCopied] = reactExports.useState(false);
|
|
113
109
|
const timeoutRef = reactExports.useRef(null);
|
|
@@ -129,6 +125,112 @@ function CopyButton({ copyText, ariaLabel, className }) {
|
|
|
129
125
|
});
|
|
130
126
|
}, children: jsxRuntimeExports.jsxs("div", { className: "relative w-3 h-3", children: [jsxRuntimeExports.jsx("div", { className: cn("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-100 opacity-100" : "scale-0 opacity-0"), children: jsxRuntimeExports.jsx(Check, { className: "w-3 h-3" }) }), jsxRuntimeExports.jsx("div", { className: cn("absolute inset-0 flex items-center justify-center transition-all duration-150 ease-out", copied ? "scale-0 opacity-0" : "scale-100 opacity-100"), children: jsxRuntimeExports.jsx(Copy, { className: "w-3 h-3" }) })] }) });
|
|
131
127
|
}
|
|
128
|
+
const encryptedPlaceholderPreview = `{
|
|
129
|
+
"input": "[encrypted]",
|
|
130
|
+
"result": "[encrypted]"
|
|
131
|
+
}`;
|
|
132
|
+
function EncryptedDataBlock() {
|
|
133
|
+
const ctx = reactExports.useContext(DecryptClickContext);
|
|
134
|
+
return jsxRuntimeExports.jsxs("div", { className: "relative min-h-20 overflow-hidden rounded-md border border-gray-alpha-400 bg-background-100", children: [jsxRuntimeExports.jsx("pre", { "aria-hidden": "true", className: "pointer-events-none m-0 select-none p-3 font-mono text-label-12 text-gray-900 blur-[4px]", children: encryptedPlaceholderPreview }), jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: ctx ? jsxRuntimeExports.jsxs(Button, { onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, size: "xs", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] }) : jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-gray-alpha-400 bg-gray-100 px-1.5 py-0.5 text-button-12 font-medium text-gray-700", children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), "Encrypted"] }) })] });
|
|
135
|
+
}
|
|
136
|
+
const serializeForClipboard = (value) => {
|
|
137
|
+
if (typeof value === "string")
|
|
138
|
+
return value;
|
|
139
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
140
|
+
return String(value);
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
return JSON.stringify(value, null, 2);
|
|
144
|
+
} catch {
|
|
145
|
+
return String(value);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
function CopyableDataBlock({ data }) {
|
|
149
|
+
return jsxRuntimeExports.jsxs("div", { className: "relative overflow-x-auto rounded-md border border-gray-alpha-400 p-3", children: [jsxRuntimeExports.jsx(CopyButton, { copyText: serializeForClipboard(data), ariaLabel: "Copy data", className: "absolute right-2 top-2 z-10 flex h-6 w-6 items-center justify-center rounded-md border border-gray-alpha-400 !bg-background-100 p-0 text-gray-900 transition-transform transition-colors duration-100 hover:bg-gray-200 active:scale-95 active:bg-gray-300" }), jsxRuntimeExports.jsx(DataInspector, { data })] });
|
|
150
|
+
}
|
|
151
|
+
function DetailCard({ summary, children, onToggle, disabled = false, defaultOpen = false, variant = "section", trailing, summaryClassName, contentClassName }) {
|
|
152
|
+
const [open, setOpen] = reactExports.useState(defaultOpen);
|
|
153
|
+
const handleToggle = (e) => {
|
|
154
|
+
if (e.target !== e.currentTarget)
|
|
155
|
+
return;
|
|
156
|
+
const next = e.currentTarget.open;
|
|
157
|
+
setOpen(next);
|
|
158
|
+
onToggle == null ? void 0 : onToggle(next);
|
|
159
|
+
};
|
|
160
|
+
if (variant === "card") {
|
|
161
|
+
if (disabled) {
|
|
162
|
+
return jsxRuntimeExports.jsx("div", { className: cn("list-none px-3 py-4 bg-background-200 [&::-webkit-details-marker]:hidden", summaryClassName), style: { cursor: "not-allowed", opacity: 0.8 }, children: summary });
|
|
163
|
+
}
|
|
164
|
+
return jsxRuntimeExports.jsxs("details", { className: "group/card last:border-b border-gray-alpha-400", open, onToggle: handleToggle, children: [jsxRuntimeExports.jsx("summary", { className: cn("list-none cursor-pointer px-3 py-4 border-t border-gray-alpha-400 bg-background-200 hover:bg-gray-100 [&::-webkit-details-marker]:hidden", summaryClassName), children: jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: cn("shrink-0 text-gray-700 group-hover/card:text-gray-1000", open && "rotate-90") }), summary] }) }), jsxRuntimeExports.jsx("div", { className: contentClassName, children })] });
|
|
165
|
+
}
|
|
166
|
+
const rowClasses = "flex h-9 items-center gap-2 px-2 -mx-2 text-heading-14 font-medium my-2";
|
|
167
|
+
if (trailing) {
|
|
168
|
+
return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsxs("div", { className: cn(rowClasses, summaryClassName), children: [jsxRuntimeExports.jsx("div", { className: "isolate relative shrink-0 w-3.5 h-3.5 text-gray-700", children: jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" }) }), jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary }), jsxRuntimeExports.jsx("div", { className: "shrink-0 pr-1", children: trailing })] }) });
|
|
169
|
+
}
|
|
170
|
+
if (disabled) {
|
|
171
|
+
return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: cn(rowClasses, summaryClassName), style: { color: "var(--ds-gray-700)", cursor: "not-allowed" }, children: jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary }) }) });
|
|
172
|
+
}
|
|
173
|
+
return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsxs("details", { className: "group", open, onToggle: handleToggle, children: [jsxRuntimeExports.jsxs("summary", { className: cn("group/trigger list-none cursor-pointer rounded hover:bg-gray-alpha-100 [&::-webkit-details-marker]:hidden", rowClasses, summaryClassName), children: [jsxRuntimeExports.jsxs("div", { className: "isolate relative shrink-0 text-gray-700 group-hover/trigger:text-gray-1000 w-3.5 h-3.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-100 group-open:opacity-0" }), jsxRuntimeExports.jsx(ChevronDown, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0 group-open:opacity-100" })] }), jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary })] }), jsxRuntimeExports.jsx("div", { className: cn("mb-3", contentClassName), children })] }) });
|
|
174
|
+
}
|
|
175
|
+
const isReservedAttributeKey = (key) => key.startsWith(RESERVED_ATTRIBUTE_KEY_PREFIX);
|
|
176
|
+
function ReservedBadge() {
|
|
177
|
+
return jsxRuntimeExports.jsx("span", { className: "shrink-0 rounded border px-1 py-px text-[10px] font-medium leading-3", style: {
|
|
178
|
+
borderColor: "var(--ds-gray-alpha-400)",
|
|
179
|
+
backgroundColor: "var(--ds-gray-100)",
|
|
180
|
+
color: "var(--ds-gray-700)"
|
|
181
|
+
}, title: `Keys prefixed with "${RESERVED_ATTRIBUTE_KEY_PREFIX}" are reserved for framework and library code`, children: "Reserved" });
|
|
182
|
+
}
|
|
183
|
+
function AttributeRow({ attributeKey, value, removed = false }) {
|
|
184
|
+
const reserved = isReservedAttributeKey(attributeKey);
|
|
185
|
+
return jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3 py-1.5", children: [jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 items-center gap-1.5 text-label-12 font-mono", style: {
|
|
186
|
+
color: reserved ? "var(--ds-gray-700)" : "var(--ds-gray-900)"
|
|
187
|
+
}, children: [jsxRuntimeExports.jsx("span", { className: "truncate", children: attributeKey }), reserved && jsxRuntimeExports.jsx(ReservedBadge, {})] }), removed ? jsxRuntimeExports.jsx("span", { className: "shrink-0 text-label-12 italic", style: { color: "var(--ds-gray-700)" }, children: "removed" }) : jsxRuntimeExports.jsx("span", { className: "max-w-[60%] truncate text-right text-label-12 font-mono text-gray-1000", title: value, children: value })] });
|
|
188
|
+
}
|
|
189
|
+
function sortAttributeKeys(keys) {
|
|
190
|
+
return [...keys].sort((a, b) => {
|
|
191
|
+
const aReserved = isReservedAttributeKey(a);
|
|
192
|
+
const bReserved = isReservedAttributeKey(b);
|
|
193
|
+
if (aReserved !== bReserved)
|
|
194
|
+
return aReserved ? 1 : -1;
|
|
195
|
+
return a.localeCompare(b);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
function RunAttributesCard({ attributes }) {
|
|
199
|
+
const keys = sortAttributeKeys(Object.keys(attributes));
|
|
200
|
+
if (keys.length === 0)
|
|
201
|
+
return null;
|
|
202
|
+
return jsxRuntimeExports.jsx(DetailCard, { summary: `Attributes (${keys.length})`, defaultOpen: true, contentClassName: "mb-0", children: jsxRuntimeExports.jsx("div", { className: "flex flex-col divide-y divide-gray-alpha-400", children: keys.map((key) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: key, value: attributes[key] }, key)) }) });
|
|
203
|
+
}
|
|
204
|
+
function isAttrSetEventData(data) {
|
|
205
|
+
if (data === null || typeof data !== "object")
|
|
206
|
+
return false;
|
|
207
|
+
const record = data;
|
|
208
|
+
return Array.isArray(record.changes) && record.changes.every((c) => c !== null && typeof c === "object" && typeof c.key === "string");
|
|
209
|
+
}
|
|
210
|
+
function describeWriter(writer) {
|
|
211
|
+
if (!writer)
|
|
212
|
+
return null;
|
|
213
|
+
if (writer.type === "workflow")
|
|
214
|
+
return "Set by workflow";
|
|
215
|
+
if (writer.type === "step") {
|
|
216
|
+
return `Set by step ${writer.stepId} (attempt ${writer.attempt})`;
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
function AttrSetEventBlock({ data }) {
|
|
221
|
+
if (!isAttrSetEventData(data)) {
|
|
222
|
+
return jsxRuntimeExports.jsx(CopyableDataBlock, { data });
|
|
223
|
+
}
|
|
224
|
+
const writerLabel = describeWriter(data.writer);
|
|
225
|
+
return jsxRuntimeExports.jsxs("div", { className: "flex flex-col px-3 py-1", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col divide-y divide-gray-alpha-400", children: data.changes.map((change, index) => jsxRuntimeExports.jsx(AttributeRow, { attributeKey: change.key, removed: change.value === null, value: change.value ?? void 0 }, `${change.key}:${index}`)) }), writerLabel && jsxRuntimeExports.jsx("div", { className: "border-t py-1.5 text-label-12", style: {
|
|
226
|
+
borderColor: "var(--ds-gray-alpha-400)",
|
|
227
|
+
color: "var(--ds-gray-700)"
|
|
228
|
+
}, children: writerLabel })] });
|
|
229
|
+
}
|
|
230
|
+
const STYLES$2 = `.wf-decrypt-btn{appearance:none;-webkit-appearance:none;border:none;display:inline-flex;align-items:center;justify-content:center;height:40px;padding:0 12px;border-radius:6px;font-size:14px;font-weight:500;line-height:20px;cursor:pointer;white-space:nowrap;gap:6px;transition:background 150ms}.wf-decrypt-idle{color:var(--ds-gray-1000);background:var(--ds-background-100);box-shadow:0 0 0 1px var(--ds-gray-400)}.wf-decrypt-idle:hover{background:var(--ds-gray-alpha-200)}.wf-decrypt-done{color:var(--ds-green-900);background:var(--ds-green-100);box-shadow:0 0 0 1px var(--ds-green-400);cursor:default}`;
|
|
231
|
+
function DecryptButton({ decrypted = false, loading = false, onClick }) {
|
|
232
|
+
return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("style", { dangerouslySetInnerHTML: { __html: STYLES$2 } }), jsxRuntimeExports.jsxs("button", { type: "button", onClick: decrypted ? void 0 : onClick, disabled: decrypted || loading, className: `wf-decrypt-btn ${decrypted ? "wf-decrypt-done" : "wf-decrypt-idle"}`, children: [loading ? jsxRuntimeExports.jsx(Spinner, { size: 14 }) : decrypted ? jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })] }) : jsxRuntimeExports.jsxs("svg", { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntimeExports.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }), jsxRuntimeExports.jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })] }), loading ? "Decrypting…" : decrypted ? "Decrypted" : "Decrypt"] })] });
|
|
233
|
+
}
|
|
132
234
|
function isStructuredError(value) {
|
|
133
235
|
return value != null && typeof value === "object" && (typeof value.message === "string" || typeof value.stack === "string");
|
|
134
236
|
}
|
|
@@ -231,17 +333,45 @@ function formatTimeDifference(diff) {
|
|
|
231
333
|
function useTimeAgo(date) {
|
|
232
334
|
const [timeAgo, setTimeAgo] = reactExports.useState("");
|
|
233
335
|
reactExports.useEffect(() => {
|
|
234
|
-
const
|
|
336
|
+
const updateTimeAgo = () => {
|
|
235
337
|
const diff = Date.now() - date;
|
|
236
|
-
const
|
|
237
|
-
setTimeAgo(
|
|
338
|
+
const formattedDiff = formatTimeDifference(diff);
|
|
339
|
+
setTimeAgo(formattedDiff ? `${formattedDiff} ago` : "Just now");
|
|
238
340
|
};
|
|
239
|
-
|
|
240
|
-
const timer = setInterval(
|
|
341
|
+
updateTimeAgo();
|
|
342
|
+
const timer = setInterval(updateTimeAgo, 1e3);
|
|
241
343
|
return () => clearInterval(timer);
|
|
242
344
|
}, [date]);
|
|
243
345
|
return timeAgo;
|
|
244
346
|
}
|
|
347
|
+
function useShortTimeAgo(date) {
|
|
348
|
+
const [shortTimeAgo, setShortTimeAgo] = reactExports.useState("");
|
|
349
|
+
reactExports.useEffect(() => {
|
|
350
|
+
if (!date) {
|
|
351
|
+
setShortTimeAgo("");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const updateShortTimeAgo = () => {
|
|
355
|
+
const diff = Date.now() - date;
|
|
356
|
+
const days = Math.floor(diff / (1e3 * 60 * 60 * 24));
|
|
357
|
+
const hours = Math.floor(diff / (1e3 * 60 * 60));
|
|
358
|
+
const minutes = Math.floor(diff / (1e3 * 60));
|
|
359
|
+
if (days > 0) {
|
|
360
|
+
setShortTimeAgo(`${days} day${days > 1 ? "s" : ""} ago`);
|
|
361
|
+
} else if (hours > 0) {
|
|
362
|
+
setShortTimeAgo(`${hours} hour${hours > 1 ? "s" : ""} ago`);
|
|
363
|
+
} else if (minutes > 0) {
|
|
364
|
+
setShortTimeAgo(`${minutes} minute${minutes > 1 ? "s" : ""} ago`);
|
|
365
|
+
} else {
|
|
366
|
+
setShortTimeAgo("Just now");
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
updateShortTimeAgo();
|
|
370
|
+
const timer = setInterval(updateShortTimeAgo, 6e4);
|
|
371
|
+
return () => clearInterval(timer);
|
|
372
|
+
}, [date]);
|
|
373
|
+
return shortTimeAgo;
|
|
374
|
+
}
|
|
245
375
|
function ZoneDateTimeRow({ date, zone }) {
|
|
246
376
|
var _a;
|
|
247
377
|
const dateObj = new Date(date);
|
|
@@ -261,133 +391,30 @@ function ZoneDateTimeRow({ date, zone }) {
|
|
|
261
391
|
minute: "2-digit",
|
|
262
392
|
second: "2-digit"
|
|
263
393
|
});
|
|
264
|
-
return jsxRuntimeExports.jsxs("div", {
|
|
265
|
-
display: "flex",
|
|
266
|
-
alignItems: "center",
|
|
267
|
-
justifyContent: "space-between",
|
|
268
|
-
gap: 12
|
|
269
|
-
}, children: [jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [jsxRuntimeExports.jsx("div", { style: {
|
|
270
|
-
display: "inline-flex",
|
|
271
|
-
alignItems: "center",
|
|
272
|
-
justifyContent: "center",
|
|
273
|
-
height: 16,
|
|
274
|
-
padding: "0 6px",
|
|
275
|
-
backgroundColor: "var(--ds-gray-200)",
|
|
276
|
-
borderRadius: 3,
|
|
277
|
-
fontSize: 11,
|
|
278
|
-
fontFamily: "var(--font-mono, monospace)",
|
|
279
|
-
fontWeight: 500,
|
|
280
|
-
color: "var(--ds-gray-900)",
|
|
281
|
-
whiteSpace: "nowrap"
|
|
282
|
-
}, children: formattedZone }), jsxRuntimeExports.jsx("span", { style: {
|
|
283
|
-
fontSize: 13,
|
|
284
|
-
color: "var(--ds-gray-1000)",
|
|
285
|
-
whiteSpace: "nowrap"
|
|
286
|
-
}, children: formattedDate })] }), jsxRuntimeExports.jsx("span", { style: {
|
|
287
|
-
fontSize: 11,
|
|
288
|
-
fontFamily: "var(--font-mono, monospace)",
|
|
289
|
-
fontVariantNumeric: "tabular-nums",
|
|
290
|
-
color: "var(--ds-gray-900)",
|
|
291
|
-
whiteSpace: "nowrap"
|
|
292
|
-
}, children: formattedTime })] });
|
|
394
|
+
return jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-4 px-1.5 bg-gray-200 rounded-xs", children: jsxRuntimeExports.jsx("span", { className: "text-[12px] font-mono text-gray-900", children: formattedZone }) }), jsxRuntimeExports.jsx("span", { className: "text-[13px] text-gray-1000", children: formattedDate })] }), jsxRuntimeExports.jsx("span", { className: "tabular-nums text-[12px] font-mono text-gray-900", children: formattedTime })] });
|
|
293
395
|
}
|
|
294
|
-
function
|
|
396
|
+
function RelativeTimeContextCardContent({ date }) {
|
|
295
397
|
const localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
296
398
|
const timeAgo = useTimeAgo(date);
|
|
297
|
-
return jsxRuntimeExports.jsxs("div", {
|
|
298
|
-
display: "flex",
|
|
299
|
-
flexDirection: "column",
|
|
300
|
-
gap: 12,
|
|
301
|
-
minWidth: 300,
|
|
302
|
-
padding: "12px 14px"
|
|
303
|
-
}, children: [jsxRuntimeExports.jsx("span", { style: {
|
|
304
|
-
fontSize: 13,
|
|
305
|
-
fontVariantNumeric: "tabular-nums",
|
|
306
|
-
color: "var(--ds-gray-900)"
|
|
307
|
-
}, children: timeAgo }), jsxRuntimeExports.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [jsxRuntimeExports.jsx(ZoneDateTimeRow, { date, zone: "UTC" }), jsxRuntimeExports.jsx(ZoneDateTimeRow, { date, zone: localTimezone })] })] });
|
|
308
|
-
}
|
|
309
|
-
const TOOLTIP_WIDTH = 330;
|
|
310
|
-
const VIEWPORT_PAD = 8;
|
|
311
|
-
function TooltipPortal({ triggerRect, onMouseEnter, onMouseLeave, date }) {
|
|
312
|
-
const tooltipRef = reactExports.useRef(null);
|
|
313
|
-
const [style, setStyle] = reactExports.useState({
|
|
314
|
-
position: "fixed",
|
|
315
|
-
zIndex: 9999,
|
|
316
|
-
visibility: "hidden"
|
|
317
|
-
});
|
|
318
|
-
reactExports.useEffect(() => {
|
|
319
|
-
const placement = triggerRect.top > 240 ? "above" : "below";
|
|
320
|
-
const centerX = triggerRect.left + triggerRect.width / 2;
|
|
321
|
-
const el = tooltipRef.current;
|
|
322
|
-
const w = el ? el.offsetWidth : TOOLTIP_WIDTH;
|
|
323
|
-
const h = el ? el.offsetHeight : 100;
|
|
324
|
-
let left = centerX - w / 2;
|
|
325
|
-
left = Math.max(VIEWPORT_PAD, Math.min(left, window.innerWidth - w - VIEWPORT_PAD));
|
|
326
|
-
let top;
|
|
327
|
-
if (placement === "above") {
|
|
328
|
-
top = triggerRect.top - h - 6;
|
|
329
|
-
if (top < VIEWPORT_PAD) {
|
|
330
|
-
top = triggerRect.bottom + 6;
|
|
331
|
-
}
|
|
332
|
-
} else {
|
|
333
|
-
top = triggerRect.bottom + 6;
|
|
334
|
-
if (top + h > window.innerHeight - VIEWPORT_PAD) {
|
|
335
|
-
top = triggerRect.top - h - 6;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
setStyle({
|
|
339
|
-
position: "fixed",
|
|
340
|
-
left,
|
|
341
|
-
top,
|
|
342
|
-
zIndex: 9999,
|
|
343
|
-
borderRadius: 10,
|
|
344
|
-
border: "1px solid var(--ds-gray-alpha-200)",
|
|
345
|
-
backgroundColor: "var(--ds-background-100)",
|
|
346
|
-
boxShadow: "0 4px 12px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.06)",
|
|
347
|
-
visibility: "visible"
|
|
348
|
-
});
|
|
349
|
-
}, [triggerRect]);
|
|
350
|
-
return reactDomExports.createPortal(
|
|
351
|
-
// biome-ignore lint/a11y/noStaticElementInteractions: tooltip hover zone
|
|
352
|
-
jsxRuntimeExports.jsx("div", { ref: tooltipRef, onMouseEnter, onMouseLeave, style, children: jsxRuntimeExports.jsx(TimestampTooltipContent, { date }) }),
|
|
353
|
-
document.body
|
|
354
|
-
);
|
|
399
|
+
return jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 min-w-[300px]", children: [jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-3", children: jsxRuntimeExports.jsx("span", { className: "tabular-nums text-[13px] text-gray-900", children: timeAgo }) }), jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [jsxRuntimeExports.jsx(ZoneDateTimeRow, { date, zone: "UTC" }), jsxRuntimeExports.jsx(ZoneDateTimeRow, { date, zone: localTimezone })] })] });
|
|
355
400
|
}
|
|
356
|
-
function
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
401
|
+
function DefaultTimeText({ date }) {
|
|
402
|
+
const shortTimeAgo = useShortTimeAgo(date);
|
|
403
|
+
return jsxRuntimeExports.jsx("span", { className: "text-label-14 text-gray-900", children: shortTimeAgo });
|
|
404
|
+
}
|
|
405
|
+
function RelativeTimeCard({ date, children: _children, ...props }) {
|
|
406
|
+
const children = _children === void 0 ? jsxRuntimeExports.jsx(DefaultTimeText, { date }) : _children;
|
|
407
|
+
if (!date)
|
|
408
|
+
return children;
|
|
409
|
+
return jsxRuntimeExports.jsx(ContextCardTrigger, { content: jsxRuntimeExports.jsx(RelativeTimeContextCardContent, { date }), ...props, children });
|
|
410
|
+
}
|
|
411
|
+
function TimestampTooltip({ date, children, side = "top" }) {
|
|
412
|
+
const hasProvider = useHasContextCardProvider();
|
|
367
413
|
const ts = date == null ? null : typeof date === "number" ? date : new Date(date).getTime();
|
|
368
414
|
if (ts == null || Number.isNaN(ts))
|
|
369
415
|
return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children });
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
clearTimeout(closeTimer.current);
|
|
373
|
-
closeTimer.current = null;
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
const scheduleClose = () => {
|
|
377
|
-
cancelClose();
|
|
378
|
-
closeTimer.current = setTimeout(() => setOpen(false), 120);
|
|
379
|
-
};
|
|
380
|
-
const handleOpen = () => {
|
|
381
|
-
cancelClose();
|
|
382
|
-
if (triggerRef.current) {
|
|
383
|
-
setTriggerRect(triggerRef.current.getBoundingClientRect());
|
|
384
|
-
}
|
|
385
|
-
setOpen(true);
|
|
386
|
-
};
|
|
387
|
-
return (
|
|
388
|
-
// biome-ignore lint/a11y/noStaticElementInteractions: tooltip trigger
|
|
389
|
-
jsxRuntimeExports.jsxs("span", { ref: triggerRef, onMouseEnter: handleOpen, onMouseLeave: scheduleClose, style: { display: "inline-flex" }, children: [children, open && triggerRect && jsxRuntimeExports.jsx(TooltipPortal, { triggerRect, onMouseEnter: cancelClose, onMouseLeave: scheduleClose, date: ts })] })
|
|
390
|
-
);
|
|
416
|
+
const card = jsxRuntimeExports.jsx(RelativeTimeCard, { date: ts, side, asChild: true, children });
|
|
417
|
+
return hasProvider ? card : jsxRuntimeExports.jsx(ContextCardProvider, { children: card });
|
|
391
418
|
}
|
|
392
419
|
const ERROR_EVENT_TYPES$1 = /* @__PURE__ */ new Set([
|
|
393
420
|
"step_failed",
|
|
@@ -423,6 +450,9 @@ function getStatusDotColor(eventType) {
|
|
|
423
450
|
if (eventType === "step_retrying") {
|
|
424
451
|
return "var(--ds-amber-700)";
|
|
425
452
|
}
|
|
453
|
+
if (eventType === "attr_set") {
|
|
454
|
+
return "var(--ds-teal-900)";
|
|
455
|
+
}
|
|
426
456
|
if (eventType === "step_completed" || eventType === "run_completed" || eventType === "workflow_completed" || eventType === "hook_disposed" || eventType === "wait_completed") {
|
|
427
457
|
return "var(--ds-green-700)";
|
|
428
458
|
}
|
|
@@ -497,7 +527,9 @@ function hasEncryptedValues(data) {
|
|
|
497
527
|
return false;
|
|
498
528
|
}
|
|
499
529
|
function isRunLevel(eventType) {
|
|
500
|
-
return eventType === "run_created" || eventType === "run_started" || eventType === "run_completed" || eventType === "run_failed" || eventType === "run_cancelled" || eventType === "workflow_started" || eventType === "workflow_completed" || eventType === "workflow_failed"
|
|
530
|
+
return eventType === "run_created" || eventType === "run_started" || eventType === "run_completed" || eventType === "run_failed" || eventType === "run_cancelled" || eventType === "workflow_started" || eventType === "workflow_completed" || eventType === "workflow_failed" || // attr_set carries a dedup correlationId rather than a child entity ID,
|
|
531
|
+
// so it groups and labels with the run itself.
|
|
532
|
+
eventType === "attr_set";
|
|
501
533
|
}
|
|
502
534
|
const GUTTER_WIDTH = 36;
|
|
503
535
|
const LANE_X = 20;
|
|
@@ -665,6 +697,9 @@ function PayloadBlock({ data, eventType }) {
|
|
|
665
697
|
if (structuredError) {
|
|
666
698
|
return jsxRuntimeExports.jsx("div", { className: "p-2", children: jsxRuntimeExports.jsx(ErrorStackBlock, { value: structuredError }) });
|
|
667
699
|
}
|
|
700
|
+
if (eventType === "attr_set") {
|
|
701
|
+
return jsxRuntimeExports.jsx(AttrSetEventBlock, { data: cleaned });
|
|
702
|
+
}
|
|
668
703
|
return jsxRuntimeExports.jsxs("div", { className: "relative group/payload", children: [jsxRuntimeExports.jsx("div", { className: "overflow-x-auto p-2 text-[11px]", style: { color: "var(--ds-gray-1000)" }, children: jsxRuntimeExports.jsx(DataInspector, { data: cleaned, expandLevel: 2 }) }), jsxRuntimeExports.jsx("button", { type: "button", onClick: handleCopy, className: "absolute bottom-2 right-2 opacity-0 group-hover/payload:opacity-100 transition-opacity flex items-center gap-1 px-2 py-1 rounded-md text-xs hover:bg-[var(--ds-gray-alpha-200)]", style: { ...BUTTON_RESET_STYLE, color: "var(--ds-gray-700)" }, "aria-label": "Copy payload", children: copied ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Check, { className: "h-3 w-3", style: { color: "var(--ds-green-700)" } }), jsxRuntimeExports.jsx("span", { style: { color: "var(--ds-green-700)" }, children: "Copied" })] }) : jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Copy" })] }) })] });
|
|
669
704
|
}
|
|
670
705
|
const SORT_OPTIONS = [
|
|
@@ -830,7 +865,7 @@ function EventRow$1({ event, index, isFirst, isLast, isExpanded, onToggleExpand,
|
|
|
830
865
|
color: "var(--ds-red-900)"
|
|
831
866
|
}, children: loadError }) : isLoading || loadedEventData === null && !hasAttemptedLoad && event.correlationId ? jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 p-3", children: [jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "75%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "50%" } }), jsxRuntimeExports.jsx(Skeleton, { className: "h-3", style: { width: "60%" } })] }) : jsxRuntimeExports.jsx("div", { className: "p-2 text-xs", style: { color: "var(--ds-gray-900)" }, children: "No data" })] })] })] });
|
|
832
867
|
}
|
|
833
|
-
function
|
|
868
|
+
function EventListViewInner({ events, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, onExactIdSearch }) {
|
|
834
869
|
const toast2 = useToast();
|
|
835
870
|
const [internalSortOrder, setInternalSortOrder] = reactExports.useState("asc");
|
|
836
871
|
const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
|
|
@@ -1098,6 +1133,9 @@ function EventListView({ events, run, onLoadEventData, hasMoreEvents = false, is
|
|
|
1098
1133
|
backgroundColor: "var(--ds-background-100)"
|
|
1099
1134
|
}, children: [jsxRuntimeExports.jsx("span", { children: isExactSearchActive ? searchError ? searchError : searchNotFound ? `No events found for ${searchQuery.trim()}` : `${sortedEvents.length} event${sortedEvents.length !== 1 ? "s" : ""} for ${searchQuery.trim()}${searchResultsTruncated ? " (results may be truncated)" : ""}` : `${sortedEvents.length} event${sortedEvents.length !== 1 ? "s" : ""} loaded` }), !isExactSearchActive && hasMoreEvents && jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: jsxRuntimeExports.jsx("div", { className: "pointer-events-auto", children: jsxRuntimeExports.jsx(LoadMoreButton, { loading: isLoadingMoreEvents, onClick: () => void (onLoadMoreEvents == null ? void 0 : onLoadMoreEvents()) }) }) })] })] }) });
|
|
1100
1135
|
}
|
|
1136
|
+
function EventListView(props) {
|
|
1137
|
+
return jsxRuntimeExports.jsx(ContextCardProvider, { children: jsxRuntimeExports.jsx(EventListViewInner, { ...props }) });
|
|
1138
|
+
}
|
|
1101
1139
|
function shouldShowVerticalLine(eventType) {
|
|
1102
1140
|
if (eventType === "hook_created" || eventType === "hook_received" || eventType === "hook_disposed") {
|
|
1103
1141
|
return true;
|
|
@@ -1150,7 +1188,8 @@ const MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1150
1188
|
"step_failed",
|
|
1151
1189
|
"run_failed",
|
|
1152
1190
|
"wait_created",
|
|
1153
|
-
"wait_completed"
|
|
1191
|
+
"wait_completed",
|
|
1192
|
+
"attr_set"
|
|
1154
1193
|
]);
|
|
1155
1194
|
function convertEventsToSpanEvents(events, filterTypes = true) {
|
|
1156
1195
|
return events.filter((event) => filterTypes ? MARKER_EVENT_TYPES.has(event.eventType) : true).map((event) => ({
|
|
@@ -1385,6 +1424,15 @@ function runToSpan(run, runEvents, nowTime) {
|
|
|
1385
1424
|
const isStepEvent = (eventType) => eventType.startsWith("step_");
|
|
1386
1425
|
const isTimerEvent = (eventType) => eventType === "wait_created" || eventType === "wait_completed";
|
|
1387
1426
|
const isHookLifecycleEvent = (eventType) => eventType === "hook_received" || eventType === "hook_created" || eventType === "hook_disposed";
|
|
1427
|
+
const isRunLevelEvent = (event) => !event.correlationId || !isTimerEvent(event.eventType) && !isHookLifecycleEvent(event.eventType) && !isStepEvent(event.eventType);
|
|
1428
|
+
function filterSpanRawEvents(events, resource, spanId) {
|
|
1429
|
+
if (resource === "run") {
|
|
1430
|
+
return events.filter(isRunLevelEvent);
|
|
1431
|
+
}
|
|
1432
|
+
if (!spanId)
|
|
1433
|
+
return [];
|
|
1434
|
+
return events.filter((e) => e.correlationId === spanId);
|
|
1435
|
+
}
|
|
1388
1436
|
function pushEvent(map, correlationId, event) {
|
|
1389
1437
|
const existing = map.get(correlationId);
|
|
1390
1438
|
if (existing) {
|
|
@@ -1865,53 +1913,6 @@ function parseContent(content) {
|
|
|
1865
1913
|
}
|
|
1866
1914
|
return [];
|
|
1867
1915
|
}
|
|
1868
|
-
const encryptedPlaceholderPreview = `{
|
|
1869
|
-
"input": "[encrypted]",
|
|
1870
|
-
"result": "[encrypted]"
|
|
1871
|
-
}`;
|
|
1872
|
-
function EncryptedDataBlock() {
|
|
1873
|
-
const ctx = reactExports.useContext(DecryptClickContext);
|
|
1874
|
-
return jsxRuntimeExports.jsxs("div", { className: "relative min-h-20 overflow-hidden rounded-md border border-gray-alpha-400 bg-background-100", children: [jsxRuntimeExports.jsx("pre", { "aria-hidden": "true", className: "pointer-events-none m-0 select-none p-3 font-mono text-label-12 text-gray-900 blur-[4px]", children: encryptedPlaceholderPreview }), jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: ctx ? jsxRuntimeExports.jsxs(Button, { onClick: ctx.onDecrypt, disabled: ctx.isDecrypting, size: "xs", children: [ctx.isDecrypting ? jsxRuntimeExports.jsx(Spinner, { size: 10 }) : jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), jsxRuntimeExports.jsx("span", { children: "Decrypt" })] }) : jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-gray-alpha-400 bg-gray-100 px-1.5 py-0.5 text-button-12 font-medium text-gray-700", children: [jsxRuntimeExports.jsx(Lock, { className: "h-3 w-3" }), "Encrypted"] }) })] });
|
|
1875
|
-
}
|
|
1876
|
-
const serializeForClipboard = (value) => {
|
|
1877
|
-
if (typeof value === "string")
|
|
1878
|
-
return value;
|
|
1879
|
-
if (typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
1880
|
-
return String(value);
|
|
1881
|
-
}
|
|
1882
|
-
try {
|
|
1883
|
-
return JSON.stringify(value, null, 2);
|
|
1884
|
-
} catch {
|
|
1885
|
-
return String(value);
|
|
1886
|
-
}
|
|
1887
|
-
};
|
|
1888
|
-
function CopyableDataBlock({ data }) {
|
|
1889
|
-
return jsxRuntimeExports.jsxs("div", { className: "relative overflow-x-auto rounded-md border border-gray-alpha-400 p-3", children: [jsxRuntimeExports.jsx(CopyButton, { copyText: serializeForClipboard(data), ariaLabel: "Copy data", className: "absolute right-2 top-2 z-10 flex h-6 w-6 items-center justify-center rounded-md border border-gray-alpha-400 !bg-background-100 p-0 text-gray-900 transition-transform transition-colors duration-100 hover:bg-gray-200 active:scale-95 active:bg-gray-300" }), jsxRuntimeExports.jsx(DataInspector, { data })] });
|
|
1890
|
-
}
|
|
1891
|
-
function DetailCard({ summary, children, onToggle, disabled = false, defaultOpen = false, variant = "section", trailing, summaryClassName, contentClassName }) {
|
|
1892
|
-
const [open, setOpen] = reactExports.useState(defaultOpen);
|
|
1893
|
-
const handleToggle = (e) => {
|
|
1894
|
-
if (e.target !== e.currentTarget)
|
|
1895
|
-
return;
|
|
1896
|
-
const next = e.currentTarget.open;
|
|
1897
|
-
setOpen(next);
|
|
1898
|
-
onToggle == null ? void 0 : onToggle(next);
|
|
1899
|
-
};
|
|
1900
|
-
if (variant === "card") {
|
|
1901
|
-
if (disabled) {
|
|
1902
|
-
return jsxRuntimeExports.jsx("div", { className: cn("list-none px-3 py-4 bg-background-200 [&::-webkit-details-marker]:hidden", summaryClassName), style: { cursor: "not-allowed", opacity: 0.8 }, children: summary });
|
|
1903
|
-
}
|
|
1904
|
-
return jsxRuntimeExports.jsxs("details", { className: "group/card last:border-b border-gray-alpha-400", open, onToggle: handleToggle, children: [jsxRuntimeExports.jsx("summary", { className: cn("list-none cursor-pointer px-3 py-4 border-t border-gray-alpha-400 bg-background-200 hover:bg-gray-100 [&::-webkit-details-marker]:hidden", summaryClassName), children: jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: cn("shrink-0 text-gray-700 group-hover/card:text-gray-1000", open && "rotate-90") }), summary] }) }), jsxRuntimeExports.jsx("div", { className: contentClassName, children })] });
|
|
1905
|
-
}
|
|
1906
|
-
const rowClasses = "flex h-9 items-center gap-2 px-2 -mx-2 text-heading-14 font-medium my-2";
|
|
1907
|
-
if (trailing) {
|
|
1908
|
-
return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsxs("div", { className: cn(rowClasses, summaryClassName), children: [jsxRuntimeExports.jsx("div", { className: "isolate relative shrink-0 w-3.5 h-3.5 text-gray-700", children: jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2" }) }), jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary }), jsxRuntimeExports.jsx("div", { className: "shrink-0 pr-1", children: trailing })] }) });
|
|
1909
|
-
}
|
|
1910
|
-
if (disabled) {
|
|
1911
|
-
return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsx("div", { className: cn(rowClasses, summaryClassName), style: { color: "var(--ds-gray-700)", cursor: "not-allowed" }, children: jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary }) }) });
|
|
1912
|
-
}
|
|
1913
|
-
return jsxRuntimeExports.jsx("section", { className: "-mx-4 border-t px-4 border-gray-alpha-400", children: jsxRuntimeExports.jsxs("details", { className: "group", open, onToggle: handleToggle, children: [jsxRuntimeExports.jsxs("summary", { className: cn("group/trigger list-none cursor-pointer rounded hover:bg-gray-alpha-100 [&::-webkit-details-marker]:hidden", rowClasses, summaryClassName), children: [jsxRuntimeExports.jsxs("div", { className: "isolate relative shrink-0 text-gray-700 group-hover/trigger:text-gray-1000 w-3.5 h-3.5", children: [jsxRuntimeExports.jsx(ChevronRight, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-100 group-open:opacity-0" }), jsxRuntimeExports.jsx(ChevronDown, { size: 14, className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0 group-open:opacity-100" })] }), jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1", children: summary })] }), jsxRuntimeExports.jsx("div", { className: cn("mb-3", contentClassName), children })] }) });
|
|
1914
|
-
}
|
|
1915
1916
|
function TabButton({ active, onClick, children }) {
|
|
1916
1917
|
return jsxRuntimeExports.jsx("button", { type: "button", role: "tab", "aria-selected": active, tabIndex: active ? 0 : -1, onClick, className: "px-3 py-1.5 text-[11px] font-medium transition-colors -mb-px", style: {
|
|
1917
1918
|
// Explicit styles to prevent app-level button overrides when web-shared
|
|
@@ -2074,15 +2075,7 @@ const parseDateValue = (value) => {
|
|
|
2074
2075
|
const date = typeof value === "number" ? new Date(value) : new Date(String(value));
|
|
2075
2076
|
return Number.isNaN(date.getTime()) ? null : date;
|
|
2076
2077
|
};
|
|
2077
|
-
const formatLocalMillisecondTime = (date) => date.
|
|
2078
|
-
year: "numeric",
|
|
2079
|
-
month: "numeric",
|
|
2080
|
-
day: "numeric",
|
|
2081
|
-
hour: "numeric",
|
|
2082
|
-
minute: "numeric",
|
|
2083
|
-
second: "numeric",
|
|
2084
|
-
fractionalSecondDigits: 3
|
|
2085
|
-
});
|
|
2078
|
+
const formatLocalMillisecondTime = (date) => format(date, "MMM dd HH:mm:ss.SS OO").toUpperCase();
|
|
2086
2079
|
const localMillisecondTimeOrNull = (value) => {
|
|
2087
2080
|
const date = parseDateValue(value);
|
|
2088
2081
|
if (!date) {
|
|
@@ -2128,13 +2121,13 @@ const attributeToDisplayFn = {
|
|
|
2128
2121
|
projectId: (_value) => null,
|
|
2129
2122
|
environment: (_value) => null,
|
|
2130
2123
|
executionContext: (_value) => null,
|
|
2131
|
-
// Attributes
|
|
2132
|
-
// Rendered in its own collapsible DetailCard;
|
|
2133
|
-
// by the hasDisplayContent gate.
|
|
2124
|
+
// Attributes — string-string metadata attached to the run.
|
|
2125
|
+
// Rendered as key-value rows in its own collapsible DetailCard;
|
|
2126
|
+
// if empty/missing, hidden by the hasDisplayContent gate.
|
|
2134
2127
|
attributes: (value) => {
|
|
2135
2128
|
if (!hasDisplayContent(value))
|
|
2136
2129
|
return null;
|
|
2137
|
-
return jsxRuntimeExports.jsx(
|
|
2130
|
+
return jsxRuntimeExports.jsx(RunAttributesCard, { attributes: value });
|
|
2138
2131
|
},
|
|
2139
2132
|
// Dates — wrapped with TimestampTooltip showing UTC/local + relative time
|
|
2140
2133
|
createdAt: timestampWithTooltipOrNull,
|
|
@@ -2348,7 +2341,7 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expiredAt, on
|
|
|
2348
2341
|
isDecrypting,
|
|
2349
2342
|
hasEncryptedData: outerDecryptCtx == null ? void 0 : outerDecryptCtx.hasEncryptedData
|
|
2350
2343
|
} : outerDecryptCtx;
|
|
2351
|
-
return jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(DecryptClickContext.Provider, { value: decryptValue, children: [visibleBasicAttributes.length > 0 && jsxRuntimeExports.jsxs("div", { className: "flex flex-col overflow-hidden divide-y divide-gray-alpha-400 mb-3", children: [orderedBasicAttributes.map((attribute) => {
|
|
2344
|
+
return jsxRuntimeExports.jsx(ContextCardProvider, { children: jsxRuntimeExports.jsx(RunClickContext.Provider, { value: onRunClick, children: jsxRuntimeExports.jsx(StreamClickContext.Provider, { value: onStreamClick, children: jsxRuntimeExports.jsxs(DecryptClickContext.Provider, { value: decryptValue, children: [visibleBasicAttributes.length > 0 && jsxRuntimeExports.jsxs("div", { className: "flex flex-col overflow-hidden divide-y divide-gray-alpha-400 mb-3", children: [orderedBasicAttributes.map((attribute) => {
|
|
2352
2345
|
var _a;
|
|
2353
2346
|
const displayValue = (_a = attributeToDisplayFn[attribute]) == null ? void 0 : _a.call(attributeToDisplayFn, displayData[attribute]);
|
|
2354
2347
|
const isModuleSpecifier = attribute === "moduleSpecifier";
|
|
@@ -2362,7 +2355,7 @@ const AttributePanel = ({ data, moduleSpecifier, isLoading, error, expiredAt, on
|
|
|
2362
2355
|
}, title: moduleSpecifierValue, onClick: () => handleCopyModuleSpecifier(moduleSpecifierValue), children: moduleSpecifierValue }) : isCopyableBasicAttribute ? jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 max-w-[70%] items-center justify-end gap-1 text-right text-[13px] font-mono", style: {
|
|
2363
2356
|
color: "var(--ds-gray-1000)"
|
|
2364
2357
|
}, title: displayValue, children: [jsxRuntimeExports.jsx(MiddleTruncate, { value: displayValue, className: "flex-1" }), jsxRuntimeExports.jsx(CopyButton, { copyText: displayValue, ariaLabel: `Copy ${getAttributeDisplayName(attribute)}`, className: "shrink-0 -mr-1" })] }) : jsxRuntimeExports.jsx("span", { className: "text-right text-label-13 font-mono", children: displayValue })] }, attribute);
|
|
2365
|
-
}), isLoading && resource === "sleep" && !displayData.resumeAt && jsxRuntimeExports.jsx("div", { className: "py-1", children: jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[14px] first-letter:uppercase", style: { color: "var(--ds-gray-700)" }, children: "resumeAt" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[55%]" })] }) })] }), error ? jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load resource details", details: error.message, className: "my-4" }) : hasExpired ? jsxRuntimeExports.jsx(ExpiredDataMessage, {}) : resolvedAttributes.length > 0 ? jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: resolvedAttributes.map((attribute) => jsxRuntimeExports.jsx(AttributeBlock, { isLoading, attribute, value: displayData[attribute], context: displayContext }, attribute)) }) : null] }) }) });
|
|
2358
|
+
}), isLoading && resource === "sleep" && !displayData.resumeAt && jsxRuntimeExports.jsx("div", { className: "py-1", children: jsxRuntimeExports.jsxs("div", { className: "flex min-h-[32px] items-center justify-between gap-4 rounded-sm px-2.5 py-1", children: [jsxRuntimeExports.jsx("span", { className: "text-[14px] first-letter:uppercase", style: { color: "var(--ds-gray-700)" }, children: "resumeAt" }), jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-[55%]" })] }) })] }), error ? jsxRuntimeExports.jsx(ErrorCard, { title: "Failed to load resource details", details: error.message, className: "my-4" }) : hasExpired ? jsxRuntimeExports.jsx(ExpiredDataMessage, {}) : resolvedAttributes.length > 0 ? jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: resolvedAttributes.map((attribute) => jsxRuntimeExports.jsx(AttributeBlock, { isLoading, attribute, value: displayData[attribute], context: displayContext }, attribute)) }) : null] }) }) }) });
|
|
2366
2359
|
};
|
|
2367
2360
|
const ERROR_EVENT_TYPES = /* @__PURE__ */ new Set(["step_failed", "step_retrying"]);
|
|
2368
2361
|
const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -2376,7 +2369,8 @@ const DATA_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
2376
2369
|
"run_completed",
|
|
2377
2370
|
"run_failed",
|
|
2378
2371
|
"wait_created",
|
|
2379
|
-
"wait_completed"
|
|
2372
|
+
"wait_completed",
|
|
2373
|
+
"attr_set"
|
|
2380
2374
|
]);
|
|
2381
2375
|
function EventItem({ event, onLoadEventData, encryptionKey }) {
|
|
2382
2376
|
const [loadedData, setLoadedData] = reactExports.useState(null);
|
|
@@ -2450,6 +2444,9 @@ function EventDataBlock({ eventType, data }) {
|
|
|
2450
2444
|
if (hasEncryptedFields({ eventType, eventData: data })) {
|
|
2451
2445
|
return jsxRuntimeExports.jsx(EncryptedDataBlock, {});
|
|
2452
2446
|
}
|
|
2447
|
+
if (eventType === "attr_set") {
|
|
2448
|
+
return jsxRuntimeExports.jsx(AttrSetEventBlock, { data });
|
|
2449
|
+
}
|
|
2453
2450
|
if (ERROR_EVENT_TYPES.has(eventType) && data != null && typeof data === "object") {
|
|
2454
2451
|
const record = data;
|
|
2455
2452
|
if (isStructuredError(record.error)) {
|
|
@@ -2705,7 +2702,7 @@ function EntityDetailPanel({ run, onStreamClick, onRunClick, spanDetailData, spa
|
|
|
2705
2702
|
}, children: [jsxRuntimeExports.jsx(Zap, { className: "h-4 w-4" }), stoppingSleep ? "Waking up..." : "Wake Up Sleep"] }), resource === "hook" && canResolveHook && jsxRuntimeExports.jsxs("button", { type: "button", onClick: () => setShowResolveHookModal(true), disabled: resolvingHook, className: clsx("flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium", "disabled:opacity-50 disabled:cursor-not-allowed transition-colors", resolvingHook ? "opacity-50 cursor-not-allowed" : "cursor-pointer"), style: {
|
|
2706
2703
|
background: "var(--ds-gray-1000)",
|
|
2707
2704
|
color: "var(--ds-background-100)"
|
|
2708
|
-
}, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }),
|
|
2705
|
+
}, children: [jsxRuntimeExports.jsx(Send, { className: "h-4 w-4" }), "Resolve Hook"] })] })] }), jsxRuntimeExports.jsx(AttributePanel, { data: displayData, moduleSpecifier, expiredAt: run.expiredAt, isLoading: loading, error: error ?? void 0, onStreamClick, onRunClick, onDecrypt, isDecrypting, resource }), rawEvents && jsxRuntimeExports.jsx(EventsList, { events: rawEvents, onLoadEventData, onStreamClick, onRunClick, encryptionKey })] }) }), jsxRuntimeExports.jsx(ResolveHookModal, { isOpen: showResolveHookModal, onClose: () => setShowResolveHookModal(false), onSubmit: handleResolveHook, isSubmitting: resolvingHook })] });
|
|
2709
2706
|
}
|
|
2710
2707
|
const COL_TEMPLATE = "340px 1px minmax(50px, 1fr)";
|
|
2711
2708
|
const ROWS = [
|
|
@@ -2758,24 +2755,6 @@ function useLoadMoreOnScroll(loadMore, { hasMore, isLoadingMore, rootRef, rootMa
|
|
|
2758
2755
|
}, [entry == null ? void 0 : entry.isIntersecting, hasMore, isLoadingMore]);
|
|
2759
2756
|
return sentinelRef;
|
|
2760
2757
|
}
|
|
2761
|
-
const QUERY = "(prefers-reduced-motion: reduce)";
|
|
2762
|
-
const useReducedMotion = () => {
|
|
2763
|
-
const [reduced, setReduced] = reactExports.useState(() => {
|
|
2764
|
-
if (typeof window === "undefined" || !window.matchMedia)
|
|
2765
|
-
return false;
|
|
2766
|
-
return window.matchMedia(QUERY).matches;
|
|
2767
|
-
});
|
|
2768
|
-
reactExports.useEffect(() => {
|
|
2769
|
-
if (typeof window === "undefined" || !window.matchMedia)
|
|
2770
|
-
return;
|
|
2771
|
-
const media = window.matchMedia(QUERY);
|
|
2772
|
-
const onChange = () => setReduced(media.matches);
|
|
2773
|
-
media.addEventListener("change", onChange);
|
|
2774
|
-
onChange();
|
|
2775
|
-
return () => media.removeEventListener("change", onChange);
|
|
2776
|
-
}, []);
|
|
2777
|
-
return reduced;
|
|
2778
|
-
};
|
|
2779
2758
|
function Kbd({ children, className }) {
|
|
2780
2759
|
return jsxRuntimeExports.jsx("kbd", { className: cn("inline-flex h-5 min-w-5 items-center justify-center rounded bg-background-100/20 px-1 text-center font-sans text-xs leading-none", className), children });
|
|
2781
2760
|
}
|
|
@@ -2982,11 +2961,11 @@ function useSelectedSpanInfo() {
|
|
|
2982
2961
|
var _a, _b;
|
|
2983
2962
|
if (!activeSpan)
|
|
2984
2963
|
return null;
|
|
2985
|
-
const
|
|
2986
|
-
const rawEvents =
|
|
2964
|
+
const resource = (_a = activeSpan.attributes) == null ? void 0 : _a.resource;
|
|
2965
|
+
const rawEvents = filterSpanRawEvents(sidebar.events, resource, activeSpan.spanId);
|
|
2987
2966
|
return {
|
|
2988
|
-
data: (
|
|
2989
|
-
resource
|
|
2967
|
+
data: (_b = activeSpan.attributes) == null ? void 0 : _b.data,
|
|
2968
|
+
resource,
|
|
2990
2969
|
spanId: activeSpan.spanId,
|
|
2991
2970
|
rawEvents
|
|
2992
2971
|
};
|
|
@@ -3194,7 +3173,7 @@ function NewTraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore }) {
|
|
|
3194
3173
|
dy *= 16;
|
|
3195
3174
|
const cursorFraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
|
|
3196
3175
|
const isMouseWheel = e.deltaMode === 1 || Math.abs(e.deltaY) >= 50;
|
|
3197
|
-
const scaleFactor =
|
|
3176
|
+
const scaleFactor = 2 ** (dy / (isMouseWheel ? 200 : 60));
|
|
3198
3177
|
setViewport((prev) => {
|
|
3199
3178
|
const prevDuration = prev.end - prev.start;
|
|
3200
3179
|
const cursorTime = prev.start + cursorFraction * prevDuration;
|