opencami 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/client/assets/{CSPContext-BBLAL_m_.js → CSPContext-Bq8j4nl9.js} +1 -1
- package/dist/client/assets/DirectionContext-BdX86BHP.js +1 -0
- package/dist/client/assets/_sessionKey-DsjnpErt.js +14 -0
- package/dist/client/assets/agents-DwxKcpP6.js +2 -0
- package/dist/client/assets/agents-screen-DwIY8hze.js +1 -0
- package/dist/client/assets/bots-CRlm-3-d.js +2 -0
- package/dist/client/assets/bots-screen-c78I920d.js +1 -0
- package/dist/client/assets/button-Dg7VFQQn.js +1 -0
- package/dist/client/assets/composite-DBl8R3ae.js +1 -0
- package/dist/client/assets/{connect-DHr3hhUR.js → connect-NYvOqiBJ.js} +1 -1
- package/dist/client/assets/file-explorer-screen-BSMbs0vi.js +1 -0
- package/dist/client/assets/files-BJbMx0_w.js +2 -0
- package/dist/client/assets/{index-B2iG4EM1.js → index-CMATW8VA.js} +1 -1
- package/dist/client/assets/{index-GTR-Xzl2.js → index-rOIRO-8E.js} +1 -1
- package/dist/client/assets/keyboard-shortcuts-dialog-BTGWdJMl.js +1 -0
- package/dist/client/assets/{main-mIHr_ble.js → main-B_dlfHME.js} +9 -9
- package/dist/client/assets/markdown-BVzT7z4x.js +87 -0
- package/dist/client/assets/memory-S3Yws6a5.js +2 -0
- package/dist/client/assets/memory-screen-C-Z9o31m.js +1 -0
- package/dist/client/assets/menu-DHNgWk_8.js +1 -0
- package/dist/client/assets/{opencami-logo-CRIdKbbZ.js → opencami-logo-BQQETnJG.js} +1 -1
- package/dist/client/assets/owner-CpRnf1fI.js +1 -0
- package/dist/client/assets/popupStateMapping-BRPDXnjv.js +1 -0
- package/dist/client/assets/proxy-BcUh9kMA.js +9 -0
- package/dist/client/assets/{react-Cfq4ot0g.js → react-irH8OzhB.js} +1 -1
- package/dist/client/assets/search-dialog-B96zx_ng.js +1 -0
- package/dist/client/assets/session-export-dialog-DPuHnhgv.js +1 -0
- package/dist/client/assets/settings-dialog-DZcRCaPj.js +1 -0
- package/dist/client/assets/skills-YZe3I63y.js +2 -0
- package/dist/client/assets/{skills-panel-Cv-N_MDk.js → skills-panel-WDUfIwnI.js} +2 -2
- package/dist/client/assets/styles-Bwo-K6Y4.css +1 -0
- package/dist/client/assets/{switch-Bh9tVOYh.js → switch-DPocNFRG.js} +1 -1
- package/dist/client/assets/tabs-B0cro1hL.js +1 -0
- package/dist/client/assets/tooltip-Dg9fy-vT.js +1 -0
- package/dist/client/assets/use-file-explorer-state-DzT0bksg.js +12 -0
- package/dist/client/assets/{useButton-DsMdJPGn.js → useButton-Cbl_9oFG.js} +1 -1
- package/dist/client/assets/useCompositeItem-BDAzTxVe.js +1 -0
- package/dist/client/assets/{useControlled-wOKVgKF4.js → useControlled-Dscz_s4f.js} +1 -1
- package/dist/client/assets/{useMutation-fJnleJAb.js → useMutation-B1FlDsNN.js} +1 -1
- package/dist/client/assets/visuallyHidden-ONmQ-0U2.js +1 -0
- package/dist/server/assets/{_sessionKey-B5UHBd2U.js → _sessionKey-B0ZlLAjH.js} +172 -567
- package/dist/server/assets/_tanstack-start-manifest_v-D5UVTs1o.js +4 -0
- package/dist/server/assets/{file-explorer-screen-CVlFiAFu.js → file-explorer-screen-DH4UFK03.js} +3 -2
- package/dist/server/assets/{files-BIEcSPGp.js → files-DYdXlQDr.js} +1 -1
- package/dist/server/assets/{index--_jH_0mX.js → index-CiUjUD0t.js} +1 -1
- package/dist/server/assets/{keyboard-shortcuts-dialog-CsNP85q8.js → keyboard-shortcuts-dialog-Cr6fOqHz.js} +1 -2
- package/dist/server/assets/markdown-BFE5y9YH.js +565 -0
- package/dist/server/assets/memory-BqZOoD7Q.js +11 -0
- package/dist/server/assets/memory-screen-BK5phS8K.js +235 -0
- package/dist/server/assets/menu-D90CDTi2.js +45 -0
- package/dist/server/assets/{router-DJA7GtMo.js → router-Uuagl6O7.js} +55 -45
- package/dist/server/assets/{search-dialog-C2a3OYm_.js → search-dialog-DZTS5SEi.js} +6 -4
- package/dist/server/assets/{session-export-dialog-CwclV0Aj.js → session-export-dialog-C53RRAah.js} +1 -2
- package/dist/server/assets/{settings-dialog-CHVzrou9.js → settings-dialog-CSYDj2qm.js} +75 -20
- package/dist/server/assets/{use-file-explorer-state-Il1LlBAe.js → use-file-explorer-state-s7CS50ho.js} +0 -41
- package/dist/server/server.js +2 -2
- package/package.json +1 -1
- package/dist/client/assets/DirectionContext-DXnZc0zz.js +0 -1
- package/dist/client/assets/_sessionKey-BidmO1-D.js +0 -100
- package/dist/client/assets/agents-CtZs_u1j.js +0 -2
- package/dist/client/assets/agents-screen-Basce5qo.js +0 -1
- package/dist/client/assets/bots-C_dWjy3z.js +0 -2
- package/dist/client/assets/bots-screen-n_xhYOEE.js +0 -1
- package/dist/client/assets/button-BaHefIXU.js +0 -1
- package/dist/client/assets/file-explorer-screen-8t6M4Xco.js +0 -1
- package/dist/client/assets/files-BdlpK3Cy.js +0 -2
- package/dist/client/assets/keyboard-shortcuts-dialog-CcKSlK52.js +0 -1
- package/dist/client/assets/search-dialog-D19x_xaG.js +0 -1
- package/dist/client/assets/session-export-dialog-DRlJwhMa.js +0 -1
- package/dist/client/assets/settings-dialog-BA5FjiyP.js +0 -1
- package/dist/client/assets/skills-lmNPZksG.js +0 -2
- package/dist/client/assets/styles-JgjN_ZCd.css +0 -1
- package/dist/client/assets/tabs-BfaEc9zS.js +0 -1
- package/dist/client/assets/tooltip-w9D-e_R-.js +0 -1
- package/dist/client/assets/use-file-explorer-state-CLaDuI9X.js +0 -12
- package/dist/client/assets/useCompositeItem-CaYygSfB.js +0 -1
- package/dist/client/assets/visuallyHidden-CqGRL_Oq.js +0 -9
- package/dist/server/assets/_tanstack-start-manifest_v-D11xMFUx.js +0 -4
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "/home/runner/work/opencami/opencami/src/routes/__root.tsx", "children": ["/", "/agents", "/bots", "/connect", "/files", "/memory", "/new", "/skills", "/api/agents", "/api/cron", "/api/follow-ups", "/api/history", "/api/llm-features", "/api/models", "/api/paths", "/api/personas", "/api/ping", "/api/send", "/api/sessions", "/api/skills", "/api/stream", "/api/stt", "/api/tts", "/chat/$sessionKey", "/api/files/delete", "/api/files/download", "/api/files/info", "/api/files/list", "/api/files/mkdir", "/api/files/read", "/api/files/rename", "/api/files/save", "/api/files/upload"], "preloads": ["/assets/main-B_dlfHME.js"], "assets": [] }, "/": { "filePath": "/home/runner/work/opencami/opencami/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-rOIRO-8E.js"] }, "/agents": { "filePath": "/home/runner/work/opencami/opencami/src/routes/agents.tsx", "assets": [], "preloads": ["/assets/agents-DwxKcpP6.js"] }, "/bots": { "filePath": "/home/runner/work/opencami/opencami/src/routes/bots.tsx", "assets": [], "preloads": ["/assets/bots-CRlm-3-d.js"] }, "/connect": { "filePath": "/home/runner/work/opencami/opencami/src/routes/connect.tsx", "assets": [], "preloads": ["/assets/connect-NYvOqiBJ.js", "/assets/index-CMATW8VA.js", "/assets/button-Dg7VFQQn.js", "/assets/react-irH8OzhB.js"] }, "/files": { "filePath": "/home/runner/work/opencami/opencami/src/routes/files.tsx", "assets": [], "preloads": ["/assets/files-BJbMx0_w.js"] }, "/memory": { "filePath": "/home/runner/work/opencami/opencami/src/routes/memory.tsx", "assets": [], "preloads": ["/assets/memory-S3Yws6a5.js"] }, "/new": { "filePath": "/home/runner/work/opencami/opencami/src/routes/new.tsx", "assets": [], "preloads": ["/assets/new-DLlBm66g.js"] }, "/skills": { "filePath": "/home/runner/work/opencami/opencami/src/routes/skills.tsx", "assets": [], "preloads": ["/assets/skills-YZe3I63y.js"] }, "/api/agents": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/agents.ts" }, "/api/cron": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/cron.ts" }, "/api/follow-ups": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/follow-ups.ts" }, "/api/history": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/history.ts" }, "/api/llm-features": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/llm-features.ts" }, "/api/models": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/models.ts" }, "/api/paths": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/paths.ts" }, "/api/personas": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/personas.ts" }, "/api/ping": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/ping.ts" }, "/api/send": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/send.ts" }, "/api/sessions": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/sessions.ts" }, "/api/skills": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/skills.ts" }, "/api/stream": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/stream.ts" }, "/api/stt": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/stt.ts" }, "/api/tts": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/tts.ts" }, "/chat/$sessionKey": { "filePath": "/home/runner/work/opencami/opencami/src/routes/chat/$sessionKey.tsx", "assets": [], "preloads": ["/assets/_sessionKey-DsjnpErt.js", "/assets/visuallyHidden-ONmQ-0U2.js", "/assets/tooltip-Dg9fy-vT.js", "/assets/button-Dg7VFQQn.js", "/assets/use-file-explorer-state-DzT0bksg.js", "/assets/useButton-Cbl_9oFG.js", "/assets/useControlled-Dscz_s4f.js", "/assets/popupStateMapping-BRPDXnjv.js", "/assets/owner-CpRnf1fI.js", "/assets/CSPContext-Bq8j4nl9.js", "/assets/DirectionContext-BdX86BHP.js", "/assets/menu-DHNgWk_8.js", "/assets/useMutation-B1FlDsNN.js", "/assets/opencami-logo-BQQETnJG.js", "/assets/proxy-BcUh9kMA.js", "/assets/markdown-BVzT7z4x.js", "/assets/index-CMATW8VA.js", "/assets/react-irH8OzhB.js"] }, "/api/files/delete": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/delete.ts" }, "/api/files/download": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/download.ts" }, "/api/files/info": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/info.ts" }, "/api/files/list": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/list.ts" }, "/api/files/mkdir": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/mkdir.ts" }, "/api/files/read": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/read.ts" }, "/api/files/rename": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/rename.ts" }, "/api/files/save": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/save.ts" }, "/api/files/upload": { "filePath": "/home/runner/work/opencami/opencami/src/routes/api/files/upload.ts" } }, "clientEntry": "/assets/main-B_dlfHME.js" });
|
|
2
|
+
export {
|
|
3
|
+
tsrStartManifest
|
|
4
|
+
};
|
package/dist/server/assets/{file-explorer-screen-CVlFiAFu.js → file-explorer-screen-DH4UFK03.js}
RENAMED
|
@@ -7,7 +7,8 @@ import { motion, AnimatePresence } from "motion/react";
|
|
|
7
7
|
import { T as TooltipProvider, a as TooltipRoot, b as TooltipTrigger, c as TooltipContent, d as chatUiQueryKey, g as getChatUiState, s as setChatUiState } from "./tooltip-DgsSPocE.js";
|
|
8
8
|
import { c as cn, b as buttonVariants, B as Button } from "./button-CwY2OHFj.js";
|
|
9
9
|
import { Link } from "@tanstack/react-router";
|
|
10
|
-
import { u as useFileExplorerState,
|
|
10
|
+
import { u as useFileExplorerState, D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-s7CS50ho.js";
|
|
11
|
+
import { M as MenuRoot, a as MenuTrigger, b as MenuContent, c as MenuItem } from "./menu-D90CDTi2.js";
|
|
11
12
|
import "@base-ui/react/tooltip";
|
|
12
13
|
import "@base-ui/react/merge-props";
|
|
13
14
|
import "@base-ui/react/use-render";
|
|
@@ -15,8 +16,8 @@ import "class-variance-authority";
|
|
|
15
16
|
import "clsx";
|
|
16
17
|
import "tailwind-merge";
|
|
17
18
|
import "@base-ui/react/dialog";
|
|
18
|
-
import "@base-ui/react/menu";
|
|
19
19
|
import "zustand";
|
|
20
|
+
import "@base-ui/react/menu";
|
|
20
21
|
function WebClawIconBig({ className }) {
|
|
21
22
|
return /* @__PURE__ */ jsxs(
|
|
22
23
|
"svg",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense, lazy } from "react";
|
|
3
|
-
const FileExplorerScreen = lazy(() => import("./file-explorer-screen-
|
|
3
|
+
const FileExplorerScreen = lazy(() => import("./file-explorer-screen-DH4UFK03.js").then((m) => ({
|
|
4
4
|
default: m.FileExplorerScreen
|
|
5
5
|
})));
|
|
6
6
|
function FilesRoute() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect } from "react";
|
|
3
|
-
import { R as Route } from "./router-
|
|
3
|
+
import { R as Route } from "./router-Uuagl6O7.js";
|
|
4
4
|
import "@tanstack/react-router";
|
|
5
5
|
import "@tanstack/react-query";
|
|
6
6
|
import "node:crypto";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-
|
|
2
|
+
import { D as DialogRoot, a as DialogContent, b as DialogTitle, c as DialogDescription, d as DialogClose } from "./use-file-explorer-state-s7CS50ho.js";
|
|
3
3
|
import { B as Button } from "./button-CwY2OHFj.js";
|
|
4
4
|
import "@base-ui/react/dialog";
|
|
5
|
-
import "@base-ui/react/menu";
|
|
6
5
|
import "zustand";
|
|
7
6
|
import "@base-ui/react/merge-props";
|
|
8
7
|
import "@base-ui/react/use-render";
|
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { marked } from "marked";
|
|
3
|
+
import { memo, useId, useMemo, useState, useCallback, useEffect } from "react";
|
|
4
|
+
import ReactMarkdown from "react-markdown";
|
|
5
|
+
import remarkBreaks from "remark-breaks";
|
|
6
|
+
import remarkGfm from "remark-gfm";
|
|
7
|
+
import { r as resolveLanguage, C as CodeBlock } from "./index-Dl2BOKP7.js";
|
|
8
|
+
import { u as useFileExplorerState, D as DialogRoot, a as DialogContent, b as DialogTitle, d as DialogClose } from "./use-file-explorer-state-s7CS50ho.js";
|
|
9
|
+
import { c as cn, B as Button } from "./button-CwY2OHFj.js";
|
|
10
|
+
import { useNavigate, Link } from "@tanstack/react-router";
|
|
11
|
+
const KNOWN_FILE_EXTENSIONS = [
|
|
12
|
+
"md",
|
|
13
|
+
"txt",
|
|
14
|
+
"json",
|
|
15
|
+
"yaml",
|
|
16
|
+
"yml",
|
|
17
|
+
"toml",
|
|
18
|
+
"py",
|
|
19
|
+
"js",
|
|
20
|
+
"ts",
|
|
21
|
+
"tsx",
|
|
22
|
+
"jsx",
|
|
23
|
+
"css",
|
|
24
|
+
"scss",
|
|
25
|
+
"html",
|
|
26
|
+
"xml",
|
|
27
|
+
"sh",
|
|
28
|
+
"bash",
|
|
29
|
+
"go",
|
|
30
|
+
"rs",
|
|
31
|
+
"rb",
|
|
32
|
+
"php",
|
|
33
|
+
"java",
|
|
34
|
+
"kt",
|
|
35
|
+
"swift",
|
|
36
|
+
"c",
|
|
37
|
+
"cpp",
|
|
38
|
+
"h",
|
|
39
|
+
"hpp",
|
|
40
|
+
"sql",
|
|
41
|
+
"graphql",
|
|
42
|
+
"dockerfile",
|
|
43
|
+
"env",
|
|
44
|
+
"conf",
|
|
45
|
+
"cfg",
|
|
46
|
+
"ini",
|
|
47
|
+
"log",
|
|
48
|
+
"csv"
|
|
49
|
+
];
|
|
50
|
+
const EXTENSION_PATTERN = KNOWN_FILE_EXTENSIONS.join("|");
|
|
51
|
+
const ABSOLUTE_OR_HOME_PATH_PATTERN = "(?:~\\/[A-Za-z0-9._\\-\\/]*[A-Za-z0-9._\\-\\/]|\\/(?:[\\w.\\-]+\\/)*[\\w.\\-]+\\/?)";
|
|
52
|
+
const RELATIVE_PATH_PATTERN = "(?:[A-Za-z0-9._\\-]+(?:\\/[A-Za-z0-9._\\-]+)+\\/?)";
|
|
53
|
+
const BARE_FILENAME_PATTERN = `(?:[A-Za-z0-9_-][A-Za-z0-9._-]*[A-Za-z0-9_-]\\.(?:${EXTENSION_PATTERN})|dockerfile)`;
|
|
54
|
+
const FILE_PATH_REGEX = new RegExp(
|
|
55
|
+
`(^|[\\s"'(,;:])(${ABSOLUTE_OR_HOME_PATH_PATTERN}|${RELATIVE_PATH_PATTERN}|${BARE_FILENAME_PATTERN})(?=$|[\\s"'),;:!?])`,
|
|
56
|
+
"gi"
|
|
57
|
+
);
|
|
58
|
+
function trimTrailingPunctuation(path) {
|
|
59
|
+
if (!path) return { path: path ?? "", trailing: "" };
|
|
60
|
+
const match = path.match(/^(.*?)([),.;:!?]+)?$/);
|
|
61
|
+
if (!match) return { path, trailing: "" };
|
|
62
|
+
return { path: match[1] || path, trailing: match[2] || "" };
|
|
63
|
+
}
|
|
64
|
+
function isLikelyFilePath(text) {
|
|
65
|
+
if (!text) return false;
|
|
66
|
+
FILE_PATH_REGEX.lastIndex = 0;
|
|
67
|
+
const match = FILE_PATH_REGEX.exec(text);
|
|
68
|
+
if (!match) return false;
|
|
69
|
+
const prefix = match[1] || "";
|
|
70
|
+
const value = match[2] || "";
|
|
71
|
+
const matchStart = match.index + prefix.length;
|
|
72
|
+
const matchEnd = matchStart + value.length;
|
|
73
|
+
return matchStart === 0 && matchEnd === text.length;
|
|
74
|
+
}
|
|
75
|
+
function splitTextByFilePaths(text) {
|
|
76
|
+
if (!text) return [{ type: "text", value: text }];
|
|
77
|
+
const segments = [];
|
|
78
|
+
let lastIndex = 0;
|
|
79
|
+
FILE_PATH_REGEX.lastIndex = 0;
|
|
80
|
+
let match;
|
|
81
|
+
while ((match = FILE_PATH_REGEX.exec(text)) !== null) {
|
|
82
|
+
const prefix = match[1] || "";
|
|
83
|
+
const rawPath = match[2] || "";
|
|
84
|
+
const fullMatch = match[0];
|
|
85
|
+
const start = match.index;
|
|
86
|
+
const prefixStart = start;
|
|
87
|
+
const pathStart = start + prefix.length;
|
|
88
|
+
if (prefixStart > lastIndex) {
|
|
89
|
+
segments.push({ type: "text", value: text.slice(lastIndex, prefixStart) });
|
|
90
|
+
}
|
|
91
|
+
if (prefix) {
|
|
92
|
+
segments.push({ type: "text", value: prefix });
|
|
93
|
+
}
|
|
94
|
+
const { path, trailing } = trimTrailingPunctuation(rawPath);
|
|
95
|
+
if (path.length > 1) {
|
|
96
|
+
segments.push({ type: "path", value: path });
|
|
97
|
+
if (trailing) {
|
|
98
|
+
segments.push({ type: "text", value: trailing });
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
segments.push({ type: "text", value: fullMatch });
|
|
102
|
+
}
|
|
103
|
+
lastIndex = pathStart + rawPath.length;
|
|
104
|
+
}
|
|
105
|
+
if (lastIndex < text.length) {
|
|
106
|
+
segments.push({ type: "text", value: text.slice(lastIndex) });
|
|
107
|
+
}
|
|
108
|
+
return segments.length > 0 ? segments : [{ type: "text", value: text }];
|
|
109
|
+
}
|
|
110
|
+
function filePathToMarkdownHref(path) {
|
|
111
|
+
return `openclaw-file://${encodeURIComponent(path)}`;
|
|
112
|
+
}
|
|
113
|
+
function markdownHrefToFilePath(href) {
|
|
114
|
+
if (!href?.startsWith("openclaw-file://")) return null;
|
|
115
|
+
try {
|
|
116
|
+
return decodeURIComponent(href.slice("openclaw-file://".length));
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function remarkFilePathLinks() {
|
|
122
|
+
return (tree) => {
|
|
123
|
+
function visit(node, parent) {
|
|
124
|
+
if (!node) return;
|
|
125
|
+
if (node.type === "text" && parent && parent.type !== "link" && parent.type !== "inlineCode" && parent.type !== "code") {
|
|
126
|
+
const segments = splitTextByFilePaths(String(node.value || ""));
|
|
127
|
+
const hasPaths = segments.some((segment) => segment.type === "path");
|
|
128
|
+
if (!hasPaths) return;
|
|
129
|
+
const replacement = segments.map((segment) => {
|
|
130
|
+
if (segment.type === "text") {
|
|
131
|
+
return { type: "text", value: segment.value };
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
type: "link",
|
|
135
|
+
url: filePathToMarkdownHref(segment.value),
|
|
136
|
+
children: [{ type: "text", value: segment.value }]
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
const index = parent.children.indexOf(node);
|
|
140
|
+
if (index >= 0) {
|
|
141
|
+
parent.children.splice(index, 1, ...replacement);
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (Array.isArray(node.children)) {
|
|
146
|
+
for (const child of [...node.children]) {
|
|
147
|
+
visit(child, node);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
visit(tree, null);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const EXTENSION_LANGUAGE_MAP = {
|
|
155
|
+
py: "python",
|
|
156
|
+
ts: "typescript",
|
|
157
|
+
js: "javascript",
|
|
158
|
+
jsx: "jsx",
|
|
159
|
+
tsx: "tsx",
|
|
160
|
+
json: "json",
|
|
161
|
+
md: "markdown",
|
|
162
|
+
yml: "yaml",
|
|
163
|
+
yaml: "yaml",
|
|
164
|
+
sh: "bash",
|
|
165
|
+
bash: "bash",
|
|
166
|
+
zsh: "bash",
|
|
167
|
+
html: "html",
|
|
168
|
+
css: "css",
|
|
169
|
+
sql: "sql",
|
|
170
|
+
xml: "xml",
|
|
171
|
+
toml: "toml",
|
|
172
|
+
rs: "rust",
|
|
173
|
+
go: "go",
|
|
174
|
+
java: "java",
|
|
175
|
+
c: "c",
|
|
176
|
+
cpp: "cpp",
|
|
177
|
+
cs: "csharp",
|
|
178
|
+
php: "php",
|
|
179
|
+
rb: "ruby",
|
|
180
|
+
graphql: "graphql",
|
|
181
|
+
diff: "diff",
|
|
182
|
+
patch: "diff",
|
|
183
|
+
env: "text"
|
|
184
|
+
};
|
|
185
|
+
function languageFromFilePath(path) {
|
|
186
|
+
if (!path) return "text";
|
|
187
|
+
const filename = path.split("/").pop() || "";
|
|
188
|
+
const lower = filename.toLowerCase();
|
|
189
|
+
if (lower === "dockerfile") return "dockerfile";
|
|
190
|
+
if (lower === "makefile") return "text";
|
|
191
|
+
const parts = lower.split(".");
|
|
192
|
+
const extension = parts.length > 1 ? parts.pop() || "" : "";
|
|
193
|
+
const mapped = EXTENSION_LANGUAGE_MAP[extension] || extension || "text";
|
|
194
|
+
return resolveLanguage(mapped);
|
|
195
|
+
}
|
|
196
|
+
const INLINE_PREVIEW_MAX_BYTES = 100 * 1024;
|
|
197
|
+
function normalizeClickedPath(path) {
|
|
198
|
+
if (!path) return "/";
|
|
199
|
+
return path.includes("/") ? path : `/${path}`;
|
|
200
|
+
}
|
|
201
|
+
function toWorkspacePath(path) {
|
|
202
|
+
let p = normalizeClickedPath(path);
|
|
203
|
+
const prefixes = ["/root/clawd/", "/root/"];
|
|
204
|
+
for (const prefix of prefixes) {
|
|
205
|
+
if (p.startsWith(prefix)) {
|
|
206
|
+
p = "/" + p.slice(prefix.length);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return p.startsWith("/") ? p : `/${p}`;
|
|
211
|
+
}
|
|
212
|
+
function hasExtension(path) {
|
|
213
|
+
const trimmed = path.replace(/\/+$/, "");
|
|
214
|
+
const name = trimmed.split("/").pop() || "";
|
|
215
|
+
if (!name || name.startsWith(".")) return false;
|
|
216
|
+
return name.includes(".");
|
|
217
|
+
}
|
|
218
|
+
function isDirectoryPathHeuristic(path) {
|
|
219
|
+
if (!path) return false;
|
|
220
|
+
return path.endsWith("/") || !hasExtension(path);
|
|
221
|
+
}
|
|
222
|
+
function isDirectoryError(code, message) {
|
|
223
|
+
const normalizedCode = String(code || "").toUpperCase();
|
|
224
|
+
const normalizedMessage = String(message || "").toLowerCase();
|
|
225
|
+
return normalizedCode.includes("DIRECTORY") || normalizedMessage.includes("is a directory") || normalizedMessage.includes("directory");
|
|
226
|
+
}
|
|
227
|
+
function parseMarkdownIntoBlocks(markdown) {
|
|
228
|
+
const tokens = marked.lexer(markdown);
|
|
229
|
+
return tokens.map((token) => token.raw);
|
|
230
|
+
}
|
|
231
|
+
function extractLanguage(className) {
|
|
232
|
+
if (!className) return "text";
|
|
233
|
+
const match = className.match(/language-([\w-]+)/);
|
|
234
|
+
return match ? match[1] : "text";
|
|
235
|
+
}
|
|
236
|
+
function extractFilenameFromMeta(meta) {
|
|
237
|
+
const value = meta?.trim();
|
|
238
|
+
if (!value) return void 0;
|
|
239
|
+
const firstToken = value.split(/\s+/)[0];
|
|
240
|
+
return firstToken || void 0;
|
|
241
|
+
}
|
|
242
|
+
const BASE_COMPONENTS = {
|
|
243
|
+
code: function CodeComponent({ className, children, node }) {
|
|
244
|
+
const isInline = !className?.includes("language-");
|
|
245
|
+
if (isInline) {
|
|
246
|
+
return /* @__PURE__ */ jsx("code", { className: "rounded bg-primary-100 px-1.5 py-1 text-sm font-mono text-primary-900 border border-primary-200", children });
|
|
247
|
+
}
|
|
248
|
+
const language = extractLanguage(className);
|
|
249
|
+
const filename = extractFilenameFromMeta(
|
|
250
|
+
node?.data?.meta
|
|
251
|
+
);
|
|
252
|
+
return /* @__PURE__ */ jsx(
|
|
253
|
+
CodeBlock,
|
|
254
|
+
{
|
|
255
|
+
content: String(children ?? ""),
|
|
256
|
+
language,
|
|
257
|
+
filename,
|
|
258
|
+
className: "w-full"
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
},
|
|
262
|
+
pre: function PreComponent({ children }) {
|
|
263
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
264
|
+
},
|
|
265
|
+
h1: function H1Component({ children }) {
|
|
266
|
+
return /* @__PURE__ */ jsx("h1", { className: "text-xl font-medium text-primary-950", children });
|
|
267
|
+
},
|
|
268
|
+
h2: function H2Component({ children }) {
|
|
269
|
+
return /* @__PURE__ */ jsx("h2", { className: "text-lg font-medium text-primary-900", children });
|
|
270
|
+
},
|
|
271
|
+
h3: function H3Component({ children }) {
|
|
272
|
+
return /* @__PURE__ */ jsx("h3", { className: "font-medium text-primary-900", children });
|
|
273
|
+
},
|
|
274
|
+
p: function PComponent({ children }) {
|
|
275
|
+
return /* @__PURE__ */ jsx("p", { className: "text-primary-950 text-pretty leading-relaxed", children });
|
|
276
|
+
},
|
|
277
|
+
ul: function UlComponent({ children }) {
|
|
278
|
+
return /* @__PURE__ */ jsx("ul", { className: "ml-4 list-disc text-primary-950 marker:text-primary-400", children });
|
|
279
|
+
},
|
|
280
|
+
ol: function OlComponent({ children }) {
|
|
281
|
+
return /* @__PURE__ */ jsx("ol", { className: "ml-4 list-decimal text-primary-950 marker:text-primary-500", children });
|
|
282
|
+
},
|
|
283
|
+
li: function LiComponent({ children }) {
|
|
284
|
+
return /* @__PURE__ */ jsx("li", { className: "leading-relaxed", children });
|
|
285
|
+
},
|
|
286
|
+
blockquote: function BlockquoteComponent({ children }) {
|
|
287
|
+
return /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 border-primary-300 pl-4 text-primary-900 italic", children });
|
|
288
|
+
},
|
|
289
|
+
strong: function StrongComponent({ children }) {
|
|
290
|
+
return /* @__PURE__ */ jsx("strong", { className: "font-medium text-primary-950", children });
|
|
291
|
+
},
|
|
292
|
+
em: function EmComponent({ children }) {
|
|
293
|
+
return /* @__PURE__ */ jsx("em", { className: "italic text-primary-950", children });
|
|
294
|
+
},
|
|
295
|
+
hr: function HrComponent() {
|
|
296
|
+
return /* @__PURE__ */ jsx("hr", { className: "my-3 border-primary-200" });
|
|
297
|
+
},
|
|
298
|
+
table: function TableComponent({ children }) {
|
|
299
|
+
return /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsx("table", { className: "w-full border-collapse text-sm", children }) });
|
|
300
|
+
},
|
|
301
|
+
thead: function TheadComponent({ children }) {
|
|
302
|
+
return /* @__PURE__ */ jsx("thead", { className: "border-b border-primary-200 bg-primary-50", children });
|
|
303
|
+
},
|
|
304
|
+
tbody: function TbodyComponent({ children }) {
|
|
305
|
+
return /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-primary-100", children });
|
|
306
|
+
},
|
|
307
|
+
tr: function TrComponent({ children }) {
|
|
308
|
+
return /* @__PURE__ */ jsx("tr", { className: "transition-colors hover:bg-primary-50/50", children });
|
|
309
|
+
},
|
|
310
|
+
th: function ThComponent({ children }) {
|
|
311
|
+
return /* @__PURE__ */ jsx("th", { className: "px-3 py-2 text-left font-medium text-primary-950", children });
|
|
312
|
+
},
|
|
313
|
+
td: function TdComponent({ children }) {
|
|
314
|
+
return /* @__PURE__ */ jsx("td", { className: "px-3 py-2 text-primary-950", children });
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
function createDefaultComponents(onOpenFilePreview) {
|
|
318
|
+
return {
|
|
319
|
+
...BASE_COMPONENTS,
|
|
320
|
+
a: function AComponent({ children, href }) {
|
|
321
|
+
const filePath = markdownHrefToFilePath(href);
|
|
322
|
+
if (filePath) {
|
|
323
|
+
return /* @__PURE__ */ jsx(
|
|
324
|
+
"button",
|
|
325
|
+
{
|
|
326
|
+
type: "button",
|
|
327
|
+
onClick: () => onOpenFilePreview(filePath),
|
|
328
|
+
className: "font-mono text-[var(--opencami-accent)] underline decoration-[var(--opencami-accent-light)] underline-offset-4 hover:opacity-90 cursor-pointer",
|
|
329
|
+
children
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
return /* @__PURE__ */ jsx(
|
|
334
|
+
"a",
|
|
335
|
+
{
|
|
336
|
+
href,
|
|
337
|
+
onClick: (event) => {
|
|
338
|
+
if (href?.startsWith("openclaw-file://")) event.preventDefault();
|
|
339
|
+
},
|
|
340
|
+
className: "text-[var(--opencami-accent)] underline decoration-[var(--opencami-accent-light)] underline-offset-4 transition-opacity hover:opacity-90",
|
|
341
|
+
target: "_blank",
|
|
342
|
+
rel: "noopener noreferrer",
|
|
343
|
+
children
|
|
344
|
+
}
|
|
345
|
+
);
|
|
346
|
+
},
|
|
347
|
+
code: function InlineCodeComponent({ children, className, node }) {
|
|
348
|
+
if (className?.includes("language-")) {
|
|
349
|
+
const language = extractLanguage(className);
|
|
350
|
+
const filename = extractFilenameFromMeta(
|
|
351
|
+
node?.data?.meta
|
|
352
|
+
);
|
|
353
|
+
return /* @__PURE__ */ jsx(
|
|
354
|
+
CodeBlock,
|
|
355
|
+
{
|
|
356
|
+
content: String(children ?? ""),
|
|
357
|
+
language,
|
|
358
|
+
filename,
|
|
359
|
+
className: "w-full"
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
const text = typeof children === "string" ? children : Array.isArray(children) ? children.filter((c) => typeof c === "string").join("") : String(children ?? "");
|
|
364
|
+
if (text && isLikelyFilePath(text)) {
|
|
365
|
+
return /* @__PURE__ */ jsx(
|
|
366
|
+
"button",
|
|
367
|
+
{
|
|
368
|
+
type: "button",
|
|
369
|
+
onClick: () => onOpenFilePreview(text),
|
|
370
|
+
className: "font-mono text-sm bg-primary-100 rounded px-1.5 py-0.5 text-primary-900 underline decoration-primary-300 underline-offset-4 hover:decoration-primary-600 cursor-pointer",
|
|
371
|
+
children
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
return /* @__PURE__ */ jsx("code", { className: "font-mono text-sm bg-primary-100 rounded px-1.5 py-0.5 text-primary-900", children });
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
const MemoizedMarkdownBlock = memo(
|
|
380
|
+
function MarkdownBlock({
|
|
381
|
+
content,
|
|
382
|
+
components
|
|
383
|
+
}) {
|
|
384
|
+
return /* @__PURE__ */ jsx(
|
|
385
|
+
ReactMarkdown,
|
|
386
|
+
{
|
|
387
|
+
remarkPlugins: [remarkGfm, remarkBreaks, remarkFilePathLinks],
|
|
388
|
+
components,
|
|
389
|
+
children: content
|
|
390
|
+
}
|
|
391
|
+
);
|
|
392
|
+
},
|
|
393
|
+
function propsAreEqual(prevProps, nextProps) {
|
|
394
|
+
return prevProps.content === nextProps.content;
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
MemoizedMarkdownBlock.displayName = "MemoizedMarkdownBlock";
|
|
398
|
+
function fileErrorMessageFromResponse(status, code) {
|
|
399
|
+
if (code === "NOT_FOUND" || status === 404) return "File not found";
|
|
400
|
+
if (code === "UNSUPPORTED_TYPE") return "Binary file";
|
|
401
|
+
if (code === "FILE_TOO_LARGE" || status === 413) return "File too large";
|
|
402
|
+
return "Failed to load file preview";
|
|
403
|
+
}
|
|
404
|
+
function MarkdownComponent({
|
|
405
|
+
children,
|
|
406
|
+
id,
|
|
407
|
+
className,
|
|
408
|
+
components
|
|
409
|
+
}) {
|
|
410
|
+
const generatedId = useId();
|
|
411
|
+
const blockId = id ?? generatedId;
|
|
412
|
+
const blocks = useMemo(() => parseMarkdownIntoBlocks(children), [children]);
|
|
413
|
+
const [filePreview, setFilePreview] = useState({ status: "idle" });
|
|
414
|
+
const navigate = useNavigate();
|
|
415
|
+
const openDirectoryInExplorer = useCallback((path) => {
|
|
416
|
+
const workspacePath = toWorkspacePath(path);
|
|
417
|
+
useFileExplorerState.getState().navigateTo(workspacePath);
|
|
418
|
+
setFilePreview({ status: "idle" });
|
|
419
|
+
navigate({ to: "/files" });
|
|
420
|
+
}, [navigate]);
|
|
421
|
+
const onOpenFilePreview = useCallback((path) => {
|
|
422
|
+
const resolvedPath = normalizeClickedPath(path);
|
|
423
|
+
if (isDirectoryPathHeuristic(resolvedPath)) {
|
|
424
|
+
openDirectoryInExplorer(resolvedPath);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
setFilePreview({ status: "loading", path: resolvedPath });
|
|
428
|
+
}, [openDirectoryInExplorer]);
|
|
429
|
+
const defaultComponents = useMemo(
|
|
430
|
+
() => createDefaultComponents(onOpenFilePreview),
|
|
431
|
+
[onOpenFilePreview]
|
|
432
|
+
);
|
|
433
|
+
const mergedComponents = useMemo(
|
|
434
|
+
() => ({ ...defaultComponents, ...components || {} }),
|
|
435
|
+
[defaultComponents, components]
|
|
436
|
+
);
|
|
437
|
+
useEffect(() => {
|
|
438
|
+
if (filePreview.status !== "loading") return;
|
|
439
|
+
const path = filePreview.path;
|
|
440
|
+
const controller = new AbortController();
|
|
441
|
+
fetch(`/api/files/read?path=${encodeURIComponent(path)}`, {
|
|
442
|
+
signal: controller.signal
|
|
443
|
+
}).then(async (response) => {
|
|
444
|
+
const payload = await response.json().catch(() => ({}));
|
|
445
|
+
if (!response.ok) {
|
|
446
|
+
if (isDirectoryError(payload.code, payload.message)) {
|
|
447
|
+
openDirectoryInExplorer(path);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const error = fileErrorMessageFromResponse(response.status, payload.code);
|
|
451
|
+
setFilePreview({ status: "error", path, message: error });
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const size = Number(payload.size ?? 0);
|
|
455
|
+
if (size > INLINE_PREVIEW_MAX_BYTES) {
|
|
456
|
+
setFilePreview({ status: "error", path, message: "File too large" });
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const content = String(payload.content ?? "");
|
|
460
|
+
setFilePreview({
|
|
461
|
+
status: "success",
|
|
462
|
+
path,
|
|
463
|
+
content,
|
|
464
|
+
language: languageFromFilePath(path)
|
|
465
|
+
});
|
|
466
|
+
}).catch(() => {
|
|
467
|
+
if (controller.signal.aborted) return;
|
|
468
|
+
setFilePreview({ status: "error", path, message: "Failed to load file preview" });
|
|
469
|
+
});
|
|
470
|
+
return () => controller.abort();
|
|
471
|
+
}, [filePreview, openDirectoryInExplorer]);
|
|
472
|
+
const previewOpen = filePreview.status !== "idle";
|
|
473
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
474
|
+
/* @__PURE__ */ jsx(
|
|
475
|
+
"div",
|
|
476
|
+
{
|
|
477
|
+
className: cn("flex min-w-0 max-w-full flex-col gap-2 overflow-x-hidden", className),
|
|
478
|
+
onClickCapture: (event) => {
|
|
479
|
+
const target = event.target;
|
|
480
|
+
const anchor = target?.closest?.('a[href^="openclaw-file://"]');
|
|
481
|
+
if (!anchor) return;
|
|
482
|
+
const filePath = markdownHrefToFilePath(anchor.getAttribute("href") ?? void 0);
|
|
483
|
+
if (!filePath) return;
|
|
484
|
+
event.preventDefault();
|
|
485
|
+
event.stopPropagation();
|
|
486
|
+
onOpenFilePreview(filePath);
|
|
487
|
+
},
|
|
488
|
+
children: blocks.map((block, index) => /* @__PURE__ */ jsx(
|
|
489
|
+
MemoizedMarkdownBlock,
|
|
490
|
+
{
|
|
491
|
+
content: block,
|
|
492
|
+
components: mergedComponents
|
|
493
|
+
},
|
|
494
|
+
`${blockId}-block-${index}`
|
|
495
|
+
))
|
|
496
|
+
}
|
|
497
|
+
),
|
|
498
|
+
/* @__PURE__ */ jsx(
|
|
499
|
+
DialogRoot,
|
|
500
|
+
{
|
|
501
|
+
open: previewOpen,
|
|
502
|
+
onOpenChange: (open) => {
|
|
503
|
+
if (!open) setFilePreview({ status: "idle" });
|
|
504
|
+
},
|
|
505
|
+
children: /* @__PURE__ */ jsxs(DialogContent, { className: "w-[min(1000px,95vw)] max-h-[88vh] overflow-hidden p-0", children: [
|
|
506
|
+
/* @__PURE__ */ jsxs("div", { className: "border-b border-primary-200 px-4 py-3 flex items-start justify-between gap-3", children: [
|
|
507
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
508
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "text-base", children: "File Preview" }),
|
|
509
|
+
filePreview.status !== "idle" && /* @__PURE__ */ jsx("p", { className: "text-xs text-primary-600 font-mono truncate", children: filePreview.path })
|
|
510
|
+
] }),
|
|
511
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
512
|
+
filePreview.status !== "idle" && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: /* @__PURE__ */ jsx(
|
|
513
|
+
Link,
|
|
514
|
+
{
|
|
515
|
+
to: "/files",
|
|
516
|
+
onClick: () => {
|
|
517
|
+
const p = filePreview.status !== "idle" ? toWorkspacePath(filePreview.path) : "";
|
|
518
|
+
if (p) {
|
|
519
|
+
const dir = p.includes("/") ? p.slice(0, p.lastIndexOf("/")) || "/" : "/";
|
|
520
|
+
useFileExplorerState.getState().navigateTo(dir);
|
|
521
|
+
}
|
|
522
|
+
setFilePreview({ status: "idle" });
|
|
523
|
+
},
|
|
524
|
+
children: "Open in Explorer"
|
|
525
|
+
}
|
|
526
|
+
) }),
|
|
527
|
+
filePreview.status !== "idle" && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", asChild: true, children: /* @__PURE__ */ jsx(
|
|
528
|
+
Link,
|
|
529
|
+
{
|
|
530
|
+
to: "/files",
|
|
531
|
+
onClick: () => {
|
|
532
|
+
const p = filePreview.status !== "idle" ? toWorkspacePath(filePreview.path) : "";
|
|
533
|
+
if (p) {
|
|
534
|
+
useFileExplorerState.getState().openInEditor(p);
|
|
535
|
+
}
|
|
536
|
+
setFilePreview({ status: "idle" });
|
|
537
|
+
},
|
|
538
|
+
children: "Open in Editor"
|
|
539
|
+
}
|
|
540
|
+
) }),
|
|
541
|
+
/* @__PURE__ */ jsx(DialogClose, { children: "Close" })
|
|
542
|
+
] })
|
|
543
|
+
] }),
|
|
544
|
+
/* @__PURE__ */ jsxs("div", { className: "p-4 overflow-auto max-h-[calc(88vh-72px)]", children: [
|
|
545
|
+
filePreview.status === "loading" && /* @__PURE__ */ jsx("p", { className: "text-sm text-primary-600", children: "Loading preview…" }),
|
|
546
|
+
filePreview.status === "error" && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600", children: filePreview.message }),
|
|
547
|
+
filePreview.status === "success" && /* @__PURE__ */ jsx(
|
|
548
|
+
CodeBlock,
|
|
549
|
+
{
|
|
550
|
+
content: filePreview.content,
|
|
551
|
+
language: filePreview.language,
|
|
552
|
+
className: "w-full"
|
|
553
|
+
}
|
|
554
|
+
)
|
|
555
|
+
] })
|
|
556
|
+
] })
|
|
557
|
+
}
|
|
558
|
+
)
|
|
559
|
+
] });
|
|
560
|
+
}
|
|
561
|
+
const Markdown = memo(MarkdownComponent);
|
|
562
|
+
Markdown.displayName = "Markdown";
|
|
563
|
+
export {
|
|
564
|
+
Markdown as M
|
|
565
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense, lazy } from "react";
|
|
3
|
+
const MemoryScreen = lazy(() => import("./memory-screen-BK5phS8K.js").then((m) => ({
|
|
4
|
+
default: m.MemoryScreen
|
|
5
|
+
})));
|
|
6
|
+
function MemoryRoute() {
|
|
7
|
+
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center text-primary-500 text-sm", children: "Loading…" }), children: /* @__PURE__ */ jsx(MemoryScreen, {}) });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
MemoryRoute as component
|
|
11
|
+
};
|