@tangle-network/sandbox-ui 0.2.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 (70) hide show
  1. package/README.md +68 -0
  2. package/dist/auth.d.ts +57 -0
  3. package/dist/auth.js +14 -0
  4. package/dist/branding-DCi5VEik.d.ts +13 -0
  5. package/dist/button-BidTtuRS.d.ts +15 -0
  6. package/dist/chat.d.ts +121 -0
  7. package/dist/chat.js +25 -0
  8. package/dist/chunk-2UHPE5T7.js +201 -0
  9. package/dist/chunk-4EIWPJMJ.js +545 -0
  10. package/dist/chunk-6MQIDUPA.js +502 -0
  11. package/dist/chunk-B26TQ7SA.js +47 -0
  12. package/dist/chunk-E6FS7R4X.js +109 -0
  13. package/dist/chunk-GRYHFH5O.js +110 -0
  14. package/dist/chunk-HMND7JPA.js +868 -0
  15. package/dist/chunk-HRMUF35V.js +19 -0
  16. package/dist/chunk-HYEAX3DC.js +822 -0
  17. package/dist/chunk-KMXV7DDX.js +174 -0
  18. package/dist/chunk-KYY2X6LY.js +318 -0
  19. package/dist/chunk-L6ZDH5F4.js +334 -0
  20. package/dist/chunk-LTFK464G.js +103 -0
  21. package/dist/chunk-M34OA6PQ.js +233 -0
  22. package/dist/chunk-M6VLC32S.js +219 -0
  23. package/dist/chunk-MCGKDCOR.js +173 -0
  24. package/dist/chunk-NI2EI43H.js +294 -0
  25. package/dist/chunk-OU4TRNQZ.js +173 -0
  26. package/dist/chunk-QD4QE5P5.js +40 -0
  27. package/dist/chunk-QSQBDR3N.js +180 -0
  28. package/dist/chunk-RQHJBTEU.js +10 -0
  29. package/dist/chunk-U62G5TS7.js +472 -0
  30. package/dist/chunk-ZOL2TR5M.js +475 -0
  31. package/dist/dashboard.d.ts +111 -0
  32. package/dist/dashboard.js +26 -0
  33. package/dist/editor.d.ts +196 -0
  34. package/dist/editor.js +713 -0
  35. package/dist/expanded-tool-detail-OkXGqTHe.d.ts +52 -0
  36. package/dist/files.d.ts +66 -0
  37. package/dist/files.js +11 -0
  38. package/dist/hooks.d.ts +22 -0
  39. package/dist/hooks.js +107 -0
  40. package/dist/index.d.ts +107 -0
  41. package/dist/index.js +551 -0
  42. package/dist/markdown.d.ts +55 -0
  43. package/dist/markdown.js +17 -0
  44. package/dist/pages.d.ts +89 -0
  45. package/dist/pages.js +1181 -0
  46. package/dist/parts-CyGkM6Fp.d.ts +50 -0
  47. package/dist/primitives.d.ts +189 -0
  48. package/dist/primitives.js +161 -0
  49. package/dist/run-CtFZ6s-D.d.ts +41 -0
  50. package/dist/run.d.ts +14 -0
  51. package/dist/run.js +29 -0
  52. package/dist/sidecar-CFU2W9j1.d.ts +8 -0
  53. package/dist/stores.d.ts +28 -0
  54. package/dist/stores.js +49 -0
  55. package/dist/terminal.d.ts +44 -0
  56. package/dist/terminal.js +160 -0
  57. package/dist/tool-call-feed-D5Ume-Pt.d.ts +66 -0
  58. package/dist/tool-display-BvsVW_Ur.d.ts +32 -0
  59. package/dist/types.d.ts +6 -0
  60. package/dist/types.js +0 -0
  61. package/dist/usage-chart-DINgSVL5.d.ts +60 -0
  62. package/dist/use-sidecar-auth-Bb0-w3lX.d.ts +339 -0
  63. package/dist/utils.d.ts +28 -0
  64. package/dist/utils.js +28 -0
  65. package/dist/workspace.d.ts +113 -0
  66. package/dist/workspace.js +15 -0
  67. package/package.json +174 -0
  68. package/src/styles/globals.css +230 -0
  69. package/src/styles/tokens.css +73 -0
  70. package/tailwind.config.cjs +99 -0
@@ -0,0 +1,173 @@
1
+ import {
2
+ Avatar,
3
+ AvatarFallback,
4
+ AvatarImage
5
+ } from "./chunk-B26TQ7SA.js";
6
+ import {
7
+ DropdownMenu,
8
+ DropdownMenuContent,
9
+ DropdownMenuItem,
10
+ DropdownMenuLabel,
11
+ DropdownMenuSeparator,
12
+ DropdownMenuTrigger
13
+ } from "./chunk-MCGKDCOR.js";
14
+ import {
15
+ Button
16
+ } from "./chunk-E6FS7R4X.js";
17
+ import {
18
+ cn
19
+ } from "./chunk-RQHJBTEU.js";
20
+
21
+ // src/auth/auth.tsx
22
+ import { jsx, jsxs } from "react/jsx-runtime";
23
+ function GitHubIcon({ className }) {
24
+ return /* @__PURE__ */ jsx(
25
+ "svg",
26
+ {
27
+ className,
28
+ viewBox: "0 0 24 24",
29
+ fill: "currentColor",
30
+ "aria-hidden": "true",
31
+ children: /* @__PURE__ */ jsx(
32
+ "path",
33
+ {
34
+ fillRule: "evenodd",
35
+ clipRule: "evenodd",
36
+ d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"
37
+ }
38
+ )
39
+ }
40
+ );
41
+ }
42
+ function GitHubLoginButton({
43
+ authUrl = "/auth/github",
44
+ variant = "default",
45
+ className,
46
+ children,
47
+ ...props
48
+ }) {
49
+ return /* @__PURE__ */ jsxs(
50
+ Button,
51
+ {
52
+ variant,
53
+ className: cn("gap-2", className),
54
+ onClick: () => {
55
+ window.location.href = authUrl;
56
+ },
57
+ ...props,
58
+ children: [
59
+ /* @__PURE__ */ jsx(GitHubIcon, { className: "h-5 w-5" }),
60
+ children ?? "Sign in with GitHub"
61
+ ]
62
+ }
63
+ );
64
+ }
65
+ function UserMenu({
66
+ user,
67
+ logoutUrl = "/auth/logout",
68
+ links = [],
69
+ variant = "sandbox",
70
+ onLogout
71
+ }) {
72
+ const initials = user.name ? user.name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) : user.email.slice(0, 2).toUpperCase();
73
+ const avatarGradient = {
74
+ sandbox: "from-purple-500 to-violet-500"
75
+ }[variant];
76
+ const handleLogout = () => {
77
+ if (onLogout) {
78
+ onLogout();
79
+ }
80
+ window.location.href = logoutUrl;
81
+ };
82
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
83
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
84
+ "button",
85
+ {
86
+ type: "button",
87
+ className: "flex items-center gap-2 rounded-lg p-1.5 transition-colors hover:bg-accent focus:outline-none focus:ring-2 focus:ring-ring",
88
+ children: [
89
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8", children: [
90
+ /* @__PURE__ */ jsx(AvatarImage, { src: void 0, alt: user.name ?? user.email }),
91
+ /* @__PURE__ */ jsx(
92
+ AvatarFallback,
93
+ {
94
+ className: cn(
95
+ "bg-gradient-to-r text-white text-xs",
96
+ avatarGradient
97
+ ),
98
+ children: initials
99
+ }
100
+ )
101
+ ] }),
102
+ /* @__PURE__ */ jsxs("div", { className: "hidden text-left md:block", children: [
103
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-sm", children: user.name ?? user.email }),
104
+ user.tier && /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground text-xs capitalize", children: [
105
+ user.tier,
106
+ " Plan"
107
+ ] })
108
+ ] })
109
+ ]
110
+ }
111
+ ) }),
112
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
113
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-1", children: [
114
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-sm", children: user.name ?? "Account" }),
115
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: user.email })
116
+ ] }) }),
117
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
118
+ links.map((link) => /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs("a", { href: link.href, className: "flex items-center gap-2", children: [
119
+ link.icon,
120
+ link.label
121
+ ] }) }, link.href)),
122
+ links.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
123
+ /* @__PURE__ */ jsx(
124
+ DropdownMenuItem,
125
+ {
126
+ onClick: handleLogout,
127
+ className: "text-red-500 focus:text-red-500",
128
+ children: "Sign out"
129
+ }
130
+ )
131
+ ] })
132
+ ] });
133
+ }
134
+ function AuthHeader({
135
+ user,
136
+ loading = false,
137
+ variant = "sandbox",
138
+ apiBaseUrl = "",
139
+ menuLinks,
140
+ className
141
+ }) {
142
+ if (loading) {
143
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
144
+ /* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-pulse rounded-full bg-muted" }),
145
+ /* @__PURE__ */ jsx("div", { className: "hidden md:block", children: /* @__PURE__ */ jsx("div", { className: "h-4 w-20 animate-pulse rounded bg-muted" }) })
146
+ ] });
147
+ }
148
+ if (!user) {
149
+ return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2", className), children: /* @__PURE__ */ jsx(
150
+ GitHubLoginButton,
151
+ {
152
+ authUrl: `${apiBaseUrl}/auth/github`,
153
+ variant,
154
+ size: "sm"
155
+ }
156
+ ) });
157
+ }
158
+ return /* @__PURE__ */ jsx(
159
+ UserMenu,
160
+ {
161
+ user,
162
+ variant,
163
+ logoutUrl: `${apiBaseUrl}/auth/logout`,
164
+ links: menuLinks
165
+ }
166
+ );
167
+ }
168
+
169
+ export {
170
+ GitHubLoginButton,
171
+ UserMenu,
172
+ AuthHeader
173
+ };
@@ -0,0 +1,40 @@
1
+ // src/utils/copy-text.ts
2
+ async function copyText(text) {
3
+ if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
4
+ try {
5
+ await navigator.clipboard.writeText(text);
6
+ return true;
7
+ } catch {
8
+ }
9
+ }
10
+ if (typeof document === "undefined") return false;
11
+ try {
12
+ const textarea = document.createElement("textarea");
13
+ textarea.value = text;
14
+ textarea.style.position = "fixed";
15
+ textarea.style.opacity = "0";
16
+ document.body.appendChild(textarea);
17
+ textarea.select();
18
+ const copied = document.execCommand("copy");
19
+ document.body.removeChild(textarea);
20
+ return copied;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ // src/utils/time-ago.ts
27
+ function timeAgo(ts) {
28
+ const secs = Math.floor((Date.now() - ts) / 1e3);
29
+ if (secs < 5) return "just now";
30
+ if (secs < 60) return `${secs}s ago`;
31
+ const mins = Math.floor(secs / 60);
32
+ if (mins < 60) return `${mins}m ago`;
33
+ const hrs = Math.floor(mins / 60);
34
+ return `${hrs}h ago`;
35
+ }
36
+
37
+ export {
38
+ copyText,
39
+ timeAgo
40
+ };
@@ -0,0 +1,180 @@
1
+ // src/utils/tool-display.ts
2
+ var TOOL_NAME_PREFIX = "tool:";
3
+ function normalizeToolName(tool) {
4
+ const n = tool?.toLowerCase() ?? "";
5
+ return n.startsWith(TOOL_NAME_PREFIX) ? n.slice(TOOL_NAME_PREFIX.length) : n;
6
+ }
7
+ function extractString(obj, key) {
8
+ if (typeof obj === "object" && obj !== null && key in obj) {
9
+ const val = obj[key];
10
+ if (typeof val === "string") return val;
11
+ }
12
+ return void 0;
13
+ }
14
+ function extractCommand(input) {
15
+ if (typeof input === "string") return input;
16
+ return extractString(input, "command") ?? extractString(input, "cmd");
17
+ }
18
+ function extractFilePath(input) {
19
+ return extractString(input, "file_path") ?? extractString(input, "path") ?? extractString(input, "filePath");
20
+ }
21
+ function cleanPath(path) {
22
+ const parts = path.split("/");
23
+ return parts.length > 3 ? ".../" + parts.slice(-2).join("/") : path;
24
+ }
25
+ var TOOL_CATEGORY_ICONS = {
26
+ command: "terminal",
27
+ write: "file-plus",
28
+ read: "file-text",
29
+ search: "search",
30
+ edit: "file-edit",
31
+ task: "cpu",
32
+ web: "globe",
33
+ todo: "check-square",
34
+ other: "box"
35
+ };
36
+ function getToolCategory(toolName) {
37
+ const name = normalizeToolName(toolName);
38
+ switch (name) {
39
+ case "bash":
40
+ case "shell":
41
+ case "command":
42
+ case "execute":
43
+ return "command";
44
+ case "write":
45
+ case "write_file":
46
+ case "create_file":
47
+ return "write";
48
+ case "read":
49
+ case "read_file":
50
+ case "cat":
51
+ return "read";
52
+ case "grep":
53
+ case "search":
54
+ case "rg":
55
+ return "search";
56
+ case "edit":
57
+ case "patch":
58
+ case "sed":
59
+ return "edit";
60
+ case "glob":
61
+ case "find":
62
+ case "ls":
63
+ return "search";
64
+ case "web_search":
65
+ case "web_fetch":
66
+ case "fetch":
67
+ return "web";
68
+ case "task":
69
+ case "agent":
70
+ case "spawn":
71
+ return "task";
72
+ case "todo":
73
+ case "todo_write":
74
+ return "todo";
75
+ default:
76
+ return "other";
77
+ }
78
+ }
79
+ function getToolDisplayMetadata(part) {
80
+ const name = normalizeToolName(part.tool);
81
+ const input = part.state.status !== "pending" ? part.state.input : void 0;
82
+ const filePath = extractFilePath(input);
83
+ const command = extractCommand(input);
84
+ switch (name) {
85
+ case "bash":
86
+ case "shell":
87
+ case "command":
88
+ case "execute":
89
+ return {
90
+ title: "Run command",
91
+ description: command ? truncateCommand(command) : void 0,
92
+ displayVariant: "command",
93
+ commandSnippet: command
94
+ };
95
+ case "write":
96
+ case "write_file":
97
+ case "create_file":
98
+ return {
99
+ title: filePath ? `Write ${cleanPath(filePath)}` : "Write file",
100
+ description: filePath,
101
+ displayVariant: "write-file",
102
+ targetPath: filePath
103
+ };
104
+ case "edit":
105
+ case "patch":
106
+ return {
107
+ title: filePath ? `Edit ${cleanPath(filePath)}` : "Edit file",
108
+ description: filePath,
109
+ hasDiffOutput: true,
110
+ diffFilePath: filePath,
111
+ targetPath: filePath
112
+ };
113
+ case "read":
114
+ case "read_file":
115
+ case "cat":
116
+ return {
117
+ title: filePath ? `Read ${cleanPath(filePath)}` : "Read file",
118
+ description: filePath,
119
+ targetPath: filePath
120
+ };
121
+ case "grep":
122
+ case "search":
123
+ case "rg": {
124
+ const pattern = extractString(input, "pattern");
125
+ return {
126
+ title: pattern ? `Search: ${pattern}` : "Search",
127
+ description: pattern,
128
+ displayVariant: "grep"
129
+ };
130
+ }
131
+ case "glob":
132
+ case "find":
133
+ case "ls": {
134
+ const pattern = extractString(input, "pattern");
135
+ return {
136
+ title: pattern ? `Find: ${pattern}` : "Find files",
137
+ description: pattern,
138
+ displayVariant: "glob"
139
+ };
140
+ }
141
+ case "web_search":
142
+ case "web_fetch":
143
+ case "fetch": {
144
+ const query = extractString(input, "query") ?? extractString(input, "url");
145
+ return {
146
+ title: query ? `Web: ${truncateCommand(query)}` : "Web search",
147
+ description: query,
148
+ displayVariant: "web-search"
149
+ };
150
+ }
151
+ case "task":
152
+ case "agent":
153
+ case "spawn": {
154
+ const desc = extractString(input, "description") ?? extractString(input, "prompt");
155
+ return {
156
+ title: desc ? `Task: ${truncateCommand(desc)}` : "Agent task",
157
+ description: desc
158
+ };
159
+ }
160
+ default:
161
+ return {
162
+ title: part.tool || "Tool"
163
+ };
164
+ }
165
+ }
166
+ function truncateCommand(cmd) {
167
+ const first = cmd.split("\n")[0];
168
+ return first.length > 60 ? first.slice(0, 57) + "..." : first;
169
+ }
170
+ function getToolErrorText(part, fallback) {
171
+ if (part.state.status !== "error") return void 0;
172
+ return part.state.error || fallback;
173
+ }
174
+
175
+ export {
176
+ TOOL_CATEGORY_ICONS,
177
+ getToolCategory,
178
+ getToolDisplayMetadata,
179
+ getToolErrorText
180
+ };
@@ -0,0 +1,10 @@
1
+ // src/lib/utils.ts
2
+ import { clsx } from "clsx";
3
+ import { twMerge } from "tailwind-merge";
4
+ function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ export {
9
+ cn
10
+ };