@yejiming/dsh-data-agent 0.0.13 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.en.md +43 -8
  2. package/README.md +43 -8
  3. package/conformance/dsh-ecosystem/inventory.json +26 -3
  4. package/conformance/dsh-ecosystem/restrictions.json +2 -2
  5. package/cordis.patch.yml +6 -3
  6. package/dsh-plugin.json +9 -4
  7. package/lib/catalog-DEJqOXRo.js +1944 -0
  8. package/lib/catalog-identity-CVftmvQL.js +96 -0
  9. package/lib/client.js +2217 -109
  10. package/lib/client.js.map +1 -1
  11. package/lib/command-CzzSPmag.js +1719 -0
  12. package/lib/command.js +2 -2
  13. package/lib/{connections-CHY4uB6z.js → connections-CFXOZTHZ.js} +223 -9
  14. package/lib/index.js +366 -16
  15. package/lib/routes.js +257 -4
  16. package/lib/{tool-ZTOS4B33.js → tool-DNkywSph.js} +364 -3
  17. package/lib/tool.js +1 -1
  18. package/lib/types/catalog-adapters.d.ts +52 -0
  19. package/lib/types/catalog-ai.d.ts +49 -0
  20. package/lib/types/catalog-command.d.ts +28 -0
  21. package/lib/types/catalog-identity.d.ts +23 -0
  22. package/lib/types/catalog-storage.d.ts +265 -0
  23. package/lib/types/catalog-tools.d.ts +5 -0
  24. package/lib/types/catalog-tui.d.ts +18 -0
  25. package/lib/types/catalog-types.d.ts +1376 -0
  26. package/lib/types/catalog.d.ts +59 -0
  27. package/lib/types/client/CatalogPanel.d.ts +15 -0
  28. package/lib/types/client/catalog-client.d.ts +57 -0
  29. package/lib/types/client/locales.d.ts +242 -0
  30. package/lib/types/command.d.ts +14 -3
  31. package/lib/types/connections.d.ts +9 -0
  32. package/lib/types/defaults.d.ts +22 -0
  33. package/lib/types/index.d.ts +42 -5
  34. package/lib/types/tui-connection-form.d.ts +11 -5
  35. package/package.json +4 -2
  36. package/preset/data-agent/agent.cordis.yml +9 -1
  37. package/lib/command-utC5MHd9.js +0 -916
  38. package/lib/defaults-Cngd8Tf8.js +0 -131
package/lib/client.js CHANGED
@@ -1001,7 +1001,7 @@ window.__ModuleLoader__.load({
1001
1001
  }
1002
1002
  //#endregion
1003
1003
  //#region \0dsh-css:/Users/yejiming/Desktop/OpenSource/dsh-data-agent/src/client/DataAgentWorkbench.module.css.mjs
1004
- 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_sqlResultEmpty,.Sv3uVW_sqlMessage{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);border-radius:8px;flex:1;min-height:150px;margin:0;padding:11px 12px}.Sv3uVW_sqlResultEmpty{color:var(--dsw-alias-label-caption,#80808080);place-items:center;font-size:12px;display:grid}.Sv3uVW_sqlMessage{max-height:280px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);white-space:pre-wrap;word-break:break-word;font-size:11.5px;line-height:1.55;overflow:auto}.Sv3uVW_sqlMessageError{border-color:var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);color:var(--dsw-alias-state-error-primary,#ef4444)}.Sv3uVW_sqlResultPanel{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);border-radius:8px;flex-direction:column;flex:1;min-height:210px;display:flex;overflow:hidden}.Sv3uVW_sqlResultToolbar{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);flex:none;justify-content:space-between;align-items:center;gap:10px;min-height:42px;padding:6px 8px 6px 11px;display:flex}.Sv3uVW_sqlResultMeta{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);white-space:nowrap;align-items:center;gap:8px;font-size:11.5px;display:flex}.Sv3uVW_sqlResultLimit{background:var(--dsw-alias-interactive-bg-hover,#80808014);color:var(--dsw-alias-label-tertiary,#808080a6);border-radius:999px;padding:1px 6px;font-size:10.5px}.Sv3uVW_sqlFeedback{color:var(--dsw-alias-state-success-primary,#16a34a);text-overflow:ellipsis;overflow:hidden}.Sv3uVW_sqlExportActions{flex:none;align-items:center;gap:5px;display:flex}.Sv3uVW_sqlExportButton,.Sv3uVW_sqlPageButton{border:1px solid var(--dsw-alias-border-l2,#80808059);height:28px;color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;cursor:pointer;background:0 0;border-radius:7px;justify-content:center;align-items:center;gap:4px;padding:0 9px;font-size:11.5px;transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_sqlExportButton:hover:not(:disabled),.Sv3uVW_sqlPageButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014);color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_sqlExportButton:focus-visible,.Sv3uVW_sqlPageButton:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 24%, transparent);outline:none}.Sv3uVW_sqlExportButton:disabled,.Sv3uVW_sqlPageButton:disabled{opacity:.42;cursor:default}.Sv3uVW_sqlTableScroll{flex:1;min-height:150px;max-height:300px;overflow:auto}.Sv3uVW_sqlResultTable{border-collapse:separate;border-spacing:0;width:max-content;min-width:100%;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:11.5px}.Sv3uVW_sqlResultTable th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#8080801f);color:var(--dsw-alias-label-secondary,#808080cc);text-align:left;white-space:nowrap;padding:7px 10px;font-size:11px;font-weight:600;position:sticky;top:0}.Sv3uVW_sqlResultTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#8080802e);text-overflow:ellipsis;white-space:nowrap;max-width:360px;padding:6px 10px;overflow:hidden}.Sv3uVW_sqlResultTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_sqlNull,.Sv3uVW_sqlEmptyString{color:var(--dsw-alias-label-caption,#80808080);font-size:10.5px}.Sv3uVW_sqlNull{font-style:italic}.Sv3uVW_sqlTableEmpty{height:92px;color:var(--dsw-alias-label-caption,#80808080);text-align:center}.Sv3uVW_sqlPagination{border-top:1px solid var(--dsw-alias-border-l1,#80808033);min-height:36px;color:var(--dsw-alias-label-tertiary,#808080a6);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:4px 8px 4px 11px;font-size:11px;display:flex}.Sv3uVW_sqlPageActions{gap:5px;display:flex}.Sv3uVW_sqlPageButton{height:26px}.Sv3uVW_visuallyHidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}.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}.Sv3uVW_sqlResultToolbar{flex-direction:column;align-items:flex-start}.Sv3uVW_sqlResultMeta{white-space:normal;flex-wrap:wrap;max-width:100%}.Sv3uVW_sqlExportActions{width:100%}.Sv3uVW_sqlExportButton{flex:1}}@media (prefers-reduced-motion:reduce){.Sv3uVW_trigger,.Sv3uVW_input,.Sv3uVW_primary,.Sv3uVW_ghost,.Sv3uVW_sqlExportButton,.Sv3uVW_sqlPageButton,.Sv3uVW_treeChevron{transition:none}}";
1004
+ 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_sqlResultEmpty,.Sv3uVW_sqlMessage{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);border-radius:8px;flex:1;min-height:150px;margin:0;padding:11px 12px}.Sv3uVW_sqlResultEmpty{color:var(--dsw-alias-label-caption,#80808080);place-items:center;font-size:12px;display:grid}.Sv3uVW_sqlMessage{max-height:280px;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);white-space:pre-wrap;word-break:break-word;font-size:11.5px;line-height:1.55;overflow:auto}.Sv3uVW_sqlMessageError{border-color:var(--dsw-alias-state-error-secondary,#ef444480);background:var(--dsw-alias-interactive-bg-hover-danger,#ef444414);color:var(--dsw-alias-state-error-primary,#ef4444)}.Sv3uVW_sqlResultPanel{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-markdown-code-block,#ffffff0a);border-radius:8px;flex-direction:column;flex:1;min-height:210px;display:flex;overflow:hidden}.Sv3uVW_sqlResultToolbar{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#ffffff0a);flex:none;justify-content:space-between;align-items:center;gap:10px;min-height:42px;padding:6px 8px 6px 11px;display:flex}.Sv3uVW_sqlResultMeta{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);white-space:nowrap;align-items:center;gap:8px;font-size:11.5px;display:flex}.Sv3uVW_sqlResultLimit{background:var(--dsw-alias-interactive-bg-hover,#80808014);color:var(--dsw-alias-label-tertiary,#808080a6);border-radius:999px;padding:1px 6px;font-size:10.5px}.Sv3uVW_sqlFeedback{color:var(--dsw-alias-state-success-primary,#16a34a);text-overflow:ellipsis;overflow:hidden}.Sv3uVW_sqlExportActions{flex:none;align-items:center;gap:5px;display:flex}.Sv3uVW_sqlExportButton,.Sv3uVW_sqlPageButton{border:1px solid var(--dsw-alias-border-l2,#80808059);height:28px;color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;cursor:pointer;background:0 0;border-radius:7px;justify-content:center;align-items:center;gap:4px;padding:0 9px;font-size:11.5px;transition:background-color .15s ease-out,border-color .15s ease-out,color .15s ease-out,opacity .15s ease-out;display:inline-flex}.Sv3uVW_sqlExportButton:hover:not(:disabled),.Sv3uVW_sqlPageButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#80808014);color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_sqlExportButton:focus-visible,.Sv3uVW_sqlPageButton:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb, var(--dsw-alias-button-info-fill,#3b82f6) 24%, transparent);outline:none}.Sv3uVW_sqlExportButton:disabled,.Sv3uVW_sqlPageButton:disabled{opacity:.42;cursor:default}.Sv3uVW_sqlTableScroll{flex:1;min-height:150px;max-height:300px;overflow:auto}.Sv3uVW_sqlResultTable{border-collapse:separate;border-spacing:0;width:max-content;min-width:100%;color:var(--dsw-alias-label-primary,inherit);font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);font-size:11.5px}.Sv3uVW_sqlResultTable th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#8080801f);color:var(--dsw-alias-label-secondary,#808080cc);text-align:left;white-space:nowrap;padding:7px 10px;font-size:11px;font-weight:600;position:sticky;top:0}.Sv3uVW_sqlResultTable td{border-bottom:1px solid var(--dsw-alias-border-l1,#8080802e);text-overflow:ellipsis;white-space:nowrap;max-width:360px;padding:6px 10px;overflow:hidden}.Sv3uVW_sqlResultTable tbody tr:hover td{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_sqlNull,.Sv3uVW_sqlEmptyString{color:var(--dsw-alias-label-caption,#80808080);font-size:10.5px}.Sv3uVW_sqlNull{font-style:italic}.Sv3uVW_sqlTableEmpty{height:92px;color:var(--dsw-alias-label-caption,#80808080);text-align:center}.Sv3uVW_sqlPagination{border-top:1px solid var(--dsw-alias-border-l1,#80808033);min-height:36px;color:var(--dsw-alias-label-tertiary,#808080a6);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:4px 8px 4px 11px;font-size:11px;display:flex}.Sv3uVW_sqlPageActions{gap:5px;display:flex}.Sv3uVW_sqlPageButton{height:26px}.Sv3uVW_catalogPanel{min-height:450px}.Sv3uVW_catalogPanel[hidden]{display:none}.Sv3uVW_catalogProgress,.Sv3uVW_catalogConfirm{align-items:center;gap:8px;display:flex}.Sv3uVW_catalogToolbar{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);flex-direction:column;padding-bottom:10px;display:flex}.Sv3uVW_catalogOverview{grid-template-columns:minmax(260px,.8fr) minmax(0,1.2fr);align-items:end;gap:14px;padding-bottom:10px;display:grid}.Sv3uVW_catalogControl{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);flex-direction:column;gap:4px;font-size:11px;display:flex}.Sv3uVW_catalogStats{min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);grid-template-columns:minmax(140px,auto) minmax(0,1fr);align-items:center;gap:5px 16px;font-size:11px;display:grid}.Sv3uVW_catalogSourceName{color:var(--dsw-alias-label-primary,inherit);text-overflow:ellipsis;white-space:nowrap;font-size:13px;overflow:hidden}.Sv3uVW_catalogCounts{align-items:center;gap:16px;min-width:0;display:flex}.Sv3uVW_catalogCounts>span{white-space:nowrap;align-items:baseline;gap:4px;display:inline-flex}.Sv3uVW_catalogCounts strong{color:var(--dsw-alias-label-primary,inherit);font-variant-numeric:tabular-nums;font-size:13px}.Sv3uVW_catalogScanTimes{min-width:0;color:var(--dsw-alias-label-caption,#8080808c);grid-column:1/-1;gap:18px;display:flex}.Sv3uVW_catalogScanTimes span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.Sv3uVW_catalogScanTimes time{color:var(--dsw-alias-label-secondary,#808080cc);font-variant-numeric:tabular-nums;margin-left:4px}.Sv3uVW_catalogLatestRun{border-top:1px solid var(--dsw-alias-border-l1,#80808029);min-width:0;color:var(--dsw-alias-label-secondary,#808080cc);align-items:center;gap:8px;padding:8px 0;font-size:11px;display:flex}.Sv3uVW_catalogLatestRun[data-error=true]{color:var(--dsw-alias-state-error-primary,#ef4444)}.Sv3uVW_catalogLatestLabel{flex:none;font-weight:600}.Sv3uVW_catalogLatestRun code{max-width:150px;color:var(--dsw-alias-label-caption,#8080808c);text-overflow:ellipsis;white-space:nowrap;font-size:10px;overflow:hidden}.Sv3uVW_catalogLatestError{overflow-wrap:anywhere;min-width:0}.Sv3uVW_catalogLatestError strong{font-weight:600}.Sv3uVW_catalogActions{flex-direction:column;display:flex}.Sv3uVW_catalogActionGroup{border-top:1px solid var(--dsw-alias-border-l1,#80808029);grid-template-columns:104px minmax(0,1fr);align-items:center;gap:12px;min-width:0;padding:10px 0 0;display:grid}.Sv3uVW_catalogActionGroup+.Sv3uVW_catalogActionGroup{margin-top:10px}.Sv3uVW_catalogActionGroup>div{min-width:0}.Sv3uVW_catalogSectionLabel{color:var(--dsw-alias-label-secondary,#808080cc);align-self:start;padding-top:7px;font-size:11px;font-weight:600}.Sv3uVW_catalogScanBar{align-items:center;gap:8px;min-width:0;display:flex}.Sv3uVW_catalogScanBar .Sv3uVW_input{flex:160px;max-width:none}.Sv3uVW_catalogInlineNotice{color:var(--dsw-alias-label-caption,#8080808c);margin-top:5px;font-size:10.5px}.Sv3uVW_catalogDiffBar{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;gap:8px;display:grid}.Sv3uVW_catalogNotice,.Sv3uVW_catalogError,.Sv3uVW_catalogProgress,.Sv3uVW_catalogConfirm{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#8080800d);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:8px;padding:8px 10px;font-size:11.5px}.Sv3uVW_catalogNotice{background:0 0;border:none;padding-block:5px}.Sv3uVW_catalogError{border-color:var(--dsw-alias-state-error-secondary,#ef444480);color:var(--dsw-alias-state-error-primary,#ef4444)}.Sv3uVW_catalogProgress code{margin-left:auto;font-size:10px}.Sv3uVW_catalogConfirm span{flex:1}.Sv3uVW_catalogWorkspace{flex:none;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:14px;height:clamp(380px,52vh,520px);min-height:0;display:grid;overflow:hidden}.Sv3uVW_catalogResults,.Sv3uVW_catalogDetail{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex;overflow:hidden}.Sv3uVW_catalogSearch{grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;display:grid}.Sv3uVW_catalogSearchQuery,.Sv3uVW_catalogSearchActions{grid-column:1/-1}.Sv3uVW_catalogSearchActions{justify-content:space-between;align-items:center;gap:8px;display:flex}.Sv3uVW_catalogCheck{color:var(--dsw-alias-label-secondary,#808080cc);align-items:center;gap:6px;font-size:11px;display:flex}.Sv3uVW_catalogList,.Sv3uVW_catalogDetail{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:9px;overflow:hidden}.Sv3uVW_catalogList{overscroll-behavior:contain;flex-direction:column;flex:1;min-height:0;display:flex;overflow-y:auto}.Sv3uVW_catalogItem{border:0;border-bottom:1px solid var(--dsw-alias-border-l1,#80808029);color:var(--dsw-alias-label-primary,inherit);font:inherit;text-align:left;cursor:pointer;background:0 0;flex-direction:column;gap:3px;padding:9px 10px;display:flex}.Sv3uVW_catalogItem:hover,.Sv3uVW_catalogItemActive{background:var(--dsw-alias-interactive-bg-hover,#80808014)}.Sv3uVW_catalogItem:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#3b82f6);outline-offset:-2px}.Sv3uVW_catalogItem code,.Sv3uVW_catalogHistoryItem code,.Sv3uVW_catalogDetailScroll>code{color:var(--dsw-alias-label-secondary,#808080cc);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;overflow:hidden}.Sv3uVW_catalogItem>span:last-child{color:var(--dsw-alias-label-caption,#8080808c);font-size:10.5px}.Sv3uVW_catalogItemHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.Sv3uVW_catalogListEmpty{min-height:160px;color:var(--dsw-alias-label-caption,#8080808c);place-items:center;display:grid}.Sv3uVW_catalogBadge{border:1px solid var(--dsw-alias-border-l2,#80808059);width:fit-content;color:var(--dsw-alias-label-secondary,#808080cc);white-space:nowrap;border-radius:999px;flex:none;align-items:center;padding:1px 7px;font-size:10px;font-weight:600;display:inline-flex}.Sv3uVW_catalogBadge_verified,.Sv3uVW_catalogBadge_observed,.Sv3uVW_catalogBadge_restored{color:#16a34a;border-color:#16a34a73}.Sv3uVW_catalogBadge_inferred,.Sv3uVW_catalogBadge_needs_review,.Sv3uVW_catalogBadge_changed{color:#d97706;border-color:#d9770673}.Sv3uVW_catalogBadge_missing,.Sv3uVW_catalogBadge_unavailable,.Sv3uVW_catalogBadge_retired{color:#dc2626;border-color:#dc262661}.Sv3uVW_catalogDetailTabs{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);flex:none;gap:3px;padding:5px;display:flex}.Sv3uVW_catalogDetailHeader{border-bottom:1px solid var(--dsw-alias-border-l1,#80808033);flex-direction:column;flex:none;gap:7px;padding:12px 12px 10px;display:flex}.Sv3uVW_catalogDetailHeader h3,.Sv3uVW_catalogDetailHeader p{margin:0}.Sv3uVW_catalogDetailHeader p{color:var(--dsw-alias-label-secondary,#808080cc);font-size:11.5px}.Sv3uVW_catalogDetailTitle{justify-content:space-between;align-items:flex-start;gap:10px;min-width:0;display:flex}.Sv3uVW_catalogDetailTitle>div{flex-direction:column;gap:2px;min-width:0;display:flex}.Sv3uVW_catalogDetailTitle code{color:var(--dsw-alias-label-secondary,#808080cc);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;overflow:hidden}.Sv3uVW_catalogDetailCounts{color:var(--dsw-alias-label-caption,#8080808c);align-items:center;gap:18px;font-size:10.5px;display:flex}.Sv3uVW_catalogDetailCounts span{align-items:baseline;gap:4px;display:inline-flex}.Sv3uVW_catalogDetailCounts strong{color:var(--dsw-alias-label-primary,inherit);font-variant-numeric:tabular-nums;font-size:13px}.Sv3uVW_catalogDetailTab,.Sv3uVW_catalogDetailTabActive{color:var(--dsw-alias-label-secondary,#808080cc);font:inherit;cursor:pointer;background:0 0;border:0;border-radius:6px;flex:1;padding:6px 8px;font-size:11.5px}.Sv3uVW_catalogDetailTabActive{background:var(--dsw-alias-interactive-bg-active,#3b82f624);color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_catalogDetailScroll{overscroll-behavior:contain;flex-direction:column;flex:1;gap:9px;min-height:0;padding:12px;display:flex;overflow:auto}.Sv3uVW_catalogDetailScroll h3,.Sv3uVW_catalogDetailScroll p,.Sv3uVW_catalogDefinition pre,.Sv3uVW_catalogHistoryItem p{margin:0}.Sv3uVW_catalogDefinition,.Sv3uVW_catalogHistoryItem{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:8px;flex-direction:column;gap:5px;padding:9px;display:flex}.Sv3uVW_catalogFacts{grid-template-columns:minmax(7rem,max-content) minmax(0,1fr);gap:.35rem .8rem;margin:.75rem 0;display:grid}.Sv3uVW_catalogFacts dt{color:var(--dsh-color-text-secondary,#64748b)}.Sv3uVW_catalogFacts dd{overflow-wrap:anywhere;min-width:0;margin:0}.Sv3uVW_catalogRelations{gap:.5rem;margin-top:1rem;display:grid}.Sv3uVW_catalogScanFacts{border-top:1px solid var(--dsw-alias-border-l1,#80808033);color:var(--dsw-alias-label-secondary,#808080cc);padding-top:8px}.Sv3uVW_catalogScanFacts summary{cursor:pointer;font-weight:600}.Sv3uVW_catalogBusinessEmpty{border:1px dashed var(--dsw-alias-border-l2,#80808059);color:var(--dsw-alias-label-secondary,#808080cc);border-radius:8px;flex-direction:column;gap:6px;padding:12px;display:flex}.Sv3uVW_catalogBusinessEmpty strong{color:var(--dsw-alias-label-primary,inherit)}.Sv3uVW_catalogBusinessEmpty p{margin:0}.Sv3uVW_catalogMeaningReview,.Sv3uVW_catalogMeaningSection,.Sv3uVW_catalogMeaningFields{flex-direction:column;display:flex}.Sv3uVW_catalogMeaningReview{gap:16px}.Sv3uVW_catalogMeaningSection{gap:8px}.Sv3uVW_catalogMeaningSection h4{margin:0;font-size:12px}.Sv3uVW_catalogMeaningFields{border:1px solid var(--dsw-alias-border-l1,#80808033);border-radius:8px;gap:0;overflow:hidden}.Sv3uVW_catalogMeaningField{border-bottom:1px solid var(--dsw-alias-border-l1,#80808029);grid-template-columns:minmax(110px,.32fr) minmax(0,1fr);gap:10px;padding:9px 10px;display:grid}.Sv3uVW_catalogMeaningField:last-child{border-bottom:0}.Sv3uVW_catalogMeaningFieldMeta{flex-direction:column;gap:3px;min-width:0;display:flex}.Sv3uVW_catalogMeaningFieldMeta strong,.Sv3uVW_catalogMeaningFieldMeta code{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.Sv3uVW_catalogMeaningFieldMeta code,.Sv3uVW_catalogMeaningOrigin,.Sv3uVW_catalogMeaningActions code{color:var(--dsw-alias-label-caption,#8080808c);font-size:10px}.Sv3uVW_catalogMeaningCard{border:1px solid var(--dsw-alias-border-l1,#80808033);background:var(--dsw-alias-bg-layer-2,#80808009);border-radius:8px;flex-direction:column;gap:7px;min-width:0;padding:10px;display:flex}.Sv3uVW_catalogMeaningCardCompact{background:0 0;border:0;padding:0}.Sv3uVW_catalogMeaningCard p,.Sv3uVW_catalogMeaningMissing{margin:0;line-height:1.55}.Sv3uVW_catalogMeaningMissing{color:var(--dsw-alias-label-caption,#8080808c)}.Sv3uVW_catalogMeaningOrigin{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.Sv3uVW_catalogMeaningActions{align-items:center;gap:6px;min-width:0;display:flex}.Sv3uVW_catalogMeaningActions code{text-overflow:ellipsis;white-space:nowrap;min-width:0;margin-left:auto;overflow:hidden}.Sv3uVW_catalogDefinition pre{background:var(--dsw-alias-markdown-code-block,#80808014);white-space:pre-wrap;border-radius:6px;padding:7px;font-size:11px;overflow:auto}.Sv3uVW_catalogEditor{border-top:1px solid var(--dsw-alias-border-l1,#80808033);flex-direction:column;gap:8px;padding-top:8px;display:flex}.Sv3uVW_catalogTextArea{box-sizing:border-box;resize:vertical;border:1px solid var(--dsw-alias-border-l2,#80808059);background:var(--dsw-alias-bg-layer-2,#ffffff0a);min-height:68px;color:var(--dsw-alias-label-primary,inherit);font:inherit;border-radius:8px;padding:8px 10px}.Sv3uVW_visuallyHidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;padding:0;position:absolute;overflow:hidden}.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<=760px){.Sv3uVW_catalogOverview{grid-template-columns:minmax(0,1fr)}.Sv3uVW_catalogStats{grid-template-columns:minmax(120px,auto) minmax(0,1fr)}.Sv3uVW_catalogWorkspace{flex-direction:column;height:auto;display:flex;overflow:visible}.Sv3uVW_catalogList,.Sv3uVW_catalogDetail{flex:none;height:min(420px,58vh);min-height:280px;max-height:420px}.Sv3uVW_catalogMeaningField{grid-template-columns:minmax(0,1fr)}}@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_catalogScanBar,.Sv3uVW_catalogConfirm,.Sv3uVW_catalogProgress{flex-direction:column;align-items:stretch}.Sv3uVW_catalogControl,.Sv3uVW_catalogScanBar .Sv3uVW_input{width:100%;max-width:none}.Sv3uVW_catalogScanBar .Sv3uVW_input{flex:none}.Sv3uVW_catalogDiffBar,.Sv3uVW_catalogSearch{grid-template-columns:minmax(0,1fr)}.Sv3uVW_catalogActionGroup{grid-template-columns:minmax(0,1fr);gap:4px}.Sv3uVW_catalogSectionLabel{padding-top:0}.Sv3uVW_catalogDiffBar>*,.Sv3uVW_catalogSearchQuery,.Sv3uVW_catalogSearchActions{grid-column:1}.Sv3uVW_catalogSearchActions{flex-direction:column;align-items:stretch}.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}.Sv3uVW_sqlResultToolbar{flex-direction:column;align-items:flex-start}.Sv3uVW_sqlResultMeta{white-space:normal;flex-wrap:wrap;max-width:100%}.Sv3uVW_sqlExportActions{width:100%}.Sv3uVW_sqlExportButton{flex:1}}@media (prefers-reduced-motion:reduce){.Sv3uVW_trigger,.Sv3uVW_input,.Sv3uVW_primary,.Sv3uVW_ghost,.Sv3uVW_sqlExportButton,.Sv3uVW_sqlPageButton,.Sv3uVW_treeChevron{transition:none}}";
1005
1005
  const tagId$1 = "@yejiming/dsh-data-agent/DataAgentWorkbench.module.css";
1006
1006
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
1007
1007
  const tag = document.createElement("style");
@@ -1011,82 +1011,150 @@ window.__ModuleLoader__.load({
1011
1011
  document.head.appendChild(tag);
1012
1012
  }
1013
1013
  var DataAgentWorkbench_module_css_default = {
1014
- "emptyState": "Sv3uVW_emptyState",
1015
- "emptyStateText": "Sv3uVW_emptyStateText",
1016
- "modalCol": "Sv3uVW_modalCol",
1017
- "sqlTableEmpty": "Sv3uVW_sqlTableEmpty",
1018
- "errorIcon": "Sv3uVW_errorIcon",
1019
- "workbenchModal": "Sv3uVW_workbenchModal",
1020
- "connectionState": "Sv3uVW_connectionState",
1021
- "label": "Sv3uVW_label",
1014
+ "catalogDetailTabActive": "Sv3uVW_catalogDetailTabActive",
1022
1015
  "trigger": "Sv3uVW_trigger",
1023
- "triggerSlot": "Sv3uVW_triggerSlot",
1024
- "schemaPanel": "Sv3uVW_schemaPanel",
1025
- "sqlExportButton": "Sv3uVW_sqlExportButton",
1026
- "sqlNull": "Sv3uVW_sqlNull",
1027
- "sqlActions": "Sv3uVW_sqlActions",
1028
- "colCount": "Sv3uVW_colCount",
1029
- "fieldGrid": "Sv3uVW_fieldGrid",
1016
+ "catalogDetail": "Sv3uVW_catalogDetail",
1017
+ "catalogPanel": "Sv3uVW_catalogPanel",
1018
+ "catalogFacts": "Sv3uVW_catalogFacts",
1019
+ "visuallyHidden": "Sv3uVW_visuallyHidden",
1020
+ "catalogError": "Sv3uVW_catalogError",
1021
+ "rememberHint": "Sv3uVW_rememberHint",
1022
+ "catalogItemHead": "Sv3uVW_catalogItemHead",
1023
+ "catalogActionGroup": "Sv3uVW_catalogActionGroup",
1024
+ "field": "Sv3uVW_field",
1025
+ "modalHint": "Sv3uVW_modalHint",
1026
+ "catalogLatestRun": "Sv3uVW_catalogLatestRun",
1027
+ "catalogDiffBar": "Sv3uVW_catalogDiffBar",
1028
+ "errorIcon": "Sv3uVW_errorIcon",
1029
+ "catalogMeaningFields": "Sv3uVW_catalogMeaningFields",
1030
+ "catalogProgress": "Sv3uVW_catalogProgress",
1030
1031
  "errorBar": "Sv3uVW_errorBar",
1031
- "sqlPagination": "Sv3uVW_sqlPagination",
1032
+ "connectionSummary": "Sv3uVW_connectionSummary",
1033
+ "ghost": "Sv3uVW_ghost",
1034
+ "treeCount": "Sv3uVW_treeCount",
1032
1035
  "primary": "Sv3uVW_primary",
1033
- "triggerDot": "Sv3uVW_triggerDot",
1034
- "summaryType": "Sv3uVW_summaryType",
1035
- "sqlInput": "Sv3uVW_sqlInput",
1036
- "tabPanel": "Sv3uVW_tabPanel",
1037
- "sqlFeedback": "Sv3uVW_sqlFeedback",
1036
+ "sqlResultLimit": "Sv3uVW_sqlResultLimit",
1037
+ "catalogBadge_inferred": "Sv3uVW_catalogBadge_inferred",
1038
+ "catalogDetailTabs": "Sv3uVW_catalogDetailTabs",
1039
+ "catalogMeaningFieldMeta": "Sv3uVW_catalogMeaningFieldMeta",
1040
+ "errorHead": "Sv3uVW_errorHead",
1041
+ "catalogCounts": "Sv3uVW_catalogCounts",
1042
+ "sqlNull": "Sv3uVW_sqlNull",
1038
1043
  "sqlPageButton": "Sv3uVW_sqlPageButton",
1039
- "tabs": "Sv3uVW_tabs",
1040
- "sqlResultTable": "Sv3uVW_sqlResultTable",
1041
- "visuallyHidden": "Sv3uVW_visuallyHidden",
1042
- "sqlResultToolbar": "Sv3uVW_sqlResultToolbar",
1043
- "sqlEmptyString": "Sv3uVW_sqlEmptyString",
1044
+ "shortcutHint": "Sv3uVW_shortcutHint",
1045
+ "catalogLatestError": "Sv3uVW_catalogLatestError",
1046
+ "sqlResultEmpty": "Sv3uVW_sqlResultEmpty",
1047
+ "workbenchModalContent": "Sv3uVW_workbenchModalContent",
1048
+ "tabActive": "Sv3uVW_tabActive",
1049
+ "catalogMeaningSection": "Sv3uVW_catalogMeaningSection",
1050
+ "rememberRow": "Sv3uVW_rememberRow",
1051
+ "catalogSectionLabel": "Sv3uVW_catalogSectionLabel",
1052
+ "schemaPanel": "Sv3uVW_schemaPanel",
1044
1053
  "sqlPanel": "Sv3uVW_sqlPanel",
1045
- "open": "Sv3uVW_open",
1046
- "sqlPageActions": "Sv3uVW_sqlPageActions",
1047
- "fieldRow2": "Sv3uVW_fieldRow2",
1048
- "sqlResultPanel": "Sv3uVW_sqlResultPanel",
1049
- "rememberHint": "Sv3uVW_rememberHint",
1050
- "sqlResultMeta": "Sv3uVW_sqlResultMeta",
1051
- "errorText": "Sv3uVW_errorText",
1052
- "sqlResultLimit": "Sv3uVW_sqlResultLimit",
1054
+ "colScroll": "Sv3uVW_colScroll",
1055
+ "sqlActions": "Sv3uVW_sqlActions",
1056
+ "catalogHistoryItem": "Sv3uVW_catalogHistoryItem",
1057
+ "catalogCheck": "Sv3uVW_catalogCheck",
1058
+ "catalogDetailTab": "Sv3uVW_catalogDetailTab",
1059
+ "catalogBadge_retired": "Sv3uVW_catalogBadge_retired",
1060
+ "emptyStateIcon": "Sv3uVW_emptyStateIcon",
1061
+ "fieldGrid": "Sv3uVW_fieldGrid",
1062
+ "catalogOverview": "Sv3uVW_catalogOverview",
1063
+ "tabs": "Sv3uVW_tabs",
1064
+ "triggerSlot": "Sv3uVW_triggerSlot",
1065
+ "catalogSourceName": "Sv3uVW_catalogSourceName",
1066
+ "catalogScanTimes": "Sv3uVW_catalogScanTimes",
1053
1067
  "treeItem": "Sv3uVW_treeItem",
1054
- "sqlTableScroll": "Sv3uVW_sqlTableScroll",
1055
- "sqlResultEmpty": "Sv3uVW_sqlResultEmpty",
1056
- "treeScroll": "Sv3uVW_treeScroll",
1057
- "active": "Sv3uVW_active",
1058
- "workbench": "Sv3uVW_workbench",
1059
- "treeNode": "Sv3uVW_treeNode",
1068
+ "catalogScanFacts": "Sv3uVW_catalogScanFacts",
1069
+ "catalogMeaningCard": "Sv3uVW_catalogMeaningCard",
1070
+ "label": "Sv3uVW_label",
1071
+ "treeChevron": "Sv3uVW_treeChevron",
1072
+ "columnsTable": "Sv3uVW_columnsTable",
1073
+ "catalogScanBar": "Sv3uVW_catalogScanBar",
1074
+ "catalogBadge_missing": "Sv3uVW_catalogBadge_missing",
1075
+ "catalogMeaningMissing": "Sv3uVW_catalogMeaningMissing",
1076
+ "catalogMeaningOrigin": "Sv3uVW_catalogMeaningOrigin",
1077
+ "catalogActions": "Sv3uVW_catalogActions",
1078
+ "catalogStats": "Sv3uVW_catalogStats",
1079
+ "catalogToolbar": "Sv3uVW_catalogToolbar",
1080
+ "summaryDb": "Sv3uVW_summaryDb",
1081
+ "catalogListEmpty": "Sv3uVW_catalogListEmpty",
1082
+ "catalogBadge_needs_review": "Sv3uVW_catalogBadge_needs_review",
1083
+ "sqlMessageError": "Sv3uVW_sqlMessageError",
1084
+ "nullCell": "Sv3uVW_nullCell",
1085
+ "connectionState": "Sv3uVW_connectionState",
1086
+ "catalogList": "Sv3uVW_catalogList",
1087
+ "sqlResultTable": "Sv3uVW_sqlResultTable",
1088
+ "treeChildren": "Sv3uVW_treeChildren",
1089
+ "catalogBadge_changed": "Sv3uVW_catalogBadge_changed",
1090
+ "catalogBadge_verified": "Sv3uVW_catalogBadge_verified",
1091
+ "catalogBusinessEmpty": "Sv3uVW_catalogBusinessEmpty",
1092
+ "catalogDetailTitle": "Sv3uVW_catalogDetailTitle",
1060
1093
  "tab": "Sv3uVW_tab",
1061
1094
  "triggerActive": "Sv3uVW_triggerActive",
1095
+ "sqlFeedback": "Sv3uVW_sqlFeedback",
1096
+ "catalogRelations": "Sv3uVW_catalogRelations",
1097
+ "sqlTableEmpty": "Sv3uVW_sqlTableEmpty",
1098
+ "colCount": "Sv3uVW_colCount",
1099
+ "sqlResultPanel": "Sv3uVW_sqlResultPanel",
1100
+ "catalogResults": "Sv3uVW_catalogResults",
1101
+ "catalogDetailHeader": "Sv3uVW_catalogDetailHeader",
1102
+ "catalogItemActive": "Sv3uVW_catalogItemActive",
1103
+ "input": "Sv3uVW_input",
1104
+ "catalogMeaningCardCompact": "Sv3uVW_catalogMeaningCardCompact",
1105
+ "catalogBadge_observed": "Sv3uVW_catalogBadge_observed",
1106
+ "treeName": "Sv3uVW_treeName",
1107
+ "hint": "Sv3uVW_hint",
1108
+ "catalogNotice": "Sv3uVW_catalogNotice",
1109
+ "catalogSearchActions": "Sv3uVW_catalogSearchActions",
1110
+ "catalogDefinition": "Sv3uVW_catalogDefinition",
1111
+ "sqlMessage": "Sv3uVW_sqlMessage",
1112
+ "sqlTableScroll": "Sv3uVW_sqlTableScroll",
1113
+ "catalogItem": "Sv3uVW_catalogItem",
1114
+ "fieldRow2": "Sv3uVW_fieldRow2",
1115
+ "catalogLatestLabel": "Sv3uVW_catalogLatestLabel",
1116
+ "catalogMeaningActions": "Sv3uVW_catalogMeaningActions",
1062
1117
  "sqlExportActions": "Sv3uVW_sqlExportActions",
1118
+ "summaryType": "Sv3uVW_summaryType",
1119
+ "catalogBadge_restored": "Sv3uVW_catalogBadge_restored",
1120
+ "catalogTextArea": "Sv3uVW_catalogTextArea",
1121
+ "catalogMeaningField": "Sv3uVW_catalogMeaningField",
1122
+ "sqlPagination": "Sv3uVW_sqlPagination",
1123
+ "sqlEmptyString": "Sv3uVW_sqlEmptyString",
1124
+ "catalogBadge_unavailable": "Sv3uVW_catalogBadge_unavailable",
1063
1125
  "modalColTitle": "Sv3uVW_modalColTitle",
1064
- "workbenchModalContent": "Sv3uVW_workbenchModalContent",
1065
- "field": "Sv3uVW_field",
1066
- "emptyStateIcon": "Sv3uVW_emptyStateIcon",
1067
- "errorHead": "Sv3uVW_errorHead",
1068
- "actions": "Sv3uVW_actions",
1069
- "treeCount": "Sv3uVW_treeCount",
1070
- "sqlMessageError": "Sv3uVW_sqlMessageError",
1071
- "sqlMessage": "Sv3uVW_sqlMessage",
1126
+ "open": "Sv3uVW_open",
1127
+ "catalogWorkspace": "Sv3uVW_catalogWorkspace",
1128
+ "workbench": "Sv3uVW_workbench",
1129
+ "sqlInput": "Sv3uVW_sqlInput",
1130
+ "sqlExportButton": "Sv3uVW_sqlExportButton",
1131
+ "errorText": "Sv3uVW_errorText",
1132
+ "tree": "Sv3uVW_tree",
1133
+ "catalogConfirm": "Sv3uVW_catalogConfirm",
1072
1134
  "typeCell": "Sv3uVW_typeCell",
1073
- "treeName": "Sv3uVW_treeName",
1074
- "modalHint": "Sv3uVW_modalHint",
1075
- "input": "Sv3uVW_input",
1076
- "rememberRow": "Sv3uVW_rememberRow",
1077
- "tabActive": "Sv3uVW_tabActive",
1078
- "treeChildren": "Sv3uVW_treeChildren",
1079
- "hint": "Sv3uVW_hint",
1080
- "connectionSummary": "Sv3uVW_connectionSummary",
1135
+ "catalogDetailCounts": "Sv3uVW_catalogDetailCounts",
1136
+ "catalogDetailScroll": "Sv3uVW_catalogDetailScroll",
1137
+ "triggerDot": "Sv3uVW_triggerDot",
1138
+ "treeScroll": "Sv3uVW_treeScroll",
1139
+ "emptyStateText": "Sv3uVW_emptyStateText",
1140
+ "catalogInlineNotice": "Sv3uVW_catalogInlineNotice",
1141
+ "catalogMeaningReview": "Sv3uVW_catalogMeaningReview",
1142
+ "actions": "Sv3uVW_actions",
1143
+ "sqlPageActions": "Sv3uVW_sqlPageActions",
1144
+ "treeNode": "Sv3uVW_treeNode",
1081
1145
  "treeIcon": "Sv3uVW_treeIcon",
1082
- "colScroll": "Sv3uVW_colScroll",
1083
- "columnsTable": "Sv3uVW_columnsTable",
1084
- "nullCell": "Sv3uVW_nullCell",
1085
- "summaryDb": "Sv3uVW_summaryDb",
1086
- "ghost": "Sv3uVW_ghost",
1087
- "shortcutHint": "Sv3uVW_shortcutHint",
1088
- "tree": "Sv3uVW_tree",
1089
- "treeChevron": "Sv3uVW_treeChevron"
1146
+ "tabPanel": "Sv3uVW_tabPanel",
1147
+ "workbenchModal": "Sv3uVW_workbenchModal",
1148
+ "modalCol": "Sv3uVW_modalCol",
1149
+ "catalogBadge": "Sv3uVW_catalogBadge",
1150
+ "sqlResultToolbar": "Sv3uVW_sqlResultToolbar",
1151
+ "catalogSearchQuery": "Sv3uVW_catalogSearchQuery",
1152
+ "catalogEditor": "Sv3uVW_catalogEditor",
1153
+ "emptyState": "Sv3uVW_emptyState",
1154
+ "catalogControl": "Sv3uVW_catalogControl",
1155
+ "sqlResultMeta": "Sv3uVW_sqlResultMeta",
1156
+ "catalogSearch": "Sv3uVW_catalogSearch",
1157
+ "active": "Sv3uVW_active"
1090
1158
  };
1091
1159
  //#endregion
1092
1160
  //#region src/client/QueryResultTable.tsx
@@ -1313,6 +1381,1781 @@ window.__ModuleLoader__.load({
1313
1381
  });
1314
1382
  }
1315
1383
  //#endregion
1384
+ //#region src/client/catalog-client.ts
1385
+ const BASE = "/plugins/data-agent/catalog";
1386
+ async function listCatalogSources(signal) {
1387
+ return (await request(`${BASE}/sources`, { signal })).sources;
1388
+ }
1389
+ async function getCatalogStatus(sourceId, signal) {
1390
+ const params = new URLSearchParams({ sourceId });
1391
+ return (await request(`${BASE}/status?${params}`, { signal })).status;
1392
+ }
1393
+ async function listCatalogRuns(sourceId, signal) {
1394
+ const params = new URLSearchParams({
1395
+ sourceId,
1396
+ limit: "100"
1397
+ });
1398
+ return (await request(`${BASE}/runs?${params}`, { signal })).runs;
1399
+ }
1400
+ async function searchCatalog(input, signal) {
1401
+ const params = new URLSearchParams({
1402
+ sourceId: input.sourceId,
1403
+ query: input.query.trim() || "*"
1404
+ });
1405
+ if (input.schema !== void 0 && input.schema !== "") params.set("schema", input.schema);
1406
+ if (input.assetKinds?.length) params.set("assetKinds", input.assetKinds.join(","));
1407
+ if (input.semanticKinds?.length) params.set("semanticKinds", input.semanticKinds.join(","));
1408
+ if (input.assetStatuses?.length) params.set("assetStatuses", input.assetStatuses.join(","));
1409
+ if (input.semanticStatuses?.length) params.set("semanticStatuses", input.semanticStatuses.join(","));
1410
+ if (input.includeInferred === true) params.set("includeInferred", "true");
1411
+ if (input.cursor !== void 0) params.set("cursor", input.cursor);
1412
+ if (input.pageSize !== void 0) params.set("pageSize", String(input.pageSize));
1413
+ return (await request(`${BASE}/search?${params}`, { signal })).page;
1414
+ }
1415
+ async function getCatalogAsset(sourceId, assetId, cursor, signal) {
1416
+ const params = new URLSearchParams({
1417
+ sourceId,
1418
+ pageSize: "100"
1419
+ });
1420
+ if (cursor !== void 0) params.set("cursor", cursor);
1421
+ return (await request(`${BASE}/assets/${encodeURIComponent(assetId)}?${params}`, { signal })).detail;
1422
+ }
1423
+ async function getCatalogSemantic(sourceId, semanticId, version, signal) {
1424
+ const params = new URLSearchParams({ sourceId });
1425
+ if (version !== void 0) params.set("version", String(version));
1426
+ return (await request(`${BASE}/semantics/${encodeURIComponent(semanticId)}?${params}`, { signal })).semantic;
1427
+ }
1428
+ async function startCatalogScan(sessionId, scope) {
1429
+ return (await request(`${BASE}/scan`, json({
1430
+ sessionId,
1431
+ scope
1432
+ }))).run;
1433
+ }
1434
+ async function cancelCatalogScan(sourceId, runId) {
1435
+ return (await request(`${BASE}/cancel`, json({
1436
+ sourceId,
1437
+ ...runId ? { runId } : {}
1438
+ }))).run;
1439
+ }
1440
+ async function getCatalogDiff(sourceId, from, to, cursor) {
1441
+ const params = new URLSearchParams({
1442
+ sourceId,
1443
+ pageSize: "100"
1444
+ });
1445
+ if (from !== void 0 && to !== void 0) {
1446
+ params.set("from", from);
1447
+ params.set("to", to);
1448
+ }
1449
+ if (cursor !== void 0) params.set("cursor", cursor);
1450
+ return (await request(`${BASE}/diff?${params}`)).diff;
1451
+ }
1452
+ async function saveCatalogCandidate(input) {
1453
+ return (await request(`${BASE}/semantics`, json(input))).semantic;
1454
+ }
1455
+ async function verifyCatalogSemantic(input) {
1456
+ return (await request(`${BASE}/semantics/${encodeURIComponent(input.semanticId)}/verify`, json({
1457
+ sourceId: input.sourceId,
1458
+ expectedVersion: input.expectedVersion,
1459
+ definition: input.definition
1460
+ }))).semantic;
1461
+ }
1462
+ async function retireCatalogSemantic(input) {
1463
+ return (await request(`${BASE}/semantics/${encodeURIComponent(input.semanticId)}/retire`, json({
1464
+ sourceId: input.sourceId,
1465
+ expectedVersion: input.expectedVersion,
1466
+ revisionNote: input.revisionNote
1467
+ }))).semantic;
1468
+ }
1469
+ async function dismissCatalogMeaning(input) {
1470
+ return (await request(`${BASE}/semantics/${encodeURIComponent(input.semanticId)}/dismiss`, json({
1471
+ sourceId: input.sourceId,
1472
+ expectedVersion: input.expectedVersion
1473
+ }))).semantic;
1474
+ }
1475
+ function json(body) {
1476
+ return {
1477
+ method: "POST",
1478
+ headers: { "content-type": "application/json" },
1479
+ body: JSON.stringify(body)
1480
+ };
1481
+ }
1482
+ async function request(url, init) {
1483
+ const response = await fetch(url, init);
1484
+ let body;
1485
+ try {
1486
+ body = await response.json();
1487
+ } catch {
1488
+ body = void 0;
1489
+ }
1490
+ if (!response.ok) {
1491
+ const error = body !== null && typeof body === "object" && typeof body.error === "string" ? body.error : `HTTP ${response.status}`;
1492
+ throw new Error(error);
1493
+ }
1494
+ return body;
1495
+ }
1496
+ //#endregion
1497
+ //#region src/client/CatalogPanel.tsx
1498
+ const EMPTY_DRAFT = {
1499
+ name: "",
1500
+ aliases: "",
1501
+ description: "",
1502
+ formula: "",
1503
+ grain: "",
1504
+ sourceAssetIds: "",
1505
+ timeFieldAssetId: "",
1506
+ filters: "",
1507
+ exclusions: "",
1508
+ validFrom: "",
1509
+ validTo: "",
1510
+ owner: "",
1511
+ revisionNote: ""
1512
+ };
1513
+ const EMPTY_TERM_DRAFT = {
1514
+ name: "",
1515
+ aliases: "",
1516
+ description: "",
1517
+ sourceAssetIds: "",
1518
+ validFrom: "",
1519
+ validTo: "",
1520
+ owner: "",
1521
+ revisionNote: ""
1522
+ };
1523
+ const catalogPanelMemory = /* @__PURE__ */ new WeakMap();
1524
+ function CatalogPanel(props) {
1525
+ const { active, connected, connectionProfileId, sessionId, t, onAvailabilityChange } = props;
1526
+ const saved = catalogPanelMemory.get(props.stateKey);
1527
+ const [sources, setSources] = (0, react.useState)(saved?.sources ?? []);
1528
+ const [sourceId, setSourceId] = (0, react.useState)(saved?.sourceId ?? "");
1529
+ const [status, setStatus] = (0, react.useState)(saved?.status ?? null);
1530
+ const [busy, setBusy] = (0, react.useState)(false);
1531
+ const [error, setError] = (0, react.useState)(null);
1532
+ const [query, setQuery] = (0, react.useState)(saved?.query ?? "");
1533
+ const [schema, setSchema] = (0, react.useState)(saved?.schema ?? "");
1534
+ const [kind, setKind] = (0, react.useState)(saved?.kind ?? "relation");
1535
+ const [assetStatus, setAssetStatus] = (0, react.useState)(saved?.assetStatus ?? "observed");
1536
+ const [semanticStatus, setSemanticStatus] = (0, react.useState)(saved?.semanticStatus ?? "");
1537
+ const [includeInferred, setIncludeInferred] = (0, react.useState)(saved?.includeInferred ?? false);
1538
+ const [items, setItems] = (0, react.useState)(saved?.items ?? []);
1539
+ const [nextCursor, setNextCursor] = (0, react.useState)(saved?.nextCursor);
1540
+ const [selection, setSelection] = (0, react.useState)(saved?.selection ?? null);
1541
+ const [assetDetail, setAssetDetail] = (0, react.useState)(saved?.assetDetail ?? null);
1542
+ const [semanticDetail, setSemanticDetail] = (0, react.useState)(saved?.semanticDetail ?? null);
1543
+ const [detailTab, setDetailTab] = (0, react.useState)(saved?.detailTab ?? "technical");
1544
+ const [scanKind, setScanKind] = (0, react.useState)(saved?.scanKind ?? "schema");
1545
+ const [scanSchema, setScanSchema] = (0, react.useState)(saved?.scanSchema ?? "");
1546
+ const [scanTable, setScanTable] = (0, react.useState)(saved?.scanTable ?? "");
1547
+ const [confirmFull, setConfirmFull] = (0, react.useState)(false);
1548
+ const [diff, setDiff] = (0, react.useState)(saved?.diff ?? null);
1549
+ const [runs, setRuns] = (0, react.useState)(saved?.runs ?? []);
1550
+ const [diffFrom, setDiffFrom] = (0, react.useState)(saved?.diffFrom ?? "");
1551
+ const [diffTo, setDiffTo] = (0, react.useState)(saved?.diffTo ?? "");
1552
+ const [editingMetric, setEditingMetric] = (0, react.useState)(saved?.editingMetric ?? false);
1553
+ const [metricDraft, setMetricDraft] = (0, react.useState)(saved?.metricDraft ?? EMPTY_DRAFT);
1554
+ const [editingTerm, setEditingTerm] = (0, react.useState)(saved?.editingTerm ?? false);
1555
+ const [termDraft, setTermDraft] = (0, react.useState)(saved?.termDraft ?? EMPTY_TERM_DRAFT);
1556
+ const detailRequestId = (0, react.useRef)(0);
1557
+ const detailController = (0, react.useRef)(null);
1558
+ const previousSourceId = (0, react.useRef)(sourceId);
1559
+ const searchInput = (0, react.useRef)({
1560
+ query,
1561
+ schema,
1562
+ kind,
1563
+ assetStatus,
1564
+ semanticStatus,
1565
+ includeInferred
1566
+ });
1567
+ (0, react.useEffect)(() => {
1568
+ searchInput.current = {
1569
+ query,
1570
+ schema,
1571
+ kind,
1572
+ assetStatus,
1573
+ semanticStatus,
1574
+ includeInferred
1575
+ };
1576
+ }, [
1577
+ query,
1578
+ schema,
1579
+ kind,
1580
+ assetStatus,
1581
+ semanticStatus,
1582
+ includeInferred
1583
+ ]);
1584
+ (0, react.useEffect)(() => {
1585
+ catalogPanelMemory.set(props.stateKey, {
1586
+ sources,
1587
+ sourceId,
1588
+ status,
1589
+ query,
1590
+ schema,
1591
+ kind,
1592
+ assetStatus,
1593
+ semanticStatus,
1594
+ includeInferred,
1595
+ items,
1596
+ ...nextCursor !== void 0 ? { nextCursor } : {},
1597
+ selection,
1598
+ assetDetail,
1599
+ semanticDetail,
1600
+ detailTab,
1601
+ scanKind,
1602
+ scanSchema,
1603
+ scanTable,
1604
+ diff,
1605
+ runs,
1606
+ diffFrom,
1607
+ diffTo,
1608
+ editingMetric,
1609
+ metricDraft,
1610
+ editingTerm,
1611
+ termDraft
1612
+ });
1613
+ });
1614
+ const scanAllowed = connected && connectionProfileId !== void 0 && (sourceId === "" || sourceId === connectionProfileId);
1615
+ const activeRun = status?.activeRun;
1616
+ const reportError = (0, react.useCallback)((cause) => {
1617
+ setError(cause instanceof Error ? cause.message : String(cause));
1618
+ }, []);
1619
+ const refreshSources = (0, react.useCallback)(async (signal) => {
1620
+ const response = await listCatalogSources(signal);
1621
+ if (signal?.aborted) return [];
1622
+ const next = Array.isArray(response) ? response : [];
1623
+ setSources(next);
1624
+ onAvailabilityChange(next.length > 0);
1625
+ setSourceId((current) => {
1626
+ if (current !== "" && next.some((source) => source.id === current)) return current;
1627
+ if (connectionProfileId !== void 0 && next.some((source) => source.id === connectionProfileId)) return connectionProfileId;
1628
+ return next[0]?.id ?? "";
1629
+ });
1630
+ return next;
1631
+ }, [connectionProfileId, onAvailabilityChange]);
1632
+ (0, react.useEffect)(() => {
1633
+ const controller = new AbortController();
1634
+ refreshSources(controller.signal).catch((cause) => {
1635
+ if (!controller.signal.aborted) reportError(cause);
1636
+ });
1637
+ return () => controller.abort();
1638
+ }, [refreshSources, reportError]);
1639
+ (0, react.useEffect)(() => () => detailController.current?.abort(), []);
1640
+ const refreshStatus = (0, react.useCallback)(async (signal) => {
1641
+ if (sourceId === "") {
1642
+ setStatus(null);
1643
+ return null;
1644
+ }
1645
+ const next = await getCatalogStatus(sourceId, signal);
1646
+ if (signal?.aborted) return next;
1647
+ setStatus(next);
1648
+ return next;
1649
+ }, [sourceId]);
1650
+ const refreshRuns = (0, react.useCallback)(async (signal) => {
1651
+ if (sourceId === "") {
1652
+ setRuns([]);
1653
+ return;
1654
+ }
1655
+ const next = await listCatalogRuns(sourceId, signal);
1656
+ if (signal?.aborted) return;
1657
+ setRuns(next);
1658
+ const successful = next.filter((run) => run.status === "succeeded");
1659
+ setDiffFrom((current) => successful.some((run) => run.id === current) ? current : successful.at(-2)?.id ?? "");
1660
+ setDiffTo((current) => successful.some((run) => run.id === current) ? current : successful.at(-1)?.id ?? "");
1661
+ }, [sourceId]);
1662
+ const runSearch = (0, react.useCallback)(async (cursor, append = false, signal) => {
1663
+ if (sourceId === "") {
1664
+ setItems([]);
1665
+ setNextCursor(void 0);
1666
+ return;
1667
+ }
1668
+ const input = searchInput.current;
1669
+ const page = await searchCatalog({
1670
+ sourceId,
1671
+ query: input.query,
1672
+ ...input.schema !== "" ? { schema: input.schema } : {},
1673
+ ...input.kind === "relation" ? { assetKinds: ["table", "view"] } : {},
1674
+ ...input.kind !== "" && input.kind !== "relation" && input.kind !== "meaning" && input.kind !== "term" && input.kind !== "metric" ? { assetKinds: [input.kind] } : {},
1675
+ ...input.kind === "meaning" || input.kind === "term" || input.kind === "metric" ? { semanticKinds: [input.kind] } : {},
1676
+ ...input.assetStatus !== "" ? { assetStatuses: [input.assetStatus] } : {},
1677
+ ...input.semanticStatus !== "" ? { semanticStatuses: [input.semanticStatus] } : {},
1678
+ includeInferred: input.includeInferred,
1679
+ ...cursor !== void 0 ? { cursor } : {},
1680
+ pageSize: 50
1681
+ }, signal);
1682
+ if (signal?.aborted) return;
1683
+ setItems((current) => append ? [...current, ...page.items] : page.items);
1684
+ setNextCursor(page.nextCursor);
1685
+ }, [sourceId]);
1686
+ (0, react.useEffect)(() => {
1687
+ if (previousSourceId.current === sourceId) return;
1688
+ previousSourceId.current = sourceId;
1689
+ detailRequestId.current += 1;
1690
+ detailController.current?.abort();
1691
+ setSelection(null);
1692
+ setAssetDetail(null);
1693
+ setSemanticDetail(null);
1694
+ setDiff(null);
1695
+ setEditingMetric(false);
1696
+ setEditingTerm(false);
1697
+ const selectedSource = sources.find((source) => source.id === sourceId);
1698
+ const nextSearch = {
1699
+ query: "",
1700
+ schema: selectedSource === void 0 ? "" : defaultBrowseSchema(selectedSource),
1701
+ kind: "relation",
1702
+ assetStatus: "observed",
1703
+ semanticStatus: "",
1704
+ includeInferred: false
1705
+ };
1706
+ searchInput.current = nextSearch;
1707
+ setQuery(nextSearch.query);
1708
+ setSchema(nextSearch.schema);
1709
+ setKind(nextSearch.kind);
1710
+ setAssetStatus(nextSearch.assetStatus);
1711
+ setSemanticStatus(nextSearch.semanticStatus);
1712
+ setIncludeInferred(nextSearch.includeInferred);
1713
+ }, [sourceId, sources]);
1714
+ (0, react.useEffect)(() => {
1715
+ if (sourceId === "") return;
1716
+ const controller = new AbortController();
1717
+ setBusy(true);
1718
+ Promise.all([
1719
+ refreshStatus(controller.signal),
1720
+ refreshRuns(controller.signal),
1721
+ runSearch(void 0, false, controller.signal)
1722
+ ]).catch((cause) => {
1723
+ if (!controller.signal.aborted) reportError(cause);
1724
+ }).finally(() => {
1725
+ if (!controller.signal.aborted) setBusy(false);
1726
+ });
1727
+ return () => controller.abort();
1728
+ }, [
1729
+ sourceId,
1730
+ refreshStatus,
1731
+ refreshRuns,
1732
+ runSearch,
1733
+ reportError
1734
+ ]);
1735
+ (0, react.useEffect)(() => {
1736
+ if (!active || activeRun === void 0 || sourceId === "") return;
1737
+ const timer = window.setInterval(() => {
1738
+ refreshStatus().then((next) => Promise.all([runSearch(), ...next?.activeRun === void 0 ? [refreshSources(), refreshRuns()] : []])).catch(reportError);
1739
+ }, 1500);
1740
+ return () => window.clearInterval(timer);
1741
+ }, [
1742
+ active,
1743
+ activeRun,
1744
+ sourceId,
1745
+ refreshStatus,
1746
+ runSearch,
1747
+ refreshSources,
1748
+ refreshRuns,
1749
+ reportError
1750
+ ]);
1751
+ const selectItem = async (item) => {
1752
+ detailController.current?.abort();
1753
+ const controller = new AbortController();
1754
+ detailController.current = controller;
1755
+ const requestId = ++detailRequestId.current;
1756
+ setSelection({
1757
+ type: item.resultType,
1758
+ item
1759
+ });
1760
+ setDetailTab(item.resultType === "asset" ? "technical" : "business");
1761
+ setAssetDetail(null);
1762
+ setSemanticDetail(null);
1763
+ setEditingMetric(false);
1764
+ setEditingTerm(false);
1765
+ setBusy(true);
1766
+ setError(null);
1767
+ try {
1768
+ if (item.resultType === "asset") {
1769
+ const detail = await getCatalogAsset(sourceId, item.id, void 0, controller.signal);
1770
+ if (requestId === detailRequestId.current) setAssetDetail(detail);
1771
+ } else {
1772
+ const semantic = await getCatalogSemantic(sourceId, item.id, void 0, controller.signal);
1773
+ if (requestId !== detailRequestId.current) return;
1774
+ setSemanticDetail(semantic);
1775
+ if (semantic.definition.kind === "metric") setMetricDraft(draftFromSemantic(semantic));
1776
+ else if (semantic.definition.kind === "term") setTermDraft(termDraftFromSemantic(semantic));
1777
+ }
1778
+ } catch (cause) {
1779
+ if (!controller.signal.aborted && requestId === detailRequestId.current) reportError(cause);
1780
+ } finally {
1781
+ setBusy((current) => requestId === detailRequestId.current ? false : current);
1782
+ }
1783
+ };
1784
+ const loadMoreFields = async () => {
1785
+ if (assetDetail?.nextCursor === void 0 || sourceId === "") return;
1786
+ setBusy(true);
1787
+ try {
1788
+ const next = await getCatalogAsset(sourceId, assetDetail.asset.assetId, assetDetail.nextCursor);
1789
+ setAssetDetail({
1790
+ ...next,
1791
+ fields: [...assetDetail.fields, ...next.fields],
1792
+ relations: [...new Map([...assetDetail.relations, ...next.relations].map((value) => [value.id, value])).values()],
1793
+ semantics: [...new Map([...assetDetail.semantics, ...next.semantics].map((value) => [value.semanticId, value])).values()],
1794
+ history: [...new Map([...assetDetail.history, ...next.history].map((value) => [value.id, value])).values()]
1795
+ });
1796
+ } catch (cause) {
1797
+ reportError(cause);
1798
+ } finally {
1799
+ setBusy(false);
1800
+ }
1801
+ };
1802
+ const beginScan = async () => {
1803
+ if (!scanAllowed) {
1804
+ setError(t("catalog.scan.reconnect"));
1805
+ return;
1806
+ }
1807
+ if (scanKind === "source" && !confirmFull) {
1808
+ setConfirmFull(true);
1809
+ return;
1810
+ }
1811
+ let scope;
1812
+ if (scanKind === "source") scope = { kind: "source" };
1813
+ else if (scanKind === "schema") {
1814
+ if (scanSchema.trim() === "") {
1815
+ setError(t("catalog.validation.schema"));
1816
+ return;
1817
+ }
1818
+ scope = {
1819
+ kind: "schema",
1820
+ schema: scanSchema.trim()
1821
+ };
1822
+ } else {
1823
+ if (scanSchema.trim() === "" || scanTable.trim() === "") {
1824
+ setError(t("catalog.validation.table"));
1825
+ return;
1826
+ }
1827
+ scope = {
1828
+ kind: "table",
1829
+ schema: scanSchema.trim(),
1830
+ table: scanTable.trim()
1831
+ };
1832
+ }
1833
+ setBusy(true);
1834
+ setError(null);
1835
+ try {
1836
+ await startCatalogScan(sessionId, scope);
1837
+ const nextSources = await refreshSources();
1838
+ const nextSourceId = connectionProfileId ?? nextSources[0]?.id;
1839
+ if (nextSourceId !== void 0) {
1840
+ setSourceId(nextSourceId);
1841
+ setStatus(await getCatalogStatus(nextSourceId));
1842
+ }
1843
+ setConfirmFull(false);
1844
+ } catch (cause) {
1845
+ reportError(cause);
1846
+ } finally {
1847
+ setBusy(false);
1848
+ }
1849
+ };
1850
+ const cancelScan = async () => {
1851
+ if (sourceId === "" || activeRun === void 0) return;
1852
+ setBusy(true);
1853
+ try {
1854
+ await cancelCatalogScan(sourceId, activeRun.id);
1855
+ await refreshStatus();
1856
+ } catch (cause) {
1857
+ reportError(cause);
1858
+ } finally {
1859
+ setBusy(false);
1860
+ }
1861
+ };
1862
+ const loadDiff = async (cursor, append = false) => {
1863
+ if (sourceId === "") return;
1864
+ setBusy(true);
1865
+ try {
1866
+ const next = await getCatalogDiff(sourceId, diffFrom || void 0, diffTo || void 0, cursor);
1867
+ setDiff((current) => append && current !== null ? {
1868
+ ...next,
1869
+ items: [...current.items, ...next.items]
1870
+ } : next);
1871
+ } catch (cause) {
1872
+ reportError(cause);
1873
+ } finally {
1874
+ setBusy(false);
1875
+ }
1876
+ };
1877
+ const startMetric = (semantic) => {
1878
+ setEditingMetric(true);
1879
+ setEditingTerm(false);
1880
+ setDetailTab("business");
1881
+ setMetricDraft(semantic?.definition.kind === "metric" ? draftFromSemantic(semantic) : {
1882
+ ...EMPTY_DRAFT,
1883
+ sourceAssetIds: selection?.type === "asset" ? selection.item.id : ""
1884
+ });
1885
+ };
1886
+ const startTerm = (semantic) => {
1887
+ setEditingTerm(true);
1888
+ setEditingMetric(false);
1889
+ setDetailTab("business");
1890
+ setTermDraft(semantic?.definition.kind === "term" ? termDraftFromSemantic(semantic) : {
1891
+ ...EMPTY_TERM_DRAFT,
1892
+ sourceAssetIds: selection?.type === "asset" ? selection.item.id : ""
1893
+ });
1894
+ };
1895
+ const metricDefinition = (state) => {
1896
+ return {
1897
+ kind: "metric",
1898
+ name: metricDraft.name,
1899
+ aliases: splitList(metricDraft.aliases),
1900
+ description: metricDraft.description,
1901
+ owner: metricDraft.owner || void 0,
1902
+ sourceAssetIds: splitList(metricDraft.sourceAssetIds),
1903
+ status: state,
1904
+ formula: metricDraft.formula,
1905
+ grain: metricDraft.grain,
1906
+ timeFieldAssetId: metricDraft.timeFieldAssetId || void 0,
1907
+ filters: splitLines(metricDraft.filters),
1908
+ exclusions: splitLines(metricDraft.exclusions),
1909
+ validFrom: metricDraft.validFrom || void 0,
1910
+ validTo: metricDraft.validTo || void 0,
1911
+ revisionNote: metricDraft.revisionNote
1912
+ };
1913
+ };
1914
+ const termDefinition = (state) => ({
1915
+ kind: "term",
1916
+ name: termDraft.name,
1917
+ aliases: splitList(termDraft.aliases),
1918
+ description: termDraft.description,
1919
+ owner: termDraft.owner || void 0,
1920
+ sourceAssetIds: splitList(termDraft.sourceAssetIds),
1921
+ status: state,
1922
+ validFrom: termDraft.validFrom || void 0,
1923
+ validTo: termDraft.validTo || void 0,
1924
+ revisionNote: termDraft.revisionNote
1925
+ });
1926
+ const saveMetric = async (verify) => {
1927
+ if (sourceId === "" || metricDraft.name.trim() === "" || metricDraft.formula.trim() === "" || metricDraft.grain.trim() === "") return;
1928
+ setBusy(true);
1929
+ setError(null);
1930
+ try {
1931
+ const semantic = verify && semanticDetail !== null ? await verifyCatalogSemantic({
1932
+ sourceId,
1933
+ semanticId: semanticDetail.semanticId,
1934
+ expectedVersion: semanticDetail.version,
1935
+ definition: metricDefinition("verified")
1936
+ }) : await saveCatalogCandidate({
1937
+ sourceId,
1938
+ ...semanticDetail !== null ? {
1939
+ semanticId: semanticDetail.semanticId,
1940
+ expectedVersion: semanticDetail.version
1941
+ } : {},
1942
+ definition: metricDefinition("inferred")
1943
+ });
1944
+ setSemanticDetail(semantic);
1945
+ setMetricDraft(draftFromSemantic(semantic));
1946
+ setEditingMetric(false);
1947
+ await runSearch();
1948
+ await refreshStatus();
1949
+ } catch (cause) {
1950
+ reportError(cause);
1951
+ } finally {
1952
+ setBusy(false);
1953
+ }
1954
+ };
1955
+ const saveTerm = async (verify) => {
1956
+ if (sourceId === "" || termDraft.name.trim() === "" || termDraft.description.trim() === "") return;
1957
+ setBusy(true);
1958
+ setError(null);
1959
+ try {
1960
+ const semantic = verify && semanticDetail !== null ? await verifyCatalogSemantic({
1961
+ sourceId,
1962
+ semanticId: semanticDetail.semanticId,
1963
+ expectedVersion: semanticDetail.version,
1964
+ definition: termDefinition("verified")
1965
+ }) : await saveCatalogCandidate({
1966
+ sourceId,
1967
+ ...semanticDetail !== null ? {
1968
+ semanticId: semanticDetail.semanticId,
1969
+ expectedVersion: semanticDetail.version
1970
+ } : {},
1971
+ definition: termDefinition("inferred")
1972
+ });
1973
+ setSemanticDetail(semantic);
1974
+ setTermDraft(termDraftFromSemantic(semantic));
1975
+ setEditingTerm(false);
1976
+ await runSearch();
1977
+ await refreshStatus();
1978
+ } catch (cause) {
1979
+ reportError(cause);
1980
+ } finally {
1981
+ setBusy(false);
1982
+ }
1983
+ };
1984
+ const retireSemantic = async (revisionNote) => {
1985
+ if (sourceId === "" || semanticDetail === null || revisionNote.trim() === "") return;
1986
+ setBusy(true);
1987
+ try {
1988
+ const semantic = await retireCatalogSemantic({
1989
+ sourceId,
1990
+ semanticId: semanticDetail.semanticId,
1991
+ expectedVersion: semanticDetail.version,
1992
+ revisionNote
1993
+ });
1994
+ setSemanticDetail(semantic);
1995
+ await runSearch();
1996
+ await refreshStatus();
1997
+ } catch (cause) {
1998
+ reportError(cause);
1999
+ } finally {
2000
+ setBusy(false);
2001
+ }
2002
+ };
2003
+ const refreshSelectedAsset = async () => {
2004
+ if (sourceId === "" || assetDetail === null) return;
2005
+ setAssetDetail(await getCatalogAsset(sourceId, assetDetail.asset.assetId));
2006
+ };
2007
+ const confirmMeaning = async (meaning) => {
2008
+ if (sourceId === "" || meaning.definition.kind !== "meaning") return;
2009
+ setBusy(true);
2010
+ setError(null);
2011
+ try {
2012
+ const semantic = await verifyCatalogSemantic({
2013
+ sourceId,
2014
+ semanticId: meaning.semanticId,
2015
+ expectedVersion: meaning.version,
2016
+ definition: {
2017
+ ...meaning.definition,
2018
+ status: "verified",
2019
+ revisionNote: "AI-generated business meaning confirmed in Catalog UI"
2020
+ }
2021
+ });
2022
+ if (semanticDetail?.semanticId === semantic.semanticId) setSemanticDetail(semantic);
2023
+ await Promise.all([
2024
+ refreshSelectedAsset(),
2025
+ runSearch(),
2026
+ refreshStatus()
2027
+ ]);
2028
+ } catch (cause) {
2029
+ reportError(cause);
2030
+ } finally {
2031
+ setBusy(false);
2032
+ }
2033
+ };
2034
+ const dismissMeaning = async (meaning) => {
2035
+ if (sourceId === "" || meaning.definition.kind !== "meaning") return;
2036
+ setBusy(true);
2037
+ setError(null);
2038
+ try {
2039
+ await dismissCatalogMeaning({
2040
+ sourceId,
2041
+ semanticId: meaning.semanticId,
2042
+ expectedVersion: meaning.version
2043
+ });
2044
+ if (semanticDetail?.semanticId === meaning.semanticId) setSemanticDetail(null);
2045
+ await Promise.all([
2046
+ refreshSelectedAsset(),
2047
+ runSearch(),
2048
+ refreshStatus()
2049
+ ]);
2050
+ } catch (cause) {
2051
+ reportError(cause);
2052
+ } finally {
2053
+ setBusy(false);
2054
+ }
2055
+ };
2056
+ const statusLabel = (value) => {
2057
+ const key = `catalog.state.${value}`;
2058
+ return key in STATUS_KEYS ? t(key) : value;
2059
+ };
2060
+ const kindLabel = (value) => {
2061
+ const key = `catalog.kind.${value}`;
2062
+ return key in KIND_KEYS ? t(key) : value;
2063
+ };
2064
+ const displayedSource = sources.find((source) => source.id === sourceId);
2065
+ const scopeInputs = scanKind !== "source";
2066
+ const technicalRows = assetDetail?.fields ?? [];
2067
+ const businessDefinitions = assetDetail?.semantics ?? (semanticDetail ? [semanticDetail] : []);
2068
+ const meaningDefinitions = businessDefinitions.filter((value) => value.definition.kind === "meaning");
2069
+ const governedDefinitions = businessDefinitions.filter((value) => value.definition.kind !== "meaning");
2070
+ const assetKind = assetDetail?.asset.payload.identity.kind;
2071
+ const relationDetail = assetKind === "table" || assetKind === "view";
2072
+ const fieldDetail = assetKind === "column";
2073
+ const fieldCount = assetDetail === null ? 0 : `${technicalRows.length}${assetDetail.nextCursor === void 0 ? "" : "+"}`;
2074
+ const tableMeaning = assetDetail === null ? void 0 : meaningDefinitions.find((value) => value.definition.kind === "meaning" && value.definition.targetAssetId === assetDetail.asset.assetId);
2075
+ const fieldMeanings = new Map(meaningDefinitions.flatMap((value) => value.definition.kind === "meaning" ? [[value.definition.targetAssetId, value]] : []));
2076
+ const canVerify = semanticDetail !== null && semanticDetail.definition.status !== "retired";
2077
+ const canSaveMetric = metricDraft.name.trim() !== "" && metricDraft.formula.trim() !== "" && metricDraft.grain.trim() !== "";
2078
+ const canSaveTerm = termDraft.name.trim() !== "" && termDraft.description.trim() !== "";
2079
+ const canVerifyMetric = canVerify && canSaveMetric && metricDraft.revisionNote.trim() !== "";
2080
+ const canVerifyTerm = canVerify && canSaveTerm && termDraft.revisionNote.trim() !== "";
2081
+ const successfulRuns = runs.filter((run) => run.status === "succeeded");
2082
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2083
+ id: props.id,
2084
+ role: "tabpanel",
2085
+ "aria-labelledby": props.labelledBy,
2086
+ className: `${DataAgentWorkbench_module_css_default.tabPanel} ${DataAgentWorkbench_module_css_default.catalogPanel}`,
2087
+ hidden: !active,
2088
+ children: [
2089
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2090
+ className: DataAgentWorkbench_module_css_default.catalogToolbar,
2091
+ children: [
2092
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2093
+ className: DataAgentWorkbench_module_css_default.catalogOverview,
2094
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2095
+ className: DataAgentWorkbench_module_css_default.catalogControl,
2096
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("catalog.source") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2097
+ className: DataAgentWorkbench_module_css_default.input,
2098
+ value: sourceId,
2099
+ onChange: (event) => setSourceId(event.target.value),
2100
+ children: [sources.length === 0 && connectionProfileId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2101
+ value: "",
2102
+ children: t("catalog.source.current")
2103
+ }), sources.map((source) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
2104
+ value: source.id,
2105
+ children: [
2106
+ source.name,
2107
+ " · ",
2108
+ source.database
2109
+ ]
2110
+ }, source.id))]
2111
+ })]
2112
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2113
+ className: DataAgentWorkbench_module_css_default.catalogStats,
2114
+ role: "status",
2115
+ children: [
2116
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
2117
+ className: DataAgentWorkbench_module_css_default.catalogSourceName,
2118
+ children: displayedSource?.name ?? t("catalog.status.never")
2119
+ }),
2120
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2121
+ className: DataAgentWorkbench_module_css_default.catalogCounts,
2122
+ children: [
2123
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status?.counts.assets ?? 0 }), t("catalog.count.assets")] }),
2124
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status?.counts.fields ?? 0 }), t("catalog.count.fields")] }),
2125
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status?.counts.needsReview ?? 0 }), t("catalog.count.review")] })
2126
+ ]
2127
+ }),
2128
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2129
+ className: DataAgentWorkbench_module_css_default.catalogScanTimes,
2130
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
2131
+ t("catalog.status.full"),
2132
+ " ",
2133
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", { children: displayedSource?.lastFullScanAt ?? "—" })
2134
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
2135
+ t("catalog.status.partial"),
2136
+ " ",
2137
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", { children: displayedSource?.lastPartialScanAt ?? "—" })
2138
+ ] })]
2139
+ })
2140
+ ]
2141
+ })]
2142
+ }),
2143
+ status?.latestRun !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2144
+ className: DataAgentWorkbench_module_css_default.catalogLatestRun,
2145
+ "data-error": status.latestRun.status === "failed" || status.latestRun.enrichment?.status === "failed" || void 0,
2146
+ children: [
2147
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2148
+ className: DataAgentWorkbench_module_css_default.catalogLatestLabel,
2149
+ children: t("catalog.status.latest")
2150
+ }),
2151
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2152
+ className: DataAgentWorkbench_module_css_default.catalogBadge,
2153
+ children: statusLabel(status.latestRun.status)
2154
+ }),
2155
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
2156
+ title: status.latestRun.id,
2157
+ children: status.latestRun.id
2158
+ }),
2159
+ status.latestRun.error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2160
+ className: DataAgentWorkbench_module_css_default.catalogLatestError,
2161
+ children: [
2162
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("catalog.status.failureReason") }),
2163
+ " ",
2164
+ status.latestRun.error
2165
+ ]
2166
+ }),
2167
+ status.latestRun.enrichment !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2168
+ className: DataAgentWorkbench_module_css_default.catalogLatestError,
2169
+ children: [
2170
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("catalog.enrichment.label") }),
2171
+ " ",
2172
+ t(`catalog.enrichment.${status.latestRun.enrichment.status}`),
2173
+ " · ",
2174
+ status.latestRun.enrichment.tablesCompleted,
2175
+ "/",
2176
+ status.latestRun.enrichment.tablesTotal,
2177
+ status.latestRun.enrichment.error !== void 0 ? ` · ${status.latestRun.enrichment.error}` : ""
2178
+ ]
2179
+ })
2180
+ ]
2181
+ }),
2182
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2183
+ className: DataAgentWorkbench_module_css_default.catalogActions,
2184
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2185
+ className: DataAgentWorkbench_module_css_default.catalogActionGroup,
2186
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2187
+ className: DataAgentWorkbench_module_css_default.catalogSectionLabel,
2188
+ children: t("catalog.section.scan")
2189
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2190
+ className: DataAgentWorkbench_module_css_default.catalogScanBar,
2191
+ children: [
2192
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2193
+ className: DataAgentWorkbench_module_css_default.input,
2194
+ value: scanKind,
2195
+ disabled: activeRun !== void 0,
2196
+ onChange: (event) => {
2197
+ setScanKind(event.target.value);
2198
+ setConfirmFull(false);
2199
+ },
2200
+ "aria-label": t("catalog.scan"),
2201
+ children: [
2202
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2203
+ value: "source",
2204
+ children: t("catalog.scan.all")
2205
+ }),
2206
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2207
+ value: "schema",
2208
+ children: t("catalog.scan.schema")
2209
+ }),
2210
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2211
+ value: "table",
2212
+ children: t("catalog.scan.table")
2213
+ })
2214
+ ]
2215
+ }),
2216
+ scopeInputs && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2217
+ className: DataAgentWorkbench_module_css_default.input,
2218
+ value: scanSchema,
2219
+ onChange: (event) => setScanSchema(event.target.value),
2220
+ placeholder: t("catalog.schema"),
2221
+ "aria-label": t("catalog.schema")
2222
+ }),
2223
+ scanKind === "table" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2224
+ className: DataAgentWorkbench_module_css_default.input,
2225
+ value: scanTable,
2226
+ onChange: (event) => setScanTable(event.target.value),
2227
+ placeholder: t("catalog.table"),
2228
+ "aria-label": t("catalog.table")
2229
+ }),
2230
+ activeRun === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2231
+ type: "button",
2232
+ className: DataAgentWorkbench_module_css_default.primary,
2233
+ disabled: busy || !scanAllowed,
2234
+ onClick: () => {
2235
+ beginScan();
2236
+ },
2237
+ children: t("catalog.scan")
2238
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2239
+ type: "button",
2240
+ className: DataAgentWorkbench_module_css_default.ghost,
2241
+ disabled: busy,
2242
+ onClick: () => {
2243
+ cancelScan();
2244
+ },
2245
+ children: t("catalog.cancel")
2246
+ })
2247
+ ]
2248
+ }), !scanAllowed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2249
+ className: DataAgentWorkbench_module_css_default.catalogInlineNotice,
2250
+ children: t("catalog.scan.reconnect")
2251
+ })] })]
2252
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2253
+ className: DataAgentWorkbench_module_css_default.catalogActionGroup,
2254
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2255
+ className: DataAgentWorkbench_module_css_default.catalogSectionLabel,
2256
+ children: t("catalog.section.diff")
2257
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2258
+ className: DataAgentWorkbench_module_css_default.catalogDiffBar,
2259
+ children: [
2260
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2261
+ className: DataAgentWorkbench_module_css_default.input,
2262
+ value: diffFrom,
2263
+ onChange: (event) => setDiffFrom(event.target.value),
2264
+ "aria-label": t("catalog.diff.from"),
2265
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2266
+ value: "",
2267
+ children: t("catalog.diff.from")
2268
+ }), successfulRuns.map((run) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2269
+ value: run.id,
2270
+ children: run.id
2271
+ }, run.id))]
2272
+ }),
2273
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2274
+ className: DataAgentWorkbench_module_css_default.input,
2275
+ value: diffTo,
2276
+ onChange: (event) => setDiffTo(event.target.value),
2277
+ "aria-label": t("catalog.diff.to"),
2278
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2279
+ value: "",
2280
+ children: t("catalog.diff.to")
2281
+ }), successfulRuns.map((run) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2282
+ value: run.id,
2283
+ children: run.id
2284
+ }, run.id))]
2285
+ }),
2286
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2287
+ type: "button",
2288
+ className: DataAgentWorkbench_module_css_default.ghost,
2289
+ disabled: busy || sourceId === "",
2290
+ onClick: () => {
2291
+ loadDiff();
2292
+ },
2293
+ children: t("catalog.diff")
2294
+ })
2295
+ ]
2296
+ })]
2297
+ })]
2298
+ })
2299
+ ]
2300
+ }),
2301
+ confirmFull && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2302
+ className: DataAgentWorkbench_module_css_default.catalogConfirm,
2303
+ role: "alert",
2304
+ children: [
2305
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("catalog.scan.confirm") }),
2306
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2307
+ type: "button",
2308
+ className: DataAgentWorkbench_module_css_default.primary,
2309
+ onClick: () => {
2310
+ beginScan();
2311
+ },
2312
+ children: t("catalog.scan.all")
2313
+ }),
2314
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2315
+ type: "button",
2316
+ className: DataAgentWorkbench_module_css_default.ghost,
2317
+ onClick: () => setConfirmFull(false),
2318
+ children: t("action.close")
2319
+ })
2320
+ ]
2321
+ }),
2322
+ activeRun !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2323
+ className: DataAgentWorkbench_module_css_default.catalogProgress,
2324
+ role: "status",
2325
+ children: [
2326
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: activeRun.enrichment?.status === "running" ? t("catalog.enrichment.running") : statusLabel(activeRun.status) }),
2327
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: activeRun.enrichment?.status === "running" ? t("catalog.enrichment.progress", {
2328
+ completed: activeRun.enrichment.tablesCompleted,
2329
+ total: activeRun.enrichment.tablesTotal,
2330
+ candidates: activeRun.enrichment.candidatesGenerated
2331
+ }) : t("catalog.progress", {
2332
+ schemas: activeRun.progress.schemas,
2333
+ relations: activeRun.progress.relations,
2334
+ fields: activeRun.progress.fields
2335
+ }) }),
2336
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: activeRun.id })
2337
+ ]
2338
+ }),
2339
+ error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2340
+ className: DataAgentWorkbench_module_css_default.catalogError,
2341
+ role: "alert",
2342
+ children: error
2343
+ }),
2344
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2345
+ className: DataAgentWorkbench_module_css_default.catalogNotice,
2346
+ children: t("catalog.warning.untrusted")
2347
+ }),
2348
+ sources.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2349
+ className: DataAgentWorkbench_module_css_default.emptyState,
2350
+ children: t("catalog.empty")
2351
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2352
+ className: DataAgentWorkbench_module_css_default.catalogWorkspace,
2353
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2354
+ className: DataAgentWorkbench_module_css_default.catalogResults,
2355
+ children: [
2356
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
2357
+ className: DataAgentWorkbench_module_css_default.catalogSearch,
2358
+ onSubmit: (event) => {
2359
+ event.preventDefault();
2360
+ setBusy(true);
2361
+ runSearch().catch(reportError).finally(() => setBusy(false));
2362
+ },
2363
+ children: [
2364
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2365
+ className: `${DataAgentWorkbench_module_css_default.input} ${DataAgentWorkbench_module_css_default.catalogSearchQuery}`,
2366
+ value: query,
2367
+ onChange: (event) => setQuery(event.target.value),
2368
+ placeholder: t("catalog.search"),
2369
+ "aria-label": t("catalog.search")
2370
+ }),
2371
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2372
+ className: DataAgentWorkbench_module_css_default.input,
2373
+ value: schema,
2374
+ onChange: (event) => setSchema(event.target.value),
2375
+ placeholder: t("catalog.schema"),
2376
+ "aria-label": t("catalog.schema.filter")
2377
+ }),
2378
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2379
+ className: DataAgentWorkbench_module_css_default.input,
2380
+ value: kind,
2381
+ onChange: (event) => setKind(event.target.value),
2382
+ "aria-label": t("catalog.filter.all"),
2383
+ children: [
2384
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2385
+ value: "relation",
2386
+ children: t("catalog.filter.tables")
2387
+ }),
2388
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2389
+ value: "",
2390
+ children: t("catalog.filter.all")
2391
+ }),
2392
+ [
2393
+ "schema",
2394
+ "table",
2395
+ "view",
2396
+ "column",
2397
+ "primary_key",
2398
+ "foreign_key",
2399
+ "index",
2400
+ "meaning",
2401
+ "term",
2402
+ "metric"
2403
+ ].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2404
+ value,
2405
+ children: kindLabel(value)
2406
+ }, value))
2407
+ ]
2408
+ }),
2409
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2410
+ className: DataAgentWorkbench_module_css_default.input,
2411
+ value: assetStatus,
2412
+ onChange: (event) => setAssetStatus(event.target.value),
2413
+ "aria-label": t("catalog.filter.assetStatus"),
2414
+ children: [
2415
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2416
+ value: "",
2417
+ children: t("catalog.filter.assetStatus")
2418
+ }),
2419
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2420
+ value: "observed",
2421
+ children: t("catalog.state.observed")
2422
+ }),
2423
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2424
+ value: "missing",
2425
+ children: t("catalog.state.missing")
2426
+ }),
2427
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2428
+ value: "unavailable",
2429
+ children: t("catalog.state.unavailable")
2430
+ })
2431
+ ]
2432
+ }),
2433
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
2434
+ className: DataAgentWorkbench_module_css_default.input,
2435
+ value: semanticStatus,
2436
+ onChange: (event) => setSemanticStatus(event.target.value),
2437
+ "aria-label": t("catalog.filter.semanticStatus"),
2438
+ children: [
2439
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2440
+ value: "",
2441
+ children: t("catalog.filter.semanticStatus")
2442
+ }),
2443
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2444
+ value: "inferred",
2445
+ children: t("catalog.state.inferred")
2446
+ }),
2447
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2448
+ value: "verified",
2449
+ children: t("catalog.state.verified")
2450
+ }),
2451
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2452
+ value: "needs_review",
2453
+ children: t("catalog.state.needs_review")
2454
+ }),
2455
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
2456
+ value: "retired",
2457
+ children: t("catalog.state.retired")
2458
+ })
2459
+ ]
2460
+ }),
2461
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2462
+ className: DataAgentWorkbench_module_css_default.catalogSearchActions,
2463
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2464
+ className: DataAgentWorkbench_module_css_default.catalogCheck,
2465
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2466
+ type: "checkbox",
2467
+ checked: includeInferred,
2468
+ onChange: (event) => setIncludeInferred(event.target.checked)
2469
+ }), t("catalog.filter.review")]
2470
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2471
+ type: "submit",
2472
+ className: DataAgentWorkbench_module_css_default.ghost,
2473
+ disabled: busy,
2474
+ children: t("catalog.refresh")
2475
+ })]
2476
+ })
2477
+ ]
2478
+ }),
2479
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2480
+ className: DataAgentWorkbench_module_css_default.catalogList,
2481
+ role: "listbox",
2482
+ "aria-label": t("action.catalog"),
2483
+ children: [items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2484
+ type: "button",
2485
+ role: "option",
2486
+ "aria-selected": selection?.item.id === item.id,
2487
+ className: `${DataAgentWorkbench_module_css_default.catalogItem}${selection?.item.id === item.id ? ` ${DataAgentWorkbench_module_css_default.catalogItemActive}` : ""}`,
2488
+ onClick: () => {
2489
+ selectItem(item);
2490
+ },
2491
+ children: [
2492
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2493
+ className: DataAgentWorkbench_module_css_default.catalogItemHead,
2494
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: item.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
2495
+ value: statusLabel(item.status),
2496
+ state: item.status
2497
+ })]
2498
+ }),
2499
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
2500
+ title: item.path,
2501
+ children: parentPath(item.path, item.name)
2502
+ }),
2503
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [kindLabel(item.kind), item.summary.trim() === "" ? "" : ` · ${item.summary}`] })
2504
+ ]
2505
+ }, `${item.resultType}:${item.id}`)), items.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2506
+ className: DataAgentWorkbench_module_css_default.catalogListEmpty,
2507
+ children: busy ? t("wb.loading") : t("wb.empty")
2508
+ })]
2509
+ }),
2510
+ nextCursor !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2511
+ type: "button",
2512
+ className: DataAgentWorkbench_module_css_default.ghost,
2513
+ disabled: busy,
2514
+ onClick: () => {
2515
+ setBusy(true);
2516
+ runSearch(nextCursor, true).catch(reportError).finally(() => setBusy(false));
2517
+ },
2518
+ children: t("catalog.loadMore")
2519
+ })
2520
+ ]
2521
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2522
+ className: DataAgentWorkbench_module_css_default.catalogDetail,
2523
+ children: selection === null && diff === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2524
+ className: DataAgentWorkbench_module_css_default.emptyState,
2525
+ children: t("catalog.detail.select")
2526
+ }) : diff !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DiffView, {
2527
+ diff,
2528
+ statusLabel,
2529
+ onClose: () => setDiff(null),
2530
+ onLoadMore: () => {
2531
+ if (diff.nextCursor !== void 0) loadDiff(diff.nextCursor, true);
2532
+ },
2533
+ busy,
2534
+ t
2535
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2536
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2537
+ className: DataAgentWorkbench_module_css_default.catalogDetailHeader,
2538
+ children: [
2539
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2540
+ className: DataAgentWorkbench_module_css_default.catalogDetailTitle,
2541
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: selection?.item.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
2542
+ title: selection?.item.path,
2543
+ children: selection?.item.path
2544
+ })] }), selection !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
2545
+ value: statusLabel(selection.item.status),
2546
+ state: selection.item.status
2547
+ })]
2548
+ }),
2549
+ assetDetail !== null && relationDetail && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2550
+ className: DataAgentWorkbench_module_css_default.catalogDetailCounts,
2551
+ "aria-label": t("catalog.detail.summary"),
2552
+ children: [
2553
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: fieldCount }), t("catalog.detail.fields")] }),
2554
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: assetDetail.relations.length }), t("catalog.detail.relationCount")] }),
2555
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: businessDefinitions.length }), t("catalog.detail.definitionCount")] })
2556
+ ]
2557
+ }),
2558
+ assetDetail?.asset.payload.comment && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: assetDetail.asset.payload.comment })
2559
+ ]
2560
+ }),
2561
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2562
+ className: DataAgentWorkbench_module_css_default.catalogDetailTabs,
2563
+ role: "tablist",
2564
+ children: [
2565
+ "technical",
2566
+ "business",
2567
+ "history"
2568
+ ].map((tab) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2569
+ type: "button",
2570
+ role: "tab",
2571
+ "aria-selected": detailTab === tab,
2572
+ className: detailTab === tab ? DataAgentWorkbench_module_css_default.catalogDetailTabActive : DataAgentWorkbench_module_css_default.catalogDetailTab,
2573
+ onClick: () => setDetailTab(tab),
2574
+ children: t(`catalog.detail.${tab}`)
2575
+ }, tab))
2576
+ }),
2577
+ detailTab === "technical" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2578
+ className: DataAgentWorkbench_module_css_default.catalogDetailScroll,
2579
+ children: assetDetail === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2580
+ className: DataAgentWorkbench_module_css_default.hint,
2581
+ children: t("wb.empty")
2582
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2583
+ fieldDetail && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
2584
+ className: DataAgentWorkbench_module_css_default.catalogFacts,
2585
+ children: [
2586
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("catalog.detail.type") }),
2587
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: assetDetail.asset.payload.dataType ?? "—" }),
2588
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("catalog.detail.nullable") }),
2589
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: nullableLabel(assetDetail.asset.payload.nullable, t) }),
2590
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("catalog.detail.parentTable") }),
2591
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: assetDetail.asset.payload.identity.relation ?? "—" })
2592
+ ]
2593
+ }),
2594
+ relationDetail && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2595
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", { children: t("catalog.detail.fields") }),
2596
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
2597
+ className: DataAgentWorkbench_module_css_default.columnsTable,
2598
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2599
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("catalog.detail.name") }),
2600
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("catalog.detail.type") }),
2601
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: t("catalog.detail.nullable") })
2602
+ ] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: technicalRows.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
2603
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: field.payload.name }),
2604
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: field.payload.dataType }),
2605
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: nullableLabel(field.payload.nullable, t) })
2606
+ ] }, field.assetId)) })]
2607
+ }),
2608
+ assetDetail.nextCursor !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2609
+ type: "button",
2610
+ className: DataAgentWorkbench_module_css_default.ghost,
2611
+ disabled: busy,
2612
+ onClick: () => {
2613
+ loadMoreFields();
2614
+ },
2615
+ children: t("catalog.loadMore")
2616
+ })
2617
+ ] }),
2618
+ assetDetail.relations.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2619
+ className: DataAgentWorkbench_module_css_default.catalogRelations,
2620
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", { children: t("catalog.detail.relations") }), assetDetail.relations.map((relation) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2621
+ className: DataAgentWorkbench_module_css_default.catalogHistoryItem,
2622
+ children: [
2623
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: kindLabel(relation.kind) }),
2624
+ " ",
2625
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: relation.name }),
2626
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("code", { children: [relation.fromAssetId, relation.toAssetId ? ` → ${relation.toAssetId}` : ""] })
2627
+ ]
2628
+ }, relation.id))]
2629
+ }),
2630
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
2631
+ className: DataAgentWorkbench_module_css_default.catalogScanFacts,
2632
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("catalog.detail.scanFacts") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
2633
+ className: DataAgentWorkbench_module_css_default.catalogFacts,
2634
+ children: [
2635
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("catalog.detail.provenance") }),
2636
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dd", { children: [
2637
+ assetDetail.asset.payload.provenance.source,
2638
+ " · ",
2639
+ assetDetail.asset.payload.provenance.dialect
2640
+ ] }),
2641
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("catalog.detail.run") }),
2642
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: assetDetail.asset.runId }) }),
2643
+ Object.entries(assetDetail.asset.payload.capabilities ?? {}).map(([capability, value]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: capability }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: statusLabel(value) })] }, capability))
2644
+ ]
2645
+ })]
2646
+ })
2647
+ ] })
2648
+ }),
2649
+ detailTab === "business" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2650
+ className: DataAgentWorkbench_module_css_default.catalogDetailScroll,
2651
+ children: [
2652
+ selection?.type === "asset" && assetDetail !== null && businessDefinitions.length === 0 && !editingMetric && !editingTerm && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2653
+ className: DataAgentWorkbench_module_css_default.catalogBusinessEmpty,
2654
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("catalog.detail.business.empty.title") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("catalog.detail.business.empty.body") })]
2655
+ }),
2656
+ relationDetail && assetDetail !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2657
+ className: DataAgentWorkbench_module_css_default.catalogMeaningReview,
2658
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2659
+ className: DataAgentWorkbench_module_css_default.catalogMeaningSection,
2660
+ "aria-labelledby": `${props.id}-table-meaning`,
2661
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
2662
+ id: `${props.id}-table-meaning`,
2663
+ children: t("catalog.meaning.table")
2664
+ }), tableMeaning === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2665
+ className: DataAgentWorkbench_module_css_default.catalogMeaningMissing,
2666
+ children: t("catalog.meaning.missing")
2667
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MeaningCard, {
2668
+ value: tableMeaning,
2669
+ busy,
2670
+ statusLabel,
2671
+ onConfirm: () => {
2672
+ confirmMeaning(tableMeaning);
2673
+ },
2674
+ onDismiss: () => {
2675
+ dismissMeaning(tableMeaning);
2676
+ },
2677
+ t
2678
+ })]
2679
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2680
+ className: DataAgentWorkbench_module_css_default.catalogMeaningSection,
2681
+ "aria-labelledby": `${props.id}-field-meanings`,
2682
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
2683
+ id: `${props.id}-field-meanings`,
2684
+ children: t("catalog.meaning.fields")
2685
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2686
+ className: DataAgentWorkbench_module_css_default.catalogMeaningFields,
2687
+ children: technicalRows.map((field) => {
2688
+ const meaning = fieldMeanings.get(field.assetId);
2689
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2690
+ className: DataAgentWorkbench_module_css_default.catalogMeaningField,
2691
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2692
+ className: DataAgentWorkbench_module_css_default.catalogMeaningFieldMeta,
2693
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: field.payload.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: field.payload.dataType ?? "—" })]
2694
+ }), meaning === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2695
+ className: DataAgentWorkbench_module_css_default.catalogMeaningMissing,
2696
+ children: t("catalog.meaning.missing")
2697
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MeaningCard, {
2698
+ value: meaning,
2699
+ compact: true,
2700
+ busy,
2701
+ statusLabel,
2702
+ onConfirm: () => {
2703
+ confirmMeaning(meaning);
2704
+ },
2705
+ onDismiss: () => {
2706
+ dismissMeaning(meaning);
2707
+ },
2708
+ t
2709
+ })]
2710
+ }, field.assetId);
2711
+ })
2712
+ })]
2713
+ })]
2714
+ }),
2715
+ selection?.type === "semantic" && semanticDetail?.definition.kind === "meaning" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MeaningCard, {
2716
+ value: semanticDetail,
2717
+ busy,
2718
+ statusLabel,
2719
+ onConfirm: () => {
2720
+ confirmMeaning(semanticDetail);
2721
+ },
2722
+ onDismiss: () => {
2723
+ dismissMeaning(semanticDetail);
2724
+ },
2725
+ t
2726
+ }),
2727
+ governedDefinitions.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2728
+ className: DataAgentWorkbench_module_css_default.catalogDefinition,
2729
+ children: [
2730
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2731
+ className: DataAgentWorkbench_module_css_default.catalogItemHead,
2732
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: value.definition.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
2733
+ value: statusLabel(value.definition.status),
2734
+ state: value.definition.status
2735
+ })]
2736
+ }),
2737
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: value.definition.description }),
2738
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("code", { children: ["v", value.version] }),
2739
+ value.definition.kind === "metric" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: value.definition.formula }),
2740
+ value.definition.kind === "metric" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2741
+ type: "button",
2742
+ className: DataAgentWorkbench_module_css_default.ghost,
2743
+ onClick: () => {
2744
+ setSemanticDetail(value);
2745
+ startMetric(value);
2746
+ },
2747
+ children: t("catalog.metric.verify")
2748
+ }),
2749
+ value.definition.kind === "term" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2750
+ type: "button",
2751
+ className: DataAgentWorkbench_module_css_default.ghost,
2752
+ onClick: () => {
2753
+ setSemanticDetail(value);
2754
+ startTerm(value);
2755
+ },
2756
+ children: t("catalog.metric.verify")
2757
+ })
2758
+ ]
2759
+ }, value.id)),
2760
+ selection?.type === "asset" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2761
+ className: DataAgentWorkbench_module_css_default.actions,
2762
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2763
+ type: "button",
2764
+ className: DataAgentWorkbench_module_css_default.ghost,
2765
+ onClick: () => startTerm(),
2766
+ children: t("catalog.term.new")
2767
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2768
+ type: "button",
2769
+ className: DataAgentWorkbench_module_css_default.ghost,
2770
+ onClick: () => startMetric(),
2771
+ children: t("catalog.metric.new")
2772
+ })]
2773
+ }),
2774
+ editingMetric && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MetricEditor, {
2775
+ draft: metricDraft,
2776
+ setDraft: setMetricDraft,
2777
+ busy,
2778
+ canSave: canSaveMetric,
2779
+ canVerify: canVerifyMetric,
2780
+ canRetire: semanticDetail?.definition.status === "verified" || semanticDetail?.definition.status === "needs_review",
2781
+ onSave: () => {
2782
+ saveMetric(false);
2783
+ },
2784
+ onVerify: () => {
2785
+ saveMetric(true);
2786
+ },
2787
+ onRetire: () => {
2788
+ retireSemantic(metricDraft.revisionNote);
2789
+ },
2790
+ t
2791
+ }),
2792
+ editingTerm && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TermEditor, {
2793
+ draft: termDraft,
2794
+ setDraft: setTermDraft,
2795
+ busy,
2796
+ canSave: canSaveTerm,
2797
+ canVerify: canVerifyTerm,
2798
+ canRetire: semanticDetail?.definition.status === "verified" || semanticDetail?.definition.status === "needs_review",
2799
+ onSave: () => {
2800
+ saveTerm(false);
2801
+ },
2802
+ onVerify: () => {
2803
+ saveTerm(true);
2804
+ },
2805
+ onRetire: () => {
2806
+ retireSemantic(termDraft.revisionNote);
2807
+ },
2808
+ t
2809
+ })
2810
+ ]
2811
+ }),
2812
+ detailTab === "history" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2813
+ className: DataAgentWorkbench_module_css_default.catalogDetailScroll,
2814
+ children: [(assetDetail?.history ?? []).map((revision) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2815
+ className: DataAgentWorkbench_module_css_default.catalogHistoryItem,
2816
+ children: [
2817
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
2818
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: ["r", revision.revision] }),
2819
+ " · ",
2820
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
2821
+ value: statusLabel(revision.status),
2822
+ state: revision.status
2823
+ })
2824
+ ] }),
2825
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: revision.runId }),
2826
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: revision.observedAt }),
2827
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: revision.changeSummary.join(", ") })
2828
+ ]
2829
+ }, revision.id)), assetDetail === null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2830
+ className: DataAgentWorkbench_module_css_default.hint,
2831
+ children: t("wb.empty")
2832
+ })]
2833
+ })
2834
+ ] })
2835
+ })]
2836
+ })
2837
+ ]
2838
+ });
2839
+ }
2840
+ function StatusBadge({ value, state }) {
2841
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2842
+ className: `${DataAgentWorkbench_module_css_default.catalogBadge} ${DataAgentWorkbench_module_css_default[`catalogBadge_${state}`] ?? ""}`,
2843
+ children: value
2844
+ });
2845
+ }
2846
+ function MeaningCard({ value, compact = false, busy, statusLabel, onConfirm, onDismiss, t }) {
2847
+ if (value.definition.kind !== "meaning") return null;
2848
+ const confirmable = value.definition.status === "inferred" || value.definition.status === "needs_review";
2849
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2850
+ className: `${DataAgentWorkbench_module_css_default.catalogMeaningCard}${compact ? ` ${DataAgentWorkbench_module_css_default.catalogMeaningCardCompact}` : ""}`,
2851
+ children: [
2852
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2853
+ className: DataAgentWorkbench_module_css_default.catalogItemHead,
2854
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
2855
+ value: statusLabel(value.definition.status),
2856
+ state: value.definition.status
2857
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2858
+ className: DataAgentWorkbench_module_css_default.catalogMeaningOrigin,
2859
+ children: [
2860
+ t("catalog.meaning.ai"),
2861
+ " · ",
2862
+ value.definition.generatedBy.provider,
2863
+ "/",
2864
+ value.definition.generatedBy.model
2865
+ ]
2866
+ })]
2867
+ }),
2868
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: value.definition.description }),
2869
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2870
+ className: DataAgentWorkbench_module_css_default.catalogMeaningActions,
2871
+ children: [
2872
+ confirmable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2873
+ type: "button",
2874
+ className: DataAgentWorkbench_module_css_default.primary,
2875
+ disabled: busy,
2876
+ onClick: onConfirm,
2877
+ children: t("catalog.meaning.confirm")
2878
+ }),
2879
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2880
+ type: "button",
2881
+ className: DataAgentWorkbench_module_css_default.ghost,
2882
+ disabled: busy,
2883
+ onClick: onDismiss,
2884
+ children: t("catalog.meaning.delete")
2885
+ }),
2886
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("code", {
2887
+ title: value.definition.generatedBy.runId,
2888
+ children: [
2889
+ "v",
2890
+ value.version,
2891
+ " · ",
2892
+ value.definition.generatedBy.runId
2893
+ ]
2894
+ })
2895
+ ]
2896
+ })
2897
+ ]
2898
+ });
2899
+ }
2900
+ function DiffView({ diff, statusLabel, onClose, onLoadMore, busy, t }) {
2901
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2902
+ className: DataAgentWorkbench_module_css_default.catalogDetailScroll,
2903
+ children: [
2904
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2905
+ className: DataAgentWorkbench_module_css_default.catalogItemHead,
2906
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [
2907
+ diff.fromRunId,
2908
+ " → ",
2909
+ diff.toRunId
2910
+ ] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2911
+ type: "button",
2912
+ className: DataAgentWorkbench_module_css_default.ghost,
2913
+ onClick: onClose,
2914
+ children: t("action.close")
2915
+ })]
2916
+ }),
2917
+ diff.items.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
2918
+ className: DataAgentWorkbench_module_css_default.catalogHistoryItem,
2919
+ children: [
2920
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
2921
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusBadge, {
2922
+ value: statusLabel(item.kind),
2923
+ state: item.kind
2924
+ }),
2925
+ " ",
2926
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: item.name })
2927
+ ] }),
2928
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: item.path }),
2929
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: item.summary.join(", ") })
2930
+ ]
2931
+ }, `${item.kind}:${item.assetId}`)),
2932
+ diff.nextCursor !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2933
+ type: "button",
2934
+ className: DataAgentWorkbench_module_css_default.ghost,
2935
+ disabled: busy,
2936
+ onClick: onLoadMore,
2937
+ children: t("catalog.loadMore")
2938
+ })
2939
+ ]
2940
+ });
2941
+ }
2942
+ function MetricEditor(props) {
2943
+ const field = (key, label, area = false) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2944
+ className: DataAgentWorkbench_module_css_default.field,
2945
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2946
+ className: DataAgentWorkbench_module_css_default.label,
2947
+ children: props.t(label)
2948
+ }), area ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
2949
+ className: DataAgentWorkbench_module_css_default.catalogTextArea,
2950
+ value: props.draft[key],
2951
+ onChange: (event) => props.setDraft({
2952
+ ...props.draft,
2953
+ [key]: event.target.value
2954
+ })
2955
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2956
+ className: DataAgentWorkbench_module_css_default.input,
2957
+ value: props.draft[key],
2958
+ onChange: (event) => props.setDraft({
2959
+ ...props.draft,
2960
+ [key]: event.target.value
2961
+ })
2962
+ })]
2963
+ });
2964
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2965
+ className: DataAgentWorkbench_module_css_default.catalogEditor,
2966
+ children: [
2967
+ field("name", "catalog.metric.name"),
2968
+ field("aliases", "catalog.semantic.aliases"),
2969
+ field("description", "catalog.metric.description", true),
2970
+ field("sourceAssetIds", "catalog.semantic.sources", true),
2971
+ field("formula", "catalog.metric.formula", true),
2972
+ field("grain", "catalog.metric.grain"),
2973
+ field("timeFieldAssetId", "catalog.metric.timeField"),
2974
+ field("filters", "catalog.metric.filters", true),
2975
+ field("exclusions", "catalog.metric.exclusions", true),
2976
+ field("validFrom", "catalog.semantic.validFrom"),
2977
+ field("validTo", "catalog.semantic.validTo"),
2978
+ field("owner", "catalog.metric.owner"),
2979
+ field("revisionNote", "catalog.metric.note", true),
2980
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2981
+ className: DataAgentWorkbench_module_css_default.actions,
2982
+ children: [
2983
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2984
+ type: "button",
2985
+ className: DataAgentWorkbench_module_css_default.ghost,
2986
+ disabled: props.busy || !props.canSave,
2987
+ onClick: props.onSave,
2988
+ children: props.t("catalog.metric.save")
2989
+ }),
2990
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2991
+ type: "button",
2992
+ className: DataAgentWorkbench_module_css_default.primary,
2993
+ disabled: props.busy || !props.canVerify,
2994
+ onClick: props.onVerify,
2995
+ children: props.t("catalog.metric.verify")
2996
+ }),
2997
+ props.canRetire && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2998
+ type: "button",
2999
+ className: DataAgentWorkbench_module_css_default.ghost,
3000
+ disabled: props.busy || props.draft.revisionNote.trim() === "",
3001
+ onClick: props.onRetire,
3002
+ children: props.t("catalog.metric.retire")
3003
+ })
3004
+ ]
3005
+ })
3006
+ ]
3007
+ });
3008
+ }
3009
+ function TermEditor(props) {
3010
+ const field = (key, label, area = false) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
3011
+ className: DataAgentWorkbench_module_css_default.field,
3012
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3013
+ className: DataAgentWorkbench_module_css_default.label,
3014
+ children: props.t(label)
3015
+ }), area ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
3016
+ className: DataAgentWorkbench_module_css_default.catalogTextArea,
3017
+ value: props.draft[key],
3018
+ onChange: (event) => props.setDraft({
3019
+ ...props.draft,
3020
+ [key]: event.target.value
3021
+ })
3022
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3023
+ className: DataAgentWorkbench_module_css_default.input,
3024
+ value: props.draft[key],
3025
+ onChange: (event) => props.setDraft({
3026
+ ...props.draft,
3027
+ [key]: event.target.value
3028
+ })
3029
+ })]
3030
+ });
3031
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3032
+ className: DataAgentWorkbench_module_css_default.catalogEditor,
3033
+ children: [
3034
+ field("name", "catalog.term.name"),
3035
+ field("aliases", "catalog.semantic.aliases"),
3036
+ field("description", "catalog.metric.description", true),
3037
+ field("sourceAssetIds", "catalog.semantic.sources", true),
3038
+ field("validFrom", "catalog.semantic.validFrom"),
3039
+ field("validTo", "catalog.semantic.validTo"),
3040
+ field("owner", "catalog.metric.owner"),
3041
+ field("revisionNote", "catalog.metric.note", true),
3042
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3043
+ className: DataAgentWorkbench_module_css_default.actions,
3044
+ children: [
3045
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3046
+ type: "button",
3047
+ className: DataAgentWorkbench_module_css_default.ghost,
3048
+ disabled: props.busy || !props.canSave,
3049
+ onClick: props.onSave,
3050
+ children: props.t("catalog.metric.save")
3051
+ }),
3052
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3053
+ type: "button",
3054
+ className: DataAgentWorkbench_module_css_default.primary,
3055
+ disabled: props.busy || !props.canVerify,
3056
+ onClick: props.onVerify,
3057
+ children: props.t("catalog.metric.verify")
3058
+ }),
3059
+ props.canRetire && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3060
+ type: "button",
3061
+ className: DataAgentWorkbench_module_css_default.ghost,
3062
+ disabled: props.busy || props.draft.revisionNote.trim() === "",
3063
+ onClick: props.onRetire,
3064
+ children: props.t("catalog.metric.retire")
3065
+ })
3066
+ ]
3067
+ })
3068
+ ]
3069
+ });
3070
+ }
3071
+ function draftFromSemantic(semantic) {
3072
+ if (semantic.definition.kind !== "metric") return EMPTY_DRAFT;
3073
+ return {
3074
+ name: semantic.definition.name,
3075
+ aliases: semantic.definition.aliases.join(", "),
3076
+ description: semantic.definition.description,
3077
+ formula: semantic.definition.formula,
3078
+ grain: semantic.definition.grain,
3079
+ sourceAssetIds: semantic.definition.sourceAssetIds.join("\n"),
3080
+ timeFieldAssetId: semantic.definition.timeFieldAssetId ?? "",
3081
+ filters: semantic.definition.filters.join("\n"),
3082
+ exclusions: semantic.definition.exclusions.join("\n"),
3083
+ validFrom: semantic.definition.validFrom ?? "",
3084
+ validTo: semantic.definition.validTo ?? "",
3085
+ owner: semantic.definition.owner ?? "",
3086
+ revisionNote: ""
3087
+ };
3088
+ }
3089
+ function termDraftFromSemantic(semantic) {
3090
+ if (semantic.definition.kind !== "term") return EMPTY_TERM_DRAFT;
3091
+ return {
3092
+ name: semantic.definition.name,
3093
+ aliases: semantic.definition.aliases.join(", "),
3094
+ description: semantic.definition.description,
3095
+ sourceAssetIds: semantic.definition.sourceAssetIds.join("\n"),
3096
+ validFrom: semantic.definition.validFrom ?? "",
3097
+ validTo: semantic.definition.validTo ?? "",
3098
+ owner: semantic.definition.owner ?? "",
3099
+ revisionNote: ""
3100
+ };
3101
+ }
3102
+ function splitList(value) {
3103
+ return value.split(/[\n,]+/).map((item) => item.trim()).filter(Boolean);
3104
+ }
3105
+ function splitLines(value) {
3106
+ return value.split(/\n+/).map((item) => item.trim()).filter(Boolean);
3107
+ }
3108
+ function defaultBrowseSchema(source) {
3109
+ return [
3110
+ "mysql",
3111
+ "clickhouse",
3112
+ "doris",
3113
+ "hive",
3114
+ "impala"
3115
+ ].includes(source.type) ? source.database : "";
3116
+ }
3117
+ function parentPath(path, name) {
3118
+ const suffix = `.${name}`;
3119
+ return path.endsWith(suffix) ? path.slice(0, -suffix.length) : path;
3120
+ }
3121
+ function nullableLabel(value, t) {
3122
+ if (value === void 0) return "—";
3123
+ return value ? t("catalog.detail.yes") : t("catalog.detail.no");
3124
+ }
3125
+ const STATUS_KEYS = {
3126
+ "catalog.state.observed": true,
3127
+ "catalog.state.inferred": true,
3128
+ "catalog.state.verified": true,
3129
+ "catalog.state.needs_review": true,
3130
+ "catalog.state.retired": true,
3131
+ "catalog.state.missing": true,
3132
+ "catalog.state.unavailable": true,
3133
+ "catalog.state.added": true,
3134
+ "catalog.state.changed": true,
3135
+ "catalog.state.restored": true,
3136
+ "catalog.state.queued": true,
3137
+ "catalog.state.running": true,
3138
+ "catalog.state.applying": true,
3139
+ "catalog.state.succeeded": true,
3140
+ "catalog.state.failed": true,
3141
+ "catalog.state.cancelled": true,
3142
+ "catalog.state.interrupted": true,
3143
+ "catalog.state.supported": true,
3144
+ "catalog.state.unsupported": true
3145
+ };
3146
+ const KIND_KEYS = {
3147
+ "catalog.kind.schema": true,
3148
+ "catalog.kind.table": true,
3149
+ "catalog.kind.view": true,
3150
+ "catalog.kind.column": true,
3151
+ "catalog.kind.primary_key": true,
3152
+ "catalog.kind.foreign_key": true,
3153
+ "catalog.kind.index": true,
3154
+ "catalog.kind.meaning": true,
3155
+ "catalog.kind.term": true,
3156
+ "catalog.kind.metric": true
3157
+ };
3158
+ //#endregion
1316
3159
  //#region src/client/DataAgentWorkbench.tsx
1317
3160
  /**
1318
3161
  * The database workbench entry for data-agent sessions.
@@ -1320,7 +3163,7 @@ window.__ModuleLoader__.load({
1320
3163
  * Only a compact database button remains mounted from the composer slot and
1321
3164
  * is visually lifted into the context row above the composer card.
1322
3165
  * Clicking it opens one Modal containing connection settings, the schema
1323
- * explorer, and SQL runner as three tabs. Hero and active conversations share
3166
+ * explorer, data Catalog, and SQL runner as four tabs. Hero and active conversations share
1324
3167
  * this exact surface; the plugin never measures or shifts host layout.
1325
3168
  *
1326
3169
  * Non-data-agent sessions render null before any effect or request runs.
@@ -1571,6 +3414,8 @@ window.__ModuleLoader__.load({
1571
3414
  const [error, setError] = (0, react.useState)(null);
1572
3415
  const [connected, setConnected] = (0, react.useState)(false);
1573
3416
  const [reconnectRequired, setReconnectRequired] = (0, react.useState)(false);
3417
+ const [connectionProfileId, setConnectionProfileId] = (0, react.useState)();
3418
+ const [catalogAvailable, setCatalogAvailable] = (0, react.useState)(false);
1574
3419
  const [workbenchOpen, setWorkbenchOpen] = (0, react.useState)(false);
1575
3420
  const [activeTab, setActiveTab] = (0, react.useState)("connection");
1576
3421
  const [restoring, setRestoring] = (0, react.useState)(false);
@@ -1586,6 +3431,7 @@ window.__ModuleLoader__.load({
1586
3431
  const [sqlResult, setSqlResult] = (0, react.useState)(null);
1587
3432
  const sqlResultId = (0, react.useRef)(0);
1588
3433
  const triggerSlotRef = (0, react.useRef)(null);
3434
+ const catalogStateKey = (0, react.useRef)({}).current;
1589
3435
  const firstDraftRun = (0, react.useRef)(true);
1590
3436
  (0, react.useEffect)(() => {
1591
3437
  if (!isDataAgent) return;
@@ -1644,6 +3490,7 @@ window.__ModuleLoader__.load({
1644
3490
  setPasswordRef(summary.passwordRef ?? "");
1645
3491
  setCredentialMode(summary.credentialMode === "reference" || summary.passwordRef !== void 0 ? "reference" : "password");
1646
3492
  setCredentialStatus(summary.credential);
3493
+ setConnectionProfileId(summary.profileId);
1647
3494
  if (!matchesSaved) {
1648
3495
  setPassword("");
1649
3496
  setRememberPassword(false);
@@ -1662,6 +3509,7 @@ window.__ModuleLoader__.load({
1662
3509
  setConnected(true);
1663
3510
  setReconnectRequired(false);
1664
3511
  setCredentialStatus(result.summary?.credential);
3512
+ setConnectionProfileId(result.summary?.profileId);
1665
3513
  } else setError(`连接恢复失败:${result.error ?? "unknown error"}`);
1666
3514
  } catch (cause) {
1667
3515
  if (!cancelled) setError(`连接恢复失败:${cause instanceof Error ? cause.message : String(cause)}`);
@@ -1724,6 +3572,7 @@ window.__ModuleLoader__.load({
1724
3572
  setConnected(true);
1725
3573
  setReconnectRequired(false);
1726
3574
  setCredentialStatus(result.summary?.credential);
3575
+ setConnectionProfileId(result.summary?.profileId);
1727
3576
  if (result.summary?.credentialMode === "none" && !sqlite) saveConnection({
1728
3577
  type,
1729
3578
  host,
@@ -1757,8 +3606,9 @@ window.__ModuleLoader__.load({
1757
3606
  setConnected(false);
1758
3607
  setReconnectRequired(false);
1759
3608
  setCredentialStatus(void 0);
3609
+ setConnectionProfileId(void 0);
1760
3610
  setReadonly(false);
1761
- setActiveTab("connection");
3611
+ if (activeTab !== "catalog") setActiveTab("connection");
1762
3612
  setSchemas([]);
1763
3613
  schemasLoaded.current = false;
1764
3614
  setActiveSchema(null);
@@ -1877,6 +3727,11 @@ window.__ModuleLoader__.load({
1877
3727
  label: t("action.browse"),
1878
3728
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableIcon, {})
1879
3729
  },
3730
+ {
3731
+ id: "catalog",
3732
+ label: t("action.catalog"),
3733
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FolderIcon, {})
3734
+ },
1880
3735
  {
1881
3736
  id: "sql",
1882
3737
  label: t("wb.sql"),
@@ -1950,7 +3805,7 @@ window.__ModuleLoader__.load({
1950
3805
  role: "tablist",
1951
3806
  "aria-label": t("wb.workbench.tabs"),
1952
3807
  children: tabs.map((tab) => {
1953
- const disabled = tab.id !== "connection" && !connected;
3808
+ const disabled = tab.id === "catalog" ? !connected && !catalogAvailable : tab.id !== "connection" && !connected;
1954
3809
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1955
3810
  id: `${tabsId}-${tab.id}-tab`,
1956
3811
  type: "button",
@@ -2341,6 +4196,17 @@ window.__ModuleLoader__.load({
2341
4196
  })
2342
4197
  ]
2343
4198
  }),
4199
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CatalogPanel, {
4200
+ id: `${tabsId}-catalog-panel`,
4201
+ labelledBy: `${tabsId}-catalog-tab`,
4202
+ active: activeTab === "catalog",
4203
+ sessionId,
4204
+ connected,
4205
+ connectionProfileId,
4206
+ stateKey: catalogStateKey,
4207
+ t,
4208
+ onAvailabilityChange: setCatalogAvailable
4209
+ }),
2344
4210
  error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2345
4211
  className: DataAgentWorkbench_module_css_default.errorBar,
2346
4212
  role: "alert",
@@ -23866,7 +25732,7 @@ window.__ModuleLoader__.load({
23866
25732
  //#region node_modules/zrender/lib/core/WeakMap.js
23867
25733
  var wmUniqueIndex = Math.round(Math.random() * 9);
23868
25734
  var supportDefineProperty = typeof Object.defineProperty === "function";
23869
- var WeakMap = function() {
25735
+ var WeakMap$1 = function() {
23870
25736
  function WeakMap() {
23871
25737
  this._id = "__ec_inner_" + wmUniqueIndex++;
23872
25738
  }
@@ -24687,7 +26553,7 @@ window.__ModuleLoader__.load({
24687
26553
  /**
24688
26554
  * AUTO-GENERATED FILE. DO NOT MODIFY.
24689
26555
  */
24690
- var decalMap = new WeakMap();
26556
+ var decalMap = new WeakMap$1();
24691
26557
  var decalCache = new LRU(100);
24692
26558
  var decalKeys = [
24693
26559
  "symbol",
@@ -43708,40 +45574,40 @@ window.__ModuleLoader__.load({
43708
45574
  document.head.appendChild(tag);
43709
45575
  }
43710
45576
  var AnalysisDashboard_module_css_default = {
43711
- "rowActions": "_1tppBG_rowActions",
43712
- "rowTitle": "_1tppBG_rowTitle",
43713
- "empty": "_1tppBG_empty",
43714
- "rowHead": "_1tppBG_rowHead",
43715
45577
  "visuallyHidden": "_1tppBG_visuallyHidden",
43716
- "view": "_1tppBG_view",
43717
- "modalShell": "_1tppBG_modalShell",
45578
+ "metricLabel": "_1tppBG_metricLabel",
45579
+ "empty": "_1tppBG_empty",
45580
+ "rowInterrupted": "_1tppBG_rowInterrupted",
43718
45581
  "modal": "_1tppBG_modal",
43719
- "rowButton": "_1tppBG_rowButton",
45582
+ "modalHeader": "_1tppBG_modalHeader",
45583
+ "metricBand": "_1tppBG_metricBand",
45584
+ "chart": "_1tppBG_chart",
45585
+ "modalShell": "_1tppBG_modalShell",
45586
+ "modalTitleWrap": "_1tppBG_modalTitleWrap",
45587
+ "rowSummary": "_1tppBG_rowSummary",
43720
45588
  "grid": "_1tppBG_grid",
43721
45589
  "preview": "_1tppBG_preview",
45590
+ "viewFull": "_1tppBG_viewFull",
43722
45591
  "viewTitle": "_1tppBG_viewTitle",
43723
- "metricLabel": "_1tppBG_metricLabel",
43724
45592
  "metricValue": "_1tppBG_metricValue",
43725
- "row": "_1tppBG_row",
43726
- "modalClose": "_1tppBG_modalClose",
43727
- "chart": "_1tppBG_chart",
43728
- "rowInterrupted": "_1tppBG_rowInterrupted",
45593
+ "view": "_1tppBG_view",
43729
45594
  "viewHalf": "_1tppBG_viewHalf",
43730
- "metric": "_1tppBG_metric",
43731
- "modalHeader": "_1tppBG_modalHeader",
43732
- "modalTitleWrap": "_1tppBG_modalTitleWrap",
43733
- "modalTitle": "_1tppBG_modalTitle",
43734
- "metricBand": "_1tppBG_metricBand",
43735
45595
  "rowError": "_1tppBG_rowError",
43736
- "tableWrap": "_1tppBG_tableWrap",
45596
+ "rowHead": "_1tppBG_rowHead",
43737
45597
  "modalBody": "_1tppBG_modalBody",
43738
- "rowSummary": "_1tppBG_rowSummary",
43739
- "emptyText": "_1tppBG_emptyText",
45598
+ "tableWrap": "_1tppBG_tableWrap",
45599
+ "rowActions": "_1tppBG_rowActions",
45600
+ "rowTitle": "_1tppBG_rowTitle",
43740
45601
  "table": "_1tppBG_table",
43741
- "chartCanvas": "_1tppBG_chartCanvas",
43742
45602
  "modalCount": "_1tppBG_modalCount",
43743
- "viewFull": "_1tppBG_viewFull",
43744
- "modalSummary": "_1tppBG_modalSummary"
45603
+ "row": "_1tppBG_row",
45604
+ "metric": "_1tppBG_metric",
45605
+ "modalClose": "_1tppBG_modalClose",
45606
+ "emptyText": "_1tppBG_emptyText",
45607
+ "modalSummary": "_1tppBG_modalSummary",
45608
+ "chartCanvas": "_1tppBG_chartCanvas",
45609
+ "modalTitle": "_1tppBG_modalTitle",
45610
+ "rowButton": "_1tppBG_rowButton"
43745
45611
  };
43746
45612
  //#endregion
43747
45613
  //#region src/client/AnalysisChart.tsx
@@ -44220,8 +46086,8 @@ window.__ModuleLoader__.load({
44220
46086
  "wb.sql.running": "运行中…",
44221
46087
  "wb.sql.shortcut": "Ctrl / ⌘ + Enter 运行",
44222
46088
  "wb.sql.empty": "运行查询后,结果会显示在这里",
44223
- "wb.sql.result.summary": "{{rows}} 行 · {{columns}} 列 · {{elapsed}} ms",
44224
- "wb.sql.result.capped": "仅保留前 {{rows}} 行",
46089
+ "wb.sql.result.summary": "{rows} 行 · {columns} 列 · {elapsed} ms",
46090
+ "wb.sql.result.capped": "仅保留前 {rows} 行",
44225
46091
  "wb.sql.result.outputTruncated": "… 输出超过大小上限,已截断",
44226
46092
  "wb.sql.result.table": "SQL 查询结果",
44227
46093
  "wb.sql.result.noRows": "查询成功,无返回行",
@@ -44232,10 +46098,10 @@ window.__ModuleLoader__.load({
44232
46098
  "wb.sql.export.clipboard": "复制",
44233
46099
  "wb.sql.exporting": "生成中…",
44234
46100
  "wb.sql.copying": "复制中…",
44235
- "wb.sql.export.done": "已导出 {{rows}} 行",
44236
- "wb.sql.copy.done": "已复制 {{rows}} 行",
44237
- "wb.sql.export.failed": "导出失败:{{detail}}",
44238
- "wb.sql.page.summary": "第 {{page}} / {{pages}} 页",
46101
+ "wb.sql.export.done": "已导出 {rows} 行",
46102
+ "wb.sql.copy.done": "已复制 {rows} 行",
46103
+ "wb.sql.export.failed": "导出失败:{detail}",
46104
+ "wb.sql.page.summary": "第 {page} / {pages} 页",
44239
46105
  "wb.sql.page.previous": "上一页",
44240
46106
  "wb.sql.page.next": "下一页",
44241
46107
  "wb.loading": "加载中…",
@@ -44244,6 +46110,127 @@ window.__ModuleLoader__.load({
44244
46110
  "wb.hint.click": "单击库展开表 · 点击表查看结构",
44245
46111
  "action.config": "连接配置",
44246
46112
  "action.browse": "库表",
46113
+ "action.catalog": "数据目录",
46114
+ "catalog.source": "数据源",
46115
+ "catalog.source.current": "当前连接(尚未扫描)",
46116
+ "catalog.empty": "尚无数据目录。连接数据库后执行首次扫描。",
46117
+ "catalog.search": "搜索表、字段、术语或指标",
46118
+ "catalog.schema": "Schema",
46119
+ "catalog.schema.filter": "Schema 筛选",
46120
+ "catalog.table": "表或视图",
46121
+ "catalog.validation.schema": "请输入 Schema。",
46122
+ "catalog.validation.table": "请输入 Schema 和表或视图。",
46123
+ "catalog.filter.all": "全部类型",
46124
+ "catalog.filter.tables": "表与视图",
46125
+ "catalog.filter.review": "包含待确认口径",
46126
+ "catalog.filter.assetStatus": "全部资产状态",
46127
+ "catalog.filter.semanticStatus": "全部口径状态",
46128
+ "catalog.scan": "扫描",
46129
+ "catalog.scan.all": "全库",
46130
+ "catalog.scan.schema": "Schema",
46131
+ "catalog.scan.table": "单表",
46132
+ "catalog.scan.confirm": "确认扫描整个数据源?该操作只读取系统元数据,但可能耗时较长。",
46133
+ "catalog.section.scan": "扫描范围",
46134
+ "catalog.section.diff": "版本对比",
46135
+ "catalog.cancel": "取消扫描",
46136
+ "catalog.diff": "查看变更",
46137
+ "catalog.diff.from": "起始成功扫描",
46138
+ "catalog.diff.to": "目标成功扫描",
46139
+ "catalog.refresh": "刷新",
46140
+ "catalog.loadMore": "加载更多",
46141
+ "catalog.status.never": "尚未扫描",
46142
+ "catalog.status.latest": "最近扫描",
46143
+ "catalog.status.full": "最近全库扫描",
46144
+ "catalog.status.partial": "最近局部扫描",
46145
+ "catalog.status.failureReason": "失败原因:",
46146
+ "catalog.count.assets": "资产",
46147
+ "catalog.count.fields": "字段",
46148
+ "catalog.count.review": "待确认",
46149
+ "catalog.progress": "{schemas} Schema · {relations} 表/视图 · {fields} 字段",
46150
+ "catalog.enrichment.label": "AI 业务含义",
46151
+ "catalog.enrichment.progress": "已完成 {completed}/{total} 张表 · {candidates} 个候选",
46152
+ "catalog.enrichment.queued": "等待 AI 生成",
46153
+ "catalog.enrichment.running": "AI 正在逐表生成业务含义",
46154
+ "catalog.enrichment.succeeded": "AI 业务含义生成成功",
46155
+ "catalog.enrichment.partial": "AI 业务含义部分成功",
46156
+ "catalog.enrichment.failed": "AI 业务含义生成失败",
46157
+ "catalog.enrichment.cancelled": "AI 业务含义生成已取消",
46158
+ "catalog.detail.technical": "技术结构",
46159
+ "catalog.detail.business": "业务定义",
46160
+ "catalog.detail.history": "变更历史",
46161
+ "catalog.detail.relations": "键、索引与关系",
46162
+ "catalog.detail.provenance": "来源",
46163
+ "catalog.detail.run": "扫描运行",
46164
+ "catalog.detail.name": "名称",
46165
+ "catalog.detail.type": "类型",
46166
+ "catalog.detail.nullable": "可空",
46167
+ "catalog.detail.parentTable": "所属表",
46168
+ "catalog.detail.select": "选择一个资产或业务定义查看详情",
46169
+ "catalog.detail.summary": "资产摘要",
46170
+ "catalog.detail.fields": "字段",
46171
+ "catalog.detail.relationCount": "关系",
46172
+ "catalog.detail.definitionCount": "业务定义",
46173
+ "catalog.detail.scanFacts": "扫描信息与能力",
46174
+ "catalog.detail.yes": "是",
46175
+ "catalog.detail.no": "否",
46176
+ "catalog.detail.business.empty.title": "尚无 AI 业务含义候选",
46177
+ "catalog.detail.business.empty.body": "本次扫描尚未成功生成候选,或候选已被删除。请查看顶部 AI 状态;AI 结果只供参考,仍需人工确认。",
46178
+ "catalog.meaning.table": "表业务含义",
46179
+ "catalog.meaning.fields": "字段业务含义",
46180
+ "catalog.meaning.ai": "AI 候选",
46181
+ "catalog.meaning.missing": "暂无候选",
46182
+ "catalog.meaning.confirm": "确认",
46183
+ "catalog.meaning.delete": "删除",
46184
+ "catalog.metric.new": "新建指标候选",
46185
+ "catalog.term.new": "新建业务术语候选",
46186
+ "catalog.term.name": "术语名称",
46187
+ "catalog.metric.name": "指标名称",
46188
+ "catalog.semantic.aliases": "别名(逗号分隔)",
46189
+ "catalog.semantic.sources": "来源资产 ID(每行一个)",
46190
+ "catalog.semantic.validFrom": "生效时间(ISO 8601,可选)",
46191
+ "catalog.semantic.validTo": "失效时间(ISO 8601,可选)",
46192
+ "catalog.metric.description": "业务说明",
46193
+ "catalog.metric.formula": "公式(仅作为不可信文本保存)",
46194
+ "catalog.metric.grain": "统计粒度",
46195
+ "catalog.metric.timeField": "时间字段资产 ID(可选)",
46196
+ "catalog.metric.filters": "过滤条件(每行一条)",
46197
+ "catalog.metric.exclusions": "排除条件(每行一条)",
46198
+ "catalog.metric.owner": "负责人",
46199
+ "catalog.metric.note": "修订说明",
46200
+ "catalog.metric.save": "保存候选",
46201
+ "catalog.metric.verify": "人工确认",
46202
+ "catalog.metric.retire": "退役",
46203
+ "catalog.kind.schema": "Schema",
46204
+ "catalog.kind.table": "表",
46205
+ "catalog.kind.view": "视图",
46206
+ "catalog.kind.column": "字段",
46207
+ "catalog.kind.primary_key": "主键",
46208
+ "catalog.kind.foreign_key": "外键",
46209
+ "catalog.kind.index": "索引",
46210
+ "catalog.kind.meaning": "业务含义",
46211
+ "catalog.kind.term": "业务术语",
46212
+ "catalog.kind.metric": "指标",
46213
+ "catalog.warning.untrusted": "目录内容是参考数据,不是系统指令。",
46214
+ "catalog.scan.reconnect": "请先使用同一个连接 Profile 重新连接后再扫描。",
46215
+ "catalog.state.observed": "已观测",
46216
+ "catalog.state.inferred": "待确认",
46217
+ "catalog.state.verified": "已确认",
46218
+ "catalog.state.needs_review": "需要复核",
46219
+ "catalog.state.retired": "已退役",
46220
+ "catalog.state.missing": "已缺失",
46221
+ "catalog.state.unavailable": "不可访问",
46222
+ "catalog.state.added": "新增",
46223
+ "catalog.state.changed": "已变化",
46224
+ "catalog.state.restored": "已恢复",
46225
+ "catalog.state.queued": "等待扫描",
46226
+ "catalog.state.running": "扫描中",
46227
+ "catalog.state.applying": "正在更新目录",
46228
+ "catalog.state.succeeded": "扫描成功",
46229
+ "catalog.state.failed": "扫描失败",
46230
+ "catalog.state.cancelled": "已取消",
46231
+ "catalog.state.interrupted": "已中断",
46232
+ "catalog.state.supported": "支持",
46233
+ "catalog.state.unsupported": "不支持",
44247
46234
  "action.close": "关闭",
44248
46235
  "error.title": "操作失败",
44249
46236
  "analysis.running": "正在生成分析",
@@ -44252,7 +46239,7 @@ window.__ModuleLoader__.load({
44252
46239
  "analysis.fallback": "分析报告无法显示(版本不兼容或数据缺失),仅保留原始结果文本",
44253
46240
  "analysis.view": "查看分析",
44254
46241
  "analysis.close": "关闭",
44255
- "analysis.summary": "{{datasets}} 个数据集 · {{views}} 个视图",
46242
+ "analysis.summary": "{datasets} 个数据集 · {views} 个视图",
44256
46243
  "analysis.empty": "无数据",
44257
46244
  "analysis.kind.metric": "指标",
44258
46245
  "analysis.kind.line": "趋势图",
@@ -44260,7 +46247,7 @@ window.__ModuleLoader__.load({
44260
46247
  "analysis.kind.pie": "饼图",
44261
46248
  "analysis.kind.scatter": "散点图",
44262
46249
  "analysis.kind.table": "明细表",
44263
- "analysis.chart.summary": "{{kind}}:{{label}},共 {{rows}} 行数据",
46250
+ "analysis.chart.summary": "{kind}:{label},共 {rows} 行数据",
44264
46251
  "analysis.metric.null": "—",
44265
46252
  "analysis.row.title": "render-analysis"
44266
46253
  };
@@ -44330,8 +46317,8 @@ window.__ModuleLoader__.load({
44330
46317
  "wb.sql.running": "Running…",
44331
46318
  "wb.sql.shortcut": "Ctrl / ⌘ + Enter to run",
44332
46319
  "wb.sql.empty": "Run a query to see its result here",
44333
- "wb.sql.result.summary": "{{rows}} rows · {{columns}} columns · {{elapsed}} ms",
44334
- "wb.sql.result.capped": "Limited to the first {{rows}} rows",
46320
+ "wb.sql.result.summary": "{rows} rows · {columns} columns · {elapsed} ms",
46321
+ "wb.sql.result.capped": "Limited to the first {rows} rows",
44335
46322
  "wb.sql.result.outputTruncated": "… output exceeded the size limit and was truncated",
44336
46323
  "wb.sql.result.table": "SQL query result",
44337
46324
  "wb.sql.result.noRows": "Query succeeded with no rows",
@@ -44342,10 +46329,10 @@ window.__ModuleLoader__.load({
44342
46329
  "wb.sql.export.clipboard": "Copy",
44343
46330
  "wb.sql.exporting": "Creating…",
44344
46331
  "wb.sql.copying": "Copying…",
44345
- "wb.sql.export.done": "Exported {{rows}} rows",
44346
- "wb.sql.copy.done": "Copied {{rows}} rows",
44347
- "wb.sql.export.failed": "Export failed: {{detail}}",
44348
- "wb.sql.page.summary": "Page {{page}} of {{pages}}",
46332
+ "wb.sql.export.done": "Exported {rows} rows",
46333
+ "wb.sql.copy.done": "Copied {rows} rows",
46334
+ "wb.sql.export.failed": "Export failed: {detail}",
46335
+ "wb.sql.page.summary": "Page {page} of {pages}",
44349
46336
  "wb.sql.page.previous": "Previous",
44350
46337
  "wb.sql.page.next": "Next",
44351
46338
  "wb.loading": "Loading…",
@@ -44354,6 +46341,127 @@ window.__ModuleLoader__.load({
44354
46341
  "wb.hint.click": "Click a database to expand tables · click a table for columns",
44355
46342
  "action.config": "Connection settings",
44356
46343
  "action.browse": "Tables",
46344
+ "action.catalog": "Data Catalog",
46345
+ "catalog.source": "Source",
46346
+ "catalog.source.current": "Current connection (not scanned yet)",
46347
+ "catalog.empty": "No Catalog snapshot yet. Connect a database and run the first scan.",
46348
+ "catalog.search": "Search tables, columns, terms, or metrics",
46349
+ "catalog.schema": "Schema",
46350
+ "catalog.schema.filter": "Schema filter",
46351
+ "catalog.table": "Table or view",
46352
+ "catalog.validation.schema": "Enter a schema.",
46353
+ "catalog.validation.table": "Enter both a schema and a table or view.",
46354
+ "catalog.filter.all": "All kinds",
46355
+ "catalog.filter.tables": "Tables and views",
46356
+ "catalog.filter.review": "Include unverified definitions",
46357
+ "catalog.filter.assetStatus": "All asset states",
46358
+ "catalog.filter.semanticStatus": "All definition states",
46359
+ "catalog.scan": "Scan",
46360
+ "catalog.scan.all": "Full source",
46361
+ "catalog.scan.schema": "Schema",
46362
+ "catalog.scan.table": "Single table",
46363
+ "catalog.scan.confirm": "Scan the entire source? Only system metadata is read, but this may take time.",
46364
+ "catalog.section.scan": "Scan scope",
46365
+ "catalog.section.diff": "Compare versions",
46366
+ "catalog.cancel": "Cancel scan",
46367
+ "catalog.diff": "View changes",
46368
+ "catalog.diff.from": "From successful scan",
46369
+ "catalog.diff.to": "To successful scan",
46370
+ "catalog.refresh": "Refresh",
46371
+ "catalog.loadMore": "Load more",
46372
+ "catalog.status.never": "Never scanned",
46373
+ "catalog.status.latest": "Latest scan",
46374
+ "catalog.status.full": "Last full scan",
46375
+ "catalog.status.partial": "Last partial scan",
46376
+ "catalog.status.failureReason": "Failure reason:",
46377
+ "catalog.count.assets": "Assets",
46378
+ "catalog.count.fields": "Fields",
46379
+ "catalog.count.review": "To review",
46380
+ "catalog.progress": "{schemas} schemas · {relations} tables/views · {fields} fields",
46381
+ "catalog.enrichment.label": "AI business meanings",
46382
+ "catalog.enrichment.progress": "{completed}/{total} tables complete · {candidates} candidates",
46383
+ "catalog.enrichment.queued": "Waiting for AI generation",
46384
+ "catalog.enrichment.running": "AI is generating meanings table by table",
46385
+ "catalog.enrichment.succeeded": "AI business meanings succeeded",
46386
+ "catalog.enrichment.partial": "AI business meanings partially succeeded",
46387
+ "catalog.enrichment.failed": "AI business meaning generation failed",
46388
+ "catalog.enrichment.cancelled": "AI business meaning generation cancelled",
46389
+ "catalog.detail.technical": "Technical structure",
46390
+ "catalog.detail.business": "Business definitions",
46391
+ "catalog.detail.history": "Change history",
46392
+ "catalog.detail.relations": "Keys, indexes, and relations",
46393
+ "catalog.detail.provenance": "Provenance",
46394
+ "catalog.detail.run": "Scan run",
46395
+ "catalog.detail.name": "Name",
46396
+ "catalog.detail.type": "Type",
46397
+ "catalog.detail.nullable": "Nullable",
46398
+ "catalog.detail.parentTable": "Parent table",
46399
+ "catalog.detail.select": "Select an asset or definition to view details",
46400
+ "catalog.detail.summary": "Asset summary",
46401
+ "catalog.detail.fields": "Fields",
46402
+ "catalog.detail.relationCount": "Relations",
46403
+ "catalog.detail.definitionCount": "Definitions",
46404
+ "catalog.detail.scanFacts": "Scan facts and capabilities",
46405
+ "catalog.detail.yes": "Yes",
46406
+ "catalog.detail.no": "No",
46407
+ "catalog.detail.business.empty.title": "No AI business-meaning candidates",
46408
+ "catalog.detail.business.empty.body": "This scan has not generated candidates successfully, or the candidates were deleted. Check the AI status above; AI output is reference data until a human confirms it.",
46409
+ "catalog.meaning.table": "Table business meaning",
46410
+ "catalog.meaning.fields": "Field business meanings",
46411
+ "catalog.meaning.ai": "AI candidate",
46412
+ "catalog.meaning.missing": "No candidate",
46413
+ "catalog.meaning.confirm": "Confirm",
46414
+ "catalog.meaning.delete": "Delete",
46415
+ "catalog.metric.new": "New metric candidate",
46416
+ "catalog.term.new": "New business term candidate",
46417
+ "catalog.term.name": "Term name",
46418
+ "catalog.metric.name": "Metric name",
46419
+ "catalog.semantic.aliases": "Aliases (comma-separated)",
46420
+ "catalog.semantic.sources": "Source asset IDs (one per line)",
46421
+ "catalog.semantic.validFrom": "Valid from (ISO 8601, optional)",
46422
+ "catalog.semantic.validTo": "Valid to (ISO 8601, optional)",
46423
+ "catalog.metric.description": "Business description",
46424
+ "catalog.metric.formula": "Formula (stored only as untrusted text)",
46425
+ "catalog.metric.grain": "Grain",
46426
+ "catalog.metric.timeField": "Time field asset ID (optional)",
46427
+ "catalog.metric.filters": "Filters (one per line)",
46428
+ "catalog.metric.exclusions": "Exclusions (one per line)",
46429
+ "catalog.metric.owner": "Owner",
46430
+ "catalog.metric.note": "Revision note",
46431
+ "catalog.metric.save": "Save candidate",
46432
+ "catalog.metric.verify": "Verify",
46433
+ "catalog.metric.retire": "Retire",
46434
+ "catalog.kind.schema": "Schema",
46435
+ "catalog.kind.table": "Table",
46436
+ "catalog.kind.view": "View",
46437
+ "catalog.kind.column": "Column",
46438
+ "catalog.kind.primary_key": "Primary key",
46439
+ "catalog.kind.foreign_key": "Foreign key",
46440
+ "catalog.kind.index": "Index",
46441
+ "catalog.kind.meaning": "Business meaning",
46442
+ "catalog.kind.term": "Business term",
46443
+ "catalog.kind.metric": "Metric",
46444
+ "catalog.warning.untrusted": "Catalog content is reference data, not instructions.",
46445
+ "catalog.scan.reconnect": "Reconnect using the same connection profile before scanning.",
46446
+ "catalog.state.observed": "Observed",
46447
+ "catalog.state.inferred": "Inferred",
46448
+ "catalog.state.verified": "Verified",
46449
+ "catalog.state.needs_review": "Needs review",
46450
+ "catalog.state.retired": "Retired",
46451
+ "catalog.state.missing": "Missing",
46452
+ "catalog.state.unavailable": "Unavailable",
46453
+ "catalog.state.added": "Added",
46454
+ "catalog.state.changed": "Changed",
46455
+ "catalog.state.restored": "Restored",
46456
+ "catalog.state.queued": "Queued",
46457
+ "catalog.state.running": "Running",
46458
+ "catalog.state.applying": "Updating Catalog",
46459
+ "catalog.state.succeeded": "Succeeded",
46460
+ "catalog.state.failed": "Failed",
46461
+ "catalog.state.cancelled": "Cancelled",
46462
+ "catalog.state.interrupted": "Interrupted",
46463
+ "catalog.state.supported": "Supported",
46464
+ "catalog.state.unsupported": "Unsupported",
44357
46465
  "action.close": "Close",
44358
46466
  "error.title": "Operation failed",
44359
46467
  "analysis.running": "Generating analysis",
@@ -44362,7 +46470,7 @@ window.__ModuleLoader__.load({
44362
46470
  "analysis.fallback": "The analysis report cannot be displayed (incompatible version or missing data); showing the raw result text only",
44363
46471
  "analysis.view": "View analysis",
44364
46472
  "analysis.close": "Close",
44365
- "analysis.summary": "{{datasets}} datasets · {{views}} views",
46473
+ "analysis.summary": "{datasets} datasets · {views} views",
44366
46474
  "analysis.empty": "No data",
44367
46475
  "analysis.kind.metric": "Metric",
44368
46476
  "analysis.kind.line": "Trend chart",
@@ -44370,7 +46478,7 @@ window.__ModuleLoader__.load({
44370
46478
  "analysis.kind.pie": "Pie chart",
44371
46479
  "analysis.kind.scatter": "Scatter chart",
44372
46480
  "analysis.kind.table": "Table",
44373
- "analysis.chart.summary": "{{kind}}: {{label}}, {{rows}} rows",
46481
+ "analysis.chart.summary": "{kind}: {label}, {rows} rows",
44374
46482
  "analysis.metric.null": "—",
44375
46483
  "analysis.row.title": "render-analysis"
44376
46484
  };