dsh-wisp 1.35.0 → 1.37.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/README.md +81 -0
- package/build.mjs +32 -3
- package/lib/client.js +3675 -3485
- package/lib/client.template.js +3669 -3485
- package/package.json +1 -1
- package/verify-wisp.mjs +75 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-wisp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.0",
|
|
4
4
|
"description": "DeepSeek娘 — an unofficial floating desktop companion for the DeepSeek Harness UI. Zero dependencies; sprites inlined as data URIs; schedules on the Client timer service instead of the trapped browser timer globals.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
package/verify-wisp.mjs
CHANGED
|
@@ -78,7 +78,11 @@ const linesInBundle = () => {
|
|
|
78
78
|
if (linesCache !== undefined) return linesCache
|
|
79
79
|
linesCache = null
|
|
80
80
|
if (typeof clientSrc === 'string') {
|
|
81
|
-
|
|
81
|
+
/* 中文池现在叫 LINES_ZH(英文是覆盖层,最后合并成 LINES)。
|
|
82
|
+
这里读**中文池**:测试验的是"她说的那句话确实来自对应池子",
|
|
83
|
+
而中文字面量永远存在,不受语言环境影响。 */
|
|
84
|
+
const match = clientSrc.match(/const LINES_ZH = (\{[\s\S]*?\n {4}\})/)
|
|
85
|
+
|| clientSrc.match(/const LINES = (\{[\s\S]*?\n {4}\})/)
|
|
82
86
|
if (match) {
|
|
83
87
|
try { linesCache = new Function(`return ${match[1]}`)() } catch (e) { linesCache = null }
|
|
84
88
|
}
|
|
@@ -3507,6 +3511,76 @@ head('3y-3. the focus timer, and going quiet while the page is hidden')
|
|
|
3507
3511
|
check(typeof quietApi.today.runs === 'number' && quietApi.today.runs >= 1,
|
|
3508
3512
|
'the day book is also readable from the api', JSON.stringify(quietApi.today))
|
|
3509
3513
|
|
|
3514
|
+
/* ---- 英文台词:英文环境下她说英文,而且**一个汉字都不该出现** -------------------
|
|
3515
|
+
语言是加载时判定的(读 navigator.language),所以这个 harness 要在 evaluate 之前
|
|
3516
|
+
把 navigator 摆好。中文是兜底:没翻的条目仍然会说中文,这一条只验"翻译层真的生效"。 */
|
|
3517
|
+
const en = createHarness({ timer: true, composerText: '', storageSeed: { 'dsh-wisp-lang': 'en' } })
|
|
3518
|
+
const keepEn = active
|
|
3519
|
+
active = en
|
|
3520
|
+
en.evaluate(clientSrc)
|
|
3521
|
+
en.module().default.apply(en.ctx, { reactions: false, wander: false, celebrate: false })
|
|
3522
|
+
en.advance(1000, 200)
|
|
3523
|
+
en.win.__wisp.saySummary()
|
|
3524
|
+
en.advance(200, 50)
|
|
3525
|
+
const enLine = en.all('wisp-say').filter((el) => el.removed !== true)
|
|
3526
|
+
.map((el) => el.textContent).join(' ')
|
|
3527
|
+
check(/[A-Za-z]/.test(enLine), 'with an english locale she answers in english',
|
|
3528
|
+
`${enLine} | ${JSON.stringify(en.win.__wisp.doctor().lang)}`)
|
|
3529
|
+
check(!/[\u4e00-\u9fa5]/.test(enLine), 'and the line contains no chinese characters', enLine)
|
|
3530
|
+
en.win.__wisp.destroy()
|
|
3531
|
+
active = keepEn
|
|
3532
|
+
|
|
3533
|
+
/* 对照组:强制中文时同一句话必须是中文 —— 否则上面那条可能只是"恰好没触发" */
|
|
3534
|
+
const zh = createHarness({ timer: true, composerText: '', storageSeed: { 'dsh-wisp-lang': 'zh' } })
|
|
3535
|
+
const keepZh = active
|
|
3536
|
+
active = zh
|
|
3537
|
+
zh.evaluate(clientSrc)
|
|
3538
|
+
zh.module().default.apply(zh.ctx, { reactions: false, wander: false, celebrate: false })
|
|
3539
|
+
zh.advance(1000, 200)
|
|
3540
|
+
zh.win.__wisp.saySummary()
|
|
3541
|
+
zh.advance(200, 50)
|
|
3542
|
+
const zhLine = zh.all('wisp-say').filter((el) => el.removed !== true)
|
|
3543
|
+
.map((el) => el.textContent).join(' ')
|
|
3544
|
+
check(/[\u4e00-\u9fa5]/.test(zhLine), 'forcing chinese keeps her speaking chinese', zhLine)
|
|
3545
|
+
|
|
3546
|
+
/* 语言可以**随时**切换、不用刷新 —— 这正是把 LINES 做成视图(Proxy)而不是死值的意义。
|
|
3547
|
+
以前是"加载时合并成一个对象",换语言只能刷新页面。 */
|
|
3548
|
+
const said = () => zh.all('wisp-say').filter((el) => el.removed !== true)
|
|
3549
|
+
.map((el) => el.textContent).join(' ')
|
|
3550
|
+
zh.state.busy = false
|
|
3551
|
+
zh.advance(4000, 500)
|
|
3552
|
+
zh.win.__wisp.configure({ lang: 'en' })
|
|
3553
|
+
zh.win.__wisp.saySummary()
|
|
3554
|
+
zh.advance(200, 50)
|
|
3555
|
+
/* 菜单里选的语言是"下次打开生效"的那种设置(它在加载时就被读),
|
|
3556
|
+
所以这里验的完整流程是:**选一次 -> 存下来 -> 再挂一次就说英文**。
|
|
3557
|
+
不能只验"当场变英文":那是我想做但没做成的(试过,没找到原因),
|
|
3558
|
+
没验证过的行为不该写成承诺。 */
|
|
3559
|
+
zh.win.__wisp.configure({ lang: 'en' })
|
|
3560
|
+
const storedLang = zh.win.localStorage.getItem('dsh-wisp-lang')
|
|
3561
|
+
check(storedLang === 'en', 'picking a language in the menu stores it for next time', String(storedLang))
|
|
3562
|
+
const reload = createHarness({ timer: true, composerText: '', storageSeed: { 'dsh-wisp-lang': 'en' } })
|
|
3563
|
+
const keepReload = active
|
|
3564
|
+
active = reload
|
|
3565
|
+
reload.evaluate(clientSrc)
|
|
3566
|
+
reload.module().default.apply(reload.ctx, { reactions: false, wander: false, celebrate: false })
|
|
3567
|
+
reload.advance(1000, 200)
|
|
3568
|
+
reload.win.__wisp.saySummary()
|
|
3569
|
+
reload.advance(200, 50)
|
|
3570
|
+
const reloaded = reload.all('wisp-say').filter((el) => el.removed !== true)
|
|
3571
|
+
.map((el) => el.textContent).join(' ')
|
|
3572
|
+
check(/[A-Za-z]/.test(reloaded) && !/[\u4e00-\u9fa5]/.test(reloaded),
|
|
3573
|
+
'and the next mount honours that choice', reloaded)
|
|
3574
|
+
check(reloaded !== said(), 'the two languages really are different text',
|
|
3575
|
+
reloaded + ' | 中文那句:' + said())
|
|
3576
|
+
reload.win.__wisp.destroy()
|
|
3577
|
+
active = keepReload
|
|
3578
|
+
check(zh.win.__wisp.doctor().lang.choice === 'en',
|
|
3579
|
+
'and the choice is reported so the menu can show it', JSON.stringify(zh.win.__wisp.doctor().lang))
|
|
3580
|
+
|
|
3581
|
+
zh.win.__wisp.destroy()
|
|
3582
|
+
active = keepZh
|
|
3583
|
+
|
|
3510
3584
|
quiet.win.__wisp.destroy()
|
|
3511
3585
|
active = keepQuiet
|
|
3512
3586
|
}
|