dsh-claude-desktop-theme 0.5.0 → 0.5.2

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 (44) hide show
  1. package/README.md +8 -6
  2. package/lib/client.js +7916 -5407
  3. package/lib/index.js +6 -6
  4. package/lib/types/client/compat/account-balance-hint.d.ts +11 -0
  5. package/lib/types/client/compat/account-balance.d.ts +2 -0
  6. package/lib/types/client/compat/conversation-stream.d.ts +5 -0
  7. package/lib/types/client/compat/files-pane.d.ts +2 -2
  8. package/lib/types/client/compat/header-menu-actions.d.ts +0 -2
  9. package/lib/types/client/compat/host-builds.d.ts +5 -4
  10. package/lib/types/client/compat/host-dom.d.ts +19 -2
  11. package/lib/types/client/compat/search-palette-port.d.ts +4 -0
  12. package/lib/types/client/compat/sidebar-editor.d.ts +32 -0
  13. package/lib/types/client/compat/sidebar-more-menu.d.ts +13 -0
  14. package/lib/types/client/compat/sidebar-navigation.d.ts +8 -0
  15. package/lib/types/client/compat/sidebar-panels.d.ts +62 -0
  16. package/lib/types/client/compat/sidebar-search.d.ts +13 -14
  17. package/lib/types/client/compat/workspace-menu.d.ts +2 -1
  18. package/lib/types/client/compat/workspace-worktree.d.ts +12 -2
  19. package/lib/types/client/contracts/ports.d.ts +102 -0
  20. package/lib/types/client/features/composer-pet/claude-frames.d.ts +2 -2
  21. package/lib/types/client/features/right-panel/mount.d.ts +5 -0
  22. package/lib/types/client/features/search-palette/SearchPalette.d.ts +23 -0
  23. package/lib/types/client/features/search-palette/model.d.ts +109 -0
  24. package/lib/types/client/features/search-palette/mount.d.ts +17 -0
  25. package/lib/types/client/features/settings/ColourMenu.d.ts +16 -0
  26. package/lib/types/client/features/settings/FontMenu.d.ts +1 -1
  27. package/lib/types/client/features/settings/ThemePanel.d.ts +21 -0
  28. package/lib/types/client/features/settings/colours.d.ts +8 -0
  29. package/lib/types/client/features/settings/fields.d.ts +6 -3
  30. package/lib/types/client/features/settings/locales.d.ts +16 -5
  31. package/lib/types/client/features/settings/mount.d.ts +7 -5
  32. package/lib/types/client/features/settings/register.d.ts +13 -2
  33. package/lib/types/client/features/sidebar/navigation-icons.d.ts +3 -0
  34. package/lib/types/client/features/sidebar-editor/MoreCardRows.d.ts +24 -0
  35. package/lib/types/client/features/sidebar-editor/SidebarEditor.d.ts +20 -0
  36. package/lib/types/client/features/sidebar-editor/copy.d.ts +9 -0
  37. package/lib/types/client/features/sidebar-editor/mount.d.ts +18 -0
  38. package/lib/types/client/features/sidebar-editor/state.d.ts +31 -0
  39. package/lib/types/client/theme/palette.d.ts +1 -1
  40. package/lib/types/host/index.d.ts +16 -16
  41. package/lib/types/shared/config.d.ts +4 -4
  42. package/lib/types/shared/identity.d.ts +1 -1
  43. package/package.json +16 -16
  44. package/lib/types/client/features/shell/index.d.ts +0 -14
@@ -0,0 +1,17 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { FeatureEnvironment } from '../../contracts/feature.ts';
3
+ import type { SearchPaletteOpener } from '../../contracts/ports.ts';
4
+ import type { CleanupScope } from '../../core/cleanup.ts';
5
+ /**
6
+ * Put the search palette in the frame-wide overlay and return its opener.
7
+ *
8
+ * The palette is this plugin's own surface: a React entry in `shell.overlay`
9
+ * whose modal card lists the host's Sessions, Workspaces and scheduled tasks
10
+ * (`compat/search-palette-port.ts`). The sidebar's Search row and the host's
11
+ * ⌘K both reach it through the returned opener (`compat/sidebar-search.ts`).
12
+ *
13
+ * @param ctx - client root context carrying the slot service and host catalogs.
14
+ * @param environment - configuration, ports and logging for this activation.
15
+ * @param cleanup - scope owning the styles, the open state and the registration.
16
+ */
17
+ export declare function mountSearchPalette(ctx: Context, environment: FeatureEnvironment, cleanup: CleanupScope): SearchPaletteOpener;
@@ -0,0 +1,16 @@
1
+ import type { ReactElement } from 'react';
2
+ export interface ColourMenuLabels {
3
+ readonly plane: string;
4
+ readonly hue: string;
5
+ }
6
+ /** A saturation/brightness plane with a hue strip, anchored to the colour pill. */
7
+ export declare function ColourMenu({ id, labelId, anchor, value, labels, onPreview, onSelect, onClose }: {
8
+ readonly id: string;
9
+ readonly labelId: string;
10
+ readonly anchor: HTMLElement;
11
+ readonly value: string;
12
+ readonly labels: ColourMenuLabels;
13
+ readonly onPreview: (value: string) => void;
14
+ readonly onSelect: (value: string) => void;
15
+ readonly onClose: () => void;
16
+ }): ReactElement;
@@ -6,7 +6,7 @@ import type { ReactElement } from 'react';
6
6
  * popup is an OS widget that ignores this page's styles and, in the desktop
7
7
  * window, does not scroll with the wheel — with several hundred families that
8
8
  * is unusable. The panel is positioned against the select box and closed by
9
- * Escape, an outside click, a scroll or a resize.
9
+ * Escape or an outside click; it follows the anchor on scroll and resize.
10
10
  */
11
11
  export interface FontMenuLabels {
12
12
  readonly search: string;
@@ -0,0 +1,21 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { ConfigPageProps } from './ConfigPage.tsx';
3
+ /**
4
+ * The Theme row's glyph: the palette `navigation-icons.ts` draws, at the size
5
+ * the column asks for. While the interface is on, `sidebar-navigation.ts`
6
+ * recognises the row by the marker and lays its own copy over this one, like
7
+ * the host's rows; while it is off, this is what the native row shows.
8
+ * @param props - the column's glyph size; `icon` is bundled, trusted markup.
9
+ */
10
+ export declare function ThemePanelGlyph({ size, icon }: {
11
+ readonly size?: number | undefined;
12
+ readonly icon: string;
13
+ }): ReactElement;
14
+ /**
15
+ * The Theme panel: this plugin's configuration as a page of the centre column,
16
+ * opened from its sidebar row. It is the same form the settings dialog's
17
+ * section draws, under the heading the Customize and Scheduled tasks pages
18
+ * carry.
19
+ * @param props - the form, the theme preference and the panel's locale seat.
20
+ */
21
+ export declare function ThemePanelPage(props: ConfigPageProps): ReactElement;
@@ -0,0 +1,8 @@
1
+ export interface HSV {
2
+ readonly h: number;
3
+ readonly s: number;
4
+ readonly v: number;
5
+ }
6
+ /** Picker coordinates use degrees for hue and unit intervals for the plane. */
7
+ export declare function colourToHSV(colour: string): HSV;
8
+ export declare function hsvToColour({ h, s, v }: HSV): string;
@@ -1,6 +1,7 @@
1
1
  import type { MouseEvent, ReactElement } from 'react';
2
2
  import type { ThemePreference } from '../../contracts/ports.ts';
3
3
  import type { FontMenuLabels } from './FontMenu.tsx';
4
+ import type { ColourMenuLabels } from './ColourMenu.tsx';
4
5
  export interface SwitchRowProps {
5
6
  readonly id: string;
6
7
  readonly label: string;
@@ -43,14 +44,14 @@ export interface ColourRowProps {
43
44
  readonly hint?: string;
44
45
  readonly value: string;
45
46
  readonly placeholder: string;
46
- readonly resetLabel: string;
47
+ readonly pickerLabels: ColourMenuLabels;
47
48
  readonly error?: string;
48
49
  readonly onChange: (value: string) => void;
49
50
  readonly onCommit: () => void;
50
- readonly onReset: () => void;
51
+ readonly onSelect: (value: string) => void;
51
52
  }
52
53
  /**
53
- * One background-colour row: a bordered hex field, written when it is left.
54
+ * One background-colour row: a preview swatch, editable hex and gradient picker.
54
55
  * @param props - Identity, copy, current text and callbacks.
55
56
  * @returns The row.
56
57
  */
@@ -63,6 +64,8 @@ export interface FontRowProps {
63
64
  readonly placeholder: string;
64
65
  readonly resetLabel: string;
65
66
  readonly error?: string;
67
+ /** Whether the served value differs from the default; the Theme panel shows Reset only then. */
68
+ readonly customized?: boolean;
66
69
  /** The open family menu's anchor box, or undefined while it is closed. */
67
70
  readonly anchor: HTMLElement | undefined;
68
71
  readonly families: readonly string[];
@@ -10,6 +10,7 @@ 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
12
  readonly 'section.personalization': '个性化';
13
+ readonly 'style.none': '关闭';
13
14
  readonly 'field.petStyle': '宠物样式';
14
15
  readonly 'field.runningStyle': '输出中状态';
15
16
  readonly 'running.whale': '鲸鱼(原生)';
@@ -25,6 +26,7 @@ export declare const zh: {
25
26
  readonly 'field.greetingName': '问候语中的称呼';
26
27
  readonly 'hint.personalization': '各项可独立切换;宠物点击后播放对应动作,问候语跟随界面语言,不显示姓名。原有模块开关仍控制显示。';
27
28
  readonly nav: 'Claude 主题';
29
+ readonly panel: '主题';
28
30
  readonly summary: 'CCD 风格界面 · 外观 · 字体';
29
31
  readonly 'section.general': '通用';
30
32
  readonly 'section.features': '模块';
@@ -41,7 +43,7 @@ export declare const zh: {
41
43
  readonly 'hint.showHeaderTeam': '显示会话顶栏的智能体团队入口,默认关闭;团队功能不受影响';
42
44
  readonly 'field.showEmptyGroups': '显示空分组';
43
45
  readonly 'hint.showEmptyGroups': '关掉时没有会话的工作区不再显示;视图选项菜单里的同一项';
44
- readonly 'field.enabled': '启用 CCD 风格界面';
46
+ readonly 'field.enabled': '开启 / 关闭 Claude 主题';
45
47
  readonly 'field.theme': '主题';
46
48
  readonly 'theme.system': '跟随系统';
47
49
  readonly 'theme.light': '浅色';
@@ -55,8 +57,10 @@ export declare const zh: {
55
57
  readonly 'field.code': '代码与等宽字体';
56
58
  readonly 'hint.fontListUnavailable': '当前环境不提供系统字体清单,请直接输入字体族名(例如 PingFang SC)。';
57
59
  readonly 'placeholder.font': '留空使用系统字体';
58
- readonly 'placeholder.canvas': '#fcfcfb';
59
- readonly 'placeholder.sidebar': '#fbfbf9';
60
+ readonly 'placeholder.canvas': '#FCFCFB';
61
+ readonly 'placeholder.sidebar': '#FCFCFB';
62
+ readonly 'picker.colourPlane': '饱和度 / 亮度(左右 / 上下方向键调整)';
63
+ readonly 'picker.hue': '色相';
60
64
  readonly 'action.reset': '恢复默认';
61
65
  readonly 'picker.search': '搜索字体';
62
66
  readonly 'picker.empty': '没有匹配的字体';
@@ -70,15 +74,22 @@ export declare const zh: {
70
74
  readonly 'state.readonly': '当前配置不可写。';
71
75
  readonly 'error.colour': '颜色需为 #rrggbb 或 #rgb';
72
76
  readonly 'error.font': '字体名只能包含字母、数字、空格与 . _ -,且不超过 64 个字符';
73
- readonly 'feature.shell': '窗口与分栏骨架';
74
- readonly 'feature.sidebar': '侧栏';
77
+ readonly 'feature.sidebar': '左侧栏';
78
+ readonly 'hint.sidebar': '左栏背景、导航与历史按钮、工作区与会话列表、账号菜单和视图选项卡片,默认开启';
79
+ readonly 'feature.right-panel': '右侧栏';
80
+ readonly 'hint.right-panel': '右栏浮动卡片、分栏布局、文件树搜索与工具栏,默认开启;关闭后恢复宿主右栏';
75
81
  readonly 'feature.new-session': '新建页';
82
+ readonly 'hint.new-session': '新建页的问候区与输入卡片布局,默认开启';
76
83
  readonly 'feature.hero-ripples': '主页字符水波纹';
77
84
  readonly 'hint.hero-ripples': '主页与标题栏的流动背景和点击扩散,默认开启;需同时开启新建页模块';
78
85
  readonly 'feature.conversation': '聊天页';
86
+ readonly 'hint.conversation': '会话顶栏、消息与 Markdown 排版、滚动渐隐和回到底部按钮,默认开启';
79
87
  readonly 'feature.tool-calls': '工具调用展示';
88
+ readonly 'hint.tool-calls': '把连续的工具调用合并为计数摘要,点开查看完整列表,默认开启';
80
89
  readonly 'feature.statistics': '统计卡片';
90
+ readonly 'hint.statistics': '新建页的用量概览、热力图与模型图表,默认开启';
81
91
  readonly 'feature.composer-pet': '输入框宠物';
92
+ readonly 'hint.composer-pet': '新建页输入卡右上角的宠物,样式在「个性化」中选择,点击播放动作,默认开启';
82
93
  readonly 'feature.composer-stats': '状态栏统计读数';
83
94
  readonly 'hint.composer-stats': '输出速度与缓存命中率,关掉时这两项不显示(默认)';
84
95
  readonly 'feature.context-panel': '上下文分解面板';
@@ -2,16 +2,18 @@ import type { Context } from '@deepseek-ai/cordis';
2
2
  import type { ConfigFormPort, DomPort, ThemePreferencePort } from '../../contracts/ports.ts';
3
3
  import type { CleanupScope } from '../../core/cleanup.ts';
4
4
  /**
5
- * Register this plugin in the main settings navigation.
5
+ * Register this plugin in the main settings navigation and as the sidebar's
6
+ * Theme panel.
6
7
  *
7
- * The page lives outside the activation scope on purpose: switching the
8
- * interface off releases every style resource, and the page has to survive that
9
- * to switch it back on.
8
+ * Both live outside the activation scope on purpose: switching the interface
9
+ * off releases every style resource, and the page has to survive that to switch
10
+ * it back on.
10
11
  * @param ctx - client context, injected for slots and the locale service.
11
12
  * @param dom - style port owning the page's stylesheet.
12
13
  * @param form - this plugin's configuration form.
13
14
  * @param themePreference - the native theme preference face, or null when the
14
15
  * theme service does not publish one.
16
+ * @param panelIcon - the Theme row's bundled palette artwork.
15
17
  * @param scope - scope owning the stylesheet, the dictionary and the registration.
16
18
  */
17
- export declare function mountSettingsPage(ctx: Context, dom: DomPort, form: ConfigFormPort, themePreference: ThemePreferencePort | null, scope: CleanupScope): void;
19
+ export declare function mountSettingsPage(ctx: Context, dom: DomPort, form: ConfigFormPort, themePreference: ThemePreferencePort | null, panelIcon: string, scope: CleanupScope): void;
@@ -1,5 +1,16 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import type { ReactElement } from 'react';
3
3
  import type { SettingsSectionProps } from '../../compat/settings-section.ts';
4
- /** Register the plugin form as a top-level settings section with localized copy. */
5
- export declare function registerSettingsPage(ctx: Context, id: string, component: (props: SettingsSectionProps) => ReactElement | null): Pick<ReturnType<Context['inject']>, 'dispose'>;
4
+ /** Sidebar row and centre-column page of the plugin's own Theme panel. */
5
+ export declare const THEME_PANEL_ID = "ccd-theme";
6
+ export interface ThemePanelComponents {
7
+ readonly page: (props: SettingsSectionProps) => ReactElement | null;
8
+ readonly glyph: (props: {
9
+ readonly size?: number;
10
+ }) => ReactElement | null;
11
+ }
12
+ /**
13
+ * Register the plugin form twice under one dictionary: as a top-level settings
14
+ * section, and as the Theme panel the sidebar lists beside Customize.
15
+ */
16
+ export declare function registerSettingsPage(ctx: Context, id: string, component: (props: SettingsSectionProps) => ReactElement | null, panel: ThemePanelComponents): Pick<ReturnType<Context['inject']>, 'dispose'>;
@@ -2,5 +2,8 @@
2
2
  export declare const SIDEBAR_NAVIGATION_ICONS: Readonly<{
3
3
  newSession: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"new\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"icon-disc\" cx=\"12\" cy=\"12\" r=\"12\" fill=\"currentColor\" fill-opacity=\"0.09\"/>\n <path d=\"M12 7V17M7 12H17\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\"/>\n</svg>";
4
4
  plugins: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"customize\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g class=\"customize-case\" stroke=\"currentColor\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M8 7V5.2C8 4.54 8.54 4 9.2 4H14.8C15.46 4 16 4.54 16 5.2V7\"/>\n <rect x=\"3\" y=\"7\" width=\"18\" height=\"12.5\" rx=\"1.5\"/>\n <path d=\"M3 13.5H7M9.5 13.5H14.5M17 13.5H21\"/>\n </g>\n</svg>";
5
+ search: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"search\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g class=\"search-glass\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\">\n <circle cx=\"10.75\" cy=\"10.75\" r=\"6.75\"/>\n <path d=\"M15.75 15.75L20.5 20.5\"/>\n </g>\n</svg>";
5
6
  routines: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"routines\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"9\"/>\n <path class=\"routine-long-hand\" d=\"M12 12V7.4\"/>\n <path d=\"M12 12L14.8 13.75\"/>\n </g>\n</svg>";
7
+ more: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"more\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g class=\"more-dots\" fill=\"currentColor\">\n <circle cx=\"3.6\" cy=\"12\" r=\"1.6\"/>\n <circle cx=\"12\" cy=\"12\" r=\"1.6\"/>\n <circle cx=\"20.4\" cy=\"12\" r=\"1.6\"/>\n </g>\n</svg>";
8
+ theme: "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"claude-sidebar-icon\" data-icon=\"theme\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <g class=\"theme-palette\">\n <path d=\"M12 3C7.03 3 3 7.03 3 12C3 16.97 7.03 21 12 21C13.1 21 13.8 20.25 13.8 19.3C13.8 18.83 13.62 18.42 13.32 18.12C13.03 17.82 12.85 17.43 12.85 16.95C12.85 15.98 13.63 15.2 14.6 15.2H16.5C19.01 15.2 21 13.21 21 10.7C21 6.47 16.97 3 12 3Z\" stroke=\"currentColor\" stroke-width=\"1.3\" stroke-linejoin=\"round\"/>\n <g fill=\"currentColor\">\n <circle cx=\"7.6\" cy=\"12.4\" r=\"1.15\"/>\n <circle cx=\"8.7\" cy=\"8.1\" r=\"1.15\"/>\n <circle cx=\"12.6\" cy=\"6.6\" r=\"1.15\"/>\n <circle cx=\"16.3\" cy=\"8.6\" r=\"1.15\"/>\n </g>\n </g>\n</svg>";
6
9
  }>;
@@ -0,0 +1,24 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { MenuRowClasses } from '../../compat/host-dom.ts';
3
+ import type { SidebarPanelsPort } from '../../compat/sidebar-panels.ts';
4
+ import type { EditorState, HiddenPanelStore } from './state.ts';
5
+ interface HiddenProps {
6
+ readonly hidden: HiddenPanelStore;
7
+ readonly port: SidebarPanelsPort;
8
+ readonly classes: MenuRowClasses;
9
+ /** `PanelMoreMenu`'s own dismissal, passed to every `sidebar.panellist.actions` row. */
10
+ readonly onDismiss?: (() => void) | undefined;
11
+ }
12
+ /**
13
+ * The panels the Edit sidebar dialog took out of the column, at the head of
14
+ * the card, so each stays one click away; a separator closes the group.
15
+ */
16
+ export declare function HiddenPanelRows({ hidden, port, classes, onDismiss }: HiddenProps): ReactElement | null;
17
+ interface EditProps {
18
+ readonly state: EditorState;
19
+ readonly classes: MenuRowClasses;
20
+ readonly onDismiss?: (() => void) | undefined;
21
+ }
22
+ /** 编辑侧边栏…, after the host's Browse and Create rows: closes the card, opens the dialog. */
23
+ export declare function EditSidebarRow({ state, classes, onDismiss }: EditProps): ReactElement;
24
+ export {};
@@ -0,0 +1,20 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { SidebarPanelsPort } from '../../compat/sidebar-panels.ts';
3
+ import type { EditorState, HiddenPanelStore } from './state.ts';
4
+ interface Props {
5
+ readonly state: EditorState;
6
+ readonly hidden: HiddenPanelStore;
7
+ readonly port: SidebarPanelsPort;
8
+ /** A copy of the glyph a panel's sidebar row draws. */
9
+ readonly glyph: (id: string) => Element | null;
10
+ }
11
+ /**
12
+ * Edit sidebar: the dialog the More card's 编辑侧边栏… row opens, after the
13
+ * reference.
14
+ *
15
+ * A native modal `<dialog>` whose body mounts per opening: each checkbox writes
16
+ * straight through to the hidden set, so the column follows every click and
17
+ * 完成 only closes.
18
+ */
19
+ export declare function SidebarEditor({ state, hidden, port, glyph }: Props): ReactElement;
20
+ export {};
@@ -0,0 +1,9 @@
1
+ export interface EditorCopy {
2
+ readonly edit: string;
3
+ readonly title: string;
4
+ readonly description: string;
5
+ readonly done: string;
6
+ readonly close: string;
7
+ }
8
+ /** The reference's words in Chinese; its English counterparts elsewhere. */
9
+ export declare function editorCopy(language: string): EditorCopy;
@@ -0,0 +1,18 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { FeatureEnvironment } from '../../contracts/feature.ts';
3
+ import type { CleanupScope } from '../../core/cleanup.ts';
4
+ /**
5
+ * Edit sidebar: choose which global panels the column lists.
6
+ *
7
+ * The More card gains 编辑侧边栏… below the host's plugin rows; it opens a
8
+ * dialog of every panel with a checkbox, and an unchecked panel leaves the
9
+ * column for the head of the same card (`compat/sidebar-editor.ts` marks its
10
+ * row, `sidebar-editor.css` hides it). The choice is kept in this window's
11
+ * storage, so it survives reloads and switching the interface off and on;
12
+ * while the interface is off, DSH lists every panel again.
13
+ *
14
+ * @param ctx - client root context carrying the slot and layout services.
15
+ * @param environment - configuration, ports and logging for this activation.
16
+ * @param cleanup - scope owning the styles, the row marks and the registrations.
17
+ */
18
+ export declare function mountSidebarEditor(ctx: Context, environment: FeatureEnvironment, cleanup: CleanupScope): void;
@@ -0,0 +1,31 @@
1
+ import type { Disposer } from '../../contracts/ports.ts';
2
+ import type { HiddenPanels } from '../../compat/sidebar-editor.ts';
3
+ /** Where the hidden panel ids live: a layout preference of this window's profile. */
4
+ export declare const HIDDEN_PANELS_KEY = "ccd-sidebar-hidden";
5
+ export interface HiddenPanelStore extends HiddenPanels {
6
+ /** The current set; replaced, never mutated, so it is a stable snapshot. */
7
+ ids(): ReadonlySet<string>;
8
+ set(id: string, hidden: boolean): void;
9
+ }
10
+ type PanelStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
11
+ /**
12
+ * The panels the Edit sidebar dialog keeps out of the column.
13
+ *
14
+ * Kept in `localStorage` beside `ccd-status-collapsed`: it is how this window
15
+ * lays its sidebar out, not configuration the Host serves. A storage that
16
+ * throws or holds something unreadable reads as "nothing hidden", so a broken
17
+ * entry can never take a row away for good. Ids of panels that are not
18
+ * registered right now stay in the set, so a plugin that loads late or is
19
+ * reinstalled comes back the way it was left.
20
+ * @param storage - the window's storage, or undefined where it is unavailable.
21
+ */
22
+ export declare function createHiddenPanels(storage: PanelStorage | undefined): HiddenPanelStore;
23
+ /** Whether the Edit sidebar dialog is open; the More card's row opens it. */
24
+ export interface EditorState {
25
+ isOpen(): boolean;
26
+ subscribe(listener: () => void): Disposer;
27
+ open(): void;
28
+ close(): void;
29
+ }
30
+ export declare function createEditorState(): EditorState;
31
+ export {};
@@ -38,7 +38,7 @@ export interface Palette {
38
38
  */
39
39
  export declare const BUILT_IN_SURFACES: Readonly<{
40
40
  canvas: "#fcfcfb";
41
- sidebar: "#fbfbf9";
41
+ sidebar: "#fcfcfb";
42
42
  border: "#e3e3e1";
43
43
  }>;
44
44
  /**
@@ -17,8 +17,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
17
17
  enabled: z<boolean, boolean, "volatile-defined">;
18
18
  debug: z<boolean, boolean, "volatile-defined">;
19
19
  features: z<NoInfer<Schemastery.ObjectS<NoInfer<{
20
- shell: z<boolean, boolean, "defined">;
21
20
  sidebar: z<boolean, boolean, "defined">;
21
+ 'right-panel': z<boolean, boolean, "defined">;
22
22
  'new-session': z<boolean, boolean, "defined">;
23
23
  conversation: z<boolean, boolean, "defined">;
24
24
  'tool-calls': z<boolean, boolean, "defined">;
@@ -28,8 +28,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
28
28
  'context-panel': z<boolean, boolean, "defined">;
29
29
  'hero-ripples': z<boolean, boolean, "defined">;
30
30
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
31
- shell: z<boolean, boolean, "defined">;
32
31
  sidebar: z<boolean, boolean, "defined">;
32
+ 'right-panel': z<boolean, boolean, "defined">;
33
33
  'new-session': z<boolean, boolean, "defined">;
34
34
  conversation: z<boolean, boolean, "defined">;
35
35
  'tool-calls': z<boolean, boolean, "defined">;
@@ -56,16 +56,16 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
56
56
  code: z<string, string, "defined">;
57
57
  }>>>, "volatile-defined">;
58
58
  personalization: z<NoInfer<Schemastery.ObjectS<NoInfer<{
59
- petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
59
+ petStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
60
60
  runningStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
61
- replySignatureStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
62
- greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
61
+ replySignatureStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
62
+ greetingStyle: z<"claude" | "explore" | "none", "claude" | "explore" | "none", "defined">;
63
63
  greetingName: z<string, string, "defined">;
64
64
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
65
- petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
65
+ petStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
66
66
  runningStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
67
- replySignatureStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
68
- greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
67
+ replySignatureStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
68
+ greetingStyle: z<"claude" | "explore" | "none", "claude" | "explore" | "none", "defined">;
69
69
  greetingName: z<string, string, "defined">;
70
70
  }>>>, "volatile-defined">;
71
71
  view: z<NoInfer<Schemastery.ObjectS<NoInfer<{
@@ -87,8 +87,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
87
87
  enabled: z<boolean, boolean, "volatile-defined">;
88
88
  debug: z<boolean, boolean, "volatile-defined">;
89
89
  features: z<NoInfer<Schemastery.ObjectS<NoInfer<{
90
- shell: z<boolean, boolean, "defined">;
91
90
  sidebar: z<boolean, boolean, "defined">;
91
+ 'right-panel': z<boolean, boolean, "defined">;
92
92
  'new-session': z<boolean, boolean, "defined">;
93
93
  conversation: z<boolean, boolean, "defined">;
94
94
  'tool-calls': z<boolean, boolean, "defined">;
@@ -98,8 +98,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
98
98
  'context-panel': z<boolean, boolean, "defined">;
99
99
  'hero-ripples': z<boolean, boolean, "defined">;
100
100
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
101
- shell: z<boolean, boolean, "defined">;
102
101
  sidebar: z<boolean, boolean, "defined">;
102
+ 'right-panel': z<boolean, boolean, "defined">;
103
103
  'new-session': z<boolean, boolean, "defined">;
104
104
  conversation: z<boolean, boolean, "defined">;
105
105
  'tool-calls': z<boolean, boolean, "defined">;
@@ -126,16 +126,16 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
126
126
  code: z<string, string, "defined">;
127
127
  }>>>, "volatile-defined">;
128
128
  personalization: z<NoInfer<Schemastery.ObjectS<NoInfer<{
129
- petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
129
+ petStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
130
130
  runningStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
131
- replySignatureStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
132
- greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
131
+ replySignatureStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
132
+ greetingStyle: z<"claude" | "explore" | "none", "claude" | "explore" | "none", "defined">;
133
133
  greetingName: z<string, string, "defined">;
134
134
  }>>>, NoInfer<Schemastery.ObjectT<NoInfer<{
135
- petStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
135
+ petStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
136
136
  runningStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
137
- replySignatureStyle: z<"claude" | "whale", "claude" | "whale", "defined">;
138
- greetingStyle: z<"claude" | "explore", "claude" | "explore", "defined">;
137
+ replySignatureStyle: z<"claude" | "none" | "whale", "claude" | "none" | "whale", "defined">;
138
+ greetingStyle: z<"claude" | "explore" | "none", "claude" | "explore" | "none", "defined">;
139
139
  greetingName: z<string, string, "defined">;
140
140
  }>>>, "volatile-defined">;
141
141
  view: z<NoInfer<Schemastery.ObjectS<NoInfer<{
@@ -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', 'hero-ripples'];
11
+ export declare const FEATURE_IDS: readonly ['sidebar', 'right-panel', '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". */
@@ -24,10 +24,10 @@ 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
26
  export interface PersonalizationConfig {
27
- readonly petStyle: 'whale' | 'claude';
27
+ readonly petStyle: 'whale' | 'claude' | 'none';
28
28
  readonly runningStyle: 'whale' | 'claude';
29
- readonly replySignatureStyle: 'whale' | 'claude';
30
- readonly greetingStyle: 'explore' | 'claude';
29
+ readonly replySignatureStyle: 'whale' | 'claude' | 'none';
30
+ readonly greetingStyle: 'explore' | 'claude' | 'none';
31
31
  readonly greetingName: string;
32
32
  }
33
33
  export declare const DEFAULT_PERSONALIZATION: PersonalizationConfig;
@@ -1,5 +1,5 @@
1
1
  export declare const PLUGIN_ID = "dsh-claude-desktop-theme";
2
2
  /** Loader entry id declared by this package's bundle patch (cordis.patch.yml). */
3
3
  export declare const ENTRY_ID = "ui-skin-ccd-style";
4
- export declare const TARGET_DSH_VERSION = "0.2.0-rc.2";
4
+ export declare const TARGET_DSH_VERSION = "0.2.1-rc.3";
5
5
  export declare const ROOT_ATTRIBUTE = "data-dsh-ccd-style";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-claude-desktop-theme",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
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",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "dsh": {
61
61
  "engines": {
62
- "dsh": "=0.2.0-rc.2"
62
+ "dsh": "=0.2.1-rc.3"
63
63
  },
64
64
  "bundle": {
65
65
  "patch": "./cordis.patch.yml"
@@ -90,25 +90,25 @@
90
90
  "effort:gifs": "node scripts/effort-gif.mjs"
91
91
  },
92
92
  "dependencies": {
93
- "@deepseek-ai/schemastery": "3.18.4"
93
+ "@deepseek-ai/schemastery": "3.18.5"
94
94
  },
95
95
  "peerDependencies": {
96
- "@deepseek-ai/cordis": "~4.0.4"
96
+ "@deepseek-ai/cordis": "~4.0.5"
97
97
  },
98
98
  "devDependencies": {
99
99
  "@babel/parser": "7.29.9",
100
- "@deepseek-ai/cordis": "4.0.4",
101
- "@deepseek-ai/dsh-api-session-controller": "0.2.0-rc.2",
102
- "@deepseek-ai/dsh-api-workspace-controller": "0.2.0-rc.2",
103
- "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
104
- "@deepseek-ai/dsh-client-store": "0.2.0-rc.2",
105
- "@deepseek-ai/dsh-client-ui-conversation": "0.2.0-rc.2",
106
- "@deepseek-ai/dsh-client-ui-layout": "0.2.0-rc.2",
107
- "@deepseek-ai/dsh-client-ui-model-selection": "0.2.0-rc.2",
108
- "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2",
109
- "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
110
- "@deepseek-ai/dsh-client-ui-theme": "0.2.0-rc.2",
111
- "@deepseek-ai/dsh-client-ui-workspace": "0.2.0-rc.2",
100
+ "@deepseek-ai/cordis": "4.0.5",
101
+ "@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.3",
102
+ "@deepseek-ai/dsh-api-workspace-controller": "0.2.1-rc.3",
103
+ "@deepseek-ai/dsh-client-locale": "0.2.1-rc.3",
104
+ "@deepseek-ai/dsh-client-store": "0.2.1-rc.3",
105
+ "@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.3",
106
+ "@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.3",
107
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.2.1-rc.3",
108
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.3",
109
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.3",
110
+ "@deepseek-ai/dsh-client-ui-theme": "0.2.1-rc.3",
111
+ "@deepseek-ai/dsh-client-ui-workspace": "0.2.1-rc.3",
112
112
  "@types/node": "26.6.3",
113
113
  "@types/react": "18.3.1",
114
114
  "esbuild": "0.28.2",
@@ -1,14 +0,0 @@
1
- import type { ImplementedFeature } from '../../contracts/feature.ts';
2
- /**
3
- * Window frame and column geometry: flat surfaces, the sidebar column and its
4
- * divider, and the right panel's floating card. The three tracks stay entirely
5
- * `ui-layout`'s solve, so resizing the sidebar with the handle moves the divider
6
- * the pointer is on; the plugin only paints the columns.
7
- *
8
- * The right panel is a column's occupant rather than a track, so its card is
9
- * two sheets: `shell.css` insets the panel's box and paints the surface, and
10
- * `right-panel.css` dresses what the panel draws inside it — the file tree's
11
- * rows included, which belong to no feature of this plugin's own. Both mount
12
- * with the frame, because neither has a switch of its own to lose.
13
- */
14
- export declare const shellFeature: ImplementedFeature;