@dsh-plugin/dsh-ui-experience 1.0.0-dev.43492422772 → 1.0.0-dev.43522015745

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -40,7 +40,13 @@ var Config = z.object({
40
40
  motionSpatialSplit: z.boolean().default(true).volatile(),
41
41
  motionQuantize: z.boolean().default(false).volatile(),
42
42
  motionReduced: z.string().pattern(MOTION_REDUCED).default("system").volatile(),
43
- motionScroll: z.boolean().default(true).volatile()
43
+ motionScroll: z.boolean().default(true).volatile(),
44
+ motionStream: z.boolean().default(true).volatile(),
45
+ motionFollowScroll: z.boolean().default(true).volatile(),
46
+ streamRevealMinMs: z.number().min(60).max(2e3).default(250).volatile(),
47
+ streamRevealMaxMs: z.number().min(200).max(8e3).default(1200).volatile(),
48
+ streamEnterMs: z.number().min(0).max(2e3).default(220).volatile(),
49
+ streamRollMs: z.number().min(0).max(2e3).default(260).volatile()
44
50
  });
45
51
  var REQUIRED_COLOR_KEYS = [
46
52
  "surface_container_lowest",
@@ -321,7 +327,13 @@ function effectiveMotion(config) {
321
327
  spatialSplit: config.motionSpatialSplit.get(),
322
328
  quantize: config.motionQuantize.get(),
323
329
  reduced: config.motionReduced.get(),
324
- scroll: config.motionScroll.get()
330
+ scroll: config.motionScroll.get(),
331
+ stream: config.motionStream.get(),
332
+ followScroll: config.motionFollowScroll.get(),
333
+ streamRevealMinMs: config.streamRevealMinMs.get(),
334
+ streamRevealMaxMs: config.streamRevealMaxMs.get(),
335
+ streamEnterMs: config.streamEnterMs.get(),
336
+ streamRollMs: config.streamRollMs.get()
325
337
  };
326
338
  }
327
339
  var paletteCache;
@@ -573,9 +585,26 @@ var UiExperienceService = class extends TypertRemoteService {
573
585
  const spatialSplit = args?.spatialSplit;
574
586
  const quantize = args?.quantize;
575
587
  const scroll = args?.scroll;
576
- if (mode === void 0 && reduced === void 0 && scale === void 0 && spatialSplit === void 0 && quantize === void 0 && scroll === void 0) {
588
+ const stream = args?.stream;
589
+ const followScroll = args?.followScroll;
590
+ const streamRevealMinMs = args?.streamRevealMinMs;
591
+ const streamRevealMaxMs = args?.streamRevealMaxMs;
592
+ const streamEnterMs = args?.streamEnterMs;
593
+ const streamRollMs = args?.streamRollMs;
594
+ if (mode === void 0 && reduced === void 0 && scale === void 0 && spatialSplit === void 0 && quantize === void 0 && scroll === void 0 && stream === void 0 && followScroll === void 0 && streamRevealMinMs === void 0 && streamRevealMaxMs === void 0 && streamEnterMs === void 0 && streamRollMs === void 0) {
577
595
  throw new Error("ui-experience: setMotion requires at least one field");
578
596
  }
597
+ for (const [name, value] of [
598
+ ["streamRevealMinMs", streamRevealMinMs],
599
+ ["streamRevealMaxMs", streamRevealMaxMs],
600
+ ["streamEnterMs", streamEnterMs],
601
+ ["streamRollMs", streamRollMs]
602
+ ]) {
603
+ if (value === void 0) continue;
604
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
605
+ throw new Error(`ui-experience: ${name} must be a non-negative number, got ${String(value)}`);
606
+ }
607
+ }
579
608
  if (mode !== void 0 && !MOTION_MODE.test(mode)) {
580
609
  throw new Error(`ui-experience: unknown motion mode ${JSON.stringify(mode)}`);
581
610
  }
@@ -594,6 +623,34 @@ var UiExperienceService = class extends TypertRemoteService {
594
623
  if (scroll !== void 0 && typeof scroll !== "boolean") {
595
624
  throw new Error(`ui-experience: scroll must be a boolean, got ${typeof scroll}`);
596
625
  }
626
+ if (stream !== void 0 && typeof stream !== "boolean") {
627
+ throw new Error(`ui-experience: stream must be a boolean, got ${typeof stream}`);
628
+ }
629
+ if (followScroll !== void 0 && typeof followScroll !== "boolean") {
630
+ throw new Error(`ui-experience: followScroll must be a boolean, got ${typeof followScroll}`);
631
+ }
632
+ for (const [name, value] of [
633
+ ["streamRevealMinMs", streamRevealMinMs],
634
+ ["streamRevealMaxMs", streamRevealMaxMs],
635
+ ["streamEnterMs", streamEnterMs],
636
+ ["streamRollMs", streamRollMs]
637
+ ]) {
638
+ if (value === void 0) continue;
639
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
640
+ throw new Error(`ui-experience: ${name} must be a non-negative number, got ${String(value)}`);
641
+ }
642
+ }
643
+ for (const [name, value] of [
644
+ ["streamRevealMinMs", streamRevealMinMs],
645
+ ["streamRevealMaxMs", streamRevealMaxMs],
646
+ ["streamEnterMs", streamEnterMs],
647
+ ["streamRollMs", streamRollMs]
648
+ ]) {
649
+ if (value === void 0) continue;
650
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
651
+ throw new Error(`ui-experience: ${name} must be a non-negative number, got ${String(value)}`);
652
+ }
653
+ }
597
654
  await this.persist((current) => ({
598
655
  ...current,
599
656
  ...mode === void 0 ? {} : { motion: mode },
@@ -601,10 +658,16 @@ var UiExperienceService = class extends TypertRemoteService {
601
658
  ...scale === void 0 ? {} : { motionDurationScale: scale },
602
659
  ...spatialSplit === void 0 ? {} : { motionSpatialSplit: spatialSplit },
603
660
  ...quantize === void 0 ? {} : { motionQuantize: quantize },
604
- ...scroll === void 0 ? {} : { motionScroll: scroll }
661
+ ...scroll === void 0 ? {} : { motionScroll: scroll },
662
+ ...stream === void 0 ? {} : { motionStream: stream },
663
+ ...followScroll === void 0 ? {} : { motionFollowScroll: followScroll },
664
+ ...streamRevealMinMs === void 0 ? {} : { streamRevealMinMs },
665
+ ...streamRevealMaxMs === void 0 ? {} : { streamRevealMaxMs },
666
+ ...streamEnterMs === void 0 ? {} : { streamEnterMs },
667
+ ...streamRollMs === void 0 ? {} : { streamRollMs }
605
668
  }));
606
669
  const applied = effectiveMotion(this.config);
607
- logLine(`setMotion: mode=${applied.mode} durationScale=${String(applied.durationScale)} spatialSplit=${String(applied.spatialSplit)} quantize=${String(applied.quantize)} reduced=${applied.reduced} scroll=${String(applied.scroll)}`);
670
+ logLine(`setMotion: mode=${applied.mode} durationScale=${String(applied.durationScale)} spatialSplit=${String(applied.spatialSplit)} quantize=${String(applied.quantize)} reduced=${applied.reduced} scroll=${String(applied.scroll)} stream=${String(applied.stream)}`);
608
671
  return applied;
609
672
  }
610
673
  /**
package/locale/en.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "meta": {
3
3
  "title": "Interface experience",
4
- "description": "Make the DSH interface follow the Material You palette matugen generates on the system. After enabling Settings → General → Matugen palette sync, the palette is layered over the current theme and follows the file whenever matugen regenerates it. Expand Palette file paths on the same row to rewrite the matugen colors file or the DSH token file path (both default under ~/.local/state/quickshell/user/generated/, the token file wins when present). Palette files are read locally and never uploaded; turning the switch off returns the native colors. Also unifies the interface border width (config option borderWidth, default 0.5px); that override applies only while the switch is on and narrows decorative borders such as markdown quote rules. A separate M3 motion row rewrites every transition and keyframe animation in the interface onto Material 3 / Material 3 Expressive curves, in place, with its own curve family, duration scale, duration snapping, and reduced-motion policy; the rewrite reaches styles injected by other plugins and restores everything exactly when switched off."
4
+ "description": "Make the DSH interface follow the Material You palette matugen generates on the system. After enabling Settings → General → Matugen palette sync, the palette is layered over the current theme and follows the file whenever matugen regenerates it. Expand Palette file paths on the same row to rewrite the matugen colors file or the DSH token file path (both default under ~/.local/state/quickshell/user/generated/, the token file wins when present). Palette files are read locally and never uploaded; turning the switch off returns the native colors. Also unifies the interface border width (config option borderWidth, default 0.5px); that override applies only while the switch is on and narrows decorative borders such as markdown quote rules. A separate M3 motion row rewrites every transition and keyframe animation in the interface onto Material 3 / Material 3 Expressive curves, in place, with its own curve family, duration scale, duration snapping, and reduced-motion policy; the rewrite reaches styles injected by other plugins and restores everything exactly when switched off. The same row also takes over smooth scrolling (including wheel easing) and the progressive reveal of streamed text: no character is truncated, only a mask moves, so selection, copying, and screen readers are unaffected."
5
5
  }
6
6
  }
package/locale/zh.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "meta": {
3
3
  "title": "界面体验",
4
- "description": "让 DSH 界面跟随系统 matugen 生成的 Material You 配色:在「设置 → 通用设置 → Matugen 配色跟随」开启后,界面配色作为叠加层套在当前主题上,并随配色文件重新生成自动更新。可在同一行展开「配色文件路径」,改写 matugen 颜色文件或 DSH 令牌文件的路径(默认 ~/.local/state/quickshell/user/generated/ 下,令牌文件优先)。配色只在本地读取,不上传。关闭开关后回到原生配色。另统一界面边框宽度(配置项 borderWidth,默认 0.5px)。该覆盖仅在开关开启时生效,且会同时压窄正文引用块等装饰性边框。还有一行「M3 动效」,按 Material 3 / Material 3 Expressive 曲线原地改写整个界面的过渡与关键帧动画,可调曲线族、时长倍率、时长对齐与减弱动效策略;改写覆盖其他插件注入的样式,关闭后原样还原。"
4
+ "description": "让 DSH 界面跟随系统 matugen 生成的 Material You 配色:在「设置 → 通用设置 → Matugen 配色跟随」开启后,界面配色作为叠加层套在当前主题上,并随配色文件重新生成自动更新。可在同一行展开「配色文件路径」,改写 matugen 颜色文件或 DSH 令牌文件的路径(默认 ~/.local/state/quickshell/user/generated/ 下,令牌文件优先)。配色只在本地读取,不上传。关闭开关后回到原生配色。另统一界面边框宽度(配置项 borderWidth,默认 0.5px)。该覆盖仅在开关开启时生效,且会同时压窄正文引用块等装饰性边框。还有一行「M3 动效」,按 Material 3 / Material 3 Expressive 曲线原地改写整个界面的过渡与关键帧动画,可调曲线族、时长倍率、时长对齐与减弱动效策略;改写覆盖其他插件注入的样式,关闭后原样还原。同一行还接管平滑滚动(含滚轮缓动)与流式文本的渐进显现:文字不截断,只移动遮罩,选择、复制与读屏不受影响。"
5
5
  }
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-plugin/dsh-ui-experience",
3
- "version": "1.0.0-dev.43492422772",
3
+ "version": "1.0.0-dev.43522015745",
4
4
  "type": "module",
5
5
  "description": "UI experience enhancements for DeepSeek Harness: follow the system matugen Material You palette as the interface theme, and rewrite interface motion onto Material 3 / Material 3 Expressive curves.",
6
6
  "license": "MIT",
@@ -28,7 +28,8 @@
28
28
  ],
29
29
  "scripts": {
30
30
  "build": "tsc -p tsconfig.json && node build.mjs",
31
- "typecheck": "tsc -p tsconfig.json"
31
+ "typecheck": "tsc -p tsconfig.json",
32
+ "test": "node --test \"test/**/*.test.mjs\""
32
33
  },
33
34
  "dependencies": {
34
35
  "@deepseek-ai/dsh-typert-protocol": "^0.2.2-rc.2",