dsh-agent-persona 0.1.6 → 0.1.7

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
@@ -4,6 +4,21 @@ All notable changes to this project are documented here.
4
4
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.1.7] - 2026-10-23
8
+
9
+ ### Fixed
10
+
11
+ - **开关的 toast 只讲自己那件事。** 提示文案原来只对两个显示开关按 `patch` 取,其余一律按
12
+ `next.autosave` 计算,于是拨动「禁止模型改写人设文件」或「保存人设版本历史」时弹出来的是
13
+ 「编辑后自动保存」——一个这次根本没碰的开关的话。现在每个偏好各有一条按方向分岔的句子
14
+ (`PREF_STATUS`),键从 `patch` 上读,未知键退化成「已保存」。
15
+ - **同一句提示连拨两次也会再弹一次。** toast 原来用固定 `key`,第二次拨回同一状态时 React 复用
16
+ 同一个组件实例:文案一样、key 一样,定时器继续走,屏幕上看不到新提示。现在 `status` 每次写入都
17
+ 推进一个 `statusSeq`,toast 按它做 key,重复的句子也会重新挂载。这也是「开启没反应、关闭才弹」
18
+ 的成因之一:两个方向的文案本来就相同,第二次写入被吞掉了。
19
+ - 顺带把「关闭自动保存」的文案从「已关闭:编辑后自动保存」改成「已关闭:改完要自己点保存」。原文案
20
+ 在关闭状态下仍然宣称会自动保存。
21
+
7
22
  ## [0.1.6] - 2026-10-22
8
23
 
9
24
  ### Added
package/lib/client.js CHANGED
@@ -229,10 +229,21 @@
229
229
  return { ...DEFAULT_PREFS };
230
230
  }
231
231
  };
232
- const prefStatus = (next, patch) => "showTab" in patch || "showSidebar" in patch ? "\u5DF2\u4FDD\u5B58\uFF1A\u5DF2\u7ACB\u5373\u751F\u6548" : next.autosave === true ? "\u5DF2\u5F00\u542F\uFF1A\u7F16\u8F91\u540E\u505C\u6B62\u8F93\u5165\u7EA6 1 \u79D2\u5373\u81EA\u52A8\u4FDD\u5B58" : "\u5DF2\u5173\u95ED\uFF1A\u7F16\u8F91\u540E\u81EA\u52A8\u4FDD\u5B58";
232
+ const PREF_STATUS = {
233
+ autosave: (on) => on ? "\u5DF2\u5F00\u542F\uFF1A\u7F16\u8F91\u540E\u505C\u6B62\u8F93\u5165\u7EA6 1 \u79D2\u5373\u81EA\u52A8\u4FDD\u5B58" : "\u5DF2\u5173\u95ED\uFF1A\u6539\u5B8C\u8981\u81EA\u5DF1\u70B9\u4FDD\u5B58",
234
+ showTab: (on) => on ? "\u5DF2\u663E\u793A\u300C\u4EBA\u8BBE\u300D\u6807\u7B7E\uFF08\u5237\u65B0\u9875\u9762\u540E\u51FA\u73B0\uFF09" : "\u5DF2\u9690\u85CF\u300C\u4EBA\u8BBE\u300D\u6807\u7B7E\uFF08\u5237\u65B0\u9875\u9762\u540E\u751F\u6548\uFF09",
235
+ showSidebar: (on) => on ? "\u5DF2\u6CE8\u518C\u5230 dsh-better-sidebar" : "\u5DF2\u4ECE dsh-better-sidebar \u6CE8\u9500",
236
+ guard: (on) => on ? "\u5DF2\u5F00\u542F\uFF1A\u6A21\u578B\u7684\u5199\u5165\u4E0E\u547D\u4EE4\u5DE5\u5177\u4E0D\u80FD\u518D\u6539\u4EBA\u8BBE\u5B58\u50A8" : "\u5DF2\u5173\u95ED\uFF1A\u6A21\u578B\u53EF\u4EE5\u76F4\u63A5\u6539\u5199\u4EBA\u8BBE\u5B58\u50A8",
237
+ history: (on) => on ? "\u5DF2\u5F00\u542F\uFF1A\u6BCF\u6B21\u4FDD\u5B58\u90FD\u4F1A\u8BB0\u4E00\u6761\u7248\u672C\u5386\u53F2" : "\u5DF2\u5173\u95ED\uFF1A\u4E0D\u518D\u8BB0\u65B0\u7248\u672C\uFF0C\u5DF2\u6709\u5386\u53F2\u4ECD\u53EF\u67E5\u770B\u4E0E\u6062\u590D"
238
+ };
239
+ const prefStatus = (patch) => {
240
+ const key = Object.keys(patch ?? {}).find((name) => Object.prototype.hasOwnProperty.call(PREF_STATUS, name));
241
+ if (key === void 0) return "\u5DF2\u4FDD\u5B58";
242
+ return PREF_STATUS[key](patch[key] === true);
243
+ };
233
244
  const persistPrefs = (api, unwrap, current, patch, report) => {
234
245
  const next = writePrefs({ ...current, ...patch });
235
- report({ prefs: next, status: prefStatus(next, patch) });
246
+ report({ prefs: next, status: prefStatus(patch) });
236
247
  syncSidebarModule();
237
248
  if (api === void 0 || typeof api.savePrefs !== "function") return next;
238
249
  void api.savePrefs(next).then((result) => {
@@ -1187,6 +1198,10 @@
1187
1198
  busy: "",
1188
1199
  error: "",
1189
1200
  status: "",
1201
+ // Bumped on every status write. The toast is keyed on it, so the same sentence twice in a
1202
+ // row (toggling one switch off and on again) remounts instead of silently extending the
1203
+ // toast that is already on screen.
1204
+ statusSeq: 0,
1190
1205
  transfer: void 0
1191
1206
  };
1192
1207
  this.mounted = false;
@@ -1195,8 +1210,15 @@
1195
1210
  this.importTextRef = React.createRef();
1196
1211
  this.importHighlightRef = React.createRef();
1197
1212
  this.importTimer = void 0;
1213
+ this.statusSeq = 0;
1198
1214
  this.onChange = (patch) => {
1199
- if (this.mounted) this.setState(patch);
1215
+ if (!this.mounted) return;
1216
+ if (patch !== null && typeof patch === "object" && "status" in patch) {
1217
+ this.statusSeq += 1;
1218
+ this.setState({ ...patch, statusSeq: this.statusSeq });
1219
+ return;
1220
+ }
1221
+ this.setState(patch);
1200
1222
  };
1201
1223
  this.onKeyDown = (event) => {
1202
1224
  if (!(event.metaKey || event.ctrlKey) || String(event.key).toLowerCase() !== "s") return;
@@ -2472,7 +2494,10 @@ ${state.proposal.trim()}
2472
2494
  }
2473
2495
  }, [h(IconPlusOutline16, { key: "i" }), h("span", { key: "t" }, busy ? "\u6B63\u5728\u65B0\u5EFA\u2026" : "\u65B0\u5EFA\u4EBA\u8BBE")])];
2474
2496
  const status = state.error !== "" ? h("div", { className: "wsp-status wsp-status-err", key: "st", "aria-live": "polite" }, state.error) : state.status === "" ? null : h(Toast, {
2475
- key: "st",
2497
+ // Keyed on the sequence, not on a constant: a repeated sentence has to mount a fresh
2498
+ // toast. With a fixed key React reuses the instance, its dismiss timer keeps running,
2499
+ // and the second flip of a switch produced no toast at all.
2500
+ key: `st-${String(state.statusSeq)}`,
2476
2501
  text: state.status,
2477
2502
  icon: h(IconCheckOutline14, {}),
2478
2503
  onDone: () => this.onChange({ status: "" })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agent-persona",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Workspace personas for DeepSeek Harness (DSH): create many system-prompt personas and scope each one by workspace path or session id (exact / prefix / regex / contains), managed from a Web settings page with Markdown editing and AI tuning.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",