@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/terminal.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as TerminalView, t as DEFAULT_TERMINAL_THEME } from "./terminal-DmSUfGha.js";
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-DmSUfGha.js";
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-QHNLHsoL.js";
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.11",
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 };