dsh-web-icon-indicator 0.3.0 → 0.3.1

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/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.1](https://github.com/waknow/dsh-web-icon-indicator/compare/v0.3.0...v0.3.1) (2026-09-02)
11
+
12
+ ### Fixed
13
+
14
+ * keep asking icon alive while agent is still running ([f9f4a08](https://github.com/waknow/dsh-web-icon-indicator/commit/f9f4a08c452549f43d379c4f7ddf8525f8674a56))
15
+
16
+ ### Changed
17
+
18
+ * add multi-agent count visualization to READMEs ([4326456](https://github.com/waknow/dsh-web-icon-indicator/commit/4326456d60f4f90bab16a3424f91b9550e25da8a))
10
19
  ## [0.3.0](https://github.com/waknow/dsh-web-icon-indicator/compare/v0.2.3...v0.3.0) (2026-08-31)
11
20
 
12
21
  ### Added
package/README.md CHANGED
@@ -45,6 +45,33 @@ The four default states, exactly as they appear in the browser tab (the `asking`
45
45
  | `asking` | `#E5484D` ⇄ `#FACC15` — red/yellow | `blink` (400 ms) |
46
46
  | `done` | `#22A06B` — green | `static`, stays `doneHoldMs`, then back to `idle` |
47
47
 
48
+ ### Multi-agent, visualized
49
+
50
+ With several agents running at once, the favicon itself becomes the counter:
51
+ while **more than one** agent is active (non-idle: `asking` / `running` / `done`,
52
+ including the short `done` hold), the whale is replaced by a full-frame count
53
+ block showing the live `active` count, filled with the aggregate state's color
54
+ and driven by the same effect — so it keeps blinking / breathing / cycling
55
+ exactly like the whale would. With 0–1 active agents it comes right back to
56
+ the whale.
57
+
58
+ <p align="center">
59
+ <img src="assets/multi-agent-count.svg" width="576" alt="active=0 dark whale, active=1 yellow whale, active=2/3 yellow count blocks, active=3 asking red block (blinks), active=100 shows 99+">
60
+ </p>
61
+
62
+ | `active` (non-idle agents) | Favicon |
63
+ | --- | --- |
64
+ | `0` | dark `idle` whale |
65
+ | `1` | that state's whale (`running` yellow, …) |
66
+ | `2`–`99` | full-frame count block; digit height ≈31–52% of the icon (1 digit = 26, 2 = 20, 3+ = 15.5), readable at 16px and in pinned tabs |
67
+ | `100`+ | `99+` |
68
+
69
+ State priority is unchanged, so `asking` still takes over with its red ⇄ yellow
70
+ 400 ms blink (the count block blinks), `done` flashes its color for
71
+ `doneHoldMs`, and the count refreshes live through the status poll (~1 s).
72
+ Same visual language as the *满幅数字* channel of
73
+ [`demo/badge.html`](./demo/badge.html).
74
+
48
75
  ## ✨ All effects, animated
49
76
 
50
77
  Every preview below is the real whale path, animated the same way the plugin renders it (the previews are self-contained animated SVGs — they play right in your browser):
package/README.zh.md CHANGED
@@ -45,6 +45,28 @@
45
45
  | `asking` 提问 | `#E5484D` ⇄ `#FACC15`——红/黄 | `blink`(400ms) |
46
46
  | `done` 完成 | `#22A06B`——绿色 | `static`,保持 `doneHoldMs` 后回到 `idle` |
47
47
 
48
+ ### 多 agent 可视化
49
+
50
+ 当多个 agent 同时运行时,favicon 本身就是计数器:只要活动 agent **超过一个**
51
+ (非待机:`asking` / `running` / `done`,含短暂的 `done` 保持期),鲸鱼就换成
52
+ 占满整帧的数字块——实时显示 `active` 计数,底色取聚合状态色、特效与鲸鱼完全
53
+ 同源(照常闪烁 / 呼吸 / 彩虹);活动数回到 0–1 时恢复鲸鱼。
54
+
55
+ <p align="center">
56
+ <img src="assets/multi-agent-count.svg" width="576" alt="active=0 深色鲸鱼、active=1 黄色鲸鱼、active=2/3 黄色数字块、active=3 asking 红色块(闪烁)、active=100 显示 99+">
57
+ </p>
58
+
59
+ | `active`(非待机 agent 数) | favicon |
60
+ | --- | --- |
61
+ | `0` | 深色 `idle` 鲸鱼 |
62
+ | `1` | 对应状态的鲸鱼(`running` 黄色,…) |
63
+ | `2`–`99` | 占满整帧的数字块,数字高度约占图标的 31%–52%(1 位 26、2 位 20、3+ 位 15.5)——16px 与固定标签页都可读 |
64
+ | `100`+ | `99+` |
65
+
66
+ 状态优先级不变:`asking` 仍以红 ⇄ 黄 400ms 闪烁接管(闪烁的是数字块),
67
+ `done` 按其颜色驻留 `doneHoldMs`,计数随状态轮询实时刷新(约 1 秒)。
68
+ 视觉与 [`demo/badge.html`](./demo/badge.html) 的「满幅数字」通道一致。
69
+
48
70
  ## ✨ 全部特效,动画演示
49
71
 
50
72
  下面每个预览都是真实的鲸鱼路径,按插件实际渲染方式做动画(预览是自包含的动画 SVG,在浏览器里直接播放):
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="576" height="116" viewBox="0 0 576 116" role="img" aria-label="Multi-agent favicon: whale below 2 active agents, full-frame count block at 2+ (asking blinks red, 100 shows 99+)"><style>.chip{fill:#ffffff;stroke:#d0d7de;stroke-width:1.5}.lbl{font:600 11px system-ui,-apple-system,Segoe UI,sans-serif;fill:#59636e;text-anchor:middle}@keyframes ask{0%,49.9%{fill:#E5484D}50%,100%{fill:#FACC15}}.ask{animation:ask .8s steps(1) infinite}</style><rect class="chip" x="8" y="8" width="80" height="80" rx="20"/><g transform="translate(23,23)"><path id="p0" d="M48.8354 10.0479C48.3232 9.79199 48.1025 10.2798 47.8032 10.5278C47.7007 10.6079 47.6143 10.7119 47.5273 10.8076C46.7793 11.624 45.9048 12.1597 44.7622 12.0957C43.0923 12 41.666 12.5356 40.4058 13.8398C40.1377 12.2319 39.2476 11.272 37.8926 10.6558C37.1836 10.3359 36.4668 10.0156 35.9702 9.31982C35.6235 8.82373 35.5293 8.27197 35.356 7.72754C35.2456 7.3999 35.1353 7.06396 34.7651 7.00781C34.3633 6.94385 34.2056 7.2876 34.0479 7.57568C33.418 8.75195 33.1733 10.0479 33.1973 11.3599C33.2524 14.312 34.4736 16.6641 36.8999 18.3359C37.1758 18.5278 37.2466 18.7197 37.1597 19C36.9946 19.5757 36.7974 20.1357 36.624 20.7119C36.5137 21.0801 36.3486 21.1597 35.9624 21C34.6309 20.4321 33.481 19.5918 32.4644 18.5757C30.7393 16.8721 29.1792 14.9917 27.2334 13.52C26.7764 13.1758 26.3193 12.856 25.8467 12.5518C23.8618 10.584 26.1069 8.96777 26.627 8.77588C27.1704 8.57568 26.8159 7.8877 25.0591 7.896C23.3022 7.90381 21.6953 8.50391 19.647 9.30371C19.3477 9.42383 19.0322 9.51172 18.7095 9.58398C16.8501 9.22363 14.9199 9.14355 12.9033 9.37598C9.10596 9.80762 6.07275 11.6396 3.84326 14.7681C1.16455 18.5278 0.53418 22.7998 1.30664 27.2559C2.11768 31.9521 4.46582 35.8398 8.07373 38.8799C11.8159 42.0322 16.1255 43.5762 21.041 43.2803C24.0269 43.104 27.3516 42.6963 31.1016 39.4561C32.0469 39.936 33.0396 40.1279 34.686 40.272C35.9546 40.3921 37.1758 40.208 38.1211 40.0078C39.6021 39.688 39.4995 38.2881 38.9639 38.0322C34.623 35.9678 35.5762 36.8081 34.71 36.1279C36.9155 33.4639 40.2402 30.6958 41.54 21.728C41.6426 21.0161 41.5557 20.5679 41.54 19.9917C41.5322 19.6396 41.6108 19.5039 42.0049 19.4639C43.0923 19.3359 44.1479 19.0317 45.1167 18.4878C47.9292 16.9199 49.064 14.3438 49.3315 11.2559C49.3711 10.7837 49.3237 10.2959 48.8354 10.0479ZM24.3262 37.8398C20.1196 34.4639 18.0791 33.3521 17.2358 33.3999C16.4482 33.4482 16.5898 34.3682 16.7632 34.9678C16.9443 35.5601 17.1812 35.9683 17.5117 36.4878C17.7402 36.832 17.8979 37.3442 17.2832 37.728C15.9282 38.584 13.5728 37.4399 13.4624 37.3838C10.7207 35.7358 8.42822 33.5601 6.81348 30.584C5.25342 27.7197 4.34766 24.6479 4.19775 21.3677C4.1582 20.5757 4.38672 20.2959 5.15869 20.1519C6.17529 19.96 7.22314 19.9199 8.23926 20.0718C12.5327 20.7119 16.1885 22.6719 19.2529 25.7759C21.002 27.5439 22.3252 29.6558 23.6885 31.7202C25.1377 33.9121 26.6978 36 28.6831 37.7119C29.3843 38.312 29.9434 38.7681 30.479 39.104C28.8643 39.2881 26.1699 39.3281 24.3262 37.8398ZM26.3433 24.6001C26.3433 24.248 26.6191 23.9678 26.9658 23.9678C27.0444 23.9678 27.1152 23.9839 27.1782 24.0078C27.2651 24.04 27.3438 24.0879 27.4067 24.1602C27.5171 24.272 27.5801 24.4321 27.5801 24.6001C27.5801 24.9521 27.3042 25.2319 26.9575 25.2319C26.6108 25.2319 26.3433 24.9521 26.3433 24.6001ZM32.6064 27.8799C32.2046 28.0479 31.8027 28.1919 31.4165 28.208C30.8179 28.2397 30.1641 27.9922 29.8096 27.688C29.2583 27.2158 28.8643 26.9521 28.6987 26.1279C28.6279 25.7759 28.6675 25.2319 28.7305 24.9199C28.8721 24.248 28.7144 23.8159 28.2495 23.4238C27.8716 23.104 27.3911 23.0161 26.8633 23.0161C26.666 23.0161 26.4849 22.9277 26.3511 22.856C26.1304 22.7441 25.9492 22.4639 26.1226 22.1201C26.1777 22.0078 26.4458 21.7358 26.5088 21.688C27.2256 21.272 28.0527 21.4077 28.8169 21.7197C29.5259 22.0161 30.0615 22.5601 30.834 23.3281C31.6216 24.2559 31.7632 24.5117 32.2124 25.208C32.5669 25.752 32.8901 26.312 33.1104 26.9521C33.2446 27.3521 33.0713 27.6802 32.6064 27.8799Z" fill="#1a1a1a"/></g><text class="lbl" x="48" y="104">0 · idle</text><rect class="chip" x="104" y="8" width="80" height="80" rx="20"/><g transform="translate(119,23)"><path id="p1" d="M48.8354 10.0479C48.3232 9.79199 48.1025 10.2798 47.8032 10.5278C47.7007 10.6079 47.6143 10.7119 47.5273 10.8076C46.7793 11.624 45.9048 12.1597 44.7622 12.0957C43.0923 12 41.666 12.5356 40.4058 13.8398C40.1377 12.2319 39.2476 11.272 37.8926 10.6558C37.1836 10.3359 36.4668 10.0156 35.9702 9.31982C35.6235 8.82373 35.5293 8.27197 35.356 7.72754C35.2456 7.3999 35.1353 7.06396 34.7651 7.00781C34.3633 6.94385 34.2056 7.2876 34.0479 7.57568C33.418 8.75195 33.1733 10.0479 33.1973 11.3599C33.2524 14.312 34.4736 16.6641 36.8999 18.3359C37.1758 18.5278 37.2466 18.7197 37.1597 19C36.9946 19.5757 36.7974 20.1357 36.624 20.7119C36.5137 21.0801 36.3486 21.1597 35.9624 21C34.6309 20.4321 33.481 19.5918 32.4644 18.5757C30.7393 16.8721 29.1792 14.9917 27.2334 13.52C26.7764 13.1758 26.3193 12.856 25.8467 12.5518C23.8618 10.584 26.1069 8.96777 26.627 8.77588C27.1704 8.57568 26.8159 7.8877 25.0591 7.896C23.3022 7.90381 21.6953 8.50391 19.647 9.30371C19.3477 9.42383 19.0322 9.51172 18.7095 9.58398C16.8501 9.22363 14.9199 9.14355 12.9033 9.37598C9.10596 9.80762 6.07275 11.6396 3.84326 14.7681C1.16455 18.5278 0.53418 22.7998 1.30664 27.2559C2.11768 31.9521 4.46582 35.8398 8.07373 38.8799C11.8159 42.0322 16.1255 43.5762 21.041 43.2803C24.0269 43.104 27.3516 42.6963 31.1016 39.4561C32.0469 39.936 33.0396 40.1279 34.686 40.272C35.9546 40.3921 37.1758 40.208 38.1211 40.0078C39.6021 39.688 39.4995 38.2881 38.9639 38.0322C34.623 35.9678 35.5762 36.8081 34.71 36.1279C36.9155 33.4639 40.2402 30.6958 41.54 21.728C41.6426 21.0161 41.5557 20.5679 41.54 19.9917C41.5322 19.6396 41.6108 19.5039 42.0049 19.4639C43.0923 19.3359 44.1479 19.0317 45.1167 18.4878C47.9292 16.9199 49.064 14.3438 49.3315 11.2559C49.3711 10.7837 49.3237 10.2959 48.8354 10.0479ZM24.3262 37.8398C20.1196 34.4639 18.0791 33.3521 17.2358 33.3999C16.4482 33.4482 16.5898 34.3682 16.7632 34.9678C16.9443 35.5601 17.1812 35.9683 17.5117 36.4878C17.7402 36.832 17.8979 37.3442 17.2832 37.728C15.9282 38.584 13.5728 37.4399 13.4624 37.3838C10.7207 35.7358 8.42822 33.5601 6.81348 30.584C5.25342 27.7197 4.34766 24.6479 4.19775 21.3677C4.1582 20.5757 4.38672 20.2959 5.15869 20.1519C6.17529 19.96 7.22314 19.9199 8.23926 20.0718C12.5327 20.7119 16.1885 22.6719 19.2529 25.7759C21.002 27.5439 22.3252 29.6558 23.6885 31.7202C25.1377 33.9121 26.6978 36 28.6831 37.7119C29.3843 38.312 29.9434 38.7681 30.479 39.104C28.8643 39.2881 26.1699 39.3281 24.3262 37.8398ZM26.3433 24.6001C26.3433 24.248 26.6191 23.9678 26.9658 23.9678C27.0444 23.9678 27.1152 23.9839 27.1782 24.0078C27.2651 24.04 27.3438 24.0879 27.4067 24.1602C27.5171 24.272 27.5801 24.4321 27.5801 24.6001C27.5801 24.9521 27.3042 25.2319 26.9575 25.2319C26.6108 25.2319 26.3433 24.9521 26.3433 24.6001ZM32.6064 27.8799C32.2046 28.0479 31.8027 28.1919 31.4165 28.208C30.8179 28.2397 30.1641 27.9922 29.8096 27.688C29.2583 27.2158 28.8643 26.9521 28.6987 26.1279C28.6279 25.7759 28.6675 25.2319 28.7305 24.9199C28.8721 24.248 28.7144 23.8159 28.2495 23.4238C27.8716 23.104 27.3911 23.0161 26.8633 23.0161C26.666 23.0161 26.4849 22.9277 26.3511 22.856C26.1304 22.7441 25.9492 22.4639 26.1226 22.1201C26.1777 22.0078 26.4458 21.7358 26.5088 21.688C27.2256 21.272 28.0527 21.4077 28.8169 21.7197C29.5259 22.0161 30.0615 22.5601 30.834 23.3281C31.6216 24.2559 31.7632 24.5117 32.2124 25.208C32.5669 25.752 32.8901 26.312 33.1104 26.9521C33.2446 27.3521 33.0713 27.6802 32.6064 27.8799Z" fill="#FACC15"/></g><text class="lbl" x="144" y="104">1 · running</text><rect class="chip" x="200" y="8" width="80" height="80" rx="20"/><rect class="" x="215" y="23" width="50" height="50" rx="11" fill="#FACC15"/><text x="240" y="56.8" text-anchor="middle" font-family="system-ui,sans-serif" font-size="26" font-weight="800" fill="#111111">2</text><text class="lbl" x="240" y="104">2 · running</text><rect class="chip" x="296" y="8" width="80" height="80" rx="20"/><rect class="" x="311" y="23" width="50" height="50" rx="11" fill="#FACC15"/><text x="336" y="56.8" text-anchor="middle" font-family="system-ui,sans-serif" font-size="26" font-weight="800" fill="#111111">3</text><text class="lbl" x="336" y="104">3 · running</text><rect class="chip" x="392" y="8" width="80" height="80" rx="20"/><rect class="ask" x="407" y="23" width="50" height="50" rx="11" fill="#E5484D"/><text x="432" y="56.8" text-anchor="middle" font-family="system-ui,sans-serif" font-size="26" font-weight="800" fill="#FFFFFF">3</text><text class="lbl" x="432" y="104">3 · asking</text><rect class="chip" x="488" y="8" width="80" height="80" rx="20"/><rect class="" x="503" y="23" width="50" height="50" rx="11" fill="#FACC15"/><text x="528" y="53.3" text-anchor="middle" font-family="system-ui,sans-serif" font-size="15.5" font-weight="800" fill="#111111">99+</text><text class="lbl" x="528" y="104">100 · running</text></svg>
package/lib/index.js CHANGED
@@ -22,8 +22,9 @@
22
22
  * session into `asking` while the agent waits on the user for a
23
23
  * permission decision (covers sandbox escalations too).
24
24
  * - `agent/turn-stopping` flips `running`/`asking` into `done`.
25
- * - A lost `tools/result` cannot pin `asking` forever: the hold re-arms at
26
- * most ASK_MAX_REARM times, then force-releases against live status.
25
+ * - A lost `tools/result` cannot pin `asking` forever either: the hold keeps
26
+ * re-arming while the agent is still `running` (the user may be deciding),
27
+ * and force-releases against live status once the turn ends.
27
28
  * - `reconcile()` (on every status request) watches `agents.list()` for
28
29
  * running→idle transitions as a fallback.
29
30
  * - The status endpoint also reports `active` — the number of non-idle
@@ -539,34 +540,35 @@ export default {
539
540
  if (!asking.has(id)) setState(id, "done");
540
541
  });
541
542
 
542
- // Asking: visible minimum (askingHoldMs). Re-arm timer while user
543
- // is still answering; clean up to live agent status once returned.
543
+ // Asking: visible minimum (askingHoldMs). Re-arm timer while the user is
544
+ // still answering; clean up to live agent status once returned.
544
545
  // A call for a brand-new pin cancels any still-pending timer first, so a
545
546
  // fast pre-execute→idle→pre-execute round-trip can't stack two timers.
546
- // as a lost `tools/result` would otherwise re-arm forever and pin the
547
- // icon to asking indefinitely.
548
- const ASK_MAX_REARM = 2; // re-arm cap while waiting on a result
549
- const askWaits = new Map(); // agentId -> consecutive re-arm count
547
+ // The pin is kept alive as long as the agent is still `running` the user
548
+ // may be reading a long question, and a fixed re-arm budget would drop the
549
+ // icon mid-think. It force-releases against live status once the agent
550
+ // leaves `running`, so a lost `tools/result` cannot pin `asking` forever.
550
551
  const scheduleAskCheck = (id) => {
551
552
  const prevHandle = askTimers.get(id);
552
553
  if (prevHandle) { try { prevHandle(); } catch (e) {} askTimers.delete(id); }
553
554
  const handle = ctx.timer.timeout(() => {
554
555
  askTimers.delete(id);
555
- if (!asking.has(id)) { askWaits.delete(id); return; }
556
+ if (!asking.has(id)) return;
556
557
  if (!askDone.has(id)) {
557
- const n = (askWaits.get(id) || 0) + 1;
558
- if (n <= ASK_MAX_REARM) { askWaits.set(id, n); scheduleAskCheck(id); return; }
559
- // Result never arrived: force-release the pin against live status so
560
- // a lost tools/result cannot keep the icon blinking forever.
561
- askWaits.delete(id);
558
+ const live = agents.get(id);
559
+ // Result not yet reported AND the agent is still mid-turn: the user
560
+ // may still be deciding — keep the pin (no re-arm budget; a human
561
+ // question can legitimately outlast many hold windows).
562
+ if (live && live.status === "running") { scheduleAskCheck(id); return; }
563
+ // Result never arrived and the turn ended (agent idle / gone): a lost
564
+ // tools/result cannot keep the icon blinking forever — force-release
565
+ // the pin against live status.
562
566
  asking.delete(id);
563
567
  askDone.delete(id);
564
- const live = agents.get(id);
565
568
  if (live) setState(id, live.status === "running" ? "running" : "idle");
566
569
  else setState(id, "idle");
567
570
  return;
568
571
  }
569
- askWaits.delete(id);
570
572
  asking.delete(id);
571
573
  askDone.delete(id);
572
574
  const live = agents.get(id);
@@ -582,7 +584,6 @@ export default {
582
584
  if (id != null) {
583
585
  asking.add(id);
584
586
  askDone.delete(id);
585
- askWaits.delete(id); // fresh pin restarts the re-arm budget
586
587
  setState(id, "asking");
587
588
  scheduleAskCheck(id);
588
589
  }
@@ -626,7 +627,6 @@ export default {
626
627
  askDone.delete(id);
627
628
  pendingApprovals.delete(id);
628
629
  lastSeen.delete(id);
629
- askWaits.delete(id);
630
630
  cancelDoneHold(id);
631
631
  const t = askTimers.get(id);
632
632
  if (t) { try { t(); } catch (e) {} askTimers.delete(id); }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-web-icon-indicator",
3
3
  "description": "Browser tab favicon reflects the DSH session state: idle / running / asking / done, recolored and animated from one base SVG in the browser (fully configurable colors + effects). · 浏览器标签页 favicon 实时反映 DSH 会话状态:待机 / 运行中 / 提问 / 完成,由单个 base.svg 在浏览器中动态上色与动画(颜色与特效完全可配置)。",
4
- "version": "0.3.0",
4
+ "version": "0.3.1",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/types/index.d.ts",