dsh-claude-desktop-theme 0.4.4 → 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.
- package/README.md +84 -67
- package/lib/client.js +7457 -474
- package/lib/index.js +19 -3
- package/lib/types/client/compat/browser-header.d.ts +1 -2
- package/lib/types/client/compat/hero-greeting.d.ts +6 -0
- package/lib/types/client/compat/host-dom.d.ts +8 -0
- package/lib/types/client/compat/permission-confirmation.d.ts +5 -0
- package/lib/types/client/compat/permission-menu.d.ts +4 -1
- package/lib/types/client/compat/pet-anchor.d.ts +5 -1
- package/lib/types/client/compat/sidebar-search.d.ts +18 -0
- package/lib/types/client/features/composer-pet/BlankPet.d.ts +4 -1
- package/lib/types/client/features/composer-pet/ClaudePet.d.ts +7 -0
- package/lib/types/client/features/composer-pet/claude-frames.d.ts +12 -0
- package/lib/types/client/features/composer-pet/claude-motion.d.ts +3 -0
- package/lib/types/client/features/model-controls/EffortPanel.d.ts +2 -1
- package/lib/types/client/features/model-controls/ModelControls.d.ts +11 -1
- package/lib/types/client/features/model-controls/model-icon-data.d.ts +31 -0
- package/lib/types/client/features/model-controls/model-icon-match.d.ts +20 -0
- package/lib/types/client/features/model-controls/model-icons.d.ts +13 -0
- package/lib/types/client/features/model-controls/selection.d.ts +2 -0
- package/lib/types/client/features/settings/ChoiceMenu.d.ts +15 -0
- package/lib/types/client/features/settings/fields.d.ts +18 -0
- package/lib/types/client/features/settings/locales.d.ts +16 -1
- package/lib/types/host/index.d.ts +30 -0
- package/lib/types/shared/config.d.ts +11 -2
- package/package.json +2 -1
package/lib/index.js
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
|
|
4
4
|
// src/shared/config.ts
|
|
5
|
+
var DEFAULT_PERSONALIZATION = Object.freeze({
|
|
6
|
+
petStyle: "whale",
|
|
7
|
+
greetingStyle: "explore",
|
|
8
|
+
greetingName: ""
|
|
9
|
+
});
|
|
5
10
|
var DEFAULT_FEATURES = Object.freeze({
|
|
6
11
|
shell: true,
|
|
7
12
|
sidebar: true,
|
|
@@ -11,7 +16,8 @@ var DEFAULT_FEATURES = Object.freeze({
|
|
|
11
16
|
statistics: false,
|
|
12
17
|
"composer-pet": true,
|
|
13
18
|
"composer-stats": false,
|
|
14
|
-
"context-panel": true
|
|
19
|
+
"context-panel": true,
|
|
20
|
+
"hero-ripples": true
|
|
15
21
|
});
|
|
16
22
|
var DEFAULT_APPEARANCE = Object.freeze({
|
|
17
23
|
canvas: "",
|
|
@@ -26,7 +32,9 @@ var DEFAULT_VIEW = Object.freeze({
|
|
|
26
32
|
showEmptyGroups: false,
|
|
27
33
|
groupByStatus: true,
|
|
28
34
|
showHeaderSubagents: false,
|
|
29
|
-
showHeaderTeam: false
|
|
35
|
+
showHeaderTeam: false,
|
|
36
|
+
showSidebarBrand: false,
|
|
37
|
+
showModelIcons: true
|
|
30
38
|
});
|
|
31
39
|
var FONT_NAME_MAX_LENGTH = 64;
|
|
32
40
|
|
|
@@ -1016,7 +1024,8 @@ var Config = z.object({
|
|
|
1016
1024
|
statistics: z.boolean().default(DEFAULT_FEATURES.statistics),
|
|
1017
1025
|
"composer-pet": z.boolean().default(DEFAULT_FEATURES["composer-pet"]),
|
|
1018
1026
|
"composer-stats": z.boolean().default(DEFAULT_FEATURES["composer-stats"]),
|
|
1019
|
-
"context-panel": z.boolean().default(DEFAULT_FEATURES["context-panel"])
|
|
1027
|
+
"context-panel": z.boolean().default(DEFAULT_FEATURES["context-panel"]),
|
|
1028
|
+
"hero-ripples": z.boolean().default(DEFAULT_FEATURES["hero-ripples"])
|
|
1020
1029
|
}).default({ ...DEFAULT_FEATURES }).description("\u6309\u6A21\u5757\u542F\u7528").volatile(),
|
|
1021
1030
|
/* One volatile node per section, exactly like `features`: Cordis rejects a
|
|
1022
1031
|
volatile field nested inside another volatile field ("volatile fields
|
|
@@ -1031,7 +1040,14 @@ var Config = z.object({
|
|
|
1031
1040
|
uiCjk: z.string().default(DEFAULT_FONTS.uiCjk).description("\u754C\u9762\u4E2D\u6587\u5B57\u4F53\u540D\uFF08\u7559\u7A7A\u7528\u7CFB\u7EDF\u6808\uFF09").pattern(FONT_NAME),
|
|
1032
1041
|
code: z.string().default(DEFAULT_FONTS.code).description("\u4EE3\u7801\u4E0E\u7B49\u5BBD\u5B57\u4F53\u540D\uFF08\u7559\u7A7A\u7528\u7CFB\u7EDF\u6808\uFF09").pattern(FONT_NAME)
|
|
1033
1042
|
}).default({ ...DEFAULT_FONTS }).description("\u5B57\u4F53").volatile(),
|
|
1043
|
+
personalization: z.object({
|
|
1044
|
+
petStyle: z.union(["whale", "claude"]).default(DEFAULT_PERSONALIZATION.petStyle).description("\u8F93\u5165\u6846\u5BA0\u7269\u6837\u5F0F"),
|
|
1045
|
+
greetingStyle: z.union(["explore", "claude"]).default(DEFAULT_PERSONALIZATION.greetingStyle).description("\u9996\u9875\u95EE\u5019\u8BED\u4E0E\u56FE\u6807\u6837\u5F0F"),
|
|
1046
|
+
greetingName: z.string().default("").pattern(/^.{0,64}$/u).description("\u95EE\u5019\u8BED\u4E2D\u7684\u79F0\u547C\uFF08\u53EF\u7559\u7A7A\uFF09")
|
|
1047
|
+
}).default({ ...DEFAULT_PERSONALIZATION }).description("\u4E2A\u6027\u5316").volatile(),
|
|
1034
1048
|
view: z.object({
|
|
1049
|
+
showModelIcons: z.boolean().default(DEFAULT_VIEW.showModelIcons).description("\u663E\u793A\u6A21\u578B\u9009\u5355\u4E2D\u7684\u524D\u7F6E\u56FE\u6807\uFF08\u9ED8\u8BA4\u5F00\u542F\uFF09"),
|
|
1050
|
+
showSidebarBrand: z.boolean().default(DEFAULT_VIEW.showSidebarBrand).description("\u663E\u793A\u4FA7\u680F DeepSeek Harness \u54C1\u724C\u6761\u76EE\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09"),
|
|
1035
1051
|
showHeaderSubagents: z.boolean().default(DEFAULT_VIEW.showHeaderSubagents).description("\u663E\u793A\u9876\u680F\u5B50\u4EE3\u7406\u5165\u53E3\uFF08\u4EC5\u63A7\u5236\u5165\u53E3\u663E\u793A\uFF09"),
|
|
1036
1052
|
showHeaderTeam: z.boolean().default(DEFAULT_VIEW.showHeaderTeam).description("\u663E\u793A\u9876\u680F\u56E2\u961F\u5165\u53E3\uFF08\u4EC5\u63A7\u5236\u5165\u53E3\u663E\u793A\uFF09"),
|
|
1037
1053
|
groupByStatus: z.boolean().default(DEFAULT_VIEW.groupByStatus).description("\u6309\u4F1A\u8BDD\u72B6\u6001\u5206\u7EC4\uFF08\u4FDD\u7559\u539F\u751F\u9879\u76EE\u89C6\u56FE\u9009\u9879\uFF09"),
|
|
@@ -2,10 +2,9 @@ import type { Disposer } from '../contracts/ports.ts';
|
|
|
2
2
|
/**
|
|
3
3
|
* The name the browsing region's own title line draws.
|
|
4
4
|
* @param text - the host's word, exactly as it rendered it.
|
|
5
|
-
* @param noHistory - whether the plugin's no-history prompt is on screen.
|
|
6
5
|
* @returns the reference's name, or null to leave the host's own word.
|
|
7
6
|
*/
|
|
8
|
-
export declare function browserHeaderWord(text: string
|
|
7
|
+
export declare function browserHeaderWord(text: string): string | null;
|
|
9
8
|
/**
|
|
10
9
|
* Name the browsing region's separate toolbar.
|
|
11
10
|
*
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PersonalizationConfig } from '../../shared/config.ts';
|
|
2
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
3
|
+
/** The greeting follows the interface language and never includes an account name. */
|
|
4
|
+
export declare function claudeGreeting(language?: string): string;
|
|
5
|
+
/** Add a reversible presentation beside the native heading without taking its React nodes. */
|
|
6
|
+
export declare function mountHeroGreeting(document: Document, config: PersonalizationConfig): Disposer;
|
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
* - `packages/client/ui-settings/src/client/SettingsRoot.module.css` (`Dws9Sa_`)
|
|
43
43
|
* - `packages/client/ui-settings-account/src/client/AccountMenu.module.css` (`ZogL4G_`)
|
|
44
44
|
* - `packages/client/ui-primitives/lib/Menu.module.css` (`_4ub78_`, `_ri079_`)
|
|
45
|
+
* - `packages/client/ui-primitives/lib/Modal.module.css` (`_o6lrb_`) and
|
|
46
|
+
* `RiskConfirmation.module.css` (`_cjd8z_`), shared static frontend styles
|
|
45
47
|
* - `packages/client/ui-primitives/lib/Menu.js` (`MenuItemButton`: the icon seat
|
|
46
48
|
* `account-menu.css` scales; its `[role="menuitem"] > span` structure)
|
|
47
49
|
* - `packages/client/ui-chat/src/client/chat/AssistantMarkdown.module.css` (`gKv1-q_`)
|
|
@@ -127,6 +129,7 @@ export declare const HOST: Readonly<{
|
|
|
127
129
|
readonly filesBody: '[data-files-body]';
|
|
128
130
|
readonly filesEntry: '[data-files-entry]';
|
|
129
131
|
readonly sidebarRoot: '._3WPZCG_root';
|
|
132
|
+
readonly sidebarCollapsed: '._3WPZCG_collapsed';
|
|
130
133
|
readonly sidebarLogoRow: '._3WPZCG_logoRow';
|
|
131
134
|
readonly sidebarBrand: '._3WPZCG_brand';
|
|
132
135
|
readonly sidebarBrandName: '._3WPZCG_brandName';
|
|
@@ -326,6 +329,11 @@ export declare const HOST: Readonly<{
|
|
|
326
329
|
children, so the statistics card is appended here and positioned against
|
|
327
330
|
the greeting. */
|
|
328
331
|
readonly heroComposerStack: '.ST7X_W_composerStack';
|
|
332
|
+
/** Shared frontend RiskConfirmation DOM, identical in both desktop builds. */
|
|
333
|
+
readonly riskConfirmation: '._confirmation_cjd8z_1[role="dialog"]';
|
|
334
|
+
readonly riskAcknowledgement: '._acknowledgement_cjd8z_38';
|
|
335
|
+
readonly riskConfirmAction: '._confirmAction_cjd8z_71';
|
|
336
|
+
readonly riskCancelAction: '._modalAction_cjd8z_67';
|
|
329
337
|
/** Every menu surface the `Menu` primitive renders, portal or in place. */
|
|
330
338
|
readonly menu: '[role="menu"]';
|
|
331
339
|
readonly menuItem: '[role="menuitem"]';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
/** Remove the redundant acknowledgement step from permission confirmations.
|
|
3
|
+
* The native handler still updates React; only the user can press Enable.
|
|
4
|
+
* Other RiskConfirmation callers retain their acknowledgement controls. */
|
|
5
|
+
export declare function mountPermissionConfirmation(document: Document, report: (error: unknown) => void): Disposer;
|
|
@@ -36,6 +36,9 @@ export interface PermissionCopy {
|
|
|
36
36
|
* @returns Chinese copy for a Chinese document, English otherwise.
|
|
37
37
|
*/
|
|
38
38
|
export declare function permissionCopy(document: Document): PermissionCopy;
|
|
39
|
+
/** Short summaries of DSH's four built-in Agent presets. */
|
|
40
|
+
export declare function agentPresetCopy(document: Document): PermissionCopy;
|
|
41
|
+
export declare function mountAgentPresetMenu(document: Document, report: (error: unknown) => void): Disposer;
|
|
39
42
|
/**
|
|
40
43
|
* The permission picker's card, drawn the way the reference draws it.
|
|
41
44
|
*
|
|
@@ -54,7 +57,7 @@ export declare function permissionCopy(document: Document): PermissionCopy;
|
|
|
54
57
|
* `permissionCopy` above. It is kept in one table per document language, so a
|
|
55
58
|
* wording change is one edit in one place.
|
|
56
59
|
*
|
|
57
|
-
* Three facts decide how the rows are reached, and each is worth stating:
|
|
60
|
+
* Three facts decide how the permission rows are reached, and each is worth stating:
|
|
58
61
|
*
|
|
59
62
|
* - **A row is recognised by its name.** `Menu` rows carry no identity of their
|
|
60
63
|
* own — no id, no data attribute, and the preset's own glyph is a thing this
|
|
@@ -27,4 +27,8 @@ export declare const PET_INSET = 12;
|
|
|
27
27
|
* selects new sessions; hidden, missing or unlaid-out cards publish null.
|
|
28
28
|
* @returns position source whose dispose releases all listeners and observers.
|
|
29
29
|
*/
|
|
30
|
-
export declare function createPetAnchor(document: Document, report: (error: unknown) => void
|
|
30
|
+
export declare function createPetAnchor(document: Document, report: (error: unknown) => void, box?: {
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
readonly inset?: number;
|
|
34
|
+
}): PetAnchorSource;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Disposer } from '../contracts/ports.ts';
|
|
2
|
+
/** Marks the sidebar column whose field is currently parked above New Session. */
|
|
3
|
+
export declare const SIDEBAR_SEARCH_PLACED_ATTRIBUTE = "data-ccd-sidebar-search-placed";
|
|
4
|
+
/**
|
|
5
|
+
* Park the browsing region's search field above New Session.
|
|
6
|
+
*
|
|
7
|
+
* The field belongs to `ui-workspace`'s `WorkspaceBrowser`, and React removes
|
|
8
|
+
* it from the section header whenever the sidebar collapses to its rail.
|
|
9
|
+
* Moving the React-owned node would make that removal target the wrong parent,
|
|
10
|
+
* so the node stays where React put it and is positioned over the gap that New
|
|
11
|
+
* Session opens above itself. That gap sits after the brand row when the brand
|
|
12
|
+
* is visible and directly below the window strip when it is not.
|
|
13
|
+
*
|
|
14
|
+
* The section header keeps its own row. With the search slot out of flow, its
|
|
15
|
+
* label takes the leading edge and the native View options trigger stays on the
|
|
16
|
+
* trailing edge.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mountSidebarSearch(document: Document, report: (error: unknown) => void): Disposer;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { PersonalizationConfig } from '../../../shared/config.ts';
|
|
2
3
|
import type { PetAnchor } from '../../compat/pet-anchor.ts';
|
|
3
4
|
/** Business face the frame overlay injects: the measured new-session corner. */
|
|
4
5
|
export interface BlankPetFace {
|
|
6
|
+
/** Visual variant chosen in settings. */
|
|
7
|
+
readonly petStyle: PersonalizationConfig['petStyle'];
|
|
5
8
|
/** Selector hook over the compat layer's measurement. */
|
|
6
9
|
readonly useAnchor: () => PetAnchor | null;
|
|
7
10
|
}
|
|
@@ -14,4 +17,4 @@ export type BlankPetProps = PropsRuntime<'shell.overlay'> & BlankPetFace;
|
|
|
14
17
|
* @param props - injected measurement.
|
|
15
18
|
* @returns the positioned whale, or null.
|
|
16
19
|
*/
|
|
17
|
-
export declare function BlankPet({ useAnchor }: BlankPetProps): import("react/jsx-runtime").JSX.Element | null;
|
|
20
|
+
export declare function BlankPet({ useAnchor, petStyle }: BlankPetProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Reference pixel companion: take out a laptop, type, then return to standing. */
|
|
2
|
+
export declare function ClaudePet(): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
/** One shared drawing path for idle and recorded poses, also used by previews. */
|
|
4
|
+
export declare function ClaudeArt({ elapsed, reducedMotion }: {
|
|
5
|
+
readonly elapsed?: number | null;
|
|
6
|
+
readonly reducedMotion?: boolean;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Geometric reconstruction of the original click sequence, sampled at 20fps.
|
|
2
|
+
* Recording antialiasing/compression fringes are not artwork: there is no outline
|
|
3
|
+
* layer. All feet have a constant 3px width; their roots follow the belly while
|
|
4
|
+
* their toes share a ground line. Only the projected feet have a deliberate bend.
|
|
5
|
+
*/
|
|
6
|
+
export type ClaudeFrame = readonly [body: string, shade: string, eyes: string, laptop: string];
|
|
7
|
+
export declare const CLAUDE_GROUND_Y = 23.5;
|
|
8
|
+
export declare const CLAUDE_IDLE: ClaudeFrame;
|
|
9
|
+
/** Pose order and hold times follow the recording; identical clean silhouettes
|
|
10
|
+
* are reused so compression noise cannot animate otherwise stationary edges. */
|
|
11
|
+
export declare const CLAUDE_FRAMES: readonly ClaudeFrame[];
|
|
12
|
+
export declare const CLAUDE_TRACK: readonly number[];
|
|
@@ -4,6 +4,7 @@ export interface EffortPanelProps {
|
|
|
4
4
|
readonly anchor: RefObject<HTMLButtonElement>;
|
|
5
5
|
readonly choices: readonly EffortChoice[];
|
|
6
6
|
readonly selected: number;
|
|
7
|
+
readonly defaultIndex: number;
|
|
7
8
|
readonly disabled: boolean;
|
|
8
9
|
readonly busy: boolean;
|
|
9
10
|
readonly error: string | null;
|
|
@@ -11,4 +12,4 @@ export interface EffortPanelProps {
|
|
|
11
12
|
readonly onClose: () => void;
|
|
12
13
|
}
|
|
13
14
|
/** Presentation-only slider: continuous local preview, one supported choice on release. */
|
|
14
|
-
export declare function EffortPanel({ anchor, choices, selected, disabled, busy, error, onCommit, onClose }: EffortPanelProps): import("react/jsx-runtime").JSX.Element | null;
|
|
15
|
+
export declare function EffortPanel({ anchor, choices, selected, defaultIndex, disabled, busy, error, onCommit, onClose }: EffortPanelProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -3,9 +3,19 @@ import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selec
|
|
|
3
3
|
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
4
|
import type { ModelSelection } from '@deepseek-ai/dsh-api-session-controller/types';
|
|
5
5
|
export type ModelControlsProps = Omit<ModelSelectInjected, 'directory'> & PropsLocale<'model'> & {
|
|
6
|
+
readonly showModelIcons: boolean;
|
|
6
7
|
readonly locked: boolean;
|
|
7
8
|
readonly useDirectory: () => ModelDirectoryState;
|
|
8
9
|
readonly selectEffort: (route: ModelSelection, effort: string | undefined) => void;
|
|
9
10
|
};
|
|
10
11
|
/** SDK-derived values/hooks and callbacks only; DSH retains all business state. */
|
|
11
|
-
export declare function ModelControls({ locked, available, useDirectory, load, select, selectEffort, t }: ModelControlsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
12
|
+
export declare function ModelControls({ showModelIcons, locked, available, useDirectory, load, select, selectEffort, t }: ModelControlsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
13
|
+
export declare function ModelPanel({ showModelIcons, anchor, state, disabled, load, t, onClose, onSelect }: PropsLocale<'model'> & {
|
|
14
|
+
readonly showModelIcons: boolean;
|
|
15
|
+
readonly anchor: React.RefObject<HTMLButtonElement>;
|
|
16
|
+
readonly state: ModelDirectoryState;
|
|
17
|
+
readonly disabled: boolean;
|
|
18
|
+
readonly load: () => void;
|
|
19
|
+
readonly onClose: () => void;
|
|
20
|
+
readonly onSelect: (selection: ModelSelection) => void;
|
|
21
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface ModelIconShape {
|
|
2
|
+
readonly kind: 'path' | 'circle' | 'ellipse' | 'rect';
|
|
3
|
+
readonly d?: string;
|
|
4
|
+
readonly cx?: string;
|
|
5
|
+
readonly cy?: string;
|
|
6
|
+
readonly r?: string;
|
|
7
|
+
readonly rx?: string;
|
|
8
|
+
readonly ry?: string;
|
|
9
|
+
readonly x?: string;
|
|
10
|
+
readonly y?: string;
|
|
11
|
+
readonly width?: string;
|
|
12
|
+
readonly height?: string;
|
|
13
|
+
readonly fillOpacity?: string;
|
|
14
|
+
readonly fillRule?: string;
|
|
15
|
+
readonly clipRule?: string;
|
|
16
|
+
readonly opacity?: string;
|
|
17
|
+
readonly transform?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ModelIconMark {
|
|
20
|
+
readonly title: string;
|
|
21
|
+
readonly viewBox: string;
|
|
22
|
+
readonly shapes: readonly ModelIconShape[];
|
|
23
|
+
readonly color?: ModelIconColor;
|
|
24
|
+
}
|
|
25
|
+
export interface ModelIconColor {
|
|
26
|
+
readonly viewBox: string;
|
|
27
|
+
readonly fill?: string;
|
|
28
|
+
readonly fillRule?: string;
|
|
29
|
+
readonly markup: string;
|
|
30
|
+
}
|
|
31
|
+
export declare const MODEL_ICONS: Readonly<Record<string, ModelIconMark>>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ModelIconMark } from './model-icon-data.ts';
|
|
2
|
+
export interface ModelIconTarget {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ModelIconMatch {
|
|
7
|
+
readonly slug: string;
|
|
8
|
+
readonly mark: ModelIconMark;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Resolve one row's mark, preferring the model over its routing group.
|
|
12
|
+
*
|
|
13
|
+
* The provider is a fallback because a group such as `Magpie` can carry
|
|
14
|
+
* several brands; matching the group first made every row in it share one
|
|
15
|
+
* initial. The model row is the closest statement of which family a route
|
|
16
|
+
* actually serves.
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveModelIcon(provider: ModelIconTarget, model: ModelIconTarget): ModelIconMatch | null;
|
|
19
|
+
/** The fallback seat: the model's own initial, not its routing group's. */
|
|
20
|
+
export declare function modelIconInitial(provider: ModelIconTarget, model: ModelIconTarget): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface ModelIconTarget {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* One row's leading glyph: the model family's mark when the index knows it,
|
|
7
|
+
* otherwise the model's initial. The seat is always drawn so rows align.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ModelIcon({ provider, model }: {
|
|
10
|
+
readonly provider: ModelIconTarget;
|
|
11
|
+
readonly model: ModelIconTarget;
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
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
|
*
|
|
@@ -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': '上下文分解面板';
|
|
@@ -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
|
+
"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",
|