@yejiming/dsh-data-agent 0.0.9 → 0.0.11

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/lib/client.js CHANGED
@@ -55,7 +55,7 @@ window.__ModuleLoader__.load({
55
55
  saved.credentialMode = "reference";
56
56
  return saved;
57
57
  }
58
- if (candidate.credentialMode === "password") saved.credentialMode = "password";
58
+ if (candidate.credentialMode === "password" || candidate.credentialMode === "none") saved.credentialMode = candidate.credentialMode;
59
59
  const persistPassword = candidate.persistPassword === true;
60
60
  if (persistPassword) saved.persistPassword = true;
61
61
  if (persistPassword && typeof candidate.password === "string") saved.password = candidate.password;
@@ -72,7 +72,10 @@ window.__ModuleLoader__.load({
72
72
  toWrite.credentialMode = "reference";
73
73
  } else {
74
74
  delete toWrite.passwordRef;
75
- if (toWrite.persistPassword !== true) delete toWrite.password;
75
+ if (toWrite.credentialMode === "none") {
76
+ delete toWrite.password;
77
+ delete toWrite.persistPassword;
78
+ } else if (toWrite.persistPassword !== true) delete toWrite.password;
76
79
  }
77
80
  storage.setItem(CONNECTION_STORAGE_KEY, JSON.stringify(toWrite));
78
81
  } catch {}
@@ -90,7 +93,7 @@ window.__ModuleLoader__.load({
90
93
  }
91
94
  //#endregion
92
95
  //#region \0dsh-css:/Users/yejiming/Desktop/OpenSource/dsh-data-agent/src/client/DataAgentWorkbench.module.css.mjs
93
- const css$1 = ".Sv3uVW_workbench{box-sizing:border-box;font-family:var(--dsw-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Microsoft YaHei\", sans-serif);color:var(--dsw-alias-label-primary,inherit);flex-direction:column;gap:10px;font-size:13px;line-height:1.5;display:flex}.Sv3uVW_strip{width:100%}.Sv3uVW_docked{width:100%;max-height:55vh;overflow-y:auto}.Sv3uVW_rail{z-index:8;border-right:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-specific-sidebar-fill,var(--dsw-alias-bg-layer-1,#ffffff08));padding:12px;overflow-y:auto}html.Sv3uVW_da-split [data-phase=active] [data-conversation-scroll]>:first-child,html.Sv3uVW_da-split [data-phase=active] [data-conversation-scroll]>[data-slot=conversation\\.session]>*{margin-left:380px}html.Sv3uVW_da-split [data-phase=active] [data-composer-seat]{padding-left:380px}.Sv3uVW_sections{flex-direction:column;gap:12px;display:flex}.Sv3uVW_card{border:1px solid var(--dsw-alias-border-l2,#80808059);border-radius:12px;flex-direction:column;gap:10px;padding:12px 14px;display:flex}.Sv3uVW_cardTitle{text-transform:uppercase;letter-spacing:.06em;color:var(--dsw-alias-label-tertiary,#808080b3);align-items:center;gap:6px;font-size:11px;font-weight:600;display:flex}.Sv3uVW_titleIcon{width:14px;height:14px;color:var(--dsw-alias-label-secondary,#808080cc);flex:none}.Sv3uVW_fieldGrid{flex-direction:column;gap:10px;display:flex}.Sv3uVW_fieldRow2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px;display:grid}.Sv3uVW_field{flex-direction:column;gap:4px;min-width:0;display:flex}.Sv3uVW_label{color:var(--dsw-alias-label-secondary,#808080b3);font-size:11px;font-weight:500}.Sv3uVW_rememberRow{color:var(--dsw-alias-label-primary,inherit);cursor:pointer;user-select:none;align-items:center;gap:6px;font-size:12px;display:flex}.Sv3uVW_rememberRow input[type=checkbox]{width:14px;height:14px;accent-color:var(--dsw-alias-button-info-fill,#3b82f6);cursor:pointer;flex:none;margin:0}.Sv3uVW_rememberHint{color:var(--dsw-alias-label-caption,#80808080);font-size:11px}.Sv3uVW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;height:32px;color:var(--dsw-alias-label-primary,inherit);font:inherit;border-radius:8px;padding:0 10px;font-size:13px;transition:border-color .15s ease-out,box-shadow .15s ease-out}.Sv3uVW_input::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_input:focus-visible,.Sv3uVW_input:focus{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_input:disabled{opacity:.55}select.Sv3uVW_input{-webkit-appearance:none;appearance:none;cursor:pointer;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' fill='none' stroke='%23777' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 10px center;background-repeat:no-repeat;padding-right:28px}.Sv3uVW_actions{align-items:center;gap:8px;margin-top:2px;display:flex}.Sv3uVW_actions>.Sv3uVW_primary,.Sv3uVW_actions>.Sv3uVW_ghost{flex:1}.Sv3uVW_primary,.Sv3uVW_ghost{height:32px;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;justify-content:center;align-items:center;gap:6px;padding:0 14px;font-size:13px;font-weight:500;transition:background-color .15s ease-out,border-color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_primary{background:var(--dsw-alias-button-info-fill,#3b82f6);color:#fff}.Sv3uVW_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover,#3573e0)}.Sv3uVW_primary:active:not(:disabled){background:var(--dsw-static-deepseek-600,#2f5fc0)}.Sv3uVW_ghost{border-color:var(--dsw-alias-border-l2,#80808059);color:var(--dsw-alias-label-primary,inherit);background:0 0}.Sv3uVW_ghost:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_ghost:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active,#80808024)}.Sv3uVW_primary:focus-visible,.Sv3uVW_ghost:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 25%, transparent);outline:none}.Sv3uVW_primary:disabled,.Sv3uVW_ghost:disabled{opacity:.45;cursor:default}.Sv3uVW_small{border-radius:6px;height:24px;padding:0 10px;font-size:12px}.Sv3uVW_hint{color:var(--dsw-alias-label-tertiary,#80808099);font-size:12px}.Sv3uVW_summaryRow{align-items:center;gap:8px;min-height:28px;display:flex}.Sv3uVW_statusOk{color:var(--dsw-alias-state-success-primary,#22c55e);flex:none;align-items:center;gap:5px;font-size:12px;font-weight:500;display:inline-flex}.Sv3uVW_summaryType{border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:999px;flex:none;padding:2px 8px;font-size:11px}.Sv3uVW_summaryDb{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);flex:1;font-size:12px;overflow:hidden}.Sv3uVW_summaryActions{flex:none;gap:6px;display:flex}.Sv3uVW_heroConnect{border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;border-radius:10px;align-items:center;gap:12px;padding:14px 16px;transition:background-color .15s ease-out,border-color .15s ease-out;display:flex}.Sv3uVW_heroConnect:hover{background:var(--dsw-alias-interactive-bg-hover,#80808014);border-color:var(--dsw-alias-border-l3,#80808080)}.Sv3uVW_heroConnect:focus-visible{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_heroIcon{width:22px;height:22px;color:var(--dsw-alias-button-info-fill,#3b82f6);flex:none}.Sv3uVW_heroText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.Sv3uVW_heroTitle{color:var(--dsw-alias-label-primary,inherit);font-size:13px;font-weight:600}.Sv3uVW_heroHint{color:var(--dsw-alias-label-caption,#80808080);font-size:11.5px;line-height:1.5}.Sv3uVW_heroChevron{width:12px;height:12px;color:var(--dsw-alias-label-tertiary,#80808099);flex:none}.Sv3uVW_browseRow{border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;height:36px;color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;border-radius:8px;align-items:center;gap:8px;padding:0 12px;font-size:13px;font-weight:500;transition:background-color .15s ease-out,border-color .15s ease-out;display:flex}.Sv3uVW_browseRow:hover{background:var(--dsw-alias-interactive-bg-hover,#80808014);border-color:var(--dsw-alias-border-l3,#80808080)}.Sv3uVW_browseRow:focus-visible{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_browseIcon{width:14px;height:14px;color:var(--dsw-alias-button-info-fill,#3b82f6);flex:none}.Sv3uVW_browseChevron{width:12px;height:12px;color:var(--dsw-alias-label-tertiary,#80808099);flex:none;margin-left:auto}.Sv3uVW_sqlInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;min-height:190px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);resize:vertical;border-radius:10px;padding:10px 12px;font-size:12.5px;line-height:1.6;transition:border-color .15s ease-out,box-shadow .15s ease-out}.Sv3uVW_sqlInput::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_sqlInput:focus-visible,.Sv3uVW_sqlInput:focus{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_sqlInput:disabled{opacity:.55}.Sv3uVW_sqlActions{justify-content:flex-end;align-items:center;gap:10px;display:flex}.Sv3uVW_sqlActions .Sv3uVW_primary{flex:none;min-width:92px}.Sv3uVW_shortcutHint{color:var(--dsw-alias-label-caption,#80808080);font-size:11.5px}.Sv3uVW_sqlResult{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);white-space:pre-wrap;word-break:break-word;border-radius:8px;max-height:200px;margin:0;padding:10px 12px;font-size:11.5px;line-height:1.55;overflow-y:auto}.Sv3uVW_errorBar{border:1px solid var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);border-radius:10px;flex-direction:column;gap:3px;padding:10px 12px;display:flex}.Sv3uVW_errorHead{color:var(--dsw-alias-state-error-primary,#ef4444);align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}.Sv3uVW_errorIcon{flex:none;width:14px;height:14px}.Sv3uVW_errorText{white-space:pre-wrap;word-break:break-word;font-size:12px}.Sv3uVW_connectModal{width:min(440px,92vw)}.Sv3uVW_connectModalBody{flex-direction:column;gap:14px;display:flex}.Sv3uVW_schemaModal{width:min(900px,94vw)}.Sv3uVW_modalBody{align-items:stretch;gap:20px;height:min(540px,58vh);display:flex}.Sv3uVW_modalCol{flex-direction:column;flex:1;gap:8px;min-width:0;min-height:0;display:flex}.Sv3uVW_modalColTitle{text-transform:uppercase;letter-spacing:.06em;color:var(--dsw-alias-label-tertiary,#808080b3);flex:none;align-items:center;gap:6px;font-size:11px;font-weight:600;display:flex}.Sv3uVW_colCount{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:999px;flex:none;padding:1px 7px;font-size:10px;font-weight:500}.Sv3uVW_treeScroll{flex:1;min-height:0;padding-right:4px;overflow-y:auto}.Sv3uVW_tree{flex-direction:column;gap:1px;margin:0;padding:0;list-style:none;display:flex}.Sv3uVW_treeNode{flex-direction:column;display:flex}.Sv3uVW_treeItem{width:100%;min-height:28px;color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:7px;align-items:center;gap:6px;padding:0 8px;font-size:12.5px;display:flex}.Sv3uVW_treeItem:hover{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_treeItem.Sv3uVW_active,.Sv3uVW_treeItem.Sv3uVW_active:hover{background:var(--dsw-alias-interactive-bg-active,#3b82f62e)}.Sv3uVW_treeChevron{width:12px;height:12px;color:var(--dsw-alias-label-tertiary,#80808099);flex:none;transition:transform .15s ease-out}.Sv3uVW_treeChevron.Sv3uVW_open{transform:rotate(90deg)}.Sv3uVW_treeIcon{width:14px;height:14px;color:var(--dsw-alias-label-secondary,#808080cc);flex:none}.Sv3uVW_treeItem.Sv3uVW_active .Sv3uVW_treeIcon{color:var(--dsw-alias-button-info-fill,#3b82f6)}.Sv3uVW_treeName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);flex:1;font-size:12px;overflow:hidden}.Sv3uVW_treeCount{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:999px;flex:none;padding:0 6px;font-size:10px}.Sv3uVW_treeChildren{border-left:1px solid var(--dsw-alias-border-l2,#80808059);flex-direction:column;gap:1px;margin-left:12px;padding-left:10px;display:flex}.Sv3uVW_colScroll{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:8px;flex:1;min-height:0;overflow:auto}.Sv3uVW_columnsTable{border-collapse:collapse;width:100%;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:12px}.Sv3uVW_columnsTable th{z-index:1;text-align:left;text-transform:uppercase;letter-spacing:.05em;color:var(--dsw-alias-label-tertiary,#808080b3);background:var(--dsw-alias-bg-layer-2,#ffffff0a);border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);padding:7px 10px;font-size:10.5px;font-weight:600;position:sticky;top:0}.Sv3uVW_columnsTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);color:var(--dsw-alias-label-primary,inherit);padding:5px 10px}.Sv3uVW_columnsTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_typeCell{color:var(--dsw-alias-label-secondary,#808080cc)}.Sv3uVW_nullCell{color:var(--dsw-alias-label-caption,#80808080);font-size:11px}.Sv3uVW_emptyState{border:1px dashed var(--dsw-alias-border-l2,#80808059);min-height:0;color:var(--dsw-alias-label-tertiary,#808080b3);border-radius:8px;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.Sv3uVW_emptyStateIcon{width:20px;height:20px;color:var(--dsw-alias-label-dimmed,#80808066)}.Sv3uVW_emptyStateText{font-size:12px}.Sv3uVW_modalHint{color:var(--dsw-alias-label-caption,#80808080);flex:none;align-items:center;gap:6px;margin-top:2px;font-size:11.5px;display:flex}@media (width<=640px){.Sv3uVW_modalBody{flex-direction:column;height:auto}.Sv3uVW_treeScroll{flex:none;height:300px}.Sv3uVW_colScroll{flex:none;height:240px}.Sv3uVW_emptyState{flex:none;height:120px}}";
96
+ const css$1 = ".Sv3uVW_triggerSlot{z-index:12;pointer-events:auto;display:flex;position:absolute;top:-42px;right:12px}.Sv3uVW_trigger{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-specific-selector,var(--dsw-alias-bg-layer-2,#ffffff0f));width:30px;height:30px;color:var(--dsw-alias-label-secondary,#808080e6);cursor:pointer;border-radius:9px;place-items:center;padding:0;transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out;display:grid;position:relative;box-shadow:0 1px 2px #0000000a}.Sv3uVW_trigger:hover,.Sv3uVW_triggerActive{border-color:var(--dsw-alias-border-l3,#80808080);background:var(--dsw-alias-interactive-bg-hover-solid,var(--dsw-alias-interactive-bg-hover,#8080801a));color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_trigger:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 25%, transparent);outline:none}.Sv3uVW_triggerDot{box-shadow:0 0 0 2px var(--dsw-specific-input-major,var(--dsw-alias-bg-base,#fff));border-radius:999px;position:absolute;bottom:-2px;right:-2px}.Sv3uVW_workbenchModal{width:min(920px,94vw)}.Sv3uVW_workbenchModalContent{min-height:min(590px,70vh);max-height:min(700px,76vh);overflow:auto}.Sv3uVW_workbench{box-sizing:border-box;min-height:520px;font-family:var(--dsw-font-family,-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"PingFang SC\", \"Microsoft YaHei\", sans-serif);color:var(--dsw-alias-label-primary,inherit);flex-direction:column;gap:14px;font-size:13px;line-height:1.5;display:flex}.Sv3uVW_connectionSummary{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);border-radius:10px;align-items:center;gap:8px;min-height:34px;padding:6px 10px;display:flex}.Sv3uVW_connectionState{flex:none;font-size:12px;font-weight:600}.Sv3uVW_summaryType{border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-1,#ffffff08);color:var(--dsw-alias-label-secondary,#808080cc);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);border-radius:999px;flex:none;padding:2px 8px;font-size:11px}.Sv3uVW_summaryDb{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.Sv3uVW_tabs{background:var(--dsw-specific-selector,var(--dsw-alias-bg-layer-2,#80808014));border-radius:10px;align-items:center;gap:4px;padding:3px;display:flex;overflow-x:auto}.Sv3uVW_tab{height:34px;color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:none;border-radius:8px;flex:1 0 120px;justify-content:center;align-items:center;gap:7px;padding:0 14px;font-size:13px;font-weight:500;display:inline-flex}.Sv3uVW_tab:hover:not(:disabled){color:var(--dsw-alias-label-primary,inherit);background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_tabActive,.Sv3uVW_tabActive:hover:not(:disabled){color:var(--dsw-alias-label-primary,inherit);background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1,#fffc));box-shadow:var(--dsw-shadow-lv1,0 1px 3px #00000014)}.Sv3uVW_tab:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 28%, transparent);outline:none}.Sv3uVW_tab:disabled{opacity:.42;cursor:default}.Sv3uVW_tabPanel{flex-direction:column;flex:1;gap:14px;min-height:0;padding:2px;display:flex}.Sv3uVW_fieldGrid{flex-direction:column;gap:11px;display:flex}.Sv3uVW_fieldRow2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;display:grid}.Sv3uVW_field{flex-direction:column;gap:5px;min-width:0;display:flex}.Sv3uVW_label{color:var(--dsw-alias-label-secondary,#808080bf);font-size:11px;font-weight:500}.Sv3uVW_rememberRow{color:var(--dsw-alias-label-primary,inherit);cursor:pointer;user-select:none;align-items:center;gap:7px;font-size:12px;display:flex}.Sv3uVW_rememberRow input[type=checkbox]{width:14px;height:14px;accent-color:var(--dsw-alias-button-info-fill,#3b82f6);flex:none;margin:0}.Sv3uVW_rememberHint{color:var(--dsw-alias-label-caption,#8080808c);font-size:11px}.Sv3uVW_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;height:34px;color:var(--dsw-alias-label-primary,inherit);font:inherit;border-radius:8px;padding:0 10px;font-size:13px;transition:border-color .15s ease-out,box-shadow .15s ease-out}.Sv3uVW_input::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_input:focus,.Sv3uVW_input:focus-visible,.Sv3uVW_sqlInput:focus,.Sv3uVW_sqlInput:focus-visible{border-color:var(--dsw-alias-button-info-fill,#3b82f6);box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 18%, transparent);outline:none}.Sv3uVW_input:disabled{opacity:.58}select.Sv3uVW_input{appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' fill='none' stroke='%23777' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 10px center;background-repeat:no-repeat;padding-right:28px}.Sv3uVW_actions{justify-content:flex-end;align-items:center;gap:8px;margin-top:auto;padding-top:4px;display:flex}.Sv3uVW_primary,.Sv3uVW_ghost{min-width:96px;height:34px;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;justify-content:center;align-items:center;gap:6px;padding:0 15px;font-size:13px;font-weight:500;transition:background-color .15s ease-out,border-color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_primary{background:var(--dsw-alias-button-info-fill,#3b82f6);color:#fff}.Sv3uVW_primary:hover:not(:disabled){background:var(--dsw-alias-button-info-hover,#3573e0)}.Sv3uVW_ghost{border-color:var(--dsw-alias-border-l2,#80808059);color:var(--dsw-alias-label-primary,inherit);background:0 0}.Sv3uVW_ghost:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_primary:focus-visible,.Sv3uVW_ghost:focus-visible,.Sv3uVW_treeItem:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 24%, transparent);outline:none}.Sv3uVW_primary:disabled,.Sv3uVW_ghost:disabled{opacity:.45;cursor:default}.Sv3uVW_schemaPanel{grid-template-columns:minmax(260px,.9fr) minmax(320px,1.1fr);gap:20px;height:min(470px,56vh);display:grid}.Sv3uVW_modalCol{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex}.Sv3uVW_modalColTitle{color:var(--dsw-alias-label-tertiary,#808080b3);letter-spacing:.06em;text-transform:uppercase;flex:none;align-items:center;gap:6px;font-size:11px;font-weight:600;display:flex}.Sv3uVW_colCount,.Sv3uVW_treeCount{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:999px;flex:none;padding:1px 7px;font-size:10px;font-weight:500}.Sv3uVW_treeScroll{flex:1;min-height:0;padding-right:4px;overflow-y:auto}.Sv3uVW_tree{flex-direction:column;gap:1px;margin:0;padding:0;list-style:none;display:flex}.Sv3uVW_treeNode,.Sv3uVW_treeChildren{flex-direction:column;gap:1px;display:flex}.Sv3uVW_treeItem{width:100%;min-height:30px;color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:7px;align-items:center;gap:6px;padding:0 8px;font-size:12.5px;display:flex}.Sv3uVW_treeItem:hover{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_treeItem.Sv3uVW_active,.Sv3uVW_treeItem.Sv3uVW_active:hover{background:var(--dsw-alias-interactive-bg-active,#3b82f62e)}.Sv3uVW_treeChevron{color:var(--dsw-alias-label-tertiary,#80808099);flex:none;transition:transform .15s ease-out}.Sv3uVW_treeChevron.Sv3uVW_open{transform:rotate(90deg)}.Sv3uVW_treeIcon{color:var(--dsw-alias-label-secondary,#808080cc);flex:none}.Sv3uVW_treeItem.Sv3uVW_active .Sv3uVW_treeIcon{color:var(--dsw-alias-button-info-fill,#3b82f6)}.Sv3uVW_treeName{min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;overflow:hidden}.Sv3uVW_treeChildren{border-left:1px solid var(--dsw-alias-border-l2,#80808059);max-height:154px;margin-left:12px;padding-left:10px;overflow-y:auto}.Sv3uVW_hint{color:var(--dsw-alias-label-tertiary,#80808099);font-size:12px}.Sv3uVW_modalHint{color:var(--dsw-alias-label-caption,#80808080);flex:none;margin-top:2px;font-size:11.5px}.Sv3uVW_colScroll{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:8px;flex:1;min-height:0;overflow:auto}.Sv3uVW_columnsTable{border-collapse:collapse;width:100%;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:12px}.Sv3uVW_columnsTable th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);color:var(--dsw-alias-label-tertiary,#808080b3);letter-spacing:.05em;text-align:left;text-transform:uppercase;padding:7px 10px;font-size:10.5px;font-weight:600;position:sticky;top:0}.Sv3uVW_columnsTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);padding:6px 10px}.Sv3uVW_columnsTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_typeCell{color:var(--dsw-alias-label-secondary,#808080cc)}.Sv3uVW_nullCell{color:var(--dsw-alias-label-caption,#80808080);font-size:11px}.Sv3uVW_emptyState{border:1px dashed var(--dsw-alias-border-l2,#80808059);min-height:0;color:var(--dsw-alias-label-tertiary,#808080b3);border-radius:8px;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.Sv3uVW_emptyStateIcon{width:20px;height:20px;color:var(--dsw-alias-label-dimmed,#80808066)}.Sv3uVW_emptyStateText{font-size:12px}.Sv3uVW_sqlPanel{min-height:430px}.Sv3uVW_sqlInput{box-sizing:border-box;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);width:100%;min-height:210px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);border-radius:10px;padding:12px;font-size:12.5px;line-height:1.6}.Sv3uVW_sqlInput::placeholder{color:var(--dsw-alias-label-caption,#80808080)}.Sv3uVW_sqlActions{justify-content:flex-end;align-items:center;gap:10px;display:flex}.Sv3uVW_shortcutHint{color:var(--dsw-alias-label-caption,#80808080);font-size:11.5px}.Sv3uVW_sqlResult{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);min-height:100px;max-height:220px;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);white-space:pre-wrap;word-break:break-word;border-radius:8px;flex:1;margin:0;padding:11px 12px;font-size:11.5px;line-height:1.55;overflow-y:auto}.Sv3uVW_errorBar{border:1px solid var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);border-radius:10px;flex-direction:column;gap:3px;padding:10px 12px;display:flex}.Sv3uVW_errorHead{color:var(--dsw-alias-state-error-primary,#ef4444);align-items:center;gap:6px;font-size:12px;font-weight:600;display:flex}.Sv3uVW_errorIcon{flex:none}.Sv3uVW_errorText{white-space:pre-wrap;word-break:break-word;font-size:12px}@media (width<=640px){.Sv3uVW_triggerSlot{top:-42px;right:10px}.Sv3uVW_workbenchModal{width:min(96vw,920px)}.Sv3uVW_workbenchModalContent{min-height:0;max-height:72vh}.Sv3uVW_workbench{min-height:0}.Sv3uVW_fieldRow2{grid-template-columns:1fr}.Sv3uVW_schemaPanel{flex-direction:column;height:auto;display:flex}.Sv3uVW_treeScroll{flex:none;height:240px}.Sv3uVW_colScroll{flex:none;height:220px}.Sv3uVW_emptyState{flex:none;min-height:120px}.Sv3uVW_rememberRow{flex-wrap:wrap;align-items:flex-start}.Sv3uVW_rememberHint{flex-basis:100%;padding-left:21px}}@media (prefers-reduced-motion:reduce){.Sv3uVW_trigger,.Sv3uVW_input,.Sv3uVW_primary,.Sv3uVW_ghost,.Sv3uVW_treeChevron{transition:none}}";
94
97
  const tagId$1 = "@yejiming/dsh-data-agent/DataAgentWorkbench.module.css";
95
98
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
96
99
  const tag = document.createElement("style");
@@ -100,104 +103,78 @@ window.__ModuleLoader__.load({
100
103
  document.head.appendChild(tag);
101
104
  }
102
105
  var DataAgentWorkbench_module_css_default = {
103
- "treeChevron": "Sv3uVW_treeChevron",
104
- "modalBody": "Sv3uVW_modalBody",
105
- "sections": "Sv3uVW_sections",
106
- "sqlActions": "Sv3uVW_sqlActions",
107
- "schemaModal": "Sv3uVW_schemaModal",
108
- "tree": "Sv3uVW_tree",
109
- "heroText": "Sv3uVW_heroText",
106
+ "triggerActive": "Sv3uVW_triggerActive",
107
+ "tab": "Sv3uVW_tab",
108
+ "modalColTitle": "Sv3uVW_modalColTitle",
109
+ "triggerDot": "Sv3uVW_triggerDot",
110
+ "sqlPanel": "Sv3uVW_sqlPanel",
111
+ "errorText": "Sv3uVW_errorText",
112
+ "connectionState": "Sv3uVW_connectionState",
113
+ "modalCol": "Sv3uVW_modalCol",
114
+ "treeItem": "Sv3uVW_treeItem",
115
+ "input": "Sv3uVW_input",
116
+ "summaryType": "Sv3uVW_summaryType",
110
117
  "typeCell": "Sv3uVW_typeCell",
111
- "browseRow": "Sv3uVW_browseRow",
112
- "label": "Sv3uVW_label",
113
- "browseChevron": "Sv3uVW_browseChevron",
114
- "sqlInput": "Sv3uVW_sqlInput",
115
- "shortcutHint": "Sv3uVW_shortcutHint",
116
- "summaryDb": "Sv3uVW_summaryDb",
117
- "treeCount": "Sv3uVW_treeCount",
118
+ "workbench": "Sv3uVW_workbench",
118
119
  "treeChildren": "Sv3uVW_treeChildren",
119
- "active": "Sv3uVW_active",
120
+ "treeName": "Sv3uVW_treeName",
120
121
  "nullCell": "Sv3uVW_nullCell",
121
- "colCount": "Sv3uVW_colCount",
122
- "hint": "Sv3uVW_hint",
123
- "heroIcon": "Sv3uVW_heroIcon",
122
+ "treeNode": "Sv3uVW_treeNode",
123
+ "shortcutHint": "Sv3uVW_shortcutHint",
124
+ "active": "Sv3uVW_active",
125
+ "tabPanel": "Sv3uVW_tabPanel",
126
+ "sqlResult": "Sv3uVW_sqlResult",
127
+ "columnsTable": "Sv3uVW_columnsTable",
128
+ "errorIcon": "Sv3uVW_errorIcon",
129
+ "sqlActions": "Sv3uVW_sqlActions",
130
+ "errorHead": "Sv3uVW_errorHead",
131
+ "emptyStateIcon": "Sv3uVW_emptyStateIcon",
132
+ "treeChevron": "Sv3uVW_treeChevron",
133
+ "primary": "Sv3uVW_primary",
134
+ "connectionSummary": "Sv3uVW_connectionSummary",
135
+ "trigger": "Sv3uVW_trigger",
124
136
  "modalHint": "Sv3uVW_modalHint",
125
- "strip": "Sv3uVW_strip",
126
- "treeScroll": "Sv3uVW_treeScroll",
137
+ "fieldRow2": "Sv3uVW_fieldRow2",
138
+ "tree": "Sv3uVW_tree",
139
+ "errorBar": "Sv3uVW_errorBar",
140
+ "tabActive": "Sv3uVW_tabActive",
141
+ "treeCount": "Sv3uVW_treeCount",
142
+ "rememberHint": "Sv3uVW_rememberHint",
143
+ "workbenchModalContent": "Sv3uVW_workbenchModalContent",
127
144
  "emptyStateText": "Sv3uVW_emptyStateText",
128
- "rail": "Sv3uVW_rail",
129
- "input": "Sv3uVW_input",
130
- "treeItem": "Sv3uVW_treeItem",
131
- "treeIcon": "Sv3uVW_treeIcon",
132
- "treeName": "Sv3uVW_treeName",
133
- "heroConnect": "Sv3uVW_heroConnect",
134
- "modalCol": "Sv3uVW_modalCol",
145
+ "summaryDb": "Sv3uVW_summaryDb",
146
+ "label": "Sv3uVW_label",
147
+ "sqlInput": "Sv3uVW_sqlInput",
135
148
  "ghost": "Sv3uVW_ghost",
136
- "errorIcon": "Sv3uVW_errorIcon",
137
- "da-split": "Sv3uVW_da-split",
138
- "small": "Sv3uVW_small",
139
- "statusOk": "Sv3uVW_statusOk",
140
- "docked": "Sv3uVW_docked",
141
- "cardTitle": "Sv3uVW_cardTitle",
142
- "titleIcon": "Sv3uVW_titleIcon",
143
- "connectModal": "Sv3uVW_connectModal",
144
- "heroHint": "Sv3uVW_heroHint",
145
- "summaryRow": "Sv3uVW_summaryRow",
146
- "rememberRow": "Sv3uVW_rememberRow",
147
- "errorBar": "Sv3uVW_errorBar",
148
- "treeNode": "Sv3uVW_treeNode",
149
+ "tabs": "Sv3uVW_tabs",
149
150
  "actions": "Sv3uVW_actions",
150
- "fieldGrid": "Sv3uVW_fieldGrid",
151
- "sqlResult": "Sv3uVW_sqlResult",
152
- "open": "Sv3uVW_open",
153
151
  "colScroll": "Sv3uVW_colScroll",
154
- "modalColTitle": "Sv3uVW_modalColTitle",
155
- "summaryType": "Sv3uVW_summaryType",
156
- "fieldRow2": "Sv3uVW_fieldRow2",
157
- "emptyStateIcon": "Sv3uVW_emptyStateIcon",
158
- "errorText": "Sv3uVW_errorText",
159
- "heroChevron": "Sv3uVW_heroChevron",
160
- "card": "Sv3uVW_card",
161
- "workbench": "Sv3uVW_workbench",
162
- "primary": "Sv3uVW_primary",
152
+ "hint": "Sv3uVW_hint",
153
+ "workbenchModal": "Sv3uVW_workbenchModal",
163
154
  "field": "Sv3uVW_field",
155
+ "rememberRow": "Sv3uVW_rememberRow",
156
+ "schemaPanel": "Sv3uVW_schemaPanel",
157
+ "treeScroll": "Sv3uVW_treeScroll",
164
158
  "emptyState": "Sv3uVW_emptyState",
165
- "errorHead": "Sv3uVW_errorHead",
166
- "connectModalBody": "Sv3uVW_connectModalBody",
167
- "rememberHint": "Sv3uVW_rememberHint",
168
- "summaryActions": "Sv3uVW_summaryActions",
169
- "heroTitle": "Sv3uVW_heroTitle",
170
- "browseIcon": "Sv3uVW_browseIcon",
171
- "columnsTable": "Sv3uVW_columnsTable"
159
+ "fieldGrid": "Sv3uVW_fieldGrid",
160
+ "open": "Sv3uVW_open",
161
+ "triggerSlot": "Sv3uVW_triggerSlot",
162
+ "colCount": "Sv3uVW_colCount",
163
+ "treeIcon": "Sv3uVW_treeIcon"
172
164
  };
173
165
  //#endregion
174
166
  //#region src/client/DataAgentWorkbench.tsx
175
167
  /**
176
- * The database workbench: connection config (collapsible after connect),
177
- * a browse button that opens the schema explorer Modal, and the SQL command
178
- * box, rendered into the composer input dock (the strip ABOVE the input bar)
179
- * for data-agent sessions.
180
- *
181
- * Layout is phase-driven by the conversation root's `data-phase` attribute:
182
- * - hero (blank session): the workbench is a full-width stacked strip above
183
- * the input bar (which stays at the bottom);
184
- * - active (conversation started): the workbench becomes a fixed left rail
185
- * (measured from the conversation column), the chat records and the input
186
- * bar shift right via the `da-split` CSS rules; if measurement is
187
- * unavailable the workbench falls back to a docked bottom panel.
168
+ * The database workbench entry for data-agent sessions.
188
169
  *
189
- * Interaction model:
190
- * - after a successful connect the connection form collapses into a summary
191
- * row (click 连接配置 to expand the readonly form again);
192
- * - the schema explorer lives in a Modal (ui-primitives) opened by the
193
- * 库表 button; a single click on a database toggles its table list in a
194
- * file-explorer style tree (folder rows with chevrons, indented table rows
195
- * with guide lines, the whole tree scrolls inside the column);
196
- * - clicking a table loads its columns into the Modal's structure panel.
170
+ * Only a compact database button remains mounted from the composer slot and
171
+ * is visually lifted into the context row above the composer card.
172
+ * Clicking it opens one Modal containing connection settings, the schema
173
+ * explorer, and SQL runner as three tabs. Hero and active conversations share
174
+ * this exact surface; the plugin never measures or shifts host layout.
197
175
  *
198
- * Non-data-agent sessions render null zero impact on ordinary sessions.
199
- * Connection state lives on the server (the dataAgentConnections store), so
200
- * remounts never lose it — this component mirrors `/status` on mount.
176
+ * Non-data-agent sessions render null before any effect or request runs.
177
+ * Connection state lives on the server and is mirrored from `/status`.
201
178
  */
202
179
  /** The plugin's preset id, matching the installed agent preset directory. */
203
180
  const DATA_AGENT_PRESET = "data-agent";
@@ -364,15 +341,6 @@ window.__ModuleLoader__.load({
364
341
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M3.4 2.1C3.4 1.66 3.88 1.4 4.26 1.62L9.9 5.02C10.26 5.23 10.26 5.77 9.9 5.98L4.26 9.38C3.88 9.6 3.4 9.34 3.4 8.9V2.1Z" })
365
342
  });
366
343
  }
367
- /** The conversation column's phase attribute value while the session is blank. */
368
- function isHeroPhase(element) {
369
- return element?.getAttribute("data-phase") === "hero";
370
- }
371
- /**
372
- * 开始对话后(active 布局)左栏工作台相对会话列顶部的下移偏移(px):
373
- * 让工作台避开会话头部区域、整体往下沉一些,顶部露出对话记录。
374
- */
375
- const RAIL_TOP_OFFSET = 96;
376
344
  /** Default port per type (used to fill the form from a saved connection). */
377
345
  function defaultPortOf(type) {
378
346
  switch (type) {
@@ -426,12 +394,22 @@ window.__ModuleLoader__.load({
426
394
  else if (saved.password !== void 0 && saved.password !== "") body.password = saved.password;
427
395
  return body;
428
396
  }
397
+ /** Whether localStorage contains enough information for a safe automatic retry. */
398
+ function canAutoReconnect(saved) {
399
+ if (saved.type === "sqlite" || saved.credentialMode === "none") return true;
400
+ if (saved.passwordRef !== void 0 && saved.passwordRef !== "") return true;
401
+ return saved.persistPassword === true && saved.password !== void 0 && saved.password !== "";
402
+ }
403
+ /** Avoid replaying the last browser credential into a different server-side profile. */
404
+ function savedMatchesSummary(saved, summary) {
405
+ if (saved.type !== summary.type || saved.database !== summary.database) return false;
406
+ if (saved.type === "sqlite") return true;
407
+ return (saved.host ?? "") === (summary.host ?? "") && (saved.port ?? void 0) === (summary.port ?? void 0) && (saved.user ?? "") === (summary.user ?? "");
408
+ }
429
409
  /** The database workbench body. */
430
410
  function DataAgentWorkbench({ sessionId, useSessions, t }) {
431
411
  const isDataAgent = useSessions((snapshot) => snapshot).byId[sessionId]?.agentPreset === DATA_AGENT_PRESET;
432
- const rootRef = (0, react.useRef)(null);
433
- const [phase, setPhase] = (0, react.useState)("hero");
434
- const [railRect, setRailRect] = (0, react.useState)(null);
412
+ const tabsId = (0, react.useId)();
435
413
  const [initialSaved] = (0, react.useState)(loadConnection);
436
414
  const [type, setType] = (0, react.useState)(initialSaved?.type ?? "mysql");
437
415
  const [host, setHost] = (0, react.useState)(initialSaved?.host ?? "127.0.0.1");
@@ -447,10 +425,13 @@ window.__ModuleLoader__.load({
447
425
  const [busy, setBusy] = (0, react.useState)(false);
448
426
  const [error, setError] = (0, react.useState)(null);
449
427
  const [connected, setConnected] = (0, react.useState)(false);
450
- const [connectModalOpen, setConnectModalOpen] = (0, react.useState)(false);
428
+ const [reconnectRequired, setReconnectRequired] = (0, react.useState)(false);
429
+ const [workbenchOpen, setWorkbenchOpen] = (0, react.useState)(false);
430
+ const [activeTab, setActiveTab] = (0, react.useState)("connection");
451
431
  const [restoring, setRestoring] = (0, react.useState)(false);
452
- const [schemaModalOpen, setSchemaModalOpen] = (0, react.useState)(false);
453
432
  const [schemas, setSchemas] = (0, react.useState)([]);
433
+ const schemasLoaded = (0, react.useRef)(false);
434
+ const [schemaBusy, setSchemaBusy] = (0, react.useState)(false);
454
435
  const [activeSchema, setActiveSchema] = (0, react.useState)(null);
455
436
  const [tables, setTables] = (0, react.useState)([]);
456
437
  const [activeTable, setActiveTable] = (0, react.useState)(null);
@@ -458,67 +439,10 @@ window.__ModuleLoader__.load({
458
439
  const [sql, setSql] = (0, react.useState)("");
459
440
  const [sqlBusy, setSqlBusy] = (0, react.useState)(false);
460
441
  const [sqlResult, setSqlResult] = (0, react.useState)(null);
461
- (0, react.useLayoutEffect)(() => {
462
- let column = rootRef.current?.closest("[data-phase]") ?? null;
463
- const refreshPhase = () => {
464
- if (column !== null) setPhase((prev) => {
465
- const next = isHeroPhase(column) ? "hero" : "active";
466
- return next === prev ? prev : next;
467
- });
468
- };
469
- const measure = () => {
470
- if (column !== null) {
471
- const rect = column.getBoundingClientRect();
472
- const bottom = window.innerHeight - rect.bottom;
473
- setRailRect((prev) => prev !== null && prev.left === rect.left && prev.top === rect.top && prev.bottom === bottom ? prev : {
474
- left: rect.left,
475
- top: rect.top,
476
- bottom
477
- });
478
- }
479
- };
480
- const observer = new MutationObserver(refreshPhase);
481
- const resizer = new ResizeObserver(measure);
482
- const sync = () => {
483
- const next = rootRef.current?.closest("[data-phase]") ?? null;
484
- if (next !== null) {
485
- if (next !== column) {
486
- observer.disconnect();
487
- resizer.disconnect();
488
- column = next;
489
- observer.observe(column, {
490
- attributes: true,
491
- attributeFilter: ["data-phase"]
492
- });
493
- resizer.observe(column);
494
- }
495
- refreshPhase();
496
- measure();
497
- }
498
- };
499
- sync();
500
- window.addEventListener("resize", measure);
501
- const poll = window.setInterval(sync, 1e3);
502
- return () => {
503
- window.clearInterval(poll);
504
- if (column !== null) resizer.unobserve(column);
505
- observer.disconnect();
506
- resizer.disconnect();
507
- window.removeEventListener("resize", measure);
508
- };
509
- }, [isDataAgent]);
510
- const split = phase === "active" && railRect !== null;
511
- (0, react.useLayoutEffect)(() => {
512
- const root = document.documentElement;
513
- const splitClass = DataAgentWorkbench_module_css_default["da-split"];
514
- if (split && splitClass !== void 0) root.classList.add(splitClass);
515
- else if (splitClass !== void 0) root.classList.remove(splitClass);
516
- return () => {
517
- if (splitClass !== void 0) root.classList.remove(splitClass);
518
- };
519
- }, [split]);
442
+ const triggerSlotRef = (0, react.useRef)(null);
520
443
  const firstDraftRun = (0, react.useRef)(true);
521
444
  (0, react.useEffect)(() => {
445
+ if (!isDataAgent) return;
522
446
  if (firstDraftRun.current) {
523
447
  firstDraftRun.current = false;
524
448
  return;
@@ -539,6 +463,7 @@ window.__ModuleLoader__.load({
539
463
  savedAt: (/* @__PURE__ */ new Date()).toISOString()
540
464
  });
541
465
  }, [
466
+ isDataAgent,
542
467
  type,
543
468
  host,
544
469
  port,
@@ -551,40 +476,43 @@ window.__ModuleLoader__.load({
551
476
  readonly
552
477
  ]);
553
478
  (0, react.useEffect)(() => {
479
+ if (!isDataAgent) return;
554
480
  let cancelled = false;
555
481
  const controller = new AbortController();
556
482
  const saved = initialSaved;
557
483
  setBusy(true);
558
484
  fetch(`/plugins/data-agent/status?sessionId=${encodeURIComponent(sessionId)}`, { signal: controller.signal }).then((response) => parseJsonResponse(response)).then(async (body) => {
559
485
  if (cancelled) return;
560
- if (body.connected) {
561
- setConnected(true);
562
- if (body.summary !== void 0) {
563
- setType(body.summary.type);
564
- setHost(body.summary.host ?? "");
565
- setPort(body.summary.port !== void 0 ? String(body.summary.port) : "");
566
- setUser(body.summary.user ?? "");
567
- setDatabase(body.summary.database);
568
- setReadonly(body.summary.readonly === true);
569
- setPasswordRef(body.summary.passwordRef ?? "");
570
- if (body.summary.passwordRef !== void 0) setCredentialMode("reference");
571
- setCredentialStatus(body.summary.credential);
486
+ const summary = body.summary;
487
+ const matchesSaved = saved !== null && summary !== void 0 && savedMatchesSummary(saved, summary);
488
+ if (summary !== void 0) {
489
+ setType(summary.type);
490
+ setHost(summary.host ?? "");
491
+ setPort(summary.port !== void 0 ? String(summary.port) : "");
492
+ setUser(summary.user ?? "");
493
+ setDatabase(summary.database);
494
+ setReadonly(summary.readonly === true);
495
+ setPasswordRef(summary.passwordRef ?? "");
496
+ setCredentialMode(summary.credentialMode === "reference" || summary.passwordRef !== void 0 ? "reference" : "password");
497
+ setCredentialStatus(summary.credential);
498
+ if (!matchesSaved) {
499
+ setPassword("");
500
+ setRememberPassword(false);
572
501
  }
573
- const schemasBody = await parseJsonResponse(await fetch(`/plugins/data-agent/schemas?sessionId=${encodeURIComponent(sessionId)}`, { signal: controller.signal }));
574
- if (!cancelled && schemasBody.ok) setSchemas(schemasBody.schemas ?? []);
575
- return;
576
502
  }
577
- if (saved !== null && saved.database !== "") {
503
+ setConnected(body.connected);
504
+ setReconnectRequired(body.reconnectRequired === true);
505
+ if (body.connected) return;
506
+ const referenceUnavailable = summary?.credentialMode === "reference" && summary.credential?.configured === false;
507
+ if (saved !== null && saved.database !== "" && canAutoReconnect(saved) && (summary === void 0 || matchesSaved) && !referenceUnavailable) {
578
508
  setRestoring(true);
579
509
  try {
580
510
  const result = await performConnect(sessionId, payloadFromSaved(saved), controller.signal);
581
511
  if (cancelled) return;
582
512
  if (result.ok) {
583
513
  setConnected(true);
514
+ setReconnectRequired(false);
584
515
  setCredentialStatus(result.summary?.credential);
585
- setConnectModalOpen(false);
586
- const schemasBody = await parseJsonResponse(await fetch(`/plugins/data-agent/schemas?sessionId=${encodeURIComponent(sessionId)}`, { signal: controller.signal }));
587
- if (!cancelled && schemasBody.ok) setSchemas(schemasBody.schemas ?? []);
588
516
  } else setError(`连接恢复失败:${result.error ?? "unknown error"}`);
589
517
  } catch (cause) {
590
518
  if (!cancelled) setError(`连接恢复失败:${cause instanceof Error ? cause.message : String(cause)}`);
@@ -599,8 +527,29 @@ window.__ModuleLoader__.load({
599
527
  cancelled = true;
600
528
  controller.abort();
601
529
  };
602
- }, [initialSaved, sessionId]);
530
+ }, [
531
+ initialSaved,
532
+ isDataAgent,
533
+ sessionId
534
+ ]);
603
535
  const sqlite = type === "sqlite";
536
+ /** Load schemas on first entry to the schema tab; cache successful empty results too. */
537
+ const loadSchemas = async (force = false) => {
538
+ if (schemaBusy || schemasLoaded.current && !force) return;
539
+ setSchemaBusy(true);
540
+ setError(null);
541
+ try {
542
+ const result = await parseJsonResponse(await fetch(`/plugins/data-agent/schemas?sessionId=${encodeURIComponent(sessionId)}`));
543
+ if (result.ok) {
544
+ setSchemas(result.schemas ?? []);
545
+ schemasLoaded.current = true;
546
+ } else setError(result.error ?? "unknown error");
547
+ } catch (cause) {
548
+ setError(cause instanceof Error ? cause.message : String(cause));
549
+ } finally {
550
+ setSchemaBusy(false);
551
+ }
552
+ };
604
553
  const connect = async () => {
605
554
  setBusy(true);
606
555
  setError(null);
@@ -623,10 +572,21 @@ window.__ModuleLoader__.load({
623
572
  const result = await performConnect(sessionId, body);
624
573
  if (result.ok) {
625
574
  setConnected(true);
575
+ setReconnectRequired(false);
626
576
  setCredentialStatus(result.summary?.credential);
627
- setConnectModalOpen(false);
628
- const schemasBody = await parseJsonResponse(await fetch(`/plugins/data-agent/schemas?sessionId=${encodeURIComponent(sessionId)}`));
629
- if (schemasBody.ok) setSchemas(schemasBody.schemas ?? []);
577
+ if (result.summary?.credentialMode === "none" && !sqlite) saveConnection({
578
+ type,
579
+ host,
580
+ ...port !== "" ? { port: Number(port) } : {},
581
+ user,
582
+ database,
583
+ readonly,
584
+ credentialMode: "none",
585
+ savedAt: (/* @__PURE__ */ new Date()).toISOString()
586
+ });
587
+ setActiveTab("schema");
588
+ schemasLoaded.current = false;
589
+ await loadSchemas(true);
630
590
  } else setError(result.error ?? "unknown error");
631
591
  } catch (cause) {
632
592
  setError(cause instanceof Error ? cause.message : String(cause));
@@ -644,10 +604,12 @@ window.__ModuleLoader__.load({
644
604
  body: JSON.stringify({ sessionId })
645
605
  }));
646
606
  setConnected(false);
607
+ setReconnectRequired(false);
647
608
  setCredentialStatus(void 0);
648
609
  setReadonly(false);
649
- setSchemaModalOpen(false);
610
+ setActiveTab("connection");
650
611
  setSchemas([]);
612
+ schemasLoaded.current = false;
651
613
  setActiveSchema(null);
652
614
  setTables([]);
653
615
  setActiveTable(null);
@@ -723,168 +685,354 @@ window.__ModuleLoader__.load({
723
685
  setSqlBusy(false);
724
686
  }
725
687
  };
688
+ const composerPlaceholder = connected ? t("composer.placeholder.connected") : reconnectRequired ? t("composer.placeholder.reconnectRequired") : t("composer.placeholder.disconnected");
689
+ (0, react.useLayoutEffect)(() => {
690
+ if (!isDataAgent) return;
691
+ const textarea = (triggerSlotRef.current?.closest("[data-composer-card]"))?.querySelector("textarea");
692
+ if (textarea === void 0 || textarea === null || textarea.disabled) return;
693
+ const hostPlaceholder = textarea.getAttribute("placeholder");
694
+ textarea.setAttribute("placeholder", composerPlaceholder);
695
+ return () => {
696
+ if (textarea.getAttribute("placeholder") !== composerPlaceholder) return;
697
+ if (hostPlaceholder === null) textarea.removeAttribute("placeholder");
698
+ else textarea.setAttribute("placeholder", hostPlaceholder);
699
+ };
700
+ });
726
701
  if (!isDataAgent) return null;
727
702
  const databaseLabel = sqlite ? t("form.database.sqlite") : type === "oracle" ? t("form.database.oracle") : type === "hive" || type === "impala" ? t("form.database.hive") : t("form.database");
728
- const railStyle = split ? {
729
- position: "fixed",
730
- left: railRect.left,
731
- top: railRect.top + RAIL_TOP_OFFSET,
732
- bottom: railRect.bottom,
733
- width: 380
734
- } : void 0;
735
703
  const formDisabled = busy || connected;
736
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
737
- ref: rootRef,
738
- className: `${DataAgentWorkbench_module_css_default.workbench} ${split ? DataAgentWorkbench_module_css_default.rail : phase === "active" ? DataAgentWorkbench_module_css_default.docked : DataAgentWorkbench_module_css_default.strip}`,
739
- style: railStyle,
740
- children: [
741
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
742
- className: DataAgentWorkbench_module_css_default.sections,
743
- children: [
744
- connected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
745
- className: DataAgentWorkbench_module_css_default.card,
746
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
747
- className: DataAgentWorkbench_module_css_default.summaryRow,
748
- children: [
749
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
750
- state: "done",
751
- size: 8,
752
- className: DataAgentWorkbench_module_css_default.dot
753
- }),
754
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
755
- className: DataAgentWorkbench_module_css_default.statusOk,
756
- children: t("state.connected")
757
- }),
758
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
759
- className: DataAgentWorkbench_module_css_default.summaryType,
760
- children: t(`type.${type}`)
761
- }),
762
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
763
- className: DataAgentWorkbench_module_css_default.summaryDb,
764
- title: database,
765
- children: database
766
- }),
767
- credentialStatus !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
768
- className: DataAgentWorkbench_module_css_default.summaryType,
769
- title: credentialStatus.source,
770
- children: credentialStatus.configured ? t("credential.configured") : t("credential.unconfigured")
771
- }),
772
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
773
- className: DataAgentWorkbench_module_css_default.summaryActions,
774
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
775
- type: "button",
776
- className: `${DataAgentWorkbench_module_css_default.ghost} ${DataAgentWorkbench_module_css_default.small}`,
777
- onClick: () => setConnectModalOpen(true),
778
- children: t("action.config")
779
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
780
- type: "button",
781
- className: `${DataAgentWorkbench_module_css_default.ghost} ${DataAgentWorkbench_module_css_default.small}`,
782
- disabled: busy,
783
- onClick: () => {
784
- disconnect();
785
- },
786
- children: t("action.disconnect")
787
- })]
788
- })
789
- ]
790
- })
791
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
792
- className: DataAgentWorkbench_module_css_default.card,
793
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
704
+ const triggerState = error !== null ? "error" : busy || restoring ? "ongoing" : connected ? "done" : "warning";
705
+ const triggerLabel = error !== null ? t("workbench.open.error") : busy || restoring ? t("workbench.open.checking") : connected ? t("workbench.open.connected") : reconnectRequired ? t("workbench.open.reconnectRequired") : t("workbench.open.disconnected");
706
+ const tabs = [
707
+ {
708
+ id: "connection",
709
+ label: t("action.config"),
710
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DatabaseIcon, {})
711
+ },
712
+ {
713
+ id: "schema",
714
+ label: t("action.browse"),
715
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableIcon, {})
716
+ },
717
+ {
718
+ id: "sql",
719
+ label: t("wb.sql"),
720
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TerminalIcon, {})
721
+ }
722
+ ];
723
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
724
+ ref: triggerSlotRef,
725
+ className: DataAgentWorkbench_module_css_default.triggerSlot,
726
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
727
+ label: triggerLabel,
728
+ side: "top",
729
+ delayMs: 400,
730
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
731
+ type: "button",
732
+ className: `${DataAgentWorkbench_module_css_default.trigger}${workbenchOpen ? ` ${DataAgentWorkbench_module_css_default.triggerActive}` : ""}`,
733
+ "aria-label": triggerLabel,
734
+ "aria-haspopup": "dialog",
735
+ "aria-expanded": workbenchOpen,
736
+ onClick: () => setWorkbenchOpen(true),
737
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDataOutline16, { size: 17 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
738
+ state: triggerState,
739
+ size: 7,
740
+ className: DataAgentWorkbench_module_css_default.triggerDot
741
+ })]
742
+ })
743
+ })
744
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
745
+ open: workbenchOpen,
746
+ onClose: () => setWorkbenchOpen(false),
747
+ title: t("wb.workbench.title"),
748
+ description: t("wb.workbench.description"),
749
+ closeLabel: t("action.close"),
750
+ className: DataAgentWorkbench_module_css_default.workbenchModal,
751
+ contentClassName: DataAgentWorkbench_module_css_default.workbenchModalContent,
752
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
753
+ className: DataAgentWorkbench_module_css_default.workbench,
754
+ children: [
755
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
756
+ className: DataAgentWorkbench_module_css_default.connectionSummary,
757
+ role: "status",
758
+ children: [
759
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
760
+ state: triggerState,
761
+ size: 8
762
+ }),
763
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
764
+ className: DataAgentWorkbench_module_css_default.connectionState,
765
+ children: error !== null ? t("error.title") : restoring ? t("state.reconnecting") : busy ? t("state.checking") : connected ? t("state.connected") : reconnectRequired ? t("state.reconnectRequired") : t("state.disconnected")
766
+ }),
767
+ (connected || reconnectRequired) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
768
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
769
+ className: DataAgentWorkbench_module_css_default.summaryType,
770
+ children: t(`type.${type}`)
771
+ }),
772
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
773
+ className: DataAgentWorkbench_module_css_default.summaryDb,
774
+ title: database,
775
+ children: database
776
+ }),
777
+ credentialStatus !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
778
+ className: DataAgentWorkbench_module_css_default.summaryType,
779
+ title: credentialStatus.source,
780
+ children: credentialStatus.configured ? t("credential.configured") : t("credential.unconfigured")
781
+ })
782
+ ] })
783
+ ]
784
+ }),
785
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
786
+ className: DataAgentWorkbench_module_css_default.tabs,
787
+ role: "tablist",
788
+ "aria-label": t("wb.workbench.tabs"),
789
+ children: tabs.map((tab) => {
790
+ const disabled = tab.id !== "connection" && !connected;
791
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
792
+ id: `${tabsId}-${tab.id}-tab`,
794
793
  type: "button",
795
- className: DataAgentWorkbench_module_css_default.heroConnect,
796
- onClick: () => setConnectModalOpen(true),
797
- children: [
798
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DatabaseIcon, { className: DataAgentWorkbench_module_css_default.heroIcon }),
799
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
800
- className: DataAgentWorkbench_module_css_default.heroText,
794
+ role: "tab",
795
+ className: `${DataAgentWorkbench_module_css_default.tab}${activeTab === tab.id ? ` ${DataAgentWorkbench_module_css_default.tabActive}` : ""}`,
796
+ "aria-selected": activeTab === tab.id,
797
+ "aria-controls": `${tabsId}-${tab.id}-panel`,
798
+ disabled,
799
+ onClick: () => {
800
+ setActiveTab(tab.id);
801
+ if (tab.id === "schema") loadSchemas();
802
+ },
803
+ children: [tab.icon, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: tab.label })]
804
+ }, tab.id);
805
+ })
806
+ }),
807
+ activeTab === "connection" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
808
+ id: `${tabsId}-connection-panel`,
809
+ role: "tabpanel",
810
+ "aria-labelledby": `${tabsId}-connection-tab`,
811
+ className: DataAgentWorkbench_module_css_default.tabPanel,
812
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
813
+ className: DataAgentWorkbench_module_css_default.fieldGrid,
814
+ children: [
815
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
816
+ className: DataAgentWorkbench_module_css_default.field,
817
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
818
+ className: DataAgentWorkbench_module_css_default.label,
819
+ children: t("form.type")
820
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
821
+ className: DataAgentWorkbench_module_css_default.input,
822
+ value: type,
823
+ disabled: formDisabled,
824
+ onChange: (event) => {
825
+ const next = event.target.value;
826
+ setType(next);
827
+ setPort(next === "postgres" ? "5432" : next === "mysql" ? "3306" : next === "oracle" ? "1521" : next === "hive" ? "10000" : next === "impala" ? "21050" : "");
828
+ },
829
+ children: [
830
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
831
+ value: "mysql",
832
+ children: t("type.mysql")
833
+ }),
834
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
835
+ value: "postgres",
836
+ children: t("type.postgres")
837
+ }),
838
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
839
+ value: "sqlite",
840
+ children: t("type.sqlite")
841
+ }),
842
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
843
+ value: "oracle",
844
+ children: t("type.oracle")
845
+ }),
846
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
847
+ value: "hive",
848
+ children: t("type.hive")
849
+ }),
850
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
851
+ value: "impala",
852
+ children: t("type.impala")
853
+ })
854
+ ]
855
+ })]
856
+ }),
857
+ !sqlite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
858
+ className: DataAgentWorkbench_module_css_default.fieldRow2,
859
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
860
+ className: DataAgentWorkbench_module_css_default.field,
801
861
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
802
- className: DataAgentWorkbench_module_css_default.heroTitle,
803
- children: t("form.hero.title")
804
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
805
- className: DataAgentWorkbench_module_css_default.heroHint,
806
- children: t("form.hero.hint")
862
+ className: DataAgentWorkbench_module_css_default.label,
863
+ children: t("form.host")
864
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
865
+ className: DataAgentWorkbench_module_css_default.input,
866
+ type: "text",
867
+ value: host,
868
+ disabled: formDisabled,
869
+ onChange: (event) => setHost(event.target.value)
807
870
  })]
808
- }),
809
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronIcon, { className: DataAgentWorkbench_module_css_default.heroChevron })
810
- ]
811
- })
812
- }),
813
- connected && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
814
- className: DataAgentWorkbench_module_css_default.card,
815
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
816
- type: "button",
817
- className: DataAgentWorkbench_module_css_default.browseRow,
818
- onClick: () => setSchemaModalOpen(true),
819
- children: [
820
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableIcon, { className: DataAgentWorkbench_module_css_default.browseIcon }),
821
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("action.browse") }),
822
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronIcon, { className: DataAgentWorkbench_module_css_default.browseChevron })
823
- ]
824
- })
825
- }),
826
- connected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
827
- className: DataAgentWorkbench_module_css_default.card,
828
- children: [
829
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
830
- className: DataAgentWorkbench_module_css_default.cardTitle,
831
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TerminalIcon, { className: DataAgentWorkbench_module_css_default.titleIcon }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("wb.sql") })]
871
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
872
+ className: DataAgentWorkbench_module_css_default.field,
873
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
874
+ className: DataAgentWorkbench_module_css_default.label,
875
+ children: t("form.port")
876
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
877
+ className: DataAgentWorkbench_module_css_default.input,
878
+ type: "number",
879
+ min: 1,
880
+ max: 65535,
881
+ value: port,
882
+ disabled: formDisabled,
883
+ onChange: (event) => setPort(event.target.value)
884
+ })]
885
+ })]
832
886
  }),
833
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
834
- className: DataAgentWorkbench_module_css_default.sqlInput,
835
- value: sql,
836
- rows: 8,
837
- spellCheck: false,
838
- placeholder: t("wb.sql.placeholder"),
839
- onChange: (event) => setSql(event.target.value),
840
- onKeyDown: (event) => {
841
- if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
842
- event.preventDefault();
843
- runSql();
844
- }
845
- }
887
+ !sqlite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
888
+ className: DataAgentWorkbench_module_css_default.fieldRow2,
889
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
890
+ className: DataAgentWorkbench_module_css_default.field,
891
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
892
+ className: DataAgentWorkbench_module_css_default.label,
893
+ children: t("form.user")
894
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
895
+ className: DataAgentWorkbench_module_css_default.input,
896
+ type: "text",
897
+ value: user,
898
+ disabled: formDisabled,
899
+ onChange: (event) => setUser(event.target.value)
900
+ })]
901
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
902
+ className: DataAgentWorkbench_module_css_default.field,
903
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
904
+ className: DataAgentWorkbench_module_css_default.label,
905
+ children: t("form.credentialMode")
906
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
907
+ className: DataAgentWorkbench_module_css_default.input,
908
+ value: credentialMode,
909
+ disabled: formDisabled,
910
+ onChange: (event) => {
911
+ const next = event.target.value;
912
+ setCredentialMode(next);
913
+ setCredentialStatus(void 0);
914
+ },
915
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
916
+ value: "password",
917
+ children: t("form.credentialMode.password")
918
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
919
+ value: "reference",
920
+ children: t("form.credentialMode.reference")
921
+ })]
922
+ })]
923
+ })]
846
924
  }),
847
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
848
- className: DataAgentWorkbench_module_css_default.sqlActions,
925
+ !sqlite && credentialMode === "password" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
926
+ className: DataAgentWorkbench_module_css_default.field,
849
927
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
850
- className: DataAgentWorkbench_module_css_default.shortcutHint,
851
- children: t("wb.sql.shortcut")
852
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
853
- type: "button",
854
- className: DataAgentWorkbench_module_css_default.primary,
855
- disabled: sqlBusy || !connected || sql.trim() === "",
856
- onClick: () => {
857
- runSql();
858
- },
859
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlayIcon, {}), sqlBusy ? t("wb.sql.running") : t("wb.sql.run")]
928
+ className: DataAgentWorkbench_module_css_default.label,
929
+ children: t("form.password")
930
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
931
+ className: DataAgentWorkbench_module_css_default.input,
932
+ type: "password",
933
+ value: password,
934
+ autoComplete: "new-password",
935
+ disabled: formDisabled,
936
+ onChange: (event) => setPassword(event.target.value)
860
937
  })]
861
938
  }),
862
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
863
- className: DataAgentWorkbench_module_css_default.sqlResult,
864
- children: sqlResult ?? t("wb.sql.empty")
939
+ !sqlite && credentialMode === "password" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
940
+ className: DataAgentWorkbench_module_css_default.rememberRow,
941
+ children: [
942
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
943
+ type: "checkbox",
944
+ checked: rememberPassword,
945
+ disabled: formDisabled,
946
+ onChange: (event) => setRememberPassword(event.target.checked)
947
+ }),
948
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("form.rememberPassword") }),
949
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
950
+ className: DataAgentWorkbench_module_css_default.rememberHint,
951
+ children: t("form.rememberPassword.hint")
952
+ })
953
+ ]
954
+ }),
955
+ !sqlite && credentialMode === "reference" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
956
+ className: DataAgentWorkbench_module_css_default.field,
957
+ children: [
958
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
959
+ className: DataAgentWorkbench_module_css_default.label,
960
+ children: t("form.passwordRef")
961
+ }),
962
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
963
+ className: DataAgentWorkbench_module_css_default.input,
964
+ type: "text",
965
+ value: passwordRef,
966
+ placeholder: "ANALYTICS_DB_PASSWORD",
967
+ disabled: formDisabled,
968
+ onChange: (event) => {
969
+ setPasswordRef(event.target.value);
970
+ setCredentialStatus(void 0);
971
+ }
972
+ }),
973
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
974
+ className: DataAgentWorkbench_module_css_default.rememberHint,
975
+ children: credentialStatus === void 0 ? t("form.passwordRef.hint") : credentialStatus.configured ? `${t("credential.configured")}${credentialStatus.source !== void 0 ? ` · ${credentialStatus.source}` : ""}` : t("credential.unconfigured")
976
+ })
977
+ ]
978
+ }),
979
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
980
+ className: DataAgentWorkbench_module_css_default.rememberRow,
981
+ children: [
982
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
983
+ type: "checkbox",
984
+ checked: readonly,
985
+ disabled: formDisabled,
986
+ onChange: (event) => setReadonly(event.target.checked)
987
+ }),
988
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("form.readonly") }),
989
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
990
+ className: DataAgentWorkbench_module_css_default.rememberHint,
991
+ children: t("form.readonly.hint")
992
+ })
993
+ ]
994
+ }),
995
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
996
+ className: DataAgentWorkbench_module_css_default.field,
997
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
998
+ className: DataAgentWorkbench_module_css_default.label,
999
+ children: databaseLabel
1000
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1001
+ className: DataAgentWorkbench_module_css_default.input,
1002
+ type: "text",
1003
+ value: database,
1004
+ placeholder: sqlite ? t("form.database.sqlite.placeholder") : void 0,
1005
+ disabled: formDisabled,
1006
+ onChange: (event) => setDatabase(event.target.value)
1007
+ })]
865
1008
  })
866
1009
  ]
867
- })
868
- ]
869
- }),
870
- error !== null && !connectModalOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
871
- className: DataAgentWorkbench_module_css_default.errorBar,
872
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
873
- className: DataAgentWorkbench_module_css_default.errorHead,
874
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlertIcon, { className: DataAgentWorkbench_module_css_default.errorIcon }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("error.title") })]
875
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
876
- className: DataAgentWorkbench_module_css_default.errorText,
877
- children: error
878
- })]
879
- }),
880
- schemaModalOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
881
- open: schemaModalOpen,
882
- onClose: () => setSchemaModalOpen(false),
883
- title: t("wb.modal.title"),
884
- closeLabel: t("action.close"),
885
- className: DataAgentWorkbench_module_css_default.schemaModal,
886
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
887
- className: DataAgentWorkbench_module_css_default.modalBody,
1010
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1011
+ className: DataAgentWorkbench_module_css_default.actions,
1012
+ children: !connected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1013
+ type: "button",
1014
+ className: DataAgentWorkbench_module_css_default.primary,
1015
+ disabled: busy || database === "" || !sqlite && host === "",
1016
+ onClick: () => {
1017
+ connect();
1018
+ },
1019
+ children: restoring ? t("state.reconnecting") : busy ? t("state.checking") : t("action.connect")
1020
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1021
+ type: "button",
1022
+ className: DataAgentWorkbench_module_css_default.ghost,
1023
+ disabled: busy,
1024
+ onClick: () => {
1025
+ disconnect();
1026
+ },
1027
+ children: t("action.disconnect")
1028
+ })
1029
+ })]
1030
+ }),
1031
+ activeTab === "schema" && connected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1032
+ id: `${tabsId}-schema-panel`,
1033
+ role: "tabpanel",
1034
+ "aria-labelledby": `${tabsId}-schema-tab`,
1035
+ className: `${DataAgentWorkbench_module_css_default.tabPanel} ${DataAgentWorkbench_module_css_default.schemaPanel}`,
888
1036
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
889
1037
  className: DataAgentWorkbench_module_css_default.modalCol,
890
1038
  children: [
@@ -899,7 +1047,7 @@ window.__ModuleLoader__.load({
899
1047
  className: DataAgentWorkbench_module_css_default.treeScroll,
900
1048
  children: [schemas.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
901
1049
  className: DataAgentWorkbench_module_css_default.hint,
902
- children: t("wb.loading")
1050
+ children: schemaBusy ? t("wb.loading") : t("wb.empty")
903
1051
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
904
1052
  className: DataAgentWorkbench_module_css_default.tree,
905
1053
  children: schemas.map((schema) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
@@ -980,251 +1128,62 @@ window.__ModuleLoader__.load({
980
1128
  })
981
1129
  })]
982
1130
  })]
983
- })
984
- }),
985
- connectModalOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
986
- open: connectModalOpen,
987
- onClose: () => setConnectModalOpen(false),
988
- title: t("form.title"),
989
- closeLabel: t("action.close"),
990
- className: DataAgentWorkbench_module_css_default.connectModal,
991
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
992
- className: DataAgentWorkbench_module_css_default.connectModalBody,
1131
+ }),
1132
+ activeTab === "sql" && connected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1133
+ id: `${tabsId}-sql-panel`,
1134
+ role: "tabpanel",
1135
+ "aria-labelledby": `${tabsId}-sql-tab`,
1136
+ className: `${DataAgentWorkbench_module_css_default.tabPanel} ${DataAgentWorkbench_module_css_default.sqlPanel}`,
993
1137
  children: [
994
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
995
- className: DataAgentWorkbench_module_css_default.fieldGrid,
996
- children: [
997
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
998
- className: DataAgentWorkbench_module_css_default.field,
999
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1000
- className: DataAgentWorkbench_module_css_default.label,
1001
- children: t("form.type")
1002
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1003
- className: DataAgentWorkbench_module_css_default.input,
1004
- value: type,
1005
- disabled: formDisabled,
1006
- onChange: (event) => {
1007
- const next = event.target.value;
1008
- setType(next);
1009
- setPort(next === "postgres" ? "5432" : next === "mysql" ? "3306" : next === "oracle" ? "1521" : next === "hive" ? "10000" : next === "impala" ? "21050" : "");
1010
- },
1011
- children: [
1012
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1013
- value: "mysql",
1014
- children: t("type.mysql")
1015
- }),
1016
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1017
- value: "postgres",
1018
- children: t("type.postgres")
1019
- }),
1020
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1021
- value: "sqlite",
1022
- children: t("type.sqlite")
1023
- }),
1024
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1025
- value: "oracle",
1026
- children: t("type.oracle")
1027
- }),
1028
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1029
- value: "hive",
1030
- children: t("type.hive")
1031
- }),
1032
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1033
- value: "impala",
1034
- children: t("type.impala")
1035
- })
1036
- ]
1037
- })]
1038
- }),
1039
- !sqlite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1040
- className: DataAgentWorkbench_module_css_default.fieldRow2,
1041
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1042
- className: DataAgentWorkbench_module_css_default.field,
1043
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1044
- className: DataAgentWorkbench_module_css_default.label,
1045
- children: t("form.host")
1046
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1047
- className: DataAgentWorkbench_module_css_default.input,
1048
- type: "text",
1049
- value: host,
1050
- disabled: formDisabled,
1051
- onChange: (event) => setHost(event.target.value)
1052
- })]
1053
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1054
- className: DataAgentWorkbench_module_css_default.field,
1055
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1056
- className: DataAgentWorkbench_module_css_default.label,
1057
- children: t("form.port")
1058
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1059
- className: DataAgentWorkbench_module_css_default.input,
1060
- type: "number",
1061
- min: 1,
1062
- max: 65535,
1063
- value: port,
1064
- disabled: formDisabled,
1065
- onChange: (event) => setPort(event.target.value)
1066
- })]
1067
- })]
1068
- }),
1069
- !sqlite && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1070
- className: DataAgentWorkbench_module_css_default.fieldRow2,
1071
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1072
- className: DataAgentWorkbench_module_css_default.field,
1073
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1074
- className: DataAgentWorkbench_module_css_default.label,
1075
- children: t("form.user")
1076
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1077
- className: DataAgentWorkbench_module_css_default.input,
1078
- type: "text",
1079
- value: user,
1080
- disabled: formDisabled,
1081
- onChange: (event) => setUser(event.target.value)
1082
- })]
1083
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1084
- className: DataAgentWorkbench_module_css_default.field,
1085
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1086
- className: DataAgentWorkbench_module_css_default.label,
1087
- children: t("form.credentialMode")
1088
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
1089
- className: DataAgentWorkbench_module_css_default.input,
1090
- value: credentialMode,
1091
- disabled: formDisabled,
1092
- onChange: (event) => {
1093
- const next = event.target.value;
1094
- setCredentialMode(next);
1095
- setCredentialStatus(void 0);
1096
- },
1097
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1098
- value: "password",
1099
- children: t("form.credentialMode.password")
1100
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1101
- value: "reference",
1102
- children: t("form.credentialMode.reference")
1103
- })]
1104
- })]
1105
- })]
1106
- }),
1107
- !sqlite && credentialMode === "password" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1108
- className: DataAgentWorkbench_module_css_default.field,
1109
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1110
- className: DataAgentWorkbench_module_css_default.label,
1111
- children: t("form.password")
1112
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1113
- className: DataAgentWorkbench_module_css_default.input,
1114
- type: "password",
1115
- value: password,
1116
- autoComplete: "new-password",
1117
- disabled: formDisabled,
1118
- onChange: (event) => setPassword(event.target.value)
1119
- })]
1120
- }),
1121
- !sqlite && credentialMode === "password" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1122
- className: DataAgentWorkbench_module_css_default.rememberRow,
1123
- children: [
1124
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1125
- type: "checkbox",
1126
- checked: rememberPassword,
1127
- disabled: formDisabled,
1128
- onChange: (event) => setRememberPassword(event.target.checked)
1129
- }),
1130
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("form.rememberPassword") }),
1131
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1132
- className: DataAgentWorkbench_module_css_default.rememberHint,
1133
- children: t("form.rememberPassword.hint")
1134
- })
1135
- ]
1136
- }),
1137
- !sqlite && credentialMode === "reference" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1138
- className: DataAgentWorkbench_module_css_default.field,
1139
- children: [
1140
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1141
- className: DataAgentWorkbench_module_css_default.label,
1142
- children: t("form.passwordRef")
1143
- }),
1144
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1145
- className: DataAgentWorkbench_module_css_default.input,
1146
- type: "text",
1147
- value: passwordRef,
1148
- placeholder: "ANALYTICS_DB_PASSWORD",
1149
- disabled: formDisabled,
1150
- onChange: (event) => {
1151
- setPasswordRef(event.target.value);
1152
- setCredentialStatus(void 0);
1153
- }
1154
- }),
1155
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1156
- className: DataAgentWorkbench_module_css_default.rememberHint,
1157
- children: credentialStatus === void 0 ? t("form.passwordRef.hint") : credentialStatus.configured ? `${t("credential.configured")}${credentialStatus.source !== void 0 ? ` · ${credentialStatus.source}` : ""}` : t("credential.unconfigured")
1158
- })
1159
- ]
1160
- }),
1161
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1162
- className: DataAgentWorkbench_module_css_default.rememberRow,
1163
- children: [
1164
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1165
- type: "checkbox",
1166
- checked: readonly,
1167
- disabled: formDisabled,
1168
- onChange: (event) => setReadonly(event.target.checked)
1169
- }),
1170
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("form.readonly") }),
1171
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1172
- className: DataAgentWorkbench_module_css_default.rememberHint,
1173
- children: t("form.readonly.hint")
1174
- })
1175
- ]
1176
- }),
1177
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1178
- className: DataAgentWorkbench_module_css_default.field,
1179
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1180
- className: DataAgentWorkbench_module_css_default.label,
1181
- children: databaseLabel
1182
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1183
- className: DataAgentWorkbench_module_css_default.input,
1184
- type: "text",
1185
- value: database,
1186
- placeholder: sqlite ? t("form.database.sqlite.placeholder") : void 0,
1187
- disabled: formDisabled,
1188
- onChange: (event) => setDatabase(event.target.value)
1189
- })]
1190
- })
1191
- ]
1138
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
1139
+ className: DataAgentWorkbench_module_css_default.sqlInput,
1140
+ value: sql,
1141
+ rows: 9,
1142
+ spellCheck: false,
1143
+ placeholder: t("wb.sql.placeholder"),
1144
+ onChange: (event) => setSql(event.target.value),
1145
+ onKeyDown: (event) => {
1146
+ if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
1147
+ event.preventDefault();
1148
+ runSql();
1149
+ }
1150
+ }
1192
1151
  }),
1193
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1194
- className: DataAgentWorkbench_module_css_default.actions,
1195
- children: !connected ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1152
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1153
+ className: DataAgentWorkbench_module_css_default.sqlActions,
1154
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1155
+ className: DataAgentWorkbench_module_css_default.shortcutHint,
1156
+ children: t("wb.sql.shortcut")
1157
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1196
1158
  type: "button",
1197
1159
  className: DataAgentWorkbench_module_css_default.primary,
1198
- disabled: busy || database === "" || !sqlite && host === "",
1199
- onClick: () => {
1200
- connect();
1201
- },
1202
- children: restoring ? t("state.reconnecting") : busy ? t("state.checking") : t("action.connect")
1203
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1204
- type: "button",
1205
- className: DataAgentWorkbench_module_css_default.ghost,
1206
- disabled: busy,
1160
+ disabled: sqlBusy || sql.trim() === "",
1207
1161
  onClick: () => {
1208
- disconnect();
1162
+ runSql();
1209
1163
  },
1210
- children: t("action.disconnect")
1211
- })
1212
- }),
1213
- error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1214
- className: DataAgentWorkbench_module_css_default.errorBar,
1215
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1216
- className: DataAgentWorkbench_module_css_default.errorHead,
1217
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlertIcon, { className: DataAgentWorkbench_module_css_default.errorIcon }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("error.title") })]
1218
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1219
- className: DataAgentWorkbench_module_css_default.errorText,
1220
- children: error
1164
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlayIcon, {}), sqlBusy ? t("wb.sql.running") : t("wb.sql.run")]
1221
1165
  })]
1166
+ }),
1167
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
1168
+ className: DataAgentWorkbench_module_css_default.sqlResult,
1169
+ children: sqlResult ?? t("wb.sql.empty")
1222
1170
  })
1223
1171
  ]
1172
+ }),
1173
+ error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1174
+ className: DataAgentWorkbench_module_css_default.errorBar,
1175
+ role: "alert",
1176
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1177
+ className: DataAgentWorkbench_module_css_default.errorHead,
1178
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AlertIcon, { className: DataAgentWorkbench_module_css_default.errorIcon }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("error.title") })]
1179
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1180
+ className: DataAgentWorkbench_module_css_default.errorText,
1181
+ children: error
1182
+ })]
1224
1183
  })
1225
- })
1226
- ]
1227
- });
1184
+ ]
1185
+ })
1186
+ })] });
1228
1187
  }
1229
1188
  const VIEW_KINDS = [
1230
1189
  "metric",
@@ -42575,40 +42534,40 @@ window.__ModuleLoader__.load({
42575
42534
  document.head.appendChild(tag);
42576
42535
  }
42577
42536
  var AnalysisDashboard_module_css_default = {
42578
- "table": "_1tppBG_table",
42579
- "chart": "_1tppBG_chart",
42580
- "rowHead": "_1tppBG_rowHead",
42581
- "rowActions": "_1tppBG_rowActions",
42582
42537
  "view": "_1tppBG_view",
42583
- "metricLabel": "_1tppBG_metricLabel",
42584
- "modalClose": "_1tppBG_modalClose",
42585
42538
  "modalTitle": "_1tppBG_modalTitle",
42586
- "visuallyHidden": "_1tppBG_visuallyHidden",
42587
- "viewHalf": "_1tppBG_viewHalf",
42588
- "viewFull": "_1tppBG_viewFull",
42589
42539
  "modalHeader": "_1tppBG_modalHeader",
42590
- "chartCanvas": "_1tppBG_chartCanvas",
42540
+ "emptyText": "_1tppBG_emptyText",
42541
+ "rowTitle": "_1tppBG_rowTitle",
42542
+ "modalClose": "_1tppBG_modalClose",
42591
42543
  "modal": "_1tppBG_modal",
42544
+ "metricLabel": "_1tppBG_metricLabel",
42545
+ "grid": "_1tppBG_grid",
42546
+ "rowActions": "_1tppBG_rowActions",
42547
+ "viewHalf": "_1tppBG_viewHalf",
42548
+ "chartCanvas": "_1tppBG_chartCanvas",
42549
+ "chart": "_1tppBG_chart",
42550
+ "tableWrap": "_1tppBG_tableWrap",
42551
+ "table": "_1tppBG_table",
42552
+ "preview": "_1tppBG_preview",
42553
+ "visuallyHidden": "_1tppBG_visuallyHidden",
42592
42554
  "modalTitleWrap": "_1tppBG_modalTitleWrap",
42593
- "rowButton": "_1tppBG_rowButton",
42594
- "modalBody": "_1tppBG_modalBody",
42595
- "rowInterrupted": "_1tppBG_rowInterrupted",
42555
+ "metric": "_1tppBG_metric",
42596
42556
  "modalCount": "_1tppBG_modalCount",
42597
- "metricValue": "_1tppBG_metricValue",
42557
+ "modalBody": "_1tppBG_modalBody",
42598
42558
  "row": "_1tppBG_row",
42599
- "tableWrap": "_1tppBG_tableWrap",
42600
- "preview": "_1tppBG_preview",
42559
+ "rowButton": "_1tppBG_rowButton",
42560
+ "metricBand": "_1tppBG_metricBand",
42561
+ "metricValue": "_1tppBG_metricValue",
42601
42562
  "rowError": "_1tppBG_rowError",
42563
+ "rowInterrupted": "_1tppBG_rowInterrupted",
42564
+ "viewFull": "_1tppBG_viewFull",
42602
42565
  "viewTitle": "_1tppBG_viewTitle",
42603
- "emptyText": "_1tppBG_emptyText",
42604
- "metric": "_1tppBG_metric",
42605
- "modalShell": "_1tppBG_modalShell",
42606
- "rowTitle": "_1tppBG_rowTitle",
42607
42566
  "empty": "_1tppBG_empty",
42608
- "grid": "_1tppBG_grid",
42609
- "rowSummary": "_1tppBG_rowSummary",
42610
42567
  "modalSummary": "_1tppBG_modalSummary",
42611
- "metricBand": "_1tppBG_metricBand"
42568
+ "rowHead": "_1tppBG_rowHead",
42569
+ "rowSummary": "_1tppBG_rowSummary",
42570
+ "modalShell": "_1tppBG_modalShell"
42612
42571
  };
42613
42572
  //#endregion
42614
42573
  //#region src/client/AnalysisChart.tsx
@@ -43060,6 +43019,18 @@ window.__ModuleLoader__.load({
43060
43019
  "state.disconnected": "未连接",
43061
43020
  "state.checking": "正在检查连接…",
43062
43021
  "state.reconnecting": "正在恢复连接…",
43022
+ "state.reconnectRequired": "需要重新认证",
43023
+ "workbench.open.connected": "数据库工作台:已连接",
43024
+ "workbench.open.disconnected": "数据库工作台:未连接",
43025
+ "workbench.open.checking": "数据库工作台:正在检查连接",
43026
+ "workbench.open.error": "数据库工作台:连接异常",
43027
+ "workbench.open.reconnectRequired": "数据库工作台:需要重新认证",
43028
+ "composer.placeholder.disconnected": "数据库未连接,请点击输入框右上角的配置按钮",
43029
+ "composer.placeholder.connected": "数据库连接成功,请描述分析内容",
43030
+ "composer.placeholder.reconnectRequired": "数据库需要重新认证,请点击输入框右上角的配置按钮",
43031
+ "wb.workbench.title": "数据库工作台",
43032
+ "wb.workbench.description": "管理连接、浏览库表并运行 SQL",
43033
+ "wb.workbench.tabs": "数据库工作台功能",
43063
43034
  "wb.schemas": "库",
43064
43035
  "wb.tables": "表",
43065
43036
  "wb.columns": "表结构",
@@ -43134,6 +43105,18 @@ window.__ModuleLoader__.load({
43134
43105
  "state.disconnected": "Not connected",
43135
43106
  "state.checking": "Checking connection…",
43136
43107
  "state.reconnecting": "Restoring connection…",
43108
+ "state.reconnectRequired": "Authentication required",
43109
+ "workbench.open.connected": "Database workbench: connected",
43110
+ "workbench.open.disconnected": "Database workbench: not connected",
43111
+ "workbench.open.checking": "Database workbench: checking connection",
43112
+ "workbench.open.error": "Database workbench: connection error",
43113
+ "workbench.open.reconnectRequired": "Database workbench: authentication required",
43114
+ "composer.placeholder.disconnected": "Database not connected. Click the configuration button at the top right of the input box.",
43115
+ "composer.placeholder.connected": "Database connected. Describe what you want to analyze.",
43116
+ "composer.placeholder.reconnectRequired": "Database authentication required. Click the configuration button at the top right of the input box.",
43117
+ "wb.workbench.title": "Database workbench",
43118
+ "wb.workbench.description": "Manage connections, browse schemas, and run SQL",
43119
+ "wb.workbench.tabs": "Database workbench sections",
43137
43120
  "wb.schemas": "Databases",
43138
43121
  "wb.tables": "Tables",
43139
43122
  "wb.columns": "Columns",
@@ -43179,7 +43162,7 @@ window.__ModuleLoader__.load({
43179
43162
  ];
43180
43163
  /**
43181
43164
  * Client plugin body: register the data-agent dictionaries and the database
43182
- * workbench into the composer input dock. The registration rides the slot
43165
+ * workbench trigger into the composer card's right control region. The registration rides the slot
43183
43166
  * service's effect wrapper, so plugin unload removes it.
43184
43167
  * @param ctx - client root context.
43185
43168
  */
@@ -43199,8 +43182,8 @@ window.__ModuleLoader__.load({
43199
43182
  getSnapshot: () => list.getSnapshot(),
43200
43183
  subscribe: (fn) => list.subscribe(fn)
43201
43184
  };
43202
- scope.slots.inject("conversation.input.dock", () => scope.slots.register({
43203
- name: "conversation.input.dock",
43185
+ scope.slots.inject("conversation.input.right", () => scope.slots.register({
43186
+ name: "conversation.input.right",
43204
43187
  id: "data-agent",
43205
43188
  order: 0,
43206
43189
  locale: NS,