dsh-wisp 1.34.1 → 1.36.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-wisp",
3
- "version": "1.34.1",
3
+ "version": "1.36.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
- const match = clientSrc.match(/const LINES = (\{[\s\S]*?\n {4}\})/)
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
  }
@@ -3430,8 +3434,12 @@ head('3y-3. the focus timer, and going quiet while the page is hidden')
3430
3434
  quiet.document.visibilityState = 'hidden'
3431
3435
  quiet.document.dispatch('visibilitychange', {})
3432
3436
  const timers = quietApi.doctor().timers
3433
- check(timers.paused === true && timers.poll === false && timers.chatter === false && timers.wander === false,
3434
- 'hiding the page stops all three timers', JSON.stringify(timers))
3437
+ /* 絮叨与踱步停掉(只给看得见的人看),但**轮询放慢而不是停掉** ——
3438
+ 值班的前提是还看得见:你走开时跑完的轮次和出的错,都要被记下来。 */
3439
+ check(timers.paused === true && timers.chatter === false && timers.wander === false,
3440
+ 'hiding the page stops the chatter and the wander', JSON.stringify(timers))
3441
+ check(timers.poll === true && timers.pollMs === 5000,
3442
+ 'but the poll keeps a slow watch instead of stopping (she is on duty)', JSON.stringify(timers))
3435
3443
 
3436
3444
  /* 藏起来期间:来了一堆报错,她也不该有任何反应(轮询停了) */
3437
3445
  quiet.state.errors = 3
@@ -3454,6 +3462,89 @@ head('3y-3. the focus timer, and going quiet while the page is hidden')
3454
3462
  quiet.state.busy = false
3455
3463
  quiet.advance(3000, 200)
3456
3464
  check(moodOf(quiet) === 'worried', 'and now the same errors do get a reaction', moodOf(quiet))
3465
+ /* ---- 值班:走开期间跑完的轮次与报错,回来要报账 ------------------------------ */
3466
+ const saidNow = () => quiet.all('wisp-say').filter((el) => el.removed !== true)
3467
+ .map((el) => el.textContent).join(' ')
3468
+ quiet.document.visibilityState = 'hidden'
3469
+ quiet.document.dispatch('visibilitychange', {})
3470
+ quiet.state.busy = true
3471
+ quiet.advance(60000, 5000) // 你走开之后,她看着一轮跑了一分钟
3472
+ quiet.state.errors = 5
3473
+ quiet.state.busy = false
3474
+ quiet.advance(180000, 5000) // 一共走开三分钟(超过"回来问候"的门槛)
3475
+ check(saidNow() === '', 'while you are away she takes notes but says nothing', saidNow())
3476
+
3477
+ quiet.document.visibilityState = 'visible'
3478
+ quiet.document.dispatch('visibilitychange', {})
3479
+ quiet.advance(1000, 200)
3480
+ const report = saidNow()
3481
+ check(/轮/.test(report) && /跑完/.test(report),
3482
+ 'coming back, she reports how many runs finished while you were away', report)
3483
+ check(/错/.test(report), 'and she mentions the errors she saw', report)
3484
+ const book = quietApi.doctor().today
3485
+ check(book.runs >= 1 && book.errors >= 1 && book.longestMs > 0,
3486
+ 'and the day book recorded the runs, the errors and the longest one',
3487
+ JSON.stringify(book))
3488
+
3489
+ /* ---- 单轮跑得异常久:她会中途说一声,而且同一轮只说一次 ---------------------- */
3490
+ quiet.state.busy = true
3491
+ /* 刚好推过"单轮跑太久"的阈值。推 11 分钟是不行的:她的话早就过期了(气泡有存活时间),
3492
+ 于是断言会看到空字符串 —— 断言本身没错,是喂给它的时间不对。 */
3493
+ /* 多推几步:busySince 是在推进开始后的第一个轮询才记下的,卡在 601000 会差 200ms。 */
3494
+ quiet.advance(604800, 1200)
3495
+ const longLine = saidNow()
3496
+ const during = quietApi.doctor()
3497
+ check(/分钟/.test(longLine), 'a single run that drags on gets a check-in',
3498
+ `她说的是「${longLine}」;runInFlight=${during.runInFlightMs} longRunSaid=${during.longRunSaid} paused=${during.timers.paused}`)
3499
+ quiet.state.busy = false
3500
+ quiet.advance(3000, 500)
3501
+
3502
+ /* ---- 今日小结:把她记着的东西一次说完 ---------------------------------------- */
3503
+ quietApi.saySummary()
3504
+ quiet.advance(200, 50)
3505
+ const summaryLine = saidNow()
3506
+ /* 词池里有三个变体(今天…/今天:…/这一天…),所以断言**内容**而不是某一个措辞 */
3507
+ check(/轮/.test(summaryLine) && /错/.test(summaryLine) && /分钟/.test(summaryLine),
3508
+ 'the daily summary reads back what she has been tracking', summaryLine)
3509
+ check(/\d/.test(summaryLine), 'with real numbers', summaryLine)
3510
+ check(summaryLine.indexOf('{') < 0, 'and no placeholder is left unfilled', summaryLine)
3511
+ check(typeof quietApi.today.runs === 'number' && quietApi.today.runs >= 1,
3512
+ 'the day book is also readable from the api', JSON.stringify(quietApi.today))
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
+ zh.win.__wisp.destroy()
3546
+ active = keepZh
3547
+
3457
3548
  quiet.win.__wisp.destroy()
3458
3549
  active = keepQuiet
3459
3550
  }