dsh-skin-install

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

dsh-deep-whale 皮肤安装与切换

dsh-deep-whale Skin Installation and Switching

目标:让 DSH Web 皮肤快速且可恢复地生效。切换和已安装 link 的代码更新走热加载;初次新增包才重启;更新与指定提交测试只在用户要求时发生。
本技能只给流程指导,具体事实以现场读取为准:仓库会更新(新增皮肤、改署名链),不要依赖本文件或记忆中的清单,实时读取。
Objective: Make DSH Web skins take effect quickly and recoverably. Switching and code updates for installed links use hot loading; restart only when adding a new package for the first time; updates and specified commit tests only occur when requested by the user.
This skill only provides process guidance; refer to real-time on-site information for specific facts: The repository will be updated (new skins added, attribution chain modified), do not rely on this document or memorized lists, read in real time.

先判断场景(决定走哪条路)

First Determine the Scenario (Decide Which Path to Take)

先查当前 dsh 环境:
dsh plugin --profile <name> list
(实际 profile 名如 web;本地路径安装显示为
link:
)。按目标皮肤的
package
名核对是否已安装,并确认本地是否有该仓库的 clone:
  • 已安装(link: 依赖)→ 场景 A 切换:直接热切换,不 clone、不提问、不介绍。
  • 未安装但本地已有仓库 clone → 场景 B 初次安装(本地仓库):直接用现有 clone,绝不重新下载。
  • 未安装且本地无 clone → 场景 B 初次安装(需克隆):此时才
    git clone
  • 用户明确要求"更新/检查更新" → 场景 C 更新:才对比远端提交。
  • 用户要求加载本地修改或测试指定提交 → 场景 D 验证开发版本:保护当前工作区和正在运行的 DSH。
First check the current dsh environment:
dsh plugin --profile <name> list
(actual profile names such as web; local path installations are displayed as
link:
). Check whether the target skin is already installed by its
package
name, and confirm whether there is a clone of the repository locally:
  • Already installed (link: dependency) → Scenario A Switch: Direct hot switch, no cloning, no questions, no introduction.
  • Not installed but local repository clone exists → Scenario B Initial Installation (Local Repository): Use the existing clone directly, never re-download.
  • Not installed and no local clone → Scenario B Initial Installation (Requires Cloning): Only perform
    git clone
    at this time.
  • User explicitly requests "update/check for updates" → Scenario C Update: Only compare remote commits at this time.
  • User requests to load local modifications or test specified commits → Scenario D Verify Development Version: Protect the current workspace and running DSH.

重启安全闸门(任何场景都不能跳过)

Restart Safety Gate (Cannot Be Skipped in Any Scenario)

DSH Web 正在运行不代表磁盘上的 profile 能再次启动;旧进程可能仍持有修改前的插件图。不要把“当前页面可用”当作冷启动证据,也不要在检查前建议用户重启。
  1. 读取目标皮肤的
    package.json.name
    skin.json.package
    ,两者必须相同。
  2. 检查
    ~/.dsh/profiles/<profile>/package.json
    :依赖键、
    dsh.profile.bundles
    条目和本地 link 目标的真实包名必须一致。发现别名或旧 scope 时,先用
    dsh plugin --profile <name> remove <错误键>
    移除,再用目标目录的绝对路径
    add
    ;不要手改
    node_modules
  3. 运行
    dsh plugin --profile <name> list
    dsh --profile <name> --dump-config
    。目标 entry 必须能组合、包名正确且启停状态符合预期。
  4. 只有确实需要重启时,先在保留现有进程的情况下运行冷启动探针:
    dsh --profile <name> --no-open --port 0
    。等待它打印临时 URL 后,只终止这个探针进程。探针失败则保留原进程,修复后重试;禁止让用户用生产端口重启来“试试看”。
  5. 冷启动探针成功后才替换原进程,并验证固定端口返回 HTTP 200、启动页
    window.__DSH_BOOT__
    含目标包名。终止进程时只操作刚刚记录的精确 PID/会话,不按进程名批量结束。
诊断必须有界:热加载未发生时先查 link 目标、
lib/client.js
哈希、boot entry 与
--dump-config
;不要递归扫描整个
~/.dsh
、全局
node_modules
,也不要用长时间 SSE 请求碰运气。
DSH Web running does not mean the profile on disk can start again; the old process may still hold the plugin graph before modification. Do not treat "current page available" as evidence of cold start, and do not suggest the user restart before checking.
  1. Read the target skin's
    package.json.name
    and
    skin.json.package
    ; the two must be identical.
  2. Check
    ~/.dsh/profiles/<profile>/package.json
    : The dependency key,
    dsh.profile.bundles
    entry, and the actual package name of the local link target must be consistent. If an alias or old scope is found, first remove it with
    dsh plugin --profile <name> remove <incorrect key>
    , then
    add
    using the absolute path of the target directory; do not manually modify
    node_modules
    .
  3. Run
    dsh plugin --profile <name> list
    and
    dsh --profile <name> --dump-config
    . The target entry must be combinable, have the correct package name, and its start-stop status must meet expectations.
  4. Only when a restart is truly needed, run the cold start probe while keeping the existing process:
    dsh --profile <name> --no-open --port 0
    . Wait for it to print the temporary URL, then terminate only this probe process. If the probe fails, keep the original process, fix the issue and retry; prohibit asking the user to restart with the production port to "try it out".
  5. Only after the cold start probe succeeds replace the original process, and verify that the fixed port returns HTTP 200 and the startup page
    window.__DSH_BOOT__
    contains the target package name. When terminating the process, only operate the exact PID/session just recorded, do not end processes in batches by process name.
Diagnosis must be bounded: When hot loading does not occur, first check the link target,
lib/client.js
hash, boot entry and
--dump-config
; do not recursively scan the entire
~/.dsh
, global
node_modules
, or use long-term SSE requests to try luck.

场景 A:切换(已安装)—— 快速切换,不啰嗦

Scenario A: Switch (Already Installed) – Fast Switching, No Extra Talk

用户点名目标皮肤(如"切到女仆皮肤"/"切到 orca-link")后直接执行,不提问、不介绍作者与许可
  1. 修改两个 patch 层(都改,home 层覆盖 profile 层):
    • ~/.dsh/profiles/<profile>/cordis.patch.yml
    • ~/.dsh/cordis.patch.yml
  2. 目标皮肤
    disabled: false
    ,其余已安装皮肤各补一行
    disabled: true
    。注意:patch 里没有行的皮肤默认启用,所以"只保留一套"必须显式停用其余每一套。
  3. 保存即热重载生效(配置 HMR),无需重启;告知用户刷新页面即可,会话不受影响。
  4. 快速验证:
    dsh --profile <name> --dump-config
    确认目标皮肤行
    disabled: false
    (有
    dsh-plugin-verify
    技能时走其三层验证)。
若用户只说了"切换皮肤"而未指明哪一套,才用一句话列出已安装皮肤询问目标。
Execute directly after the user specifies the target skin (e.g., "switch to maid skin"/"switch to orca-link"), no questions, no introduction of author and license:
  1. Modify two patch layers (both must be modified; home layer overrides profile layer):
    • ~/.dsh/profiles/<profile>/cordis.patch.yml
    • ~/.dsh/cordis.patch.yml
  2. Set
    disabled: false
    for the target skin, and add a line
    disabled: true
    for each other installed skin. Note: Skins not listed in the patch are enabled by default, so "only keep one set" requires explicitly disabling all others.
  3. Hot reload takes effect upon saving (configured with HMR), no restart required; inform the user to refresh the page, and the session will not be affected.
  4. Quick verification: Use
    dsh --profile <name> --dump-config
    to confirm the target skin line has
    disabled: false
    (use the three-layer verification of the
    dsh-plugin-verify
    skill if available).
If the user only says "switch skin" without specifying which one, list the installed skins in one sentence and ask for the target.

场景 B:初次安装(未安装)

Scenario B: Initial Installation (Not Installed)

1. 定位仓库(本地优先,绝不重复下载)

1. Locate the Repository (Local Priority, Never Re-download)

  • 在当前工作目录或常见位置找含
    skin.json
    的目录(仓库根或子目录);找到即用,不重新 clone
  • 找不到本地 clone 时,才
    git clone https://github.com/Small-tailqwq/dsh-deep-whale
    到临时目录。
  • 皮肤目录形态:每个皮肤 = 一个含
    skin.json
    的子目录(如
    maid-atelier/
    orca-link/
    ),
    lib/
    内是预构建的 client bundle(随仓库分发,无需自行构建)。
  • Look for directories containing
    skin.json
    in the current working directory or common locations (repository root or subdirectory); use it once found, do not re-clone.
  • If no local clone is found, only then
    git clone https://github.com/Small-tailqwq/dsh-deep-whale
    to a temporary directory.
  • Skin directory structure: Each skin = a subdirectory containing
    skin.json
    (e.g.,
    maid-atelier/
    ,
    orca-link/
    ), with the pre-built client bundle in
    lib/
    (distributed with the repository, no need to build yourself).

2. 扫描皮肤清单(实时,勿硬编码)

2. Scan Skin List (Real-time, Do Not Hardcode)

对仓库中每个含
skin.json
的目录,读取并汇总:
  • id
    /
    name
    (中文名)/
    nameEn
    /
    tagline
  • package
    (npm 包名)、
    wiring.id
    (patch 层控制的插件 id)
  • preview
    (亮/暗预览图)
For each directory in the repository containing
skin.json
, read and summarize:
  • id
    /
    name
    (Chinese name) /
    nameEn
    /
    tagline
  • package
    (npm package name),
    wiring.id
    (plugin id controlled by patch layer)
  • preview
    (light/dark preview images)

3. 与用户交互:列出全部皮肤,询问激活哪一套

3. Interact with the User: List All Skins, Ask Which One to Activate

用交互工具(如
ask_user_question
)列出所有皮肤(名称 + tagline),询问激活哪一套,并始终提供"保持现状/不切换"选项。初次安装不要跳过交互擅自安装。
Use an interaction tool (such as
ask_user_question
) to list all skins (name + tagline), ask which one to activate, and always provide the "keep current status/do not switch" option. Do not skip interaction and install without permission during initial installation.

4. 向用户交代版权署名链与许可(初次安装必做)

4. Inform the User of Copyright Attribution Chain and License (Mandatory for Initial Installation)

  • 署名链:读取所选皮肤的
    NOTICE
    (署名链权威来源)与 README,简述创作链("一创 XX → 二创 XX → 本皮肤 XX"),附作者主页链接。以 NOTICE 实际内容为准,不要凭记忆介绍。
  • 许可:以皮肤
    LICENSE
    为准。当前皮肤为 CC BY-NC-SA 4.0(署名-非商业性使用-相同方式共享),简明解释:
    • ✅ 可以:个人/非商业使用、复制、分享、二次修改
    • ❌ 不可以:商业性使用;移除署名(须保留完整创作链);以其他协议发布衍生作品(须相同方式共享)
    • 禁止商用是红线,务必点明。
  • Attribution Chain: Read the
    NOTICE
    (authoritative source of attribution chain) and README of the selected skin, briefly describe the creation chain ("Original creation by XX → Secondary creation by XX → This skin by XX"), and attach the author's homepage link. Follow the actual content of NOTICE, do not introduce from memory.
  • License: Follow the skin's
    LICENSE
    . The current skin uses CC BY-NC-SA 4.0 (Attribution-NonCommercial-ShareAlike 4.0 International), briefly explain:
    • ✅ Allowed: Personal/non-commercial use, copying, sharing, secondary modification
    • ❌ Prohibited: Commercial use; removing attribution (must retain complete creation chain); releasing derivative works under other licenses (must share alike)
    • Prohibition of commercial use is a red line, be sure to point it out.

5. 注册并启用

5. Register and Enable

  • dsh plugin --profile <name> add <仓库绝对路径>/<皮肤目录>
    (本地路径自动按
    link:
    注册)。新增插件包需要重启,但必须先通过“重启安全闸门”的一致性检查与冷启动探针。 路径规范(安装失败高发区):绝对路径最稳(Windows 正斜杠/反斜杠均可,pnpm 会自动规范化);相对路径按 dsh 命令调用目录解析——
    ./
    ../
    前缀可以,但不要用裸目录名(如
    add maid-atelier
    ,会被当作 npm 包名去 registry 拉取而 404 失败)。安装后先
    dsh plugin --profile <name> list
    确认包已注册,再继续。更新(场景 C)后 bundle 变化走热切换,无需重启;初次安装是新增插件包,必须重启
  • 安装并安全重启后,同样写入两个 patch 层的
    disabled
    行(见场景 A),保持同一时间只启用一套皮肤。
  • dsh plugin --profile <name> add <absolute repository path>/<skin directory>
    (local paths are automatically registered as
    link:
    ). Adding a new plugin package requires a restart, but must first pass the consistency check and cold start probe of the "Restart Safety Gate". Path Specification (High Failure Rate Area for Installation): Absolute paths are the most stable (Windows forward slashes/backslashes are both acceptable, pnpm will automatically normalize); relative paths are resolved according to the directory where the dsh command is called – prefixes like
    ./
    and
    ../
    are acceptable, but do not use bare directory names (e.g.,
    add maid-atelier
    , which will be treated as an npm package name and pulled from the registry resulting in a 404 failure). After installation, first use
    dsh plugin --profile <name> list
    to confirm the package is registered, then proceed. After updates (Scenario C), bundle changes take effect via hot switching in Scenario A (no restart required, unless adding/removing plugin packages); initial installation involves adding a new plugin package, which requires a restart.
  • After installation and safe restart, also write the
    disabled
    lines in the two patch layers (see Scenario A) to keep only one skin enabled at a time.

6. 验证生效

6. Verify Effectiveness

  • dsh --profile <name> --dump-config
    核对皮肤行
    disabled
    状态与 patch 来源:每行标注
    patched by <文件路径>
    ,确认两个 patch 层都生效(home 层覆盖 profile 层)。
  • dsh-plugin-verify
    技能时走其三层验证(组合层/产物层/执行层);没有时至少做到:刷新页面后
    window.__DSH_BOOT__
    的 entries 含目标皮肤的 package 名(boot 图以包名为 key,不是
    wiring.id
    ),且进程未重启(PID 不变,证明走的是热重载)。
  • 告知用户刷新页面查看效果;皮肤异常(控制台报错、布局问题)时收集现象再排查。
  • Use
    dsh --profile <name> --dump-config
    to check the
    disabled
    status of the skin line and patch source: Each line is marked
    patched by <file path>
    , confirm both patch layers take effect (home layer overrides profile layer).
  • If the
    dsh-plugin-verify
    skill is available, use its three-layer verification (combination layer/product layer/execution layer); if not, at least ensure: After refreshing the page, the entries in
    window.__DSH_BOOT__
    contain the package name of the target skin (the boot graph uses the package name as the key, not
    wiring.id
    ), and the process has not restarted (PID remains unchanged, proving hot reload was used).
  • Inform the user to refresh the page to view the effect; collect phenomena for troubleshooting if the skin is abnormal (console errors, layout issues).

场景 C:更新(仅用户明确要求时)

Scenario C: Update (Only When Explicitly Requested by User)

默认不做任何网络同步——已 clone/已安装就原样使用。仅当用户明确表达"更新皮肤/检查更新"时:
  1. git fetch origin
  2. 对比本地与远端:
    git rev-list --count HEAD..origin/main
    (落后提交数)
  3. 落后 > 0 →
    git pull --ff-only
    ,并告知更新内容(
    git log --oneline HEAD@{1}..HEAD
    );已是最新 → 直接告知,不做多余操作。
  4. 已安装皮肤若更新了 bundle,仍走场景 A 的 patch 热切换生效(无需重启,除非涉及新增/删除插件包)。
By default, do not perform any network synchronization – use installed/cloned skins as-is. Only when the user explicitly expresses "update skin/check for updates":
  1. git fetch origin
  2. Compare local and remote:
    git rev-list --count HEAD..origin/main
    (number of落后 commits)
  3. If behind > 0 →
    git pull --ff-only
    , and inform the user of the update content (
    git log --oneline HEAD@{1}..HEAD
    ); if already up-to-date → directly inform the user, do not perform unnecessary operations.
  4. If the bundle of an installed skin is updated, still use the patch hot switching in Scenario A to take effect (no restart required, unless adding/removing plugin packages).

场景 D:加载本地修改或测试指定提交

Scenario D: Load Local Modifications or Test Specified Commits

  • 当前 link 目录里的源码修改:先按仓库脚本构建并确认提交型
    lib/
    同步,再通过 patch 禁用/启用目标 entry 触发热加载;记录并复核 PID,正常情况下不重启。
  • 测试指定提交:禁止对用户正在使用的工作区执行
    git restore --source=<commit> --worktree -- <skin>
    。创建临时 detached worktree,在其中构建并验证,然后用绝对路径把同名包重新 link 到该 worktree;记录原 link 路径,测试结束后才能按用户指示恢复。
  • 重新 link 后先核对依赖键仍等于目标
    package.json.name
    。若包身份改变,按“移除旧键 → 绝对路径 add → dump-config → 冷启动探针”的顺序处理,不能依赖旧进程内存里的插件图。
  • 热加载失败时不要触碰未变化的 patch 文件伪造刷新,也不要立即建议重启;先走有界诊断。只有新增/删除插件包或启动图确实无法热更新时才使用安全重启流程。
  • Source code modifications in the current link directory: First build according to the repository script and confirm the commit-type
    lib/
    is synchronized, then trigger hot loading by disabling/enabling the target entry via patch; record and review the PID, no restart is required under normal circumstances.
  • Test specified commits: Prohibit executing
    git restore --source=<commit> --worktree -- <skin>
    in the workspace the user is currently using. Create a temporary detached worktree, build and verify in it, then re-link the package with the same name to this worktree using the absolute path; record the original link path, and only restore according to the user's instructions after testing is completed.
  • After re-linking, first check that the dependency key still equals the target
    package.json.name
    . If the package identity changes, follow the sequence "remove old key → add via absolute path → dump-config → cold start probe", do not rely on the plugin graph in the old process memory.
  • If hot loading fails, do not touch unchanged patch files to fake a refresh, and do not immediately suggest restarting; perform bounded diagnosis first. Only use the safe restart process when adding/removing plugin packages or when the boot graph truly cannot be hot-updated.

已知要点(判断用,非写死事实)

Known Key Points (For Judgment, Not Hardcoded Facts)

  • 本仓库皮肤是纯展示层 client 插件:不注入服务、不发 Cordis 事件、不触达模型请求;素材以数据 URI 内嵌于 bundle,激活不依赖远程资源。
  • 皮肤可热切换,
    wiring.id
    即 patch 层控制的插件 id;皮肤中心/互斥切换机制兼容。
  • 仓库 README 安装示例推荐绝对路径
    dsh plugin --profile web add <clone 绝对路径>/<皮肤目录>
    ),并附相对路径规则与失败排查表;懒人版是直接让 dsh 说"安装这个皮肤包"。
  • 反馈问题走仓库 issue,不要联系画师本人;二创关注是另一回事。
  • Skins in this repository are pure client plugins for the presentation layer: No service injection, no Cordis events sent, no model requests accessed; materials are embedded in the bundle as data URIs, activation does not rely on remote resources.
  • Skins can be hot-switched,
    wiring.id
    is the plugin id controlled by the patch layer; compatible with skin center/mutual exclusion switching mechanism.
  • The installation example in the repository README recommends absolute paths (
    dsh plugin --profile web add <absolute clone path>/<skin directory>
    ), and includes relative path rules and a failure troubleshooting table; the lazy version is to directly let dsh say "install this skin package".
  • Submit issues to the repository for feedback, do not contact the artist directly; following secondary creations is a different matter.