@tangle-network/sandbox-ui 0.134.11 → 0.134.12
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/hooks.js +1 -1
- package/dist/index.js +2 -2
- package/dist/terminal-X6r5pjgv.js +1704 -0
- package/dist/terminal.js +1 -1
- package/dist/{use-pty-session-Bf4hBLXJ.js → use-pty-session-B5Q_i9RI.js} +10 -2
- package/dist/{workbench-QHNLHsoL.js → workbench-BzXAYUId.js} +1 -1
- package/dist/workbench.js +1 -1
- package/package.json +2 -1
- package/dist/terminal-DmSUfGha.js +0 -203
package/dist/terminal.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as TerminalView, t as DEFAULT_TERMINAL_THEME } from "./terminal-
|
|
1
|
+
import { n as TerminalView, t as DEFAULT_TERMINAL_THEME } from "./terminal-X6r5pjgv.js";
|
|
2
2
|
export { DEFAULT_TERMINAL_THEME, TerminalView };
|
|
@@ -17,13 +17,18 @@ function createEmptyBatch() {
|
|
|
17
17
|
*/
|
|
18
18
|
const WS_READY_TIMEOUT_MS = 1e4;
|
|
19
19
|
/** Convert an http(s) base URL into the matching ws(s) URL. */
|
|
20
|
-
function toWsUrl(apiUrl, sessionId) {
|
|
20
|
+
function toWsUrl(apiUrl, sessionId, defaultShell) {
|
|
21
21
|
try {
|
|
22
22
|
const base = typeof window !== "undefined" ? window.location.href : void 0;
|
|
23
23
|
const url = new URL(`${apiUrl}/terminals/${sessionId}/ws`, base);
|
|
24
24
|
if (url.protocol === "https:") url.protocol = "wss:";
|
|
25
25
|
else if (url.protocol === "http:") url.protocol = "ws:";
|
|
26
26
|
else return null;
|
|
27
|
+
if (defaultShell) {
|
|
28
|
+
url.searchParams.set("cols", String(defaultShell.cols));
|
|
29
|
+
url.searchParams.set("rows", String(defaultShell.rows));
|
|
30
|
+
url.searchParams.set("defaultShell", "1");
|
|
31
|
+
}
|
|
27
32
|
return url.toString();
|
|
28
33
|
} catch {
|
|
29
34
|
return null;
|
|
@@ -215,7 +220,10 @@ function usePtySession({ enabled = true, apiUrl, token, onData, connectionId: pr
|
|
|
215
220
|
resolve(false);
|
|
216
221
|
return;
|
|
217
222
|
}
|
|
218
|
-
const wsUrl = toWsUrl(apiUrl, sessionId
|
|
223
|
+
const wsUrl = toWsUrl(apiUrl, sessionId, options.initOnOpen && !exactAttachRequiredRef.current ? {
|
|
224
|
+
cols: colsRef.current,
|
|
225
|
+
rows: rowsRef.current
|
|
226
|
+
} : void 0);
|
|
219
227
|
if (!wsUrl) {
|
|
220
228
|
resolve(false);
|
|
221
229
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as cn$1 } from "./utils-DzWbktWG.js";
|
|
2
2
|
import { a as PortsList } from "./dashboard-C1ALa6lw.js";
|
|
3
|
-
import { n as TerminalView } from "./terminal-
|
|
3
|
+
import { n as TerminalView } from "./terminal-X6r5pjgv.js";
|
|
4
4
|
import { RichFileTree } from "./files.js";
|
|
5
5
|
import { n as PreviewView } from "./embedded-app-view-CYb9hevq.js";
|
|
6
6
|
import { Button, Skeleton, Textarea } from "@tangle-network/ui/primitives";
|
package/dist/workbench.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as computeDiffStats, c as BRAND_PRISM_THEME, d as DiffStatsBadge, f as GitStatusBadge, i as buildUnifiedPatch, l as CodeSurface, m as PillTabs, n as SandboxArtifactPane, o as CodeView, p as PanelHeader, r as DiffView, s as FileBreadcrumb, t as ChangesPane, u as resolveLanguage } from "./workbench-
|
|
1
|
+
import { a as computeDiffStats, c as BRAND_PRISM_THEME, d as DiffStatsBadge, f as GitStatusBadge, i as buildUnifiedPatch, l as CodeSurface, m as PillTabs, n as SandboxArtifactPane, o as CodeView, p as PanelHeader, r as DiffView, s as FileBreadcrumb, t as ChangesPane, u as resolveLanguage } from "./workbench-BzXAYUId.js";
|
|
2
2
|
import { n as PreviewView, t as EmbeddedAppView } from "./embedded-app-view-CYb9hevq.js";
|
|
3
3
|
export { BRAND_PRISM_THEME, ChangesPane, CodeSurface, CodeView, DiffStatsBadge, DiffView, EmbeddedAppView, FileBreadcrumb, GitStatusBadge, PanelHeader, PillTabs, PreviewView, SandboxArtifactPane, buildUnifiedPatch, computeDiffStats, resolveLanguage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-ui",
|
|
3
|
-
"version": "0.134.
|
|
3
|
+
"version": "0.134.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
|
|
6
6
|
"repository": {
|
|
@@ -239,6 +239,7 @@
|
|
|
239
239
|
"@types/react": "^19.3.0",
|
|
240
240
|
"@types/react-dom": "^19.3.0",
|
|
241
241
|
"@xterm/addon-fit": "^0.11.0",
|
|
242
|
+
"@xterm/addon-unicode-graphemes": "^0.4.0",
|
|
242
243
|
"@xterm/addon-web-links": "^0.12.0",
|
|
243
244
|
"@xterm/addon-webgl": "^0.19.0",
|
|
244
245
|
"@xterm/xterm": "^6.0.0",
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { t as usePtySession } from "./use-pty-session-Bf4hBLXJ.js";
|
|
2
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useEffect, useMemo, useRef } from "react";
|
|
4
|
-
import "@xterm/xterm/css/xterm.css";
|
|
5
|
-
import { Terminal } from "@xterm/xterm";
|
|
6
|
-
import { FitAddon } from "@xterm/addon-fit";
|
|
7
|
-
import { WebLinksAddon } from "@xterm/addon-web-links";
|
|
8
|
-
//#region src/terminal/terminal-view.tsx
|
|
9
|
-
const DEFAULT_TERMINAL_THEME = {
|
|
10
|
-
background: "#0c0c0e",
|
|
11
|
-
foreground: "#d4d4d8",
|
|
12
|
-
cursor: "#34d399",
|
|
13
|
-
cursorAccent: "#0c0c0e",
|
|
14
|
-
selectionBackground: "#7c3aed33",
|
|
15
|
-
selectionForeground: "#d4d4d8",
|
|
16
|
-
black: "#18181b",
|
|
17
|
-
red: "#ef4444",
|
|
18
|
-
green: "#34d399",
|
|
19
|
-
yellow: "#fbbf24",
|
|
20
|
-
blue: "#60a5fa",
|
|
21
|
-
magenta: "#a78bfa",
|
|
22
|
-
cyan: "#22d3ee",
|
|
23
|
-
white: "#d4d4d8",
|
|
24
|
-
brightBlack: "#52525b",
|
|
25
|
-
brightRed: "#f87171",
|
|
26
|
-
brightGreen: "#6ee7b7",
|
|
27
|
-
brightYellow: "#fde68a",
|
|
28
|
-
brightBlue: "#93c5fd",
|
|
29
|
-
brightMagenta: "#c4b5fd",
|
|
30
|
-
brightCyan: "#67e8f9",
|
|
31
|
-
brightWhite: "#fafafa"
|
|
32
|
-
};
|
|
33
|
-
function TerminalView({ session, apiUrl, token, theme, title = "Terminal", subtitle = "Connected to PTY session", isActive = true, connectionId, incarnationId, control, fontSize = 13 }) {
|
|
34
|
-
const resolvedTheme = useMemo(() => ({
|
|
35
|
-
...DEFAULT_TERMINAL_THEME,
|
|
36
|
-
...theme
|
|
37
|
-
}), [theme]);
|
|
38
|
-
const resolvedFontSize = Number.isFinite(fontSize) && fontSize > 0 ? fontSize : 13;
|
|
39
|
-
const fontSizeRef = useRef(resolvedFontSize);
|
|
40
|
-
fontSizeRef.current = resolvedFontSize;
|
|
41
|
-
const containerRef = useRef(null);
|
|
42
|
-
const termRef = useRef(null);
|
|
43
|
-
const fitAddonRef = useRef(null);
|
|
44
|
-
const pendingWritesRef = useRef([]);
|
|
45
|
-
const writeRafRef = useRef(null);
|
|
46
|
-
const onData = useCallback((data) => {
|
|
47
|
-
if (!data) return;
|
|
48
|
-
pendingWritesRef.current.push(data);
|
|
49
|
-
if (writeRafRef.current !== null) return;
|
|
50
|
-
writeRafRef.current = requestAnimationFrame(() => {
|
|
51
|
-
writeRafRef.current = null;
|
|
52
|
-
const chunks = pendingWritesRef.current;
|
|
53
|
-
if (chunks.length === 0) return;
|
|
54
|
-
pendingWritesRef.current = [];
|
|
55
|
-
termRef.current?.write(chunks.length === 1 ? chunks[0] : chunks.join(""));
|
|
56
|
-
});
|
|
57
|
-
}, []);
|
|
58
|
-
const usesCallerSession = session !== void 0;
|
|
59
|
-
const shellSession = usePtySession({
|
|
60
|
-
enabled: !usesCallerSession,
|
|
61
|
-
apiUrl,
|
|
62
|
-
token,
|
|
63
|
-
onData,
|
|
64
|
-
connectionId,
|
|
65
|
-
incarnationId,
|
|
66
|
-
control
|
|
67
|
-
});
|
|
68
|
-
const { isConnected, error, sendCommand, resizeTerminal, reconnect } = session ?? shellSession;
|
|
69
|
-
const subscribeData = session?.subscribeData;
|
|
70
|
-
useEffect(() => subscribeData?.(onData), [subscribeData, onData]);
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
if (!containerRef.current) return;
|
|
73
|
-
const term = new Terminal({
|
|
74
|
-
theme: resolvedTheme,
|
|
75
|
-
fontFamily: "\"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", Menlo, monospace",
|
|
76
|
-
fontSize: fontSizeRef.current,
|
|
77
|
-
lineHeight: 1.4,
|
|
78
|
-
cursorBlink: true,
|
|
79
|
-
cursorStyle: "bar",
|
|
80
|
-
scrollback: 5e3,
|
|
81
|
-
convertEol: true,
|
|
82
|
-
allowProposedApi: true
|
|
83
|
-
});
|
|
84
|
-
const fitAddon = new FitAddon();
|
|
85
|
-
const webLinksAddon = new WebLinksAddon();
|
|
86
|
-
term.loadAddon(fitAddon);
|
|
87
|
-
term.loadAddon(webLinksAddon);
|
|
88
|
-
term.open(containerRef.current);
|
|
89
|
-
let webglAddon = null;
|
|
90
|
-
let webglCancelled = false;
|
|
91
|
-
(async () => {
|
|
92
|
-
try {
|
|
93
|
-
const mod = await import("@xterm/addon-webgl");
|
|
94
|
-
if (webglCancelled) return;
|
|
95
|
-
try {
|
|
96
|
-
const addon = new mod.WebglAddon();
|
|
97
|
-
addon.onContextLoss(() => {
|
|
98
|
-
webglAddon?.dispose();
|
|
99
|
-
webglAddon = null;
|
|
100
|
-
});
|
|
101
|
-
webglAddon = addon;
|
|
102
|
-
term.loadAddon(addon);
|
|
103
|
-
} catch {}
|
|
104
|
-
} catch {}
|
|
105
|
-
})();
|
|
106
|
-
requestAnimationFrame(() => {
|
|
107
|
-
fitAddon.fit();
|
|
108
|
-
});
|
|
109
|
-
termRef.current = term;
|
|
110
|
-
fitAddonRef.current = fitAddon;
|
|
111
|
-
term.onData((data) => {
|
|
112
|
-
if (!usesCallerSession && data === "\f") {
|
|
113
|
-
termRef.current?.clear();
|
|
114
|
-
sendCommand("\r").catch(console.error);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
sendCommand(data).catch((err) => {
|
|
118
|
-
termRef.current?.writeln(`\r\n\x1b[31m${err instanceof Error ? err.message : "Send failed"}\x1b[0m`);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
term.onResize(({ cols, rows }) => {
|
|
122
|
-
resizeTerminal(cols, rows).catch(console.error);
|
|
123
|
-
});
|
|
124
|
-
const ro = new ResizeObserver(() => {
|
|
125
|
-
requestAnimationFrame(() => {
|
|
126
|
-
fitAddon.fit();
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
ro.observe(containerRef.current);
|
|
130
|
-
return () => {
|
|
131
|
-
webglCancelled = true;
|
|
132
|
-
ro.disconnect();
|
|
133
|
-
if (writeRafRef.current !== null) {
|
|
134
|
-
cancelAnimationFrame(writeRafRef.current);
|
|
135
|
-
writeRafRef.current = null;
|
|
136
|
-
}
|
|
137
|
-
pendingWritesRef.current = [];
|
|
138
|
-
webglAddon?.dispose();
|
|
139
|
-
term.dispose();
|
|
140
|
-
termRef.current = null;
|
|
141
|
-
fitAddonRef.current = null;
|
|
142
|
-
};
|
|
143
|
-
}, [
|
|
144
|
-
sendCommand,
|
|
145
|
-
resizeTerminal,
|
|
146
|
-
title,
|
|
147
|
-
subtitle,
|
|
148
|
-
usesCallerSession
|
|
149
|
-
]);
|
|
150
|
-
useEffect(() => {
|
|
151
|
-
if (termRef.current) termRef.current.options.theme = resolvedTheme;
|
|
152
|
-
}, [resolvedTheme]);
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
const term = termRef.current;
|
|
155
|
-
if (!term || term.options.fontSize === resolvedFontSize) return;
|
|
156
|
-
term.options.fontSize = resolvedFontSize;
|
|
157
|
-
const rafId = requestAnimationFrame(() => fitAddonRef.current?.fit());
|
|
158
|
-
return () => cancelAnimationFrame(rafId);
|
|
159
|
-
}, [resolvedFontSize]);
|
|
160
|
-
useEffect(() => {
|
|
161
|
-
if (isConnected && termRef.current) {
|
|
162
|
-
resizeTerminal(termRef.current.cols, termRef.current.rows).catch(console.error);
|
|
163
|
-
if (isActive) termRef.current.focus();
|
|
164
|
-
}
|
|
165
|
-
}, [
|
|
166
|
-
isConnected,
|
|
167
|
-
resizeTerminal,
|
|
168
|
-
isActive
|
|
169
|
-
]);
|
|
170
|
-
useEffect(() => {
|
|
171
|
-
if (isActive && termRef.current && fitAddonRef.current) setTimeout(() => {
|
|
172
|
-
fitAddonRef.current?.fit();
|
|
173
|
-
termRef.current?.focus();
|
|
174
|
-
}, 50);
|
|
175
|
-
}, [isActive]);
|
|
176
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
177
|
-
className: "relative h-full w-full group cursor-text",
|
|
178
|
-
onClick: () => termRef.current?.focus(),
|
|
179
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
180
|
-
ref: containerRef,
|
|
181
|
-
className: "h-full w-full overflow-hidden relative z-0",
|
|
182
|
-
style: { backgroundColor: resolvedTheme.background }
|
|
183
|
-
}), (!isConnected || error) && /* @__PURE__ */ jsx("div", {
|
|
184
|
-
className: "absolute inset-0 flex items-center justify-center bg-surface-container-lowest",
|
|
185
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
186
|
-
className: "text-center",
|
|
187
|
-
children: error ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
|
|
188
|
-
className: "text-sm text-[var(--surface-danger-text)] mb-3",
|
|
189
|
-
children: error
|
|
190
|
-
}), /* @__PURE__ */ jsx("button", {
|
|
191
|
-
onClick: reconnect,
|
|
192
|
-
className: "text-sm text-[var(--surface-success-text)] hover:opacity-80 underline cursor-pointer",
|
|
193
|
-
children: "Retry connection"
|
|
194
|
-
})] }) : /* @__PURE__ */ jsx("p", {
|
|
195
|
-
className: "text-[13px] text-muted-foreground",
|
|
196
|
-
children: "Connecting to terminal..."
|
|
197
|
-
})
|
|
198
|
-
})
|
|
199
|
-
})]
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
//#endregion
|
|
203
|
-
export { TerminalView as n, DEFAULT_TERMINAL_THEME as t };
|