🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

陶土主题套件 HwFee/HwFee-dsh

DeepSeek Harness
HwFee2 天前有提交已提供中文文档扫描:高危

DeepSeek Harness 插件:一套 Claude Design System 主题、系统字体和一个用量面板。设计语言取自 open-claude-ui。

36.4/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add HwFee/HwFee-dsh
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · market
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 2 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/20) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包HwFee-dsh(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/3 07:16:24

🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

静态扫描发现安装期即执行代码,或命令参数由运行时变量拼接(参数来源无法静态判定,从严处理)。

命令参数由运行时变量拼接读写/删除本地文件发起外部网络请求
查看扫描证据(共 70 处,展示前 57 条)
  • 读取本地文件
    market/build-index.mjs:43
    const read = (path) => JSON.parse(readFileSync(path, 'utf8'))
  • 发起网络请求
    market/build-index.mjs:48
    const response = await fetch(`${registry}/${encodeURIComponent(name)}`, {
  • 读取本地文件
    market/build-index.mjs:58
    const pluginDirs = readdirSync(join(root, 'plugins'))
  • 读取本地文件
    market/build-index.mjs:59
    .filter((dir) => statSync(join(root, 'plugins', dir)).isDirectory())
  • 读取本地文件
    market/build-index.mjs:71
    if (!existsSync(join(dirPath, 'icon.svg'))) throw new Error(`${dir} has no icon.svg`)
  • 写入本地文件
    market/build-index.mjs:113
    writeFileSync(join(root, 'market', 'index.json'), JSON.stringify(index, null, 2) + '\n', 'utf8')
  • 读取本地文件
    market/check-release-assets.mjs:108
    for (const dir of readdirSync(pluginsDir)) {
  • 读取本地文件
    market/check-release-assets.mjs:112
    entries = readdirSync(fontsDir)
  • 读取本地文件
    market/check-release-assets.mjs:118
    const bytes = readFileSync(join(fontsDir, file))
  • 执行外部命令运行时拼接
    market/check-release-assets.mjs:226
    const out = execFileSync(`npm pack --pack-destination "${dest}" --json`, {
  • 读取本地文件
    market/check-release-assets.mjs:233
    if (!statSync(tgz).isFile()) throw new Error(`npm pack produced no file in ${dest}`)
  • 读取本地文件
    market/check-release-assets.mjs:236
    size: statSync(tgz).size,
  • 删除本地文件递归
    market/check-release-assets.mjs:237
    cleanup: () => rmSync(dest, { recursive: true, force: true }),
  • 读取本地文件
    market/check-release-assets.mjs:242
    const manifest = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'))
  • 执行外部命令运行时拼接
    market/compare-published.mjs:91
    const out = execFileSync(`npm pack --pack-destination "${dest}" --json`, {
  • 读取本地文件
    market/compare-published.mjs:98
    const files = readTar(gunzipSync(readFileSync(tgz)))
  • 读取本地文件
    market/compare-published.mjs:100
    return { files, manifest, filename: info.filename, size: statSync(tgz).size }
  • 删除本地文件递归
    market/compare-published.mjs:102
    rmSync(dest, { recursive: true, force: true })
  • 执行外部命令运行时拼接
    market/compare-published.mjs:109
    execFileSync(`npm pack "${name}@${version}" --registry=${registry} --json`, {
  • 读取本地文件
    market/compare-published.mjs:114
    const tgz = readdirSync(dest).find((f) => f.endsWith('.tgz'))
  • 读取本地文件
    market/compare-published.mjs:116
    const files = readTar(gunzipSync(readFileSync(join(dest, tgz))))
  • 读取本地文件
    market/compare-published.mjs:121
    return { files, manifest, filename: tgz, size: statSync(join(dest, tgz)).size }
  • 删除本地文件递归
    market/compare-published.mjs:123
    rmSync(dest, { recursive: true, force: true })
  • 执行外部命令运行时拼接
    market/compare-published.mjs:129
    return execFileSync(`npm view "${name}" version --registry=${registry}`, {
  • 执行外部命令运行时拼接
    market/compare-published.mjs:158
    return execFileSync(`git ${args}`, { cwd, encoding: 'utf8', shell: true }).replace(/ +$/, '')
  • 读取本地文件
    market/compare-published.mjs:179
    const dirs = readdirSync(pluginsDir)
  • 写入本地文件
    market/compare-published.mjs:298
    writeFileSync(REPORT, lines.join('\n'), 'utf8')
  • 写入本地文件
    plugins/cds-theme/lib/paste-store.js:101
    await mkdir(directory, { recursive: true })
  • 删除本地文件
    plugins/cds-theme/lib/paste-store.js:123
    await unlink(target).catch(() => {})
  • 执行外部命令固定命令
    plugins/git-bash/lib/index.js:1010
    execFile('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true }, (error) => {
  • 执行外部命令来自配置/变量
    plugins/git-bash/lib/index.js:1108
    const child = spawn(command, args, {
  • 执行外部命令来自配置/变量
    plugins/git-bash/lib/resolve.js:142
    return execFileSync(command, args, { encoding: 'utf8', windowsHide: true, timeout: 5000 })
  • 执行外部命令来自配置/变量
    plugins/git-bash/lib/resolve.js:156
    execFile(command, args, { windowsHide: true, timeout: 5000 }, (error, stdout) => {
  • 执行外部命令来自配置/变量
    plugins/system-fonts/lib/system-fonts.js:177
    execFile(file, args, {
  • 读取本地文件
    plugins/usage-stats/lib/usage-cache.js:101
    return typeof file === 'string' && file !== '' && existsSync(file)
  • 读取本地文件
    plugins/usage-stats/lib/usage-cache.js:161
    parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 写入本地文件
    plugins/usage-stats/lib/usage-cache.js:200
    mkdirSync(directory, { recursive: true })
  • 写入本地文件
    plugins/usage-stats/lib/usage-cache.js:201
    writeFileSync(temporary, text)
  • 写入本地文件
    plugins/usage-stats/lib/usage-cache.js:202
    renameSync(temporary, file)
  • 读取本地文件
    plugins/usage-stats/lib/usage-ledger.js:48
    parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 写入本地文件
    plugins/usage-stats/lib/usage-ledger.js:86
    mkdirSync(path.dirname(file), { recursive: true })
  • 写入本地文件
    plugins/usage-stats/lib/usage-ledger.js:87
    writeFileSync(temporary, text)
  • 写入本地文件
    plugins/usage-stats/lib/usage-ledger.js:88
    renameSync(temporary, file)
  • 读取本地文件
    plugins/usage-stats/lib/usage-store.js:292
    entries = readdirSync(directory, { withFileTypes: true })
  • 读取本地文件
    plugins/usage-stats/lib/usage-store.js:474
    stat = statSync(file)
  • 删除本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:87
    rmSync(dir, {
  • 读取本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:98
    return readFileSync(path, "utf8");
  • 写入本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:115
    mkdirSync(dirname(path), { recursive: true });
  • 写入本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:116
    writeFileSync(path, content, "utf8");
  • 读取本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:121
    return statSync(path).isFile();
  • 读取本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:129
    return statSync(path).isDirectory();
  • 读取本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:163
    for (const candidate of candidates) if (existsSync(join(candidate, "ts")) && existsSync(join(candidate, "js"))) return resolve(candidate);
  • 读取本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:169
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:186
    content: renderTemplate(readFileSync(join(root, rel), "utf8"), context)
  • 执行外部命令来自配置/变量
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:1526
    if (process.platform === "win32") return spawn(winCommandLine(command, args), {
  • 执行外部命令来自配置/变量
    skills/dsh-plugin-guide/dist/dsh-plugin-dev.js:1538
    return spawn(command, args, {
  • 读取本地文件
    skills/dsh-plugin-guide/index.js:46
    const { description, body } = splitFrontmatter(readFileSync(skillPath, 'utf8'))
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
HwFee-dsh DeepSeek Harness(DSH)的六个插件:Claude Design System 主题、字体与字号设置、用量面板、生成式 UI 卡片、下一句提示词预测,以及藏在 run_shell 工具背后的 Git Bash。 新建 DSH 会话:主标题、下方的用量面板(含六个计数器和热力图),以及输入框 中文界面:assets/screenshot-home-zh.png。 六个插件 | 包 | 作用 | 安装名 | | dsh-cds-theme | 替换宿主外观:调色板、字体排印、圆角、阴影,以及代码块、表格、工具卡片的组件样式 | dsh-cds-theme | | dsh-system-fonts | 为正文、代码、终端、界面提供字体选择器,另有行内代码与界面字号、行高、字距 | dsh-system-fonts | | @hwfee/dsh-usage-stats | 新建会话页上的用量面板,数据汇总自本地会话日志 | @hwfee/dsh-usage-stats | | @hwfee/dsh-genui | render_ui:模型用交互卡片作答,不再输出大段文字 | @hwfee/dsh-genui |
展开完整文档(README 剩余 1 节)
HwFee-dsh

DeepSeek Harness(DSH)的六个插件:Claude Design System 主题、字体与字号设置、用量面板、生成式 UI 卡片、下一句提示词预测,以及藏在 run_shell 工具背后的 Git Bash。

新建 DSH 会话:主标题、下方的用量面板(含六个计数器和热力图),以及输入框

中文界面:assets/screenshot-home-zh.png。

六个插件

| 包 | 作用 | 安装名 |
| dsh-cds-theme | 替换宿主外观:调色板、字体排印、圆角、阴影,以及代码块、表格、工具卡片的组件样式 | dsh-cds-theme |
| dsh-system-fonts | 为正文、代码、终端、界面提供字体选择器,另有行内代码与界面字号、行高、字距 | dsh-system-fonts |
| @hwfee/dsh-usage-stats | 新建会话页上的用量面板,数据汇总自本地会话日志 | @hwfee/dsh-usage-stats |
| @hwfee/dsh-genui | render_ui:模型用交互卡片作答,不再输出大段文字 | @hwfee/dsh-genui |
| @hwfee/dsh-git-bash | 在 Windows 上让 run_shell 走 Git Bash,并提供 shell 设置项 | @hwfee/dsh-git-bash |
| @hwfee/dsh-predict | 在输入框里淡淡提示你的下一句话;按 Tab 填入 | @hwfee/dsh-predict |

设置 → 插件,已安装插件区,六个开关全部打开

每个插件都是独立包,各有自己的 manifest、预构建客户端 bundle 和测试套件。装一个或装六个都行;停用任意一个,宿主即恢复原样。

各插件详解

dsh-cds-theme — Claude 风格主题

通过宿主的 overrideTokens 路径注入 319 个设计 token(173 个颜色、133 个字体排印、13 个圆角/阴影/动效,明暗两套),组件规则则挂在稳定的 data- 钩子上,不依赖宿主那些哈希类名。

- 组件改造:空白页上的衬线展示体问候语;带边框的 Markdown 表格,表头着色、数字等宽;代码块亮色模式为白底,暗色模式为 #1a1a19;工具调用统一成单卡片布局;diff 与写入卡片由主题渲染,按语言着色语法,并逐词高亮改动。
- 「主题」设置页,与「通用」并列:亮色/暗色/跟随系统、四种强调色、表面暖度、圆角刻度、阴影强度、组件精修开关、中文字体优先、长粘贴转文件,以及空白页上的 ASCII 海洋。鲸鱼颜色可选黑色、DeepSeek 蓝或渐变;开启减少动效后场景静止。
- 代码块默认换行,宿主「不换行」开关已移除——不换行不是这个主题提供的状态。

主题下的 Python 代码块,以及它周围的推理文本和命令输出

设置 → 主题:模式、强调色、表面暖度、圆角、层次、组件精修

限制:主题针对特定的宿主钩子和插槽;宿主一旦改动这些钩子,组件规则可能匹配不到任何东西,直到插件更新。「组件精修」可以关掉,退回只用 token 的主题化。

完整设置列表与实现说明:plugins/cds-theme/README.md。

dsh-system-fonts — 字体与间距

- 四个字体槽位:正文、代码、终端,以及一个界面字体族——你没设置之前它跟随正文。宿主的三个行是原地替换,不是复制一份。
- 两个像素步进器:界面字号(10–20px,未设置时 14px)缩放界面文字,不动布局;行内代码字号(10–20px,未设置时 12px)只影响行内代码。
- 行高与字距滑块,实时生效。
- Windows 字体发现合并 GDI 字体族、注册表和逐文件 OpenType 名称,所以 PingFang SC 和 苹方-简 会归到同一条目。

通用 → 字体展开:文本、代码、行内代码、终端、界面字体与界面字号各行

限制:它只改字体族和间距——不改 font-weight,不改颜色。宿主自己 CSS 模块里写死的字号(侧边栏和设置行文字)从 CSS 够不到;界面字号能作用到文本节点,但不是每个固定 px 都能覆盖。

行顺序与字体发现:plugins/system-fonts/README.md。

@hwfee/dsh-usage-stats — 本地用量面板

空白页问候语下方的一张卡片,完全从 ~/.dsh/sessions 算出,不发任何网络请求:

- 六个计数器——会话、消息、token、活跃天数、高峰时段、最常用模型——外加一个模型标签页,显示 token 占比,可在全部时间、30 天、7 天之间切换。
- 活动热力图,最后一格永远是今天,还能和一本经典小说的字数做对比。
- 持久账本:首次冷扫描要几秒,之后启动读 ~/.dsh/cache/usage-stats/ 里的缓存。计数只增不减——删掉某个会话的日志,它不会从总数里消失;要重建就删掉账本文件。

面板就是本页顶部截图里问候语下方的那张卡片。

限制:它读本地日志,所以新机器从零开始;总数是账本,不是磁盘现状的快照。

缓存、账本与高度设置:plugins/usage-stats/README.md。

@hwfee/dsh-genui — 生成式 UI 卡片

模型调用 render_ui,结果就是对话里一张活的 React 卡片:图表、对比表格、表单、开关。按钮能改变卡片状态。
render_ui 卡片:标题、总计、七日柱状图,以及模型输出的一行页脚

- 卡片代码在沙箱 iframe 里运行,属性为 sandbox="allow-scripts",不带 allow-same-origin,因此它的文档来源是不透明的;其中的 CSP 会屏蔽文档里列出的网络 API、页面跳转、嵌套框架和表单。
- interact() 只是发起请求,不是发送。 宿主会在 iframe 外画一行确认栏,显示原句和发送、丢弃两个按钮;只有点击才会发送。
- 自带 React:React、ReactDOM 和 Scheduler 在构建时编译进 iframe,卡片完全不碰宿主的 React 或模块表。
- 出错时错误显示在卡片的位置,点一下就能看到源码。

限制:它能保证卡片代码读不到宿主页面、存储和 Cookie,也不能替你发言。它不保证模型写的代码无害——那段代码照样会运行,只是跑在自己的 iframe 里。

完整的 CSP、消息校验,以及卡片能做什么:见 plugins/genui/README.md。

@hwfee/dsh-git-bash — 用 Git Bash 当 shell

新增 run_shell 工具,以及一行 Default shell 设置,有三种模式:Automatic、Windows PowerShell、Git Bash。

- 找的是真正的 Git for Windows bash,不是 C:\Windows\System32\bash.exe 那个 WSL 占位程序:先看 DSH_GIT_BASH,再看 git --exec-path,最后查已知安装路径。
- 标明每条命令在哪运行:· host 表示走宿主的 ctx.shell,并带上会话的沙箱模式;· direct 表示由插件直接启动进程。
- 失败即拒绝:Git Bash 无法在 Windows 沙箱里运行,所以只读、workspace-write 和无法判定的会话会在启动进程之前*就被拒绝。拒绝信息会指向 Windows PowerShell,绝不会让调用方放宽沙箱。只有显式声明 danger-full-access 的会话才直接运行 Git Bash。
- 取消、超时和输出超限会终止真正的进程树,而不只是插件启动的那个 shell。

一次 run_shell 调用显示为命令卡片:命令带 $ 前缀,输出在下方滚动

限制:在 Windows 上,POSIX 命令只在允许直接执行的会话里可用。受限会话里同样的请求会返回错误,这是有意设计。

shell 的解析方式和沙箱决策表:见 plugins/git-bash/README.md。

@hwfee/dsh-predict — 下一条提示词建议

每次回复之后,输入框里会出现一条灰色的建议,提示你下一条消息。按 Tab 填入,不会发送。

输入框里的灰色幽灵文字,提示下一条消息

- 旁路通道:在 turn/end 之后通过宿主的 LLM 服务运行,关闭推理。它不写会话日志,不开启新一轮对话,失败也不会在对话里留下任何东西。
- 把摘录发给你的服务商:每次预测都是一条短请求,带上最近几轮对话,走同一个服务商、同一套凭证和计费,跟正常回复一样。插件自己不建立任何连接;把这一行关掉,这些摘录就不会离开本机。
- 失败后退避:连续失败三次,就静默十轮;预测超过 20 秒直接丢弃。

限制:会话第一轮不做预测;模型返回空内容时也不做——那是正常的空结果,不是错误。

设置、时序表和数据流:plugins/predict/README.md。

安装

六个一起装,版本从官方 registry 解析:

pwsh market/install-all.ps1 -Profile desktop

智能体操作手册(安装、层级检查、挂载验证、失败处理):docs/install-plugins.md。

或者在终端里,每个插件一条命令:

dsh plugin --profile desktop add dsh-cds-theme@0.1.11 --registry=https://registry.npmjs.org
dsh plugin --profile desktop add dsh-system-fonts@0.1.3 --registry=https://registry.npmjs.org
dsh plugin --profile desktop add @hwfee/dsh-usage-stats@0.1.5 --registry=https://registry.npmjs.org
dsh plugin --profile desktop add @hwfee/dsh-genui@0.1.2 --registry=https://registry.npmjs.org
dsh plugin --profile desktop add @hwfee/dsh-predict@0.1.2 --registry=https://registry.npmjs.org
dsh plugin --profile desktop add @hwfee/dsh-git-bash@0.1.2 --registry=https://registry.npmjs.org

或者把同样的包名粘贴到 Settings → Plugins → Add Plugin。

添加或移除插件后,退出并重启 DSH。 插件包在应用启动时加载,刷新页面不够。移除用同样的命令,把 add 换成 remove:

dsh plugin --profile desktop remove dsh-cds-theme

这些版本于 2026-10-24 在 DSH 0.2.1-rc.3 上验证通过。不锁定版本的 predict 安装仍会解析到 0.1.1,因要求 rc.2 而被拒绝;请用上面的锁定命令,或走市场索引。见安装矩阵。

没有 npm 账号:用 GitHub Releases

每个包也会以 .tgz 资产发布在 Releases,每个包一个 tag,因为六个包各自独立发版:

| Tag | <plugin>-v<version>,例如 cds-theme-v<version> |
| 资产名 | npm pack 生成的文件名;带 scope 的包会去掉 scope,所以 @hwfee/dsh-genui 是 hwfee-dsh-genui-<version>.tgz |
| 安装 | dsh plugin --profile desktop add <资产 URL 或本地 .tgz 路径> |

打开 release 页面点资产,别自己拼 URL——少个 hwfee- 前缀或多留个 @scope/ 就是 404。

两种装不上的方式:git 子目录(git+https://…#…&path:/plugins/…——pnpm 安装的是仓库根目录,会忽略 path),以及旧的共享 tag,它的资产只有第一个 release。请用按包分的 tag。

从源码安装

client/client.js 的预构建产物已提交到仓库,所以克隆下来就能直接 link:

git clone https://github.com/HwFee/HwFee-dsh.git
cd HwFee-dsh/plugins/cds-theme
npm ci && npm run build
dsh plugin --profile desktop add link:.

版本缺失怎么办

安装渠道只支持官方 npm registry 和 GitHub Release tarball,这里不维护镜像。先确认你的 registry 指向官方源:

npm config set registry https://registry.npmjs.org

然后锁定版本安装:

dsh plugin --profile desktop add dsh-cds-theme@<version> --registry=https://registry.npmjs.org

不锁版本的 dsh plugin add <name> 仍可能装到旧版本:pnpm 会从本地状态解析 latest 标签。我们实测过,同一个官方 registry 下,pnpm view 报 0.1.10,而 pnpm add 装的是 0.1.8。market/install-all.ps1 绕开了这一步,它先向 npm 查询版本,再安装 name@version。

dsh-cds-theme@0.1.9 在 npm 上已标记为废弃:它会破坏代码字体和数学字体。请安装 0.1.10 或更新版本。

升级前有一点值得知道。插件一旦变成 npm/Release 包、不再是 link:,配置档就不再指向工作区,此时改源码、重新构建 bundle 都不会生效,除非你再用 link: 安装一次;而实体化安装会先清空 link: 指向的内容,所以如果源码还没提交推送就做这一步,工作区文件会被删掉。

字体与许可

主题带两类字体,许可条款不同:

| 以内联 data:font/woff2 形式打包 | 2 款 —— 子集化的 Source Han Sans / Serif(Noto),SIL OFL 许可,带 avar 字重校准,让中文笔画与拉丁字重档位对齐。这是包里仅有的字体字节 |
| 六款 Anthropic 字体(Sans / Serif / Mono × Roman / Italic) | 商业字体,无再分发许可:只声明为 local(),打包零字节 |
| 这意味着什么 | 装了这些字体家族时,local() 会解析到它们;没装则回退到系统字体 |
| 这六个源文件 | 已从 git 跟踪中移除,并被 .gitignore 拦截;新克隆的仓库不含它们 |
| 强制校验 | 构建会拒绝产物中的受限字节,包测试会复查已提交的 bundle 并确认这些文件仍未被跟踪,仓库审计覆盖每个产物,发布资产门禁会打开真实 tarball。字体通过 tools/font-licences.mjs 中的哈希和 96 字节前缀识别,所以四道门禁都不需要这些文件就能工作 |

此次变更之前构建的 Release 仍带八款内联字体,不会追溯修复;请安装变更之后的构建。详情和复查命令见 market/PUBLISHING.md。

安全边界

简短版,不打包票:

| 插件 | 边界 |
| genui | 卡片代码在 iframe 中运行,不带 allow-same-origin,所以它读不到宿主 DOM、localStorage 和 cookie——是真的读不到,不只是藏起来。发送需要点击宿主的确认行。这不代表模型写的代码就无害了,CSP 只覆盖文档里列出的网络 API,扩展和代理不在其内 |
| git-bash | 在 Windows 上,Git Bash 进不了宿主沙箱,所以受限会话和未确定会话在任何进程启动前就被拒绝;只有 danger-full-access 能直接运行。取消、超时和输出超限都会终止整个进程树 |
| predict | 把最近几轮对话作为普通模型请求,发给你配置的服务商 |
| usage-stats | 读取 ~/.dsh/sessions,写一份计数台账;不走网络 |

从旧版本升级

回访用户会注意到四处变化:

1. 从卡片发送要多点一次。 interact 现在会创建一条待处理请求;卡片没法自己把文本塞进对话。
2. 受限 Windows 会话里 Git Bash 会被拒绝。 以前通过它跑命令的只读会话和 workspace-write 会话,现在会收到报错,指向 Windows PowerShell。
3. 没装 Anthropic 字族的机器上,拉丁文本改用系统字体渲染,因为这些字体不再内嵌。中文不受影响:Noto 子集仍然内联。
4. 新增的字体行初始为未设置状态,显示默认值(界面字号和内联代码字号),直到你手动调整;在那之前不会有任何变化。

仓库结构

HwFee-dsh/
├── plugins/
│ ├── cds-theme/ # theme tokens + component rules
│ ├── system-fonts/ # font family and spacing rows
│ ├── usage-stats/ # local usage panel
│ ├── genui/ # render_ui cards
│ ├── predict/ # next-prompt ghost text
│ └── git-bash/ # run_shell through Git Bash
├── assets/ # screenshots used by these READMEs
├── market/ # market index, catalog entries, publish scripts
├── docs/ # evidence docs (specs, host hooks, audits)
├── patches/ # optional host patches
└── tools/audit.mjs # repo-wide static audit

每个插件目录都有自己的 npm test:先查构建是否最新,再查 manifest 契约,最后跑测试套件。总数每次修复都会变,所以看输出,别信这里写的数字。

npm run build # rebuild every plugin from the repository root
npm test # run every plugin's freshness, manifest and behaviour checks
npm run audit # unsafe DOM, observer lifecycle, token pairs and font assets
npm run verify # theme-specific checks

维护者规则见 AGENTS.md,其中包括为什么重建后的 bundle 需要完整重启应用,而不是刷新一下。
预览分享卡片长什么样 ↓HwFee/HwFee-dsh
分享 · DeepSeek Harness Hub
HwFee/HwFee-dsh

DeepSeek Harness 插件:一套 Claude Design System 主题、系统字体和一个用量面板。设计语言取自 open-claude-ui。

这是你的仓库?认领条目

回到顶部