@sparkelf/dsh-dataops-managed 0.1.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,32 +2,40 @@
2
2
 
3
3
  ## 中文
4
4
 
5
- 这是DataOps托管工作区使用的DeepSeek Harness呈现插件。安装后,DSH Settings显示只读的DataOps页面,说明当前Harness由DataOps工作区托管、身份与权限由当前DataOps会话管理、DataOps工具由工作区自动提供。
5
+ 这是DataOps托管工作区使用的DeepSeek Harness集成插件。它接收当前DataOps会话JWT,并通过credential-backed HTTP MCP提供DataOps工具;DSH Settings显示只读的DataOps身份与权限说明。
6
6
 
7
- 本包不读取DataOps账号,不注册HTTP路由,不发起OAuth,不持有access token、refresh token或DataOps JWT,也不提供连接、重新授权或断开按钮。实际DataOps工具仍由部署方配置的DataOps-owned Unix broker和通用MCP client提供。
7
+ 本包不发起OAuth,也不提供连接、重新授权或断开按钮。DataOps父页面把现有JWT交给固定Host route;插件把它存入DSH credential,MCP transport在每次请求前读取当前值。DataOps API根据该JWT对应的当前角色和资源授权决定可执行范围。
8
8
 
9
9
  本包只应安装到DataOps托管profile。独立DSH需要用户授权时使用@sparkelf/dsh-dataops-integration,两者不应同时安装。
10
10
 
11
+ ### 万相品牌
12
+
13
+ DataOps设置中的“应用万相品牌”默认开启,并在本机浏览器中持久化。开启时,侧栏、折叠导航、新会话欢迎页、浏览器标题和favicon使用万相数据平台品牌;关闭后立即恢复DSH官方品牌。欢迎页四单元Logo在支持hover且未启用减少动态效果时播放轻微的等距展开动画。
14
+
11
15
  ### 模型体验
12
16
 
13
- 本包只贡献Settings呈现,不增加system prompt、tool schema、模型输入或session log事件。token和KV cache均不受影响。
17
+ 本包增加命名空间化DataOps MCP tool schema,但不把JWT写入system prompt、tool参数、结果或session log。认证本身不增加token或改变KV cache。
14
18
 
15
19
  ### 已知限制
16
20
 
17
- - 页面说明部署所有权,不探测broker实时状态;实际工具错误由MCP client和DataOps工作区链路呈现。
21
+ - JWT尚未同步或DataOps拒绝当前权限时,MCP client直接呈现对应连接或工具错误。
18
22
 
19
23
  ## English
20
24
 
21
- This is the DeepSeek Harness presentation plugin for DataOps-managed workspaces. Once installed, DSH Settings includes a read-only DataOps page explaining that the current Harness is managed by the DataOps workspace, identity and permissions belong to the current DataOps session, and DataOps tools are supplied automatically by the workspace.
25
+ This is the DeepSeek Harness integration plugin for DataOps-managed workspaces. It accepts the current DataOps session JWT and provides DataOps tools through credential-backed HTTP MCP; DSH Settings shows a read-only identity and permission summary.
22
26
 
23
- The package reads no DataOps account, registers no HTTP route, starts no OAuth flow, holds no access token, refresh token, or DataOps JWT, and exposes no connect, reauthorize, or disconnect control. The deployment-owned Unix broker and the generic MCP client continue to provide the actual DataOps tools.
27
+ The package starts no OAuth flow and exposes no connect, reauthorize, or disconnect control. The DataOps parent supplies its existing JWT to one fixed Host route; the plugin stores it as a DSH credential, and the MCP transport resolves the current value before every request. DataOps APIs decide the allowed operations from the JWT principal's current roles and resource grants.
24
28
 
25
29
  Install this package only in a DataOps-managed profile. Standalone DSH deployments that need user authorization use @sparkelf/dsh-dataops-integration; the two packages must not be installed together.
26
30
 
31
+ ### Wanxiang Branding
32
+
33
+ The Apply Wanxiang branding setting defaults on and persists in the local browser. When enabled, the sidebar, collapsed rail, New Session welcome view, document title, and favicon use the Wanxiang Data Platform identity; disabling it immediately restores the official DSH identity. The four-unit welcome mark animates a subtle isometric expansion only on hover-capable devices when reduced motion is not requested.
34
+
27
35
  ### Model Experience
28
36
 
29
- The package contributes Settings presentation only. It adds no system prompt, tool schema, model input, or session-log event, and has no token or KV-cache effect.
37
+ The package adds namespaced DataOps MCP tool schemas but never places the JWT in the system prompt, tool arguments, results, or Session log. Authentication adds no model tokens and does not affect the KV cache.
30
38
 
31
39
  ### Known Limitations
32
40
 
33
- - The page explains deployment ownership rather than probing live broker state. MCP client and DataOps workspace errors remain the source for actual tool failures.
41
+ - Before JWT synchronization, or when DataOps rejects current permissions, the MCP client exposes the corresponding connection or tool error.
package/lib/client.js CHANGED
@@ -4,35 +4,74 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
7
8
  let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
8
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region src/client/brand-store.ts
11
+ /** Stable local preference key shared by Settings and brand-slot registration. */
12
+ const WANXIANG_BRAND_PREFERENCE_KEY = "dsh.dataops.wanxiangBrand";
13
+ function initialPreference() {
14
+ if (typeof localStorage === "undefined") return { enabled: true };
15
+ try {
16
+ const value = JSON.parse(localStorage.getItem("dsh.dataops.wanxiangBrand") ?? "null");
17
+ return typeof value === "object" && value !== null && "enabled" in value && typeof value.enabled === "boolean" ? { enabled: value.enabled } : { enabled: true };
18
+ } catch {
19
+ return { enabled: true };
20
+ }
21
+ }
22
+ let preference = initialPreference();
23
+ const listeners = /* @__PURE__ */ new Set();
24
+ /** Observable preference compatible with React's useSyncExternalStore. */
25
+ const wanxiangBrandPreference = {
26
+ getSnapshot: () => preference,
27
+ subscribe: (listener) => {
28
+ listeners.add(listener);
29
+ return () => {
30
+ listeners.delete(listener);
31
+ };
32
+ }
33
+ };
34
+ /** Toggle the Wanxiang shell identity from the DataOps Settings section. */
35
+ function setWanxiangBrandEnabled(enabled) {
36
+ if (preference.enabled === enabled) return;
37
+ preference = { enabled };
38
+ if (typeof localStorage !== "undefined") try {
39
+ localStorage.setItem(WANXIANG_BRAND_PREFERENCE_KEY, JSON.stringify(preference));
40
+ } catch {}
41
+ for (const listener of listeners) listener();
42
+ }
43
+ //#endregion
9
44
  //#region \0dsh-css:/home/runner/work/dsh-plugins-plus/dsh-plugins-plus/packages/dataops-managed/src/client/ManagedDataOpsSection.module.css.mjs
10
- const css = ".aGKsna_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px;display:flex}.aGKsna_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.aGKsna_statusRow{align-items:center;gap:8px;min-height:24px;font-size:14px;line-height:22px;display:flex}.aGKsna_description{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.aGKsna_details{border-top:1px solid var(--dsw-alias-border-l2);margin:2px 0 0}.aGKsna_detailRow{border-bottom:1px solid var(--dsw-alias-border-l2);grid-template-columns:minmax(140px,2fr) minmax(0,3fr);gap:20px;padding:12px 0;display:grid}.aGKsna_detailRow dt,.aGKsna_detailRow dd{margin:0;font-size:14px;line-height:22px}.aGKsna_detailRow dt{color:var(--dsw-alias-label-secondary)}.aGKsna_detailRow dd{color:var(--dsw-alias-label-primary)}";
11
- const tagId = "@sparkelf/dsh-dataops-managed/ManagedDataOpsSection.module.css";
12
- if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
45
+ const css$1 = ".aGKsna_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:14px;display:flex}.aGKsna_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.aGKsna_statusRow{align-items:center;gap:8px;min-height:24px;font-size:14px;line-height:22px;display:flex}.aGKsna_description{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.aGKsna_details{border-top:1px solid var(--dsw-alias-border-l2);margin:2px 0 0}.aGKsna_detailRow{border-bottom:1px solid var(--dsw-alias-border-l2);grid-template-columns:minmax(140px,2fr) minmax(0,3fr);gap:20px;padding:12px 0;display:grid}.aGKsna_detailRow dt,.aGKsna_detailRow dd{margin:0;font-size:14px;line-height:22px}.aGKsna_detailRow dt{color:var(--dsw-alias-label-secondary)}.aGKsna_detailRow dd{color:var(--dsw-alias-label-primary)}.aGKsna_brandingRow{border-top:1px solid var(--dsw-alias-border-l2);border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:20px;padding:12px 0;display:flex}.aGKsna_brandingCopy{flex-direction:column;flex:1;gap:3px;min-width:0;display:flex}.aGKsna_brandingCopy strong{font-size:14px;font-weight:500;line-height:22px}.aGKsna_brandingCopy span{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.aGKsna_switch{background:var(--dsw-alias-border-l1);cursor:pointer;border:0;border-radius:10px;flex:none;width:34px;height:20px;padding:0;transition:background-color .12s;position:relative}.aGKsna_switch>span{background:var(--dsw-alias-bg-base);border-radius:50%;width:14px;height:14px;transition:transform .12s;position:absolute;top:3px;left:3px;box-shadow:0 1px 2px #0003}.aGKsna_switch[data-checked=true]{background:var(--dsw-alias-state-business-primary)}.aGKsna_switch[data-checked=true]>span{transform:translate(14px)}.aGKsna_switch:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}@media (prefers-reduced-motion:reduce){.aGKsna_switch,.aGKsna_switch>span{transition:none}}";
46
+ const tagId$1 = "@sparkelf/dsh-dataops-managed/ManagedDataOpsSection.module.css";
47
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
13
48
  const tag = document.createElement("style");
14
49
  tag.dataset.plugin = "@sparkelf/dsh-dataops-managed";
15
- tag.dataset.pluginCss = tagId;
16
- tag.textContent = css;
50
+ tag.dataset.pluginCss = tagId$1;
51
+ tag.textContent = css$1;
17
52
  document.head.appendChild(tag);
18
53
  }
19
54
  var ManagedDataOpsSection_module_css_default = {
20
55
  "statusRow": "aGKsna_statusRow",
56
+ "brandingRow": "aGKsna_brandingRow",
57
+ "brandingCopy": "aGKsna_brandingCopy",
58
+ "description": "aGKsna_description",
59
+ "title": "aGKsna_title",
21
60
  "details": "aGKsna_details",
22
61
  "detailRow": "aGKsna_detailRow",
23
62
  "section": "aGKsna_section",
24
- "description": "aGKsna_description",
25
- "title": "aGKsna_title"
63
+ "switch": "aGKsna_switch"
26
64
  };
27
65
  //#endregion
28
66
  //#region src/client/ManagedDataOpsSection.tsx
29
67
  /**
30
- * Explain DataOps-managed ownership without exposing standalone authorization controls.
68
+ * Explain the DataOps-managed JWT and permission owner without standalone controls.
31
69
  * @param props - Settings slot injection values.
32
70
  * @returns The localized managed DataOps section, or nothing before injection.
33
71
  */
34
72
  function ManagedDataOpsSection(props) {
35
73
  const { t } = props;
74
+ const branding = (0, react.useSyncExternalStore)(wanxiangBrandPreference.subscribe, wanxiangBrandPreference.getSnapshot, wanxiangBrandPreference.getSnapshot);
36
75
  if (t === void 0) return null;
37
76
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
38
77
  className: ManagedDataOpsSection_module_css_default.section,
@@ -49,6 +88,24 @@ window.__ModuleLoader__.load({
49
88
  className: ManagedDataOpsSection_module_css_default.description,
50
89
  children: t("description")
51
90
  }),
91
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
92
+ className: ManagedDataOpsSection_module_css_default.brandingRow,
93
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
94
+ className: ManagedDataOpsSection_module_css_default.brandingCopy,
95
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("brandingTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("brandingDescription") })]
96
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
97
+ type: "button",
98
+ className: ManagedDataOpsSection_module_css_default.switch,
99
+ role: "switch",
100
+ "aria-label": t("brandingToggle"),
101
+ "aria-checked": branding.enabled,
102
+ "data-checked": branding.enabled,
103
+ onClick: () => {
104
+ setWanxiangBrandEnabled(!branding.enabled);
105
+ },
106
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {})
107
+ })]
108
+ }),
52
109
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
53
110
  className: ManagedDataOpsSection_module_css_default.details,
54
111
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -63,32 +120,333 @@ window.__ModuleLoader__.load({
63
120
  });
64
121
  }
65
122
  //#endregion
123
+ //#region \0dsh-css:/home/runner/work/dsh-plugins-plus/dsh-plugins-plus/packages/dataops-managed/src/client/WanxiangBrand.module.css.mjs
124
+ const css = ".z1AG8W_mark{color:inherit;flex:none;display:block;overflow:visible}.z1AG8W_animatedMark{cursor:pointer}.z1AG8W_mark g{transform-box:fill-box;transform-origin:50%}.z1AG8W_sidebarName{min-width:0;height:24px;color:inherit;align-items:center;gap:6px;display:inline-flex}.z1AG8W_sidebarName>svg:first-child{flex:0 auto;min-width:0;max-width:102px}.z1AG8W_harness{flex:none;display:block;overflow:visible}@keyframes z1AG8W_unit-top{0%,to{transform:translate(0)}50%{transform:translateY(-2px)}}@keyframes z1AG8W_unit-left{0%,to{transform:translate(0)}50%{transform:translate(-2px,1px)}}@keyframes z1AG8W_unit-right{0%,to{transform:translate(0)}50%{transform:translate(2px,1px)}}@keyframes z1AG8W_unit-core{0%,to{transform:translate(0)}50%{transform:translateY(2px)}}@media (hover:hover) and (prefers-reduced-motion:no-preference){.z1AG8W_animatedMark:hover .z1AG8W_unitTop{animation:1.6s ease-in-out infinite z1AG8W_unit-top}.z1AG8W_animatedMark:hover .z1AG8W_unitLeft{animation:1.6s ease-in-out infinite z1AG8W_unit-left}.z1AG8W_animatedMark:hover .z1AG8W_unitRight{animation:1.6s ease-in-out infinite z1AG8W_unit-right}.z1AG8W_animatedMark:hover .z1AG8W_unitCore{animation:1.6s ease-in-out infinite z1AG8W_unit-core}}@media (prefers-reduced-motion:reduce){.z1AG8W_animatedMark,.z1AG8W_animatedMark g{animation:none!important;transform:none!important}}";
125
+ const tagId = "@sparkelf/dsh-dataops-managed/WanxiangBrand.module.css";
126
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
127
+ const tag = document.createElement("style");
128
+ tag.dataset.plugin = "@sparkelf/dsh-dataops-managed";
129
+ tag.dataset.pluginCss = tagId;
130
+ tag.textContent = css;
131
+ document.head.appendChild(tag);
132
+ }
133
+ var WanxiangBrand_module_css_default = {
134
+ "unit-top": "z1AG8W_unit-top",
135
+ "unit-core": "z1AG8W_unit-core",
136
+ "mark": "z1AG8W_mark",
137
+ "unitCore": "z1AG8W_unitCore",
138
+ "unitTop": "z1AG8W_unitTop",
139
+ "unitLeft": "z1AG8W_unitLeft",
140
+ "unit-left": "z1AG8W_unit-left",
141
+ "unit-right": "z1AG8W_unit-right",
142
+ "unitRight": "z1AG8W_unitRight",
143
+ "sidebarName": "z1AG8W_sidebarName",
144
+ "animatedMark": "z1AG8W_animatedMark",
145
+ "harness": "z1AG8W_harness"
146
+ };
147
+ //#endregion
148
+ //#region src/client/WanxiangBrand.tsx
149
+ const WORDMARK_VIEWBOX = "1.64 115.64 5927.36 933.38";
150
+ const WORDMARK_RATIO = 5927.36 / 933.38;
151
+ const WORDMARK_PATHS = [
152
+ {
153
+ "d": "M62 765V691H333C326 434 312 123 34 -24C53 -38 77 -62 89 -82C287 28 361 217 390 414H767C752 147 735 37 705 9C693 -2 681 -4 657 -3C631 -3 558 -3 483 4C498 -17 508 -48 509 -70C578 -74 648 -75 686 -72C724 -70 749 -62 772 -36C811 5 829 126 846 450C847 460 847 487 847 487H399C406 556 409 625 411 691H939V765Z",
154
+ "transform": "translate(0.00 940.00) scale(0.96000 -0.94000)"
155
+ },
156
+ {
157
+ "d": "M546 474H850V300H546ZM546 542V710H850V542ZM546 231H850V57H546ZM473 781V-73H546V-12H850V-70H926V781ZM214 840V626H52V554H205C170 416 99 258 29 175C41 157 60 127 68 107C122 176 175 287 214 402V-79H287V378C325 329 370 267 389 234L435 295C413 322 322 429 287 464V554H430V626H287V840Z",
158
+ "transform": "translate(1002.00 940.00) scale(0.96000 -0.94000)"
159
+ },
160
+ {
161
+ "d": "M443 821C425 782 393 723 368 688L417 664C443 697 477 747 506 793ZM88 793C114 751 141 696 150 661L207 686C198 722 171 776 143 815ZM410 260C387 208 355 164 317 126C279 145 240 164 203 180C217 204 233 231 247 260ZM110 153C159 134 214 109 264 83C200 37 123 5 41 -14C54 -28 70 -54 77 -72C169 -47 254 -8 326 50C359 30 389 11 412 -6L460 43C437 59 408 77 375 95C428 152 470 222 495 309L454 326L442 323H278L300 375L233 387C226 367 216 345 206 323H70V260H175C154 220 131 183 110 153ZM257 841V654H50V592H234C186 527 109 465 39 435C54 421 71 395 80 378C141 411 207 467 257 526V404H327V540C375 505 436 458 461 435L503 489C479 506 391 562 342 592H531V654H327V841ZM629 832C604 656 559 488 481 383C497 373 526 349 538 337C564 374 586 418 606 467C628 369 657 278 694 199C638 104 560 31 451 -22C465 -37 486 -67 493 -83C595 -28 672 41 731 129C781 44 843 -24 921 -71C933 -52 955 -26 972 -12C888 33 822 106 771 198C824 301 858 426 880 576H948V646H663C677 702 689 761 698 821ZM809 576C793 461 769 361 733 276C695 366 667 468 648 576Z",
162
+ "transform": "translate(2004.00 940.00) scale(0.96000 -0.94000)"
163
+ },
164
+ {
165
+ "d": "M484 238V-81H550V-40H858V-77H927V238H734V362H958V427H734V537H923V796H395V494C395 335 386 117 282 -37C299 -45 330 -67 344 -79C427 43 455 213 464 362H663V238ZM468 731H851V603H468ZM468 537H663V427H467L468 494ZM550 22V174H858V22ZM167 839V638H42V568H167V349C115 333 67 319 29 309L49 235L167 273V14C167 0 162 -4 150 -4C138 -5 99 -5 56 -4C65 -24 75 -55 77 -73C140 -74 179 -71 203 -59C228 -48 237 -27 237 14V296L352 334L341 403L237 370V568H350V638H237V839Z",
166
+ "transform": "translate(3006.00 940.00) scale(0.96000 -0.94000)"
167
+ },
168
+ {
169
+ "d": "M174 630C213 556 252 459 266 399L337 424C323 482 282 578 242 650ZM755 655C730 582 684 480 646 417L711 396C750 456 797 552 834 633ZM52 348V273H459V-79H537V273H949V348H537V698H893V773H105V698H459V348Z",
170
+ "transform": "translate(4008.00 940.00) scale(0.96000 -0.94000)"
171
+ },
172
+ {
173
+ "d": "M179 342V-79H255V-25H741V-77H821V342ZM255 48V270H741V48ZM126 426C165 441 224 443 800 474C825 443 846 414 861 388L925 434C873 518 756 641 658 727L599 687C647 644 699 591 745 540L231 516C320 598 410 701 490 811L415 844C336 720 219 593 183 559C149 526 124 505 101 500C110 480 122 442 126 426Z",
174
+ "transform": "translate(5010.00 940.00) scale(0.96000 -0.94000)"
175
+ }
176
+ ];
177
+ const HARNESS_PATHS = [
178
+ {
179
+ "d": "M132.848 8.93205H134.08V16.137H132.848V8.93205ZM136.5 8.93205H137.732V16.137H136.5V8.93205ZM133.365 13.024V11.99H137.193V13.024H133.365Z",
180
+ "fill": "var(--dsw-alias-label-primary-inverted)"
181
+ },
182
+ {
183
+ "d": "M140.397 14.432L140.672 13.453H143.202L143.532 14.432H140.397ZM140.287 16.137H139.055L141.277 8.93205H142.201L142.146 9.74605L140.947 13.915H140.969L140.287 16.137ZM145.039 16.137H143.741L143.07 13.948L143.081 13.937L141.871 9.74605L141.926 8.93205H142.817L145.039 16.137Z",
184
+ "fill": "var(--dsw-alias-label-primary-inverted)"
185
+ },
186
+ {
187
+ "d": "M146.846 8.93205H149.068C149.852 8.93205 150.443 9.11538 150.839 9.48205C151.235 9.84138 151.433 10.3327 151.433 10.956C151.433 11.22 151.396 11.4657 151.323 11.693C151.249 11.9204 151.125 12.1257 150.949 12.309C150.773 12.4924 150.531 12.65 150.223 12.782C149.922 12.9067 149.541 13.0057 149.079 13.079V13.321H146.846V12.639L148.023 12.485C148.631 12.4044 149.09 12.298 149.398 12.166C149.706 12.034 149.915 11.8764 150.025 11.693C150.135 11.5024 150.19 11.2934 150.19 11.066C150.19 10.6994 150.083 10.417 149.871 10.219C149.658 10.021 149.324 9.92205 148.87 9.92205H146.846V8.93205ZM146.395 8.93205H147.627V16.137H146.395V8.93205ZM151.917 16.093V16.137H150.366L149.024 14.322C148.87 14.1094 148.73 13.9407 148.606 13.816C148.481 13.684 148.345 13.5887 148.199 13.53C148.052 13.464 147.872 13.42 147.66 13.398C147.447 13.3687 147.176 13.3504 146.846 13.343V13.145H149.079C149.233 13.211 149.368 13.2844 149.486 13.365C149.61 13.4457 149.735 13.5447 149.86 13.662C149.992 13.7794 150.138 13.937 150.3 14.135L151.917 16.093Z",
188
+ "fill": "var(--dsw-alias-label-primary-inverted)"
189
+ },
190
+ {
191
+ "d": "M153.58 9.57005L153.591 8.93205H154.46L157.584 15.51V16.137H156.704L153.58 9.57005ZM158.024 16.137H156.968L156.88 8.93205H158.024V16.137ZM154.24 16.137H153.096V8.93205H154.152L154.24 16.137Z",
192
+ "fill": "var(--dsw-alias-label-primary-inverted)"
193
+ },
194
+ {
195
+ "d": "M159.963 8.93205H161.206V16.137H159.963V8.93205ZM160.095 9.96605V8.93205H164.858V9.96605H160.095ZM160.095 16.137V15.103H164.902V16.137H160.095ZM160.095 13.013V11.99H164.374V13.013H160.095Z",
196
+ "fill": "var(--dsw-alias-label-primary-inverted)"
197
+ },
198
+ {
199
+ "d": "M169.052 15.257C169.543 15.257 169.895 15.1654 170.108 14.982C170.328 14.7987 170.438 14.5457 170.438 14.223C170.438 14.047 170.405 13.8967 170.339 13.772C170.273 13.6474 170.152 13.5337 169.976 13.431C169.807 13.321 169.558 13.2147 169.228 13.112L168.491 12.881C167.846 12.6757 167.38 12.4044 167.094 12.067C166.808 11.7297 166.665 11.3007 166.665 10.78C166.665 10.428 166.76 10.1017 166.951 9.80105C167.142 9.50038 167.428 9.25838 167.809 9.07505C168.19 8.89172 168.663 8.80005 169.228 8.80005C169.631 8.80005 169.998 8.82938 170.328 8.88805C170.665 8.93938 171.039 9.01638 171.45 9.11905L171.274 10.175C170.834 10.0504 170.442 9.96238 170.097 9.91105C169.76 9.85238 169.463 9.82305 169.206 9.82305C168.737 9.82305 168.403 9.90738 168.205 10.076C168.007 10.2374 167.908 10.439 167.908 10.681C167.908 10.857 167.941 11.0147 168.007 11.154C168.073 11.286 168.19 11.407 168.359 11.517C168.535 11.627 168.784 11.7334 169.107 11.836L169.866 12.078C170.526 12.276 170.995 12.5327 171.274 12.848C171.553 13.156 171.692 13.585 171.692 14.135C171.692 14.5604 171.589 14.9344 171.384 15.257C171.179 15.5797 170.878 15.8327 170.482 16.016C170.093 16.1994 169.609 16.291 169.03 16.291C168.627 16.291 168.212 16.247 167.787 16.159C167.362 16.071 166.9 15.9427 166.401 15.774L166.665 14.718C167.156 14.894 167.6 15.0297 167.996 15.125C168.399 15.213 168.751 15.257 169.052 15.257Z",
200
+ "fill": "var(--dsw-alias-label-primary-inverted)"
201
+ },
202
+ {
203
+ "d": "M175.809 15.257C176.3 15.257 176.652 15.1654 176.865 14.982C177.085 14.7987 177.195 14.5457 177.195 14.223C177.195 14.047 177.162 13.8967 177.096 13.772C177.03 13.6474 176.909 13.5337 176.733 13.431C176.564 13.321 176.315 13.2147 175.985 13.112L175.248 12.881C174.603 12.6757 174.137 12.4044 173.851 12.067C173.565 11.7297 173.422 11.3007 173.422 10.78C173.422 10.428 173.517 10.1017 173.708 9.80105C173.899 9.50038 174.185 9.25838 174.566 9.07505C174.947 8.89172 175.42 8.80005 175.985 8.80005C176.388 8.80005 176.755 8.82938 177.085 8.88805C177.422 8.93938 177.796 9.01638 178.207 9.11905L178.031 10.175C177.591 10.0504 177.199 9.96238 176.854 9.91105C176.517 9.85238 176.22 9.82305 175.963 9.82305C175.494 9.82305 175.16 9.90738 174.962 10.076C174.764 10.2374 174.665 10.439 174.665 10.681C174.665 10.857 174.698 11.0147 174.764 11.154C174.83 11.286 174.947 11.407 175.116 11.517C175.292 11.627 175.541 11.7334 175.864 11.836L176.623 12.078C177.283 12.276 177.752 12.5327 178.031 12.848C178.31 13.156 178.449 13.585 178.449 14.135C178.449 14.5604 178.346 14.9344 178.141 15.257C177.936 15.5797 177.635 15.8327 177.239 16.016C176.85 16.1994 176.366 16.291 175.787 16.291C175.384 16.291 174.969 16.247 174.544 16.159C174.119 16.071 173.657 15.9427 173.158 15.774L173.422 14.718C173.913 14.894 174.357 15.0297 174.753 15.125C175.156 15.213 175.508 15.257 175.809 15.257Z",
204
+ "fill": "var(--dsw-alias-label-primary-inverted)"
205
+ }
206
+ ];
207
+ function classes(...values) {
208
+ return values.filter(Boolean).join(" ");
209
+ }
210
+ function Cube({ transform, className }) {
211
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("g", {
212
+ transform,
213
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
214
+ className,
215
+ stroke: "currentColor",
216
+ strokeWidth: "1.7",
217
+ strokeLinejoin: "round",
218
+ children: [
219
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
220
+ d: "M12 0 24 7 12 14 0 7 12 0Z",
221
+ fill: "none"
222
+ }),
223
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
224
+ d: "M0 7 12 14v16L0 23V7Z",
225
+ fill: "currentColor"
226
+ }),
227
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
228
+ d: "M12 14 24 7v16L12 30V14Z",
229
+ fill: "currentColor",
230
+ fillOpacity: ".18"
231
+ })
232
+ ]
233
+ })
234
+ });
235
+ }
236
+ /** Four linked data units; its ink follows the host surface through currentColor. */
237
+ function WanxiangMark({ size, className, animated = false }) {
238
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
239
+ width: size,
240
+ height: size * 58 / 54,
241
+ className: classes(WanxiangBrand_module_css_default.mark, animated ? WanxiangBrand_module_css_default.animatedMark : void 0, className),
242
+ viewBox: "0 0 54 58",
243
+ fill: "none",
244
+ "aria-hidden": "true",
245
+ children: [
246
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cube, {
247
+ className: WanxiangBrand_module_css_default.unitTop,
248
+ transform: "translate(15 0)"
249
+ }),
250
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cube, {
251
+ className: WanxiangBrand_module_css_default.unitLeft,
252
+ transform: "translate(0 16)"
253
+ }),
254
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cube, {
255
+ className: WanxiangBrand_module_css_default.unitRight,
256
+ transform: "translate(30 16)"
257
+ }),
258
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cube, {
259
+ className: WanxiangBrand_module_css_default.unitCore,
260
+ transform: "translate(15 27)"
261
+ })
262
+ ]
263
+ });
264
+ }
265
+ /** Approved rounded-Heiti artwork, stored as paths with no runtime font dependency. */
266
+ function WanxiangWordmark({ height, accessible = false, className }) {
267
+ const accessibility = accessible ? {
268
+ role: "img",
269
+ "aria-label": "万相数据平台"
270
+ } : { "aria-hidden": true };
271
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
272
+ width: height * WORDMARK_RATIO,
273
+ height,
274
+ className,
275
+ viewBox: WORDMARK_VIEWBOX,
276
+ ...accessibility,
277
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("g", {
278
+ fill: "currentColor",
279
+ stroke: "currentColor",
280
+ strokeWidth: "42",
281
+ strokeLinejoin: "round",
282
+ strokeLinecap: "round",
283
+ paintOrder: "stroke fill",
284
+ children: WORDMARK_PATHS.map((path) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
285
+ d: path.d,
286
+ transform: path.transform
287
+ }, path.transform))
288
+ })
289
+ });
290
+ }
291
+ /** Exact HARNESS badge artwork extracted from the current DSH BrandWordmark. */
292
+ function HarnessBadge({ height = 14 }) {
293
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
294
+ width: height * 53 / 15.5,
295
+ height,
296
+ className: WanxiangBrand_module_css_default.harness,
297
+ viewBox: "129 5 53 15.5",
298
+ style: { "--dsw-alias-label-primary-inverted": "var(--dsw-alias-bg-base)" },
299
+ "aria-hidden": "true",
300
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
301
+ x: "129.348",
302
+ y: "5.5",
303
+ width: "52",
304
+ height: "14",
305
+ rx: "2",
306
+ fill: "currentColor"
307
+ }), HARNESS_PATHS.map((path, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
308
+ d: path.d,
309
+ fill: path.fill
310
+ }, index))]
311
+ });
312
+ }
313
+ /** Expanded-sidebar brand name plus the unchanged official HARNESS badge. */
314
+ function WanxiangSidebarName() {
315
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
316
+ className: WanxiangBrand_module_css_default.sidebarName,
317
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WanxiangWordmark, { height: 16 }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HarnessBadge, { height: 14 })]
318
+ });
319
+ }
320
+ /** Welcome-page logo with four-unit hover motion. */
321
+ function WanxiangHeroMark({ size, className }) {
322
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WanxiangMark, {
323
+ size,
324
+ className,
325
+ animated: true
326
+ });
327
+ }
328
+ //#endregion
329
+ //#region src/client/install-branding.tsx
330
+ const BRAND_TITLE = "万相数据平台 Harness";
331
+ const SLOT_PRIORITY = -100;
332
+ const FAVICON_ID = "dataops-wanxiang-favicon";
333
+ const FAVICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 58"><style>:root{color:#1b1b1d}@media(prefers-color-scheme:dark){:root{color:#f7f7f8}}</style><g transform="translate(15 0)" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"><path d="M12 0 24 7 12 14 0 7Z" fill="none"/><path d="M0 7 12 14v16L0 23Z" fill="currentColor"/><path d="M12 14 24 7v16L12 30Z" fill="currentColor" fill-opacity=".18"/></g><g transform="translate(0 16)" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"><path d="M12 0 24 7 12 14 0 7Z" fill="none"/><path d="M0 7 12 14v16L0 23Z" fill="currentColor"/><path d="M12 14 24 7v16L12 30Z" fill="currentColor" fill-opacity=".18"/></g><g transform="translate(30 16)" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"><path d="M12 0 24 7 12 14 0 7Z" fill="none"/><path d="M0 7 12 14v16L0 23Z" fill="currentColor"/><path d="M12 14 24 7v16L12 30Z" fill="currentColor" fill-opacity=".18"/></g><g transform="translate(15 27)" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"><path d="M12 0 24 7 12 14 0 7Z" fill="none"/><path d="M0 7 12 14v16L0 23Z" fill="currentColor"/><path d="M12 14 24 7v16L12 30Z" fill="currentColor" fill-opacity=".18"/></g></svg>`;
334
+ function registerWanxiangSlots(ctx) {
335
+ return ctx.slots.inject("sidebar.brand.mark", () => ctx.slots.inject("sidebar.brand.name", () => ctx.slots.inject("conversation.hero.brand.mark", function* () {
336
+ yield ctx.slots.register({
337
+ name: "sidebar.brand.mark",
338
+ priority: SLOT_PRIORITY,
339
+ registrant: "dataops-managed"
340
+ }, WanxiangMark);
341
+ yield ctx.slots.register({
342
+ name: "sidebar.brand.name",
343
+ priority: SLOT_PRIORITY,
344
+ registrant: "dataops-managed"
345
+ }, WanxiangSidebarName);
346
+ yield ctx.slots.register({
347
+ name: "conversation.hero.brand.mark",
348
+ priority: SLOT_PRIORITY,
349
+ registrant: "dataops-managed"
350
+ }, WanxiangHeroMark);
351
+ })));
352
+ }
353
+ function installFavicon() {
354
+ const existing = document.getElementById(FAVICON_ID);
355
+ if (existing instanceof HTMLLinkElement) return existing;
356
+ const link = document.createElement("link");
357
+ link.id = FAVICON_ID;
358
+ link.rel = "icon";
359
+ link.type = "image/svg+xml";
360
+ link.href = `data:image/svg+xml,${encodeURIComponent(FAVICON_SVG)}`;
361
+ document.head.append(link);
362
+ return link;
363
+ }
364
+ /** Keep shell slots, browser title, and favicon on the same persisted preference. */
365
+ function installWanxiangBranding(ctx) {
366
+ const originalTitle = document.title;
367
+ let disposeSlots;
368
+ let favicon;
369
+ let titleObserver;
370
+ const stopTitleObserver = () => {
371
+ titleObserver?.disconnect();
372
+ titleObserver = void 0;
373
+ };
374
+ const keepBrandTitle = () => {
375
+ if (document.title !== BRAND_TITLE) document.title = BRAND_TITLE;
376
+ if (titleObserver !== void 0) return;
377
+ titleObserver = new MutationObserver(() => {
378
+ if (wanxiangBrandPreference.getSnapshot().enabled && document.title !== BRAND_TITLE) document.title = BRAND_TITLE;
379
+ });
380
+ titleObserver.observe(document.head, {
381
+ childList: true,
382
+ subtree: true,
383
+ characterData: true
384
+ });
385
+ };
386
+ const synchronize = () => {
387
+ if (wanxiangBrandPreference.getSnapshot().enabled) {
388
+ disposeSlots ??= registerWanxiangSlots(ctx);
389
+ favicon ??= installFavicon();
390
+ keepBrandTitle();
391
+ document.documentElement.dataset.dataopsBrand = "wanxiang";
392
+ return;
393
+ }
394
+ disposeSlots?.();
395
+ disposeSlots = void 0;
396
+ favicon?.remove();
397
+ favicon = void 0;
398
+ stopTitleObserver();
399
+ document.title = originalTitle;
400
+ delete document.documentElement.dataset.dataopsBrand;
401
+ };
402
+ ctx.effect(() => {
403
+ synchronize();
404
+ const unsubscribe = wanxiangBrandPreference.subscribe(synchronize);
405
+ return () => {
406
+ unsubscribe();
407
+ disposeSlots?.();
408
+ favicon?.remove();
409
+ stopTitleObserver();
410
+ document.title = originalTitle;
411
+ delete document.documentElement.dataset.dataopsBrand;
412
+ };
413
+ }, "dataops-managed: Wanxiang shell branding");
414
+ }
415
+ //#endregion
66
416
  //#region src/client/locales.ts
67
417
  /** English managed DataOps Settings copy. */
68
418
  const en = {
69
419
  nav: "DataOps",
70
420
  title: "DataOps",
71
421
  managed: "Managed by this DataOps workspace",
72
- description: "DataOps tools are provided automatically through the workspace-managed channel. No connection or authorization is required here.",
422
+ description: "DSH uses your current DataOps session JWT. DataOps applies its role and resource permissions to every tool request.",
73
423
  identityLabel: "Identity and permissions",
74
- identityValue: "Managed by your current DataOps session",
424
+ identityValue: "Current DataOps JWT",
75
425
  toolsLabel: "DataOps tools",
76
- toolsValue: "Provided automatically by the workspace"
426
+ toolsValue: "Authorized by DataOps on every request",
427
+ brandingTitle: "Apply Wanxiang branding",
428
+ brandingDescription: "Use the Wanxiang Data Platform identity in navigation, the New Session welcome view, browser title, and favicon.",
429
+ brandingToggle: "Apply Wanxiang branding"
77
430
  };
78
431
  /** Chinese managed DataOps Settings copy. */
79
432
  const zh = {
80
433
  nav: "DataOps",
81
434
  title: "DataOps",
82
435
  managed: "由当前 DataOps 工作区托管",
83
- description: "DataOps 工具通过工作区托管通道自动提供,无需在这里连接、重新授权或断开。",
436
+ description: "DSH 使用当前 DataOps 会话 JWT;DataOps 对每次工具请求应用角色与资源权限。",
84
437
  identityLabel: "身份与权限",
85
- identityValue: "由当前 DataOps 会话管理",
438
+ identityValue: "当前 DataOps JWT",
86
439
  toolsLabel: "DataOps 工具",
87
- toolsValue: "由工作区自动提供"
440
+ toolsValue: "每次请求均由 DataOps 授权",
441
+ brandingTitle: "应用万相品牌",
442
+ brandingDescription: "在导航、新会话欢迎页、浏览器标题和图标中使用万相数据平台品牌。",
443
+ brandingToggle: "应用万相品牌"
88
444
  };
89
445
  //#endregion
90
446
  //#region src/client/index.ts
91
447
  const NS = "settings.dataops-managed";
448
+ const AUTH_UPDATED_MESSAGE = "dataops-auth-updated";
449
+ const MANAGED_AUTH_PATH = "/integrations/dataops/managed-auth";
92
450
  /** Required client services for the managed DataOps Settings section. */
93
451
  const inject = ["slots", "locale"];
94
452
  /**
@@ -100,6 +458,7 @@ window.__ModuleLoader__.load({
100
458
  zh,
101
459
  en
102
460
  }), "dataops-managed: settings copy");
461
+ installWanxiangBranding(ctx);
103
462
  const t = ctx.locale.bind(NS);
104
463
  ctx.slots.inject("settings.section", () => ctx.slots.register({
105
464
  name: "settings.section",
@@ -108,6 +467,22 @@ window.__ModuleLoader__.load({
108
467
  label: () => t("nav"),
109
468
  inject: () => ({ t })
110
469
  }, ManagedDataOpsSection));
470
+ const synchronizeJwt = async () => {
471
+ const response = await fetch(new URL(MANAGED_AUTH_PATH, window.location.origin), {
472
+ method: "POST",
473
+ credentials: "same-origin"
474
+ });
475
+ if (!response.ok) throw new Error(`DataOps managed JWT synchronization failed with HTTP ${String(response.status)}`);
476
+ };
477
+ const onMessage = (event) => {
478
+ if (event.source !== window.parent || event.data?.type !== AUTH_UPDATED_MESSAGE) return;
479
+ synchronizeJwt().catch((error) => console.error("dataops-managed.jwt_sync_failed", error));
480
+ };
481
+ ctx.effect(() => {
482
+ window.addEventListener("message", onMessage);
483
+ synchronizeJwt().catch((error) => console.error("dataops-managed.jwt_sync_failed", error));
484
+ return () => window.removeEventListener("message", onMessage);
485
+ }, "dataops-managed: JWT synchronization");
111
486
  }
112
487
  //#endregion
113
488
  exports.apply = apply;
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["styles","StateDot"],"sources":["../src/client/ManagedDataOpsSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { en } from './locales.ts'\nimport styles from './ManagedDataOpsSection.module.css'\n\n/** Values injected by the DSH Settings slot. */\nexport interface ManagedDataOpsSectionInjected {\n /** Translate one managed DataOps Settings message key. */\n t: (key: keyof typeof en) => string\n}\n\n/** Props accepted by the managed DataOps Settings section. */\nexport type ManagedDataOpsSectionProps = Partial<InjectFace<ManagedDataOpsSectionInjected>>\n\n/**\n * Explain DataOps-managed ownership without exposing standalone authorization controls.\n * @param props - Settings slot injection values.\n * @returns The localized managed DataOps section, or nothing before injection.\n */\nexport function ManagedDataOpsSection(props: ManagedDataOpsSectionProps) {\n const { t } = props\n if (t === undefined) return null\n\n return (\n <section className={styles.section}>\n <h2 className={styles.title}>{t('title')}</h2>\n <div className={styles.statusRow}>\n <StateDot state=\"done\" />\n <strong>{t('managed')}</strong>\n </div>\n <p className={styles.description}>{t('description')}</p>\n <dl className={styles.details}>\n <div className={styles.detailRow}>\n <dt>{t('identityLabel')}</dt>\n <dd>{t('identityValue')}</dd>\n </div>\n <div className={styles.detailRow}>\n <dt>{t('toolsLabel')}</dt>\n <dd>{t('toolsValue')}</dd>\n </div>\n </dl>\n </section>\n )\n}\n","/** English managed DataOps Settings copy. */\nexport const en = {\n nav: 'DataOps',\n title: 'DataOps',\n managed: 'Managed by this DataOps workspace',\n description: 'DataOps tools are provided automatically through the workspace-managed channel. No connection or authorization is required here.',\n identityLabel: 'Identity and permissions',\n identityValue: 'Managed by your current DataOps session',\n toolsLabel: 'DataOps tools',\n toolsValue: 'Provided automatically by the workspace',\n} as const\n\n/** Stable key set shared by every managed DataOps locale. */\nexport type ManagedDataOpsKey = keyof typeof en\n\n/** Chinese managed DataOps Settings copy. */\nexport const zh: Record<ManagedDataOpsKey, string> = {\n nav: 'DataOps',\n title: 'DataOps',\n managed: '由当前 DataOps 工作区托管',\n description: 'DataOps 工具通过工作区托管通道自动提供,无需在这里连接、重新授权或断开。',\n identityLabel: '身份与权限',\n identityValue: '由当前 DataOps 会话管理',\n toolsLabel: 'DataOps 工具',\n toolsValue: '由工作区自动提供',\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport { ManagedDataOpsSection } from './ManagedDataOpsSection.tsx'\nimport type { ManagedDataOpsSectionInjected } from './ManagedDataOpsSection.tsx'\nimport { en, zh, type ManagedDataOpsKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.dataops-managed': ManagedDataOpsKey\n }\n}\n\nconst NS = 'settings.dataops-managed'\n\n/** Required client services for the managed DataOps Settings section. */\nexport const inject = ['slots', 'locale']\n\n/**\n * Register localized managed DataOps Settings navigation and content.\n * @param ctx - DSH client context with locale and settings slots.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dataops-managed: settings copy')\n const t = ctx.locale.bind(NS) as ManagedDataOpsSectionInjected['t']\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'dataops',\n order: 25,\n label: () => t('nav'),\n inject: () => ({ t }),\n }, ManagedDataOpsSection))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBA,SAAgB,sBAAsB,OAAmC;GACvE,MAAM,EAAE,MAAM;GACd,IAAI,MAAM,KAAA,GAAW,OAAO;GAE5B,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;IAAS,WAAWA,yCAAO;IAA3B,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yCAAO;MAAQ,UAAA,EAAE,OAAO;KAAM,CAAA;KAC7C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yCAAO;MAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,sCAAAA,UAAD,EAAU,OAAM,OAAQ,CAAA,GACxB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD,EAAA,UAAS,EAAE,SAAS,EAAU,CAAA,CAC3B;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWD,yCAAO;MAAc,UAAA,EAAE,aAAa;KAAK,CAAA;KACvD,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;MAAI,WAAWA,yCAAO;MAAtB,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yCAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,eAAe,EAAM,CAAA,GAC5B,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,eAAe,EAAM,CAAA,CACzB;MACL,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yCAAO;OAAvB,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,YAAY,EAAM,CAAA,GACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAK,EAAE,YAAY,EAAM,CAAA,CACtB;MACH,CAAA,CAAA;;IACG;;EAEb;;;;EC1CA,MAAa,KAAK;GAChB,KAAK;GACL,OAAO;GACP,SAAS;GACT,aAAa;GACb,eAAe;GACf,eAAe;GACf,YAAY;GACZ,YAAY;EACd;;EAMA,MAAa,KAAwC;GACnD,KAAK;GACL,OAAO;GACP,SAAS;GACT,aAAa;GACb,eAAe;GACf,eAAe;GACf,YAAY;GACZ,YAAY;EACd;;;ECZA,MAAM,KAAK;;EAGX,MAAa,SAAS,CAAC,SAAS,QAAQ;;;;;EAMxC,SAAgB,MAAM,KAA0B;GAC9C,IAAI,aAAa,IAAI,OAAO,SAAS,IAAI;IAAE;IAAI;GAAG,CAAC,GAAG,gCAAgC;GACtF,MAAM,IAAI,IAAI,OAAO,KAAK,EAAE;GAC5B,IAAI,MAAM,OAAO,0BAA0B,IAAI,MAAM,SAAS;IAC5D,MAAM;IACN,IAAI;IACJ,OAAO;IACP,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,EAAE;GACrB,GAAG,qBAAqB,CAAC;EAC3B"}
1
+ {"version":3,"file":"client.js","names":["useSyncExternalStore","styles","StateDot","css"],"sources":["../src/client/brand-store.ts","../src/client/ManagedDataOpsSection.tsx","../src/client/WanxiangBrand.tsx","../src/client/install-branding.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/** Persisted client preference for the managed DataOps shell identity. */\nexport interface WanxiangBrandPreference {\n enabled: boolean\n}\n\n/** Stable local preference key shared by Settings and brand-slot registration. */\nexport const WANXIANG_BRAND_PREFERENCE_KEY = 'dsh.dataops.wanxiangBrand'\n\nfunction initialPreference(): WanxiangBrandPreference {\n if (typeof localStorage === 'undefined') return { enabled: true }\n try {\n const value = JSON.parse(localStorage.getItem(WANXIANG_BRAND_PREFERENCE_KEY) ?? 'null') as unknown\n return typeof value === 'object' && value !== null && 'enabled' in value\n && typeof (value as { enabled?: unknown }).enabled === 'boolean'\n ? { enabled: (value as { enabled: boolean }).enabled }\n : { enabled: true }\n } catch {\n return { enabled: true }\n }\n}\n\nlet preference = initialPreference()\nconst listeners = new Set<() => void>()\n\n/** Observable preference compatible with React's useSyncExternalStore. */\nexport const wanxiangBrandPreference = {\n getSnapshot: (): WanxiangBrandPreference => preference,\n subscribe: (listener: () => void): (() => void) => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n}\n\n/** Toggle the Wanxiang shell identity from the DataOps Settings section. */\nexport function setWanxiangBrandEnabled(enabled: boolean): void {\n if (preference.enabled === enabled) return\n preference = { enabled }\n if (typeof localStorage !== 'undefined') {\n try {\n localStorage.setItem(WANXIANG_BRAND_PREFERENCE_KEY, JSON.stringify(preference))\n } catch {\n // Storage failure must not block an in-memory preference change.\n }\n }\n for (const listener of listeners) listener()\n}\n","import { useSyncExternalStore } from 'react'\nimport { StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { en } from './locales.ts'\nimport { setWanxiangBrandEnabled, wanxiangBrandPreference } from './brand-store.ts'\nimport styles from './ManagedDataOpsSection.module.css'\n\n/** Values injected by the DSH Settings slot. */\nexport interface ManagedDataOpsSectionInjected {\n /** Translate one managed DataOps Settings message key. */\n t: (key: keyof typeof en) => string\n}\n\n/** Props accepted by the managed DataOps Settings section. */\nexport type ManagedDataOpsSectionProps = Partial<InjectFace<ManagedDataOpsSectionInjected>>\n\n/**\n * Explain the DataOps-managed JWT and permission owner without standalone controls.\n * @param props - Settings slot injection values.\n * @returns The localized managed DataOps section, or nothing before injection.\n */\nexport function ManagedDataOpsSection(props: ManagedDataOpsSectionProps) {\n const { t } = props\n const branding = useSyncExternalStore(\n wanxiangBrandPreference.subscribe,\n wanxiangBrandPreference.getSnapshot,\n wanxiangBrandPreference.getSnapshot,\n )\n if (t === undefined) return null\n\n return (\n <section className={styles.section}>\n <h2 className={styles.title}>{t('title')}</h2>\n <div className={styles.statusRow}>\n <StateDot state=\"done\" />\n <strong>{t('managed')}</strong>\n </div>\n <p className={styles.description}>{t('description')}</p>\n <div className={styles.brandingRow}>\n <div className={styles.brandingCopy}>\n <strong>{t('brandingTitle')}</strong>\n <span>{t('brandingDescription')}</span>\n </div>\n <button\n type=\"button\"\n className={styles.switch}\n role=\"switch\"\n aria-label={t('brandingToggle')}\n aria-checked={branding.enabled}\n data-checked={branding.enabled}\n onClick={() => { setWanxiangBrandEnabled(!branding.enabled) }}\n >\n <span />\n </button>\n </div>\n <dl className={styles.details}>\n <div className={styles.detailRow}>\n <dt>{t('identityLabel')}</dt>\n <dd>{t('identityValue')}</dd>\n </div>\n <div className={styles.detailRow}>\n <dt>{t('toolsLabel')}</dt>\n <dd>{t('toolsValue')}</dd>\n </div>\n </dl>\n </section>\n )\n}\n","import type { CSSProperties } from 'react'\nimport css from './WanxiangBrand.module.css'\n\nconst WORDMARK_VIEWBOX = \"1.64 115.64 5927.36 933.38\"\nconst WORDMARK_RATIO = 5927.36 / 933.38\nconst WORDMARK_PATHS = [\n {\n \"d\": \"M62 765V691H333C326 434 312 123 34 -24C53 -38 77 -62 89 -82C287 28 361 217 390 414H767C752 147 735 37 705 9C693 -2 681 -4 657 -3C631 -3 558 -3 483 4C498 -17 508 -48 509 -70C578 -74 648 -75 686 -72C724 -70 749 -62 772 -36C811 5 829 126 846 450C847 460 847 487 847 487H399C406 556 409 625 411 691H939V765Z\",\n \"transform\": \"translate(0.00 940.00) scale(0.96000 -0.94000)\"\n },\n {\n \"d\": \"M546 474H850V300H546ZM546 542V710H850V542ZM546 231H850V57H546ZM473 781V-73H546V-12H850V-70H926V781ZM214 840V626H52V554H205C170 416 99 258 29 175C41 157 60 127 68 107C122 176 175 287 214 402V-79H287V378C325 329 370 267 389 234L435 295C413 322 322 429 287 464V554H430V626H287V840Z\",\n \"transform\": \"translate(1002.00 940.00) scale(0.96000 -0.94000)\"\n },\n {\n \"d\": \"M443 821C425 782 393 723 368 688L417 664C443 697 477 747 506 793ZM88 793C114 751 141 696 150 661L207 686C198 722 171 776 143 815ZM410 260C387 208 355 164 317 126C279 145 240 164 203 180C217 204 233 231 247 260ZM110 153C159 134 214 109 264 83C200 37 123 5 41 -14C54 -28 70 -54 77 -72C169 -47 254 -8 326 50C359 30 389 11 412 -6L460 43C437 59 408 77 375 95C428 152 470 222 495 309L454 326L442 323H278L300 375L233 387C226 367 216 345 206 323H70V260H175C154 220 131 183 110 153ZM257 841V654H50V592H234C186 527 109 465 39 435C54 421 71 395 80 378C141 411 207 467 257 526V404H327V540C375 505 436 458 461 435L503 489C479 506 391 562 342 592H531V654H327V841ZM629 832C604 656 559 488 481 383C497 373 526 349 538 337C564 374 586 418 606 467C628 369 657 278 694 199C638 104 560 31 451 -22C465 -37 486 -67 493 -83C595 -28 672 41 731 129C781 44 843 -24 921 -71C933 -52 955 -26 972 -12C888 33 822 106 771 198C824 301 858 426 880 576H948V646H663C677 702 689 761 698 821ZM809 576C793 461 769 361 733 276C695 366 667 468 648 576Z\",\n \"transform\": \"translate(2004.00 940.00) scale(0.96000 -0.94000)\"\n },\n {\n \"d\": \"M484 238V-81H550V-40H858V-77H927V238H734V362H958V427H734V537H923V796H395V494C395 335 386 117 282 -37C299 -45 330 -67 344 -79C427 43 455 213 464 362H663V238ZM468 731H851V603H468ZM468 537H663V427H467L468 494ZM550 22V174H858V22ZM167 839V638H42V568H167V349C115 333 67 319 29 309L49 235L167 273V14C167 0 162 -4 150 -4C138 -5 99 -5 56 -4C65 -24 75 -55 77 -73C140 -74 179 -71 203 -59C228 -48 237 -27 237 14V296L352 334L341 403L237 370V568H350V638H237V839Z\",\n \"transform\": \"translate(3006.00 940.00) scale(0.96000 -0.94000)\"\n },\n {\n \"d\": \"M174 630C213 556 252 459 266 399L337 424C323 482 282 578 242 650ZM755 655C730 582 684 480 646 417L711 396C750 456 797 552 834 633ZM52 348V273H459V-79H537V273H949V348H537V698H893V773H105V698H459V348Z\",\n \"transform\": \"translate(4008.00 940.00) scale(0.96000 -0.94000)\"\n },\n {\n \"d\": \"M179 342V-79H255V-25H741V-77H821V342ZM255 48V270H741V48ZM126 426C165 441 224 443 800 474C825 443 846 414 861 388L925 434C873 518 756 641 658 727L599 687C647 644 699 591 745 540L231 516C320 598 410 701 490 811L415 844C336 720 219 593 183 559C149 526 124 505 101 500C110 480 122 442 126 426Z\",\n \"transform\": \"translate(5010.00 940.00) scale(0.96000 -0.94000)\"\n }\n] as const\nconst HARNESS_PATHS = [\n {\n \"d\": \"M132.848 8.93205H134.08V16.137H132.848V8.93205ZM136.5 8.93205H137.732V16.137H136.5V8.93205ZM133.365 13.024V11.99H137.193V13.024H133.365Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n },\n {\n \"d\": \"M140.397 14.432L140.672 13.453H143.202L143.532 14.432H140.397ZM140.287 16.137H139.055L141.277 8.93205H142.201L142.146 9.74605L140.947 13.915H140.969L140.287 16.137ZM145.039 16.137H143.741L143.07 13.948L143.081 13.937L141.871 9.74605L141.926 8.93205H142.817L145.039 16.137Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n },\n {\n \"d\": \"M146.846 8.93205H149.068C149.852 8.93205 150.443 9.11538 150.839 9.48205C151.235 9.84138 151.433 10.3327 151.433 10.956C151.433 11.22 151.396 11.4657 151.323 11.693C151.249 11.9204 151.125 12.1257 150.949 12.309C150.773 12.4924 150.531 12.65 150.223 12.782C149.922 12.9067 149.541 13.0057 149.079 13.079V13.321H146.846V12.639L148.023 12.485C148.631 12.4044 149.09 12.298 149.398 12.166C149.706 12.034 149.915 11.8764 150.025 11.693C150.135 11.5024 150.19 11.2934 150.19 11.066C150.19 10.6994 150.083 10.417 149.871 10.219C149.658 10.021 149.324 9.92205 148.87 9.92205H146.846V8.93205ZM146.395 8.93205H147.627V16.137H146.395V8.93205ZM151.917 16.093V16.137H150.366L149.024 14.322C148.87 14.1094 148.73 13.9407 148.606 13.816C148.481 13.684 148.345 13.5887 148.199 13.53C148.052 13.464 147.872 13.42 147.66 13.398C147.447 13.3687 147.176 13.3504 146.846 13.343V13.145H149.079C149.233 13.211 149.368 13.2844 149.486 13.365C149.61 13.4457 149.735 13.5447 149.86 13.662C149.992 13.7794 150.138 13.937 150.3 14.135L151.917 16.093Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n },\n {\n \"d\": \"M153.58 9.57005L153.591 8.93205H154.46L157.584 15.51V16.137H156.704L153.58 9.57005ZM158.024 16.137H156.968L156.88 8.93205H158.024V16.137ZM154.24 16.137H153.096V8.93205H154.152L154.24 16.137Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n },\n {\n \"d\": \"M159.963 8.93205H161.206V16.137H159.963V8.93205ZM160.095 9.96605V8.93205H164.858V9.96605H160.095ZM160.095 16.137V15.103H164.902V16.137H160.095ZM160.095 13.013V11.99H164.374V13.013H160.095Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n },\n {\n \"d\": \"M169.052 15.257C169.543 15.257 169.895 15.1654 170.108 14.982C170.328 14.7987 170.438 14.5457 170.438 14.223C170.438 14.047 170.405 13.8967 170.339 13.772C170.273 13.6474 170.152 13.5337 169.976 13.431C169.807 13.321 169.558 13.2147 169.228 13.112L168.491 12.881C167.846 12.6757 167.38 12.4044 167.094 12.067C166.808 11.7297 166.665 11.3007 166.665 10.78C166.665 10.428 166.76 10.1017 166.951 9.80105C167.142 9.50038 167.428 9.25838 167.809 9.07505C168.19 8.89172 168.663 8.80005 169.228 8.80005C169.631 8.80005 169.998 8.82938 170.328 8.88805C170.665 8.93938 171.039 9.01638 171.45 9.11905L171.274 10.175C170.834 10.0504 170.442 9.96238 170.097 9.91105C169.76 9.85238 169.463 9.82305 169.206 9.82305C168.737 9.82305 168.403 9.90738 168.205 10.076C168.007 10.2374 167.908 10.439 167.908 10.681C167.908 10.857 167.941 11.0147 168.007 11.154C168.073 11.286 168.19 11.407 168.359 11.517C168.535 11.627 168.784 11.7334 169.107 11.836L169.866 12.078C170.526 12.276 170.995 12.5327 171.274 12.848C171.553 13.156 171.692 13.585 171.692 14.135C171.692 14.5604 171.589 14.9344 171.384 15.257C171.179 15.5797 170.878 15.8327 170.482 16.016C170.093 16.1994 169.609 16.291 169.03 16.291C168.627 16.291 168.212 16.247 167.787 16.159C167.362 16.071 166.9 15.9427 166.401 15.774L166.665 14.718C167.156 14.894 167.6 15.0297 167.996 15.125C168.399 15.213 168.751 15.257 169.052 15.257Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n },\n {\n \"d\": \"M175.809 15.257C176.3 15.257 176.652 15.1654 176.865 14.982C177.085 14.7987 177.195 14.5457 177.195 14.223C177.195 14.047 177.162 13.8967 177.096 13.772C177.03 13.6474 176.909 13.5337 176.733 13.431C176.564 13.321 176.315 13.2147 175.985 13.112L175.248 12.881C174.603 12.6757 174.137 12.4044 173.851 12.067C173.565 11.7297 173.422 11.3007 173.422 10.78C173.422 10.428 173.517 10.1017 173.708 9.80105C173.899 9.50038 174.185 9.25838 174.566 9.07505C174.947 8.89172 175.42 8.80005 175.985 8.80005C176.388 8.80005 176.755 8.82938 177.085 8.88805C177.422 8.93938 177.796 9.01638 178.207 9.11905L178.031 10.175C177.591 10.0504 177.199 9.96238 176.854 9.91105C176.517 9.85238 176.22 9.82305 175.963 9.82305C175.494 9.82305 175.16 9.90738 174.962 10.076C174.764 10.2374 174.665 10.439 174.665 10.681C174.665 10.857 174.698 11.0147 174.764 11.154C174.83 11.286 174.947 11.407 175.116 11.517C175.292 11.627 175.541 11.7334 175.864 11.836L176.623 12.078C177.283 12.276 177.752 12.5327 178.031 12.848C178.31 13.156 178.449 13.585 178.449 14.135C178.449 14.5604 178.346 14.9344 178.141 15.257C177.936 15.5797 177.635 15.8327 177.239 16.016C176.85 16.1994 176.366 16.291 175.787 16.291C175.384 16.291 174.969 16.247 174.544 16.159C174.119 16.071 173.657 15.9427 173.158 15.774L173.422 14.718C173.913 14.894 174.357 15.0297 174.753 15.125C175.156 15.213 175.508 15.257 175.809 15.257Z\",\n \"fill\": \"var(--dsw-alias-label-primary-inverted)\"\n }\n] as const\n\ninterface MarkProps {\n size: number\n className?: string | undefined\n}\n\nfunction classes(...values: Array<string | undefined>): string {\n return values.filter(Boolean).join(' ')\n}\n\nfunction Cube({ transform, className }: { transform: string; className: string }) {\n return (\n <g transform={transform}>\n <g className={className} stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinejoin=\"round\">\n <path d=\"M12 0 24 7 12 14 0 7 12 0Z\" fill=\"none\" />\n <path d=\"M0 7 12 14v16L0 23V7Z\" fill=\"currentColor\" />\n <path d=\"M12 14 24 7v16L12 30V14Z\" fill=\"currentColor\" fillOpacity=\".18\" />\n </g>\n </g>\n )\n}\n\n/** Four linked data units; its ink follows the host surface through currentColor. */\nexport function WanxiangMark({ size, className, animated = false }: MarkProps & { animated?: boolean }) {\n return (\n <svg\n width={size}\n height={(size * 58) / 54}\n className={classes(css.mark, animated ? css.animatedMark : undefined, className)}\n viewBox=\"0 0 54 58\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <Cube className={css.unitTop} transform=\"translate(15 0)\" />\n <Cube className={css.unitLeft} transform=\"translate(0 16)\" />\n <Cube className={css.unitRight} transform=\"translate(30 16)\" />\n <Cube className={css.unitCore} transform=\"translate(15 27)\" />\n </svg>\n )\n}\n\n/** Approved rounded-Heiti artwork, stored as paths with no runtime font dependency. */\nexport function WanxiangWordmark({ height, accessible = false, className }: {\n height: number\n accessible?: boolean\n className?: string | undefined\n}) {\n const accessibility = accessible\n ? { role: 'img', 'aria-label': '万相数据平台' }\n : { 'aria-hidden': true }\n return (\n <svg\n width={height * WORDMARK_RATIO}\n height={height}\n className={className}\n viewBox={WORDMARK_VIEWBOX}\n {...accessibility}\n >\n <g\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeWidth=\"42\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n paintOrder=\"stroke fill\"\n >\n {WORDMARK_PATHS.map(path => <path key={path.transform} d={path.d} transform={path.transform} />)}\n </g>\n </svg>\n )\n}\n\n/** Exact HARNESS badge artwork extracted from the current DSH BrandWordmark. */\nexport function HarnessBadge({ height = 14 }: { height?: number }) {\n const style = { '--dsw-alias-label-primary-inverted': 'var(--dsw-alias-bg-base)' } as CSSProperties\n return (\n <svg\n width={(height * 53) / 15.5}\n height={height}\n className={css.harness}\n viewBox=\"129 5 53 15.5\"\n style={style}\n aria-hidden=\"true\"\n >\n <rect x=\"129.348\" y=\"5.5\" width=\"52\" height=\"14\" rx=\"2\" fill=\"currentColor\" />\n {HARNESS_PATHS.map((path, index) => <path key={index} d={path.d} fill={path.fill} />)}\n </svg>\n )\n}\n\n/** Expanded-sidebar brand name plus the unchanged official HARNESS badge. */\nexport function WanxiangSidebarName() {\n return <span className={css.sidebarName}><WanxiangWordmark height={16} /><HarnessBadge height={14} /></span>\n}\n\n/** Welcome-page logo with four-unit hover motion. */\nexport function WanxiangHeroMark({ size, className }: MarkProps) {\n return <WanxiangMark size={size} className={className} animated />\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport { wanxiangBrandPreference } from './brand-store.ts'\nimport {\n WanxiangHeroMark,\n WanxiangMark,\n WanxiangSidebarName,\n} from './WanxiangBrand.tsx'\n\nconst BRAND_TITLE = '万相数据平台 Harness'\nconst SLOT_PRIORITY = -100\nconst FAVICON_ID = 'dataops-wanxiang-favicon'\nconst FAVICON_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 54 58\"><style>:root{color:#1b1b1d}@media(prefers-color-scheme:dark){:root{color:#f7f7f8}}</style><g transform=\"translate(15 0)\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linejoin=\"round\"><path d=\"M12 0 24 7 12 14 0 7Z\" fill=\"none\"/><path d=\"M0 7 12 14v16L0 23Z\" fill=\"currentColor\"/><path d=\"M12 14 24 7v16L12 30Z\" fill=\"currentColor\" fill-opacity=\".18\"/></g><g transform=\"translate(0 16)\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linejoin=\"round\"><path d=\"M12 0 24 7 12 14 0 7Z\" fill=\"none\"/><path d=\"M0 7 12 14v16L0 23Z\" fill=\"currentColor\"/><path d=\"M12 14 24 7v16L12 30Z\" fill=\"currentColor\" fill-opacity=\".18\"/></g><g transform=\"translate(30 16)\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linejoin=\"round\"><path d=\"M12 0 24 7 12 14 0 7Z\" fill=\"none\"/><path d=\"M0 7 12 14v16L0 23Z\" fill=\"currentColor\"/><path d=\"M12 14 24 7v16L12 30Z\" fill=\"currentColor\" fill-opacity=\".18\"/></g><g transform=\"translate(15 27)\" stroke=\"currentColor\" stroke-width=\"1.7\" stroke-linejoin=\"round\"><path d=\"M12 0 24 7 12 14 0 7Z\" fill=\"none\"/><path d=\"M0 7 12 14v16L0 23Z\" fill=\"currentColor\"/><path d=\"M12 14 24 7v16L12 30Z\" fill=\"currentColor\" fill-opacity=\".18\"/></g></svg>`\n\n\nfunction registerWanxiangSlots(ctx: ClientContext): () => void {\n return ctx.slots.inject('sidebar.brand.mark', () =>\n ctx.slots.inject('sidebar.brand.name', () =>\n ctx.slots.inject('conversation.hero.brand.mark', function* () {\n yield ctx.slots.register({\n name: 'sidebar.brand.mark',\n priority: SLOT_PRIORITY,\n registrant: 'dataops-managed',\n }, WanxiangMark)\n yield ctx.slots.register({\n name: 'sidebar.brand.name',\n priority: SLOT_PRIORITY,\n registrant: 'dataops-managed',\n }, WanxiangSidebarName)\n yield ctx.slots.register({\n name: 'conversation.hero.brand.mark',\n priority: SLOT_PRIORITY,\n registrant: 'dataops-managed',\n }, WanxiangHeroMark)\n })))\n}\n\nfunction installFavicon(): HTMLLinkElement {\n const existing = document.getElementById(FAVICON_ID)\n if (existing instanceof HTMLLinkElement) return existing\n const link = document.createElement('link')\n link.id = FAVICON_ID\n link.rel = 'icon'\n link.type = 'image/svg+xml'\n link.href = `data:image/svg+xml,${encodeURIComponent(FAVICON_SVG)}`\n document.head.append(link)\n return link\n}\n\n/** Keep shell slots, browser title, and favicon on the same persisted preference. */\nexport function installWanxiangBranding(ctx: ClientContext): void {\n const originalTitle = document.title\n let disposeSlots: (() => void) | undefined\n let favicon: HTMLLinkElement | undefined\n let titleObserver: MutationObserver | undefined\n\n const stopTitleObserver = (): void => {\n titleObserver?.disconnect()\n titleObserver = undefined\n }\n const keepBrandTitle = (): void => {\n if (document.title !== BRAND_TITLE) document.title = BRAND_TITLE\n if (titleObserver !== undefined) return\n titleObserver = new MutationObserver(() => {\n if (wanxiangBrandPreference.getSnapshot().enabled && document.title !== BRAND_TITLE) {\n document.title = BRAND_TITLE\n }\n })\n titleObserver.observe(document.head, { childList: true, subtree: true, characterData: true })\n }\n\n const synchronize = (): void => {\n const enabled = wanxiangBrandPreference.getSnapshot().enabled\n if (enabled) {\n disposeSlots ??= registerWanxiangSlots(ctx)\n favicon ??= installFavicon()\n keepBrandTitle()\n document.documentElement.dataset.dataopsBrand = 'wanxiang'\n return\n }\n disposeSlots?.()\n disposeSlots = undefined\n favicon?.remove()\n favicon = undefined\n stopTitleObserver()\n document.title = originalTitle\n delete document.documentElement.dataset.dataopsBrand\n }\n\n ctx.effect(() => {\n synchronize()\n const unsubscribe = wanxiangBrandPreference.subscribe(synchronize)\n return () => {\n unsubscribe()\n disposeSlots?.()\n favicon?.remove()\n stopTitleObserver()\n document.title = originalTitle\n delete document.documentElement.dataset.dataopsBrand\n }\n }, 'dataops-managed: Wanxiang shell branding')\n}\n","/** English managed DataOps Settings copy. */\nexport const en = {\n nav: 'DataOps',\n title: 'DataOps',\n managed: 'Managed by this DataOps workspace',\n description: 'DSH uses your current DataOps session JWT. DataOps applies its role and resource permissions to every tool request.',\n identityLabel: 'Identity and permissions',\n identityValue: 'Current DataOps JWT',\n toolsLabel: 'DataOps tools',\n toolsValue: 'Authorized by DataOps on every request',\n brandingTitle: 'Apply Wanxiang branding',\n brandingDescription: 'Use the Wanxiang Data Platform identity in navigation, the New Session welcome view, browser title, and favicon.',\n brandingToggle: 'Apply Wanxiang branding',\n} as const\n\n/** Stable key set shared by every managed DataOps locale. */\nexport type ManagedDataOpsKey = keyof typeof en\n\n/** Chinese managed DataOps Settings copy. */\nexport const zh: Record<ManagedDataOpsKey, string> = {\n nav: 'DataOps',\n title: 'DataOps',\n managed: '由当前 DataOps 工作区托管',\n description: 'DSH 使用当前 DataOps 会话 JWT;DataOps 对每次工具请求应用角色与资源权限。',\n identityLabel: '身份与权限',\n identityValue: '当前 DataOps JWT',\n toolsLabel: 'DataOps 工具',\n toolsValue: '每次请求均由 DataOps 授权',\n brandingTitle: '应用万相品牌',\n brandingDescription: '在导航、新会话欢迎页、浏览器标题和图标中使用万相数据平台品牌。',\n brandingToggle: '应用万相品牌',\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport { ManagedDataOpsSection } from './ManagedDataOpsSection.tsx'\nimport { installWanxiangBranding } from './install-branding.tsx'\nimport type { ManagedDataOpsSectionInjected } from './ManagedDataOpsSection.tsx'\nimport { en, zh, type ManagedDataOpsKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.dataops-managed': ManagedDataOpsKey\n }\n}\n\nconst NS = 'settings.dataops-managed'\nconst AUTH_UPDATED_MESSAGE = 'dataops-auth-updated'\nconst MANAGED_AUTH_PATH = '/integrations/dataops/managed-auth'\n\n/** Required client services for the managed DataOps Settings section. */\nexport const inject = ['slots', 'locale']\n\n/**\n * Register localized managed DataOps Settings navigation and content.\n * @param ctx - DSH client context with locale and settings slots.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dataops-managed: settings copy')\n installWanxiangBranding(ctx)\n const t = ctx.locale.bind(NS) as ManagedDataOpsSectionInjected['t']\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'dataops',\n order: 25,\n label: () => t('nav'),\n inject: () => ({ t }),\n }, ManagedDataOpsSection))\n\n const synchronizeJwt = async (): Promise<void> => {\n const response = await fetch(new URL(MANAGED_AUTH_PATH, window.location.origin), {\n method: 'POST',\n credentials: 'same-origin',\n })\n if (!response.ok) throw new Error(`DataOps managed JWT synchronization failed with HTTP ${String(response.status)}`)\n }\n const onMessage = (event: MessageEvent<unknown>): void => {\n if (event.source !== window.parent\n || (event.data as { type?: unknown } | null)?.type !== AUTH_UPDATED_MESSAGE) return\n void synchronizeJwt().catch(error => console.error('dataops-managed.jwt_sync_failed', error))\n }\n ctx.effect(() => {\n window.addEventListener('message', onMessage)\n void synchronizeJwt().catch(error => console.error('dataops-managed.jwt_sync_failed', error))\n return () => window.removeEventListener('message', onMessage)\n }, 'dataops-managed: JWT synchronization')\n}\n"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -1,10 +1,88 @@
1
+ import { credentialRef } from "@deepseek-ai/dsh-credentials";
2
+ import * as McpClient from "@sparkelf/dsh-plugin-mcp-credentials";
3
+ import z from "@deepseek-ai/schemastery";
1
4
  //#region src/index.ts
2
- /** Cordis plugin name for the DataOps-managed Settings contribution. */
5
+ /** Cordis plugin name for the DataOps-managed integration. */
3
6
  const name = "dataops-managed";
7
+ /** Host services required by managed JWT and MCP ownership. */
8
+ const inject = [
9
+ "credentials",
10
+ "webServer",
11
+ "tools"
12
+ ];
13
+ const MANAGED_AUTH_PATH = "/integrations/dataops/managed-auth";
14
+ /** Schemastery parser for managed DataOps configuration. */
15
+ const Config = z.object({
16
+ baseUrl: z.string().default("http://host.docker.internal:3101"),
17
+ serverName: z.string().default("dataops"),
18
+ credentialRef: z.string().role("credential-ref").default("DATAOPS_ACCESS_TOKEN"),
19
+ toolCallTimeoutMs: z.number().min(1).default(12e4)
20
+ });
21
+ function bearerToken(request) {
22
+ const authorization = request.headers.authorization?.trim() ?? "";
23
+ if (!authorization.startsWith("Bearer ")) return null;
24
+ const token = authorization.slice(7).trim();
25
+ return token === "" ? null : token;
26
+ }
4
27
  /**
5
- * Keep the Host seat intentionally empty because DataOps owns the broker process.
6
- * @param _ctx - DSH Host context retained for the installable bundle contract.
28
+ * Accept the current DataOps JWT and expose DataOps MCP tools through its credential.
29
+ * @param ctx - DSH Host context with credentials, Web routes, and tools.
30
+ * @param config - Managed DataOps origin and MCP settings.
31
+ * @returns Startup readiness after an existing JWT is connected when present.
7
32
  */
8
- function apply(_ctx) {}
33
+ async function apply(ctx, config) {
34
+ const baseUrl = new URL(config.baseUrl).origin;
35
+ const accessRef = credentialRef(config.credentialRef);
36
+ let mcpFiber;
37
+ const ensureMcp = async () => {
38
+ if (mcpFiber !== void 0 && mcpFiber.uid !== null) return;
39
+ const fiber = ctx.plugin(McpClient, {
40
+ transport: "streamable-http",
41
+ serverName: config.serverName,
42
+ url: `${baseUrl}/api/ai/data-query/mcp`,
43
+ headers: {},
44
+ bearerTokenRef: config.credentialRef,
45
+ toolCallTimeoutMs: config.toolCallTimeoutMs
46
+ });
47
+ mcpFiber = fiber;
48
+ try {
49
+ await fiber.await();
50
+ } catch (error) {
51
+ if (mcpFiber === fiber) mcpFiber = void 0;
52
+ await fiber.dispose();
53
+ throw error;
54
+ }
55
+ };
56
+ ctx.effect(() => async () => {
57
+ const fiber = mcpFiber;
58
+ mcpFiber = void 0;
59
+ if (fiber !== void 0 && fiber.uid !== null) await fiber.dispose();
60
+ }, "dataops-managed: MCP lifecycle");
61
+ if (await ctx.credentials.resolve(accessRef) !== void 0) await ensureMcp();
62
+ ctx.effect(() => ctx.webServer.register({
63
+ kind: "exact",
64
+ path: MANAGED_AUTH_PATH,
65
+ handler: async (request, response) => {
66
+ if (request.method !== "POST") {
67
+ response.writeHead(405, {
68
+ allow: "POST",
69
+ "content-length": "0"
70
+ });
71
+ response.end();
72
+ return;
73
+ }
74
+ const token = bearerToken(request);
75
+ if (token === null) {
76
+ response.writeHead(401, { "content-length": "0" });
77
+ response.end();
78
+ return;
79
+ }
80
+ await ctx.credentials.set(accessRef, token);
81
+ await ensureMcp();
82
+ response.writeHead(204, { "cache-control": "no-store" });
83
+ response.end();
84
+ }
85
+ }), "dataops-managed: JWT intake route");
86
+ }
9
87
  //#endregion
10
- export { apply, name };
88
+ export { Config, MANAGED_AUTH_PATH, apply, inject, name };
@@ -8,7 +8,7 @@ export interface ManagedDataOpsSectionInjected {
8
8
  /** Props accepted by the managed DataOps Settings section. */
9
9
  export type ManagedDataOpsSectionProps = Partial<InjectFace<ManagedDataOpsSectionInjected>>;
10
10
  /**
11
- * Explain DataOps-managed ownership without exposing standalone authorization controls.
11
+ * Explain the DataOps-managed JWT and permission owner without standalone controls.
12
12
  * @param props - Settings slot injection values.
13
13
  * @returns The localized managed DataOps section, or nothing before injection.
14
14
  */
@@ -0,0 +1,23 @@
1
+ interface MarkProps {
2
+ size: number;
3
+ className?: string | undefined;
4
+ }
5
+ /** Four linked data units; its ink follows the host surface through currentColor. */
6
+ export declare function WanxiangMark({ size, className, animated }: MarkProps & {
7
+ animated?: boolean;
8
+ }): import("react").JSX.Element;
9
+ /** Approved rounded-Heiti artwork, stored as paths with no runtime font dependency. */
10
+ export declare function WanxiangWordmark({ height, accessible, className }: {
11
+ height: number;
12
+ accessible?: boolean;
13
+ className?: string | undefined;
14
+ }): import("react").JSX.Element;
15
+ /** Exact HARNESS badge artwork extracted from the current DSH BrandWordmark. */
16
+ export declare function HarnessBadge({ height }: {
17
+ height?: number;
18
+ }): import("react").JSX.Element;
19
+ /** Expanded-sidebar brand name plus the unchanged official HARNESS badge. */
20
+ export declare function WanxiangSidebarName(): import("react").JSX.Element;
21
+ /** Welcome-page logo with four-unit hover motion. */
22
+ export declare function WanxiangHeroMark({ size, className }: MarkProps): import("react").JSX.Element;
23
+ export {};
@@ -0,0 +1,13 @@
1
+ /** Persisted client preference for the managed DataOps shell identity. */
2
+ export interface WanxiangBrandPreference {
3
+ enabled: boolean;
4
+ }
5
+ /** Stable local preference key shared by Settings and brand-slot registration. */
6
+ export declare const WANXIANG_BRAND_PREFERENCE_KEY = "dsh.dataops.wanxiangBrand";
7
+ /** Observable preference compatible with React's useSyncExternalStore. */
8
+ export declare const wanxiangBrandPreference: {
9
+ getSnapshot: () => WanxiangBrandPreference;
10
+ subscribe: (listener: () => void) => (() => void);
11
+ };
12
+ /** Toggle the Wanxiang shell identity from the DataOps Settings section. */
13
+ export declare function setWanxiangBrandEnabled(enabled: boolean): void;
@@ -1,4 +1,4 @@
1
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
1
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
2
  import { type ManagedDataOpsKey } from './locales.ts';
3
3
  declare module '@deepseek-ai/dsh-client-ui-slots' {
4
4
  interface LocaleNamespaceMap {
@@ -0,0 +1,3 @@
1
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
2
+ /** Keep shell slots, browser title, and favicon on the same persisted preference. */
3
+ export declare function installWanxiangBranding(ctx: ClientContext): void;
@@ -3,11 +3,14 @@ export declare const en: {
3
3
  readonly nav: "DataOps";
4
4
  readonly title: "DataOps";
5
5
  readonly managed: "Managed by this DataOps workspace";
6
- readonly description: "DataOps tools are provided automatically through the workspace-managed channel. No connection or authorization is required here.";
6
+ readonly description: "DSH uses your current DataOps session JWT. DataOps applies its role and resource permissions to every tool request.";
7
7
  readonly identityLabel: "Identity and permissions";
8
- readonly identityValue: "Managed by your current DataOps session";
8
+ readonly identityValue: "Current DataOps JWT";
9
9
  readonly toolsLabel: "DataOps tools";
10
- readonly toolsValue: "Provided automatically by the workspace";
10
+ readonly toolsValue: "Authorized by DataOps on every request";
11
+ readonly brandingTitle: "Apply Wanxiang branding";
12
+ readonly brandingDescription: "Use the Wanxiang Data Platform identity in navigation, the New Session welcome view, browser title, and favicon.";
13
+ readonly brandingToggle: "Apply Wanxiang branding";
11
14
  };
12
15
  /** Stable key set shared by every managed DataOps locale. */
13
16
  export type ManagedDataOpsKey = keyof typeof en;
@@ -1,8 +1,28 @@
1
+ /** DataOps-managed JWT intake and credential-backed MCP composition. */
1
2
  import type { Context } from '@deepseek-ai/cordis';
2
- /** Cordis plugin name for the DataOps-managed Settings contribution. */
3
+ import z from '@deepseek-ai/schemastery';
4
+ /** Cordis plugin name for the DataOps-managed integration. */
3
5
  export declare const name = "dataops-managed";
6
+ /** Host services required by managed JWT and MCP ownership. */
7
+ export declare const inject: string[];
8
+ export declare const MANAGED_AUTH_PATH = "/integrations/dataops/managed-auth";
9
+ /** Configuration for the DataOps-managed MCP connection. */
10
+ export interface Config {
11
+ /** DataOps browser/API origin reachable from the DSH Host. */
12
+ baseUrl: string;
13
+ /** Local namespace for DataOps MCP tools. */
14
+ serverName: string;
15
+ /** DSH credential reference that stores the current DataOps access JWT. */
16
+ credentialRef: string;
17
+ /** Per-tool-call timeout forwarded to the MCP client. */
18
+ toolCallTimeoutMs: number;
19
+ }
20
+ /** Schemastery parser for managed DataOps configuration. */
21
+ export declare const Config: z<Config>;
4
22
  /**
5
- * Keep the Host seat intentionally empty because DataOps owns the broker process.
6
- * @param _ctx - DSH Host context retained for the installable bundle contract.
23
+ * Accept the current DataOps JWT and expose DataOps MCP tools through its credential.
24
+ * @param ctx - DSH Host context with credentials, Web routes, and tools.
25
+ * @param config - Managed DataOps origin and MCP settings.
26
+ * @returns Startup readiness after an existing JWT is connected when present.
7
27
  */
8
- export declare function apply(_ctx: Context): void;
28
+ export declare function apply(ctx: Context, config: Config): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sparkelf/dsh-dataops-managed",
3
- "version": "0.1.0",
4
- "description": "Managed DataOps workspace ownership information for DeepSeek Harness settings.",
3
+ "version": "0.3.1",
4
+ "description": "DataOps JWT intake and credential-backed MCP tools for managed DeepSeek Harness workspaces.",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
7
7
  "types": "./lib/types/index.d.ts",
@@ -23,11 +23,13 @@
23
23
  "client": {
24
24
  "platform": "web",
25
25
  "inject": [
26
- "@deepseek-ai/dsh-client-runtime",
27
26
  "@deepseek-ai/dsh-client-ui-settings",
28
27
  "@deepseek-ai/dsh-client-locale",
29
28
  "@deepseek-ai/dsh-client-ui-primitives",
30
- "@deepseek-ai/dsh-client-ui-slots"
29
+ "@deepseek-ai/dsh-client-ui-slots",
30
+ "@deepseek-ai/dsh-client-ui-renderer",
31
+ "@deepseek-ai/dsh-client-ui-conversation",
32
+ "@deepseek-ai/dsh-client-ui-sidebar"
31
33
  ]
32
34
  }
33
35
  },
@@ -53,25 +55,39 @@
53
55
  "access": "public"
54
56
  },
55
57
  "peerDependencies": {
56
- "@deepseek-ai/cordis": "^4.0.1",
57
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
58
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
59
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
60
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
61
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
62
- "react": ">=18.2.0 <20"
58
+ "@deepseek-ai/cordis": "^4.0.2",
59
+ "@deepseek-ai/dsh-credentials": "0.1.5-alpha.1",
60
+ "@deepseek-ai/dsh-host-webserver": "0.1.5-alpha.1",
61
+ "@deepseek-ai/dsh-client-locale": "0.1.5-alpha.1",
62
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-alpha.1",
63
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.5-alpha.1",
64
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-alpha.1",
65
+ "@deepseek-ai/dsh-tools": "0.1.5-alpha.1",
66
+ "@deepseek-ai/schemastery": ">=3.18.1",
67
+ "@sparkelf/dsh-plugin-mcp-credentials": ">=0.1.0-rc.14",
68
+ "react": ">=18.2.0 <20",
69
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-alpha.1",
70
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-alpha.1",
71
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.5-alpha.1"
63
72
  },
64
73
  "devDependencies": {
65
- "@deepseek-ai/cordis": "4.0.1",
66
- "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
67
- "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
68
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
69
- "@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
70
- "@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
74
+ "@deepseek-ai/cordis": "4.0.2",
75
+ "@deepseek-ai/dsh-credentials": "0.1.5-alpha.1",
76
+ "@deepseek-ai/dsh-host-webserver": "0.1.5-alpha.1",
77
+ "@deepseek-ai/dsh-client-locale": "0.1.5-alpha.1",
78
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-alpha.1",
79
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.5-alpha.1",
80
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-alpha.1",
81
+ "@deepseek-ai/dsh-tools": "0.1.5-alpha.1",
82
+ "@deepseek-ai/schemastery": "3.18.2",
83
+ "@sparkelf/dsh-plugin-mcp-credentials": "0.1.0-rc.14",
71
84
  "@types/react": "~18.3.1",
72
85
  "lightningcss": "^1.32.0",
73
86
  "react": "^18.2.0",
74
- "tsdown": "^0.22.2"
87
+ "tsdown": "^0.22.2",
88
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-alpha.1",
89
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-alpha.1",
90
+ "@deepseek-ai/dsh-client-ui-sidebar": "0.1.5-alpha.1"
75
91
  },
76
92
  "scripts": {
77
93
  "build": "rm -rf lib && tsc -p tsconfig.build.json && tsdown",