@datalayer/core 1.2.27 → 1.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/api/evals/__tests__/external-definition.golden.json +110 -0
  2. package/lib/api/evals/client.d.ts +13 -1
  3. package/lib/api/evals/client.js +13 -0
  4. package/lib/api/evals/types.d.ts +168 -1
  5. package/lib/api/mcp/agentAccess.d.ts +10 -0
  6. package/lib/api/mcp/agentAccess.js +28 -0
  7. package/lib/api/mcp/generated.js +20 -0
  8. package/lib/api/mcp/index.d.ts +1 -0
  9. package/lib/api/mcp/index.js +1 -0
  10. package/lib/components/index.d.ts +1 -0
  11. package/lib/components/index.js +1 -0
  12. package/lib/components/mcp/ScopeList.js +10 -1
  13. package/lib/components/toast/ToastPanel.d.ts +11 -0
  14. package/lib/components/toast/ToastPanel.js +31 -0
  15. package/lib/components/toast/index.d.ts +2 -0
  16. package/lib/components/toast/index.js +6 -0
  17. package/lib/components/toast/toastQueue.d.ts +33 -0
  18. package/lib/components/toast/toastQueue.js +47 -0
  19. package/lib/hooks/useDatalayer.js +12 -16
  20. package/lib/hooks/useToast.d.ts +6 -0
  21. package/lib/hooks/useToast.js +40 -1
  22. package/lib/models/McpAgentAccess.d.ts +95 -0
  23. package/lib/models/McpAgentAccess.js +5 -0
  24. package/lib/models/index.d.ts +1 -0
  25. package/lib/models/index.js +1 -0
  26. package/lib/otel/views/OtelLive.js +2 -2
  27. package/lib/otel/views/OtelLiveSpans.js +2 -2
  28. package/lib/otel/views/OtelLogsList.js +3 -3
  29. package/lib/otel/views/OtelMetricsChart.d.ts +13 -0
  30. package/lib/otel/views/OtelMetricsChart.js +109 -26
  31. package/lib/otel/views/OtelSpanDetail.js +3 -3
  32. package/lib/otel/views/OtelSqlView.js +4 -4
  33. package/lib/otel/views/OtelSystemView.js +2 -2
  34. package/lib/otel/views/OtelTimelineRangeSlider.js +2 -2
  35. package/lib/otel/views/OtelTracesList.js +2 -2
  36. package/lib/views/mcp/AuditLog.js +1 -1
  37. package/lib/views/mcp/ConnectedAgents.d.ts +1 -1
  38. package/lib/views/mcp/ConnectedAgents.js +13 -10
  39. package/lib/views/mcp/McpDashboard.d.ts +1 -1
  40. package/lib/views/mcp/McpDashboard.js +6 -6
  41. package/lib/views/mcp/McpHome.d.ts +3 -1
  42. package/lib/views/mcp/McpHome.js +19 -9
  43. package/lib/views/mcp/Policies.js +1 -1
  44. package/lib/views/mcp/types.d.ts +8 -4
  45. package/lib/views/otel/OtelHeader.js +2 -2
  46. package/package.json +2 -2
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  * Available tables: `spans`, `metrics`, `logs`.
15
15
  */
16
16
  import { useState, useCallback } from 'react';
17
- import { Box } from '@datalayer/primer-addons';
17
+ import { Box, Card } from '@datalayer/primer-addons';
18
18
  import { ActionList, ActionMenu, Button, Text, Textarea, Spinner, } from '@primer/react';
19
19
  import { HistoryIcon, TableIcon, XCircleIcon, DownloadIcon, } from '@primer/octicons-react';
20
20
  import { useOtelQuery } from '../hooks/index.js';
@@ -105,7 +105,7 @@ export const OtelSqlView = ({ token, baseUrl = '', }) => {
105
105
  }
106
106
  };
107
107
  const columns = rows.length > 0 ? Object.keys(rows[0]) : [];
108
- return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, height: "100%", gap: 3, p: 4, bg: "canvas.default", color: "fg.default", overflow: "auto", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", children: "Preset queries" }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsx(ActionList, { children: PRESET_GROUPS.map(group => (_jsx(ActionList.Group, { title: group, children: PRESETS.filter(p => p.group === group).map(p => (_jsx(ActionList.Item, { onSelect: () => setSql(p.sql), children: p.label }, p.label))) }, group))) }) })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["\u2318 Enter to run \u00B7 Tables:", ' ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "spans" }), ', ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "metrics" }), ', ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "logs" })] })] }), _jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsx(Textarea, { "aria-label": "SQL query", value: sql, onChange: e => setSql(e.target.value), onKeyDown: handleKeyDown, placeholder: "SELECT \u2026 FROM spans LIMIT 20", rows: 5, resize: "vertical", sx: { fontFamily: 'mono', fontSize: 1, width: '100%' } }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Button, { variant: "primary", onClick: handleRun, disabled: loading, size: "small", children: loading ? 'Running…' : 'Run' }), loading && _jsx(Spinner, { size: "small" })] })] }), error && (_jsx(Box, { p: 3, bg: "danger.subtle", borderRadius: 2, border: "1px solid", borderColor: "danger.muted", children: _jsx(Text, { sx: { color: 'danger.fg', fontFamily: 'mono', fontSize: 1 }, children: error }) })), !error && rows.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, mb: 1, children: [_jsx(TableIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.default' }, children: "Results" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', ml: 1 }, children: ["(", rows.length, " row", rows.length !== 1 ? 's' : '', ")"] }), _jsxs(Box, { as: "button", onClick: clear, title: "Clear results", ml: "auto", display: "flex", alignItems: "center", gap: 1, px: 2, py: "2px", border: "none", borderRadius: 2, bg: "transparent", color: "fg.muted", cursor: "pointer", fontSize: 0, hover: { color: 'danger.fg', bg: 'danger.subtle' }, children: [_jsx(XCircleIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "Clear" })] }), _jsxs(Box, { as: "button", onClick: () => {
108
+ return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, height: "100%", gap: 3, p: 4, bg: "canvas.default", color: "fg.default", overflow: "auto", children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", children: "Preset queries" }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsx(ActionList, { children: PRESET_GROUPS.map(group => (_jsx(ActionList.Group, { title: group, children: PRESETS.filter(p => p.group === group).map(p => (_jsx(ActionList.Item, { onSelect: () => setSql(p.sql), children: p.label }, p.label))) }, group))) }) })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["\u2318 Enter to run \u00B7 Tables:", ' ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "spans" }), ', ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "metrics" }), ', ', _jsx(Box, { as: "code", fontFamily: "mono", fontSize: 0, children: "logs" })] })] }), _jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsx(Textarea, { "aria-label": "SQL query", value: sql, onChange: e => setSql(e.target.value), onKeyDown: handleKeyDown, placeholder: "SELECT \u2026 FROM spans LIMIT 20", rows: 5, resize: "vertical", sx: { fontFamily: 'mono', fontSize: 1, width: '100%' } }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Button, { variant: "primary", onClick: handleRun, disabled: loading, size: "small", children: loading ? 'Running…' : 'Run' }), loading && _jsx(Spinner, { size: "small" })] })] }), error && (_jsx(Card, { border: true, shadow: "none", display: "block", p: 3, bg: "danger.subtle", borderColor: "danger.muted", children: _jsx(Text, { sx: { color: 'danger.fg', fontFamily: 'mono', fontSize: 1 }, children: error }) })), !error && rows.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, mb: 1, children: [_jsx(TableIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', color: 'fg.default' }, children: "Results" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', ml: 1 }, children: ["(", rows.length, " row", rows.length !== 1 ? 's' : '', ")"] }), _jsxs(Box, { as: "button", onClick: clear, title: "Clear results", ml: "auto", display: "flex", alignItems: "center", gap: 1, px: 2, py: "2px", border: "none", borderRadius: 2, bg: "transparent", color: "fg.muted", cursor: "pointer", fontSize: 0, hover: { color: 'danger.fg', bg: 'danger.subtle' }, children: [_jsx(XCircleIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "Clear" })] }), _jsxs(Box, { as: "button", onClick: () => {
109
109
  const header = columns.join(',');
110
110
  const body = rows
111
111
  .map(row => columns
@@ -128,12 +128,12 @@ export const OtelSqlView = ({ token, baseUrl = '', }) => {
128
128
  a.download = 'otel-query-result.csv';
129
129
  a.click();
130
130
  URL.revokeObjectURL(url);
131
- }, title: "Download as CSV", display: "flex", alignItems: "center", gap: 1, px: 2, py: "2px", border: "none", borderRadius: 2, bg: "transparent", color: "fg.muted", cursor: "pointer", fontSize: 0, hover: { color: 'accent.fg', bg: 'accent.subtle' }, children: [_jsx(DownloadIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "CSV" })] })] }), _jsx(Box, { flex: 1, minHeight: 200, overflow: "auto", border: "1px solid", borderColor: "border.default", borderRadius: 2, children: _jsxs(Box, { as: "table", width: "100%", borderCollapse: "collapse", children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", bg: "canvas.subtle", children: columns.map(col => (_jsx(Box, { as: "th", px: 3, py: 2, textAlign: "left", fontWeight: "bold", fontSize: 0, color: "fg.muted", borderBottom: "1px solid", borderColor: "border.default", whiteSpace: "nowrap", children: col }, col))) }) }), _jsx(Box, { as: "tbody", children: rows.map((row, ri) => (_jsx(Box, { as: "tr", hover: { bg: 'canvas.subtle' }, sx: {
131
+ }, title: "Download as CSV", display: "flex", alignItems: "center", gap: 1, px: 2, py: "2px", border: "none", borderRadius: 2, bg: "transparent", color: "fg.muted", cursor: "pointer", fontSize: 0, hover: { color: 'accent.fg', bg: 'accent.subtle' }, children: [_jsx(DownloadIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0 }, children: "CSV" })] })] }), _jsx(Card, { border: true, shadow: "none", display: "block", flex: 1, minHeight: 200, overflow: "auto", children: _jsxs(Box, { as: "table", width: "100%", borderCollapse: "collapse", children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", bg: "canvas.subtle", children: columns.map(col => (_jsx(Box, { as: "th", px: 3, py: 2, textAlign: "left", fontWeight: "bold", fontSize: 0, color: "fg.muted", borderBottom: "1px solid", borderColor: "border.default", whiteSpace: "nowrap", children: col }, col))) }) }), _jsx(Box, { as: "tbody", children: rows.map((row, ri) => (_jsx(Box, { as: "tr", hover: { bg: 'canvas.subtle' }, sx: {
132
132
  '&:not(:last-child) td': {
133
133
  borderBottom: '1px solid',
134
134
  borderColor: 'border.muted',
135
135
  },
136
- }, children: columns.map(col => (_jsx(Box, { as: "td", px: 3, py: 2, fontSize: 0, fontFamily: "mono", maxWidth: "300px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: String(row[col] ?? '') }, col))) }, ri))) })] }) })] })), !error && !loading && rows.length === 0 && (_jsx(Box, { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", color: "fg.muted", children: _jsx(Text, { sx: { fontSize: 1 }, children: "Run a query to see results." }) })), history.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, mb: 1, children: [_jsx(HistoryIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "History" })] }), _jsx(Box, { display: "flex", flexDirection: "column", border: "1px solid", borderColor: "border.default", borderRadius: 2, overflow: "hidden", children: history.map((entry, i) => (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 3, py: "6px", cursor: "pointer", bg: i % 2 === 0 ? 'canvas.default' : 'canvas.subtle', borderTop: i > 0 ? '1px solid' : 'none', borderColor: "border.muted", hover: { bg: 'accent.subtle' }, onClick: () => setSql(entry), children: [_jsx(Text, { sx: {
136
+ }, children: columns.map(col => (_jsx(Box, { as: "td", px: 3, py: 2, fontSize: 0, fontFamily: "mono", maxWidth: "300px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", children: String(row[col] ?? '') }, col))) }, ri))) })] }) })] })), !error && !loading && rows.length === 0 && (_jsx(Box, { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", color: "fg.muted", children: _jsx(Text, { sx: { fontSize: 1 }, children: "Run a query to see results." }) })), history.length > 0 && (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, mb: 1, children: [_jsx(HistoryIcon, { size: 12 }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "History" })] }), _jsx(Card, { border: true, shadow: "none", display: "flex", flexDirection: "column", overflow: "hidden", children: history.map((entry, i) => (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, px: 3, py: "6px", cursor: "pointer", bg: i % 2 === 0 ? 'canvas.default' : 'canvas.subtle', borderTop: i > 0 ? '1px solid' : 'none', borderColor: "border.muted", hover: { bg: 'accent.subtle' }, onClick: () => setSql(entry), children: [_jsx(Text, { sx: {
137
137
  fontFamily: 'mono',
138
138
  fontSize: 0,
139
139
  color: 'fg.default',
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Box } from '@datalayer/primer-addons';
2
+ import { Box, Card } from '@datalayer/primer-addons';
3
3
  import { Button, Spinner, Text } from '@primer/react';
4
4
  import { SyncIcon } from '@primer/octicons-react';
5
5
  import { useOtelSystem } from '../hooks/index.js';
@@ -41,5 +41,5 @@ const SystemViewContent = ({ data }) => {
41
41
  };
42
42
  export const OtelSystemView = ({ baseUrl = '', token, }) => {
43
43
  const { data, loading, error, refresh } = useOtelSystem({ baseUrl, token });
44
- return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "auto", p: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 3, flexShrink: 0, children: [_jsx(Text, { sx: { fontSize: 2, fontWeight: 'bold' }, children: "System Statistics" }), _jsx(Button, { size: "small", variant: "invisible", onClick: refresh, disabled: loading, leadingVisual: SyncIcon, children: "Refresh" })] }), loading && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading\u2026" })] })), !loading && error && (_jsx(Box, { bg: "danger.subtle", border: "1px solid", borderColor: "danger.muted", borderRadius: 2, p: 3, children: _jsx(Text, { sx: { color: 'danger.fg', fontSize: 1 }, children: error }) })), !loading && !error && data && _jsx(SystemViewContent, { data: data }), !loading && !error && !data && (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No data available." }))] }));
44
+ return (_jsxs(Box, { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "auto", p: 3, children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 3, flexShrink: 0, children: [_jsx(Text, { sx: { fontSize: 2, fontWeight: 'bold' }, children: "System Statistics" }), _jsx(Button, { size: "small", variant: "invisible", onClick: refresh, disabled: loading, leadingVisual: SyncIcon, children: "Refresh" })] }), loading && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading\u2026" })] })), !loading && error && (_jsx(Card, { border: true, shadow: "none", display: "block", bg: "danger.subtle", borderColor: "danger.muted", p: 3, children: _jsx(Text, { sx: { color: 'danger.fg', fontSize: 1 }, children: error }) })), !loading && !error && data && _jsx(SystemViewContent, { data: data }), !loading && !error && !data && (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No data available." }))] }));
45
45
  };
@@ -17,7 +17,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
17
17
  * @module otel/OtelTimelineRangeSlider
18
18
  */
19
19
  import { useCallback, useRef, useState, useMemo } from 'react';
20
- import { Box } from '@datalayer/primer-addons';
20
+ import { Box, Card } from '@datalayer/primer-addons';
21
21
  import { Text } from '@primer/react';
22
22
  // ── Helpers ─────────────────────────────────────────────────────────
23
23
  function clamp(v, min, max) {
@@ -180,7 +180,7 @@ export const OtelTimelineRangeSlider = ({ timelineStart, timelineEnd, selectedSt
180
180
  const barWidth = 100 / (histogram.length || 1);
181
181
  const barH = (h.count / histMax) * 100;
182
182
  return (_jsx(Box, { position: "absolute", bottom: 0, left: `${pct}%`, width: `${barWidth}%`, height: `${barH}%`, bg: "accent.fg", opacity: 0.35, borderRadius: "1px 1px 0 0", pointerEvents: "none", zIndex: 4 }, i));
183
- }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'start'), position: "absolute", top: 0, left: `${startPct}%`, width: HANDLE_WIDTH, height: HANDLE_HEIGHT, ml: `-${HANDLE_WIDTH / 2}px`, bg: "accent.fg", borderRadius: 1, cursor: "ew-resize", zIndex: 3, display: "flex", alignItems: "center", justifyContent: "center", transition: isDragging ? 'none' : 'left 0.05s ease', boxShadow: "shadow.medium", hover: { bg: 'accent.emphasis' }, children: _jsx(Box, { width: "2px", height: "40%", bg: "fg.onEmphasis", borderRadius: 1 }) }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'end'), position: "absolute", top: 0, left: `${endPct}%`, width: HANDLE_WIDTH, height: HANDLE_HEIGHT, ml: `-${HANDLE_WIDTH / 2}px`, bg: "accent.fg", borderRadius: 1, cursor: "ew-resize", zIndex: 3, display: "flex", alignItems: "center", justifyContent: "center", transition: isDragging ? 'none' : 'left 0.05s ease', boxShadow: "shadow.medium", hover: { bg: 'accent.emphasis' }, children: _jsx(Box, { width: "2px", height: "40%", bg: "fg.onEmphasis", borderRadius: 1 }) }), hoverPct !== null && !isDragging && (_jsxs(_Fragment, { children: [_jsx(Box, { position: "absolute", top: 0, left: `${hoverPct}%`, width: "1px", height: RAIL_HEIGHT, borderLeft: "1px dashed", borderColor: "fg.default", opacity: 0.55, pointerEvents: "none", zIndex: 5 }), _jsx(Box, { position: "absolute", top: -36, left: `${hoverPct}%`, transform: "translateX(-50%)", bg: "canvas.overlay", border: "1px solid", borderColor: "border.default", borderRadius: 2, px: 2, py: "2px", pointerEvents: "none", zIndex: 10, boxShadow: "shadow.medium", whiteSpace: "nowrap", children: _jsx(Text, { sx: {
183
+ }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'start'), position: "absolute", top: 0, left: `${startPct}%`, width: HANDLE_WIDTH, height: HANDLE_HEIGHT, ml: `-${HANDLE_WIDTH / 2}px`, bg: "accent.fg", borderRadius: 1, cursor: "ew-resize", zIndex: 3, display: "flex", alignItems: "center", justifyContent: "center", transition: isDragging ? 'none' : 'left 0.05s ease', boxShadow: "shadow.medium", hover: { bg: 'accent.emphasis' }, children: _jsx(Box, { width: "2px", height: "40%", bg: "fg.onEmphasis", borderRadius: 1 }) }), _jsx(Box, { onPointerDown: e => handlePointerDown(e, 'end'), position: "absolute", top: 0, left: `${endPct}%`, width: HANDLE_WIDTH, height: HANDLE_HEIGHT, ml: `-${HANDLE_WIDTH / 2}px`, bg: "accent.fg", borderRadius: 1, cursor: "ew-resize", zIndex: 3, display: "flex", alignItems: "center", justifyContent: "center", transition: isDragging ? 'none' : 'left 0.05s ease', boxShadow: "shadow.medium", hover: { bg: 'accent.emphasis' }, children: _jsx(Box, { width: "2px", height: "40%", bg: "fg.onEmphasis", borderRadius: 1 }) }), hoverPct !== null && !isDragging && (_jsxs(_Fragment, { children: [_jsx(Box, { position: "absolute", top: 0, left: `${hoverPct}%`, width: "1px", height: RAIL_HEIGHT, borderLeft: "1px dashed", borderColor: "fg.default", opacity: 0.55, pointerEvents: "none", zIndex: 5 }), _jsx(Card, { border: true, shadow: "none", display: "block", position: "absolute", top: -36, left: `${hoverPct}%`, transform: "translateX(-50%)", bg: "canvas.overlay", px: 2, py: "2px", pointerEvents: "none", zIndex: 10, boxShadow: "shadow.medium", whiteSpace: "nowrap", children: _jsx(Text, { sx: {
184
184
  fontSize: '11px',
185
185
  color: 'fg.default',
186
186
  fontFamily: 'mono',
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
14
  * @module otel/OtelTracesList
15
15
  */
16
16
  import { useMemo, useCallback, useState } from 'react';
17
- import { Box } from '@datalayer/primer-addons';
17
+ import { Box, Card } from '@datalayer/primer-addons';
18
18
  import { Text, Label, Spinner } from '@primer/react';
19
19
  import { Blankslate } from '@primer/react/experimental';
20
20
  import { TelescopeIcon, ChevronRightIcon, ChevronDownIcon, } from '@primer/octicons-react';
@@ -123,7 +123,7 @@ export const OtelTracesList = ({ spans, loading, selectedSpanId, onSelectSpan, e
123
123
  const usage = getTokenUsage(span);
124
124
  if (!usage)
125
125
  return null;
126
- return (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "2px", border: "1px solid", borderColor: "border.default", borderRadius: 2, px: 1, fontSize: "10px", fontFamily: "mono", color: "fg.muted", flexShrink: 0, lineHeight: "16px", children: [usage.input != null && (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "1px", children: [_jsx(Text, { sx: { fontSize: '9px', color: 'fg.subtle' }, children: "\u2197" }), _jsx(Text, { children: usage.input })] })), usage.output != null && (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "1px", children: [_jsx(Text, { sx: { fontSize: '9px', color: 'fg.subtle' }, children: "\u2199" }), _jsx(Text, { children: usage.output })] }))] }));
126
+ return (_jsxs(Card, { border: true, shadow: "none", display: "inline-flex", alignItems: "center", gap: "2px", px: 1, fontSize: "10px", fontFamily: "mono", color: "fg.muted", flexShrink: 0, lineHeight: "16px", children: [usage.input != null && (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "1px", children: [_jsx(Text, { sx: { fontSize: '9px', color: 'fg.subtle' }, children: "\u2197" }), _jsx(Text, { children: usage.input })] })), usage.output != null && (_jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "1px", children: [_jsx(Text, { sx: { fontSize: '9px', color: 'fg.subtle' }, children: "\u2199" }), _jsx(Text, { children: usage.output })] }))] }));
127
127
  })(), description && (_jsx(Text, { sx: {
128
128
  fontSize: 1,
129
129
  color: 'fg.muted',
@@ -87,7 +87,7 @@ export const AuditLog = ({ errorState, routes, filters, onFiltersChange, retenti
87
87
  }), children: [_jsx(Select.Option, { value: "", children: "Every decision" }), _jsx(Select.Option, { value: "allowed", children: "Allowed" }), _jsx(Select.Option, { value: "refused", children: "Refused" })] }), _jsxs(Select, { size: "small", "aria-label": "Outcome", value: filters.outcome ?? '', onChange: event => set({
88
88
  outcome: (event.currentTarget.value ||
89
89
  undefined),
90
- }), children: [_jsx(Select.Option, { value: "", children: "Every outcome" }), _jsx(Select.Option, { value: "ok", children: "Succeeded" }), _jsx(Select.Option, { value: "error", children: "Failed" }), _jsx(Select.Option, { value: "is_error", children: "Tool error" })] }), _jsx(Box, { display: "flex", gap: 2, justifyContent: "flex-end", children: _jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", leadingVisual: DownloadIcon, disabled: exporting.isPending, children: "Export" }), _jsx(ActionMenu.Overlay, { align: "end", children: _jsxs(ActionList, { children: [_jsxs(ActionList.Item, { onSelect: () => exportAs('jsonl'), children: ["JSONL", _jsx(ActionList.Description, { variant: "block", children: "One row per line, as a SIEM reads it." })] }), _jsxs(ActionList.Item, { onSelect: () => exportAs('csv'), children: ["CSV", _jsx(ActionList.Description, { variant: "block", children: "The same rows for a spreadsheet." })] })] }) })] }) })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["Audit rows are written once and never changed or deleted by anyone, here or elsewhere. Arguments are redacted before they are written.", ' ', retention] }), page.isPending && !page.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 6, children: _jsx(Spinner, {}) })) : rows.length === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(HistoryIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "Nothing to audit yet" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Every call an agent makes is written down here with its decision and its outcome. Connect a client and ask it to list your notebooks." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.access), children: "Connect an agent" })] })) : (
90
+ }), children: [_jsx(Select.Option, { value: "", children: "Every outcome" }), _jsx(Select.Option, { value: "ok", children: "Succeeded" }), _jsx(Select.Option, { value: "error", children: "Failed" }), _jsx(Select.Option, { value: "is_error", children: "Tool error" })] }), _jsx(Box, { display: "flex", gap: 2, justifyContent: "flex-end", children: _jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { size: "small", leadingVisual: DownloadIcon, disabled: exporting.isPending, children: "Export" }), _jsx(ActionMenu.Overlay, { align: "end", children: _jsxs(ActionList, { children: [_jsxs(ActionList.Item, { onSelect: () => exportAs('jsonl'), children: ["JSONL", _jsx(ActionList.Description, { variant: "block", children: "One row per line, as a SIEM reads it." })] }), _jsxs(ActionList.Item, { onSelect: () => exportAs('csv'), children: ["CSV", _jsx(ActionList.Description, { variant: "block", children: "The same rows for a spreadsheet." })] })] }) })] }) })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: ["Audit rows are written once and never changed or deleted by anyone, here or elsewhere. Arguments are redacted before they are written.", ' ', retention] }), page.isPending && !page.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 6, children: _jsx(Spinner, {}) })) : rows.length === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(HistoryIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "Nothing to audit yet" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Every call an agent makes is written down here with its decision and its outcome. Connect a client and ask it to list your notebooks." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.configuration), children: "Connect an agent" })] })) : (
91
91
  /* The rail of the activity view: each mark on a tinted disc, the discs
92
92
  linked by a line, so the rows carry no border of their own. */
93
93
  _jsx(Box, { display: "grid", children: rows.map((event, index) => {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The agents a person has connected, and the one action that matters:
2
+ * The MCP clients a person has authorized, and the one action that matters:
3
3
  * disconnecting one.
4
4
  *
5
5
  * A grant is not a setting — it is authority a person handed to a piece of
@@ -3,7 +3,7 @@ import { useMemo, useRef, useState } from 'react';
3
3
  import { ActionList, ActionMenu, Button, Heading, Label, RelativeTime, Spinner, Text, } from '@primer/react';
4
4
  import { Blankslate, DataTable, Dialog, Table, } from '@primer/react/experimental';
5
5
  import { Box } from '@datalayer/primer-addons';
6
- import { KebabHorizontalIcon, PlugIcon } from '@primer/octicons-react';
6
+ import { KebabHorizontalIcon, McpIcon } from '@primer/octicons-react';
7
7
  import { ClientBadge, McpErrorBlankslate, ScopeList, } from '../../components/mcp/index.js';
8
8
  import { useConnectedAgents, useDisconnectAgent, useDisconnectEveryAgent, } from '../../hooks/useMcp.js';
9
9
  import { useNavigate, useToast } from '../../hooks/index.js';
@@ -24,8 +24,8 @@ export const ConnectedAgents = ({ errorState, routes, showTitle = true, readOnly
24
24
  disconnectEvery.mutate(undefined, {
25
25
  onSuccess: answer => {
26
26
  enqueueToast(answer.revoked === 1
27
- ? '1 agent disconnected.'
28
- : `${answer.revoked} agents disconnected.`, { variant: 'success' });
27
+ ? '1 client disconnected.'
28
+ : `${answer.revoked} clients disconnected.`, { variant: 'success' });
29
29
  setDisconnectingEvery(false);
30
30
  },
31
31
  onError: error => {
@@ -75,19 +75,22 @@ export const ConnectedAgents = ({ errorState, routes, showTitle = true, readOnly
75
75
  {
76
76
  header: 'Allowed to',
77
77
  id: 'scopes',
78
- width: 'growCollapse',
78
+ // Room for its scopes, which wrap inside the cell rather than run
79
+ // over the dates beside it (30 October 2026).
80
+ width: 'grow',
81
+ minWidth: '240px',
79
82
  renderCell: row => _jsx(ScopeList, { scopes: row.scopes }),
80
83
  },
81
84
  {
82
85
  header: 'Connected',
83
86
  id: 'created',
84
- width: '130px',
87
+ width: '140px',
85
88
  renderCell: row => row.createdAt ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: _jsx(RelativeTime, { datetime: row.createdAt }) })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "\u2014" })),
86
89
  },
87
90
  {
88
91
  header: 'Last used',
89
92
  id: 'last-used',
90
- width: '130px',
93
+ width: '140px',
91
94
  renderCell: row => row.lastUsedAt ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: _jsx(RelativeTime, { datetime: row.lastUsedAt }) })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Never" })),
92
95
  },
93
96
  {
@@ -99,9 +102,9 @@ export const ConnectedAgents = ({ errorState, routes, showTitle = true, readOnly
99
102
  },
100
103
  ];
101
104
  if (agents.isError) {
102
- return (_jsx(McpErrorBlankslate, { state: errorState(agents.error, 'Connected agents'), onRetry: () => agents.refetch() }));
105
+ return (_jsx(McpErrorBlankslate, { state: errorState(agents.error, 'Authorized clients'), onRetry: () => agents.refetch() }));
103
106
  }
104
- return (_jsxs(Box, { display: "grid", gap: 3, minWidth: 0, children: [showTitle && (_jsxs(Box, { display: "flex", alignItems: "start", justifyContent: "space-between", gap: 3, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Connected Agents" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Every agent you have authorized, what it may do, and when it last did it." })] }), !readOnly && rows.length > 0 && (_jsx(Button, { variant: "danger", onClick: () => setDisconnectingEvery(true), disabled: disconnectEvery.isPending, children: "Disconnect all" }))] })), agents.isPending && !agents.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 5, children: _jsx(Spinner, {}) })) : rows.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "connected-agents", children: "Agents" }), _jsx(Table.Subtitle, { as: "p", id: "connected-agents-subtitle", children: "An agent acts with exactly the access of the person who authorized it, and no more." }), _jsx(DataTable, { "aria-labelledby": "connected-agents", "aria-describedby": "connected-agents-subtitle", data: rows, columns: columns })] })) : (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(PlugIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No agent connected" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Connect an MCP client and approve the scopes it asks for; the grant appears here and can be revoked from here." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.access), children: "Connect an agent" })] })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: "Narrowing a grant to fewer scopes without disconnecting arrives with the organization policy." }), disconnecting && (_jsx(Dialog, { title: "Disconnect this agent?", onClose: () => setDisconnecting(null), returnFocusRef: returnFocusRef, footerButtons: [
107
+ return (_jsxs(Box, { display: "grid", gap: 3, minWidth: 0, children: [showTitle && (_jsxs(Box, { display: "flex", alignItems: "start", justifyContent: "space-between", gap: 3, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Authorized clients" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Every MCP client you have authorized, what it may do, and when it last did it." })] }), !readOnly && rows.length > 0 && (_jsx(Button, { variant: "danger", onClick: () => setDisconnectingEvery(true), disabled: disconnectEvery.isPending, children: "Disconnect all" }))] })), agents.isPending && !agents.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 5, children: _jsx(Spinner, {}) })) : rows.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "authorized-clients", children: "Clients" }), _jsx(Table.Subtitle, { as: "p", id: "authorized-clients-subtitle", children: "A client acts with exactly the access of the person who authorized it, and no more." }), _jsx(DataTable, { "aria-labelledby": "authorized-clients", "aria-describedby": "authorized-clients-subtitle", data: rows, columns: columns })] })) : (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(McpIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "No client authorized" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Connect an MCP client and approve the scopes it asks for; the grant appears here and can be revoked from here." }) }), _jsx(Button, { size: "small", onClick: () => navigate(routes.configuration), children: "Connect a client" })] })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.subtle' }, children: "Narrowing a grant to fewer scopes without disconnecting arrives with the organization policy." }), disconnecting && (_jsx(Dialog, { title: "Disconnect this client?", onClose: () => setDisconnecting(null), returnFocusRef: returnFocusRef, footerButtons: [
105
108
  {
106
109
  buttonType: 'default',
107
110
  content: 'Keep it',
@@ -113,7 +116,7 @@ export const ConnectedAgents = ({ errorState, routes, showTitle = true, readOnly
113
116
  onClick: confirmDisconnect,
114
117
  disabled: disconnect.isPending,
115
118
  },
116
- ], children: _jsxs(Text, { sx: { fontSize: 1 }, children: [disconnecting.clientName || disconnecting.clientId, " loses its grant at once and its next call is refused. An access token it still holds dies with its own short expiry. The other agents are untouched, and nothing this one already did is undone."] }) })), disconnectingEvery && (_jsxs(Dialog, { title: "Disconnect every agent?", onClose: () => setDisconnectingEvery(false), returnFocusRef: returnFocusRef, footerButtons: [
119
+ ], children: _jsxs(Text, { sx: { fontSize: 1 }, children: [disconnecting.clientName || disconnecting.clientId, " loses its grant at once and its next call is refused. An access token it still holds dies with its own short expiry. The other clients are untouched, and nothing this one already did is undone."] }) })), disconnectingEvery && (_jsxs(Dialog, { title: "Disconnect every client?", onClose: () => setDisconnectingEvery(false), returnFocusRef: returnFocusRef, footerButtons: [
117
120
  {
118
121
  buttonType: 'default',
119
122
  content: 'Keep them',
@@ -125,6 +128,6 @@ export const ConnectedAgents = ({ errorState, routes, showTitle = true, readOnly
125
128
  onClick: confirmDisconnectEvery,
126
129
  disabled: disconnectEvery.isPending,
127
130
  },
128
- ], children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Every agent you have authorized loses its grant at once \u2014 signing out everywhere. Each will ask again the next time you connect it, and this time it goes through the approval screen rather than being answered from what you agreed before, so this is also how you force a fresh approval." }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', mt: 2, mb: 0 }, children: "Yours only. Nobody else\u2019s sessions end, in this organization or any other, and nothing any agent already did is undone." })] }))] }));
131
+ ], children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Every client you have authorized loses its grant at once \u2014 signing out everywhere. Each will ask again the next time you connect it, and this time it goes through the approval screen rather than being answered from what you agreed before, so this is also how you force a fresh approval." }), _jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', mt: 2, mb: 0 }, children: "Yours only. Nobody else\u2019s sessions end, in this organization or any other, and nothing any client already did is undone." })] }))] }));
129
132
  };
130
133
  export default ConnectedAgents;
@@ -45,6 +45,6 @@ export interface McpDashboardProps {
45
45
  section: McpDashboardSection;
46
46
  }
47
47
  /** The parts of the dashboard, each its own tab. */
48
- export type McpDashboardSection = 'overview' | 'agents' | 'runs' | 'sandboxes' | 'calls';
48
+ export type McpDashboardSection = 'overview' | 'clients' | 'runs' | 'sandboxes' | 'calls';
49
49
  export declare const McpDashboard: ({ errorState, routes, org, showTitle, section, }: McpDashboardProps) => JSX.Element;
50
50
  export default McpDashboard;
@@ -3,7 +3,7 @@ import { useMemo, useRef, useState } from 'react';
3
3
  import { ActionList, ActionMenu, Button, Heading, Label, Link, RelativeTime, Select, Spinner, Text, } from '@primer/react';
4
4
  import { Blankslate, DataTable, Dialog, Table, } from '@primer/react/experimental';
5
5
  import { Box, Card } from '@datalayer/primer-addons';
6
- import { ChecklistIcon, KebabHorizontalIcon, PlayIcon, PlugIcon, StackIcon, } from '@primer/octicons-react';
6
+ import { ChecklistIcon, KebabHorizontalIcon, PlayIcon, McpIcon, PackageIcon, } from '@primer/octicons-react';
7
7
  import { ShareAccessDialog, sandboxSharingUrl } from '../../components/sharing/index.js';
8
8
  import { ClientBadge, McpErrorBlankslate } from '../../components/mcp/index.js';
9
9
  import { useDisconnectAgent, useMcpActivity, useTerminateBinding, } from '../../hooks/useMcp.js';
@@ -375,17 +375,17 @@ export const McpDashboard = ({ errorState, routes, org, showTitle = true, sectio
375
375
  'repeat(2, 1fr)',
376
376
  'repeat(3, 1fr)',
377
377
  'repeat(6, 1fr)',
378
- ], children: [_jsx(Count, { label: "Clients connected", value: clients.length, to: routes.agents, onOpen: navigate }), _jsx(Count, { label: "Sandboxes bound", to: routes.sandboxes, onOpen: navigate, value: sandboxes.filter(binding => (binding.state ?? 'active') === 'active').length }), _jsx(Count, { label: "Tasks running", value: data?.tasks.length ?? 0, to: routes.runs, onOpen: navigate }), _jsx(Count, { label: "Calls today", value: data?.today.calls ?? 0, to: routes.calls, onOpen: navigate }), _jsx(Count, { label: "Refusals today", value: data?.today.refusals ?? 0, to: routes.audit, onOpen: navigate, tone: (data?.today.refusals ?? 0) > 0 ? 'danger' : 'neutral' }), _jsx(Count, { label: "Credits by agents", value: data?.today.credits ?? 0, note: "today",
378
+ ], children: [_jsx(Count, { label: "Clients connected", value: clients.length, to: routes.clients, onOpen: navigate }), _jsx(Count, { label: "Sandboxes bound", to: routes.sandboxes, onOpen: navigate, value: sandboxes.filter(binding => (binding.state ?? 'active') === 'active').length }), _jsx(Count, { label: "Tasks running", value: data?.tasks.length ?? 0, to: routes.runs, onOpen: navigate }), _jsx(Count, { label: "Calls today", value: data?.today.calls ?? 0, to: routes.calls, onOpen: navigate }), _jsx(Count, { label: "Refusals today", value: data?.today.refusals ?? 0, to: routes.audit, onOpen: navigate, tone: (data?.today.refusals ?? 0) > 0 ? 'danger' : 'neutral' }), _jsx(Count, { label: "Credits by agents", value: data?.today.credits ?? 0, note: "today",
379
379
  // Credits are summed from the day's calls, which the Calls tab
380
380
  // lists.
381
- to: routes.calls, onOpen: navigate })] }))), draws('agents') &&
381
+ to: routes.calls, onOpen: navigate })] }))), draws('clients') &&
382
382
  !loading &&
383
- (clients.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-clients", children: "Connected clients" }), _jsxs(Table.Subtitle, { as: "p", id: "mcp-clients-subtitle", children: [plural(clients.length, 'client'), " with a live grant on your workspace."] }), _jsx(DataTable, { "aria-labelledby": "mcp-clients", "aria-describedby": "mcp-clients-subtitle", data: clients, columns: clientColumns })] })) : (_jsx(PanelEmpty, { icon: PlugIcon, heading: "No client connected", description: "Connect Claude Code, Codex, Cursor, VS Code or any MCP client to your workspace, and it appears here on its first call.", action: {
383
+ (clients.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-clients", children: "Live connections" }), _jsxs(Table.Subtitle, { as: "p", id: "mcp-clients-subtitle", children: [plural(clients.length, 'client'), " connected to your workspace now, with its status and the last tool it called."] }), _jsx(DataTable, { "aria-labelledby": "mcp-clients", "aria-describedby": "mcp-clients-subtitle", data: clients, columns: clientColumns })] })) : (_jsx(PanelEmpty, { icon: McpIcon, heading: "No client connected", description: "Connect Claude Code, Codex, Cursor, VS Code or any MCP client to your workspace, and it appears here on its first call.", action: {
384
384
  label: 'Set up a client',
385
- onClick: () => navigate(routes.access),
385
+ onClick: () => navigate(routes.configuration),
386
386
  } }))), draws('runs') && !loading && (_jsx(Box, { children: tasks.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-runs", children: "Running now" }), _jsx(Table.Subtitle, { as: "p", id: "mcp-runs-subtitle", children: "A tool call that outlives its request. Open one to watch its output, cancel it, or answer it when it is waiting on you." }), _jsx(DataTable, { "aria-labelledby": "mcp-runs", "aria-describedby": "mcp-runs-subtitle", data: tasks, columns: taskColumns })] })) : (_jsx(PanelEmpty, { icon: PlayIcon, heading: "Nothing is running", description: "A tool call that outlives its request becomes a task you can watch, cancel and answer. Ask a client for one \u2014 an agent that runs a long cell \u2014 and it appears here while it runs." })) })), draws('sandboxes') &&
387
387
  !loading &&
388
- (sandboxes.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-sandboxes", children: "Sandboxes bound" }), _jsx(Table.Subtitle, { as: "p", id: "mcp-sandboxes-subtitle", children: "The sessions your agents execute in. Terminating one ends its open work." }), _jsx(DataTable, { "aria-labelledby": "mcp-sandboxes", "aria-describedby": "mcp-sandboxes-subtitle", data: sandboxes, columns: sandboxColumns })] })) : (_jsx(PanelEmpty, { icon: StackIcon, heading: "No sandbox bound", description: "An agent that launches a sandbox keeps it for the session; it appears here with its provider, its capabilities and what it is doing." }))), draws('calls') &&
388
+ (sandboxes.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-sandboxes", children: "Sandboxes bound" }), _jsx(Table.Subtitle, { as: "p", id: "mcp-sandboxes-subtitle", children: "The sessions your agents execute in. Terminating one ends its open work." }), _jsx(DataTable, { "aria-labelledby": "mcp-sandboxes", "aria-describedby": "mcp-sandboxes-subtitle", data: sandboxes, columns: sandboxColumns })] })) : (_jsx(PanelEmpty, { icon: PackageIcon, heading: "No Code Sandbox bound", description: "An agent that launches a sandbox keeps it for the session; it appears here with its provider, its capabilities and what it is doing." }))), draws('calls') &&
389
389
  !loading &&
390
390
  (calls.length > 0 ? (_jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h3", id: "mcp-calls", children: "Recent calls" }), _jsx(Table.Subtitle, { as: "p", id: "mcp-calls-subtitle", children: "The last calls as they landed. Every one of them has an audit row that outlives this page." }), _jsx(Table.Actions, { children: _jsxs(Box, { display: "flex", gap: 2, alignItems: "center", children: [_jsxs(Select, { size: "small", "aria-label": "Filter by client", value: callClient, onChange: event => setCallClient(event.currentTarget.value), children: [_jsx(Select.Option, { value: "", children: "Every client" }), clients.map(client => (_jsx(Select.Option, { value: client.clientId, children: client.clientName || client.clientId }, client.clientId)))] }), _jsxs(Select, { size: "small", "aria-label": "Filter by tool", value: callTool, onChange: event => setCallTool(event.currentTarget.value), children: [_jsx(Select.Option, { value: "", children: "Every tool" }), callTools.map(tool => (_jsx(Select.Option, { value: tool, children: tool }, tool)))] }), _jsxs(Select, { size: "small", "aria-label": "Filter by outcome", value: callOutcome, onChange: event => setCallOutcome(event.currentTarget.value), children: [_jsx(Select.Option, { value: "", children: "Every outcome" }), _jsx(Select.Option, { value: "ok", children: "Succeeded" }), _jsx(Select.Option, { value: "error", children: "Failed" }), _jsx(Select.Option, { value: "refused", children: "Refused" })] })] }) }), filteredCalls.length > 0 ? (_jsx(DataTable, { "aria-labelledby": "mcp-calls", "aria-describedby": "mcp-calls-subtitle", data: filteredCalls, columns: callColumns })) : (_jsx(Box, { p: 4, textAlign: "center", color: "fg.muted", fontSize: 1, children: "No call matches these filters." }))] })) : (_jsx(PanelEmpty, { icon: ChecklistIcon, heading: "No call yet", description: "Ask your agent to list your notebooks. The call, its decision and its outcome land here and in the audit log.", action: {
391
391
  label: 'Open the audit log',
@@ -85,8 +85,10 @@ export declare const MCP_CLIENTS: {
85
85
  * does: a reader who has seen one and then the other should not have to
86
86
  * work out whether they are the same affordance.
87
87
  */
88
- export declare const Copyable: ({ text }: {
88
+ export declare const Copyable: ({ text, compact, }: {
89
89
  text: string;
90
+ /** As wide as the text, with the button right after it. */
91
+ compact?: boolean;
90
92
  }) => JSX.Element;
91
93
  export declare const McpHome: ({ routes, clientDocsBase, showTitle, showSummaries, showSetup, onOpenDocs, }: McpHomeProps) => JSX.Element;
92
94
  export default McpHome;
@@ -39,12 +39,12 @@ export const MCP_CLIENTS = [
39
39
  * does: a reader who has seen one and then the other should not have to
40
40
  * work out whether they are the same affordance.
41
41
  */
42
- export const Copyable = ({ text }) => {
42
+ export const Copyable = ({ text, compact = false, }) => {
43
43
  const [copied, setCopied] = useState(false);
44
- return (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, p: 2, bg: "canvas.inset", borderRadius: 2, minWidth: 0, children: [_jsx(Text, { sx: {
44
+ return (_jsxs(Box, { display: compact ? 'inline-flex' : 'flex', justifySelf: compact ? 'start' : undefined, maxWidth: "100%", alignItems: "center", gap: 2, p: 2, bg: "canvas.inset", borderRadius: 2, minWidth: 0, children: [_jsx(Text, { sx: {
45
45
  fontFamily: 'mono',
46
46
  fontSize: 0,
47
- flex: 1,
47
+ flex: compact ? undefined : 1,
48
48
  minWidth: 0,
49
49
  overflow: 'hidden',
50
50
  textOverflow: 'ellipsis',
@@ -79,7 +79,7 @@ export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitl
79
79
  const live = activity.data?.clients.length ?? 0;
80
80
  return (_jsxs(Box, { display: "grid", gap: 4, minWidth: 0, children: [showTitle && (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "MCP" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Connect your agents to your notebooks, data and sandboxes through the Model Context Protocol." })] })), showSetup && (_jsxs(_Fragment, { children: [_jsxs(Card, { border: true, shadow: "none", variant: "subtle", flexDirection: "row", display: "flex", alignItems: "center", gap: 3, flexWrap: "wrap", p: 3, children: [_jsx(Text, { sx: { fontSize: 1 }, children: live > 0
81
81
  ? `${plural(live, 'client')} connected right now.`
82
- : 'No client is connected right now.' }), _jsx(Button, { size: "small", leadingVisual: PulseIcon, onClick: () => navigate(routes.dashboard), children: "What is going on" })] }), _jsxs(Box, { display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "The endpoint" }), _jsx(Copyable, { text: endpoint || 'https://mcp.datalayer.run/mcp' }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(KeyIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: signedIn
82
+ : 'No client is connected right now.' }), _jsx(Button, { size: "small", leadingVisual: PulseIcon, onClick: () => navigate(routes.dashboard), children: "What is going on" })] }), _jsxs(Box, { display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "The endpoint" }), _jsx(Copyable, { compact: true, text: endpoint || 'https://mcp.datalayer.run/mcp' }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(KeyIcon, { size: 14 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: signedIn
83
83
  ? 'You are signed in, so a client you set up from here authorizes through OAuth without a shared token.'
84
84
  : 'Sign in to authorize a client through OAuth; without it a client can only use a personal access token.' })] })] }), _jsxs(Box, { display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "Set up a client" }), _jsx(Box, { display: "grid", gap: 3, gridTemplateColumns: ['1fr', 'repeat(2, 1fr)', 'repeat(3, 1fr)'], children: MCP_CLIENTS.map(client => (_jsxs(Card, { border: true, shadow: "none", p: 3, display: "grid", gap: 2, minWidth: 0, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold' }, children: client.name }), _jsx(Copyable, { text: mcpSetupCommand(client.setup) }), _jsx(Link, { href: `${clientDocsBase}/${client.setup}`, sx: { fontSize: 0, cursor: 'pointer', textAlign: 'left' }, onClick: event => {
85
85
  // A modified click is the reader asking for a new tab or
@@ -91,10 +91,10 @@ export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitl
91
91
  }
92
92
  event.preventDefault();
93
93
  onOpenDocs(`${clientDocsBase}/${client.setup}`);
94
- }, children: "Configuration and authorization" })] }, client.setup))) })] })] })), showSummaries && (_jsxs(Box, { display: "grid", gap: 3, gridTemplateColumns: ['1fr', 'repeat(2, 1fr)', 'repeat(3, 1fr)'], children: [_jsx(Summary, { icon: AiAgentIcon, title: "Agents", to: routes.agents, onOpen: navigate, action: {
95
- label: 'Connected agents',
96
- onClick: () => navigate(routes.agents),
97
- }, children: connected.length === 0 ? (_jsx(Text, { children: "No agent has been authorized yet. Set up a client above and approve the scopes it asks for." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [plural(connected.length, 'agent'), " authorized."] }), connected.slice(0, 3).map(agent => (_jsxs(Text, { children: [agent.clientName || agent.clientId, " \u2014", ' ', agent.lastUsedAt
94
+ }, children: "Configuration and authorization" })] }, client.setup))) })] })] })), showSummaries && (_jsxs(Box, { display: "grid", gap: 3, gridTemplateColumns: ['1fr', 'repeat(2, 1fr)', 'repeat(3, 1fr)'], children: [_jsx(Summary, { icon: AiAgentIcon, title: "Clients", to: routes.clients, onOpen: navigate, action: {
95
+ label: 'Authorized clients',
96
+ onClick: () => navigate(routes.clients),
97
+ }, children: connected.length === 0 ? (_jsx(Text, { children: "No client has been authorized yet. Set up a client above and approve the scopes it asks for." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { children: [plural(connected.length, 'client'), " authorized."] }), connected.slice(0, 3).map(agent => (_jsxs(Text, { children: [agent.clientName || agent.clientId, " \u2014", ' ', agent.lastUsedAt
98
98
  ? `used ${timeAgo(agent.lastUsedAt)}`
99
99
  : 'never used'] }, agent.uid)))] })) }), _jsx(Summary, { icon: PulseIcon, title: "Runs", to: routes.runs, onOpen: navigate, action: { label: 'All runs', onClick: () => navigate(routes.runs) }, children: runs.length === 0 ? (_jsx(Text, { children: "Nothing has run yet. A tool call that outlives its request becomes a run you can watch and cancel." })) : (runs.map(task => (_jsxs(Text, { children: [task.tool, " \u2014 ", task.status, " ", timeAgo(task.lastUpdatedAt)] }, task.uid)))) }), _jsxs(Summary, { icon: TelescopeIcon, title: "Observability", to: routes.observability, onOpen: navigate, action: {
100
100
  label: 'Runs and metrics',
@@ -106,7 +106,17 @@ export const McpHome = ({ routes, clientDocsBase = '/docs/mcp-clients', showTitl
106
106
  : 'Latency not measured yet.' }), _jsx(Text, { children: metrics.data?.slis.availability === null ||
107
107
  metrics.data?.slis.availability === undefined
108
108
  ? 'Error rate not measured yet.'
109
- : `${((1 - metrics.data.slis.availability) * 100).toFixed(1)}% of calls failed.` })] }), _jsx(Summary, { icon: ToolsIcon, title: "Tools", children: _jsx(Text, { children: "The toolsets an agent may execute \u2014 the Contents sources you have enabled for it, their tools, their approval policy and their health \u2014 are managed here once toolset bindings ship." }) }), _jsx(Summary, { icon: RssIcon, title: "Reach", children: _jsx(Text, { children: "Which notebooks and sources an agent can actually reach, as a list you can read at a glance, arrives with sharing to agents as principals." }) }), _jsx(Summary, { icon: ShieldCheckIcon, title: "Policies", to: routes.policies, onOpen: navigate, action: {
109
+ : `${((1 - metrics.data.slis.availability) * 100).toFixed(1)}% of calls failed.` })] }), _jsx(Summary, { icon: ToolsIcon, title: "Tools", to: routes.tools, onOpen: navigate, action: routes.tools
110
+ ? {
111
+ label: 'What each agent may execute',
112
+ onClick: () => navigate(routes.tools),
113
+ }
114
+ : undefined, children: _jsx(Text, { children: "The toolsets each of your agents may execute, with their tools, their approval policy and their health." }) }), _jsx(Summary, { icon: RssIcon, title: "Reach", to: routes.reach, onOpen: navigate, action: routes.reach
115
+ ? {
116
+ label: 'What each agent reaches',
117
+ onClick: () => navigate(routes.reach),
118
+ }
119
+ : undefined, children: _jsx(Text, { children: "The notebooks and sources each of your agents can actually reach, and whether it may read, edit or run them." }) }), _jsx(Summary, { icon: ShieldCheckIcon, title: "Policies", to: routes.policies, onOpen: navigate, action: {
110
120
  label: 'What applies',
111
121
  onClick: () => navigate(routes.policies),
112
122
  }, children: _jsx(Text, { children: "What your agents are allowed to do, and which layer decided each rule." }) })] }))] }));
@@ -157,7 +157,7 @@ export const Policies = ({ errorState, routes, organizationName, showTitle = tru
157
157
  }
158
158
  return (_jsxs(Box, { display: "grid", gap: 4, minWidth: 0, children: [showTitle && (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Policies" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: previewAs
159
159
  ? 'What applies to this agent, and which layer decided it.'
160
- : 'What applies to your agents, and which layer decided it.' })] })), (agents.data?.length ?? 0) > 1 && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Preview as" }), _jsx(Box, { minWidth: "18rem", children: _jsxs(Select, { value: previewAs, onChange: event => setPreviewAs(event.target.value), "aria-label": "Preview the policy as", children: [_jsx(Select.Option, { value: "", children: "You \u2014 your own token" }), (agents.data ?? []).map(agent => (_jsx(Select.Option, { value: agent.clientId, children: agent.clientName || agent.clientId }, agent.uid)))] }) }), previewAs && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "A grant carries its own scopes and its own admitted clients, so this can differ from what applies to you." }))] })), policy.isPending && !policy.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 6, children: _jsx(Spinner, {}) })) : rows.length === 0 && tools.length === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(ShieldCheckIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "The defaults apply" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "No agent is connected yet, so nothing narrows the Datalayer defaults. Connect a client and this page fills with what its calls are allowed to do." }) }), _jsx(Link, { as: "button", sx: { cursor: 'pointer' }, onClick: () => navigate(routes.access), children: "Set up a client" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "What applies to your agents" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Scope of this reading: ", policy.data?.scope ?? 'personal', policy.data?.evaluatedAt
160
+ : 'What applies to your agents, and which layer decided it.' })] })), (agents.data?.length ?? 0) > 1 && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Preview as" }), _jsx(Box, { minWidth: "18rem", children: _jsxs(Select, { value: previewAs, onChange: event => setPreviewAs(event.target.value), "aria-label": "Preview the policy as", children: [_jsx(Select.Option, { value: "", children: "You \u2014 your own token" }), (agents.data ?? []).map(agent => (_jsx(Select.Option, { value: agent.clientId, children: agent.clientName || agent.clientId }, agent.uid)))] }) }), previewAs && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "A grant carries its own scopes and its own admitted clients, so this can differ from what applies to you." }))] })), policy.isPending && !policy.data ? (_jsx(Box, { display: "flex", justifyContent: "center", py: 6, children: _jsx(Spinner, {}) })) : rows.length === 0 && tools.length === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(ShieldCheckIcon, { size: "medium" }) }), _jsx(Blankslate.Heading, { children: "The defaults apply" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "No agent is connected yet, so nothing narrows the Datalayer defaults. Connect a client and this page fills with what its calls are allowed to do." }) }), _jsx(Link, { as: "button", sx: { cursor: 'pointer' }, onClick: () => navigate(routes.configuration), children: "Set up a client" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Box, { display: "grid", gap: 2, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "What applies to your agents" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Scope of this reading: ", policy.data?.scope ?? 'personal', policy.data?.evaluatedAt
161
161
  ? ` · evaluated ${policy.data.evaluatedAt}`
162
162
  : ''] })] }), _jsxs(Table.Container, { children: [_jsx(Table.Title, { as: "h4", id: "effective-policy", children: "Effective policy" }), _jsx(Table.Subtitle, { as: "p", id: "effective-policy-subtitle", children: "Each layer only narrows the one above it, so the strictest rule is what applies." }), _jsxs(Box, { as: "table", "aria-labelledby": "effective-policy", "aria-describedby": "effective-policy-subtitle", width: "100%", borderCollapse: "collapse", children: [_jsx(Box, { as: "thead", children: _jsx(Box, { as: "tr", children: ['Rule', 'What applies', 'Decided by'].map(header => (_jsx(Box, { as: "th", textAlign: "left", fontSize: 0, color: "fg.muted", fontWeight: "semibold", py: 2, px: 2, borderBottom: "1px solid", borderColor: "border.default", children: header }, header))) }) }), _jsx(Box, { as: "tbody", children: rows.map(row => (_jsxs(Box, { as: "tr", children: [_jsxs(Box, { as: "td", py: 2, px: 2, borderBottom: "1px solid", borderColor: "border.muted", verticalAlign: "top", children: [_jsx(Text, { sx: { fontSize: 1, display: 'block' }, children: row.label }), row.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: row.description }))] }), _jsx(Box, { as: "td", py: 2, px: 2, borderBottom: "1px solid", borderColor: "border.muted", verticalAlign: "top", children: _jsx(Text, { sx: { fontSize: 1 }, children: ruleValueLabel(row.rule.value) }) }), _jsxs(Box, { as: "td", py: 2, px: 2, borderBottom: "1px solid", borderColor: "border.muted", verticalAlign: "top", whiteSpace: "nowrap", children: [_jsx(Label, { size: "small", variant: LAYER_VARIANT[row.rule.decidedBy], children: layerLabel(row.rule.decidedBy, organizationName) }), row.rule.reason && (_jsx(Text, { sx: {
163
163
  fontSize: 0,
@@ -51,20 +51,24 @@ export type McpErrorStateFn = (error: unknown, subject: string) => McpErrorState
51
51
  export interface McpRoutes {
52
52
  /** The dashboard: what the connected clients are doing right now. */
53
53
  dashboard: string;
54
- /** Setup and access: the endpoint and the per-client cards. */
55
- access: string;
54
+ /** Configuration: the endpoint and the per-client setup cards. */
55
+ configuration: string;
56
56
  /** The audit log. */
57
57
  audit: string;
58
58
  /** The runs list; a task appends `/{uid}`. */
59
59
  runs: string;
60
60
  /** The observability panes. */
61
61
  observability: string;
62
- /** The connected agents. */
63
- agents: string;
62
+ /** The MCP clients: live connections and authorized clients. */
63
+ clients: string;
64
64
  /** The effective policy. */
65
65
  policies: string;
66
66
  /** The calls list, where an Overview count of calls or credits leads. */
67
67
  calls?: string;
68
68
  /** The bound code sandboxes, where the Overview's sandbox count leads. */
69
69
  sandboxes?: string;
70
+ /** What each agent may execute, where the Tools summary leads. */
71
+ tools?: string;
72
+ /** What each agent can reach, where the Reach summary leads. */
73
+ reach?: string;
70
74
  }
@@ -11,7 +11,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
11
11
  * pass `onSignOut` to wire up your own logout action.
12
12
  */
13
13
  import { useState, useCallback, useRef } from 'react';
14
- import { Box } from '@datalayer/primer-addons';
14
+ import { Box, Card } from '@datalayer/primer-addons';
15
15
  import { Text, Button, Dialog } from '@primer/react';
16
16
  import { TelescopeIcon, SignOutIcon } from '@primer/octicons-react';
17
17
  import { UserBadge } from '../profile/index.js';
@@ -67,5 +67,5 @@ export const OtelHeader = ({ baseUrl = '', token, trailing, onNavigate, onSignOu
67
67
  onClick: () => setDialogOpen(false),
68
68
  buttonType: 'default',
69
69
  },
70
- ], children: [_jsxs(Box, { mb: 2, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Request" }), _jsx(Box, { as: "pre", fontFamily: "mono", fontSize: 1, p: 2, mt: 1, bg: "canvas.inset", borderRadius: 2, overflow: "auto", color: "fg.default", whiteSpace: "pre-wrap", wordBreak: "break-all", border: "1px solid", borderColor: "border.default", children: dialogRequest })] }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Response" }), _jsx(Box, { as: "pre", fontFamily: "mono", fontSize: 1, p: 2, mt: 1, bg: "canvas.subtle", borderRadius: 2, overflow: "auto", maxHeight: 300, color: dialogVariant === 'error' ? 'danger.fg' : 'fg.default', whiteSpace: "pre-wrap", wordBreak: "break-all", children: dialogBody })] })] }))] }));
70
+ ], children: [_jsxs(Box, { mb: 2, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Request" }), _jsx(Card, { border: true, shadow: "none", display: "block", as: "pre", fontFamily: "mono", fontSize: 1, p: 2, mt: 1, bg: "canvas.inset", overflow: "auto", color: "fg.default", whiteSpace: "pre-wrap", wordBreak: "break-all", children: dialogRequest })] }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1, color: 'fg.muted' }, children: "Response" }), _jsx(Box, { as: "pre", fontFamily: "mono", fontSize: 1, p: 2, mt: 1, bg: "canvas.subtle", borderRadius: 2, overflow: "auto", maxHeight: 300, color: dialogVariant === 'error' ? 'danger.fg' : 'fg.default', whiteSpace: "pre-wrap", wordBreak: "break-all", children: dialogBody })] })] }))] }));
71
71
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/core",
3
- "version": "1.2.27",
3
+ "version": "1.2.28",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -137,7 +137,7 @@
137
137
  "@primer/behaviors": "^1.8.4",
138
138
  "@primer/brand-primitives": "^0.51.0",
139
139
  "@primer/css": "^21.5.1",
140
- "@primer/octicons-react": "^19.35.0",
140
+ "@primer/octicons-react": "^19.42.0",
141
141
  "@primer/primitives": "^10.7.0",
142
142
  "@primer/react": "^37.31.0",
143
143
  "@primer/react-brand": "^0.58.0",