Repository navigation
DSH Tavern 的卡片更新器 #149
XGUIMAX
started this conversation in
Show and tell
Replies: 2 comments 1 reply
|
所以你们有什么好用的卡片编辑器嘛 |
1 reply
|
这清晰的设计思路跟喂饭级说明书教程👍 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
自己搓的一个卡片更新器
https://github.com/XGUIMAX/dsh-card-updater
dsh-card-updater
DSH Tavern 的卡片更新器:盯住作者发布页,发现新版就提醒你。
人物卡更新了没有、更新到哪个版本、新版要不要密码或权限才能拿,这些原本要自己隔三差五去社区翻一遍。这个插件把这件事变成点一次按钮:配好每张卡的发布链接,之后检测、比对、合并都交给它。
可以做什么
版本 1.2、beta0.5.5、【9.14更新 …】等多种写法。tavern_helper。package.json,git pull之后会自己跟着变。界面
侧栏底部与「插件市场 / 设置」同排的入口,宽侧栏显示图标加文字,收成窄轨道时显示为图标按钮。同一套面板也在「设置 → 卡片更新器」下。
每张卡的名称右侧有两列状态,分别对应原卡和 MVU 版:
调试记录来自 Tavern 的卡片工作台对话(每张卡在
data/chats下都有一个),插件只读不写。打开调试需要这张卡有游玩对话,没有的话按钮会灰掉并说明原因。与错题库联动
面板右上角有一个 「● 错题库 · 已连接」 按钮,用来显示另一个插件在不在。
它有三种状态:
任何时候点它都会打开错题库的仓库页(https://github.com/XGUIMAX/dsh-wrongbook):未连接时那是补装入口,已连接时那是查更新和看文档的地方。鼠标悬停会写明当前状态。
探测方式是往对方插件自己的路由发一次
GET /dsh-wrongbook/state,每 15 秒复查一次。用对方的公开接口,不需要事先约定协议,也不要求两个插件同时升级 —— 对方没装或版本老,这里只会显示未连接,不会有报错弹出来。这边提供的联动数据
错题库会读取本插件状态里的这两项来工作(都是本插件本来就公开的接口数据,不需要额外开关):
config.cards[].primary.gates—— 含preset表示作者「另附专用预设」,错题库据此在卡片列表上显示标记。这条信息的来源就是本插件的「认得出帖子附带的东西」那一项能力:帖子里写了专用/专属预设时才会出现。config.cards[].plain.path—— 原卡文件路径,错题库用它把自己那边的卡片分类与这里的条目对上号。没配原卡路径的条目可能对不上(表现为错题库那边不显示标记,不是报错)。错题库只读这些字段,不写、不改本插件的数据。
搜索与排序
卡片列表上方有一行工具:
默认排序分四档:
同一档内保持配置里的顺序。在这个下拉里选了别的排序,就完全按选的来,不再叠加默认这几档,因为挑好的顺序才是正在找的顺序。
一条卡都没检测过、也没配工作台的目录,看起来和以前完全一样。
合并策略
name/description/personality/scenario/first_mes/mes_example/system_prompt/post_history_instructions/creator_notes/alternate_greetings/tags等正文字段character_book:原版新增的写进去,内容一致的按原版更新,本地改过的保留并报告冲突三个档位都不会触碰 MVU 的状态栏脚本、变量定义和
tavern_helper。转换生成的产物一律保留。 开场白里的状态入口(
<mvu-status/>或<StatusPlaceHolderImpl/>)和<initvar>初值块不会被作者的新开场白覆盖,判据是这些标记本身 —— 作者的卡不可能有它们。这一条比"看起来带机器"严格,是必要的:作者自己的开场白也常常带<style>或<script>,旧判据会认为两边"一样带机器",然后把字段交给作者。宿主侧的校验要求每个开场白恰好一个状态入口,覆盖掉不只是丢功能,而是让卡直接不通过校验。顶层与
data层的开场白会对齐。 一张卡有两份first_mes/alternate_greetings:载荷顶层一份、data里一份。转换只往data那份追加状态入口和初值块,所以本机每张转换过的卡这两份都不一致,顶层那份正是缺入口的。宿主读data层,因此平时看不出来,但按顶层读的地方就完全没有入口 —— 而合并只改data层,不管它就会越差越远。从原版补进来的正则会被去掉
maxDepth深度上限。 需要深度上限的正则,恰恰是最不该有的那些:负责把占位符从提示词里剥掉的规则一旦过了 N 条消息就失效,占位符就会裸着进入所有更早的消息。另有两个开关:合并结果是否写回原版卡、是否自动递增
character_version。合并结果与磁盘上已有的内容完全一致时不会写卡,也不会留下快照 —— 连点两次「合并」不会重写一遍整张卡,也不会用重复快照挤掉更早的回滚点。
安装
前置条件
先装 DSH Tavern。 这个插件是它的伴生工具:人物卡、卡片工作台对话与游玩数据都由 Tavern 提供,插件只负责比对远端更新、更新原版卡、把变更合并进 MVU 版。没装 Tavern 时打开面板会直接说明并给出安装地址,而不是显示一个空列表。
Tavern 地址:https://github.com/flizzywine/dsh-tavern
此外需要已经在用的 DSH,且有一个 profile(本说明中默认叫
tavern,Tavern 项目用的就是它)。插件是 DSH 插件,不是独立程序。用 dsh 命令安装
dsh plugin是 DSH 自带的插件管理命令:把参数转给 profile 目录下的 pnpm,装完之后再按已安装状态核对dsh.profile.bundles—— 声明了dsh.bundle的依赖自动进入层栈,被移除的自动离开。所以不必手工改 profile 的package.json。在本项目目录里执行:
装到别的 profile 就换名字:
dsh plugin --profile web add .也可以直接从 GitHub 装,不必先 clone:
两种装法只差插件从哪来。本地目录装的是
link:,改源码立刻生效,适合跟随仓库改;GitHub 装的是仓库快照,靠dsh plugin update更新。装完重启 DSH,侧栏底部出现「卡片更新器」即装好。
在 dsh-tavern(CLI 独立版)里安装
dsh-tavern 用的是自己的目录,和标准 DSH 的
~/.dsh不同:独立安装时默认根目录是~/.dsh-tavern,它的私有 CLI 运行时也装在里面。所以这条命令有两处和上面不一样 ——DSH_HOME要指过去,执行的也得是运行时里那个dsh,而不是 PATH 上的标准版。macOS / Linux(按默认目录安装):
Windows(按默认目录安装):
运行时入口的位置按平台不同:macOS / Linux 上是
runtime/bin/dsh,Windows 上是runtime\dsh.cmd,因为 npm 在 Windows 上把命令直接放在 prefix 根目录,不进bin。安装时如果选的是「2 当前目录」(直接回车就是它)或「3 其他目录」,把上面出现的两处
~/.dsh-tavern一起换成你的实际安装根目录即可。要卸载就把
add github:XGUIMAX/dsh-card-updater换成remove dsh-card-updater。这里跑的仍然是同一套dsh plugin,所以dsh.profile.bundles一样会自动维护。卸载
重启 DSH 后入口消失。配置与备份留在
~/.dsh/profile-data/tavern/data/tools/card-updater,要一并清掉就手动删该目录。更新
本地目录装的:在项目目录里
git pull,重启 DSH。GitHub 装的:
面板右上角标着当前版本号,每次打开还会自动查一次 GitHub,有新版就变成可点的「发现新版」。
备选:随附脚本
如果
dsh命令不在PATH里,或者你希望在改 profile 清单之前先留一份备份,可以用仓库里带的脚本。它们做的是同一件事:写dependencies、把插件追加进dsh.profile.bundles、在 profile 目录执行pnpm install,并在动手前把 profile 的package.json备份成package.json.pre-card-updater-<时间戳>。Windows:
macOS / Linux:
卸载:
需要手工回退时:把备份的
package.json覆盖回去,在 profile 目录执行pnpm install,重启 DSH。首次配置
1. 填卡片
打开面板,「重新扫描卡片目录」会按卡片自己声明的名字把原版卡与 MVU 版配对。文件名怎么改都不影响。
配对结果会写在卡片副标题上,例如
MVU 版:姬侠传v0.5.6 MVU版本.json。三对都通过卡内名称匹配,测试的 8 张卡里 7 对全部命中。2. 填主要链接
「主要链接」就是卡在社区的发布贴或发布页。Discord 贴子直接贴链接即可:
只填卡名也行:检测时会用卡片自己的
name字段去索引站搜索,标题匹配上就自动填进来。如果一张卡的更新记录在作者的作品集总页里(一页多卡),把定位这张卡的文字填进「版本关键词」,否则抓到的是整页最大的版本号。
3. 索引站授权
社区索引站的贴子需要登录才能读取。在索引站页面按 F12 打开控制台,执行:
把返回值(不含引号)粘到「合并设置 → 索引站授权」,点「验证」。
令牌只保存在本机
config.json,且只发送给forum.shimmerday.top一个域名。令牌有效期约 7 天。 它是后端签发的 JWT,过期后所有贴子检索都会返回 401。插件会直接读令牌里的过期时间,所以打开面板就能看到「令牌已于 xx 过期」,不用等检索失败才发现;旁边那颗「重新获取令牌」按钮会打开索引站的登录页。
刷新令牌的办法:先退出登录,再用 Discord 重新登录一次。
令牌是后端在 OAuth 回调时以网址
#token=片段的形式带回来的,页面加载时写入 localStorage,除此之外前端没有任何地方写这个键。而登录态靠 cookie 维持,只要它还活着,站点就不会重走授权,也就不会有新的片段,读到的永远是上一次那个值。退出登录正是为了把它打回需要重新授权的状态。localStorage.getItem("auth_token"),把新值粘回面板旧的不用手动清,登录成功后会被整段覆盖。
localStorage.removeItem('auth_token')只在你想亲眼确认「确实写入了新值」时才需要。面板会在令牌剩余不足 24 小时时转成黄色提醒,因为刷新它要折腾一趟登出登录,不适合等检索开始失败了才发现。
日常使用
检测:卡片上的「检测」只查这一张,「检测全部」查所有启用的卡。检测出更新的卡会自动排到列表最前面,其余保持原顺序,不用在长列表里自己找哪张有动静。
版本是怎么比的。基线是卡片自己的
character_version,因为它说的是这台机器手上实际有什么;贴子上的数字会随作者改个标题就漂移。贴子那一侧的信号按可靠程度排:v前缀的写法如v4.3.3日期不是版本。 它说的是作者什么时候发的,不是卡里有什么。把
9.21拿去和卡内的5.2比大小,赢了是巧合,输了是冤枉,而且作者只改日期、卡没动的时候也会被判成有新版。所以日期现在只以「贴子更新于 9.21」的形式显示,不进版本比较。真正可靠的更新信号是索引站记录的更新消息时间:它变了,说明作者确实发了新东西。
贴子改名会单独提示。 作者把「创世回廊」改成「龙娘回廊」这类事会发生,贴子还是那张贴子、卡还是那张卡。判据是贴子标题里还有没有这张卡的关键词,没有就写出「作者改过贴子名,链接仍是同一个(现在叫 ✨龙娘回廊!9.21更新…)」。链接才是身份,标题只是盖在上面的标签,所以这句话说的是标题变了,不是链接不对。
用关键词判断而不是「标题和上次不一样」,是因为后者对已经改过的名字永远不会触发:第一次检测读到的就已经是新名字,此后每次读到的也是它,两次比较永远相等。
读不到正文,这是已知的边界。 社区索引站只收录贴子的标题、摘要和几个时间字段,不收录正文;Discord 那边不登录读不到内容。所以作者把版本写在正文里(「9月21日更新5.3」)时,插件看不到它,只能用索引站记录的更新消息时间判断「作者发了新东西」,无法说出具体版本号。如果你希望某个贴子的版本号被准确读到,那取决于作者是否填写了索引站的版本字段。
卡片上这三个动作,区别只在「原版卡的新内容从哪来」和「要不要顺手合并」:
日常路径:
「更新并合并」里的"更新"是从来源链接自动下载。 社区贴子的下载普遍挂在密码、权限或 Discord 社区身份后面,插件拿不到,所以这一步经常失败;能手动下载时走上面那条路更可靠。
导入新版会先解析确认那确实是一张人物卡,通过后才备份并覆盖原版卡,选错文件不会改坏现有卡。
导入会跟随新卡的名字。 作者改名是常事(
创世回廊变成了龙娘回廊),下载来的新卡文件自带的也是新名字。只写内容而保留旧名字的话,面板、索引检索和文件夹三者会各说各的。所以导入时会一次同步四处:name字段。文件名是你可以随便改的,卡内的名字是作者写进去的、也是这张卡对外的自称;两者冲突时以卡内为准,文件名只在卡里没写名字时兜底name不参与这一项创世回廊5.2 MVU版本.json变成龙娘回廊!5.3 MVU版本.json。名字里没有 MVU 标记的副本不动,因为分辨不出哪一段是卡名创世回廊5.3),只能靠下面那行文件名分辨。副本是你自己派生的卡而不是作者的原文,给它加标记不算改别人的东西;写回时保留kind、version、meta整套外壳originals/cards/<卡名>.png),只改卡不管图的话,卡会退回默认头像 —— 这是看得见的损失,比标签写错更闹心。原版和 MVU 版各自的图都会跟着走;MVU 版直接用原版那张新图,因为它们是同一张卡,沿用旧 MVU 图会显示上一版的美术,看起来像头像没更新cards/<卡名>.json),卡改名后这些路径就悬空了,对话会报「人物卡已删除」,而卡就在旁边、聊天记录一条没少。改名时会把这些指针一并改到新路径,索引文件在写之前先备份已经导入过的卡也能补同步:再点一次「导入新版」选当前这张原版卡。插件会识别出选的就是它自己,不复制内容,只把上面那几处名字对齐。这是不重新导入也能触发同步的唯一入口。
导入完成的提示会写出这次动了什么,形如
创世回廊!5.2_1.json → 龙娘回廊!5.3.json · 关键词改为 龙娘回廊 · MVU 版改名 龙娘回廊!5.3 MVU版本.json。卡图不归插件管。 卡片头像由 Tavern 自己按卡片文件解析并缓存,改完名刷新页面(或重开 Tavern)会重新读;新头像要放在卡片目录里、与卡片文件同名。插件面板里的头像是按原版卡路径现取的,改名后立刻跟着变。
合并到 MVU 只读本地文件、不联网,所以它同步的是「原版卡此刻的内容」。原版卡还没弄成新版的话,合并过去的就是旧的。
(1.23.0 之前另有一个只下载不合并的「更新原版」按钮。因为社区贴子的卡基本都下载不了,它已被移除,下载能力保留在「更新并合并」里。所有写入动作都会先备份。)
有卡正在调试时会挡住写卡的操作。 手动备份、还原、导入新版、更新原版、合并到 MVU、更新并合并都会先检查一遍,命中就弹「有角色卡正在调试中,请等待调试结束再操作」。理由是卡片 Agent 自己持有一份卡并在收工时写回,这时候从面板改同一个文件,两边只会互相覆盖。检测、搜索、筛选这些不碰文件的照常可用。
单张卡的操作结果会显示在那张卡自己的按钮行左侧,一眼能看出是哪张卡的事;「检测全部」「重新扫描卡片目录」这类属于整个面板的操作,结果显示在面板顶部。
上面四个写入动作成功后,提示里会附一句「为确保卡功能与内容完善,建议调试一遍」。改的是卡的内容,而状态栏脚本、变量定义和依赖旧措辞的正则未必跟着走,这些要实际跑一轮才看得出来。
还原:面板里的「还原」列出所有备份,按卡片分组,展开能看到每一份的时间和大小,可回滚到任意一份。
重新载入:工具栏最右那颗按钮会丢弃未保存的改动并重新读取后台状态。平时用不到,每个操作完成后界面都会自己刷新,它只是留给「显示的结论看起来不对」这种情况。
卡被删了但有残留:在 Tavern 里删掉一张卡只会删文件,配置里指向它的条目会留下,面板上就多出一条点「检测」怎么都没反应的记录。这种条目的状态标签现在会直接写「卡文件已不在」,并排到列表最后;工具栏的「清理失效条目」会带上数量,点它一次把这类条目清掉(先弹确认,并列出是哪几个)。
不会自动清,也不会碰只缺一半的条目:外置盘没插、卡临时挪走,看起来和「被删了」一模一样,而这两种情况想要的结果正好相反。所以判断只在每次读取状态时现算,文件回来了标记就消失。清理只删配置条目,不动任何卡片文件,但那条条目的发布链接会一起丢掉。
数据
profile-data/<profile>/data/tools/card-updater/config.jsonprofile-data/<profile>/data/tools/card-updater/state.jsonprofile-data/<profile>/data/tools/card-updater/backups/profile-data/<profile>/data/tools/card-updater/卡片目录固定为
profile-data/<profile>/data/resources/cards。备份保留策略:每张卡文件保留最近 5 份,每个标签(导入 / 合并 / 手动 / 还原前)另各留最新 1 份,总量上限 1000 份。按每张卡文件计算,所以加卡不会挤掉别的卡的历史;总量上限只防失控增长,1000 份完整快照大致是几个 GB 的量级。
备份目录可以自己选。 打开「还原」面板,目录那行有「选择备份目录」—— 点它先问 宿主自己的目录选择器(桌面版就是系统的「选择文件夹」对话框),选完直接生效。宿主的选择器没能打开时,自动退回面板自带的目录浏览器,并把具体原因写在上方一行(是宿主没有选择器、还是选择器自己报错),不再只是悄悄换一个界面。
面板浏览器本身能跨盘:顶部的路径输入框接受
D:\备份、D:、带引号的粘贴路径、正斜杠,以及相对卡片目录的名字,回车或点「转到」即可;「盘符」按钮列出本机所有盘(C:D:…),盘根再点「上一层」就回到这个盘符表 —— 放在别的盘上的文件夹因此也够得着。换完目录旧目录里的快照会自动搬到新目录,规则是先全部复制、成功之后才删原目录:中途出错就不改配置、原目录原封不动,修好再点一次即可(已经复制过去的不重复复制)。新旧目录里同名、内容也相同的算同一份,只留一份;同名但内容不同的两边都留着,并在面板上告诉你有几个、在哪个目录。想改回来点「改回默认目录」。备份目录不能选在卡片目录里面,否则备份文件会被当成人物卡。拼写不同但其实是同一个文件夹(大小写、末尾分隔符)不会被当成换目录,也不会白白重搬一遍。
自动清理只认本插件自己写的快照文件名(
<毫秒>__<标签>__<卡文件名>.json)。所以就算把备份目录指到一个放满别的 JSON 的文件夹,清理也不会碰它们;搬目录时同样只搬自己的快照,删除和还原单个快照也按同一条规定校验 —— 面板上删不掉不属于本工具的 JSON。自动清理覆盖的是常规情况。想立刻把旧的清掉,点工具栏下方那句提示末尾的「打开备份目录」,手动删文件即可 —— 这些是普通快照文件,删掉不影响插件运行,只是失去对应的回滚点。
权限
插件要读卡片文件、要联网、要在点击时打开系统文件管理器。每一类权限的用途、触发时机、涉及的目标和失败时的行为都列在 PERMISSIONS.md 里,包括 DSH / Node 兼容范围声明,以及在一次性 profile 上做安装、启动、卸载的实测步骤。
对 DSH 的影响
这个插件只做三件事,都限制在自己的范围内:
只改自己那份 profile 的
package.json,且改前备份。不触碰@deepseek-ai/*下的宿主包,不触碰其它 profile。运行时只读宿主结构。 侧栏入口通过
sidebar.footer.action槽位注册,位置、几何、收起态表现全部由侧栏外壳决定。插件不做 DOM 注入、不克隆宿主元素、不写宿主元素的内联样式,因此停用后侧栏不会留下痕迹。写入只发生两处:卡片目录(本职,写前自动备份)和插件自己的数据目录。
常见问题
检测说「无法访问该网址」:先确认浏览器能打开 Discord。能打开就检查代理是否开了 TUN 模式。
提示「索引站令牌无效或已过期」:在索引站重新登录,按上面的步骤取一次新令牌。
找不到这张卡的 MVU 版:卡片副标题会说明是「未找到同名 MVU 版」还是「按名称前缀推测配对,请确认」。前者手动选一次文件即可;后者是插件按名称前缀猜的,建议核对。
合并报告里有冲突条目:那些是世界书条目在原版和 MVU 版里内容不一致,插件选择保留本地改过的那份。要用原版内容的话需要单独处理。
单卡没有
character_version:插件不会凭空造版本号,合并后仍为空。在卡里填一个初值之后就会正常递增。「检测更新」显示检测失败:先确认浏览器能打开 GitHub。能打开而这里不通,同样是代理没开 TUN 模式。
「检测更新」是怎么工作的:面板右上角那个按钮显示的是插件自身在 GitHub 上的版本状况。发现新版时点它就直接更新,不用去浏览器:插件跑在 git 检出里,更新就是一次
git pull --ff-only。用--ff-only是因为仓库里有未提交的改动时应该停下来告诉你,而不是自己合成一个没人要的合并提交。拉取前后会各读一次修订号,所以成功提示里写的是旧 → 新,而不是笼统的一句"已更新"。更新完重启 DSH 生效。报「这个插件不是 git 检出,没法自动更新」:说明安装方式不是从仓库 checkout,而是从 npm 或压缩包来的。那种情况用
dsh plugin --profile <profile> add重新安装,之后就能自更新了。作者改了贴子标题,检测就报「无法定位这张卡」:1.19.0 之前会这样。插件拿「版本关键词」去贴子里找位置,找不到就判定失败;但 thread_id 不会变,标题会变,作者一改名就全盘失效。现在关键词只在真的能找到时用来缩小范围,找不到就退回到整个贴子:Discord 贴子整个都属于这一张卡,不存在认错的问题。仍然依赖关键词定位的只有普通网页,因为那种页面上可能并排放着好几张卡。
提示「页面上没有找到「某某」」:现在只会在普通网页上出现,说明关键词和页面内容对不上。把「版本关键词」清空,让它改从卡片自己的名字提取(1.18.1 起尾部标点会自动去掉),或者改成页面里实际出现的写法。
「检测更新」显示暂无发布版本:仓库还没打过任何版本标签,插件无法比对。见下面的「发版」。
安全软件报
TrojanDownloader/JS.Agent.is:误报,两个原因叠在一起。插件本职要下载卡文件并写入磁盘,这本身就有"下载者"的形状;而 1.17.0 之前,它在 Windows 上还会调用 PowerShell 生成头像缩略图,那次调用带了-ExecutionPolicy Bypass和运行时拼接的命令串,正是终端防护判定"脚本启动器"的特征。1.18.0 已经把那段调用删掉了,头像直接交给浏览器缩放,现在整个宿主端只剩一处外部命令调用(打开系统文件管理器)。报毒时把插件目录加入信任区即可。它需要写人物卡文件,这是它的功能本身,不是异常。
点「更新原版」或「更新并合并」提示来源无法直接更新:这张卡的来源挂着密码、权限或赞助,插件拿不到文件。点「跳转到原贴」去按作者的方式下载新卡,回来点「导入新版」,再点「合并到 MVU」。检测结果里标着「有下载条件:密码 · 权限 · 回复可见」的卡都属于这种情况。
提示令牌已过期:索引站的令牌有效期约 7 天,过期后检索贴子会返回 401。刷新方式见上面「索引站授权」一节:先退出登录,再用 Discord 重新登录一次,然后重新取。注意浏览器里看着还登录着是正常的,登录态靠 cookie,令牌是另一条凭据,两者不会互相刷新。
macOS / Linux 上和 Windows 有什么不一样:打开目录这一处。macOS 用
open,Linux 用xdg-open,Windows 用cmd.exe /c start。Windows 上不能直接explorer.exe <目录>:那样打开的窗口不会显示(实测一个备份目录堆了 31 个同名窗口、全部不可见,按钮看起来就是"没反应"),start才是把路径交给 shell 的正确方式。开发
纯 JavaScript,无构建步骤、无第三方依赖。
宿主端注册四个路由,浏览器端通过它们通信:
GET /dsh-card-updater/state— 配置与最近报告GET /dsh-card-updater/list— 目录浏览(?path=可为空、盘符表、或任意可解析路径)GET /dsh-card-updater/avatar— 卡片头像POST /dsh-card-updater/action— 所有操作,取值为check/importPlain/merge/updateAndMerge/save/suggest/backupList/restoreBackup/deleteBackup/manualBackup/prune/setBackupDir/verifyIndex/pickFolder/openFolder/checkUpdate/selfcheck等改了
lib/index.js需要重启 DSH;只改client.js刷新页面即可。测试
三套都跑在临时目录里。宿主端通过把
DSH_HOME指到一个临时沙箱来隔离 —— 插件所有路径都是从它推出来的,所以沙箱里的运行读不到也写不到真实卡片目录。test/real.mjs会把本机最小的那对卡复制进沙箱再合并,逐对检查扩展、世界观书和开场白里的状态栏占位符没有丢失,并且连合两次第二次不再写盘;找不到卡片时自动跳过。test/harness.mjs把两个半边的源码在内存里改写成可注入的模块 —— 宿主端去掉node:导入,浏览器端喂一个假的window.__ModuleLoader__和react—— 源码文件本身不动,所以这些内部函数不必为了测试而导出。平台
宿主端只用 Node 内置模块,没有第三方依赖,路径一律走
node:path。DSH 主目录取DSH_HOME,没设时用~/.dsh,三个平台解析到同一个位置。需要跟随平台的地方各有分支:open/xdg-open/ Windows 上的cmd.exe /c start(不能直接调explorer.exe,那样打开的窗口不显示)dsh plugin --profile <name> add / remove,跨平台通用;另外随附 PowerShell 与 POSIX 脚本各一套作为备选不要给 package.json 加 BOM
DSH 读这个清单来判断一个包是不是 bundle,一个 UTF-8 BOM 就会让清单变成非法 JSON,插件直接加载失败,报的是:
这是踩过一次的坑:Windows PowerShell 5.1 的
Set-Content -Encoding UTF8会主动写 BOM,用它改版本号就会中招。改这个文件请用不带 BOM 的方式,比如仓库里用的编辑工具,或者:修完可以用这句确认前三个字节不是
EF BB BF:发版
「检测更新」比对的是本机
package.json里的version与仓库的 release / tag,所以新版要能被检测到,必须打上对应的标签:标签名用
vX.Y.Z,且与package.json的version保持一致。只推代码不打标签的话,插件会一直认为自己就是最新版。许可
MIT
All reactions