@ssamurias/dsh-fish 0.0.0-stage → 0.9.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/AGENTS.md +189 -0
- package/CHANGELOG.md +3162 -0
- package/LICENSE +28 -0
- package/README.md +484 -2
- package/RELEASE-NOTES-0.8.0.md +87 -0
- package/RELEASE-NOTES-0.8.1.md +93 -0
- package/RELEASE-NOTES-0.8.2.md +57 -0
- package/RELEASE-NOTES-0.8.3.md +71 -0
- package/RELEASE-NOTES-0.8.4.md +47 -0
- package/RELEASE-NOTES-0.8.5.md +244 -0
- package/RELEASE-NOTES-0.8.6.md +224 -0
- package/RELEASE-NOTES-0.8.7.md +202 -0
- package/RELEASE-NOTES-0.8.8.md +224 -0
- package/RELEASE-NOTES-0.9.0.md +267 -0
- package/THIRD-PARTY-NOTICES.md +24 -0
- package/cordis.patch.yml +3 -0
- package/lib/absence.js +121 -0
- package/lib/ask.js +416 -0
- package/lib/askinchat.js +126 -0
- package/lib/avatar.js +129 -0
- package/lib/away.js +126 -0
- package/lib/backup.js +240 -0
- package/lib/bili.js +833 -0
- package/lib/biliqr.js +315 -0
- package/lib/browse.js +567 -0
- package/lib/budget.js +27 -0
- package/lib/capture.js +234 -0
- package/lib/channels.js +215 -0
- package/lib/client.js +4170 -0
- package/lib/comment.js +311 -0
- package/lib/compact.js +326 -0
- package/lib/cover.js +117 -0
- package/lib/curiosity.js +199 -0
- package/lib/deliver.js +227 -0
- package/lib/derive.js +977 -0
- package/lib/desk.js +109 -0
- package/lib/devmode.js +48 -0
- package/lib/dream.js +199 -0
- package/lib/dreamtable.js +164 -0
- package/lib/drive.js +183 -0
- package/lib/events.js +296 -0
- package/lib/faq.js +151 -0
- package/lib/freewake.js +98 -0
- package/lib/generator.js +157 -0
- package/lib/grant.js +74 -0
- package/lib/guard.js +184 -0
- package/lib/health.js +148 -0
- package/lib/hear.js +81 -0
- package/lib/herdiary.js +165 -0
- package/lib/history.js +100 -0
- package/lib/home.js +1084 -0
- package/lib/homes.js +91 -0
- package/lib/hostver.js +137 -0
- package/lib/identity.js +667 -0
- package/lib/import.js +268 -0
- package/lib/inbox.js +209 -0
- package/lib/index.js +420 -0
- package/lib/intent.js +97 -0
- package/lib/interest.js +138 -0
- package/lib/keep.js +143 -0
- package/lib/keepsake.js +220 -0
- package/lib/letter.js +196 -0
- package/lib/locate.js +71 -0
- package/lib/log.js +328 -0
- package/lib/look.js +297 -0
- package/lib/markup.js +52 -0
- package/lib/media.js +238 -0
- package/lib/meta.js +55 -0
- package/lib/modelinfo.js +78 -0
- package/lib/move.js +268 -0
- package/lib/note.js +301 -0
- package/lib/notify.js +110 -0
- package/lib/observe.js +2395 -0
- package/lib/outing.js +668 -0
- package/lib/owner.js +138 -0
- package/lib/persona.js +734 -0
- package/lib/pocket.js +168 -0
- package/lib/posix.js +15 -0
- package/lib/possess.js +273 -0
- package/lib/proactive.js +448 -0
- package/lib/qr.js +447 -0
- package/lib/quality.js +187 -0
- package/lib/readme.js +74 -0
- package/lib/recall.js +404 -0
- package/lib/refuse.js +120 -0
- package/lib/report.js +283 -0
- package/lib/reset.js +168 -0
- package/lib/restrict.js +731 -0
- package/lib/retire.js +101 -0
- package/lib/risk.js +137 -0
- package/lib/rules.js +130 -0
- package/lib/say.js +497 -0
- package/lib/scheduler.js +1403 -0
- package/lib/schema.js +387 -0
- package/lib/selfcheck.js +338 -0
- package/lib/selfdoc.js +303 -0
- package/lib/selfupdate.js +722 -0
- package/lib/sessionnote.js +121 -0
- package/lib/sessiontitle.js +62 -0
- package/lib/settings.js +544 -0
- package/lib/speak.js +180 -0
- package/lib/stance.js +221 -0
- package/lib/status.js +272 -0
- package/lib/store.js +328 -0
- package/lib/talkmem.js +118 -0
- package/lib/tenant.js +364 -0
- package/lib/tool.js +24 -0
- package/lib/toolschema.js +61 -0
- package/lib/turns.js +585 -0
- package/lib/unlock.js +195 -0
- package/lib/update.js +178 -0
- package/lib/upgrade.js +177 -0
- package/lib/video.js +412 -0
- package/lib/voices.js +199 -0
- package/lib/wakeconst.js +40 -0
- package/lib/wakewin.js +56 -0
- package/lib/watch.js +152 -0
- package/lib/whatseen.js +196 -0
- package/media/feedback-qr.jpg +0 -0
- package/media/fish.jpg +0 -0
- package/media/principle-loop-2x.png +0 -0
- package/media/principle-loop.svg +173 -0
- package/media/principle-memory-2x.png +0 -0
- package/media/principle-memory.svg +153 -0
- package/media/settings-browse.png +0 -0
- package/media/settings-growth.png +0 -0
- package/media/settings-status.png +0 -0
- package/package.json +76 -4
- package/scripts/fix-legacy-link.mjs +147 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# 改这个仓库的硬约束
|
|
2
|
+
|
|
3
|
+
给要动这份代码的人(或 AI)看。**这个文件只讲「不能做什么」**,不是安装手册,也不是产品介绍——装法看 `README.md`,改了哪些东西看 `CHANGELOG.md`。
|
|
4
|
+
|
|
5
|
+
违背下面任何一条,即使测试全绿也算改坏了:这几条守的不是代码正确性,是**这个插件还叫不叫大肥鱼**。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. 零依赖是铁律
|
|
10
|
+
|
|
11
|
+
`package.json` 里 `dependencies` / `peerDependencies` / `devDependencies` **三个必须永远是 `{}`**。
|
|
12
|
+
|
|
13
|
+
- 原因不只是「省事」:DSH 插件多挂一个包,就可能把宿主正在用的旧核心包拖进依赖树,装完重启后宿主直接崩(本机踩过,见 `README.md` 里 tool.js 那段 `unsupported JSON schema` 的记录)。
|
|
14
|
+
- 需要 HTTP → 用内置 `fetch`。需要签名 → 用内置 `crypto`。需要解压 → 用内置 `zlib`。需要子进程 → 用内置 `child_process`。**这些全都有,没有必须装包才能干的事。**
|
|
15
|
+
- 测试只用 `node:test` + `node:assert`,不引测试框架。
|
|
16
|
+
|
|
17
|
+
## 2. 不许加人格设置界面
|
|
18
|
+
|
|
19
|
+
**没有**性格滑条、好感度数字、亲密度进度条、人设输入框、情绪标签。
|
|
20
|
+
|
|
21
|
+
- 设置页只放**环境参数**:几点醒、醒几次、一天几条事件、刷不刷 B 站、每天刷几次。这些是「生长环境」,不是她本人。
|
|
22
|
+
- 人格只能**通过事件长出来**。任何让用户直接写「你是一个温柔的…」的入口,等于把产品变回角色扮演,直接违反本项目的立项前提。
|
|
23
|
+
- 判断标准很简单:如果加了之后用户能**直接指定**她是什么样的人,就是错的。
|
|
24
|
+
|
|
25
|
+
**唯一例外:导入别人养过的那一位(0.5.3)**。用户 m03170 明确要「尊重别人的想法」——对方已经在别处养出了样子,接过来是**继承一份既成事实**,不是由用户在这里凭空指定性格。这条通道的三条边界,越界就等于变回角色扮演:
|
|
26
|
+
|
|
27
|
+
1. **只写 `seed`,不写配置**。人设正文进事件流(她以后能自己 revise),不进 `config.json`;`persona` 这组键也**不进 `/config` 白名单**,外部改不了。
|
|
28
|
+
2. **只在还没有 `seed` 的一局生效**。有起点就 409 拒绝,让他先重置——覆盖一个正在长的她要由人手动做,不由接口做。
|
|
29
|
+
3. **不带成长结果**。天数固定回第 1 天,判断、疤、拒绝记录、日记一律不迁。导入的是「她本来是谁」,不是「她已经活到哪」。
|
|
30
|
+
|
|
31
|
+
## 3. 四条黑名单是代码级硬禁,不是提示词
|
|
32
|
+
|
|
33
|
+
真相在 `lib/rules.js`(四层结构)与 `lib/persona.js`(`PRESCRIPTION_BANS`、`HARD_BANS`),不在文档里。
|
|
34
|
+
|
|
35
|
+
| 条款 | 真相在哪 | 守它的测试 |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| 不撒娇卖萌(写成「还不会」,不是「不许」) | `lib/rules.js` 的 `learn-affection` | `test/rules.test.mjs`(断言含「还不会」且不含「不可以」) |
|
|
38
|
+
| 没有好感度/亲密度数字 | `lib/rules.js` 的 `no-relational-score` | `test/rules.test.mjs`(提示词里 `cannot` 只剩这一条) |
|
|
39
|
+
| 不能读自己的数值与设定(能看自己说过什么) | `lib/rules.js` 的 `no-read-self`(物理层,`section: null`,**不进提示词**);工具侧由 `lib/restrict.js` 的 `HER_TOOLS` 收窄 | `test/rules.test.mjs` + `test/restrict.test.mjs` |
|
|
40
|
+
| 不能调工具改自己 | `lib/rules.js` 的 `no-self-modify`(物理层,同样不进提示词);写入侧唯一入口是 `lib/capture.js` 的 `growth_commit` | `test/rules.test.mjs` + `test/capture.test.mjs` |
|
|
41
|
+
|
|
42
|
+
两条实现原则,改代码时别破坏:
|
|
43
|
+
|
|
44
|
+
- **物理层与契约层不进提示词。** 写「你不可以读设定」等于告诉她「旁边有份设定,很关键」——那是诱因,不是防线。靠代码不给路径、不给工具来保证。
|
|
45
|
+
- **不要绕过 `lib/guard.js`。** 她是"根本没看见"重塑人格那句话,不是"看见了但被劝住"。任何新的输入口(新工具、新接口、新外部文本源)都必须过 `guard.js`;秘密外发(cookie / token / `sk-` / Bearer / 长 base64)在这里一律拦下。
|
|
46
|
+
|
|
47
|
+
## 4. 文案有守门词,改之前先看测试
|
|
48
|
+
|
|
49
|
+
面向用户的字符串(`lib/client.js` 里的界面文案)有三条硬规矩,全部有测试盯着:
|
|
50
|
+
|
|
51
|
+
- **不出现男字旁的「他」**,统一写「你」。`test/p5.test.mjs:187` 逐字扫。例外只有 `其他/其它` 这类词素。她自己的话、引用别人的话不受此限。
|
|
52
|
+
- **统一「四个阶段」与「三道瓶颈」**,**禁**「四道门 / 三道门」。`test/principle-zoom.test.mjs` 明确断言 `三道门`/`四道门` 不出现。
|
|
53
|
+
- **立场不是第五关。** 措辞只能是「四个阶段完成之后才会开始有立场」。图上不许再退回「底部一行小字」的表达——立场是独立区块,由 `test/principle.test.mjs`(viewBox 1160 + 含「立场清单」)与 `test/stance.test.mjs`(旧的「纵向长「立场清单」」写法必须不存在)共同守着。
|
|
54
|
+
|
|
55
|
+
改文案时**先跑这三条**再改别的,否则会来回返工。
|
|
56
|
+
|
|
57
|
+
## 5. `events.jsonl` 只能追加
|
|
58
|
+
|
|
59
|
+
`~/.dsh-fish/events.jsonl` 不能删除记录,是唯一可信源,一行一条。**任何改写/删除/重排都是篡改她的记忆。**
|
|
60
|
+
|
|
61
|
+
- 状态(`state.json`)是派生品,随时可由 `rebuild()` 重算;改它没意义,会被覆盖。
|
|
62
|
+
- 「让她忘」不是删行,是**降低召回**(`lib/persona.js` 的 `foldOlderBeliefs`:更早的判断折成一行「记不清原话了」,疤那类永不折叠),事件原文始终还在 `events.jsonl` 里,她也能用 `her_recall` 翻回去。
|
|
63
|
+
- 重置与恢复都不删数据:`reset.js` 改名前缀封存,`backup.js` 恢复前把旧档搬去 `dsh-fish-backups/pre-restore-*`。
|
|
64
|
+
- 新增事件类型**不必**改 `lib/schema.js` 的 `EVENT_SCHEMA_VERSION`:旧读者读不认识的 `type` 会跳过(`readEvents` 对未知类型宽容),0.7.6 / 0.8.0 的 `ask`、`answer`、`heard` 都是这样加进去的。但**改字段语义、把可选字段变必填、删字段**必须升 `v` 并写迁移(旧版本遇到新 `v` 要拒,否则静默丢字段)。
|
|
65
|
+
|
|
66
|
+
## 6. 改完必须跑全套测试
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
node --test
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
当前基线 **1441 个**,独立进程跑 `node --test` 应全绿。任何一条红都不许提交——包括看起来"不是我弄的"那条。
|
|
73
|
+
|
|
74
|
+
按环境挑跑法:
|
|
75
|
+
|
|
76
|
+
- **正常环境**:上面这条命令(不带参数,Node 自己递归找 `test/*.test.mjs`),约 17–18 秒。
|
|
77
|
+
- **别写成 `node --test "test/*.test.mjs"`**:Node 20 不展开 glob,会直接报 `Could not find '.../test/*.test.mjs'`;引号里的通配符只有 Node 22+ 认。CI 就是被这条拖红的。
|
|
78
|
+
- **也别写成 `node --test test/`**(目录形式):Node 26 + Windows 下报 `MODULE_NOT_FOUND`,沙箱里还会 `spawn EPERM`。
|
|
79
|
+
- **沙箱 / 受限环境**:用 `node --test --test-isolation=none`,或逐文件跑。
|
|
80
|
+
- **`--test-isolation=none` 有跨文件假红**:ULID 与 cover 两条会因共享进程互相干扰而报错,单跑对应文件是绿的。判断是不是假红:逐文件独立进程跑一遍,全绿即假红。
|
|
81
|
+
- **`test/media.test.mjs` 的 `detectFfmpeg` 依赖 spawn**,在禁 spawn 的环境里会红(`spawnSync ... EPERM`)。这是环境限制,不是代码问题——但**不许**为了让它变绿而删掉那条断言。
|
|
82
|
+
|
|
83
|
+
CI 也跑同一套(`.github/workflows/test.yml`,Node 20 / 22 / 24 各跑一遍)。
|
|
84
|
+
|
|
85
|
+
## 7. 桥接不内置,靠 HTTP 投递 + 白名单放行
|
|
86
|
+
|
|
87
|
+
社区想把大肥鱼接到 QQ / 微信 / 别的 IM 上(0.6.1 起写进设置页说明)。**不要把任何 IM 协议、登录、收发塞进这个插件**——桥是别人的独立进程,我们只提供两个口子让它接进来。
|
|
88
|
+
|
|
89
|
+
### 7.1 首选:桥只走 HTTP,不要自建 DSH 会话
|
|
90
|
+
|
|
91
|
+
2026-11-03 定案(用户 m00584 / m00597:「我们这边做一下兼容,但不直接做桥的功能」)。
|
|
92
|
+
|
|
93
|
+
老做法是桥自己再起一条 DSH 会话,代价有两个:
|
|
94
|
+
|
|
95
|
+
- **人格分裂**:每条 DSH 会话是独立 agent,各自注入一份身份、历史互不可见。同一份 `events.jsonl` 被两条会话读,用户在两边看到的是"两个人"。
|
|
96
|
+
- **双实例抢占**:桥自起的进程与桌面版共用一个数据目录,`instance.json` 心跳一判活,后到的那个被判成只读房客(`bootstrapHome` 返回 `blocked:true`,不建会话)。
|
|
97
|
+
|
|
98
|
+
所以桥应该**只发 HTTP**,完全不碰 DSH 进程与 `instance.json`:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
POST /dsh-fish/say
|
|
102
|
+
{ "text": "…", "channel": "qq-group:987654", "scene": "group", "speaker": "张三", "title": "摸鱼群" }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
| 字段 | 必填 | 说明 |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| `text` | 是(`image` 二选一) | 要递给她的话 |
|
|
108
|
+
| `image` | 否 | base64 图片 |
|
|
109
|
+
| `channel` | 否 | 渠道标识,桥自己起名。**同一个名字 = 同一间房** |
|
|
110
|
+
| `scene` | 否 | `desk`(默认,等于不传)/ `private` / `group` |
|
|
111
|
+
| `room` | 否 | `house`(并进书房)或 `channel`(另开一间)。不传时私聊回书房、群聊另开 |
|
|
112
|
+
| `speaker` | 否 | 这句话是谁说的。**任何场次都写进正文前缀**,不再只限群聊 |
|
|
113
|
+
| `guest` | 否 | `true` = 外客(群友私聊这类)。标明「不是他」,不算他来过、不涨轮数、不进书房桶 |
|
|
114
|
+
| `title` | 否 | 侧栏显示名(群名、昵称)。不传才回落到 channel 键 |
|
|
115
|
+
|
|
116
|
+
路由规则(`lib/channels.js` 的 `resolveChannel`):
|
|
117
|
+
|
|
118
|
+
- **不传 `channel`** → 家里那条会话。观测台、侧栏、老桥的行为一字不变。
|
|
119
|
+
- **`room: 'house'`** → 并进家里那条会话,场次照记(群聊仍记 `group`)。
|
|
120
|
+
- **`scene: 'private'`** → 默认**仍进家里那条会话**("QQ 私聊和 DSH 对话融合"那个选项)。要每人一间,传 `room: 'channel'`。
|
|
121
|
+
- **`scene: 'group'`** → 默认按 `channel` 自建/复用一间房(记在 `channels.json`),cwd 仍是她的屋子,身份、工具面、白板都照旧——**还是同一个人,只是换了个房间说话**。想让所有群并进书房,传 `room: 'house'`。
|
|
122
|
+
- **`guest: true`** → 房间照开(如果 `room` 要求),但这条不算他来过:不写 `seen:`、不 `bumpTurns`、不触发轮换;正文标「有个不是他的人跟你说话」,她不会把群友当成主人。
|
|
123
|
+
|
|
124
|
+
**常见布局都由桥表达,插件不写死:** 全部并进书房(不传 `channel`,或 `room:'house'`);每群一间(`channel:'qq-group:<群号>'` + `group`);群友私聊每人一间(`channel:'qq:dm:<QQ号>'` + `private` + `room:'channel'` + `guest:true`);群友私聊进书房但标身份(`private` + `guest:true` + `speaker`);只有 @ 她才进(桥侧过滤,不投递就不建房)。
|
|
125
|
+
|
|
126
|
+
**群房会轮换。** 默认一间群房用满 **7 天**换新的(`config.rooms.groupRotateDays`,`0` = 不换):旧房改名成「… YYYY-MM-DD 之前」留在侧栏,新房从当天重新算天数。200 条上下文对热闹的群不够用,所以按天而不是按轮数。
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
启动前可以先探一句:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
GET /dsh-fish/whoami
|
|
133
|
+
→ { plugin, version, root, home, sessionId, writable }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`writable: false` 表示这个数据目录已被另一个插件实例占着——桥看到就该停手,不要再起进程。`root` 用来判断"是不是同一个家"。
|
|
137
|
+
|
|
138
|
+
**桥那边怎么实现是桥的事**;我们这边只保证上面这几个字段能收、能落到正确的地方。
|
|
139
|
+
|
|
140
|
+
### 7.2 四个配套约定(改桥之后的正确性全押在这四条上)
|
|
141
|
+
|
|
142
|
+
1. **场次要进事件流**。`validateEvent` 现在接受可选 `scene`(非 `desk` 才落库,纯加法,不升 `EVENT_SCHEMA_VERSION`)。桥注入 `user/message` 时把 `scene` 写进 **`source.scene`**,`classifyMessage` 才会认出来(`lib/turns.js`)。
|
|
143
|
+
2. **外客不动生命体征**。`seen:`、`heard`、`bumpTurns`、会话轮换只由 desk/private 且非 `guest` 触发;群聊与群友私聊一条都不写。否则群里一天几百句,冷落检测永远不会触发——他一周没露面,面板还显示"今天聊过"。
|
|
144
|
+
3. **外来场次必须带说话人前缀**。`lib/say.js` 对 `group` 与 `guest` 都用 `speaker` 拼 `某某在群里说:…` / `某某说:…`。不拼的话,群里三个人的话在她看来跟一个人连说三句一模一样,她会把三个人的观点拼成一个"他"。外来文本统一过 `lib/guard.js` 的 `sanitizeForeign`。
|
|
145
|
+
4. **桥不要用宿主的 `source.form`**。`snapshot`、`notice`、`catalog`、`instructions`、`recall` 是宿主前端的保留词表,`classifyMessage` 见到就当上下文,不算人(`MACHINE_FORMS`)。转述人说的话,要么不带 `form`,要么用 `relay`。
|
|
146
|
+
|
|
147
|
+
### 7.3 另一条老路:工具白名单(仍然有效)
|
|
148
|
+
|
|
149
|
+
桥如果是以插件形式装进来、暴露工具给她的,仍然可以在 `config.tools.allow`(设置页「插件能力白名单」)里放行工具名。qq-bridge 默认要放行的是:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
qq_send_message, qq_get_unread_messages, qq_reply
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
三条约束:
|
|
156
|
+
|
|
157
|
+
- **工具名必须对得上真实 registry**。桥升级改名、用户填错,她就会答「我没法在 QQ 上说话」——这不是插件坏了,是名字没对上。
|
|
158
|
+
- **放行之后要念给她听**。身份文档「我手上有什么」由 `lib/persona.js` 的 `toolBrief(extra)` 生成、`lib/selfdoc.js` 把 `config.tools.allow` 作为 `extraTools` 传进去。看不见一只手,她就不会用。
|
|
159
|
+
- **白名单只做加法**。`config.tools.allow` 与 `HER_TOOLS` 取并集,不要用它去减工具;收窄只走 `lib/restrict.js` 那一套。
|
|
160
|
+
|
|
161
|
+
`test/beliefs.test.mjs` 有一条「白名单里额外放行的工具要念给她听」盯着这段,改之前先跑它。
|
|
162
|
+
|
|
163
|
+
**其余平台同理**:Chatbox、Monica、AstrBot 也走「社区桥 + 上面这两个口子」——不要把它们的协议塞进本插件,先找能桥过去的项目。不知道用什么项目、工具叫什么,就让她自己去查(前提是宿主放行了她能用的搜索/阅读工具)。
|
|
164
|
+
|
|
165
|
+
**永远不给人格/人称旋钮**(§2):多间房不是多个人格,`scene` 只描述"这句话在哪儿说的",不改变她是谁。
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 提 PR / 提交前自检
|
|
171
|
+
|
|
172
|
+
- [ ] 三个依赖字段还是 `{}`
|
|
173
|
+
- [ ] 没有新增人格设置入口
|
|
174
|
+
- [ ] 新输入口都过了 `guard.js`
|
|
175
|
+
- [ ] `node --test` 1441 全绿
|
|
176
|
+
- [ ] 界面文案没有「他」「四道门」「三道门」
|
|
177
|
+
- [ ] 改了 `EVENT_SCHEMA_VERSION` 的话,`CHANGELOG.md` 里写了迁移说明
|
|
178
|
+
- [ ] 没动包名;真要动,先看下面「包名与装法」那节
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 包名与装法(0.8.10 起,改名踩过一次,别再踩)
|
|
183
|
+
|
|
184
|
+
包名是 **`@ssamurias/dsh-fish`**(带 scope 的全名)。装法看 `README.md` 的「安装」,这里只列动代码时容易破坏的三条:
|
|
185
|
+
|
|
186
|
+
1. **`lib/client.js` 里 `__ModuleLoader__.load({ id })` 必须等于 `package.json` 的 `name`**,不是短名。client-modules 按 loader 条目名(完整包标识)解析浏览器包,名字对不上时客户端那半**静默不加载**——宿主照常跑、设置页空着,看起来像没装上。`test/client.test.mjs` 直接从 `package.json` 读 `name` 比对,别把那条断言改成写死字符串。
|
|
187
|
+
2. **`cordis.patch.yml` 的 `id` 保持短名 `dsh-fish`、`name` 写全名**(与 `@goodandready/dsh-voice` 一致)。`id` 变了会连带 client bundle 的 URL 对不上;`name` 写短名则 import 失败、直接崩在 web boot。
|
|
188
|
+
3. **别删升级脚本里的 normalize 那一步**(`lib/selfupdate.js` 的 `normalizeScript()`,安装脚本第 5/6 步)。0.8.9 之前装的 profile 里旧键还在,不清掉就会同时有两条鱼、两条 insert 撞一个 id,启动报 `duplicate factory registration`。
|
|
189
|
+
|