grain-tools 0.10.13 → 0.10.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp-app.html CHANGED
@@ -12717,6 +12717,7 @@ function detectInitialTheme() {
12717
12717
  }
12718
12718
  const useAppStore = create$3((set2, get2) => ({
12719
12719
  theme: detectInitialTheme(),
12720
+ panelTheme: "inherit",
12720
12721
  activeView: "query",
12721
12722
  copyIncludesHeaders: true,
12722
12723
  rowDensity: "normal",
@@ -12811,41 +12812,23 @@ const useAppStore = create$3((set2, get2) => ({
12811
12812
  if (c.fontSize !== void 0) {
12812
12813
  newState.fontSize = c.fontSize !== null && c.fontSize !== void 0 && c.fontSize > 0 ? c.fontSize : null;
12813
12814
  }
12814
- if (c.maxRowsToDisplay !== void 0) {
12815
- newState.maxRowsToDisplay = c.maxRowsToDisplay;
12816
- }
12817
- if (c.telemetryEnabled !== void 0) {
12818
- newState.telemetryEnabled = c.telemetryEnabled;
12819
- }
12820
- if (c.chartsEnabled !== void 0) {
12821
- newState.chartsEnabled = c.chartsEnabled;
12822
- }
12823
- if (c.chartLayout !== void 0) {
12824
- newState.chartLayout = c.chartLayout;
12825
- }
12826
- if (c.filterResultsByActiveFile !== void 0) {
12827
- newState.filterResultsByActiveFile = c.filterResultsByActiveFile;
12828
- }
12829
- if (c.mcpEnabled !== void 0) {
12830
- newState.mcpEnabled = c.mcpEnabled;
12831
- }
12832
- if (c.mcpEntitled !== void 0) {
12833
- newState.mcpEntitled = c.mcpEntitled;
12834
- }
12835
- if (c.mcpSafeMode !== void 0) {
12836
- newState.mcpSafeMode = c.mcpSafeMode;
12837
- }
12838
- if (c.activeConnectorType !== void 0) {
12839
- newState.activeConnectorType = c.activeConnectorType;
12840
- }
12841
- if (c.activeConnectionId !== void 0) {
12842
- newState.activeConnectionId = c.activeConnectionId;
12843
- }
12844
- if (c.activeConnectionName !== void 0) {
12845
- newState.activeConnectionName = c.activeConnectionName;
12846
- }
12847
- if (c.confirmWriteQueries !== void 0) {
12848
- newState.confirmWriteQueries = c.confirmWriteQueries;
12815
+ const passthrough = [
12816
+ "maxRowsToDisplay",
12817
+ "telemetryEnabled",
12818
+ "chartsEnabled",
12819
+ "chartLayout",
12820
+ "panelTheme",
12821
+ "filterResultsByActiveFile",
12822
+ "mcpEnabled",
12823
+ "mcpEntitled",
12824
+ "mcpSafeMode",
12825
+ "activeConnectorType",
12826
+ "activeConnectionId",
12827
+ "activeConnectionName",
12828
+ "confirmWriteQueries"
12829
+ ];
12830
+ for (const key of passthrough) {
12831
+ if (c[key] !== void 0) Object.assign(newState, { [key]: c[key] });
12849
12832
  }
12850
12833
  if (c.mcpStatus !== void 0) {
12851
12834
  newState.mcpPort = ((_a3 = c.mcpStatus) == null ? void 0 : _a3.port) ?? null;
@@ -12874,7 +12857,8 @@ const useAppStore = create$3((set2, get2) => ({
12874
12857
  };
12875
12858
  set2((state) => ({
12876
12859
  tabs: [...state.tabs, newTab],
12877
- activeTabId: activate ? id : state.activeTabId
12860
+ activeTabId: activate ? id : state.activeTabId,
12861
+ guideHub: activate ? null : state.guideHub
12878
12862
  }));
12879
12863
  return id;
12880
12864
  },
@@ -12890,7 +12874,7 @@ const useAppStore = create$3((set2, get2) => ({
12890
12874
  activeTabId: newActiveId
12891
12875
  };
12892
12876
  }),
12893
- setActiveTab: (id) => set2({ activeTabId: id }),
12877
+ setActiveTab: (id) => set2({ activeTabId: id, guideHub: null }),
12894
12878
  updateTab: (id, updates) => set2((state) => ({
12895
12879
  tabs: state.tabs.map((tab) => {
12896
12880
  if (tab.id !== id) {
@@ -12900,6 +12884,10 @@ const useAppStore = create$3((set2, get2) => ({
12900
12884
  if (updates.isLoading === true && !tab.isLoading) {
12901
12885
  next.loadingStartedAt = Date.now();
12902
12886
  next.cancelled = false;
12887
+ next.notPersisted = false;
12888
+ }
12889
+ if (updates.result) {
12890
+ next.notPersisted = false;
12903
12891
  }
12904
12892
  if (updates.result !== void 0 && updates.chartSpec === void 0) {
12905
12893
  const signature = (r) => r ? r.columns.map((c) => `${c.name}:${c.type}`).join(" ") : "";
@@ -147468,6 +147456,109 @@ function getConnectorGroup(id) {
147468
147456
  function CloseIcon({ size = 10 }) {
147469
147457
  return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: size, height: size, viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 8.707l3.646 3.647.708-.707L8.707 8l3.647-3.646-.707-.708L8 7.293 4.354 3.646l-.708.708L7.293 8l-3.647 3.646.708.707L8 8.707z" }) });
147470
147458
  }
147459
+ const PATHS = {
147460
+ play: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 3.5v9l7-4.5-7-4.5z" }),
147461
+ stop: /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1" }),
147462
+ copy: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147463
+ /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "5.5", y: "5.5", width: "8", height: "8", rx: "1.5" }),
147464
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M10.5 3.5v-.5a1 1 0 0 0-1-1H3.5a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h.5" })
147465
+ ] }),
147466
+ download: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 2.5v8M4.5 7L8 10.5 11.5 7M3 13.5h10" }),
147467
+ filter: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2.5 3.5h11L9.25 8.5v4l-2.5 1.25V8.5L2.5 3.5z" }),
147468
+ close: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 4l8 8M12 4l-8 8" }),
147469
+ settings: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147470
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "8", cy: "8", r: "2" }),
147471
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 1.75v1.5M8 12.75v1.5M14.25 8h-1.5M3.25 8h-1.5M12.42 3.58l-1.06 1.06M4.64 11.36l-1.06 1.06M12.42 12.42l-1.06-1.06M4.64 4.64L3.58 3.58" })
147472
+ ] }),
147473
+ refresh: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M13.5 8a5.5 5.5 0 1 1-1.61-3.89M13.5 2.5v3h-3" }),
147474
+ undo: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5.5 3L2.5 6l3 3M2.5 6h7a4 4 0 0 1 0 8H7" }),
147475
+ "arrow-left": /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M13 8H3M7 4L3 8l4 4" }),
147476
+ "chevron-down": /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 6l4 4 4-4" }),
147477
+ alert: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147478
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "8", cy: "8", r: "6" }),
147479
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 4.75v3.75M8 10.75v.5" })
147480
+ ] }),
147481
+ info: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147482
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "8", cy: "8", r: "6" }),
147483
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 7.25v3.75M8 4.75v.5" })
147484
+ ] }),
147485
+ warning: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 2.25L14.25 13H1.75L8 2.25zM8 6.5v3M8 11.25v.25" }),
147486
+ check: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M3 8.5l3 3 7-7" }),
147487
+ plus: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 3v10M3 8h10" }),
147488
+ file: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147489
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 1.75H4.25a1 1 0 0 0-1 1v10.5a1 1 0 0 0 1 1h7.5a1 1 0 0 0 1-1V5.5L9 1.75z" }),
147490
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 1.75V5.5h3.75" })
147491
+ ] }),
147492
+ grid: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147493
+ /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "2.5", y: "2.5", width: "11", height: "11", rx: "1.5" }),
147494
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2.5 6.5h11M2.5 10h11M6.5 6.5v7" })
147495
+ ] }),
147496
+ chart: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2.5 13.5h11M4.5 11V8M8 11V4M11.5 11V6.5" }),
147497
+ more: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
147498
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "3.5", cy: "8", r: "0.75" }),
147499
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "8", cy: "8", r: "0.75" }),
147500
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12.5", cy: "8", r: "0.75" })
147501
+ ] })
147502
+ };
147503
+ function Icon({ name, size = 14, className }) {
147504
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
147505
+ "svg",
147506
+ {
147507
+ className: className ? `sp-icon ${className}` : "sp-icon",
147508
+ width: size,
147509
+ height: size,
147510
+ viewBox: "0 0 16 16",
147511
+ fill: "none",
147512
+ stroke: "currentColor",
147513
+ strokeWidth: 1.4,
147514
+ strokeLinecap: "round",
147515
+ strokeLinejoin: "round",
147516
+ "aria-hidden": "true",
147517
+ focusable: "false",
147518
+ children: PATHS[name]
147519
+ }
147520
+ );
147521
+ }
147522
+ const VARIANT_CLASS = {
147523
+ primary: "sp-btn sp-btn-primary",
147524
+ secondary: "sp-btn",
147525
+ ghost: "sp-btn sp-btn-ghost",
147526
+ danger: "sp-btn sp-btn-danger"
147527
+ };
147528
+ const Button = reactExports.forwardRef(function Button2({ variant = "secondary", icon, children, className, type = "button", ...rest }, ref) {
147529
+ const classes = className ? `${VARIANT_CLASS[variant]} ${className}` : VARIANT_CLASS[variant];
147530
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { ref, type, className: classes, ...rest, children: [
147531
+ icon && /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: icon, size: 14 }),
147532
+ children
147533
+ ] });
147534
+ });
147535
+ reactExports.forwardRef(function IconButton2({ icon, label, active, className, type = "button", title, ...rest }, ref) {
147536
+ const classes = ["sp-icon-btn", active ? "active" : "", className ?? ""].filter(Boolean).join(" ");
147537
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
147538
+ "button",
147539
+ {
147540
+ ref,
147541
+ type,
147542
+ className: classes,
147543
+ "aria-label": label,
147544
+ title: title ?? label,
147545
+ ...rest,
147546
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: icon, size: 14 })
147547
+ }
147548
+ );
147549
+ });
147550
+ function PageHeader({ title, backLabel, onBack, meta, actions: actions2 }) {
147551
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("header", { className: "sp-page-header", children: [
147552
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "sp-page-back", onClick: onBack, children: [
147553
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { name: "arrow-left", size: 14 }),
147554
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: backLabel })
147555
+ ] }),
147556
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-page-header-sep", "aria-hidden": "true", children: "/" }),
147557
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "sp-page-title", children: title }),
147558
+ meta && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-page-meta", children: meta }),
147559
+ actions2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-page-actions", children: actions2 })
147560
+ ] });
147561
+ }
147471
147562
  const OPTIONAL_DRIVERS = [
147472
147563
  {
147473
147564
  connectorType: "snowflake",
@@ -147667,7 +147758,7 @@ function schemaForConnectionMode(schema, connectorId, mode) {
147667
147758
  }
147668
147759
  };
147669
147760
  }
147670
- const ConnectionsManager = ({ initialAdd = false }) => {
147761
+ const ConnectionsManager = ({ initialAdd = false, onSubpageChange }) => {
147671
147762
  const { callServerTool, isReady, mode, sendMessage, onMessage } = useHostContext();
147672
147763
  const supportsActiveConnection = mode === "vscode";
147673
147764
  const trackUi = useTrackUi();
@@ -147695,6 +147786,7 @@ const ConnectionsManager = ({ initialAdd = false }) => {
147695
147786
  const [isPopoverOpen, setIsPopoverOpen] = reactExports.useState(false);
147696
147787
  const switcherWrapRef = reactExports.useRef(null);
147697
147788
  const isFormVisible = isFormOpen || !!selectedConnectionId;
147789
+ reactExports.useEffect(() => onSubpageChange == null ? void 0 : onSubpageChange(isFormVisible), [isFormVisible, onSubpageChange]);
147698
147790
  reactExports.useEffect(() => {
147699
147791
  if (isFormVisible) {
147700
147792
  trackUi("ui_state_shown", { state: "connection_form" });
@@ -147736,7 +147828,6 @@ const ConnectionsManager = ({ initialAdd = false }) => {
147736
147828
  }
147737
147829
  setConnectionsUnreachable(false);
147738
147830
  } catch (e2) {
147739
- console.error("Failed to fetch data:", e2);
147740
147831
  setConnectionsUnreachable(true);
147741
147832
  } finally {
147742
147833
  setIsLoading(false);
@@ -147746,7 +147837,16 @@ const ConnectionsManager = ({ initialAdd = false }) => {
147746
147837
  fetchData();
147747
147838
  }, [fetchData]);
147748
147839
  reactExports.useEffect(() => {
147749
- if (!onMessage) return;
147840
+ if (!connectionsUnreachable) {
147841
+ return;
147842
+ }
147843
+ const timer = setInterval(() => void fetchData(), 5e3);
147844
+ return () => clearInterval(timer);
147845
+ }, [connectionsUnreachable, fetchData]);
147846
+ reactExports.useEffect(() => {
147847
+ if (!onMessage) {
147848
+ return;
147849
+ }
147750
147850
  return onMessage((msg) => {
147751
147851
  if ((msg == null ? void 0 : msg.type) === "connectionsImported" || (msg == null ? void 0 : msg.type) === "updateConfig") {
147752
147852
  void fetchData();
@@ -147919,7 +148019,9 @@ const ConnectionsManager = ({ initialAdd = false }) => {
147919
148019
  }
147920
148020
  };
147921
148021
  const handleDeleteConnection = (id, name) => {
147922
- if (!isReady) return;
148022
+ if (!isReady) {
148023
+ return;
148024
+ }
147923
148025
  setPendingConfirm({
147924
148026
  title: "Delete connection",
147925
148027
  message: `Delete connection '${name}'? This can't be undone.`,
@@ -148030,6 +148132,23 @@ const ConnectionsManager = ({ initialAdd = false }) => {
148030
148132
  setSelectedType("");
148031
148133
  setToast(null);
148032
148134
  }, []);
148135
+ reactExports.useEffect(() => {
148136
+ if (!isFormVisible) {
148137
+ return;
148138
+ }
148139
+ const onKeyDown = (event) => {
148140
+ if (event.key !== "Escape" || pendingConfirm) {
148141
+ return;
148142
+ }
148143
+ const target = event.target;
148144
+ if (target instanceof Element && target.closest("input, select, textarea")) {
148145
+ return;
148146
+ }
148147
+ closeForm();
148148
+ };
148149
+ document.addEventListener("keydown", onKeyDown);
148150
+ return () => document.removeEventListener("keydown", onKeyDown);
148151
+ }, [isFormVisible, pendingConfirm, closeForm]);
148033
148152
  reactExports.useEffect(() => {
148034
148153
  function handleClickOutside(event) {
148035
148154
  if (isPopoverOpen && switcherWrapRef.current && !switcherWrapRef.current.contains(event.target)) {
@@ -148048,7 +148167,9 @@ const ConnectionsManager = ({ initialAdd = false }) => {
148048
148167
  );
148049
148168
  const emptyFormInitialData = reactExports.useMemo(() => ({}), []);
148050
148169
  const renderToast = () => {
148051
- if (!toast) return null;
148170
+ if (!toast) {
148171
+ return null;
148172
+ }
148052
148173
  const advice = toast.advice;
148053
148174
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
148054
148175
  "div",
@@ -148152,71 +148273,62 @@ const ConnectionsManager = ({ initialAdd = false }) => {
148152
148273
  }
148153
148274
  return null;
148154
148275
  };
148155
- const renderConnectionForm = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-detail", children: [
148156
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-header", children: [
148157
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
148158
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-detail-kicker", children: "Add connection" }),
148159
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "sp-conn-detail-title", children: "New connection" })
148160
- ] }),
148161
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "sp-btn", onClick: closeForm, "aria-label": "Cancel", children: "Cancel" })
148162
- ] }),
148163
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-body", children: [
148164
- renderToast(),
148165
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-section", children: "Database Type" }),
148166
- ["local", "server"].map((group) => {
148167
- const groupConnectors = connectors.filter((c) => getConnectorGroup(c.id) === group);
148168
- if (groupConnectors.length === 0) return null;
148169
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(React$2.Fragment, { children: [
148170
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-type-group-label", id: `sp-conn-type-group-${group}`, children: CONNECTOR_GROUP_LABELS[group] }),
148171
- /* @__PURE__ */ jsxRuntimeExports.jsx(
148172
- "div",
148173
- {
148174
- className: "sp-conn-type-grid",
148175
- role: "group",
148176
- "aria-labelledby": `sp-conn-type-group-${group}`,
148177
- children: groupConnectors.map((c) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
148178
- "button",
148179
- {
148180
- type: "button",
148181
- className: `sp-conn-type-card${selectedType === c.id ? " selected" : ""}`,
148182
- onClick: () => {
148183
- setSelectedType(c.id);
148184
- trackUi("first_value_step", {
148185
- step: "connector_selected",
148186
- outcome: "success"
148187
- });
148188
- },
148189
- "aria-pressed": selectedType === c.id,
148190
- children: [
148191
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-type-card-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ConnectorGlyph, { type: c.id }) }),
148192
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-type-card-name", children: c.displayName || c.id })
148193
- ]
148276
+ const renderConnectionForm = () => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-detail", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-body", children: [
148277
+ renderToast(),
148278
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-section", children: "Database Type" }),
148279
+ ["local", "server"].map((group) => {
148280
+ const groupConnectors = connectors.filter((c) => getConnectorGroup(c.id) === group);
148281
+ if (groupConnectors.length === 0) {
148282
+ return null;
148283
+ }
148284
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(React$2.Fragment, { children: [
148285
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-type-group-label", id: `sp-conn-type-group-${group}`, children: CONNECTOR_GROUP_LABELS[group] }),
148286
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
148287
+ "div",
148288
+ {
148289
+ className: "sp-conn-type-grid",
148290
+ role: "group",
148291
+ "aria-labelledby": `sp-conn-type-group-${group}`,
148292
+ children: groupConnectors.map((c) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
148293
+ "button",
148294
+ {
148295
+ type: "button",
148296
+ className: `sp-conn-type-card${selectedType === c.id ? " selected" : ""}`,
148297
+ onClick: () => {
148298
+ setSelectedType(c.id);
148299
+ trackUi("first_value_step", {
148300
+ step: "connector_selected",
148301
+ outcome: "success"
148302
+ });
148194
148303
  },
148195
- c.id
148196
- ))
148197
- }
148198
- )
148199
- ] }, group);
148200
- }),
148201
- activeSchemaDef && activeFormSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
148202
- DynamicForm,
148203
- {
148204
- schema: { ...activeFormSchema, type: "object" },
148205
- initialData: emptyFormInitialData,
148206
- onSubmit: (formData) => handleSaveConnection(formData),
148207
- onTest: (formData) => handleTestFormData(formData),
148208
- onCancel: closeForm,
148209
- isSubmitting: isLoading
148210
- }
148211
- ) : selectedType ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-hint", style: { color: "var(--sp-error)" }, children: "This connector does not define a configuration schema." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-empty sp-conn-empty-compact", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-empty-text", children: "Choose a database type to begin." }) })
148212
- ] })
148213
- ] });
148304
+ "aria-pressed": selectedType === c.id,
148305
+ children: [
148306
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-type-card-icon", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ConnectorGlyph, { type: c.id }) }),
148307
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-type-card-name", children: c.displayName || c.id })
148308
+ ]
148309
+ },
148310
+ c.id
148311
+ ))
148312
+ }
148313
+ )
148314
+ ] }, group);
148315
+ }),
148316
+ activeSchemaDef && activeFormSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
148317
+ DynamicForm,
148318
+ {
148319
+ schema: { ...activeFormSchema, type: "object" },
148320
+ initialData: emptyFormInitialData,
148321
+ onSubmit: (formData) => handleSaveConnection(formData),
148322
+ onTest: (formData) => handleTestFormData(formData),
148323
+ onCancel: closeForm,
148324
+ isSubmitting: isLoading
148325
+ }
148326
+ ) : selectedType ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-hint sp-conn-schema-error", children: "This connector does not define a configuration schema." }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-empty sp-conn-empty-compact", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-empty-text", children: "Choose a database type to begin." }) })
148327
+ ] }) });
148214
148328
  const renderConnectionDetails = () => {
148215
148329
  if (!selectedConnection) {
148216
148330
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-detail", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-empty sp-conn-empty-compact", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-empty-text", children: "Select a connection to view details, test it, or use it for queries." }) }) });
148217
148331
  }
148218
- const status = statuses[selectedConnection.id] || "unknown";
148219
- const isActive = supportsActiveConnection && activeConnectionId === selectedConnection.id;
148220
148332
  const schemaDef = connectors.find((c) => c.id === selectedConnection.type);
148221
148333
  const canManagePassword = supportsActiveConnection && schemaHasPasswordField(schemaDef == null ? void 0 : schemaDef.schema);
148222
148334
  const editSchema = (schemaDef == null ? void 0 : schemaDef.schema) && canManagePassword ? schemaWithoutPasswordField(schemaDef.schema) : schemaDef == null ? void 0 : schemaDef.schema;
@@ -148260,78 +148372,22 @@ const ConnectionsManager = ({ initialAdd = false }) => {
148260
148372
  ] })
148261
148373
  ] });
148262
148374
  };
148263
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-detail", children: [
148264
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
148265
- "div",
148375
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-detail", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-body", children: [
148376
+ renderToast(),
148377
+ modeAwareEditSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
148378
+ DynamicForm,
148266
148379
  {
148267
- className: "sp-conn-detail-header",
148268
- style: {
148269
- display: "flex",
148270
- justifyContent: "space-between",
148271
- alignItems: "center",
148272
- flexWrap: "wrap",
148273
- gap: "16px",
148274
- paddingBottom: "16px",
148275
- borderBottom: "1px solid var(--sp-border)",
148276
- marginBottom: "16px"
148277
- },
148278
- children: [
148279
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px", flexWrap: "wrap" }, children: [
148280
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontWeight: 600, fontSize: "14px", color: "var(--sp-fg)" }, children: selectedConnection ? "Edit Connection" : "New Connection" }),
148281
- selectedConnection && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
148282
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-type-badge", children: selectedConnection.type }),
148283
- isActive && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-active-badge", children: "Active" }),
148284
- selectedConnection.builtIn && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-built-in-label", children: "Built-in" })
148285
- ] })
148286
- ] }),
148287
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
148288
- "div",
148289
- {
148290
- className: "sp-conn-detail-actions",
148291
- style: { display: "flex", gap: "8px", flexWrap: "wrap" },
148292
- children: [
148293
- supportsActiveConnection && /* @__PURE__ */ jsxRuntimeExports.jsx(
148294
- "button",
148295
- {
148296
- className: `sp-btn${isActive ? " sp-btn-primary" : ""}`,
148297
- onClick: () => handleSetActiveConnection(selectedConnection),
148298
- disabled: isActive || status === "testing",
148299
- "aria-label": `Set ${selectedConnection.name} as the active connection for queries`,
148300
- children: isActive ? "Active" : "Set active"
148301
- }
148302
- ),
148303
- !selectedConnection.builtIn && /* @__PURE__ */ jsxRuntimeExports.jsx(
148304
- "button",
148305
- {
148306
- className: "sp-btn sp-btn-ghost-danger",
148307
- onClick: () => handleDeleteConnection(selectedConnection.id, selectedConnection.name),
148308
- "aria-label": `Delete connection ${selectedConnection.name}`,
148309
- children: "Delete"
148310
- }
148311
- )
148312
- ]
148313
- }
148314
- )
148315
- ]
148316
- }
148317
- ),
148318
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-body", children: [
148319
- renderToast(),
148320
- modeAwareEditSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
148321
- DynamicForm,
148322
- {
148323
- schema: { ...modeAwareEditSchema, type: "object" },
148324
- initialData: selectedFormInitialData,
148325
- onSubmit: (formData) => handleSaveConnection(formData, selectedConnection),
148326
- onTest: (formData) => handleTestFormData(formData, selectedConnection),
148327
- isSubmitting: isLoading,
148328
- renderAfterField: renderPasswordManagementField,
148329
- actionStatus: renderConnectionStatusMessage(selectedConnection),
148330
- submitFeedback: lastSavedConnectionId === selectedConnection.id ? "Saved successfully" : void 0
148331
- }
148332
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-hint", style: { color: "var(--sp-error)" }, children: "This connector does not define a configuration schema." })
148333
- ] })
148334
- ] });
148380
+ schema: { ...modeAwareEditSchema, type: "object" },
148381
+ initialData: selectedFormInitialData,
148382
+ onSubmit: (formData) => handleSaveConnection(formData, selectedConnection),
148383
+ onTest: (formData) => handleTestFormData(formData, selectedConnection),
148384
+ isSubmitting: isLoading,
148385
+ renderAfterField: renderPasswordManagementField,
148386
+ actionStatus: renderConnectionStatusMessage(selectedConnection),
148387
+ submitFeedback: lastSavedConnectionId === selectedConnection.id ? "Saved successfully" : void 0
148388
+ }
148389
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-hint sp-conn-schema-error", children: "This connector does not define a configuration schema." })
148390
+ ] }) });
148335
148391
  };
148336
148392
  const renderGrid = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-grid-view", children: [
148337
148393
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-head", style: { marginBottom: 16 }, children: [
@@ -148397,7 +148453,11 @@ const ConnectionsManager = ({ initialAdd = false }) => {
148397
148453
  gap: "12px"
148398
148454
  },
148399
148455
  children: connections.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-empty", style: { gridColumn: "1 / -1" }, children: [
148400
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: connectionsUnreachable ? "Can't reach the Grain engine right now. Your connections are saved on disk and will reappear once it reconnects." : "No connections configured." }),
148456
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: connectionsUnreachable ? "Can't reach Grain. Start Grain and try again." : "No connections configured." }),
148457
+ connectionsUnreachable && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { marginTop: 12, display: "flex", gap: 8 }, children: [
148458
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "sp-btn", onClick: fetchData, children: "Retry" }),
148459
+ mode === "vscode" && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "sp-btn", onClick: () => sendMessage == null ? void 0 : sendMessage("startGrain"), children: "Start Grain" })
148460
+ ] }),
148401
148461
  mode === "vscode" && !connectionsUnreachable && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
148402
148462
  "button",
148403
148463
  {
@@ -148487,30 +148547,45 @@ const ConnectionsManager = ({ initialAdd = false }) => {
148487
148547
  }
148488
148548
  )
148489
148549
  ] });
148490
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-page", children: [
148491
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn", children: !isFormOpen && !selectedConnectionId ? renderGrid() : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
148550
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: isFormVisible ? "sp-conn-subpage" : "sp-conn-page", children: [
148551
+ isFormVisible ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
148492
148552
  /* @__PURE__ */ jsxRuntimeExports.jsx(
148493
- "button",
148553
+ PageHeader,
148494
148554
  {
148495
- className: "sp-btn",
148496
- onClick: closeForm,
148497
- style: { marginBottom: 12, alignSelf: "flex-start" },
148498
- children: "← Back to connections"
148555
+ backLabel: "Connections",
148556
+ onBack: closeForm,
148557
+ title: isFormOpen ? "New connection" : (selectedConnection == null ? void 0 : selectedConnection.name) ?? "Connection",
148558
+ meta: selectedConnection && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
148559
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-type-badge", children: selectedConnection.type }),
148560
+ supportsActiveConnection && activeConnectionId === selectedConnection.id && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-active-badge", children: "Active" }),
148561
+ selectedConnection.builtIn && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-built-in-label", children: "Built-in" })
148562
+ ] }),
148563
+ actions: isFormOpen ? /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", onClick: closeForm, "aria-label": "Cancel", children: "Cancel" }) : selectedConnection && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
148564
+ supportsActiveConnection && /* @__PURE__ */ jsxRuntimeExports.jsx(
148565
+ Button,
148566
+ {
148567
+ variant: "ghost",
148568
+ onClick: () => handleSetActiveConnection(selectedConnection),
148569
+ disabled: activeConnectionId === selectedConnection.id || statuses[selectedConnection.id] === "testing",
148570
+ "aria-label": `Set ${selectedConnection.name} as the active connection for queries`,
148571
+ children: activeConnectionId === selectedConnection.id ? "Active" : "Set active"
148572
+ }
148573
+ ),
148574
+ !selectedConnection.builtIn && /* @__PURE__ */ jsxRuntimeExports.jsx(
148575
+ Button,
148576
+ {
148577
+ variant: "secondary",
148578
+ className: "sp-btn-ghost-danger",
148579
+ onClick: () => handleDeleteConnection(selectedConnection.id, selectedConnection.name),
148580
+ "aria-label": `Delete connection ${selectedConnection.name}`,
148581
+ children: "Delete"
148582
+ }
148583
+ )
148584
+ ] })
148499
148585
  }
148500
148586
  ),
148501
- /* @__PURE__ */ jsxRuntimeExports.jsx(
148502
- "section",
148503
- {
148504
- "aria-label": "Connection details",
148505
- style: {
148506
- background: "var(--sp-bg)",
148507
- border: "1px solid var(--sp-border)",
148508
- borderRadius: 6
148509
- },
148510
- children: isFormOpen ? renderConnectionForm() : renderConnectionDetails()
148511
- }
148512
- )
148513
- ] }) }),
148587
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-subpage-body", children: /* @__PURE__ */ jsxRuntimeExports.jsx("section", { "aria-label": "Connection details", className: "sp-conn-subpage-column", children: isFormOpen ? renderConnectionForm() : renderConnectionDetails() }) })
148588
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn", children: renderGrid() }),
148514
148589
  /* @__PURE__ */ jsxRuntimeExports.jsx(
148515
148590
  ConfirmDialog,
148516
148591
  {
@@ -171814,7 +171889,7 @@ body.light-theme .ag-theme-quartz {
171814
171889
  --sp-warning: var(--vscode-charts-yellow, #ca8a04);
171815
171890
 
171816
171891
  --sp-font: var(
171817
- --vscode-editor-font-family,
171892
+ --vscode-font-family,
171818
171893
  -apple-system,
171819
171894
  BlinkMacSystemFont,
171820
171895
  'Segoe UI',
@@ -172099,75 +172174,55 @@ body {
172099
172174
  gap: 6px;
172100
172175
  }
172101
172176
 
172102
- .sp-active-file-indicator {
172177
+ .sp-chip {
172103
172178
  display: inline-flex;
172104
172179
  align-items: center;
172105
- gap: 4px;
172180
+ gap: 5px;
172106
172181
  max-width: 220px;
172107
- margin-right: 8px;
172108
- padding: 2px 6px;
172109
- border: 1px solid transparent;
172110
- border-radius: var(--sp-radius);
172111
- background: var(--sp-badge-bg);
172112
- color: var(--sp-badge-fg);
172182
+ height: 22px;
172183
+ padding: 0 8px;
172184
+ border: 1px dashed var(--sp-border);
172185
+ border-radius: 999px;
172186
+ background: transparent;
172187
+ color: var(--sp-muted-fg);
172113
172188
  font: inherit;
172114
172189
  font-size: 11px;
172115
172190
  cursor: pointer;
172116
- opacity: 0.9;
172191
+ transition:
172192
+ color 0.1s,
172193
+ background 0.1s,
172194
+ border-color 0.1s;
172117
172195
  }
172118
-
172119
- .sp-active-file-indicator:hover {
172120
- opacity: 1;
172121
- border-color: var(--sp-focus-border);
172196
+ .sp-chip:hover {
172197
+ color: var(--sp-fg);
172198
+ border-color: var(--sp-muted-fg);
172122
172199
  }
172123
-
172124
- .sp-active-file-icon {
172125
- flex-shrink: 0;
172200
+ .sp-chip.on {
172201
+ border-style: solid;
172202
+ border-color: color-mix(in srgb, var(--sp-focus-border) 55%, transparent);
172203
+ background: color-mix(in srgb, var(--sp-focus-border) 14%, transparent);
172204
+ color: var(--sp-fg);
172126
172205
  }
172127
-
172128
- .sp-active-file-name {
172206
+ .sp-chip.on .sp-icon {
172207
+ color: var(--sp-focus-border);
172208
+ }
172209
+ .sp-chip:focus-visible {
172210
+ outline: 1px solid var(--sp-focus-border);
172211
+ outline-offset: 1px;
172212
+ }
172213
+ .sp-chip-label {
172129
172214
  min-width: 0;
172130
172215
  overflow: hidden;
172131
172216
  text-overflow: ellipsis;
172132
172217
  white-space: nowrap;
172133
172218
  }
172134
172219
 
172135
- .sp-active-file-state {
172136
- color: var(--sp-muted-fg);
172137
- flex-shrink: 0;
172138
- }
172139
-
172140
- /* Sibling of the file chip: states whether the tab list is narrowed to that file,
172141
- and switches it. Quiet by default so it reads as status until hovered. */
172142
- .sp-active-file-toggle {
172143
- flex-shrink: 0;
172144
- margin-right: 8px;
172145
- padding: 2px 6px;
172146
- border: 1px solid transparent;
172147
- border-radius: var(--sp-radius);
172148
- background: var(--sp-badge-bg);
172149
- color: var(--sp-muted-fg);
172150
- font: inherit;
172151
- font-size: 11px;
172152
- cursor: pointer;
172153
- opacity: 0.9;
172154
- }
172155
-
172156
- .sp-active-file-toggle.on {
172157
- color: var(--sp-badge-fg);
172158
- }
172159
-
172160
- .sp-active-file-toggle:hover {
172161
- opacity: 1;
172162
- border-color: var(--sp-focus-border);
172163
- }
172164
-
172165
172220
  .sp-tab {
172166
172221
  display: flex;
172167
172222
  align-items: center;
172168
- gap: 4px;
172169
- padding: 0 10px;
172170
- height: 35px;
172223
+ gap: 6px;
172224
+ padding: 0 10px 0 12px;
172225
+ height: 30px;
172171
172226
  cursor: pointer;
172172
172227
  white-space: nowrap;
172173
172228
  border-bottom: 2px solid transparent;
@@ -172338,8 +172393,8 @@ body {
172338
172393
  padding: 0 10px;
172339
172394
  border-bottom: 1px solid var(--sp-border);
172340
172395
  flex-shrink: 0;
172341
- height: 36px;
172342
- background: var(--sp-header-bg);
172396
+ height: 32px;
172397
+ background: var(--sp-bg);
172343
172398
  gap: 8px;
172344
172399
  }
172345
172400
 
@@ -172382,36 +172437,62 @@ body {
172382
172437
  .sp-btn {
172383
172438
  display: inline-flex;
172384
172439
  align-items: center;
172385
- gap: 4px;
172386
- padding: 3px 8px;
172387
- font-size: 11px;
172440
+ justify-content: center;
172441
+ gap: 5px;
172442
+ height: 24px;
172443
+ padding: 0 8px;
172444
+ font-size: 12px;
172445
+ font-weight: 500;
172388
172446
  font-family: var(--sp-font);
172389
172447
  cursor: pointer;
172390
- border: none;
172448
+ border: 1px solid transparent;
172391
172449
  border-radius: var(--sp-radius);
172392
172450
  background: var(--sp-btn-sec-bg);
172393
172451
  color: var(--sp-btn-sec-fg);
172394
172452
  white-space: nowrap;
172395
- transition: background 0.1s;
172396
- line-height: 1.4;
172453
+ transition:
172454
+ background 0.1s,
172455
+ color 0.1s,
172456
+ border-color 0.1s;
172457
+ line-height: 1;
172397
172458
  }
172398
172459
  .sp-btn:hover:not(:disabled) {
172399
172460
  background: var(--sp-btn-sec-hover);
172400
172461
  }
172462
+ .sp-btn:focus-visible {
172463
+ outline: 1px solid var(--sp-focus-border);
172464
+ outline-offset: 1px;
172465
+ }
172401
172466
  .sp-btn:disabled {
172402
172467
  opacity: 0.4;
172403
172468
  cursor: default;
172404
172469
  }
172470
+ .sp-btn .sp-icon {
172471
+ flex-shrink: 0;
172472
+ }
172405
172473
 
172406
172474
  .sp-btn-primary {
172407
172475
  background: var(--sp-btn-bg);
172408
172476
  color: var(--sp-btn-fg);
172409
- font-weight: 500;
172410
172477
  }
172411
172478
  .sp-btn-primary:hover:not(:disabled) {
172412
172479
  background: var(--sp-btn-hover);
172413
172480
  }
172414
172481
 
172482
+ .sp-btn-ghost {
172483
+ background: transparent;
172484
+ color: var(--sp-fg);
172485
+ }
172486
+ .sp-btn-ghost .sp-icon {
172487
+ color: var(--sp-muted-fg);
172488
+ }
172489
+ .sp-btn-ghost:hover:not(:disabled) {
172490
+ background: var(--sp-hover-bg);
172491
+ }
172492
+ .sp-btn-ghost:hover:not(:disabled) .sp-icon {
172493
+ color: var(--sp-fg);
172494
+ }
172495
+
172415
172496
  .sp-btn-danger {
172416
172497
  background: var(--sp-btn-danger-bg);
172417
172498
  color: var(--sp-btn-danger-fg);
@@ -172481,14 +172562,14 @@ body {
172481
172562
  .sp-icon-btn:hover {
172482
172563
  color: var(--sp-fg);
172483
172564
  background: var(--sp-hover-bg);
172484
- border-color: var(--sp-border);
172565
+ }
172566
+ .sp-icon-btn:focus-visible {
172567
+ outline: 1px solid var(--sp-focus-border);
172568
+ outline-offset: -1px;
172485
172569
  }
172486
172570
  .sp-icon-btn.active {
172487
- color: var(--sp-btn-bg);
172571
+ color: var(--sp-fg);
172488
172572
  background: var(--sp-hover-bg);
172489
- border-color: transparent !important;
172490
- outline: none !important;
172491
- box-shadow: none !important;
172492
172573
  }
172493
172574
 
172494
172575
  /* ── Grid container ────────────────────────────────────────── */
@@ -172505,19 +172586,22 @@ body {
172505
172586
  .sp-loading {
172506
172587
  display: flex;
172507
172588
  flex-direction: column;
172508
- align-items: center;
172509
- justify-content: center;
172510
172589
  height: 100%;
172511
- gap: 12px;
172512
172590
  color: var(--sp-muted-fg);
172513
172591
  font-size: 13px;
172514
172592
  }
172593
+ .sp-loading .sp-empty-state {
172594
+ flex: 1;
172595
+ height: auto;
172596
+ }
172515
172597
  .sp-loading p {
172516
172598
  margin: 0;
172517
172599
  }
172518
172600
  /* Live elapsed readout; tabular digits so the count-up doesn't jitter horizontally. */
172519
172601
  .sp-loading-elapsed {
172520
172602
  margin-left: 6px;
172603
+ color: var(--sp-muted-fg);
172604
+ font-weight: 400;
172521
172605
  font-variant-numeric: tabular-nums;
172522
172606
  }
172523
172607
 
@@ -172835,9 +172919,40 @@ body {
172835
172919
  --ag-row-height: 28px;
172836
172920
  --ag-header-height: 32px;
172837
172921
  --ag-icon-size: 14px;
172838
- --ag-header-column-separator-display: block;
172839
- --ag-header-column-separator-height: 100%;
172840
- --ag-header-column-separator-width: 1px;
172922
+ --ag-header-column-separator-display: none;
172923
+ --ag-header-column-resize-handle-display: block;
172924
+ --ag-header-column-resize-handle-width: 1px;
172925
+ --ag-header-column-resize-handle-height: 40%;
172926
+ --ag-header-column-resize-handle-color: var(--sp-border);
172927
+ --ag-wrapper-border-radius: 0;
172928
+ --ag-borders: none;
172929
+ --ag-row-border-color: color-mix(in srgb, var(--sp-border) 60%, transparent);
172930
+ }
172931
+
172932
+ .sp-ag-grid .ag-header-cell-resize:hover::after {
172933
+ height: 100%;
172934
+ top: 0;
172935
+ background-color: var(--sp-focus-border);
172936
+ }
172937
+
172938
+ .sp-ag-grid .ag-header-cell-text {
172939
+ font-weight: 600;
172940
+ }
172941
+
172942
+ .sp-ag-grid .ag-header-cell .ag-header-cell-filter-button,
172943
+ .sp-ag-grid .ag-header-cell .ag-sort-indicator-icon {
172944
+ color: var(--sp-muted-fg);
172945
+ }
172946
+
172947
+ .sp-ag-grid .ag-header-cell .ag-header-cell-filter-button {
172948
+ opacity: 0;
172949
+ transition: opacity 0.1s;
172950
+ }
172951
+
172952
+ .sp-ag-grid .ag-header-cell:hover .ag-header-cell-filter-button,
172953
+ .sp-ag-grid .ag-header-cell:focus-within .ag-header-cell-filter-button,
172954
+ .sp-ag-grid .ag-header-cell-filtered .ag-header-cell-filter-button {
172955
+ opacity: 1;
172841
172956
  }
172842
172957
 
172843
172958
  .sp-ag-grid .ag-header-cell-filtered {
@@ -174983,6 +175098,322 @@ body.vscode-high-contrast .ag-theme-quartz {
174983
175098
  .sp-conn-status-testing {
174984
175099
  opacity: 0.7;
174985
175100
  }
175101
+ }
175102
+
175103
+ /* ── Primitives: notice ────────────────────────────────────── */
175104
+ .sp-notice {
175105
+ display: flex;
175106
+ align-items: flex-start;
175107
+ gap: 8px;
175108
+ padding: 6px 8px 6px 12px;
175109
+ border-bottom: 1px solid var(--sp-border);
175110
+ background: var(--sp-header-bg);
175111
+ color: var(--sp-fg);
175112
+ font-size: 12px;
175113
+ line-height: 1.45;
175114
+ flex-shrink: 0;
175115
+ }
175116
+ .sp-notice-icon {
175117
+ display: inline-flex;
175118
+ padding-top: 2px;
175119
+ color: var(--sp-muted-fg);
175120
+ flex-shrink: 0;
175121
+ }
175122
+ .sp-notice-error .sp-notice-icon {
175123
+ color: var(--sp-error);
175124
+ }
175125
+ .sp-notice-warning .sp-notice-icon {
175126
+ color: var(--sp-warning);
175127
+ }
175128
+ .sp-notice-info .sp-notice-icon {
175129
+ color: var(--sp-focus-border);
175130
+ }
175131
+ .sp-notice-body {
175132
+ display: flex;
175133
+ flex: 1;
175134
+ flex-direction: column;
175135
+ gap: 2px;
175136
+ min-width: 0;
175137
+ padding-top: 1px;
175138
+ }
175139
+ .sp-notice-title {
175140
+ overflow-wrap: anywhere;
175141
+ }
175142
+ .sp-notice-detail {
175143
+ color: var(--sp-muted-fg);
175144
+ overflow-wrap: anywhere;
175145
+ }
175146
+ .sp-notice-actions {
175147
+ display: flex;
175148
+ align-items: center;
175149
+ gap: 6px;
175150
+ flex-shrink: 0;
175151
+ }
175152
+ .sp-notice-dismiss {
175153
+ width: 22px;
175154
+ height: 22px;
175155
+ flex-shrink: 0;
175156
+ }
175157
+
175158
+ /* ── Primitives: empty state ───────────────────────────────── */
175159
+ .sp-empty-state {
175160
+ display: flex;
175161
+ flex-direction: column;
175162
+ align-items: center;
175163
+ justify-content: center;
175164
+ gap: 6px;
175165
+ height: 100%;
175166
+ padding: 24px;
175167
+ color: var(--sp-muted-fg);
175168
+ font-size: 12px;
175169
+ text-align: center;
175170
+ }
175171
+ .sp-empty-state-icon {
175172
+ display: inline-flex;
175173
+ margin-bottom: 2px;
175174
+ color: var(--sp-muted-fg);
175175
+ }
175176
+ .sp-empty-state-error .sp-empty-state-icon {
175177
+ color: var(--sp-error);
175178
+ }
175179
+ .sp-empty-state-title {
175180
+ color: var(--sp-fg);
175181
+ font-size: 13px;
175182
+ font-weight: 600;
175183
+ }
175184
+ .sp-empty-state-detail {
175185
+ max-width: 60ch;
175186
+ line-height: 1.5;
175187
+ overflow-wrap: anywhere;
175188
+ }
175189
+ .sp-empty-state-detail code,
175190
+ .sp-empty-state-message {
175191
+ display: block;
175192
+ max-height: 40vh;
175193
+ overflow: auto;
175194
+ padding: 8px 10px;
175195
+ border: 1px solid var(--sp-border);
175196
+ border-radius: var(--sp-radius);
175197
+ background: var(--sp-header-bg);
175198
+ color: var(--sp-fg);
175199
+ font-family: var(--sp-font-mono, var(--vscode-editor-font-family, monospace));
175200
+ font-size: calc(var(--sp-font-size) - 1px);
175201
+ text-align: left;
175202
+ white-space: pre-wrap;
175203
+ word-break: break-word;
175204
+ user-select: text;
175205
+ }
175206
+ .sp-empty-state-actions {
175207
+ display: flex;
175208
+ align-items: center;
175209
+ gap: 6px;
175210
+ margin-top: 8px;
175211
+ }
175212
+ .sp-empty-state-meta {
175213
+ font-variant-numeric: tabular-nums;
175214
+ }
175215
+
175216
+ /* ── Primitives: progress ──────────────────────────────────── */
175217
+ @keyframes sp-progress-slide {
175218
+ 0% {
175219
+ transform: translateX(-100%);
175220
+ }
175221
+ 100% {
175222
+ transform: translateX(400%);
175223
+ }
175224
+ }
175225
+ .sp-progress {
175226
+ position: relative;
175227
+ height: 2px;
175228
+ overflow: hidden;
175229
+ flex-shrink: 0;
175230
+ }
175231
+ .sp-progress-bar {
175232
+ position: absolute;
175233
+ inset: 0 auto 0 0;
175234
+ width: 25%;
175235
+ background: var(--sp-focus-border);
175236
+ animation: sp-progress-slide 1.1s cubic-bezier(0.45, 0, 0.55, 1) infinite;
175237
+ }
175238
+ @keyframes sp-busy-pulse {
175239
+ 0%,
175240
+ 100% {
175241
+ opacity: 0.35;
175242
+ transform: scale(0.8);
175243
+ }
175244
+ 50% {
175245
+ opacity: 1;
175246
+ transform: scale(1);
175247
+ }
175248
+ }
175249
+ .sp-busy-dot {
175250
+ display: inline-flex;
175251
+ align-items: center;
175252
+ justify-content: center;
175253
+ width: 8px;
175254
+ height: 8px;
175255
+ flex-shrink: 0;
175256
+ }
175257
+ .sp-busy-dot > span {
175258
+ width: 6px;
175259
+ height: 6px;
175260
+ border-radius: 50%;
175261
+ background: var(--sp-focus-border);
175262
+ animation: sp-busy-pulse 1s ease-in-out infinite;
175263
+ }
175264
+ @media (prefers-reduced-motion: reduce) {
175265
+ .sp-progress-bar {
175266
+ width: 100%;
175267
+ animation: none;
175268
+ opacity: 0.6;
175269
+ }
175270
+ .sp-busy-dot > span {
175271
+ animation: none;
175272
+ }
175273
+ }
175274
+
175275
+ /* ── Primitives: page header ───────────────────────────────── */
175276
+ .sp-page-header {
175277
+ display: flex;
175278
+ align-items: center;
175279
+ gap: 6px;
175280
+ min-height: 35px;
175281
+ padding: 0 10px;
175282
+ border-bottom: 1px solid var(--sp-border);
175283
+ background: var(--sp-header-bg);
175284
+ flex-shrink: 0;
175285
+ }
175286
+ .sp-page-back {
175287
+ display: inline-flex;
175288
+ align-items: center;
175289
+ gap: 4px;
175290
+ height: 24px;
175291
+ padding: 0 6px;
175292
+ border: none;
175293
+ border-radius: var(--sp-radius);
175294
+ background: transparent;
175295
+ color: var(--sp-muted-fg);
175296
+ font: inherit;
175297
+ font-size: 12px;
175298
+ cursor: pointer;
175299
+ }
175300
+ .sp-page-back:hover {
175301
+ color: var(--sp-fg);
175302
+ background: var(--sp-hover-bg);
175303
+ }
175304
+ .sp-page-back:focus-visible {
175305
+ outline: 1px solid var(--sp-focus-border);
175306
+ outline-offset: -1px;
175307
+ }
175308
+ .sp-page-header-sep {
175309
+ color: var(--sp-border);
175310
+ }
175311
+ .sp-page-title {
175312
+ margin: 0;
175313
+ font-size: 13px;
175314
+ font-weight: 600;
175315
+ color: var(--sp-fg);
175316
+ white-space: nowrap;
175317
+ overflow: hidden;
175318
+ text-overflow: ellipsis;
175319
+ }
175320
+ .sp-page-meta {
175321
+ display: flex;
175322
+ align-items: center;
175323
+ gap: 6px;
175324
+ }
175325
+ .sp-page-actions {
175326
+ display: flex;
175327
+ align-items: center;
175328
+ gap: 6px;
175329
+ margin-left: auto;
175330
+ }
175331
+
175332
+ /* ── Result toolbar ────────────────────────────────────────── */
175333
+ .sp-toolbar-sep {
175334
+ width: 1px;
175335
+ height: 14px;
175336
+ margin: 0 4px;
175337
+ background: var(--sp-border);
175338
+ flex-shrink: 0;
175339
+ }
175340
+
175341
+ /* ── Primitives: segmented control ─────────────────────────── */
175342
+ .sp-segmented {
175343
+ display: inline-flex;
175344
+ padding: 2px;
175345
+ gap: 2px;
175346
+ border: 1px solid var(--sp-border);
175347
+ border-radius: calc(var(--sp-radius) + 2px);
175348
+ background: var(--sp-bg);
175349
+ flex-shrink: 0;
175350
+ }
175351
+ .sp-segmented-item {
175352
+ height: 22px;
175353
+ padding: 0 8px;
175354
+ border: none;
175355
+ border-radius: var(--sp-radius);
175356
+ background: transparent;
175357
+ color: var(--sp-muted-fg);
175358
+ font: inherit;
175359
+ font-size: 12px;
175360
+ cursor: pointer;
175361
+ white-space: nowrap;
175362
+ transition:
175363
+ background 0.1s,
175364
+ color 0.1s;
175365
+ }
175366
+ .sp-segmented-item:hover {
175367
+ color: var(--sp-fg);
175368
+ }
175369
+ .sp-segmented-item.active {
175370
+ background: var(--sp-header-bg);
175371
+ color: var(--sp-fg);
175372
+ font-weight: 600;
175373
+ box-shadow: inset 0 0 0 1px var(--sp-border);
175374
+ }
175375
+ .sp-segmented-item:focus-visible {
175376
+ outline: 1px solid var(--sp-focus-border);
175377
+ outline-offset: -1px;
175378
+ }
175379
+ /* ── Connection subpage ── */
175380
+ .sp-settings-page-body.sp-settings-page-body-subpage {
175381
+ padding: 0;
175382
+ overflow: hidden;
175383
+ }
175384
+
175385
+ .sp-settings-conn-panel-subpage,
175386
+ .sp-conn-subpage {
175387
+ display: flex;
175388
+ flex: 1;
175389
+ flex-direction: column;
175390
+ min-height: 0;
175391
+ height: 100%;
175392
+ }
175393
+
175394
+ .sp-conn-subpage {
175395
+ width: 100%;
175396
+ }
175397
+
175398
+ .sp-conn-subpage-body {
175399
+ flex: 1;
175400
+ min-height: 0;
175401
+ overflow-y: auto;
175402
+ padding: 24px 32px 32px;
175403
+ }
175404
+
175405
+ .sp-conn-subpage-column {
175406
+ display: block;
175407
+ max-width: 720px;
175408
+ margin-inline: auto;
175409
+ }
175410
+
175411
+ .sp-conn-subpage .sp-conn-detail-body {
175412
+ padding: 0;
175413
+ }
175414
+
175415
+ .sp-conn-schema-error {
175416
+ color: var(--sp-error);
174986
175417
  }</style>
174987
175418
  </head>
174988
175419