dsh-muv-table 0.2.1 → 0.2.2

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/CHANGELOG.md CHANGED
@@ -1,21 +1,52 @@
1
- # Changelog
2
-
3
- ## v0.2.0 (2026-08-27)
4
-
5
- ### ✨ 新功能
6
- - **宏测试浮窗**:点击面板 header 的「📐 宏」按钮弹出
7
- - 输入宏语法 → 展开测试 → 实时看结果
8
- - 展开结果支持「📋 复制」和「⬆ 填入」(回填到输入框继续编辑)
9
- - 🎲 快捷骰子栏:d4/d6/d8/d10/d12/d20/2d6/3d6/1d100 一键掷骰
10
- - 📌 Pick 缓存列表:展示所有缓存 key→值,单个重抽或全部清除
11
- - 📖 语法帮助折叠区
12
-
13
- ### 🔧 改进
14
- - Header 按钮精简:去掉重复的「🍺 酒馆」按钮(与 🔄 刷新功能重复),替换为「📐 宏」
15
- - 依赖 muv-engine 升级到 `^0.2.0`
16
-
17
- ---
18
-
19
- ## v0.1.0 (2026-08-26)
20
-
1
+ # Changelog
2
+
3
+ ## v0.2.2 (2026-09-13)
4
+
5
+ ### 🐛 修复
6
+
7
+ - **exports 放开 `./lib/*` 子路径**:`dsh-muv-engine` 需要导入本包的
8
+ `lib/muv-parser.js`、`lib/block-generator.js`、`lib/initvar-parser.js`,
9
+ 但 `exports` 只映射了 `.` 与 `./client`,子路径导入会被 Node 的 exports 门禁拦住:
10
+
11
+ ```
12
+ import('dsh-muv-table/lib/muv-parser.js')
13
+ -> ERR_PACKAGE_PATH_NOT_EXPORTED
14
+ ```
15
+
16
+ 新增 `"./lib/*": "./lib/*"` 后即可正常解析。
17
+
18
+ ### 🔧 改进
19
+
20
+ - **`panel.html` 读取改为容错**:原先在模块加载时直接
21
+ `const PANEL_HTML = fs.readFileSync(...)`,一旦文件缺失就抛 `ENOENT`。
22
+ 由于模块加载失败会让所在 loader 行激活失败,而 DSH 启动时会校验每一行,
23
+ 这会让**整个 DSH 起不来**。改为 `let PANEL_HTML = ''` + `try/catch` 兜底。
24
+ 此改动与已发布的 0.2.1 npm 包保持一致(git 仓库此前落后于发布版)。
25
+
26
+ ### 📝 注意
27
+
28
+ - `lib/panel.html` 被 `.gitignore` 排除,因此**从 `git clone` 的目录直接
29
+ `dsh plugin add <路径>` 安装时该文件不存在**。容错改动后不会再导致启动失败,
30
+ 但面板内容会为空 —— 请走 npm registry 安装。
31
+
32
+ ---
33
+
34
+ ## v0.2.0 (2026-08-27)
35
+
36
+ ### ✨ 新功能
37
+ - **宏测试浮窗**:点击面板 header 的「📐 宏」按钮弹出
38
+ - 输入宏语法 → 展开测试 → 实时看结果
39
+ - 展开结果支持「📋 复制」和「⬆ 填入」(回填到输入框继续编辑)
40
+ - 🎲 快捷骰子栏:d4/d6/d8/d10/d12/d20/2d6/3d6/1d100 一键掷骰
41
+ - 📌 Pick 缓存列表:展示所有缓存 key→值,单个重抽或全部清除
42
+ - 📖 语法帮助折叠区
43
+
44
+ ### 🔧 改进
45
+ - Header 按钮精简:去掉重复的「🍺 酒馆」按钮(与 🔄 刷新功能重复),替换为「📐 宏」
46
+ - 依赖 muv-engine 升级到 `^0.2.0`
47
+
48
+ ---
49
+
50
+ ## v0.1.0 (2026-08-26)
51
+
21
52
  - 初始版本:树形变量表格编辑器、酒馆侧边栏入口、从酒馆加载角色卡、MUV 块生成
package/LICENSE CHANGED
@@ -1,86 +1,86 @@
1
- # PolyForm Noncommercial Copyleft License 1.0.0
2
-
3
- Copyright (c) 2026 chen731215-dev
4
-
5
- ## Acceptance
6
-
7
- In order to get any license under these terms, you must agree to them as both
8
- strict obligations and conditions to all your licenses.
9
-
10
- ## Copyright License
11
-
12
- The licensor grants you a copyright license for the software to do everything
13
- you might do with the software that would otherwise infringe the licensor's
14
- copyright for any purpose except for a commercial purpose.
15
-
16
- ## Noncommercial Purposes
17
-
18
- A noncommercial purpose is any purpose that is not a commercial purpose.
19
-
20
- A commercial purpose is one intended for commercial advantage or monetary
21
- compensation. For purposes of this license, commercial advantage or monetary
22
- compensation includes but is not limited to:
23
-
24
- 1. selling, licensing, or distributing the software as part of a commercial
25
- product or service
26
-
27
- 2. using the software to provide a commercial service, including but not
28
- limited to software-as-a-service, platform-as-a-service, or
29
- infrastructure-as-a-service offerings
30
-
31
- 3. using the software in any manner that directly or indirectly generates
32
- revenue
33
-
34
- ## Copyleft
35
-
36
- With respect to any copies or modifications of the software that you make or
37
- distribute, you must license them to recipients under the same terms as this
38
- license. You must make available the source code of any modifications you make.
39
-
40
- ## Notices
41
-
42
- You must ensure that everyone who gets a copy of any part of the software
43
- from you also gets a copy of these terms or a link to
44
- https://polyformproject.org/licenses/noncommercial-copyleft/1.0.0/.
45
-
46
- ## Patent License
47
-
48
- The licensor grants you a patent license for the software that covers patent
49
- claims the licensor can license, or becomes able to license, that you would
50
- infringe by using the software.
51
-
52
- ## No Other Rights
53
-
54
- These terms do not allow you to sublicense or transfer any of your licenses
55
- to anyone else, or prevent the licensor from granting licenses to anyone else.
56
- These terms do not imply any other licenses.
57
-
58
- ## No Liability
59
-
60
- ***As far as the law allows, the software comes as is, without any warranty
61
- or condition, and the licensor will not be liable to you for any damages
62
- arising out of these terms or the use or nature of the software, under any
63
- kind of legal claim.***
64
-
65
- ## Definitions
66
-
67
- The **licensor** is the individual or entity offering these terms, and the
68
- **software** is the software the licensor makes available under these terms.
69
-
70
- **You** refers to the individual or entity agreeing to these terms.
71
-
72
- **Your company** is any legal entity, sole proprietorship, or other kind of
73
- organization that you work for, plus all organizations that have control over,
74
- are under the control of, or are under common control with that organization.
75
- Control means ownership of substantially all the assets of an entity, or the
76
- power to direct its management and policies by vote, contract, or otherwise.
77
- Control can be direct or indirect.
78
-
79
- **Your licenses** are all the licenses granted to you for the software under
80
- these terms.
81
-
82
- **Use** means anything you do with the software requiring one of your licenses.
83
-
84
- **Modify** means to copy from or adapt all or part of the work in a fashion
85
- requiring copyright permission, other than the making of an exact copy. The
1
+ # PolyForm Noncommercial Copyleft License 1.0.0
2
+
3
+ Copyright (c) 2026 chen731215-dev
4
+
5
+ ## Acceptance
6
+
7
+ In order to get any license under these terms, you must agree to them as both
8
+ strict obligations and conditions to all your licenses.
9
+
10
+ ## Copyright License
11
+
12
+ The licensor grants you a copyright license for the software to do everything
13
+ you might do with the software that would otherwise infringe the licensor's
14
+ copyright for any purpose except for a commercial purpose.
15
+
16
+ ## Noncommercial Purposes
17
+
18
+ A noncommercial purpose is any purpose that is not a commercial purpose.
19
+
20
+ A commercial purpose is one intended for commercial advantage or monetary
21
+ compensation. For purposes of this license, commercial advantage or monetary
22
+ compensation includes but is not limited to:
23
+
24
+ 1. selling, licensing, or distributing the software as part of a commercial
25
+ product or service
26
+
27
+ 2. using the software to provide a commercial service, including but not
28
+ limited to software-as-a-service, platform-as-a-service, or
29
+ infrastructure-as-a-service offerings
30
+
31
+ 3. using the software in any manner that directly or indirectly generates
32
+ revenue
33
+
34
+ ## Copyleft
35
+
36
+ With respect to any copies or modifications of the software that you make or
37
+ distribute, you must license them to recipients under the same terms as this
38
+ license. You must make available the source code of any modifications you make.
39
+
40
+ ## Notices
41
+
42
+ You must ensure that everyone who gets a copy of any part of the software
43
+ from you also gets a copy of these terms or a link to
44
+ https://polyformproject.org/licenses/noncommercial-copyleft/1.0.0/.
45
+
46
+ ## Patent License
47
+
48
+ The licensor grants you a patent license for the software that covers patent
49
+ claims the licensor can license, or becomes able to license, that you would
50
+ infringe by using the software.
51
+
52
+ ## No Other Rights
53
+
54
+ These terms do not allow you to sublicense or transfer any of your licenses
55
+ to anyone else, or prevent the licensor from granting licenses to anyone else.
56
+ These terms do not imply any other licenses.
57
+
58
+ ## No Liability
59
+
60
+ ***As far as the law allows, the software comes as is, without any warranty
61
+ or condition, and the licensor will not be liable to you for any damages
62
+ arising out of these terms or the use or nature of the software, under any
63
+ kind of legal claim.***
64
+
65
+ ## Definitions
66
+
67
+ The **licensor** is the individual or entity offering these terms, and the
68
+ **software** is the software the licensor makes available under these terms.
69
+
70
+ **You** refers to the individual or entity agreeing to these terms.
71
+
72
+ **Your company** is any legal entity, sole proprietorship, or other kind of
73
+ organization that you work for, plus all organizations that have control over,
74
+ are under the control of, or are under common control with that organization.
75
+ Control means ownership of substantially all the assets of an entity, or the
76
+ power to direct its management and policies by vote, contract, or otherwise.
77
+ Control can be direct or indirect.
78
+
79
+ **Your licenses** are all the licenses granted to you for the software under
80
+ these terms.
81
+
82
+ **Use** means anything you do with the software requiring one of your licenses.
83
+
84
+ **Modify** means to copy from or adapt all or part of the work in a fashion
85
+ requiring copyright permission, other than the making of an exact copy. The
86
86
  resulting work is called a modification of the earlier work.
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # PolyForm Noncommercial Copyleft 1.0.0
2
+
3
+ This software is licensed under the PolyForm Noncommercial Copyleft 1.0.0 license.
4
+
5
+ Full license: https://polyformproject.org/licenses/noncommercial-copyleft/1.0.0/
6
+
7
+ - ✅ Free for non-commercial use
8
+ - ✅ Modifications must be shared under the same license
9
+ - ❌ Commercial use requires a separate license
package/README.md CHANGED
@@ -1,60 +1,60 @@
1
- # 📊 dsh-muv-table
2
-
3
- MUV 变量表格编辑器 —— 酒馆伴生插件。
4
-
5
- > 🍺 本插件是 [dsh-tavern-v2](https://github.com/chen731215-dev/dsh-tavern-v2) 的扩展,需配合酒馆使用。
6
-
7
- ## 是什么
8
-
9
- 把酒馆角色卡的 MUV 变量渲染成结构化表格,Agent 直接编辑表格即可生成格式100%正确的 `<UpdateVariable>` 块,彻底避免 DeepSeek 漏变量、缩进错、标签不闭合的问题。
10
-
11
- ## 安装
12
-
13
- ```bash
14
- # 前提:已安装 dsh-tavern-v2
15
- dsh plugin --profile web add dsh-muv-table
16
- ```
17
-
18
- 或手动编辑 `~/.dsh/profiles/web/package.json`:
19
-
20
- ```json
21
- {
22
- "dependencies": {
23
- "dsh-muv-table": "github:chen731215-dev/dsh-muv-table"
24
- },
25
- "dsh": {
26
- "profile": {
27
- "bundles": ["dsh-muv-table"]
28
- }
29
- }
30
- }
31
- ```
32
-
33
- ## 使用
34
-
35
- ### 1. 打开面板
36
- 左侧边栏点击「MUV 表格」,弹出变量编辑窗口。
37
-
38
- ### 2. 加载角色卡
39
- - **自动同步**:面板打开时自动读取酒馆当前角色卡
40
- - **手动加载**:点击「🍺 酒馆」按钮
41
- - **拖放**:将角色卡 JSON 文件拖入面板
42
-
43
- ### 3. 编辑变量
44
- - 点击容器行展开/折叠子变量
45
- - 直接修改数值或文本
46
- - 修改过的字段金色高亮
47
-
48
- ### 4. 生成 MUV 块
49
- 点击「⚡ 生成 MUV 块」→ 复制 → 粘贴到酒馆对话末尾。
50
-
51
- ## 支持的角色卡
52
-
53
- | 类型 | 说明 |
54
- |------|------|
55
- | 有 `<initvar>` 默认数据 | 直接显示完整变量表 |
56
- | 无 `<initvar>`(如瑟瑟提瓦特) | 显示空表,LLM 输出 UpdateVariable 后自动填充 |
57
-
58
- ## 协议
59
-
1
+ # 📊 dsh-muv-table
2
+
3
+ MUV 变量表格编辑器 —— 酒馆伴生插件。
4
+
5
+ > 🍺 本插件是 [dsh-tavern-v2](https://github.com/chen731215-dev/dsh-tavern-v2) 的扩展,需配合酒馆使用。
6
+
7
+ ## 是什么
8
+
9
+ 把酒馆角色卡的 MUV 变量渲染成结构化表格,Agent 直接编辑表格即可生成格式100%正确的 `<UpdateVariable>` 块,彻底避免 DeepSeek 漏变量、缩进错、标签不闭合的问题。
10
+
11
+ ## 安装
12
+
13
+ ```bash
14
+ # 前提:已安装 dsh-tavern-v2
15
+ dsh plugin --profile web add dsh-muv-table
16
+ ```
17
+
18
+ 或手动编辑 `~/.dsh/profiles/web/package.json`:
19
+
20
+ ```json
21
+ {
22
+ "dependencies": {
23
+ "dsh-muv-table": "github:chen731215-dev/dsh-muv-table"
24
+ },
25
+ "dsh": {
26
+ "profile": {
27
+ "bundles": ["dsh-muv-table"]
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## 使用
34
+
35
+ ### 1. 打开面板
36
+ 左侧边栏点击「MUV 表格」,弹出变量编辑窗口。
37
+
38
+ ### 2. 加载角色卡
39
+ - **自动同步**:面板打开时自动读取酒馆当前角色卡
40
+ - **手动加载**:点击「🍺 酒馆」按钮
41
+ - **拖放**:将角色卡 JSON 文件拖入面板
42
+
43
+ ### 3. 编辑变量
44
+ - 点击容器行展开/折叠子变量
45
+ - 直接修改数值或文本
46
+ - 修改过的字段金色高亮
47
+
48
+ ### 4. 生成 MUV 块
49
+ 点击「⚡ 生成 MUV 块」→ 复制 → 粘贴到酒馆对话末尾。
50
+
51
+ ## 支持的角色卡
52
+
53
+ | 类型 | 说明 |
54
+ |------|------|
55
+ | 有 `<initvar>` 默认数据 | 直接显示完整变量表 |
56
+ | 无 `<initvar>`(如瑟瑟提瓦特) | 显示空表,LLM 输出 UpdateVariable 后自动填充 |
57
+
58
+ ## 协议
59
+
60
60
  PolyForm-Noncommercial-Copyleft-1.0.0 — 详见 [LICENSE](./LICENSE)
package/cordis.patch.yml CHANGED
@@ -1,6 +1,6 @@
1
- # dsh-muv-table bundle patch: mounts the MUV table editor plugin.
2
- # The plugin parses MUV character cards, renders Zod schemas as
3
- # structured tables, and generates correct <UpdateVariable> blocks.
4
- - insert:
5
- - id: muv-table
1
+ # dsh-muv-table bundle patch: mounts the MUV table editor plugin.
2
+ # The plugin parses MUV character cards, renders Zod schemas as
3
+ # structured tables, and generates correct <UpdateVariable> blocks.
4
+ - insert:
5
+ - id: muv-table
6
6
  name: 'dsh-muv-table'
@@ -1,57 +1,57 @@
1
- // MUV Block Generator: takes structured table data and generates
2
- // a correctly formatted <UpdateVariable><initvar> block.
3
-
4
- import { serializeInitvar } from './initvar-parser.js'
5
-
6
- /**
7
- * Generate a complete <UpdateVariable> block from a nested data object.
8
- * @param {object} data - The full variable data (nested object)
9
- * @returns {string} The formatted <UpdateVariable><initvar>...</initvar></UpdateVariable> block
10
- */
11
- export function generateMuvBlock(data) {
12
- const inner = serializeInitvar(data)
13
- return `<UpdateVariable>\n<initvar>\n${inner}</initvar>\n</UpdateVariable>`
14
- }
15
-
16
- /**
17
- * Apply table edits to the data tree and generate the MUV block.
18
- * @param {object} originalData - The original parsed initvar data
19
- * @param {Array<{path: string, value: any}>} edits - Array of path-value edits
20
- * @returns {string} The generated MUV block
21
- */
22
- export function applyEditsAndGenerate(originalData, edits) {
23
- const data = JSON.parse(JSON.stringify(originalData)) // deep clone
24
-
25
- for (const edit of edits) {
26
- setNestedValue(data, edit.path, edit.value)
27
- }
28
-
29
- return generateMuvBlock(data)
30
- }
31
-
32
- /**
33
- * Set a deeply nested value by dot-separated path.
34
- * @param {object} obj
35
- * @param {string} path - e.g. "Player.资产.黄金"
36
- * @param {*} value
37
- */
38
- function setNestedValue(obj, path, value) {
39
- const keys = path.split('.')
40
- let current = obj
41
- for (let i = 0; i < keys.length - 1; i++) {
42
- const key = keys[i]
43
- if (!(key in current)) {
44
- current[key] = {}
45
- }
46
- current = current[key]
47
- }
48
- const lastKey = keys[keys.length - 1]
49
-
50
- // Coerce types
51
- if (typeof current[lastKey] === 'number' || (!isNaN(current[lastKey]) && current[lastKey] !== '' && current[lastKey] !== null && current[lastKey] !== undefined)) {
52
- const num = Number(value)
53
- current[lastKey] = isNaN(num) ? value : num
54
- } else {
55
- current[lastKey] = value
56
- }
1
+ // MUV Block Generator: takes structured table data and generates
2
+ // a correctly formatted <UpdateVariable><initvar> block.
3
+
4
+ import { serializeInitvar } from './initvar-parser.js'
5
+
6
+ /**
7
+ * Generate a complete <UpdateVariable> block from a nested data object.
8
+ * @param {object} data - The full variable data (nested object)
9
+ * @returns {string} The formatted <UpdateVariable><initvar>...</initvar></UpdateVariable> block
10
+ */
11
+ export function generateMuvBlock(data) {
12
+ const inner = serializeInitvar(data)
13
+ return `<UpdateVariable>\n<initvar>\n${inner}</initvar>\n</UpdateVariable>`
14
+ }
15
+
16
+ /**
17
+ * Apply table edits to the data tree and generate the MUV block.
18
+ * @param {object} originalData - The original parsed initvar data
19
+ * @param {Array<{path: string, value: any}>} edits - Array of path-value edits
20
+ * @returns {string} The generated MUV block
21
+ */
22
+ export function applyEditsAndGenerate(originalData, edits) {
23
+ const data = JSON.parse(JSON.stringify(originalData)) // deep clone
24
+
25
+ for (const edit of edits) {
26
+ setNestedValue(data, edit.path, edit.value)
27
+ }
28
+
29
+ return generateMuvBlock(data)
30
+ }
31
+
32
+ /**
33
+ * Set a deeply nested value by dot-separated path.
34
+ * @param {object} obj
35
+ * @param {string} path - e.g. "Player.资产.黄金"
36
+ * @param {*} value
37
+ */
38
+ function setNestedValue(obj, path, value) {
39
+ const keys = path.split('.')
40
+ let current = obj
41
+ for (let i = 0; i < keys.length - 1; i++) {
42
+ const key = keys[i]
43
+ if (!(key in current)) {
44
+ current[key] = {}
45
+ }
46
+ current = current[key]
47
+ }
48
+ const lastKey = keys[keys.length - 1]
49
+
50
+ // Coerce types
51
+ if (typeof current[lastKey] === 'number' || (!isNaN(current[lastKey]) && current[lastKey] !== '' && current[lastKey] !== null && current[lastKey] !== undefined)) {
52
+ const num = Number(value)
53
+ current[lastKey] = isNaN(num) ? value : num
54
+ } else {
55
+ current[lastKey] = value
56
+ }
57
57
  }