@lmzhen/dsh-evolution-skill-history 0.22.0 → 0.24.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/lib/client.js CHANGED
@@ -139,7 +139,7 @@ window.__ModuleLoader__.load({
139
139
  "time.years": "{n} 年前",
140
140
  "time.years.one": "1 年前",
141
141
  error: "读取失败",
142
- "error.hint": "面板读不到宿主路由:通常是插件版本与宿主不匹配,重启 dsh web 后重试。"
142
+ "error.hint": "面板读不到宿主路由:通常是插件版本与宿主不匹配。请重启 DeepSeek Harness 后重试;仍不行就在对话里说明。"
143
143
  };
144
144
  /** English dictionary: the same keys, or the panel falls back to the key itself. */
145
145
  const en = {
@@ -214,7 +214,7 @@ window.__ModuleLoader__.load({
214
214
  "time.years": "{n} years ago",
215
215
  "time.years.one": "1 year ago",
216
216
  error: "Could not load",
217
- "error.hint": "The panel could not reach the host routes — usually a plugin/host version mismatch; restart dsh web and retry."
217
+ "error.hint": "The panel could not reach the host routes — usually a plugin/host version mismatch. Restart DeepSeek Harness and retry; if it persists, ask in the conversation."
218
218
  };
219
219
  /**
220
220
  * One message without the locale seat (the fallback path, and what a spec reads).
@@ -223,7 +223,7 @@ window.__ModuleLoader__.load({
223
223
  * @returns the copy, or the key itself when neither dictionary carries it.
224
224
  */
225
225
  function message(language, key) {
226
- return (language === "en" ? en : zh)[key] ?? key;
226
+ return (language === "zh" ? zh : en)[key] ?? key;
227
227
  }
228
228
  /**
229
229
  * Fill one TEMPLATE’s `{n}` slots. The seat resolves the key, this fills it, so the panel needs
@@ -704,18 +704,18 @@ window.__ModuleLoader__.load({
704
704
  /** One `<pre>` rendering of a diff: added lines marked `+`, removed ones `-`. */
705
705
  function sourceBlock(diff) {
706
706
  const rows = [];
707
- for (const hunk of diff.hunks) {
707
+ for (const [hunkIndex, hunk] of diff.hunks.entries()) {
708
708
  for (const [index, line] of hunk.oldText.split("\n").entries()) {
709
709
  if (hunk.oldText === "" && line === "") continue;
710
710
  rows.push((0, react.createElement)("div", {
711
- key: "old-" + String(index),
711
+ key: "old-" + String(hunkIndex) + "-" + String(index),
712
712
  className: "evo-doc-line-del"
713
713
  }, "- " + line));
714
714
  }
715
715
  for (const [index, line] of hunk.newText.split("\n").entries()) {
716
716
  if (hunk.newText === "" && line === "") continue;
717
717
  rows.push((0, react.createElement)("div", {
718
- key: "new-" + String(index),
718
+ key: "new-" + String(hunkIndex) + "-" + String(index),
719
719
  className: "evo-doc-line-add"
720
720
  }, "+ " + line));
721
721
  }
@@ -1146,7 +1146,7 @@ window.__ModuleLoader__.load({
1146
1146
  }
1147
1147
  }, "evolution-skill-history: locale");
1148
1148
  const seatTranslator = registered ? seam.locale.bind(NS) : null;
1149
- const t = (key) => seatTranslator === null ? message("zh", key) : seatTranslator(key);
1149
+ const t = (key) => seatTranslator === null ? message("en", key) : seatTranslator(key);
1150
1150
  ctx.effect(() => {
1151
1151
  if (document.querySelector("style[data-plugin-css=\"@lmzhen/dsh-evolution-skill-history/panel.css\"]") === null) {
1152
1152
  const tag = document.createElement("style");
package/lib/index.js CHANGED
@@ -44,11 +44,19 @@ function makeSkillHistoryRoutes(services) {
44
44
  /** Guard: trust fence, then method. Every refusal is a JSON body, never an empty response. */
45
45
  const guard = (req, res, method) => {
46
46
  if (!isLoopbackRequest(req)) {
47
- writeJson(res, 403, { error: "forbidden: loopback-only" });
47
+ writeJson(res, 403, {
48
+ ok: false,
49
+ code: "forbidden",
50
+ message: "禁止访问:仅限回环地址"
51
+ });
48
52
  return false;
49
53
  }
50
54
  if (req.method !== method) {
51
- writeJson(res, 405, { error: "method not allowed: " + (req.method ?? "") });
55
+ writeJson(res, 405, {
56
+ ok: false,
57
+ code: "method-not-allowed",
58
+ message: "方法不允许:" + (req.method ?? "")
59
+ });
52
60
  return false;
53
61
  }
54
62
  return true;
@@ -99,7 +107,7 @@ function makeSkillHistoryRoutes(services) {
99
107
  writeJson(res, 400, {
100
108
  ok: false,
101
109
  code: "bad-request",
102
- message: "name is required"
110
+ message: "缺少 name"
103
111
  });
104
112
  return;
105
113
  }
@@ -156,7 +164,7 @@ function makeSkillHistoryRoutes(services) {
156
164
  writeJson(res, 400, {
157
165
  ok: false,
158
166
  code: "bad-request",
159
- message: "name and a positive integer v are required"
167
+ message: "需要 name 与正整数 v"
160
168
  });
161
169
  return;
162
170
  }
@@ -167,7 +175,7 @@ function makeSkillHistoryRoutes(services) {
167
175
  writeJson(res, 404, {
168
176
  ok: false,
169
177
  code: "not-found",
170
- message: "that version is not in the recorded history of \"" + name + "\""
178
+ message: "该版本不在「" + name + "」的记录历史里"
171
179
  });
172
180
  return;
173
181
  }
@@ -179,7 +187,7 @@ function makeSkillHistoryRoutes(services) {
179
187
  writeJson(res, 404, {
180
188
  ok: false,
181
189
  code: "not-found",
182
- message: "the stored content of that version could not be read"
190
+ message: "该版本的存储内容读不出来"
183
191
  });
184
192
  return;
185
193
  }
@@ -208,7 +216,7 @@ function makeSkillHistoryRoutes(services) {
208
216
  writeJson(res, 400, {
209
217
  ok: false,
210
218
  code: "bad-request",
211
- message: "name and a positive integer v are required"
219
+ message: "需要 name 与正整数 v"
212
220
  });
213
221
  return;
214
222
  }
@@ -218,7 +226,7 @@ function makeSkillHistoryRoutes(services) {
218
226
  writeJson(res, 404, {
219
227
  ok: false,
220
228
  code: "not-found",
221
- message: "the stored content of that version could not be read"
229
+ message: "该版本的存储内容读不出来"
222
230
  });
223
231
  return;
224
232
  }
@@ -246,7 +254,7 @@ function makeSkillHistoryRoutes(services) {
246
254
  writeJson(res, 400, {
247
255
  ok: false,
248
256
  code: "bad-request",
249
- message: "name is required"
257
+ message: "缺少 name"
250
258
  });
251
259
  return;
252
260
  }
@@ -255,7 +263,7 @@ function makeSkillHistoryRoutes(services) {
255
263
  writeJson(res, 400, {
256
264
  ok: false,
257
265
  code: "bad-request",
258
- message: "v must be a positive integer"
266
+ message: "v 必须是正整数"
259
267
  });
260
268
  return;
261
269
  }
@@ -112,11 +112,14 @@ export interface VersionBodyRow {
112
112
  readonly chars: number;
113
113
  readonly truncated: boolean;
114
114
  }
115
- /** The two chains, plus the live body hash the panel marks as "current". */
115
+ /**
116
+ * The two chains. G4.2 whitelist audit: the payload's `liveHash` is DELETED here — the host route already
117
+ * compares it (`undoable: entry.hash !== liveHash`, routes.ts) and delivers the verdict per row, so the
118
+ * "current" marker has one source. A declared field nobody reads is drift waiting to happen.
119
+ */
116
120
  export interface VersionsPayload {
117
121
  readonly content: readonly VersionRow[];
118
122
  readonly support: readonly VersionRow[];
119
- readonly liveHash: string | null;
120
123
  }
121
124
  /** The panel's data face: plain callbacks, no service handle. */
122
125
  export interface SkillHistoryApi {
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Is this a non-null, non-array object (what JSON calls an object)?
3
+ * @param value - the value to test.
4
+ * @returns whether it is a plain object.
5
+ */
6
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
7
+ /**
8
+ * Read a value as a record, or undefined when it is not one.
9
+ * @param value - the value to read.
10
+ * @returns the value typed as a record, or undefined.
11
+ */
12
+ export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
13
+ //# sourceMappingURL=guards.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-skill-history",
3
3
  "description": "Web surface for skill content history: loopback host routes plus the sidebar panel (community build)",
4
- "version": "0.22.0",
4
+ "version": "0.24.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -30,23 +30,23 @@
30
30
  ],
31
31
  "license": "MIT",
32
32
  "dependencies": {
33
- "@lmzhen/dsh-evolution-core": "^0.22.0"
33
+ "@lmzhen/dsh-evolution-core": "^0.24.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@deepseek-ai/cordis": "^4.0.1",
37
37
  "@deepseek-ai/dsh-host-webserver": "^0.2.0-rc.1",
38
38
  "react": "^18.2.0",
39
- "@lmzhen/dsh-evolution-curator": "^0.22.0"
39
+ "@lmzhen/dsh-evolution-curator": "^0.24.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@deepseek-ai/cordis": "^4.0.1",
43
43
  "@deepseek-ai/dsh-host-webserver": "^0.2.0-rc.1",
44
44
  "@types/react": "~18.3.1",
45
45
  "react": "^18.2.0",
46
- "@lmzhen/dsh-evolution-core": "^0.22.0",
47
- "@lmzhen/dsh-evolution-curator": "^0.22.0",
48
- "@lmzhen/dsh-evolution-io": "^0.22.0",
49
- "@lmzhen/dsh-evolution-io-node": "^0.22.0"
46
+ "@lmzhen/dsh-evolution-core": "^0.24.0",
47
+ "@lmzhen/dsh-evolution-curator": "^0.24.0",
48
+ "@lmzhen/dsh-evolution-io": "^0.24.0",
49
+ "@lmzhen/dsh-evolution-io-node": "^0.24.0"
50
50
  },
51
51
  "dsh": {
52
52
  "client": {