@burdenoff/microfe-botmanor 2026.1109.2 → 2026.1110.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/botlit/components/Badge.js +2 -2
- package/dist/botlit/components/Badge.js.map +1 -1
- package/dist/botlit/components/ChannelSelectorSheet.js +4 -4
- package/dist/botlit/components/ChannelSelectorSheet.js.map +1 -1
- package/dist/botlit/components/LoadMore.d.ts +9 -0
- package/dist/botlit/components/LoadMore.js +22 -0
- package/dist/botlit/components/LoadMore.js.map +1 -0
- package/dist/botlit/components/index.d.ts +1 -0
- package/dist/botlit/hooks/internal/workspaceGateway.d.ts +47 -0
- package/dist/botlit/hooks/internal/workspaceGateway.js +59 -1
- package/dist/botlit/hooks/internal/workspaceGateway.js.map +1 -1
- package/dist/botlit/hooks/useAgents.d.ts +2 -6
- package/dist/botlit/hooks/useAgents.js +71 -95
- package/dist/botlit/hooks/useAgents.js.map +1 -1
- package/dist/botlit/hooks/useBots.d.ts +2 -6
- package/dist/botlit/hooks/useBots.js +51 -75
- package/dist/botlit/hooks/useBots.js.map +1 -1
- package/dist/botlit/hooks/useExecutions.d.ts +2 -2
- package/dist/botlit/hooks/useExecutions.js +30 -34
- package/dist/botlit/hooks/useExecutions.js.map +1 -1
- package/dist/botlit/hooks/useStore.d.ts +3 -3
- package/dist/botlit/hooks/useStore.js +41 -50
- package/dist/botlit/hooks/useStore.js.map +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentDetailPage.js +1 -1
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.js +157 -156
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.js +24 -24
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.js +147 -146
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.js +3 -3
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js +2 -2
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.js +141 -134
- package/dist/botlit/pages/ExecutionsPage.js.map +1 -1
- package/dist/botlit/pages/InstalledPackagesPage.js +43 -36
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.js +1 -1
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +2 -2
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillDetailPage.js +1 -1
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.js +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.js +150 -143
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -7,17 +7,18 @@ import { Button as l } from "../components/Button.js";
|
|
|
7
7
|
import { Input as u } from "../components/Input.js";
|
|
8
8
|
import { Badge as d } from "../components/Badge.js";
|
|
9
9
|
import { EmptyState as f } from "../components/EmptyState.js";
|
|
10
|
-
import {
|
|
10
|
+
import { LoadMore as ee } from "../components/LoadMore.js";
|
|
11
|
+
import { ErrorState as te } from "../components/ErrorState.js";
|
|
11
12
|
import "../hooks/index.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
13
|
+
import { storePackageName as p, useInstalledPackages as m, usePinPackageVersion as ne, useUninstallPackage as re, useUpdateInstalledPackage as h } from "../hooks/useStore.js";
|
|
14
|
+
import { formatRelativeTime as g } from "../utils/formatters.js";
|
|
14
15
|
import { PackageKind as _ } from "../../generated/wspace-types.js";
|
|
15
16
|
import "../permissions/index.js";
|
|
16
17
|
import { useMemo as v, useState as y } from "react";
|
|
17
18
|
import { GlassCard as b, PagePurpose as x } from "@burdenoff/fe-libs/ui";
|
|
18
19
|
import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
19
|
-
import { Link as
|
|
20
|
-
import { ArrowUpCircle as T, Copy as
|
|
20
|
+
import { Link as ie } from "react-router";
|
|
21
|
+
import { ArrowUpCircle as T, Copy as ae, Download as E, ExternalLink as oe, GitBranch as se, Link2 as ce, Package as D, RefreshCw as le, Search as ue, Settings as O, Trash2 as k } from "lucide-react";
|
|
21
22
|
import { toast as A } from "sonner";
|
|
22
23
|
// src/botlit/pages/InstalledPackagesPage.tsx
|
|
23
24
|
var j = [
|
|
@@ -112,17 +113,17 @@ function R(e, t) {
|
|
|
112
113
|
return typeof n == "string" && n !== "" ? n : void 0;
|
|
113
114
|
}
|
|
114
115
|
var z = () => {
|
|
115
|
-
let { navigateTo: M, getPath: N } = e(), { data: z, loading: B, error: V, refetch: H } =
|
|
116
|
+
let { navigateTo: M, getPath: N } = e(), { data: z, loading: B, error: V, refetch: H, hasMore: de, loadingMore: U, loadMore: fe } = m(), { uninstall: pe, loading: me } = re(), { update: he, loading: ge } = h(), { pin: _e } = ne(), [W, ve] = y(""), [ye, G] = y(!1), [K, be] = y("all"), [q, J] = y(null), Y = v(() => {
|
|
116
117
|
let e = W.trim().toLowerCase();
|
|
117
118
|
return z.filter((t) => {
|
|
118
|
-
let n = !e || P(t).toLowerCase().includes(e) ||
|
|
119
|
+
let n = !e || P(t).toLowerCase().includes(e) || p(t.package).toLowerCase().includes(e), r = K === "all" || F(t) === K;
|
|
119
120
|
return n && r;
|
|
120
121
|
});
|
|
121
122
|
}, [
|
|
122
123
|
z,
|
|
123
124
|
W,
|
|
124
125
|
K
|
|
125
|
-
]), X = v(() => z.find((e) => e.id === q) ?? null, [z, q]),
|
|
126
|
+
]), X = v(() => z.find((e) => e.id === q) ?? null, [z, q]), xe = v(() => z.filter(L).length, [z]), Se = async () => {
|
|
126
127
|
G(!0);
|
|
127
128
|
try {
|
|
128
129
|
await H();
|
|
@@ -131,14 +132,14 @@ var z = () => {
|
|
|
131
132
|
}
|
|
132
133
|
}, Z = async (e) => {
|
|
133
134
|
if (confirm("Are you sure you want to uninstall this package?")) try {
|
|
134
|
-
await
|
|
135
|
+
await pe(e.id), A.success(`Uninstalled "${p(e.package) || P(e)}"`), J(null), H();
|
|
135
136
|
} catch (e) {
|
|
136
137
|
A.error(e instanceof Error ? e.message : "Failed to uninstall package");
|
|
137
138
|
}
|
|
138
|
-
},
|
|
139
|
+
}, Ce = async (e) => {
|
|
139
140
|
let t = e.package?.version;
|
|
140
141
|
if (t) try {
|
|
141
|
-
await
|
|
142
|
+
await he({
|
|
142
143
|
installedId: e.id,
|
|
143
144
|
input: { installedVersion: t }
|
|
144
145
|
}), A.success(`Updated to v${t}`), H();
|
|
@@ -147,7 +148,7 @@ var z = () => {
|
|
|
147
148
|
}
|
|
148
149
|
}, Q = async (e, t, n) => {
|
|
149
150
|
try {
|
|
150
|
-
await
|
|
151
|
+
await _e({
|
|
151
152
|
installedId: e.id,
|
|
152
153
|
environment: t,
|
|
153
154
|
version: n,
|
|
@@ -156,7 +157,7 @@ var z = () => {
|
|
|
156
157
|
} catch (e) {
|
|
157
158
|
A.error(e instanceof Error ? e.message : "Failed to change version pin");
|
|
158
159
|
}
|
|
159
|
-
}, $ = (e) => e === "LINKED" ? /* @__PURE__ */ C(
|
|
160
|
+
}, $ = (e) => e === "LINKED" ? /* @__PURE__ */ C(ce, { className: "h-4 w-4 text-status-info-text" }) : /* @__PURE__ */ C(ae, { className: "h-4 w-4 text-status-warning-text" }), we = ({ pkg: e }) => {
|
|
160
161
|
let t = I(e), o = P(e), s = L(e), c = j.filter((t) => R(e, t));
|
|
161
162
|
return /* @__PURE__ */ C(i, {
|
|
162
163
|
className: "hover:shadow-md transition-shadow cursor-pointer",
|
|
@@ -175,7 +176,7 @@ var z = () => {
|
|
|
175
176
|
className: "flex items-center gap-2",
|
|
176
177
|
children: [/* @__PURE__ */ C("h3", {
|
|
177
178
|
className: "font-semibold",
|
|
178
|
-
children:
|
|
179
|
+
children: p(e.package) || o
|
|
179
180
|
}), s && /* @__PURE__ */ w(d, {
|
|
180
181
|
variant: "warning",
|
|
181
182
|
className: "gap-1",
|
|
@@ -215,7 +216,7 @@ var z = () => {
|
|
|
215
216
|
children: "Installed"
|
|
216
217
|
}), /* @__PURE__ */ C("p", {
|
|
217
218
|
className: "font-medium",
|
|
218
|
-
children:
|
|
219
|
+
children: g(e.installedAt)
|
|
219
220
|
})] })
|
|
220
221
|
]
|
|
221
222
|
}),
|
|
@@ -249,7 +250,7 @@ var z = () => {
|
|
|
249
250
|
onClick: (e) => {
|
|
250
251
|
e.stopPropagation(), M(`store/package/${o}`);
|
|
251
252
|
},
|
|
252
|
-
children: [/* @__PURE__ */ C(
|
|
253
|
+
children: [/* @__PURE__ */ C(oe, { className: "h-4 w-4 mr-1" }), "View in Store"]
|
|
253
254
|
}),
|
|
254
255
|
s && /* @__PURE__ */ C(r, {
|
|
255
256
|
permission: n.STORE_UPDATE,
|
|
@@ -257,9 +258,9 @@ var z = () => {
|
|
|
257
258
|
variant: "outline",
|
|
258
259
|
size: "sm",
|
|
259
260
|
onClick: (t) => {
|
|
260
|
-
t.stopPropagation(),
|
|
261
|
+
t.stopPropagation(), Ce(e);
|
|
261
262
|
},
|
|
262
|
-
isLoading:
|
|
263
|
+
isLoading: ge,
|
|
263
264
|
children: [/* @__PURE__ */ C(T, { className: "h-4 w-4 mr-1" }), "Update"]
|
|
264
265
|
})
|
|
265
266
|
}),
|
|
@@ -273,7 +274,7 @@ var z = () => {
|
|
|
273
274
|
onClick: (t) => {
|
|
274
275
|
t.stopPropagation(), Z(e);
|
|
275
276
|
},
|
|
276
|
-
isLoading:
|
|
277
|
+
isLoading: me,
|
|
277
278
|
children: /* @__PURE__ */ C(k, { className: "h-4 w-4" })
|
|
278
279
|
})
|
|
279
280
|
})
|
|
@@ -301,12 +302,12 @@ var z = () => {
|
|
|
301
302
|
className: "flex gap-2",
|
|
302
303
|
children: [/* @__PURE__ */ C(l, {
|
|
303
304
|
variant: "outline",
|
|
304
|
-
leftIcon: /* @__PURE__ */ C(
|
|
305
|
-
onClick: () => void
|
|
306
|
-
isLoading:
|
|
305
|
+
leftIcon: /* @__PURE__ */ C(le, { size: 16 }),
|
|
306
|
+
onClick: () => void Se(),
|
|
307
|
+
isLoading: ye,
|
|
307
308
|
children: "Check Updates"
|
|
308
309
|
}), /* @__PURE__ */ C(l, {
|
|
309
|
-
leftIcon: /* @__PURE__ */ C(
|
|
310
|
+
leftIcon: /* @__PURE__ */ C(D, { size: 16 }),
|
|
310
311
|
onClick: () => M("store"),
|
|
311
312
|
children: "Browse Store"
|
|
312
313
|
})]
|
|
@@ -314,10 +315,10 @@ var z = () => {
|
|
|
314
315
|
children: [
|
|
315
316
|
/* @__PURE__ */ C(x, {
|
|
316
317
|
className: "mb-6",
|
|
317
|
-
icon: /* @__PURE__ */ C(
|
|
318
|
+
icon: /* @__PURE__ */ C(D, { size: 18 }),
|
|
318
319
|
children: "These are the packages you have installed from the BotManor Store and how they are wired into your workspace. Manage each one’s installation mode (linked, so it auto-updates, or forked as an independent copy), pin specific versions per environment, and update or uninstall — this is your dependency manager for everything you pulled from the store."
|
|
319
320
|
}),
|
|
320
|
-
V ? /* @__PURE__ */ C(
|
|
321
|
+
V ? /* @__PURE__ */ C(te, {
|
|
321
322
|
resource: "installed packages",
|
|
322
323
|
error: V,
|
|
323
324
|
onRetry: () => void H()
|
|
@@ -364,7 +365,7 @@ var z = () => {
|
|
|
364
365
|
className: "p-6 text-center",
|
|
365
366
|
children: [/* @__PURE__ */ C("p", {
|
|
366
367
|
className: "text-3xl font-bold tabular-nums text-text-primary",
|
|
367
|
-
children:
|
|
368
|
+
children: xe
|
|
368
369
|
}), /* @__PURE__ */ C("p", {
|
|
369
370
|
className: "text-sm text-text-secondary",
|
|
370
371
|
children: "Updates Available"
|
|
@@ -376,10 +377,10 @@ var z = () => {
|
|
|
376
377
|
className: "flex flex-col md:flex-row gap-4 mb-6",
|
|
377
378
|
children: [/* @__PURE__ */ w("div", {
|
|
378
379
|
className: "relative flex-1",
|
|
379
|
-
children: [/* @__PURE__ */ C(
|
|
380
|
+
children: [/* @__PURE__ */ C(ue, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ C(u, {
|
|
380
381
|
placeholder: "Search packages...",
|
|
381
382
|
value: W,
|
|
382
|
-
onChange: (e) =>
|
|
383
|
+
onChange: (e) => ve(e.target.value),
|
|
383
384
|
className: "pl-9"
|
|
384
385
|
})]
|
|
385
386
|
}), /* @__PURE__ */ C("div", {
|
|
@@ -388,7 +389,7 @@ var z = () => {
|
|
|
388
389
|
"aria-label": "Filter by package type",
|
|
389
390
|
className: "flex h-10 rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm",
|
|
390
391
|
value: K,
|
|
391
|
-
onChange: (e) =>
|
|
392
|
+
onChange: (e) => be(e.target.value),
|
|
392
393
|
children: [
|
|
393
394
|
/* @__PURE__ */ C("option", {
|
|
394
395
|
value: "all",
|
|
@@ -420,7 +421,7 @@ var z = () => {
|
|
|
420
421
|
}),
|
|
421
422
|
Y.length > 0 ? /* @__PURE__ */ C("div", {
|
|
422
423
|
className: "grid grid-cols-1 md:grid-cols-2 gap-4",
|
|
423
|
-
children: Y.map((e) => /* @__PURE__ */ C(
|
|
424
|
+
children: Y.map((e) => /* @__PURE__ */ C(we, { pkg: e }, e.id))
|
|
424
425
|
}) : /* @__PURE__ */ C(f, {
|
|
425
426
|
illustration: "empty-generic",
|
|
426
427
|
title: W || K !== "all" ? "No matching packages" : "No packages installed",
|
|
@@ -430,12 +431,18 @@ var z = () => {
|
|
|
430
431
|
leftIcon: /* @__PURE__ */ C(E, { className: "h-4 w-4" }),
|
|
431
432
|
children: "Browse Store"
|
|
432
433
|
})
|
|
434
|
+
}),
|
|
435
|
+
/* @__PURE__ */ C(ee, {
|
|
436
|
+
hasMore: de,
|
|
437
|
+
loadingMore: U,
|
|
438
|
+
onLoadMore: () => void fe(),
|
|
439
|
+
loadedCount: z.length
|
|
433
440
|
})
|
|
434
441
|
] }),
|
|
435
442
|
X && /* @__PURE__ */ C(({ pkg: e, onClose: t }) => {
|
|
436
443
|
let u = I(e), d = P(e), f = e.bindings ?? {};
|
|
437
444
|
return /* @__PURE__ */ C("div", {
|
|
438
|
-
className: "fixed inset-0 bg-
|
|
445
|
+
className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-50",
|
|
439
446
|
children: /* @__PURE__ */ w("div", {
|
|
440
447
|
className: "bg-bg-surface rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto",
|
|
441
448
|
children: [
|
|
@@ -450,7 +457,7 @@ var z = () => {
|
|
|
450
457
|
children: u.icon
|
|
451
458
|
}), /* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("h2", {
|
|
452
459
|
className: "text-xl font-bold",
|
|
453
|
-
children:
|
|
460
|
+
children: p(e.package) || d
|
|
454
461
|
}), /* @__PURE__ */ C("p", {
|
|
455
462
|
className: "text-sm text-text-secondary font-mono",
|
|
456
463
|
children: d
|
|
@@ -507,7 +514,7 @@ var z = () => {
|
|
|
507
514
|
})] }),
|
|
508
515
|
/* @__PURE__ */ w(i, { children: [/* @__PURE__ */ w(s, { children: [/* @__PURE__ */ w(c, {
|
|
509
516
|
className: "text-base flex items-center gap-2",
|
|
510
|
-
children: [/* @__PURE__ */ C(
|
|
517
|
+
children: [/* @__PURE__ */ C(se, { className: "h-4 w-4" }), "Environment Version Pins"]
|
|
511
518
|
}), /* @__PURE__ */ C(o, { children: "Pin specific versions for each environment" })] }), /* @__PURE__ */ C(a, { children: /* @__PURE__ */ C("div", {
|
|
512
519
|
className: "space-y-3",
|
|
513
520
|
children: j.map((t) => {
|
|
@@ -545,7 +552,7 @@ var z = () => {
|
|
|
545
552
|
}) })] }),
|
|
546
553
|
Object.keys(f).length > 0 && /* @__PURE__ */ w(i, { children: [/* @__PURE__ */ C(s, { children: /* @__PURE__ */ w(c, {
|
|
547
554
|
className: "text-base flex items-center gap-2",
|
|
548
|
-
children: [/* @__PURE__ */ C(
|
|
555
|
+
children: [/* @__PURE__ */ C(O, { className: "h-4 w-4" }), "Configuration Bindings"]
|
|
549
556
|
}) }), /* @__PURE__ */ C(a, { children: /* @__PURE__ */ C("div", {
|
|
550
557
|
className: "space-y-2",
|
|
551
558
|
children: Object.entries(f).map(([e, t]) => /* @__PURE__ */ w("div", {
|
|
@@ -570,7 +577,7 @@ var z = () => {
|
|
|
570
577
|
children: "Installed At"
|
|
571
578
|
}), /* @__PURE__ */ C("p", {
|
|
572
579
|
className: "font-medium",
|
|
573
|
-
children:
|
|
580
|
+
children: g(e.installedAt)
|
|
574
581
|
})] }),
|
|
575
582
|
/* @__PURE__ */ w("div", { children: [/* @__PURE__ */ C("p", {
|
|
576
583
|
className: "text-text-secondary",
|
|
@@ -608,7 +615,7 @@ var z = () => {
|
|
|
608
615
|
})
|
|
609
616
|
}), /* @__PURE__ */ w("div", {
|
|
610
617
|
className: "flex gap-2",
|
|
611
|
-
children: [/* @__PURE__ */ C(
|
|
618
|
+
children: [/* @__PURE__ */ C(ie, {
|
|
612
619
|
to: N(`store/package/${d}`),
|
|
613
620
|
children: /* @__PURE__ */ C(l, {
|
|
614
621
|
variant: "outline",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstalledPackagesPage.js","names":["_Fragment","GqlPackageKind","ENVIRONMENTS","PACKAGE_KIND_CONFIG","UNKNOWN_KIND","installSlug","pkg","installKind","kindConfigFor","kind","hasUpdate","latest","pinnedVersionFor","value","env","InstalledPackagesPage","useBotlit","packages","useInstalledPackages","uninstallLoading","useUninstallPackage","updateLoading","useUpdateInstalledPackage","usePinPackageVersion","search","setSearch","useState","refreshing","setRefreshing","kindFilter","setKindFilter","selectedPackageId","setSelectedPackageId","filteredPackages","useMemo","needle","matchesSearch","storePackageName","matchesKind","selectedPackage","updatesAvailable","handleCheckUpdates","refetch","handleUninstall","uninstall","toast","err","handleUpdate","update","handlePinVersion","pin","version","getModeIcon","mode","Link2","Copy","PackageCard","kindConfig","slug","updateAvailable","pinnedEnvironments","Card","CardContent","Badge","ArrowUpCircle","formatRelativeTime","pinnedVersion","Button","navigateTo","ExternalLink","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","e","Trash2","loading","PageLayout","i","RefreshCw","Package","PagePurpose","error","ErrorState","Fragment","GlassCard","Search","Input","PackageKind","EmptyState","Download","bindings","onClose","CardHeader","CardTitle","GitBranch","CardDescription","Settings","key","Link","getPath"],"sources":["../../../src/botlit/pages/InstalledPackagesPage.tsx"],"sourcesContent":["/**\n * Installed Packages Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Package,\n Download,\n RefreshCw,\n Trash2,\n GitBranch,\n Link2,\n Copy,\n Settings,\n ArrowUpCircle,\n Search,\n ExternalLink,\n} from 'lucide-react';\nimport { toast } from 'sonner';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useInstalledPackages,\n useUninstallPackage,\n useUpdateInstalledPackage,\n usePinPackageVersion,\n storePackageName,\n type InstalledPackageRecord,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { PackageKind as GqlPackageKind } from '../../generated/wspace-types';\nimport type { Environment, PackageKind } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nconst ENVIRONMENTS: Environment[] = ['DEV', 'STAGING', 'PROD'];\n\nconst PACKAGE_KIND_CONFIG: Record<string, { label: string; icon: string }> = {\n APP: { label: 'Bot', icon: '📱' },\n AGENT: { label: 'Agent', icon: '🤖' },\n SKILL: { label: 'Skill', icon: '⚡' },\n MCP_PACK: { label: 'MCP Pack', icon: '🔧' },\n PROMPT_TEMPLATE: { label: 'Template', icon: '📝' },\n PROMPT: { label: 'Prompt', icon: '📝' },\n RETRIEVAL_PROFILE: { label: 'Retrieval', icon: '🔍' },\n POLICY_BUNDLE: { label: 'Policy', icon: '🛡️' },\n CHANNEL_TEMPLATE: { label: 'Channel', icon: '📡' },\n A2A_AGENT: { label: 'A2A Agent', icon: '🔗' },\n KB_TEMPLATE: { label: 'KB Template', icon: '📚' },\n KNOWLEDGE_BASE: { label: 'Knowledge Base', icon: '📚' },\n INTEGRATION: { label: 'Integration', icon: '🔌' },\n TEMPLATE: { label: 'Template', icon: '📝' },\n TOOL: { label: 'Tool', icon: '🔧' },\n WORKFLOW: { label: 'Workflow', icon: '🔀' },\n};\n\nconst UNKNOWN_KIND = { label: 'Package', icon: '📦' };\n\n/** Store slug for an install, falling back to the package id when unresolved. */\nfunction installSlug(pkg: InstalledPackageRecord): string {\n return pkg.package?.slug ?? pkg.packageId;\n}\n\nfunction installKind(pkg: InstalledPackageRecord): string | undefined {\n return pkg.package?.kind;\n}\n\nfunction kindConfigFor(pkg: InstalledPackageRecord) {\n const kind = installKind(pkg);\n return (kind && PACKAGE_KIND_CONFIG[kind]) || UNKNOWN_KIND;\n}\n\nfunction hasUpdate(pkg: InstalledPackageRecord): boolean {\n const latest = pkg.package?.version;\n return Boolean(latest && latest !== pkg.installedVersion);\n}\n\n/** `pinnedByEnv` is free-form JSON — read one environment's pin defensively. */\nfunction pinnedVersionFor(pkg: InstalledPackageRecord, env: Environment): string | undefined {\n const value = pkg.pinnedByEnv?.[env];\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nexport const InstalledPackagesPage: FC = () => {\n const { navigateTo, getPath } = useBotlit();\n const { data: packages, loading, error, refetch } = useInstalledPackages();\n const { uninstall, loading: uninstallLoading } = useUninstallPackage();\n const { update, loading: updateLoading } = useUpdateInstalledPackage();\n const { pin } = usePinPackageVersion();\n\n const [search, setSearch] = useState('');\n const [refreshing, setRefreshing] = useState(false);\n const [kindFilter, setKindFilter] = useState<PackageKind | 'all'>('all');\n const [selectedPackageId, setSelectedPackageId] = useState<string | null>(null);\n\n const filteredPackages = useMemo(() => {\n const needle = search.trim().toLowerCase();\n return packages.filter((pkg) => {\n const matchesSearch =\n !needle ||\n installSlug(pkg).toLowerCase().includes(needle) ||\n storePackageName(pkg.package).toLowerCase().includes(needle);\n const matchesKind = kindFilter === 'all' || installKind(pkg) === kindFilter;\n return matchesSearch && matchesKind;\n });\n }, [packages, search, kindFilter]);\n\n const selectedPackage = useMemo(\n () => packages.find((pkg) => pkg.id === selectedPackageId) ?? null,\n [packages, selectedPackageId]\n );\n\n const updatesAvailable = useMemo(() => packages.filter(hasUpdate).length, [packages]);\n\n const handleCheckUpdates = async () => {\n setRefreshing(true);\n try {\n await refetch();\n } finally {\n setRefreshing(false);\n }\n };\n\n const handleUninstall = async (pkg: InstalledPackageRecord) => {\n if (!confirm('Are you sure you want to uninstall this package?')) return;\n try {\n await uninstall(pkg.id);\n toast.success(`Uninstalled \"${storePackageName(pkg.package) || installSlug(pkg)}\"`);\n setSelectedPackageId(null);\n void refetch();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to uninstall package');\n }\n };\n\n const handleUpdate = async (pkg: InstalledPackageRecord) => {\n const latest = pkg.package?.version;\n if (!latest) return;\n try {\n await update({ installedId: pkg.id, input: { installedVersion: latest } });\n toast.success(`Updated to v${latest}`);\n void refetch();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update package');\n }\n };\n\n const handlePinVersion = async (\n pkg: InstalledPackageRecord,\n env: Environment,\n version: string\n ) => {\n try {\n await pin({\n installedId: pkg.id,\n environment: env,\n version,\n pinnedByEnv: pkg.pinnedByEnv,\n });\n toast.success(version ? `Pinned ${env} to v${version}` : `Unpinned ${env}`);\n void refetch();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to change version pin');\n }\n };\n\n const getModeIcon = (mode: string) =>\n mode === 'LINKED' ? (\n <Link2 className=\"h-4 w-4 text-status-info-text\" />\n ) : (\n <Copy className=\"h-4 w-4 text-status-warning-text\" />\n );\n\n const PackageCard: FC<{ pkg: InstalledPackageRecord }> = ({ pkg }) => {\n const kindConfig = kindConfigFor(pkg);\n const slug = installSlug(pkg);\n const updateAvailable = hasUpdate(pkg);\n const pinnedEnvironments = ENVIRONMENTS.filter((env) => pinnedVersionFor(pkg, env));\n\n return (\n <Card\n className=\"hover:shadow-md transition-shadow cursor-pointer\"\n onClick={() => setSelectedPackageId(pkg.id)}\n >\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div className=\"p-2 rounded-lg bg-bg-sunken text-2xl\">{kindConfig.icon}</div>\n <div>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"font-semibold\">{storePackageName(pkg.package) || slug}</h3>\n {updateAvailable && (\n <Badge variant=\"warning\" className=\"gap-1\">\n <ArrowUpCircle className=\"h-3 w-3\" />\n Update\n </Badge>\n )}\n </div>\n <p className=\"text-sm text-text-secondary font-mono\">{slug}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {getModeIcon(pkg.mode)}\n <Badge variant=\"outline\">{kindConfig.label}</Badge>\n </div>\n </div>\n\n <div className=\"mt-4 grid grid-cols-3 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Installed Version</p>\n <p className=\"font-medium font-mono\">v{pkg.installedVersion}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Mode</p>\n <p className=\"font-medium flex items-center gap-1\">\n {getModeIcon(pkg.mode)}\n {pkg.mode}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Installed</p>\n <p className=\"font-medium\">{formatRelativeTime(pkg.installedAt)}</p>\n </div>\n </div>\n\n {/* Environment Pins */}\n {pinnedEnvironments.length > 0 && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary mb-2\">Pinned Versions</p>\n <div className=\"flex gap-2\">\n {ENVIRONMENTS.map((env) => {\n const pinnedVersion = pinnedVersionFor(pkg, env);\n return (\n <Badge\n key={env}\n variant={pinnedVersion ? 'default' : 'outline'}\n className=\"text-xs\"\n >\n {env}: {pinnedVersion ?? 'latest'}\n </Badge>\n );\n })}\n </div>\n </div>\n )}\n\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n navigateTo(`store/package/${slug}`);\n }}\n >\n <ExternalLink className=\"h-4 w-4 mr-1\" />\n View in Store\n </Button>\n {updateAvailable && (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n void handleUpdate(pkg);\n }}\n isLoading={updateLoading}\n >\n <ArrowUpCircle className=\"h-4 w-4 mr-1\" />\n Update\n </Button>\n </BotmanorPermissionGate>\n )}\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_DELETE}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Uninstall package\"\n className=\"text-status-error-text hover:text-status-error-text\"\n onClick={(e) => {\n e.stopPropagation();\n void handleUninstall(pkg);\n }}\n isLoading={uninstallLoading}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </CardContent>\n </Card>\n );\n };\n\n const PackageDetailModal: FC<{ pkg: InstalledPackageRecord; onClose: () => void }> = ({\n pkg,\n onClose,\n }) => {\n const kindConfig = kindConfigFor(pkg);\n const slug = installSlug(pkg);\n const bindings = pkg.bindings ?? {};\n\n return (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-bg-surface rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto\">\n <div className=\"p-6 border-b border-border-subtle\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div className=\"p-3 rounded-lg bg-bg-sunken text-3xl\">{kindConfig.icon}</div>\n <div>\n <h2 className=\"text-xl font-bold\">{storePackageName(pkg.package) || slug}</h2>\n <p className=\"text-sm text-text-secondary font-mono\">{slug}</p>\n </div>\n </div>\n <Button variant=\"ghost\" size=\"sm\" aria-label=\"Close\" onClick={onClose}>\n ×\n </Button>\n </div>\n </div>\n\n <div className=\"p-6 space-y-6\">\n {/* Version Info */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Version Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Installed Version</p>\n <p className=\"font-mono font-medium\">v{pkg.installedVersion}</p>\n </div>\n {pkg.package && (\n <div>\n <p className=\"text-sm text-text-secondary\">Latest Version</p>\n <p className=\"font-mono font-medium\">v{pkg.package.version}</p>\n </div>\n )}\n </div>\n\n <div>\n <p className=\"text-sm text-text-secondary mb-2\">Installation Mode</p>\n <div className=\"flex items-center gap-2\">\n {getModeIcon(pkg.mode)}\n <span className=\"font-medium\">{pkg.mode}</span>\n <span className=\"text-sm text-text-secondary\">\n {pkg.mode === 'LINKED'\n ? '- Receives updates automatically'\n : '- Independent copy, no auto-updates'}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Environment Pinning */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <GitBranch className=\"h-4 w-4\" />\n Environment Version Pins\n </CardTitle>\n <CardDescription>Pin specific versions for each environment</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {ENVIRONMENTS.map((env) => {\n const pinnedVersion = pinnedVersionFor(pkg, env);\n return (\n <div\n key={env}\n className=\"flex items-center justify-between p-3 bg-bg-sunken rounded-lg\"\n >\n <div>\n <p className=\"font-medium\">{env}</p>\n <p className=\"text-sm text-text-secondary font-mono\">\n {pinnedVersion ? `v${pinnedVersion}` : 'Using latest'}\n </p>\n </div>\n <div className=\"flex gap-2\">\n {pinnedVersion ? (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handlePinVersion(pkg, env, '')}\n >\n Unpin\n </Button>\n </BotmanorPermissionGate>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n void handlePinVersion(pkg, env, pkg.installedVersion)\n }\n >\n Pin Current\n </Button>\n </BotmanorPermissionGate>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n {/* Bindings */}\n {Object.keys(bindings).length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Settings className=\"h-4 w-4\" />\n Configuration Bindings\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {Object.entries(bindings).map(([key, value]) => (\n <div key={key} className=\"flex justify-between p-2 bg-bg-sunken rounded\">\n <span className=\"font-mono text-sm\">{key}</span>\n <span className=\"font-mono text-sm text-text-secondary\">\n {typeof value === 'string' ? value : JSON.stringify(value)}\n </span>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Metadata</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Installed At</p>\n <p className=\"font-medium\">{formatRelativeTime(pkg.installedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Installed By</p>\n <p className=\"font-medium\">{pkg.installedBy}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Package ID</p>\n <p className=\"font-mono text-xs\">{pkg.packageId}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Installation ID</p>\n <p className=\"font-mono text-xs\">{pkg.id}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"p-6 border-t border-border-subtle flex justify-between\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_DELETE}>\n <Button variant=\"destructive\" onClick={() => void handleUninstall(pkg)}>\n <Trash2 className=\"h-4 w-4 mr-2\" />\n Uninstall\n </Button>\n </BotmanorPermissionGate>\n <div className=\"flex gap-2\">\n <Link to={getPath(`store/package/${slug}`)}>\n <Button variant=\"outline\">View in Store</Button>\n </Link>\n <Button variant=\"outline\" onClick={onClose}>\n Close\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n };\n\n if (loading) {\n return (\n <PageLayout title=\"Installed Packages\" description=\"Manage installed store packages\">\n <div className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n ))}\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Installed Packages\"\n description=\"Manage packages installed from the BotManor Store\"\n actions={\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n leftIcon={<RefreshCw size={16} />}\n onClick={() => void handleCheckUpdates()}\n isLoading={refreshing}\n >\n Check Updates\n </Button>\n <Button leftIcon={<Package size={16} />} onClick={() => navigateTo('store')}>\n Browse Store\n </Button>\n </div>\n }\n >\n <PagePurpose className=\"mb-6\" icon={<Package size={18} />}>\n These are the packages you have installed from the BotManor Store and how they are wired\n into your workspace. Manage each one’s installation mode (linked, so it auto-updates,\n or forked as an independent copy), pin specific versions per environment, and update or\n uninstall — this is your dependency manager for everything you pulled from the store.\n </PagePurpose>\n\n {error ? (\n <ErrorState resource=\"installed packages\" error={error} onRetry={() => void refetch()} />\n ) : (\n <>\n {/* Summary Cards */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-6\">\n <GlassCard treatment=\"glass\" glow className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">{packages.length}</p>\n <p className=\"text-sm text-text-secondary\">Total Installed</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {packages.filter((pkg) => pkg.mode === 'LINKED').length}\n </p>\n <p className=\"text-sm text-text-secondary\">Linked</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {packages.filter((pkg) => pkg.mode === 'FORKED').length}\n </p>\n <p className=\"text-sm text-text-secondary\">Forked</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {updatesAvailable}\n </p>\n <p className=\"text-sm text-text-secondary\">Updates Available</p>\n </GlassCard>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col md:flex-row gap-4 mb-6\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search packages...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <div className=\"flex gap-2\">\n <select\n aria-label=\"Filter by package type\"\n className=\"flex h-10 rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={kindFilter}\n onChange={(e) => setKindFilter(e.target.value as PackageKind | 'all')}\n >\n <option value=\"all\">All Types</option>\n <option value={GqlPackageKind.Agent}>Agents</option>\n <option value={GqlPackageKind.Skill}>Skills</option>\n <option value={GqlPackageKind.McpPack}>MCP Packs</option>\n <option value={GqlPackageKind.PromptTemplate}>Templates</option>\n <option value={GqlPackageKind.RetrievalProfile}>Retrieval Profiles</option>\n </select>\n </div>\n </div>\n\n {/* Package List */}\n {filteredPackages.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {filteredPackages.map((pkg) => (\n <PackageCard key={pkg.id} pkg={pkg} />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={\n search || kindFilter !== 'all' ? 'No matching packages' : 'No packages installed'\n }\n description={\n search || kindFilter !== 'all'\n ? 'Try adjusting your search or type filter.'\n : 'Browse the BotManor Store to find agents, skills, and tools to install.'\n }\n action={\n <Button\n onClick={() => navigateTo('store')}\n leftIcon={<Download className=\"h-4 w-4\" />}\n >\n Browse Store\n </Button>\n }\n />\n )}\n </>\n )}\n\n {/* Detail Modal */}\n {selectedPackage && (\n <PackageDetailModal pkg={selectedPackage} onClose={() => setSelectedPackageId(null)} />\n )}\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA4CA,IAAME,IAA8B;CAAC;CAAO;CAAW;AAAM,GAEvDC,IAAuE;CAC3E,KAAK;EAAE,OAAO;EAAO,MAAM;CAAK;CAChC,OAAO;EAAE,OAAO;EAAS,MAAM;CAAK;CACpC,OAAO;EAAE,OAAO;EAAS,MAAM;CAAI;CACnC,UAAU;EAAE,OAAO;EAAY,MAAM;CAAK;CAC1C,iBAAiB;EAAE,OAAO;EAAY,MAAM;CAAK;CACjD,QAAQ;EAAE,OAAO;EAAU,MAAM;CAAK;CACtC,mBAAmB;EAAE,OAAO;EAAa,MAAM;CAAK;CACpD,eAAe;EAAE,OAAO;EAAU,MAAM;CAAM;CAC9C,kBAAkB;EAAE,OAAO;EAAW,MAAM;CAAK;CACjD,WAAW;EAAE,OAAO;EAAa,MAAM;CAAK;CAC5C,aAAa;EAAE,OAAO;EAAe,MAAM;CAAK;CAChD,gBAAgB;EAAE,OAAO;EAAkB,MAAM;CAAK;CACtD,aAAa;EAAE,OAAO;EAAe,MAAM;CAAK;CAChD,UAAU;EAAE,OAAO;EAAY,MAAM;CAAK;CAC1C,MAAM;EAAE,OAAO;EAAQ,MAAM;CAAK;CAClC,UAAU;EAAE,OAAO;EAAY,MAAM;CAAK;AAC5C,GAEMC,IAAe;CAAE,OAAO;CAAW,MAAM;AAAK;AAGpD,SAASC,EAAY,GAAqC;CACxD,OAAOC,EAAI,SAAS,QAAQA,EAAI;AAClC;AAEA,SAASC,EAAY,GAAiD;CACpE,OAAOD,EAAI,SAAS;AACtB;AAEA,SAASE,EAAc,GAA6B;CAClD,IAAMC,IAAOF,EAAYD,CAAG;CAC5B,OAAQG,KAAQN,EAAoBM,MAAUL;AAChD;AAEA,SAASM,EAAU,GAAsC;CACvD,IAAMC,IAASL,EAAI,SAAS;CAC5B,OAAO,GAAQK,KAAUA,MAAWL,EAAI;AAC1C;AAGA,SAASM,EAAiB,GAA6B,GAAsC;CAC3F,IAAMC,IAAQP,EAAI,cAAcQ;CAChC,OAAO,OAAOD,KAAU,YAAYA,MAAU,KAAKA,IAAQ,KAAA;AAC7D;AAEA,IAAaE,UAAkC;CAC7C,IAAM,EAAE,eAAY,eAAYC,EAAU,GACpC,EAAE,MAAMC,GAAU,YAAS,UAAO,eAAYC,EAAqB,GACnE,EAAE,cAAW,SAASC,OAAqBC,GAAoB,GAC/D,EAAE,YAAQ,SAASC,OAAkBC,EAA0B,GAC/D,EAAE,YAAQC,GAAqB,GAE/B,CAACC,GAAQC,MAAaC,EAAS,EAAE,GACjC,CAACC,IAAYC,KAAiBF,EAAS,EAAK,GAC5C,CAACG,GAAYC,MAAiBJ,EAA8B,KAAK,GACjE,CAACK,GAAmBC,KAAwBN,EAAwB,IAAI,GAExEO,IAAmBC,QAAc;EACrC,IAAMC,IAASX,EAAO,KAAK,CAAC,CAAC,YAAY;EACzC,OAAOP,EAAS,QAAQ,MAAQ;GAC9B,IAAMmB,IACJ,CAACD,KACD9B,EAAYC,CAAG,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS6B,CAAM,KAC9CE,EAAiB/B,EAAI,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS6B,CAAM,GACvDG,IAAcT,MAAe,SAAStB,EAAYD,CAAG,MAAMuB;GACjE,OAAOO,KAAiBE;EAC1B,CAAC;CACH,GAAG;EAACrB;EAAUO;EAAQK;CAAU,CAAC,GAE3BU,IAAkBL,QAChBjB,EAAS,MAAM,MAAQX,EAAI,OAAOyB,CAAiB,KAAK,MAC9D,CAACd,GAAUc,CAAiB,CAC9B,GAEMS,KAAmBN,QAAcjB,EAAS,OAAOP,CAAS,CAAC,CAAC,QAAQ,CAACO,CAAQ,CAAC,GAE9EwB,KAAqB,YAAY;EACrC,EAAc,EAAI;EAClB,IAAI;GACF,MAAMC,EAAQ;EAChB,UAAU;GACR,EAAc,EAAK;EACrB;CACF,GAEMC,IAAkB,OAAO,MAAgC;EAC7D,IAAK,QAAQ,kDAAkD,GAC/D,IAAI;GAIF,AAHA,MAAMC,EAAUtC,EAAI,EAAE,GACtBuC,EAAM,QAAQ,gBAAgBR,EAAiB/B,EAAI,OAAO,KAAKD,EAAYC,CAAG,EAAE,EAAE,GAClF0B,EAAqB,IAAI,GACzBU,EAAa;EACf,SAASI,GAAK;GACZ,EAAM,MAAMA,aAAe,QAAQA,EAAI,UAAU,6BAA6B;EAChF;CACF,GAEMC,KAAe,OAAO,MAAgC;EAC1D,IAAMpC,IAASL,EAAI,SAAS;EAC5B,IAAKK,GACL,IAAI;GAGF,AAFA,MAAMqC,GAAO;IAAE,aAAa1C,EAAI;IAAI,OAAO,EAAE,kBAAkBK,EAAO;GAAE,CAAC,GACzEkC,EAAM,QAAQ,eAAelC,GAAQ,GACrC+B,EAAa;EACf,SAASI,GAAK;GACZ,EAAM,MAAMA,aAAe,QAAQA,EAAI,UAAU,0BAA0B;EAC7E;CACF,GAEMG,IAAmB,OACvB,GACA,GACA,MACG;EACH,IAAI;GAQF,AAPA,MAAMC,GAAI;IACR,aAAa5C,EAAI;IACjB,aAAaQ;IACb;IACA,aAAaR,EAAI;GACnB,CAAC,GACDuC,EAAM,QAAQM,IAAU,UAAUrC,EAAI,OAAOqC,MAAY,YAAYrC,GAAK,GAC1E4B,EAAa;EACf,SAASI,GAAK;GACZ,EAAM,MAAMA,aAAe,QAAQA,EAAI,UAAU,8BAA8B;EACjF;CACF,GAEMM,KAAe,MACnBC,MAAS,WACP,kBAACC,IAAD,EAAO,WAAU,gCAAiC,CAAA,IAElD,kBAACC,IAAD,EAAM,WAAU,mCAAoC,CAAA,GAGlDC,MAAoD,EAAE,aAAU;EACpE,IAAMC,IAAajD,EAAcF,CAAG,GAC9BoD,IAAOrD,EAAYC,CAAG,GACtBqD,IAAkBjD,EAAUJ,CAAG,GAC/BsD,IAAqB1D,EAAa,QAAQ,MAAQU,EAAiBN,GAAKQ,CAAG,CAAC;EAElF,OACE,kBAAC+C,GAAD;GACE,WAAU;GACV,eAAe7B,EAAqB1B,EAAI,EAAE;GAE1C,UAAA,kBAACwD,GAAD;IAAa,WAAU;IAAvB,UAAA;KACE,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;QAAwC,UAAAL,EAAW;OAAU,CAAA,GAC5E,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACE,kBAAC,MAAD;SAAI,WAAU;SAAiB,UAAApB,EAAiB/B,EAAI,OAAO,KAAKoD;QAAS,CAAA,GACxEC,KACC,kBAACI,GAAD;SAAO,SAAQ;SAAU,WAAU;SAAnC,UAAA,CACE,kBAACC,GAAD,EAAe,WAAU,UAAW,CAAA,GAAC,QAEhC;QAEN,CAAA,CAAA;OACL,CAAA,GAAA,kBAAC,KAAD;QAAG,WAAU;QAAyC,UAAAN;OAAQ,CAAA,CAC3D,EAAA,CAAA,CACF;MACL,CAAA,GAAA,kBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACGN,EAAY9C,EAAI,IAAI,GACrB,kBAACyD,GAAD;QAAO,SAAQ;QAAW,UAAAN,EAAW;OAAa,CAAA,CAC/C;MACF,CAAA,CAAA;;KAEL,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA;OACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QAAsB,UAAA;OAAoB,CAAA,GACvD,kBAAC,KAAD;QAAG,WAAU;QAAb,UAAA,CAAqC,KAAEnD,EAAI,gBAAoB;OAC5D,CAAA,CAAA,EAAA,CAAA;OACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QAAsB,UAAA;OAAO,CAAA,GAC1C,kBAAC,KAAD;QAAG,WAAU;QAAb,UAAA,CACG8C,EAAY9C,EAAI,IAAI,GACpBA,EAAI,IACJ;OACA,CAAA,CAAA,EAAA,CAAA;OACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QAAsB,UAAA;OAAY,CAAA,GAC/C,kBAAC,KAAD;QAAG,WAAU;QAAe,UAAA2D,EAAmB3D,EAAI,WAAW;OAAK,CAAA,CAChE,EAAA,CAAA;MACF;;KAGJsD,EAAmB,SAAS,KAC3B,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;OAAmC,UAAA;MAAkB,CAAA,GAClE,kBAAC,OAAD;OAAK,WAAU;OACZ,UAAA1D,EAAa,KAAK,MAAQ;QACzB,IAAMgE,IAAgBtD,EAAiBN,GAAKQ,CAAG;QAC/C,OACE,kBAACiD,GAAD;SAEE,SAASG,IAAgB,YAAY;SACrC,WAAU;SAHZ,UAAA;UAKGpD;UAAI;UAAGoD,KAAiB;SACpB;QALA,GAAApD,CAKA;OAEX,CAAC;MACE,CAAA,CACF;;KAGP,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA;OACE,kBAACqD,GAAD;QACE,SAAQ;QACR,MAAK;QACL,UAAU,MAAM;SAEd,AADA,EAAE,gBAAgB,GAClBC,EAAW,iBAAiBV,GAAM;QACpC;QANF,UAAA,CAQE,kBAACW,GAAD,EAAc,WAAU,eAAgB,CAAA,GAAC,eAEnC;;OACPV,KACC,kBAACW,GAAD;QAAwB,YAAYC,EAAqB;QACvD,UAAA,kBAACJ,GAAD;SACE,SAAQ;SACR,MAAK;SACL,UAAU,MAAM;UAEd,AADAK,EAAE,gBAAgB,GAClBzB,GAAkBzC,CAAG;SACvB;SACA,WAAWe;SAPb,UAAA,CASE,kBAAC2C,GAAD,EAAe,WAAU,eAAgB,CAAA,GAAC,QAEpC;;OACc,CAAA;OAE1B,kBAACM,GAAD;QAAwB,YAAYC,EAAqB;QACvD,UAAA,kBAACJ,GAAD;SACE,SAAQ;SACR,MAAK;SACL,cAAW;SACX,WAAU;SACV,UAAU,MAAM;UAEd,AADAK,EAAE,gBAAgB,GAClB7B,EAAqBrC,CAAG;SAC1B;SACA,WAAWa;SAEX,UAAA,kBAACsD,GAAD,EAAQ,WAAU,UAAW,CAAA;QACvB,CAAA;OACc,CAAA;MACrB;;IACM;;EACT,CAAA;CAEV;CA4MA,OAZIC,IAEA,kBAACC,GAAD;EAAY,OAAM;EAAqB,aAAY;EACjD,UAAA,kBAAC,OAAD;GAAK,WAAU;GACZ,UAAA;IAAC;IAAG;IAAG;GAAC,CAAC,CAAC,KAAK,MACd,kBAAC,OAAD,EAAa,WAAU,8DAA+D,GAA5EC,CAA4E,CACvF;EACE,CAAA;CACK,CAAA,IAKd,kBAACD,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAACR,GAAD;IACE,SAAQ;IACR,UAAU,kBAACU,IAAD,EAAW,MAAM,GAAK,CAAA;IAChC,eAAe,KAAKpC,GAAmB;IACvC,WAAWd;IACZ,UAAA;GAEO,CAAA,GACR,kBAACwC,GAAD;IAAQ,UAAU,kBAACW,GAAD,EAAS,MAAM,GAAK,CAAA;IAAG,eAAeV,EAAW,OAAO;IAAG,UAAA;GAErE,CAAA,CACL;;EAhBT,UAAA;GAmBE,kBAACW,GAAD;IAAa,WAAU;IAAO,MAAM,kBAACD,GAAD,EAAS,MAAM,GAAK,CAAA;IAAG,UAAA;GAK9C,CAAA;GAEZE,IACC,kBAACC,IAAD;IAAY,UAAS;IAA4B;IAAO,eAAe,KAAKvC,EAAQ;GAAI,CAAA,IAExF,kBAAA1C,GAAA,EAAA,UAAA;IAEE,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,kBAACmF,GAAD;OAAW,WAAU;OAAQ,MAAA;OAAK,WAAU;OAA5C,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QAAqD,UAAAlE,EAAS;OAAU,CAAA,GACrF,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAkB,CAAA,CACpD;;MACX,kBAACkE,GAAD;OAAW,WAAU;OAAS,WAAU;OAAxC,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QACV,UAAAlE,EAAS,QAAQ,MAAQX,EAAI,SAAS,QAAQ,CAAC,CAAC;OAChD,CAAA,GACH,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAS,CAAA,CAC3C;;MACX,kBAAC6E,GAAD;OAAW,WAAU;OAAS,WAAU;OAAxC,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QACV,UAAAlE,EAAS,QAAQ,MAAQX,EAAI,SAAS,QAAQ,CAAC,CAAC;OAChD,CAAA,GACH,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAS,CAAA,CAC3C;;MACX,kBAAC6E,GAAD;OAAW,WAAU;OAAS,WAAU;OAAxC,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;QACV,UAAA3C;OACA,CAAA,GACH,kBAAC,KAAD;QAAG,WAAU;QAA8B,UAAA;OAAoB,CAAA,CACtD;;KACR;;IAGL,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,kBAAC4C,IAAD,EAAQ,WAAU,uEAAwE,CAAA,GAC1F,kBAACC,GAAD;OACE,aAAY;OACZ,OAAO7D;OACP,WAAW,MAAMC,GAAU,EAAE,OAAO,KAAK;OACzC,WAAU;MACX,CAAA,CACE;KACL,CAAA,GAAA,kBAAC,OAAD;MAAK,WAAU;MACb,UAAA,kBAAC,UAAD;OACE,cAAW;OACX,WAAU;OACV,OAAOI;OACP,WAAW,MAAMC,GAAc,EAAE,OAAO,KAA4B;OAJtE,UAAA;QAME,kBAAC,UAAD;SAAQ,OAAM;SAAM,UAAA;QAAiB,CAAA;QACrC,kBAAC,UAAD;SAAQ,OAAO7B,EAAe;SAAO,UAAA;QAAc,CAAA;QACnD,kBAAC,UAAD;SAAQ,OAAOA,EAAe;SAAO,UAAA;QAAc,CAAA;QACnD,kBAAC,UAAD;SAAQ,OAAOA,EAAe;SAAS,UAAA;QAAiB,CAAA;QACxD,kBAAC,UAAD;SAAQ,OAAOA,EAAe;SAAgB,UAAA;QAAiB,CAAA;QAC/D,kBAAC,UAAD;SAAQ,OAAOA,EAAe;SAAkB,UAAA;QAA0B,CAAA;OACpE;;KACL,CAAA,CACF;;IAGJgC,EAAiB,SAAS,IACzB,kBAAC,OAAD;KAAK,WAAU;KACZ,UAAAA,EAAiB,KAAK,MACrB,kBAACuB,IAAD,EAA+B,OAAM,GAAnBlD,EAAI,EAAe,CACtC;IACE,CAAA,IAEL,kBAACiF,GAAD;KACE,cAAa;KACb,OACE/D,KAAUK,MAAe,QAAQ,yBAAyB;KAE5D,aACEL,KAAUK,MAAe,QACrB,8CACA;KAEN,QACE,kBAACsC,GAAD;MACE,eAAeC,EAAW,OAAO;MACjC,UAAU,kBAACoB,GAAD,EAAU,WAAU,UAAW,CAAA;MAC1C,UAAA;KAEO,CAAA;IAEX,CAAA;GAEH,EAAA,CAAA;GAIHjD,KACC,mBAhUgF,EACpF,QACA,iBACI;IACJ,IAAMkB,IAAajD,EAAcF,CAAG,GAC9BoD,IAAOrD,EAAYC,CAAG,GACtBmF,IAAWnF,EAAI,YAAY,CAAC;IAElC,OACE,kBAAC,OAAD;KAAK,WAAU;KACb,UAAA,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA;OACE,kBAAC,OAAD;QAAK,WAAU;QACb,UAAA,kBAAC,OAAD;SAAK,WAAU;SAAf,UAAA,CACE,kBAAC,OAAD;UAAK,WAAU;UAAf,UAAA,CACE,kBAAC,OAAD;WAAK,WAAU;WAAwC,UAAAmD,EAAW;UAAU,CAAA,GAC5E,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;WAAI,WAAU;WAAqB,UAAApB,EAAiB/B,EAAI,OAAO,KAAKoD;UAAS,CAAA,GAC7E,kBAAC,KAAD;WAAG,WAAU;WAAyC,UAAAA;UAAQ,CAAA,CAC3D,EAAA,CAAA,CACF;SACL,CAAA,GAAA,kBAACS,GAAD;UAAQ,SAAQ;UAAQ,MAAK;UAAK,cAAW;UAAQ,SAASuB;UAAS,UAAA;SAE/D,CAAA,CACL;;OACF,CAAA;OAEL,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA;SAEE,kBAAC7B,GAAD,EAAA,UAAA,CACE,kBAAC8B,GAAD,EAAA,UACE,kBAACC,GAAD;UAAW,WAAU;UAAY,UAAA;SAA8B,CAAA,EACrD,CAAA,GACZ,kBAAC9B,GAAD;UAAa,WAAU;UAAvB,UAAA,CACE,kBAAC,OAAD;WAAK,WAAU;WAAf,UAAA,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;YAA8B,UAAA;WAAoB,CAAA,GAC/D,kBAAC,KAAD;YAAG,WAAU;YAAb,UAAA,CAAqC,KAAExD,EAAI,gBAAoB;WAC5D,CAAA,CAAA,EAAA,CAAA,GACJA,EAAI,WACH,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;YAA8B,UAAA;WAAiB,CAAA,GAC5D,kBAAC,KAAD;YAAG,WAAU;YAAb,UAAA,CAAqC,KAAEA,EAAI,QAAQ,OAAW;WAC3D,CAAA,CAAA,EAAA,CAAA,CAEJ;UAEL,CAAA,GAAA,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;WAAG,WAAU;WAAmC,UAAA;UAAoB,CAAA,GACpE,kBAAC,OAAD;WAAK,WAAU;WAAf,UAAA;YACG8C,EAAY9C,EAAI,IAAI;YACrB,kBAAC,QAAD;aAAM,WAAU;aAAe,UAAAA,EAAI;YAAW,CAAA;YAC9C,kBAAC,QAAD;aAAM,WAAU;aACb,UAAAA,EAAI,SAAS,WACV,qCACA;YACA,CAAA;WACH;UACF,CAAA,CAAA,EAAA,CAAA,CACM;SACT,CAAA,CAAA,EAAA,CAAA;SAGN,kBAACuD,GAAD,EAAA,UAAA,CACE,kBAAC8B,GAAD,EAAA,UAAA,CACE,kBAACC,GAAD;UAAW,WAAU;UAArB,UAAA,CACE,kBAACC,IAAD,EAAW,WAAU,UAAW,CAAA,GAAC,0BAExB;SACX,CAAA,GAAA,kBAACC,GAAD,EAAA,UAAiB,6CAA2D,CAAA,CAClE,EAAA,CAAA,GACZ,kBAAChC,GAAD,EAAA,UACE,kBAAC,OAAD;UAAK,WAAU;UACZ,UAAA5D,EAAa,KAAK,MAAQ;WACzB,IAAMgE,IAAgBtD,EAAiBN,GAAKQ,CAAG;WAC/C,OACE,kBAAC,OAAD;YAEE,WAAU;YAFZ,UAAA,CAIE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;aAAG,WAAU;aAAe,UAAAA;YAAO,CAAA,GACnC,kBAAC,KAAD;aAAG,WAAU;aACV,UAAAoD,IAAgB,IAAIA,MAAkB;YACtC,CAAA,CACA,EAAA,CAAA,GACL,kBAAC,OAAD;aAAK,WAAU;aACZ,UAAAA,IACC,kBAACI,GAAD;cAAwB,YAAYC,EAAqB;cACvD,UAAA,kBAACJ,GAAD;eACE,SAAQ;eACR,MAAK;eACL,eAAe,KAAKlB,EAAiB3C,GAAKQ,GAAK,EAAE;eAClD,UAAA;cAEO,CAAA;aACc,CAAA,IAExB,kBAACwD,GAAD;cAAwB,YAAYC,EAAqB;cACvD,UAAA,kBAACJ,GAAD;eACE,SAAQ;eACR,MAAK;eACL,eACE,KAAKlB,EAAiB3C,GAAKQ,GAAKR,EAAI,gBAAgB;eAEvD,UAAA;cAEO,CAAA;aACc,CAAA;YAEvB,CAAA,CACF;WAlCE,GAAAQ,CAkCF;UAET,CAAC;SACE,CAAA,EACM,CAAA,CACT,EAAA,CAAA;SAGL,OAAO,KAAK2E,CAAQ,CAAC,CAAC,SAAS,KAC9B,kBAAC5B,GAAD,EAAA,UAAA,CACE,kBAAC8B,GAAD,EAAA,UACE,kBAACC,GAAD;UAAW,WAAU;UAArB,UAAA,CACE,kBAACG,IAAD,EAAU,WAAU,UAAW,CAAA,GAAC,wBAEvB;SACD,CAAA,EAAA,CAAA,GACZ,kBAACjC,GAAD,EAAA,UACE,kBAAC,OAAD;UAAK,WAAU;UACZ,UAAA,OAAO,QAAQ2B,CAAQ,CAAC,CAAC,KAAK,CAACO,GAAKnF,OACnC,kBAAC,OAAD;WAAe,WAAU;WAAzB,UAAA,CACE,kBAAC,QAAD;YAAM,WAAU;YAAqB,UAAAmF;WAAU,CAAA,GAC/C,kBAAC,QAAD;YAAM,WAAU;YACb,UAAA,OAAOnF,KAAU,WAAWA,IAAQ,KAAK,UAAUA,CAAK;WACrD,CAAA,CACH;UALK,GAAAmF,CAKL,CACN;SACE,CAAA,EACM,CAAA,CACT,EAAA,CAAA;SAIR,kBAACnC,GAAD,EAAA,UAAA,CACE,kBAAC8B,GAAD,EAAA,UACE,kBAACC,GAAD;UAAW,WAAU;UAAY,UAAA;SAAmB,CAAA,EAC1C,CAAA,GACZ,kBAAC9B,GAAD,EAAA,UACE,kBAAC,OAAD;UAAK,WAAU;UAAf,UAAA;WACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;YAAsB,UAAA;WAAe,CAAA,GAClD,kBAAC,KAAD;YAAG,WAAU;YAAe,UAAAG,EAAmB3D,EAAI,WAAW;WAAK,CAAA,CAChE,EAAA,CAAA;WACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;YAAsB,UAAA;WAAe,CAAA,GAClD,kBAAC,KAAD;YAAG,WAAU;YAAe,UAAAA,EAAI;WAAe,CAAA,CAC5C,EAAA,CAAA;WACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;YAAsB,UAAA;WAAa,CAAA,GAChD,kBAAC,KAAD;YAAG,WAAU;YAAqB,UAAAA,EAAI;WAAa,CAAA,CAChD,EAAA,CAAA;WACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;YAAG,WAAU;YAAsB,UAAA;WAAkB,CAAA,GACrD,kBAAC,KAAD;YAAG,WAAU;YAAqB,UAAAA,EAAI;WAAM,CAAA,CACzC,EAAA,CAAA;UACF;SACM,CAAA,EAAA,CAAA,CACT,EAAA,CAAA;QACH;;OAEL,kBAAC,OAAD;QAAK,WAAU;QAAf,UAAA,CACE,kBAACgE,GAAD;SAAwB,YAAYC,EAAqB;SACvD,UAAA,kBAACJ,GAAD;UAAQ,SAAQ;UAAc,eAAe,KAAKxB,EAAgBrC,CAAG;UAArE,UAAA,CACE,kBAACmE,GAAD,EAAQ,WAAU,eAAgB,CAAA,GAAC,WAE7B;;QACc,CAAA,GACxB,kBAAC,OAAD;SAAK,WAAU;SAAf,UAAA,CACE,kBAACwB,IAAD;UAAM,IAAIC,EAAQ,iBAAiBxC,GAAM;UACvC,UAAA,kBAACS,GAAD;WAAQ,SAAQ;WAAU,UAAA;UAAqB,CAAA;SAC3C,CAAA,GACN,kBAACA,GAAD;UAAQ,SAAQ;UAAU,SAASuB;UAAS,UAAA;SAEpC,CAAA,CACL;QACF,CAAA,CAAA;;MACF;;IACF,CAAA;GAET,GAoIM;IAAoB,KAAKnD;IAAiB,eAAeP,EAAqB,IAAI;GAAI,CAAA;EAE9E;;AAEhB"}
|
|
1
|
+
{"version":3,"file":"InstalledPackagesPage.js","names":["_Fragment","GqlPackageKind","ENVIRONMENTS","PACKAGE_KIND_CONFIG","UNKNOWN_KIND","installSlug","pkg","installKind","kindConfigFor","kind","hasUpdate","latest","pinnedVersionFor","value","env","InstalledPackagesPage","useBotlit","packages","useInstalledPackages","uninstallLoading","useUninstallPackage","updateLoading","useUpdateInstalledPackage","usePinPackageVersion","search","setSearch","useState","refreshing","setRefreshing","kindFilter","setKindFilter","selectedPackageId","setSelectedPackageId","filteredPackages","useMemo","needle","matchesSearch","storePackageName","matchesKind","selectedPackage","updatesAvailable","handleCheckUpdates","refetch","handleUninstall","uninstall","toast","err","handleUpdate","update","handlePinVersion","pin","version","getModeIcon","mode","Link2","Copy","PackageCard","kindConfig","slug","updateAvailable","pinnedEnvironments","Card","CardContent","Badge","ArrowUpCircle","formatRelativeTime","pinnedVersion","Button","navigateTo","ExternalLink","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","e","Trash2","loading","PageLayout","i","RefreshCw","Package","PagePurpose","error","ErrorState","Fragment","GlassCard","Search","Input","PackageKind","EmptyState","Download","LoadMore","loadMore","bindings","onClose","CardHeader","CardTitle","GitBranch","CardDescription","Settings","key","Link","getPath"],"sources":["../../../src/botlit/pages/InstalledPackagesPage.tsx"],"sourcesContent":["/**\n * Installed Packages Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Package,\n Download,\n RefreshCw,\n Trash2,\n GitBranch,\n Link2,\n Copy,\n Settings,\n ArrowUpCircle,\n Search,\n ExternalLink,\n} from 'lucide-react';\nimport { toast } from 'sonner';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { LoadMore } from '../components/LoadMore';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useInstalledPackages,\n useUninstallPackage,\n useUpdateInstalledPackage,\n usePinPackageVersion,\n storePackageName,\n type InstalledPackageRecord,\n} from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { PackageKind as GqlPackageKind } from '../../generated/wspace-types';\nimport type { Environment, PackageKind } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nconst ENVIRONMENTS: Environment[] = ['DEV', 'STAGING', 'PROD'];\n\nconst PACKAGE_KIND_CONFIG: Record<string, { label: string; icon: string }> = {\n APP: { label: 'Bot', icon: '📱' },\n AGENT: { label: 'Agent', icon: '🤖' },\n SKILL: { label: 'Skill', icon: '⚡' },\n MCP_PACK: { label: 'MCP Pack', icon: '🔧' },\n PROMPT_TEMPLATE: { label: 'Template', icon: '📝' },\n PROMPT: { label: 'Prompt', icon: '📝' },\n RETRIEVAL_PROFILE: { label: 'Retrieval', icon: '🔍' },\n POLICY_BUNDLE: { label: 'Policy', icon: '🛡️' },\n CHANNEL_TEMPLATE: { label: 'Channel', icon: '📡' },\n A2A_AGENT: { label: 'A2A Agent', icon: '🔗' },\n KB_TEMPLATE: { label: 'KB Template', icon: '📚' },\n KNOWLEDGE_BASE: { label: 'Knowledge Base', icon: '📚' },\n INTEGRATION: { label: 'Integration', icon: '🔌' },\n TEMPLATE: { label: 'Template', icon: '📝' },\n TOOL: { label: 'Tool', icon: '🔧' },\n WORKFLOW: { label: 'Workflow', icon: '🔀' },\n};\n\nconst UNKNOWN_KIND = { label: 'Package', icon: '📦' };\n\n/** Store slug for an install, falling back to the package id when unresolved. */\nfunction installSlug(pkg: InstalledPackageRecord): string {\n return pkg.package?.slug ?? pkg.packageId;\n}\n\nfunction installKind(pkg: InstalledPackageRecord): string | undefined {\n return pkg.package?.kind;\n}\n\nfunction kindConfigFor(pkg: InstalledPackageRecord) {\n const kind = installKind(pkg);\n return (kind && PACKAGE_KIND_CONFIG[kind]) || UNKNOWN_KIND;\n}\n\nfunction hasUpdate(pkg: InstalledPackageRecord): boolean {\n const latest = pkg.package?.version;\n return Boolean(latest && latest !== pkg.installedVersion);\n}\n\n/** `pinnedByEnv` is free-form JSON — read one environment's pin defensively. */\nfunction pinnedVersionFor(pkg: InstalledPackageRecord, env: Environment): string | undefined {\n const value = pkg.pinnedByEnv?.[env];\n return typeof value === 'string' && value !== '' ? value : undefined;\n}\n\nexport const InstalledPackagesPage: FC = () => {\n const { navigateTo, getPath } = useBotlit();\n const {\n data: packages,\n loading,\n error,\n refetch,\n hasMore,\n loadingMore,\n loadMore,\n } = useInstalledPackages();\n const { uninstall, loading: uninstallLoading } = useUninstallPackage();\n const { update, loading: updateLoading } = useUpdateInstalledPackage();\n const { pin } = usePinPackageVersion();\n\n const [search, setSearch] = useState('');\n const [refreshing, setRefreshing] = useState(false);\n const [kindFilter, setKindFilter] = useState<PackageKind | 'all'>('all');\n const [selectedPackageId, setSelectedPackageId] = useState<string | null>(null);\n\n const filteredPackages = useMemo(() => {\n const needle = search.trim().toLowerCase();\n return packages.filter((pkg) => {\n const matchesSearch =\n !needle ||\n installSlug(pkg).toLowerCase().includes(needle) ||\n storePackageName(pkg.package).toLowerCase().includes(needle);\n const matchesKind = kindFilter === 'all' || installKind(pkg) === kindFilter;\n return matchesSearch && matchesKind;\n });\n }, [packages, search, kindFilter]);\n\n const selectedPackage = useMemo(\n () => packages.find((pkg) => pkg.id === selectedPackageId) ?? null,\n [packages, selectedPackageId]\n );\n\n const updatesAvailable = useMemo(() => packages.filter(hasUpdate).length, [packages]);\n\n const handleCheckUpdates = async () => {\n setRefreshing(true);\n try {\n await refetch();\n } finally {\n setRefreshing(false);\n }\n };\n\n const handleUninstall = async (pkg: InstalledPackageRecord) => {\n if (!confirm('Are you sure you want to uninstall this package?')) return;\n try {\n await uninstall(pkg.id);\n toast.success(`Uninstalled \"${storePackageName(pkg.package) || installSlug(pkg)}\"`);\n setSelectedPackageId(null);\n void refetch();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to uninstall package');\n }\n };\n\n const handleUpdate = async (pkg: InstalledPackageRecord) => {\n const latest = pkg.package?.version;\n if (!latest) return;\n try {\n await update({ installedId: pkg.id, input: { installedVersion: latest } });\n toast.success(`Updated to v${latest}`);\n void refetch();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to update package');\n }\n };\n\n const handlePinVersion = async (\n pkg: InstalledPackageRecord,\n env: Environment,\n version: string\n ) => {\n try {\n await pin({\n installedId: pkg.id,\n environment: env,\n version,\n pinnedByEnv: pkg.pinnedByEnv,\n });\n toast.success(version ? `Pinned ${env} to v${version}` : `Unpinned ${env}`);\n void refetch();\n } catch (err) {\n toast.error(err instanceof Error ? err.message : 'Failed to change version pin');\n }\n };\n\n const getModeIcon = (mode: string) =>\n mode === 'LINKED' ? (\n <Link2 className=\"h-4 w-4 text-status-info-text\" />\n ) : (\n <Copy className=\"h-4 w-4 text-status-warning-text\" />\n );\n\n const PackageCard: FC<{ pkg: InstalledPackageRecord }> = ({ pkg }) => {\n const kindConfig = kindConfigFor(pkg);\n const slug = installSlug(pkg);\n const updateAvailable = hasUpdate(pkg);\n const pinnedEnvironments = ENVIRONMENTS.filter((env) => pinnedVersionFor(pkg, env));\n\n return (\n <Card\n className=\"hover:shadow-md transition-shadow cursor-pointer\"\n onClick={() => setSelectedPackageId(pkg.id)}\n >\n <CardContent className=\"pt-6\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div className=\"p-2 rounded-lg bg-bg-sunken text-2xl\">{kindConfig.icon}</div>\n <div>\n <div className=\"flex items-center gap-2\">\n <h3 className=\"font-semibold\">{storePackageName(pkg.package) || slug}</h3>\n {updateAvailable && (\n <Badge variant=\"warning\" className=\"gap-1\">\n <ArrowUpCircle className=\"h-3 w-3\" />\n Update\n </Badge>\n )}\n </div>\n <p className=\"text-sm text-text-secondary font-mono\">{slug}</p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n {getModeIcon(pkg.mode)}\n <Badge variant=\"outline\">{kindConfig.label}</Badge>\n </div>\n </div>\n\n <div className=\"mt-4 grid grid-cols-3 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Installed Version</p>\n <p className=\"font-medium font-mono\">v{pkg.installedVersion}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Mode</p>\n <p className=\"font-medium flex items-center gap-1\">\n {getModeIcon(pkg.mode)}\n {pkg.mode}\n </p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Installed</p>\n <p className=\"font-medium\">{formatRelativeTime(pkg.installedAt)}</p>\n </div>\n </div>\n\n {/* Environment Pins */}\n {pinnedEnvironments.length > 0 && (\n <div className=\"mt-4 pt-4 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary mb-2\">Pinned Versions</p>\n <div className=\"flex gap-2\">\n {ENVIRONMENTS.map((env) => {\n const pinnedVersion = pinnedVersionFor(pkg, env);\n return (\n <Badge\n key={env}\n variant={pinnedVersion ? 'default' : 'outline'}\n className=\"text-xs\"\n >\n {env}: {pinnedVersion ?? 'latest'}\n </Badge>\n );\n })}\n </div>\n </div>\n )}\n\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n navigateTo(`store/package/${slug}`);\n }}\n >\n <ExternalLink className=\"h-4 w-4 mr-1\" />\n View in Store\n </Button>\n {updateAvailable && (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n void handleUpdate(pkg);\n }}\n isLoading={updateLoading}\n >\n <ArrowUpCircle className=\"h-4 w-4 mr-1\" />\n Update\n </Button>\n </BotmanorPermissionGate>\n )}\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_DELETE}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Uninstall package\"\n className=\"text-status-error-text hover:text-status-error-text\"\n onClick={(e) => {\n e.stopPropagation();\n void handleUninstall(pkg);\n }}\n isLoading={uninstallLoading}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </CardContent>\n </Card>\n );\n };\n\n const PackageDetailModal: FC<{ pkg: InstalledPackageRecord; onClose: () => void }> = ({\n pkg,\n onClose,\n }) => {\n const kindConfig = kindConfigFor(pkg);\n const slug = installSlug(pkg);\n const bindings = pkg.bindings ?? {};\n\n return (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50\">\n <div className=\"bg-bg-surface rounded-lg shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto\">\n <div className=\"p-6 border-b border-border-subtle\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div className=\"p-3 rounded-lg bg-bg-sunken text-3xl\">{kindConfig.icon}</div>\n <div>\n <h2 className=\"text-xl font-bold\">{storePackageName(pkg.package) || slug}</h2>\n <p className=\"text-sm text-text-secondary font-mono\">{slug}</p>\n </div>\n </div>\n <Button variant=\"ghost\" size=\"sm\" aria-label=\"Close\" onClick={onClose}>\n ×\n </Button>\n </div>\n </div>\n\n <div className=\"p-6 space-y-6\">\n {/* Version Info */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Version Information</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-sm text-text-secondary\">Installed Version</p>\n <p className=\"font-mono font-medium\">v{pkg.installedVersion}</p>\n </div>\n {pkg.package && (\n <div>\n <p className=\"text-sm text-text-secondary\">Latest Version</p>\n <p className=\"font-mono font-medium\">v{pkg.package.version}</p>\n </div>\n )}\n </div>\n\n <div>\n <p className=\"text-sm text-text-secondary mb-2\">Installation Mode</p>\n <div className=\"flex items-center gap-2\">\n {getModeIcon(pkg.mode)}\n <span className=\"font-medium\">{pkg.mode}</span>\n <span className=\"text-sm text-text-secondary\">\n {pkg.mode === 'LINKED'\n ? '- Receives updates automatically'\n : '- Independent copy, no auto-updates'}\n </span>\n </div>\n </div>\n </CardContent>\n </Card>\n\n {/* Environment Pinning */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <GitBranch className=\"h-4 w-4\" />\n Environment Version Pins\n </CardTitle>\n <CardDescription>Pin specific versions for each environment</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n {ENVIRONMENTS.map((env) => {\n const pinnedVersion = pinnedVersionFor(pkg, env);\n return (\n <div\n key={env}\n className=\"flex items-center justify-between p-3 bg-bg-sunken rounded-lg\"\n >\n <div>\n <p className=\"font-medium\">{env}</p>\n <p className=\"text-sm text-text-secondary font-mono\">\n {pinnedVersion ? `v${pinnedVersion}` : 'Using latest'}\n </p>\n </div>\n <div className=\"flex gap-2\">\n {pinnedVersion ? (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handlePinVersion(pkg, env, '')}\n >\n Unpin\n </Button>\n </BotmanorPermissionGate>\n ) : (\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_UPDATE}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() =>\n void handlePinVersion(pkg, env, pkg.installedVersion)\n }\n >\n Pin Current\n </Button>\n </BotmanorPermissionGate>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </CardContent>\n </Card>\n\n {/* Bindings */}\n {Object.keys(bindings).length > 0 && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base flex items-center gap-2\">\n <Settings className=\"h-4 w-4\" />\n Configuration Bindings\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {Object.entries(bindings).map(([key, value]) => (\n <div key={key} className=\"flex justify-between p-2 bg-bg-sunken rounded\">\n <span className=\"font-mono text-sm\">{key}</span>\n <span className=\"font-mono text-sm text-text-secondary\">\n {typeof value === 'string' ? value : JSON.stringify(value)}\n </span>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n )}\n\n {/* Metadata */}\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">Metadata</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid grid-cols-2 gap-4 text-sm\">\n <div>\n <p className=\"text-text-secondary\">Installed At</p>\n <p className=\"font-medium\">{formatRelativeTime(pkg.installedAt)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Installed By</p>\n <p className=\"font-medium\">{pkg.installedBy}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Package ID</p>\n <p className=\"font-mono text-xs\">{pkg.packageId}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Installation ID</p>\n <p className=\"font-mono text-xs\">{pkg.id}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"p-6 border-t border-border-subtle flex justify-between\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.STORE_DELETE}>\n <Button variant=\"destructive\" onClick={() => void handleUninstall(pkg)}>\n <Trash2 className=\"h-4 w-4 mr-2\" />\n Uninstall\n </Button>\n </BotmanorPermissionGate>\n <div className=\"flex gap-2\">\n <Link to={getPath(`store/package/${slug}`)}>\n <Button variant=\"outline\">View in Store</Button>\n </Link>\n <Button variant=\"outline\" onClick={onClose}>\n Close\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n };\n\n if (loading) {\n return (\n <PageLayout title=\"Installed Packages\" description=\"Manage installed store packages\">\n <div className=\"space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\" />\n ))}\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Installed Packages\"\n description=\"Manage packages installed from the BotManor Store\"\n actions={\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n leftIcon={<RefreshCw size={16} />}\n onClick={() => void handleCheckUpdates()}\n isLoading={refreshing}\n >\n Check Updates\n </Button>\n <Button leftIcon={<Package size={16} />} onClick={() => navigateTo('store')}>\n Browse Store\n </Button>\n </div>\n }\n >\n <PagePurpose className=\"mb-6\" icon={<Package size={18} />}>\n These are the packages you have installed from the BotManor Store and how they are wired\n into your workspace. Manage each one’s installation mode (linked, so it auto-updates,\n or forked as an independent copy), pin specific versions per environment, and update or\n uninstall — this is your dependency manager for everything you pulled from the store.\n </PagePurpose>\n\n {error ? (\n <ErrorState resource=\"installed packages\" error={error} onRetry={() => void refetch()} />\n ) : (\n <>\n {/* Summary Cards */}\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-6\">\n <GlassCard treatment=\"glass\" glow className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">{packages.length}</p>\n <p className=\"text-sm text-text-secondary\">Total Installed</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {packages.filter((pkg) => pkg.mode === 'LINKED').length}\n </p>\n <p className=\"text-sm text-text-secondary\">Linked</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {packages.filter((pkg) => pkg.mode === 'FORKED').length}\n </p>\n <p className=\"text-sm text-text-secondary\">Forked</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-6 text-center\">\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {updatesAvailable}\n </p>\n <p className=\"text-sm text-text-secondary\">Updates Available</p>\n </GlassCard>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col md:flex-row gap-4 mb-6\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search packages...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <div className=\"flex gap-2\">\n <select\n aria-label=\"Filter by package type\"\n className=\"flex h-10 rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={kindFilter}\n onChange={(e) => setKindFilter(e.target.value as PackageKind | 'all')}\n >\n <option value=\"all\">All Types</option>\n <option value={GqlPackageKind.Agent}>Agents</option>\n <option value={GqlPackageKind.Skill}>Skills</option>\n <option value={GqlPackageKind.McpPack}>MCP Packs</option>\n <option value={GqlPackageKind.PromptTemplate}>Templates</option>\n <option value={GqlPackageKind.RetrievalProfile}>Retrieval Profiles</option>\n </select>\n </div>\n </div>\n\n {/* Package List */}\n {filteredPackages.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {filteredPackages.map((pkg) => (\n <PackageCard key={pkg.id} pkg={pkg} />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={\n search || kindFilter !== 'all' ? 'No matching packages' : 'No packages installed'\n }\n description={\n search || kindFilter !== 'all'\n ? 'Try adjusting your search or type filter.'\n : 'Browse the BotManor Store to find agents, skills, and tools to install.'\n }\n action={\n <Button\n onClick={() => navigateTo('store')}\n leftIcon={<Download className=\"h-4 w-4\" />}\n >\n Browse Store\n </Button>\n }\n />\n )}\n <LoadMore\n hasMore={hasMore}\n loadingMore={loadingMore}\n onLoadMore={() => void loadMore()}\n loadedCount={packages.length}\n />\n </>\n )}\n\n {/* Detail Modal */}\n {selectedPackage && (\n <PackageDetailModal pkg={selectedPackage} onClose={() => setSelectedPackageId(null)} />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
@@ -244,7 +244,7 @@ var I = () => {
|
|
|
244
244
|
})]
|
|
245
245
|
}),
|
|
246
246
|
J && /* @__PURE__ */ O("div", {
|
|
247
|
-
className: "fixed inset-0 bg-
|
|
247
|
+
className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-50",
|
|
248
248
|
children: /* @__PURE__ */ k(r, {
|
|
249
249
|
className: "w-full max-w-lg",
|
|
250
250
|
children: [/* @__PURE__ */ k(o, { children: [/* @__PURE__ */ O(s, { children: I("botlit.mcpServers.form.title", "Add MCP Server") }), /* @__PURE__ */ O(a, { children: I("botlit.mcpServers.form.description", "Connect a new MCP server") })] }), /* @__PURE__ */ k(i, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPServersPage.js","names":["MCPServersPage","t","useTr","useBotlit","servers","useMCPServers","connectServer","connectResult","useCreateMCPServer","deleteServer","deleteResult","useDeleteMCPServer","testConnection","testResult","useTestMCPConnection","showAddModal","setShowAddModal","useState","newServer","setNewServer","handleConnect","err","toast","refetch","handleDisconnect","server","handleTest","PageLayout","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","Button","Plus","PagePurpose","Plug","loading","i","error","ErrorState","Card","CardHeader","isMCPServerHealthy","PlugZap","CardTitle","CardDescription","mcpServerDescription","StatusBadge","CardContent","Badge","formatRelativeTime","mcpServerEndpoint","Settings","navigateTo","Trash2","EmptyState","GlassCard","preset","FormField","Input"],"sources":["../../../src/botlit/pages/MCPServersPage.tsx"],"sourcesContent":["/**\n * MCP Servers Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Plus, Plug, PlugZap, Settings, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, FormField } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useMCPServers,\n useCreateMCPServer,\n useDeleteMCPServer,\n useTestMCPConnection,\n isMCPServerHealthy,\n mcpServerDescription,\n mcpServerEndpoint,\n type MCPServerRecord,\n} from '../hooks/useMCPServers';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { MCPTransport } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nexport const MCPServersPage: FC = () => {\n const t = useTr();\n const { navigateTo } = useBotlit();\n const { data: servers, loading, error, refetch } = useMCPServers();\n const [connectServer, connectResult] = useCreateMCPServer();\n const [deleteServer, deleteResult] = useDeleteMCPServer();\n const [testConnection, testResult] = useTestMCPConnection();\n const [showAddModal, setShowAddModal] = useState(false);\n const [newServer, setNewServer] = useState({\n name: '',\n description: '',\n transport: 'HTTP_JSON' as MCPTransport,\n baseUrl: '',\n });\n\n const handleConnect = async () => {\n if (!newServer.name || !newServer.baseUrl) return;\n\n try {\n await connectServer({\n name: newServer.name,\n type: newServer.transport,\n config: {\n url: newServer.baseUrl,\n description: newServer.description,\n },\n });\n } catch (err) {\n // Keep the dialog open so the operator can correct and retry — closing it\n // here is what made failed writes look like successes.\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.connectError', 'Failed to connect MCP server')\n );\n return;\n }\n\n toast.success(\n t('botlit.mcpServers.toast.connectSuccess', 'Connected \"{{name}}\"', {\n name: newServer.name,\n })\n );\n void refetch();\n setNewServer({ name: '', description: '', transport: 'HTTP_JSON', baseUrl: '' });\n setShowAddModal(false);\n };\n\n const handleDisconnect = async (server: MCPServerRecord) => {\n try {\n await deleteServer(server.id);\n toast.success(\n t('botlit.mcpServers.toast.disconnectSuccess', 'Disconnected \"{{name}}\"', {\n name: server.name,\n })\n );\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.disconnectError', 'Failed to disconnect MCP server')\n );\n }\n };\n\n const handleTest = async (server: MCPServerRecord) => {\n try {\n const ok = await testConnection(server.id);\n if (ok) {\n toast.success(\n t('botlit.mcpServers.toast.reachable', '\"{{name}}\" is reachable', {\n name: server.name,\n })\n );\n } else {\n toast.error(\n t('botlit.mcpServers.toast.unreachable', '\"{{name}}\" did not respond', {\n name: server.name,\n })\n );\n }\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.testError', 'Failed to test MCP connection')\n );\n }\n };\n\n return (\n <PageLayout\n title={t('botlit.mcpServers.title', 'MCP Servers')}\n description={t(\n 'botlit.mcpServers.description',\n 'Connect Model Context Protocol servers to extend agent capabilities'\n )}\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Plug size={18} />}>\n {t(\n 'botlit.mcpServers.purpose',\n 'MCP (Model Context Protocol) servers are how your agents reach the outside world — they expose real tools an agent can call, like searching the web, reading a GitHub repo, querying a database or posting to Slack. Connect a server here and its tools become available to your agents (gated by your tool policies), turning a chatbot into something that can take action.'\n )}\n </PagePurpose>\n\n {/* Server List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"MCP servers\" error={error} onRetry={() => void refetch()} />\n ) : servers.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {servers.map((server: MCPServerRecord) => (\n <Card key={server.id}>\n <CardHeader className=\"flex flex-row items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div\n className={`p-2 rounded-lg ${\n isMCPServerHealthy(server.status)\n ? 'bg-status-success-bg-subtle'\n : 'bg-bg-sunken'\n }`}\n >\n {isMCPServerHealthy(server.status) ? (\n <PlugZap className=\"h-5 w-5 text-status-success-text\" />\n ) : (\n <Plug className=\"h-5 w-5 text-text-secondary\" />\n )}\n </div>\n <div>\n <CardTitle className=\"text-base\">{server.name}</CardTitle>\n <CardDescription>{mcpServerDescription(server)}</CardDescription>\n </div>\n </div>\n <StatusBadge status={server.status} />\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {/* Transport Info */}\n <div className=\"flex flex-wrap items-center gap-4 text-sm\">\n <Badge variant=\"outline\" className=\"capitalize\">\n {server.type.toLowerCase().replace('_', ' ')}\n </Badge>\n {server.lastConnectedAt && (\n <span className=\"text-text-secondary\">\n {t('botlit.botsList.createdLabel', 'Created')}{' '}\n {formatRelativeTime(server.lastConnectedAt)}\n </span>\n )}\n </div>\n\n {/* Endpoint */}\n {mcpServerEndpoint(server) && (\n <p className=\"truncate text-sm text-text-secondary\">\n {mcpServerEndpoint(server)}\n </p>\n )}\n\n {server.errorMessage && (\n <p className=\"text-sm text-status-error-text\">{server.errorMessage}</p>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_TEST}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleTest(server)}\n isLoading={testResult.loading}\n >\n {t('botlit.mcpServers.actions.testConnection', 'Test connection')}\n </Button>\n </BotmanorPermissionGate>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n leftIcon={<Settings size={14} />}\n onClick={() => navigateTo(`mcp/${server.id}`)}\n >\n {t('botlit.mcpServers.actions.configure', 'Configure')}\n </Button>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_DELETE}>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"ml-auto\"\n aria-label={`Disconnect ${server.name}`}\n onClick={() => void handleDisconnect(server)}\n isLoading={deleteResult.loading}\n >\n <Trash2 size={16} />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={t('botlit.mcpServers.empty.title', 'No MCP servers connected')}\n description={t(\n 'botlit.mcpServers.empty.description',\n 'Connect MCP servers to give your agents access to external tools and resources.'\n )}\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n\n {/* Available MCP Servers */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.mcpServers.presets.title', 'Popular MCP Servers')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.mcpServers.presets.description', 'Quick-add common MCP servers')}\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {[\n {\n name: t('botlit.mcpServers.presets.github', 'GitHub'),\n description: t(\n 'botlit.mcpServers.presets.githubDesc',\n 'Repository management and code operations'\n ),\n baseUrl: 'https://mcp.github.com',\n },\n {\n name: t('botlit.mcpServers.presets.filesystem', 'Filesystem'),\n description: t(\n 'botlit.mcpServers.presets.filesystemDesc',\n 'Local file system access'\n ),\n baseUrl: 'http://localhost:3001',\n },\n {\n name: t('botlit.mcpServers.presets.braveSearch', 'Brave Search'),\n description: t(\n 'botlit.mcpServers.presets.braveSearchDesc',\n 'Web search capabilities'\n ),\n baseUrl: 'https://mcp.search.brave.com',\n },\n {\n name: t('botlit.mcpServers.presets.postgres', 'PostgreSQL'),\n description: t(\n 'botlit.mcpServers.presets.postgresDesc',\n 'Database queries and management'\n ),\n baseUrl: 'http://localhost:3002',\n },\n {\n name: t('botlit.mcpServers.presets.slack', 'Slack'),\n description: t(\n 'botlit.mcpServers.presets.slackDesc',\n 'Slack messaging integration'\n ),\n baseUrl: 'https://mcp.slack.com',\n },\n {\n name: t('botlit.mcpServers.presets.puppeteer', 'Puppeteer'),\n description: t('botlit.mcpServers.presets.puppeteerDesc', 'Browser automation'),\n baseUrl: 'http://localhost:3003',\n },\n ].map((preset) => (\n <button\n key={preset.name}\n className=\"p-4 text-left border border-border-subtle rounded-lg hover:bg-accent transition-colors\"\n onClick={() => {\n setNewServer({\n name: preset.name,\n description: preset.description,\n transport: 'HTTP_JSON',\n baseUrl: preset.baseUrl,\n });\n setShowAddModal(true);\n }}\n >\n <p className=\"font-medium\">{preset.name}</p>\n <p className=\"text-sm text-text-secondary mt-1\">{preset.description}</p>\n </button>\n ))}\n </div>\n </GlassCard>\n\n {/* Add Server Modal */}\n {showAddModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-lg\">\n <CardHeader>\n <CardTitle>{t('botlit.mcpServers.form.title', 'Add MCP Server')}</CardTitle>\n <CardDescription>\n {t('botlit.mcpServers.form.description', 'Connect a new MCP server')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label={t('botlit.mcpServers.form.nameLabel', 'Server Name')} required>\n <Input\n placeholder={t('botlit.mcpServers.form.namePlaceholder', 'e.g., GitHub')}\n value={newServer.name}\n onChange={(e) => setNewServer({ ...newServer, name: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.descriptionLabel', 'Description')}>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.descriptionPlaceholder',\n 'What does this server do?'\n )}\n value={newServer.description}\n onChange={(e) => setNewServer({ ...newServer, description: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.transportLabel', 'Transport')}>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={newServer.transport}\n onChange={(e) =>\n setNewServer({ ...newServer, transport: e.target.value as MCPTransport })\n }\n >\n <option value=\"HTTP_JSON\">HTTP JSON</option>\n <option value=\"JSON_RPC\">JSON RPC</option>\n <option value=\"SSE\">Server-Sent Events</option>\n <option value=\"CUSTOM\">Custom</option>\n </select>\n </FormField>\n <FormField label={t('botlit.mcpServers.form.baseUrlLabel', 'Base URL')} required>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.baseUrlPlaceholder',\n 'e.g., https://mcp.example.com'\n )}\n value={newServer.baseUrl}\n onChange={(e) => setNewServer({ ...newServer, baseUrl: e.target.value })}\n />\n </FormField>\n <div className=\"flex justify-end gap-2 pt-4\">\n <Button variant=\"outline\" onClick={() => setShowAddModal(false)}>\n {t('botlit.mcpServers.actions.cancel', 'Cancel')}\n </Button>\n <Button\n onClick={handleConnect}\n isLoading={connectResult.loading}\n disabled={!newServer.name || !newServer.baseUrl}\n >\n {t('botlit.mcpServers.actions.connect', 'Connect')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MCPServersPage.js","names":["MCPServersPage","t","useTr","useBotlit","servers","useMCPServers","connectServer","connectResult","useCreateMCPServer","deleteServer","deleteResult","useDeleteMCPServer","testConnection","testResult","useTestMCPConnection","showAddModal","setShowAddModal","useState","newServer","setNewServer","handleConnect","err","toast","refetch","handleDisconnect","server","handleTest","PageLayout","BotmanorPermissionGate","BOTMANOR_PERMISSIONS","Button","Plus","PagePurpose","Plug","loading","i","error","ErrorState","Card","CardHeader","isMCPServerHealthy","PlugZap","CardTitle","CardDescription","mcpServerDescription","StatusBadge","CardContent","Badge","formatRelativeTime","mcpServerEndpoint","Settings","navigateTo","Trash2","EmptyState","GlassCard","preset","FormField","Input"],"sources":["../../../src/botlit/pages/MCPServersPage.tsx"],"sourcesContent":["/**\n * MCP Servers Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport { Plus, Plug, PlugZap, Settings, Trash2 } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTr } from '../../shared/hooks/useTr';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input, FormField } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport {\n useMCPServers,\n useCreateMCPServer,\n useDeleteMCPServer,\n useTestMCPConnection,\n isMCPServerHealthy,\n mcpServerDescription,\n mcpServerEndpoint,\n type MCPServerRecord,\n} from '../hooks/useMCPServers';\nimport { formatRelativeTime } from '../utils/formatters';\nimport type { MCPTransport } from '../types';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nexport const MCPServersPage: FC = () => {\n const t = useTr();\n const { navigateTo } = useBotlit();\n const { data: servers, loading, error, refetch } = useMCPServers();\n const [connectServer, connectResult] = useCreateMCPServer();\n const [deleteServer, deleteResult] = useDeleteMCPServer();\n const [testConnection, testResult] = useTestMCPConnection();\n const [showAddModal, setShowAddModal] = useState(false);\n const [newServer, setNewServer] = useState({\n name: '',\n description: '',\n transport: 'HTTP_JSON' as MCPTransport,\n baseUrl: '',\n });\n\n const handleConnect = async () => {\n if (!newServer.name || !newServer.baseUrl) return;\n\n try {\n await connectServer({\n name: newServer.name,\n type: newServer.transport,\n config: {\n url: newServer.baseUrl,\n description: newServer.description,\n },\n });\n } catch (err) {\n // Keep the dialog open so the operator can correct and retry — closing it\n // here is what made failed writes look like successes.\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.connectError', 'Failed to connect MCP server')\n );\n return;\n }\n\n toast.success(\n t('botlit.mcpServers.toast.connectSuccess', 'Connected \"{{name}}\"', {\n name: newServer.name,\n })\n );\n void refetch();\n setNewServer({ name: '', description: '', transport: 'HTTP_JSON', baseUrl: '' });\n setShowAddModal(false);\n };\n\n const handleDisconnect = async (server: MCPServerRecord) => {\n try {\n await deleteServer(server.id);\n toast.success(\n t('botlit.mcpServers.toast.disconnectSuccess', 'Disconnected \"{{name}}\"', {\n name: server.name,\n })\n );\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.disconnectError', 'Failed to disconnect MCP server')\n );\n }\n };\n\n const handleTest = async (server: MCPServerRecord) => {\n try {\n const ok = await testConnection(server.id);\n if (ok) {\n toast.success(\n t('botlit.mcpServers.toast.reachable', '\"{{name}}\" is reachable', {\n name: server.name,\n })\n );\n } else {\n toast.error(\n t('botlit.mcpServers.toast.unreachable', '\"{{name}}\" did not respond', {\n name: server.name,\n })\n );\n }\n void refetch();\n } catch (err) {\n toast.error(\n err instanceof Error\n ? err.message\n : t('botlit.mcpServers.toast.testError', 'Failed to test MCP connection')\n );\n }\n };\n\n return (\n <PageLayout\n title={t('botlit.mcpServers.title', 'MCP Servers')}\n description={t(\n 'botlit.mcpServers.description',\n 'Connect Model Context Protocol servers to extend agent capabilities'\n )}\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<Plug size={18} />}>\n {t(\n 'botlit.mcpServers.purpose',\n 'MCP (Model Context Protocol) servers are how your agents reach the outside world — they expose real tools an agent can call, like searching the web, reading a GitHub repo, querying a database or posting to Slack. Connect a server here and its tools become available to your agents (gated by your tool policies), turning a chatbot into something that can take action.'\n )}\n </PagePurpose>\n\n {/* Server List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"MCP servers\" error={error} onRetry={() => void refetch()} />\n ) : servers.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {servers.map((server: MCPServerRecord) => (\n <Card key={server.id}>\n <CardHeader className=\"flex flex-row items-start justify-between\">\n <div className=\"flex items-start gap-3\">\n <div\n className={`p-2 rounded-lg ${\n isMCPServerHealthy(server.status)\n ? 'bg-status-success-bg-subtle'\n : 'bg-bg-sunken'\n }`}\n >\n {isMCPServerHealthy(server.status) ? (\n <PlugZap className=\"h-5 w-5 text-status-success-text\" />\n ) : (\n <Plug className=\"h-5 w-5 text-text-secondary\" />\n )}\n </div>\n <div>\n <CardTitle className=\"text-base\">{server.name}</CardTitle>\n <CardDescription>{mcpServerDescription(server)}</CardDescription>\n </div>\n </div>\n <StatusBadge status={server.status} />\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {/* Transport Info */}\n <div className=\"flex flex-wrap items-center gap-4 text-sm\">\n <Badge variant=\"outline\" className=\"capitalize\">\n {server.type.toLowerCase().replace('_', ' ')}\n </Badge>\n {server.lastConnectedAt && (\n <span className=\"text-text-secondary\">\n {t('botlit.botsList.createdLabel', 'Created')}{' '}\n {formatRelativeTime(server.lastConnectedAt)}\n </span>\n )}\n </div>\n\n {/* Endpoint */}\n {mcpServerEndpoint(server) && (\n <p className=\"truncate text-sm text-text-secondary\">\n {mcpServerEndpoint(server)}\n </p>\n )}\n\n {server.errorMessage && (\n <p className=\"text-sm text-status-error-text\">{server.errorMessage}</p>\n )}\n\n {/* Actions */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_TEST}>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => void handleTest(server)}\n isLoading={testResult.loading}\n >\n {t('botlit.mcpServers.actions.testConnection', 'Test connection')}\n </Button>\n </BotmanorPermissionGate>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n leftIcon={<Settings size={14} />}\n onClick={() => navigateTo(`mcp/${server.id}`)}\n >\n {t('botlit.mcpServers.actions.configure', 'Configure')}\n </Button>\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_DELETE}>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"ml-auto\"\n aria-label={`Disconnect ${server.name}`}\n onClick={() => void handleDisconnect(server)}\n isLoading={deleteResult.loading}\n >\n <Trash2 size={16} />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-generic\"\n title={t('botlit.mcpServers.empty.title', 'No MCP servers connected')}\n description={t(\n 'botlit.mcpServers.empty.description',\n 'Connect MCP servers to give your agents access to external tools and resources.'\n )}\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.MCP_CREATE}>\n <Button leftIcon={<Plus size={16} />} onClick={() => setShowAddModal(true)}>\n {t('botlit.mcpServers.actions.add', 'Add MCP Server')}\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n\n {/* Available MCP Servers */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold tracking-tight text-text-primary\">\n {t('botlit.mcpServers.presets.title', 'Popular MCP Servers')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {t('botlit.mcpServers.presets.description', 'Quick-add common MCP servers')}\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-3 gap-4\">\n {[\n {\n name: t('botlit.mcpServers.presets.github', 'GitHub'),\n description: t(\n 'botlit.mcpServers.presets.githubDesc',\n 'Repository management and code operations'\n ),\n baseUrl: 'https://mcp.github.com',\n },\n {\n name: t('botlit.mcpServers.presets.filesystem', 'Filesystem'),\n description: t(\n 'botlit.mcpServers.presets.filesystemDesc',\n 'Local file system access'\n ),\n baseUrl: 'http://localhost:3001',\n },\n {\n name: t('botlit.mcpServers.presets.braveSearch', 'Brave Search'),\n description: t(\n 'botlit.mcpServers.presets.braveSearchDesc',\n 'Web search capabilities'\n ),\n baseUrl: 'https://mcp.search.brave.com',\n },\n {\n name: t('botlit.mcpServers.presets.postgres', 'PostgreSQL'),\n description: t(\n 'botlit.mcpServers.presets.postgresDesc',\n 'Database queries and management'\n ),\n baseUrl: 'http://localhost:3002',\n },\n {\n name: t('botlit.mcpServers.presets.slack', 'Slack'),\n description: t(\n 'botlit.mcpServers.presets.slackDesc',\n 'Slack messaging integration'\n ),\n baseUrl: 'https://mcp.slack.com',\n },\n {\n name: t('botlit.mcpServers.presets.puppeteer', 'Puppeteer'),\n description: t('botlit.mcpServers.presets.puppeteerDesc', 'Browser automation'),\n baseUrl: 'http://localhost:3003',\n },\n ].map((preset) => (\n <button\n key={preset.name}\n className=\"p-4 text-left border border-border-subtle rounded-lg hover:bg-accent transition-colors\"\n onClick={() => {\n setNewServer({\n name: preset.name,\n description: preset.description,\n transport: 'HTTP_JSON',\n baseUrl: preset.baseUrl,\n });\n setShowAddModal(true);\n }}\n >\n <p className=\"font-medium\">{preset.name}</p>\n <p className=\"text-sm text-text-secondary mt-1\">{preset.description}</p>\n </button>\n ))}\n </div>\n </GlassCard>\n\n {/* Add Server Modal */}\n {showAddModal && (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50\">\n <Card className=\"w-full max-w-lg\">\n <CardHeader>\n <CardTitle>{t('botlit.mcpServers.form.title', 'Add MCP Server')}</CardTitle>\n <CardDescription>\n {t('botlit.mcpServers.form.description', 'Connect a new MCP server')}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FormField label={t('botlit.mcpServers.form.nameLabel', 'Server Name')} required>\n <Input\n placeholder={t('botlit.mcpServers.form.namePlaceholder', 'e.g., GitHub')}\n value={newServer.name}\n onChange={(e) => setNewServer({ ...newServer, name: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.descriptionLabel', 'Description')}>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.descriptionPlaceholder',\n 'What does this server do?'\n )}\n value={newServer.description}\n onChange={(e) => setNewServer({ ...newServer, description: e.target.value })}\n />\n </FormField>\n <FormField label={t('botlit.mcpServers.form.transportLabel', 'Transport')}>\n <select\n className=\"flex h-10 w-full rounded-md border border-border-default bg-bg-surface px-3 py-2 text-sm\"\n value={newServer.transport}\n onChange={(e) =>\n setNewServer({ ...newServer, transport: e.target.value as MCPTransport })\n }\n >\n <option value=\"HTTP_JSON\">HTTP JSON</option>\n <option value=\"JSON_RPC\">JSON RPC</option>\n <option value=\"SSE\">Server-Sent Events</option>\n <option value=\"CUSTOM\">Custom</option>\n </select>\n </FormField>\n <FormField label={t('botlit.mcpServers.form.baseUrlLabel', 'Base URL')} required>\n <Input\n placeholder={t(\n 'botlit.mcpServers.form.baseUrlPlaceholder',\n 'e.g., https://mcp.example.com'\n )}\n value={newServer.baseUrl}\n onChange={(e) => setNewServer({ ...newServer, baseUrl: e.target.value })}\n />\n </FormField>\n <div className=\"flex justify-end gap-2 pt-4\">\n <Button variant=\"outline\" onClick={() => setShowAddModal(false)}>\n {t('botlit.mcpServers.actions.cancel', 'Cancel')}\n </Button>\n <Button\n onClick={handleConnect}\n isLoading={connectResult.loading}\n disabled={!newServer.name || !newServer.baseUrl}\n >\n {t('botlit.mcpServers.actions.connect', 'Connect')}\n </Button>\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|