@tangle-network/sandbox-ui 0.44.0 → 0.46.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/dist/{WorkflowGraph-7YYGIBNV.js → WorkflowGraph-6IKZYPST.js} +2 -1
- package/dist/assets.js +1 -0
- package/dist/assistant.js +2 -1
- package/dist/auth.js +1 -0
- package/dist/chat.js +4 -3
- package/dist/{chunk-6NDOA4SB.js → chunk-2ISY4R72.js} +112 -104
- package/dist/{chunk-KIRJZUX2.js → chunk-BR2LMUAE.js} +61 -34
- package/dist/{chunk-H7GMPMPB.js → chunk-CXV6X33U.js} +19 -1
- package/dist/{chunk-CUUUFJF5.js → chunk-KOUYJ6QP.js} +23 -23
- package/dist/{chunk-3RNYDTQ3.js → chunk-LQHTCM56.js} +21 -27
- package/dist/chunk-NXUSLH7H.js +7528 -0
- package/dist/{chunk-2XNT74ZX.js → chunk-OMUIPJQZ.js} +28 -20
- package/dist/{chunk-KCWIC3SJ.js → chunk-PZ62T5PM.js} +281 -214
- package/dist/chunk-U67V476Y.js +35 -0
- package/dist/chunk-VIREDUBF.js +215 -0
- package/dist/dashboard.d.ts +82 -66
- package/dist/dashboard.js +5 -4
- package/dist/editor.js +2 -0
- package/dist/files.d.ts +5 -0
- package/dist/files.js +1 -0
- package/dist/globals.css +1155 -50
- package/dist/hooks.js +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +95 -65
- package/dist/integrations.js +2 -1
- package/dist/markdown.js +2 -0
- package/dist/openui.d.ts +0 -5
- package/dist/openui.js +1 -0
- package/dist/pages.d.ts +1 -1
- package/dist/pages.js +89 -88
- package/dist/ports-list-DfG0VfPt.d.ts +17 -0
- package/dist/primitives.js +1 -0
- package/dist/run.js +1 -0
- package/dist/sdk-hooks.js +1 -0
- package/dist/stores.js +1 -0
- package/dist/styles.css +1155 -50
- package/dist/terminal.js +5 -209
- package/dist/tokens.css +13 -2
- package/dist/utils.js +1 -0
- package/dist/workbench.d.ts +227 -0
- package/dist/workbench.js +40 -0
- package/dist/workflows.js +2 -1
- package/dist/workspace.d.ts +6 -2
- package/dist/workspace.js +2 -1
- package/package.json +15 -9
package/dist/terminal.js
CHANGED
|
@@ -1,213 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import "
|
|
7
|
-
import { useEffect, useRef, useCallback, useMemo } from "react";
|
|
8
|
-
import { Terminal } from "@xterm/xterm";
|
|
9
|
-
import { FitAddon } from "@xterm/addon-fit";
|
|
10
|
-
import { WebLinksAddon } from "@xterm/addon-web-links";
|
|
11
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
var DEFAULT_TERMINAL_THEME = {
|
|
13
|
-
background: "#0c0c0e",
|
|
14
|
-
foreground: "#d4d4d8",
|
|
15
|
-
cursor: "#34d399",
|
|
16
|
-
cursorAccent: "#0c0c0e",
|
|
17
|
-
selectionBackground: "#7c3aed33",
|
|
18
|
-
selectionForeground: "#d4d4d8",
|
|
19
|
-
black: "#18181b",
|
|
20
|
-
red: "#ef4444",
|
|
21
|
-
green: "#34d399",
|
|
22
|
-
yellow: "#fbbf24",
|
|
23
|
-
blue: "#60a5fa",
|
|
24
|
-
magenta: "#a78bfa",
|
|
25
|
-
cyan: "#22d3ee",
|
|
26
|
-
white: "#d4d4d8",
|
|
27
|
-
brightBlack: "#52525b",
|
|
28
|
-
brightRed: "#f87171",
|
|
29
|
-
brightGreen: "#6ee7b7",
|
|
30
|
-
brightYellow: "#fde68a",
|
|
31
|
-
brightBlue: "#93c5fd",
|
|
32
|
-
brightMagenta: "#c4b5fd",
|
|
33
|
-
brightCyan: "#67e8f9",
|
|
34
|
-
brightWhite: "#fafafa"
|
|
35
|
-
};
|
|
36
|
-
function TerminalView({
|
|
37
|
-
apiUrl,
|
|
38
|
-
token,
|
|
39
|
-
theme,
|
|
40
|
-
title = "Terminal",
|
|
41
|
-
subtitle = "Connected to PTY session",
|
|
42
|
-
isActive = true,
|
|
43
|
-
connectionId,
|
|
44
|
-
fontSize = 13
|
|
45
|
-
}) {
|
|
46
|
-
const resolvedTheme = useMemo(
|
|
47
|
-
() => ({ ...DEFAULT_TERMINAL_THEME, ...theme }),
|
|
48
|
-
[theme]
|
|
49
|
-
);
|
|
50
|
-
const resolvedFontSize = Number.isFinite(fontSize) && fontSize > 0 ? fontSize : 13;
|
|
51
|
-
const fontSizeRef = useRef(resolvedFontSize);
|
|
52
|
-
fontSizeRef.current = resolvedFontSize;
|
|
53
|
-
const containerRef = useRef(null);
|
|
54
|
-
const termRef = useRef(null);
|
|
55
|
-
const fitAddonRef = useRef(null);
|
|
56
|
-
const pendingWritesRef = useRef([]);
|
|
57
|
-
const writeRafRef = useRef(null);
|
|
58
|
-
const onData = useCallback((data) => {
|
|
59
|
-
if (!data) return;
|
|
60
|
-
pendingWritesRef.current.push(data);
|
|
61
|
-
if (writeRafRef.current !== null) return;
|
|
62
|
-
writeRafRef.current = requestAnimationFrame(() => {
|
|
63
|
-
writeRafRef.current = null;
|
|
64
|
-
const chunks = pendingWritesRef.current;
|
|
65
|
-
if (chunks.length === 0) return;
|
|
66
|
-
pendingWritesRef.current = [];
|
|
67
|
-
termRef.current?.write(chunks.length === 1 ? chunks[0] : chunks.join(""));
|
|
68
|
-
});
|
|
69
|
-
}, []);
|
|
70
|
-
const { isConnected, error, sendCommand, resizeTerminal, reconnect } = usePtySession({
|
|
71
|
-
apiUrl,
|
|
72
|
-
token,
|
|
73
|
-
onData,
|
|
74
|
-
connectionId
|
|
75
|
-
});
|
|
76
|
-
useEffect(() => {
|
|
77
|
-
if (!containerRef.current) return;
|
|
78
|
-
const term = new Terminal({
|
|
79
|
-
theme: resolvedTheme,
|
|
80
|
-
fontFamily: '"JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, monospace',
|
|
81
|
-
fontSize: fontSizeRef.current,
|
|
82
|
-
lineHeight: 1.4,
|
|
83
|
-
cursorBlink: true,
|
|
84
|
-
cursorStyle: "bar",
|
|
85
|
-
scrollback: 5e3,
|
|
86
|
-
convertEol: true,
|
|
87
|
-
allowProposedApi: true
|
|
88
|
-
});
|
|
89
|
-
const fitAddon = new FitAddon();
|
|
90
|
-
const webLinksAddon = new WebLinksAddon();
|
|
91
|
-
term.loadAddon(fitAddon);
|
|
92
|
-
term.loadAddon(webLinksAddon);
|
|
93
|
-
term.open(containerRef.current);
|
|
94
|
-
let webglAddon = null;
|
|
95
|
-
let webglCancelled = false;
|
|
96
|
-
void (async () => {
|
|
97
|
-
try {
|
|
98
|
-
const mod = await import("@xterm/addon-webgl");
|
|
99
|
-
if (webglCancelled) return;
|
|
100
|
-
try {
|
|
101
|
-
const addon = new mod.WebglAddon();
|
|
102
|
-
addon.onContextLoss(() => {
|
|
103
|
-
webglAddon?.dispose();
|
|
104
|
-
webglAddon = null;
|
|
105
|
-
});
|
|
106
|
-
webglAddon = addon;
|
|
107
|
-
term.loadAddon(addon);
|
|
108
|
-
} catch {
|
|
109
|
-
}
|
|
110
|
-
} catch {
|
|
111
|
-
}
|
|
112
|
-
})();
|
|
113
|
-
requestAnimationFrame(() => {
|
|
114
|
-
fitAddon.fit();
|
|
115
|
-
});
|
|
116
|
-
termRef.current = term;
|
|
117
|
-
fitAddonRef.current = fitAddon;
|
|
118
|
-
term.onData((data) => {
|
|
119
|
-
if (data === "\f") {
|
|
120
|
-
termRef.current?.clear();
|
|
121
|
-
sendCommand("\r").catch(console.error);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
sendCommand(data).catch((err) => {
|
|
125
|
-
termRef.current?.writeln(
|
|
126
|
-
`\r
|
|
127
|
-
\x1B[31m${err instanceof Error ? err.message : "Send failed"}\x1B[0m`
|
|
128
|
-
);
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
term.onResize(({ cols, rows }) => {
|
|
132
|
-
resizeTerminal(cols, rows).catch(console.error);
|
|
133
|
-
});
|
|
134
|
-
const ro = new ResizeObserver(() => {
|
|
135
|
-
requestAnimationFrame(() => {
|
|
136
|
-
fitAddon.fit();
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
ro.observe(containerRef.current);
|
|
140
|
-
return () => {
|
|
141
|
-
webglCancelled = true;
|
|
142
|
-
ro.disconnect();
|
|
143
|
-
if (writeRafRef.current !== null) {
|
|
144
|
-
cancelAnimationFrame(writeRafRef.current);
|
|
145
|
-
writeRafRef.current = null;
|
|
146
|
-
}
|
|
147
|
-
pendingWritesRef.current = [];
|
|
148
|
-
webglAddon?.dispose();
|
|
149
|
-
term.dispose();
|
|
150
|
-
termRef.current = null;
|
|
151
|
-
fitAddonRef.current = null;
|
|
152
|
-
};
|
|
153
|
-
}, [sendCommand, resizeTerminal, title, subtitle]);
|
|
154
|
-
useEffect(() => {
|
|
155
|
-
if (termRef.current) {
|
|
156
|
-
termRef.current.options.theme = resolvedTheme;
|
|
157
|
-
}
|
|
158
|
-
}, [resolvedTheme]);
|
|
159
|
-
useEffect(() => {
|
|
160
|
-
const term = termRef.current;
|
|
161
|
-
if (!term || term.options.fontSize === resolvedFontSize) return;
|
|
162
|
-
term.options.fontSize = resolvedFontSize;
|
|
163
|
-
const rafId = requestAnimationFrame(() => fitAddonRef.current?.fit());
|
|
164
|
-
return () => cancelAnimationFrame(rafId);
|
|
165
|
-
}, [resolvedFontSize]);
|
|
166
|
-
useEffect(() => {
|
|
167
|
-
if (isConnected && termRef.current) {
|
|
168
|
-
resizeTerminal(termRef.current.cols, termRef.current.rows).catch(console.error);
|
|
169
|
-
if (isActive) {
|
|
170
|
-
termRef.current.focus();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}, [isConnected, resizeTerminal, isActive]);
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
if (isActive && termRef.current && fitAddonRef.current) {
|
|
176
|
-
setTimeout(() => {
|
|
177
|
-
fitAddonRef.current?.fit();
|
|
178
|
-
termRef.current?.focus();
|
|
179
|
-
}, 50);
|
|
180
|
-
}
|
|
181
|
-
}, [isActive]);
|
|
182
|
-
return /* @__PURE__ */ jsxs(
|
|
183
|
-
"div",
|
|
184
|
-
{
|
|
185
|
-
className: "relative h-full w-full group cursor-text",
|
|
186
|
-
onClick: () => termRef.current?.focus(),
|
|
187
|
-
children: [
|
|
188
|
-
/* @__PURE__ */ jsx(
|
|
189
|
-
"div",
|
|
190
|
-
{
|
|
191
|
-
ref: containerRef,
|
|
192
|
-
className: "h-full w-full overflow-hidden relative z-0",
|
|
193
|
-
style: { backgroundColor: resolvedTheme.background }
|
|
194
|
-
}
|
|
195
|
-
),
|
|
196
|
-
(!isConnected || error) && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-background", children: /* @__PURE__ */ jsx("div", { className: "text-center", children: error ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
197
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--surface-danger-text)] mb-3", children: error }),
|
|
198
|
-
/* @__PURE__ */ jsx(
|
|
199
|
-
"button",
|
|
200
|
-
{
|
|
201
|
-
onClick: reconnect,
|
|
202
|
-
className: "text-sm text-[var(--surface-success-text)] hover:opacity-80 underline cursor-pointer",
|
|
203
|
-
children: "Retry connection"
|
|
204
|
-
}
|
|
205
|
-
)
|
|
206
|
-
] }) : /* @__PURE__ */ jsx("p", { className: "text-[13px] text-muted-foreground", children: "Connecting to terminal..." }) }) })
|
|
207
|
-
]
|
|
208
|
-
}
|
|
209
|
-
);
|
|
210
|
-
}
|
|
2
|
+
DEFAULT_TERMINAL_THEME,
|
|
3
|
+
TerminalView
|
|
4
|
+
} from "./chunk-VIREDUBF.js";
|
|
5
|
+
import "./chunk-77WVVJA4.js";
|
|
6
|
+
import "./chunk-U67V476Y.js";
|
|
211
7
|
export {
|
|
212
8
|
DEFAULT_TERMINAL_THEME,
|
|
213
9
|
TerminalView
|
package/dist/tokens.css
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
/* Brand: warm purple palette, #5B4ED4 primary */
|
|
3
3
|
|
|
4
4
|
/* MD3 surface hierarchy */
|
|
5
|
+
/* Dark is the default theme (`:root`/`[data-sandbox-ui]`). It also responds to
|
|
6
|
+
* the standard `[data-theme="dark"]` / `.dark` switch so any consumer can pin or
|
|
7
|
+
* toggle a theme without inventing an ad-hoc `data-sandbox-theme` name. */
|
|
5
8
|
:root,
|
|
6
|
-
[data-sandbox-ui]
|
|
9
|
+
[data-sandbox-ui],
|
|
10
|
+
[data-theme="dark"],
|
|
11
|
+
.dark {
|
|
7
12
|
--md3-surface: #0a0a14;
|
|
8
13
|
--md3-surface-dim: #07070d;
|
|
9
14
|
--md3-surface-bright: #1b1a2c;
|
|
@@ -304,7 +309,13 @@
|
|
|
304
309
|
--font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
|
|
305
310
|
}
|
|
306
311
|
|
|
307
|
-
|
|
312
|
+
/* Light theme — reachable via the named `vault` theme or the standard
|
|
313
|
+
* `[data-theme="light"]` / `.light` switch. Both blocks are single-attribute/
|
|
314
|
+
* class selectors, and this one is later in source order, so when an element
|
|
315
|
+
* carries both `data-sandbox-ui` (dark) and `data-theme="light"`, light wins. */
|
|
316
|
+
[data-sandbox-theme="vault"],
|
|
317
|
+
[data-theme="light"],
|
|
318
|
+
.light {
|
|
308
319
|
/* Light theme — clean professional, warm purple accents */
|
|
309
320
|
|
|
310
321
|
/* MD3 surface hierarchy */
|
package/dist/utils.js
CHANGED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { CSSProperties } from 'react';
|
|
4
|
+
import { RichFileTreeGitEntry, RichFileTreeGitStatus } from '@tangle-network/ui/files';
|
|
5
|
+
import { E as ExposedPort } from './ports-list-DfG0VfPt.js';
|
|
6
|
+
|
|
7
|
+
/** Which surface the artifact pane is currently showing. */
|
|
8
|
+
type ArtifactView = "code" | "diff" | "preview" | "ports" | "terminal";
|
|
9
|
+
/**
|
|
10
|
+
* A single artifact rendered by the pane. `content` is the working copy;
|
|
11
|
+
* when `baselineContent` differs from it, the Diff view becomes available
|
|
12
|
+
* and renders a word-level unified diff of baseline → content.
|
|
13
|
+
*/
|
|
14
|
+
interface SandboxArtifact {
|
|
15
|
+
id: string;
|
|
16
|
+
/** Canonical path inside the sandbox, e.g. `src/lib/retry.ts`. */
|
|
17
|
+
path: string;
|
|
18
|
+
/** Display name for the active file (usually the last path segment). */
|
|
19
|
+
filename: string;
|
|
20
|
+
/** Working-copy contents of the file. */
|
|
21
|
+
content: string;
|
|
22
|
+
/** Prior contents the working copy is diffed against. */
|
|
23
|
+
baselineContent?: string;
|
|
24
|
+
/** Explicit syntax language id (overrides extension inference). */
|
|
25
|
+
language?: string;
|
|
26
|
+
mimeType?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Live PTY terminal binding. Maps straight onto `TerminalView` — both
|
|
30
|
+
* `apiUrl` and `token` are required to open a session against the sidecar.
|
|
31
|
+
*/
|
|
32
|
+
interface SandboxArtifactTerminal {
|
|
33
|
+
apiUrl: string;
|
|
34
|
+
token: string;
|
|
35
|
+
/** Stable id so the same PTY is restored across remounts. */
|
|
36
|
+
connectionId?: string;
|
|
37
|
+
title?: string;
|
|
38
|
+
subtitle?: string;
|
|
39
|
+
}
|
|
40
|
+
interface SandboxArtifactPaneProps {
|
|
41
|
+
/** The active artifact shown in the Code / Diff surfaces. */
|
|
42
|
+
artifact: SandboxArtifact;
|
|
43
|
+
/**
|
|
44
|
+
* Flat list of canonical paths for the file-tree rail in the Code view.
|
|
45
|
+
* Defaults to `[artifact.path]` when omitted (single-file tree).
|
|
46
|
+
*/
|
|
47
|
+
paths?: ReadonlyArray<string>;
|
|
48
|
+
/** Per-path git-status decorations for the file tree. */
|
|
49
|
+
gitStatus?: ReadonlyArray<RichFileTreeGitEntry>;
|
|
50
|
+
/** Show the Code view's file-tree rail. Off for single-file embeds where the host owns navigation/tabs. */
|
|
51
|
+
showTree?: boolean;
|
|
52
|
+
/** Exposed ports; presence enables the Ports tab. */
|
|
53
|
+
ports?: ExposedPort[];
|
|
54
|
+
/** Live preview origin; presence enables the Preview tab. */
|
|
55
|
+
previewUrl?: string;
|
|
56
|
+
/** Live terminal binding; presence enables the Terminal tab. */
|
|
57
|
+
terminal?: SandboxArtifactTerminal;
|
|
58
|
+
/** Controlled active view. Pair with `onViewChange`. */
|
|
59
|
+
activeView?: ArtifactView;
|
|
60
|
+
/** Initial view when uncontrolled. Defaults to the first available view. */
|
|
61
|
+
defaultView?: ArtifactView;
|
|
62
|
+
onViewChange?: (view: ArtifactView) => void;
|
|
63
|
+
/** Fired when a different file is chosen in the tree (host swaps artifact). */
|
|
64
|
+
onFileSelect?: (path: string) => void;
|
|
65
|
+
/** Forwarded to the Ports view. */
|
|
66
|
+
onExposePort?: (port: number) => void;
|
|
67
|
+
onRemovePort?: (port: number) => void;
|
|
68
|
+
className?: string;
|
|
69
|
+
style?: CSSProperties;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Blueprint-grade artifact workbench. Composes the sandbox-ui substrate
|
|
74
|
+
* (`RichFileTree`, `PortsList`, `TerminalView`, `@pierre/diffs`) behind a
|
|
75
|
+
* single pill-tab view switcher: Code · Diff · Preview · Ports · Terminal.
|
|
76
|
+
* Tabs appear only when their data is present (Diff requires a differing
|
|
77
|
+
* baseline; Preview a url; Ports a port list; Terminal a live binding), so the
|
|
78
|
+
* chrome never shows a dead surface.
|
|
79
|
+
*/
|
|
80
|
+
declare function SandboxArtifactPane({ artifact, paths, gitStatus, showTree, ports, previewUrl, terminal, activeView, defaultView, onViewChange, onFileSelect, onExposePort, onRemovePort, className, style, }: SandboxArtifactPaneProps): react_jsx_runtime.JSX.Element;
|
|
81
|
+
|
|
82
|
+
interface PillTabItem<T extends string> {
|
|
83
|
+
value: T;
|
|
84
|
+
label: string;
|
|
85
|
+
icon?: React.ReactNode;
|
|
86
|
+
}
|
|
87
|
+
interface PillTabsProps<T extends string> {
|
|
88
|
+
items: ReadonlyArray<PillTabItem<T>>;
|
|
89
|
+
value: T;
|
|
90
|
+
onChange: (value: T) => void;
|
|
91
|
+
className?: string;
|
|
92
|
+
"aria-label"?: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Sliding-pill segmented control. Reimplemented from blueprint-agent's
|
|
96
|
+
* framer-motion `PillTabs` with a measured CSS transform instead — no motion
|
|
97
|
+
* dependency. A `ResizeObserver` re-measures on container resize and font
|
|
98
|
+
* load so the indicator tracks the active tab exactly. Token-swapped onto the
|
|
99
|
+
* sandbox-ui surface ladder.
|
|
100
|
+
*/
|
|
101
|
+
declare function PillTabs<T extends string>({ items, value, onChange, className, "aria-label": ariaLabel, }: PillTabsProps<T>): react_jsx_runtime.JSX.Element;
|
|
102
|
+
|
|
103
|
+
interface DiffStats {
|
|
104
|
+
added: number;
|
|
105
|
+
removed: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Count added / removed lines between two file revisions.
|
|
109
|
+
*
|
|
110
|
+
* Ported from blueprint-agent's `computeDiffStats`: normalize CRLF, short-
|
|
111
|
+
* circuit on equality, then `diffLines` with `ignoreWhitespace` so pure
|
|
112
|
+
* reindentation does not inflate the counts. `newlineIsToken:false` keeps a
|
|
113
|
+
* line (not its trailing newline) as the unit, matching the +/- a reader
|
|
114
|
+
* counts by eye.
|
|
115
|
+
*/
|
|
116
|
+
declare function computeDiffStats(original: string, current: string): DiffStats;
|
|
117
|
+
/**
|
|
118
|
+
* Build a single-file unified patch (baseline → current) for `@pierre/diffs`'
|
|
119
|
+
* `PatchDiff`. `context: Infinity` would print the whole file; the default
|
|
120
|
+
* 4-line context keeps hunks compact while preserving locality. Equal inputs
|
|
121
|
+
* yield an empty string so callers can treat "" as "no diff".
|
|
122
|
+
*/
|
|
123
|
+
declare function buildUnifiedPatch(filename: string, baseline: string, current: string): string;
|
|
124
|
+
|
|
125
|
+
declare function GitStatusBadge({ status }: {
|
|
126
|
+
status: RichFileTreeGitStatus;
|
|
127
|
+
}): react_jsx_runtime.JSX.Element;
|
|
128
|
+
interface PanelHeaderProps {
|
|
129
|
+
filename: string;
|
|
130
|
+
gitStatus?: RichFileTreeGitStatus;
|
|
131
|
+
/** Added/removed line counts; rendered only when provided (Diff view). */
|
|
132
|
+
stats?: DiffStats;
|
|
133
|
+
/** Enables the copy-to-clipboard action when set. */
|
|
134
|
+
copyText?: string;
|
|
135
|
+
/** Extra content rendered at the right edge, before the copy button. */
|
|
136
|
+
children?: React.ReactNode;
|
|
137
|
+
className?: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Thin bordered chrome bar above the artifact body — filename, git-status
|
|
141
|
+
* badge, optional diff counts, and a copy action. Ported in spirit from
|
|
142
|
+
* blueprint-agent's `PanelHeader` (min-h, hairline bottom border, dense
|
|
143
|
+
* horizontal rhythm), retoned to the sandbox-ui surface ladder.
|
|
144
|
+
*/
|
|
145
|
+
declare function PanelHeader({ filename, gitStatus, stats, copyText, children, className }: PanelHeaderProps): react_jsx_runtime.JSX.Element;
|
|
146
|
+
|
|
147
|
+
interface FileBreadcrumbProps {
|
|
148
|
+
/** Canonical path, e.g. `src/lib/retry.ts`. */
|
|
149
|
+
path: string;
|
|
150
|
+
className?: string;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Slim path breadcrumb for the code panel. Reimplemented (not ported) from
|
|
154
|
+
* blueprint-agent's `FileBreadcrumb` — that one nests a `FileTree` dropdown per
|
|
155
|
+
* segment and couples to the workbench store + framer-motion. Here the rail
|
|
156
|
+
* already owns navigation, so this is a read-only trail: caret-separated parent
|
|
157
|
+
* segments with a file-icon leaf.
|
|
158
|
+
*/
|
|
159
|
+
declare function FileBreadcrumb({ path, className }: FileBreadcrumbProps): react_jsx_runtime.JSX.Element;
|
|
160
|
+
|
|
161
|
+
interface CodeViewProps {
|
|
162
|
+
path: string;
|
|
163
|
+
filename: string;
|
|
164
|
+
content: string;
|
|
165
|
+
language?: string;
|
|
166
|
+
/** Flat list of paths for the rail; defaults to `[path]`. */
|
|
167
|
+
paths?: ReadonlyArray<string>;
|
|
168
|
+
gitStatus?: ReadonlyArray<RichFileTreeGitEntry>;
|
|
169
|
+
onFileSelect?: (path: string) => void;
|
|
170
|
+
/** Show the file-tree rail. Off for single-file embeds where the host owns navigation. */
|
|
171
|
+
showTree?: boolean;
|
|
172
|
+
className?: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Code surface: a fixed-width `RichFileTree` rail (with git-status
|
|
176
|
+
* decorations) beside a breadcrumb-topped, syntax-highlighted read-only file
|
|
177
|
+
* view. The rail owns navigation; selecting a path fans out to `onFileSelect`
|
|
178
|
+
* so the host can swap the active artifact.
|
|
179
|
+
*/
|
|
180
|
+
declare function CodeView({ path, filename, content, language, paths, gitStatus, onFileSelect, showTree, className, }: CodeViewProps): react_jsx_runtime.JSX.Element;
|
|
181
|
+
|
|
182
|
+
interface DiffViewProps {
|
|
183
|
+
filename: string;
|
|
184
|
+
baseline: string;
|
|
185
|
+
current: string;
|
|
186
|
+
className?: string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Word-level unified diff via `@pierre/diffs`' `PatchDiff`. The patch is built
|
|
190
|
+
* with jsdiff's `createTwoFilesPatch` (baseline → current); the renderer owns
|
|
191
|
+
* hunking, intra-line word diffing, gutters, and syntax highlighting.
|
|
192
|
+
*/
|
|
193
|
+
declare function DiffView({ filename, baseline, current, className }: DiffViewProps): react_jsx_runtime.JSX.Element;
|
|
194
|
+
|
|
195
|
+
interface PreviewViewProps {
|
|
196
|
+
/** Origin to load in the preview iframe. */
|
|
197
|
+
url: string;
|
|
198
|
+
className?: string;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Live preview: a slim address bar (reload + open-in-new-tab) over a sandboxed
|
|
202
|
+
* iframe. The iframe is force-remounted by bumping `iframeKey` on reload — the
|
|
203
|
+
* same remount trick blueprint-agent's `Preview` uses. The readiness probe is
|
|
204
|
+
* intentionally a stub here: the iframe shows optimistically and a loading
|
|
205
|
+
* veil clears on `onLoad` (or a short fallback timer), which is the right
|
|
206
|
+
* behavior for a static origin without a probe service wired in.
|
|
207
|
+
*/
|
|
208
|
+
declare function PreviewView({ url, className }: PreviewViewProps): react_jsx_runtime.JSX.Element;
|
|
209
|
+
|
|
210
|
+
/** Resolve a Prism language id from an explicit hint or the filename. */
|
|
211
|
+
declare function resolveLanguage(filename: string, explicit?: string): string;
|
|
212
|
+
declare const BRAND_PRISM_THEME: Record<string, CSSProperties>;
|
|
213
|
+
interface CodeSurfaceProps {
|
|
214
|
+
code: string;
|
|
215
|
+
filename: string;
|
|
216
|
+
language?: string;
|
|
217
|
+
showLineNumbers?: boolean;
|
|
218
|
+
className?: string;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Read-only, brand-themed code renderer. Wrapped in a scroll container so the
|
|
222
|
+
* highlighter itself never grows the layout; line numbers sit in a muted,
|
|
223
|
+
* tabular column.
|
|
224
|
+
*/
|
|
225
|
+
declare function CodeSurface({ code, filename, language, showLineNumbers, className, }: CodeSurfaceProps): react_jsx_runtime.JSX.Element;
|
|
226
|
+
|
|
227
|
+
export { type ArtifactView, BRAND_PRISM_THEME, CodeSurface, type CodeSurfaceProps, CodeView, type CodeViewProps, type DiffStats, DiffView, type DiffViewProps, FileBreadcrumb, type FileBreadcrumbProps, GitStatusBadge, PanelHeader, type PanelHeaderProps, type PillTabItem, PillTabs, type PillTabsProps, PreviewView, type PreviewViewProps, type SandboxArtifact, SandboxArtifactPane, type SandboxArtifactPaneProps, type SandboxArtifactTerminal, buildUnifiedPatch, computeDiffStats, resolveLanguage };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BRAND_PRISM_THEME,
|
|
3
|
+
CodeSurface,
|
|
4
|
+
CodeView,
|
|
5
|
+
DiffView,
|
|
6
|
+
FileBreadcrumb,
|
|
7
|
+
GitStatusBadge,
|
|
8
|
+
PanelHeader,
|
|
9
|
+
PillTabs,
|
|
10
|
+
PreviewView,
|
|
11
|
+
SandboxArtifactPane,
|
|
12
|
+
buildUnifiedPatch,
|
|
13
|
+
computeDiffStats,
|
|
14
|
+
resolveLanguage
|
|
15
|
+
} from "./chunk-NXUSLH7H.js";
|
|
16
|
+
import "./chunk-3J6FG3FJ.js";
|
|
17
|
+
import "./chunk-PZ62T5PM.js";
|
|
18
|
+
import "./chunk-OMUIPJQZ.js";
|
|
19
|
+
import "./chunk-VIREDUBF.js";
|
|
20
|
+
import "./chunk-77WVVJA4.js";
|
|
21
|
+
import "./chunk-4ZZUMXPX.js";
|
|
22
|
+
import "./chunk-BR2LMUAE.js";
|
|
23
|
+
import "./chunk-LQHTCM56.js";
|
|
24
|
+
import "./chunk-EI44GEQ5.js";
|
|
25
|
+
import "./chunk-U67V476Y.js";
|
|
26
|
+
export {
|
|
27
|
+
BRAND_PRISM_THEME,
|
|
28
|
+
CodeSurface,
|
|
29
|
+
CodeView,
|
|
30
|
+
DiffView,
|
|
31
|
+
FileBreadcrumb,
|
|
32
|
+
GitStatusBadge,
|
|
33
|
+
PanelHeader,
|
|
34
|
+
PillTabs,
|
|
35
|
+
PreviewView,
|
|
36
|
+
SandboxArtifactPane,
|
|
37
|
+
buildUnifiedPatch,
|
|
38
|
+
computeDiffStats,
|
|
39
|
+
resolveLanguage
|
|
40
|
+
};
|
package/dist/workflows.js
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
buildWorkflowGraph
|
|
3
3
|
} from "./chunk-SUC6ZJZW.js";
|
|
4
4
|
import "./chunk-7JLB7UZ3.js";
|
|
5
|
+
import "./chunk-U67V476Y.js";
|
|
5
6
|
|
|
6
7
|
// src/workflows/WorkflowGraphLazy.tsx
|
|
7
8
|
import {
|
|
@@ -26,7 +27,7 @@ function retryImport(factory, retries = 2, delayMs = 350) {
|
|
|
26
27
|
function lazyWorkflowGraph() {
|
|
27
28
|
return lazy(
|
|
28
29
|
() => retryImport(
|
|
29
|
-
() => import("./WorkflowGraph-
|
|
30
|
+
() => import("./WorkflowGraph-6IKZYPST.js").then((m) => ({ default: m.WorkflowGraph }))
|
|
30
31
|
)
|
|
31
32
|
);
|
|
32
33
|
}
|
package/dist/workspace.d.ts
CHANGED
|
@@ -100,7 +100,8 @@ interface StatusBannerProps {
|
|
|
100
100
|
declare function StatusBanner({ type, message, detail, onDismiss, className }: StatusBannerProps): react_jsx_runtime.JSX.Element;
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* StatusBar — bottom bar
|
|
103
|
+
* StatusBar — compact bottom bar: connection state, file/artifact context
|
|
104
|
+
* badges, credits. The active model lives in the input box, not here.
|
|
104
105
|
*/
|
|
105
106
|
interface ContextBadge {
|
|
106
107
|
id: string;
|
|
@@ -108,7 +109,10 @@ interface ContextBadge {
|
|
|
108
109
|
count?: number;
|
|
109
110
|
}
|
|
110
111
|
interface StatusBarProps {
|
|
112
|
+
/** @deprecated The model now lives in the input box; the status bar no longer
|
|
113
|
+
* renders it. Retained so existing callers keep type-checking. */
|
|
111
114
|
modelLabel?: string;
|
|
115
|
+
/** @deprecated See `modelLabel`. */
|
|
112
116
|
onModelClick?: () => void;
|
|
113
117
|
credits?: number;
|
|
114
118
|
contextBadges?: ContextBadge[];
|
|
@@ -116,7 +120,7 @@ interface StatusBarProps {
|
|
|
116
120
|
status?: "connected" | "connecting" | "disconnected" | "provisioning";
|
|
117
121
|
className?: string;
|
|
118
122
|
}
|
|
119
|
-
declare function StatusBar({
|
|
123
|
+
declare function StatusBar({ credits, contextBadges, onRemoveBadge, status, className, }: StatusBarProps): react_jsx_runtime.JSX.Element;
|
|
120
124
|
|
|
121
125
|
/**
|
|
122
126
|
* Terminal — read-only terminal output panel.
|
package/dist/workspace.js
CHANGED
|
@@ -19,8 +19,9 @@ import {
|
|
|
19
19
|
dispatchSessionCreated,
|
|
20
20
|
shellShouldRevalidate,
|
|
21
21
|
useOptimisticSessionItems
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-2ISY4R72.js";
|
|
23
23
|
import "./chunk-EI44GEQ5.js";
|
|
24
|
+
import "./chunk-U67V476Y.js";
|
|
24
25
|
export {
|
|
25
26
|
AgentWorkbench,
|
|
26
27
|
ApprovalQueue,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,6 +42,10 @@
|
|
|
42
42
|
"import": "./dist/workspace.js",
|
|
43
43
|
"types": "./dist/workspace.d.ts"
|
|
44
44
|
},
|
|
45
|
+
"./workbench": {
|
|
46
|
+
"import": "./dist/workbench.js",
|
|
47
|
+
"types": "./dist/workbench.d.ts"
|
|
48
|
+
},
|
|
45
49
|
"./openui": {
|
|
46
50
|
"import": "./dist/openui.js",
|
|
47
51
|
"types": "./dist/openui.d.ts"
|
|
@@ -122,12 +126,12 @@
|
|
|
122
126
|
"test:bridge": "pnpm build && vitest run src/__tests__/re-export-identity.test.ts"
|
|
123
127
|
},
|
|
124
128
|
"peerDependencies": {
|
|
125
|
-
"@tangle-network/
|
|
129
|
+
"@tangle-network/agent-interface": ">=0.10.0 <1.0.0",
|
|
130
|
+
"@tangle-network/brand": "^0.6.0",
|
|
126
131
|
"@tangle-network/ui": "^4.0.0",
|
|
132
|
+
"@xyflow/react": "^12.0.0",
|
|
127
133
|
"react": "^18 || ^19",
|
|
128
|
-
"react-dom": "^18 || ^19"
|
|
129
|
-
"@tangle-network/agent-interface": ">=0.10.0 <1.0.0",
|
|
130
|
-
"@xyflow/react": "^12.0.0"
|
|
134
|
+
"react-dom": "^18 || ^19"
|
|
131
135
|
},
|
|
132
136
|
"peerDependenciesMeta": {
|
|
133
137
|
"@xyflow/react": {
|
|
@@ -154,8 +158,10 @@
|
|
|
154
158
|
},
|
|
155
159
|
"dependencies": {
|
|
156
160
|
"@lobehub/icons-static-svg": "^1.90.0",
|
|
161
|
+
"@pierre/diffs": "^1.2.11",
|
|
157
162
|
"@radix-ui/react-dropdown-menu": "^2.1.0",
|
|
158
163
|
"@radix-ui/react-select": "^2.1.0",
|
|
164
|
+
"diff": "^5.2.0",
|
|
159
165
|
"lucide-react": "^0.469.0",
|
|
160
166
|
"nanostores": "^1.2.0",
|
|
161
167
|
"yaml": "^2.5.0"
|
|
@@ -168,7 +174,6 @@
|
|
|
168
174
|
"devDependencies": {
|
|
169
175
|
"@hocuspocus/provider": "^3.4.4",
|
|
170
176
|
"@nanostores/react": "^1.1.0",
|
|
171
|
-
"@xyflow/react": "^12.11.0",
|
|
172
177
|
"@pierre/trees": "1.0.0-beta.3",
|
|
173
178
|
"@storybook/addon-essentials": "^8",
|
|
174
179
|
"@storybook/addon-mcp": "^0.4.2",
|
|
@@ -176,7 +181,8 @@
|
|
|
176
181
|
"@storybook/react-vite": "^8.6.18",
|
|
177
182
|
"@tailwindcss/postcss": "^4.2.2",
|
|
178
183
|
"@tailwindcss/vite": "^4.2.2",
|
|
179
|
-
"@tangle-network/
|
|
184
|
+
"@tangle-network/agent-interface": ">=0.10.0 <1.0.0",
|
|
185
|
+
"@tangle-network/brand": "^0.6.0",
|
|
180
186
|
"@tangle-network/ui": "^4.1.0",
|
|
181
187
|
"@tanstack/react-query": "^5.91.0",
|
|
182
188
|
"@testing-library/dom": "^10.4.1",
|
|
@@ -193,6 +199,7 @@
|
|
|
193
199
|
"@xterm/addon-web-links": "^0.12.0",
|
|
194
200
|
"@xterm/addon-webgl": "^0.19.0",
|
|
195
201
|
"@xterm/xterm": "^6.0.0",
|
|
202
|
+
"@xyflow/react": "^12.11.0",
|
|
196
203
|
"jsdom": "^29.0.2",
|
|
197
204
|
"marked": "^17.0.5",
|
|
198
205
|
"postcss": "^8.5.8",
|
|
@@ -212,7 +219,6 @@
|
|
|
212
219
|
"typescript": "^5.8.3",
|
|
213
220
|
"vite": "^8.0.5",
|
|
214
221
|
"vitest": "^4.1.3",
|
|
215
|
-
"yjs": "^13.6.30"
|
|
216
|
-
"@tangle-network/agent-interface": ">=0.10.0 <1.0.0"
|
|
222
|
+
"yjs": "^13.6.30"
|
|
217
223
|
}
|
|
218
224
|
}
|