dsh-anthropic-fonts 0.1.1 → 0.3.0

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/LICENSE CHANGED
@@ -1,21 +1,29 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 dsh-anthropic-fonts contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Isilsolme and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Font files notice: `fonts/AnthropicSansWebText.ttf`, `fonts/AnthropicSerifWebText.ttf`
26
+ and `fonts/AnthropicMonoVariable.ttf` are proprietary typefaces of Anthropic,
27
+ extracted from Anthropic's web products. They are included in this repository
28
+ for personal use only and are **not** covered by the MIT license above; all
29
+ rights remain with Anthropic. The npm package does not ship these files.
package/README.en.md CHANGED
@@ -1,101 +1,211 @@
1
- # dsh-anthropic-fonts
2
-
3
- Apply Anthropic's typefaces to the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web UI:
4
-
5
- - **Interface** (sidebar, headings, buttons, settings): `Anthropic Sans Web Text`
6
- - **Model conversation** (Markdown body / headings / tables): `Anthropic Serif Web Text`
7
- - **Code / code blocks**: `Anthropic Mono Variable`
8
-
9
- CJK text falls back to the Source Han family (`Noto Sans SC` / `Source Han Sans SC` / `Noto Serif SC`), then to system fonts.
10
-
11
- ## Fonts
12
-
13
- The `fonts/` directory ships the three Latin fonts; install them for the best English / code rendering:
14
-
15
- | Font | File | Role |
16
- |---|---|---|
17
- | Anthropic Sans Web Text | `fonts/AnthropicSansWebText.ttf` | Interface |
18
- | Anthropic Serif Web Text | `fonts/AnthropicSerifWebText.ttf` | Conversation |
19
- | Anthropic Mono Variable | `fonts/AnthropicMonoVariable.ttf` | Code |
20
-
21
- Install: double-click each `.ttf` on Windows → **Install**; on macOS use **Font Book**.
22
-
23
- Chinese needs no extra install — it falls back to the Source Han fonts (Noto Sans/Serif SC, Source Han), then to system CJK fonts.
24
-
25
- ## Install
26
-
27
- A standard `dsh` bundle plugin — the same shape as
28
- [`dsh-whale-animation`](https://github.com/LeemanCheung/dsh-whale-animation).
29
-
30
- ### CLI (recommended)
31
-
32
- Published on npm — install in one command:
33
-
34
- ```sh
35
- dsh plugin --profile web add dsh-anthropic-fonts
36
- ```
37
-
38
- or from GitHub:
39
-
40
- ```sh
41
- dsh plugin --profile web add "github:Isilsolme/dsh-anthropic-fonts"
42
- ```
43
-
44
- `dsh plugin add` runs `pnpm add` inside the profile and auto-appends the
45
- bundle to `dsh.profile.bundles`. Restart the web surface afterwards.
46
-
47
- ### Manual
48
-
49
- ```jsonc
50
- // ~/.dsh/profiles/web/package.json
51
- {
52
- "dependencies": {
53
- "dsh-anthropic-fonts": "link:C:/path/to/dsh-anthropic-fonts"
54
- },
55
- "dsh": {
56
- "profile": {
57
- "bundles": [
58
- "@deepseek-ai/dsh-base",
59
- "@deepseek-ai/dsh-web-app",
60
- "dsh-anthropic-fonts"
61
- ]
62
- }
63
- }
64
- }
65
- ```
66
-
67
- then:
68
-
69
- ```sh
70
- cd ~/.dsh/profiles/web && pnpm install
71
- ```
72
-
73
- ## Uninstall / toggle off
74
-
75
- ```sh
76
- dsh plugin --profile web remove dsh-anthropic-fonts
77
- ```
78
-
79
- (or remove it from `dependencies` and `bundles`, then `pnpm install`).
80
- Restart to restore the default fonts.
81
-
82
- ## How it works
83
-
84
- Overrides the DSH typography tokens: `--dsw-font-family` (UI) and the non-code
85
- `--dsw-font-markdown-*` tokens (conversation body). The injected `<style>` is
86
- owned by the client fiber and removed on uninstall.
87
-
88
- ## Structure
89
-
90
- - `lib/index.js` — host half (empty; the effect is browser-only)
91
- - `lib/client.js` — client half (injects the font CSS variable overrides)
92
- - `cordis.patch.yml` — bundle patch inserting the plugin row
93
- - `fonts/` — the three Latin font files
94
-
95
- ## Credits
96
-
97
- Font stack modeled on [`blaxisomu/typora_claude`](https://github.com/blaxisomu/typora_claude) (Anthropic Web fonts for Latin, Source Han for CJK).
98
-
99
- ## License
100
-
101
- MIT
1
+ # dsh-anthropic-fonts
2
+
3
+ [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
4
+
5
+ Apply Anthropic's typefaces to the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web UI:
6
+
7
+ - **Interface** (sidebar, headings, buttons, settings): `Anthropic Sans Web Text`
8
+ - **Model conversation** (Markdown body / headings / tables): `Anthropic Serif Web Text`
9
+ - **Code / code blocks**: `Anthropic Mono Variable`
10
+
11
+ CJK text falls back to the Source Han family (`Noto Sans SC` / `Source Han Sans SC` / `Noto Serif SC`), then to system fonts.
12
+
13
+ ## Fonts
14
+
15
+ > **Important: the plugin does not bundle fonts.** The npm package does not ship
16
+ > font files; install the fonts below manually, then refresh / restart the web
17
+ > surface for the change to take effect.
18
+
19
+ The plugin references three Anthropic Latin typefaces (install them for the best
20
+ English / code rendering):
21
+
22
+ | Font | Role | Where to get it |
23
+ |---|---|---|
24
+ | Anthropic Sans Web Text | Interface | Download from [`fonts/`](fonts/), or extract from a Claude app |
25
+ | Anthropic Serif Web Text | Conversation | Download from [`fonts/`](fonts/), or extract from a Claude app |
26
+ | Anthropic Mono Variable | Code | Download from [`fonts/`](fonts/), or extract from a Claude app |
27
+
28
+ Install: double-click each `.ttf` on Windows → **Install**; on macOS use **Font Book**. Then **refresh / restart** the web surface.
29
+
30
+ > The fonts are proprietary to Anthropic, for personal use only, and are **not**
31
+ > covered by the MIT license (see the font notice in [LICENSE](LICENSE)).
32
+
33
+ Chinese needs no extra install — it falls back to the Source Han fonts (Noto Sans/Serif SC, Source Han), then to system CJK fonts.
34
+
35
+ ## Install
36
+
37
+ A standard `dsh` bundle plugin — the same shape as
38
+ [`dsh-whale-animation`](https://github.com/LeemanCheung/dsh-whale-animation).
39
+
40
+ ### CLI (recommended)
41
+
42
+ Published on npm — install in one command:
43
+
44
+ ```sh
45
+ dsh plugin --profile web add dsh-anthropic-fonts
46
+ ```
47
+
48
+ or from GitHub:
49
+
50
+ ```sh
51
+ dsh plugin --profile web add "github:Isilsolme/dsh-anthropic-fonts"
52
+ ```
53
+
54
+ `dsh plugin add` runs `pnpm add` inside the profile and auto-appends the
55
+ bundle to `dsh.profile.bundles`. Restart the web surface afterwards.
56
+
57
+ > ⚠️ After installing the plugin you **still need to install the font files
58
+ > manually** (see "Fonts" above) — the npm package does not ship them.
59
+
60
+ ### Manual
61
+
62
+ ```jsonc
63
+ // ~/.dsh/profiles/web/package.json
64
+ {
65
+ "dependencies": {
66
+ "dsh-anthropic-fonts": "^0.3.0"
67
+ },
68
+ "dsh": {
69
+ "profile": {
70
+ "bundles": [
71
+ "@deepseek-ai/dsh-base",
72
+ "@deepseek-ai/dsh-web-app",
73
+ "dsh-anthropic-fonts"
74
+ ]
75
+ }
76
+ }
77
+ }
78
+ ```
79
+
80
+ then:
81
+
82
+ ```sh
83
+ cd ~/.dsh/profiles/web && pnpm install
84
+ ```
85
+
86
+ > For local development you can instead use
87
+ > `"dsh-anthropic-fonts": "link:C:/path/to/dsh-anthropic-fonts"` to point at a
88
+ > local checkout.
89
+
90
+ ## Uninstall / toggle off
91
+
92
+ ```sh
93
+ dsh plugin --profile web remove dsh-anthropic-fonts
94
+ ```
95
+
96
+ (or remove it from `dependencies` and `bundles`, then `pnpm install`).
97
+ Restart to restore the default fonts.
98
+
99
+ ## Interaction with DSH's own font settings
100
+
101
+ DSH 0.2 added **Text font** / **Code font** fields under *Settings → Appearance*.
102
+ The plugin targets the **empty (default)** state of those fields: a value typed
103
+ there is written as an inline custom property on `body`, which outranks the
104
+ plugin's stylesheet, so body and code text fall back to your font (the
105
+ conversation serif is still owned by the plugin). Leave both fields empty to use
106
+ the plugin's typefaces.
107
+
108
+ ## Compatibility & permissions
109
+
110
+ | Field | Declared in | Value |
111
+ |---|---|---|
112
+ | DSH range (enforced by DSH) | `engines.dsh` | `>=0.1.0-rc.7 <0.3.0` |
113
+ | DSH range (docs / market display) | `dsh.compatibility.dsh` | `>=0.1.0-rc.7 <0.3.0` |
114
+ | DSH per release | `dsh.compatibility.dshReleases` | see below |
115
+ | Node.js | `engines.node` | `>=22` |
116
+ | Profile | `dsh.compatibility.profiles`, `dsh.client.platform` | `web` |
117
+
118
+ Since 0.2, DSH runs a compatibility preflight before starting a profile and
119
+ **disables** any plugin row whose `engines.dsh` (or `@deepseek-ai/dsh*` peer
120
+ range) is unmet. Declaring `engines.dsh` makes an out-of-range install fail
121
+ loudly instead of silently doing nothing.
122
+
123
+ `dshReleases` records every DSH release as `compatible`, `incompatible`, or
124
+ `unknown`. **Only releases actually smoke-tested in a disposable profile are
125
+ marked `compatible`**; releases covered by the range but not individually tested
126
+ stay `unknown` — a range is never presented as verified evidence.
127
+
128
+ Smoke-tested releases (disposable profile, `DSH_HOME` pointed at a temp
129
+ directory, never the real profile):
130
+
131
+ | DSH release | install | start | uninstall |
132
+ |---|---|---|---|
133
+ | 0.1.5-alpha.2 | ✅ | ✅ | ✅ |
134
+ | 0.1.5-rc.1 | ✅ | ✅ | ✅ |
135
+ | 0.1.5-rc.2 | ✅ | ✅ | ✅ |
136
+ | 0.2.1-rc.5 | ✅ | ✅ | ✅ |
137
+
138
+ 0.2.1-rc.5 additionally got an in-browser acceptance check: computed styles were
139
+ read from the live page — interface `--dsw-font-family` resolves to Anthropic
140
+ Sans; the Markdown container, h1–h4, p, strong, em and tables resolve to
141
+ Anthropic Serif; inline code and code blocks resolve to Anthropic Mono — while
142
+ sizes, line heights and weights stay identical to the DSH defaults
143
+ (h1 21px/700/30px, body 14px/24px, tables 13px/22px, …).
144
+
145
+ How each release was checked:
146
+
147
+ ```sh
148
+ DSH_HOME=/tmp/dsh-smoke dsh plugin --profile web add /path/to/dsh-anthropic-fonts # install
149
+ DSH_HOME=/tmp/dsh-smoke dsh --profile web --dump-config # entry anthropic-fonts in the composed tree
150
+ DSH_HOME=/tmp/dsh-smoke dsh --profile web --port 39123 --no-open # start, prints the served URL
151
+ DSH_HOME=/tmp/dsh-smoke dsh plugin --profile web remove dsh-anthropic-fonts # uninstall
152
+ ```
153
+
154
+ Covered: dependency installed into the profile, bundle appended to
155
+ `dsh.profile.bundles`, bundle patch inserting entry `anthropic-fonts` (and not
156
+ disabled by the compatibility preflight), the web server binding and serving a
157
+ page whose boot payload registers `dsh-anthropic-fonts/client.js`, and full
158
+ removal of both the dependency and the bundle row. **Not covered**: an
159
+ independent security audit.
160
+
161
+ **Permissions**: the client half injects a single `<style>` element into
162
+ `document.head`; no file, network, command, or credential access. The host half
163
+ (`lib/index.js`) is empty.
164
+
165
+ After a new DSH release: re-run the four steps in a disposable profile, add that
166
+ release to `dsh.compatibility.dshReleases` as `compatible`, bump this plugin's
167
+ SemVer, and push.
168
+
169
+ ## How it works
170
+
171
+ Since DSH 0.2 the typography tokens come in two layers:
172
+
173
+ - `--dsh-font-family-{text,code}` is the single source of truth (the *Text font*
174
+ / *Code font* settings write exactly these);
175
+ - the theme derives `--dsw-font-family` / `--ds-font-family-code` from them on
176
+ `body`, and every other typography token references those two.
177
+
178
+ The plugin therefore overrides the `--dsh-*` layer. **Writing only
179
+ `--dsw-font-family` stopped working in 0.2**: the derivation rule on `body`
180
+ overrides the inherited `:root` value, which is why the plugin appeared to fall
181
+ back to the default fonts after the 0.2.1 update. 0.1.x has no `--dsh-*` layer
182
+ and reads `--dsw-font-family` directly, so both sets are written.
183
+
184
+ The serif conversation text comes from the Markdown shorthand tokens. In 0.2.x
185
+ Markdown body and headings use `font: var(--dsw-font-markdown-h1)` style
186
+ shorthands with the family already baked in, so the standalone
187
+ `--dsw-font-markdown-*-font-family` tokens are no longer read by any selector.
188
+ The plugin rebuilds those shorthands from the host's own `-font-style` /
189
+ `-font-weight` / `-font-size` / `-line-height` components, swapping only the
190
+ family: sizes, line heights and weights keep following DSH (including the size
191
+ settings), with DSH defaults as fallbacks so 0.1.x keeps working too.
192
+
193
+ The code font goes through `--dsh-font-family-code` / `--ds-font-family-code`;
194
+ the terminal font (`--dsh-font-family-terminal`) is out of scope.
195
+
196
+ The injected `<style>` is owned by the client fiber and removed on uninstall.
197
+
198
+ ## Structure
199
+
200
+ - `lib/index.js` — host half (empty; the effect is browser-only)
201
+ - `lib/client.js` — client half (injects the font CSS variable overrides)
202
+ - `cordis.patch.yml` — bundle patch inserting the plugin row
203
+ - `fonts/` — the three Latin font files
204
+
205
+ ## Credits
206
+
207
+ Font stack modeled on [`blaxisomu/typora_claude`](https://github.com/blaxisomu/typora_claude) (Anthropic Web fonts for Latin, Source Han for CJK).
208
+
209
+ ## License
210
+
211
+ MIT
package/README.md CHANGED
@@ -1,96 +1,161 @@
1
- # dsh-anthropic-fonts
2
-
3
- 给 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web 界面换上 Anthropic 字体:
4
-
5
- - **界面**(侧栏、标题、按钮、设置):`Anthropic Sans Web Text`
6
- - **模型对话**(Markdown 正文 / 标题 / 表格):`Anthropic Serif Web Text`
7
- - **代码 / 代码块**:`Anthropic Mono Variable`
8
-
9
- 中文回退到思源字体(`Noto Sans SC` / `Source Han Sans SC` / `Noto Serif SC`),未安装时回退到系统字体(苹方 / 微软雅黑 / 宋体)。
10
-
11
- ## 字体
12
-
13
- 仓库 `fonts/` 附带三个拉丁字体,安装后英文 / 代码效果最佳:
14
-
15
- | 字体 | 文件 | 用途 |
16
- |---|---|---|
17
- | Anthropic Sans Web Text | `fonts/AnthropicSansWebText.ttf` | 界面 |
18
- | Anthropic Serif Web Text | `fonts/AnthropicSerifWebText.ttf` | 模型对话 |
19
- | Anthropic Mono Variable | `fonts/AnthropicMonoVariable.ttf` | 代码 |
20
-
21
- 安装:Windows 双击每个 `.ttf` → 点「安装」;macOS 用「字体册」导入。
22
-
23
- 中文无需额外安装:会回退到思源黑体 / 宋体(Noto Sans/Serif SC、Source Han),没有则用系统字体。
24
-
25
- ## 安装
26
-
27
- 标准的 `dsh` bundle 插件 —— 与 [`dsh-whale-animation`](https://github.com/LeemanCheung/dsh-whale-animation) 同一种形态。
28
-
29
- ### CLI(推荐)
30
-
31
- 已发布到 npm,一条命令安装:
32
-
33
- ```sh
34
- dsh plugin --profile web add dsh-anthropic-fonts
35
- ```
36
-
37
- 也可以从 GitHub 安装:
38
-
39
- ```sh
40
- dsh plugin --profile web add "github:Isilsolme/dsh-anthropic-fonts"
41
- ```
42
-
43
- `dsh plugin add` 会在 profile 内执行 `pnpm add`,并自动把 bundle 追加到 `dsh.profile.bundles`。之后重启 web 即可生效。
44
-
45
- ### 手动安装
46
-
47
- ```jsonc
48
- // ~/.dsh/profiles/web/package.json
49
- {
50
- "dependencies": {
51
- "dsh-anthropic-fonts": "link:C:/path/to/dsh-anthropic-fonts"
52
- },
53
- "dsh": {
54
- "profile": {
55
- "bundles": [
56
- "@deepseek-ai/dsh-base",
57
- "@deepseek-ai/dsh-web-app",
58
- "dsh-anthropic-fonts"
59
- ]
60
- }
61
- }
62
- }
63
- ```
64
-
65
- 然后:
66
-
67
- ```sh
68
- cd ~/.dsh/profiles/web && pnpm install
69
- ```
70
-
71
- ## 卸载 / 关闭
72
-
73
- ```sh
74
- dsh plugin --profile web remove dsh-anthropic-fonts
75
- ```
76
-
77
- (或从 `dependencies` 和 `bundles` 里移除,再 `pnpm install`)。重启即恢复默认字体。
78
-
79
- ## 原理
80
-
81
- 覆盖 DSH 的排版 token:`--dsw-font-family`(UI 用),以及全部非代码的 `--dsw-font-markdown-*`(对话正文用)。注入的 `<style>` 归属 client fiber,卸载时一并清理。
82
-
83
- ## 结构
84
-
85
- - `lib/index.js` —— Host 半边(空;字体效果只在浏览器)
86
- - `lib/client.js` —— Client 半边(注入字体 CSS 变量覆盖)
87
- - `cordis.patch.yml` —— bundle patch,插入插件行
88
- - `fonts/` —— 三个拉丁字体文件
89
-
90
- ## 参考
91
-
92
- 字体栈参考了 [`blaxisomu/typora_claude`](https://github.com/blaxisomu/typora_claude) 的实现(拉丁用 Anthropic Web 字体、中文回退思源字体)。
93
-
94
- ## 许可
95
-
96
- MIT
1
+ # dsh-anthropic-fonts
2
+
3
+ [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
4
+
5
+ 给 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web 界面换上 Anthropic 字体:
6
+
7
+ - **界面**(侧栏、标题、按钮、设置):`Anthropic Sans Web Text`
8
+ - **模型对话**(Markdown 正文 / 标题 / 表格):`Anthropic Serif Web Text`
9
+ - **代码 / 代码块**:`Anthropic Mono Variable`
10
+
11
+ 中文回退到思源字体(`Noto Sans SC` / `Source Han Sans SC` / `Noto Serif SC`),未安装时回退到系统字体(苹方 / 微软雅黑 / 宋体)。
12
+
13
+ ## 字体
14
+
15
+ > **重要:插件不内置字体**。npm 包不随包分发字体文件;安装插件后还需手动安装字体(见下表),然后刷新 / 重启 web 才会生效。
16
+
17
+ 插件引用的三个 Anthropic 拉丁字体(建议安装,英文 / 代码效果最佳):
18
+
19
+ | 字体 | 用途 | 获取方式 |
20
+ |---|---|---|
21
+ | Anthropic Sans Web Text | 界面 | 仓库 [`fonts/`](fonts/) 下载,或从 Claude 应用提取 |
22
+ | Anthropic Serif Web Text | 模型对话 | 仓库 [`fonts/`](fonts/) 下载,或从 Claude 应用提取 |
23
+ | Anthropic Mono Variable | 代码 | 仓库 [`fonts/`](fonts/) 下载,或从 Claude 应用提取 |
24
+
25
+ 安装:Windows 双击每个 `.ttf` → 点「安装」;macOS 用「字体册」导入。安装后**刷新 / 重启 web** 生效。
26
+
27
+ > 字体版权归 Anthropic 所有,仅供个人使用,不适用 MIT 许可(详见 [LICENSE](LICENSE) 字体声明)。
28
+
29
+ 中文无需额外安装:会回退到思源黑体 / 宋体(Noto Sans/Serif SC、Source Han),没有则用系统字体。
30
+
31
+ ## 安装
32
+
33
+ 标准的 `dsh` bundle 插件 —— 与 [`dsh-whale-animation`](https://github.com/LeemanCheung/dsh-whale-animation) 同一种形态。
34
+
35
+ ### CLI(推荐)
36
+
37
+ 已发布到 npm,一条命令安装:
38
+
39
+ ```sh
40
+ dsh plugin --profile web add dsh-anthropic-fonts
41
+ ```
42
+
43
+ 也可以从 GitHub 安装:
44
+
45
+ ```sh
46
+ dsh plugin --profile web add "github:Isilsolme/dsh-anthropic-fonts"
47
+ ```
48
+
49
+ `dsh plugin add` 会在 profile 内执行 `pnpm add`,并自动把 bundle 追加到 `dsh.profile.bundles`。之后重启 web 即可生效。
50
+
51
+ > ⚠️ 安装插件后**还需手动安装字体文件**(见上方「字体」)——npm 包不随包分发字体。
52
+
53
+ ### 手动安装
54
+
55
+ ```jsonc
56
+ // ~/.dsh/profiles/web/package.json
57
+ {
58
+ "dependencies": {
59
+ "dsh-anthropic-fonts": "^0.3.0"
60
+ },
61
+ "dsh": {
62
+ "profile": {
63
+ "bundles": [
64
+ "@deepseek-ai/dsh-base",
65
+ "@deepseek-ai/dsh-web-app",
66
+ "dsh-anthropic-fonts"
67
+ ]
68
+ }
69
+ }
70
+ }
71
+ ```
72
+
73
+ 然后:
74
+
75
+ ```sh
76
+ cd ~/.dsh/profiles/web && pnpm install
77
+ ```
78
+
79
+ > 本地调试时,可用 `"dsh-anthropic-fonts": "link:C:/path/to/dsh-anthropic-fonts"` 指向本地目录。
80
+
81
+ ## 卸载 / 关闭
82
+
83
+ ```sh
84
+ dsh plugin --profile web remove dsh-anthropic-fonts
85
+ ```
86
+
87
+ (或从 `dependencies` 和 `bundles` 里移除,再 `pnpm install`)。重启即恢复默认字体。
88
+
89
+ ## 与 DSH 自带字体设置的关系
90
+
91
+ DSH 0.2 起「设置 → 外观」里有「正文字体 / 代码字体」。插件针对的是**这两栏留空(默认)**的情况:如果你在那里填了自己的字体,DSH 会把它写成 `body` 上的内联变量,优先级高于插件注入的样式表——正文和代码会回落到你填的字体(对话衬线仍由插件接管)。想用插件的字体,保持这两栏为空即可。
92
+
93
+ ## 兼容性与权限
94
+
95
+ | 项目 | 声明位置 | 值 |
96
+ |---|---|---|
97
+ | DSH 范围(DSH 实际校验) | `engines.dsh` | `>=0.1.0-rc.7 <0.3.0` |
98
+ | DSH 范围(文档 / 市场展示) | `dsh.compatibility.dsh` | `>=0.1.0-rc.7 <0.3.0` |
99
+ | DSH 逐版本 | `dsh.compatibility.dshReleases` | 见下 |
100
+ | Node.js | `engines.node` | `>=22` |
101
+ | Profile | `dsh.compatibility.profiles`、`dsh.client.platform` | `web` |
102
+
103
+ DSH 0.2 起,启动 profile 前会先按 `engines.dsh`(没有则看 `@deepseek-ai/dsh*` 的 peer 依赖)做一次兼容性 preflight,不满足的插件行会被**直接禁用**。这里写 `engines.dsh` 是为了让超出范围时失败得明确,而不是静默不生效。
104
+
105
+ `dshReleases` 对每个 DSH 版本逐项写 `compatible` / `incompatible` / `unknown`。**只有实际跑过一次性 Profile 冒烟验证的版本才写 `compatible`**;范围覆盖但未逐版本验证的一律是 `unknown`,范围声明不会被当作已验证。
106
+
107
+ 已验证版本(一次性 Profile,`DSH_HOME` 指向临时目录,不触碰真实 Profile):
108
+
109
+ | DSH 版本 | 安装 | 启动 | 卸载 |
110
+ |---|---|---|---|
111
+ | 0.1.5-alpha.2 | ✅ | ✅ | ✅ |
112
+ | 0.1.5-rc.1 | ✅ | ✅ | ✅ |
113
+ | 0.1.5-rc.2 | ✅ | ✅ | ✅ |
114
+ | 0.2.1-rc.5 | ✅ | ✅ | ✅ |
115
+
116
+ 0.2.1-rc.5 额外做了浏览器内验收:在真实页面里读取计算样式,界面 `--dsw-font-family` 为 Anthropic Sans,Markdown 容器 / h1–h4 / p / strong / em / 表格为 Anthropic Serif,行内代码与代码块为 Anthropic Mono,且字号、行高、字重与 DSH 默认值逐项一致(h1 21px/700/30px、正文 14px/24px、表格 13px/22px 等)。
117
+
118
+ 验证步骤(每个版本各跑一次):
119
+
120
+ ```sh
121
+ DSH_HOME=/tmp/dsh-smoke dsh plugin --profile web add /path/to/dsh-anthropic-fonts # 安装
122
+ DSH_HOME=/tmp/dsh-smoke dsh --profile web --dump-config # 入口 anthropic-fonts 出现在组合配置里
123
+ DSH_HOME=/tmp/dsh-smoke dsh --profile web --port 39123 --no-open # 启动并输出访问地址
124
+ DSH_HOME=/tmp/dsh-smoke dsh plugin --profile web remove dsh-anthropic-fonts # 卸载
125
+ ```
126
+
127
+ 覆盖到的证据:依赖写入 profile、bundle 追加进 `dsh.profile.bundles`、bundle patch 插入入口 `anthropic-fonts`(且没被兼容性 preflight 禁用)、web 服务正常监听并返回页面(启动载荷里已注册 `dsh-anthropic-fonts/client.js`)、卸载后依赖与 bundle 行都被移除。**未覆盖**:独立安全审计。
128
+
129
+ **权限**:客户端只往 `document.head` 注入一个 `<style>`;不读写文件、不访问网络、不执行命令、不接触凭据。Host 半边(`lib/index.js`)为空。
130
+
131
+ 新的 DSH 版本发布后:在一次性 Profile 里重跑上面四步,把该版本写进 `dsh.compatibility.dshReleases`(`compatible`),并提升本插件 SemVer 后推送。
132
+
133
+ ## 原理
134
+
135
+ DSH 0.2 起排版 token 分成两层:
136
+
137
+ - `--dsh-font-family-{text,code}` 是唯一事实来源(「设置 → 外观」里的正文字体 / 代码字体写的就是它们);
138
+ - theme 在 `body` 上把它们拼进 `--dsw-font-family` / `--ds-font-family-code`,其余所有排版 token 再引用这两个。
139
+
140
+ 所以插件覆盖的是 `--dsh-*` 这一层。**只写 `--dsw-font-family` 在 0.2 起会失效**:`body` 上那条派生声明会盖掉 `:root` 上的继承值——这正是 0.2.1 版本更新后插件「整体回到默认字体」的原因。0.1.x 没有 `--dsh-*` 层、直接读 `--dsw-font-family`,因此两套都写,两条曲线同时可用。
141
+
142
+ 对话的衬线来自 Markdown 简写 token。0.2.x 起 Markdown 正文与标题改用 `font: var(--dsw-font-markdown-h1)` 这类简写,字体族已经烧进简写值里,单独的 `--dsw-font-markdown-*-font-family` 不再被任何选择器读取。插件改用宿主自己的 `-font-style` / `-font-weight` / `-font-size` / `-line-height` 分量重建这些简写,只把字体族换成衬线:字号、行高、字重仍然跟着 DSH(包括设置里的字号调整),分量缺失时回退到 DSH 默认值,0.1.x 也照常工作。
143
+
144
+ 代码字体走 `--dsh-font-family-code` / `--ds-font-family-code`;终端字体(`--dsh-font-family-terminal`)不在插件范围内。
145
+
146
+ 注入的 `<style>` 归属 client fiber,卸载时一并清理。
147
+
148
+ ## 结构
149
+
150
+ - `lib/index.js` —— Host 半边(空;字体效果只在浏览器)
151
+ - `lib/client.js` —— Client 半边(注入字体 CSS 变量覆盖)
152
+ - `cordis.patch.yml` —— bundle patch,插入插件行
153
+ - `fonts/` —— 三个拉丁字体文件
154
+
155
+ ## 参考
156
+
157
+ 字体栈参考了 [`blaxisomu/typora_claude`](https://github.com/blaxisomu/typora_claude) 的实现(拉丁用 Anthropic Web 字体、中文回退思源字体)。
158
+
159
+ ## 许可
160
+
161
+ MIT
package/lib/client.js CHANGED
@@ -1,43 +1,96 @@
1
- window.__ModuleLoader__.load({
2
- id: "dsh-anthropic-fonts",
3
- factory: function (require) {
4
- var module = { exports: {} };
5
- var exports = module.exports;
6
-
7
- var css = "html:root{--dsw-font-family:'Anthropic Sans Web Text','Noto Sans SC','Source Han Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei','Helvetica Neue',Helvetica,Arial,sans-serif;--dsw-font-serif:'Anthropic Serif Web Text',Georgia,'Times New Roman','Noto Serif SC','Source Han Serif SC','Songti SC','SimSun',serif;--ds-font-family-code:'Anthropic Mono Variable','Source Han Sans SC',ui-monospace,'SF Mono','JetBrains Mono','Fira Code',Consolas,'Liberation Mono',Menlo,Courier,monospace}" +
8
- "html body{" +
9
- "--dsw-font-markdown-h1:700 24px/34px var(--dsw-font-serif);--dsw-font-markdown-h1-font-family:var(--dsw-font-serif);" +
10
- "--dsw-font-markdown-h2:700 22px/32px var(--dsw-font-serif);--dsw-font-markdown-h2-font-family:var(--dsw-font-serif);" +
11
- "--dsw-font-markdown-h3:700 20px/30px var(--dsw-font-serif);--dsw-font-markdown-h3-font-family:var(--dsw-font-serif);" +
12
- "--dsw-font-markdown-h4:600 16px/28px var(--dsw-font-serif);--dsw-font-markdown-h4-font-family:var(--dsw-font-serif);" +
13
- "--dsw-font-markdown-base:16px/28px var(--dsw-font-serif);--dsw-font-markdown-base-font-family:var(--dsw-font-serif);" +
14
- "--dsw-font-markdown-base-strong:600 16px/28px var(--dsw-font-serif);--dsw-font-markdown-base-strong-font-family:var(--dsw-font-serif);" +
15
- "--dsw-font-markdown-base-italic:italic 16px/28px var(--dsw-font-serif);--dsw-font-markdown-base-italic-font-family:var(--dsw-font-serif);" +
16
- "--dsw-font-markdown-base-strong-italic:italic 600 16px/28px var(--dsw-font-serif);--dsw-font-markdown-base-strong-italic-font-family:var(--dsw-font-serif);" +
17
- "--dsw-font-markdown-table:15px/25px var(--dsw-font-serif);--dsw-font-markdown-table-font-family:var(--dsw-font-serif);" +
18
- "--dsw-font-markdown-table-head:500 15px/25px var(--dsw-font-serif);--dsw-font-markdown-table-head-font-family:var(--dsw-font-serif);" +
19
- "--dsw-font-markdown-small:14px/24px var(--dsw-font-serif);--dsw-font-markdown-small-font-family:var(--dsw-font-serif);" +
20
- "--dsw-font-markdown-small-strong:600 14px/24px var(--dsw-font-serif);--dsw-font-markdown-small-strong-font-family:var(--dsw-font-serif);" +
21
- "--dsw-font-markdown-small-italic:italic 14px/24px var(--dsw-font-serif);--dsw-font-markdown-small-italic-font-family:var(--dsw-font-serif);" +
22
- "--dsw-font-markdown-small-strong-italic:italic 600 14px/24px var(--dsw-font-serif);--dsw-font-markdown-small-strong-italic-font-family:var(--dsw-font-serif);" +
23
- "}";
24
-
25
- function apply(ctx) {
26
- if (typeof document === "undefined") return;
27
- var tagId = "dsh-anthropic-fonts/fonts.css";
28
- if (document.querySelector('style[data-plugin-css=' + JSON.stringify(tagId) + ']') !== null) return;
29
- var tag = document.createElement("style");
30
- tag.dataset.plugin = "dsh-anthropic-fonts";
31
- tag.dataset.pluginCss = tagId;
32
- tag.textContent = css;
33
- document.head.appendChild(tag);
34
- ctx.effect(function () {
35
- return function () { tag.remove(); };
36
- });
37
- }
38
-
39
- exports.apply = apply;
40
- exports.inject = [];
41
- return module.exports;
42
- }
43
- });
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-anthropic-fonts",
3
+ factory: function (require) {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+
7
+ // 只覆盖字体族,字号 / 行高 / 字重全部交给 DSH 自己的排版 token。
8
+ var SANS =
9
+ "'Anthropic Sans Web Text','Noto Sans SC','Source Han Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei','Helvetica Neue',Helvetica,Arial,sans-serif";
10
+ var SERIF =
11
+ "'Anthropic Serif Web Text',Georgia,'Times New Roman','Noto Serif SC','Source Han Serif SC','Songti SC','SimSun',serif";
12
+ var MONO =
13
+ "'Anthropic Mono Variable','Source Han Sans SC',ui-monospace,'SF Mono','JetBrains Mono','Fira Code',Consolas,'Liberation Mono',Menlo,Courier,monospace";
14
+
15
+ // DSH >= 0.2 的排版分两层:--dsh-font-family-{text,code} 是唯一事实来源(设置里的
16
+ // 「正文字体 / 代码字体」写的就是它们),theme 再在 body 上把它们拼进 --dsw-font-family /
17
+ // --ds-font-family-code。所以必须覆盖 --dsh-* 这一层:只写 --dsw-font-family 会被 body 上那条
18
+ // 派生声明盖掉(0.1.x 没有 --dsh-* 层,故两套都写,两条曲线同时可用)。
19
+ var ROOT =
20
+ "html:root{" +
21
+ "--dsh-font-family-text:" + SANS + ";" +
22
+ "--dsh-font-family-code:" + MONO + ";" +
23
+ "--dsw-font-family:" + SANS + ";" +
24
+ "--ds-font-family-code:" + MONO + ";" +
25
+ "--dsw-font-serif:" + SERIF +
26
+ "}";
27
+
28
+ // 0.2.x 起 Markdown 正文与标题都走 font 简写 token(font:var(--dsw-font-markdown-h1)),
29
+ // 字体族已经烧进简写里,单独的 --dsw-font-markdown-*-font-family 不再被任何选择器读取。
30
+ // 这里用宿主自己的 style / weight / size / line-height 分量重建简写:字号行高继续跟随 DSH
31
+ // (含设置里的字号调整),只把字体族换成衬线。分量缺失时回退到 DSH 的默认值。
32
+ var DELTA = "var(--dsh-content-font-delta)";
33
+ var DELTA_2 = "var(--dsh-content-font-delta-secondary,0px)";
34
+ var SIZE = "var(--dsh-content-font-size,14px)";
35
+ var SIZE_2 = "var(--dsh-content-font-size-secondary,13px)";
36
+ // [variant, font-style, font-weight, font-size, line-height]
37
+ var VARIANTS = [
38
+ ["h1", "normal", "700", "calc(21px + " + DELTA + ")", "calc(30px + " + DELTA + ")"],
39
+ ["h2", "normal", "700", "calc(19px + " + DELTA + ")", "calc(28px + " + DELTA + ")"],
40
+ ["h3", "normal", "700", "calc(18px + " + DELTA + ")", "calc(26px + " + DELTA + ")"],
41
+ ["h4", "normal", "600", SIZE, "calc(24px + " + DELTA + ")"],
42
+ ["base", "normal", "400", SIZE, "calc(24px + " + DELTA + ")"],
43
+ ["base-strong", "normal", "600", SIZE, "calc(24px + " + DELTA + ")"],
44
+ ["base-italic", "italic", "400", SIZE, "calc(24px + " + DELTA + ")"],
45
+ ["base-strong-italic", "italic", "600", SIZE, "calc(24px + " + DELTA + ")"],
46
+ ["table", "normal", "400", SIZE_2, "calc(22px + " + DELTA_2 + ")"],
47
+ ["table-head", "normal", "500", SIZE_2, "calc(22px + " + DELTA_2 + ")"],
48
+ ["small", "normal", "400", "12px", "20px"],
49
+ ["small-strong", "normal", "600", "12px", "20px"],
50
+ ["small-italic", "italic", "400", "12px", "20px"],
51
+ ["small-strong-italic", "italic", "600", "12px", "20px"]
52
+ ];
53
+
54
+ function part(variant, field, fallback) {
55
+ return "var(--dsw-font-markdown-" + variant + "-" + field + "," + fallback + ")";
56
+ }
57
+
58
+ function markdownTokens() {
59
+ var decls = [];
60
+ for (var i = 0; i < VARIANTS.length; i++) {
61
+ var variant = VARIANTS[i][0];
62
+ // 0.1.x 的选择器读的是这个族 token;0.2.x 已没有选择器读它,保留不影响新版本。
63
+ decls.push("--dsw-font-markdown-" + variant + "-font-family:var(--dsw-font-serif)");
64
+ decls.push(
65
+ "--dsw-font-markdown-" + variant + ":" +
66
+ part(variant, "font-style", VARIANTS[i][1]) + " " +
67
+ part(variant, "font-weight", VARIANTS[i][2]) + " " +
68
+ part(variant, "font-size", VARIANTS[i][3]) + "/" +
69
+ part(variant, "line-height", VARIANTS[i][4]) + " " +
70
+ "var(--dsw-font-serif)"
71
+ );
72
+ }
73
+ return "html body{" + decls.join(";") + "}";
74
+ }
75
+
76
+ var css = ROOT + markdownTokens();
77
+
78
+ function apply(ctx) {
79
+ if (typeof document === "undefined") return;
80
+ var tagId = "dsh-anthropic-fonts/fonts.css";
81
+ if (document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") !== null) return;
82
+ var tag = document.createElement("style");
83
+ tag.dataset.plugin = "dsh-anthropic-fonts";
84
+ tag.dataset.pluginCss = tagId;
85
+ tag.textContent = css;
86
+ document.head.appendChild(tag);
87
+ ctx.effect(function () {
88
+ return function () { tag.remove(); };
89
+ });
90
+ }
91
+
92
+ exports.apply = apply;
93
+ exports.inject = [];
94
+ return module.exports;
95
+ }
96
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-anthropic-fonts",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Switch the DSH web interface to Anthropic Sans Web Text and model conversation to Anthropic Serif Web Text.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,7 +20,6 @@
20
20
  },
21
21
  "files": [
22
22
  "lib",
23
- "fonts",
24
23
  "cordis.patch.yml",
25
24
  "README.md",
26
25
  "README.en.md",
@@ -36,7 +35,8 @@
36
35
  "anthropic"
37
36
  ],
38
37
  "engines": {
39
- "node": ">=20"
38
+ "node": ">=22",
39
+ "dsh": ">=0.1.0-rc.7 <0.3.0"
40
40
  },
41
41
  "dsh": {
42
42
  "bundle": {
@@ -46,6 +46,31 @@
46
46
  "inject": [],
47
47
  "platform": "web",
48
48
  "immediately": true
49
+ },
50
+ "compatibility": {
51
+ "dsh": ">=0.1.0-rc.7 <0.3.0",
52
+ "dshReleases": {
53
+ "rc.7": "unknown",
54
+ "rc.8": "unknown",
55
+ "0.1.1-rc.1": "unknown",
56
+ "0.1.1-rc.2": "unknown",
57
+ "0.1.2-alpha.2": "unknown",
58
+ "0.1.2-alpha.3": "unknown",
59
+ "0.1.2-alpha.4": "unknown",
60
+ "0.1.2-alpha.5": "unknown",
61
+ "0.1.2-rc.1": "unknown",
62
+ "0.1.3-alpha.1": "unknown",
63
+ "0.1.3-alpha.2": "unknown",
64
+ "0.1.5-alpha.1": "unknown",
65
+ "0.1.5-alpha.2": "compatible",
66
+ "0.1.5-rc.1": "compatible",
67
+ "0.1.5-rc.2": "compatible",
68
+ "0.2.1-rc.2": "unknown",
69
+ "0.2.1-rc.5": "compatible"
70
+ },
71
+ "profiles": [
72
+ "web"
73
+ ]
49
74
  }
50
75
  },
51
76
  "peerDependencies": {
Binary file
Binary file
Binary file