@burtson-labs/bandit-engine 2.0.106 → 2.0.108

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  StreamingMarkdown_default
3
- } from "./chunk-KYC7CC6C.mjs";
3
+ } from "./chunk-VR2ZWFTN.mjs";
4
4
  import {
5
5
  aiProviderInitService
6
6
  } from "./chunk-HAUDGBUS.mjs";
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-BN3D45E2.mjs";
15
15
  import {
16
16
  chat_modal_default
17
- } from "./chunk-RN3AKXKI.mjs";
17
+ } from "./chunk-XPNXECXM.mjs";
18
18
  import {
19
19
  AddIcon,
20
20
  ArchiveIcon,
@@ -42,14 +42,12 @@ import {
42
42
  DownloadIcon,
43
43
  EditNoteOutlinedIcon,
44
44
  ErrorIcon,
45
- ErrorOutlineIcon,
46
45
  ExpandMoreIcon,
47
46
  FaceRetouchingNaturalIcon,
48
47
  FileUploadIcon,
49
48
  FolderIcon,
50
49
  FolderOpenIcon,
51
50
  GroupIcon,
52
- HealthAndSafetyIcon,
53
51
  InfoIcon,
54
52
  LinkIcon,
55
53
  LockIcon,
@@ -86,7 +84,7 @@ import {
86
84
  predefinedThemes,
87
85
  useNotificationService,
88
86
  useVoiceStore
89
- } from "./chunk-VIKZPBVO.mjs";
87
+ } from "./chunk-3WKPBIRD.mjs";
90
88
  import {
91
89
  TOPICS,
92
90
  brandingService_default,
@@ -909,7 +907,7 @@ var PersonalitiesTab = ({
909
907
  Card,
910
908
  {
911
909
  sx: {
912
- mb: { xs: 1.5, md: 2 },
910
+ mb: { xs: 1, md: 1.25 },
913
911
  background: "linear-gradient(135deg, #1976d2 0%, #42a5f5 100%)",
914
912
  border: "2px solid transparent",
915
913
  borderRadius: { xs: 2.25, sm: 3 },
@@ -946,7 +944,7 @@ var PersonalitiesTab = ({
946
944
  setPersonalityTabIndex(1);
947
945
  },
948
946
  children: /* @__PURE__ */ jsxs2(CardContent, { sx: {
949
- p: { xs: 1.5, sm: 1.75 },
947
+ p: { xs: 1, sm: 1.25 },
950
948
  color: "white",
951
949
  textAlign: "left",
952
950
  position: "relative",
@@ -1024,7 +1022,7 @@ var PersonalitiesTab = ({
1024
1022
  lg: "repeat(4, 1fr)",
1025
1023
  xl: "repeat(4, 1fr)"
1026
1024
  },
1027
- gap: { xs: 1.25, sm: 2.5, md: 3 },
1025
+ gap: { xs: 1, sm: 1.5, md: 1.75 },
1028
1026
  alignItems: "stretch"
1029
1027
  }, children: promptTemplates.map((template, index) => /* @__PURE__ */ jsx2(
1030
1028
  Card,
@@ -1078,7 +1076,7 @@ var PersonalitiesTab = ({
1078
1076
  },
1079
1077
  onClick: () => handleTemplateSelect(template),
1080
1078
  children: /* @__PURE__ */ jsxs2(CardContent, { sx: {
1081
- p: { xs: 1.5, sm: 2 },
1079
+ p: { xs: 1.25, sm: 1.5 },
1082
1080
  display: "flex",
1083
1081
  flexDirection: "column",
1084
1082
  height: "100%",
@@ -1097,8 +1095,8 @@ var PersonalitiesTab = ({
1097
1095
  src: template.avatar,
1098
1096
  alt: template.name,
1099
1097
  sx: {
1100
- width: { xs: 40, sm: 48, md: 52 },
1101
- height: { xs: 40, sm: 48, md: 52 },
1098
+ width: { xs: 38, sm: 44, md: 46 },
1099
+ height: { xs: 38, sm: 44, md: 46 },
1102
1100
  mr: { xs: 1.2, md: 2 },
1103
1101
  transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
1104
1102
  boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
@@ -9243,7 +9241,7 @@ var ProviderTab = () => {
9243
9241
 
9244
9242
  // src/management/components/MCPToolsTabV2.tsx
9245
9243
  import { useEffect as useEffect11, useMemo as useMemo5, useState as useState14 } from "react";
9246
- import { Box as Box13, Typography as Typography12, Paper as Paper7, Chip as Chip10, Stack as Stack6, IconButton as IconButton7, Tooltip as Tooltip4, LinearProgress as LinearProgress6, Switch as Switch4, FormControlLabel as FormControlLabel3 } from "@mui/material";
9244
+ import { Alert as Alert11, Box as Box13, Typography as Typography12, Paper as Paper7, IconButton as IconButton7, Tooltip as Tooltip4, LinearProgress as LinearProgress6, Switch as Switch4 } from "@mui/material";
9247
9245
 
9248
9246
  // src/services/mcp/mcpControllerService.ts
9249
9247
  var isPlaygroundMode = () => {
@@ -9316,17 +9314,18 @@ async function fetchMcpHealth() {
9316
9314
  }
9317
9315
 
9318
9316
  // src/management/components/McpServersSection.tsx
9319
- import { useCallback as useCallback8, useEffect as useEffect10, useState as useState13 } from "react";
9317
+ import { useCallback as useCallback8, useEffect as useEffect10, useRef as useRef6, useState as useState13 } from "react";
9320
9318
  import {
9321
9319
  Alert as Alert10,
9322
9320
  Box as Box12,
9323
9321
  Button as Button10,
9324
9322
  Chip as Chip9,
9325
- CircularProgress as CircularProgress2,
9326
9323
  Collapse as Collapse2,
9324
+ CircularProgress as CircularProgress2,
9327
9325
  FormControlLabel as FormControlLabel2,
9328
9326
  IconButton as IconButton6,
9329
9327
  LinearProgress as LinearProgress5,
9328
+ Link,
9330
9329
  MenuItem as MenuItem4,
9331
9330
  Paper as Paper6,
9332
9331
  Stack as Stack5,
@@ -9337,15 +9336,85 @@ import {
9337
9336
  } from "@mui/material";
9338
9337
  import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
9339
9338
  var emptyForm = { name: "", url: "", authType: "none", authValue: "", headerName: "" };
9339
+ var CATALOG = [
9340
+ {
9341
+ key: "linear",
9342
+ name: "Linear",
9343
+ blurb: "Create and track issues, projects, and cycles",
9344
+ letter: "L",
9345
+ accent: "#5E6AD2",
9346
+ url: "https://mcp.linear.app/sse",
9347
+ authType: "bearer",
9348
+ tokenLabel: "Linear API key",
9349
+ tokenHelp: "https://linear.app/settings/api"
9350
+ },
9351
+ {
9352
+ key: "notion",
9353
+ name: "Notion",
9354
+ blurb: "Search and update pages across your workspace",
9355
+ letter: "N",
9356
+ accent: "#0f0f0f",
9357
+ url: "https://mcp.notion.com/mcp",
9358
+ authType: "bearer",
9359
+ tokenLabel: "Notion integration token",
9360
+ tokenHelp: "https://www.notion.so/my-integrations"
9361
+ },
9362
+ {
9363
+ key: "github",
9364
+ name: "GitHub",
9365
+ blurb: "Issues, pull requests, code search, and actions",
9366
+ letter: "G",
9367
+ accent: "#24292f",
9368
+ url: "https://api.githubcopilot.com/mcp/",
9369
+ authType: "bearer",
9370
+ tokenLabel: "GitHub personal access token",
9371
+ tokenHelp: "https://github.com/settings/tokens"
9372
+ },
9373
+ {
9374
+ key: "sentry",
9375
+ name: "Sentry",
9376
+ blurb: "Triage errors and inspect production issues",
9377
+ letter: "S",
9378
+ accent: "#362D59",
9379
+ url: "https://mcp.sentry.dev/mcp",
9380
+ authType: "bearer",
9381
+ tokenLabel: "Sentry auth token",
9382
+ tokenHelp: "https://sentry.io/settings/auth-tokens/"
9383
+ },
9384
+ {
9385
+ key: "atlassian",
9386
+ name: "Jira & Confluence",
9387
+ blurb: "Atlassian issues, boards, and docs",
9388
+ letter: "J",
9389
+ accent: "#0052CC",
9390
+ url: "https://mcp.atlassian.com/v1/sse",
9391
+ authType: "bearer",
9392
+ tokenLabel: "Atlassian API token",
9393
+ tokenHelp: "https://id.atlassian.com/manage-profile/security/api-tokens"
9394
+ },
9395
+ {
9396
+ key: "stripe",
9397
+ name: "Stripe",
9398
+ blurb: "Payments, customers, and invoices",
9399
+ letter: "S",
9400
+ accent: "#635BFF",
9401
+ url: "https://mcp.stripe.com",
9402
+ authType: "bearer",
9403
+ tokenLabel: "Stripe restricted key",
9404
+ tokenHelp: "https://dashboard.stripe.com/apikeys"
9405
+ }
9406
+ ];
9340
9407
  var McpServersSection = () => {
9341
9408
  const [servers, setServers] = useState13([]);
9342
9409
  const [loading, setLoading] = useState13(false);
9343
9410
  const [error, setError] = useState13(null);
9344
9411
  const [form, setForm] = useState13(emptyForm);
9412
+ const [activeEntry, setActiveEntry] = useState13(null);
9345
9413
  const [adding, setAdding] = useState13(false);
9346
9414
  const [showForm, setShowForm] = useState13(false);
9347
9415
  const [tools, setTools] = useState13({});
9348
9416
  const reloadChatTools = useMCPToolsStore((s) => s.loadMcpServerTools);
9417
+ const formRef = useRef6(null);
9349
9418
  const refresh = useCallback8(async () => {
9350
9419
  setLoading(true);
9351
9420
  setError(null);
@@ -9360,6 +9429,20 @@ var McpServersSection = () => {
9360
9429
  useEffect10(() => {
9361
9430
  refresh();
9362
9431
  }, [refresh]);
9432
+ const connectedKeys = new Set(servers.map((s) => s.url.replace(/\/+$/, "")));
9433
+ const openForCatalog = (entry) => {
9434
+ setActiveEntry(entry);
9435
+ setForm({ name: entry.name, url: entry.url, authType: entry.authType, authValue: "", headerName: "" });
9436
+ setShowForm(true);
9437
+ setError(null);
9438
+ requestAnimationFrame(() => formRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" }));
9439
+ };
9440
+ const openCustom = () => {
9441
+ setActiveEntry(null);
9442
+ setForm(emptyForm);
9443
+ setShowForm((v) => !v);
9444
+ setError(null);
9445
+ };
9363
9446
  const handleAdd = async () => {
9364
9447
  if (!form.name.trim() || !form.url.trim()) {
9365
9448
  setError("Name and URL are required.");
@@ -9376,6 +9459,7 @@ var McpServersSection = () => {
9376
9459
  headerName: form.authType === "header" ? form.headerName : void 0
9377
9460
  });
9378
9461
  setForm(emptyForm);
9462
+ setActiveEntry(null);
9379
9463
  setShowForm(false);
9380
9464
  await refresh();
9381
9465
  void reloadChatTools();
@@ -9414,101 +9498,185 @@ var McpServersSection = () => {
9414
9498
  setTools((prev) => ({ ...prev, [id]: { error: e instanceof Error ? e.message : "Could not connect." } }));
9415
9499
  }
9416
9500
  };
9417
- return /* @__PURE__ */ jsxs12(Paper6, { sx: { p: 2, mb: 2 }, children: [
9418
- /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1, gap: 1, flexWrap: "wrap" }, children: [
9419
- /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
9420
- /* @__PURE__ */ jsx12(CloudIcon, {}),
9421
- /* @__PURE__ */ jsx12(Typography11, { variant: "subtitle1", sx: { fontWeight: 700 }, children: "MCP Servers" }),
9422
- /* @__PURE__ */ jsx12(Chip9, { size: "small", label: String(servers.length) })
9423
- ] }),
9424
- /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
9425
- /* @__PURE__ */ jsx12(Tooltip3, { title: "Refresh", children: /* @__PURE__ */ jsx12(IconButton6, { onClick: refresh, size: "small", children: /* @__PURE__ */ jsx12(RefreshIcon, {}) }) }),
9426
- /* @__PURE__ */ jsx12(Button10, { size: "small", variant: "contained", startIcon: /* @__PURE__ */ jsx12(AddIcon, {}), onClick: () => setShowForm((v) => !v), children: "Add server" })
9427
- ] })
9501
+ return /* @__PURE__ */ jsxs12(Box12, { children: [
9502
+ /* @__PURE__ */ jsxs12(Box12, { sx: { mb: 2.5 }, children: [
9503
+ /* @__PURE__ */ jsx12(Typography11, { variant: "h6", sx: { fontWeight: 700, mb: 0.5 }, children: "Connect your tools" }),
9504
+ /* @__PURE__ */ jsx12(Typography11, { variant: "body2", color: "text.secondary", sx: { maxWidth: 680, lineHeight: 1.6 }, children: "Let Bandit work inside the apps you already use \u2014 open a Linear issue, search Notion, or triage a Sentry error right from chat. Connect a service once; the gateway holds the connection securely, so your browser never talks to it directly." })
9428
9505
  ] }),
9429
- /* @__PURE__ */ jsx12(Typography11, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: "Connect a remote Model Context Protocol server to give the assistant its tools. The gateway holds the connection and proxies calls \u2014 your browser never talks to the server directly." }),
9430
9506
  error && /* @__PURE__ */ jsx12(Alert10, { severity: "error", sx: { mb: 2 }, onClose: () => setError(null), children: error }),
9431
- /* @__PURE__ */ jsx12(Collapse2, { in: showForm, children: /* @__PURE__ */ jsx12(Paper6, { variant: "outlined", sx: { p: 2, mb: 2 }, children: /* @__PURE__ */ jsxs12(Stack5, { spacing: 2, children: [
9432
- /* @__PURE__ */ jsx12(
9433
- TextField7,
9434
- {
9435
- label: "Name",
9436
- size: "small",
9437
- value: form.name,
9438
- onChange: (e) => setForm({ ...form, name: e.target.value }),
9439
- placeholder: "e.g. github",
9440
- fullWidth: true
9441
- }
9442
- ),
9443
- /* @__PURE__ */ jsx12(
9444
- TextField7,
9445
- {
9446
- label: "Server URL",
9447
- size: "small",
9448
- value: form.url,
9449
- onChange: (e) => setForm({ ...form, url: e.target.value }),
9450
- placeholder: "https://mcp.example.com/mcp",
9451
- fullWidth: true
9452
- }
9453
- ),
9454
- /* @__PURE__ */ jsxs12(
9455
- TextField7,
9456
- {
9457
- select: true,
9458
- label: "Auth",
9459
- size: "small",
9460
- value: form.authType,
9461
- onChange: (e) => setForm({ ...form, authType: e.target.value }),
9462
- sx: { maxWidth: 220 },
9463
- children: [
9464
- /* @__PURE__ */ jsx12(MenuItem4, { value: "none", children: "None" }),
9465
- /* @__PURE__ */ jsx12(MenuItem4, { value: "bearer", children: "Bearer token" }),
9466
- /* @__PURE__ */ jsx12(MenuItem4, { value: "header", children: "Custom header" })
9467
- ]
9468
- }
9469
- ),
9470
- form.authType === "header" && /* @__PURE__ */ jsx12(
9471
- TextField7,
9472
- {
9473
- label: "Header name",
9474
- size: "small",
9475
- value: form.headerName,
9476
- onChange: (e) => setForm({ ...form, headerName: e.target.value }),
9477
- placeholder: "X-Api-Key",
9478
- fullWidth: true
9479
- }
9480
- ),
9481
- form.authType !== "none" && /* @__PURE__ */ jsx12(
9482
- TextField7,
9483
- {
9484
- label: form.authType === "bearer" ? "Token" : "Header value",
9485
- size: "small",
9486
- type: "password",
9487
- value: form.authValue,
9488
- onChange: (e) => setForm({ ...form, authValue: e.target.value }),
9489
- fullWidth: true
9490
- }
9491
- ),
9492
- /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", gap: 1 }, children: [
9493
- /* @__PURE__ */ jsx12(Button10, { variant: "contained", onClick: handleAdd, disabled: adding, children: adding ? "Adding\u2026" : "Add server" }),
9507
+ /* @__PURE__ */ jsx12(Typography11, { variant: "overline", color: "text.secondary", sx: { fontWeight: 700, letterSpacing: 0.6 }, children: "Popular integrations" }),
9508
+ /* @__PURE__ */ jsx12(
9509
+ Box12,
9510
+ {
9511
+ sx: {
9512
+ mt: 1,
9513
+ mb: 3,
9514
+ display: "grid",
9515
+ gridTemplateColumns: { xs: "1fr", sm: "repeat(2, 1fr)", lg: "repeat(3, 1fr)" },
9516
+ gap: 1.25
9517
+ },
9518
+ children: CATALOG.map((entry) => {
9519
+ const connected = connectedKeys.has(entry.url.replace(/\/+$/, ""));
9520
+ return /* @__PURE__ */ jsxs12(
9521
+ Paper6,
9522
+ {
9523
+ variant: "outlined",
9524
+ sx: {
9525
+ p: 1.5,
9526
+ display: "flex",
9527
+ alignItems: "center",
9528
+ gap: 1.25,
9529
+ borderRadius: 2,
9530
+ transition: "border-color 0.15s ease, transform 0.15s ease",
9531
+ "&:hover": { borderColor: "primary.main", transform: "translateY(-1px)" }
9532
+ },
9533
+ children: [
9534
+ /* @__PURE__ */ jsx12(
9535
+ Box12,
9536
+ {
9537
+ sx: {
9538
+ width: 36,
9539
+ height: 36,
9540
+ borderRadius: 1.5,
9541
+ flexShrink: 0,
9542
+ display: "grid",
9543
+ placeItems: "center",
9544
+ color: "#fff",
9545
+ fontWeight: 700,
9546
+ fontSize: 16,
9547
+ bgcolor: entry.accent
9548
+ },
9549
+ children: entry.letter
9550
+ }
9551
+ ),
9552
+ /* @__PURE__ */ jsxs12(Box12, { sx: { minWidth: 0, flex: 1 }, children: [
9553
+ /* @__PURE__ */ jsx12(Typography11, { variant: "subtitle2", sx: { fontWeight: 700, lineHeight: 1.2 }, children: entry.name }),
9554
+ /* @__PURE__ */ jsx12(
9555
+ Typography11,
9556
+ {
9557
+ variant: "caption",
9558
+ color: "text.secondary",
9559
+ sx: { display: "block", lineHeight: 1.35 },
9560
+ children: entry.blurb
9561
+ }
9562
+ )
9563
+ ] }),
9564
+ connected ? /* @__PURE__ */ jsx12(Chip9, { size: "small", color: "success", label: "Added", sx: { flexShrink: 0 } }) : /* @__PURE__ */ jsx12(
9565
+ Button10,
9566
+ {
9567
+ size: "small",
9568
+ variant: "outlined",
9569
+ onClick: () => openForCatalog(entry),
9570
+ sx: { flexShrink: 0, minWidth: 0 },
9571
+ children: "Connect"
9572
+ }
9573
+ )
9574
+ ]
9575
+ },
9576
+ entry.key
9577
+ );
9578
+ })
9579
+ }
9580
+ ),
9581
+ /* @__PURE__ */ jsx12(Box12, { ref: formRef, children: /* @__PURE__ */ jsx12(Collapse2, { in: showForm, children: /* @__PURE__ */ jsxs12(Paper6, { variant: "outlined", sx: { p: 2, mb: 2, borderRadius: 2 }, children: [
9582
+ /* @__PURE__ */ jsx12(Typography11, { variant: "subtitle2", sx: { fontWeight: 700, mb: 0.5 }, children: activeEntry ? `Connect ${activeEntry.name}` : "Add a custom server" }),
9583
+ activeEntry?.tokenHelp && /* @__PURE__ */ jsxs12(Typography11, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 1.5 }, children: [
9584
+ "Paste your ",
9585
+ activeEntry.tokenLabel,
9586
+ ".",
9587
+ " ",
9588
+ /* @__PURE__ */ jsx12(Link, { href: activeEntry.tokenHelp, target: "_blank", rel: "noopener noreferrer", children: "Get one here \u2192" })
9589
+ ] }),
9590
+ /* @__PURE__ */ jsxs12(Stack5, { spacing: 1.75, children: [
9494
9591
  /* @__PURE__ */ jsx12(
9495
- Button10,
9592
+ TextField7,
9496
9593
  {
9497
- onClick: () => {
9498
- setShowForm(false);
9499
- setForm(emptyForm);
9500
- },
9501
- children: "Cancel"
9594
+ label: "Name",
9595
+ size: "small",
9596
+ value: form.name,
9597
+ onChange: (e) => setForm({ ...form, name: e.target.value }),
9598
+ placeholder: "e.g. Linear",
9599
+ fullWidth: true
9502
9600
  }
9503
- )
9601
+ ),
9602
+ /* @__PURE__ */ jsx12(
9603
+ TextField7,
9604
+ {
9605
+ label: "Server URL",
9606
+ size: "small",
9607
+ value: form.url,
9608
+ onChange: (e) => setForm({ ...form, url: e.target.value }),
9609
+ placeholder: "https://mcp.example.com/mcp",
9610
+ fullWidth: true
9611
+ }
9612
+ ),
9613
+ /* @__PURE__ */ jsxs12(
9614
+ TextField7,
9615
+ {
9616
+ select: true,
9617
+ label: "Auth",
9618
+ size: "small",
9619
+ value: form.authType,
9620
+ onChange: (e) => setForm({ ...form, authType: e.target.value }),
9621
+ sx: { maxWidth: 220 },
9622
+ children: [
9623
+ /* @__PURE__ */ jsx12(MenuItem4, { value: "none", children: "None" }),
9624
+ /* @__PURE__ */ jsx12(MenuItem4, { value: "bearer", children: "Bearer token" }),
9625
+ /* @__PURE__ */ jsx12(MenuItem4, { value: "header", children: "Custom header" })
9626
+ ]
9627
+ }
9628
+ ),
9629
+ form.authType === "header" && /* @__PURE__ */ jsx12(
9630
+ TextField7,
9631
+ {
9632
+ label: "Header name",
9633
+ size: "small",
9634
+ value: form.headerName,
9635
+ onChange: (e) => setForm({ ...form, headerName: e.target.value }),
9636
+ placeholder: "X-Api-Key",
9637
+ fullWidth: true
9638
+ }
9639
+ ),
9640
+ form.authType !== "none" && /* @__PURE__ */ jsx12(
9641
+ TextField7,
9642
+ {
9643
+ label: activeEntry?.tokenLabel ?? (form.authType === "bearer" ? "Token" : "Header value"),
9644
+ size: "small",
9645
+ type: "password",
9646
+ value: form.authValue,
9647
+ onChange: (e) => setForm({ ...form, authValue: e.target.value }),
9648
+ fullWidth: true
9649
+ }
9650
+ ),
9651
+ /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", gap: 1 }, children: [
9652
+ /* @__PURE__ */ jsx12(Button10, { variant: "contained", onClick: handleAdd, disabled: adding, children: adding ? "Connecting\u2026" : "Connect" }),
9653
+ /* @__PURE__ */ jsx12(
9654
+ Button10,
9655
+ {
9656
+ onClick: () => {
9657
+ setShowForm(false);
9658
+ setActiveEntry(null);
9659
+ setForm(emptyForm);
9660
+ },
9661
+ children: "Cancel"
9662
+ }
9663
+ )
9664
+ ] })
9504
9665
  ] })
9505
9666
  ] }) }) }),
9667
+ /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1 }, children: [
9668
+ /* @__PURE__ */ jsxs12(Typography11, { variant: "overline", color: "text.secondary", sx: { fontWeight: 700, letterSpacing: 0.6 }, children: [
9669
+ "Your connections",
9670
+ servers.length ? ` (${servers.length})` : ""
9671
+ ] }),
9672
+ /* @__PURE__ */ jsx12(Button10, { size: "small", startIcon: /* @__PURE__ */ jsx12(AddIcon, {}), onClick: openCustom, children: "Custom server" })
9673
+ ] }),
9506
9674
  loading && /* @__PURE__ */ jsx12(LinearProgress5, { sx: { mb: 2 } }),
9507
- /* @__PURE__ */ jsxs12(Stack5, { spacing: 1.5, children: [
9508
- servers.length === 0 && !loading && /* @__PURE__ */ jsx12(Typography11, { variant: "body2", color: "text.secondary", children: "No MCP servers connected yet." }),
9675
+ /* @__PURE__ */ jsxs12(Stack5, { spacing: 1.25, children: [
9676
+ servers.length === 0 && !loading && /* @__PURE__ */ jsx12(Typography11, { variant: "body2", color: "text.secondary", sx: { py: 1 }, children: "Nothing connected yet \u2014 pick a tool above to get started." }),
9509
9677
  servers.map((server) => {
9510
9678
  const toolState = tools[server.id];
9511
- return /* @__PURE__ */ jsxs12(Paper6, { variant: "outlined", sx: { p: 1.5 }, children: [
9679
+ return /* @__PURE__ */ jsxs12(Paper6, { variant: "outlined", sx: { p: 1.5, borderRadius: 2 }, children: [
9512
9680
  /* @__PURE__ */ jsxs12(Box12, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 1 }, children: [
9513
9681
  /* @__PURE__ */ jsxs12(Box12, { sx: { minWidth: 0 }, children: [
9514
9682
  /* @__PURE__ */ jsx12(Typography11, { variant: "subtitle2", sx: { fontWeight: 700 }, children: server.name }),
@@ -9536,6 +9704,11 @@ var McpServersSection = () => {
9536
9704
  toolState && !Array.isArray(toolState) && toolState !== "loading" && /* @__PURE__ */ jsx12(Alert10, { severity: "warning", sx: { mt: 1 }, children: toolState.error })
9537
9705
  ] }, server.id);
9538
9706
  })
9707
+ ] }),
9708
+ /* @__PURE__ */ jsxs12(Typography11, { variant: "caption", color: "text.secondary", sx: { display: "block", mt: 2, lineHeight: 1.5 }, children: [
9709
+ "Running a local server (Figma Dev Mode, Azure DevOps)? Add it as a custom server \u2014 note the cloud gateway can't reach ",
9710
+ /* @__PURE__ */ jsx12("code", { children: "localhost" }),
9711
+ ", so local servers need the Bandit desktop app."
9539
9712
  ] })
9540
9713
  ] });
9541
9714
  };
@@ -9629,85 +9802,98 @@ var MCPToolsTabV2 = () => {
9629
9802
  return map;
9630
9803
  }, [localTools]);
9631
9804
  return /* @__PURE__ */ jsxs13(Box13, { children: [
9632
- /* @__PURE__ */ jsxs13(Box13, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2 }, children: [
9633
- /* @__PURE__ */ jsx13(Typography12, { variant: "h5", sx: { fontWeight: 600, color: "primary.main" }, children: "Available Tools" }),
9634
- /* @__PURE__ */ jsx13(Box13, { children: /* @__PURE__ */ jsx13(Tooltip4, { title: "Refresh", children: /* @__PURE__ */ jsx13(IconButton7, { onClick: refresh, children: /* @__PURE__ */ jsx13(RefreshIcon, {}) }) }) })
9635
- ] }),
9636
9805
  /* @__PURE__ */ jsx13(McpServersSection_default, {}),
9637
- !gatewayConfigured && /* @__PURE__ */ jsx13(Paper7, { sx: { p: 2, mb: 2 }, children: /* @__PURE__ */ jsx13(Typography12, { variant: "body2", color: "text.secondary", children: "Gateway API URL isn\u2019t configured. The controller endpoints will be fetched relative to this origin." }) }),
9638
- /* @__PURE__ */ jsx13(Paper7, { sx: { p: 2, mb: 2 }, children: /* @__PURE__ */ jsxs13(Box13, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
9639
- health?.status === "healthy" ? /* @__PURE__ */ jsx13(HealthAndSafetyIcon, { color: "success" }) : health?.status === "unhealthy" ? /* @__PURE__ */ jsx13(ErrorOutlineIcon, { color: "error" }) : /* @__PURE__ */ jsx13(ErrorOutlineIcon, { color: "disabled" }),
9640
- /* @__PURE__ */ jsx13(Typography12, { variant: "subtitle1", sx: { fontWeight: 600 }, children: "Controller Health" }),
9641
- /* @__PURE__ */ jsx13(
9642
- Chip10,
9643
- {
9644
- size: "small",
9645
- label: (health?.status || "unknown").toString(),
9646
- color: health?.status === "healthy" ? "success" : health?.status === "unhealthy" ? "error" : "default",
9647
- sx: { ml: 1 }
9648
- }
9649
- ),
9650
- health?.timestamp && /* @__PURE__ */ jsx13(Typography12, { variant: "caption", color: "text.secondary", sx: { ml: 1 }, children: new Date(health.timestamp).toLocaleString() })
9651
- ] }) }),
9652
- loading && /* @__PURE__ */ jsx13(Box13, { sx: { mb: 2 }, children: /* @__PURE__ */ jsx13(LinearProgress6, {}) }),
9653
- error && /* @__PURE__ */ jsx13(Paper7, { sx: { p: 2, mb: 2 }, children: /* @__PURE__ */ jsx13(Typography12, { color: "error", children: error }) }),
9654
- /* @__PURE__ */ jsx13(Stack6, { spacing: 2, children: tools.map((tool) => {
9655
- let locallyEnabled = localEnabledMap.get(tool.id);
9656
- if (locallyEnabled === void 0) {
9657
- locallyEnabled = localEnabledMap.get(tool.name);
9658
- }
9659
- if (locallyEnabled === void 0) {
9660
- const directLookup = localTools.find(
9661
- (t) => t.id === tool.id || t.function.name === tool.id || t.name === tool.name
9662
- );
9663
- locallyEnabled = directLookup?.enabled ?? tool.isEnabled;
9664
- }
9665
- return /* @__PURE__ */ jsxs13(Paper7, { sx: { p: 2 }, children: [
9666
- /* @__PURE__ */ jsxs13(Box13, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
9667
- /* @__PURE__ */ jsxs13(Box13, { children: [
9668
- /* @__PURE__ */ jsx13(Typography12, { variant: "h6", sx: { fontWeight: 700 }, children: tool.name }),
9669
- /* @__PURE__ */ jsx13(Typography12, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: tool.description })
9670
- ] }),
9671
- /* @__PURE__ */ jsxs13(Box13, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
9672
- /* @__PURE__ */ jsx13(
9673
- FormControlLabel3,
9674
- {
9675
- control: /* @__PURE__ */ jsx13(Switch4, { checked: !!locallyEnabled, onChange: () => {
9676
- let local = localTools.find((t) => t.function.name === tool.id);
9677
- if (!local) {
9678
- local = localTools.find((t) => t.function.name === tool.name);
9679
- }
9680
- if (!local) {
9681
- local = localTools.find((t) => t.id === tool.id);
9682
- }
9683
- if (!local) {
9684
- local = localTools.find((t) => t.name === tool.name);
9685
- }
9686
- if (local) {
9687
- toggleTool(local.id);
9688
- } else {
9689
- console.warn("Could not find local tool for server tool:", tool);
9690
- }
9691
- } }),
9692
- label: locallyEnabled ? "Enabled" : "Disabled"
9806
+ /* @__PURE__ */ jsxs13(Box13, { sx: { mt: 4 }, children: [
9807
+ /* @__PURE__ */ jsxs13(Box13, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 0.5 }, children: [
9808
+ /* @__PURE__ */ jsx13(Typography12, { variant: "overline", color: "text.secondary", sx: { fontWeight: 700, letterSpacing: 0.6 }, children: "Built-in capabilities" }),
9809
+ /* @__PURE__ */ jsxs13(Box13, { sx: { display: "flex", alignItems: "center", gap: 0.75 }, children: [
9810
+ /* @__PURE__ */ jsx13(Tooltip4, { title: `Controller: ${health?.status || "unknown"}`, children: /* @__PURE__ */ jsx13(
9811
+ Box13,
9812
+ {
9813
+ sx: {
9814
+ width: 8,
9815
+ height: 8,
9816
+ borderRadius: "50%",
9817
+ bgcolor: health?.status === "healthy" ? "success.main" : health?.status === "unhealthy" ? "error.main" : "grey.500"
9693
9818
  }
9694
- ),
9695
- /* @__PURE__ */ jsx13(Tooltip4, { title: "Controller-driven tools (read-only schema)", children: /* @__PURE__ */ jsx13(SettingsIcon, { color: "disabled" }) })
9696
- ] })
9697
- ] }),
9698
- !!tool.supportedParameters?.length && /* @__PURE__ */ jsxs13(Box13, { sx: { mt: 1.5 }, children: [
9699
- /* @__PURE__ */ jsx13(Typography12, { variant: "caption", color: "text.secondary", children: "Supported parameters" }),
9700
- /* @__PURE__ */ jsx13(Box13, { sx: { mt: 0.5, display: "flex", flexWrap: "wrap", gap: 1 }, children: tool.supportedParameters.map((p) => /* @__PURE__ */ jsx13(Chip10, { size: "small", label: p }, p)) })
9819
+ }
9820
+ ) }),
9821
+ /* @__PURE__ */ jsx13(Tooltip4, { title: "Refresh", children: /* @__PURE__ */ jsx13(IconButton7, { size: "small", onClick: refresh, children: /* @__PURE__ */ jsx13(RefreshIcon, { fontSize: "small" }) }) })
9701
9822
  ] })
9702
- ] }, tool.id);
9703
- }) })
9823
+ ] }),
9824
+ /* @__PURE__ */ jsx13(Typography12, { variant: "body2", color: "text.secondary", sx: { mb: 1.5 }, children: "Things Bandit can do on its own \u2014 toggle what it\u2019s allowed to use." }),
9825
+ loading && /* @__PURE__ */ jsx13(LinearProgress6, { sx: { mb: 2 } }),
9826
+ error && /* @__PURE__ */ jsx13(Alert11, { severity: "warning", sx: { mb: 2 }, children: error }),
9827
+ !gatewayConfigured && /* @__PURE__ */ jsx13(Alert11, { severity: "info", sx: { mb: 2 }, children: "Using this origin for tool endpoints (no gateway URL configured)." }),
9828
+ /* @__PURE__ */ jsxs13(
9829
+ Box13,
9830
+ {
9831
+ sx: {
9832
+ display: "grid",
9833
+ gridTemplateColumns: { xs: "1fr", sm: "repeat(2, 1fr)" },
9834
+ gap: 1.25
9835
+ },
9836
+ children: [
9837
+ tools.map((tool) => {
9838
+ let locallyEnabled = localEnabledMap.get(tool.id);
9839
+ if (locallyEnabled === void 0) {
9840
+ locallyEnabled = localEnabledMap.get(tool.name);
9841
+ }
9842
+ if (locallyEnabled === void 0) {
9843
+ const directLookup = localTools.find(
9844
+ (t) => t.id === tool.id || t.function.name === tool.id || t.name === tool.name
9845
+ );
9846
+ locallyEnabled = directLookup?.enabled ?? tool.isEnabled;
9847
+ }
9848
+ return /* @__PURE__ */ jsxs13(
9849
+ Paper7,
9850
+ {
9851
+ variant: "outlined",
9852
+ sx: {
9853
+ p: 1.5,
9854
+ borderRadius: 2,
9855
+ display: "flex",
9856
+ alignItems: "flex-start",
9857
+ justifyContent: "space-between",
9858
+ gap: 1
9859
+ },
9860
+ children: [
9861
+ /* @__PURE__ */ jsxs13(Box13, { sx: { minWidth: 0 }, children: [
9862
+ /* @__PURE__ */ jsx13(Typography12, { variant: "subtitle2", sx: { fontWeight: 700 }, children: tool.name }),
9863
+ /* @__PURE__ */ jsx13(Typography12, { variant: "caption", color: "text.secondary", sx: { display: "block", lineHeight: 1.4 }, children: tool.description })
9864
+ ] }),
9865
+ /* @__PURE__ */ jsx13(
9866
+ Switch4,
9867
+ {
9868
+ size: "small",
9869
+ checked: !!locallyEnabled,
9870
+ sx: { flexShrink: 0 },
9871
+ onChange: () => {
9872
+ let local = localTools.find((t) => t.function.name === tool.id);
9873
+ if (!local) local = localTools.find((t) => t.function.name === tool.name);
9874
+ if (!local) local = localTools.find((t) => t.id === tool.id);
9875
+ if (!local) local = localTools.find((t) => t.name === tool.name);
9876
+ if (local) toggleTool(local.id);
9877
+ }
9878
+ }
9879
+ )
9880
+ ]
9881
+ },
9882
+ tool.id
9883
+ );
9884
+ }),
9885
+ !loading && tools.length === 0 && /* @__PURE__ */ jsx13(Typography12, { variant: "body2", color: "text.secondary", children: "No built-in tools reported." })
9886
+ ]
9887
+ }
9888
+ )
9889
+ ] })
9704
9890
  ] });
9705
9891
  };
9706
9892
  var MCPToolsTabV2_default = MCPToolsTabV2;
9707
9893
 
9708
9894
  // src/management/management.tsx
9709
9895
  import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
9710
- var preloadChatPage = () => import("./chat-HQHHNWBS.mjs");
9896
+ var preloadChatPage = () => import("./chat-JDAI4UHT.mjs");
9711
9897
  var buildCapabilitiesUrl = (gatewayApiUrl) => {
9712
9898
  const trimmed = gatewayApiUrl.replace(/\/$/, "");
9713
9899
  if (trimmed.endsWith("/api")) {
@@ -11073,4 +11259,4 @@ export {
11073
11259
  useGatewayMemory,
11074
11260
  management_default
11075
11261
  };
11076
- //# sourceMappingURL=chunk-2LL5XMLK.mjs.map
11262
+ //# sourceMappingURL=chunk-UVIMO6XT.mjs.map