dsh-kaomoji 0.1.0 → 0.1.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 +20 -0
- package/README.en.md +24 -6
- package/README.md +38 -10
- package/lib/client.js +42 -26
- package/lib/index.js +13 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/lang/zh-CN/
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.2] - 2026-09-10
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `auto` 模式的适用范围明确包含日常推荐、购物建议和实用 how-to 回答:这类
|
|
15
|
+
对话式回答同样会带一个颜文字,只有纯代码、正式技术交付和高风险内容跳过。
|
|
16
|
+
|
|
17
|
+
## [0.1.1] - 2026-09-10
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- 设置 RPC 默认信任范围改为 `trusted-host`:本机与 Host 声明的受信主机(如 Tailscale
|
|
22
|
+
组网的服务器)都能保存设置;可用 `settingsAuthority: loopback` 收紧回仅本机。
|
|
23
|
+
- 设置卡片会显示 RPC 失败原因(来源不受信任 / Host 未加载 / 保存失败),不再静默只读。
|
|
24
|
+
- `auto` 模式改为更积极地输出颜文字:友好的寒暄、闲聊、共情类回复都会带一个。
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- 远程(Tailscale / 局域网)页面打开设置卡片时只能看、不能改的问题。
|
|
29
|
+
|
|
10
30
|
## [0.1.0] - 2026-09-09
|
|
11
31
|
|
|
12
32
|
### Added
|
package/README.en.md
CHANGED
|
@@ -26,7 +26,7 @@ largest Japanese kaomoji sites.
|
|
|
26
26
|
instead of inventing malformed faces.
|
|
27
27
|
- **12 mood buckets** — happy, love, sad, cry, angry, surprised, confused,
|
|
28
28
|
shy, playful, encourage, thanks, sorry.
|
|
29
|
-
- **Three frequency modes** — `auto` (default), `frequent`, `off`.
|
|
29
|
+
- **Three frequency modes** — `auto` (default; greetings, casual chat, recommendations and empathetic replies get one), `frequent`, `off`.
|
|
30
30
|
- **Placement control** — `inline` after the mood-matching sentence (default)
|
|
31
31
|
or `end` of the reply.
|
|
32
32
|
- **Visual settings card** under Settings → General, saved live without a restart.
|
|
@@ -62,12 +62,12 @@ Node.js `^22.19.0 || >=24.0.0`, pnpm 11.
|
|
|
62
62
|
```powershell
|
|
63
63
|
cd "$env:USERPROFILE\.dsh\profiles\web"
|
|
64
64
|
|
|
65
|
-
# Option A: install
|
|
66
|
-
dsh plugin --profile web add github:TianJie52009/dsh-kaomoji
|
|
67
|
-
|
|
68
|
-
# Option B: install from npm (after the package is published)
|
|
65
|
+
# Option A: install from npm (recommended)
|
|
69
66
|
dsh plugin --profile web add dsh-kaomoji
|
|
70
67
|
|
|
68
|
+
# Option B: install straight from GitHub (no npm release needed)
|
|
69
|
+
dsh plugin --profile web add github:TianJie52009/dsh-kaomoji
|
|
70
|
+
|
|
71
71
|
# Local development build
|
|
72
72
|
pnpm add file:C:\path\to\dsh-kaomoji
|
|
73
73
|
```
|
|
@@ -102,15 +102,25 @@ Example `cordis.patch.yml`:
|
|
|
102
102
|
|
|
103
103
|
| Key | Type | Default | Description |
|
|
104
104
|
| --- | --- | --- | --- |
|
|
105
|
-
| `mode` | `'off' \| 'auto' \| 'frequent'` | `'auto'` | `off` disables; `auto`
|
|
105
|
+
| `mode` | `'off' \| 'auto' \| 'frequent'` | `'auto'` | `off` disables; `auto` adds one to greetings, casual chat, recommendations and empathetic replies; `frequent` adds one to every conversational reply (code-only/formal replies excluded) |
|
|
106
106
|
| `placement` | `'inline' \| 'end'` | `'inline'` | Put the kaomoji after the best-matching sentence, or at the reply end |
|
|
107
107
|
| `maxPerTurn` | `number` (1–5) | `1` | Max kaomoji per reply |
|
|
108
108
|
| `customPrompt` | `string` | `''` | Extra style/scene guidance; cannot change mode, whitelist or limits |
|
|
109
109
|
| `settingsFile` | `string` | `~/.dsh/dsh-kaomoji.json` | (advanced) user-settings file path |
|
|
110
|
+
| `settingsAuthority` | `'trusted-host' \| 'loopback'` | `'trusted-host'` | Settings RPC trust scope: by default the local Host plus declared trusted hosts (Tailscale/LAN) may write; set `loopback` to restrict to the local machine |
|
|
110
111
|
|
|
111
112
|
Card edits take effect immediately; deployment-default edits in
|
|
112
113
|
`cordis.patch.yml` require a dsh restart.
|
|
113
114
|
|
|
115
|
+
### Remote access (Tailscale / LAN)
|
|
116
|
+
|
|
117
|
+
- If the dsh page is reachable remotely, the Host already trusts that origin;
|
|
118
|
+
with the default `settingsAuthority: trusted-host` the General card can save
|
|
119
|
+
settings from the remote session.
|
|
120
|
+
- If the card reports that the origin is not trusted, add the host to the
|
|
121
|
+
server’s `trustedHosts` (dsh-client-connection) or temporarily switch to
|
|
122
|
+
`settingsAuthority: loopback` and edit on the server itself.
|
|
123
|
+
|
|
114
124
|
## Kaomoji library & attribution
|
|
115
125
|
|
|
116
126
|
The built-in library lives in [`data/catalog.json`](./data/catalog.json), with a
|
|
@@ -196,6 +206,14 @@ npm publish --access public --registry https://registry.npmjs.org
|
|
|
196
206
|
|
|
197
207
|
## FAQ
|
|
198
208
|
|
|
209
|
+
- **No kaomoji in replies?** Check, in order: (1) the Host half is mounted —
|
|
210
|
+
`dsh plugin --profile web add dsh-kaomoji` writes both `dependencies` and
|
|
211
|
+
`dsh.profile.bundles`; a bare `pnpm add` only loads the client card, so
|
|
212
|
+
re-install with the dsh CLI or add the `insert` row to `cordis.patch.yml`
|
|
213
|
+
and restart (the log should show `[dsh-kaomoji] 已挂载(mode=...)`);
|
|
214
|
+
(2) the mode — `auto` only fires on friendly/casual/empathetic replies, use
|
|
215
|
+
`frequent` for one per conversational reply; (3) the settings card status —
|
|
216
|
+
“Host not loaded” / “origin not trusted” also means the guidance is absent.
|
|
199
217
|
- **Why does the model sometimes skip kaomoji in `auto` mode?** That is by
|
|
200
218
|
design. Only `frequent` requires one per conversational reply.
|
|
201
219
|
- **Can I use kaomoji outside the whitelist?** Yes — put the exact string in
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
- **纯提示词方案**:不截断、不改写模型流,也不额外调用模型,稳定且对 KV 缓存友好。
|
|
18
18
|
- **白名单防乱码**:模型只会从词库中逐字符复制颜文字,不会凭印象拼出坏字符。
|
|
19
19
|
- **情绪分桶**:内置 12 个情绪分类(开心 / 心动 / 难过 / 大哭 / 生气 / 惊讶 / 困惑 / 害羞 / 俏皮 / 鼓励 / 感谢 / 道歉),并随规则给出可用样例。
|
|
20
|
-
- **三种频率模式**:`auto
|
|
20
|
+
- **三种频率模式**:`auto`(智能:寒暄/闲聊/推荐建议/共情回复都会带一个,默认)/ `frequent`(每条对话回复都带)/ `off`(关闭)。
|
|
21
21
|
- **放置位置可选**:贴在情绪最贴切的句子后(`inline`,默认)或固定在回复末尾(`end`)。
|
|
22
22
|
- **可视化配置卡片**:卡片位于「设置 → 通用设置」,保存即生效、无需重启。
|
|
23
23
|
- **零第三方运行时依赖**:只用 dsh 自带的 `systemPrompt` 服务与 Node 标准库。
|
|
@@ -59,7 +59,18 @@
|
|
|
59
59
|
- Node.js `^22.19.0 || >=24.0.0`
|
|
60
60
|
- pnpm 11(dsh 默认使用 pnpm)
|
|
61
61
|
|
|
62
|
-
### 方式一:从
|
|
62
|
+
### 方式一:从 npm 安装(推荐)
|
|
63
|
+
|
|
64
|
+
包已发布到 npm,直接安装即可,dsh CLI 会自动把插件加入 `dsh.profile.bundles`:
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
cd "$env:USERPROFILE\.dsh\profiles\web"
|
|
68
|
+
dsh plugin --profile web add dsh-kaomoji
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
> 包刚发布的 24 小时内,如果对方的 pnpm 开启了「新包安全期」,裸名安装可能暂时解析不到;这种情况可先用下面的 GitHub 方式安装。
|
|
72
|
+
|
|
73
|
+
### 方式二:从 GitHub 直装(无需等 npm)
|
|
63
74
|
|
|
64
75
|
无需等 npm 发布,dsh CLI 支持直接装 GitHub 仓库:
|
|
65
76
|
|
|
@@ -74,15 +85,10 @@ cd "$env:USERPROFILE\.dsh\profiles\web"
|
|
|
74
85
|
pnpm add github:TianJie52009/dsh-kaomoji
|
|
75
86
|
```
|
|
76
87
|
|
|
77
|
-
###
|
|
88
|
+
### 方式三:本地开发版
|
|
78
89
|
|
|
79
90
|
```powershell
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# dsh CLI 会自动把插件加入 dsh.profile.bundles
|
|
83
|
-
dsh plugin --profile web add dsh-kaomoji
|
|
84
|
-
|
|
85
|
-
# 本地开发版:先把仓库 clone/解压到本地,再把路径换成该目录
|
|
91
|
+
# 先把仓库 clone/解压到本地,再把路径换成该目录
|
|
86
92
|
pnpm add file:C:\path\to\dsh-kaomoji
|
|
87
93
|
```
|
|
88
94
|
|
|
@@ -112,14 +118,20 @@ pnpm add file:C:\path\to\dsh-kaomoji
|
|
|
112
118
|
|
|
113
119
|
| 配置项 | 类型 | 默认值 | 说明 |
|
|
114
120
|
| --- | --- | --- | --- |
|
|
115
|
-
| `mode` | `'off' \| 'auto' \| 'frequent'` | `'auto'` | `off` 关闭;`auto`
|
|
121
|
+
| `mode` | `'off' \| 'auto' \| 'frequent'` | `'auto'` | `off` 关闭;`auto` 寒暄/闲聊/推荐建议/共情回复都会带一个;`frequent` 每条对话回复都带一个(两者都跳过纯代码 / 正式技术交付) |
|
|
116
122
|
| `placement` | `'inline' \| 'end'` | `'inline'` | 放在情绪最贴切的句子/短段后,或固定在回复末尾 |
|
|
117
123
|
| `maxPerTurn` | `number`(1–5) | `1` | 每条回复最多允许的颜文字数量 |
|
|
118
124
|
| `customPrompt` | `string` | `''` | 附加风格/场景说明;不能改变模式、白名单或数量上限 |
|
|
119
125
|
| `settingsFile` | `string` | `~/.dsh/dsh-kaomoji.json` | (进阶)用户设置持久化文件路径 |
|
|
126
|
+
| `settingsAuthority` | `'trusted-host' \| 'loopback'` | `'trusted-host'` | 设置 RPC 信任范围:默认允许本机与 Host 声明的受信主机(Tailscale/局域网)保存设置;改成 `loopback` 则仅本机可改 |
|
|
120
127
|
|
|
121
128
|
卡片里的修改即时写入用户层并热生效;修改 `cordis.patch.yml` 的部署默认值后需重启 dsh。
|
|
122
129
|
|
|
130
|
+
### 远程访问(Tailscale / 局域网)
|
|
131
|
+
|
|
132
|
+
- 只要能正常远程打开 dsh 页面,说明 Host 已信任该来源;默认 `settingsAuthority: trusted-host` 下,通用设置卡片可以直接修改并保存。
|
|
133
|
+
- 如果卡片提示「当前来源不在 Host 的信任列表里」,说明服务端 `@deepseek-ai/dsh-client-connection` 没有把该域名/IP 加进 `trustedHosts`;先在服务端配置受信主机,或临时改用 `settingsAuthority: loopback` 并到服务器本机编辑。
|
|
134
|
+
|
|
123
135
|
## 词库来源与许可
|
|
124
136
|
|
|
125
137
|
内置词库见 [`data/catalog.json`](./data/catalog.json),每个分类都标注了 kaomojiya.org 对应的来源页:
|
|
@@ -199,6 +211,22 @@ npm publish --access public --registry https://registry.npmjs.org
|
|
|
199
211
|
|
|
200
212
|
## FAQ
|
|
201
213
|
|
|
214
|
+
### 回答里没有颜文字?
|
|
215
|
+
|
|
216
|
+
按顺序检查:
|
|
217
|
+
|
|
218
|
+
1. **Host 半是否真的挂载了**:`dsh plugin --profile web add dsh-kaomoji` 会把插件同时写进 `dependencies` 和 `dsh.profile.bundles`;如果只用 `pnpm add` 手动装,client 卡片会出现但 Host 不会注入提示词。重新用 dsh CLI 安装一次,或在 profile 的 `cordis.patch.yml` 里补:
|
|
219
|
+
|
|
220
|
+
```yaml
|
|
221
|
+
- insert:
|
|
222
|
+
- id: dsh-kaomoji
|
|
223
|
+
name: dsh-kaomoji
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
然后重启 dsh,日志里应出现 `[dsh-kaomoji] 已挂载(mode=...)`。
|
|
227
|
+
2. **确认模式**:默认 `auto` 只在友好/闲聊/共情等场景使用;想要每条对话回复都带,在通用设置卡片切到「高频」,或在 `cordis.patch.yml` 写 `mode: frequent`。
|
|
228
|
+
3. **看设置卡片状态**:卡片提示「Host 未加载」或「来源不受信任」时,提示词也不会注入,先按上面的步骤修好挂载/信任。
|
|
229
|
+
|
|
202
230
|
### 为什么模型偶尔没有加颜文字?
|
|
203
231
|
|
|
204
232
|
`auto` 模式本来就不要求每回合使用;只有 `frequent` 才要求「对话回复都带一个」。如果 `frequent` 下仍经常漏掉,多半是回复被模型判为纯代码/正式交付,或上下文里其它 persona 指令更强势——可用 `customPrompt` 再强调一次。
|
package/lib/client.js
CHANGED
|
@@ -56,7 +56,7 @@ window.__ModuleLoader__.load({
|
|
|
56
56
|
"mode.off": "关闭",
|
|
57
57
|
"mode.off.desc": "不使用颜文字",
|
|
58
58
|
"mode.auto": "智能",
|
|
59
|
-
"mode.auto.desc": "
|
|
59
|
+
"mode.auto.desc": "寒暄、闲聊、推荐建议、共情回复都会带一个",
|
|
60
60
|
"mode.frequent": "高频",
|
|
61
61
|
"mode.frequent.desc": "每条对话回复都带一个(纯代码/正式交付除外)",
|
|
62
62
|
"field.placement": "放置位置",
|
|
@@ -69,7 +69,8 @@ window.__ModuleLoader__.load({
|
|
|
69
69
|
"action.reset": "恢复默认",
|
|
70
70
|
"status.loading": "正在读取设置…",
|
|
71
71
|
"status.saved": "已保存,下一次回复生效。",
|
|
72
|
-
"status.unsupported": "
|
|
72
|
+
"status.unsupported": "Host 未加载颜文字插件或该来源不被信任,无法保存设置。",
|
|
73
|
+
"status.forbidden": "当前来源不在 Host 的信任列表里,无法保存设置。",
|
|
73
74
|
"status.error": "保存失败,请重试。",
|
|
74
75
|
};
|
|
75
76
|
|
|
@@ -80,7 +81,7 @@ window.__ModuleLoader__.load({
|
|
|
80
81
|
"mode.off": "Off",
|
|
81
82
|
"mode.off.desc": "No kaomoji",
|
|
82
83
|
"mode.auto": "Smart",
|
|
83
|
-
"mode.auto.desc": "
|
|
84
|
+
"mode.auto.desc": "Greetings, casual chat, recommendations and empathetic replies get one",
|
|
84
85
|
"mode.frequent": "Frequent",
|
|
85
86
|
"mode.frequent.desc": "One kaomoji in every conversational reply (code-only/formal excluded)",
|
|
86
87
|
"field.placement": "Placement",
|
|
@@ -93,7 +94,8 @@ window.__ModuleLoader__.load({
|
|
|
93
94
|
"action.reset": "Reset to defaults",
|
|
94
95
|
"status.loading": "Loading settings…",
|
|
95
96
|
"status.saved": "Saved — applies to the next reply.",
|
|
96
|
-
"status.unsupported": "
|
|
97
|
+
"status.unsupported": "The Host did not load the kaomoji plugin, or this origin is not trusted.",
|
|
98
|
+
"status.forbidden": "This origin is not in the Host trust list, so settings cannot be saved.",
|
|
97
99
|
"status.error": "Save failed, please retry.",
|
|
98
100
|
};
|
|
99
101
|
|
|
@@ -211,12 +213,12 @@ window.__ModuleLoader__.load({
|
|
|
211
213
|
* 轻量快照 store(getSnapshot/subscribe),slot runtime 会把它包装成
|
|
212
214
|
* useKaomoji(selector) hook。所有写操作都串行经过 loopback RPC。
|
|
213
215
|
*/
|
|
214
|
-
function createSettingsStore(rpc
|
|
216
|
+
function createSettingsStore(rpc) {
|
|
215
217
|
let snapshot = {
|
|
216
|
-
status:
|
|
218
|
+
status: "loading",
|
|
217
219
|
settings: cloneSettings(DEFAULT_SETTINGS),
|
|
218
220
|
revision: undefined,
|
|
219
|
-
writable:
|
|
221
|
+
writable: true,
|
|
220
222
|
saveError: null,
|
|
221
223
|
justSaved: false,
|
|
222
224
|
};
|
|
@@ -238,16 +240,24 @@ window.__ModuleLoader__.load({
|
|
|
238
240
|
return task;
|
|
239
241
|
};
|
|
240
242
|
|
|
243
|
+
const fail = (code) => {
|
|
244
|
+
publish({
|
|
245
|
+
status: "unavailable",
|
|
246
|
+
writable: false,
|
|
247
|
+
saveError: code,
|
|
248
|
+
justSaved: false,
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
|
|
241
252
|
const callRpc = async (endpoint, payload) => {
|
|
242
|
-
if (!isLoopback) {
|
|
243
|
-
publish({ status: "unavailable", saveError: null });
|
|
244
|
-
return undefined;
|
|
245
|
-
}
|
|
246
253
|
try {
|
|
247
254
|
const result = await rpc.call(RPC_CHANNEL, endpoint, payload);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
return
|
|
255
|
+
if (result && result.ok === true) return { value: result.value };
|
|
256
|
+
const code = result && result.error && result.error.code;
|
|
257
|
+
return { error: code === "forbidden" ? "forbidden" : "rejected" };
|
|
258
|
+
} catch (error) {
|
|
259
|
+
const message = String((error && error.message) || error || "");
|
|
260
|
+
return { error: /403|forbidden/i.test(message) ? "forbidden" : "unreachable" };
|
|
251
261
|
}
|
|
252
262
|
};
|
|
253
263
|
|
|
@@ -258,11 +268,12 @@ window.__ModuleLoader__.load({
|
|
|
258
268
|
return () => listeners.delete(listener);
|
|
259
269
|
},
|
|
260
270
|
async refresh() {
|
|
261
|
-
const
|
|
262
|
-
if (
|
|
263
|
-
|
|
271
|
+
const result = await callRpc("get", {});
|
|
272
|
+
if (result.error !== undefined) {
|
|
273
|
+
fail(result.error === "forbidden" ? "forbidden" : "load");
|
|
264
274
|
return;
|
|
265
275
|
}
|
|
276
|
+
const value = result.value;
|
|
266
277
|
publish({
|
|
267
278
|
status: "ready",
|
|
268
279
|
settings: normalizeSettings(value.settings),
|
|
@@ -272,6 +283,7 @@ window.__ModuleLoader__.load({
|
|
|
272
283
|
});
|
|
273
284
|
},
|
|
274
285
|
patch(field) {
|
|
286
|
+
if (!snapshot.writable) return Promise.resolve();
|
|
275
287
|
const next = normalizeSettings({ ...snapshot.settings, ...field });
|
|
276
288
|
publish({
|
|
277
289
|
status: "ready",
|
|
@@ -280,14 +292,15 @@ window.__ModuleLoader__.load({
|
|
|
280
292
|
justSaved: false,
|
|
281
293
|
});
|
|
282
294
|
return enqueue(async () => {
|
|
283
|
-
const
|
|
295
|
+
const result = await callRpc("save", {
|
|
284
296
|
settings: next,
|
|
285
297
|
expectedRevision: snapshot.revision,
|
|
286
298
|
});
|
|
287
|
-
if (
|
|
288
|
-
|
|
299
|
+
if (result.error !== undefined) {
|
|
300
|
+
fail(result.error === "forbidden" ? "forbidden" : "save");
|
|
289
301
|
return;
|
|
290
302
|
}
|
|
303
|
+
const value = result.value;
|
|
291
304
|
publish({
|
|
292
305
|
settings: normalizeSettings(value.settings),
|
|
293
306
|
revision: value.revision,
|
|
@@ -299,13 +312,14 @@ window.__ModuleLoader__.load({
|
|
|
299
312
|
});
|
|
300
313
|
},
|
|
301
314
|
async reset() {
|
|
302
|
-
if (!
|
|
315
|
+
if (!snapshot.writable) return;
|
|
303
316
|
publish({ saveError: null, justSaved: false });
|
|
304
|
-
const
|
|
305
|
-
if (
|
|
306
|
-
|
|
317
|
+
const result = await callRpc("reset", { expectedRevision: snapshot.revision });
|
|
318
|
+
if (result.error !== undefined) {
|
|
319
|
+
fail(result.error === "forbidden" ? "forbidden" : "save");
|
|
307
320
|
return;
|
|
308
321
|
}
|
|
322
|
+
const value = result.value;
|
|
309
323
|
publish({
|
|
310
324
|
settings: normalizeSettings(value.settings),
|
|
311
325
|
revision: value.revision,
|
|
@@ -332,7 +346,9 @@ window.__ModuleLoader__.load({
|
|
|
332
346
|
}, [settings.customPrompt]);
|
|
333
347
|
|
|
334
348
|
const statusText = state.saveError
|
|
335
|
-
?
|
|
349
|
+
? state.saveError === "forbidden"
|
|
350
|
+
? t("status.forbidden")
|
|
351
|
+
: t("status.error")
|
|
336
352
|
: state.status === "loading"
|
|
337
353
|
? t("status.loading")
|
|
338
354
|
: !state.writable
|
|
@@ -466,7 +482,7 @@ window.__ModuleLoader__.load({
|
|
|
466
482
|
"dsh-kaomoji: dictionaries",
|
|
467
483
|
);
|
|
468
484
|
const connection = ctx.get("connection");
|
|
469
|
-
const controller = createSettingsStore(connection.rpc
|
|
485
|
+
const controller = createSettingsStore(connection.rpc);
|
|
470
486
|
void controller.refresh();
|
|
471
487
|
|
|
472
488
|
ctx.effect(() => {
|
package/lib/index.js
CHANGED
|
@@ -30,6 +30,8 @@ export const SETTINGS_FILE_SCHEMA_VERSION = 1;
|
|
|
30
30
|
|
|
31
31
|
export const MODES = ["off", "auto", "frequent"];
|
|
32
32
|
export const PLACEMENTS = ["inline", "end"];
|
|
33
|
+
/** 设置 RPC 的信任范围:trusted-host = 本机 + 服务端声明的受信主机(如 Tailscale)。 */
|
|
34
|
+
export const SETTINGS_AUTHORITIES = ["trusted-host", "loopback"];
|
|
33
35
|
|
|
34
36
|
export const DEFAULT_CONFIG = Object.freeze({
|
|
35
37
|
/** off=关闭;auto=智能(确实有助于表达才用);frequent=高频(每条对话回复都带)。 */
|
|
@@ -144,8 +146,9 @@ export function buildGuidance(config) {
|
|
|
144
146
|
|
|
145
147
|
const modeLines = {
|
|
146
148
|
auto: [
|
|
147
|
-
"
|
|
148
|
-
"
|
|
149
|
+
"Most conversational replies should include one fitting kaomoji — greetings, casual chat, empathy, everyday recommendations or shopping advice, and practical how-to answers.",
|
|
150
|
+
"Skip it only when the reply is purely code, a formal/technical deliverable, or serious/high-stakes content.",
|
|
151
|
+
"One per reply is usually enough; never replace real content with it.",
|
|
149
152
|
],
|
|
150
153
|
frequent: [
|
|
151
154
|
"In every conversational reply — except code-only output, formal/technical deliverables, or tool calls — include one fitting kaomoji.",
|
|
@@ -203,6 +206,11 @@ function cloneSettings(settings) {
|
|
|
203
206
|
return { ...settings, customPrompt: settings.customPrompt };
|
|
204
207
|
}
|
|
205
208
|
|
|
209
|
+
/** 设置 RPC 的信任范围;未显式配置时用 trusted-host(本机 + 服务端声明的受信主机)。 */
|
|
210
|
+
function resolveAuthority(config) {
|
|
211
|
+
return config?.settingsAuthority === "loopback" ? "loopback" : "trusted-host";
|
|
212
|
+
}
|
|
213
|
+
|
|
206
214
|
function defaultSettingsFile(config) {
|
|
207
215
|
if (typeof config?.settingsFile === "string" && config.settingsFile.trim() !== "") {
|
|
208
216
|
return resolve(config.settingsFile);
|
|
@@ -362,6 +370,7 @@ function createSettingsRpcHandler(ctx, settingsFile, getState, commit) {
|
|
|
362
370
|
export function apply(ctx, config = {}) {
|
|
363
371
|
const baseSettings = normalizeConfig(config);
|
|
364
372
|
const settingsFile = defaultSettingsFile(config);
|
|
373
|
+
const authority = resolveAuthority(config);
|
|
365
374
|
const stored = loadSettingsDocument(settingsFile);
|
|
366
375
|
|
|
367
376
|
// currentSettings = 用户层(~/.dsh/dsh-kaomoji.json)覆盖部署默认值后的实时设置。
|
|
@@ -406,14 +415,14 @@ export function apply(ctx, config = {}) {
|
|
|
406
415
|
connectionCtx.effect(
|
|
407
416
|
() =>
|
|
408
417
|
connectionCtx.connection.rpc.handle(SETTINGS_RPC_CHANNEL, handler, {
|
|
409
|
-
authority
|
|
418
|
+
authority,
|
|
410
419
|
}),
|
|
411
420
|
"dsh-kaomoji: settings rpc",
|
|
412
421
|
);
|
|
413
422
|
});
|
|
414
423
|
|
|
415
424
|
ctx.logger?.info?.(
|
|
416
|
-
`[dsh-kaomoji] 已挂载(mode=${currentSettings.mode}, placement=${currentSettings.placement}, settingsFile=${settingsFile})`,
|
|
425
|
+
`[dsh-kaomoji] 已挂载(mode=${currentSettings.mode}, placement=${currentSettings.placement}, authority=${authority}, settingsFile=${settingsFile})`,
|
|
417
426
|
);
|
|
418
427
|
}
|
|
419
428
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-kaomoji",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Add mood-aware Japanese kaomoji to DeepSeek Harness (dsh) replies; prompt-injection plugin with a curated library from kaomojiya.org.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|