@xia-sc/dsh-cc-studio 0.4.1 → 0.8.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 CHANGED
@@ -10,361 +10,184 @@
10
10
 
11
11
  > 从一句话点子到可导入 SillyTavern / Risu 的 `chara_card_v3`。专治「只有点子,世界观薄弱」。
12
12
 
13
- DSH(DeepSeek Harness)插件:输入框上方的胶囊 → 全屏融合工坊,配合 `CC 模式` 预设让 LLM 通过 14 个 Tool **先问再填**、与你共创角色卡,最后一键导出 `JSON / PNG / CHARX`。
13
+ DSH(DeepSeek Harness)插件:输入框上方的胶囊 → 全屏融合工坊,配合 `CC 模式` 预设让 LLM 通过 19 个 Tool **先问再填**、与你共创角色卡,最后一键导出 `JSON / PNG / CHARX`。
14
14
 
15
15
  | 项目 | 值 |
16
16
  | --- | --- |
17
- | 插件包名 | `@xia-sc/dsh-cc-studio` |
18
- | 当前版本 | `0.4.1` |
19
- | 兼容与权限 | DSH `>=0.1.5-rc.1`、Node `>=22`、**零运行依赖**;权限边界见 [兼容与权限](#兼容与权限) |
20
- | 宿主 RPC | `/dsh-cc-studio-rpc`(自带路由,适配 dsh ≥ `0.1.5-rc.1`;已在 `0.1.6-alpha.2` / `0.1.7-alpha.1` / `0.1.7-rc.1` 实测) |
21
- | CC 预设 | `presets/cc.patch.yml`(dsh ≥ `0.1.7-alpha.1`,组合声明行)/`<DSH_HOME>/.agent-presets/cc`(≤ `0.1.6-alpha.2`,目录形态) |
22
- | 客户端挂载点 | `conversation.input.dock`(胶囊)+ `shell.overlay`(工坊)+ `settings.section` |
23
- | 落盘位置 | `<DSH_HOME>/cc-library/`(角色卡)、`<DSH_HOME>/cc-drafts/`(会话草稿);`DSH_HOME` 默认 `~/.dsh`。0.3.6 起认 `DSH_HOME`,旧的 `~/.dsh` 位置**仍然读得到**(读时回退) |
17
+ | 包名 / 版本 | `@xia-sc/dsh-cc-studio` `0.8.0` |
18
+ | 兼容 | DSH `>=0.1.5-rc.1`(含**桌面版**)、Node `>=22`、**零运行依赖**;逐版本实测见 [兼容与权限](#兼容与权限) |
19
+ | 落盘位置 | `<DSH_HOME>/cc-library/`(角色卡)、`<DSH_HOME>/cc-drafts/`(会话草稿);`DSH_HOME` 默认 `~/.dsh`,旧位置仍读得到 |
20
+ | 文档 | 用户文档=本文件;改代码前必读 [AGENTS.md](./AGENTS.md);完整历史 [CHANGELOG.md](./CHANGELOG.md) |
24
21
 
25
- ## 安装
26
-
27
- 本插件同时支持 **`dsh web`(CLI 起的 Web GUI)** 与 **DSH 桌面版(DeepSeek Harness Desktop)**:两者是同一个 dsh 宿主,插件都装在 profile 的 `dsh.profile.bundles` 里,加载方式与全部功能完全一致。下面以 `web` profile 为例;桌面版的差异只有 profile 名与「重启应用」这一步,见下文 **[7. 桌面版](#7-桌面版deepseek-harness-desktop)**。
28
-
29
- ### 1. 从 npm 安装(推荐)
30
-
31
- ```bash
32
- dsh plugin --profile web add @xia-sc/dsh-cc-studio
33
-
34
- # 锁定版本
35
- dsh plugin --profile web add @xia-sc/dsh-cc-studio@0.4.0
36
- ```
37
-
38
- **或从 GitHub 源安装**:
39
-
40
- ```bash
41
- dsh plugin --profile web add github:xia-sc/dsh-cc-studio
42
- ```
43
-
44
- `dsh plugin` 只是把参数转发给 profile 目录(`~/.dsh/profiles/web`)里的 pnpm;装完 dsh 会把 `@xia-sc/dsh-cc-studio` 自动追加到该 profile 的 `dsh.profile.bundles`,不需要手改 `package.json`。
45
-
46
- > **0.3.2 起包名由 `@dsh-plugins/dsh-cc-studio` 改为 `@xia-sc/dsh-cc-studio`**(前者不是本项目持有的 npm scope,发布不出去)。装过旧名的先按「5. 更新与卸载」移除旧包再装新包;`~/.dsh/cc-library/`、`~/.dsh/cc-drafts/`、`~/.dsh/.agent-presets/cc/` 以及插件设置都不受影响。
47
-
48
- - **锁定版本 / 指定分支**:`github:xia-sc/dsh-cc-studio#v0.3.0`、`...#master`(tag 见仓库 Tags)。
49
- - **`allowBuilds` 提示**:本插件没有 `prepare` 构建脚本,正常安装不会触发 pnpm 的构建拦截;若 pnpm 仍打印该提示,把提示里给出的键加进 `~/.dsh/profiles/web/pnpm-workspace.yaml` 的 `allowBuilds` 后重跑。
50
- - **在 DSH 会话里由 Agent 执行时**:写入位置在会话工作区之外,需先把文件权限切到 `danger-full-access`;自己在终端执行则无此限制。
51
-
52
- ### 2. 从本地仓库安装(开发 / 调试)
53
-
54
- ```bash
55
- git clone https://github.com/xia-sc/dsh-cc-studio.git
56
- cd dsh-cc-studio
57
- dsh plugin --profile web add .
58
- ```
59
-
60
- 相对路径按**你执行命令时所在的目录**解析(dsh 会先把 `.`、`./xxx` 重写成绝对路径再交给 pnpm,避免误链到 profile 目录)。装出来的是 `link:` 到源码目录:改 `lib/*.js` 后重启 dsh web 生效;只改 `lib/client.js` 时刷新页面即可(若同时跑着 dsh 仓库的 `pnpm run dev:web`,客户端 bundle 会重建,连刷新都省了)。
61
-
62
- ### 3. CC 预设(随插件自动可用,无需手工拷贝)
63
-
64
- 装完插件、重启 `dsh web` 后即可在会话模式里选到 `CC 模式`(preset id 恒为 `cc` —— 宿主 `isCcPreset()` 与浏览器 `CC_PRESET_ID` 都按它精确比较)。**投递方式按 dsh 版本分两代,两代都不需要你手工拷文件**:
65
-
66
- | dsh 版本 | 预设从哪来 | 你要做什么 |
67
- | --- | --- | --- |
68
- | ≥ `0.1.7-alpha.1` | 插件随包带的补丁层 `presets/cc.patch.yml`:往组合里 insert 一行 `@deepseek-ai/dsh-agent-preset` 的**声明**(与内置 `standard` / `ptc` / `minimal` / `cordis` 完全同构) | 什么都不用做 |
69
- | ≤ `0.1.6-alpha.2` | 插件挂载时把 `presets/cc` 装到 `<DSH_HOME>/.agent-presets/cc`(目录形态,行为与 0.3.5 之前一致) | 什么都不用做 |
70
-
71
- **为什么 0.1.7 必须换机制**:那一版起 dsh 的预设**只来自组合里的声明行**,`<DSH_HOME>/.agent-presets/` 已经没有任何代码读取 —— 升级后 `CC 模式` 从 roster 里消失就是这个原因:目录还在,只是**没人再看它**。插件因此把声明写进 `package.json` 的 `dsh.bundle.patch` 第二层(第一层是宿主插件行),插件装进哪个 profile,`CC 模式` 就出现在哪个 profile 的 roster 里;新版上**不会再往磁盘写一个字**。
72
-
73
- **关掉 `CC 模式`(≥ `0.1.7-alpha.1`)**:不必卸载插件,在自己的补丁层里按 id 关掉那一行即可(`<profile>/cordis.patch.yml`,或对所有 profile 生效的 `$DSH_HOME/cordis.patch.yml`):
74
-
75
- ```yaml
76
- - id: preset-cc
77
- name: '@deepseek-ai/dsh-agent-preset'
78
- disabled: true
79
- ```
80
-
81
- <details>
82
- <summary>≤ 0.1.6-alpha.2:目录安装的更新策略、开关与手工兜底</summary>
22
+ ---
83
23
 
84
- **旧版上插件挂载时仍会把 `presets/cc` 装到 `<DSH_HOME>/.agent-presets/cc`**(`DSH_HOME` 默认 `~/.dsh`),目录名固定为 `cc`。之所以需要这一步:那条路径上 dsh 的预设发现只扫三个根——**shipped 根**(`dsh-agent-presets` 包内自带)+ **部署 `config.roots`** + **用户根 `<DSH_HOME>/.agent-presets`**;插件包内的 `presets/` 不在其中,**「随包分发」≠「已注册」**,所以由插件在启动时把它装进用户根。
85
-
86
- 更新策略是幂等的,且**绝不静默覆盖你的改动**:
87
-
88
- | 目标文件状态 | 行为 |
89
- | --- | --- |
90
- | 不存在 | 写入模板 |
91
- | 与模板一致 | 不动(只补记安装记录) |
92
- | 与插件上次写入的内容一致(你没改过) | 插件升级时安全更新 |
93
- | 你改过 / 是旧版手工拷贝(无安装记录) | **保留并告警**,不覆盖 |
94
-
95
- 安装记录是预设目录里的 `.dsh-cc-studio-preset.json`(记版本与各文件写入时的 sha256)。若出现「已保留未覆盖」的告警而你想改用插件模板,二选一:
96
-
97
- ```powershell
98
- # A. 删掉旧目录,重启 dsh web 即重新自动安装
99
- Remove-Item "$env:USERPROFILE\.dsh\.agent-presets\cc" -Recurse -Force
100
- ```
101
-
102
- ```bash
103
- # B. 用环境变量强制覆盖后重启 dsh web(macOS / Linux)
104
- DSH_CC_STUDIO_PRESET_INSTALL=force dsh web # auto(默认)| force | off
105
- ```
24
+ ## 安装
106
25
 
107
- ```powershell
108
- # B. 同上(Windows PowerShell)
109
- $env:DSH_CC_STUDIO_PRESET_INSTALL = 'force'; dsh web
110
- ```
26
+ 插件同时支持 **`dsh web`(CLI 起的 Web GUI)** 与 **DSH 桌面版(DeepSeek Harness Desktop)** —— 两者是同一个宿主,插件都装进 profile 的 `dsh.profile.bundles`,功能完全一致,差别只有 profile 名和「怎么重启」。
111
27
 
112
- > 也可在插件行声明 `config.presetInstall`(需自己写 overlay patch),它的优先级高于环境变量。`off` 时请按下面的手工方式自行管理预设。
28
+ ### 🤖 给 AI Agent 的安装引导
113
29
 
114
- <details>
115
- <summary>手工安装(仅在自动安装被关闭或失败时需要)</summary>
30
+ 把下面整段交给你的 Agent(DSH 里的 Agent、Claude Code、Codex 都行),它就能自己装好并验证:
116
31
 
117
- ```powershell
118
- # Windows PowerShell(GitHub 安装)
119
- $src = "$env:USERPROFILE\.dsh\profiles\web\node_modules\@dsh-plugins\dsh-cc-studio\presets\cc"
120
- Copy-Item $src "$env:USERPROFILE\.dsh\.agent-presets\cc" -Recurse -Force
32
+ ```text
33
+ 任务:给 DSH 安装 @xia-sc/dsh-cc-studio 插件。
121
34
 
122
- # 本地仓库开发时改用:$src = ".\presets\cc"
123
- ```
35
+ 1. 确认目标 profile 名:问用户,或看 ~/.dsh/profiles/ 下的目录名。
36
+ (桌面版通常叫 desktop,CLI 起的 Web GUI 通常叫 web。)
37
+ 2. 安装(把 <profile> 换成实际名字):
38
+ dsh plugin --profile <profile> add @xia-sc/dsh-cc-studio
39
+ 若 dsh 不在 PATH:桌面版自带 CLI 在 <安装目录>/resources/runtime/cli/bin/dsh(Windows 为 dsh.cmd)。
40
+ 命令行参数顺序固定为:dsh plugin --profile <profile> add <包名>(--profile 不能省)。
41
+ 3. 验证已进入组合(只读、不启服务、不用重启):
42
+ dsh --profile <profile> --dump-config
43
+ 期望在 `# == @xia-sc/dsh-cc-studio` 那一层下看到两行:`id: dsh-cc-studio`(宿主行)与 `id: preset-cc`(CC 预设行)。
44
+ 4. 告诉用户重启:宿主行只在启动时组合 —— CLI 重启 `dsh web`,桌面版退出并重新打开应用。
45
+ 5. 重启后可选自检:在「CC 模式」会话里调任意一个 cc_* 工具,返回里带 "build": "0.7.1" 即说明新代码已加载
46
+ (这也是判断「改了但没重启」的唯一可靠依据)。
47
+ 6. 不要做的事:
48
+ - 不要手工把 presets/ 拷进 ~/.dsh/.agent-presets/(dsh >= 0.1.7-alpha.1 已不读该目录,拷了也不生效);
49
+ - 不要手改 ~/.dsh/profiles/*/package.json(dsh plugin 会自己维护 dsh.profile.bundles);
50
+ - 不要为了「验证」反复重装 —— 装不上先看第 3 步的 dump-config 输出。
124
51
 
125
- ```bash
126
- # macOS / Linux(GitHub 安装)
127
- mkdir -p ~/.dsh/.agent-presets/cc
128
- cp -R ~/.dsh/profiles/web/node_modules/@xia-sc/dsh-cc-studio/presets/cc/. ~/.dsh/.agent-presets/cc/
52
+ 权限提醒:插件要写 <DSH_HOME>/cc-drafts/ 与 <DSH_HOME>/cc-library/(默认 ~/.dsh 下)。
53
+ 在 DSH 会话里由 Agent 执行安装时,这些路径在工作区之外,需要先把文件权限切到 danger-full-access;用户在终端自己执行则无此限制。
129
54
  ```
130
55
 
131
- > 若你自定义了 `DSH_HOME`,把上面命令里的 `~/.dsh` / `%USERPROFILE%\.dsh` 换成该路径;插件本体位于 `<DSH_HOME>/profiles/web/node_modules/@xia-sc/dsh-cc-studio/`。
132
-
133
- `agent.cordis.yml` 在一份 `standard` 拷贝上追加 `id: cc-studio-agent, name: '@xia-sc/dsh-cc-studio/agent'`,并把 `persona` 改为「共创搭档」——先问再填、每步 1-2 问。切换会话模式后胶囊自动出现。
134
-
135
- > 手工拷贝的目录**没有**安装记录,因此会被自动安装流程视为「你的自有文件」而跳过;想交回插件管理,删掉该目录后重启即可。
136
-
137
- > 升级到 `0.1.7-alpha.1` 后这个目录既不会被读取也不会再被写入:插件**不会**替你删任何东西,想删就自己删(`Remove-Item "$env:USERPROFILE\.dsh\.agent-presets\cc" -Recurse -Force`)。
138
-
139
- </details>
140
-
141
- > 卸载/删除插件**不会**删除 `<DSH_HOME>/.agent-presets/cc/`(自动安装也不注册删除动作)。
142
-
143
- ### 4. 重启与验证
56
+ ### 手动安装
144
57
 
145
58
  ```bash
146
- # 宿主行在启动时组合,装完必须重启 dsh web
147
- dsh web
148
-
149
- # 配置里应出现插件行
150
- dsh --profile web --dump-config | findstr dsh-cc-studio # Windows
151
- dsh --profile web --dump-config | grep dsh-cc-studio # macOS / Linux
152
-
153
- # —— 以下两项自检需要会话 cookie:用 dsh web 启动时打印的 token 换取 ——
154
- TOKEN='<dsh web 打印的 token>'
155
- COOKIE=$(curl -s -D - -o /dev/null "http://127.0.0.1:3080/?token=$TOKEN" \
156
- | sed -n 's/^[Ss]et-[Cc]ookie:[[:space:]]*\(dsh-auth-[^;]*\).*/\1/p' | head -1)
157
-
158
- # 客户端资源应返回 200。地址形如 /plugins/??<包名>/client.js&rev=<内容哈希>:
159
- # 缺 ?? 或缺 rev 都会 404,而 rev 每次改 lib/client.js 都会变,所以从首页里取。
160
- ASSET=$(curl -s http://127.0.0.1:3080/ -H "cookie: $COOKIE" \
161
- | grep -o '/plugins/??@xia-sc/dsh-cc-studio/client\.js&rev=[0-9a-f]*' | head -1)
162
- curl -s -o /dev/null -w "%{http_code} $ASSET\n" "http://127.0.0.1:3080$ASSET" -H "cookie: $COOKIE"
163
- # -> 200 /plugins/??@xia-sc/dsh-cc-studio/client.js&rev=…
164
-
165
- # RPC 自检(与其它 /api 同源:需要宿主/Origin 围栏 + 会话 cookie)
166
- curl -s http://127.0.0.1:3080/dsh-cc-studio-rpc/ping \
167
- -H 'content-type: application/json' \
168
- -H "cookie: $COOKIE" \
169
- --data '{"type":"client-request","rpcId":"smoke","method":"ping","payload":{}}'
170
- # -> {"type":"server-response","rpcId":"smoke","result":{"ok":true,"value":{"ok":true,"time":...}}}
171
- ```
59
+ # 从 npm 安装(推荐)
60
+ dsh plugin --profile web add @xia-sc/dsh-cc-studio
61
+ dsh plugin --profile web add @xia-sc/dsh-cc-studio@0.7.1 # 锁定版本
172
62
 
173
- Windows PowerShell 等价写法(`rev` 同样从首页取):
63
+ # 从 GitHub 源安装(可加 #v0.7.1 / #master 指定 tag / 分支)
64
+ dsh plugin --profile web add github:xia-sc/dsh-cc-studio
174
65
 
175
- ```powershell
176
- $TOKEN='<dsh web 打印的 token>'
177
- $s=New-Object Microsoft.PowerShell.Commands.WebRequestSession
178
- $null=Invoke-WebRequest "http://127.0.0.1:3080/?token=$TOKEN" -WebSession $s -UseBasicParsing
179
- $idx=(Invoke-WebRequest 'http://127.0.0.1:3080/' -WebSession $s -UseBasicParsing).Content
180
- $asset=[regex]::Match($idx,'/plugins/\?\?@xia-sc/dsh-cc-studio/client\.js&rev=[0-9a-f]+').Value
181
- Invoke-WebRequest "http://127.0.0.1:3080$asset" -WebSession $s -UseBasicParsing | Select-Object StatusCode
66
+ # 从本地仓库安装(开发 / 调试):装出来是 link:,改 lib/*.js 重启即生效
67
+ git clone https://github.com/xia-sc/dsh-cc-studio.git && cd dsh-cc-studio
68
+ dsh plugin --profile web add .
182
69
  ```
183
70
 
184
- 首页(`/`)与 RPC 端点都受会话 cookie 保护,不带 cookie 会得到 `401 dsh web authentication required`,这是正常行为,不代表插件没装上。会话 cookie 的**名字不是** `dsh-auth-127.0.0.1:3080`,而是 `dsh-auth-` + base64url(sha256(权威段)),本机即 `dsh-auth-VPhEEcLKeqRDBoBalzN2Nm7CnfxKhLE00pKIDWxt1sw`——从浏览器 devtools 抄,或用上面的 token 换取。另外,资源地址 `/plugins/??…&rev=…` 本身不走鉴权,缺 `??` / `rev` 只会 404,别把 404 误判成鉴权问题。浏览器刷新页面后切到 `CC 模式` 会话,输入框上方出现胶囊即安装成功。
185
-
186
- ### 5. 更新与卸载
187
-
188
- ```bash
189
- # 更新到 npm 上的最新版
190
- dsh plugin --profile web add @xia-sc/dsh-cc-studio@latest
191
-
192
- # 更新到默认分支(master)最新提交:重新执行 add,pnpm 会重新解析
193
- dsh plugin --profile web add github:xia-sc/dsh-cc-studio
71
+ `dsh plugin` 只是把参数转发给 profile 目录里的 pnpm,装完会把包名自动追加进该 profile 的 `dsh.profile.bundles`,不用手改 `package.json`。
194
72
 
195
- # 若解析未前移,先移除再装
196
- dsh plugin --profile web remove @xia-sc/dsh-cc-studio
197
- dsh plugin --profile web add @xia-sc/dsh-cc-studio@latest
198
-
199
- # 卸载(dsh 会同步把它从 dsh.profile.bundles 移除)
200
- dsh plugin --profile web remove @xia-sc/dsh-cc-studio
201
- ```
73
+ - **桌面版**:应用内左侧「插件」面板搜索 `@xia-sc/dsh-cc-studio` 安装,或用 `dsh plugin --profile desktop add @xia-sc/dsh-cc-studio`;生效方式是**退出并重新打开应用**(窗口里的刷新不足以加载宿主改动)。
74
+ - **CC 预设无需手工操作**:插件会自己把 `CC 模式` 带到 roster 里(≥ `0.1.7-alpha.1` 走随包补丁层 `presets/cc.patch.yml` 的声明行;≤ `0.1.6-alpha.2` 由插件挂载时装到 `<DSH_HOME>/.agent-presets/cc`)。升级 dsh 后若 `CC 模式` 从列表里消失,见下方常见问题。
75
+ - **包名迁移**:0.3.2 起由 `@dsh-plugins/dsh-cc-studio` 改为 `@xia-sc/dsh-cc-studio`(旧名不在本项目的 npm scope 下)。装过旧名的先 `remove` 再 `add`;`cc-library/`、`cc-drafts/` 与插件设置都不受影响。
202
76
 
203
- **从旧包名 `@dsh-plugins/dsh-cc-studio` 迁移**:包名变了就是另一个包,必须显式换掉,否则 `dsh.profile.bundles` 里会留下一行永远解析不到的旧名。
77
+ ### 更新与卸载
204
78
 
205
79
  ```bash
206
- dsh plugin --profile web remove @dsh-plugins/dsh-cc-studio
207
- dsh plugin --profile web add @xia-sc/dsh-cc-studio
80
+ dsh plugin --profile web add @xia-sc/dsh-cc-studio@latest # 更新到 npm 最新版
81
+ dsh plugin --profile web remove @xia-sc/dsh-cc-studio # 卸载(同时移出 dsh.profile.bundles)
208
82
  ```
209
83
 
210
- 记录在 `~/.dsh/cc-library/` 的角色卡与 `~/.dsh/cc-drafts/` 的会话草稿不会被卸载流程删除。
84
+ 卸载**不会**删除 `~/.dsh/cc-library/` 与 `~/.dsh/cc-drafts/` 里的角色卡和草稿。
211
85
 
212
- ### 6. 常见问题
86
+ ### 常见问题
213
87
 
214
88
  | 现象 | 处理 |
215
89
  | --- | --- |
216
- | 输入框上方没有胶囊 | 确认当前会话模式是 `CC 模式`;**dsh ≥ `0.1.7-alpha.1`**:`dsh --profile web --dump-config` 里应看到 `- id: preset-cc`(在 `# == @xia-sc/dsh-cc-studio` 那一层下),再看设置 →「Agent 预设」里 `CC 模式` 是否带「加载失败」诊断;**≤ `0.1.6-alpha.2`**:确认 `~/.dsh/.agent-presets/cc/` 下 `preset.yml` 与 `agent.cordis.yml` 都在且目录名是 `cc`(正常应由插件自动安装);两种情况都要重启 dsh web 后刷新页面 |
217
- | 想直接读预设台账(诊断用) | dsh 把每个 Remote 挂成 `POST /api/<namespace>/<method>`,envelope 与 connection RPC 相同(cookie 用 `/?token=…` 换)。`/api/agentPresets/list` 会剥掉 `name` 与 `broken`,**完整台账**要 `/api/pluginInventory/list`(看 `agentPresets` 里 `cc` 的 `broken` 是否为空、`cc-agent` 的 `fiberPhase` 是否 `active`)。另注:插件的 `info` 日志只进 Cordis logger,**不会**出现在 `dsh web` 的 stdout/stderr —— 别指望 grep `[dsh-cc-studio]` 判断装没装上 |
218
- | 工坊出现橙色条「草稿已新建」 | 该会话没有历史草稿(首次创建或草稿目录被清);已存档会话恢复时会改为蓝色条并显示 `creation_date`,下次写入后提示消失 |
219
- | 切 CC 模式报 `invalid config: S.prefix missing required value` | `presets/cc/agent.cordis.yml` 是 0.2.22 之前的旧版(persona 用了 `text:`),重新拷贝新模板 |
220
- | dsh 启动报 `cannot get property "webServer" without inject` | 插件版本低于 0.2.22,更新插件 |
221
- | 校验报错 | 必填 `spec: chara_card_v3` / `spec_version: 3.0` / `group_only_greetings`;主图标需唯一;正则需合法 |
222
- | 重启后浏览器报 `Failed to load plugins` / `web boot: 1 entry did not activate` / `import failed` | 包名迁移后**没有按新名重装**:profile 里的安装身份(`dsh.profile.bundles` 那行与 `dependencies` 里的 `link:`)还是旧名 `@dsh-plugins/dsh-cc-studio`,而包内 `package.json` 与 `lib/client.js` 已改叫 `@xia-sc/dsh-cc-studio`,客户端资源就解析不上(宿主照样起,只有浏览器那一半挂)。看一眼 `~/.dsh/profiles/web/node_modules/` 下的目录名是否等于 `package.json` 的 `name` 即可确认;修法是按新名重装(见「5. 更新与卸载」的迁移命令)→ 重启 `dsh web` → **硬刷新**(`Ctrl+Shift+R`;旧页面的引导图是缓存,普通刷新会复现同一句错) |
223
-
224
- ### 7. 桌面版(DeepSeek Harness Desktop)
225
-
226
- **桌面版就是同一个 dsh 宿主**(Electron 内嵌),插件照样装在 profile 的 `dsh.profile.bundles` 里,所以本插件**不需要任何额外适配**:三个客户端挂载点(胶囊 / 工坊 / 设置页)、`CC 模式` 预设、RPC 通道、草稿与角色卡落盘,都与 `dsh web` 一模一样(0.4.0 在桌面版 profile 上实测跑通全流程:胶囊 → 工坊 → 导入导出 → 草稿落盘)。
227
-
228
- 差异只有「怎么装」和「怎么生效」两步:
229
-
230
- | | `dsh web`(CLI) | 桌面版 |
231
- | --- | --- | --- |
232
- | 安装 | `dsh plugin --profile web add @xia-sc/dsh-cc-studio` | 应用内左侧「插件」面板安装 `@xia-sc/dsh-cc-studio`;装了 CLI 的话也可以用 `dsh plugin --profile desktop add @xia-sc/dsh-cc-studio` |
233
- | profile | 一般是 `web` | 一般是 `desktop`(`~/.dsh/profiles/desktop`),以应用内显示为准 |
234
- | 宿主 / 插件改动 | 重启 `dsh web` | 退出并重新打开桌面应用 |
235
- | 只改客户端(`lib/client.js`) | 刷新页面 | 在应用窗口里刷新(找不到刷新入口就重启应用) |
236
- | 数据位置 | `<DSH_HOME>/cc-drafts/`、`<DSH_HOME>/cc-library/`(默认 `~/.dsh`) | 同上,桌面版共用同一套 `DSH_HOME` 与落盘目录 |
90
+ | 输入框上方没有胶囊 | 先确认当前会话模式是 `CC 模式`;再 `dsh --profile web --dump-config` 看有没有 `preset-cc` 行,并到设置 →「Agent 预设」看 `CC 模式` 是否带「加载失败」诊断;**改动宿主/预设后必须重启 dsh + 刷新页面** |
91
+ | 找不到诊断入口 | 完整台账用 `POST /api/pluginInventory/list`(看 `agentPresets` 里 `cc.broken` 是否为空、`cc-agent` 的 `fiberPhase` 是否 `active`);插件的日志只进 Cordis logger,**不会**出现在 `dsh web` 的 stdout,别靠 grep 判断装没装上 |
92
+ | 重启后浏览器报 `Failed to load plugins` / `web boot: 1 entry did not activate` | 包名迁移后没按新名重装(profile 里的安装身份还是旧名)。看一眼 `~/.dsh/profiles/web/node_modules/` 下的目录名是否等于 `package.json` 的 `name`;修法是按新名重装 → 重启 → **硬刷新**(`Ctrl+Shift+R`) |
93
+ | 工坊顶部橙条「草稿已新建」 | 该会话没有历史草稿(首次使用或草稿目录被清)。已存档会话恢复时是蓝条并显示 `creation_date`,下次写入后提示消失 |
94
+ | 改完代码没变化 | 分三层看:改 `lib/client.js` → 刷新页面;改 `lib/index.js`(宿主)或预设 → **重启 dsh(桌面版重启应用)**;先看一眼工具返回里的 `build` 是不是你以为的版本 |
237
95
 
238
- > 桌面版的应用窗口本身就是它的 Web GUI(端口由应用分配),所以「重启应用」≈ 重启宿主、「刷新窗口」≈ 刷新页面,排查问题时两者可以混用。
96
+ ---
239
97
 
240
98
  ## 快速上手
241
99
 
242
- 1. 新建会话,会话模式选 **CC 模式**(胶囊随即出现在输入框上方)。
243
- 2. 直接说需求:「我想做雨城记忆典当行老板娘,世界观很薄」。
244
- 3. LLM 按 6 步推进,每一步都会先问你 1-2 个问题再落笔;每次调用 Tool,胶囊与工坊实时刷新:
245
- `cc_get_card`(总结进度并提问)→ `cc_patch_character`(讨论气质/关系后填四件套)→ `cc_patch_world`(讨论世界侧重后补 ≥3 维,`autoLorebook`)→ `cc_add_lorebook_entries`(讨论触发词后补 ≥5,至少 1 条 `constant`)→ `cc_patch_greetings`(讨论场景后补问候语)→ `cc_validate`。
246
- 4. 随时点胶囊进工坊手改。校验通过后:侧栏 `★ 保存当前`(已载入 ID 时原地覆盖,未载入则新建 ID)或 `+ 另存为新`,或导出 `JSON / PNG / CHARX`。后续可按 ID 载入/重命名/导出/删除(顶部 `已载入 ID:xxxx` 高亮当前卡),也可以直接对模型说「帮我载入 ID xxxx」。
100
+ 1. 新建会话,会话模式选 **CC 模式** —— 胶囊随即出现在输入框上方,后台会把 CC 预设挂上。
101
+ 2. 直接说需求,例如「我想做雨城记忆典当行老板娘,世界观很薄」。
102
+ 3. 模型按 **6 步**推进,每步先用 1-2 个开放问题问你的偏好,再落笔;每次调用 Tool,胶囊与工坊实时刷新:
103
+ `cc_get_card`(总结进度 + 提问)→ `cc_patch_character`(气质/关系 → 四件套)→ `cc_patch_world`(世界侧重 → ≥3 维 + `autoLorebook`)→ `cc_add_lorebook_entries`(触发词 → ≥5 条,至少 1 条 `constant`)→ `cc_patch_greetings`(开场场景 → 问候语)→ `cc_validate`。
104
+ 4. 随时点胶囊进工坊手改。校验通过后:侧栏 `★ 保存当前`(已载入 ID 时原地覆盖,否则新建)、`+ 另存为新`,或导出 `JSON / PNG / CHARX`;也可以直接对模型说「帮我载入 ID xxxx」。
247
105
 
248
- ## 特性
106
+ ---
249
107
 
250
- ### 融合工坊(客户端)
251
-
252
- - **布局**:输入框上方胶囊(CC 模式自动出现)→ `shell.overlay` 全屏工坊,左侧导航 **3 页**(**5维世界观 / 角色细化 / 世界书**)+ 左下角「**校验导出**」入口 / 自适应主区 / 268px 可折叠已存角色侧栏 / 主区底部两块默认收起的阅读辅助(实时 `card.json` 预览、CBS 速查)。深浅色自适应(DSW Token + 品牌紫 `#7c5cff` 固定)。
253
- - **导出入口只有两处**(0.4.1 归一):左下角「校验导出」与已存角色卡片上的「导出」,两者打开的是同一个**导出页**(`JSON / PNG / 写入PNG / CHARX / 校验`)——导出页导出的始终是当前工坊里的角色卡(标题后面就写着卡名,没名字时显示「未命名」),要导某张已存卡请先「载入」;顶部工具条不再有「导出 JSON」。卡片上的「导出」点下去会立刻变成「已切到 ✓」,若那张卡还没载入,导出页顶部会提示「要导它请先点它那行的『载入』」。
254
- - **风格标签**:在「角色细化」中以逗号分隔编辑 `tags`,实时写回 `data.tags`。
255
- - **5 维世界观**:年表 / 势力 / 地理 / 力量体系 / 日常 → `cc_patch_world(autoLorebook=true)` 自动生成带 `@@position / @@depth / @@activate` 的 Lorebook 条目(至少 1 条 `constant` 常驻;再次调用自动覆盖旧自动条目、保留手动条目)。五维默认是**文档式阅读排版**(无边框 textarea 按内容自动撑高,点进去就能改),写长文可点右上「⛶」开 720px 大框(带打开时快照,「取消」真回滚)。
256
- - **全量长文本大框编辑**:`description / personality / scenario / system_prompt / post_history_instructions / first_mes / alternate_greetings / group_only_greetings / mes_example / creator_notes` 都可点「⛶」开 720px 大框,实时同步,解决多行长文难预览/编辑的问题。
257
- - **已存角色侧栏(ID 化 CRUD)**:268px 可折叠(收成 40px 竖条),高亮当前载入卡(紫框 + 顶部 `已载入 ID:xxxx`,显示 ID 前 8 位),`★ 保存当前` 在已载入 ID 时原地覆盖、`+ 另存为新` 强制新建、`✎ 重命名` / `+ 新建`;搜索 / 载入 / 导出 / 删除落盘 `~/.dsh/cc-library/<id>.json`。
258
- - **导入导出**:侧栏 `⬆ 导入 JSON/PNG/CHARX` 自动识别容器;导出页 `⬇ JSON` / `⬇ PNG`(1×1 占位图)/ `⬆ 写入 PNG`(写入你上传的任意 PNG,自动剥离旧 `ccv3/chara` 块并 `CRC32` 重算)/ `⬇ CHARX`(打包 `card.json`)。
259
- - **中英双语**:完整 `zh / en` 词表(`locale: dshCcStudio`),跟随全局 `设置 → 通用 → 语言` 自动切换(胶囊/工坊/设置即时刷新,插件内无手动开关)。
260
- - **深浅色自适应**:全量使用 `var(--dsw-alias-bg-* / border-l1/l2 / label-primary/secondary)`,主按钮/选中态固定品牌紫,刷新即生效。
108
+ ## 功能
261
109
 
262
- ### CC 模式(模型侧 14 个 Tool)
110
+ ### 融合工坊(客户端)
263
111
 
264
- - **6 步工作流 + 共创约束**:每步前 LLM 必须用 1-2 个开放问题征求偏好(气质/关系/世界侧重/触发词/开场场景等),严禁未讨论就一次性推断填满;角色四件套 → 五维 ≥3 → 世界书 ≥5 → 问候语 → `cc_validate` 才可收口。
265
- `cc_get_card` / `cc_patch_character` / `cc_patch_world` / `cc_add_lorebook_entries` / `cc_patch_greetings` / `cc_validate`
266
- - **Lorebook 精细管理**:`cc_delete_lorebook_entries` / `cc_update_lorebook_entry`。
267
- - **已存库 CRUD(与侧栏共享 ID)**:`cc_list_library` / `cc_save_to_library` / `cc_load_from_library` / `cc_delete_from_library` / `cc_rename_in_library` / `cc_get_library_entry`——用户说「帮我更新/载入 ID xxxx」时模型可直接操作,无需手动点 UI。
112
+ - **布局**:胶囊(CC 模式下常驻)→ `shell.overlay` 全屏工坊;左侧 3 页导航(**5 维世界观 / 角色细化 / 世界书**)+ 左下角「**校验导出**」,中部自适应阅读区,右侧 268px 可折叠「已存角色」(收起成 40px 竖条)。主区底部两块默认收起:实时 `card.json` 预览与 CBS 速查。
113
+ - **导出入口只有两处**(0.4.1 归一):左下角「校验导出」与卡片上的「导出」,打开的是同一个导出页(`JSON / PNG / 写入PNG / CHARX / 校验`)。导出页导出的**永远是当前工坊里的卡**(标题后带卡名),要导某张已存卡请先「载入」——卡片按钮点下去会先变成「已切到 ✓」,若那张卡尚未载入,页内会给出醒目提示。
114
+ - **文档式阅读排版**:字段是无边框 textarea、按内容自动撑高,点进去即可改;长文点「⛶」开 720px 大框(带打开时快照,「取消」真回滚)。写作是主线,手动编辑是次要入口。
115
+ - **5 维世界观**:年表 / 势力 / 地理 / 力量体系 / 日常 → `autoLorebook` 自动生成带 `@@position / @@depth / @@activate` 的条目(至少 1 条 `constant`;再次调用覆盖旧自动条目、保留手工条目)。
116
+ - **ID 化 CRUD**:`★ 保存当前`(已载入时原地覆盖)/ `+ 另存为新` / `✎ 重命名` / `+ 新建` / 载入 / 删除,搜索、高亮当前卡,落盘 `<DSH_HOME>/cc-library/<id>.json`。
117
+ - **导入导出**:`⬆ 导入 JSON/PNG/CHARX` 自动识别容器;`⬇ JSON`、`⬇ PNG`(1×1 占位图)、`⬆ 写入 PNG`(写入你上传的任意 PNG,自动剥离旧 `ccv3/chara` 块并重算 CRC32)、`⬇ CHARX`(打包 `card.json`)。
118
+ - **中英双语 + 深浅色**:完整 `zh / en` 词表,跟随 `设置 → 通用 → 语言` 实时切换;配色走 `var(--dsw-alias-*)`,主操作固定品牌紫 `#7c5cff`。
268
119
 
269
- ### 校验与规范
120
+ ### CC 模式(模型侧 23 个 Tool)
270
121
 
271
- - 宿主实时校验:`spec / group_only_greetings` 必填、主图标唯一性、正则合法性,`spec: chara_card_v3 / spec_version: 3.0`。
272
- - CCv3 全覆盖:`name / nickname / tags / description / personality / scenario / system_prompt / post_history_instructions / first_mes / alternate_greetings / group_only_greetings / mes_example / creator_notes / assets / character_book`,支持 CBS `{{char}} / {{random}} / {{roll}}`。
122
+ **6 步工作流 + 共创约束**:每步前必须先问偏好,严禁无讨论就一次性填满;世界书的完成态是「**≥5 条且至少 1 条共创**」(纯自动条目不算完成)。每次返回只有一份 `workflow.next`(下一步)+ `workflow.state`(四项三态进度)+ `message`(给用户的一句话),另有 `build` 标明插件版本。
273
123
 
274
- ## 结构
124
+ | 分类 | 工具 |
125
+ | --- | --- |
126
+ | 工作流(必调) | `cc_get_card` / `cc_patch_character` / `cc_patch_world` / `cc_add_lorebook_entries` / `cc_patch_greetings` / `cc_validate` |
127
+ | 世界书质量 | `cc_simulate_trigger`(拿一句用户会说的话验命中)/ `cc_lint_lorebook`(静态体检,含**最坏情况单次触发量**)/ `cc_patch_book_meta`(命名 / `scan_depth` / `token_budget` / 递归扫描) |
128
+ | 条目管理 | `cc_update_lorebook_entry` / `cc_delete_lorebook_entries` |
129
+ | 导出与起点 | `cc_preview_export`(体积、估算 token、字段清单、重复内容量)/ `cc_new_card`(破坏性,须用户同意后带 `confirm:true`) |
130
+ | 人物关系(0.8.0) | `cc_get_relations` / `cc_patch_relations` / `cc_render_relations` / `cc_group_check` |
131
+ | 已存库 CRUD | `cc_list_library` / `cc_save_to_library` / `cc_load_from_library` / `cc_delete_from_library` / `cc_rename_in_library` / `cc_get_library_entry` |
275
132
 
276
- ```
277
- dsh-cc-studio/
278
- ├── package.json # @xia-sc/dsh-cc-studio, dsh.bundle.patch + dsh.client, exports ./client ./agent
279
- ├── cordis.patch.yml # 补丁层 1:宿主行插入(id dsh-cc-studio)
280
- ├── lib/
281
- │ ├── index.js # host: /dsh-cc-studio-rpc(validate, cc_getDraft/cc_setDraft/cc_patchDraft, cc_isCcMode,
282
- │ │ # cc_validateDraft, 草稿槽 cc_migrateDraft, 已存库 cc_*Library, 容器 cc_importFromPng/cc_exportPng(+imageB64)/
283
- │ │ # cc_importFromCharx/cc_exportCharx, CRC32/ZIP/STORE&DEFLATE)
284
- │ ├── agent.js # CC 模式 Tools:6 步共创 + 2 Lorebook 管理 + 6 已存库 CRUD = 14 个,含「先与用户讨论」提示
285
- │ └── client.js # client: dock 胶囊 + overlay 工坊 + settings.section(DSW Token 深浅色、品牌紫、
286
- │ # 五维回显、长文本大框、JSON/PNG/CHARX 导入导出/写入)
287
- ├── presets/
288
- │ ├── cc.patch.yml # 补丁层 2:CC 预设声明行(dsh ≥ 0.1.7-alpha.1)
289
- │ └── cc/ # CC 预设目录模板(dsh ≤ 0.1.6-alpha.2,插件挂载时安装到用户根)
290
- │ ├── preset.yml
291
- │ └── agent.cordis.yml
292
- ├── tests/ # 10 个测试文件、380 项断言(不随包发布)
293
- │ ├── rpc-channel.test.mjs # host 半 RPC 通道回归(假 ctx + 真实 http,45 项断言)
294
- │ ├── preset-install.test.mjs # 预设安装决策 + native 让位 + 两份清单防漂移 + 行契约,79 项断言
295
- │ ├── cc-detection.test.mjs # CC 模式探测的源码级守卫,51 项断言
296
- │ ├── client-greetings.test.mjs # 客户端问候语与 i18n 守卫,62 项断言
297
- │ ├── draft-slot-sync.test.mjs # 草稿槽行为级回归(假 React/slot/RPC harness),18 项断言
298
- │ ├── nav-highlight.test.mjs # 工坊步骤导航三态回归(选中/键盘焦点/悬停互斥),23 项断言
299
- │ ├── clear-card.test.mjs # 「清空当前角色卡」二次确认回归,20 项断言
300
- │ ├── export-entry.test.mjs # 导出入口归一回归(三处导出收成两处),31 项断言
301
- │ ├── close-button.test.mjs # 工坊关闭按钮 ✕(悬停红底)回归,14 项断言
302
- │ └── data-root.test.mjs # 落盘根:DSH_HOME 优先 + 读时回退 ~/.dsh,37 项断言
303
- ├── CHANGELOG.md # 完整版本历史
304
- ├── README.md # 中文(默认)
305
- └── README_EN.md # English
306
- ```
133
+ 几条值得知道的约定:
307
134
 
308
- > `dsh-cc-agent` 已于 `5f95110` 合并为 `lib/agent.js`(`@xia-sc/dsh-cc-studio/agent`),无需单独安装;`CC 模式` 预设仅挂该单一来源,不污染 `standard`。
135
+ - `cc_patch_world` 的 **`loreKeys`**:为每一维自报触发词(真实对话里用户会说的实体名)。不给的话自动条目只能用维度名当 key,**真实对话永远命中不了**。同一实体被分给多个维度时会当场警告。
136
+ - **载入后直接保存会更新原卡**(草稿旁记着来源 id),不会再莫名多出一张同名重复卡;改名同时改列表名与卡内 `data.name`。
137
+ - 写类工具支持 **`expectedRev` 乐观锁**;不传也会在返回里给 `revDrift` 与 `draftStatus.watchedRev`,多端同时改卡时不会静默覆盖。
138
+ - 工具返回的 `build` 与 `package.json` 的 `version` 同步 —— 能一眼确认当前跑的是哪一版代码。
309
139
 
310
- ## 开发与测试
140
+ ### 群聊与人物关系(0.8.0)
311
141
 
312
- ```bash
313
- npm test # 10 个文件、380 项断言(十个 node 脚本串联)
314
- node tests/rpc-channel.test.mjs # 只跑 host 半 RPC 通道回归(45 项断言)
315
- ```
142
+ 做一批「互相有关系的卡」时,CCv3 没有关系字段 —— 硬造会污染导出、别的客户端也不认。所以分成两层:
316
143
 
317
- - **改客户端**:`lib/client.js` 改动刷新页面即可;跑着 dsh 仓库的 `pnpm run dev:web` 时可热更新。
318
- - **改宿主**:`lib/index.js` 改动需重启 dsh web(宿主行在启动时组合)。
144
+ - **插件层图谱是真源**:在工坊右侧「已存角色」里新建**分组**,把同一世界观的角色拉进去,再用分组旁的「关系」按钮打开**关系视图**维护关系 —— 三维 = **方向(A→B 与 B→A 可以不同)× 类型(师徒 / 恋慕 / 敌对…10 类)× 强度(1-5)**。节点有两类:有独立卡的角色,以及**卡内 NPC**(如「柳长老」,没有自己的卡)—— 所以同一张图谱既能服务多卡群聊,也能让单卡「立体」。数据落在 `<DSH_HOME>/cc-groups/`,**不写进卡的任何 CCv3 字段**。
145
+ - **渲染让卡自包含**:「渲染到当前卡」会把「我的关系」写进 `description` 的固定标记区(`<!-- cc-relations:begin --> … <!-- cc-relations:end -->`),分享出去的卡别人拿到就能用;重复渲染是**替换**,不会越写越长。模型侧对应 `cc_render_relations`(支持 `dryRun` 预览)。
146
+ - **跨卡体检**(关系视图的「体检」/ `cc_group_check`)会报:孤儿节点(卡已删)、悬空关系、重名节点、未渲染或已过期的关系段,以及**群聊每轮固定开销**(成员卡常驻条目之和 vs 预算)—— 群聊的开销是「乘法」:5 张卡各带一条常驻,每轮就是 5 份。
147
+ ### 校验与导出
319
148
 
320
- ## 外观
149
+ - 宿主实时校验:`spec: chara_card_v3` / `spec_version: 3.0` / `group_only_greetings` 必填、主图标唯一、正则合法;`cc_validate` 另给逐项 errors 与 warnings(缺字段、keys 质量问题、预算等)。
150
+ - CCv3 字段全覆盖:`name / nickname / tags / description / personality / scenario / system_prompt / post_history_instructions / first_mes / alternate_greetings / group_only_greetings / mes_example / creator_notes / assets / character_book`,支持 CBS `{{char}} / {{random}} / {{roll}}`。规范依据:[CCv3 SPEC_V3.md](https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md)(权威)。
321
151
 
322
- 深浅色通过 `var(--dsw-alias-*)` 自动适配(`body[data-ds-dark-theme]`),主操作固定 `#7c5cff` 保证对比度。切换路径:设置 → 外观 → 浅色/深色/跟随系统,刷新后工坊立即生效。
152
+ ---
323
153
 
324
154
  ## 兼容与权限
325
155
 
326
- 上架元数据(`dsh.compatibility` / `engines` / 运行依赖)与权限边界都集中在这里;DSH STORE 的固定源审查读的也是这几处。
156
+ 上架元数据(`dsh.compatibility` / `engines` / 运行依赖)与权限边界集中在这里,DSH STORE 的固定源审查读的也是这几处。
327
157
 
328
158
  | 项 | 值 |
329
159
  | --- | --- |
330
- | DSH 兼容范围 | `>=0.1.5-rc.1`(`package.json` 的 `dsh.compatibility.dsh`) |
331
- | 逐版本证据 | `dsh.compatibility.dshReleases` 里 `0.1.5-rc.1` / `0.1.5-rc.2` / `0.1.6-alpha.1` / `0.1.6-alpha.2` / `0.1.7-alpha.1` / `0.1.7-rc.1` / **`0.2.0-rc.2`** 为 `compatible`。**没实测过的版本不写**(`0.1.7-alpha.2`、`0.1.7-rc.2`、`0.2.0-rc.1`、`0.2.1-alpha.1` 保持未声明,商城显示为未知),而不是先写 `compatible` 再补测 |
332
- | Node.js | `engines.node: ">=22"`(实测运行时 Node v26.9.0) |
333
- | 宿主形态 | `dsh web`(CLI)与 **DSH 桌面版(DeepSeek Harness Desktop)** 都是同一套宿主 + profile bundles 机制,**均支持**(差异与安装方式见 [7. 桌面版](#7-桌面版deepseek-harness-desktop)) |
334
- | 客户端平台 | `dsh.client.platform: "web"` —— 这是**浏览器半**的平台标识,与 dsh 的 profile 名(`web` / `desktop` …)不是一回事;桌面版与 CLI 加载的是同一份客户端 bundle |
335
- | 运行依赖 | **无**。`lib/*.js` 只 `import` `node:` 内建与相对路径;随包的补丁 / 预设是静态 YAML,没有安装期脚本 |
336
- | 生命周期脚本 | **无** `preinstall` / `install` / `postinstall` / `prepare`(只有 `test` 与 `prepublishOnly`,只在本仓库跑,不发给安装端) |
337
- | 权限 · 文件 | 读 `<DSH_HOME>`(含旧根 `~/.dsh`)下自己的三个目录:`cc-drafts/`、`cc-library/`、`.agent-presets/cc/`(后者只在 dsh ≤ `0.1.6-alpha.2` 上写);另读自身 `package.json`。不写宿主配置,不碰别的插件的数据 |
338
- | 权限 · 网络 | 无。宿主半只在宿主 `webServer` 上注册 `POST /dsh-cc-studio-rpc/<endpoint>`;浏览器半只打同源 RPC |
339
- | 权限 · 命令 | 无。不起子进程、不执行 shell |
340
- | 权限 · 凭据 | 不读也不存任何 token / 密钥 / cookie。只读两个环境变量:`DSH_HOME`、`DSH_CC_STUDIO_PRESET_INSTALL`。宿主 HTTP 路由复用宿主自己的 cookie 围栏(`connection.requestRejection`),插件不解析凭据 |
160
+ | DSH 兼容范围 | `>=0.1.5-rc.1`;逐版本矩阵里 `0.1.5-rc.1` / `0.1.5-rc.2` / `0.1.6-alpha.1` / `0.1.6-alpha.2` / `0.1.7-alpha.1` / `0.1.7-rc.1` / `0.2.0-rc.2` 为 `compatible`。**没实测过的版本不写**(`0.1.7-alpha.2` / `0.1.7-rc.2` / `0.2.0-rc.1` / `0.2.1-alpha.1` 保持未声明) |
161
+ | 宿主形态 | `dsh web`(CLI)与 **DSH 桌面版**同一套宿主 + profile bundles 机制,**均支持** |
162
+ | 客户端平台 | `dsh.client.platform: "web"` 是**浏览器半**的平台标识,与 profile 名(`web` / `desktop`)不是一回事;两者加载同一份客户端 bundle |
163
+ | 运行依赖 / 生命周期脚本 | **都没有**。`lib/*.js` 只 `import` `node:` 内建与相对路径,随包补丁与预设是静态 YAML |
164
+ | 权限 · 文件 | 只读写 `<DSH_HOME>`(含旧根 `~/.dsh`)下自己的三个目录:`cc-drafts/`、`cc-library/`、`.agent-presets/cc/`(最后一个只在 dsh ≤ `0.1.6-alpha.2` 上写),另读自身 `package.json` |
165
+ | 权限 · 网络 / 命令 / 凭据 | 无网络请求、不起子进程、不读也不存任何 token 或 cookie。只读两个环境变量:`DSH_HOME`、`DSH_CC_STUDIO_PRESET_INSTALL`。HTTP 路由复用宿主自己的 cookie 围栏(`connection.requestRejection`),插件不解析凭据 |
166
+
167
+ > **为什么商城不会给它「自动通过」**:STORE 的自动低风险通道要求运行时代码完全不出现文件 / 网络 / 命令 / 凭据四类信号,而本插件的核心功能就是草稿与角色卡落盘(文件信号)并读 `DSH_HOME`(扫描器把任何 `process.env` 读取都算凭据信号)。这两条不会为了迎合扫描器而消除 —— 对这类合法插件,商城的正确档位是 `user-reviewed`。隔离环境下的安装 / 启动 / 卸载证据见 [CHANGELOG.md](./CHANGELOG.md) 的 `0.3.7` 小节。
341
168
 
342
- > **为什么商城不会给它「自动通过」**:DSH STORE 的自动低风险通道(`source-verified`)要求运行时代码**完全不出现**文件、网络、命令、凭据四类信号;而本插件的核心功能就是角色卡与草稿落盘(文件信号),并且要读 `DSH_HOME`(扫描器把任何 `process.env` 读取都算凭据信号)。这两条不会为了迎合扫描器而消除 —— 对这类合法插件,商城的正确档位是 `user-reviewed`(展示变更、由用户逐次确认安装)。
169
+ ---
343
170
 
344
- 一次性 Profile 的安装 / 启动 / 卸载证据见 [CHANGELOG.md](./CHANGELOG.md) 的 `0.3.7` 小节:隔离 profile + 隔离 `DSH_HOME` / `HOME` / `USERPROFILE`,三个前端挂载点全部 `active`、预设 roster 含 `cc`、RPC 往返一致、PNG / CHARX 导出→导入往返一致,真实 `~/.dsh` 全程零变化。
171
+ ## 开发与测试
345
172
 
346
- ## 规范依据
173
+ ```bash
174
+ npm test # 12 个文件、509 项断言,全绿才算过
175
+ node tests/tools-contract.test.mjs # 只跑 CC 工具链契约(88 项)
176
+ ```
347
177
 
348
- - [CCv3 SPEC_V3.md](https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md)(权威)
349
- - [concepts.md](https://github.com/kwaroran/character-card-spec-v3/blob/main/concepts.md) 已过时,仅参考
178
+ - 改 `lib/client.js`:刷新页面即可;改 `lib/index.js` / 预设:**重启 dsh**。
179
+ - 架构与约定(三半分工、RPC 线协议、预设两代投递、落盘根、测试隔离要求、常见坑)都在 [AGENTS.md](./AGENTS.md) —— 动代码前先读它。
350
180
 
351
181
  ## 更新日志
352
182
 
353
- 完整历史见 [CHANGELOG.md](./CHANGELOG.md)。最近几版:
354
-
355
- - `0.4.1` **导出入口归一**:同一个「导出」原本在工坊里出现三处(顶部「⬇ 导出 JSON」/ 左侧导航第 4 步「校验导出」/ 已存角色卡片里的「导出」),彼此重复又不一致。现在顶部那枚删掉;左侧导航与顶部胶囊都只留写作三步,「校验导出」与左下角那枚「校验」按钮合并成一枚入口,点开即是导出页;卡片上的「导出」保留原位置、但改成切到同一页 —— 导出动作只剩导出页那一套实现(卡片「导出」不再直接下载 JSON,`store.exportLibraryEntry` 旁路已删),导出页新增一行说明「导出的是当前工坊里的卡,要导某张已存角色请先载入」。**另一半是文档**:README / README_EN 写明**桌面版(DeepSeek Harness Desktop)支持** —— 新增「7. 桌面版」一节(安装入口、profile 名、重启应用 vs 刷新窗口、数据位置),「兼容与权限」表补「宿主形态」行,并把容易误读的 `Profile | web` 改名为「客户端平台」。另外按实机反馈补了四处:导出页标题带上当前卡名(没名字时显示「未命名」)、卡片「导出」点下去立刻变成「已切到 ✓」并在 6 秒后复原、导出页在「你点的那张卡还没载入」时给出醒目提示、左下角那枚入口按钮**不做选中态**(它一旦跟着亮,就和卡片那枚反馈凑成「两处看起来像选中」)。工作坊头部的「收起」也换成了「✕」图标按钮(悬停红底白字,点击关闭)。测试 335 → 380 项(新增 `tests/export-entry.test.mjs` 31 项、`tests/close-button.test.mjs` 14 项)。
356
- - `0.4.0` 修工坊左侧步骤列表的高亮:鼠标点过某一步后,那一项周围会多出一圈「莫名其妙的描边」,再用顶部胶囊切步时描边还赖在旧项上,看起来像同时选中了两项。根因是 `navItem` 只画 `s.cur` 的选中态、从没管过浏览器焦点(`<button>` 被点击后一直持有焦点,宿主/UA 的焦点描边就留在按钮外沿)。现在:导航项 `onMouseDown` 阻止默认(鼠标点击不抢焦点、键盘 Tab 照旧)、`outline` 由插件自己接管(只在 `:focus-visible` 时给 2px 品牌色环)、选中态换成品牌紫淡底 + 左竖条 + `aria-current`,并补上 hover 反馈与「鼠标一动就收起焦点环」。新增**「清空当前角色卡」按钮**(左侧底部「校验」下面,`window.confirm` 二次确认后换回空卡,并解除与已存角色的关联 —— 否则接着点「保存当前」会把库里那张覆盖成空卡)。**并重构了工坊 UI(本版主线)**:砍掉右侧占地 360px 那一栏,实时 CCv3 预览与 CBS 速查收到主区底部、**默认全部折叠**(预览那行仍显示 spec 与通过/失败徽章;原「融合说明」那块纯介绍文案已删除);字段改成「文档式」阅读排版(无边框 textarea + `field-sizing: content` 自动撑高),手动编辑退成次要入口(长文走 ⛶ 大框),阅读区从 ~700px 拓到 ~876px。功能一个没少。`tests/nav-highlight.test.mjs`(23 项)与 `tests/clear-card.test.mjs`(20 项)钉住新行为。测试 292 → 335 项。
357
- - `0.3.8` 补 DSH STORE 上架契约([Store #1173](https://github.com/AI-Scarlett/DSH-Store/issues/1173)):`engines.node: ">=22"`、`dsh.compatibility`(兼容范围 + **只写实测过版本**的精确矩阵)、删掉那个从 0.3.0 起就没被任何代码 import 过的 `@deepseek-ai/cordis` 运行依赖,README / README_EN 新增「兼容与权限」披露节,`tests/preset-install.test.mjs` 加 11 项契约守卫(281 → 292 项断言)。**但这个 issue 光改仓库修不完**:商城条目的包名还停在 0.3.0 的旧名 `@dsh-plugins/dsh-cc-studio`,STORE 复检第一步就因「包名与条目身份不符」判 `update-blocked`,得先由 STORE 侧迁移条目身份(重新提交也绕不过,`entryIds` 会撞旧条目);而 files / credentials 两个权限信号是本插件的核心功能(角色卡草稿落盘 + 读 `DSH_HOME`),自动低风险通道**不可能**通过,商城只应按 `user-reviewed`(用户逐次确认)收录。另已做完 **dsh `0.2.0-rc.2` 兼容性审计**(隔离宿主实测宿主行/预设行组合、RPC 线协议与围栏、会话槽 key、预设 roster 含 `cc` 且 `broken` 空、三个客户端挂载点 `active`、PNG/CHARX 往返逐字一致、真实 `~/.dsh` 零变化),矩阵补上 `0.2.0-rc.2: compatible`;`0.2.0-rc.1` / `0.2.1-alpha.1` 未测,仍不声明。
358
- - `0.3.7` dsh `0.1.7-rc.1` 兼容性审计:**接口面无一处需要适配**(隔离宿主实测了 RPC 路由/线协议、预设 roster、三个前端挂载点、草稿槽 key、落盘根、PNG/CHARX 往返)。真正的修复是预设里**一行自始漏抄**:`command-goal` 在内置 `standard` 里从 `0.1.6-alpha.2` 起就有,本预设初次拷贝时就漏了它 —— 不报错、不判 broken,只是 CC 模式会话少了 `/goal` 斜杠命令(与 0.3.4 补回的 `present` 同类),现已两份载体同步补齐并加了**行集快照**守卫。另更正 3 处会误导下次升级的文档口径(「异步迭代 `IncomingMessage` 必抛」实测不成立且官方 `/api` 桥自己就在用;`/api/agentPresets/list` 其实带可选 `name`/`description`/`broken`;channel/endpoint 命名正则在 `dsh-client-connection` 而非 `webServer.register`),并给「客户端 `preset.ccLabel` 必须逐字等于宿主预设显示名」这条隐性耦合补了跨文件守卫。顺带精简了 roster 下拉里「CC 模式」的介绍文案:原来把模型侧的 6 个工具名(`cc_get_card` / `cc_patch_character` / …)全列在用户界面上,既撑满下拉项又对用户没有信息量(工具名只对读 persona 的模型有意义),现在只讲「模型先问再填 / 胶囊实时同步 / 工坊全屏编辑 / 导出 JSON、PNG、CHARX」。测试 278 → 281 项。
359
- - `0.3.6` 修 dsh `0.1.7-alpha.1` 上「`CC 模式` 预设消失」+ 落盘根统一。① 预设:那一版起 dsh 的预设只来自组合里的**声明行**,`<DSH_HOME>/.agent-presets/` 已无人读取(目录还在、只是没人看),插件改为随包带一层补丁 `presets/cc.patch.yml`(与内置 `standard` 同构的 `@deepseek-ai/dsh-agent-preset` 声明),新版上不再写任何文件,目录安装只为 ≤ `0.1.6-alpha.2` 保留并在新版自动让位。② 草稿与角色库:以前写死 `~/.dsh`、不认 `DSH_HOME`(自定义 `DSH_HOME` 的用户两套根并存,隔离实测还会写进真实 `~/.dsh`),现在改为 **`DSH_HOME` 优先 + 读时回退 `~/.dsh`**,未设置时路径与以前完全一致。测试 216 → 278 项。
360
- - `0.3.5` 修 #5「前端与 Tools 读到不同草稿槽」:`useCcPreset` 读的 `useSessions().current` 字段在 dsh `0.1.6-alpha.2` 的 `SessionListState` 里并不存在(恒为 `null`),加上启动时那次无 key 的拉取占掉了全局节流,前端一直用 `default` 槽 —— 而模型经 Tools 写的是 `session-<会话id>` 槽,于是「模型说写好了 / 工坊说没数据」。现在会话 id 只从 slot props 取并发布到 store、拉草稿没有会话 id 就一次都不发、节流按 key、主机回传 key 不一致时不渲染而是告警;另修胶囊闪退(根域实例每秒钟把会话域实例判定的 CC 状态清掉)并新增 `cc_migrateDraft` 与「迁入本会话槽」一键救回。测试 158 → 216 项(新增行为级 `tests/draft-slot-sync.test.mjs`)。
361
- - `0.3.4` 适配 dsh `0.1.6-alpha.2` 并补回两处预设漏抄:CC 预设缺 `present` 行(CC 模式下模型没有「登记交付物」的工具,且不报错)、`tool-subagent` 行缺 `modelSelectionSettings: true`(子代理的指定模型入口被静默关掉);顺带补上 alpha.2 新增的 `tool-plugin-manager` 行(`disabled`,与内置 `standard` 对齐到只剩有意的行差)。新增 7 项预设行契约守卫。
362
- - `0.3.3` 发布流程自动化:打 `v*` tag 即由 GitHub Actions 发布到 npm(OIDC trusted publishing,零密钥)并自动建 GitHub Release;手动触发默认只做安全自检。插件运行时行为未变。
363
- - `0.3.2` 包名迁移至 `@xia-sc/dsh-cc-studio`(原 `@dsh-plugins` 不是本项目持有的 npm scope),并首次发布到 npm;新增 `publishConfig.access` / `prepublishOnly` 等发布元数据。
364
- - `0.3.1` 适配 dsh `0.1.6-alpha.1`:CC 预设里的 `workflow-worker-thread` 行换成 `workflow-ptc`,否则整份预设被判「加载失败」、CC 模式直接不可选。
365
- - `0.3.0` 移除「点子」页:工坊导航改为 4 页(5维世界观 / 角色细化 / 世界书 / 校验导出),`⛶ 大框` 能力改用统一 `fieldHead()` 落到全部长文本 string 字段,侧栏搜索保留。同步修掉该改动引入的数组往返回退(`[]` 会被写成 `[""]`,即凭空多一条空白问候语);并把问候语字段改为**逐条独立编辑**(一条 = 一个编辑框),根除「多段问候语一编辑就被拆成多条」的静默损坏,顺带补上问候语增删与 10 条上限对齐。另修大框「取消」真正回滚、清掉自 67172fd 起就调不通的 `expandIdea` / `expandWorld` 死代码、**完成全量 i18n 接线**(此前词表已建好但大量调用点硬编码中文,切到 English 仍显示中文;现全部 122 条中文字面量接入词表,中文界面逐字未变)、**CC 预设改为自动安装**(此前需手工拷贝),并修掉**首次切到 CC 模式时胶囊不出现**(探测读错了 `projectionValues.agentPreset` 字段,导致必须刷新页面或切换会话才出现)。
366
- - `0.2.22` 适配 dsh `0.1.5-rc.1` 启动崩溃:`connection.rpc.handle()` 对外部插件不可用,host 半改为在 `webServer` 上自注册 `/dsh-cc-studio-rpc` 前缀路由并实现同一套 RPC 线上协议;请求体改事件式读取;修 `presets/cc` persona 的 `prefix`;新增 23 项回归测试。
367
- - `0.2.21` 修复 #2 草稿静默丢失:草稿变更即落盘 `~/.dsh/cc-drafts/<会话>.json`,重启/换会话自动恢复;建空会警告、恢复会提示。
183
+ 完整历史见 [CHANGELOG.md](./CHANGELOG.md)。最近三版都是「另一个 LLM 以工具使用者身份跑回归」挖出来的问题:
184
+
185
+ - `0.8.0` **人物关系图谱与群聊分组**:CCv3 没有关系字段 → 插件层图谱(`<DSH_HOME>/cc-groups/`)做真源,三维(方向 × 类型 × 强度),节点分「有独立卡的角色」与「卡内 NPC」;`cc_render_relations` 把关系渲染进 `description` 的固定标记区让卡自包含(幂等、可 `dryRun`、空图谱 = 清空)。新增 4 个工具(19 → 23)与工坊侧的**分组选择器 + 关系视图**(`s.cur === 4`,不进左侧导航)。另修 `cc_save_to_library` 的 `action` 谎报(传库里不存在的 id 派生新卡时报 updated)与 `cc_render_relations` 漏赋值(`changed:true` 却没写进卡)。测试 464 → 509 项。**需重启 dsh(桌面版重启应用)**。- `0.7.1` 修 **B1**:dsh 重启后第一次 `cc_get_card` 报 `value is not lossless JSON` —— DSH 对返回值做 lossless-JSON 校验,**任何嵌套 `undefined` 都会让整次调用失败**,而外部导入的卡(PNG / CHARX)可能整个缺 `spec_version` / `creation_date`。三层修法:加载即补齐(`normalizeCardShape`)、`creation_date` 兜底 `null`、返回前统一 `sanitizeJson()`。另加 `build` 版本标识与 `watchedRev`,`changed` 与 `rev` 改用同一套判据。
186
+ - `0.7.0` 修 **N2**:长五维 + autoLorebook 原文照搬会让**一句话**吃满整份世界书预算(实测 1139 token / 预算 1200),而调大 `token_budget` 还能把告警一并消掉 → `cc_lint_lorebook` 新增**最坏情况单次触发量**。另修:`creator` 此前**没有写入路径**(validate 却一直催)、主动重置不再被误报「内容可能已丢失」、不传 `expectedRev` 也会提示 `revDrift`、空改动不再消耗 `rev`。
187
+ - `0.6.0` 修 **P0-6**:草稿被外部(工坊 / host 恢复)换掉时模型完全无感知,实测因此误伤过另一张卡 → 每个返回都带 `cardName` / `cardId` / `rev`,`getDraft()` 以盘为准重载,写类工具支持 `expectedRev` 乐观锁。
188
+ - `0.5.0` 第一轮 LLM 测试的整轮修复:`loreKeys` 解决「自动条目是死条目」、世界书完成态改为「≥5 条且 ≥1 条共创」、`cc_validate` 有了终态、载入后保存不再产生重复卡,并新增 5 个工具(14 → 19)。
189
+
190
+ **改完后记得**:宿主/预设改动要重启 dsh(桌面版重启应用),客户端改动刷新页面即可。
368
191
 
369
192
  ## License
370
193