@opengeni/react 5.0.5-canary.0 → 5.0.5-canary.1
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/dist/{chunk-SCZ6SUBW.js → chunk-H63SQTGI.js} +1258 -1837
- package/dist/chunk-H63SQTGI.js.map +1 -0
- package/dist/chunk-HQV2I5HV.js +124 -0
- package/dist/chunk-HQV2I5HV.js.map +1 -0
- package/dist/chunk-M2HNWZYR.js +835 -0
- package/dist/chunk-M2HNWZYR.js.map +1 -0
- package/dist/{chunk-Z7WBDB4E.js → chunk-V3WX3TQG.js} +283 -391
- package/dist/chunk-V3WX3TQG.js.map +1 -0
- package/dist/components/message-timeline.d.ts +3 -1
- package/dist/composer.js +2 -1
- package/dist/connect-chooser.d.ts +1 -0
- package/dist/connect-panel.d.ts +2 -1
- package/dist/connect.d.ts +7 -0
- package/dist/connect.js +791 -183
- package/dist/connect.js.map +1 -1
- package/dist/connection-catalog.d.ts +33 -0
- package/dist/connection-installed.d.ts +15 -0
- package/dist/connection-logo.d.ts +6 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/index.js +17 -12
- package/dist/index.js.map +1 -1
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +14 -0
- package/dist/session-ui.d.ts +3 -0
- package/dist/session-ui.js +113 -2
- package/dist/session-ui.js.map +1 -1
- package/dist/skill-discovery.d.ts +29 -0
- package/dist/timeline/activity-rail.d.ts +3 -1
- package/dist/timeline/genie-loading.d.ts +24 -0
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/package.json +4 -3
- package/src/components/message-timeline.tsx +127 -20
- package/src/connect-chooser.tsx +81 -21
- package/src/connect-panel.tsx +7 -1
- package/src/connect.ts +21 -0
- package/src/connection-catalog.tsx +153 -0
- package/src/connection-installed.tsx +45 -0
- package/src/connection-logo.tsx +29 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/hooks/use-codex-accounts.ts +1 -0
- package/src/plugin-details.tsx +182 -0
- package/src/plugin-discovery.tsx +161 -0
- package/src/session-ui.ts +3 -0
- package/src/skill-discovery.tsx +152 -0
- package/src/timeline/activity-rail.tsx +75 -4
- package/src/timeline/genie-loading.tsx +112 -0
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/turn-summary.tsx +8 -3
- package/styles/compiled.css +73 -0
- package/styles/connect.css +149 -1
- package/styles/index.css +15 -0
- package/dist/chunk-SCZ6SUBW.js.map +0 -1
- package/dist/chunk-Z7WBDB4E.js.map +0 -1
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
import {
|
|
2
|
+
copyTextToClipboard,
|
|
3
|
+
tableElementToTsv
|
|
4
|
+
} from "./chunk-JVYQRRC4.js";
|
|
5
|
+
import {
|
|
6
|
+
Tooltip,
|
|
7
|
+
TooltipContent,
|
|
8
|
+
TooltipProvider,
|
|
9
|
+
TooltipTrigger
|
|
10
|
+
} from "./chunk-HQV2I5HV.js";
|
|
11
|
+
import {
|
|
12
|
+
cn
|
|
13
|
+
} from "./chunk-22KP6LR5.js";
|
|
14
|
+
|
|
15
|
+
// src/components/copy-button.tsx
|
|
16
|
+
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
17
|
+
import { useEffect, useRef, useState } from "react";
|
|
18
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
19
|
+
var COPIED_MS = 1600;
|
|
20
|
+
function CopyButton({
|
|
21
|
+
text,
|
|
22
|
+
label = "Copy",
|
|
23
|
+
className,
|
|
24
|
+
reveal = "group-hover"
|
|
25
|
+
}) {
|
|
26
|
+
const [copied, setCopied] = useState(false);
|
|
27
|
+
const [tipOpen, setTipOpen] = useState(false);
|
|
28
|
+
const timerRef = useRef(null);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
return () => {
|
|
31
|
+
if (timerRef.current !== null) {
|
|
32
|
+
clearTimeout(timerRef.current);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}, []);
|
|
36
|
+
const onClick = async (event) => {
|
|
37
|
+
event.preventDefault();
|
|
38
|
+
event.stopPropagation();
|
|
39
|
+
const button = event.currentTarget;
|
|
40
|
+
const pointerActivated = event.detail > 0;
|
|
41
|
+
const value = typeof text === "function" ? text() : text;
|
|
42
|
+
const ok = await copyTextToClipboard(value);
|
|
43
|
+
if (!ok) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
setCopied(true);
|
|
47
|
+
setTipOpen(true);
|
|
48
|
+
if (timerRef.current !== null) {
|
|
49
|
+
clearTimeout(timerRef.current);
|
|
50
|
+
}
|
|
51
|
+
timerRef.current = setTimeout(() => {
|
|
52
|
+
timerRef.current = null;
|
|
53
|
+
setCopied(false);
|
|
54
|
+
setTipOpen(false);
|
|
55
|
+
}, COPIED_MS);
|
|
56
|
+
if (pointerActivated) {
|
|
57
|
+
button.blur();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const tip = copied ? "Copied" : label;
|
|
61
|
+
return /* @__PURE__ */ jsxs(
|
|
62
|
+
Tooltip,
|
|
63
|
+
{
|
|
64
|
+
open: copied ? true : tipOpen,
|
|
65
|
+
onOpenChange: (next) => {
|
|
66
|
+
if (!copied) {
|
|
67
|
+
setTipOpen(next);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
"data-og-copy": "",
|
|
76
|
+
"data-state": copied ? "copied" : "idle",
|
|
77
|
+
"aria-label": tip,
|
|
78
|
+
onClick,
|
|
79
|
+
className: cn(
|
|
80
|
+
"inline-flex size-7 shrink-0 items-center justify-center rounded-og-sm pointer-coarse:size-11",
|
|
81
|
+
"text-og-fg-subtle transition-[opacity,color,background-color] duration-150",
|
|
82
|
+
"hover:bg-og-surface-2/80 hover:text-og-fg",
|
|
83
|
+
"focus-visible:opacity-100 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent/40",
|
|
84
|
+
reveal === "group-hover" && "opacity-0 group-hover/copy:opacity-100 group-focus-within/copy:opacity-100 pointer-coarse:opacity-70",
|
|
85
|
+
copied && "opacity-100 text-og-accent",
|
|
86
|
+
className
|
|
87
|
+
),
|
|
88
|
+
children: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5", "aria-hidden": true }) : /* @__PURE__ */ jsx(CopyIcon, { className: "size-3.5", "aria-hidden": true })
|
|
89
|
+
}
|
|
90
|
+
) }),
|
|
91
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: tip })
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function CopyHoverFrame({
|
|
97
|
+
children,
|
|
98
|
+
className,
|
|
99
|
+
copyText,
|
|
100
|
+
label,
|
|
101
|
+
align = "end",
|
|
102
|
+
trailing
|
|
103
|
+
}) {
|
|
104
|
+
if (copyText.trim().length === 0) {
|
|
105
|
+
return /* @__PURE__ */ jsx("div", { className, children });
|
|
106
|
+
}
|
|
107
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("group/copy", className), children: [
|
|
108
|
+
children,
|
|
109
|
+
/* @__PURE__ */ jsxs(
|
|
110
|
+
"div",
|
|
111
|
+
{
|
|
112
|
+
"data-og-annotation-chrome": "",
|
|
113
|
+
className: cn(
|
|
114
|
+
"mt-1 flex h-7 items-center gap-1.5",
|
|
115
|
+
align === "end" ? "justify-end" : "justify-start"
|
|
116
|
+
),
|
|
117
|
+
children: [
|
|
118
|
+
/* @__PURE__ */ jsx(CopyButton, { text: copyText, label, reveal: "group-hover" }),
|
|
119
|
+
trailing
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/components/markdown.tsx
|
|
127
|
+
import {
|
|
128
|
+
Children,
|
|
129
|
+
isValidElement,
|
|
130
|
+
memo,
|
|
131
|
+
useEffect as useEffect2,
|
|
132
|
+
useMemo,
|
|
133
|
+
useReducer,
|
|
134
|
+
useRef as useRef2,
|
|
135
|
+
useState as useState2
|
|
136
|
+
} from "react";
|
|
137
|
+
import ReactMarkdown, {
|
|
138
|
+
defaultUrlTransform
|
|
139
|
+
} from "react-markdown";
|
|
140
|
+
import remarkGfm from "remark-gfm";
|
|
141
|
+
|
|
142
|
+
// src/lib/motion.ts
|
|
143
|
+
import { flushSync } from "react-dom";
|
|
144
|
+
var query;
|
|
145
|
+
function prefersReducedMotion() {
|
|
146
|
+
if (query === void 0) {
|
|
147
|
+
query = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
|
|
148
|
+
}
|
|
149
|
+
return query?.matches ?? false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/lib/motion-inspect.ts
|
|
153
|
+
var MOTION_INSPECT_SCALE = 1;
|
|
154
|
+
|
|
155
|
+
// src/components/soften-streaming-markdown.ts
|
|
156
|
+
function softenStreamingMarkdown(source) {
|
|
157
|
+
if (source.length === 0) {
|
|
158
|
+
return source;
|
|
159
|
+
}
|
|
160
|
+
let text = source;
|
|
161
|
+
if (countFences(text) % 2 === 1) {
|
|
162
|
+
text += text.endsWith("\n") ? "```" : "\n```";
|
|
163
|
+
}
|
|
164
|
+
const segments = splitByFences(text);
|
|
165
|
+
for (const segment of segments) {
|
|
166
|
+
if (segment.kind === "fence") {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
segment.value = closeInlineMarkers(segment.value);
|
|
170
|
+
}
|
|
171
|
+
let result = segments.map((segment) => segment.value).join("");
|
|
172
|
+
if (text.endsWith("\n") && !result.endsWith("\n")) {
|
|
173
|
+
result += "\n";
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
function countFences(text) {
|
|
178
|
+
let count = 0;
|
|
179
|
+
for (const line of text.split("\n")) {
|
|
180
|
+
if (/^ {0,3}```/.test(line)) {
|
|
181
|
+
count += 1;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return count;
|
|
185
|
+
}
|
|
186
|
+
function splitByFences(text) {
|
|
187
|
+
const segments = [];
|
|
188
|
+
const lines = text.split("\n");
|
|
189
|
+
let buf = [];
|
|
190
|
+
let inFence = false;
|
|
191
|
+
const flush = (kind, mode) => {
|
|
192
|
+
if (buf.length === 0) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
let value = buf.join("\n");
|
|
196
|
+
if (mode === "boundary") {
|
|
197
|
+
value += "\n";
|
|
198
|
+
}
|
|
199
|
+
segments.push({ kind, value });
|
|
200
|
+
buf = [];
|
|
201
|
+
};
|
|
202
|
+
for (const line of lines) {
|
|
203
|
+
const isFence = /^ {0,3}```/.test(line);
|
|
204
|
+
if (isFence) {
|
|
205
|
+
if (inFence) {
|
|
206
|
+
buf.push(line);
|
|
207
|
+
flush("fence", "end");
|
|
208
|
+
inFence = false;
|
|
209
|
+
} else {
|
|
210
|
+
flush("prose", "boundary");
|
|
211
|
+
buf.push(line);
|
|
212
|
+
inFence = true;
|
|
213
|
+
}
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
buf.push(line);
|
|
217
|
+
}
|
|
218
|
+
flush(inFence ? "fence" : "prose", "end");
|
|
219
|
+
return segments;
|
|
220
|
+
}
|
|
221
|
+
function closeInlineMarkers(prose) {
|
|
222
|
+
let text = prose;
|
|
223
|
+
text = closeDelimiter(text, "~~");
|
|
224
|
+
text = closeDelimiter(text, "**");
|
|
225
|
+
text = closeDelimiter(text, "__");
|
|
226
|
+
text = closeSingleBackticks(text);
|
|
227
|
+
text = closeSingleAsterisks(text);
|
|
228
|
+
text = closeUnfinishedLink(text);
|
|
229
|
+
return text;
|
|
230
|
+
}
|
|
231
|
+
function closeDelimiter(text, delimiter) {
|
|
232
|
+
let count = 0;
|
|
233
|
+
let i = 0;
|
|
234
|
+
while (i < text.length) {
|
|
235
|
+
if (text[i] === "\\" && i + 1 < text.length) {
|
|
236
|
+
i += 2;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (text.startsWith(delimiter, i)) {
|
|
240
|
+
count += 1;
|
|
241
|
+
i += delimiter.length;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
i += 1;
|
|
245
|
+
}
|
|
246
|
+
return count % 2 === 1 ? insertBeforeTrailingNewlines(text, delimiter) : text;
|
|
247
|
+
}
|
|
248
|
+
function insertBeforeTrailingNewlines(text, suffix) {
|
|
249
|
+
let end = text.length;
|
|
250
|
+
while (end > 0 && text[end - 1] === "\n") {
|
|
251
|
+
end -= 1;
|
|
252
|
+
}
|
|
253
|
+
return text.slice(0, end) + suffix + text.slice(end);
|
|
254
|
+
}
|
|
255
|
+
function closeSingleBackticks(text) {
|
|
256
|
+
let count = 0;
|
|
257
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
258
|
+
if (text[i] === "\\" && i + 1 < text.length) {
|
|
259
|
+
i += 1;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (text[i] === "`") {
|
|
263
|
+
if (text.startsWith("```", i)) {
|
|
264
|
+
i += 2;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
count += 1;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return count % 2 === 1 ? insertBeforeTrailingNewlines(text, "`") : text;
|
|
271
|
+
}
|
|
272
|
+
function closeSingleAsterisks(text) {
|
|
273
|
+
let count = 0;
|
|
274
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
275
|
+
if (text[i] === "\\" && i + 1 < text.length) {
|
|
276
|
+
i += 1;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (text[i] === "*" && text[i + 1] === "*") {
|
|
280
|
+
i += 1;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (text[i] === "*") {
|
|
284
|
+
count += 1;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return count % 2 === 1 ? insertBeforeTrailingNewlines(text, "*") : text;
|
|
288
|
+
}
|
|
289
|
+
function closeUnfinishedLink(text) {
|
|
290
|
+
const open = text.lastIndexOf("](");
|
|
291
|
+
if (open === -1) {
|
|
292
|
+
return text;
|
|
293
|
+
}
|
|
294
|
+
const after = text.slice(open + 2);
|
|
295
|
+
if (after.includes(")")) {
|
|
296
|
+
return text;
|
|
297
|
+
}
|
|
298
|
+
if (after.includes("[")) {
|
|
299
|
+
return text;
|
|
300
|
+
}
|
|
301
|
+
return insertBeforeTrailingNewlines(text, ")");
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/components/stream-reveal.ts
|
|
305
|
+
var INK_FADE_MS = 420 * MOTION_INSPECT_SCALE;
|
|
306
|
+
var INITIAL_ANIMATED_LIMIT = 400;
|
|
307
|
+
function createStreamReveal() {
|
|
308
|
+
let batches = [];
|
|
309
|
+
let revealedChars = -1;
|
|
310
|
+
return {
|
|
311
|
+
observe(text, now) {
|
|
312
|
+
if (revealedChars === -1) {
|
|
313
|
+
revealedChars = text.length > INITIAL_ANIMATED_LIMIT ? text.length : 0;
|
|
314
|
+
}
|
|
315
|
+
if (text.length <= revealedChars) {
|
|
316
|
+
revealedChars = Math.max(revealedChars, text.length);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
batches.push({ start: revealedChars, end: text.length, birth: now });
|
|
320
|
+
revealedChars = text.length;
|
|
321
|
+
batches = batches.filter((batch) => batch.birth + INK_FADE_MS > now);
|
|
322
|
+
},
|
|
323
|
+
delayFor(offset, now) {
|
|
324
|
+
const batch = findBatch(batches, offset);
|
|
325
|
+
if (!batch) {
|
|
326
|
+
return null;
|
|
327
|
+
}
|
|
328
|
+
const delay = batch.birth - now;
|
|
329
|
+
return delay + INK_FADE_MS <= 0 ? null : delay;
|
|
330
|
+
},
|
|
331
|
+
hasActive(now) {
|
|
332
|
+
const last = batches[batches.length - 1];
|
|
333
|
+
return last !== void 0 && last.birth + INK_FADE_MS > now;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
function findBatch(batches, offset) {
|
|
338
|
+
let low = 0;
|
|
339
|
+
let high = batches.length - 1;
|
|
340
|
+
while (low <= high) {
|
|
341
|
+
const mid = low + high >> 1;
|
|
342
|
+
const batch = batches[mid];
|
|
343
|
+
if (offset < batch.start) {
|
|
344
|
+
high = mid - 1;
|
|
345
|
+
} else if (offset >= batch.end) {
|
|
346
|
+
low = mid + 1;
|
|
347
|
+
} else {
|
|
348
|
+
return batch;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
function rehypeStreamReveal(options) {
|
|
354
|
+
const { reveal, now } = options;
|
|
355
|
+
return (tree) => {
|
|
356
|
+
walk(tree, false);
|
|
357
|
+
};
|
|
358
|
+
function walk(node, insideVerbatim) {
|
|
359
|
+
if (!node.children) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const verbatim = insideVerbatim || node.tagName === "code" || node.tagName === "pre";
|
|
363
|
+
const next = [];
|
|
364
|
+
for (const child of node.children) {
|
|
365
|
+
if (child.type === "text" && !verbatim) {
|
|
366
|
+
next.push(...splitTextNode(child));
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
walk(child, verbatim);
|
|
370
|
+
next.push(child);
|
|
371
|
+
}
|
|
372
|
+
node.children = next;
|
|
373
|
+
}
|
|
374
|
+
function splitTextNode(node) {
|
|
375
|
+
const sourceOffset = node.position?.start?.offset;
|
|
376
|
+
if (sourceOffset === void 0) {
|
|
377
|
+
return [node];
|
|
378
|
+
}
|
|
379
|
+
const value = node.value;
|
|
380
|
+
const out = [];
|
|
381
|
+
let plain = "";
|
|
382
|
+
const flushPlain = () => {
|
|
383
|
+
if (plain.length > 0) {
|
|
384
|
+
out.push({ type: "text", value: plain });
|
|
385
|
+
plain = "";
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
let i = 0;
|
|
389
|
+
while (i < value.length) {
|
|
390
|
+
const delay = reveal.delayFor(sourceOffset + i, now);
|
|
391
|
+
let j = i + 1;
|
|
392
|
+
while (j < value.length) {
|
|
393
|
+
const nextDelay = reveal.delayFor(sourceOffset + j, now);
|
|
394
|
+
if (nextDelay !== delay) {
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
j += 1;
|
|
398
|
+
}
|
|
399
|
+
const slice = value.slice(i, j);
|
|
400
|
+
if (delay === null) {
|
|
401
|
+
plain += slice;
|
|
402
|
+
} else {
|
|
403
|
+
flushPlain();
|
|
404
|
+
out.push({
|
|
405
|
+
type: "element",
|
|
406
|
+
tagName: "span",
|
|
407
|
+
properties: {
|
|
408
|
+
className: ["og-stream-ink"],
|
|
409
|
+
style: `animation-delay:${Math.round(delay)}ms`
|
|
410
|
+
},
|
|
411
|
+
children: [{ type: "text", value: slice }]
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
i = j;
|
|
415
|
+
}
|
|
416
|
+
flushPlain();
|
|
417
|
+
return out.length > 0 ? out : [node];
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// src/components/markdown.tsx
|
|
422
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
423
|
+
var baseComponents = {
|
|
424
|
+
h1: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
425
|
+
"h1",
|
|
426
|
+
{
|
|
427
|
+
className: "mt-5 mb-2.5 text-xl font-semibold tracking-tight text-og-fg first:mt-0",
|
|
428
|
+
...props,
|
|
429
|
+
children
|
|
430
|
+
}
|
|
431
|
+
),
|
|
432
|
+
h2: ({ children, ...props }) => /* @__PURE__ */ jsx2("h2", { className: "mt-5 mb-2 text-lg font-semibold tracking-tight text-og-fg first:mt-0", ...props, children }),
|
|
433
|
+
h3: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
434
|
+
"h3",
|
|
435
|
+
{
|
|
436
|
+
className: "mt-4 mb-1.5 text-og-md font-semibold tracking-tight text-og-fg first:mt-0",
|
|
437
|
+
...props,
|
|
438
|
+
children
|
|
439
|
+
}
|
|
440
|
+
),
|
|
441
|
+
h4: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
442
|
+
"h4",
|
|
443
|
+
{
|
|
444
|
+
className: "mt-4 mb-1.5 text-og-sm font-semibold uppercase tracking-[0.04em] text-og-fg-muted first:mt-0",
|
|
445
|
+
...props,
|
|
446
|
+
children
|
|
447
|
+
}
|
|
448
|
+
),
|
|
449
|
+
p: ({ children, ...props }) => /* @__PURE__ */ jsx2("p", { className: "my-2.5 leading-7 first:mt-0 last:mb-0", ...props, children }),
|
|
450
|
+
strong: ({ children, ...props }) => /* @__PURE__ */ jsx2("strong", { className: "font-semibold text-og-fg", ...props, children }),
|
|
451
|
+
em: ({ children, ...props }) => /* @__PURE__ */ jsx2("em", { className: "italic", ...props, children }),
|
|
452
|
+
ul: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
453
|
+
"ul",
|
|
454
|
+
{
|
|
455
|
+
className: "my-2.5 ml-5 flex list-disc flex-col gap-1 marker:text-og-fg-subtle first:mt-0 last:mb-0",
|
|
456
|
+
...props,
|
|
457
|
+
children
|
|
458
|
+
}
|
|
459
|
+
),
|
|
460
|
+
ol: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
461
|
+
"ol",
|
|
462
|
+
{
|
|
463
|
+
className: "my-2.5 ml-5 flex list-decimal flex-col gap-1 marker:text-og-fg-subtle first:mt-0 last:mb-0",
|
|
464
|
+
...props,
|
|
465
|
+
children
|
|
466
|
+
}
|
|
467
|
+
),
|
|
468
|
+
// GFM task-list items carry a leading checkbox <input>; `list-none` + a
|
|
469
|
+
// negative margin pull the checkbox back to the bullet column so it aligns
|
|
470
|
+
// with the text.
|
|
471
|
+
li: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
472
|
+
"li",
|
|
473
|
+
{
|
|
474
|
+
className: "leading-7 marker:text-og-fg-subtle [&>ul]:my-1 [&>ol]:my-1 [&:has(>input)]:list-none [&:has(>input)]:-ml-5",
|
|
475
|
+
...props,
|
|
476
|
+
children
|
|
477
|
+
}
|
|
478
|
+
),
|
|
479
|
+
input: ({ type, ...props }) => type === "checkbox" ? /* @__PURE__ */ jsx2(
|
|
480
|
+
"input",
|
|
481
|
+
{
|
|
482
|
+
...props,
|
|
483
|
+
type: "checkbox",
|
|
484
|
+
disabled: true,
|
|
485
|
+
className: "mr-2 size-3.5 translate-y-[2px] cursor-default accent-og-accent align-baseline"
|
|
486
|
+
}
|
|
487
|
+
) : /* @__PURE__ */ jsx2("input", { type, ...props }),
|
|
488
|
+
blockquote: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
489
|
+
"blockquote",
|
|
490
|
+
{
|
|
491
|
+
className: "my-3 border-l-2 border-og-border-strong pl-3.5 text-og-fg-muted [&>p]:my-1.5 first:mt-0 last:mb-0",
|
|
492
|
+
...props,
|
|
493
|
+
children
|
|
494
|
+
}
|
|
495
|
+
),
|
|
496
|
+
hr: (props) => /* @__PURE__ */ jsx2("hr", { className: "my-4 border-0 border-t border-og-border", ...props }),
|
|
497
|
+
// Inline `code` vs fenced code blocks. react-markdown v10 no longer passes an
|
|
498
|
+
// `inline` flag; a fenced block is a <code> whose parent is <pre> (styled by
|
|
499
|
+
// the `pre` renderer), so a `code` reaching here is treated as inline.
|
|
500
|
+
code: ({ children, className: _className, ...props }) => /* @__PURE__ */ jsx2(
|
|
501
|
+
"code",
|
|
502
|
+
{
|
|
503
|
+
className: "rounded-og-xs bg-og-surface-1 px-1 py-0.5 font-og-mono text-og-sm text-og-fg",
|
|
504
|
+
...props,
|
|
505
|
+
children
|
|
506
|
+
}
|
|
507
|
+
),
|
|
508
|
+
// Fenced code — quiet mono block (no card / no nested vertical scroll).
|
|
509
|
+
pre: ({ children }) => /* @__PURE__ */ jsx2(MarkdownCodeBlock, { children }),
|
|
510
|
+
// Tables stay unboxed (hairline rules); hover reveals a TSV copy control.
|
|
511
|
+
table: ({ children, ...props }) => /* @__PURE__ */ jsx2(MarkdownTable, { ...props, children }),
|
|
512
|
+
thead: ({ children, ...props }) => /* @__PURE__ */ jsx2("thead", { ...props, children }),
|
|
513
|
+
th: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
514
|
+
"th",
|
|
515
|
+
{
|
|
516
|
+
className: "border-b border-og-border px-0 py-1.5 pr-4 text-left font-medium text-og-fg first:pl-0",
|
|
517
|
+
...props,
|
|
518
|
+
children
|
|
519
|
+
}
|
|
520
|
+
),
|
|
521
|
+
td: ({ children, ...props }) => /* @__PURE__ */ jsx2(
|
|
522
|
+
"td",
|
|
523
|
+
{
|
|
524
|
+
className: "border-b border-og-border/70 px-0 py-1.5 pr-4 align-top text-og-fg-muted [tr:last-child>&]:border-b-0",
|
|
525
|
+
...props,
|
|
526
|
+
children
|
|
527
|
+
}
|
|
528
|
+
),
|
|
529
|
+
img: ({ alt, src, ...props }) => src ? /* @__PURE__ */ jsx2(
|
|
530
|
+
"img",
|
|
531
|
+
{
|
|
532
|
+
alt: alt ?? "",
|
|
533
|
+
src,
|
|
534
|
+
className: "my-3 max-w-full rounded-og-md border border-og-border",
|
|
535
|
+
...props
|
|
536
|
+
}
|
|
537
|
+
) : alt ? /* @__PURE__ */ jsx2("span", { className: "text-og-fg-subtle", "aria-disabled": "true", children: alt }) : null
|
|
538
|
+
};
|
|
539
|
+
var MARKDOWN_LINK_CLASS = "break-words font-medium text-og-accent-strong underline-offset-2 hover:underline";
|
|
540
|
+
function markdownComponents(onSandboxFile) {
|
|
541
|
+
return {
|
|
542
|
+
...baseComponents,
|
|
543
|
+
a: ({ children, href, ...props }) => {
|
|
544
|
+
const location = sandboxFileLocationFromHref(href);
|
|
545
|
+
if (location !== null) {
|
|
546
|
+
return /* @__PURE__ */ jsx2(SandboxMarkdownLink, { location, onSandboxFile, children });
|
|
547
|
+
}
|
|
548
|
+
if (isSandboxHref(href) || !href) {
|
|
549
|
+
return /* @__PURE__ */ jsx2(
|
|
550
|
+
"span",
|
|
551
|
+
{
|
|
552
|
+
className: "break-words font-medium text-og-fg-subtle underline decoration-dotted underline-offset-2",
|
|
553
|
+
"aria-disabled": "true",
|
|
554
|
+
title: isSandboxHref(href) ? "This sandbox file reference is invalid" : "This link is unavailable",
|
|
555
|
+
children
|
|
556
|
+
}
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
return /* @__PURE__ */ jsx2(
|
|
560
|
+
"a",
|
|
561
|
+
{
|
|
562
|
+
className: MARKDOWN_LINK_CLASS,
|
|
563
|
+
target: "_blank",
|
|
564
|
+
rel: "noreferrer noopener",
|
|
565
|
+
href,
|
|
566
|
+
...props,
|
|
567
|
+
children
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
function SandboxMarkdownLink({
|
|
574
|
+
location,
|
|
575
|
+
onSandboxFile,
|
|
576
|
+
children
|
|
577
|
+
}) {
|
|
578
|
+
const [state, setState] = useState2("idle");
|
|
579
|
+
const { path, line } = location;
|
|
580
|
+
if (!onSandboxFile) {
|
|
581
|
+
return /* @__PURE__ */ jsx2(
|
|
582
|
+
"span",
|
|
583
|
+
{
|
|
584
|
+
className: "break-words font-medium text-og-fg-subtle underline decoration-dotted underline-offset-2",
|
|
585
|
+
"aria-disabled": "true",
|
|
586
|
+
title: "This sandbox file requires a session-aware handler",
|
|
587
|
+
children
|
|
588
|
+
}
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
const idleTitle = line !== null ? `Open ${path} at line ${line}` : `Open ${path}`;
|
|
592
|
+
return /* @__PURE__ */ jsxs2(
|
|
593
|
+
"button",
|
|
594
|
+
{
|
|
595
|
+
type: "button",
|
|
596
|
+
className: cn(
|
|
597
|
+
MARKDOWN_LINK_CLASS,
|
|
598
|
+
"inline-flex min-h-7 cursor-pointer items-center disabled:cursor-wait disabled:opacity-70 pointer-coarse:min-h-11"
|
|
599
|
+
),
|
|
600
|
+
disabled: state === "loading",
|
|
601
|
+
"aria-busy": state === "loading",
|
|
602
|
+
title: state === "error" ? "Couldn't open this file. Select to retry." : idleTitle,
|
|
603
|
+
onClick: () => {
|
|
604
|
+
setState("loading");
|
|
605
|
+
void Promise.resolve(onSandboxFile(path, line ?? void 0)).then(
|
|
606
|
+
() => setState("idle"),
|
|
607
|
+
() => setState("error")
|
|
608
|
+
);
|
|
609
|
+
},
|
|
610
|
+
children: [
|
|
611
|
+
children,
|
|
612
|
+
state === "loading" ? " (opening\u2026)" : state === "error" ? " (retry)" : null
|
|
613
|
+
]
|
|
614
|
+
}
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
var SANDBOX_SCHEME = "sandbox:";
|
|
618
|
+
var LEGACY_WORKSPACE_PREFIX = "/workspace/";
|
|
619
|
+
var TRAILING_LINE = /:([0-9]+)$/u;
|
|
620
|
+
var TRAILING_INVALID_LINE = /:-(?:[0-9]+)$|:[0-9]+-[0-9]+$/u;
|
|
621
|
+
var CONTROL_CHARACTER = /[\u0000-\u001f\u007f]/u;
|
|
622
|
+
function isSandboxHref(href) {
|
|
623
|
+
return href?.startsWith(SANDBOX_SCHEME) ?? false;
|
|
624
|
+
}
|
|
625
|
+
function sandboxFileLocationFromHref(href) {
|
|
626
|
+
if (!href) return null;
|
|
627
|
+
const encodedLocation = isSandboxHref(href) ? href.slice(SANDBOX_SCHEME.length) : href.startsWith(LEGACY_WORKSPACE_PREFIX) ? href : null;
|
|
628
|
+
if (!encodedLocation || encodedLocation.includes("?") || encodedLocation.includes("#")) {
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
if (TRAILING_INVALID_LINE.test(encodedLocation)) return null;
|
|
632
|
+
const lineMatch = TRAILING_LINE.exec(encodedLocation);
|
|
633
|
+
const encodedPath = lineMatch ? encodedLocation.slice(0, -lineMatch[0].length) : encodedLocation;
|
|
634
|
+
const line = lineMatch?.[1] ? Number(lineMatch[1]) : null;
|
|
635
|
+
if (line !== null && (!Number.isSafeInteger(line) || line < 1)) return null;
|
|
636
|
+
if (!encodedPath) return null;
|
|
637
|
+
try {
|
|
638
|
+
const path = decodeURIComponent(encodedPath);
|
|
639
|
+
return path && !CONTROL_CHARACTER.test(path) ? { path, line } : null;
|
|
640
|
+
} catch {
|
|
641
|
+
return null;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function sandboxFilePathFromHref(href) {
|
|
645
|
+
return sandboxFileLocationFromHref(href)?.path ?? null;
|
|
646
|
+
}
|
|
647
|
+
var markdownUrlTransform = (url, key, node) => key === "href" && node.tagName === "a" && isSandboxHref(url) ? url : defaultUrlTransform(url);
|
|
648
|
+
var REVEAL_LINGER_MS = 480 * MOTION_INSPECT_SCALE;
|
|
649
|
+
var MARKDOWN_SETTLE_MS = 480 * MOTION_INSPECT_SCALE;
|
|
650
|
+
function nodeText(node) {
|
|
651
|
+
if (node == null || typeof node === "boolean") {
|
|
652
|
+
return "";
|
|
653
|
+
}
|
|
654
|
+
if (typeof node === "string" || typeof node === "number") {
|
|
655
|
+
return String(node);
|
|
656
|
+
}
|
|
657
|
+
if (Array.isArray(node)) {
|
|
658
|
+
return node.map(nodeText).join("");
|
|
659
|
+
}
|
|
660
|
+
if (isValidElement(node)) {
|
|
661
|
+
return nodeText(node.props.children);
|
|
662
|
+
}
|
|
663
|
+
return "";
|
|
664
|
+
}
|
|
665
|
+
function fenceLanguage(children) {
|
|
666
|
+
let found = null;
|
|
667
|
+
Children.forEach(children, (child) => {
|
|
668
|
+
if (found || !isValidElement(child)) {
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
const match = /language-([a-zA-Z0-9_+-]+)/.exec(child.props.className ?? "");
|
|
672
|
+
if (match?.[1]) {
|
|
673
|
+
found = match[1];
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
return found;
|
|
677
|
+
}
|
|
678
|
+
function MarkdownCodeBlock({ children }) {
|
|
679
|
+
const code = nodeText(children).replace(/\n$/, "");
|
|
680
|
+
const language = fenceLanguage(children);
|
|
681
|
+
return /* @__PURE__ */ jsxs2("div", { className: "group/copy relative mt-3 first:mt-0", children: [
|
|
682
|
+
/* @__PURE__ */ jsxs2("div", { className: "pointer-events-none absolute top-1.5 right-1.5 z-10 flex items-center gap-1", children: [
|
|
683
|
+
language ? /* @__PURE__ */ jsx2("span", { className: "rounded px-1 py-0.5 font-og-mono text-[10px] uppercase tracking-wide text-og-fg-subtle/80 opacity-0 transition-opacity group-hover/copy:opacity-100 pointer-coarse:opacity-70", children: language }) : null,
|
|
684
|
+
/* @__PURE__ */ jsx2("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx2(CopyButton, { text: code, label: "Copy code", reveal: "group-hover" }) })
|
|
685
|
+
] }),
|
|
686
|
+
/* @__PURE__ */ jsx2(
|
|
687
|
+
"pre",
|
|
688
|
+
{
|
|
689
|
+
tabIndex: 0,
|
|
690
|
+
className: "overflow-x-auto overflow-y-hidden rounded-og-md bg-og-surface-1/70 px-3 py-2.5 font-og-mono text-og-sm leading-5 text-og-fg-muted [scrollbar-gutter:stable] [&>code]:block [&>code]:border-0 [&>code]:bg-transparent [&>code]:p-0 [&>code]:leading-5 [&>code]:text-inherit",
|
|
691
|
+
children
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
] });
|
|
695
|
+
}
|
|
696
|
+
function MarkdownTable({ children, className, ...props }) {
|
|
697
|
+
const wrapperRef = useRef2(null);
|
|
698
|
+
const tableRef = useRef2(null);
|
|
699
|
+
const layoutRef = useRef2(void 0);
|
|
700
|
+
useEffect2(() => {
|
|
701
|
+
const wrapper = wrapperRef.current;
|
|
702
|
+
const table = tableRef.current;
|
|
703
|
+
if (!wrapper?.closest("[data-og-wide-table-message]") || !table) return;
|
|
704
|
+
let disposed = false;
|
|
705
|
+
void import("./markdown-table-layout-PFUEZ2U4.js").then(({ observeMarkdownTableLayout }) => {
|
|
706
|
+
if (!disposed) layoutRef.current = observeMarkdownTableLayout(wrapper, table);
|
|
707
|
+
}).catch(() => {
|
|
708
|
+
});
|
|
709
|
+
return () => {
|
|
710
|
+
disposed = true;
|
|
711
|
+
layoutRef.current?.disconnect();
|
|
712
|
+
layoutRef.current = void 0;
|
|
713
|
+
};
|
|
714
|
+
}, []);
|
|
715
|
+
useEffect2(() => {
|
|
716
|
+
layoutRef.current?.measure();
|
|
717
|
+
}, [children]);
|
|
718
|
+
return /* @__PURE__ */ jsxs2("div", { ref: wrapperRef, className: "group/copy relative mt-3 max-w-full first:mt-0", children: [
|
|
719
|
+
/* @__PURE__ */ jsx2("div", { className: "pointer-events-none absolute top-0 right-0 z-10", children: /* @__PURE__ */ jsx2("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx2(
|
|
720
|
+
CopyButton,
|
|
721
|
+
{
|
|
722
|
+
text: () => tableElementToTsv(tableRef.current),
|
|
723
|
+
label: "Copy table",
|
|
724
|
+
reveal: "group-hover"
|
|
725
|
+
}
|
|
726
|
+
) }) }),
|
|
727
|
+
/* @__PURE__ */ jsx2("div", { className: "overflow-x-auto", tabIndex: 0, children: /* @__PURE__ */ jsx2(
|
|
728
|
+
"table",
|
|
729
|
+
{
|
|
730
|
+
ref: tableRef,
|
|
731
|
+
className: cn("w-full min-w-0 border-collapse text-og-base", className),
|
|
732
|
+
...props,
|
|
733
|
+
children
|
|
734
|
+
}
|
|
735
|
+
) })
|
|
736
|
+
] });
|
|
737
|
+
}
|
|
738
|
+
function MarkdownImpl({ children, className, streaming = false, onSandboxFile }) {
|
|
739
|
+
const revealRef = useRef2(null);
|
|
740
|
+
const bodyRef = useRef2(null);
|
|
741
|
+
const [, bump] = useReducer((n) => n + 1, 0);
|
|
742
|
+
const [settling, setSettling] = useState2(false);
|
|
743
|
+
const hadRevealRef = useRef2(false);
|
|
744
|
+
const now = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
745
|
+
const crystallize = (mutate) => {
|
|
746
|
+
mutate();
|
|
747
|
+
setSettling(true);
|
|
748
|
+
bump();
|
|
749
|
+
return setTimeout(() => setSettling(false), MARKDOWN_SETTLE_MS);
|
|
750
|
+
};
|
|
751
|
+
if (streaming && revealRef.current === null && !prefersReducedMotion()) {
|
|
752
|
+
revealRef.current = createStreamReveal();
|
|
753
|
+
}
|
|
754
|
+
const reveal = revealRef.current;
|
|
755
|
+
if (reveal !== null && streaming) {
|
|
756
|
+
reveal.observe(children, now);
|
|
757
|
+
}
|
|
758
|
+
if (reveal !== null) {
|
|
759
|
+
hadRevealRef.current = true;
|
|
760
|
+
}
|
|
761
|
+
const revealActive = reveal !== null && (streaming || reveal.hasActive(now));
|
|
762
|
+
const rehypePlugins = revealActive && reveal !== null ? [[rehypeStreamReveal, { reveal, now }]] : void 0;
|
|
763
|
+
useEffect2(() => {
|
|
764
|
+
if (streaming || revealRef.current === null) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
let clearSettle;
|
|
768
|
+
const timer = setTimeout(() => {
|
|
769
|
+
const shouldSettle = hadRevealRef.current && !prefersReducedMotion();
|
|
770
|
+
if (shouldSettle) {
|
|
771
|
+
hadRevealRef.current = false;
|
|
772
|
+
}
|
|
773
|
+
if (shouldSettle) {
|
|
774
|
+
clearSettle = crystallize(() => {
|
|
775
|
+
revealRef.current = null;
|
|
776
|
+
});
|
|
777
|
+
} else {
|
|
778
|
+
revealRef.current = null;
|
|
779
|
+
bump();
|
|
780
|
+
}
|
|
781
|
+
}, REVEAL_LINGER_MS);
|
|
782
|
+
return () => {
|
|
783
|
+
clearTimeout(timer);
|
|
784
|
+
if (clearSettle !== void 0) {
|
|
785
|
+
clearTimeout(clearSettle);
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
}, [streaming]);
|
|
789
|
+
const wasStreamingRef = useRef2(streaming);
|
|
790
|
+
useEffect2(() => {
|
|
791
|
+
const ended = wasStreamingRef.current && !streaming;
|
|
792
|
+
wasStreamingRef.current = streaming;
|
|
793
|
+
if (!ended || revealRef.current !== null || prefersReducedMotion()) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
setSettling(true);
|
|
797
|
+
const timer = setTimeout(() => setSettling(false), MARKDOWN_SETTLE_MS);
|
|
798
|
+
return () => clearTimeout(timer);
|
|
799
|
+
}, [streaming]);
|
|
800
|
+
const parseText = streaming || revealActive ? softenStreamingMarkdown(children) : children;
|
|
801
|
+
const components = useMemo(() => markdownComponents(onSandboxFile), [onSandboxFile]);
|
|
802
|
+
return /* @__PURE__ */ jsx2(TooltipProvider, { delayDuration: 400, children: /* @__PURE__ */ jsx2(
|
|
803
|
+
"div",
|
|
804
|
+
{
|
|
805
|
+
ref: bodyRef,
|
|
806
|
+
className: cn(
|
|
807
|
+
"og-markdown-body min-w-0 break-words",
|
|
808
|
+
settling && "og-markdown-settle",
|
|
809
|
+
className
|
|
810
|
+
),
|
|
811
|
+
children: /* @__PURE__ */ jsx2(
|
|
812
|
+
ReactMarkdown,
|
|
813
|
+
{
|
|
814
|
+
remarkPlugins: [remarkGfm],
|
|
815
|
+
rehypePlugins,
|
|
816
|
+
components,
|
|
817
|
+
urlTransform: markdownUrlTransform,
|
|
818
|
+
children: parseText
|
|
819
|
+
}
|
|
820
|
+
)
|
|
821
|
+
}
|
|
822
|
+
) });
|
|
823
|
+
}
|
|
824
|
+
var Markdown = memo(MarkdownImpl);
|
|
825
|
+
|
|
826
|
+
export {
|
|
827
|
+
prefersReducedMotion,
|
|
828
|
+
MOTION_INSPECT_SCALE,
|
|
829
|
+
CopyButton,
|
|
830
|
+
CopyHoverFrame,
|
|
831
|
+
sandboxFileLocationFromHref,
|
|
832
|
+
sandboxFilePathFromHref,
|
|
833
|
+
Markdown
|
|
834
|
+
};
|
|
835
|
+
//# sourceMappingURL=chunk-M2HNWZYR.js.map
|