npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-skin-alphacoders

v0.4.3

Published

DSH skin plugin: Alphacoders popular wallpapers as the DeepSeek Harness Web GUI background (gallery, search, local upload, per-theme wallpapers, favorites, auto-change, history, glass blur)

Readme

dsh-skin-alphacoders

English | 中文

License: MIT npm version GitHub Release Topic: dsh-plugin

DSH 皮肤插件:把 Alphacoders 热门壁纸 设为 DeepSeek Harness Web GUI 的背景,并支持 MoeWalls / Pexels 动态壁纸(视频背景)。符合 DSH 插件包规范的双半(Host + Client)Cordis 插件。

壁纸效果预览

设置面板

功能

静态壁纸(Alphacoders)

  • 壁纸库:设置面板新增「壁纸」分区,浏览 Alphacoders 热门壁纸(每页 15 张、可翻页、懒加载)。
  • 搜索:按关键词搜索壁纸(走 Alphacoders 官方搜索页,单页最多 30 条);清除搜索恢复热门列表。
  • 一键应用:点击缩略图即应用为背景;只有页面骨架(应用框架、对话区、侧边栏)经主题 token 半透明化透出壁纸;所有凸起表面保持不透明(--dsw-alias-bg-layer-1/2/3 沿用产品原生值)——卡片、输入框、菜单、弹窗与「修改文件」悬浮预览的文字对比度与默认界面一致,不会与壁纸混在一起。

动态壁纸(视频背景,v3)

  • MoeWalls / DesktopHut 双源:动态壁纸 tab 内可切换两个视频源;分类/搜索/分页浏览缩略图。
  • 下载制(v3.4):点击缩略图跳转原站(moewalls.com / desktophut.com)下载视频文件,再通过「上传本地图片/视频」设为动态壁纸——插件不做在线流式播放,避免被原站限流拖慢。
  • 本地上传视频(v3.4):支持 PNG/JPEG/WebP/GIF 图片与 WebM/MP4 视频;视频作为动态壁纸循环播放,文件存于 $DSH_HOME/storages/skin-alphacoders/,重启后恢复;上限 200MB。
  • 无缝循环(v3.3):双 <video> 接力 + 瞬时切换(无交叉淡化),循环无停顿、无暗亮闪,效果接近 Wallpaper Engine;毛玻璃/遮罩/淡入同样作用于视频层。

视觉与显示

  • 毛玻璃(v3):0~30px 背景模糊,只作用于壁纸层——界面与文字在其上层保持清晰。
  • Ken Burns 微动效(v3.1):静态壁纸缓慢缩放平移,背景不再死板。
  • 渐变分层遮罩(v3.1):边缘压暗 + 中间半透 + 柔光暗角 + 品牌光晕,由单一遮罩滑条驱动;浅色主题白雾、深色主题黑雾,跟随 DSH 主题(light/dark/system)。
  • 换壁纸淡入(v3.1):新壁纸 0.8s 淡入,滑条/主题切换不会闪屏。
  • 显示控制:四种填充方式(铺满/完整/居中/拉伸)与 0~90% 遮罩强度。

其他(v2)

  • 浅深双主题壁纸:浅色与深色主题各保存一张壁纸,切换明暗自动跟随。
  • 收藏:画廊卡片右上角 ☆ 一键收藏,持久化于 user-data.json,点击收藏卡即应用。
  • 自动更换:定时自动换壁纸——随机(远程新鲜壁纸)/顺序(按收藏顺序轮换)/仅收藏(收藏中随机),另有「立即换一张」按钮;间隔 1~168 小时可调。
  • 历史记录(v3.1):应用过的壁纸自动记录(最多 5 条,重复应用自动去重移顶),一键恢复旧壁纸。
  • 持久化:偏好存于插件自有文档 $DSH_HOME/storages/skin-alphacoders/settings.json(DSH 0.2 移除了 0.4.2 所用的插件 settings 服务),原子写入;收藏与历史存于同目录 user-data.json。从 ≤0.4.2 升级不会迁移旧的 settings.yaml 分节,升级后重新选一次壁纸即可。
  • 性能:背景默认使用 1920px 变体(thumb-1920-<id>),不下载 5K/8K 原图;列表/搜索/动态壁纸均有内存 TTL 缓存。
  • 干净卸载:移除插件行后 route、调度器、样式全部消失,GUI 恢复默认外观。

安装

方式一:npm 安装(推荐)

# 安装到 web profile(含构建产物,无需本地构建)
dsh plugin --profile web add dsh-skin-alphacoders

方式二:从源码构建安装

# 1. 构建本包(生成 lib/ 产物)
pnpm install && pnpm build   # 或 npm install && npm run build

# 2. 安装进 web profile(从本包所在目录的上级执行)
dsh plugin --profile web add "file:<本包绝对路径>"

两种方式都需在 $DSH_HOME/profiles/web/cordis.patch.yml 中登记插件行:

# $DSH_HOME/profiles/web/cordis.patch.yml
- insert:
    - id: skin-alphacoders
      name: 'dsh-skin-alphacoders'
      config:
        cacheTtlMs: 3600000      # 可选:列表缓存 TTL(毫秒)
        requestTimeoutMs: 20000  # 可选:抓取超时(毫秒)
        localMaxBytes: 209715200 # 可选:本地上传上限(字节,默认 200MB)

重启 dsh web 生效;设置面板 → 「壁纸」分区即可使用。

提示:开发迭代时,可用目录联接把 profile 的 node_modules/dsh-skin-alphacoders 指向源码目录(pnpm 的 file: 依赖默认硬链接复制,修改源码后需要重建联接或重新 add)。

架构

┌─ Host 半(node)─────────────────────────────────────────────┐
│  alphacoders:fetch + 解析 popular-wallpapers?page=N         │
│  (服务端渲染的 schema.org ImageObject,15 条/页)            │
│  moewalls(v3):REST 列表/分类 → Chrome 抓取降级 → HTML 页   │
│  详情按页面 URL 解析;视频经本地代理 + 磁盘缓存(LRU 10)     │
│  desktophut(v3.5):Node 直抓首页/分类/搜索页,         │
│  wallpaper-card 卡片解析(缩略图兼容 /images 与 /img,     │
│  首页解析为空时回退 /popular-live-wallpapers);视频走      │
│  原站下载制(播放需本地上传)                              │
│  内存 TTL 缓存(列表 6h、详情 6h、分类 24h)                 │
│  settings.json 自有文档(原子写 + 串行写队列)               │
│  user-data.json(收藏 ≤200、历史 ≤5,原子写入)              │
│  自动更换调度器(setTimeout 链,按模式选池)                 │
│  HTTP route(经 ctx.webServer):                            │
│    GET  /skin-alphacoders/wallpapers?page=N | ?query=Q       │
│    GET  /skin-alphacoders/moewalls/{categories,list,detail,video} │
│    GET  /skin-alphacoders/desktophut/list                    │
│    GET  /skin-alphacoders/settings | POST(字段白名单 patch)│
│    GET  /skin-alphacoders/user-data                          │
│    POST /skin-alphacoders/favorites(+ /favorites/remove)   │
│    POST /skin-alphacoders/history/remove                     │
│    POST /skin-alphacoders/theme / auto-change/now            │
│    POST /skin-alphacoders/local(图片/视频上传)              │
│    GET  /skin-alphacoders/health                             │
└──────────────────────────────────────────────────────────────┘
        同源 fetch(无 CORS 面)
┌─ Client 半(浏览器)─────────────────────────────────────────┐
│  skin-store:GET/POST settings route 的本地快照 + 订阅        │
│  user-data store:收藏/历史快照                              │
│  双主题镜像:theme/change 时把当前主题槽同步到扁平字段         │
│              (带 fromTheme 标记,不产生历史记录)            │
│  background:body::before 壁纸层 + ::after 渐变遮罩层         │
│              + 视频接力层(双 <video> 瞬时切换,无暗亮闪)    │
│              + ctx.theme.overrideTokens 表面半透明            │
│              (签名去重防 theme/change 重入风暴)             │
│  settings.section「壁纸」:静态库 + 动态库 + 上传 + 收藏      │
│  + 历史 + 自动换 + 主题 tab                                  │
└──────────────────────────────────────────────────────────────┘

为什么由插件自己持有设置文档

api-proxy 的 settings 协议是 Host 白名单(locale、ui-theme 等),仓库外插件注册的 namespace 只会得到 settings-not-exposed;DSH 0.2 又进一步移除了插件侧的 settings 服务(ctx.settings.register / SettingsScope 已不存在)。因此 Host 侧改为自持一份普通文档 $DSH_HOME/storages/skin-alphacoders/settings.json(promise 队列串行 + 临时文件原子替换),浏览器侧仍只经插件自己的 HTTP route 读写。0.4.2 写在 $DSH_HOME/settings.yaml 的 ui-skin 分节不会迁移。

配置

| 字段 | 默认 | 说明 | |---|---|---| | cacheTtlMs | 3600000 | 壁纸列表页内存缓存时长(毫秒) | | requestTimeoutMs | 20000 | 抓取远程站点的超时(毫秒) | | localMaxBytes | 209715200 | 本地上传(图片/视频)大小上限(字节) |

版权与合规

  • 壁纸版权归原作者与 Alphacoders / MoeWalls / DesktopHut 所有;本插件仅供个人使用,不批量下载或再分发壁纸。
  • 请在网络策略允许访问上述站点与其图片/视频 CDN 的环境中使用。

验证

e2e/verify.mjs 是 Puppeteer(连接本机 Chrome)端到端验证:需先按上述步骤装好插件并启动 dsh --profile web --port 3090(测试实例可用 E2E_URL 环境变量覆盖端口),再执行:

node e2e/verify.mjs

覆盖(70 项断言):画廊渲染、收藏往返、双主题独立壁纸、明暗联动、刷新持久化、历史恢复(含去重)、自动更换、毛玻璃/滤镜增强/Ken Burns/渐变遮罩、搜索、动态壁纸列表/分页/跳转原站、本地上传(图片与视频)、动态壁纸无缝接力、本地壁纸清理、收藏/历史持久化、无页面错误。

另有三个数据源脚本:e2e/bench-desktophut.mjs(抓取层,直打真实站点)、e2e/verify-live-sources-ui.mjs(UI 层,覆盖静态壁纸 / MoeWalls / DesktopHut 三个源,需 E2E_PAGE_URL 指向带 token 的实例)、e2e/net-probe-alt-sites.mjs(源站连通性)。

DesktopHut 壁纸数为 0 的排查顺序

DesktopHut 的列表来自服务端渲染的 HTML,站点改版会让解析静默失败——不报错,只是列表为空。按抓取层 → Host 路由层 → UI 层依次排查:

# 1) 抓取层(直接打真实站点,不需要启动实例;失败时退出码为 1)
node e2e/bench-desktophut.mjs
#    期望:ALL PASS,其中 “all (cat="") p1” 的 items ≥ 3

# 2) Host 路由层(PowerShell;items 不能是空数组)
Invoke-RestMethod "http://127.0.0.1:3080/skin-alphacoders/desktophut/list?page=1" | ConvertTo-Json -Depth 3
Invoke-RestMethod "http://127.0.0.1:3080/skin-alphacoders/desktophut/list?cat=anime-live-wallpapers&page=1" | ConvertTo-Json -Depth 3

# 3) 分类 slug 是否还有效(失效 slug 返回 404 → 该分类为空)
Invoke-WebRequest "https://www.desktophut.com/category/<slug>/" -Method Head -UseBasicParsing | Select-Object StatusCode

# 4) UI 层(需要带 token 的实例地址;断言三个源网格非空、缩略图无需滚动即全部加载,并截图)
$env:E2E_PAGE_URL='http://127.0.0.1:3090/?token=<token>'
node e2e/verify-live-sources-ui.mjs

排查要点:

  • 默认「全部」页签走的是站点首页 https://www.desktophut.com。站点会不定时改版(2026-09-25 就把首页缩略图从 /images/… 换成了 /img/<W>x<H>/…),解析规则已同时兼容两种路径;若首页再次改版导致解析为空,会自动回退到 /popular-live-wallpapers。
  • 分类 slug 会被站点改名且不做跳转。当前表在 src/fetch-desktophut.ts 的 DESKTOPHUT_CATEGORIES(Host 校验与 UI 下拉共用同一份)。要重新同步,从 https://www.desktophut.com/show/all-categories 里读取 /category/<slug> 链接,并用上面的 bench 脚本逐个验证非空。
  • 空结果不再进缓存:列表在内存里有 1 小时 TTL 缓存(cacheTtlMs),但从 v3.5.1 起空页不写缓存,所以「本页没有壁纸」时点一次重试就会真正重新抓取。改了 Host 代码后仍需重启 Host;重启后浏览器再硬刷新一次(client 半也更新了)。
  • 切换到动态源几乎是瞬时的:进入「壁纸」分区时,插件会并行预热 MoeWalls 与 DesktopHut 的第一页(Host 端按页缓存并合并并发请求),因此首次切换不再付冷抓成本;预热失败不影响任何源的正常加载。