@surf-kit/agent 0.1.1 → 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.
- package/README.md +19 -1
- package/dist/agent-BNSmiexZ.d.cts +44 -0
- package/dist/agent-BNSmiexZ.d.ts +44 -0
- package/dist/agent-identity/index.cjs +157 -0
- package/dist/agent-identity/index.cjs.map +1 -0
- package/dist/agent-identity/index.d.cts +35 -0
- package/dist/agent-identity/index.d.ts +35 -0
- package/dist/agent-identity/index.js +127 -0
- package/dist/agent-identity/index.js.map +1 -0
- package/dist/chat/index.cjs +1281 -0
- package/dist/chat/index.cjs.map +1 -0
- package/dist/chat/index.d.cts +72 -0
- package/dist/chat/index.d.ts +72 -0
- package/dist/chat/index.js +1239 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat--OifhIRe.d.ts +24 -0
- package/dist/chat-ChYl2XjV.d.cts +24 -0
- package/dist/confidence/index.cjs +253 -0
- package/dist/confidence/index.cjs.map +1 -0
- package/dist/confidence/index.d.cts +40 -0
- package/dist/confidence/index.d.ts +40 -0
- package/dist/confidence/index.js +222 -0
- package/dist/confidence/index.js.map +1 -0
- package/dist/feedback/index.cjs +186 -0
- package/dist/feedback/index.cjs.map +1 -0
- package/dist/feedback/index.d.cts +27 -0
- package/dist/feedback/index.d.ts +27 -0
- package/dist/feedback/index.js +157 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/{hooks-B8CSeOsn.d.cts → hooks-BGs8-4GK.d.ts} +4 -99
- package/dist/{hooks-B8CSeOsn.d.ts → hooks-DLfF18IU.d.cts} +4 -99
- package/dist/hooks.d.cts +4 -1
- package/dist/hooks.d.ts +4 -1
- package/dist/index-BazLnae1.d.cts +67 -0
- package/dist/index-BazLnae1.d.ts +67 -0
- package/dist/index.cjs +889 -144
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -321
- package/dist/index.d.ts +15 -321
- package/dist/index.js +879 -142
- package/dist/index.js.map +1 -1
- package/dist/layouts/index.cjs +1588 -0
- package/dist/layouts/index.cjs.map +1 -0
- package/dist/layouts/index.d.cts +46 -0
- package/dist/layouts/index.d.ts +46 -0
- package/dist/layouts/index.js +1548 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/mcp/index.cjs +522 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +2 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +492 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/response/index.cjs +519 -0
- package/dist/response/index.cjs.map +1 -0
- package/dist/response/index.d.cts +44 -0
- package/dist/response/index.d.ts +44 -0
- package/dist/response/index.js +478 -0
- package/dist/response/index.js.map +1 -0
- package/dist/sources/index.cjs +243 -0
- package/dist/sources/index.cjs.map +1 -0
- package/dist/sources/index.d.cts +44 -0
- package/dist/sources/index.d.ts +44 -0
- package/dist/sources/index.js +212 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/streaming/index.cjs +531 -0
- package/dist/streaming/index.cjs.map +1 -0
- package/dist/streaming/index.d.cts +81 -0
- package/dist/streaming/index.d.ts +81 -0
- package/dist/streaming/index.js +495 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/streaming-DbQxScpi.d.ts +39 -0
- package/dist/streaming-DfT22A0z.d.cts +39 -0
- package/package.json +62 -17
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/mcp/index.ts
|
|
21
|
+
var mcp_exports = {};
|
|
22
|
+
__export(mcp_exports, {
|
|
23
|
+
MCPApprovalDialog: () => MCPApprovalDialog,
|
|
24
|
+
MCPResourceView: () => MCPResourceView,
|
|
25
|
+
MCPServerStatus: () => MCPServerStatus,
|
|
26
|
+
MCPToolCall: () => MCPToolCall
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(mcp_exports);
|
|
29
|
+
|
|
30
|
+
// src/mcp/MCPToolCall/MCPToolCall.tsx
|
|
31
|
+
var import_class_variance_authority = require("class-variance-authority");
|
|
32
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
33
|
+
var import_core = require("@surf-kit/core");
|
|
34
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
35
|
+
var statusBadgeIntent = {
|
|
36
|
+
pending: "default",
|
|
37
|
+
running: "info",
|
|
38
|
+
success: "success",
|
|
39
|
+
error: "error"
|
|
40
|
+
};
|
|
41
|
+
var statusLabel = {
|
|
42
|
+
pending: "Pending",
|
|
43
|
+
running: "Running",
|
|
44
|
+
success: "Success",
|
|
45
|
+
error: "Error"
|
|
46
|
+
};
|
|
47
|
+
var container = (0, import_class_variance_authority.cva)(
|
|
48
|
+
"rounded-lg border text-sm",
|
|
49
|
+
{
|
|
50
|
+
variants: {
|
|
51
|
+
status: {
|
|
52
|
+
pending: "border-neutral-200 bg-neutral-50",
|
|
53
|
+
running: "border-sky-200 bg-sky-50",
|
|
54
|
+
success: "border-status-success-subtle bg-status-success-subtle/30",
|
|
55
|
+
error: "border-status-error-subtle bg-status-error-subtle/30"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
defaultVariants: { status: "pending" }
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
function formatDuration(start, end) {
|
|
62
|
+
if (!start || !end) return null;
|
|
63
|
+
const ms = end.getTime() - start.getTime();
|
|
64
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
65
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
66
|
+
}
|
|
67
|
+
function formatValue(value) {
|
|
68
|
+
if (typeof value === "string") return value;
|
|
69
|
+
return JSON.stringify(value, null, 2);
|
|
70
|
+
}
|
|
71
|
+
function MCPToolCall({ call, isExpanded = false, onToggleExpand, className }) {
|
|
72
|
+
const duration = formatDuration(call.startedAt, call.completedAt);
|
|
73
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
74
|
+
"div",
|
|
75
|
+
{
|
|
76
|
+
className: (0, import_tailwind_merge.twMerge)(container({ status: call.status }), className),
|
|
77
|
+
"data-testid": "mcp-tool-call",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
80
|
+
"button",
|
|
81
|
+
{
|
|
82
|
+
type: "button",
|
|
83
|
+
className: "flex w-full items-center justify-between gap-2 px-3 py-2",
|
|
84
|
+
onClick: onToggleExpand,
|
|
85
|
+
"aria-expanded": isExpanded,
|
|
86
|
+
"data-testid": "mcp-tool-call-header",
|
|
87
|
+
children: [
|
|
88
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
89
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "font-medium text-text-primary truncate", "data-testid": "mcp-tool-name", children: call.name }),
|
|
90
|
+
call.serverName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-text-secondary truncate", children: call.serverName })
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
93
|
+
call.status === "running" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Spinner, { size: "sm" }) }),
|
|
94
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
95
|
+
import_core.Badge,
|
|
96
|
+
{
|
|
97
|
+
intent: statusBadgeIntent[call.status],
|
|
98
|
+
size: "sm",
|
|
99
|
+
role: "status",
|
|
100
|
+
"aria-label": `Status: ${statusLabel[call.status]}`,
|
|
101
|
+
"data-testid": "mcp-tool-status",
|
|
102
|
+
children: statusLabel[call.status]
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
duration && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-text-secondary", "data-testid": "mcp-tool-duration", children: duration }),
|
|
106
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
107
|
+
"svg",
|
|
108
|
+
{
|
|
109
|
+
className: `h-4 w-4 text-text-secondary transition-transform ${isExpanded ? "rotate-180" : ""}`,
|
|
110
|
+
viewBox: "0 0 20 20",
|
|
111
|
+
fill: "currentColor",
|
|
112
|
+
"aria-hidden": "true",
|
|
113
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
114
|
+
"path",
|
|
115
|
+
{
|
|
116
|
+
fillRule: "evenodd",
|
|
117
|
+
d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
|
|
118
|
+
clipRule: "evenodd"
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
] })
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
),
|
|
127
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "border-t border-inherit px-3 py-2 space-y-3", "data-testid": "mcp-tool-call-body", children: [
|
|
128
|
+
Object.keys(call.arguments).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "text-xs font-medium text-text-secondary mb-1", children: "Arguments" }),
|
|
130
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dl", { className: "space-y-1", "data-testid": "mcp-tool-arguments", children: Object.entries(call.arguments).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2", children: [
|
|
131
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dt", { className: "text-xs font-mono text-text-secondary shrink-0", children: [
|
|
132
|
+
key,
|
|
133
|
+
":"
|
|
134
|
+
] }),
|
|
135
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { className: "text-xs font-mono text-text-primary break-all", children: formatValue(value) })
|
|
136
|
+
] }, key)) })
|
|
137
|
+
] }),
|
|
138
|
+
call.result !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
139
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "text-xs font-medium text-text-secondary mb-1", children: "Result" }),
|
|
140
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
141
|
+
"pre",
|
|
142
|
+
{
|
|
143
|
+
className: "text-xs font-mono text-text-primary bg-neutral-100 rounded p-2 overflow-x-auto whitespace-pre-wrap",
|
|
144
|
+
"data-testid": "mcp-tool-result",
|
|
145
|
+
children: typeof call.result === "string" ? call.result : JSON.stringify(call.result, null, 2)
|
|
146
|
+
}
|
|
147
|
+
)
|
|
148
|
+
] }),
|
|
149
|
+
call.error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
150
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "text-xs font-medium text-status-error mb-1", children: "Error" }),
|
|
151
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
152
|
+
"p",
|
|
153
|
+
{
|
|
154
|
+
className: "text-xs text-status-error bg-status-error-subtle/30 rounded p-2",
|
|
155
|
+
"data-testid": "mcp-tool-error",
|
|
156
|
+
children: call.error
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
] })
|
|
160
|
+
] })
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/mcp/MCPResourceView/MCPResourceView.tsx
|
|
167
|
+
var import_tailwind_merge2 = require("tailwind-merge");
|
|
168
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
169
|
+
function isImageMime(mime) {
|
|
170
|
+
return !!mime && mime.startsWith("image/");
|
|
171
|
+
}
|
|
172
|
+
function isTextMime(mime) {
|
|
173
|
+
if (!mime) return true;
|
|
174
|
+
return mime.startsWith("text/") || mime === "application/json" || mime === "application/xml" || mime === "application/javascript" || mime === "application/typescript";
|
|
175
|
+
}
|
|
176
|
+
function isUrlContent(content) {
|
|
177
|
+
if (typeof content !== "string") return false;
|
|
178
|
+
return /^https?:\/\//.test(content.trim());
|
|
179
|
+
}
|
|
180
|
+
function MCPResourceView({ resource, className }) {
|
|
181
|
+
const { uri, name, mimeType, description, content } = resource;
|
|
182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
183
|
+
"div",
|
|
184
|
+
{
|
|
185
|
+
className: (0, import_tailwind_merge2.twMerge)("rounded-lg border border-border bg-surface p-3 text-sm", className),
|
|
186
|
+
"data-testid": "mcp-resource-view",
|
|
187
|
+
children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mb-2", children: [
|
|
189
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "font-medium text-text-primary", "data-testid": "mcp-resource-name", children: name }),
|
|
190
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
191
|
+
"span",
|
|
192
|
+
{
|
|
193
|
+
className: "ml-2 text-xs text-text-secondary font-mono truncate",
|
|
194
|
+
"data-testid": "mcp-resource-uri",
|
|
195
|
+
children: uri
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
] }),
|
|
199
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs text-text-secondary mb-2", "data-testid": "mcp-resource-description", children: description }),
|
|
200
|
+
content !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { "data-testid": "mcp-resource-content", children: isImageMime(mimeType) && typeof content === "string" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
201
|
+
"img",
|
|
202
|
+
{
|
|
203
|
+
src: content,
|
|
204
|
+
alt: name,
|
|
205
|
+
className: "max-w-full rounded",
|
|
206
|
+
"data-testid": "mcp-resource-image"
|
|
207
|
+
}
|
|
208
|
+
) : isUrlContent(content) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
209
|
+
"a",
|
|
210
|
+
{
|
|
211
|
+
href: typeof content === "string" ? content.trim() : void 0,
|
|
212
|
+
target: "_blank",
|
|
213
|
+
rel: "noopener noreferrer",
|
|
214
|
+
className: "text-sm text-interactive-primary hover:underline break-all",
|
|
215
|
+
"data-testid": "mcp-resource-link",
|
|
216
|
+
children: typeof content === "string" ? content.trim() : ""
|
|
217
|
+
}
|
|
218
|
+
) : isTextMime(mimeType) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
219
|
+
"pre",
|
|
220
|
+
{
|
|
221
|
+
className: "text-xs font-mono text-text-primary bg-neutral-100 rounded p-2 overflow-x-auto whitespace-pre-wrap",
|
|
222
|
+
"data-testid": "mcp-resource-code",
|
|
223
|
+
children: typeof content === "string" ? content : "[Binary data]"
|
|
224
|
+
}
|
|
225
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "text-xs text-text-secondary italic", children: [
|
|
226
|
+
"Unsupported content type: ",
|
|
227
|
+
mimeType
|
|
228
|
+
] }) })
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/mcp/MCPServerStatus/MCPServerStatus.tsx
|
|
235
|
+
var import_react = require("react");
|
|
236
|
+
var import_class_variance_authority2 = require("class-variance-authority");
|
|
237
|
+
var import_tailwind_merge3 = require("tailwind-merge");
|
|
238
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
239
|
+
var statusDot = (0, import_class_variance_authority2.cva)("inline-block h-2 w-2 rounded-full shrink-0", {
|
|
240
|
+
variants: {
|
|
241
|
+
status: {
|
|
242
|
+
connected: "bg-status-success",
|
|
243
|
+
disconnected: "bg-neutral-400",
|
|
244
|
+
error: "bg-status-error"
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
defaultVariants: { status: "disconnected" }
|
|
248
|
+
});
|
|
249
|
+
var statusLabel2 = {
|
|
250
|
+
connected: "Connected",
|
|
251
|
+
disconnected: "Disconnected",
|
|
252
|
+
error: "Error"
|
|
253
|
+
};
|
|
254
|
+
function formatLastPing(date) {
|
|
255
|
+
if (!date) return null;
|
|
256
|
+
return date.toLocaleTimeString();
|
|
257
|
+
}
|
|
258
|
+
function MCPServerStatus({ server, className }) {
|
|
259
|
+
const [showTools, setShowTools] = (0, import_react.useState)(false);
|
|
260
|
+
const [showResources, setShowResources] = (0, import_react.useState)(false);
|
|
261
|
+
const lastPing = formatLastPing(server.lastPing);
|
|
262
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
263
|
+
"div",
|
|
264
|
+
{
|
|
265
|
+
className: (0, import_tailwind_merge3.twMerge)("rounded-lg border border-border bg-surface p-3 text-sm", className),
|
|
266
|
+
"data-testid": "mcp-server-status",
|
|
267
|
+
children: [
|
|
268
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 mb-1", children: [
|
|
269
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
270
|
+
"span",
|
|
271
|
+
{
|
|
272
|
+
className: statusDot({ status: server.status }),
|
|
273
|
+
role: "status",
|
|
274
|
+
"aria-label": statusLabel2[server.status],
|
|
275
|
+
"data-testid": "mcp-server-status-dot"
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "font-medium text-text-primary", "data-testid": "mcp-server-name", children: server.name }),
|
|
279
|
+
server.version && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "text-xs text-text-secondary", "data-testid": "mcp-server-version", children: [
|
|
280
|
+
"v",
|
|
281
|
+
server.version
|
|
282
|
+
] })
|
|
283
|
+
] }),
|
|
284
|
+
lastPing && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "text-xs text-text-secondary ml-4 mb-2", "data-testid": "mcp-server-last-ping", children: [
|
|
285
|
+
"Last ping: ",
|
|
286
|
+
lastPing
|
|
287
|
+
] }),
|
|
288
|
+
server.tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mt-2", children: [
|
|
289
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
290
|
+
"button",
|
|
291
|
+
{
|
|
292
|
+
type: "button",
|
|
293
|
+
className: "flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary w-full",
|
|
294
|
+
onClick: () => setShowTools((prev) => !prev),
|
|
295
|
+
"aria-expanded": showTools,
|
|
296
|
+
"data-testid": "mcp-server-tools-toggle",
|
|
297
|
+
children: [
|
|
298
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
299
|
+
"svg",
|
|
300
|
+
{
|
|
301
|
+
className: `h-3 w-3 transition-transform ${showTools ? "rotate-90" : ""}`,
|
|
302
|
+
viewBox: "0 0 20 20",
|
|
303
|
+
fill: "currentColor",
|
|
304
|
+
"aria-hidden": "true",
|
|
305
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
306
|
+
"path",
|
|
307
|
+
{
|
|
308
|
+
fillRule: "evenodd",
|
|
309
|
+
d: "M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z",
|
|
310
|
+
clipRule: "evenodd"
|
|
311
|
+
}
|
|
312
|
+
)
|
|
313
|
+
}
|
|
314
|
+
),
|
|
315
|
+
"Tools (",
|
|
316
|
+
server.tools.length,
|
|
317
|
+
")"
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
),
|
|
321
|
+
showTools && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mt-1 ml-4 space-y-1", "data-testid": "mcp-server-tools-list", children: server.tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "text-xs text-text-primary", children: [
|
|
322
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "font-mono", children: tool.name }),
|
|
323
|
+
tool.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "text-text-secondary ml-1", children: [
|
|
324
|
+
"\u2014 ",
|
|
325
|
+
tool.description
|
|
326
|
+
] })
|
|
327
|
+
] }, tool.name)) })
|
|
328
|
+
] }),
|
|
329
|
+
server.resources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "mt-2", children: [
|
|
330
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
331
|
+
"button",
|
|
332
|
+
{
|
|
333
|
+
type: "button",
|
|
334
|
+
className: "flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary w-full",
|
|
335
|
+
onClick: () => setShowResources((prev) => !prev),
|
|
336
|
+
"aria-expanded": showResources,
|
|
337
|
+
"data-testid": "mcp-server-resources-toggle",
|
|
338
|
+
children: [
|
|
339
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
340
|
+
"svg",
|
|
341
|
+
{
|
|
342
|
+
className: `h-3 w-3 transition-transform ${showResources ? "rotate-90" : ""}`,
|
|
343
|
+
viewBox: "0 0 20 20",
|
|
344
|
+
fill: "currentColor",
|
|
345
|
+
"aria-hidden": "true",
|
|
346
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
347
|
+
"path",
|
|
348
|
+
{
|
|
349
|
+
fillRule: "evenodd",
|
|
350
|
+
d: "M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z",
|
|
351
|
+
clipRule: "evenodd"
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
}
|
|
355
|
+
),
|
|
356
|
+
"Resources (",
|
|
357
|
+
server.resources.length,
|
|
358
|
+
")"
|
|
359
|
+
]
|
|
360
|
+
}
|
|
361
|
+
),
|
|
362
|
+
showResources && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "mt-1 ml-4 space-y-1", "data-testid": "mcp-server-resources-list", children: server.resources.map((res) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { className: "text-xs text-text-primary", children: [
|
|
363
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "font-mono", children: res.name }),
|
|
364
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "text-text-secondary ml-1", children: [
|
|
365
|
+
"(",
|
|
366
|
+
res.uri,
|
|
367
|
+
")"
|
|
368
|
+
] })
|
|
369
|
+
] }, res.uri)) })
|
|
370
|
+
] })
|
|
371
|
+
]
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/mcp/MCPApprovalDialog/MCPApprovalDialog.tsx
|
|
377
|
+
var import_react2 = require("react");
|
|
378
|
+
var import_class_variance_authority3 = require("class-variance-authority");
|
|
379
|
+
var import_tailwind_merge4 = require("tailwind-merge");
|
|
380
|
+
var import_react_aria = require("react-aria");
|
|
381
|
+
var import_core2 = require("@surf-kit/core");
|
|
382
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
383
|
+
var riskBadgeIntent = {
|
|
384
|
+
low: "success",
|
|
385
|
+
medium: "warning",
|
|
386
|
+
high: "error"
|
|
387
|
+
};
|
|
388
|
+
var riskLabel = {
|
|
389
|
+
low: "Low Risk",
|
|
390
|
+
medium: "Medium Risk",
|
|
391
|
+
high: "High Risk"
|
|
392
|
+
};
|
|
393
|
+
var riskBorder = (0, import_class_variance_authority3.cva)("relative bg-surface rounded-xl shadow-xl border p-6 outline-none w-full max-w-lg", {
|
|
394
|
+
variants: {
|
|
395
|
+
risk: {
|
|
396
|
+
low: "border-status-success-subtle",
|
|
397
|
+
medium: "border-status-warning-subtle",
|
|
398
|
+
high: "border-status-error-subtle"
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
defaultVariants: { risk: "low" }
|
|
402
|
+
});
|
|
403
|
+
function formatValue2(value) {
|
|
404
|
+
if (typeof value === "string") return value;
|
|
405
|
+
return JSON.stringify(value, null, 2);
|
|
406
|
+
}
|
|
407
|
+
function MCPApprovalDialog({
|
|
408
|
+
call,
|
|
409
|
+
riskLevel = "low",
|
|
410
|
+
onApprove,
|
|
411
|
+
onDeny,
|
|
412
|
+
isOpen,
|
|
413
|
+
className
|
|
414
|
+
}) {
|
|
415
|
+
const ref = (0, import_react2.useRef)(null);
|
|
416
|
+
const { dialogProps, titleProps } = (0, import_react_aria.useDialog)({ role: "alertdialog" }, ref);
|
|
417
|
+
(0, import_react2.useEffect)(() => {
|
|
418
|
+
if (!isOpen) return;
|
|
419
|
+
const handleKeyDown = (e) => {
|
|
420
|
+
if (e.key === "Escape") {
|
|
421
|
+
e.preventDefault();
|
|
422
|
+
e.stopPropagation();
|
|
423
|
+
}
|
|
424
|
+
};
|
|
425
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
426
|
+
return () => document.removeEventListener("keydown", handleKeyDown, true);
|
|
427
|
+
}, [isOpen]);
|
|
428
|
+
if (!isOpen) return null;
|
|
429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
430
|
+
"div",
|
|
431
|
+
{
|
|
432
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50",
|
|
433
|
+
"data-testid": "mcp-approval-overlay",
|
|
434
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_aria.FocusScope, { contain: true, restoreFocus: true, autoFocus: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
435
|
+
"div",
|
|
436
|
+
{
|
|
437
|
+
...dialogProps,
|
|
438
|
+
ref,
|
|
439
|
+
className: (0, import_tailwind_merge4.twMerge)(riskBorder({ risk: riskLevel }), className),
|
|
440
|
+
"data-testid": "mcp-approval-dialog",
|
|
441
|
+
children: [
|
|
442
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
444
|
+
"h2",
|
|
445
|
+
{
|
|
446
|
+
...titleProps,
|
|
447
|
+
className: "text-lg font-semibold text-text-primary",
|
|
448
|
+
"data-testid": "mcp-approval-title",
|
|
449
|
+
children: "Tool Approval Required"
|
|
450
|
+
}
|
|
451
|
+
),
|
|
452
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
453
|
+
import_core2.Badge,
|
|
454
|
+
{
|
|
455
|
+
intent: riskBadgeIntent[riskLevel],
|
|
456
|
+
size: "sm",
|
|
457
|
+
"data-testid": "mcp-approval-risk-badge",
|
|
458
|
+
children: riskLabel[riskLevel]
|
|
459
|
+
}
|
|
460
|
+
)
|
|
461
|
+
] }),
|
|
462
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "space-y-3 text-sm", children: [
|
|
463
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
464
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "text-xs font-medium text-text-secondary mb-1", children: "Tool" }),
|
|
465
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "font-mono text-text-primary", "data-testid": "mcp-approval-tool-name", children: call.name }),
|
|
466
|
+
call.serverName && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-xs text-text-secondary mt-0.5", "data-testid": "mcp-approval-server", children: [
|
|
467
|
+
"Server: ",
|
|
468
|
+
call.serverName
|
|
469
|
+
] })
|
|
470
|
+
] }),
|
|
471
|
+
Object.keys(call.arguments).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
472
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "text-xs font-medium text-text-secondary mb-1", children: "Arguments" }),
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
474
|
+
"dl",
|
|
475
|
+
{
|
|
476
|
+
className: "space-y-1 bg-neutral-100 rounded p-2",
|
|
477
|
+
"data-testid": "mcp-approval-arguments",
|
|
478
|
+
children: Object.entries(call.arguments).map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex gap-2", children: [
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("dt", { className: "text-xs font-mono text-text-secondary shrink-0", children: [
|
|
480
|
+
key,
|
|
481
|
+
":"
|
|
482
|
+
] }),
|
|
483
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("dd", { className: "text-xs font-mono text-text-primary break-all", children: formatValue2(value) })
|
|
484
|
+
] }, key))
|
|
485
|
+
}
|
|
486
|
+
)
|
|
487
|
+
] })
|
|
488
|
+
] }),
|
|
489
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mt-6 flex justify-end gap-3", children: [
|
|
490
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
491
|
+
import_core2.Button,
|
|
492
|
+
{
|
|
493
|
+
intent: "secondary",
|
|
494
|
+
onPress: onDeny,
|
|
495
|
+
"aria-label": "Deny tool execution",
|
|
496
|
+
children: "Deny"
|
|
497
|
+
}
|
|
498
|
+
),
|
|
499
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
500
|
+
import_core2.Button,
|
|
501
|
+
{
|
|
502
|
+
intent: "primary",
|
|
503
|
+
onPress: onApprove,
|
|
504
|
+
"aria-label": "Approve tool execution",
|
|
505
|
+
children: "Approve"
|
|
506
|
+
}
|
|
507
|
+
)
|
|
508
|
+
] })
|
|
509
|
+
]
|
|
510
|
+
}
|
|
511
|
+
) })
|
|
512
|
+
}
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
516
|
+
0 && (module.exports = {
|
|
517
|
+
MCPApprovalDialog,
|
|
518
|
+
MCPResourceView,
|
|
519
|
+
MCPServerStatus,
|
|
520
|
+
MCPToolCall
|
|
521
|
+
});
|
|
522
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/index.ts","../../src/mcp/MCPToolCall/MCPToolCall.tsx","../../src/mcp/MCPResourceView/MCPResourceView.tsx","../../src/mcp/MCPServerStatus/MCPServerStatus.tsx","../../src/mcp/MCPApprovalDialog/MCPApprovalDialog.tsx"],"sourcesContent":["export { MCPToolCall } from './MCPToolCall'\nexport type { MCPToolCallProps } from './MCPToolCall'\n\nexport { MCPResourceView } from './MCPResourceView'\nexport type { MCPResourceViewProps } from './MCPResourceView'\n\nexport { MCPServerStatus } from './MCPServerStatus'\nexport type { MCPServerStatusProps } from './MCPServerStatus'\n\nexport { MCPApprovalDialog } from './MCPApprovalDialog'\nexport type { MCPApprovalDialogProps } from './MCPApprovalDialog'\n","import React from 'react'\nimport { cva } from 'class-variance-authority'\nimport { twMerge } from 'tailwind-merge'\nimport { Badge, Spinner } from '@surf-kit/core'\nimport type { MCPToolCallData, MCPToolStatus } from '../../types/mcp'\n\nexport type MCPToolCallProps = {\n call: MCPToolCallData\n isExpanded?: boolean\n onToggleExpand?: () => void\n className?: string\n}\n\nconst statusBadgeIntent: Record<MCPToolStatus, 'default' | 'info' | 'success' | 'error'> = {\n pending: 'default',\n running: 'info',\n success: 'success',\n error: 'error',\n}\n\nconst statusLabel: Record<MCPToolStatus, string> = {\n pending: 'Pending',\n running: 'Running',\n success: 'Success',\n error: 'Error',\n}\n\nconst container = cva(\n 'rounded-lg border text-sm',\n {\n variants: {\n status: {\n pending: 'border-neutral-200 bg-neutral-50',\n running: 'border-sky-200 bg-sky-50',\n success: 'border-status-success-subtle bg-status-success-subtle/30',\n error: 'border-status-error-subtle bg-status-error-subtle/30',\n },\n },\n defaultVariants: { status: 'pending' },\n },\n)\n\nfunction formatDuration(start?: Date, end?: Date): string | null {\n if (!start || !end) return null\n const ms = end.getTime() - start.getTime()\n if (ms < 1000) return `${ms}ms`\n return `${(ms / 1000).toFixed(1)}s`\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value\n return JSON.stringify(value, null, 2)\n}\n\nfunction MCPToolCall({ call, isExpanded = false, onToggleExpand, className }: MCPToolCallProps) {\n const duration = formatDuration(call.startedAt, call.completedAt)\n\n return (\n <div\n className={twMerge(container({ status: call.status }), className)}\n data-testid=\"mcp-tool-call\"\n >\n {/* Header */}\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-2 px-3 py-2\"\n onClick={onToggleExpand}\n aria-expanded={isExpanded}\n data-testid=\"mcp-tool-call-header\"\n >\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"font-medium text-text-primary truncate\" data-testid=\"mcp-tool-name\">\n {call.name}\n </span>\n {call.serverName && (\n <span className=\"text-xs text-text-secondary truncate\">\n {call.serverName}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2 shrink-0\">\n {call.status === 'running' && (\n <span aria-hidden=\"true\">\n <Spinner size=\"sm\" />\n </span>\n )}\n <Badge\n intent={statusBadgeIntent[call.status]}\n size=\"sm\"\n role=\"status\"\n aria-label={`Status: ${statusLabel[call.status]}`}\n data-testid=\"mcp-tool-status\"\n >\n {statusLabel[call.status]}\n </Badge>\n {duration && (\n <span className=\"text-xs text-text-secondary\" data-testid=\"mcp-tool-duration\">\n {duration}\n </span>\n )}\n <svg\n className={`h-4 w-4 text-text-secondary transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </div>\n </button>\n\n {/* Expandable body */}\n {isExpanded && (\n <div className=\"border-t border-inherit px-3 py-2 space-y-3\" data-testid=\"mcp-tool-call-body\">\n {/* Arguments */}\n {Object.keys(call.arguments).length > 0 && (\n <div>\n <h4 className=\"text-xs font-medium text-text-secondary mb-1\">Arguments</h4>\n <dl className=\"space-y-1\" data-testid=\"mcp-tool-arguments\">\n {Object.entries(call.arguments).map(([key, value]) => (\n <div key={key} className=\"flex gap-2\">\n <dt className=\"text-xs font-mono text-text-secondary shrink-0\">{key}:</dt>\n <dd className=\"text-xs font-mono text-text-primary break-all\">\n {formatValue(value)}\n </dd>\n </div>\n ))}\n </dl>\n </div>\n )}\n\n {/* Result */}\n {call.result !== undefined && (\n <div>\n <h4 className=\"text-xs font-medium text-text-secondary mb-1\">Result</h4>\n <pre\n className=\"text-xs font-mono text-text-primary bg-neutral-100 rounded p-2 overflow-x-auto whitespace-pre-wrap\"\n data-testid=\"mcp-tool-result\"\n >\n {typeof call.result === 'string' ? call.result : JSON.stringify(call.result, null, 2)}\n </pre>\n </div>\n )}\n\n {/* Error */}\n {call.error && (\n <div>\n <h4 className=\"text-xs font-medium text-status-error mb-1\">Error</h4>\n <p\n className=\"text-xs text-status-error bg-status-error-subtle/30 rounded p-2\"\n data-testid=\"mcp-tool-error\"\n >\n {call.error}\n </p>\n </div>\n )}\n </div>\n )}\n </div>\n )\n}\n\nexport { MCPToolCall }\n","import React from 'react'\nimport { twMerge } from 'tailwind-merge'\nimport type { MCPResource } from '../../types/mcp'\n\nexport type MCPResourceViewProps = {\n resource: MCPResource\n className?: string\n}\n\nfunction isImageMime(mime?: string): boolean {\n return !!mime && mime.startsWith('image/')\n}\n\nfunction isTextMime(mime?: string): boolean {\n if (!mime) return true\n return (\n mime.startsWith('text/') ||\n mime === 'application/json' ||\n mime === 'application/xml' ||\n mime === 'application/javascript' ||\n mime === 'application/typescript'\n )\n}\n\nfunction isUrlContent(content?: string | Uint8Array): boolean {\n if (typeof content !== 'string') return false\n return /^https?:\\/\\//.test(content.trim())\n}\n\nfunction MCPResourceView({ resource, className }: MCPResourceViewProps) {\n const { uri, name, mimeType, description, content } = resource\n\n return (\n <div\n className={twMerge('rounded-lg border border-border bg-surface p-3 text-sm', className)}\n data-testid=\"mcp-resource-view\"\n >\n {/* Header */}\n <div className=\"mb-2\">\n <span className=\"font-medium text-text-primary\" data-testid=\"mcp-resource-name\">\n {name}\n </span>\n <span\n className=\"ml-2 text-xs text-text-secondary font-mono truncate\"\n data-testid=\"mcp-resource-uri\"\n >\n {uri}\n </span>\n </div>\n\n {description && (\n <p className=\"text-xs text-text-secondary mb-2\" data-testid=\"mcp-resource-description\">\n {description}\n </p>\n )}\n\n {/* Content rendering */}\n {content !== undefined && (\n <div data-testid=\"mcp-resource-content\">\n {isImageMime(mimeType) && typeof content === 'string' ? (\n <img\n src={content}\n alt={name}\n className=\"max-w-full rounded\"\n data-testid=\"mcp-resource-image\"\n />\n ) : isUrlContent(content) ? (\n <a\n href={typeof content === 'string' ? content.trim() : undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm text-interactive-primary hover:underline break-all\"\n data-testid=\"mcp-resource-link\"\n >\n {typeof content === 'string' ? content.trim() : ''}\n </a>\n ) : isTextMime(mimeType) ? (\n <pre\n className=\"text-xs font-mono text-text-primary bg-neutral-100 rounded p-2 overflow-x-auto whitespace-pre-wrap\"\n data-testid=\"mcp-resource-code\"\n >\n {typeof content === 'string' ? content : '[Binary data]'}\n </pre>\n ) : (\n <p className=\"text-xs text-text-secondary italic\">\n Unsupported content type: {mimeType}\n </p>\n )}\n </div>\n )}\n </div>\n )\n}\n\nexport { MCPResourceView }\n","import React, { useState } from 'react'\nimport { cva } from 'class-variance-authority'\nimport { twMerge } from 'tailwind-merge'\nimport type { MCPServerInfo } from '../../types/mcp'\n\nexport type MCPServerStatusProps = {\n server: MCPServerInfo\n className?: string\n}\n\nconst statusDot = cva('inline-block h-2 w-2 rounded-full shrink-0', {\n variants: {\n status: {\n connected: 'bg-status-success',\n disconnected: 'bg-neutral-400',\n error: 'bg-status-error',\n },\n },\n defaultVariants: { status: 'disconnected' },\n})\n\nconst statusLabel: Record<MCPServerInfo['status'], string> = {\n connected: 'Connected',\n disconnected: 'Disconnected',\n error: 'Error',\n}\n\nfunction formatLastPing(date?: Date): string | null {\n if (!date) return null\n return date.toLocaleTimeString()\n}\n\nfunction MCPServerStatus({ server, className }: MCPServerStatusProps) {\n const [showTools, setShowTools] = useState(false)\n const [showResources, setShowResources] = useState(false)\n const lastPing = formatLastPing(server.lastPing)\n\n return (\n <div\n className={twMerge('rounded-lg border border-border bg-surface p-3 text-sm', className)}\n data-testid=\"mcp-server-status\"\n >\n {/* Header */}\n <div className=\"flex items-center gap-2 mb-1\">\n <span\n className={statusDot({ status: server.status })}\n role=\"status\"\n aria-label={statusLabel[server.status]}\n data-testid=\"mcp-server-status-dot\"\n />\n <span className=\"font-medium text-text-primary\" data-testid=\"mcp-server-name\">\n {server.name}\n </span>\n {server.version && (\n <span className=\"text-xs text-text-secondary\" data-testid=\"mcp-server-version\">\n v{server.version}\n </span>\n )}\n </div>\n\n {lastPing && (\n <p className=\"text-xs text-text-secondary ml-4 mb-2\" data-testid=\"mcp-server-last-ping\">\n Last ping: {lastPing}\n </p>\n )}\n\n {/* Tools list */}\n {server.tools.length > 0 && (\n <div className=\"mt-2\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary w-full\"\n onClick={() => setShowTools((prev) => !prev)}\n aria-expanded={showTools}\n data-testid=\"mcp-server-tools-toggle\"\n >\n <svg\n className={`h-3 w-3 transition-transform ${showTools ? 'rotate-90' : ''}`}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clipRule=\"evenodd\"\n />\n </svg>\n Tools ({server.tools.length})\n </button>\n {showTools && (\n <ul className=\"mt-1 ml-4 space-y-1\" data-testid=\"mcp-server-tools-list\">\n {server.tools.map((tool) => (\n <li key={tool.name} className=\"text-xs text-text-primary\">\n <span className=\"font-mono\">{tool.name}</span>\n {tool.description && (\n <span className=\"text-text-secondary ml-1\">— {tool.description}</span>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n\n {/* Resources list */}\n {server.resources.length > 0 && (\n <div className=\"mt-2\">\n <button\n type=\"button\"\n className=\"flex items-center gap-1 text-xs font-medium text-text-secondary hover:text-text-primary w-full\"\n onClick={() => setShowResources((prev) => !prev)}\n aria-expanded={showResources}\n data-testid=\"mcp-server-resources-toggle\"\n >\n <svg\n className={`h-3 w-3 transition-transform ${showResources ? 'rotate-90' : ''}`}\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z\"\n clipRule=\"evenodd\"\n />\n </svg>\n Resources ({server.resources.length})\n </button>\n {showResources && (\n <ul className=\"mt-1 ml-4 space-y-1\" data-testid=\"mcp-server-resources-list\">\n {server.resources.map((res) => (\n <li key={res.uri} className=\"text-xs text-text-primary\">\n <span className=\"font-mono\">{res.name}</span>\n <span className=\"text-text-secondary ml-1\">({res.uri})</span>\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n </div>\n )\n}\n\nexport { MCPServerStatus }\n","import React, { useRef, useEffect } from 'react'\nimport { cva } from 'class-variance-authority'\nimport { twMerge } from 'tailwind-merge'\nimport { useDialog, FocusScope } from 'react-aria'\nimport { Button, Badge } from '@surf-kit/core'\nimport type { MCPToolCallData } from '../../types/mcp'\n\nexport type MCPApprovalDialogProps = {\n call: MCPToolCallData\n riskLevel?: 'low' | 'medium' | 'high'\n onApprove: () => void\n onDeny: () => void\n isOpen: boolean\n className?: string\n}\n\nconst riskBadgeIntent: Record<string, 'success' | 'warning' | 'error'> = {\n low: 'success',\n medium: 'warning',\n high: 'error',\n}\n\nconst riskLabel: Record<string, string> = {\n low: 'Low Risk',\n medium: 'Medium Risk',\n high: 'High Risk',\n}\n\nconst riskBorder = cva('relative bg-surface rounded-xl shadow-xl border p-6 outline-none w-full max-w-lg', {\n variants: {\n risk: {\n low: 'border-status-success-subtle',\n medium: 'border-status-warning-subtle',\n high: 'border-status-error-subtle',\n },\n },\n defaultVariants: { risk: 'low' },\n})\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value\n return JSON.stringify(value, null, 2)\n}\n\nfunction MCPApprovalDialog({\n call,\n riskLevel = 'low',\n onApprove,\n onDeny,\n isOpen,\n className,\n}: MCPApprovalDialogProps) {\n const ref = useRef<HTMLDivElement>(null)\n const { dialogProps, titleProps } = useDialog({ role: 'alertdialog' }, ref)\n\n // Block Escape key — user must explicitly approve or deny\n useEffect(() => {\n if (!isOpen) return\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault()\n e.stopPropagation()\n }\n }\n document.addEventListener('keydown', handleKeyDown, true)\n return () => document.removeEventListener('keydown', handleKeyDown, true)\n }, [isOpen])\n\n if (!isOpen) return null\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\"\n data-testid=\"mcp-approval-overlay\"\n >\n <FocusScope contain restoreFocus autoFocus>\n <div\n {...dialogProps}\n ref={ref}\n className={twMerge(riskBorder({ risk: riskLevel }), className)}\n data-testid=\"mcp-approval-dialog\"\n >\n {/* Title */}\n <div className=\"flex items-center justify-between mb-4\">\n <h2\n {...titleProps}\n className=\"text-lg font-semibold text-text-primary\"\n data-testid=\"mcp-approval-title\"\n >\n Tool Approval Required\n </h2>\n <Badge\n intent={riskBadgeIntent[riskLevel]}\n size=\"sm\"\n data-testid=\"mcp-approval-risk-badge\"\n >\n {riskLabel[riskLevel]}\n </Badge>\n </div>\n\n {/* Tool info */}\n <div className=\"space-y-3 text-sm\">\n <div>\n <h3 className=\"text-xs font-medium text-text-secondary mb-1\">Tool</h3>\n <p className=\"font-mono text-text-primary\" data-testid=\"mcp-approval-tool-name\">\n {call.name}\n </p>\n {call.serverName && (\n <p className=\"text-xs text-text-secondary mt-0.5\" data-testid=\"mcp-approval-server\">\n Server: {call.serverName}\n </p>\n )}\n </div>\n\n {/* Arguments */}\n {Object.keys(call.arguments).length > 0 && (\n <div>\n <h3 className=\"text-xs font-medium text-text-secondary mb-1\">Arguments</h3>\n <dl\n className=\"space-y-1 bg-neutral-100 rounded p-2\"\n data-testid=\"mcp-approval-arguments\"\n >\n {Object.entries(call.arguments).map(([key, value]) => (\n <div key={key} className=\"flex gap-2\">\n <dt className=\"text-xs font-mono text-text-secondary shrink-0\">{key}:</dt>\n <dd className=\"text-xs font-mono text-text-primary break-all\">\n {formatValue(value)}\n </dd>\n </div>\n ))}\n </dl>\n </div>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"mt-6 flex justify-end gap-3\">\n <Button\n intent=\"secondary\"\n onPress={onDeny}\n aria-label=\"Deny tool execution\"\n >\n Deny\n </Button>\n <Button\n intent=\"primary\"\n onPress={onApprove}\n aria-label=\"Approve tool execution\"\n >\n Approve\n </Button>\n </div>\n </div>\n </FocusScope>\n </div>\n )\n}\n\nexport { MCPApprovalDialog }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,sCAAoB;AACpB,4BAAwB;AACxB,kBAA+B;AAmEvB;AAzDR,IAAM,oBAAqF;AAAA,EACzF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAEA,IAAM,cAA6C;AAAA,EACjD,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACT;AAEA,IAAM,gBAAY;AAAA,EAChB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,QAAQ;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,iBAAiB,EAAE,QAAQ,UAAU;AAAA,EACvC;AACF;AAEA,SAAS,eAAe,OAAc,KAA2B;AAC/D,MAAI,CAAC,SAAS,CAAC,IAAK,QAAO;AAC3B,QAAM,KAAK,IAAI,QAAQ,IAAI,MAAM,QAAQ;AACzC,MAAI,KAAK,IAAM,QAAO,GAAG,EAAE;AAC3B,SAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AAClC;AAEA,SAAS,YAAY,OAAwB;AAC3C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AACtC;AAEA,SAAS,YAAY,EAAE,MAAM,aAAa,OAAO,gBAAgB,UAAU,GAAqB;AAC9F,QAAM,WAAW,eAAe,KAAK,WAAW,KAAK,WAAW;AAEhE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW,+BAAQ,UAAU,EAAE,QAAQ,KAAK,OAAO,CAAC,GAAG,SAAS;AAAA,MAChE,eAAY;AAAA,MAGZ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAS;AAAA,YACT,iBAAe;AAAA,YACf,eAAY;AAAA,YAEZ;AAAA,2DAAC,SAAI,WAAU,mCACb;AAAA,4DAAC,UAAK,WAAU,0CAAyC,eAAY,iBAClE,eAAK,MACR;AAAA,gBACC,KAAK,cACJ,4CAAC,UAAK,WAAU,wCACb,eAAK,YACR;AAAA,iBAEJ;AAAA,cACA,6CAAC,SAAI,WAAU,oCACZ;AAAA,qBAAK,WAAW,aACf,4CAAC,UAAK,eAAY,QAChB,sDAAC,uBAAQ,MAAK,MAAK,GACrB;AAAA,gBAEF;AAAA,kBAAC;AAAA;AAAA,oBACC,QAAQ,kBAAkB,KAAK,MAAM;AAAA,oBACrC,MAAK;AAAA,oBACL,MAAK;AAAA,oBACL,cAAY,WAAW,YAAY,KAAK,MAAM,CAAC;AAAA,oBAC/C,eAAY;AAAA,oBAEX,sBAAY,KAAK,MAAM;AAAA;AAAA,gBAC1B;AAAA,gBACC,YACC,4CAAC,UAAK,WAAU,+BAA8B,eAAY,qBACvD,oBACH;AAAA,gBAEF;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,oDAAoD,aAAa,eAAe,EAAE;AAAA,oBAC7F,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,eAAY;AAAA,oBAEZ;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAS;AAAA,wBACT,GAAE;AAAA,wBACF,UAAS;AAAA;AAAA,oBACX;AAAA;AAAA,gBACF;AAAA,iBACF;AAAA;AAAA;AAAA,QACF;AAAA,QAGC,cACC,6CAAC,SAAI,WAAU,+CAA8C,eAAY,sBAEtE;AAAA,iBAAO,KAAK,KAAK,SAAS,EAAE,SAAS,KACpC,6CAAC,SACC;AAAA,wDAAC,QAAG,WAAU,gDAA+C,uBAAS;AAAA,YACtE,4CAAC,QAAG,WAAU,aAAY,eAAY,sBACnC,iBAAO,QAAQ,KAAK,SAAS,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAC9C,6CAAC,SAAc,WAAU,cACvB;AAAA,2DAAC,QAAG,WAAU,kDAAkD;AAAA;AAAA,gBAAI;AAAA,iBAAC;AAAA,cACrE,4CAAC,QAAG,WAAU,iDACX,sBAAY,KAAK,GACpB;AAAA,iBAJQ,GAKV,CACD,GACH;AAAA,aACF;AAAA,UAID,KAAK,WAAW,UACf,6CAAC,SACC;AAAA,wDAAC,QAAG,WAAU,gDAA+C,oBAAM;AAAA,YACnE;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,eAAY;AAAA,gBAEX,iBAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,UAAU,KAAK,QAAQ,MAAM,CAAC;AAAA;AAAA,YACtF;AAAA,aACF;AAAA,UAID,KAAK,SACJ,6CAAC,SACC;AAAA,wDAAC,QAAG,WAAU,8CAA6C,mBAAK;AAAA,YAChE;AAAA,cAAC;AAAA;AAAA,gBACC,WAAU;AAAA,gBACV,eAAY;AAAA,gBAEX,eAAK;AAAA;AAAA,YACR;AAAA,aACF;AAAA,WAEJ;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;ACnKA,IAAAA,yBAAwB;AAqClB,IAAAC,sBAAA;AA7BN,SAAS,YAAY,MAAwB;AAC3C,SAAO,CAAC,CAAC,QAAQ,KAAK,WAAW,QAAQ;AAC3C;AAEA,SAAS,WAAW,MAAwB;AAC1C,MAAI,CAAC,KAAM,QAAO;AAClB,SACE,KAAK,WAAW,OAAO,KACvB,SAAS,sBACT,SAAS,qBACT,SAAS,4BACT,SAAS;AAEb;AAEA,SAAS,aAAa,SAAwC;AAC5D,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,SAAO,eAAe,KAAK,QAAQ,KAAK,CAAC;AAC3C;AAEA,SAAS,gBAAgB,EAAE,UAAU,UAAU,GAAyB;AACtE,QAAM,EAAE,KAAK,MAAM,UAAU,aAAa,QAAQ,IAAI;AAEtD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW,gCAAQ,0DAA0D,SAAS;AAAA,MACtF,eAAY;AAAA,MAGZ;AAAA,sDAAC,SAAI,WAAU,QACb;AAAA,uDAAC,UAAK,WAAU,iCAAgC,eAAY,qBACzD,gBACH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,eAAY;AAAA,cAEX;AAAA;AAAA,UACH;AAAA,WACF;AAAA,QAEC,eACC,6CAAC,OAAE,WAAU,oCAAmC,eAAY,4BACzD,uBACH;AAAA,QAID,YAAY,UACX,6CAAC,SAAI,eAAY,wBACd,sBAAY,QAAQ,KAAK,OAAO,YAAY,WAC3C;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAY;AAAA;AAAA,QACd,IACE,aAAa,OAAO,IACtB;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,OAAO,YAAY,WAAW,QAAQ,KAAK,IAAI;AAAA,YACrD,QAAO;AAAA,YACP,KAAI;AAAA,YACJ,WAAU;AAAA,YACV,eAAY;AAAA,YAEX,iBAAO,YAAY,WAAW,QAAQ,KAAK,IAAI;AAAA;AAAA,QAClD,IACE,WAAW,QAAQ,IACrB;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,eAAY;AAAA,YAEX,iBAAO,YAAY,WAAW,UAAU;AAAA;AAAA,QAC3C,IAEA,8CAAC,OAAE,WAAU,sCAAqC;AAAA;AAAA,UACrB;AAAA,WAC7B,GAEJ;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AC5FA,mBAAgC;AAChC,IAAAC,mCAAoB;AACpB,IAAAC,yBAAwB;AA0ChB,IAAAC,sBAAA;AAlCR,IAAM,gBAAY,sCAAI,8CAA8C;AAAA,EAClE,UAAU;AAAA,IACR,QAAQ;AAAA,MACN,WAAW;AAAA,MACX,cAAc;AAAA,MACd,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,QAAQ,eAAe;AAC5C,CAAC;AAED,IAAMC,eAAuD;AAAA,EAC3D,WAAW;AAAA,EACX,cAAc;AAAA,EACd,OAAO;AACT;AAEA,SAAS,eAAe,MAA4B;AAClD,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,KAAK,mBAAmB;AACjC;AAEA,SAAS,gBAAgB,EAAE,QAAQ,UAAU,GAAyB;AACpE,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AACxD,QAAM,WAAW,eAAe,OAAO,QAAQ;AAE/C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW,gCAAQ,0DAA0D,SAAS;AAAA,MACtF,eAAY;AAAA,MAGZ;AAAA,sDAAC,SAAI,WAAU,gCACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,UAAU,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,cAC9C,MAAK;AAAA,cACL,cAAYA,aAAY,OAAO,MAAM;AAAA,cACrC,eAAY;AAAA;AAAA,UACd;AAAA,UACA,6CAAC,UAAK,WAAU,iCAAgC,eAAY,mBACzD,iBAAO,MACV;AAAA,UACC,OAAO,WACN,8CAAC,UAAK,WAAU,+BAA8B,eAAY,sBAAqB;AAAA;AAAA,YAC3E,OAAO;AAAA,aACX;AAAA,WAEJ;AAAA,QAEC,YACC,8CAAC,OAAE,WAAU,yCAAwC,eAAY,wBAAuB;AAAA;AAAA,UAC1E;AAAA,WACd;AAAA,QAID,OAAO,MAAM,SAAS,KACrB,8CAAC,SAAI,WAAU,QACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM,aAAa,CAAC,SAAS,CAAC,IAAI;AAAA,cAC3C,iBAAe;AAAA,cACf,eAAY;AAAA,cAEZ;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,gCAAgC,YAAY,cAAc,EAAE;AAAA,oBACvE,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,eAAY;AAAA,oBAEZ;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAS;AAAA,wBACT,GAAE;AAAA,wBACF,UAAS;AAAA;AAAA,oBACX;AAAA;AAAA,gBACF;AAAA,gBAAM;AAAA,gBACE,OAAO,MAAM;AAAA,gBAAO;AAAA;AAAA;AAAA,UAC9B;AAAA,UACC,aACC,6CAAC,QAAG,WAAU,uBAAsB,eAAY,yBAC7C,iBAAO,MAAM,IAAI,CAAC,SACjB,8CAAC,QAAmB,WAAU,6BAC5B;AAAA,yDAAC,UAAK,WAAU,aAAa,eAAK,MAAK;AAAA,YACtC,KAAK,eACJ,8CAAC,UAAK,WAAU,4BAA2B;AAAA;AAAA,cAAG,KAAK;AAAA,eAAY;AAAA,eAH1D,KAAK,IAKd,CACD,GACH;AAAA,WAEJ;AAAA,QAID,OAAO,UAAU,SAAS,KACzB,8CAAC,SAAI,WAAU,QACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM,iBAAiB,CAAC,SAAS,CAAC,IAAI;AAAA,cAC/C,iBAAe;AAAA,cACf,eAAY;AAAA,cAEZ;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,gCAAgC,gBAAgB,cAAc,EAAE;AAAA,oBAC3E,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,eAAY;AAAA,oBAEZ;AAAA,sBAAC;AAAA;AAAA,wBACC,UAAS;AAAA,wBACT,GAAE;AAAA,wBACF,UAAS;AAAA;AAAA,oBACX;AAAA;AAAA,gBACF;AAAA,gBAAM;AAAA,gBACM,OAAO,UAAU;AAAA,gBAAO;AAAA;AAAA;AAAA,UACtC;AAAA,UACC,iBACC,6CAAC,QAAG,WAAU,uBAAsB,eAAY,6BAC7C,iBAAO,UAAU,IAAI,CAAC,QACrB,8CAAC,QAAiB,WAAU,6BAC1B;AAAA,yDAAC,UAAK,WAAU,aAAa,cAAI,MAAK;AAAA,YACtC,8CAAC,UAAK,WAAU,4BAA2B;AAAA;AAAA,cAAE,IAAI;AAAA,cAAI;AAAA,eAAC;AAAA,eAF/C,IAAI,GAGb,CACD,GACH;AAAA,WAEJ;AAAA;AAAA;AAAA,EAEJ;AAEJ;;;AC/IA,IAAAC,gBAAyC;AACzC,IAAAC,mCAAoB;AACpB,IAAAC,yBAAwB;AACxB,wBAAsC;AACtC,IAAAC,eAA8B;AA+EpB,IAAAC,sBAAA;AAnEV,IAAM,kBAAmE;AAAA,EACvE,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AACR;AAEA,IAAM,YAAoC;AAAA,EACxC,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AACR;AAEA,IAAM,iBAAa,sCAAI,oFAAoF;AAAA,EACzG,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,iBAAiB,EAAE,MAAM,MAAM;AACjC,CAAC;AAED,SAASC,aAAY,OAAwB;AAC3C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AACtC;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA2B;AACzB,QAAM,UAAM,sBAAuB,IAAI;AACvC,QAAM,EAAE,aAAa,WAAW,QAAI,6BAAU,EAAE,MAAM,cAAc,GAAG,GAAG;AAG1E,+BAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,UAAM,gBAAgB,CAAC,MAAqB;AAC1C,UAAI,EAAE,QAAQ,UAAU;AACtB,UAAE,eAAe;AACjB,UAAE,gBAAgB;AAAA,MACpB;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,eAAe,IAAI;AACxD,WAAO,MAAM,SAAS,oBAAoB,WAAW,eAAe,IAAI;AAAA,EAC1E,GAAG,CAAC,MAAM,CAAC;AAEX,MAAI,CAAC,OAAQ,QAAO;AAEpB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,eAAY;AAAA,MAEZ,uDAAC,gCAAW,SAAO,MAAC,cAAY,MAAC,WAAS,MACxC;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ;AAAA,UACA,eAAW,gCAAQ,WAAW,EAAE,MAAM,UAAU,CAAC,GAAG,SAAS;AAAA,UAC7D,eAAY;AAAA,UAGZ;AAAA,0DAAC,SAAI,WAAU,0CACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACE,GAAG;AAAA,kBACJ,WAAU;AAAA,kBACV,eAAY;AAAA,kBACb;AAAA;AAAA,cAED;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAQ,gBAAgB,SAAS;AAAA,kBACjC,MAAK;AAAA,kBACL,eAAY;AAAA,kBAEX,oBAAU,SAAS;AAAA;AAAA,cACtB;AAAA,eACF;AAAA,YAGA,8CAAC,SAAI,WAAU,qBACb;AAAA,4DAAC,SACC;AAAA,6DAAC,QAAG,WAAU,gDAA+C,kBAAI;AAAA,gBACjE,6CAAC,OAAE,WAAU,+BAA8B,eAAY,0BACpD,eAAK,MACR;AAAA,gBACC,KAAK,cACJ,8CAAC,OAAE,WAAU,sCAAqC,eAAY,uBAAsB;AAAA;AAAA,kBACzE,KAAK;AAAA,mBAChB;AAAA,iBAEJ;AAAA,cAGC,OAAO,KAAK,KAAK,SAAS,EAAE,SAAS,KACpC,8CAAC,SACC;AAAA,6DAAC,QAAG,WAAU,gDAA+C,uBAAS;AAAA,gBACtE;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAU;AAAA,oBACV,eAAY;AAAA,oBAEX,iBAAO,QAAQ,KAAK,SAAS,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,MAC9C,8CAAC,SAAc,WAAU,cACvB;AAAA,oEAAC,QAAG,WAAU,kDAAkD;AAAA;AAAA,wBAAI;AAAA,yBAAC;AAAA,sBACrE,6CAAC,QAAG,WAAU,iDACX,UAAAA,aAAY,KAAK,GACpB;AAAA,yBAJQ,GAKV,CACD;AAAA;AAAA,gBACH;AAAA,iBACF;AAAA,eAEJ;AAAA,YAGA,8CAAC,SAAI,WAAU,+BACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAO;AAAA,kBACP,SAAS;AAAA,kBACT,cAAW;AAAA,kBACZ;AAAA;AAAA,cAED;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,QAAO;AAAA,kBACP,SAAS;AAAA,kBACT,cAAW;AAAA,kBACZ;AAAA;AAAA,cAED;AAAA,eACF;AAAA;AAAA;AAAA,MACF,GACF;AAAA;AAAA,EACF;AAEJ;","names":["import_tailwind_merge","import_jsx_runtime","import_class_variance_authority","import_tailwind_merge","import_jsx_runtime","statusLabel","import_react","import_class_variance_authority","import_tailwind_merge","import_core","import_jsx_runtime","formatValue"]}
|