@xia-sc/dsh-cc-studio 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/lib/agent.js +224 -318
- package/lib/client.js +247 -34
- package/lib/group-layer.js +624 -0
- package/lib/index.js +317 -180
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ DSH(DeepSeek Harness)插件:输入框上方的胶囊 → 全屏融合工
|
|
|
14
14
|
|
|
15
15
|
| 项目 | 值 |
|
|
16
16
|
| --- | --- |
|
|
17
|
-
| 包名 / 版本 | `@xia-sc/dsh-cc-studio` `0.
|
|
17
|
+
| 包名 / 版本 | `@xia-sc/dsh-cc-studio` `0.10.0` |
|
|
18
18
|
| 兼容 | DSH `>=0.4.5-rc.4`(含**桌面版**)、Node `>=22`、**零运行依赖**;逐版本实测见 [兼容与权限](#兼容与权限) |
|
|
19
19
|
| 落盘位置 | `<DSH_HOME>/cc-library/`(角色卡)、`<DSH_HOME>/cc-drafts/`(会话草稿);`DSH_HOME` 默认 `~/.dsh`,旧位置仍读得到 |
|
|
20
20
|
| 文档 | 用户文档=本文件;改代码前必读 [AGENTS.md](./AGENTS.md);完整历史 [CHANGELOG.md](./CHANGELOG.md) |
|
|
@@ -42,7 +42,7 @@ DSH(DeepSeek Harness)插件:输入框上方的胶囊 → 全屏融合工
|
|
|
42
42
|
dsh --profile <profile> --dump-config
|
|
43
43
|
期望在 `# == @xia-sc/dsh-cc-studio` 那一层下看到两行:`id: dsh-cc-studio`(宿主行)与 `id: preset-cc`(CC 预设行)。
|
|
44
44
|
4. 告诉用户重启:宿主行只在启动时组合 —— CLI 重启 `dsh web`,桌面版退出并重新打开应用。
|
|
45
|
-
5. 重启后可选自检:在「CC 模式」会话里调任意一个 cc_* 工具,返回里带 "build": "0.
|
|
45
|
+
5. 重启后可选自检:在「CC 模式」会话里调任意一个 cc_* 工具,返回里带 "build": "0.10.0" 即说明新代码已加载
|
|
46
46
|
(这也是判断「改了但没重启」的唯一可靠依据)。
|
|
47
47
|
6. 不要做的事:
|
|
48
48
|
- 不要手工把 presets/ 拷进 ~/.dsh/.agent-presets/(dsh >= 0.4.7-alpha.4 已不读该目录,拷了也不生效);
|
|
@@ -58,9 +58,9 @@ DSH(DeepSeek Harness)插件:输入框上方的胶囊 → 全屏融合工
|
|
|
58
58
|
```bash
|
|
59
59
|
# 从 npm 安装(推荐)
|
|
60
60
|
dsh plugin --profile web add @xia-sc/dsh-cc-studio
|
|
61
|
-
dsh plugin --profile web add @xia-sc/dsh-cc-studio@0.
|
|
61
|
+
dsh plugin --profile web add @xia-sc/dsh-cc-studio@0.10.0 # 锁定版本
|
|
62
62
|
|
|
63
|
-
# 从 GitHub 源安装(可加 #v0.
|
|
63
|
+
# 从 GitHub 源安装(可加 #v0.10.0 / #master 指定 tag / 分支)
|
|
64
64
|
dsh plugin --profile web add github:xia-sc/dsh-cc-studio
|
|
65
65
|
|
|
66
66
|
# 从本地仓库安装(开发 / 调试):装出来是 link:,改 lib/*.js 重启即生效
|
|
@@ -128,7 +128,7 @@ dsh plugin --profile web remove @xia-sc/dsh-cc-studio # 卸载(同时移
|
|
|
128
128
|
| 条目管理 | `cc_update_lorebook_entry` / `cc_delete_lorebook_entries` |
|
|
129
129
|
| 导出与起点 | `cc_preview_export`(体积、估算 token、字段清单、重复内容量)/ `cc_new_card`(破坏性,须用户同意后带 `confirm:true`) |
|
|
130
130
|
| 人物关系(0.8.0) | `cc_get_relations` / `cc_patch_relations` / `cc_render_relations` / `cc_group_check` |
|
|
131
|
-
| 共享世界书(0.9.0) | `cc_get_shared_book` / `cc_patch_shared_book` / `cc_promote_shared_entries` / `cc_apply_shared_book` |
|
|
131
|
+
| 共享世界书(0.9.0) | `cc_get_shared_book` / `cc_patch_shared_book` / `cc_promote_shared_entries` / `cc_apply_shared_book` —— 工坊导出页给两种形态:**CCv3 独立世界书**(`lorebook_v3`)与 **SillyTavern 世界书**(`{entries:{…}}`;ST 只认后者)。导卡时(JSON / PNG / CHARX)自动在导出副本上写 ST 的世界书绑定(`data.extensions.world`),PNG 同时带 `ccv3`(纯 CCv3)与 `chara`(V2 回填)两个块 |
|
|
132
132
|
| 分组管理(0.8.0) | `cc_list_groups` / `cc_create_group` / `cc_rename_group` / `cc_delete_group` / `cc_set_card_group` |
|
|
133
133
|
| 已存库 CRUD | `cc_list_library` / `cc_save_to_library` / `cc_load_from_library` / `cc_delete_from_library` / `cc_rename_in_library` / `cc_get_library_entry` |
|
|
134
134
|
|
|
@@ -174,8 +174,9 @@ dsh plugin --profile web remove @xia-sc/dsh-cc-studio # 卸载(同时移
|
|
|
174
174
|
## 开发与测试
|
|
175
175
|
|
|
176
176
|
```bash
|
|
177
|
-
npm test #
|
|
177
|
+
npm test # 22 个文件、852 项断言,全绿才算过
|
|
178
178
|
node tests/tools-contract.test.mjs # 只跑 CC 工具链契约(97 项)
|
|
179
|
+
node tests/group-layer-guard.test.mjs # 只跑卡组层的耦合守卫(16 项)
|
|
179
180
|
```
|
|
180
181
|
|
|
181
182
|
- 改 `lib/client.js`:刷新页面即可;改 `lib/index.js` / 预设:**重启 dsh**。
|
|
@@ -185,6 +186,10 @@ node tests/tools-contract.test.mjs # 只跑 CC 工具链契约(97 项
|
|
|
185
186
|
|
|
186
187
|
完整历史见 [CHANGELOG.md](./CHANGELOG.md)。最近几版大多是「另一个 LLM 以工具使用者身份跑回归」挖出来的问题:
|
|
187
188
|
|
|
189
|
+
- `0.10.0` **卡组不再是一堆工具的组合,而是一层**:0.9.x 的两轮补丁都打在同一个地方 —— 组级共享世界上线后,`simulate` / `lint` / `group_check` / `preview_export` / `validate` 五个「读数」工具**各自**补了一遍「把共享书算进来」(「改了四个、漏了第五个」)。根因不是手滑,而是同一个语义存在多份实现:卡组数据读取两半各一份、取作用域每个工具各写一遍、卡组级统计与世界书统计平行两套、界面再自己算一遍。修法是立三层并**让两半共用同一个文件** `lib/group-layer.js`(纯函数、零 IO):**数据层** `readLibrarySnapshot()` + `groupScope()`(来源卡 → 组 → 成员 → 书,唯一入口,支持 `include` / `maxCards` / 传快照避免重复读盘)、**口径层** `groupMetrics()`(所有「多少条 / 多少 token」只在这里产生,五段 + 派生量;`lorebookMetrics` 变薄包装、旧输出逐字不变)、**检查层** `runGroupChecks()` + `GROUP_CHECKS` 注册表(一份清单、一套 issue 形状、一个 `byCheck` 计数)。`checkGroup` 只剩 6 行薄包装(以前 48 行 if 序列),宿主端点、工具与既有测试一行未改。**第五个功能作为验收用例落地**:新增 **cross-card** 类别 —— 跨卡触发词冲突(只报涉及 ≥2 个来源的)、卡内条目与共享书逐字重复、组内五维漂移、成员卡全 auto,外加 **lore-quality**(共享书自身条目质量);这五项只改了注册表,五个既有工具的口径代码**一行未动**(`tests/group-layer-guard.test.mjs` 钉住)。入口仍是 `cc_group_check` / `cc_groupCheck`(新增 `checks` 参数与 `byCheck`),界面把体检结果从「一行拼接」改成按 error / warn 分组的清单。顺带:组体检读盘 `1+2N` → `1+N`;记录一个已知不可达检查(`type-unknown` —— `normalizeGroup` 早把未知 type 归一到 `other`)。测试 735 → **852 项(22 个文件)**。**需重启 dsh(桌面版重启应用)→ 刷新页面**。
|
|
190
|
+
|
|
191
|
+
- `0.9.1` **共享世界书导不进 SillyTavern**:把 CCv3 独立 lorebook(`{spec:"lorebook_v3", data}`)拖进「世界信息 → 导入」只会得到 `Error importing world info: … Bad Request`。根因有两层(对着本地 ST 1.19.0 源码 + 实测复现):服务端 `/api/worldinfo/import` 拿到文件第一句就是 `if (!('entries' in worldContent)) throw` —— 顶层没有 `entries` 一律 **400**;而 ST 客户端 `importWorldInfo()` 只转 Novel / Agnai / Risu,整份 `world-info.js` 里搜不到 `lorebook_v3`(**它不是「换个后缀」能解决的**)。另外 ST 的 `parseDecorators()` 只认 `@@activate` / `@@dont_activate`,其余 `@@` 行会**连同正文一起被丢掉**。修法是多一种形态而非改掉原来那种:共享书页与导出页各多一枚「⬇ SillyTavern 世界书」,导出 `{entries:{"<uid>":{…}}}`,字段照抄 ST 自己的 `convertCharacterBook()`,`@@position` / `@@depth` 翻译成 ST 的 `position` / `depth` 并从正文删掉(`@@activate` 原样留给 ST),文件名 = 书名(ST 用上传文件名当世界名);**CCv3 那份一个字节没动**。实测:同一本真书导出的 ST 文件导入返回 **200 + `{"name":…}`**、ST 落盘、条目 uid 与源 `id` 一致、「年表」落在 `position:1`。测试 647 → 683 项(16 个文件)。**同一版还补齐了 SillyTavern 兼容层**:PNG 现在同时写 `ccv3`(纯 CCv3)与 `chara`(诚实的 V2 投影,按规范摘掉装饰器)两个块,读取器改成**按载荷里的 spec 判并优先 `ccv3`**(此前是「取第一个命中的块」,而 ST 导出的 PNG 是 `chara` 在前,于是把 ST 导出的卡拖进工坊会报「spec 需为 chara_card_v3」);导出 PNG / CHARX / JSON 时若该卡所属分组有共享书,会**只在导出副本上**写 ST 的世界书绑定(`data.extensions.world = 书名`)—— ST 里的顺序是先导世界书、再导卡,绑定就自动接上(卡内私有条目还要点一次 Import Card Lore)。规范同样明文禁止往卡片里加应用私有字段,所以卡片顶层一个 ST 私有键都不加。实测:我们导出的双块 PNG 进 ST 返回 **200**,ST 回读 `data.extensions.world`、卡内 3 条书条目与 V3 独有字段俱在且世界名可解析;ST 落盘的「V2 在前」PNG 我们也能读了。测试 683 → **718 项(17 个文件)**。**同一版还有第三步:V2 卡现在能进工坊了** —— SillyTavern 里绝大多数存量卡是 V2(ST 界面新建的就是 V2 形状,只是 `spec` 被改写成 v3 标签),此前拖 PNG/JSON 进来只会得到「spec 需为 chara_card_v3」。现在 `upgradeCardToV3()` 一份实现管 PNG / CHARX / JSON 三条导入路径(规则照 ST 的 `readFromV2()`:顶层 V1 平铺字段只在 `data` 缺值时补、`creatorcomment`→`creator_notes`、`talkativeness`/`fav`→`data.extensions`、纯 V1 整份包成 `data`),导入返回带 `upgradedFrom`、界面明说「V2 卡已升级为 CCv3」(不静默变换);JSON 导入也收口到宿主的新端点 `cc_importFromJson`(客户端不再自己 parse 卡 JSON)。`cc_setDraft` 故意不升级(它是工坊自己草稿的镜像)。测试 718 → **735 项(17 个文件)**。**需重启 dsh(桌面版重启应用)→ 刷新页面**。
|
|
192
|
+
|
|
188
193
|
- `0.9.0` **「共享世界书」的收口版**:0.8.2 把世界设定从「每张卡一份」挪到了「组上一本」,但**所有读数、判定与质量检查还按「卡里」算** —— 五轮 LLM 侧回归把它逐个补平:四个读数工具(`simulate` / `lint` / `group_check` / `preview_export`)全部拆成「**卡内 / 共享书 / 合计**」三段(`simulate` 此前会把「会命中」报成「不会命中」,实测低估约 3 倍);**提升去重后自动同步草稿**(否则下一次保存会把重复原样写回卡里);`cc_validate` 的「世界书 ≥5 条」改走合计口径(按最佳实践去重过的卡此前**必然判不合格**);重复检测补上「**卡 ↔ 共享书**」一类(`bookDuplicates` / `wouldClean`);`constant` 与 `@@decorator` 的存在性检查两端统一;**共享书自己的逐条质量检查**补上(此前「共享书质量走 `cc_get_shared_book`」只是一句没实现的说明 —— 那条线上只有重复检测)。口径与质量各收口成一个纯函数(`lorebookMetrics` / `auditLoreEntries`),以后改口径只动一处。测试 604 → 647 项(15 个文件)。
|
|
189
194
|
|
|
190
195
|
- `0.8.2` **群聊卡这一整段迭代的正式发版**:关系图谱(`<DSH_HOME>/cc-groups/`,三维 = 方向 × 类型 × 强度;节点分「有独立卡的角色」与「卡内 NPC」)+ `cc_render_relations` 把关系渲染进 `description` 的固定标记区让卡自包含(幂等、可 `dryRun`、空图谱 = 清空);随后补齐**模型侧的分组增删改查**(`cc_list_groups` / `cc_create_group` / `cc_rename_group` / `cc_delete_group` / `cc_set_card_group`)、新增**组级共享世界书**(`<DSH_HOME>/cc-books/`,一组一本、文件本身就是 CCv3 官方 `lorebook_v3` JSON,`cc_promote_shared_entries` 一键把成员卡里逐字重复的条目提升进去并从各卡删除),并把工坊左侧改成**卡片结构导航**(总览 / 角色 / 世界观 / 世界书 / 开场与示例 / 关系与分组 / 共享世界书,每项带三态进度徽章)。工具 19 → 32。修的既有问题:**B4** 工具半保存一次就把卡踢出分组(两半 `makeLibraryEntryMeta` 漂移)、**B5** `mutual` 对等边完全不渲染、**关系视图「关系 · 0」与导航 0 条**(客户端读错宿主返回形状 —— 边在 `group` 里)、**换卡后关系视图不换组**。测试 509 → 604 项(14 个文件)。**需重启 dsh(桌面版重启应用)→ 刷新页面**。
|