DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

inju0524 /

inju0524/dsh-inju-boot

Verified

给 DeepSeek Harness 装一支开机动画:每次启动全屏播放 WebGL2 实时粒子动画(花 → 月球 → 虚影文字 → 实体 LOGO),带极客 HUD / 终端层与程序化音效,全部参数可在设置里调。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@872c9c65
INJU 启动动画

dsh-inju-boot · INJU 启动动画

给 DeepSeek Harness 装一支开机动画。 每次启动 Harness,全屏播放一支 WebGL2 实时粒子动画 —— 花 → 月球 → 虚影文字 → 实体 LOGO, 带一套极客 HUD / 终端层和 Apple 发布会式的程序化音效,播完自动淡出把界面交还给你。

test license node dependencies

快速开始 · 设置项 · 工作原理 · 自检 · 排障 · English

INJU 启动动画 · 10 个阶段
6.3 秒走完全部 10 个阶段(每段约 0.6 秒,硬切)· 720×405 · 4 MB

十个环节

# 阶段 时间 画面
01 汇聚 0 – 3.2s 星尘云团被吸聚成一朵参数化 3D 雏菊(花瓣 / 花心 / 花托 / 花茎 / 地面亮点)
02 花体 · 环绕巡游 3.2 – 5.8s 相机缓慢环绕,花瓣层次与花茎前后关系都看得到
03 崩解 5.8 – 7.3s 每颗粒子沿花心向外爆散,带湍流冲量与惯性拖尾
04 重聚 7.3 – 9.3s 回吸聚合成一颗 3D 粒子月球(撞击坑 / 月海 / 山脉)
05 月球 · 静默自转 9.3 – 11.7s 坑谷环脊在光照下缓缓转出
06 显影 11.7 – 14.4s 月球 → 虚影文字,粒子变细、变弥散、开始抖动
07 虚影 · 闪烁漂移 14.4 – 15.7s 全息虚影闪烁、漂浮
08 像素偏移闪切 15.7 – 16.45s 28 条横向切片错位 + 13×11 块状位移 + RGB 分离 + 过曝闪白
09 实体 · 平面 LOGO 16.45 – 20.05s 硬切为实体平面 LOGO,带扫光;残留粒子成为光晕
10 循环 · 淡出 20.05 – 21.05s 淡出并重新开始

全部 10 个阶段的时长、手感、每阶段的粒子尺寸 / 抖动 / 爆散冲量 / 体积光都能在设置页调; 上面这张表读的就是动画目录那份 inju.config.js。


这是什么

一个 DeepSeek Harness 插件(bundle),给 Web 界面加两样东西:

启动覆盖层 挂在 shell.overlay,页面一加载就全屏播放动画,播到设定位置后淡出
设置页 挂在 settings.section,与宿主其它设置页并排,动画的一切参数都在这里调

动画本体是一支零依赖的单文件 WebGL2 作品:6 万颗自发光粒子、10 个阶段、程序化生成的 3D 雏菊 / 粒子月球 / 虚影文字 / 实体 LOGO,外加一层画在画布内、会跟着一起吃泛光与像素偏移闪切的 极客 HUD(数字雨、跟随主体的目标框、扫描线、实时点云小图、终端日志、遥测、hex dump)。

它还带了 DeepSeek Harness 的产品身份层:顶部逐字拉开的 DEEPSEEK HARNESS 铭牌、 左上角的 root@deepseek-harness:~# dsh --profile desktop、遥测里的 MODEL / RUNTIME 字段、 以及一整套 DSH 启动序列的终端日志。

花体阶段(完整分辨率) 实体 LOGO 阶段(完整分辨率)
完整分辨率静帧:第 02 阶段 · 花体环绕巡游  |  第 09 阶段 · 实体平面 LOGO

它还带了 DeepSeek Harness 的产品身份层:顶部逐字拉开的 DEEPSEEK HARNESS 铭牌、 左上角的 root@deepseek-harness:~# dsh --profile desktop、遥测里的 MODEL / RUNTIME 字段、 以及一整套 DSH 启动序列的终端日志。

y=  27  root@deepseek-harness:~# dsh --profile desktop          PHASE   2 / 10  花体 · 环绕巡游
y=  29                    D E E P S E E K   H A R N E S S
y=  55  [ok] cordis composition online · sandbox: workspace-local          2.00 / 21.05 s
y=  63        agent runtime · cordis composition · profile desktop
y=  83  [!!] approval: never · telemetry: local · sig 0x000E              60,000
y= 194  MODEL    deepseek-v4.1-flash
y= 222  RUNTIME  dsh 0.1.7 · node 22
y= 296  TARGET FLOWER · LOCKED
y= 804  [boot]  deepseek-harness 0.1.7 :: profile desktop
y= 935  [███░░░░░░░░░░░░░░░░░░░░░░░] 10%  DEEPSEEK HARNESS

上面是 node tools/check-animation.mjs --dump 打出来的真实绘制调用(1920×1080,t=2.0s)。 想看你自己屏幕尺寸下的排版:node tools/check-animation.mjs --dump --w=1440 --h=900 --t=9.5

预览图 / 动图是怎么来的(想自己重新生成的话)

动画自带静帧模式:?t=<秒> 定格在指定时刻并暂停,hud=0 隐藏页面 DOM 装饰、telemetry=1 保留极客 HUD。 插件把动画挂在 /api/inju-boot/boot.html,所以只要 Harness 在跑,直接用浏览器打开这个地址就能截图:

http://127.0.0.1:19387/api/inju-boot/boot.html?t=4.0&hud=0&telemetry=1     # 花体阶段
http://127.0.0.1:19387/api/inju-boot/boot.html?t=10.5&hud=0&telemetry=1    # 月球阶段
http://127.0.0.1:19387/api/inju-boot/boot.html?t=17.6&hud=0&telemetry=1    # 实体 LOGO

两张静帧就是这样抓的:headless Edge + CDP,等 90 帧后 Page.captureScreenshot,再转成 WebP(1920×1080,共 240 KB)。

hero 动图是 10 段拼起来的:动画本体暴露了确定性单帧驱动 window.__render.set(t), 所以可以对每个阶段钉住播放头、各取 5 帧(段内连续、段间硬切),再交给 ffmpeg:

ffmpeg -framerate 8 -i frames/f_%04d.png -vf "scale=720:-1:flags=lanczos,split[a][b];\
[a]palettegen=max_colors=64:stats_mode=diff[p];[b][p]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle" \
  -loop 0 docs/preview-stages.gif

三个踩过的坑,省得下次再走一遍:

  1. headless 下别加 --disable-frame-rate-limit --disable-gpu-vsync。 那两个开关会让 requestAnimationFrame 的 dt 趋近 0,而 HUD 每 1/30 秒才重绘一次 —— 结果截到一张没有 HUD 的干净画面。 (用注入钩子数过 fillText:4 次 vs 去掉开关后的 10534 次。)
  2. GIF 对这个画面极其不友好。 每颗粒子每帧都在动,等于每帧都是全帧更新。 实测 800×450 / 90 帧 是 16 MB;把动画自带的 render.grain(每像素胶片噪点)临时关掉后直接降到 7.5 MB。 粒子数与数字雨开关几乎不影响体积(5.1 MB vs 5.1 MB),真正决定体积的只有分辨率 × 帧数。
  3. ffmpeg 在这台机器上写不了 %TEMP%(Permission denied),输出直接落仓库目录里就行。

快速开始

安装

方式 A:交给 Harness 自己装(推荐)

让 Harness 里的 Agent 调用 plugin_manager:

plugin_manager action=install_bundle target=<这个仓库的绝对路径>

它会替你写 profile 的 package.json / cordis.patch.yml 并完成安装 —— 不要手改那两个文件。

方式 B:dsh CLI

dsh --profile <你的 profile> plugin add "file:<这个仓库的绝对路径>"
# 或直接从 GitHub 装:
dsh --profile <你的 profile> plugin add "github:inju0524/dsh-inju-boot"

装完重启一次 Harness(新增 bundle 需要重新组装 profile)。下一次启动就会看到动画。

卸载:plugin_manager action=remove_bundle target=dsh-inju-boot 只是不想看了:设置页关掉「启用启动动画」,或在 cordis.patch.yml 里给这一行加 disabled: true。

动画从哪来

插件按这个顺序找动画:

  1. 设置页里显式填的「动画目录」(填到含 inju-particles.html 的目录)
  2. 插件的上一级目录 —— 把这个插件文件夹放进你自己的动画项目里,它就用那份活的动画, 你在 inju.config.js 里改一个数字,刷新页面就生效
  3. 插件自带的 assets/ 副本 —— 独立 clone 出来时用这份,保证任何机器上都能播

设置项

设置 → INJU 启动动画。

分组 项 说明
播放 启用启动动画 总开关
每次启动只播一次 会话级去重,开发时热重载不会反复重播
时长倍率 等比拉伸整条时间轴(>1 更慢)
结束阶段 播到第几个阶段末尾就淡出(默认播完整个循环)
淡出时长 结束时的淡出毫秒数
背景音乐 背景音乐 / 音效 是否播放背景音乐。关掉时连引擎都不加载(?audio=0)
背景音乐音量 0~1,覆盖动画配置里的 audio.master
首次点击只解锁声音 默认开。第一次点击/按键只用来出声,不中断动画
自动播放被拦下时提示 只在浏览器确实拦下自动播放时才出现
跳过 点击中断动画 是否允许点击中断动画
按键中断动画 是否允许按键中断动画(Esc 始终可跳过)
显示跳过按钮 / 按钮文字 右下角的跳过按钮
画面 LOGO / 虚影文字 虚影文字与最终实体 LOGO 都用它
粒子数量 1000 ~ 400000
粒子尺寸 / 粒子亮度 / 泛光强度 / 机距 直通动画的 size / intensity / bloom / dist
极客 HUD / 终端层 可选,默认开启。DSH 铭牌与启动命令行 + 数字雨 + 目标框 + 扫描线 + 点云小图 + 终端日志 + 遥测 + hex dump
模式 flower3d 程序化 3D 雏菊 / photo 照片粒子化
窗口顶栏 顶栏融入动画 默认开启。仅 Windows 桌面端:让最小化/最大化/关闭背后的标题栏背景变透明
隐藏「应用 / 编辑」菜单 默认开启。仅 Windows 桌面端:动画期间隐藏 Desktop 注入的菜单条,播完恢复
高级 动画目录 留空 = 自动探测
HUD 终端台词 一行一条 秒 文本;{text} 会换成真正的 LOGO 文字
inju.config.js 覆盖 一段 JSON,深度合并到动画目录那份 inju.config.js 之上

配置落在 <DSH_HOME>/inju-boot/config.json(默认 ~/.dsh/inju-boot/config.json), cordis.patch.yml 里那一行的 config 是出厂种子。三层优先级: 内置默认值 ← YAML 种子 ← config.json(设置页写这里)。

「inju.config.js 覆盖」能改什么

动画配置的全部字段,键名与 inju.config.js 完全一致:

{
  "camera": { "orbitYaw": 0.6, "dist": 20 },
  "moon":   { "radius": 2.6, "craters": 110 },
  "flower": { "layers": [ { "n": 40, "len": 2.4 } ] },
  "render": { "bloom": 1.2, "exposure": 1.1 },
  "hud":    { "brand": { "title": "MY HARNESS", "subtitle": "我的启动序列" } },
  "stages": [ { "dur": 3.2 }, { "dur": 4.0 } ]
}

stages 数组按下标合并,只写想改的那几项就够了。


工作原理

一、动画托管:原文件一个字节都不改

inju-particles.html 里 <script src="inju.config.js"> 是相对路径,所以当 Host 把动画挂在 /api/inju-boot/boot.html 时,浏览器会去取 /api/inju-boot/inju.config.js —— 而这条路由返回的是 运行时合成的配置:

动画目录的 inju.config.js   ←   插件 advanced 覆盖   ←   时间轴倍率

Host 用 node:vm 在沙箱里取出动画目录那份配置对象(纯字面量,无副作用),深合并后序列化成 window.INJU_CONFIG = {...}。所以你既可以直接改项目里的 inju.config.js,也可以在设置页叠加覆盖, 互不打架。动画本体和它的配置都是按请求现读的,改完刷新页面即生效,不用重启 Harness。

Host 半身在 ctx.inject(['webServer'], …) 里注册 7 条 exact 路由,全部挂在 ctx.effect 上,卸载即回收:

路由 作用
GET/POST /api/inju-boot/config 读 / 写配置(replace: true 整份替换,reset: true 回出厂)
GET /api/inju-boot/boot.html 动画本体(原文件原样吐出,供覆盖层 iframe 使用)
GET /api/inju-boot/inju.config.js 运行时合成的 window.INJU_CONFIG
GET /api/inju-boot/inju-audio.js 音效引擎
GET /api/inju-boot/inju-particles.html 原文件(想单独打开看的时候用)
GET /api/inju-boot/asset?name=… 动画目录里的其它资源(白名单扩展名 + 拒绝任何跨目录/绝对路径)
GET /api/inju-boot/preview-url 覆盖层 iframe 的查询串

二、背景音乐怎么做到自动播放

「必须点一下才有声音,但一点动画就没了」是两个原因叠在一起:

  1. 动画的音频引擎不会自己启动。 inju-audio.js 的 init()(里面才 new AudioContext()) 只从 unlock() 调用,而 unlock() 只挂在动画自己窗口的首次 pointerdown/keydown 上。 所以哪怕浏览器策略再宽松,没人推它一把它也永远不出声。
  2. 那一下点击同时又命中了跳过规则,动画当场结束。

覆盖层的解法:

  1. 主动解锁。 iframe 与宿主同源,覆盖层在 iframe 的 load 事件里直接调用 iframe.contentWindow.INJU_AUDIO.unlock()。DSH Desktop 是 Electron,默认 autoplayPolicy = no-user-gesture-required,所以这一步之后不需要任何点击,音乐直接响。
  2. 第一次手势只解锁声音。 普通浏览器会把 AudioContext 挂起,这时必须有一次真实手势。 开启「首次点击只解锁声音」后,第一次点击/按键被吃掉(只用来出声),动画继续播; 从第二次起才按「点击中断动画 / 按键中断动画」走。
  3. 只在真的被拦下时才提示。 覆盖层新建一个 AudioContext 探它是 running 还是 suspended (自动播放策略按顶层文档判定,同源 iframe 与之共享),只有 suspended 才在底部显示 「点一下画面开启声音(这次点击不会中断动画)」。
  4. 每次手势都会再推一次 unlock()(幂等),所以引擎晚一点就绪也接得上。

三、Windows 顶栏:为什么它一开始会「压」在动画上

这不是调大 z-index 能解决的 —— 两处漏点各有各的原因:

① 左上角「应用 / 编辑」菜单条(DOM)。 Desktop 的 preload 往 body 上注入了一个 div[data-windows-menu](内含 shadow root), position: fixed; z-index: 1100。而 shell.overlay 的条目渲染在 .BynINW_overlayLayer{position: absolute; z-index: 20} 里 —— 那是一个层叠上下文, 所以覆盖层写多大的 z-index 都只在 20 这一层里有效,必然被 1100 压住。 → 解法:动画期间 display: none 掉它,播完移除样式自动恢复。

② 右上角最小化 / 最大化 / 关闭(原生 Window Controls Overlay)。 这三个按钮由 Chromium 画在网页内容之上,CSS 碰不到按钮本身。但它们的背景色是可变的: preload 里有个探针元素用 background-color: var(--dsw-specific-sidebar-fill) 量出色值, 再经 windowsAppearance IPC 调 mainWindow.setTitleBarOverlay()。而主进程的校验是 /^(?:#[\da-f]{3,8}|rgba?\([\d.,%\s]+\))$/ —— 8 位 hex 和 rgba 都接受。 → 解法:动画期间把 --dsw-specific-sidebar-fill 置为 transparent,原生顶栏背景就变成 rgba(0, 0, 0, 0),动画从三个按钮后面透出来;DOM 里那条 40px 标题栏 (.BynINW_frame::before)用的是同一个变量,一起透明。顺带把 --dsw-alias-label-primary (原生按钮的符号色)按覆盖层底色算成亮/暗,保证按钮在动画上看得清。

这个 <style> 必须挂在 document.head:preload 的 MutationObserver 只观察 head 的 childList/subtree,挂在别处不会触发它重新量色。它是本插件唯一一次「组件之外的 DOM 写入」, 所以每条退出路径(正常播完 / 超时 / 卡住 / 组件卸载)都会把它移除,不会留下一个透明顶栏。

四、覆盖层怎么知道「播完了」

它不去猜时长,而是读动画自己的进度条 #scrub —— 那是动画公开的播放头 (value = T/TOTAL*1000)。总时长来自 Host 算好的 resolved.stages,所以「结束阶段」选到第几秒是精确的。 另外还有三层兜底:文档 8 秒没起来、进度一直停在 0 超过 20 秒、以及 maxDurationMs 硬上限 —— 任何意外都不会让覆盖层永久挡住界面。

为什么用 iframe:动画本身是一支自带全局 CSS(html,body{overflow:hidden})和 WebGL2 上下文的独立作品,直接塞进 React 树会污染宿主页面的全局样式。iframe 把它隔离成一个独立 artwork 文档。设置页则是纯 React + --dsw-alias-* 主题令牌,与宿主其它设置页同构。


自检

零依赖,不需要 Harness、不需要浏览器(CI 也跑这三套):

npm test                        # 三套一起跑
node tools/selftest.mjs         # Host 半身:84 项
node tools/selftest-client.mjs  # 浏览器半身:62 项
node tools/check-animation.mjs  # 动画本体:38 项
node tools/check-animation.mjs --dump --w=1440 --h=900 --t=9.5   # 打出 HUD 排版
套件 验什么
selftest.mjs 起一个真 http 服务跑 7 条路由:配置读 / 写 / 整份替换 / 复位、路径穿越防护、越界输入收敛、动画目录解析、inju.config.js 合成、身份层下发
selftest-client.mjs 把 client.js 当真正的 bundle 加载:ModuleLoader 契约、插槽注册、音频桥、首次手势策略、顶栏处理、源码卫生(只允许主题令牌、不 import 宿主 Client 包、不往 body 追加节点)
check-animation.mjs 内联脚本语法;把 hudDraw() 抽出来配一个会记账的假 2D 上下文真跑一遍,断言铭牌/命令行/遥测字段/进度条产品名/DSH 日志真的被画出来、标题居中且带字距、1920/1280/640 三种宽度下都不越界

在线(对着正在运行的 Harness 打真实请求):

node tools/selftest-live.mjs                    # 默认 http://127.0.0.1:19387
node tools/selftest-live.mjs http://127.0.0.1:19387

40 项:Host 路由在线、动画本体与音效可被浏览器取到、服务出去的 inju.config.js 能真的跑出 window.INJU_CONFIG 且合并正确、极客 HUD 与音频开关都真的接通了、bundle 解析链、profile 的 bundles 列表。

tools/ 里还有三个只读的 asar 工具,用来翻 DSH 自带文档与源码(这个插件的顶栏那一段就是靠它们查出来的):

node tools/asar-list.mjs    "<...>/resources/app.asar" windows-titlebar
node tools/asar-extract.mjs "<...>/resources/app.asar" "lib/preload-app.cjs" ./out
node tools/asar-grep.mjs    "<...>/resources/app.asar" "app-region" --ext .js

排障

现象 原因 / 处理
启动没动画 设置页看「当前生效」那一行:✗ 表示没找到动画目录,把「动画目录」填成含 inju-particles.html 的目录
设置页打不开 / 列表里没有入口 Host 半身没挂上:确认 profile 的 dsh.profile.bundles 里有 dsh-inju-boot,然后重启 Harness
画面干净但没有极客 HUD 「极客 HUD / 终端层」被关掉了(默认开),打开它
想开 HUD 但看不到台词 台词在「HUD 终端台词」里,逐行 秒 文本;清空就不显示日志
完全没有声音 ①「背景音乐」是不是被关了;② 音量是不是拉到 0;③ 普通浏览器下需要先有一次点击(第一次点击只解锁声音、不会中断动画,覆盖层会在底部提示你);④ 桌面端正常应自动出声
点一下就中断了动画 关掉「点击中断动画」;若想保留它又要点一下出声,确认「首次点击只解锁声音」是开的
左上角「应用 / 编辑」压在动画上 开「隐藏「应用 / 编辑」菜单」
右上角三个按钮背后有一条色带 开「顶栏融入动画」。若无效,可能是自定义主题绕过了 --dsw-specific-sidebar-fill
动画结束后顶栏颜色没还原 不该发生;插件在播完 / 超时 / 卸载时都会移除那个 <style>。真遇到刷新页面即可
动画在播但界面被挡住很久 把「结束阶段」调到 09,或把「时长倍率」调小;Esc / 点击 / 任意键都能跳过
想把铭牌换成自己的 「inju.config.js 覆盖」里写 {"hud":{"brand":{"title":"…","subtitle":"…"},"shell":"…"}}
想改回出厂 设置页「恢复出厂默认」,或删掉 <DSH_HOME>/inju-boot/config.json

目录

dsh-inju-boot/
├── package.json            # 包清单:dsh.bundle.patch + dsh.client(platform=web, immediately)
├── cordis.patch.yml        # profile 层:insert 一行把 Host 半身挂上去(config 是出厂种子)
├── index.js                # Host 半身:配置 + /api/inju-boot/* 路由(零依赖,只用 node: 内建模块)
├── client.js               # 浏览器半身:启动覆盖层(音频桥 / 顶栏处理)+ 设置页(手写 ModuleLoader bundle)
├── icon.svg                # 插件图标
├── locale/{zh,en}.json     # 展示文案
├── docs/                   # README 的 hero 动图(10 阶段蒙太奇)+ 两张静帧
├── assets/                 # 动画副本(独立 clone 时的兜底;放在动画项目里则走项目那份)
├── tools/                  # 三套自检 + 三个只读 asar 工具
└── .github/workflows/      # CI:push / PR 自动跑三套自检

依赖与兼容

  • 零运行时依赖:Host 半身只用 node: 内建模块;浏览器半身只用 shell 已经提供的 react。 不 import 任何 @deepseek-ai/* 运行时包 —— 那一层 API 面会漂移,能不依赖就不依赖。
  • 插件挂载用 ctx.inject(['webServer'], …),插槽用 ctx.slots.inject(...)(等插槽出现才注册), 所以宿主缺这些能力时是安静地不激活,而不是启动报错。
  • 顶栏那两项只在 Windows 桌面端有效(靠 preload 打的 data-windows-titlebar 标记); macOS 的窗口本来就透明,浏览器里根本没有这些元素,开了也是空操作。

验证边界(说实话)

三套离线自检 + 一套在线自检共 224 项断言,覆盖的是契约与绘制调用,不是截图。 动画那一套会把真正的 hudDraw() 抽出来、配一个会记账的假 2D 上下文跑一遍, 断言每个元素真的被画了出来、位置与居中对不对、窄窗口会不会越界 —— 这是没有浏览器时能拿到的最强证据。 但字体的真实字宽与假上下文的估算(0.6em)可能有几个百分点出入, 所以 640px 那种极限宽度下「缩字号 vs 不画」的边界可能略有偏移(两侧预留是按实测宽度算的,不会重叠)。


素材与许可

  • 代码:MIT © inju0524
  • 动画本体(inju-particles.html / inju-audio.js / inju.config.js)与内嵌照片(assets/flower.jpg) 为本项目自有素材,随本仓库一并以 MIT 分发;照片请勿单独转载。

English

dsh-inju-boot is a DeepSeek Harness plugin that plays a full-screen WebGL2 particle startup animation every time Harness launches — a procedural 3D daisy blooms, collapses into a particle moon, resolves into ghost text and snaps into a solid logo, with a geek HUD/terminal layer (digital rain, target lock box, scanline, live point cloud, terminal log, telemetry, hex dump) and a programmatically synthesised Apple-keynote-style soundtrack. The hero GIF above walks through all ten stages in 6.3 s.

  • Zero dependencies. The Host half uses only node: built-ins; the browser half only uses the react the shell already provides. No @deepseek-ai/* runtime imports.
  • Everything is configurable in Settings → INJU 启动动画: text, particle count, size, bloom, brightness, camera distance, playback speed, end stage, fade-out, skip behaviour, background music and volume, HUD on/off, the DSH nameplate / terminal lines, and a free-form deep-merge override of the animation's own inju.config.js.
  • The animation file is never modified. The Host composes window.INJU_CONFIG at request time by merging the animation project's own config with your overrides.
  • Background music autoplays on the desktop app: the overlay proactively calls the animation's INJU_AUDIO.unlock() (the engine only builds its AudioContext there). The first click/keypress is consumed to unlock audio and no longer dismisses the animation.
  • The Windows titlebar blends into the animation. The native min/max/close background colour is driven by --dsw-specific-sidebar-fill (the preload probes it and pushes it over IPC to setTitleBarOverlay), so the plugin sets it to transparent while playing; the injected Application / Edit menu bar (div[data-windows-menu], z-index: 1100) is hidden for the duration.
# install (let the Harness agent do it):
plugin_manager action=install_bundle target=<absolute path to this repo>
# or with the CLI:
dsh --profile <profile> plugin add "github:inju0524/dsh-inju-boot"

Then restart Harness. Tests need neither Harness nor a browser: npm test runs 184 assertions across three suites, and node tools/check-animation.mjs --dump prints the real HUD draw calls as a layout map.

—/ 5

No ratings yet

Verified DSH bundle

Commit 872c9c659f68

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout