@xia-sc/dsh-cc-studio 0.3.7 → 0.4.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 +31 -5
- package/lib/client.js +218 -114
- package/package.json +17 -5
package/README.md
CHANGED
|
@@ -15,7 +15,8 @@ DSH(DeepSeek Harness)插件:输入框上方的胶囊 → 全屏融合工
|
|
|
15
15
|
| 项目 | 值 |
|
|
16
16
|
| --- | --- |
|
|
17
17
|
| 插件包名 | `@xia-sc/dsh-cc-studio` |
|
|
18
|
-
| 当前版本 | `0.
|
|
18
|
+
| 当前版本 | `0.4.0` |
|
|
19
|
+
| 兼容与权限 | DSH `>=0.1.5-rc.1`、Node `>=22`、**零运行依赖**;权限边界见 [兼容与权限](#兼容与权限) |
|
|
19
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` 实测) |
|
|
20
21
|
| CC 预设 | `presets/cc.patch.yml`(dsh ≥ `0.1.7-alpha.1`,组合声明行)/`<DSH_HOME>/.agent-presets/cc`(≤ `0.1.6-alpha.2`,目录形态) |
|
|
21
22
|
| 客户端挂载点 | `conversation.input.dock`(胶囊)+ `shell.overlay`(工坊)+ `settings.section` |
|
|
@@ -269,12 +270,14 @@ dsh-cc-studio/
|
|
|
269
270
|
│ └── cc/ # CC 预设目录模板(dsh ≤ 0.1.6-alpha.2,插件挂载时安装到用户根)
|
|
270
271
|
│ ├── preset.yml
|
|
271
272
|
│ └── agent.cordis.yml
|
|
272
|
-
├── tests/ #
|
|
273
|
+
├── tests/ # 8 个测试文件、335 项断言(不随包发布)
|
|
273
274
|
│ ├── rpc-channel.test.mjs # host 半 RPC 通道回归(假 ctx + 真实 http,45 项断言)
|
|
274
|
-
│ ├── preset-install.test.mjs # 预设安装决策 + native 让位 + 两份清单防漂移 + 行契约,
|
|
275
|
-
│ ├── cc-detection.test.mjs # CC 模式探测的源码级守卫,
|
|
275
|
+
│ ├── preset-install.test.mjs # 预设安装决策 + native 让位 + 两份清单防漂移 + 行契约,79 项断言
|
|
276
|
+
│ ├── cc-detection.test.mjs # CC 模式探测的源码级守卫,51 项断言
|
|
276
277
|
│ ├── client-greetings.test.mjs # 客户端问候语与 i18n 守卫,62 项断言
|
|
277
278
|
│ ├── draft-slot-sync.test.mjs # 草稿槽行为级回归(假 React/slot/RPC harness),18 项断言
|
|
279
|
+
│ ├── nav-highlight.test.mjs # 工坊步骤导航三态回归(选中/键盘焦点/悬停互斥),23 项断言
|
|
280
|
+
│ ├── clear-card.test.mjs # 「清空当前角色卡」二次确认回归,20 项断言
|
|
278
281
|
│ └── data-root.test.mjs # 落盘根:DSH_HOME 优先 + 读时回退 ~/.dsh,37 项断言
|
|
279
282
|
├── CHANGELOG.md # 完整版本历史
|
|
280
283
|
├── README.md # 中文(默认)
|
|
@@ -286,7 +289,7 @@ dsh-cc-studio/
|
|
|
286
289
|
## 开发与测试
|
|
287
290
|
|
|
288
291
|
```bash
|
|
289
|
-
npm test #
|
|
292
|
+
npm test # 8 个文件、335 项断言(八个 node 脚本串联)
|
|
290
293
|
node tests/rpc-channel.test.mjs # 只跑 host 半 RPC 通道回归(45 项断言)
|
|
291
294
|
```
|
|
292
295
|
|
|
@@ -297,6 +300,27 @@ node tests/rpc-channel.test.mjs # 只跑 host 半 RPC 通道回归(
|
|
|
297
300
|
|
|
298
301
|
深浅色通过 `var(--dsw-alias-*)` 自动适配(`body[data-ds-dark-theme]`),主操作固定 `#7c5cff` 保证对比度。切换路径:设置 → 外观 → 浅色/深色/跟随系统,刷新后工坊立即生效。
|
|
299
302
|
|
|
303
|
+
## 兼容与权限
|
|
304
|
+
|
|
305
|
+
上架元数据(`dsh.compatibility` / `engines` / 运行依赖)与权限边界都集中在这里;DSH STORE 的固定源审查读的也是这几处。
|
|
306
|
+
|
|
307
|
+
| 项 | 值 |
|
|
308
|
+
| --- | --- |
|
|
309
|
+
| DSH 兼容范围 | `>=0.1.5-rc.1`(`package.json` 的 `dsh.compatibility.dsh`) |
|
|
310
|
+
| 逐版本证据 | `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` 再补测 |
|
|
311
|
+
| Node.js | `engines.node: ">=22"`(实测运行时 Node v26.9.0) |
|
|
312
|
+
| Profile | `web`(由 `dsh.client.platform` 推出) |
|
|
313
|
+
| 运行依赖 | **无**。`lib/*.js` 只 `import` `node:` 内建与相对路径;随包的补丁 / 预设是静态 YAML,没有安装期脚本 |
|
|
314
|
+
| 生命周期脚本 | **无** `preinstall` / `install` / `postinstall` / `prepare`(只有 `test` 与 `prepublishOnly`,只在本仓库跑,不发给安装端) |
|
|
315
|
+
| 权限 · 文件 | 读 `<DSH_HOME>`(含旧根 `~/.dsh`)下自己的三个目录:`cc-drafts/`、`cc-library/`、`.agent-presets/cc/`(后者只在 dsh ≤ `0.1.6-alpha.2` 上写);另读自身 `package.json`。不写宿主配置,不碰别的插件的数据 |
|
|
316
|
+
| 权限 · 网络 | 无。宿主半只在宿主 `webServer` 上注册 `POST /dsh-cc-studio-rpc/<endpoint>`;浏览器半只打同源 RPC |
|
|
317
|
+
| 权限 · 命令 | 无。不起子进程、不执行 shell |
|
|
318
|
+
| 权限 · 凭据 | 不读也不存任何 token / 密钥 / cookie。只读两个环境变量:`DSH_HOME`、`DSH_CC_STUDIO_PRESET_INSTALL`。宿主 HTTP 路由复用宿主自己的 cookie 围栏(`connection.requestRejection`),插件不解析凭据 |
|
|
319
|
+
|
|
320
|
+
> **为什么商城不会给它「自动通过」**:DSH STORE 的自动低风险通道(`source-verified`)要求运行时代码**完全不出现**文件、网络、命令、凭据四类信号;而本插件的核心功能就是角色卡与草稿落盘(文件信号),并且要读 `DSH_HOME`(扫描器把任何 `process.env` 读取都算凭据信号)。这两条不会为了迎合扫描器而消除 —— 对这类合法插件,商城的正确档位是 `user-reviewed`(展示变更、由用户逐次确认安装)。
|
|
321
|
+
|
|
322
|
+
一次性 Profile 的安装 / 启动 / 卸载证据见 [CHANGELOG.md](./CHANGELOG.md) 的 `0.3.7` 小节:隔离 profile + 隔离 `DSH_HOME` / `HOME` / `USERPROFILE`,三个前端挂载点全部 `active`、预设 roster 含 `cc`、RPC 往返一致、PNG / CHARX 导出→导入往返一致,真实 `~/.dsh` 全程零变化。
|
|
323
|
+
|
|
300
324
|
## 规范依据
|
|
301
325
|
|
|
302
326
|
- [CCv3 SPEC_V3.md](https://github.com/kwaroran/character-card-spec-v3/blob/main/SPEC_V3.md)(权威)
|
|
@@ -306,6 +330,8 @@ node tests/rpc-channel.test.mjs # 只跑 host 半 RPC 通道回归(
|
|
|
306
330
|
|
|
307
331
|
完整历史见 [CHANGELOG.md](./CHANGELOG.md)。最近几版:
|
|
308
332
|
|
|
333
|
+
- `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 项。
|
|
334
|
+
- `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` 未测,仍不声明。
|
|
309
335
|
- `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 项。
|
|
310
336
|
- `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 项。
|
|
311
337
|
- `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`)。
|
package/lib/client.js
CHANGED
|
@@ -85,6 +85,7 @@ window.__ModuleLoader__.load({
|
|
|
85
85
|
"workshop.world.title":"世界观 5维(Q2-B 深度问卷)",
|
|
86
86
|
"workshop.world.hint":"每维填 1-2 句即可,CC 模式下 LLM 会通过工具引导你补全,并自动生成带 @@decorator 的 Lorebook。点击卡片预览可展开大框,适合长文编辑。",
|
|
87
87
|
"workshop.world.empty":"(空)点击右上“展开编辑”填写,支持多行长文",
|
|
88
|
+
"workshop.field.empty":"未填写",
|
|
88
89
|
"workshop.world.previewHint":"预览(点击卡片或按钮展开大框编辑)",
|
|
89
90
|
"workshop.world.edit":"⛶ 编辑",
|
|
90
91
|
"workshop.world.fill":"+ 填写",
|
|
@@ -121,8 +122,6 @@ window.__ModuleLoader__.load({
|
|
|
121
122
|
"workshop.preview.title":"实时 CCv3 预览",
|
|
122
123
|
"workshop.preview.cbsTitle":"CBS 速查",
|
|
123
124
|
"workshop.preview.cbsHint":"大小写不敏感,逗号用 \\, 转义。",
|
|
124
|
-
"workshop.preview.fusionTitle":"融合说明",
|
|
125
|
-
"workshop.preview.fusionDesc":"默认只占一行胶囊;点开为全屏工坊,左侧导航可收起为图标,右侧实时预览常驻。后续可加“侧边抽屉”半屏态。",
|
|
126
125
|
"workshop.library.title":"已存角色",
|
|
127
126
|
"workshop.library.collapsed":"已存 {n}",
|
|
128
127
|
"workshop.library.loaded":"已载入 ID:{id} · 再次保存将更新此卡",
|
|
@@ -192,6 +191,8 @@ window.__ModuleLoader__.load({
|
|
|
192
191
|
"store.savedAsNew":"已另存为新卡:{name}",
|
|
193
192
|
"store.errSaveAsFailed":"另存失败",
|
|
194
193
|
"store.switchedNew":"已切换为新卡(保存将新建)",
|
|
194
|
+
"store.confirmClear":"确定清空当前角色卡的全部内容?\n\n已存角色里的存档不受影响,此操作不可撤销。",
|
|
195
|
+
"store.cleared":"已清空当前角色卡(已存角色未动)",
|
|
195
196
|
"store.loadedCard":"已载入:{name} · {n} lore(ID:{id},再次保存将更新此卡)",
|
|
196
197
|
"store.errLoadFailed":"载入失败",
|
|
197
198
|
"store.confirmDelete":"确定删除该角色?此操作不可撤销。",
|
|
@@ -296,6 +297,7 @@ window.__ModuleLoader__.load({
|
|
|
296
297
|
"workshop.world.title":"Worldbuilding 5D (Q2-B Deep Dive)",
|
|
297
298
|
"workshop.world.hint":"1–2 sentences per dimension is enough; LLM guides completion and auto-generates Lorebook with @@decorator. Click preview to edit in large modal.",
|
|
298
299
|
"workshop.world.empty":"(empty) Click Edit to fill, multi-line supported",
|
|
300
|
+
"workshop.field.empty":"Empty",
|
|
299
301
|
"workshop.world.previewHint":"Preview (click card or button for large editor)",
|
|
300
302
|
"workshop.world.edit":"⛶ Edit",
|
|
301
303
|
"workshop.world.fill":"+ Fill",
|
|
@@ -332,8 +334,6 @@ window.__ModuleLoader__.load({
|
|
|
332
334
|
"workshop.preview.title":"Live CCv3 Preview",
|
|
333
335
|
"workshop.preview.cbsTitle":"CBS Cheatsheet",
|
|
334
336
|
"workshop.preview.cbsHint":"Case-insensitive, escape comma with \\,.",
|
|
335
|
-
"workshop.preview.fusionTitle":"Fusion",
|
|
336
|
-
"workshop.preview.fusionDesc":"One-line capsule by default; click for fullscreen workshop, left nav collapsible, right preview sticky. Drawer half-screen later.",
|
|
337
337
|
"workshop.library.title":"Saved Characters",
|
|
338
338
|
"workshop.library.collapsed":"Saved {n}",
|
|
339
339
|
"workshop.library.loaded":"Loaded ID:{id} · save will update",
|
|
@@ -403,6 +403,8 @@ window.__ModuleLoader__.load({
|
|
|
403
403
|
"store.savedAsNew":"Saved as a new card: {name}",
|
|
404
404
|
"store.errSaveAsFailed":"Save-as failed",
|
|
405
405
|
"store.switchedNew":"Switched to a new card (saving will create one)",
|
|
406
|
+
"store.confirmClear":"Clear everything in the current card?\n\nSaved characters in the library are untouched. This cannot be undone.",
|
|
407
|
+
"store.cleared":"Current card cleared (saved characters untouched)",
|
|
406
408
|
"store.loadedCard":"Loaded: {name} · {n} lore (ID:{id}, saving again will update this card)",
|
|
407
409
|
"store.errLoadFailed":"Load failed",
|
|
408
410
|
"store.confirmDelete":"Delete this character? This cannot be undone.",
|
|
@@ -837,6 +839,21 @@ window.__ModuleLoader__.load({
|
|
|
837
839
|
set({libraryBusy:null});
|
|
838
840
|
}
|
|
839
841
|
function clearCurrentLibraryId(){ set({currentLibraryId:null, lastMsg:t("store.switchedNew")}); }
|
|
842
|
+
// 清空当前角色卡:整份草稿换回空卡(makeDraft),并解除「跟已存角色的关联」——
|
|
843
|
+
// 否则清空后点「保存当前」会把库里那张卡覆盖成空卡(要删卡请用右侧列表的删除)。
|
|
844
|
+
// 落盘与其它写入走同一条路(pushDraftToHost):刷新页面、模型侧读到的都是空卡。
|
|
845
|
+
// 二次确认由调用方负责(工坊底部那枚按钮),这里只管状态本身。
|
|
846
|
+
function clearDraft(){
|
|
847
|
+
set({
|
|
848
|
+
draft: makeDraft(),
|
|
849
|
+
world: { timeline:"", factions:"", geo:"", power:"", daily:"" },
|
|
850
|
+
valid: {valid:true, errors:[], warnings:[]},
|
|
851
|
+
editingWorld:null, editingWorldRevert:null, editingText:null,
|
|
852
|
+
currentLibraryId:null,
|
|
853
|
+
lastMsg: t("store.cleared")
|
|
854
|
+
});
|
|
855
|
+
setTimeout(pushDraftToHost, 80);
|
|
856
|
+
}
|
|
840
857
|
async function loadFromLibrary(id){
|
|
841
858
|
if(!id) return;
|
|
842
859
|
try{
|
|
@@ -905,33 +922,49 @@ window.__ModuleLoader__.load({
|
|
|
905
922
|
}catch(e){ set({lastMsg: String(e && e.message || e)}); }
|
|
906
923
|
set({libraryBusy:null});
|
|
907
924
|
}
|
|
908
|
-
return { getSnapshot:getSnapshot, subscribe:subscribe, setCur:setCur, setPanel:setPanel, setSideExpanded:setSideExpanded, setIsCcMode:setIsCcMode, setDraftFromHost:setDraftFromHost, setSessionId:setSessionId, setSlotWarn:setSlotWarn, setAlternateSlots:setAlternateSlots, migrateSlot:migrateSlot, checkIsCcMode:checkIsCcMode, setPollEnabled:setPollEnabled, setPollInterval:setPollInterval, setAutoValidate:setAutoValidate, setAutoSaveOnImport:setAutoSaveOnImport, updateDraft:updateDraft, validate:validate, exportJSON:exportJSON, exportPNG:exportPNG, embedIntoPng:embedIntoPng, exportCharx:exportCharx, importJSON:importJSON, importAny:importAny, setWorldPatch:setWorldPatch, setEditingWorld:setEditingWorld, cancelEditingWorld:cancelEditingWorld, setEditingText:setEditingText, clearEditingText:clearEditingText, cancelEditingText:cancelEditingText, updateEditingText:updateEditingText, addEntry:addEntry, setLibraryQuery:setLibraryQuery, toggleLibraryCollapsed:toggleLibraryCollapsed, refreshLibrary:refreshLibrary, saveCurrentToLibrary:saveCurrentToLibrary, saveAsNewToLibrary:saveAsNewToLibrary, clearCurrentLibraryId:clearCurrentLibraryId, loadFromLibrary:loadFromLibrary, deleteFromLibrary:deleteFromLibrary, exportLibraryEntry:exportLibraryEntry, renameCurrentInLibrary:renameCurrentInLibrary };
|
|
925
|
+
return { getSnapshot:getSnapshot, subscribe:subscribe, setCur:setCur, setPanel:setPanel, setSideExpanded:setSideExpanded, setIsCcMode:setIsCcMode, setDraftFromHost:setDraftFromHost, setSessionId:setSessionId, setSlotWarn:setSlotWarn, setAlternateSlots:setAlternateSlots, migrateSlot:migrateSlot, checkIsCcMode:checkIsCcMode, setPollEnabled:setPollEnabled, setPollInterval:setPollInterval, setAutoValidate:setAutoValidate, setAutoSaveOnImport:setAutoSaveOnImport, updateDraft:updateDraft, validate:validate, exportJSON:exportJSON, exportPNG:exportPNG, embedIntoPng:embedIntoPng, exportCharx:exportCharx, importJSON:importJSON, importAny:importAny, setWorldPatch:setWorldPatch, setEditingWorld:setEditingWorld, cancelEditingWorld:cancelEditingWorld, setEditingText:setEditingText, clearEditingText:clearEditingText, cancelEditingText:cancelEditingText, updateEditingText:updateEditingText, addEntry:addEntry, setLibraryQuery:setLibraryQuery, toggleLibraryCollapsed:toggleLibraryCollapsed, refreshLibrary:refreshLibrary, saveCurrentToLibrary:saveCurrentToLibrary, saveAsNewToLibrary:saveAsNewToLibrary, clearCurrentLibraryId:clearCurrentLibraryId, clearDraft:clearDraft, loadFromLibrary:loadFromLibrary, deleteFromLibrary:deleteFromLibrary, exportLibraryEntry:exportLibraryEntry, renameCurrentInLibrary:renameCurrentInLibrary };
|
|
909
926
|
}
|
|
910
927
|
|
|
911
928
|
var S={
|
|
912
929
|
overlay:{ position:"fixed", inset:0, background:"rgba(0,0,0,.45)", backdropFilter:"blur(8px)", display:"flex", alignItems:"center", justifyContent:"center", padding:"18px", zIndex:30 },
|
|
913
930
|
workshop:{ width:"min(1360px, 96vw)", height:"min(860px, 92vh)", background:"var(--dsw-alias-bg-layer-1, #fff)", border:"1px solid var(--dsw-alias-border-l1, rgba(0,0,0,.1))", borderRadius:18, overflow:"hidden", display:"flex", flexDirection:"column", boxShadow:"var(--dsw-shadow-lv3, 0 20px 80px rgba(0,0,0,.2))" },
|
|
914
931
|
head:{ height:56, display:"flex", alignItems:"center", justifyContent:"space-between", padding:"0 16px", borderBottom:"1px solid var(--dsw-alias-border-l1)", background:"var(--dsw-alias-bg-layer-2, #f9fafb)" },
|
|
915
|
-
step:{ padding:"6px 10px", borderRadius:999, fontSize:12, border:"1px solid var(--dsw-alias-border-l1)", color:"var(--dsw-alias-label-secondary)", background:"var(--dsw-alias-bg-layer-2)", cursor:"pointer" },
|
|
932
|
+
step:{ padding:"6px 10px", borderRadius:999, fontSize:12, border:"1px solid var(--dsw-alias-border-l1)", color:"var(--dsw-alias-label-secondary)", background:"var(--dsw-alias-bg-layer-2)", cursor:"pointer", outline:"none", transition:"background .12s ease, border-color .12s ease, color .12s ease" },
|
|
916
933
|
stepActive:{ background:"#7c5cff", borderColor:"#7c5cff", color:"#fff" },
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
934
|
+
stepHover:{ background:"var(--dsw-alias-bg-layer-1)", borderColor:"rgba(124,92,255,.55)", color:"var(--dsw-alias-label-primary)" },
|
|
935
|
+
body:{ flex:1, display:"grid", gridTemplateColumns:"200px 1fr 268px", minHeight:0, background:"var(--dsw-alias-bg-base)" },
|
|
936
|
+
nav:{ borderRight:"1px solid var(--dsw-alias-border-l1)", background:"var(--dsw-alias-bg-layer-1)", padding:"12px", display:"flex", flexDirection:"column", gap:8 },
|
|
937
|
+
navBtn:{ width:"100%", boxSizing:"border-box", maxWidth:"100%", textAlign:"left", padding:"10px 12px", borderRadius:10, border:"1px solid transparent", background:"transparent", color:"var(--dsw-alias-label-secondary)", cursor:"pointer", outline:"none", transition:"background .12s ease, border-color .12s ease, color .12s ease" },
|
|
938
|
+
navBtnHover:{ background:"var(--dsw-alias-bg-layer-2)", color:"var(--dsw-alias-label-primary)" },
|
|
939
|
+
navBtnFocus:{ outline:"2px solid #7c5cff", outlineOffset:2 },
|
|
940
|
+
navBtnActive:{ background:"rgba(124,92,255,.16)", borderColor:"rgba(124,92,255,.5)", color:"var(--dsw-alias-label-primary)", boxShadow:"inset 3px 0 0 0 #7c5cff" },
|
|
941
|
+
main:{ padding:"18px 20px 28px", overflow:"auto", minWidth:0, background:"var(--dsw-alias-bg-base)" },
|
|
942
|
+
// —— 阅读态排版(0.4.0 重构)——
|
|
943
|
+
// 字段默认以「文档」形态呈现:无边框 textarea + field-sizing:content(Chrome 123+ 按内容自动撑高),
|
|
944
|
+
// 点进去就能改;长文仍可走右上角 ⛶ 大框(带快照回滚)。手动编辑从「满屏输入框」退成次要入口。
|
|
945
|
+
readCard:{ background:"var(--dsw-alias-bg-layer-1)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:14, padding:"16px 18px", marginBottom:12 },
|
|
946
|
+
readTitle:{ margin:"0 0 4px", fontSize:14, fontWeight:600, color:"var(--dsw-alias-label-primary)" },
|
|
947
|
+
readHint:{ fontSize:12, color:"var(--dsw-alias-label-secondary)", marginBottom:10, lineHeight:1.7 },
|
|
948
|
+
fieldRow:{ marginBottom:12 },
|
|
949
|
+
fieldLabel:{ display:"flex", alignItems:"center", justifyContent:"space-between", gap:8, marginBottom:2 },
|
|
950
|
+
fieldName:{ fontSize:12, fontWeight:600, color:"var(--dsw-alias-label-secondary)" },
|
|
951
|
+
fieldTools:{ display:"flex", alignItems:"center", gap:6 },
|
|
952
|
+
iconBtn:{ appearance:"none", border:"1px solid transparent", background:"transparent", color:"var(--dsw-alias-label-secondary)", borderRadius:6, padding:"0 6px", fontSize:12, lineHeight:"20px", cursor:"pointer", outline:"none" },
|
|
953
|
+
readText:{ display:"block", width:"100%", boxSizing:"border-box", maxWidth:"100%", background:"transparent", border:"1px solid transparent", borderRadius:8, color:"var(--dsw-alias-label-primary)", padding:"6px 8px", margin:"0 -8px", font:"inherit", fontSize:13, lineHeight:1.8, resize:"none", outline:"none", fieldSizing:"content", minHeight:30, overflow:"hidden" },
|
|
954
|
+
readInput:{ display:"block", width:"100%", boxSizing:"border-box", maxWidth:"100%", background:"transparent", border:"1px solid transparent", borderRadius:8, color:"var(--dsw-alias-label-primary)", padding:"6px 8px", margin:"0 -8px", font:"inherit", fontSize:13, lineHeight:1.8, outline:"none" },
|
|
955
|
+
// 主区底部的折叠区(实时预览 / CBS 速查 / 融合说明):默认只占一行标题,点开才铺开
|
|
956
|
+
fold:{ border:"1px solid var(--dsw-alias-border-l1)", borderRadius:12, background:"var(--dsw-alias-bg-layer-1)", marginBottom:8, overflow:"hidden" },
|
|
957
|
+
foldHead:{ display:"flex", alignItems:"center", justifyContent:"space-between", gap:8, width:"100%", boxSizing:"border-box", padding:"10px 14px", background:"transparent", border:"none", color:"var(--dsw-alias-label-primary)", fontSize:12, fontWeight:600, cursor:"pointer", textAlign:"left", outline:"none", fontFamily:"inherit" },
|
|
958
|
+
foldBody:{ padding:"12px 14px 14px", borderTop:"1px solid var(--dsw-alias-border-l1)" },
|
|
923
959
|
library:{ borderLeft:"1px solid var(--dsw-alias-border-l1)", background:"var(--dsw-alias-bg-layer-1)", display:"flex", flexDirection:"column", minWidth:0, overflow:"hidden" },
|
|
924
960
|
libraryHead:{ height:46, display:"flex", alignItems:"center", justifyContent:"space-between", padding:"8px 10px", borderBottom:"1px solid var(--dsw-alias-border-l1)", background:"var(--dsw-alias-bg-layer-2)", flexShrink:0 },
|
|
925
961
|
libraryList:{ flex:1, overflow:"auto", padding:"8px", display:"flex", flexDirection:"column", gap:8 },
|
|
926
962
|
libraryItem:{ background:"var(--dsw-alias-bg-layer-2)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:10, padding:10 },
|
|
927
963
|
libraryCollapsedBar:{ width:40, borderLeft:"1px solid var(--dsw-alias-border-l1)", background:"var(--dsw-alias-bg-layer-1)", display:"flex", flexDirection:"column", alignItems:"center", padding:"10px 6px", gap:10, boxShadow:"inset 1px 0 0 var(--dsw-alias-border-l1)" },
|
|
928
|
-
card:{ background:"var(--dsw-alias-bg-layer-1)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:12, padding:12, marginBottom:12 },
|
|
929
|
-
field:{ display:"flex", flexDirection:"column", gap:6, marginBottom:10 },
|
|
930
964
|
badge:{ fontSize:11, padding:"2px 6px", borderRadius:999, border:"1px solid var(--dsw-alias-border-l1)", background:"var(--dsw-alias-bg-layer-2)", color:"var(--dsw-alias-label-secondary)" },
|
|
931
965
|
chip:{ fontSize:11, padding:"4px 8px", borderRadius:999, background:"var(--dsw-alias-bg-layer-2)", border:"1px solid var(--dsw-alias-border-l1)", color:"var(--dsw-alias-label-secondary)", cursor:"pointer" },
|
|
932
966
|
btn:{ appearance:"none", border:"1px solid transparent", background:"#7c5cff", color:"#fff", borderRadius:10, padding:"8px 14px", fontWeight:600, cursor:"pointer" },
|
|
933
967
|
btnGhost:{ background:"transparent", borderColor:"var(--dsw-alias-border-l1)", color:"var(--dsw-alias-label-primary)" },
|
|
934
|
-
mono:{ fontFamily:"ui-monospace,Menlo,Consolas,monospace", fontSize:12, color:"var(--dsw-alias-label-secondary)" },
|
|
935
968
|
dockWrap:{ boxSizing:"border-box", display:"flex", justifyContent:"flex-start", width:"100%", boxSizing:"border-box", maxWidth:"100%", paddingLeft:"calc((100% - var(--dsh-composer-card-max-width, 778px)) / 2)", margin:"2px 0" },
|
|
936
969
|
capsule:{ display:"inline-flex", alignItems:"center", gap:8, maxWidth:360, padding:"1px 10px", borderRadius:999, border:"1px solid rgba(127,127,127,0.25)", background:"rgba(127,127,127,0.12)", color:"var(--dsw-alias-label-secondary, #c8ccd2)", fontSize:12, lineHeight:"20px", cursor:"pointer", whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis" },
|
|
937
970
|
input:{ width:"100%", boxSizing:"border-box", maxWidth:"100%", background:"var(--dsw-alias-bg-base, #fff)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:8, color:"var(--dsw-alias-label-primary)", padding:"6px 10px", fontSize:12 },
|
|
@@ -1097,142 +1130,199 @@ window.__ModuleLoader__.load({
|
|
|
1097
1130
|
);
|
|
1098
1131
|
}
|
|
1099
1132
|
|
|
1133
|
+
// 破坏性操作的二次确认:拿不到确认框(或它抛错)一律当「没确认」——
|
|
1134
|
+
// 宁可什么都不做,也不静默清掉用户的数据。
|
|
1135
|
+
function confirmClear(t){
|
|
1136
|
+
try{
|
|
1137
|
+
if(typeof window==="undefined" || typeof window.confirm!=="function") return false;
|
|
1138
|
+
return !!window.confirm(t("store.confirmClear"));
|
|
1139
|
+
}catch(e){ return false; }
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
// 键盘焦点判定:只有 :focus-visible(键盘 Tab 进来)才画焦点环;鼠标点出来的焦点不画。
|
|
1143
|
+
// 老浏览器没有 :focus-visible 时按「有焦点」处理 —— 宁可多画一环,不可让键盘用户失去位置感。
|
|
1144
|
+
function isFocusVisible(e){
|
|
1145
|
+
try{
|
|
1146
|
+
var el=e && e.currentTarget;
|
|
1147
|
+
if(!el || typeof el.matches!=="function") return true;
|
|
1148
|
+
return !!el.matches(":focus-visible");
|
|
1149
|
+
}catch(err){ return true; }
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1100
1152
|
function Workshop(props){
|
|
1101
1153
|
var store=props.store; var t=props.t;
|
|
1102
1154
|
var currentId = useCcPreset(store, props, t);
|
|
1103
1155
|
var sRef=React.useState(function(){ return store.getSnapshot(); }); var s=sRef[0], setS=sRef[1];
|
|
1156
|
+
// 悬停 / 键盘焦点是纯局部视觉状态,不进 store:否则鼠标每移动一次都要重渲染整棵工坊树(右侧预览是整份 JSON)。
|
|
1157
|
+
var hoverRef=React.useState(null); var hoverKey=hoverRef[0], setHoverKey=hoverRef[1];
|
|
1158
|
+
var focusRef=React.useState(null); var focusKey=focusRef[0], setFocusKey=focusRef[1];
|
|
1159
|
+
// 主区底部三块阅读辅助(实时预览 / CBS 速查 / 融合说明)默认全收起:占地方、但不常看
|
|
1160
|
+
var foldRef=React.useState({}); var openFold=foldRef[0], setOpenFold=foldRef[1];
|
|
1104
1161
|
React.useEffect(function(){ return store.subscribe(function(){ setS(store.getSnapshot()); }); }, [store]);
|
|
1105
1162
|
React.useEffect(function(){
|
|
1106
1163
|
if(s.panelOpen) store.refreshLibrary();
|
|
1107
1164
|
}, [s.panelOpen]);
|
|
1108
1165
|
if(!s.panelOpen) return null;
|
|
1109
1166
|
var steps=[t("step.world"), t("step.char"), t("step.lore"), t("step.export")];
|
|
1167
|
+
// 步骤项的三个视觉状态严格互斥:选中(active) / 键盘焦点(focus-visible) / 悬停(hover)。
|
|
1168
|
+
// 鼠标点击走 onMouseDown preventDefault,不把焦点抢到按钮上 —— 否则旧项的焦点环会留在原地,
|
|
1169
|
+
// 与新的选中项同时发亮,看起来像「同时选中了两个」(这是本次修的问题)。
|
|
1110
1170
|
function navItem(i, title, desc){
|
|
1111
1171
|
var active=s.cur===i;
|
|
1112
|
-
|
|
1172
|
+
var hovered=hoverKey==="nav:"+i;
|
|
1173
|
+
var focused=focusKey==="nav:"+i;
|
|
1174
|
+
return h("button",{key:i, type:"button", "aria-current": active? "step": undefined,
|
|
1175
|
+
style: Object.assign({}, S.navBtn, hovered&&!active? S.navBtnHover:{}, focused? S.navBtnFocus:{}, active? S.navBtnActive:{}),
|
|
1176
|
+
onMouseDown:function(e){ if(e && e.preventDefault) e.preventDefault(); },
|
|
1177
|
+
onMouseEnter:function(){ setHoverKey("nav:"+i); },
|
|
1178
|
+
onMouseLeave:function(){ setHoverKey(null); },
|
|
1179
|
+
onFocus:function(e){ setFocusKey(isFocusVisible(e)? "nav:"+i : null); },
|
|
1180
|
+
onBlur:function(){ setFocusKey(null); },
|
|
1181
|
+
onClick:function(){ store.setCur(i); }
|
|
1182
|
+
}, title, h("div",{style:{fontSize:11, color:"var(--dsw-alias-label-secondary)", marginTop:2}}, desc));
|
|
1183
|
+
}
|
|
1184
|
+
// 工具按钮(⛶ / 删除…)鼠标按下就拦掉默认行为:别把焦点抢走,否则又留下一圈焦点描边
|
|
1185
|
+
function stopFocusSteal(e){ if(e && e.preventDefault) e.preventDefault(); }
|
|
1186
|
+
// 折叠区:主区底部那几块「阅读辅助」(实时 CCv3 预览 / CBS 速查 / 融合说明)。
|
|
1187
|
+
// 默认全部收起 —— 它们不常看,收起来只占一行标题,阅读区因此能拿到整幅宽度。
|
|
1188
|
+
function foldPanel(id, title, badge, body){
|
|
1189
|
+
var open = !!openFold[id];
|
|
1190
|
+
return h("section",{style:S.fold},
|
|
1191
|
+
h("button",{type:"button", style:S.foldHead, "aria-expanded": open? "true": "false", onMouseDown:stopFocusSteal,
|
|
1192
|
+
onClick:function(){ setOpenFold(function(prev){ var nx=Object.assign({}, prev); nx[id]=!nx[id]; return nx; }); }},
|
|
1193
|
+
h("span",null, (open? "▾ " : "▸ ")+title),
|
|
1194
|
+
badge||null),
|
|
1195
|
+
open? h("div",{style:S.foldBody}, body): null);
|
|
1113
1196
|
}
|
|
1114
|
-
//
|
|
1115
|
-
//
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1197
|
+
// —— 阅读态字段(0.4.0 重构的核心构件)——
|
|
1198
|
+
// 标签(+ 可选工具)+ 无边框输入控件;textarea 用 field-sizing:content 按内容自动撑高,
|
|
1199
|
+
// 所以默认视图看起来就是排好版的正文,点进去直接改。长文仍可走 ⛶ 大框(带打开时快照,「取消」真回滚)。
|
|
1200
|
+
function field(title, key, opts){
|
|
1201
|
+
opts=opts||{};
|
|
1202
|
+
var raw = opts.value!==undefined ? opts.value : s.draft.data[key];
|
|
1203
|
+
var val = raw==null? "" : String(raw);
|
|
1204
|
+
var write = opts.onChange || function(v){ store.updateDraft(function(d){ d[key]=v; }); };
|
|
1205
|
+
var tools=[];
|
|
1206
|
+
if(opts.tools) tools=tools.concat(opts.tools);
|
|
1207
|
+
if(opts.bigBox!==false) tools.push(h("button",{key:"bigbox", type:"button", style:S.iconBtn, title:t("action.expand"), onMouseDown:stopFocusSteal,
|
|
1208
|
+
onClick:function(){
|
|
1209
|
+
var snapshot=s.draft.data[key]; // 「取消」回滚用
|
|
1210
|
+
store.setEditingText(title, val,
|
|
1211
|
+
function(v){ store.updateDraft(function(d){ d[key]=v; }); },
|
|
1212
|
+
function(){ store.updateDraft(function(d){ d[key]=snapshot; }); });
|
|
1213
|
+
}}, "⛶"));
|
|
1214
|
+
return h("div",{key:opts.rowKey, style:Object.assign({}, S.fieldRow, opts.style)},
|
|
1215
|
+
h("div",{style:S.fieldLabel},
|
|
1216
|
+
h("label",{style:S.fieldName}, title),
|
|
1217
|
+
tools.length? h("div",{style:S.fieldTools}, tools): null),
|
|
1218
|
+
opts.input
|
|
1219
|
+
? h("input",{style:Object.assign({}, S.readInput, opts.readOnly? {color:"var(--dsw-alias-label-secondary)"}:{}), value:val, readOnly:!!opts.readOnly, placeholder:opts.placeholder||t("workshop.field.empty"), onChange:function(e){ write(e.target.value); }})
|
|
1220
|
+
: h("textarea",{style:S.readText, value:val, readOnly:!!opts.readOnly, placeholder:opts.placeholder||t("workshop.field.empty"), onChange:function(e){ write(e.target.value); }})
|
|
1221
|
+
);
|
|
1126
1222
|
}
|
|
1127
|
-
//
|
|
1223
|
+
// 每条问候语一段正文(元素内部换行原样保留,不做「每行一条」的序列化);阅读态 + 逐条 ⛶ / 删除
|
|
1128
1224
|
function greetingList(key, title, hint){
|
|
1129
1225
|
var arr = Array.isArray(s.draft.data[key]) ? s.draft.data[key] : [];
|
|
1130
1226
|
var atMax = arr.length >= GREETING_MAX;
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
h("
|
|
1135
|
-
h("div",{style:{display:"flex", gap:6, alignItems:"center"}},
|
|
1136
|
-
h("button",{style:Object.assign({}, S.btnGhost, {padding:"2px 8px", fontSize:11, border:"1px solid var(--dsw-alias-border-l1)", background:"transparent", color:"var(--dsw-alias-label-primary)"}),
|
|
1137
|
-
onClick:function(){
|
|
1138
|
-
store.setEditingText(t("workshop.greeting.entryLabel",{title:title, n:(i+1)}), String(raw==null? "": raw),
|
|
1139
|
-
function(v){ store.updateDraft(function(d){ d[key]=setGreetingAt(d[key], i, v); }); },
|
|
1140
|
-
function(){ store.updateDraft(function(d){ d[key]=setGreetingAt(d[key], i, raw); }); });
|
|
1141
|
-
}}, "⛶"),
|
|
1142
|
-
h("button",{style:Object.assign({}, S.btnGhost, {padding:"2px 8px", fontSize:11, border:"1px solid #3a2a2a", background:"transparent", color:"#e8a6a6"}),
|
|
1143
|
-
onClick:function(){ store.updateDraft(function(d){ d[key]=removeGreetingAt(d[key], i); }); }}, t("common.delete"))
|
|
1144
|
-
));
|
|
1145
|
-
}
|
|
1146
|
-
return h("div",{style:S.field},
|
|
1147
|
-
h("div",{style:{display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom:4}},
|
|
1148
|
-
h("label",{style:{fontSize:12,color:"var(--dsw-alias-label-secondary)"}}, title),
|
|
1149
|
-
h("div",{style:{display:"flex", gap:6, alignItems:"center"}},
|
|
1227
|
+
return h("div",{style:S.fieldRow},
|
|
1228
|
+
h("div",{style:S.fieldLabel},
|
|
1229
|
+
h("label",{style:S.fieldName}, title),
|
|
1230
|
+
h("div",{style:S.fieldTools},
|
|
1150
1231
|
h("span",{style:{fontSize:10, color:"var(--dsw-alias-label-secondary)"}}, hint+" · "+arr.length+"/"+GREETING_MAX),
|
|
1151
|
-
h("button",{style:Object.assign({}, S.
|
|
1152
|
-
onClick:function(){ store.updateDraft(function(d){ d[key]=appendGreeting(d[key]); }); }}, atMax? t("workshop.greeting.atMax",{max:GREETING_MAX}):t("workshop.greeting.add"))
|
|
1153
|
-
|
|
1232
|
+
h("button",{type:"button", style:Object.assign({}, S.iconBtn, {borderColor:"var(--dsw-alias-border-l1)"}), disabled:atMax, onMouseDown:stopFocusSteal,
|
|
1233
|
+
onClick:function(){ store.updateDraft(function(d){ d[key]=appendGreeting(d[key]); }); }}, atMax? t("workshop.greeting.atMax",{max:GREETING_MAX}):t("workshop.greeting.add")))
|
|
1234
|
+
),
|
|
1154
1235
|
arr.length===0
|
|
1155
|
-
? h("div",{style:{fontSize:12, color:"var(--dsw-alias-label-secondary)", border:"1px dashed var(--dsw-alias-border-l1)", borderRadius:
|
|
1236
|
+
? h("div",{style:{fontSize:12, color:"var(--dsw-alias-label-secondary)", border:"1px dashed var(--dsw-alias-border-l1)", borderRadius:10, padding:"12px", textAlign:"center"}}, t("workshop.greeting.empty"))
|
|
1156
1237
|
: arr.map(function(text, i){
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
h("
|
|
1160
|
-
|
|
1238
|
+
var label=t("workshop.greeting.entryLabel",{title:title, n:(i+1)});
|
|
1239
|
+
return h("div",{key:i, style:{border:"1px solid var(--dsw-alias-border-l1)", borderRadius:10, padding:"8px 10px", marginBottom:8, background:"var(--dsw-alias-bg-base)"}},
|
|
1240
|
+
h("div",{style:S.fieldLabel},
|
|
1241
|
+
h("span",{style:{fontSize:11, fontWeight:600, color:"var(--dsw-alias-label-secondary)"}}, label),
|
|
1242
|
+
h("div",{style:S.fieldTools},
|
|
1243
|
+
h("button",{type:"button", style:S.iconBtn, title:t("action.expand"), onMouseDown:stopFocusSteal,
|
|
1244
|
+
onClick:function(){
|
|
1245
|
+
store.setEditingText(label, String(text==null? "": text),
|
|
1246
|
+
function(v){ store.updateDraft(function(d){ d[key]=setGreetingAt(d[key], i, v); }); },
|
|
1247
|
+
function(){ store.updateDraft(function(d){ d[key]=setGreetingAt(d[key], i, text); }); });
|
|
1248
|
+
}}, "⛶"),
|
|
1249
|
+
h("button",{type:"button", style:Object.assign({}, S.iconBtn, {color:"#e8a6a6"}), onMouseDown:stopFocusSteal,
|
|
1250
|
+
onClick:function(){ store.updateDraft(function(d){ d[key]=removeGreetingAt(d[key], i); }); }}, t("common.delete")))
|
|
1251
|
+
),
|
|
1252
|
+
h("textarea",{style:S.readText, value:String(text==null? "": text), placeholder:t("workshop.field.empty"),
|
|
1161
1253
|
onChange:function(e){ var v=e.target.value; store.updateDraft(function(d){ d[key]=setGreetingAt(d[key], i, v); }); }}));
|
|
1162
1254
|
})
|
|
1163
1255
|
);
|
|
1164
1256
|
}
|
|
1165
1257
|
var main=null;
|
|
1166
1258
|
if(s.cur===0){
|
|
1259
|
+
// 五维世界观:默认直接读全文(无边框 textarea 自动撑高),⛶ 仍可放大框写长文
|
|
1167
1260
|
function worldField(key, title){
|
|
1168
1261
|
var val = s.world[key]||"";
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
h("div",{style:{fontSize:12, fontWeight:600}}, title),
|
|
1174
|
-
h("div",{style:{display:"flex", gap:6, alignItems:"center"}},
|
|
1262
|
+
return h("div",{key:key, style:S.fieldRow},
|
|
1263
|
+
h("div",{style:S.fieldLabel},
|
|
1264
|
+
h("label",{style:S.fieldName}, title),
|
|
1265
|
+
h("div",{style:S.fieldTools},
|
|
1175
1266
|
h("span",{style:{fontSize:10, color:"var(--dsw-alias-label-secondary)"}}, t("workshop.world.chars",{n:String(val.length)})),
|
|
1176
|
-
h("button",{
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
h("div",{style:{flex:1, maxHeight:84, overflow:"auto", background:"var(--dsw-alias-bg-base)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:8, padding:"8px", fontSize:12, lineHeight:1.5, whiteSpace:"pre-wrap", color: has? "var(--dsw-alias-label-primary)" : "var(--dsw-alias-label-secondary)", cursor:"pointer"}, onClick:function(){ store.setEditingWorld(key); }}, has ? preview : preview),
|
|
1180
|
-
h("div",{style:{fontSize:10, color:"var(--dsw-alias-label-secondary)", marginTop:6, textAlign:"right"}}, has ? t("workshop.world.previewHint") : " ")
|
|
1181
|
-
);
|
|
1267
|
+
h("button",{type:"button", style:S.iconBtn, title:t("action.expand"), onMouseDown:stopFocusSteal, onClick:function(){ store.setEditingWorld(key); }}, "⛶"))),
|
|
1268
|
+
h("textarea",{style:S.readText, value:String(val), placeholder:t("workshop.world.empty"),
|
|
1269
|
+
onChange:function(e){ store.setWorldPatch(key, e.target.value); }}));
|
|
1182
1270
|
}
|
|
1183
1271
|
main=h("div",null,
|
|
1184
|
-
h("div",{style:S.
|
|
1185
|
-
h("h3",{style:
|
|
1186
|
-
h("div",{style:
|
|
1187
|
-
h("div",{style:{display:"grid", gridTemplateColumns:"1fr 1fr", gap:
|
|
1272
|
+
h("div",{style:S.readCard},
|
|
1273
|
+
h("h3",{style:S.readTitle},t("workshop.world.title")),
|
|
1274
|
+
h("div",{style:S.readHint},t("workshop.world.hint")),
|
|
1275
|
+
h("div",{style:{display:"grid", gridTemplateColumns:"1fr 1fr", gap:"0 18px"}},
|
|
1188
1276
|
worldField("timeline", t("workshop.world.timeline")),
|
|
1189
1277
|
worldField("factions", t("workshop.world.factions")),
|
|
1190
1278
|
worldField("geo", t("workshop.world.geo")),
|
|
1191
1279
|
worldField("power", t("workshop.world.power")),
|
|
1192
|
-
h("div",{style:{gridColumn:"span 2"}}, worldField("daily", t("workshop.world.daily")))
|
|
1280
|
+
h("div",{style:{gridColumn:"span 2", display:"grid"}}, worldField("daily", t("workshop.world.daily")))
|
|
1193
1281
|
),
|
|
1194
|
-
h("div",{style:{display:"flex", gap:8, marginTop:
|
|
1195
|
-
h("button",{style: Object.assign({}, S.btn, S.btnGhost), onClick:function(){ store.setCur(1); }}, t("action.nextChar"))
|
|
1282
|
+
h("div",{style:{display:"flex", gap:8, marginTop:6}},
|
|
1283
|
+
h("button",{type:"button", style: Object.assign({}, S.btn, S.btnGhost), onMouseDown:stopFocusSteal, onClick:function(){ store.setCur(1); }}, t("action.nextChar"))
|
|
1196
1284
|
),
|
|
1197
1285
|
s.lastMsg? h("div",{style:{marginTop:10, fontSize:12, color:"var(--dsw-alias-label-secondary)"}}, s.lastMsg):null
|
|
1198
1286
|
)
|
|
1199
1287
|
);
|
|
1200
1288
|
} else if(s.cur===1){
|
|
1201
1289
|
main=h("div",null,
|
|
1202
|
-
h("div",{style:S.
|
|
1203
|
-
h("
|
|
1204
|
-
|
|
1205
|
-
|
|
1290
|
+
h("div",{style:S.readCard},
|
|
1291
|
+
h("h3",{style:S.readTitle},t("workshop.char.sixTitle")),
|
|
1292
|
+
h("div",{style:{display:"grid", gridTemplateColumns:"1fr 1fr", gap:"0 18px"}},
|
|
1293
|
+
field("name","name",{rowKey:"name", input:true}),
|
|
1294
|
+
field(t("workshop.field.nickname"),"nickname",{rowKey:"nickname", input:true})
|
|
1206
1295
|
),
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1296
|
+
field(t("workshop.field.tags"),"tags",{rowKey:"tags", input:true, bigBox:false, value:s.draft.data.tags.join(", "), onChange:function(v){ store.updateDraft(function(d){ d.tags=v.split(",").map(function(x){return x.trim();}).filter(Boolean); }); }}),
|
|
1297
|
+
field("description","description",{rowKey:"desc"}),
|
|
1298
|
+
field("personality","personality",{rowKey:"pers"}),
|
|
1299
|
+
field("scenario","scenario",{rowKey:"scen"}),
|
|
1211
1300
|
h("div",{style:{display:"grid", gridTemplateColumns:"1fr 1fr", gap:10}},
|
|
1212
|
-
|
|
1213
|
-
|
|
1301
|
+
field("system_prompt","system_prompt",{rowKey:"sys"}),
|
|
1302
|
+
field("post_history_instructions","post_history_instructions",{rowKey:"phi"})
|
|
1214
1303
|
)
|
|
1215
1304
|
),
|
|
1216
|
-
h("div",{style:S.
|
|
1217
|
-
h("
|
|
1305
|
+
h("div",{style:S.readCard},
|
|
1306
|
+
h("h3",{style:S.readTitle},t("workshop.char.openingTitle")),
|
|
1307
|
+
field("first_mes","first_mes",{rowKey:"first"}),
|
|
1218
1308
|
greetingList("alternate_greetings", t("workshop.greeting.altTitle"), t("workshop.greeting.altHint")),
|
|
1219
1309
|
greetingList("group_only_greetings", t("workshop.greeting.groupTitle"), t("workshop.greeting.groupHint")),
|
|
1220
|
-
|
|
1310
|
+
field(t("workshop.field.mesExample"),"mes_example",{rowKey:"mes"})
|
|
1221
1311
|
)
|
|
1222
1312
|
);
|
|
1223
1313
|
} else if(s.cur===2){
|
|
1224
1314
|
var entries=s.draft.data.character_book.entries;
|
|
1225
1315
|
main=h("div",null,
|
|
1226
|
-
h("div",{style:S.
|
|
1316
|
+
h("div",{style:S.readCard},
|
|
1227
1317
|
h("div",{style:{display:"flex", alignItems:"center", justifyContent:"space-between", marginBottom:8}},
|
|
1228
|
-
h("h3",{style:
|
|
1318
|
+
h("h3",{style:S.readTitle},t("workshop.lore.title")),
|
|
1229
1319
|
h("span",{style:S.badge}, "scan_depth "+s.draft.data.character_book.scan_depth+" · token_budget "+s.draft.data.character_book.token_budget+" · "+t("common.entries",{n:entries.length}))
|
|
1230
1320
|
),
|
|
1231
1321
|
h("div",null, entries.map(function(e){
|
|
1232
1322
|
return h("div",{key:e.id, style:{display:"grid", gridTemplateColumns:"1fr auto", gap:8, background:"var(--dsw-alias-bg-base)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:10, padding:10, marginBottom:8}},
|
|
1233
1323
|
h("div",null,
|
|
1234
1324
|
h("div",{style:{fontWeight:600, fontSize:12}}, e.name, h("span",{style:Object.assign({}, S.badge, {marginLeft:6})}, e.constant? "constant": (e.keys.join(", ")||"—")), h("span",{style:Object.assign({}, S.badge, {marginLeft:6})}, "order "+e.insertion_order)),
|
|
1235
|
-
h("div",{style:
|
|
1325
|
+
h("div",{style:{fontSize:13, lineHeight:1.8, color:"var(--dsw-alias-label-primary)", marginTop:4, whiteSpace:"pre-wrap", wordBreak:"break-word"}}, e.content),
|
|
1236
1326
|
h("div",{style:{display:"flex", flexWrap:"wrap", gap:6, marginTop:6}}, h("span",{style:S.badge},"@@depth/@@position"), h("span",{style:S.badge},"CBS: {{char}}"))
|
|
1237
1327
|
),
|
|
1238
1328
|
h("div",{style:{display:"flex", flexDirection:"column", gap:6}}, h("label",{style:{fontSize:12}}, h("input",{type:"checkbox", checked:e.enabled, onChange:function(ev){ store.updateDraft(function(d){ var f=d.character_book.entries.find(function(x){return x.id===e.id;}); if(f) f.enabled=ev.target.checked; }); }}), " enabled"), h("button",{style: Object.assign({}, S.btn, S.btnGhost, {padding:"4px 8px", fontSize:12}), onClick:function(){ store.updateDraft(function(d){ d.character_book.entries=d.character_book.entries.filter(function(x){return x.id!==e.id;}); }); }}, t("common.delete")))
|
|
@@ -1248,8 +1338,8 @@ window.__ModuleLoader__.load({
|
|
|
1248
1338
|
} else {
|
|
1249
1339
|
var v=s.valid;
|
|
1250
1340
|
main=h("div",null,
|
|
1251
|
-
h("div",{style:S.
|
|
1252
|
-
h("h3",{style:
|
|
1341
|
+
h("div",{style:S.readCard},
|
|
1342
|
+
h("h3",{style:S.readTitle},t("workshop.export.title")),
|
|
1253
1343
|
h("div",{style:{display:"flex", flexWrap:"wrap", gap:8, marginBottom:8}},
|
|
1254
1344
|
h("span",{style: Object.assign({}, S.badge, v.valid? {borderColor:"var(--dsw-alias-state-success-primary)", color:"#a6e8c8", background:"color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, var(--dsw-alias-bg-base))"}:{borderColor:"var(--dsw-alias-state-error-primary)", color:"#e8a6a6", background:"color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, var(--dsw-alias-bg-base))"})}, v.valid? t("workshop.export.passed"):t("workshop.export.failed")),
|
|
1255
1345
|
h("span",{style:S.badge},t("common.groupGreetings",{n:s.draft.data.group_only_greetings.length})),
|
|
@@ -1265,10 +1355,10 @@ window.__ModuleLoader__.load({
|
|
|
1265
1355
|
h("button",{style: Object.assign({}, S.btn, S.btnGhost), onClick:function(){ store.validate(); }}, s.busy==="validate"? t("action.validating"): t("action.validate")),
|
|
1266
1356
|
h("span",{style:{color:"var(--dsw-alias-label-secondary)", fontSize:11, alignSelf:"center"}}, t("workshop.export.hint2"))
|
|
1267
1357
|
),
|
|
1268
|
-
|
|
1358
|
+
field(t("workshop.export.creatorNotes"),"creator_notes",{rowKey:"notes"}),
|
|
1269
1359
|
h("div",{style:{display:"grid", gridTemplateColumns:"1fr 1fr", gap:10}},
|
|
1270
|
-
|
|
1271
|
-
|
|
1360
|
+
field("creation_date","creation_date",{rowKey:"cdate", input:true, readOnly:true, bigBox:false, value:String(s.draft.data.creation_date)}),
|
|
1361
|
+
field(t("workshop.export.modificationDate"),"modification_date",{rowKey:"mdate", input:true, readOnly:true, bigBox:false, value:String(s.draft.data.modification_date)})
|
|
1272
1362
|
),
|
|
1273
1363
|
s.lastMsg? h("div",{style:{marginTop:8, fontSize:12, color:"var(--dsw-alias-label-secondary)"}}, s.lastMsg):null
|
|
1274
1364
|
)
|
|
@@ -1276,7 +1366,11 @@ window.__ModuleLoader__.load({
|
|
|
1276
1366
|
}
|
|
1277
1367
|
var stepsEls=steps.map(function(label, i){
|
|
1278
1368
|
var active=s.cur===i;
|
|
1279
|
-
|
|
1369
|
+
var hovered=hoverKey==="step:"+i;
|
|
1370
|
+
return h("span",{key:i, style: Object.assign({}, S.step, hovered&&!active? S.stepHover:{}, active? S.stepActive:{}),
|
|
1371
|
+
onMouseEnter:function(){ setHoverKey("step:"+i); },
|
|
1372
|
+
onMouseLeave:function(){ setHoverKey(null); },
|
|
1373
|
+
onClick:function(){ store.setCur(i); }}, (i+1)+". "+label);
|
|
1280
1374
|
});
|
|
1281
1375
|
var filteredLibrary = (function(){
|
|
1282
1376
|
var q = String(s.libraryQuery||"").trim().toLowerCase();
|
|
@@ -1288,7 +1382,7 @@ window.__ModuleLoader__.load({
|
|
|
1288
1382
|
return nameMatch || tagMatch || loreMatch;
|
|
1289
1383
|
});
|
|
1290
1384
|
})();
|
|
1291
|
-
var bodyStyle = Object.assign({}, S.body, {gridTemplateColumns: s.libraryCollapsed ? "
|
|
1385
|
+
var bodyStyle = Object.assign({}, S.body, {gridTemplateColumns: s.libraryCollapsed ? "200px 1fr 40px" : "200px 1fr 268px"});
|
|
1292
1386
|
function renderLibrary(){
|
|
1293
1387
|
if(s.libraryCollapsed){
|
|
1294
1388
|
return h("div",{style:S.libraryCollapsedBar},
|
|
@@ -1357,7 +1451,12 @@ window.__ModuleLoader__.load({
|
|
|
1357
1451
|
)
|
|
1358
1452
|
);
|
|
1359
1453
|
}
|
|
1360
|
-
return h("div",{style:S.overlay,
|
|
1454
|
+
return h("div",{style:S.overlay,
|
|
1455
|
+
onClick:function(e){ if(e.target===e.currentTarget) store.setPanel(false); },
|
|
1456
|
+
// 鼠标一操作就收起键盘焦点环:否则「键盘 Tab 聚焦 A → 鼠标点顶部胶囊切步」时,
|
|
1457
|
+
// A 的光环会一直挂在那儿,看起来又是一个「选中」。这里只清我们自己的环,不抢焦点
|
|
1458
|
+
// (输入框/文本域照常能点进去)。
|
|
1459
|
+
onMouseDown:function(){ if(focusKey) setFocusKey(null); }},
|
|
1361
1460
|
h("div",{style:S.workshop, role:"dialog", "aria-modal":"true"},
|
|
1362
1461
|
h("div",{style:S.head},
|
|
1363
1462
|
h("div",{style:{display:"flex", gap:12, alignItems:"center", flexWrap:"wrap"}},
|
|
@@ -1406,25 +1505,30 @@ window.__ModuleLoader__.load({
|
|
|
1406
1505
|
navItem(2, t("step.lore"), t("step.lore.desc")),
|
|
1407
1506
|
navItem(3, t("step.export"), t("step.export.desc")),
|
|
1408
1507
|
h("div",{style:{marginTop:"auto", paddingTop:12, borderTop:"1px solid var(--dsw-alias-border-l1)", display:"flex", flexDirection:"column", gap:8}},
|
|
1409
|
-
h("button",{style: Object.assign({}, S.btn, {padding:"6px 10px", fontSize:12}),
|
|
1508
|
+
h("button",{type:"button", style: Object.assign({}, S.btn, {padding:"6px 10px", fontSize:12}),
|
|
1509
|
+
onMouseDown:function(e){ if(e && e.preventDefault) e.preventDefault(); }, // 鼠标点击不抢焦点,免得又留下一圈焦点描边(同左侧步骤项)
|
|
1510
|
+
onClick:function(){ store.validate(); }}, s.busy==="validate"? t("action.validating"): t("action.validate")),
|
|
1511
|
+
// 清空是破坏性操作:先过二次确认才动手;工坊里没有撤销,所以按钮用危险色并与「校验」分开放
|
|
1512
|
+
h("button",{type:"button", style: Object.assign({}, S.btn, S.btnGhost, {padding:"6px 10px", fontSize:12, borderColor:"rgba(224,85,85,.55)", color:"#e05555"}),
|
|
1513
|
+
onMouseDown:function(e){ if(e && e.preventDefault) e.preventDefault(); },
|
|
1514
|
+
onClick:function(){ if(confirmClear(t)) store.clearDraft(); }}, t("action.clear")),
|
|
1410
1515
|
h("div",{style:{fontSize:11, color:"var(--dsw-alias-label-secondary)", textAlign:"center"}}, s.busy? s.busy: (s.lastMsg||t("workshop.library.noCcHint")))
|
|
1411
1516
|
)
|
|
1412
1517
|
),
|
|
1413
|
-
h("div",{style:S.main},
|
|
1518
|
+
h("div",{style:S.main},
|
|
1519
|
+
main,
|
|
1520
|
+
// 三块阅读辅助收到主区底部、默认收起:它们原来占着右侧 360px 一整栏,把阅读区压得很窄
|
|
1521
|
+
foldPanel("preview", t("workshop.preview.title"),
|
|
1522
|
+
h("span",{style:{display:"flex", gap:6, alignItems:"center", flexShrink:0}},
|
|
1523
|
+
h("span",{style:S.badge}, t("common.spec")),
|
|
1524
|
+
h("span",{style:Object.assign({}, S.badge, s.valid.valid? {color:"#a6e8c8", borderColor:"var(--dsw-alias-state-success-primary)"}:{color:"#e8a6a6", borderColor:"var(--dsw-alias-state-error-primary)"})}, s.valid.valid? t("common.passed"):t("common.failed"))),
|
|
1525
|
+
h("pre",{style:{whiteSpace:"pre-wrap", wordBreak:"break-all", background:"var(--dsw-alias-bg-base)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:10, padding:12, maxHeight:420, overflow:"auto", margin:0, fontSize:11, lineHeight:1.6}}, JSON.stringify(s.draft, null, 2))),
|
|
1526
|
+
foldPanel("cbs", t("workshop.preview.cbsTitle"), null,
|
|
1527
|
+
h("div",null,
|
|
1528
|
+
h("div",{style:{display:"flex", flexWrap:"wrap", gap:6}}, ["{{char}}","{{user}}","{{random:A,B}}","{{roll:d6}}",t("workshop.preview.cbsComment")].map(function(c){ return h("span",{key:c, style:S.chip}, c); })),
|
|
1529
|
+
h("div",{style:{color:"var(--dsw-alias-label-secondary)", fontSize:12, marginTop:8}}, t("workshop.preview.cbsHint")))),
|
|
1530
|
+
),
|
|
1414
1531
|
renderLibrary(),
|
|
1415
|
-
h("div",{style:S.side},
|
|
1416
|
-
h("div",{style:S.card}, h("h3",{style:{margin:"0 0 8px", fontSize:13}},t("workshop.preview.title")),
|
|
1417
|
-
h("div",{style:{display:"flex", flexWrap:"wrap", gap:6, marginBottom:8}}, h("span",{style:S.badge},t("common.spec")), h("span",{style: Object.assign({}, S.badge, s.valid.valid? {color:"#a6e8c8", borderColor:"var(--dsw-alias-state-success-primary)"}:{color:"#e8a6a6", borderColor:"var(--dsw-alias-state-error-primary)"})}, s.valid.valid? t("common.passed"):t("common.failed"))),
|
|
1418
|
-
h("pre",{style:{whiteSpace:"pre-wrap", wordBreak:"break-all", background:"var(--dsw-alias-bg-base)", border:"1px solid var(--dsw-alias-border-l1)", borderRadius:10, padding:10, maxHeight:420, overflow:"auto", margin:0, fontSize:11}}, JSON.stringify(s.draft, null, 2))
|
|
1419
|
-
),
|
|
1420
|
-
h("div",{style:S.card}, h("h3",{style:{margin:"0 0 8px", fontSize:13}},t("workshop.preview.cbsTitle")),
|
|
1421
|
-
h("div",{style:{display:"flex", flexWrap:"wrap", gap:6}}, ["{{char}}","{{user}}","{{random:A,B}}","{{roll:d6}}",t("workshop.preview.cbsComment")].map(function(c){ return h("span",{key:c, style:S.chip}, c); })),
|
|
1422
|
-
h("div",{style:{color:"var(--dsw-alias-label-secondary)", fontSize:12, marginTop:8}}, t("workshop.preview.cbsHint"))
|
|
1423
|
-
),
|
|
1424
|
-
h("div",{style:S.card}, h("h3",{style:{margin:"0 0 8px", fontSize:13}},t("workshop.preview.fusionTitle")),
|
|
1425
|
-
h("div",{style:{color:"var(--dsw-alias-label-secondary)", fontSize:12, lineHeight:1.5}}, t("workshop.preview.fusionDesc"))
|
|
1426
|
-
)
|
|
1427
|
-
)
|
|
1428
1532
|
)
|
|
1429
1533
|
),
|
|
1430
1534
|
s.editingWorld ? h("div",{style:Object.assign({}, S.overlay, {background:"rgba(0,0,0,.55)", zIndex:40}), onClick:function(e){ if(e.target===e.currentTarget) store.setEditingWorld(null); }},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xia-sc/dsh-cc-studio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "CCv3 角色卡工坊:融合工坊 + CC 模式 + JSON/PNG/CHARX + 中英双语(跟随全局)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"type": "module",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=22"
|
|
27
|
+
},
|
|
25
28
|
"main": "lib/index.js",
|
|
26
29
|
"exports": {
|
|
27
30
|
".": "./lib/index.js",
|
|
@@ -35,7 +38,7 @@
|
|
|
35
38
|
"presets"
|
|
36
39
|
],
|
|
37
40
|
"scripts": {
|
|
38
|
-
"test": "node tests/rpc-channel.test.mjs && node tests/preset-install.test.mjs && node tests/cc-detection.test.mjs && node tests/client-greetings.test.mjs && node tests/draft-slot-sync.test.mjs && node tests/data-root.test.mjs",
|
|
41
|
+
"test": "node tests/rpc-channel.test.mjs && node tests/preset-install.test.mjs && node tests/cc-detection.test.mjs && node tests/client-greetings.test.mjs && node tests/draft-slot-sync.test.mjs && node tests/nav-highlight.test.mjs && node tests/clear-card.test.mjs && node tests/data-root.test.mjs",
|
|
39
42
|
"prepublishOnly": "npm test"
|
|
40
43
|
},
|
|
41
44
|
"dsh": {
|
|
@@ -52,11 +55,20 @@
|
|
|
52
55
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
53
56
|
"@deepseek-ai/dsh-client-ui-layout"
|
|
54
57
|
]
|
|
58
|
+
},
|
|
59
|
+
"compatibility": {
|
|
60
|
+
"dsh": ">=0.1.5-rc.1",
|
|
61
|
+
"dshReleases": {
|
|
62
|
+
"0.1.5-rc.1": "compatible",
|
|
63
|
+
"0.1.5-rc.2": "compatible",
|
|
64
|
+
"0.1.6-alpha.1": "compatible",
|
|
65
|
+
"0.1.6-alpha.2": "compatible",
|
|
66
|
+
"0.1.7-alpha.1": "compatible",
|
|
67
|
+
"0.1.7-rc.1": "compatible",
|
|
68
|
+
"0.2.0-rc.2": "compatible"
|
|
69
|
+
}
|
|
55
70
|
}
|
|
56
71
|
},
|
|
57
|
-
"dependencies": {
|
|
58
|
-
"@deepseek-ai/cordis": "^4.0.1"
|
|
59
|
-
},
|
|
60
72
|
"publishConfig": {
|
|
61
73
|
"access": "public"
|
|
62
74
|
}
|