sql-preview 0.6.1 → 0.6.3

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/Changelog.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.6.3] - 2026-06-03
6
+
7
+ ### Added
8
+
9
+ - Added an MCP-accessible credential request flow that returns a short-lived local browser form so agents can ask users to store connection passwords without putting secrets in chat transcripts.
10
+ - Added local interactive Snowflake Browser SSO support for MCP/daemon connection tests, including analyst-style `user` and `authenticator=externalbrowser` aliases.
11
+
12
+ ### Fixed
13
+
14
+ - Fixed unconfigured VS Code workspaces showing a phantom built-in `Workspace Trino` connection beside saved Snowflake profiles.
15
+
16
+ ### Changed
17
+
18
+ - Simplified the Snowflake connection form by moving token caching and warehouse/database/schema/role defaults into optional settings, with SSO token caching enabled by default.
19
+
20
+ ## [0.6.2] - 2026-06-03
21
+
22
+ ### Added
23
+
24
+ - Added a product strategy note on using SQL Preview's query wedge to accelerate toward a broader agentic query layer.
25
+ - Added the initial RFC-054 Zed MCP extension scaffold, local verification script, and setup guide.
26
+ - Added Zed marketplace readiness checks, CI, and publishing instructions for submitting the SQL Preview MCP extension to `zed-industries/extensions`.
27
+ - Added Snowflake Browser SSO profile support for VS Code by passing `EXTERNALBROWSER` auth options to the Snowflake driver without storing a Snowflake password.
28
+
29
+ ### Fixed
30
+
31
+ - Added Snowflake SDK optional-dependency handling so packaged VS Code installs surface guided installation advice instead of an unexplained missing-module failure.
32
+
5
33
  ## [0.6.1] - 2026-05-29
6
34
 
7
35
  ### Fixed
package/dist/mcp-app.html CHANGED
@@ -74174,6 +74174,7 @@ const DynamicForm = ({
74174
74174
  submitFeedback
74175
74175
  }) => {
74176
74176
  const [formData, setFormData] = reactExports.useState({});
74177
+ const [isAdvancedOpen, setIsAdvancedOpen] = reactExports.useState(false);
74177
74178
  const lastResetKey = reactExports.useRef(void 0);
74178
74179
  const resetKey = reactExports.useMemo(
74179
74180
  () => JSON.stringify({
@@ -74186,6 +74187,29 @@ const DynamicForm = ({
74186
74187
  }),
74187
74188
  [initialData, schema.properties]
74188
74189
  );
74190
+ const isFieldVisible = (prop, data) => {
74191
+ var _a3;
74192
+ const visibleWhen = (_a3 = prop.ui) == null ? void 0 : _a3.visibleWhen;
74193
+ if (!visibleWhen) {
74194
+ return true;
74195
+ }
74196
+ const actual = data[visibleWhen.field];
74197
+ if ("equals" in visibleWhen) {
74198
+ return actual === visibleWhen.equals;
74199
+ }
74200
+ if ("notEquals" in visibleWhen) {
74201
+ return actual !== visibleWhen.notEquals;
74202
+ }
74203
+ if (Array.isArray(visibleWhen.in)) {
74204
+ return visibleWhen.in.includes(actual);
74205
+ }
74206
+ return true;
74207
+ };
74208
+ const visiblePropertyEntries = () => Object.entries(schema.properties || {}).filter(([, prop]) => isFieldVisible(prop, formData));
74209
+ const visibleFormData = () => {
74210
+ const visibleKeys = /* @__PURE__ */ new Set(["name", ...visiblePropertyEntries().map(([key]) => key)]);
74211
+ return Object.fromEntries(Object.entries(formData).filter(([key]) => visibleKeys.has(key)));
74212
+ };
74189
74213
  reactExports.useEffect(() => {
74190
74214
  if (lastResetKey.current === resetKey) {
74191
74215
  return;
@@ -74209,17 +74233,111 @@ const DynamicForm = ({
74209
74233
  };
74210
74234
  const handleSubmit = (e2) => {
74211
74235
  e2.preventDefault();
74212
- onSubmit(formData);
74236
+ onSubmit(visibleFormData());
74213
74237
  };
74214
74238
  const handleTest = () => {
74215
74239
  if (onTest) {
74216
- onTest(formData);
74240
+ onTest(visibleFormData());
74217
74241
  }
74218
74242
  };
74243
+ const hasMeaningfulInitialValue = (key) => {
74244
+ const value = initialData[key];
74245
+ return value !== void 0 && value !== null && value !== "" && value !== false;
74246
+ };
74247
+ const advancedInitiallyOpen = Object.entries(schema.properties || {}).some(
74248
+ ([key, prop]) => {
74249
+ var _a3;
74250
+ return ((_a3 = prop.ui) == null ? void 0 : _a3.advanced) && hasMeaningfulInitialValue(key);
74251
+ }
74252
+ );
74253
+ reactExports.useEffect(() => {
74254
+ setIsAdvancedOpen(advancedInitiallyOpen);
74255
+ }, [advancedInitiallyOpen, resetKey]);
74219
74256
  const fieldClass = (key, baseClass) => {
74257
+ var _a3, _b2;
74220
74258
  const normalizedKey = key.replace(/[^a-z0-9_-]/gi, "-").toLowerCase();
74221
- return `${baseClass} sp-conn-form-field sp-conn-form-field-${normalizedKey}`;
74259
+ const fullWidth = ((_b2 = (_a3 = schema.properties[key]) == null ? void 0 : _a3.ui) == null ? void 0 : _b2.fullWidth) ? " sp-conn-form-field-full" : "";
74260
+ return `${baseClass} sp-conn-form-field sp-conn-form-field-${normalizedKey}${fullWidth}`;
74261
+ };
74262
+ const renderPropertyField = ([key, prop]) => {
74263
+ var _a3;
74264
+ const isRequired = (_a3 = schema.required) == null ? void 0 : _a3.includes(key);
74265
+ const value = formData[key];
74266
+ const fieldId = `form-${key}`;
74267
+ const field = (() => {
74268
+ var _a4;
74269
+ if (prop.type === "boolean") {
74270
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-check-row"), children: [
74271
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
74272
+ "input",
74273
+ {
74274
+ type: "checkbox",
74275
+ id: fieldId,
74276
+ checked: !!value,
74277
+ onChange: (e2) => handleChange(key, e2.target.checked)
74278
+ }
74279
+ ),
74280
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: fieldId, className: "sp-conn-form-label", style: { marginBottom: 0 }, children: prop.title || key }),
74281
+ prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description })
74282
+ ] });
74283
+ }
74284
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-group"), children: [
74285
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { htmlFor: fieldId, className: "sp-conn-form-label", children: [
74286
+ prop.title || key,
74287
+ isRequired && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "required", children: "*" })
74288
+ ] }),
74289
+ prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description }),
74290
+ Array.isArray(prop.enum) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
74291
+ "select",
74292
+ {
74293
+ id: fieldId,
74294
+ required: isRequired,
74295
+ className: "sp-conn-form-input",
74296
+ value: value || "",
74297
+ onChange: (e2) => handleChange(key, e2.target.value),
74298
+ children: prop.enum.map((option, index2) => {
74299
+ var _a5;
74300
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: option, children: ((_a5 = prop.enumNames) == null ? void 0 : _a5[index2]) ?? option }, option);
74301
+ })
74302
+ }
74303
+ ) : prop.type === "number" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
74304
+ "input",
74305
+ {
74306
+ id: fieldId,
74307
+ type: "number",
74308
+ required: isRequired,
74309
+ className: "sp-conn-form-input",
74310
+ value: value !== void 0 ? String(value) : "",
74311
+ onChange: (e2) => handleChange(key, e2.target.value !== "" ? Number(e2.target.value) : void 0)
74312
+ }
74313
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
74314
+ "input",
74315
+ {
74316
+ id: fieldId,
74317
+ type: ((_a4 = prop.ui) == null ? void 0 : _a4.widget) === "password" ? "password" : "text",
74318
+ required: isRequired,
74319
+ className: "sp-conn-form-input",
74320
+ value: value || "",
74321
+ onChange: (e2) => handleChange(key, e2.target.value)
74322
+ }
74323
+ )
74324
+ ] });
74325
+ })();
74326
+ const afterField = renderAfterField == null ? void 0 : renderAfterField(key);
74327
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(React$2.Fragment, { children: [
74328
+ field,
74329
+ afterField
74330
+ ] }, key);
74222
74331
  };
74332
+ const visibleEntries = visiblePropertyEntries();
74333
+ const primaryEntries = visibleEntries.filter(([, prop]) => {
74334
+ var _a3;
74335
+ return !((_a3 = prop.ui) == null ? void 0 : _a3.advanced);
74336
+ });
74337
+ const advancedEntries = visibleEntries.filter(([, prop]) => {
74338
+ var _a3;
74339
+ return (_a3 = prop.ui) == null ? void 0 : _a3.advanced;
74340
+ });
74223
74341
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, className: "sp-conn-form", role: "form", children: [
74224
74342
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-form-fields", children: [
74225
74343
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass("name", "sp-conn-form-group"), children: [
@@ -74239,68 +74357,20 @@ const DynamicForm = ({
74239
74357
  }
74240
74358
  )
74241
74359
  ] }),
74242
- Object.entries(schema.properties || {}).map(([key, prop]) => {
74243
- var _a3;
74244
- const isRequired = (_a3 = schema.required) == null ? void 0 : _a3.includes(key);
74245
- const value = formData[key];
74246
- const field = (() => {
74247
- var _a4;
74248
- if (prop.type === "boolean") {
74249
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-check-row"), children: [
74250
- /* @__PURE__ */ jsxRuntimeExports.jsx(
74251
- "input",
74252
- {
74253
- type: "checkbox",
74254
- id: `form-${key}`,
74255
- checked: !!value,
74256
- onChange: (e2) => handleChange(key, e2.target.checked)
74257
- }
74258
- ),
74259
- /* @__PURE__ */ jsxRuntimeExports.jsx(
74260
- "label",
74261
- {
74262
- htmlFor: `form-${key}`,
74263
- className: "sp-conn-form-label",
74264
- style: { marginBottom: 0 },
74265
- children: prop.title || key
74266
- }
74267
- ),
74268
- prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description })
74269
- ] });
74270
- }
74271
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: fieldClass(key, "sp-conn-form-group"), children: [
74272
- /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "sp-conn-form-label", children: [
74273
- prop.title || key,
74274
- isRequired && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "required", children: "*" })
74275
- ] }),
74276
- prop.description && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-form-hint", children: prop.description }),
74277
- prop.type === "number" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
74278
- "input",
74279
- {
74280
- type: "number",
74281
- required: isRequired,
74282
- className: "sp-conn-form-input",
74283
- value: value !== void 0 ? String(value) : "",
74284
- onChange: (e2) => handleChange(key, e2.target.value !== "" ? Number(e2.target.value) : void 0)
74285
- }
74286
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
74287
- "input",
74288
- {
74289
- type: ((_a4 = prop.ui) == null ? void 0 : _a4.widget) === "password" ? "password" : "text",
74290
- required: isRequired,
74291
- className: "sp-conn-form-input",
74292
- value: value || "",
74293
- onChange: (e2) => handleChange(key, e2.target.value)
74294
- }
74295
- )
74296
- ] });
74297
- })();
74298
- const afterField = renderAfterField == null ? void 0 : renderAfterField(key);
74299
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(React$2.Fragment, { children: [
74300
- field,
74301
- afterField
74302
- ] }, key);
74303
- })
74360
+ primaryEntries.map(renderPropertyField),
74361
+ advancedEntries.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
74362
+ "details",
74363
+ {
74364
+ className: "sp-conn-form-advanced",
74365
+ open: isAdvancedOpen,
74366
+ onToggle: (event) => setIsAdvancedOpen(event.currentTarget.open),
74367
+ children: [
74368
+ /* @__PURE__ */ jsxRuntimeExports.jsx("summary", { className: "sp-conn-form-advanced-summary", children: "Optional settings" }),
74369
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-advanced-fields", children: advancedEntries.map(renderPropertyField) })
74370
+ ]
74371
+ },
74372
+ `advanced-${resetKey}`
74373
+ )
74304
74374
  ] }),
74305
74375
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-form-actions", children: [
74306
74376
  actionStatus && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-form-action-status", children: actionStatus }),
@@ -74340,12 +74410,20 @@ const DynamicForm = ({
74340
74410
  ] })
74341
74411
  ] });
74342
74412
  };
74343
- const DUCKDB_OPTIONAL_DEPENDENCY_ADVICE = {
74344
- dependency: "@duckdb/node-api",
74345
- installCommand: "npm install @duckdb/node-api",
74346
- title: "DUCKDB support is required",
74347
- guidance: "Local file queries require optional DuckDB support, but the DuckDB native module is not available in this extension runtime."
74348
- };
74413
+ const OPTIONAL_DEPENDENCY_ADVICE = [
74414
+ {
74415
+ dependency: "@duckdb/node-api",
74416
+ installCommand: "npm install @duckdb/node-api",
74417
+ title: "DUCKDB support is required",
74418
+ guidance: "Local file queries require optional DuckDB support, but the DuckDB native module is not available in this extension runtime."
74419
+ },
74420
+ {
74421
+ dependency: "snowflake-sdk",
74422
+ installCommand: "npm install snowflake-sdk",
74423
+ title: "Snowflake support is required",
74424
+ guidance: "Snowflake connections require optional Snowflake SDK support, but the SDK is not available in this extension runtime."
74425
+ }
74426
+ ];
74349
74427
  const CONNECTOR_ICONS = {
74350
74428
  duckdb: "🦆",
74351
74429
  trino: "⚡",
@@ -74358,10 +74436,18 @@ const CONNECTOR_ICONS = {
74358
74436
  };
74359
74437
  function getOptionalDependencyAdvice(message) {
74360
74438
  const lowerMessage = message.toLowerCase();
74361
- if (message.includes("@duckdb/node-api") || lowerMessage.includes("duckdb native module")) {
74362
- return DUCKDB_OPTIONAL_DEPENDENCY_ADVICE;
74363
- }
74364
- return null;
74439
+ return OPTIONAL_DEPENDENCY_ADVICE.find((advice) => {
74440
+ if (message.includes(advice.dependency)) {
74441
+ return true;
74442
+ }
74443
+ if (advice.dependency === "@duckdb/node-api") {
74444
+ return lowerMessage.includes("duckdb native module");
74445
+ }
74446
+ if (advice.dependency === "snowflake-sdk") {
74447
+ return lowerMessage.includes("snowflake sdk") || lowerMessage.includes("sdk is not available");
74448
+ }
74449
+ return false;
74450
+ }) ?? null;
74365
74451
  }
74366
74452
  function getOptionalDependencyDetails(message) {
74367
74453
  return message.replace(/^Connection Test Failed:\s*/i, "").replace(/^Error:\s*/i, "").trim();
@@ -74383,6 +74469,16 @@ function isErrorToolResult(result, text) {
74383
74469
  }
74384
74470
  return result.isError === true || text.toLowerCase().includes("failed") || text.toLowerCase().includes("error");
74385
74471
  }
74472
+ function buildConnectionTestToast(structuredContent, text) {
74473
+ const advice = (structuredContent == null ? void 0 : structuredContent.optionalDependencyAdvice) ?? getOptionalDependencyAdvice(text);
74474
+ const lowerText = text.toLowerCase();
74475
+ const isError = structuredContent ? !structuredContent.success : lowerText.includes("error") || lowerText.includes("failed");
74476
+ return {
74477
+ text: advice ? advice.guidance : text,
74478
+ severity: advice ? "warning" : isError ? "error" : "success",
74479
+ ...advice ? { advice } : {}
74480
+ };
74481
+ }
74386
74482
  function getFormInitialData(connection) {
74387
74483
  if (!connection) {
74388
74484
  return {};
@@ -74409,6 +74505,32 @@ function schemaWithoutPasswordField(schema) {
74409
74505
  ...required2 ? { required: required2 } : {}
74410
74506
  };
74411
74507
  }
74508
+ function schemaForConnectionMode(schema, connectorId, mode) {
74509
+ if (connectorId !== "snowflake" || mode !== "headless") {
74510
+ return schema;
74511
+ }
74512
+ const authModeProperty = schema.properties["authMode"];
74513
+ if (!Array.isArray(authModeProperty == null ? void 0 : authModeProperty.enum)) {
74514
+ return schema;
74515
+ }
74516
+ const allowedIndexes = authModeProperty.enum.map((option, index2) => ({ option, index: index2 })).filter(({ option }) => option !== "externalbrowser");
74517
+ const enumNames = Array.isArray(authModeProperty.enumNames) ? allowedIndexes.map(({ option, index: index2 }) => {
74518
+ var _a3;
74519
+ return ((_a3 = authModeProperty.enumNames) == null ? void 0 : _a3[index2]) ?? option;
74520
+ }) : void 0;
74521
+ return {
74522
+ ...schema,
74523
+ properties: {
74524
+ ...schema.properties,
74525
+ authMode: {
74526
+ ...authModeProperty,
74527
+ enum: allowedIndexes.map(({ option }) => option),
74528
+ ...enumNames ? { enumNames } : {},
74529
+ default: authModeProperty.default === "externalbrowser" ? "password" : authModeProperty.default
74530
+ }
74531
+ }
74532
+ };
74533
+ }
74412
74534
  const ConnectionsManager = () => {
74413
74535
  const { callServerTool, isReady, mode, sendMessage } = useHostContext();
74414
74536
  const supportsActiveConnection = mode === "vscode";
@@ -74421,6 +74543,7 @@ const ConnectionsManager = () => {
74421
74543
  const [statuses, setStatuses] = reactExports.useState({});
74422
74544
  const [statusMessages, setStatusMessages] = reactExports.useState({});
74423
74545
  const [toast, setToast] = reactExports.useState(null);
74546
+ const toastRef = reactExports.useRef(null);
74424
74547
  const [isFormOpen, setIsFormOpen] = reactExports.useState(false);
74425
74548
  const [selectedType, setSelectedType] = reactExports.useState("");
74426
74549
  const fetchData = reactExports.useCallback(async () => {
@@ -74485,6 +74608,16 @@ const ConnectionsManager = () => {
74485
74608
  });
74486
74609
  }
74487
74610
  }, [connections]);
74611
+ reactExports.useEffect(() => {
74612
+ if (!toast || toast.severity !== "warning") {
74613
+ return;
74614
+ }
74615
+ window.requestAnimationFrame(() => {
74616
+ var _a3, _b2;
74617
+ (_a3 = toastRef.current) == null ? void 0 : _a3.scrollIntoView({ behavior: "smooth", block: "center" });
74618
+ (_b2 = toastRef.current) == null ? void 0 : _b2.focus({ preventScroll: true });
74619
+ });
74620
+ }, [toast]);
74488
74621
  const handleTestConnection = async (connectionId) => {
74489
74622
  var _a3;
74490
74623
  if (!isReady) {
@@ -74511,7 +74644,7 @@ const ConnectionsManager = () => {
74511
74644
  }
74512
74645
  };
74513
74646
  const handleTestFormData = async (formData, connection) => {
74514
- var _a3, _b2;
74647
+ var _a3;
74515
74648
  const typeToTest = (connection == null ? void 0 : connection.type) ?? selectedType;
74516
74649
  if (!isReady || !typeToTest) {
74517
74650
  return;
@@ -74535,15 +74668,11 @@ const ConnectionsManager = () => {
74535
74668
  });
74536
74669
  const text = getToolText(result, ((_a3 = result.structuredContent) == null ? void 0 : _a3.message) ?? "No response");
74537
74670
  const isError = isErrorToolResult(result, text);
74538
- const advice = ((_b2 = result.structuredContent) == null ? void 0 : _b2.optionalDependencyAdvice) ?? getOptionalDependencyAdvice(text);
74539
74671
  if (connection) {
74540
74672
  setStatuses((prev) => ({ ...prev, [connection.id]: isError ? "error" : "ok" }));
74541
74673
  setStatusMessages((prev) => ({ ...prev, [connection.id]: text }));
74542
74674
  } else {
74543
- setToast({
74544
- text: advice ? advice.guidance : text,
74545
- severity: advice ? "warning" : isError ? "error" : "success"
74546
- });
74675
+ setToast(buildConnectionTestToast(result.structuredContent, text));
74547
74676
  }
74548
74677
  } catch (e2) {
74549
74678
  const message = `Error: ${e2}`;
@@ -74554,7 +74683,8 @@ const ConnectionsManager = () => {
74554
74683
  } else {
74555
74684
  setToast({
74556
74685
  text: advice ? advice.guidance : message,
74557
- severity: advice ? "warning" : "error"
74686
+ severity: advice ? "warning" : "error",
74687
+ ...advice ? { advice } : {}
74558
74688
  });
74559
74689
  }
74560
74690
  }
@@ -74686,6 +74816,7 @@ const ConnectionsManager = () => {
74686
74816
  };
74687
74817
  const activeSchemaDef = connectors.find((c) => c.id === selectedType);
74688
74818
  const selectedConnection = selectedConnectionId ? connections.find((c) => c.id === selectedConnectionId) : void 0;
74819
+ const activeFormSchema = (activeSchemaDef == null ? void 0 : activeSchemaDef.schema) ? schemaForConnectionMode(activeSchemaDef.schema, activeSchemaDef.id, mode) : void 0;
74689
74820
  const selectedFormInitialData = reactExports.useMemo(
74690
74821
  () => getFormInitialData(selectedConnection),
74691
74822
  [selectedConnection]
@@ -74693,18 +74824,40 @@ const ConnectionsManager = () => {
74693
74824
  const emptyFormInitialData = reactExports.useMemo(() => ({}), []);
74694
74825
  const renderToast = () => {
74695
74826
  if (!toast) return null;
74696
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `sp-conn-toast sp-conn-toast-${toast.severity}`, children: [
74697
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-toast-text", children: toast.text }),
74698
- /* @__PURE__ */ jsxRuntimeExports.jsx(
74699
- "button",
74700
- {
74701
- className: "sp-conn-toast-close",
74702
- onClick: () => setToast(null),
74703
- "aria-label": "Close message",
74704
- children: "✕"
74705
- }
74706
- )
74707
- ] });
74827
+ const advice = toast.advice;
74828
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
74829
+ "div",
74830
+ {
74831
+ ref: toastRef,
74832
+ className: `sp-conn-toast sp-conn-toast-${toast.severity}`,
74833
+ role: toast.severity === "warning" || toast.severity === "error" ? "alert" : "status",
74834
+ tabIndex: -1,
74835
+ children: [
74836
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "sp-conn-toast-text", children: toast.text }),
74837
+ advice && /* @__PURE__ */ jsxRuntimeExports.jsxs(
74838
+ "button",
74839
+ {
74840
+ type: "button",
74841
+ className: "sp-btn sp-btn-primary sp-conn-toast-action",
74842
+ onClick: () => handleInstallOptionalDependency(advice),
74843
+ children: [
74844
+ "Install ",
74845
+ advice.dependency
74846
+ ]
74847
+ }
74848
+ ),
74849
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
74850
+ "button",
74851
+ {
74852
+ className: "sp-conn-toast-close",
74853
+ onClick: () => setToast(null),
74854
+ "aria-label": "Close message",
74855
+ children: "✕"
74856
+ }
74857
+ )
74858
+ ]
74859
+ }
74860
+ );
74708
74861
  };
74709
74862
  const renderConnectionStatusMessage = (connection) => {
74710
74863
  const status = statuses[connection.id] || "unknown";
@@ -74772,10 +74925,10 @@ const ConnectionsManager = () => {
74772
74925
  },
74773
74926
  c.id
74774
74927
  )) }),
74775
- activeSchemaDef && activeSchemaDef.schema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
74928
+ activeSchemaDef && activeFormSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
74776
74929
  DynamicForm,
74777
74930
  {
74778
- schema: { ...activeSchemaDef.schema, type: "object" },
74931
+ schema: { ...activeFormSchema, type: "object" },
74779
74932
  initialData: emptyFormInitialData,
74780
74933
  onSubmit: (formData) => handleSaveConnection(formData),
74781
74934
  onTest: (formData) => handleTestFormData(formData),
@@ -74794,6 +74947,7 @@ const ConnectionsManager = () => {
74794
74947
  const schemaDef = connectors.find((c) => c.id === selectedConnection.type);
74795
74948
  const canManagePassword = supportsActiveConnection && !selectedConnection.builtIn && schemaHasPasswordField(schemaDef == null ? void 0 : schemaDef.schema);
74796
74949
  const editSchema = (schemaDef == null ? void 0 : schemaDef.schema) && canManagePassword ? schemaWithoutPasswordField(schemaDef.schema) : schemaDef == null ? void 0 : schemaDef.schema;
74950
+ const modeAwareEditSchema = editSchema ? schemaForConnectionMode(editSchema, selectedConnection.type, mode) : void 0;
74797
74951
  const passwordAnchorField = (editSchema == null ? void 0 : editSchema.properties["user"]) ? "user" : (editSchema == null ? void 0 : editSchema.properties["username"]) ? "username" : void 0;
74798
74952
  const renderPasswordManagementField = (key) => {
74799
74953
  if (!canManagePassword || key !== passwordAnchorField) {
@@ -74870,10 +75024,10 @@ const ConnectionsManager = () => {
74870
75024
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "sp-conn-detail-body", children: [
74871
75025
  renderToast(),
74872
75026
  isActive && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "sp-conn-active-callout", role: "status", children: "Queries from SQL Preview and MCP will use this connection unless a query overrides it." }),
74873
- editSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
75027
+ modeAwareEditSchema ? /* @__PURE__ */ jsxRuntimeExports.jsx(
74874
75028
  DynamicForm,
74875
75029
  {
74876
- schema: { ...editSchema, type: "object" },
75030
+ schema: { ...modeAwareEditSchema, type: "object" },
74877
75031
  initialData: selectedFormInitialData,
74878
75032
  onSubmit: (formData) => handleSaveConnection(formData, selectedConnection),
74879
75033
  onTest: (formData) => handleTestFormData(formData, selectedConnection),
@@ -98712,7 +98866,8 @@ body.vscode-high-contrast .ag-theme-quartz {
98712
98866
  }
98713
98867
 
98714
98868
  .sp-conn-form-fields > .sp-conn-form-group:first-child,
98715
- .sp-conn-form-field-name {
98869
+ .sp-conn-form-field-name,
98870
+ .sp-conn-form-field-full {
98716
98871
  grid-column: 1 / -1;
98717
98872
  }
98718
98873
 
@@ -98741,6 +98896,31 @@ body.vscode-high-contrast .ag-theme-quartz {
98741
98896
  margin-top: 4px;
98742
98897
  }
98743
98898
 
98899
+ .sp-conn-form-advanced {
98900
+ grid-column: 1 / -1;
98901
+ padding-top: 2px;
98902
+ }
98903
+
98904
+ .sp-conn-form-advanced-summary {
98905
+ cursor: pointer;
98906
+ color: var(--sp-muted-fg);
98907
+ font-size: 12px;
98908
+ font-weight: 600;
98909
+ outline: none;
98910
+ }
98911
+
98912
+ .sp-conn-form-advanced-summary:hover,
98913
+ .sp-conn-form-advanced-summary:focus-visible {
98914
+ color: var(--sp-fg);
98915
+ }
98916
+
98917
+ .sp-conn-form-advanced-fields {
98918
+ display: grid;
98919
+ grid-template-columns: repeat(12, minmax(0, 1fr));
98920
+ gap: 12px 16px;
98921
+ margin-top: 10px;
98922
+ }
98923
+
98744
98924
  .sp-conn-credential-state {
98745
98925
  font-size: 11px;
98746
98926
  color: var(--sp-muted-fg);
@@ -98883,6 +99063,10 @@ body.vscode-high-contrast .ag-theme-quartz {
98883
99063
  overflow-wrap: anywhere;
98884
99064
  word-break: break-word;
98885
99065
  }
99066
+ .sp-conn-toast-action {
99067
+ flex-shrink: 0;
99068
+ align-self: center;
99069
+ }
98886
99070
  .sp-conn-toast-close {
98887
99071
  background: none;
98888
99072
  border: none;
@@ -98999,7 +99183,8 @@ body.vscode-high-contrast .ag-theme-quartz {
98999
99183
  grid-template-columns: minmax(0, 1fr);
99000
99184
  }
99001
99185
 
99002
- .sp-conn-form-fields {
99186
+ .sp-conn-form-fields,
99187
+ .sp-conn-form-advanced-fields {
99003
99188
  grid-template-columns: minmax(0, 1fr);
99004
99189
  }
99005
99190