dsh-lite-pet 0.2.2 → 0.2.3

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/index.js CHANGED
@@ -323,10 +323,17 @@ function handlePetLine(ctx, runtime, profile, message) {
323
323
  runtime.doneText = null
324
324
  runtime.doneAt = 0
325
325
  runtime.lastSent = ''
326
+ // The pet tries first: it can show or restore the window on its own, and only if it
327
+ // finds the window hidden does it need the shell reached from this process.
326
328
  void openHarness(ctx, runtime)
327
329
  pushState(ctx, runtime, profile)
328
330
  return
329
331
  }
332
+ if (message?.t === 'hidden') {
333
+ // Sent after the pet's own attempt failed, so the cheap routes are already exhausted.
334
+ void reopenHidden(ctx, runtime)
335
+ return
336
+ }
330
337
  if (message?.t === 'balance') {
331
338
  void sendBalance(ctx, runtime, profile)
332
339
  return
@@ -526,17 +533,22 @@ function pushState(ctx, runtime, profile) {
526
533
  runningTouched = state.touched
527
534
  }
528
535
  }
536
+ // Priority, highest first: waiting (yellow) > done (green) > working (plain).
537
+ //
538
+ // The green completion state outranks working on purpose. A session that just finished is
539
+ // the thing the user is waiting to hear about, and it would otherwise be drowned out by any
540
+ // other session that happens to be busy — which is the common case with several chats open.
541
+ // It stays below waiting because a pending decision blocks that session and demands
542
+ // attention.
529
543
  if (waitingAgent !== null) {
530
544
  mode = 'waiting'
531
545
  text = bubbleText(runtime.agents.get(waitingAgent).text) || '需要你确认一下'
532
- } else if (runningAgent !== null) {
533
- mode = 'working'
534
- text = bubbleText(runtime.agents.get(runningAgent).text) || '正在工作…'
535
546
  } else if (runtime.doneText !== null && now - runtime.doneAt < DONE_VISIBLE_MS) {
536
- // Only when nothing else is going on: a completed session must never take the bubble
537
- // away from one that is still working or still waiting for an answer.
538
547
  mode = 'done'
539
548
  text = runtime.doneText
549
+ } else if (runningAgent !== null) {
550
+ mode = 'working'
551
+ text = bubbleText(runtime.agents.get(runningAgent).text) || '正在工作…'
540
552
  }
541
553
 
542
554
  const payload = JSON.stringify({ t: 'state', mode, text })
@@ -682,36 +694,54 @@ function clickTrayIcon() {
682
694
  })
683
695
  })
684
696
  }
697
+ /**
698
+ * Reopen the desktop window, doing the cheap thing first.
699
+ *
700
+ * The pet can handle the common cases itself: it already enumerates the shell's windows, and
701
+ * IsWindowVisible / IsIconic / WM_SYSCOMMAND are plain Win32 calls that the sandbox's low
702
+ * integrity does not restrict. So it is told to try first, and the tray click — which costs
703
+ * a PowerShell process and about 650 ms, because only a medium-integrity process can read
704
+ * the taskbar's automation tree — happens only when the pet reports that the window is hidden
705
+ * and out of its reach.
706
+ *
707
+ * In steady state, where the window is already visible or merely minimised, nothing here
708
+ * runs at all.
709
+ */
685
710
  async function openHarness(ctx, runtime) {
686
- // A hidden window can only be reopened through the shell's own focusPrimaryWindow(), and
687
- // asking for that means clicking its tray icon. That has to happen here rather than in the
688
- // pet, for the integrity reason documented on clickTrayIcon.
689
- const clicked = await clickTrayIcon(ctx)
690
- if (!clicked && runtime.pet === null) {
691
- // No pet to fall back through, and the helper failed: leave the click alone rather than
692
- // guessing at a URL that may not belong to this window.
693
- return
694
- }
695
- if (runtime.pet !== null) {
696
- // The pet knows how to restore a minimised window and has the dsh:// fallback, and it
697
- // also brings the window to the foreground once it is back.
698
- sendPet(runtime, { t: 'raise' })
699
- return
700
- }
701
- const url = (() => {
711
+ if (runtime.pet === null) {
712
+ // No pet to try through: go straight to the shell's own route.
713
+ if (await clickTrayIcon()) return
714
+ const url = (() => {
715
+ try {
716
+ return ctx.get('webApp', false)?.getAdvertisedUrl?.()
717
+ } catch {
718
+ return undefined
719
+ }
720
+ })()
721
+ if (url === undefined || url === null || url === '') return
702
722
  try {
703
- return ctx.get('webApp', false)?.getAdvertisedUrl?.()
704
- } catch {
705
- return undefined
723
+ const child = spawn('cmd.exe', ['/c', 'start', '', url], { windowsHide: true, detached: true, stdio: 'ignore' })
724
+ child.unref()
725
+ } catch (error) {
726
+ ctx.logger?.warn?.(`[dsh-lite-pet] cannot open the Harness: ${String(error?.message ?? error)}`)
706
727
  }
707
- })()
708
- if (url === undefined || url === null || url === '') return
709
- try {
710
- const child = spawn('cmd.exe', ['/c', 'start', '', url], { windowsHide: true, detached: true, stdio: 'ignore' })
711
- child.unref()
712
- } catch (error) {
713
- ctx.logger?.warn?.(`[dsh-lite-pet] cannot open the Harness: ${String(error?.message ?? error)}`)
728
+ return
714
729
  }
730
+ sendPet(runtime, { t: 'raise' })
731
+ }
732
+
733
+ /**
734
+ * Click the tray icon on the pet's behalf.
735
+ *
736
+ * The pet sends this after its own attempt showed that the window is hidden, so no
737
+ * visibility check is repeated here: the point of the message is that the cheap routes are
738
+ * exhausted.
739
+ */
740
+ async function reopenHidden(ctx, runtime) {
741
+ if (await clickTrayIcon()) return
742
+ // The shell route is the last thing left; it does not reopen a hidden window on this
743
+ // machine, but it is harmless and does work in builds whose handler runs synchronously.
744
+ sendPet(runtime, { t: 'raise' })
715
745
  }
716
746
 
717
747
  // ——— browser routes ————————————————————————————————————————————————————
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-lite-pet",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "轻量系统级桌宠:原生进程逐像素透明渲染,工作正文/等待确认/完成提示与余额查询联动,点击穿透",
5
5
  "type": "module",
6
6
  "main": "index.js",
Binary file