@memef1f1y/dsh-plugin-tts 0.6.3 → 0.6.5

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/TODO.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # TODO(待办)
2
2
 
3
+ ## 2026-09-27 Mac 交接前进度(已 push,工作区干净)
4
+
5
+ - [x] 五提供者指南:Edge / Index-TTS2 / CosyVoice / Cloud TTS / RVC per-provider guides + agent handoff header(`docs/`,2026-09-22)。
6
+ - [x] 分块播放:indexed chunk serve order、prewarm skip、starved chunk clamp、orphan sweep + overlap detector、fluency trio(cosy trim / chunk retry-skip / stall watchdog,2026-09-22)。
7
+ - [x] 诊断:diag log JSON 导出 + triage(calibration / cache / model / jobs)+ per-provider triage + chunk forensics(host build tag / job summaries / early-done,2026-09-25)。
8
+ - [x] 发布:npm `@memef1f1y/dsh-plugin-tts`,v0.6.1 chunk-order、v0.6.2 loader-name、v0.6.3 scroll-follow v2(2026-09-25~26)。
9
+ - [x] scroll-follow v2:stepwise signal + latch-off + highlight + spans;`ttsFollow` 提至 apply scope + ratio fallback 修复(HEAD `149fb9d`,v0.6.4,2026-09-26,已 push,`origin/main` 同步,工作区干净)。
10
+ - [ ] 待 Mac 端:`docs/scroll-follow-v2.md` 在 UTF-8 下读出乱码(疑似 GBK 存档),需确认源编码并转 UTF-8;`TODO.md` 此前停留在 08-17,本次已补齐。
11
+
12
+ > 交接注意:`dsh-plugin-TTS/` 外层(`edge-tts-worker.cjs` 旧独立 worker、`README.md` 旧版、6 个 `rvc-*.log`、`.npm-cache/`)不在 git 内,Mac 端只需 clone `plugin/` 本体(`https://github.com/1624318455/dsh-plugin-tts.git`,`main@149fb9d`);外层文件无需带走,log 已被 `plugin/.gitignore` 的 `*.log` 排除。
13
+
3
14
  ## 发布与引流
4
15
 
5
16
  - [x] **B站介绍视频已发布**,简介已放便携运行时网盘链接(`E:\rvc-portable-torch2.7-cu128.zip`,4.35GB)。
package/lib/client.js CHANGED
@@ -18,7 +18,7 @@ window.__ModuleLoader__.load({
18
18
 
19
19
  // Bundle build tag: bump on every client fix so a console line proves
20
20
  // WHICH code is actually running (rules out stale-bundle confusion).
21
- const CLIENT_BUILD = "2026-09-26.04-follow-v2";
21
+ const CLIENT_BUILD = "2026-10-11.01-remove-dead-runtime-inject";
22
22
  const apply = ctx => {
23
23
  const slots = ctx.slots ?? (typeof ctx.get === "function" ? ctx.get("slots") : undefined);
24
24
  if (!slots) throw new Error("[dsh-plugin-tts] slots service unavailable");
@@ -1490,6 +1490,13 @@ window.__ModuleLoader__.load({
1490
1490
  return shared.rvc.baseVoice || shared.voice;
1491
1491
  }
1492
1492
 
1493
+ // --- Scroll-follow v2 state: apply-scope singleton so BOTH speakText
1494
+ // (new-read re-latch) and TtsReadingOverlay (tick / takeover / resume)
1495
+ // share the SAME object. Must NOT live inside the component (each render
1496
+ // would recreate it: speakText would throw ReferenceError AND latch-off
1497
+ // would be lost on next render).
1498
+ const ttsFollow = { latched: true, touchActive: false, selfUntil: 0 };
1499
+
1493
1500
  // ---------- approval voice alerts (Agent-event broadcast) ----------
1494
1501
  // The Host ingests approval session events (approval/asked, approval/
1495
1502
  // decided) from the session/event firehose and serves them through
@@ -3546,7 +3553,8 @@ window.__ModuleLoader__.load({
3546
3553
  // with manual resume; reduced-motion respected. No polling loop:
3547
3554
  // evaluation runs per chunk-index change + on scroll/touch/viewport
3548
3555
  // events (the old 250ms full-DOM scan forced reflow at 4Hz).
3549
- const ttsFollow = { latched: true, touchActive: false, selfUntil: 0 };
3556
+ // NOTE: ttsFollow lives in apply scope (shared singleton) — do NOT
3557
+ // redeclare here, or speakText can't see it (0.6.3 ReferenceError).
3550
3558
  const ttsReducedMotion = () => {
3551
3559
  try { return !!(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches); } catch (e) { return false; }
3552
3560
  };
@@ -3640,6 +3648,7 @@ window.__ModuleLoader__.load({
3640
3648
  // one forever (that froze follow at the initial spot).
3641
3649
  const fullNeedle = shared.currentText || "";
3642
3650
  if (!fullNeedle) { mark("no-needle"); return false; }
3651
+ const ratio = total ? (idx - 1) / total : 0;
3643
3652
  const pos = Math.floor(fullNeedle.length * Math.min(0.99, Math.max(0, ratio)));
3644
3653
  const needle = fullNeedle.slice(Math.max(0, pos - 50), pos + 50);
3645
3654
  if (!needle) { mark("no-needle"); return false; }
package/lib/index.mjs CHANGED
@@ -9,7 +9,9 @@
9
9
  // GET /dsh-tts-api/rvc-packs-installed -> { installed }
10
10
  // POST /dsh-tts-api/rvc-pack-install {registry, packId} -> download+sha256-verify+install
11
11
  // Synthesis runs a zero-dependency Edge TTS worker via `node -e`
12
- // (Sec-MS-GEC query-param protocol, mirroring node-edge-tts@1.2.10).
12
+ // (Sec-MS-GEC query-param protocol, mirroring node-edge-tts@1.2.10;
13
+ // 2026-10 v1->v2 migration per rany2/edge-tts#490: WSS host is now
14
+ // api.msedgeservices.com with Ocp-Apim-Subscription-Key, legacy token kept).
13
15
  import { spawn } from 'node:child_process';
14
16
  import { readFileSync, writeFileSync, existsSync, mkdirSync, rmSync } from 'node:fs';
15
17
  import { createHash } from 'node:crypto';
@@ -31,7 +33,7 @@ const path = require('node:path');
31
33
  const TRUSTED_CLIENT_TOKEN = '6A5AA1D4EAFF4E9FB37E23D68491D6F4';
32
34
  const CHROMIUM_FULL_VERSION = '143.0.3650.75';
33
35
  const WINDOWS_FILE_TIME_EPOCH = 11644473600n;
34
- const WSS_BASE = 'wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1';
36
+ const WSS_BASE = 'wss://api.msedgeservices.com/tts/cognitiveservices/websocket/v1';
35
37
  const CRLF = String.fromCharCode(13, 10);
36
38
  function generateSecMsGecToken() {
37
39
  const ticks = BigInt(Math.floor(Date.now() / 1000) + Number(WINDOWS_FILE_TIME_EPOCH)) * 10000000n;
@@ -62,7 +64,8 @@ function isHardWorkerError(msg) {
62
64
  function synthesizeOnce(voice, text, outPath, lang, rate, pitch, volume) {
63
65
  return new Promise(function (resolve, reject) {
64
66
  const secMsGec = generateSecMsGecToken();
65
- const url = WSS_BASE + '?TrustedClientToken=' + TRUSTED_CLIENT_TOKEN + '&Sec-MS-GEC=' + secMsGec + '&Sec-MS-GEC-Version=1-' + CHROMIUM_FULL_VERSION;
67
+ const connectionId = crypto.randomBytes(16).toString('hex');
68
+ const url = WSS_BASE + '?Ocp-Apim-Subscription-Key=' + TRUSTED_CLIENT_TOKEN + '&Sec-MS-GEC=' + secMsGec + '&Sec-MS-GEC-Version=1-' + CHROMIUM_FULL_VERSION + '&ConnectionId=' + connectionId;
66
69
  const ws = new WebSocket(url, {
67
70
  headers: {
68
71
  'Pragma': 'no-cache',
@@ -92,7 +95,7 @@ function synthesizeOnce(voice, text, outPath, lang, rate, pitch, volume) {
92
95
  parts.push('detail=' + s.slice(0, 200));
93
96
  }
94
97
  }
95
- parts.push('url=speech.platform.bing.com/edge/v1');
98
+ parts.push('url=api.msedgeservices.com/tts/v1');
96
99
  return 'websocket error (' + parts.join(' ') + ')';
97
100
  } catch (err) {
98
101
  return 'websocket error: ' + String(e);
@@ -1991,7 +1994,7 @@ const WORKER_META = {
1991
1994
  // Bump on every Host-side playback fix: package.json versions only move on
1992
1995
  // releases, so without this two different Host builds are indistinguishable
1993
1996
  // in an exported log (exactly what stalled the 1/3/2 swap triage).
1994
- const HOST_BUILD = '2026-09-26.02-job-summary';
1997
+ const HOST_BUILD = '2026-10-11.01-remove-dead-runtime-inject';
1995
1998
 
1996
1999
  export function apply(ctx) {
1997
2000
  const webServer = ctx.get('webServer');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@memef1f1y/dsh-plugin-tts",
3
3
  "description": "Edge TTS 语音大集成插件:消息朗读按钮、自动朗读开关、语音设置面板(Edge TTS / RVC / Index-TTS2 / CosyVoice / Google Cloud TTS)",
4
- "version": "0.6.3",
4
+ "version": "0.6.5",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22"
@@ -22,7 +22,6 @@
22
22
  "client": {
23
23
  "platform": "web",
24
24
  "inject": [
25
- "@deepseek-ai/dsh-client-runtime",
26
25
  "@deepseek-ai/dsh-client-ui-slots"
27
26
  ]
28
27
  }
@@ -33,8 +32,8 @@
33
32
  "react": "^18.2.0"
34
33
  },
35
34
  "devDependencies": {
36
- "@deepseek-ai/cordis": "^4.0.1",
37
- "@deepseek-ai/dsh-base": ">=0.1.0-rc.6"
35
+ "@deepseek-ai/cordis": "^4.0.4",
36
+ "@deepseek-ai/dsh-base": "0.2.0-rc.2"
38
37
  },
39
38
  "scripts": {
40
39
  "test": "node tests/smoke.mjs",