@deepseek-ai/dsh-client-ui-settings-general 0.1.5-rc.2 → 0.1.6-alpha.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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/ui-settings-general/README.md
5
- README.md: 845d9c48dce2264d478f0ac854ef85a480828a14
6
- README.zh.md: 4a96e78a13dd8e6aefd759926f6e2cb153f0b259
5
+ README.md: af68c42ad111f74e68037436e18a5be57195a64b
6
+ README.zh.md: f929df66a13cde7beb63721922f2a3f4aa90ba43
package/README.md CHANGED
@@ -25,7 +25,7 @@ Use this package to give the dsh web client a Settings panel, connection-recover
25
25
  <a id="use-this-package"></a>
26
26
  ## Use this package
27
27
 
28
- Users reach the shell through the sidebar's bottom Settings control; feature plugins contribute their pages and onboarding steps through the slot ledgers this shell projects. In both the expanded sidebar and collapsed rail, the control exposes the localized Settings label as its accessible name. A pale-yellow **Disconnected** action beside Settings indicates browser offline suspension. Automatic recovery shows **Reconnecting** with one to three dots advancing every 500ms. Hover or keyboard focus changes either yellow label to **Reconnect now** without changing its background; press feedback stays within the warning palette, and selecting it starts retry 1 immediately. Recovery changes the region to pale-green **Connected** for two seconds before it disappears. The icon, left-aligned text origin, height, and width remain fixed across every visible state. Initial startup and uninterrupted healthy operation remain silent. The shell renders the modal panel, the navigation built from `settings.section` entries, and exactly one mounted onboarding step at a time.
28
+ Users reach the shell through the sidebar's bottom Settings control; feature plugins contribute their pages and onboarding steps through the slot ledgers this shell projects. In both the expanded sidebar and collapsed rail, the control exposes the localized Settings label as its accessible name. A pale-yellow **Disconnected** action beside Settings indicates browser offline suspension; its permanent retry glyph marks the retry action, which the Chinese outage copy also names (连接异常,刷新重试). Every recovery attempt shows a spinner beside **Reconnecting** with one to three dots advancing every 500ms, and an attempt stays visible for at least 800ms so brief retries do not flicker. Selecting either yellow state starts an immediate retry; press feedback stays within the warning palette. Recovery changes the region to pale-green **Connected** for two seconds from the moment the green pill becomes visible. The pill fades in on appearance, fades out over 150ms on removal, and sizes to its current label. Initial startup and uninterrupted healthy operation remain silent. The shell renders the modal panel, the navigation built from `settings.section` entries, and exactly one mounted onboarding step at a time.
29
29
 
30
30
  ### The General section
31
31
 
@@ -55,7 +55,7 @@ The navigation is a projection of the `settings.section` ledger; nav labels may
55
55
 
56
56
  ### Connection recovery
57
57
 
58
- The shell is an explicit recovery consumer, so it injects Connection directly rather than adding lifecycle controls to `ctx.remote`. Its private hooks compartment binds `ctx.connection.state`, while the component receives only the selected state and an injected callback for `ctx.connection.reconnect()`. `ConnectionIndicator` owns the inline presentation and receives all visible and accessible copy from the `settings` locale namespace; the shell owns the two-second recovered-state timer.
58
+ The shell is an explicit recovery consumer, so it injects Connection directly rather than adding lifecycle controls to `ctx.remote`. Its private hooks compartment binds `ctx.connection.state`, while the component receives only the selected state and an injected callback for `ctx.connection.reconnect()`. `ConnectionIndicator` owns the inline presentation and receives all visible and accessible copy from the `settings` locale namespace; the shell owns the 800ms minimum-visible hold for the connecting state and the two-second recovered-state timer, which starts when the recovered pill becomes visible after the hold.
59
59
 
60
60
  ### Document availability
61
61
 
package/README.zh.md CHANGED
@@ -25,7 +25,7 @@ kind: "package-reference"
25
25
  <a id="use-this-package"></a>
26
26
  ## 使用本包
27
27
 
28
- 用户通过侧边栏底部的 Settings 控件进入外壳;功能插件通过本外壳所投影的 slot 账本贡献自己的页面与引导步骤。在展开侧边栏和收起轨道中,该控件都会把本地化的 Settings 文案作为其可访问名称。Settings 右侧浅黄色的**连接异常**操作表示浏览器离线暂停;自动恢复期间显示**自动重连中**,其后一至三个点每 500ms 前进一次。鼠标悬浮或键盘聚焦任一黄色状态时,只有文案变为**立即重连**,背景保持不变;按压反馈留在黄色色阶内,选中后立即从 retry 1 开始。恢复后该区域变为浅绿色的**连接成功**,驻留 2 秒再消失。所有可见状态的文字都左对齐,且图标、文字起点、高度和宽度保持固定。首次启动与未曾中断的健康连接保持静默。外壳渲染模态面板、由 `settings.section` 条目构建的导航,以及每次只挂载一个的引导步骤。
28
+ 用户通过侧边栏底部的 Settings 控件进入外壳;功能插件通过本外壳所投影的 slot 账本贡献自己的页面与引导步骤。在展开侧边栏和收起轨道中,该控件都会把本地化的 Settings 文案作为其可访问名称。Settings 右侧浅黄色的**连接异常**操作表示浏览器离线暂停;其常驻重试图形与中文文案「连接异常,刷新重试」都指明重试动作。每次恢复尝试都显示 spinner 加**重新连接中**,其后一至三个点每 500ms 前进一次,且每次尝试至少可见 800ms,短暂重试不会闪动。选中任一黄色状态都会立即发起重试;按压反馈留在黄色色阶内。恢复后该区域变为浅绿色的**连接成功**,从绿色药丸可见起驻留 2 秒再消失。药丸出现时淡入、移除时以 150ms 淡出,宽度随当前文案自适应。首次启动与未曾中断的健康连接保持静默。外壳渲染模态面板、由 `settings.section` 条目构建的导航,以及每次只挂载一个的引导步骤。
29
29
 
30
30
  ### 「通用」分区
31
31
 
@@ -55,11 +55,11 @@ kind: "package-reference"
55
55
 
56
56
  ### 连接恢复
57
57
 
58
- 外壳是明确的恢复功能消费方,因此直接注入 Connection,而不把生命周期控制放进 `ctx.remote`。它的私有 hooks compartment 绑定 `ctx.connection.state`,组件只接收选出的状态与调用 `ctx.connection.reconnect()` 的注入回调。`ConnectionIndicator` 拥有内联展示并从 `settings` locale namespace 接收全部可见与无障碍文案;2 秒恢复状态计时器归外壳所有。
58
+ 外壳是明确的恢复功能消费方,因此直接注入 Connection,而不把生命周期控制放进 `ctx.remote`。它的私有 hooks compartment 绑定 `ctx.connection.state`,组件只接收选出的状态与调用 `ctx.connection.reconnect()` 的注入回调。`ConnectionIndicator` 拥有内联展示并从 `settings` locale namespace 接收全部可见与无障碍文案;连接中状态的 800ms 最短可见驻留与 2 秒恢复确认计时器归外壳所有;恢复计时从驻留结束、恢复药丸实际可见时开始。
59
59
 
60
60
  ### 文档可用性
61
61
 
62
- 在 loopback 页面上,Client 通过 `settings/describe` 加载提供方的 `hasDocument` 能力,且只有在 Host 确认可准备好一份由提供方持有的本地文档时才渲染配置文件操作。该操作调用无路径参数且经浏览器认证的 `settings/openSettingsDocument` Remote;Host 会再次解析提供方路径、在文档缺失时将其创建出来,并交给原生文本编辑器(macOS 上使用 `open -t`,绕过浏览器文件关联;Linux 和 Windows 上使用桌面文件关联;WSL 上经 `wslpath -w` 转换后使用 Windows 文件关联)。打开失败时该操作仍可使用,并渲染本地化错误。临时读取失败或 Host 拓扑变化后,重新打开对话框或重新连接会刷新可用性。非 loopback 页面保留 Client 策略,不提供该原生操作及其 settings 读取。
62
+ 在 loopback 页面上,Client 通过 `settings/describe` 加载提供方的 `hasDocument` 能力,且只有在 Host 确认可准备好一份由提供方持有的本地文档时才渲染**打开配置文件**操作。该操作调用无路径参数且经浏览器认证的 `settings/openSettingsDocument` Remote;Host 会再次解析提供方路径、在文档缺失时将其创建出来,并交给原生文本编辑器(macOS 上使用 `open -t`,绕过浏览器文件关联;Linux 和 Windows 上使用桌面文件关联;WSL 上经 `wslpath -w` 转换后使用 Windows 文件关联)。打开失败时该操作仍可使用,并渲染本地化错误。临时读取失败或 Host 拓扑变化后,重新打开对话框或重新连接会刷新可用性。非 loopback 页面保留 Client 策略,不提供该原生操作及其 settings 读取。
63
63
 
64
64
  ### 宿主端
65
65
 
package/lib/client.js CHANGED
@@ -72,6 +72,8 @@ window.__ModuleLoader__.load({
72
72
  * to the step, so a mounted-but-deciding step paints nothing here.
73
73
  */
74
74
  const RECOVERY_CONFIRMATION_MS = 2e3;
75
+ /** Minimum visible time for the connecting pill; shorter attempts read as flicker. */
76
+ const CONNECTING_MIN_VISIBLE_MS = 800;
75
77
  /** Nav glyph by section id; unknown ids fall back to the settings gear. */
76
78
  function navIcon(id) {
77
79
  if (id === "models") return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDataOutline16, {
@@ -86,6 +88,10 @@ window.__ModuleLoader__.load({
86
88
  className: SettingsRoot_module_css_default.navIcon,
87
89
  size: 16
88
90
  });
91
+ if (id === "archived-sessions") return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconArchiveOutline20, {
92
+ className: SettingsRoot_module_css_default.navIcon,
93
+ size: 16
94
+ });
89
95
  return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSettingsOutline16, {
90
96
  className: SettingsRoot_module_css_default.navIcon,
91
97
  size: 16
@@ -181,6 +187,8 @@ window.__ModuleLoader__.load({
181
187
  const [activeId, setActiveId] = (0, react.useState)(void 0);
182
188
  const [completedOnboarding, setCompletedOnboarding] = (0, react.useState)(() => /* @__PURE__ */ new Set());
183
189
  const [showRecovery, setShowRecovery] = (0, react.useState)(false);
190
+ const [holdConnecting, setHoldConnecting] = (0, react.useState)(false);
191
+ const connectingShownAt = (0, react.useRef)(void 0);
184
192
  const triggerButton = (0, react.useRef)(null);
185
193
  const wasOpen = (0, react.useRef)(open);
186
194
  const close = (0, react.useCallback)(() => {
@@ -214,12 +222,34 @@ window.__ModuleLoader__.load({
214
222
  }
215
223
  if (previous !== "disconnected" && previous !== "connecting") return;
216
224
  setShowRecovery(true);
225
+ }, [connectionState]);
226
+ (0, react.useLayoutEffect)(() => {
227
+ if (!showRecovery || holdConnecting) return;
217
228
  const timeout = window.setTimeout(() => {
218
229
  setShowRecovery(false);
219
230
  }, RECOVERY_CONFIRMATION_MS);
220
231
  return () => {
221
232
  window.clearTimeout(timeout);
222
233
  };
234
+ }, [showRecovery, holdConnecting]);
235
+ (0, react.useLayoutEffect)(() => {
236
+ if (connectionState === "connecting") {
237
+ connectingShownAt.current = Date.now();
238
+ return;
239
+ }
240
+ const shownAt = connectingShownAt.current;
241
+ if (shownAt === void 0) return;
242
+ connectingShownAt.current = void 0;
243
+ const remaining = CONNECTING_MIN_VISIBLE_MS - (Date.now() - shownAt);
244
+ if (remaining <= 0) return;
245
+ setHoldConnecting(true);
246
+ const timeout = window.setTimeout(() => {
247
+ setHoldConnecting(false);
248
+ }, remaining);
249
+ return () => {
250
+ window.clearTimeout(timeout);
251
+ setHoldConnecting(false);
252
+ };
223
253
  }, [connectionState]);
224
254
  const completeOnboardingStep = (0, react.useCallback)((id) => {
225
255
  setCompletedOnboarding((previous) => {
@@ -228,8 +258,8 @@ window.__ModuleLoader__.load({
228
258
  });
229
259
  }, []);
230
260
  let connectionIndicator;
231
- if (connectionState === "disconnected") connectionIndicator = "disconnected";
232
- else if (connectionState === "connecting") connectionIndicator = "connecting";
261
+ if (connectionState === "connecting" || holdConnecting) connectionIndicator = "connecting";
262
+ else if (connectionState === "disconnected") connectionIndicator = "disconnected";
233
263
  else if (showRecovery) connectionIndicator = "recovered";
234
264
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
235
265
  (0, react_jsx_runtime.jsxs)("div", {
@@ -248,7 +278,6 @@ window.__ModuleLoader__.load({
248
278
  }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.ConnectionIndicator, {
249
279
  state: wide ? connectionIndicator : void 0,
250
280
  disconnectedLabel: t("connection.error"),
251
- reconnectLabel: t("connection.retry"),
252
281
  connectingLabel: t("connection.connecting"),
253
282
  recoveredLabel: t("connection.connected"),
254
283
  reconnectActionLabel: t("connection.reconnect"),
@@ -486,12 +515,11 @@ window.__ModuleLoader__.load({
486
515
  "openDocument": "打开配置文件",
487
516
  "openDocument.error": "无法打开配置文件",
488
517
  "general.nav": "通用设置",
489
- "connection.error": "连接异常",
490
- "connection.retry": "立即重连",
491
- "connection.connecting": "自动重连中",
518
+ "connection.error": "连接异常,刷新重试",
519
+ "connection.connecting": "重新连接中",
492
520
  "connection.connected": "连接成功",
493
521
  "connection.reconnect": "连接异常,点击立即重连",
494
- "connection.restart": "连接中断,正在自动重试,点击立即重连"
522
+ "connection.restart": "连接中断,正在重试,点击立即重连"
495
523
  };
496
524
  /** English dictionary, checked complete against the zh key set. */
497
525
  const en = {
@@ -502,11 +530,10 @@ window.__ModuleLoader__.load({
502
530
  "openDocument.error": "Could not open configuration file",
503
531
  "general.nav": "General",
504
532
  "connection.error": "Disconnected",
505
- "connection.retry": "Reconnect now",
506
533
  "connection.connecting": "Reconnecting",
507
534
  "connection.connected": "Connected",
508
535
  "connection.reconnect": "Disconnected, reconnect now",
509
- "connection.restart": "Reconnecting automatically, reconnect now"
536
+ "connection.restart": "Reconnecting, reconnect now"
510
537
  };
511
538
  //#endregion
512
539
  //#region lib/types/client/index.js
@@ -8,7 +8,6 @@ export declare const zh: {
8
8
  'openDocument.error': string;
9
9
  'general.nav': string;
10
10
  'connection.error': string;
11
- 'connection.retry': string;
12
11
  'connection.connecting': string;
13
12
  'connection.connected': string;
14
13
  'connection.reconnect': string;
@@ -25,7 +24,6 @@ export declare const en: {
25
24
  'openDocument.error': string;
26
25
  'general.nav': string;
27
26
  'connection.error': string;
28
- 'connection.retry': string;
29
27
  'connection.connecting': string;
30
28
  'connection.connected': string;
31
29
  'connection.reconnect': string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-settings-general",
3
3
  "description": "Settings ownerless-copy and product onboarding plugin: the General section, shell trigger/header chrome content, settings dictionaries, and the versioned welcome notice",
4
- "version": "0.1.5-rc.2",
4
+ "version": "0.1.6-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -46,21 +46,22 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/react": "~18.3.1",
49
- "react": "^18.2.0",
50
49
  "clsx": "^2.0.0",
51
- "@deepseek-ai/dsh-api-remotes": "^0.1.5-rc.2",
52
- "@deepseek-ai/dsh-client-connection": "^0.1.5-rc.2",
53
- "@deepseek-ai/dsh-client-locale": "^0.1.5-rc.2",
54
- "@deepseek-ai/dsh-client-store": "^0.1.5-rc.2",
55
- "@deepseek-ai/dsh-client-test-runtime": "^0.1.5-rc.2",
56
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.5-rc.2",
57
- "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.5-rc.2",
58
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.5-rc.2",
50
+ "react": "^18.2.0",
59
51
  "@deepseek-ai/cordis": "^4.0.2",
60
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.5-rc.2",
61
- "@deepseek-ai/dsh-client-ui-renderer": "^0.1.5-rc.2",
62
- "@deepseek-ai/dsh-client-ui-session": "^0.1.5-rc.2",
63
- "@deepseek-ai/dsh-settings": "^0.1.5-rc.2"
52
+ "@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.1",
53
+ "@deepseek-ai/dsh-client-connection": "^0.1.6-alpha.1",
54
+ "@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.1",
55
+ "@deepseek-ai/dsh-client-store": "^0.1.6-alpha.1",
56
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.1",
57
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.1",
58
+ "@deepseek-ai/dsh-client-ui-session": "^0.1.6-alpha.1",
59
+ "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.6-alpha.1",
60
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.1",
61
+ "@deepseek-ai/dsh-remote-mock": "^0.1.6-alpha.1",
62
+ "@deepseek-ai/dsh-settings": "^0.1.6-alpha.1",
63
+ "@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.1",
64
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.6-alpha.1"
64
65
  },
65
66
  "files": [
66
67
  "lib/index.js",