@tangle-network/sandbox-ui 0.6.1 → 0.8.4
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/auth.d.ts +10 -6
- package/dist/auth.js +3 -3
- package/dist/{chat-container-Cg-GwyiK.d.ts → chat-container-f4yEs6KN.d.ts} +9 -1
- package/dist/chat.d.ts +12 -2
- package/dist/chat.js +10 -10
- package/dist/{chunk-TSE423UF.js → chunk-2QZ6G7NM.js} +6 -6
- package/dist/{chunk-WBQ7VULC.js → chunk-34A66VBG.js} +7 -7
- package/dist/{chunk-JP725R4W.js → chunk-34I7UFSX.js} +2 -2
- package/dist/{chunk-YS66Q3RC.js → chunk-3CJ2SOEI.js} +2 -2
- package/dist/{chunk-CNWVHQFY.js → chunk-54SQQMMM.js} +6 -24
- package/dist/{chunk-DLCFZDGX.js → chunk-5UM2XMEJ.js} +39 -14
- package/dist/{chunk-YYGECNZZ.js → chunk-66EZOYZR.js} +3 -3
- package/dist/chunk-7U2Z23NE.js +49 -0
- package/dist/{chunk-RKXIRRKQ.js → chunk-BUOQTBTO.js} +70 -66
- package/dist/{chunk-DCPYTL4W.js → chunk-D4CZWJCD.js} +72 -148
- package/dist/{chunk-MXRQ4MJE.js → chunk-DXMIEK4K.js} +34 -23
- package/dist/{chunk-ZMWWE5RF.js → chunk-EXSOPXIY.js} +141 -123
- package/dist/{chunk-GW4GRAWJ.js → chunk-GSZA3TSY.js} +18 -12
- package/dist/{chunk-W4LM3QYZ.js → chunk-HB5Y37YU.js} +8 -8
- package/dist/{chunk-E2XT3G52.js → chunk-HFMAXUHV.js} +136 -137
- package/dist/{chunk-BRBTD7RH.js → chunk-MA7YKRUP.js} +28 -18
- package/dist/{chunk-MJUDMVRU.js → chunk-MT5FJ3ZT.js} +17 -17
- package/dist/chunk-OKLQVY3Y.js +139 -0
- package/dist/{chunk-KH5UDAJ2.js → chunk-QDH5GEGY.js} +58 -54
- package/dist/{chunk-33W2TLUL.js → chunk-QID2OOMG.js} +12 -3
- package/dist/{chunk-FJSVPBKY.js → chunk-S7OXQTST.js} +17 -3
- package/dist/chunk-T7HMZEVO.js +216 -0
- package/dist/{chunk-FNYJFCGU.js → chunk-U6QTHMY6.js} +145 -256
- package/dist/{chunk-565V6JTN.js → chunk-UXQMIR3D.js} +60 -99
- package/dist/{chunk-XTPAWK7L.js → chunk-VOUV7GGB.js} +25 -47
- package/dist/{chunk-OVNLOE3Y.js → chunk-WXK43R62.js} +41 -41
- package/dist/{chunk-6V4XVKFY.js → chunk-XXDFEF72.js} +340 -335
- package/dist/{chunk-TDYQBLL5.js → chunk-ZMNSRDMH.js} +6 -6
- package/dist/dashboard.d.ts +135 -3
- package/dist/dashboard.js +848 -8
- package/dist/{document-editor-pane-DWWUTTTZ.js → document-editor-pane-TLPVRBBU.js} +3 -3
- package/dist/editor.d.ts +9 -8
- package/dist/editor.js +3 -3
- package/dist/files.js +3 -3
- package/dist/globals.css +5304 -68
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +7 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +28 -28
- package/dist/markdown.js +1 -1
- package/dist/openui.js +5 -5
- package/dist/pages.d.ts +47 -3
- package/dist/pages.js +911 -357
- package/dist/primitives.d.ts +5 -2
- package/dist/primitives.js +10 -10
- package/dist/run.js +4 -4
- package/dist/sdk-hooks.d.ts +2 -3
- package/dist/sdk-hooks.js +5 -5
- package/dist/styles.css +5304 -68
- package/dist/template-card-BAtvcAkU.d.ts +18 -0
- package/dist/terminal.d.ts +3 -1
- package/dist/terminal.js +66 -32
- package/dist/tokens.css +701 -40
- package/dist/{usage-chart-XCoB_7Xu.d.ts → usage-chart-SSiOgeQI.d.ts} +3 -1
- package/dist/{use-pty-session-COzVkhtc.d.ts → use-pty-session-0AOuwXgq.d.ts} +2 -0
- package/dist/{index-BT_-ecpc.d.ts → variant-list-C8wx2TqF.d.ts} +17 -8
- package/dist/workspace.d.ts +1 -1
- package/dist/workspace.js +13 -13
- package/package.json +3 -1
- package/tailwind.config.cjs +3 -2
- package/dist/chunk-3HW53XTH.js +0 -228
- package/dist/chunk-OKCIKTXQ.js +0 -63
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ArtifactPane
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HB5Y37YU.js";
|
|
4
4
|
import {
|
|
5
5
|
Markdown
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-T7HMZEVO.js";
|
|
7
7
|
import {
|
|
8
8
|
cn
|
|
9
9
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -92,9 +92,9 @@ function getFileColor(name) {
|
|
|
92
92
|
case "xlsx":
|
|
93
93
|
return "text-emerald-400";
|
|
94
94
|
case "md":
|
|
95
|
-
return "text-
|
|
95
|
+
return "text-foreground";
|
|
96
96
|
default:
|
|
97
|
-
return "text-
|
|
97
|
+
return "text-muted-foreground";
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
function TreeNode({ node, depth, selectedPath, onSelect, defaultExpanded }) {
|
|
@@ -108,25 +108,27 @@ function TreeNode({ node, depth, selectedPath, onSelect, defaultExpanded }) {
|
|
|
108
108
|
onSelect?.(node.path, node);
|
|
109
109
|
};
|
|
110
110
|
const Icon = isDir ? expanded ? FolderOpen : Folder : getFileIcon(node.name);
|
|
111
|
-
const iconColor = isDir ? "text-
|
|
111
|
+
const iconColor = isDir ? "text-primary" : getFileColor(node.name);
|
|
112
112
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
113
113
|
/* @__PURE__ */ jsxs(
|
|
114
114
|
"button",
|
|
115
115
|
{
|
|
116
|
-
|
|
116
|
+
type: "button",
|
|
117
117
|
className: cn(
|
|
118
|
-
"flex items-center gap-1.5 w-full text-left px-2 py-
|
|
119
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
"flex items-center gap-1.5 w-full text-left px-2 py-[2px] cursor-pointer text-[13px] transition-colors",
|
|
119
|
+
"appearance-none bg-transparent border-none",
|
|
120
|
+
"hover:bg-accent",
|
|
121
|
+
isSelected ? "bg-primary/15 text-foreground" : "text-foreground"
|
|
122
122
|
),
|
|
123
123
|
style: { paddingLeft: `${depth * 16 + 8}px` },
|
|
124
|
+
onClick: handleClick,
|
|
125
|
+
"aria-expanded": isDir ? expanded : void 0,
|
|
124
126
|
children: [
|
|
125
127
|
isDir && /* @__PURE__ */ jsx(
|
|
126
128
|
ChevronRight,
|
|
127
129
|
{
|
|
128
130
|
className: cn(
|
|
129
|
-
"h-3 w-3 shrink-0 text-
|
|
131
|
+
"h-3 w-3 shrink-0 text-muted-foreground transition-transform",
|
|
130
132
|
expanded && "rotate-90"
|
|
131
133
|
)
|
|
132
134
|
}
|
|
@@ -134,7 +136,7 @@ function TreeNode({ node, depth, selectedPath, onSelect, defaultExpanded }) {
|
|
|
134
136
|
!isDir && /* @__PURE__ */ jsx("span", { className: "w-3" }),
|
|
135
137
|
/* @__PURE__ */ jsx(Icon, { className: cn("h-4 w-4 shrink-0", iconColor) }),
|
|
136
138
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: node.name }),
|
|
137
|
-
node.size !== void 0 && !isDir && /* @__PURE__ */ jsx("span", { className: "text-
|
|
139
|
+
node.size !== void 0 && !isDir && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs ml-auto tabular-nums", children: formatSize(node.size) })
|
|
138
140
|
]
|
|
139
141
|
}
|
|
140
142
|
),
|
|
@@ -171,7 +173,7 @@ function FileTree({
|
|
|
171
173
|
if (!visibleRoot) {
|
|
172
174
|
return null;
|
|
173
175
|
}
|
|
174
|
-
return /* @__PURE__ */ jsx("div", { className: cn("text-sm font-
|
|
176
|
+
return /* @__PURE__ */ jsx("div", { className: cn("text-sm font-sans", className), children: visibleRoot.children ? visibleRoot.children.sort((a, b) => {
|
|
175
177
|
if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
|
|
176
178
|
return a.name.localeCompare(b.name);
|
|
177
179
|
}).map((child) => /* @__PURE__ */ jsx(
|
|
@@ -209,11 +211,12 @@ function getPreviewType(filename, mimeType) {
|
|
|
209
211
|
if (mimeType?.startsWith("image/") || ["png", "jpg", "jpeg", "gif", "svg", "webp"].includes(ext)) return "image";
|
|
210
212
|
if (["csv"].includes(ext)) return "csv";
|
|
211
213
|
if (["xlsx", "xls"].includes(ext)) return "spreadsheet";
|
|
212
|
-
if (["py", "ts", "js", "tsx", "jsx", "sh", "bash"].includes(ext)) return "code";
|
|
214
|
+
if (["py", "ts", "js", "tsx", "jsx", "sh", "bash"].includes(ext) || ["profile", "bashrc", "bash_logout", "env", "gitignore"].includes(ext)) return "code";
|
|
213
215
|
if (["json"].includes(ext)) return "json";
|
|
214
216
|
if (["yaml", "yml"].includes(ext)) return "yaml";
|
|
215
217
|
if (["md", "markdown"].includes(ext)) return "markdown";
|
|
216
218
|
if (["txt", "log", "text"].includes(ext)) return "text";
|
|
219
|
+
if (mimeType?.startsWith("text/plain")) return "text";
|
|
217
220
|
return "unknown";
|
|
218
221
|
}
|
|
219
222
|
function getPreviewLabel(previewType) {
|
|
@@ -243,15 +246,15 @@ function getPreviewLabel(previewType) {
|
|
|
243
246
|
function CodePreview({ content, filename }) {
|
|
244
247
|
const lines = content.split("\n");
|
|
245
248
|
const language = filename.split(".").pop()?.toUpperCase() || "TXT";
|
|
246
|
-
return /* @__PURE__ */ jsxs2("div", { className: "relative bg-
|
|
247
|
-
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-3 border-b border-
|
|
249
|
+
return /* @__PURE__ */ jsxs2("div", { className: "relative bg-background rounded-[var(--radius-md)] border border-border overflow-hidden", children: [
|
|
250
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
|
|
248
251
|
/* @__PURE__ */ jsxs2("div", { className: "flex gap-1.5", children: [
|
|
249
252
|
/* @__PURE__ */ jsx2("div", { className: "w-3 h-3 rounded-full bg-[#FF5F57]" }),
|
|
250
253
|
/* @__PURE__ */ jsx2("div", { className: "w-3 h-3 rounded-full bg-[#FEBC2E]" }),
|
|
251
254
|
/* @__PURE__ */ jsx2("div", { className: "w-3 h-3 rounded-full bg-[#8E59FF]" })
|
|
252
255
|
] }),
|
|
253
|
-
/* @__PURE__ */ jsx2("div", { className: "ml-2 min-w-0 flex-1 truncate text-xs font-
|
|
254
|
-
/* @__PURE__ */ jsxs2("div", { className: "inline-flex items-center gap-2 rounded-[var(--radius-full)] border border-
|
|
256
|
+
/* @__PURE__ */ jsx2("div", { className: "ml-2 min-w-0 flex-1 truncate text-xs font-mono text-muted-foreground", children: filename }),
|
|
257
|
+
/* @__PURE__ */ jsxs2("div", { className: "inline-flex items-center gap-2 rounded-[var(--radius-full)] border border-border bg-card px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground", children: [
|
|
255
258
|
/* @__PURE__ */ jsx2("span", { children: language }),
|
|
256
259
|
/* @__PURE__ */ jsx2("span", { className: "h-1 w-1 rounded-full bg-[var(--border-hover)]" }),
|
|
257
260
|
/* @__PURE__ */ jsxs2("span", { children: [
|
|
@@ -260,9 +263,9 @@ function CodePreview({ content, filename }) {
|
|
|
260
263
|
] })
|
|
261
264
|
] })
|
|
262
265
|
] }),
|
|
263
|
-
/* @__PURE__ */ jsx2("div", { className: "overflow-auto max-h-[70vh]", children: /* @__PURE__ */ jsx2("table", { className: "w-full", children: /* @__PURE__ */ jsx2("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tr", { className: "hover:bg-
|
|
264
|
-
/* @__PURE__ */ jsx2("td", { className: "text-right pr-4 pl-4 py-0 select-none text-
|
|
265
|
-
/* @__PURE__ */ jsx2("td", { className: "pr-4 py-0 font-
|
|
266
|
+
/* @__PURE__ */ jsx2("div", { className: "overflow-auto max-h-[70vh]", children: /* @__PURE__ */ jsx2("table", { className: "w-full", children: /* @__PURE__ */ jsx2("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tr", { className: "hover:bg-accent", children: [
|
|
267
|
+
/* @__PURE__ */ jsx2("td", { className: "text-right pr-4 pl-4 py-0 select-none text-muted-foreground text-xs font-mono w-10 align-top leading-[1.55]", children: i + 1 }),
|
|
268
|
+
/* @__PURE__ */ jsx2("td", { className: "pr-4 py-0 font-mono text-[13px] text-foreground leading-[1.55] whitespace-pre", children: line || " " })
|
|
266
269
|
] }, i)) }) }) })
|
|
267
270
|
] });
|
|
268
271
|
}
|
|
@@ -299,19 +302,19 @@ function CsvPreview({ content }) {
|
|
|
299
302
|
const rows = lines.slice(1).map(
|
|
300
303
|
(line) => parseCsvRow(line).map((cell) => cell.replace(/^"|"$/g, ""))
|
|
301
304
|
);
|
|
302
|
-
return /* @__PURE__ */ jsx2("div", { className: "overflow-auto max-h-[70vh] rounded-[var(--radius-md)] border border-
|
|
303
|
-
/* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { className: "bg-
|
|
305
|
+
return /* @__PURE__ */ jsx2("div", { className: "overflow-auto max-h-[70vh] rounded-[var(--radius-md)] border border-border", children: /* @__PURE__ */ jsxs2("table", { className: "w-full text-sm", children: [
|
|
306
|
+
/* @__PURE__ */ jsx2("thead", { children: /* @__PURE__ */ jsx2("tr", { className: "bg-muted/50 sticky top-0", children: headers.map((h, i) => /* @__PURE__ */ jsx2(
|
|
304
307
|
"th",
|
|
305
308
|
{
|
|
306
|
-
className: "px-3 py-2 text-left text-xs font-semibold text-
|
|
309
|
+
className: "px-3 py-2 text-left text-xs font-semibold text-foreground border-b border-border whitespace-nowrap",
|
|
307
310
|
children: h
|
|
308
311
|
},
|
|
309
312
|
i
|
|
310
313
|
)) }) }),
|
|
311
|
-
/* @__PURE__ */ jsx2("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx2("tr", { className: "border-b border-
|
|
314
|
+
/* @__PURE__ */ jsx2("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx2("tr", { className: "border-b border-border hover:bg-accent", children: row.map((cell, j) => /* @__PURE__ */ jsx2(
|
|
312
315
|
"td",
|
|
313
316
|
{
|
|
314
|
-
className: "px-3 py-1.5 text-
|
|
317
|
+
className: "px-3 py-1.5 text-foreground font-mono text-xs whitespace-nowrap",
|
|
315
318
|
children: cell
|
|
316
319
|
},
|
|
317
320
|
j
|
|
@@ -319,10 +322,10 @@ function CsvPreview({ content }) {
|
|
|
319
322
|
] }) });
|
|
320
323
|
}
|
|
321
324
|
function ImagePreview({ src, filename }) {
|
|
322
|
-
return /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-center p-4 bg-
|
|
325
|
+
return /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-center p-4 bg-background rounded-[var(--radius-md)] border border-border", children: /* @__PURE__ */ jsx2("img", { src, alt: filename, className: "max-w-full max-h-[70vh] object-contain rounded" }) });
|
|
323
326
|
}
|
|
324
327
|
function PdfPreview({ blobUrl, filename }) {
|
|
325
|
-
return /* @__PURE__ */ jsx2("div", { className: "rounded-[var(--radius-md)] border border-
|
|
328
|
+
return /* @__PURE__ */ jsx2("div", { className: "rounded-[var(--radius-md)] border border-border overflow-hidden bg-background", children: /* @__PURE__ */ jsx2(
|
|
326
329
|
"iframe",
|
|
327
330
|
{
|
|
328
331
|
src: blobUrl,
|
|
@@ -332,25 +335,25 @@ function PdfPreview({ blobUrl, filename }) {
|
|
|
332
335
|
) });
|
|
333
336
|
}
|
|
334
337
|
function TextPreview({ content }) {
|
|
335
|
-
return /* @__PURE__ */ jsx2("pre", { className: "bg-
|
|
338
|
+
return /* @__PURE__ */ jsx2("pre", { className: "bg-background rounded-[var(--radius-md)] border border-border p-4 overflow-auto max-h-[70vh] text-sm text-foreground font-mono leading-[1.55]", children: content });
|
|
336
339
|
}
|
|
337
340
|
function UnsupportedPreview({
|
|
338
341
|
filename,
|
|
339
342
|
title,
|
|
340
343
|
description
|
|
341
344
|
}) {
|
|
342
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center rounded-[var(--radius-md)] border border-dashed border-
|
|
345
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center rounded-[var(--radius-md)] border border-dashed border-border bg-background px-6 py-16 text-center text-muted-foreground", children: [
|
|
343
346
|
/* @__PURE__ */ jsx2(FileText2, { className: "mb-3 h-12 w-12 opacity-30" }),
|
|
344
|
-
/* @__PURE__ */ jsx2("p", { className: "text-sm text-
|
|
347
|
+
/* @__PURE__ */ jsx2("p", { className: "text-sm text-foreground", children: title }),
|
|
345
348
|
/* @__PURE__ */ jsx2("p", { className: "mt-1 max-w-md text-xs", children: description }),
|
|
346
349
|
/* @__PURE__ */ jsx2("p", { className: "mt-4 text-[11px] uppercase tracking-[0.12em]", children: filename })
|
|
347
350
|
] });
|
|
348
351
|
}
|
|
349
352
|
function MarkdownPreview({ content }) {
|
|
350
|
-
return /* @__PURE__ */ jsx2("div", { className: "rounded-[var(--radius-md)] border border-
|
|
353
|
+
return /* @__PURE__ */ jsx2("div", { className: "rounded-[var(--radius-md)] border border-border bg-background p-5", children: /* @__PURE__ */ jsx2(Markdown, { className: "prose-sm max-w-none", children: content }) });
|
|
351
354
|
}
|
|
352
355
|
function EmptyPreview({ filename }) {
|
|
353
|
-
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-16 text-
|
|
356
|
+
return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center justify-center py-16 text-muted-foreground", children: [
|
|
354
357
|
/* @__PURE__ */ jsx2(FileText2, { className: "h-12 w-12 mb-3 opacity-30" }),
|
|
355
358
|
/* @__PURE__ */ jsxs2("p", { className: "text-sm", children: [
|
|
356
359
|
"Cannot preview ",
|
|
@@ -373,10 +376,10 @@ function FilePreview({
|
|
|
373
376
|
const previewLabel = getPreviewLabel(previewType);
|
|
374
377
|
const hasRenderableSource = Boolean(content) || Boolean(blobUrl) || previewType === "unknown" || previewType === "spreadsheet";
|
|
375
378
|
return /* @__PURE__ */ jsxs2("div", { className: cn("flex flex-col h-full", className), children: [
|
|
376
|
-
!hideHeader && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-
|
|
379
|
+
!hideHeader && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border shrink-0", children: [
|
|
377
380
|
/* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
378
|
-
/* @__PURE__ */ jsx2("div", { className: "truncate text-sm font-medium text-
|
|
379
|
-
/* @__PURE__ */ jsx2("div", { className: "mt-0.5 text-[11px] uppercase tracking-[0.12em] text-
|
|
381
|
+
/* @__PURE__ */ jsx2("div", { className: "truncate text-sm font-medium text-foreground", children: filename }),
|
|
382
|
+
/* @__PURE__ */ jsx2("div", { className: "mt-0.5 text-[11px] uppercase tracking-[0.12em] text-muted-foreground", children: previewLabel })
|
|
380
383
|
] }),
|
|
381
384
|
onDownload && /* @__PURE__ */ jsx2(
|
|
382
385
|
"button",
|
|
@@ -384,7 +387,7 @@ function FilePreview({
|
|
|
384
387
|
type: "button",
|
|
385
388
|
onClick: onDownload,
|
|
386
389
|
"aria-label": `Download ${filename}`,
|
|
387
|
-
className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-
|
|
390
|
+
className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
388
391
|
children: /* @__PURE__ */ jsx2(Download, { className: "h-4 w-4" })
|
|
389
392
|
}
|
|
390
393
|
),
|
|
@@ -394,7 +397,7 @@ function FilePreview({
|
|
|
394
397
|
type: "button",
|
|
395
398
|
onClick: onClose,
|
|
396
399
|
"aria-label": `Close ${filename}`,
|
|
397
|
-
className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-
|
|
400
|
+
className: "p-1.5 rounded-[var(--radius-sm)] hover:bg-accent text-muted-foreground hover:text-foreground transition-colors",
|
|
398
401
|
children: /* @__PURE__ */ jsx2(X, { className: "h-4 w-4" })
|
|
399
402
|
}
|
|
400
403
|
)
|
|
@@ -402,10 +405,10 @@ function FilePreview({
|
|
|
402
405
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 overflow-auto p-3", children: [
|
|
403
406
|
previewType === "pdf" && blobUrl && /* @__PURE__ */ jsx2(PdfPreview, { blobUrl, filename }),
|
|
404
407
|
previewType === "image" && blobUrl && /* @__PURE__ */ jsx2(ImagePreview, { src: blobUrl, filename }),
|
|
405
|
-
previewType === "csv" && content && /* @__PURE__ */ jsx2(CsvPreview, { content }),
|
|
406
|
-
(previewType === "code" || previewType === "json" || previewType === "yaml") && content && /* @__PURE__ */ jsx2(CodePreview, { content, filename }),
|
|
407
|
-
previewType === "text" && content && /* @__PURE__ */ jsx2(TextPreview, { content }),
|
|
408
|
-
previewType === "markdown" && content && /* @__PURE__ */ jsx2(MarkdownPreview, { content }),
|
|
408
|
+
previewType === "csv" && typeof content === "string" && /* @__PURE__ */ jsx2(CsvPreview, { content }),
|
|
409
|
+
(previewType === "code" || previewType === "json" || previewType === "yaml") && typeof content === "string" && /* @__PURE__ */ jsx2(CodePreview, { content, filename }),
|
|
410
|
+
previewType === "text" && typeof content === "string" && /* @__PURE__ */ jsx2(TextPreview, { content }),
|
|
411
|
+
previewType === "markdown" && typeof content === "string" && /* @__PURE__ */ jsx2(MarkdownPreview, { content }),
|
|
409
412
|
previewType === "spreadsheet" && /* @__PURE__ */ jsx2(
|
|
410
413
|
UnsupportedPreview,
|
|
411
414
|
{
|
|
@@ -414,8 +417,9 @@ function FilePreview({
|
|
|
414
417
|
description: "Download the workbook or convert it to CSV when you need an inline preview."
|
|
415
418
|
}
|
|
416
419
|
),
|
|
417
|
-
previewType === "unknown" && /* @__PURE__ */ jsx2(EmptyPreview, { filename }),
|
|
418
|
-
|
|
420
|
+
previewType === "unknown" && typeof content !== "string" && /* @__PURE__ */ jsx2(EmptyPreview, { filename }),
|
|
421
|
+
previewType === "unknown" && typeof content === "string" && /* @__PURE__ */ jsx2(TextPreview, { content }),
|
|
422
|
+
!hasRenderableSource && typeof content !== "string" && /* @__PURE__ */ jsx2(
|
|
419
423
|
UnsupportedPreview,
|
|
420
424
|
{
|
|
421
425
|
filename,
|
|
@@ -438,15 +442,15 @@ function getTabIcon(name) {
|
|
|
438
442
|
}
|
|
439
443
|
function FileTabs({ tabs, activeId, onSelect, onClose, className }) {
|
|
440
444
|
if (tabs.length === 0) return null;
|
|
441
|
-
return /* @__PURE__ */ jsx3("div", { className: cn("flex items-center border-b border-
|
|
445
|
+
return /* @__PURE__ */ jsx3("div", { className: cn("flex items-center border-b border-border bg-background overflow-x-auto", className), children: tabs.map((tab) => {
|
|
442
446
|
const isActive = tab.id === activeId;
|
|
443
447
|
const Icon = getTabIcon(tab.name);
|
|
444
448
|
return /* @__PURE__ */ jsxs3(
|
|
445
449
|
"div",
|
|
446
450
|
{
|
|
447
451
|
className: cn(
|
|
448
|
-
"group flex items-center border-r border-
|
|
449
|
-
isActive ? "bg-
|
|
452
|
+
"group flex items-center border-r border-border shrink-0",
|
|
453
|
+
isActive ? "bg-card text-foreground border-b-2 border-b-primary" : "text-muted-foreground hover:bg-muted/50"
|
|
450
454
|
),
|
|
451
455
|
children: [
|
|
452
456
|
/* @__PURE__ */ jsxs3(
|
|
@@ -454,11 +458,11 @@ function FileTabs({ tabs, activeId, onSelect, onClose, className }) {
|
|
|
454
458
|
{
|
|
455
459
|
type: "button",
|
|
456
460
|
onClick: () => onSelect(tab.id),
|
|
457
|
-
className: "flex min-w-0 items-center gap-1.5 px-3 py-1.5 text-xs transition-colors hover:text-
|
|
461
|
+
className: "flex min-w-0 items-center gap-1.5 px-3 py-1.5 text-xs transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary/60",
|
|
458
462
|
children: [
|
|
459
463
|
/* @__PURE__ */ jsx3(Icon, { className: "h-3 w-3 shrink-0" }),
|
|
460
464
|
/* @__PURE__ */ jsx3("span", { className: "max-w-[120px] truncate", children: tab.name }),
|
|
461
|
-
tab.dirty && /* @__PURE__ */ jsx3("span", { className: "h-1.5 w-1.5 rounded-full bg-
|
|
465
|
+
tab.dirty && /* @__PURE__ */ jsx3("span", { className: "h-1.5 w-1.5 rounded-full bg-primary" })
|
|
462
466
|
]
|
|
463
467
|
}
|
|
464
468
|
),
|
|
@@ -468,7 +472,7 @@ function FileTabs({ tabs, activeId, onSelect, onClose, className }) {
|
|
|
468
472
|
type: "button",
|
|
469
473
|
"aria-label": `Close ${tab.name}`,
|
|
470
474
|
onClick: () => onClose(tab.id),
|
|
471
|
-
className: "mr-1 rounded p-0.5 opacity-0 transition-opacity hover:bg-
|
|
475
|
+
className: "mr-1 rounded p-0.5 opacity-0 transition-opacity hover:bg-accent focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60 group-hover:opacity-100",
|
|
472
476
|
children: /* @__PURE__ */ jsx3(X2, { className: "h-2.5 w-2.5" })
|
|
473
477
|
}
|
|
474
478
|
)
|
|
@@ -484,7 +488,7 @@ import { lazy, Suspense } from "react";
|
|
|
484
488
|
import { Download as Download2, X as X3 } from "lucide-react";
|
|
485
489
|
import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
486
490
|
var LazyDocumentEditorPane = lazy(async () => {
|
|
487
|
-
const module = await import("./document-editor-pane-
|
|
491
|
+
const module = await import("./document-editor-pane-TLPVRBBU.js");
|
|
488
492
|
return { default: module.DocumentEditorPane };
|
|
489
493
|
});
|
|
490
494
|
function FileArtifactPane({
|
|
@@ -525,7 +529,7 @@ function FileArtifactPane({
|
|
|
525
529
|
type: "button",
|
|
526
530
|
"aria-label": `Download ${filename}`,
|
|
527
531
|
onClick: onDownload,
|
|
528
|
-
className: "rounded-[var(--radius-sm)] p-1.5 text-
|
|
532
|
+
className: "rounded-[var(--radius-sm)] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60",
|
|
529
533
|
children: /* @__PURE__ */ jsx4(Download2, { className: "h-4 w-4" })
|
|
530
534
|
}
|
|
531
535
|
),
|
|
@@ -535,7 +539,7 @@ function FileArtifactPane({
|
|
|
535
539
|
type: "button",
|
|
536
540
|
"aria-label": `Close ${filename}`,
|
|
537
541
|
onClick: onClose,
|
|
538
|
-
className: "rounded-[var(--radius-sm)] p-1.5 text-
|
|
542
|
+
className: "rounded-[var(--radius-sm)] p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60",
|
|
539
543
|
children: /* @__PURE__ */ jsx4(X3, { className: "h-4 w-4" })
|
|
540
544
|
}
|
|
541
545
|
)
|
|
@@ -556,7 +560,7 @@ function FileArtifactPane({
|
|
|
556
560
|
className,
|
|
557
561
|
tabs: paneTabs,
|
|
558
562
|
headerActions,
|
|
559
|
-
children: /* @__PURE__ */ jsx4("div", { className: "flex min-h-[12rem] items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-
|
|
563
|
+
children: /* @__PURE__ */ jsx4("div", { className: "flex min-h-[12rem] items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-border bg-muted text-sm text-muted-foreground", children: "Loading editor\u2026" })
|
|
560
564
|
}
|
|
561
565
|
),
|
|
562
566
|
children: /* @__PURE__ */ jsx4(
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ToolCallGroup,
|
|
3
3
|
ToolCallStep
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MT5FJ3ZT.js";
|
|
5
5
|
import {
|
|
6
6
|
Markdown
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-T7HMZEVO.js";
|
|
8
8
|
import {
|
|
9
9
|
cn
|
|
10
10
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -54,7 +54,7 @@ function parseToolEvent(event) {
|
|
|
54
54
|
const toolName = data.name || data.tool || "unknown";
|
|
55
55
|
const input = data.input;
|
|
56
56
|
return {
|
|
57
|
-
id: data.id || data.toolUseId ||
|
|
57
|
+
id: data.id || data.toolUseId || createId(),
|
|
58
58
|
type: mapToolName(toolName),
|
|
59
59
|
label: formatToolLabel(toolName, input),
|
|
60
60
|
status: "running",
|
|
@@ -73,6 +73,15 @@ function parseToolEvent(event) {
|
|
|
73
73
|
}
|
|
74
74
|
return null;
|
|
75
75
|
}
|
|
76
|
+
function createId() {
|
|
77
|
+
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.randomUUID === "function") {
|
|
78
|
+
try {
|
|
79
|
+
return globalThis.crypto.randomUUID();
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return `tool_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
84
|
+
}
|
|
76
85
|
function mapToolName(name) {
|
|
77
86
|
const lower = name.toLowerCase();
|
|
78
87
|
if (lower.includes("bash") || lower.includes("terminal") || lower.includes("exec")) return "bash";
|
|
@@ -8,12 +8,18 @@ function useAuth({
|
|
|
8
8
|
const [user, setUser] = React.useState(null);
|
|
9
9
|
const [isLoading, setIsLoading] = React.useState(true);
|
|
10
10
|
const [error, setError] = React.useState(null);
|
|
11
|
+
const retryTimerRef = React.useRef(null);
|
|
12
|
+
const abortRef = React.useRef(null);
|
|
11
13
|
const fetchSession = React.useCallback(async () => {
|
|
14
|
+
abortRef.current?.abort();
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
abortRef.current = controller;
|
|
12
17
|
setIsLoading(true);
|
|
13
18
|
setError(null);
|
|
14
19
|
try {
|
|
15
20
|
const res = await fetch(`${apiBaseUrl}/auth/session`, {
|
|
16
|
-
credentials: "include"
|
|
21
|
+
credentials: "include",
|
|
22
|
+
signal: controller.signal
|
|
17
23
|
});
|
|
18
24
|
if (!res.ok) {
|
|
19
25
|
throw new Error("Not authenticated");
|
|
@@ -25,17 +31,25 @@ function useAuth({
|
|
|
25
31
|
setUser(null);
|
|
26
32
|
}
|
|
27
33
|
} catch (err) {
|
|
34
|
+
if (err.name === "AbortError") return;
|
|
28
35
|
setError(err instanceof Error ? err : new Error("Unknown error"));
|
|
29
36
|
setUser(null);
|
|
30
37
|
if (shouldRetryOnError) {
|
|
31
|
-
|
|
38
|
+
if (retryTimerRef.current) clearTimeout(retryTimerRef.current);
|
|
39
|
+
retryTimerRef.current = setTimeout(fetchSession, 5e3);
|
|
32
40
|
}
|
|
33
41
|
} finally {
|
|
34
|
-
|
|
42
|
+
if (!controller.signal.aborted) {
|
|
43
|
+
setIsLoading(false);
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
46
|
}, [apiBaseUrl, shouldRetryOnError]);
|
|
37
47
|
React.useEffect(() => {
|
|
38
48
|
fetchSession();
|
|
49
|
+
return () => {
|
|
50
|
+
abortRef.current?.abort();
|
|
51
|
+
if (retryTimerRef.current) clearTimeout(retryTimerRef.current);
|
|
52
|
+
};
|
|
39
53
|
}, [fetchSession]);
|
|
40
54
|
React.useEffect(() => {
|
|
41
55
|
if (!revalidateOnFocus) return;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn
|
|
3
|
+
} from "./chunk-RQHJBTEU.js";
|
|
4
|
+
|
|
5
|
+
// src/markdown/code-block.tsx
|
|
6
|
+
import {
|
|
7
|
+
memo,
|
|
8
|
+
useCallback,
|
|
9
|
+
useEffect,
|
|
10
|
+
useRef,
|
|
11
|
+
useState
|
|
12
|
+
} from "react";
|
|
13
|
+
import SyntaxHighlighter from "react-syntax-highlighter";
|
|
14
|
+
import { Check, Copy } from "lucide-react";
|
|
15
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
function getSyntaxTheme() {
|
|
17
|
+
const el = typeof document !== "undefined" ? document.documentElement : null;
|
|
18
|
+
const v = (name, fallback) => el ? getComputedStyle(el).getPropertyValue(name).trim() || fallback : fallback;
|
|
19
|
+
const comment = v("--syntax-comment", "#6B7094");
|
|
20
|
+
const keyword = v("--syntax-keyword", "#A78FFF");
|
|
21
|
+
const string = v("--syntax-string", "#10b981");
|
|
22
|
+
const fn = v("--syntax-function", "#6D9FFF");
|
|
23
|
+
const number = v("--syntax-number", "#FFB347");
|
|
24
|
+
const meta = v("--syntax-meta", "#8263FF");
|
|
25
|
+
const error = v("--syntax-error", "#FF4D6D");
|
|
26
|
+
const variable = v("--syntax-variable", "#C4C0D8");
|
|
27
|
+
const fg = v("--syntax-foreground", "#E8E6F6");
|
|
28
|
+
return {
|
|
29
|
+
"hljs-comment": { color: comment, fontStyle: "italic" },
|
|
30
|
+
"hljs-quote": { color: comment, fontStyle: "italic" },
|
|
31
|
+
"hljs-doctag": { color: comment },
|
|
32
|
+
"hljs-keyword": { color: keyword },
|
|
33
|
+
"hljs-selector-tag": { color: keyword },
|
|
34
|
+
"hljs-literal": { color: keyword },
|
|
35
|
+
"hljs-type": { color: keyword },
|
|
36
|
+
"hljs-class": { color: keyword },
|
|
37
|
+
"hljs-string": { color: string },
|
|
38
|
+
"hljs-template-tag": { color: string },
|
|
39
|
+
"hljs-template-variable": { color: string },
|
|
40
|
+
"hljs-addition": { color: string },
|
|
41
|
+
"hljs-regexp": { color: string },
|
|
42
|
+
"hljs-title": { color: fn },
|
|
43
|
+
"hljs-section": { color: fn },
|
|
44
|
+
"hljs-built_in": { color: fn },
|
|
45
|
+
"hljs-name": { color: fn },
|
|
46
|
+
"hljs-function": { color: fn },
|
|
47
|
+
"hljs-selector-id": { color: fn },
|
|
48
|
+
"hljs-selector-class": { color: fn },
|
|
49
|
+
"hljs-attribute": { color: fn },
|
|
50
|
+
"hljs-number": { color: number },
|
|
51
|
+
"hljs-symbol": { color: number },
|
|
52
|
+
"hljs-bullet": { color: number },
|
|
53
|
+
"hljs-link": { color: number, textDecoration: "underline" },
|
|
54
|
+
"hljs-meta": { color: meta },
|
|
55
|
+
"hljs-selector-pseudo": { color: meta },
|
|
56
|
+
"hljs-deletion": { color: error },
|
|
57
|
+
"hljs-params": { color: variable },
|
|
58
|
+
"hljs-variable": { color: variable },
|
|
59
|
+
"hljs-tag": { color: variable },
|
|
60
|
+
"hljs-attr": { color: variable },
|
|
61
|
+
"hljs-subst": { color: variable },
|
|
62
|
+
"hljs-strong": { fontWeight: "bold" },
|
|
63
|
+
"hljs-emphasis": { fontStyle: "italic" },
|
|
64
|
+
"hljs": { color: fg, background: "transparent" }
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
var LIGHT_THEMES = /* @__PURE__ */ new Set(["vault", "dawn"]);
|
|
68
|
+
function detectLightTheme() {
|
|
69
|
+
return typeof document !== "undefined" && LIGHT_THEMES.has(document.documentElement.getAttribute("data-sandbox-theme") ?? "");
|
|
70
|
+
}
|
|
71
|
+
function useIsLightTheme() {
|
|
72
|
+
const [isLight, setIsLight] = useState(detectLightTheme);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (typeof document === "undefined") return;
|
|
75
|
+
setIsLight(detectLightTheme());
|
|
76
|
+
const observer = new MutationObserver(() => setIsLight(detectLightTheme()));
|
|
77
|
+
observer.observe(document.documentElement, {
|
|
78
|
+
attributes: true,
|
|
79
|
+
attributeFilter: ["data-sandbox-theme"]
|
|
80
|
+
});
|
|
81
|
+
return () => observer.disconnect();
|
|
82
|
+
}, []);
|
|
83
|
+
return isLight;
|
|
84
|
+
}
|
|
85
|
+
var CodeBlock = memo(
|
|
86
|
+
({ code, language, showLineNumbers = false, light: lightProp, className, children, ...props }) => {
|
|
87
|
+
const isLight = useIsLightTheme();
|
|
88
|
+
const light = lightProp ?? isLight;
|
|
89
|
+
const theme = getSyntaxTheme();
|
|
90
|
+
const bg = "bg-card border-border";
|
|
91
|
+
const headerBg = light ? "bg-muted/50 border-border" : "bg-background border-border";
|
|
92
|
+
const langColor = "text-muted-foreground";
|
|
93
|
+
return /* @__PURE__ */ jsxs(
|
|
94
|
+
"div",
|
|
95
|
+
{
|
|
96
|
+
className: cn("group relative overflow-hidden rounded-lg border font-mono", bg, className),
|
|
97
|
+
...props,
|
|
98
|
+
children: [
|
|
99
|
+
language && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between border-b px-3 py-1", headerBg), children: [
|
|
100
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-[calc(var(--font-size-xs)-1px)] font-mono font-medium uppercase tracking-widest", langColor), children: language }),
|
|
101
|
+
children
|
|
102
|
+
] }),
|
|
103
|
+
!language && children && /* @__PURE__ */ jsx("div", { className: "absolute right-2 top-2 z-10 flex items-center gap-2 opacity-0 transition-opacity group-hover:opacity-100", children }),
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
SyntaxHighlighter,
|
|
106
|
+
{
|
|
107
|
+
language: language ?? "text",
|
|
108
|
+
style: theme,
|
|
109
|
+
showLineNumbers,
|
|
110
|
+
lineNumberStyle: {
|
|
111
|
+
color: light ? "#8B92B8" : "#4A4D6A",
|
|
112
|
+
minWidth: "2.5em",
|
|
113
|
+
paddingRight: "1em"
|
|
114
|
+
},
|
|
115
|
+
customStyle: {
|
|
116
|
+
margin: 0,
|
|
117
|
+
padding: "var(--code-padding-y, 0.625rem) var(--code-padding-x, 0.75rem)",
|
|
118
|
+
background: "transparent",
|
|
119
|
+
fontSize: "var(--code-font-size, 0.8125rem)",
|
|
120
|
+
lineHeight: "var(--code-line-height, 1.5)",
|
|
121
|
+
overflowX: "auto"
|
|
122
|
+
},
|
|
123
|
+
codeTagProps: { style: { fontFamily: "var(--font-mono, 'JetBrains Mono', ui-monospace, monospace)" } },
|
|
124
|
+
wrapLines: false,
|
|
125
|
+
children: code
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
CodeBlock.displayName = "CodeBlock";
|
|
134
|
+
var CopyButton = memo(({ text }) => {
|
|
135
|
+
const [copied, setCopied] = useState(false);
|
|
136
|
+
const timerRef = useRef(null);
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
return () => {
|
|
139
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
140
|
+
};
|
|
141
|
+
}, []);
|
|
142
|
+
const handleCopy = useCallback(async () => {
|
|
143
|
+
try {
|
|
144
|
+
await navigator.clipboard.writeText(text);
|
|
145
|
+
setCopied(true);
|
|
146
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
147
|
+
timerRef.current = setTimeout(() => setCopied(false), 2e3);
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.warn("Clipboard write failed:", err);
|
|
150
|
+
}
|
|
151
|
+
}, [text]);
|
|
152
|
+
return /* @__PURE__ */ jsx(
|
|
153
|
+
"button",
|
|
154
|
+
{
|
|
155
|
+
onClick: handleCopy,
|
|
156
|
+
className: "flex items-center justify-center w-6 h-6 rounded-md bg-muted border border-border hover:border-primary/20 transition-colors",
|
|
157
|
+
title: "Copy to clipboard",
|
|
158
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 text-emerald-500" }) : /* @__PURE__ */ jsx(Copy, { className: "w-3.5 h-3.5 text-muted-foreground" })
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
CopyButton.displayName = "CopyButton";
|
|
163
|
+
|
|
164
|
+
// src/markdown/markdown.tsx
|
|
165
|
+
import { memo as memo2 } from "react";
|
|
166
|
+
import ReactMarkdown from "react-markdown";
|
|
167
|
+
import remarkGfm from "remark-gfm";
|
|
168
|
+
import rehypeSanitize from "rehype-sanitize";
|
|
169
|
+
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
170
|
+
var Markdown = memo2(({ children, className }) => {
|
|
171
|
+
return /* @__PURE__ */ jsx2(
|
|
172
|
+
"div",
|
|
173
|
+
{
|
|
174
|
+
className: cn("prose prose-sm dark:prose-invert max-w-none", className),
|
|
175
|
+
children: /* @__PURE__ */ jsx2(
|
|
176
|
+
ReactMarkdown,
|
|
177
|
+
{
|
|
178
|
+
remarkPlugins: [remarkGfm],
|
|
179
|
+
rehypePlugins: [rehypeSanitize],
|
|
180
|
+
components: {
|
|
181
|
+
pre({ children: preChildren }) {
|
|
182
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: preChildren });
|
|
183
|
+
},
|
|
184
|
+
code({ className: codeClass, children: codeChildren, ...rest }) {
|
|
185
|
+
const match = /language-(\w+)/.exec(codeClass || "");
|
|
186
|
+
const language = match?.[1];
|
|
187
|
+
const code = String(codeChildren).replace(/\n$/, "");
|
|
188
|
+
if (!language && !code.includes("\n")) {
|
|
189
|
+
return /* @__PURE__ */ jsx2(
|
|
190
|
+
"code",
|
|
191
|
+
{
|
|
192
|
+
className: cn(
|
|
193
|
+
"px-1.5 py-0.5 rounded border border-border bg-card text-[var(--code-keyword)] text-[0.85em] font-mono",
|
|
194
|
+
codeClass
|
|
195
|
+
),
|
|
196
|
+
...rest,
|
|
197
|
+
children: codeChildren
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
return /* @__PURE__ */ jsx2(CodeBlock, { code, language, children: /* @__PURE__ */ jsx2(CopyButton, { text: code }) });
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
children
|
|
205
|
+
}
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
Markdown.displayName = "Markdown";
|
|
211
|
+
|
|
212
|
+
export {
|
|
213
|
+
CodeBlock,
|
|
214
|
+
CopyButton,
|
|
215
|
+
Markdown
|
|
216
|
+
};
|