@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.
Files changed (45) hide show
  1. package/dist/{WorkflowGraph-7YYGIBNV.js → WorkflowGraph-6IKZYPST.js} +2 -1
  2. package/dist/assets.js +1 -0
  3. package/dist/assistant.js +2 -1
  4. package/dist/auth.js +1 -0
  5. package/dist/chat.js +4 -3
  6. package/dist/{chunk-6NDOA4SB.js → chunk-2ISY4R72.js} +112 -104
  7. package/dist/{chunk-KIRJZUX2.js → chunk-BR2LMUAE.js} +61 -34
  8. package/dist/{chunk-H7GMPMPB.js → chunk-CXV6X33U.js} +19 -1
  9. package/dist/{chunk-CUUUFJF5.js → chunk-KOUYJ6QP.js} +23 -23
  10. package/dist/{chunk-3RNYDTQ3.js → chunk-LQHTCM56.js} +21 -27
  11. package/dist/chunk-NXUSLH7H.js +7528 -0
  12. package/dist/{chunk-2XNT74ZX.js → chunk-OMUIPJQZ.js} +28 -20
  13. package/dist/{chunk-KCWIC3SJ.js → chunk-PZ62T5PM.js} +281 -214
  14. package/dist/chunk-U67V476Y.js +35 -0
  15. package/dist/chunk-VIREDUBF.js +215 -0
  16. package/dist/dashboard.d.ts +82 -66
  17. package/dist/dashboard.js +5 -4
  18. package/dist/editor.js +2 -0
  19. package/dist/files.d.ts +5 -0
  20. package/dist/files.js +1 -0
  21. package/dist/globals.css +1155 -50
  22. package/dist/hooks.js +1 -0
  23. package/dist/index.d.ts +3 -1
  24. package/dist/index.js +95 -65
  25. package/dist/integrations.js +2 -1
  26. package/dist/markdown.js +2 -0
  27. package/dist/openui.d.ts +0 -5
  28. package/dist/openui.js +1 -0
  29. package/dist/pages.d.ts +1 -1
  30. package/dist/pages.js +89 -88
  31. package/dist/ports-list-DfG0VfPt.d.ts +17 -0
  32. package/dist/primitives.js +1 -0
  33. package/dist/run.js +1 -0
  34. package/dist/sdk-hooks.js +1 -0
  35. package/dist/stores.js +1 -0
  36. package/dist/styles.css +1155 -50
  37. package/dist/terminal.js +5 -209
  38. package/dist/tokens.css +13 -2
  39. package/dist/utils.js +1 -0
  40. package/dist/workbench.d.ts +227 -0
  41. package/dist/workbench.js +40 -0
  42. package/dist/workflows.js +2 -1
  43. package/dist/workspace.d.ts +6 -2
  44. package/dist/workspace.js +2 -1
  45. package/package.json +15 -9
package/dist/terminal.js CHANGED
@@ -1,213 +1,9 @@
1
1
  import {
2
- usePtySession
3
- } from "./chunk-77WVVJA4.js";
4
-
5
- // src/terminal/terminal-view.tsx
6
- import "@xterm/xterm/css/xterm.css";
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
- [data-sandbox-theme="vault"] {
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
@@ -11,6 +11,7 @@ import {
11
11
  timeAgo,
12
12
  truncateText
13
13
  } from "./chunk-TK46XFLM.js";
14
+ import "./chunk-U67V476Y.js";
14
15
  export {
15
16
  TOOL_CATEGORY_ICONS,
16
17
  cn,
@@ -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-7YYGIBNV.js").then((m) => ({ default: m.WorkflowGraph }))
30
+ () => import("./WorkflowGraph-6IKZYPST.js").then((m) => ({ default: m.WorkflowGraph }))
30
31
  )
31
32
  );
32
33
  }
@@ -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 with model selector, context badges, credits.
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({ modelLabel, onModelClick, credits, contextBadges, onRemoveBadge, status, className, }: StatusBarProps): react_jsx_runtime.JSX.Element;
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-6NDOA4SB.js";
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.44.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/brand": "^0.5.0",
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/brand": "^0.5.0",
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
  }