dsh-claude-desktop-theme 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +95 -140
  2. package/lib/client.js +9036 -812
  3. package/lib/index.js +56 -19
  4. package/lib/types/client/compat/browser-header.d.ts +1 -2
  5. package/lib/types/client/compat/frame.d.ts +29 -0
  6. package/lib/types/client/compat/hero-greeting.d.ts +6 -0
  7. package/lib/types/client/compat/host-dom.d.ts +8 -0
  8. package/lib/types/client/compat/mutation-scope.d.ts +43 -0
  9. package/lib/types/client/compat/pane-chrome.d.ts +2 -0
  10. package/lib/types/client/compat/permission-confirmation.d.ts +5 -0
  11. package/lib/types/client/compat/permission-menu.d.ts +4 -1
  12. package/lib/types/client/compat/pet-anchor.d.ts +5 -1
  13. package/lib/types/client/compat/sidebar-search.d.ts +18 -0
  14. package/lib/types/client/compat/view-switch.d.ts +1 -1
  15. package/lib/types/client/contracts/ports.d.ts +2 -0
  16. package/lib/types/client/features/composer-pet/BlankPet.d.ts +4 -1
  17. package/lib/types/client/features/composer-pet/ClaudePet.d.ts +7 -0
  18. package/lib/types/client/features/composer-pet/claude-frames.d.ts +12 -0
  19. package/lib/types/client/features/composer-pet/claude-motion.d.ts +3 -0
  20. package/lib/types/client/features/conversation/header-actions/HeaderActionButton.d.ts +2 -2
  21. package/lib/types/client/features/conversation/header-actions/entries.d.ts +11 -15
  22. package/lib/types/client/features/conversation/view-switch-icons.d.ts +2 -2
  23. package/lib/types/client/features/model-controls/EffortPanel.d.ts +2 -1
  24. package/lib/types/client/features/model-controls/ModelControls.d.ts +11 -1
  25. package/lib/types/client/features/model-controls/model-icon-data.d.ts +31 -0
  26. package/lib/types/client/features/model-controls/model-icon-match.d.ts +20 -0
  27. package/lib/types/client/features/model-controls/model-icons.d.ts +13 -0
  28. package/lib/types/client/features/model-controls/popup.d.ts +20 -0
  29. package/lib/types/client/features/model-controls/selection.d.ts +2 -0
  30. package/lib/types/client/features/new-session/ripples.d.ts +2 -2
  31. package/lib/types/client/features/settings/ChoiceMenu.d.ts +15 -0
  32. package/lib/types/client/features/settings/fields.d.ts +18 -0
  33. package/lib/types/client/features/settings/locales.d.ts +16 -1
  34. package/lib/types/client/features/statistics/source.d.ts +2 -1
  35. package/lib/types/host/index.d.ts +30 -0
  36. package/lib/types/shared/config.d.ts +11 -2
  37. package/package.json +2 -1
@@ -1,4 +1,23 @@
1
1
  import type { RefObject } from 'react';
2
+ interface Size {
3
+ width: number;
4
+ height: number;
5
+ }
6
+ /**
7
+ * The panel's border box, kept between placements.
8
+ *
9
+ * Its size changes only when its own content does, which the resize observer
10
+ * below already reports, so each placement can read the trigger alone instead
11
+ * of forcing a second layout of the surface. The first read is the seeding one:
12
+ * the panel has been shown by the time `place()` runs, so its box is real.
13
+ *
14
+ * @param surface - the popover element.
15
+ * @returns the cached size, and a way to re-read it when the observer fires.
16
+ */
17
+ export declare function cachedSize(surface: Element): {
18
+ current: () => Size;
19
+ refresh: () => void;
20
+ };
2
21
  /** Viewport-clamped top-layer surface; focus and observers die with the panel. */
3
22
  export declare function usePopup(anchor: RefObject<HTMLButtonElement>, close: () => void): {
4
23
  panel: RefObject<HTMLDivElement>;
@@ -8,3 +27,4 @@ export declare function usePopup(anchor: RefObject<HTMLButtonElement>, close: ()
8
27
  visibility: 'hidden' | 'visible';
9
28
  };
10
29
  };
30
+ export {};
@@ -36,6 +36,8 @@ export interface EffortViewCopy {
36
36
  * @returns every id a commit may carry, in provider order.
37
37
  */
38
38
  export declare function effortChoices(model: ModelCatalogModel | undefined, defaultName: string): EffortChoice[];
39
+ /** Default marker: a valid provider default wins; otherwise mark High if offered. */
40
+ export declare function effortDefaultIndex(model: ModelCatalogModel | undefined): number;
39
41
  /**
40
42
  * Lay out the card's stops, the resting thumb, and the trigger caption.
41
43
  *
@@ -1,8 +1,8 @@
1
1
  import type { HeroRippleImpulse } from '../../contracts/hero-canvas.ts';
2
- /** One character's stable grain and time-varying light, before the edge fade. */
2
+ /** One cell's independently changing character and moving light, before edge fade. */
3
3
  export declare function rippleCell(x: number, y: number, elapsed: number, width: number, height: number, impulses?: readonly HeroRippleImpulse[]): {
4
4
  alpha: number;
5
5
  glyph: string;
6
6
  };
7
- /** Stationary ASCII rows lit by an autonomous, slowly swelling wave field. */
7
+ /** Shimmering ASCII rows lit by an autonomous, slowly swelling wave field. */
8
8
  export declare function drawHeroRipples(canvas: HTMLCanvasElement, elapsed: number, impulses?: readonly HeroRippleImpulse[]): void;
@@ -0,0 +1,15 @@
1
+ import type { ReactElement } from 'react';
2
+ export declare function MenuCheck(): ReactElement;
3
+ /** A small choice list with native-style focus, dismissal and keyboard navigation. */
4
+ export declare function ChoiceMenu({ id, labelId, anchor, value, options, onSelect, onClose }: {
5
+ readonly id: string;
6
+ readonly labelId: string;
7
+ readonly anchor: HTMLElement;
8
+ readonly value: string;
9
+ readonly options: readonly {
10
+ readonly value: string;
11
+ readonly label: string;
12
+ }[];
13
+ readonly onSelect: (value: string) => void;
14
+ readonly onClose: () => void;
15
+ }): ReactElement;
@@ -81,3 +81,21 @@ export interface FontRowProps {
81
81
  * @returns The row and, when open, its menu.
82
82
  */
83
83
  export declare function FontRow(props: FontRowProps): ReactElement;
84
+ /** Styled choice control for named visual variants. */
85
+ export declare function ChoiceRow({ id, label, value, options, onChange }: {
86
+ readonly id: string;
87
+ readonly label: string;
88
+ readonly value: string;
89
+ readonly options: readonly {
90
+ readonly value: string;
91
+ readonly label: string;
92
+ }[];
93
+ readonly onChange: (value: string) => void;
94
+ }): ReactElement;
95
+ export declare function NameRow({ id, label, value, onChange, onCommit }: {
96
+ readonly id: string;
97
+ readonly label: string;
98
+ readonly value: string;
99
+ readonly onChange: (value: string) => void;
100
+ readonly onCommit: () => void;
101
+ }): ReactElement;
@@ -9,6 +9,15 @@
9
9
  export declare const SETTINGS_NAMESPACE = "ccdSettings";
10
10
  /** Simplified Chinese dictionary; the key set is the source of truth. */
11
11
  export declare const zh: {
12
+ readonly 'section.personalization': '个性化';
13
+ readonly 'field.petStyle': '宠物样式';
14
+ readonly 'pet.whale': '小鲸鱼';
15
+ readonly 'pet.claude': 'Claude 像素宠物';
16
+ readonly 'field.greetingStyle': '首页问候';
17
+ readonly 'greeting.explore': '探索未知之境';
18
+ readonly 'greeting.claude': 'Claude 问候与图标';
19
+ readonly 'field.greetingName': '问候语中的称呼';
20
+ readonly 'hint.personalization': '两项可独立切换;宠物点击后播放对应动作,问候语跟随界面语言,不显示姓名。原有模块开关仍控制显示。';
12
21
  readonly nav: 'Claude 主题';
13
22
  readonly summary: 'CCD 风格界面 · 外观 · 字体';
14
23
  readonly 'section.general': '通用';
@@ -16,6 +25,10 @@ export declare const zh: {
16
25
  readonly 'section.appearance': '外观';
17
26
  readonly 'section.fonts': '字体';
18
27
  readonly 'section.view': '视图';
28
+ readonly 'field.showModelIcons': '显示模型图标';
29
+ readonly 'hint.showModelIcons': '显示模型选单中名称前的图标,默认开启';
30
+ readonly 'field.showSidebarBrand': '显示 DeepSeek Harness 品牌条目';
31
+ readonly 'hint.showSidebarBrand': '显示侧栏顶部的品牌标志与名称,默认关闭';
19
32
  readonly 'field.showHeaderSubagents': '显示顶栏子代理入口';
20
33
  readonly 'hint.showHeaderSubagents': '显示会话顶栏的子代理数量与列表入口,默认关闭;子代理运行与侧栏树不受影响';
21
34
  readonly 'field.showHeaderTeam': '显示顶栏团队入口';
@@ -53,10 +66,12 @@ export declare const zh: {
53
66
  readonly 'feature.shell': '窗口与分栏骨架';
54
67
  readonly 'feature.sidebar': '侧栏';
55
68
  readonly 'feature.new-session': '新建页';
69
+ readonly 'feature.hero-ripples': '主页字符水波纹';
70
+ readonly 'hint.hero-ripples': '主页与标题栏的流动背景和点击扩散,默认开启;需同时开启新建页模块';
56
71
  readonly 'feature.conversation': '聊天页';
57
72
  readonly 'feature.tool-calls': '工具调用展示';
58
73
  readonly 'feature.statistics': '统计卡片';
59
- readonly 'feature.composer-pet': '输入框小鲸鱼';
74
+ readonly 'feature.composer-pet': '输入框宠物';
60
75
  readonly 'feature.composer-stats': '状态栏统计读数';
61
76
  readonly 'hint.composer-stats': '输出速度与缓存命中率,关掉时这两项不显示(默认)';
62
77
  readonly 'feature.context-panel': '上下文分解面板';
@@ -10,7 +10,8 @@
10
10
  * are still being folded (`pending > 0`) the card is genuinely incomplete, so
11
11
  * it refreshes every couple of seconds; once the snapshot is complete it drops
12
12
  * to a slow poll. A missing route (the host half is off) hides the card rather
13
- * than failing the mount.
13
+ * than failing the mount. Hidden documents pause reads and resume immediately
14
+ * when visible, keeping background windows from repeatedly aggregating history.
14
15
  */
15
16
  import { type StatsSnapshot } from '../../../shared/stats.ts';
16
17
  import type { Logger } from '../../contracts/ports.ts';
@@ -26,6 +26,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
26
26
  'composer-pet': z<boolean, boolean, "defined">;
27
27
  'composer-stats': z<boolean, boolean, "defined">;
28
28
  'context-panel': z<boolean, boolean, "defined">;
29
+ 'hero-ripples': z<boolean, boolean, "defined">;
29
30
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
30
31
  shell: z<boolean, boolean, "defined">;
31
32
  sidebar: z<boolean, boolean, "defined">;
@@ -36,6 +37,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
36
37
  'composer-pet': z<boolean, boolean, "defined">;
37
38
  'composer-stats': z<boolean, boolean, "defined">;
38
39
  'context-panel': z<boolean, boolean, "defined">;
40
+ 'hero-ripples': z<boolean, boolean, "defined">;
39
41
  }>>>, "volatile-defined">;
40
42
  appearance: z<NoInfer<Schemastery.ObjectS<NoInfer<{
41
43
  canvas: z<string, string, "defined">;
@@ -53,12 +55,25 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
53
55
  uiCjk: z<string, string, "defined">;
54
56
  code: z<string, string, "defined">;
55
57
  }>>>, "volatile-defined">;
58
+ personalization: z<NoInfer<Schemastery.ObjectS<NoInfer<{
59
+ petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
60
+ greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
61
+ greetingName: z<string, string, "defined">;
62
+ }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
63
+ petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
64
+ greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
65
+ greetingName: z<string, string, "defined">;
66
+ }>>>, "volatile-defined">;
56
67
  view: z<NoInfer<Schemastery.ObjectS<NoInfer<{
68
+ showModelIcons: z<boolean, boolean, "defined">;
69
+ showSidebarBrand: z<boolean, boolean, "defined">;
57
70
  showHeaderSubagents: z<boolean, boolean, "defined">;
58
71
  showHeaderTeam: z<boolean, boolean, "defined">;
59
72
  groupByStatus: z<boolean, boolean, "defined">;
60
73
  showEmptyGroups: z<boolean, boolean, "defined">;
61
74
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
75
+ showModelIcons: z<boolean, boolean, "defined">;
76
+ showSidebarBrand: z<boolean, boolean, "defined">;
62
77
  showHeaderSubagents: z<boolean, boolean, "defined">;
63
78
  showHeaderTeam: z<boolean, boolean, "defined">;
64
79
  groupByStatus: z<boolean, boolean, "defined">;
@@ -77,6 +92,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
77
92
  'composer-pet': z<boolean, boolean, "defined">;
78
93
  'composer-stats': z<boolean, boolean, "defined">;
79
94
  'context-panel': z<boolean, boolean, "defined">;
95
+ 'hero-ripples': z<boolean, boolean, "defined">;
80
96
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
81
97
  shell: z<boolean, boolean, "defined">;
82
98
  sidebar: z<boolean, boolean, "defined">;
@@ -87,6 +103,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
87
103
  'composer-pet': z<boolean, boolean, "defined">;
88
104
  'composer-stats': z<boolean, boolean, "defined">;
89
105
  'context-panel': z<boolean, boolean, "defined">;
106
+ 'hero-ripples': z<boolean, boolean, "defined">;
90
107
  }>>>, "volatile-defined">;
91
108
  appearance: z<NoInfer<Schemastery.ObjectS<NoInfer<{
92
109
  canvas: z<string, string, "defined">;
@@ -104,12 +121,25 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
104
121
  uiCjk: z<string, string, "defined">;
105
122
  code: z<string, string, "defined">;
106
123
  }>>>, "volatile-defined">;
124
+ personalization: z<NoInfer<Schemastery.ObjectS<NoInfer<{
125
+ petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
126
+ greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
127
+ greetingName: z<string, string, "defined">;
128
+ }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
129
+ petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
130
+ greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
131
+ greetingName: z<string, string, "defined">;
132
+ }>>>, "volatile-defined">;
107
133
  view: z<NoInfer<Schemastery.ObjectS<NoInfer<{
134
+ showModelIcons: z<boolean, boolean, "defined">;
135
+ showSidebarBrand: z<boolean, boolean, "defined">;
108
136
  showHeaderSubagents: z<boolean, boolean, "defined">;
109
137
  showHeaderTeam: z<boolean, boolean, "defined">;
110
138
  groupByStatus: z<boolean, boolean, "defined">;
111
139
  showEmptyGroups: z<boolean, boolean, "defined">;
112
140
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
141
+ showModelIcons: z<boolean, boolean, "defined">;
142
+ showSidebarBrand: z<boolean, boolean, "defined">;
113
143
  showHeaderSubagents: z<boolean, boolean, "defined">;
114
144
  showHeaderTeam: z<boolean, boolean, "defined">;
115
145
  groupByStatus: z<boolean, boolean, "defined">;
@@ -8,7 +8,7 @@
8
8
  * pill (the output rate, or the cache-hit share) in place of the host's own
9
9
  * label.
10
10
  */
11
- export declare const FEATURE_IDS: readonly ['shell', 'sidebar', 'new-session', 'conversation', 'tool-calls', 'statistics', 'composer-pet', 'composer-stats', 'context-panel'];
11
+ export declare const FEATURE_IDS: readonly ['shell', 'sidebar', 'new-session', 'conversation', 'tool-calls', 'statistics', 'composer-pet', 'composer-stats', 'context-panel', 'hero-ripples'];
12
12
  export type FeatureId = typeof FEATURE_IDS[number];
13
13
  export type FeatureFlags = Readonly<Record<FeatureId, boolean>>;
14
14
  /** Fields of the background-colour section; an empty string means "built-in palette". */
@@ -16,13 +16,20 @@ export declare const APPEARANCE_FIELDS: readonly ['canvas', 'sidebar'];
16
16
  /** Fields of the typeface section; an empty string means "system stack". */
17
17
  export declare const FONT_FIELDS: readonly ['uiLatin', 'uiCjk', 'code'];
18
18
  /** Fields of the view-options section. */
19
- export declare const VIEW_FIELDS: readonly ['showEmptyGroups', 'groupByStatus', 'showHeaderSubagents', 'showHeaderTeam'];
19
+ export declare const VIEW_FIELDS: readonly ['showEmptyGroups', 'groupByStatus', 'showHeaderSubagents', 'showHeaderTeam', 'showSidebarBrand', 'showModelIcons'];
20
20
  export type AppearanceField = typeof APPEARANCE_FIELDS[number];
21
21
  export type FontField = typeof FONT_FIELDS[number];
22
22
  export type ViewField = typeof VIEW_FIELDS[number];
23
23
  export type AppearanceConfig = Readonly<Record<AppearanceField, string>>;
24
24
  export type FontsConfig = Readonly<Record<FontField, string>>;
25
25
  export type ViewConfig = Readonly<Record<ViewField, boolean>>;
26
+ export interface PersonalizationConfig {
27
+ readonly petStyle: 'whale' | 'claude';
28
+ readonly greetingStyle: 'explore' | 'claude';
29
+ readonly greetingName: string;
30
+ }
31
+ export declare const DEFAULT_PERSONALIZATION: PersonalizationConfig;
32
+ export declare function normalizeGreetingName(value: unknown): string;
26
33
  export interface StyleConfig {
27
34
  readonly enabled: boolean;
28
35
  readonly debug: boolean;
@@ -30,6 +37,7 @@ export interface StyleConfig {
30
37
  readonly appearance: AppearanceConfig;
31
38
  readonly fonts: FontsConfig;
32
39
  readonly view: ViewConfig;
40
+ readonly personalization: PersonalizationConfig;
33
41
  }
34
42
  export interface StyleOptions {
35
43
  readonly enabled?: boolean;
@@ -38,6 +46,7 @@ export interface StyleOptions {
38
46
  readonly appearance?: Partial<Record<AppearanceField, unknown>>;
39
47
  readonly fonts?: Partial<Record<FontField, unknown>>;
40
48
  readonly view?: Partial<Record<ViewField, unknown>>;
49
+ readonly personalization?: Partial<Record<keyof PersonalizationConfig, unknown>>;
41
50
  }
42
51
  export declare const DEFAULT_FEATURES: FeatureFlags;
43
52
  /** Empty strings keep the built-in palette and the system font stack in charge. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-claude-desktop-theme",
3
- "version": "0.4.3",
3
+ "version": "0.4.5",
4
4
  "license": "MIT",
5
5
  "description": "Claude Code Desktop-style theme for DeepSeek Harness (DSH) Desktop on macOS and Windows, with light/dark themes, model/effort pickers and an interactive pixel whale",
6
6
  "author": "zkforge",
@@ -81,6 +81,7 @@
81
81
  "typecheck": "tsc --noEmit",
82
82
  "check:architecture": "node scripts/check-architecture.mjs",
83
83
  "check:package": "node scripts/check-package.mjs",
84
+ "icons:models": "node scripts/generate-model-icons.mjs",
84
85
  "test": "node --test tests/*.test.ts tests/*.test.mjs",
85
86
  "check": "npm run typecheck && npm run check:architecture && npm test && npm run build && npm run check:package",
86
87
  "prepack": "npm run check",